jaguar2: init-time firmware register IO-offload (HalMAC cfg_param)#329
Merged
Conversation
Route the static BB/AGC/RF phy-table write stream through the HalMAC cfg_param
firmware offload: batch the (addr, value) writes into a 12-byte-per-command
buffer, DMA each ~160-command batch to the reserved H2C-extra-info page, and
fire one FW_OFFLOAD/CFG_PARAM H2C the on-chip firmware replays — collapsing the
per-init USB register control transfers into a handful of bulk transfers. This
is the 11ac HalMAC ancestor of the mac_ax CMD_OFLD offload shipped for Kestrel.
New src/HalmacCfgParam.{h,cpp}: generation-agnostic command packer + flush with
injected transport (dl_rsvd_page + send_h2c_pkt + a BB read-back verify). Static
table entries are full-register writes (MSK_EN=0), so the firmware writes the
value verbatim. Each flush reads back the batch's last BB write and polls until
it lands — this both confirms the firmware actually replayed the buffer (vs
silently dropping the H2C) and gates reuse of the extra-info page; a mismatch
fails the offload so the caller redoes the tables direct (idempotent).
Wired on Jaguar2 via DEVOURER_FW_TABLE_OFLD (DeviceConfig.tuning.fw_table_offload,
default 0): bit 1 = BB + AGC, bit 2 = also the RF radio tables (RF_W). Exposes
send_h2c_pkt / next_h2c_seq / wait_h2c_drained / cfg_param_page on the MacInit
H2C queue and a data-descriptor download_rsvd_page on the Fw. On-air 8812BU: the
read-back verify passes (firmware replays correctly, RF state matches the direct
path) and init drops ~6.5 s -> ~5.5 s (this DUT's init is fixed-cost-heavy — an
LCK-timeout poll dominates; the write-bound dies show more).
tests/fw_table_offload.sh: cold-cycle A/B harness (init-time + read-back verdict).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ow-up) Jaguar3 (8822C/8822E) support was investigated: a config-dump A/B confirms the firmware DOES replay the cfg_param buffer, but it replays lazily (needs an end-of-apply verify, not a per-batch read-back) and the gen-3 reserved-page download stalls ~1 s per batch. Left as a documented follow-up; only Jaguar2 is wired here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Cold-boot init on the HalMAC generations is register-write-bound — the BB/AGC/RF phy-table load is thousands of synchronous USB register control transfers (measured: 8822E ~1.4 s / 9207 writes; 8812BU ~5.7 s of writes). Realtek's HalMAC firmware exposes
cfg_param(SUB_CMD0x08, classFW_OFFLOAD) — the 11ac ancestor of the mac_axCMD_OFLDshipped for Kestrel in #328: a buffer of register-write commands the on-chip CPU replays. This routes the static phy-table writes through it, collapsing the control-transfer stream into a handful of bulk transfers.src/HalmacCfgParam.{h,cpp}— generation-agnostic 12-byte-per-command packer + flush with injected transport (dl_rsvd_page+send_h2c_pkt+ a BB read-back verify). Table entries are full-register writes (MSK_EN=0), so the fw writes the value verbatim.DEVOURER_FW_TABLE_OFLD(tuning.fw_table_offload, default 0): bit 1 = BB+AGC, bit 2 = also the RF radio tables (RF_W).Result (on-air, RTL8812BU)
The read-back verify passes (firmware replays correctly; RF state matches the direct path) and 2768 register writes move off the control-transfer path. This DUT's init is dominated by a fixed-cost LCK-timeout poll, so the exposed write fraction (~15%) understates the effect — the config-identity (offloaded == direct) is the real proof.
Gating / safety
DEVOURER_FW_TABLE_OFLD=0(default) is byte-identical to before. A transport error or a read-back mismatch triggers a full direct re-apply. Opt-in — init is higher blast-radius than a hop.Jaguar3 (follow-up)
Investigated but not shipped here. A config-dump A/B proved the 8822C/E firmware does replay
cfg_param(5/6 core BB registers match the direct path with fw-only writes), but it replays lazily (needs an end-of-apply verify, not a per-batch read-back) and its reserved-page download stalls ~1 s per batch. Left as a documented follow-up.Validation
ctest36/36; per-chip build-config matrix unaffected (new file is in the always-compiled core).tests/fw_table_offload.sh: cold-cycle A/B harness (init-time + read-back verdict).🤖 Generated with Claude Code