Skip to content

Jaguar3: no dynamic initial gain (DIG) — IGI is static after bring-up (parity gap vs Jaguar1/2) #190

Description

@josephnef

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):

  1. 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].
  2. 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).
  3. 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.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions