diff options
author | Ping-Ke Shih <pkshih@realtek.com> | 2022-01-07 04:42:25 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@kernel.org> | 2022-01-28 16:56:36 +0100 |
commit | d62816b4a44e731fd7f192b40a947eec2b2b1a81 (patch) | |
tree | 37cb4dbad05822bc1afd05a0e771df81697dd01c /drivers/net/wireless/realtek/rtw89/mac80211.c | |
parent | rtw89: add C2H handle of BCN_CNT (diff) | |
download | linux-d62816b4a44e731fd7f192b40a947eec2b2b1a81.tar.xz linux-d62816b4a44e731fd7f192b40a947eec2b2b1a81.zip |
rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets
Update beacon content if TIM bitmap maintained by mac80211 is changed.
Since .set_tim must be atomic but driver uses mutex lock, we add a work.
Otherwise, kernel says "sched: RT throttling activated" and lock down.
Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220107034239.22002-6-pkshih@realtek.com
Diffstat (limited to 'drivers/net/wireless/realtek/rtw89/mac80211.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw89/mac80211.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/realtek/rtw89/mac80211.c b/drivers/net/wireless/realtek/rtw89/mac80211.c index 8883d406649f..02480a6bdf4c 100644 --- a/drivers/net/wireless/realtek/rtw89/mac80211.c +++ b/drivers/net/wireless/realtek/rtw89/mac80211.c @@ -102,7 +102,9 @@ static int rtw89_ops_add_interface(struct ieee80211_hw *hw, int ret = 0; mutex_lock(&rtwdev->mutex); + rtwvif->rtwdev = rtwdev; list_add_tail(&rtwvif->list, &rtwdev->rtwvifs_list); + INIT_WORK(&rtwvif->update_beacon_work, rtw89_core_update_beacon_work); rtw89_leave_ps_mode(rtwdev); rtw89_traffic_stats_init(rtwdev, &rtwvif->stats); @@ -141,6 +143,8 @@ static void rtw89_ops_remove_interface(struct ieee80211_hw *hw, struct rtw89_dev *rtwdev = hw->priv; struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv; + cancel_work_sync(&rtwvif->update_beacon_work); + mutex_lock(&rtwdev->mutex); rtw89_leave_ps_mode(rtwdev); rtw89_btc_ntfy_role_info(rtwdev, rtwvif, NULL, BTC_ROLE_STOP); @@ -364,6 +368,18 @@ static void rtw89_ops_bss_info_changed(struct ieee80211_hw *hw, mutex_unlock(&rtwdev->mutex); } +static int rtw89_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + bool set) +{ + struct rtw89_dev *rtwdev = hw->priv; + struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv; + struct rtw89_vif *rtwvif = rtwsta->rtwvif; + + ieee80211_queue_work(rtwdev->hw, &rtwvif->update_beacon_work); + + return 0; +} + static int rtw89_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 ac, const struct ieee80211_tx_queue_params *params) @@ -680,6 +696,7 @@ const struct ieee80211_ops rtw89_ops = { .remove_interface = rtw89_ops_remove_interface, .configure_filter = rtw89_ops_configure_filter, .bss_info_changed = rtw89_ops_bss_info_changed, + .set_tim = rtw89_ops_set_tim, .conf_tx = rtw89_ops_conf_tx, .sta_state = rtw89_ops_sta_state, .set_key = rtw89_ops_set_key, |