Skip to content

Jaguar3: RCR AAP bit + 8822E path-B TXAGC ref fix — single-radio self-capture works#160

Merged
josephnef merged 1 commit into
masterfrom
fix/jaguar3-rcr-aap-and-eu-pathb-ref
Jul 4, 2026
Merged

Jaguar3: RCR AAP bit + 8822E path-B TXAGC ref fix — single-radio self-capture works#160
josephnef merged 1 commit into
masterfrom
fix/jaguar3-rcr-aap-and-eu-pathb-ref

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Closes the two hardware follow-ups from #158, both root-caused by cold-chip bisection (VBUS power-cycling the DUT per experiment — chip state provably leaks across soft re-inits and had produced several false leads).

1. Jaguar3 monitor mode was never promiscuous (RCR AAP)

monitor_rx_cfg's RCR (0xF410400E, commented "accept-all") was missing BIT_AAP (bit 0, accept-all unicast) — decoded against halmac_bit_8822c.h, only APM|AM|AB were set. The host therefore received broadcast/multicast/self-addressed frames only, silently dropping every third-party unicast: NDPA control frames, VHT beamforming reports, unicast data. The beamformee only ever surfaced NDPAs because its arm programs the self-MAC to the NDPA RA (physical match).

With AAP set, the single-radio beamforming self-sounding ground station works on both Jaguar3 variants: 53,132 (8822CU) / 53,409 (8822EU) self-captured reports per 20 s at full sounding rate (2,215 at the 10 Hz design rate), zero errors — and a bare Jaguar3 monitor finally sees all traffic. Jaguar1/Jaguar2 RCRs already accept all unicast.

2. 8822E RX-desense: one register field

The EU's TX+RX desense bisected down to 0x41e8[16:10] — the path-B OFDM TXAGC reference: any nonzero value desenses the EU's RX to near-deaf (value-independent; double-reads stable and the written value lands exactly, so RMW pollution is ruled out). Everything else is RX-safe: path-A ref, CCK refs, the per-rate diff table, DPK force-bypass, the 0x1c90 gate, the coex/pwr_track runtime — earlier observations blaming DPK/TXAGC broadly were chip-state pollution.

apply_power_by_rate_8822e gains skip_path_b_ofdm_ref: TX+RX mode on the EU now applies the full per-rate power-by-rate table + DPK bypass and leaves only that one field at its table default (previously the entire per-rate path was traded for flat power). TX-only behavior unchanged. Why the kernel tolerates a nonzero 0x41e8 where devourer's bring-up does not remains open; the practical impact is one skipped write in one mode.

Also: txbf_rfmode_sounder now brackets its RF mode-table writes with rstb_3wire + the anapar-update tail (same mechanism as the RF table load; readback-verified).

Hardware validation (cold chips)

  • EU TX+RX: ambient RX alive with the near-full power path
  • EU + CU single-radio self-capture acceptance: 53k reports each / 20 s
  • EU TX-only ch100 sustain: unchanged (29k frames / 70 s, coex housekeeping intact)
  • build + ctest green

🤖 Generated with Claude Code

…-capture works

Two hardware-bisected root causes (cold-chip VBUS-cycling protocol), closing
the follow-ups from the StartRxLoop split:

RCR AAP (monitor promiscuity). Jaguar3's monitor_rx_cfg RCR (0xF410400E) was
missing BIT_AAP (bit 0, accept-all unicast): the "accept-all" monitor config
actually passed only broadcast/multicast/physical-match frames to the host,
silently dropping every third-party unicast — NDPA control frames, VHT
beamforming reports, unicast data. The beamformee only ever saw NDPAs because
its arm programs the self-MAC to the NDPA RA. With AAP set, the single-radio
beamforming self-sounding ground station works on BOTH Jaguar3 variants:
53,132 (8822CU) / 53,409 (8822EU) self-captured reports per 20 s at full
sounding rate, and a bare Jaguar3 monitor finally sees all traffic. Jaguar1
and Jaguar2 RCRs already accept all unicast.

8822E path-B OFDM TXAGC reference (0x41e8[16:10]). Any nonzero value in that
one field desenses the EU's RX to near-deaf — value-independent, and the
mechanism is clean (reads stable, written value lands exactly). Everything
else in the power path is RX-safe: path-A ref, CCK refs, the per-rate diff
table, and the DPK force-bypass (earlier observations blaming them were
chip-state pollution across soft re-inits). apply_power_by_rate_8822e gains
skip_path_b_ofdm_ref; TX+RX mode on the EU now applies the FULL per-rate
power-by-rate table + DPK bypass and leaves only 0x41e8 at its table default
(previously the whole per-rate path was traded for flat power). TX-only
behavior is unchanged. Why the kernel tolerates a nonzero 0x41e8 where
devourer's bring-up does not is a remaining question; the practical impact is
one skipped write in one mode.

