diff options
author | Chin-Yen Lee <timlee@realtek.com> | 2024-08-05 17:00:25 +0800 |
---|---|---|
committer | Ping-Ke Shih <pkshih@realtek.com> | 2024-08-09 08:39:05 +0800 |
commit | 0f683c2cf673da99b08b718db79e11451c42dc7e (patch) | |
tree | d1999f24ee7d932ddc27052ab0ae1b84fe280f2b /drivers/net/wireless/realtek/rtw89/wow.c | |
parent | 45ae0e8cf8c75f41da8bfc588038864dc82614f9 (diff) |
wifi: rtw89: wow: implement PS mode for net-detect
When net-detect is enabled, WoWLAN firmware will periodically
scan until beacon or probe response of configured networks are
received. To reduce power consumption, the FW-IPS mode is
implemented to keep WiFi chip in idle mode between each scan.
The FW-IPS is controlled by WoWLAN firmware to turn of some critical
electrical components, and is different from the original IPS mode
which most electrical components are turned off.
Signed-off-by: Chin-Yen Lee <timlee@realtek.com>
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Link: https://patch.msgid.link/20240805090028.27768-3-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/wow.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/wow.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 9882064ef68d..fa7fd6571051 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -687,17 +687,30 @@ static void rtw89_wow_enter_deep_ps(struct rtw89_dev *rtwdev) __rtw89_enter_ps_mode(rtwdev, rtwvif); } -static void rtw89_wow_enter_lps(struct rtw89_dev *rtwdev) +static void rtw89_wow_enter_ps(struct rtw89_dev *rtwdev) { struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; - rtw89_enter_lps(rtwdev, rtwvif, false); + if (rtw89_wow_mgd_linked(rtwdev)) + rtw89_enter_lps(rtwdev, rtwvif, false); + else if (rtw89_wow_no_link(rtwdev)) + rtw89_fw_h2c_fwips(rtwdev, rtwvif, true); } -static void rtw89_wow_leave_lps(struct rtw89_dev *rtwdev) +static void rtw89_wow_leave_ps(struct rtw89_dev *rtwdev, bool enable_wow) { - rtw89_leave_lps(rtwdev); + struct ieee80211_vif *wow_vif = rtwdev->wow.wow_vif; + struct rtw89_vif *rtwvif = (struct rtw89_vif *)wow_vif->drv_priv; + + if (rtw89_wow_mgd_linked(rtwdev)) { + rtw89_leave_lps(rtwdev); + } else if (rtw89_wow_no_link(rtwdev)) { + if (enable_wow) + rtw89_leave_ips(rtwdev); + else + rtw89_fw_h2c_fwips(rtwdev, rtwvif, false); + } } static int rtw89_wow_config_mac(struct rtw89_dev *rtwdev, bool enable_wow) @@ -1430,7 +1443,7 @@ static int rtw89_wow_enable(struct rtw89_dev *rtwdev) goto out; } - rtw89_wow_enter_lps(rtwdev); + rtw89_wow_enter_ps(rtwdev); ret = rtw89_wow_enable_trx_post(rtwdev); if (ret) { @@ -1455,7 +1468,7 @@ static int rtw89_wow_disable(struct rtw89_dev *rtwdev) goto out; } - rtw89_wow_leave_lps(rtwdev); + rtw89_wow_leave_ps(rtwdev, false); ret = rtw89_wow_fw_stop(rtwdev); if (ret) { @@ -1480,6 +1493,12 @@ out: return ret; } +static void rtw89_wow_restore_ps(struct rtw89_dev *rtwdev) +{ + if (rtw89_wow_no_link(rtwdev)) + rtw89_enter_ips(rtwdev); +} + int rtw89_wow_resume(struct rtw89_dev *rtwdev) { int ret; @@ -1504,6 +1523,7 @@ int rtw89_wow_resume(struct rtw89_dev *rtwdev) if (ret) rtw89_err(rtwdev, "failed to disable wow\n"); + rtw89_wow_restore_ps(rtwdev); out: rtw89_wow_clear_wakeups(rtwdev); return ret; @@ -1519,7 +1539,7 @@ int rtw89_wow_suspend(struct rtw89_dev *rtwdev, struct cfg80211_wowlan *wowlan) return ret; } - rtw89_wow_leave_lps(rtwdev); + rtw89_wow_leave_ps(rtwdev, true); ret = rtw89_wow_enable(rtwdev); if (ret) { |