fix: 8821AU ch100 chip wedge on second channel-set during init (issue #59)#70
Merged
Conversation
Closes the 8821AU UNII-2/3 RX-side gate from issue #59. The 6+ prior hypotheses tested in `kaeru:8821au-5ghz-unii2-tx-gate-five-hypotheses-refuted-2026-06-01` all focused on TX-out registers. The real bug was elsewhere: 8821AU wedges mid-init at ch100 if the channel-set runs twice. ## Root cause `HalModule::rtw_hal_init` invokes two channel-sets back-to-back: 1. `rtl8812au_hal_init()` hardcoded `registry_priv::channel = 36` (compile-time default) for the initial channel-set. 2. `init_hw_mlme_ext(selectedChannel)` reset state (`_currentChannel = 0`, `current_band_type = BAND_MAX`) and re-ran the channel-set with the user's actual channel. For most chip/channel combos the second pass is wasted work. For 8821AU at ch100 specifically, the SECOND `phy_SwChnlAndSetBwMode8812` wedges the chip mid-TX-power-write loop — chip stops ACK'ing USB vendor control transfers after the 2nd or 3rd BB write, leaving the demo deadlocked on `libusb_control_transfer` until SIGKILL. After the wedge, the dongle can't be re-opened cleanly until a USB unbind/bind cycle. Confirmed not caused by band switch (test with `registry_priv::channel = 100` → both passes at ch100, second still wedges). Some 8821-specific UNII-2 BB state the first init leaves behind makes the chip reject the second pass's reprogramming. ## Fix Two complementary changes: 1. **`HalModule::rtl8812au_hal_init(uint8_t init_channel)`** — parameterise the initial channel-set so init runs directly at the user's selected channel, not at the registry default. With this, both init passes target the same channel → init_hw_mlme_ext has nothing to do. 2. **`init_hw_mlme_ext`** — when the chip is 8821AU AND the post-init state already matches the requested channel/bw/offset, skip the reset-and-redo and just call `Set_HW_VAR_ENABLE_RX_BAR`. Gated to CHIP_8821 only because some 8814AU init paths appear to depend on the second-channel-set side effects (initial gating-by-default regressed 8814 ch6 RX loop entry). The fix preserves the historical behaviour byte-for-byte for 8812AU and 8814AU. Only 8821AU gets the early-return. ## Verification - **8821AU ch100 init**: previously wedged after 2 TX-power writes with no RX loop entry; now completes init + enters RX loop + receives frames within seconds. - **`8814-ker TX → 8821-dev RX @ ch100` = 400 / 444 ✓** (was `0 / 442 ✗` per kernel-canary captures and issue #59). - **`8821-dev TX → 8814-ker RX @ ch100` = 5901 / 7000 ✓** (unchanged, still works post-fix). - **8814 ch6 RX loop**: still enters + receives frames (chip-gating preserves historical 8814 behaviour). - **8821 ch6 RX loop**: still works post-fix. Remaining pre-existing 8821 / 8814 gaps unaffected by this fix: 8814 TX-gate (issue #36), 5GHz dev-dev gap (separate root cause), 8814 RX broken at 5G (separate). Co-Authored-By: Claude Opus 4.7 (1M context) <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.
Summary
Closes the 8821AU UNII-2/3 RX-side gate from issue #59. The 6+ prior hypotheses tested in
kaeru:8821au-5ghz-unii2-tx-gate-five-hypotheses-refuted-2026-06-01all focused on TX-out registers. The real bug was elsewhere: 8821AU wedges mid-init at ch100 if the channel-set runs twice during devourer'srtw_hal_init.Root cause
HalModule::rtw_hal_initinvokes two channel-sets back-to-back:rtl8812au_hal_init()hardcodedregistry_priv::channel = 36(compile-time default) for the initial channel-set.init_hw_mlme_ext(selectedChannel)reset state (_currentChannel = 0,current_band_type = BAND_MAX) and re-ran the channel-set with the user's actual channel.For most chip/channel combos the second pass is wasted work. For 8821AU at ch100 specifically, the SECOND
phy_SwChnlAndSetBwMode8812wedges the chip mid-TX-power-write loop — chip stops ACK'ing USB vendor control transfers after the 2nd or 3rd BB write, leaving the demo deadlocked onlibusb_control_transferuntil SIGKILL.Confirmed not caused by band switch (test with
registry_priv::channel = 100→ both passes at ch100, second still wedges). Some 8821-specific UNII-2 BB state the first init leaves behind makes the chip reject the second pass's reprogramming.Fix
Two complementary changes:
HalModule::rtl8812au_hal_init(uint8_t init_channel)— parameterise the initial channel-set so init runs directly at the user's selected channel, not at the registry default. With this, both init passes target the same channel → init_hw_mlme_ext has nothing to do.init_hw_mlme_ext— when the chip is 8821AU AND the post-init state already matches the requested channel/bw/offset, skip the reset-and-redo and just callSet_HW_VAR_ENABLE_RX_BAR. Chip-gated to 8821 only because some 8814AU init paths depend on the second-channel-set side effects (initial gating-by-default regressed 8814 ch6 RX loop entry).The fix preserves historical behaviour byte-for-byte for 8812AU and 8814AU.
Verification
8814-ker TX → 8821-dev RX @ ch1000 / 442 ✗400 / 444 ✓8821-dev TX → 8814-ker RX @ ch100Test plan
8814-ker TX → 8821-dev RX @ ch100cell: closed (was the documented UNII-2/3 RX-side gate per README).Remaining 8821 gaps (out of scope for this fix)
🤖 Generated with Claude Code