Also: txbf_rfmode_sounder brackets its RF mode-table writes with rstb_3wire +
the anapar-update tail, matching the RF table-load mechanism (readback-
verified the entries land).

Validated on hardware (cold chips): EU TX+RX ambient RX alive with near-full
power; EU + CU single-radio acceptance (53k reports each, 2,215 at the 10 Hz
design rate); EU TX-only ch100 sustain unchanged (29k frames / 70 s, coex
housekeeping intact); build + ctest green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef josephnef merged commit 19460a6 into master Jul 4, 2026
13 checks passed
@josephnef josephnef deleted the fix/jaguar3-rcr-aap-and-eu-pathb-ref branch July 4, 2026 05:06
josephnef added a commit that referenced this pull request Jul 4, 2026
… complete (#161)

Executes the Jaguar-2 plan recorded in #151 (deferred there until the
Jaguar-2 port landed, which #157 did): mirror the Jaguar-3 arming/NDPA
blocks into `src/jaguar2/` and validate on hardware. Self-sounding now
covers all three devourer generations, in both directions, including the
single-radio ground station. Closes #151.

## What

- **`FrameParserJaguar2.h`**: `SET_TX_DESC_NDPA_8822B` /
`SET_TX_DESC_NAVUSEHDR_8822B` (dword3 `+0x0C` bits [23:22] / bit 15 —
verified against the vendor `halmac_tx_desc_nic.h`, same positions as
Jaguar-3) and a `ndpa` param on `fill_data_tx_desc_8822b`. The NDPA
block sits **above the descriptor checksum**: dword3 is inside the 32
bytes the 8822B HW checksums, and a mismatch silently drops the frame at
TXDMA.
- **`RtlJaguar2Device`**: beamformee arm in `Init`
(`DEVOURER_BF_ARM_BFEE` / `_MU`) using the shared `kBfeeJaguar23` —
which was transcribed from `hal_txbf_8822b_enter()`, i.e. it *is* the
8822B recipe — with self-MAC `00:e0:4c:88:22:bb` programmed to 0x0610
(Jaguar-2 bring-up, like Jaguar-3's, never writes it) and placed after
`bring_up` so the recipe's RXFLTMAP RMW follows `init_wmac_cfg`; sounder
arm in `InitWrite` (`DEVOURER_BF_ARM_SOUNDER`, protocol byte 0xDB);
`DEVOURER_TX_NDPA` gate in `send_packet`.
- **`tests/bf_selfsound_jaguar2.sh`**: 3-cell matrix — unarmed/armed
beamformee direction (+ optional `RUN_MU=1` cell), and a
sounder-direction cell that doubles as the single-radio ground-station
check (`DEVOURER_TX_WITH_RX=thread`, self-capture vs. independent
sniffer separates RX-side from NDP-side failures).

## Vendor-parity notes

- **No RF mode-table poke on the sounder side**: the vendor's
`hal_txbf_8822b_rf_mode()` body is entirely `#if 0`'d in rtl88x2bu —
unlike the 8822C, whose active equivalent became Jaguar-3's
`txbf_rfmode_sounder`. Confirmed unnecessary on-air.
- **No pre-`InitWrite` env constraint for TX+RX** (unlike Jaguar-3):
Jaguar-2's shared bring-up always enables RX, never closes the RX
filters, and has no coex thread on bulk-IN.
- Jaguar-2's RCR already carries AAP (per #160), so report capture
needed no RX work.

## Hardware validation (Archer T3U 2357:012d, ch100, reproduced twice)

| cell | result |
|---|---|
| beamformee, unarmed | **0** reports (negative control) |
| beamformee, armed | **855 / 888** reports, `sa=00:e0:4c:88:22:bb Nc=2
Nr=2` — unassociated HW responder |
| beamformee, MU | **920** reports, len=153 — MU Exclusive per-tone SNR
decodes clean (20 groups, 20.7–21.7 dB) |
| sounder + single-radio GS | **85k self-captured** reports / 33 s
(sniffer cross-check 78k) |

`tools/bf_report_decode.py` on the captures confirms the same Realtek
compact 10-bit codebook seen on Jaguar-1/-3: stable cross-frame Givens
angles (var 0.008), per-stream SNR 33.75/21.75 dB, smooth per-tone
|h_B/h_A| structure. Build + ctest green.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant