]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: rtw89: ps: refactor PS flow to support MLO
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 6 Dec 2024 05:57:10 +0000 (13:57 +0800)
committerPing-Ke Shih <pkshih@realtek.com>
Thu, 12 Dec 2024 02:12:44 +0000 (10:12 +0800)
Firmware can only support PS on single one VIF operating in station mode,
so argument of PS entry rtw89_enter_lps() should be rtwvif insetad of
rtwvif_link.

To enter PS under MLO, for each rtwvif, driver sends H2C command to tell
firmware which mac_id will enter PS one by one, and afterward asks
firmware to enter deep PS.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20241206055716.18598-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/ps.c
drivers/net/wireless/realtek/rtw89/ps.h
drivers/net/wireless/realtek/rtw89/wow.c

index 29d0ac502bab2a9001de1868a7c5da9ed3674443..0519b082628175aeaa254b3c3b0aec0fa009cecc 100644 (file)
@@ -2729,10 +2729,6 @@ static enum rtw89_ps_mode rtw89_update_ps_mode(struct rtw89_dev *rtwdev)
 {
        const struct rtw89_chip_info *chip = rtwdev->chip;
 
-       /* FIXME: Fix __rtw89_enter_ps_mode() to consider MLO cases. */
-       if (rtwdev->support_mlo)
-               return RTW89_PS_MODE_NONE;
-
        if (rtw89_disable_ps_mode || !chip->ps_mode_supported ||
            RTW89_CHK_FW_FEATURE(NO_DEEP_PS, &rtwdev->fw))
                return RTW89_PS_MODE_NONE;
@@ -3469,21 +3465,10 @@ static bool rtw89_traffic_stats_track(struct rtw89_dev *rtwdev)
        return tfc_changed;
 }
 
-static void rtw89_vif_enter_lps(struct rtw89_dev *rtwdev,
-                               struct rtw89_vif_link *rtwvif_link)
-{
-       if (rtwvif_link->wifi_role != RTW89_WIFI_ROLE_STATION &&
-           rtwvif_link->wifi_role != RTW89_WIFI_ROLE_P2P_CLIENT)
-               return;
-
-       rtw89_enter_lps(rtwdev, rtwvif_link, true);
-}
-
 static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
 {
-       struct rtw89_vif_link *rtwvif_link;
+       struct ieee80211_vif *vif;
        struct rtw89_vif *rtwvif;
-       unsigned int link_id;
 
        rtw89_for_each_rtwvif(rtwdev, rtwvif) {
                if (rtwvif->tdls_peer)
@@ -3495,8 +3480,13 @@ static void rtw89_enter_lps_track(struct rtw89_dev *rtwdev)
                    rtwvif->stats.rx_tfc_lv != RTW89_TFC_IDLE)
                        continue;
 
-               rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id)
-                       rtw89_vif_enter_lps(rtwdev, rtwvif_link);
+               vif = rtwvif_to_vif(rtwvif);
+
+               if (!(vif->type == NL80211_IFTYPE_STATION ||
+                     vif->type == NL80211_IFTYPE_P2P_CLIENT))
+                       continue;
+
+               rtw89_enter_lps(rtwdev, rtwvif, true);
        }
 }
 
index c1c12abc2ea93aa54ddeb77b5468ebfc3c45f463..5e3a5e3c9776fdfeae0db266e6a2c11cd8a0fbbd 100644 (file)
@@ -62,11 +62,8 @@ static void rtw89_ps_power_mode_change(struct rtw89_dev *rtwdev, bool enter)
                rtw89_mac_power_mode_change(rtwdev, enter);
 }
 
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link)
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev)
 {
-       if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
-               return;
-
        if (!rtwdev->ps_mode)
                return;
 
@@ -85,8 +82,8 @@ void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
                rtw89_ps_power_mode_change(rtwdev, false);
 }
 
