summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/realtek/rtw89/ps.c
diff options
context:
space:
mode:
authorPing-Ke Shih <pkshih@realtek.com>2023-05-27 11:29:38 +0300
committerKalle Valo <kvalo@kernel.org>2023-06-01 16:16:41 +0300
commit26a125f550a3bf86ac91d38752f4d446426dfe1c (patch)
treee784846f0929c90c4f460efd431ce360aa581c2a /drivers/net/wireless/realtek/rtw89/ps.c
parent3918dd0177ee08970683a2c22a3388825d82fd79 (diff)
downloadlinux-26a125f550a3bf86ac91d38752f4d446426dfe1c.tar.xz
wifi: rtw89: correct PS calculation for SUPPORTS_DYNAMIC_PS
This driver relies on IEEE80211_CONF_PS of hw->conf.flags to turn off PS or turn on dynamic PS controlled by driver and firmware. Though this would be incorrect, it did work before because the flag is always recalculated until the commit 28977e790b5d ("wifi: mac80211: skip powersave recalc if driver SUPPORTS_DYNAMIC_PS") is introduced by kernel 5.20 to skip to recalculate IEEE80211_CONF_PS of hw->conf.flags if driver sets SUPPORTS_DYNAMIC_PS. Correct this by doing recalculation while BSS_CHANGED_PS is changed and interface is added or removed. For now, it is allowed to enter PS only if single one station vif is working, and it could possible to have PS per vif after firmware can support it. Without this fix, driver doesn't enter PS anymore that causes higher power consumption. Fixes: e3ec7017f6a2 ("rtw89: add Realtek 802.11ax driver") Cc: stable@vger.kernel.org # 6.1+ Signed-off-by: Ping-Ke Shih <pkshih@realtek.com> Signed-off-by: Kalle Valo <kvalo@kernel.org> Link: https://lore.kernel.org/r/20230527082939.11206-3-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/ps.c')
-rw-r--r--drivers/net/wireless/realtek/rtw89/ps.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/ps.c b/drivers/net/wireless/realtek/rtw89/ps.c
index fa94335f699a..84201ef19c17 100644
--- a/drivers/net/wireless/realtek/rtw89/ps.c
+++ b/drivers/net/wireless/realtek/rtw89/ps.c
@@ -252,3 +252,29 @@ void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif)
rtw89_p2p_disable_all_noa(rtwdev, vif);
rtw89_p2p_update_noa(rtwdev, vif);
}
+
+void rtw89_recalc_lps(struct rtw89_dev *rtwdev)
+{
+ struct ieee80211_vif *vif, *found_vif = NULL;
+ struct rtw89_vif *rtwvif;
+ int count = 0;
+
+ rtw89_for_each_rtwvif(rtwdev, rtwvif) {
+ vif = rtwvif_to_vif(rtwvif);
+
+ if (vif->type != NL80211_IFTYPE_STATION) {
+ count = 0;
+ break;
+ }
+
+ count++;
+ found_vif = vif;
+ }
+
+ if (count == 1 && found_vif->cfg.ps) {
+ rtwdev->lps_enabled = true;
+ } else {
+ rtw89_leave_lps(rtwdev);
+ rtwdev->lps_enabled = false;
+ }
+}