Skip to content

Commit c17f271

Browse files
Po-Hao HuangKalle Valo
authored andcommitted
rtw88: fix idle mode flow for hw scan
Upon hw scan completion, idle mode is not re-entered. This might increase power consumption under no link mode. Fix this by adding the re-enter flow. We need another work for this since enter_ips waits for c2h_work to finish, which might lead to deadlock if caller is in the same work. Fixes: 10d162b ("rtw88: 8822c: add ieee80211_ops::hw_scan") Signed-off-by: Po-Hao Huang <[email protected]> Signed-off-by: Ping-Ke Shih <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent a12f809 commit c17f271

File tree

4 files changed

+23
-4
lines changed

4 files changed

+23
-4
lines changed

drivers/net/wireless/realtek/rtw88/fw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ void rtw_hw_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
20302030
rtwdev->hal.rcr |= BIT_CBSSID_BCN;
20312031
rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
20322032

2033-
rtw_core_scan_complete(rtwdev, vif);
2033+
rtw_core_scan_complete(rtwdev, vif, true);
20342034

20352035
ieee80211_wake_queues(rtwdev->hw);
20362036
ieee80211_scan_completed(rtwdev->hw, &info);

drivers/net/wireless/realtek/rtw88/mac80211.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
7272
struct rtw_dev *rtwdev = hw->priv;
7373
int ret = 0;
7474

75+
/* let previous ips work finish to ensure we don't leave ips twice */
76+
cancel_work_sync(&rtwdev->ips_work);
77+
7578
mutex_lock(&rtwdev->mutex);
7679

7780
rtw_leave_lps_deep(rtwdev);
@@ -614,7 +617,7 @@ static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
614617
struct rtw_dev *rtwdev = hw->priv;
615618

616619
mutex_lock(&rtwdev->mutex);
617-
rtw_core_scan_complete(rtwdev, vif);
620+
rtw_core_scan_complete(rtwdev, vif, false);
618621
mutex_unlock(&rtwdev->mutex);
619622
}
620623

drivers/net/wireless/realtek/rtw88/main.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ static void rtw_c2h_work(struct work_struct *work)
272272
}
273273
}
274274

275+
static void rtw_ips_work(struct work_struct *work)
276+
{
277+
struct rtw_dev *rtwdev = container_of(work, struct rtw_dev, ips_work);
278+
279+
mutex_lock(&rtwdev->mutex);
280+
rtw_enter_ips(rtwdev);
281+
mutex_unlock(&rtwdev->mutex);
282+
}
283+
275284
static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
276285
{
277286
unsigned long mac_id;
@@ -1339,7 +1348,8 @@ void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
13391348
set_bit(RTW_FLAG_SCANNING, rtwdev->flags);
13401349
}
13411350

1342-
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
1351+
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
1352+
bool hw_scan)
13431353
{
13441354
struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
13451355
u32 config = 0;
@@ -1354,6 +1364,9 @@ void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif)
13541364
rtw_vif_port_config(rtwdev, rtwvif, config);
13551365

13561366
rtw_coex_scan_notify(rtwdev, COEX_SCAN_FINISH);
1367+
1368+
if (rtwvif->net_type == RTW_NET_NO_LINK && hw_scan)
1369+
ieee80211_queue_work(rtwdev->hw, &rtwdev->ips_work);
13571370
}
13581371

13591372
int rtw_core_start(struct rtw_dev *rtwdev)
@@ -1919,6 +1932,7 @@ int rtw_core_init(struct rtw_dev *rtwdev)
19191932
INIT_DELAYED_WORK(&coex->wl_ccklock_work, rtw_coex_wl_ccklock_work);
19201933
INIT_WORK(&rtwdev->tx_work, rtw_tx_work);
19211934
INIT_WORK(&rtwdev->c2h_work, rtw_c2h_work);
1935+
INIT_WORK(&rtwdev->ips_work, rtw_ips_work);
19221936
INIT_WORK(&rtwdev->fw_recovery_work, rtw_fw_recovery_work);
19231937
INIT_WORK(&rtwdev->ba_work, rtw_txq_ba_work);
19241938
skb_queue_head_init(&rtwdev->c2h_queue);

drivers/net/wireless/realtek/rtw88/main.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1960,6 +1960,7 @@ struct rtw_dev {
19601960
/* c2h cmd queue & handler work */
19611961
struct sk_buff_head c2h_queue;
19621962
struct work_struct c2h_work;
1963+
struct work_struct ips_work;
19631964
struct work_struct fw_recovery_work;
19641965

19651966
/* used to protect txqs list */
@@ -2101,7 +2102,8 @@ void rtw_tx_report_purge_timer(struct timer_list *t);
21012102
void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si);
21022103
void rtw_core_scan_start(struct rtw_dev *rtwdev, struct rtw_vif *rtwvif,
21032104
const u8 *mac_addr, bool hw_scan);
2104-
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif);
2105+
void rtw_core_scan_complete(struct rtw_dev *rtwdev, struct ieee80211_vif *vif,
2106+
bool hw_scan);
21052107
int rtw_core_start(struct rtw_dev *rtwdev);
21062108
void rtw_core_stop(struct rtw_dev *rtwdev);
21072109
int rtw_chip_info_setup(struct rtw_dev *rtwdev);

0 commit comments

Comments
 (0)