Gap
Jaguar3 (8822CU/8812EU/8822EU) has no false-alarm-driven RX gain adaptation. The initial gain index (IGI, 0x1d70[6:0]) is set once by the igi_toggle in HalJaguar3::enable_rx_path (src/jaguar3/HalJaguar3.cpp:331-335 — a 0x1d70 -= 0x202 then restore, which just emits the 3-wire RX-mode command) and never moves again. The other two families adapt it continuously:
- Jaguar1:
PhydmWatchdog (src/jaguar1/PhydmWatchdog.{h,cpp}) — the phydm DIG port, FA-thresholded IGI stepping within bounds [0x1c, 0x2a], on the watchdog cadence.
- Jaguar2:
HalJaguar2::dig_step on a ~100 ms thread (RtlJaguar2Device.cpp:240), FA-driven within [0x1c, 0x3e].
The vendor switch_channel path toggles IGI per hop and the phydm watchdog re-optimizes it every ~2 s in steady state; devourer's Jaguar3 does neither. GetRxEnergy reads the static 0x1d70 value back (RtlJaguar3Device.cpp:600) — the read side exists, the adapt side doesn't.
Consequence — and why it may be benign
In a stable noise environment a well-chosen static IGI is fine, and the FastRetune measurements showed no RX catch-rate decay over hundreds of kickless retunes (docs/frequency-hopping.md), so per-hop IGI kicking is confirmed unnecessary for hopping. The open risk is steady-state weak-signal RX in a changing interference floor: with false alarms rising (a nearby interferer switching on), Jaguar1/2 raise IGI to suppress them and hold sensitivity, while Jaguar3 sits at its bring-up gain. Whether that measurably costs delivery on the EU/CU has not been characterized — this issue is to close the parity gap if the symptom shows, not to assume it.
This is the same shape as the Jaguar2 thermal-tracking gap (#184): a per-family capability the other generations have and one doesn't.
What porting looks like
The vendor rtl88x2cu / rtl88x2eu phydm_dig.c is the source (same algorithm devourer's PhydmWatchdog already ports for Jaguar1, and dig_step for Jaguar2):
- Read the FA counters devourer already reads for
GetRxEnergy (OFDM-FA sum across 0x2d04/08/10/20/0c, CCK-FA 0x1a5c) and the current IGI 0x1d70[6:0].
- FA-thresholded IGI step within the Jaguar3 bounds (from the vendor
phydm_dig.h DIG_MAX/MIN_* for this IC — note Jaguar3's IGI field is 7-bit, unlike the 6-bit older parts).
- Write
0x1d70[6:0]. This must serialize on _reg_mu — the coex runtime thread already RMWs neighbouring BB registers on its ~2 s tick, so the DIG tick can ride that same thread (the natural cadence) rather than a new one.
- Respect the lean-hop contract: DIG runs in steady state, not per FastRetune (the hop path deliberately skips the RX kick and that's validated).
Validation
Marginal-link RX delivery with a swept interference floor (B210 AWGN / CW injection, tests/fade_sla_onair.sh-style): with DIG on, FA count should fall and delivery hold as the floor rises, vs the static-IGI baseline drooping. Register check: 0x1d70 moves under rising FA and settles; no movement across a FastRetune (hop path untouched). First step is the measurement that decides whether this is worth building — quantify the static-IGI penalty on the EU before porting.
Context
Found in the RX-vs-TX runtime-control research after #188. RX gain is chip-closed by design (per-frame AGC + this slow DIG loop + LNA-saturation AGC-table switching); this is about restoring the slow-loop parity Jaguar3 is missing, not exposing a host knob.
Gap
Jaguar3 (8822CU/8812EU/8822EU) has no false-alarm-driven RX gain adaptation. The initial gain index (IGI,
0x1d70[6:0]) is set once by theigi_toggleinHalJaguar3::enable_rx_path(src/jaguar3/HalJaguar3.cpp:331-335— a0x1d70 -= 0x202then restore, which just emits the 3-wire RX-mode command) and never moves again. The other two families adapt it continuously:PhydmWatchdog(src/jaguar1/PhydmWatchdog.{h,cpp}) — the phydm DIG port, FA-thresholded IGI stepping within bounds[0x1c, 0x2a], on the watchdog cadence.HalJaguar2::dig_stepon a ~100 ms thread (RtlJaguar2Device.cpp:240), FA-driven within[0x1c, 0x3e].The vendor
switch_channelpath toggles IGI per hop and the phydm watchdog re-optimizes it every ~2 s in steady state; devourer's Jaguar3 does neither.GetRxEnergyreads the static0x1d70value back (RtlJaguar3Device.cpp:600) — the read side exists, the adapt side doesn't.Consequence — and why it may be benign
In a stable noise environment a well-chosen static IGI is fine, and the FastRetune measurements showed no RX catch-rate decay over hundreds of kickless retunes (
docs/frequency-hopping.md), so per-hop IGI kicking is confirmed unnecessary for hopping. The open risk is steady-state weak-signal RX in a changing interference floor: with false alarms rising (a nearby interferer switching on), Jaguar1/2 raise IGI to suppress them and hold sensitivity, while Jaguar3 sits at its bring-up gain. Whether that measurably costs delivery on the EU/CU has not been characterized — this issue is to close the parity gap if the symptom shows, not to assume it.This is the same shape as the Jaguar2 thermal-tracking gap (#184): a per-family capability the other generations have and one doesn't.
What porting looks like
The vendor rtl88x2cu / rtl88x2eu
phydm_dig.cis the source (same algorithm devourer'sPhydmWatchdogalready ports for Jaguar1, anddig_stepfor Jaguar2):GetRxEnergy(OFDM-FA sum across0x2d04/08/10/20/0c, CCK-FA0x1a5c) and the current IGI0x1d70[6:0].phydm_dig.hDIG_MAX/MIN_*for this IC — note Jaguar3's IGI field is 7-bit, unlike the 6-bit older parts).0x1d70[6:0]. This must serialize on_reg_mu— the coex runtime thread already RMWs neighbouring BB registers on its ~2 s tick, so the DIG tick can ride that same thread (the natural cadence) rather than a new one.Validation
Marginal-link RX delivery with a swept interference floor (B210 AWGN / CW injection,
tests/fade_sla_onair.sh-style): with DIG on, FA count should fall and delivery hold as the floor rises, vs the static-IGI baseline drooping. Register check:0x1d70moves under rising FA and settles; no movement across a FastRetune (hop path untouched). First step is the measurement that decides whether this is worth building — quantify the static-IGI penalty on the EU before porting.Context
Found in the RX-vs-TX runtime-control research after #188. RX gain is chip-closed by design (per-frame AGC + this slow DIG loop + LNA-saturation AGC-table switching); this is about restoring the slow-loop parity Jaguar3 is missing, not exposing a host knob.