Skip to content

Jaguar3: firmware channel-switch fast path on 8822C/8822E#319

Merged
josephnef merged 3 commits into
masterfrom
fastretune-fw-jaguar3
Jul 20, 2026
Merged

Jaguar3: firmware channel-switch fast path on 8822C/8822E#319
josephnef merged 3 commits into
masterfrom
fastretune-fw-jaguar3

Conversation

@josephnef

Copy link
Copy Markdown
Collaborator

Extends DEVOURER_FASTRETUNE_FW (#318) to Jaguar3 — both dies wire the same H2C 0x1D SINGLE_CHANNELSWITCH_V2 in their vendor drivers (rtl8822c/e_phy.c), so the fw block in RadioManagementJaguar3::fast_retune mirrors the Jaguar2 port: fire-and-confirm-later, one RF-window read at the next hop, compose caches invalidated under the firmware's writes, =2 accepts cross-band with host-side re-fold of active power knobs.

The J3-specific wiring detail: the H2C goes through an injected sender into HalJaguar3::send_h2c_raw, because the coex runtime thread sends its H2Cs through the same HMEBOX box counter — a second independent counter would corrupt the mailbox rotation (both callers hold _reg_mu). central_and_pri()'s pri output is already the H2C's VHT_DATA_SC encoding. 8822E spur channels keep declining every fast path, fw included.

On-air validation (8812CU, kchansw oracles, chip-clock fits)

arm (dead air) n med p99
software fast path, 36↔40 581 2.40 ms 5.19
fw path =1, 36↔40 581 2.28 ms 5.94
fw path =2, 36↔6 cross-band 379 2.63 ms 10.95

The honest headline differs from the 8822B: on the 8822C the two paths tie on air — that die's ~2.3 ms RF settle dominates whichever engine sequences it. The fw wins are (a) per-hop host/USB cost, ~0.8 ms vs ~1.9 ms of composed writes, and (b) cross-band hops at 2.63 ms versus the ~90 ms full-path fallback. Hopping-RX decode identical fw vs sw (matched runs); ctest 36/36; the default =0 path is unchanged. The 8822E shares the code path but is stated as not on-air-validated (no E-die on the rig).

Also in this PR: the frequency-hopping ports table gains a fw-path host-cost column cross-linked to the offload note, and the channel-switch docs drop changelog narration ("now") — one such sentence had already rotted into a stale scope claim.

🤖 Generated with Claude Code

josephnef and others added 3 commits July 20, 2026 13:30
Both Jaguar3 vendor drivers wire the same H2C 0x1D fw switch, so
DEVOURER_FASTRETUNE_FW now covers the generation: the fw block in
RadioManagementJaguar3::fast_retune mirrors the Jaguar2 port
(fire-and-confirm-later, one RF-window read at the next hop, compose
caches invalidated under the fw's writes), and the H2C rides
HalJaguar3::send_h2c_raw via an injected sender so it shares the HMEBOX
box counter with the coex runtime thread's H2Cs under the same lock.
8822E spur channels keep declining every fast path, fw included.

On-air (8812CU, kchansw oracles): 36↔40 fw 2.28 ms med / p99 5.94 vs sw
2.40 / 5.19 — a tie on air (the 8822C's RF settle dominates), with ~3×
lower per-hop host cost (0.6 ms H2C vs ~1.9 ms composed writes);
cross-band 36↔6 through the firmware 2.63 ms med (n=379) vs the ~90 ms
full path. Hopping-RX decode identical fw vs sw. The 8822E shares the
code path, not yet on-air-validated (no E-die on the rig).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Cross-links the H2C 0x1D mode into the per-generation table (host-cost
column, like-for-like hop.dwell medians) with the on-air dead-time and
cross-band numbers pointing at kernel-channel-switch-offload.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
"now" dates a sentence to its writing; state the current shape instead —
and the port section's opening had gone stale (it predated the Jaguar3
coverage described two paragraphs below it).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@josephnef
josephnef merged commit cad2a5b into master Jul 20, 2026
18 checks passed
@josephnef
josephnef deleted the fastretune-fw-jaguar3 branch July 20, 2026 10:46
josephnef added a commit that referenced this pull request Jul 20, 2026
Third in the standard-driver FHSS series (#269 baseline, #270/#316
firmware offload). Determines whether Realtek's Multi-Channel
Concurrency / Fast Channel Switch — one radio holding two channel
contexts under a firmware schedule — can be repurposed as a
frequency-hopping primitive. It cannot; this is a documented negative
result. Docs-only.

## Findings

**Source map** (`hal_mcc.c` + `rtw_mlme_ext.c`): the FCS schedule-upload
H2C sequence (0x10 `MCC_LOCATION` → 0x16 `MACID_BITMAP` → 0x17/0x18
`MCC_CTRL` → 0x19 `TIME_SETTING`), the `C2H_MCC` `MCC_RPT_*` status
codes, and the live-read policy table — **all four policies have a fixed
100 TU (~102 ms) period** with 20/80/36/30 TU slot splits. Contexts are
pre-loaded to reserved pages once; the firmware flips between them
autonomously, so a slot boundary is the same on-chip RF switch measured
in exp-2, not a per-slot host H2C.

**Two hardware findings** (RTL8822BU, MCC-variant vendor build,
pinned-kernel VM, two helper APs):
- The `chbw_grouped` gate — MCC starts *only* for channel pairs that
can't share one radio channel. Adjacent 20 MHz pairs like the nominal
"36↔40" fit inside one 40 MHz channel and take the single-radio union
path; MCC never engages. Confirmed on air (ch1+ch11 non-groupable
co-associate stably; 36+40 starves one vif).
- The schedule doesn't start from the cfg80211/`iw connect` path —
`en_mcc:1` engages with two linked non-groupable STAs, but `mcc_status`
never reaches `DOING_MCC` and no `MCC_RPT_READY` arrives. The start hook
is in the vendor's internal join flow and the reserved-page builder
emits P2P-GO NOA content: MCC here needs a P2P GO/GC anchor, not dual
open-BSS STA (matching rtw89's P2P-driven MCC). Per the experiment's
rule, no on-air dwell is claimed from a schedule not observed running.

**Cross-chip**: the same `hal_mcc.c` engine and policy table ship in
every 11ac vendor tree — Jaguar1 (8812/8814/8821A), Jaguar2 (8822B,
8821C), Jaguar3 (8822C, 8822E; 8822E differs by 3 TU of guard only).
Kestrel (8852B/C) has no `hal_mcc.c` — its multi-channel path is rtw89
`chanctx`, separately P2P-driven. The verdict holds family-wide by
shared source.

## Go/no-go: reject

MCC is a two-context time-share (TU-quantized ≥20 ms slots, fixed ~102
ms period, two channels, non-groupable pairs, P2P-gated) — not a hopping
engine. Its one hopping-relevant element, the slot-boundary RF switch,
is the H2C 0x1D switch already shipped as `DEVOURER_FASTRETUNE_FW`
(#318/#319). Experiments 4–5 should build on that direct switch, not the
MCC scheduler.

Adds `docs/mcc-fcs-investigation.md`; updates the offload-doc forward
reference and the README index.

🤖 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