Skip to content

Frequency-resolved link quality (2/3): LA-mode IQ capture + offline FFT — true per-tone CSI from Jaguar silicon #150

Description

@josephnef

Why

Per-subcarrier CSI is not host-readable on Jaguar-class chips through any normal path — but phydm's LA (logic-analyzer) / ADC-sampling mode is a documented debug escape hatch: it captures raw baseband IQ into the TX packet buffer, which the host can read back. An offline FFT of a captured L-LTF (or VHT-LTF) is the full per-tone channel estimate H(k). One-shot and slow, but it turns any Jaguar dongle into a per-subcarrier channel sounder for bench characterisation — ground truth for the coarse sweep of issue 1, and the data source the precoder README's "Tier 4" shape verification wanted.

What's already in-tree

  • src/jaguar1/BbDbgportReader.h — the dbg-port transport (selector 0x8FC, readback 0xFA0) with save/restore, chip-liveness check, wedge latching, and the recovery ladder. Its header comment says the phydm selector catalogue is "not vendored in this tree" — that note is stale: phydm_adc_sampling.c/h now exist under reference/rtl8812au/, reference/rtl88x2bu/, reference/rtl88x2cu/, and reference/rtl88x2eu/hal/phydm/. The missing piece is no longer missing.
  • demo/main.cpp DEVOURER_RX_DUMP_CSI — the env-gated selector-sweep research hook (throttled, first-8-frames).

Mechanism (from reference/rtl8812au/hal/phydm/phydm_adc_sampling.c)

  • phydm_la_mode_bb_setting() routes the chosen internal BB bus to the debug port (phydm_set_bb_dbg_port(DBGPORT_PRI_3, dbg_port)), sets trigger mode/edge/sample-rate (0x9a0[4:0] trigger select).
  • MAC-side capture control at R_0x7c0 (+ 0x38[23:16] for MAC-trigger mode): DMA the sampled bus into the TX packet buffer, poll for round-up/finish address.
  • Host reads the capture buffer back (txpktbuf read path), then decodes the packed IQ format offline.
  • Compiled upstream for ODM_IC_11AC_SERIES (8812A/8814A/8821A/8822B) and ODM_IC_JGR3_SERIES (8822C/…), so both our HALs have a silicon path.

Milestones

  • M1 — capture plumbing (8812AU first). Port trigger setup + 0x7c0 capture + buffer readback into a research-gated module (same opt-in pattern as BbDbgportReader); dump the raw buffer to a file. Update the stale BbDbgportReader comment while there.
  • M2 — IQ format decode. Establish the packed sample layout (bit width, I/Q order, per-path interleave) from the vendor readout code; python unpacker.
  • M3 — L-LTF locate + FFT. Trigger on frame RX (or fake-trigger during a peer's known TX), locate the L-LTF in the capture, FFT → per-tone H(k) magnitude/phase. Offline tool under tools/ or tests/.
  • M4 — validation. Same-frame comparison against a B210 capture (existing SDR rig): per-tone |H(k)| correlation between chip-captured and SDR-derived estimates.
  • M5 (stretch) — Jaguar3 port via the reference/rtl88x2cu JGR3 variant of the same code.

Risk

0x8FC pokes while RX is live can wedge demod state machines (see the BRICK RISK section of BbDbgportReader.h, incl. the 3-step recovery ladder). Keep everything env-gated, save/restore always, treat first runs as destructive until proven otherwise.

Part 2 of a 3-issue series; part 1 is the narrowband sweep (coarse, cheap, online), part 3 is passive VHT beamforming-report capture.

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