Skip to content

Commit

Permalink
wifi: rtw89: correct PS calculation for SUPPORTS_DYNAMIC_PS
Browse files Browse the repository at this point in the history
commit 26a125f 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 28977e7 ("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: e3ec701 ("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
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Ping-Ke Shih authored and gregkh committed Jun 14, 2023
1 parent ae9517e commit c009ddc
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 9 deletions.
16 changes: 7 additions & 9 deletions drivers/net/wireless/realtek/rtw89/mac80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,6 @@ static int rtw89_ops_config(struct ieee80211_hw *hw, u32 changed)
!(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);
Expand Down Expand Up @@ -147,6 +138,8 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw,
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);

Expand All @@ -170,6 +163,8 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw,
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);
}

Expand Down Expand Up @@ -425,6 +420,9 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw,
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);
}

Expand Down
26 changes: 26 additions & 0 deletions drivers/net/wireless/realtek/rtw89/ps.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,3 +244,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;
}
}
1 change: 1 addition & 0 deletions drivers/net/wireless/realtek/rtw89/ps.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ void rtw89_enter_ips(struct rtw89_dev *rtwdev);
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

0 comments on commit c009ddc

Please sign in to comment.