OSDN Git Service

rtw89: implement mac80211_ops::set_tim to indicate STA to receive packets
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 7 Jan 2022 03:42:25 +0000 (11:42 +0800)
committerKalle Valo <kvalo@kernel.org>
Fri, 28 Jan 2022 15:56:36 +0000 (17:56 +0200)
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
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac80211.c

index 115392f..274f1fb 100644 (file)
@@ -2243,6 +2243,21 @@ static void rtw89_core_ppdu_sts_init(struct rtw89_dev *rtwdev)
                rtwdev->ppdu_sts.curr_rx_ppdu_cnt[i] = U8_MAX;
 }
 
+void rtw89_core_update_beacon_work(struct work_struct *work)
+{
+       struct rtw89_dev *rtwdev;
+       struct rtw89_vif *rtwvif = container_of(work, struct rtw89_vif,
+                                               update_beacon_work);
+
+       if (rtwvif->net_type != RTW89_NET_TYPE_AP_MODE)
+               return;
+
+       rtwdev = rtwvif->rtwdev;
+       mutex_lock(&rtwdev->mutex);
+       rtw89_fw_h2c_update_beacon(rtwdev, rtwvif);
+       mutex_unlock(&rtwdev->mutex);
+}
+
 int rtw89_core_start(struct rtw89_dev *rtwdev)
 {
        int ret;
index d57e40c..e9a9fd5 100644 (file)
@@ -1923,6 +1923,7 @@ struct rtw89_phy_rate_pattern {
 
 struct rtw89_vif {
        struct list_head list;
+       struct rtw89_dev *rtwdev;
        u8 mac_id;
        u8 port;
        u8 mac_addr[ETH_ALEN];
@@ -1944,6 +1945,7 @@ struct rtw89_vif {
        bool wowlan_magic;
        bool is_hesta;
        bool last_a_ctrl;
+       struct work_struct update_beacon_work;
        struct rtw89_addr_cam_entry addr_cam;
        struct rtw89_bssid_cam_entry bssid_cam;
        struct ieee80211_tx_queue_params tx_params[IEEE80211_NUM_ACS];
@@ -3395,5 +3397,6 @@ void rtw89_traffic_stats_init(struct rtw89_dev *rtwdev,
                              struct rtw89_traffic_stats *stats);
 int rtw89_core_start(struct rtw89_dev *rtwdev);
 void rtw89_core_stop(struct rtw89_dev *rtwdev);
+void rtw89_core_update_beacon_work(struct work_struct *work);
 
 #endif
index 8883d40..02480a6 100644 (file)
@@ -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,