Commit 7312100d authored by Ping-Ke Shih's avatar Ping-Ke Shih Committed by Kalle Valo
Browse files

wifi: rtw89: allocate address CAM and MAC ID to TDLS peer



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: default avatarPing-Ke Shih <pkshih@realtek.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://lore.kernel.org/r/20220610072610.27095-2-pkshih@realtek.com
parent a8eb8e6f
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -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;
+7 −3
Original line number Diff line number Diff line
@@ -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)
	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;
}

+1 −1
Original line number Diff line number Diff line
@@ -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);
	}
+7 −6
Original line number Diff line number Diff line
@@ -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;

	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);
					  rtwvif);

	rtw89_cam_deinit(rtwdev, rtwvif);
}