Patch "wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode" has been added to the 6.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode

to the 6.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     wifi-rtw89-wow-refine-wowlan-flows-of-hci-interrupts.patch
and it can be found in the queue-6.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 0ef5a57c4dabba31cfc1c1d13ba7a56e8e84a3e9
Author: Chih-Kang Chang <gary.chang@xxxxxxxxxxx>
Date:   Thu May 2 10:24:55 2024 +0800

    wifi: rtw89: wow: refine WoWLAN flows of HCI interrupts and low power mode
    
    [ Upstream commit baaf806e4632a259cc959fd1c516c2d9ed48df6d ]
    
    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: 5c12bb66b79d ("wifi: rtw89: refine packet offload flow")
    Signed-off-by: Chih-Kang Chang <gary.chang@xxxxxxxxxxx>
    Signed-off-by: Ping-Ke Shih <pkshih@xxxxxxxxxxx>
    Link: https://msgid.link/20240502022505.28966-3-pkshih@xxxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index 31290d8cb7f7c..92074b73ebebd 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -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);
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c
index ccad026defb50..ca4835008b56e 100644
--- a/drivers/net/wireless/realtek/rtw89/wow.c
+++ b/drivers/net/wireless/realtek/rtw89/wow.c
@@ -457,14 +457,17 @@ 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)
@@ -472,12 +475,18 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
 	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,
@@ -520,7 +529,6 @@ static int rtw89_wow_swap_fw(struct rtw89_dev *rtwdev, bool wow)
 	}
 
 	rtw89_mac_hw_mgnt_sec(rtwdev, wow);
-	rtw89_hci_enable_intr(rtwdev);
 
 	return 0;
 }




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux