Skip to content

8822E: fix MCS4+/48M+ TX, resolve the 0x41e8 RX-desense quirk, port kernel channel/runtime obligations + quirks doc (#238)#268

Merged
josephnef merged 2 commits into
masterfrom
238-8822e-quirks-campaign
Jul 12, 2026
Merged

8822E: fix MCS4+/48M+ TX, resolve the 0x41e8 RX-desense quirk, port kernel channel/runtime obligations + quirks doc (#238)#268
josephnef merged 2 commits into
masterfrom
238-8822e-quirks-campaign

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Closes the reproducible half of #238 on the reference hardware (LB-LINK BL-M8812EU2, rfe-21) and lands the issue's deliverable, docs/8822e-quirks.md. Everything below is hardware-validated on the two-adapter bench (8812EU ↔ 8822CU, plus the vendor kernel and an in-tree rtw88 ground as controls); reproducers ship under tests/.

Root causes & fixes

  • MCS4+/48M+ whole-PPDU TX corruption (the follow-up comments' bug): two interacting halves —
    1. the DPDT antenna switch was never routed to WL control (halmac pin-mux family devourer's hand-rolled MAC init skips): REG_LED_CFG 0x4c[24] = BIT_DPDT_WLBT_SEL set, [22] clear, applied post-coex;
    2. OFDM 1SS TX must ride ONE path (kernel txpath_1ss semantics): 0x820=0x32 (1ss-B) at 5 GHz / 0x31 at 2.4 GHz. The old 1ss-on-both mapping interacts with the DPDT fix (MCS0 wedges).
      Result: MCS7 goes 0 → ~5000 clean/12 s EVM −48; full ladder MCS0/4/7/54M clean; 40 MHz 5226 @ −53; 80 MHz TX verified against an independent kernel ground (5658 frames).
  • Quirk Small mods to build on android #1 (0x41e8 path-B RX-desense) RESOLVED: it was a downstream artifact of the same front-end mis-config, not TSSI asymmetry (tests/eu_41e8_desense_recheck.sh: poking the ref with RX live = −2 %, noise). The structural skip is retired — path-B OFDM TX power is controllable in TX+RX mode again (full-duplex proof: 24k RX frames + 14.3k clean MCS7 simultaneously, tests/eu_fullduplex_pathb_check.sh).
  • RF reg 0x0 writes silently no-op'd through the direct BB window — routed through the legacy FON port 0x1808/0x4108 per the kernel, in both halrf impls AND the radio-table loader (the vendor tables carry reg-0 entries). Verified via the TXGAPK gain-table readback (all-zero before, kernel-shaped ramps after).
  • Construction-time TX-power state was clobbered by the FW power/coex H2Cs — authoritative TXAGC re-apply now runs after them; PAD_CTRL1[29:28] re-asserted there too.

Kernel channel/runtime obligations ported (systematic source diff vs reference/rtl88x2eu)

  • Spur elimination (14 harmonic channel/BW combos + explicit spur-free default, every switch; FastRetune declines spur hops — hop parity PASS at 20 and 40 MHz)
  • CCK TX shaping filter (per-2.4 GHz-channel, ch14 special set)
  • IGI toggle after every full channel set, both variants — fixes the intermittent post-switch RX deafness / first-cell TX wedge (CU ch6 ground liveness 5/5, EU wedge 0/6 repro)
  • LCK synthesizer re-lock on ≥4-unit thermal drift (fired live in a 22-min max-duty soak: 1.10 M clean MCS7 frames, EVM drift +3 dB)
  • phydm monitor-mode dynamic mechanisms (PhydmRuntimeJaguar3): FA/CCA statistics, unlinked DIG, CCK-PD type4, EDCCA tracking — with one hardware-forced deviation: the DIG floor is 0x1e, not phydm's generic 0x1c (at 0x1c the 8822CU's dense-QAM RX decodes 0 of 65k MCS7 frames; 0x1e passes 65.9k — same class as the kernel's per-IC "For HW setting" exceptions). RX-only sessions tick from a dedicated thread (register I/O on the bulk-IN event thread starves its own event loop).

Verified non-gaps & closures

  • TSSI subsystem NOT needed (kernel runs thermal mode here; 0x1e7c[30]=0 under both drivers); thermal LUT already at parity; TX descriptor byte-identical (48 B).
  • Matched-power TX EVM parity (tests/eu_matched_power_evm.sh, refs bit-identical): MCS7 median −60 under both drivers.
  • Quirk Fix unreadable code in logs #3 (2.4 GHz TX): kernel parity — the module airs undecodable 2.4 GHz under BOTH drivers (in-session verified ground; 51k kernel frames → 0). README bench row corrected; not a devourer gap.
  • Quirks Log libusb error code in rtw_read #2/Remove color code in logger #6 validated (2.4 GHz RX on ch1/6/11 + 11× 5↔2.4 band-hop cycles; RF 0x1a TX_CCK_IND held post-IQK in full and fast paths).

Out of scope / follow-ups

ctest 19/19 across the rebase onto current master; per-chip config subsets build (spot-checked no-Jaguar3).

🤖 Generated with Claude Code

josephnef and others added 2 commits July 12, 2026 09:59
…nel/runtime obligations (#238)

Root causes found by golden end-state diff (kernel via /proc read_reg live vs
devourer via new DEVOURER_BB_DUMP, 0x000..0x4ffc) + subset bisection with a
Jaguar3 DEVOURER_REPLAY_WSEQ port, kernel-TX ground truth on the same unit.

Fixes (all bench-validated, 8812EU->8822CU ch36 + SDR):
- MCS4+/48M+ whole-PPDU TX corruption: route the DPDT antenna switch to WL
  control (REG_LED_CFG 0x4c[24] = BIT_DPDT_WLBT_SEL, [22] clear; halmac
  pinmux family devourer's hand-rolled MAC init skipped) + single-path OFDM
  1SS TX routing (0x820: 1ss-B@5G / 1ss-A@2G, kernel semantics; the old
  1ss-on-AB mapping interacts with the DPDT fix and wedges MCS0). MCS7 goes
  0 -> ~5000 clean/12s EVM -48; full ladder MCS0/4/7/54M clean.
- 0x41e8 path-B RX-desense quirk RESOLVED: it was a downstream artifact of
  the same front-end mis-config, not TSSI asymmetry. Structural skip retired;
  path-B OFDM TX power is controllable in TX+RX mode again (full-duplex
  validated: 24k RX frames + 14.3k clean MCS7 simultaneously).
- RF reg 0x0 writes: direct-window writes silently no-op; route through the
  legacy FON port 0x1808/0x4108 (addr<<20|data) in Halrf8822e, Halrf8822c
  and the radio-table loader (vendor tables carry reg-0 entries).
- Construction-time TX-power state was clobbered by the FW power/coex H2Cs:
  authoritative TXAGC re-apply now runs post-coex (with readback diff log);
  PAD_CTRL1[29:28] re-asserted there too.
- Channel-switch ports from the kernel switch_channel tail: spur elimination
  (14 harmonic channel/BW combos, NBI+CSI mask; FastRetune declines spur
  hops), CCK TX shaping filter (per-2G-channel, ch14 special), IGI toggle on
  BOTH Jaguar3 variants (fixes the intermittent post-switch RX deafness /
  MCS0 first-cell TX wedge; CU ch6 ground liveness now 5/5).
- LCK synthesizer re-lock (AACK+RTK on >=4-unit thermal drift) wired into the
  coex-tick thermal tracker; fired live in a 22-min max-duty soak (1.10M
  clean MCS7 frames, EVM drift +3 dB).

Verified non-gaps: TSSI subsystem (kernel runs THERMAL mode here, 0x1e7c[30]
= 0 both drivers), thermal codeword LUT (end-state identical), TX descriptor
(48B, byte-identical). 2.4 GHz TX airs undecodable frames under BOTH drivers
(kernel-parity, module property) -- README row corrected, quirk documented.

Docs: docs/8822e-quirks.md (the issue deliverable -- every quirk root-caused
or kernel-parity-proven, with reproducers). Diag: replay hook at end of both
bring-ups, DEVOURER_BB_DUMP, coex-tick TXAGC register watch,
DEVOURER_TX_PWR_OFFSET_QDB on txdemo. Tests: 14 new harnesses
(tests/eu_*.sh, cu_2g_ground_liveness.sh, sdr_burst_len.py);
txpwr_offset_regcheck.sh path-B cell inverted to the new semantics.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…D/EDCCA)

The vendor watchdog's RX-side adaptation loop, run every ~2 s like the
kernel's: false-alarm/CCA window statistics (read + reset,
phydm_fa_cnt_statistics_jgr3), unlinked DIG (IGI stepping in 0x1d70 by FA
level, DFS channels pinned to 0x20), CCK packet-detection type4 (CCK-FA
moving average driving the PD/CS ladder in 0x1ac8/0x1acc/0x1ad0), and EDCCA
threshold tracking (0x84c, th_l2h = max(IGI+8, 48) / -8 — matches the
kernel's end state; suppressed while SetCcaMode's EDCCA-disable is active).

The DIG coverage window floors at 0x1e, not phydm's generic
DIG_MIN_COVERAGE 0x1c: at IGI 0x1c the 8822CU's dense-QAM RX decodes
NOTHING (0 of 65k kernel-injected MCS7 frames; 0x1e passes 65.9k) —
hardware-bisected, value-specific, the same class of per-IC "For HW
setting" floor exception the kernel carries for other ICs.

TX/TX+RX sessions tick from the coex thread; RX-only sessions get a
dedicated housekeeping thread — register I/O cannot run on the bulk-IN
event thread (a sync control transfer there starves its own event loop).

The kernel's remaining watchdog mechanisms self-disable without a link and
are intentionally absent: CFO tracking (returns unless associated), RA and
the beamforming watchdog (no station entries), antenna diversity (2T2R).

Matched-power TX EVM parity verified (tests/eu_matched_power_evm.sh, one
ground session, refs bit-identical at devourer offset -44 == kernel
`txpower fixed 500`): MCS7 median EVM -60 both drivers; MCS0 -64 vs -66.
Default-power ladder unchanged (MCS7 6407 clean / -48, MCS0 5680 / -27).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef merged commit b5a6df7 into master Jul 12, 2026
15 checks passed
@josephnef josephnef deleted the 238-8822e-quirks-campaign branch July 12, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant