mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-12 19:44:51 -04:00
wifi: rtw89: ps: refactor PS flow to support MLO
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
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user