wifi: rtw89: allocate address CAM and MAC ID to TDLS peer
authorPing-Ke Shih <pkshih@realtek.com>
Fri, 10 Jun 2022 07:26:00 +0000 (15:26 +0800)
committerKalle Valo <kvalo@kernel.org>
Tue, 21 Jun 2022 06:15:46 +0000 (09:15 +0300)
Normally, we only allocate an address CAM and single one MAC ID to AP in
STA mode. To support TDLS, we handle TDLS peers like AP handles stations.

Signed-off-by: Ping-Ke Shih <pkshih@realtek.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220610072610.27095-2-pkshih@realtek.com
drivers/net/wireless/realtek/rtw89/core.c
drivers/net/wireless/realtek/rtw89/core.h
drivers/net/wireless/realtek/rtw89/mac80211.c
drivers/net/wireless/realtek/rtw89/ser.c

index bd7b66e9848097a62e3ee799f72850b1ba5e6d8e..be9a472cbd870f7fa0025c813a42d7cc3f296938 100644 (file)
@@ -2286,13 +2286,13 @@ int rtw89_core_sta_add(struct rtw89_dev *rtwdev,
 
        ewma_rssi_init(&rtwsta->avg_rssi);
 
-       if (vif->type == NL80211_IFTYPE_STATION) {
+       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
                /* for station mode, assign the mac_id from itself */
                rtwsta->mac_id = rtwvif->mac_id;
                rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
                                         BTC_ROLE_MSTS_STA_CONN_START);
                rtw89_chip_rfk_channel(rtwdev);
-       } else if (vif->type == NL80211_IFTYPE_AP) {
+       } else if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
                rtwsta->mac_id = rtw89_core_acquire_bit_map(rtwdev->mac_id_map,
                                                            RTW89_MAX_MAC_ID_NUM);
        }
@@ -2323,10 +2323,10 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
        rtw89_mac_bf_monitor_calc(rtwdev, sta, true);
        rtw89_mac_bf_disassoc(rtwdev, vif, sta);
        rtw89_core_free_sta_pending_ba(rtwdev, sta);
-       if (vif->type == NL80211_IFTYPE_AP)
+       if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
                rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
 
-       if (vif->type == NL80211_IFTYPE_STATION)
+       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
                rtw89_vif_type_mapping(vif, false);
 
        ret = rtw89_fw_h2c_assoc_cmac_tbl(rtwdev, vif, sta);
@@ -2341,7 +2341,7 @@ int rtw89_core_sta_disconnect(struct rtw89_dev *rtwdev,
                return ret;
        }
 
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
                ret = rtw89_fw_h2c_role_maintain(rtwdev, rtwvif, rtwsta, RTW89_ROLE_REMOVE);
                if (ret) {
                        rtw89_warn(rtwdev, "failed to send h2c role info\n");
@@ -2367,7 +2367,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
        struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
        int ret;
 
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (vif->type == NL80211_IFTYPE_AP || sta->tdls) {
                ret = rtw89_mac_set_macid_pause(rtwdev, rtwsta->mac_id, false);
                if (ret) {
                        rtw89_warn(rtwdev, "failed to send h2c macid pause\n");
@@ -2417,7 +2417,7 @@ int rtw89_core_sta_assoc(struct rtw89_dev *rtwdev,
        rtw89_mac_bf_assoc(rtwdev, vif, sta);
        rtw89_mac_bf_monitor_calc(rtwdev, sta, false);
 
-       if (vif->type == NL80211_IFTYPE_STATION) {
+       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls) {
                rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
                                         BTC_ROLE_MSTS_STA_CONN_END);
                rtw89_core_get_no_ul_ofdma_htc(rtwdev, &rtwsta->htc_template);
@@ -2433,10 +2433,10 @@ int rtw89_core_sta_remove(struct rtw89_dev *rtwdev,
        struct rtw89_vif *rtwvif = (struct rtw89_vif *)vif->drv_priv;
        struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
 
-       if (vif->type == NL80211_IFTYPE_STATION)
+       if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
                rtw89_btc_ntfy_role_info(rtwdev, rtwvif, rtwsta,
                                         BTC_ROLE_MSTS_STA_DIS_CONN);
-       else if (vif->type == NL80211_IFTYPE_AP)
+       else if (vif->type == NL80211_IFTYPE_AP || sta->tdls)
                rtw89_core_release_bit_map(rtwdev->mac_id_map, rtwsta->mac_id);
 
        return 0;
index cf60adaed64ae0c67a71c0074096571ab95ec483..c15874f173fff3393faba604698a54dc03f2a63a 100644 (file)
@@ -1975,7 +1975,7 @@ struct rtw89_sta {
        struct ieee80211_rx_status rx_status;
        u16 rx_hw_rate;
        __le32 htc_template;
-       struct rtw89_addr_cam_entry addr_cam; /* AP mode only */
+       struct rtw89_addr_cam_entry addr_cam; /* AP mode or TDLS peer only */
 
        bool use_cfg_mask;
        struct cfg80211_bitrate_mask mask;
@@ -3558,8 +3558,12 @@ static inline
 struct rtw89_addr_cam_entry *rtw89_get_addr_cam_of(struct rtw89_vif *rtwvif,
                                                   struct rtw89_sta *rtwsta)
 {
-       if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE && rtwsta)
-               return &rtwsta->addr_cam;
+       if (rtwsta) {
+               struct ieee80211_sta *sta = rtwsta_to_sta(rtwsta);
+
+               if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+                       return &rtwsta->addr_cam;
+       }
        return &rtwvif->addr_cam;
 }
 
index 0e3c95cf4c9990002785272a5c2192a06d266a55..20fb4c5500104f584380dc8d11909f0365d68da2 100644 (file)
@@ -456,7 +456,7 @@ static int __rtw89_ops_sta_state(struct ieee80211_hw *hw,
 
        if (old_state == IEEE80211_STA_AUTH &&
            new_state == IEEE80211_STA_ASSOC) {
-               if (vif->type == NL80211_IFTYPE_STATION)
+               if (vif->type == NL80211_IFTYPE_STATION && !sta->tdls)
                        return 0; /* defer to bss_info_changed to have vif info */
                return rtw89_core_sta_assoc(rtwdev, vif, sta);
        }
index 9e95ed9727108e35bfa589dae7a0a6db23aa00d2..a5d530b0422261b5ddb60801dfadc9923ca1cd75 100644 (file)
@@ -300,18 +300,19 @@ static void ser_reset_vif(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 
 static void ser_sta_deinit_addr_cam_iter(void *data, struct ieee80211_sta *sta)
 {
-       struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
+       struct rtw89_vif *rtwvif = (struct rtw89_vif *)data;
+       struct rtw89_dev *rtwdev = rtwvif->rtwdev;
        struct rtw89_sta *rtwsta = (struct rtw89_sta *)sta->drv_priv;
 
-       rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
+       if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE || sta->tdls)
+               rtw89_cam_deinit_addr_cam(rtwdev, &rtwsta->addr_cam);
 }
 
 static void ser_deinit_cam(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
 {
-       if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
-               ieee80211_iterate_stations_atomic(rtwdev->hw,
-                                                 ser_sta_deinit_addr_cam_iter,
-                                                 rtwdev);
+       ieee80211_iterate_stations_atomic(rtwdev->hw,
+                                         ser_sta_deinit_addr_cam_iter,
+                                         rtwvif);
 
        rtw89_cam_deinit(rtwdev, rtwvif);
 }