Commit 6239da18 authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: mac80211: adjust EHT capa when lowering bandwidth

If intending to associate with a lower bandwidth, remove capabilities
related to 320 MHz from the EHT capabilities element. Also change the
EHT MCS-NSS set accordingly: if just reducing 320->160 or similar the
format doesn't change, just cut off the last bytes. If changing from
higher bandwidth to 20 MHz only EHT STA, adjust the format.

Note that this also requires adjusting the caller in mlme.c since the
data written can now be shorter than it determined. We need to clean
all that up. Since the other callers pass NULL for the conn limit, we
don't need to change things there.

Link: https://msgid.link/20240129202041.b5f6df108c77.I0d8ea04079c61cb3744cc88625eeaf0d4776dc2b@changeid


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 90233160
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3060,6 +3060,9 @@ ieee80211_he_spr_size(const u8 *he_spr_ie)
#define IEEE80211_EHT_PHY_CAP5_SUPP_EXTRA_EHT_LTF		0x40
#define IEEE80211_EHT_PHY_CAP6_MAX_NUM_SUPP_EHT_LTF_MASK	0x07

#define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_80MHZ			0x08
#define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_160MHZ		0x30
#define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_320MHZ		0x40
#define IEEE80211_EHT_PHY_CAP6_MCS15_SUPP_MASK			0x78
#define IEEE80211_EHT_PHY_CAP6_EHT_DUP_6GHZ_SUPP		0x80

+2 −1
Original line number Diff line number Diff line
@@ -2652,7 +2652,8 @@ void ieee80211_init_frag_cache(struct ieee80211_fragment_cache *cache);
void ieee80211_destroy_frag_cache(struct ieee80211_fragment_cache *cache);

u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata);
u8 *ieee80211_ie_build_eht_cap(u8 *pos,
u8 *ieee80211_ie_build_eht_cap(const struct ieee80211_conn_settings *conn,
			       u8 *pos,
			       const struct ieee80211_sta_he_cap *he_cap,
			       const struct ieee80211_sta_eht_cap *eht_cap,
			       u8 *end,
+2 −1
Original line number Diff line number Diff line
@@ -668,7 +668,8 @@ int mesh_add_eht_cap_ie(struct ieee80211_sub_if_data *sdata,
		return -ENOMEM;

	pos = skb_put(skb, ie_len);
	ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + ie_len, false);
	ieee80211_ie_build_eht_cap(NULL, pos, he_cap, eht_cap, pos + ie_len,
				   false);

	return 0;
}
+10 −5
Original line number Diff line number Diff line
@@ -1072,9 +1072,10 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,

static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata,
				 struct sk_buff *skb,
				 struct ieee80211_supported_band *sband)
				 struct ieee80211_supported_band *sband,
				 const struct ieee80211_conn_settings *conn)
{
	u8 *pos;
	u8 *pos, *pre_eht_pos;
	const struct ieee80211_sta_he_cap *he_cap;
	const struct ieee80211_sta_eht_cap *eht_cap;
	u8 eht_cap_size;
@@ -1097,8 +1098,11 @@ static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata,
		ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
				       eht_cap->eht_cap_elem.phy_cap_info);
	pos = skb_put(skb, eht_cap_size);
	ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + eht_cap_size,
				   false);
	pre_eht_pos = pos;
	pos = ieee80211_ie_build_eht_cap(conn, pos, he_cap, eht_cap,
					 pos + eht_cap_size, false);
	/* trim excess if any */
	skb_trim(skb, skb->len - (pre_eht_pos + eht_cap_size - pos));
}

static void ieee80211_assoc_add_rates(struct sk_buff *skb,
@@ -1453,7 +1457,8 @@ static size_t ieee80211_assoc_link_elems(struct ieee80211_sub_if_data *sdata,
	present_elems = NULL;

	if (assoc_data->link[link_id].conn.mode >= IEEE80211_CONN_MODE_EHT)
		ieee80211_add_eht_ie(sdata, skb, sband);
		ieee80211_add_eht_ie(sdata, skb, sband,
				     &assoc_data->link[link_id].conn);

	if (sband->band == NL80211_BAND_S1GHZ) {
		ieee80211_add_aid_request_ie(sdata, skb);
+3 −2
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
 * Copyright 2014, Intel Corporation
 * Copyright 2014  Intel Mobile Communications GmbH
 * Copyright 2015 - 2016 Intel Deutschland GmbH
 * Copyright (C) 2019, 2021-2023 Intel Corporation
 * Copyright (C) 2019, 2021-2024 Intel Corporation
 */

#include <linux/ieee80211.h>
@@ -604,7 +604,8 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_link_data *link,
			ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
					       eht_cap->eht_cap_elem.phy_cap_info);
		pos = skb_put(skb, cap_size);
		ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + cap_size, false);
		ieee80211_ie_build_eht_cap(NULL, pos, he_cap, eht_cap,
					   pos + cap_size, false);
	}

	/* add any remaining IEs */
Loading