jaguar3: EFUSE walk assumed ordered sections and quit early (8822C read rfe_type=0) - #384
jaguar3: EFUSE walk assumed ordered sections and quit early (8822C read rfe_type=0)#384snokvist wants to merge 2 commits into
Conversation
PR Summary by QodoFix Jaguar3 EFUSE decode to handle unordered logical sections
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1.
|
|
Both review findings addressed. 1. Read past if (a >= kPhysMax)
return 0xFF;
2. Stale Re-verified on hardware after both changes, unchanged from the original results:
|
josephnef
left a comment
There was a problem hiding this comment.
Reviewed with the branch checked out; decode math verified against the dump, callers audited. The fix is correct and the hardware evidence is exactly the right shape — before/after on the affected 8822CU cross-validated against the vendor kernel efuse_map, with the 8822EU as an explicit no-change regression check. CI fully green.
Correctness — verified:
- The decode math checks out against the dump:
hdr=0x0F ext=0x48→ offset0x20→ base0x100;hdr=0x4F ext=0x5D→0x2A→ base0x150. Both match the hand-decode, so the unordered-sections claim is substantiated, not inferred. - Removing
uptoinstead of leaving it unused is the right call — a parameter that looks like a bound but isn't would reintroduce exactly this bug class. - Smaller callers stay safe:
read_efuse_rfe_type's0x140-byte stack map vs the section at base0x150is handled by theidx < lenguard on every data write. - The
kPhysMaxguard inrd()is load-bearing, not belt-and-braces:efuse_OneByteReadmasks to 10 bits, so a truncated straddling section would alias back to phys 0 and decode the start of the EFUSE into a bogus logical base. Previously theuptobreak made that unreachable; with the full walk it matters. - 8822E untouched as claimed: the EU branch
returns before the removed break, and neither of its callers depended onupto.
Performance: the 8822C non-cached paths now walk the full programmed area (per-byte USB control reads), but the walk still stops at the first 0xFF header and both callers are one-shot at bring-up/probe time — no meaningful cost.
One factual error in the shipped comment (inline, worth fixing before merge — it's the kind of number a future debugging session will trust) plus two comment-style nits inline.
| * so asking for anything below 0x100 — including EEPROM_RFE_OPTION at 0xCA — | ||
| * ended the walk after three sections and returned a map that was 0xFF almost | ||
| * everywhere. On that adapter read_efuse_rfe_type() therefore returned 0 while | ||
| * the kernel driver read 0x15 from the same chip, i.e. the BB/RFE config was |
There was a problem hiding this comment.
Factual slip: per the PR's own hardware table, the kernel value on the affected 8822CU is 0x03 — 0x15 is the 8822EU's (the regression-check adapter). The follow-up commit says "correct the stale doc" but this one survived it. Worth fixing: this exact number is what a future debugging session will trust.
| * the kernel driver read 0x15 from the same chip, i.e. the BB/RFE config was | |
| * the kernel driver read 0x03 from the same chip, i.e. the BB/RFE config was |
| * fills 0xFF for gaps). Standard Realtek section format: header (or header+ext) | ||
| * gives a logical block offset + 4-bit word-enable; each enabled 2-byte word | ||
| * follows. */ | ||
| * including the block holding) every programmed logical offset. Shared by |
There was a problem hiding this comment.
Splice leftover from the old "up to offset upto" text — "up to (and including the block holding) every programmed logical offset" is grammatically broken now. Simpler to just say it decodes the whole programmed area.
Also (pre-existing, but this PR grows the block 4×): this comment documents read_efuse_logical_map yet sits above probe_efuse_map. Consider moving it down to the function it describes while touching it.
| * header (or header+ext) gives a logical block offset + 4-bit word-enable; each | ||
| * enabled 2-byte word follows. | ||
| * | ||
| * The walk runs to the end of the programmed area. It used to stop early once a |
There was a problem hiding this comment.
Style nit: the "It used to stop early…" framing is changelog-ish — git carries the history. The measured phys dump is the valuable part (it proves the unordered-sections invariant) and should stay; the framing could be present-tense: "sections are not in ascending base order (measured on an RTL8822CU: …), so the walk must not stop at any requested offset."
The bug
HalJaguar3::read_efuse_logical_mapstopped walking as soon as a section'slogical base passed the byte the caller asked for:
That is only valid if sections appear in ascending base order. They do not.
Physical EFUSE dumped off an RTL8822CU (
0bda:c812), decoded by hand:The third section on the chip jumps to base 0x100, so any request below that
— including
EEPROM_RFE_OPTION_8822Cat logical 0xCA, which is the whole reasonread_efuse_rfe_type()calls this — ended the walk after three sections andreturned a map that was 0xFF almost everywhere.
Why it matters
On the affected adapter
read_efuse_rfe_type()returned 0, while the vendorkernel driver reads 0x03 from the same chip
(
/proc/net/rtl88x2cu/<iface>/efuse_map, logical 0xCA). The RFE type gates BB /RFE configuration, so those units were being brought up against an unprogrammed
default rather than their actual front-end.
It is silent: nothing errors, the map just reads unprogrammed.
The fix
Walk the whole programmed area (the existing 0xFF-header terminator and
kPhysMaxbound already stop it). Theuptoparameter is removed rather thanleft unused — a parameter that still looks like it bounds the walk is how this
comes back.
The 8822E branch is untouched: it never used
upto, terminating on a long 0xFFrun instead, which is why only the C path was affected.
Hardware verification
efuse_map0xCA)0bda:c812, C8822C)rfe_type=0x00rfe_type=0x030bda:a81a, C8822E)rfe_type=0x15rfe_type=0x15The EU is the regression check — unchanged, and its
efuse decoded (0x22=46 0x4c=51 0xca=15)line is identical before and after. The 8822C EFUSE stabilityprobe also now reports a valid
0x8129EEPROM ID.Found while implementing #383 (EFUSE MAC as a per-unit identity), which could not
read the MAC on 8822C for this reason. With this fix that adapter's MAC decodes
correctly —
40:a5:ef:2f:23:08, matching its netdev exactly. The two changes areindependent; this one stands on its own regardless of what happens to #383.