Skip to content

Commit

Permalink
wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power…
Browse files Browse the repository at this point in the history
… mode

After enabling packet offload, the TX will be stuck after resume from
WoWLAN mode. And the 8852c gets error messages like

rtw89_8852ce 0000:04:00.0: No busy txwd pages available
rtw89_8852ce 0000:04:00.0: queue 0 txwd 100 is not idle
rtw89_8852ce 0000:04:00.0: queue 0 txwd 101 is not idle
rtw89_8852ce 0000:04:00.0: queue 0 txwd 102 is not idle
rtw89_8852ce 0000:04:00.0: queue 0 txwd 103 is not idle

If suspend/resume many times that firmware will download failed and
disconnection.

To fix these issues, We removed the rtw89_hci_disable_intr() and
rtw89_hci_enable_intr() during rtw89_wow_swap_fw() to prevent add packet
offload can't receive c2h back due to interrupt disable. Only 8852C and
8922A needs to disable interrupt before downloading fw.

Furthermore, we avoid using low power HCI mode on WoWLAN mode, to prevent
interrupt enabled, then get interrupt and calculate RXBD mismatched due to
software RXBD index already reset but hardware RXBD index not yet.

Fixes: 5c12bb6 ("wifi: rtw89: refine packet offload flow")
Signed-off-by: Chih-Kang Chang <gary.chang@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://msgid.link/20240502022505.28966-3-pkshih@realtek.com
  • Loading branch information
Chih-Kang Chang authored and Ping-Ke Shih committed May 3, 2024
1 parent a79264e commit baaf806
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 3 deletions.
3 changes: 2 additions & 1 deletion drivers/net/wireless/realtek/rtw89/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ static void rtw89_ps_power_mode_change_with_hci(struct rtw89_dev *rtwdev,

static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
{
if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode))
if (rtwdev->chip->low_power_hci_modes & BIT(rtwdev->ps_mode) &&
!test_bit(RTW89_FLAG_WOWLAN, rtwdev->flags))
rtw89_ps_power_mode_change_with_hci(rtwdev, enter);
else
rtw89_mac_power_mode_change(rtwdev, enter);
Expand Down
12 changes: 10 additions & 2 deletions drivers/net/wireless/realtek/rtw89/wow.c
Original file line number Diff line number Diff line change
Expand Up @@ -458,27 +458,36 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
struct rtw89_wow_param *rtw_wow = &rtwdev->wow;
struct ieee80211_vif *wow_vif = rtw_wow->wow_vif;
struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv;
enum rtw89_core_chip_id chip_id = rtwdev->chip->chip_id;
const struct rtw89_chip_info *chip = rtwdev->chip;
bool include_bb = !!chip->bbmcu_nr;
bool disable_intr_for_dlfw = false;
struct ieee80211_sta *wow_sta;
struct rtw89_sta *rtwsta = NULL;
bool is_conn = true;
int ret;

rtw89_hci_disable_intr(rtwdev);
if (chip_id == RTL8852C || chip_id == RTL8922A)
disable_intr_for_dlfw = true;

wow_sta = ieee80211_find_sta(wow_vif, rtwvif->bssid);
if (wow_sta)
rtwsta = (struct rtw89_sta *)wow_sta->drv_priv;
else
is_conn = false;

if (disable_intr_for_dlfw)
rtw89_hci_disable_intr(rtwdev);

ret = rtw89_fw_download(rtwdev, fw_type, include_bb);
if (ret) {
rtw89_warn(rtwdev, "download fw failed\n");
return ret;
}

if (disable_intr_for_dlfw)
rtw89_hci_enable_intr(rtwdev);

rtw89_phy_init_rf_reg(rtwdev, true);

ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta,
Expand Down Expand Up @@ -524,7 +533,6 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
rtw89_phy_rfk_pre_ntfy_and_wait(rtwdev, RTW89_PHY_0, 5);

rtw89_mac_hw_mgnt_sec(rtwdev, wow);
rtw89_hci_enable_intr(rtwdev);

return 0;
}
Expand Down

0 comments on commit baaf806

Please sign in to comment.