Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/HalModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ HalModule::HalModule(
_eepromManager{eepromManager}, _logger{logger} {}

bool HalModule::rtw_hal_init(SelectedChannel selectedChannel) {
auto status = rtl8812au_hal_init();
auto status = rtl8812au_hal_init(selectedChannel.Channel);

if (status) {
_radioManagementModule->init_hw_mlme_ext(selectedChannel);
Expand All @@ -79,7 +79,7 @@ bool HalModule::rtw_hal_init(SelectedChannel selectedChannel) {
return status;
}

bool HalModule::rtl8812au_hal_init() {
bool HalModule::rtl8812au_hal_init(uint8_t init_channel) {
// Check if MAC has already power on. by tynli. 2011.05.27.
auto value8 = _device.rtw_read8(REG_SYS_CLKR + 1);
auto regCr = _device.rtw_read8(REG_CR);
Expand Down Expand Up @@ -319,14 +319,23 @@ bool HalModule::rtl8812au_hal_init() {
_device.phy_set_bb_reg(rTxPath_Jaguar, bMaskLWord, 0x1111);
}

if (registry_priv::channel <= 14) {
/* Init directly at the user's selected channel so we only run the
* per-rate TX-power write loop once. The redundant prior pattern
* (init at registry_priv::channel = 36, then re-channel-set to the
* user's channel from `init_hw_mlme_ext`) wedged 8821AU at ch100
* mid-second-channel-set TX-power loop — the chip stopped ACK'ing
* USB control transfers after 2 BB writes, leaving the demo
* deadlocked on libusb_control_transfer until SIGKILL. See kaeru
* cite "8821AU ch100 wedge — confirmed second-channel-set is the
* trigger, not band-switch 2026-06-02". */
if (init_channel <= 14) {
_radioManagementModule->PHY_SwitchWirelessBand8812(BandType::BAND_ON_2_4G);
} else {
_radioManagementModule->PHY_SwitchWirelessBand8812(BandType::BAND_ON_5G);
}

_radioManagementModule->rtw_hal_set_chnl_bw(
registry_priv::channel, ChannelWidth_t::CHANNEL_WIDTH_20,
init_channel, ChannelWidth_t::CHANNEL_WIDTH_20,
HAL_PRIME_CHNL_OFFSET_DONT_CARE, HAL_PRIME_CHNL_OFFSET_DONT_CARE);

// HW SEQ CTRL
Expand Down
2 changes: 1 addition & 1 deletion src/HalModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class HalModule {
bool rtw_hal_init(SelectedChannel selectedChannel);

private:
bool rtl8812au_hal_init();
bool rtl8812au_hal_init(uint8_t init_channel);
bool InitPowerOn();
bool InitLLTTable8812A(uint8_t txpktbuf_bndy);
bool InitLLTTable8814A();
Expand Down
23 changes: 23 additions & 0 deletions src/RadioManagementModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,29 @@ uint32_t RadioManagementModule::phy_get_tx_bb_swing_8812a(BandType Band,
}

void RadioManagementModule::init_hw_mlme_ext(SelectedChannel pmlmeext) {
/* If `HalModule::rtl8812au_hal_init` already programmed the same
* (channel, bw, offset) AND the chip is an 8821AU, skip the
* reset-and-redo. The second channel-set wedges 8821AU at ch100
* mid-TX-power loop (chip stops ACK'ing USB control transfers
* after 2 BB writes — see kaeru cite "8821AU ch100 wedge —
* confirmed second-channel-set is the trigger, not band-switch
* 2026-06-02"). Other chips (8812AU, 8814AU) tolerate the second
* pass; some 8814AU init steps appear to depend on it (gating the
* skip caused 8814 ch6 to lose its RX loop entry).
*
* Falls through to the historical reset+redo path for everything
* else. */
bool same_target =
(_currentChannel == pmlmeext.Channel) &&
(_currentChannelBw == pmlmeext.ChannelWidth) &&
(_cur40MhzPrimeSc == pmlmeext.ChannelOffset) &&
(current_band_type != BandType::BAND_MAX);
bool is_8821 = _eepromManager->version_id.ICType == CHIP_8821;
if (same_target && is_8821) {
Set_HW_VAR_ENABLE_RX_BAR(true);
return;
}

/* Modify to make sure first time change channel(band) would be done properly
*/
_currentChannel = 0;
Expand Down
Loading