From 37b1db27b93cbac8b13e51f28e2ebe0dcfa70e9b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 12 Jun 2023 12:06:32 +0200 Subject: [PATCH] 6.3-stable patches added patches: wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch --- queue-6.3/series | 2 + ...-calculation-for-supports_dynamic_ps.patch | 149 ++++++++++++++++++ ...-calculation-for-supports_dynamic_ps.patch | 121 ++++++++++++++ 3 files changed, 272 insertions(+) create mode 100644 queue-6.3/wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch create mode 100644 queue-6.3/wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch diff --git a/queue-6.3/series b/queue-6.3/series index 27c7f0f0d47..4c3e39a3e9b 100644 --- a/queue-6.3/series +++ b/queue-6.3/series @@ -155,3 +155,5 @@ bluetooth-refcnt-drop-must-be-placed-last-in-hci_conn_unlink.patch bluetooth-fix-uaf-in-hci_conn_hash_flush-again.patch revert-ext4-don-t-clear-sb_rdonly-when-remounting-r-w-until-quota-is-re-enabled.patch ext4-only-check-dquot_initialize_needed-when-debugging.patch +wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch +wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch diff --git a/queue-6.3/wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch b/queue-6.3/wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch new file mode 100644 index 00000000000..47c21e7e197 --- /dev/null +++ b/queue-6.3/wifi-rtw88-correct-ps-calculation-for-supports_dynamic_ps.patch @@ -0,0 +1,149 @@ +From 3918dd0177ee08970683a2c22a3388825d82fd79 Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Sat, 27 May 2023 16:29:37 +0800 +Subject: wifi: rtw88: correct PS calculation for SUPPORTS_DYNAMIC_PS + +From: Ping-Ke Shih + +commit 3918dd0177ee08970683a2c22a3388825d82fd79 upstream. + +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. It is allowed to enter PS only if single +one station vif is working. Without this fix, driver doesn't enter PS +anymore that causes higher power consumption. + +Fixes: bcde60e599fb ("rtw88: remove misleading module parameter rtw_fw_support_lps") +Cc: stable@vger.kernel.org # 6.1+ +Signed-off-by: Ping-Ke Shih +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230527082939.11206-2-pkshih@realtek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw88/mac80211.c | 14 +++----- + drivers/net/wireless/realtek/rtw88/main.c | 4 +- + drivers/net/wireless/realtek/rtw88/ps.c | 43 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw88/ps.h | 2 + + 4 files changed, 52 insertions(+), 11 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw88/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw88/mac80211.c +@@ -88,15 +88,6 @@ static int rtw_ops_config(struct ieee802 + } + } + +- if (changed & IEEE80211_CONF_CHANGE_PS) { +- if (hw->conf.flags & IEEE80211_CONF_PS) { +- rtwdev->ps_enabled = true; +- } else { +- rtwdev->ps_enabled = false; +- rtw_leave_lps(rtwdev); +- } +- } +- + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) + rtw_set_channel(rtwdev); + +@@ -206,6 +197,7 @@ static int rtw_ops_add_interface(struct + rtwvif->bcn_ctrl = bcn_ctrl; + config |= PORT_SET_BCN_CTRL; + rtw_vif_port_config(rtwdev, rtwvif, config); ++ rtw_recalc_lps(rtwdev, vif); + + mutex_unlock(&rtwdev->mutex); + +@@ -236,6 +228,7 @@ static void rtw_ops_remove_interface(str + rtwvif->bcn_ctrl = 0; + config |= PORT_SET_BCN_CTRL; + rtw_vif_port_config(rtwdev, rtwvif, config); ++ rtw_recalc_lps(rtwdev, NULL); + + mutex_unlock(&rtwdev->mutex); + } +@@ -428,6 +421,9 @@ static void rtw_ops_bss_info_changed(str + if (changed & BSS_CHANGED_ERP_SLOT) + rtw_conf_tx(rtwdev, rtwvif); + ++ if (changed & BSS_CHANGED_PS) ++ rtw_recalc_lps(rtwdev, NULL); ++ + rtw_vif_port_config(rtwdev, rtwvif, config); + + mutex_unlock(&rtwdev->mutex); +--- a/drivers/net/wireless/realtek/rtw88/main.c ++++ b/drivers/net/wireless/realtek/rtw88/main.c +@@ -250,8 +250,8 @@ static void rtw_watch_dog_work(struct wo + * more than two stations associated to the AP, then we can not enter + * lps, because fw does not handle the overlapped beacon interval + * +- * mac80211 should iterate vifs and determine if driver can enter +- * ps by passing IEEE80211_CONF_PS to us, all we need to do is to ++ * rtw_recalc_lps() iterate vifs and determine if driver can enter ++ * ps by vif->type and vif->cfg.ps, all we need to do here is to + * get that vif and check if device is having traffic more than the + * threshold. + */ +--- a/drivers/net/wireless/realtek/rtw88/ps.c ++++ b/drivers/net/wireless/realtek/rtw88/ps.c +@@ -299,3 +299,46 @@ void rtw_leave_lps_deep(struct rtw_dev * + + __rtw_leave_lps_deep(rtwdev); + } ++ ++struct rtw_vif_recalc_lps_iter_data { ++ struct rtw_dev *rtwdev; ++ struct ieee80211_vif *found_vif; ++ int count; ++}; ++ ++static void __rtw_vif_recalc_lps(struct rtw_vif_recalc_lps_iter_data *data, ++ struct ieee80211_vif *vif) ++{ ++ if (data->count < 0) ++ return; ++ ++ if (vif->type != NL80211_IFTYPE_STATION) { ++ data->count = -1; ++ return; ++ } ++ ++ data->count++; ++ data->found_vif = vif; ++} ++ ++static void rtw_vif_recalc_lps_iter(void *data, u8 *mac, ++ struct ieee80211_vif *vif) ++{ ++ __rtw_vif_recalc_lps(data, vif); ++} ++ ++void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif) ++{ ++ struct rtw_vif_recalc_lps_iter_data data = { .rtwdev = rtwdev }; ++ ++ if (new_vif) ++ __rtw_vif_recalc_lps(&data, new_vif); ++ rtw_iterate_vifs(rtwdev, rtw_vif_recalc_lps_iter, &data); ++ ++ if (data.count == 1 && data.found_vif->cfg.ps) { ++ rtwdev->ps_enabled = true; ++ } else { ++ rtwdev->ps_enabled = false; ++ rtw_leave_lps(rtwdev); ++ } ++} +--- a/drivers/net/wireless/realtek/rtw88/ps.h ++++ b/drivers/net/wireless/realtek/rtw88/ps.h +@@ -23,4 +23,6 @@ void rtw_enter_lps(struct rtw_dev *rtwde + void rtw_leave_lps(struct rtw_dev *rtwdev); + void rtw_leave_lps_deep(struct rtw_dev *rtwdev); + enum rtw_lps_deep_mode rtw_get_lps_deep_mode(struct rtw_dev *rtwdev); ++void rtw_recalc_lps(struct rtw_dev *rtwdev, struct ieee80211_vif *new_vif); ++ + #endif diff --git a/queue-6.3/wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch b/queue-6.3/wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch new file mode 100644 index 00000000000..c3dbb31e4cc --- /dev/null +++ b/queue-6.3/wifi-rtw89-correct-ps-calculation-for-supports_dynamic_ps.patch @@ -0,0 +1,121 @@ +From 26a125f550a3bf86ac91d38752f4d446426dfe1c Mon Sep 17 00:00:00 2001 +From: Ping-Ke Shih +Date: Sat, 27 May 2023 16:29:38 +0800 +Subject: wifi: rtw89: correct PS calculation for SUPPORTS_DYNAMIC_PS + +From: Ping-Ke Shih + +commit 26a125f550a3bf86ac91d38752f4d446426dfe1c upstream. + +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 +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20230527082939.11206-3-pkshih@realtek.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/realtek/rtw89/mac80211.c | 16 +++++++--------- + drivers/net/wireless/realtek/rtw89/ps.c | 26 ++++++++++++++++++++++++++ + drivers/net/wireless/realtek/rtw89/ps.h | 1 + + 3 files changed, 34 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/realtek/rtw89/mac80211.c ++++ b/drivers/net/wireless/realtek/rtw89/mac80211.c +@@ -79,15 +79,6 @@ static int rtw89_ops_config(struct ieee8 + !(hw->conf.flags & IEEE80211_CONF_IDLE)) + rtw89_leave_ips(rtwdev); + +- if (changed & IEEE80211_CONF_CHANGE_PS) { +- if (hw->conf.flags & IEEE80211_CONF_PS) { +- rtwdev->lps_enabled = true; +- } else { +- rtw89_leave_lps(rtwdev); +- rtwdev->lps_enabled = false; +- } +- } +- + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, + &hw->conf.chandef); +@@ -147,6 +138,8 @@ static int rtw89_ops_add_interface(struc + rtw89_core_txq_init(rtwdev, vif->txq); + + rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_START); ++ ++ rtw89_recalc_lps(rtwdev); + out: + mutex_unlock(&rtwdev->mutex); + +@@ -170,6 +163,8 @@ static void rtw89_ops_remove_interface(s + rtw89_mac_remove_vif(rtwdev, rtwvif); + rtw89_core_release_bit_map(rtwdev->hw_port, rtwvif->port); + list_del_init(&rtwvif->list); ++ rtw89_recalc_lps(rtwdev); ++ + mutex_unlock(&rtwdev->mutex); + } + +@@ -425,6 +420,9 @@ static void rtw89_ops_bss_info_changed(s + if (changed & BSS_CHANGED_P2P_PS) + rtw89_process_p2p_ps(rtwdev, vif); + ++ if (changed & BSS_CHANGED_PS) ++ rtw89_recalc_lps(rtwdev); ++ + mutex_unlock(&rtwdev->mutex); + } + +--- a/drivers/net/wireless/realtek/rtw89/ps.c ++++ b/drivers/net/wireless/realtek/rtw89/ps.c +@@ -244,3 +244,29 @@ void rtw89_process_p2p_ps(struct rtw89_d + 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; ++ } ++} +--- a/drivers/net/wireless/realtek/rtw89/ps.h ++++ b/drivers/net/wireless/realtek/rtw89/ps.h +@@ -14,5 +14,6 @@ void rtw89_enter_ips(struct rtw89_dev *r + void rtw89_leave_ips(struct rtw89_dev *rtwdev); + void rtw89_set_coex_ctrl_lps(struct rtw89_dev *rtwdev, bool btc_ctrl); + void rtw89_process_p2p_ps(struct rtw89_dev *rtwdev, struct ieee80211_vif *vif); ++void rtw89_recalc_lps(struct rtw89_dev *rtwdev); + + #endif -- 2.47.2