-static void __rtw89_enter_lps(struct rtw89_dev *rtwdev,
-                             struct rtw89_vif_link *rtwvif_link)
+static void __rtw89_enter_lps_link(struct rtw89_dev *rtwdev,
+                                  struct rtw89_vif_link *rtwvif_link)
 {
        struct rtw89_lps_parm lps_param = {
                .macid = rtwvif_link->mac_id,
@@ -121,17 +118,27 @@ void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev)
        __rtw89_leave_ps_mode(rtwdev);
 }
 
-void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                     bool ps_mode)
 {
+       struct rtw89_vif_link *rtwvif_link;
+       bool can_ps_mode = true;
+       unsigned int link_id;
+
        lockdep_assert_held(&rtwdev->mutex);
 
        if (test_and_set_bit(RTW89_FLAG_LEISURE_PS, rtwdev->flags))
                return;
 
-       __rtw89_enter_lps(rtwdev, rtwvif_link);
-       if (ps_mode)
-               __rtw89_enter_ps_mode(rtwdev, rtwvif_link);
+       rtw89_vif_for_each_link(rtwvif, rtwvif_link, link_id) {
+               __rtw89_enter_lps_link(rtwdev, rtwvif_link);
+
+               if (rtwvif_link->wifi_role == RTW89_WIFI_ROLE_P2P_CLIENT)
+                       can_ps_mode = false;
+       }
+
+       if (ps_mode && can_ps_mode)
+               __rtw89_enter_ps_mode(rtwdev);
 }
 
 static void rtw89_leave_lps_vif(struct rtw89_dev *rtwdev,
@@ -282,12 +289,6 @@ void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
        enum rtw89_entity_mode mode;
        int count = 0;
 
-       /* FIXME: Fix rtw89_enter_lps() and __rtw89_enter_ps_mode()
-        * to take MLO cases into account before doing the following.
-        */
-       if (rtwdev->support_mlo)
-               goto disable_lps;
-
        mode = rtw89_get_entity_mode(rtwdev);
        if (mode == RTW89_ENTITY_MODE_MCC)
                goto disable_lps;
index cdd712966b09d9b32f2e0de20c7c1846645655a9..2b88f254a32d08774ebc9f4b06eb521994fdf143 100644 (file)
@@ -5,11 +5,11 @@
 #ifndef __RTW89_PS_H_
 #define __RTW89_PS_H_
 
-void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link,
+void rtw89_enter_lps(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif,
                     bool ps_mode);
 void rtw89_leave_lps(struct rtw89_dev *rtwdev);
 void __rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
-void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev, struct rtw89_vif_link *rtwvif_link);
+void __rtw89_enter_ps_mode(struct rtw89_dev *rtwdev);
 void rtw89_leave_ps_mode(struct rtw89_dev *rtwdev);
 void rtw89_enter_ips(struct rtw89_dev *rtwdev);
 void rtw89_leave_ips(struct rtw89_dev *rtwdev);
index 1e1dbb20d47ad4d638884e6d9a7bc0f5498374bc..01754d031bb43feb5ef66cd1c98520f567d34a6f 100644 (file)
@@ -694,9 +694,7 @@ static void rtw89_wow_leave_deep_ps(struct rtw89_dev *rtwdev)
 
 static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev)
 {
-       struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
-
-       __rtw89_enter_ps_mode(rtwdev, rtwvif_link);
+       __rtw89_enter_ps_mode(rtwdev);
 }
 
 static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev)
@@ -704,7 +702,7 @@ static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev)
        struct rtw89_vif_link *rtwvif_link = rtwdev->wow.rtwvif_link;
 
        if (rtw89_wow_mgd_linked(rtwdev))
-               rtw89_enter_lps(rtwdev, rtwvif_link, false);
+               rtw89_enter_lps(rtwdev, rtwvif_link->rtwvif, false);
        else if (rtw89_wow_no_link(rtwdev))
                rtw89_fw_h2c_fwips(rtwdev, rtwvif_link, true);
 }