cca gates: make the Jaguar1 arm of the regcheck actually runnable - #429
Conversation
The harness shipped in #427 could not check Jaguar1 at all. Two independent reasons, both of which made the tracker cell report a clean-looking non-result rather than fail. The probe builds a default DeviceConfig, so tuning.phydm_watchdog is false. On Jaguar1 that watchdog IS the EDCCA tracker — HalModule constructs it only under that flag — so SetEdccaTrack was never reached and the cell reported "no EDCCA tracker running in the default arm" on a backend whose tracking path had simply never been instantiated. A --phydm-watchdog flag builds it; Jaguar3 ignores the field, its phydm runtime rides the RX/coex thread. Separately, peek32/poke32 addressed chipstate by --pid alone while the probe got --vid. Any adapter enumerating under a vendor VID rather than 0x0bda — TP-Link 0x2357, and most retail parts — failed every register cell, because the peek was looking for it under the default Realtek VID. Six failed cells on the first Jaguar1 run here, none of them about the gates. With both fixed, an RTL8821AU (Jaguar1, chip-id 0x05, 1T1R) reports 11 passed / 0 failed / 0 skipped, and the tracker cell gives a real verdict instead of a skip: note: 0x0120 track: tracker IS running at 0x8a4 in the default arm PASS: 0x0120 track: EDCCA tracking stops when EDCCA is the gate turned off note: 0x0120 cntdown: 0x524[11] constant at 1 — not an EDCCA gate here That last one is the documented known-limit path behaving correctly: Jaguar1 never writes 0x524, so the cell reports rather than fails. This also retires the "not hardware-validated" caveat on the tracker-ordering fix from #427. The race reproduces on this part once the window is widened and the disable lands while DIG is still walking IGI: pre-fix parked 0x8a4=0x7f7f, tracker still ON, window open PhydmWatchdog: EDCCA L2H/H2L re-tracked to 3/-4 (igi=0x1e) window closed, about to clear the tracker fixed 0 overwrites inside the same window, across three disable arms Worth recording that the tracker is write-on-change, so the race only fires while DIG is actively moving IGI — once it converges the pre-fix ordering looks correct. A first negative control missed the bug for exactly that reason. Verified: build clean, ctest 63/63, regcheck 11/0/0 on the RTL8821AU and no regression on an 8822E, 8822C, 8822BU or RTL8733BU. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0192ViRjaiFT9vTiiJpohZGT
PR Summary by QodoMake Jaguar1 CCA gate regression checks runnable
AI Description
Diagram
High-Level Assessment
Files changed (2)
|
Code Review by Qodo
1. Probe metadata breaks JSON streams
|
…ag is not Two things a reader of this harness has to know and could not have learned from it. The tracker is write-on-change (l2h != _edcca_last_l2h), so the cell only sees it act while DIG is still walking IGI. Each arm restarts the probe, so DIG restarts with it and is in motion during the sample window — but if it has converged instead, the default arm reads as "no tracker" and the EDCCA-off arm skips. That degrades to no verdict rather than a false one, which is the right failure, but a SKIP there means the cell could not create the condition, not that the tracker behaved. This is the same property that made a first negative control miss the race entirely. And --phydm-watchdog is a test lever, not a hint at a better default. That thread is opt-in because its periodic BB traffic shares the libusb queue with the TX bulk path and costs throughput — 4500 to 1000 TX submits in 10s on an 8821 at ch100, per HalModule. This probe never transmits, so it pays none of it, which is why the cell can afford the flag and a normal session cannot. Comments only. Build clean, ctest 63/63, and an untouched end-to-end run of the committed script reports 13 passed / 0 failed / 0 skipped over an 8822C and an RTL8733BU. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0192ViRjaiFT9vTiiJpohZGT
rtw_hal_deinit() clears REG_CR, zeroes REG_RCR and runs the card-disable
power sequence with the phydm watchdog thread still ticking. That thread
does periodic BB reads and writes — FA counters, DIG on 0xc50/0xe50, the
EDCCA thresholds — so teardown races register access against power-off,
which is the one ordering hazard this driver is careful about everywhere
else.
Stop() first. It compare-exchanges _running, so it is idempotent and the
destructor's own Stop() after this is a no-op; the pointer is null whenever
tuning.phydm_watchdog did not build one, which is the default.
Pre-existing, but only reachable once something sets that config, and until
now nothing in-tree did — the --phydm-watchdog probe flag in this branch is
what makes it reachable, so it is fixed here rather than left for whoever
next turns the watchdog on.
Measured on an RTL8821AU, marking every tick and widening the de-init window
to 6 s so the 2 s tick has to land in it:
pre-fix clean de-init (stop TRX + card-disable)
TICKMARK: watchdog touching the chip
TICKMARK: watchdog touching the chip
PowerOff: card-disable applied
=> 2 ticks inside the window
fixed clean de-init (stop TRX + card-disable)
PowerOff: card-disable applied
=> 0 ticks inside the window
Found by Qodo on #429. Build clean, ctest 63/63.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0192ViRjaiFT9vTiiJpohZGT
|
Final validation on the merged bytes ( Zero skips anywhere, which is the point of the change — the Jaguar1 tracker cell now produces a verdict instead of a non-result. Build clean, Both Qodo findings handled: the teardown race was real and is fixed in |
A Jaguar1 reached this bench after #427 merged — an RTL8821AU (TP-Link Archer T2U PLUS,
2357:0120), which dispatches toRtlJaguarDevice, chip-id0x05,CHIP_8821_Normal_Chip_TSMC_D_CUT_1T1R. A second Jaguar1 die alongside the 8812AU the split was measured on.Using it found that the harness #427 shipped cannot check Jaguar1 at all. Two independent reasons, and both produce a clean-looking non-result rather than a failure, which is the worst shape for this kind of gap.
1. The tracker cell measures a tracker that was never built
tests/cca_gates_probe.cppconstructs a defaultDeviceConfig, sotuning.phydm_watchdogis false. On Jaguar1 that watchdog is the EDCCA tracker —HalModulebuilds_phydmWatchdogonly under that flag, sophydm_watchdog()returnsnullptrandSetEdccaTrackis never reached. A default probe run on the 8821AU:The cell then reports
no EDCCA tracker running in the default armabout a backend whose tracking path was simply never instantiated, and skips. That is a second reason the Jaguar1 arm could not produce a verdict, independent of the per-family register fix in #427 — so my note on that PR, that the cell would now give a real verdict on an 8812AU, was wrong. It would still have skipped.--phydm-watchdogbuilds it. Jaguar3 ignorestuning.phydm_watchdogentirely (onlysrc/jaguar1/reads it — its own phydm runtime rides the RX/coex thread), so the tracker cell can pass the flag unconditionally.2. Every register cell fails on a vendor VID
peek32/poke32addressedchipstateby--pidalone whilestart_holdpassed--vid "$VID". Any adapter enumerating under a vendor VID rather than0x0bda— TP-Link0x2357, and most retail parts — had every peek look for it under the default Realtek VID and fail:Six failed cells, none of them about the gates.
Result
With both fixed, the RTL8821AU is 11 passed / 0 failed / 0 skipped, and the tracker cell gives a real verdict:
That last line is the documented known-limit path working: Jaguar1 never writes
0x524, so the cell reports instead of failing.This retires the unvalidated caveat from #427
The tracker-ordering fix went in without silicon behind it. It reproduces here. Instrumenting the park instant, widening the window, and landing the disable while DIG is still walking IGI:
One nuance worth recording, because it cost me a wrong conclusion first: the tracker is write-on-change (
l2h != _edcca_last_l2h), so the race only fires while DIG is actively moving IGI. My first negative control ran the disable arm ~30 s after bring-up, by which point DIG had converged, IGI had stopped moving, and the pre-fix ordering looked perfectly correct —0x8a4sat parked at7f7facross five samples. A negative control that fails to reproduce can mean the trigger condition was absent, not that the bug is. The window had to be forced early.So the bug is real but narrower than #427's description implied: it needs a tick inside a window that is microseconds wide in production and IGI in motion. The fix removes it rather than narrowing it.
Verification
Build clean,
ctest63/63, and the regcheck over everything plugged here:2357:0120RTL8821AU0bda:a81aRTL8822E0bda:c812RTL8822C0bda:b812RTL8822BU0bda:b733RTL8733BU26 pass / 0 fail / 0 skip on the non-Jaguar1 set, with no regression from the
GATES-GENline gaining aphydm_watchdog=Nfield.Not covered: no 8812AU or 8814AU here, so the Jaguar1 evidence is one die (8821A, 1T1R). The on-air delivery tables in #427 remain @snokvist's and are not re-measured — this is register-level and tracker-level only.
🤖 Generated with Claude Code
https://claude.ai/code/session_0192ViRjaiFT9vTiiJpohZGT