From 4f5675d612eb81d3aeb02d0c77d57f43678fe37a Mon Sep 17 00:00:00 2001 From: Joseph <162703152+josephnef@users.noreply.github.com> Date: Fri, 29 May 2026 22:47:33 +0300 Subject: [PATCH] RTL8814AU: post-fwdl init block was mis-gated on CHIP_8821 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The block in `rtl8812au_hal_init()` whose comment said "Trace-derived 8814 post-fwdl init writes" and whose closing log line said "8814A: REG_MACID + trace-derived post-fwdl writes applied" was inside `if (CHIP_8821) {}`. On 8814AU it never ran — REG_RRSR (0x0440), 0x04bc, REG_QUEUE_CTRL (0x04c6), REG_TX_PTCL_CTRL (0x0520), REG_RD_CTRL (0x0524), 0x0670 (NAV-related), and the RA-table base 0x0990-0x09a4 were left at their chip-reset defaults. Cold-init usbmon diff vs `aircrack-ng/88XXau` (devourer-testrig VM, 2026-05-29) flagged all of these as kernel-only writes. Compounded: the u32 values in those calls stored wire-byte order rather than LE u32. On a little-endian host, `rtw_write32(0x0440, 0xff0f0000u)` puts the value in memory as `00 00 0f ff` and that's what hits the wire — exactly the opposite of what kernel writes (`ff 0f 00 00`, u32 0x00000fff). Even if the block had run on the 8814 path, every value would have been byte-reversed. This commit: * Moves the misnamed block out of `if (CHIP_8821)` and into an `if (is_8814a)` block. * Reverses the u32 literals to match what the kernel actually writes on the wire: 0x0440 0xff0f0000u → 0x00000fffu (REG_RRSR: all-rates response mask) 0x0520 0x0f2f0000u → 0x00002f0fu (REG_TX_PTCL_CTRL) 0x0670 0x000000c0u → 0xc0000000u (NAV-related) 0x0990 0xffff1027u → 0x27100000u (RA-table base) 0x0994 0x0001484cu → 0x4c480100u 0x0998 0x24282c30u → 0x302c2824u 0x099c 0x34383c40u → 0x403c3834u 0x09a0 0x44000000u → 0x00000044u 0x09a4 0x80000800u → 0x00080080u 0x04bc and 0x04c6 are 1-byte writes (no endian issue). 0x0524 kept at 0xf4fff00u — no usbmon-trace reference value in the current capture set; left unchanged so this commit is strictly a scope-correction + byte-order fix rather than a value-rewrite. * Drops the misleading "REG_MACID +" prefix from the log line — MAC programming lives in the separate `if (is_8814a)` block earlier in the function. Verified on the wire post-fix (tools/usbmon_pcap_diff.py against an 8814AU cold-init capture): the previously-absent addresses now appear with byte values matching the kernel's, reducing the kernel-only address delta from 19 to 15 (the remaining 15 are IQK / DPK calibration loop writes plus a periodic GPIO heartbeat, neither of which devourer has infrastructure to replicate). Does NOT close the 8814AU on-air TX gate by itself — AR9271 + 8812AU + 8821AU sniffer triplet still observes zero frames matching CANONICAL_SA post-fix. The gate remains at a level not reachable from usbmon. But the 8814 path now correctly applies the TX-protocol setup the kernel relies on, which is a prerequisite for any further investigation. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/HalModule.cpp | 71 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 23 deletions(-) diff --git a/src/HalModule.cpp b/src/HalModule.cpp index a296652..66b380d 100644 --- a/src/HalModule.cpp +++ b/src/HalModule.cpp @@ -525,34 +525,59 @@ bool HalModule::rtl8812au_hal_init() { _device.rtw_write32(0x0cb4, 0x20000077u); _device.rtw_write32(0x0e90, 0x01800c00u); _logger->info("8821 trace-derived BB/AGC value overrides applied"); + } - /* Trace-derived 8814 post-fwdl init writes. usbmon diff vs - * kernel-driver (cold-init → monitor → inject) revealed these are - * present in the kernel path and absent from devourer. Applied as a - * batch to bring devourer's chip state into MAC-TX-ready shape. + if (is_8814a) { + /* Trace-derived 8814 post-fwdl init writes. Captured from + * aircrack-ng/88XXau cold-init → monitor → inject; usbmon diff vs + * devourer surfaced these as kernel-only writes. Previously these + * lived inside the `if (CHIP_8821)` block above (BUG: they were + * gated on the 8821 path and never ran on 8814AU, fixed here 2026-05-29 + * after the per-register diff cross-check confirmed they were absent + * from the wire on every 8814AU run). * - * REG_RRSR (0x0440) = 0xff0f0000 Response Rate Set - * 0x04bc = 0x00 TX queue gate - * REG_QUEUE_CTRL (0x04c6) = 0x04 Queue control - * REG_TX_PTCL_CTRL (0x520) = 0x0f2f0000 TX protocol control - * REG_RD_CTRL (0x0524) = 0x0f4fff00 RD control - * 0x0670 = 0x000000c0 NAV-related - * RA-table init at 0x0990-0x09a4 + * Values are LITTLE-ENDIAN u32. usbmon shows wire bytes in + * transmission order, so to write a value via rtw_write32 on a LE + * host the bytes need to be reversed from the usbmon text. The + * previous values stored the wire bytes directly as u32 (e.g. + * `0xff0f0000u` for REG_RRSR), which produced wire bytes `00 00 0f ff` + * on the chip — opposite of what kernel writes (`ff 0f 00 00` ⇒ + * u32 = 0x00000fff). The reversed values below match the kernel + * wire byte-for-byte. + * + * addr kernel wire bytes → u32 to write + * 0x0440 ff 0f 00 00 0x00000fff REG_RRSR + * 0x04bc 00 0x00 TX queue gate (1 byte) + * 0x04c6 04 0x04 REG_QUEUE_CTRL (1 byte) + * 0x0520 0f 2f 00 00 0x00002f0f REG_TX_PTCL_CTRL + * 0x0524 00 ff 4f 0f 0x0f4fff00 REG_RD_CTRL + * (kept value; no usbmon + * trace for 0x0524 in + * current capture set) + * 0x0670 00 00 00 c0 0xc0000000 NAV-related + * 0x0990 00 00 10 27 0x27100000 RA-table base + * 0x0994 00 01 48 4c 0x4c480100 + * 0x0998 24 28 2c 30 0x302c2824 + * 0x099c 34 38 3c 40 0x403c3834 + * 0x09a0 44 00 00 00 0x00000044 + * 0x09a4 80 00 08 00 0x00080080 */ - _device.rtw_write32(0x0440, 0xff0f0000u); /* REG_RRSR */ + _device.rtw_write32(0x0440, 0x00000fffu); /* REG_RRSR */ _device.rtw_write8(0x04bc, 0x00); _device.rtw_write8(0x04c6, 0x04); /* REG_QUEUE_CTRL */ - _device.rtw_write32(0x0520, 0x0f2f0000u); /* REG_TX_PTCL_CTRL */ - _device.rtw_write32(0x0524, 0x0f4fff00u); /* REG_RD_CTRL */ - _device.rtw_write32(0x0670, 0x000000c0u); - /* Rate-adaptation table init (final values from trace). */ - _device.rtw_write32(0x0990, 0xffff1027u); - _device.rtw_write32(0x0994, 0x0001484cu); - _device.rtw_write32(0x0998, 0x24282c30u); - _device.rtw_write32(0x099c, 0x34383c40u); - _device.rtw_write32(0x09a0, 0x44000000u); - _device.rtw_write32(0x09a4, 0x80000800u); - _logger->info("8814A: REG_MACID + trace-derived post-fwdl writes applied"); + _device.rtw_write32(0x0520, 0x00002f0fu); /* REG_TX_PTCL_CTRL */ + _device.rtw_write32(0x0524, 0x0f4fff00u); /* REG_RD_CTRL — kept */ + _device.rtw_write32(0x0670, 0xc0000000u); + /* Rate-adaptation table init (first-write values from cold-init + * trace; kernel emits 3+ runtime updates from IQK that devourer + * cannot reproduce — settle for the first/initial value). */ + _device.rtw_write32(0x0990, 0x27100000u); + _device.rtw_write32(0x0994, 0x4c480100u); + _device.rtw_write32(0x0998, 0x302c2824u); + _device.rtw_write32(0x099c, 0x403c3834u); + _device.rtw_write32(0x09a0, 0x00000044u); + _device.rtw_write32(0x09a4, 0x00080080u); + _logger->info("8814A: trace-derived post-fwdl writes applied"); } if (is_8814a) {