Commit 4f58121d authored by Ilan Peer's avatar Ilan Peer Committed by Luca Coelho
Browse files

iwlwifi: mvm: Block 26-tone RU OFDMA transmissions



In case that there are OBSS that do not know how to properly
interpret 26-tone RU OFDMA transmissions, instruct the FW not
to use such transmissions.

The check is currently only performed upon association.

Signed-off-by: default avatarIlan Peer <ilan.peer@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 07c89a60
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -500,6 +500,9 @@ struct iwl_he_pkt_ext {
 *	enabled AGG, i.e. both BACK and non-BACK frames in a single AGG
 * @STA_CTXT_HE_MU_EDCA_CW: indicates that there is an element of MU EDCA
 *	parameter set, i.e. the backoff counters for trig-based ACs
 * @STA_CTXT_HE_RU_2MHZ_BLOCK: indicates that 26-tone RU OFDMA transmission are
 *      not allowed (as there are OBSS that might classify such transmissions as
 *      radar pulses).
 */
enum iwl_he_sta_ctxt_flags {
	STA_CTXT_HE_REF_BSSID_VALID		= BIT(4),
@@ -511,6 +514,7 @@ enum iwl_he_sta_ctxt_flags {
	STA_CTXT_HE_CONST_TRIG_RND_ALLOC	= BIT(10),
	STA_CTXT_HE_ACK_ENABLED			= BIT(11),
	STA_CTXT_HE_MU_EDCA_CW			= BIT(12),
	STA_CTXT_HE_RU_2MHZ_BLOCK		= BIT(14),
};

/**
+54 −0
Original line number Diff line number Diff line
@@ -2254,6 +2254,10 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,

	flags = 0;

	/* Block 26-tone RU OFDMA transmissions */
	if (mvmvif->he_ru_2mhz_block)
		flags |= STA_CTXT_HE_RU_2MHZ_BLOCK;

	/* HTC flags */
	if (sta->he_cap.he_cap_elem.mac_cap_info[0] &
	    IEEE80211_HE_MAC_CAP0_HTC_HE)
@@ -3205,6 +3209,51 @@ iwl_mvm_tdls_check_trigger(struct iwl_mvm *mvm,
				peer_addr, action);
}

struct iwl_mvm_he_obss_narrow_bw_ru_data {
	bool tolerated;
};

static void iwl_mvm_check_he_obss_narrow_bw_ru_iter(struct wiphy *wiphy,
						    struct cfg80211_bss *bss,
						    void *_data)
{
	struct iwl_mvm_he_obss_narrow_bw_ru_data *data = _data;
	const struct element *elem;

	elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY, bss->ies->data,
				  bss->ies->len);

	if (!elem || elem->datalen < 10 ||
	    !(elem->data[10] &
	      WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT)) {
		data->tolerated = false;
	}
}

static void iwl_mvm_check_he_obss_narrow_bw_ru(struct ieee80211_hw *hw,
					       struct ieee80211_vif *vif)
{
	struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
	struct iwl_mvm_he_obss_narrow_bw_ru_data iter_data = {
		.tolerated = true,
	};

	if (!(vif->bss_conf.chandef.chan->flags & IEEE80211_CHAN_RADAR)) {
		mvmvif->he_ru_2mhz_block = false;
		return;
	}

	cfg80211_bss_iter(hw->wiphy, &vif->bss_conf.chandef,
			  iwl_mvm_check_he_obss_narrow_bw_ru_iter,
			  &iter_data);

	/*
	 * If there is at least one AP on radar channel that cannot
	 * tolerate 26-tone RU UL OFDMA transmissions using HE TB PPDU.
	 */
	mvmvif->he_ru_2mhz_block = !iter_data.tolerated;
}

static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
				 struct ieee80211_vif *vif,
				 struct ieee80211_sta *sta,
@@ -3306,6 +3355,11 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
				iwl_mvm_cfg_he_sta(mvm, vif, mvm_sta->sta_id);
		} else if (vif->type == NL80211_IFTYPE_STATION) {
			vif->bss_conf.he_support = sta->he_cap.has_he;

			mvmvif->he_ru_2mhz_block = false;
			if (sta->he_cap.has_he)
				iwl_mvm_check_he_obss_narrow_bw_ru(hw, vif);

			iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
		}

+3 −0
Original line number Diff line number Diff line
@@ -504,6 +504,9 @@ struct iwl_mvm_vif {

	/* we can only have 2 GTK + 2 IGTK active at a time */
	struct ieee80211_key_conf *ap_early_keys[4];

	/* 26-tone RU OFDMA transmissions should be blocked */
	bool he_ru_2mhz_block;
};

static inline struct iwl_mvm_vif *