Repository navigation
kestrel: 8852C TX path selection from P-MAC (dead ACK bring-ups) - #492
Conversation
Some 8852C bring-ups armed the ACK responder, read the entry back, and answered no ACK for the whole session (OpenIPC#490). The chip built the ACK, but the TX path selection the MAC attached to it was garbage in those bring-ups: it enabled a path this 2T2R die does not have, or mapped path A off the signal, so no antenna sent it. The selection comes from MAC state nothing initialises, which is why it changed per bring-up. The halbb glue now follows the T-MAC path routing at bring-up with halbb_ctrl_tx_path_pmac_8852c(RF_PATH_AB): the BB takes the path enable and the path A/B maps from its own P-MAC registers (0x09a4 [4:2]), paths A+B with A on IFFT 0 and B on IFFT 1, plus the vendor's per-path TSSI reset pulse. 8852C only; the switch applies to every PPDU. - ack_responder_ok is true on the 8852C as well (still an explicit list of measured variants). - docs/kestrel-ack-responder.md: the dead-bring-up section now gives the cause, how it was found (the TX-info debug port, decoded with the BB's INTF_TXINFO layout), what was ruled out, and the fix's numbers. Measured (TX50UH responder, TX20U Nano soliciting, ch161, MCS1, 8 s per session): before, 3 of 12, 6 of 15 and 4 of 30 sessions dead (the last on master with OpenIPC#491); the map-A-1 selection died 10 of 10 times. After, 0 dead of 123 armed sessions across the register-level override and this vendor call (30 of them on this exact code), 15 of them with the bad selection, all 96.8-100%; solicitor across a live disarm 3791/3845 then 0/1602 and 3829/3843 then 0/1639; never armed 0/1591. Second bench: 0 of 20 on ch6 and ch161, both units. One-stream injection unchanged (MCS1 and 6M ~1900/2000 to the 8852B, ch6 and ch161 with carrier sense on). Two- stream injection from the 8852C does not decode with or without this, so its effect there is not measured.
PR Summary by QodoFix intermittent 8852C ACK loss by selecting TX paths from P-MAC
AI Description
Diagram
High-Level Assessment
Files changed (7)
|
Code Review by Qodo
1.
|
…heck Review follow-up on the OpenIPC#490 requirements: - AdapterCaps.h and the doc give the date and time window of every responder series (the dead rate drifts through a day, OpenIPC#490 item 4). The 4-of-30 series without the fix ran between series with it, so the difference is not the time of day. - The doc states that OpenIPC#490's suggested experiments (firmware RAM dump of dead against good sessions, vendor-driver A/B on the same unit) were not run, and what the attribution rests on instead. - The injection numbers are scoped as a before/after check of this change on the same build, not an absolute 5 GHz TX figure; the vendor-driver injection A/B of OpenIPC#490 item 2 was not run.
The two experiments OpenIPC#490 proposed, run after the cause was found: - Firmware RAM: the firmware's writable data memory (about 590 KB, read through the indirect window at the CPU's own addresses) dumped in 26 sessions and grouped by the TX-info path word. No bit separates the groups, and the firmware's own few-valued words take each value in both, so the path selection is not recorded in firmware memory. - Vendor driver: the same TX50UH on the Realtek Windows driver, associated to an AP on ch161, through 45 full driver restarts: 0 dead, 88.6-98.3% ACKed, against 4 dead of 30 for devourer without the fix on the same unit. The vendor bring-up initialises the response's path selection; which write does it is still not found.
josephnef
left a comment
There was a problem hiding this comment.
Re-run on ea0552d on this bench (two TX50UH, 8812CU soliciting with CCX tx.report, 8 s per session, 2026-10-16 morning; yesterday afternoon the same cells were ~85% dead):
| cell | sessions | result |
|---|---|---|
| bus-3 unit, ch6 | 8 | all alive, 98.2-99.0% |
| bus-3 unit, ch161 | 6 | all alive, 100% each |
| bus-9 unit, ch6 | 4 | all alive, 88.6-96.3% |
| live disarm, solicitor across it (3 cells) | 3 | ~40% of the first 40% of reports, then 0: clean step |
| never armed (3 cells) | 3 | 0 |
0 dead of 18 armed sessions. Injection from the bus-3 unit with the default carrier-sense configuration (master with #491): ch6 224/444, ch161 229/442, same as before the change. The bring-up logs the P-MAC line once; Linux build + ctest 83/83.
Code: one vendor call after the T-MAC routing, 8852C-only, with the per-path pulse now included; the caps flag stays an explicit list of measured variants; the contract and doc say what the response depends on. The doc's firmware-RAM and vendor-driver sections answer the two experiments #490 asked for, and the 5 GHz injection numbers are scoped as a before/after of this change only, which is the right claim. The three Qodo threads were posted against the earlier head and read as answered by ea0552d (comparison evidence, the scoped 5 GHz claim, the times in AdapterCaps.h); they need resolving for the gate. Approving.
The `build-mingw` job has failed on every run since 2026-10-16 (twice on #492's head after a re-run): `pacman: error: target not found: mingw-w64-x86_64-libusb`. The action also warns that MINGW64 is deprecated. The package file is still on the mirror, but the `mingw64.db` database no longer lists libusb, while `ucrt64.db` ships every package the job installs at the same versions (gcc 16.2.0, cmake 4.4.4, ninja 1.13.2, libusb 1.0.30, pkgconf 3.0.8, openssl 3.6.5). The job moves to UCRT64 with the `mingw-w64-ucrt-x86_64-*` package names. Same gcc, same pkg-config libusb path, same binary-stdin and station-crypto test coverage; the configure and build steps are unchanged. Not a required check, so this is the only thing that turns it green again. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Fixes the dead ACK bring-ups on the 8852C (item 1 of #490).
In short
Some 8852C bring-ups armed the hardware ACK responder and then answered no ACK for the whole session. The chip did build the ACK, but every frame also carries a selection of which transmit antenna paths to use, and the one the MAC attached to the ACK was garbage in those bring-ups: it enabled a path this 2T2R chip does not have, or wired path A to the wrong signal, so no antenna sent it. The selection comes from MAC state nothing initialises, which is why some bring-ups were fine and others were not.
The fix makes the baseband take the path selection from its own registers instead of from the MAC, using the vendor's own function for it, right after the existing path routing at bring-up. 8852C only.
The change
kestrel_halbb_ctrl_tx_path(halbb glue) callshalbb_ctrl_tx_path_pmac_8852c(RF_PATH_AB)afterhalbb_ctrl_tx_path_tmac_8852c:0x09a4[4:2] selects P-MAC as the source of the path enable and the path A/B maps, set to paths A+B with A on IFFT 0 and B on IFFT 1.ack_responder_okis true on the 8852C too, still as an explicit list of measured variants.docs/kestrel-ack-responder.md: the dead-bring-up section now gives the cause, how it was found, what was ruled out, and the numbers.AdapterCaps.hand theSetAckRespondercontract follow.Measured
TX50UH responder, TX20U Nano soliciting, ch161, MCS1, 8 s per session:
ctest79/79 on Windows.Your two notes
bb->tx_pathto RF_PATH_AB, as in the vendor driver.Not in this PR