diff options
author | Ilan Peer <ilan.peer@intel.com> | 2022-02-14 17:30:01 +0100 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2022-02-16 15:44:00 +0100 |
commit | 820acc810fb6ec43459ed313a361cf3a9e26cc44 (patch) | |
tree | 2b1828f3253482bf2689ada1b97f20e9ee610e07 /net/mac80211/util.c | |
parent | 5dca295dd76756c7918ad7113fc4a3cf8262ed43 (diff) | |
download | lwn-820acc810fb6ec43459ed313a361cf3a9e26cc44.tar.gz lwn-820acc810fb6ec43459ed313a361cf3a9e26cc44.zip |
mac80211: Add EHT capabilities to association/probe request
Add the EHT capabilities element to both probe request and
association request frames, if advertised by the driver.
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Link: https://lore.kernel.org/r/20220214173004.2ec94388acee.I40d2ef06099cb091e9c2c01f8ef521b993a3d559@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r-- | net/mac80211/util.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 09bf9c45256e..caea8dbd1d9b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -1812,6 +1812,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata, struct ieee80211_local *local = sdata->local; struct ieee80211_supported_band *sband; const struct ieee80211_sta_he_cap *he_cap; + const struct ieee80211_sta_eht_cap *eht_cap; u8 *pos = buffer, *end = buffer + buffer_len; size_t noffset; int supp_rates_len, i; @@ -1992,6 +1993,18 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata, goto out_err; } + eht_cap = ieee80211_get_eht_iftype_cap(sband, + ieee80211_vif_type_p2p(&sdata->vif)); + + if (eht_cap && + cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band), + IEEE80211_CHAN_NO_HE | + IEEE80211_CHAN_NO_EHT)) { + pos = ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, end); + if (!pos) + goto out_err; + } + if (cfg80211_any_usable_channels(local->hw.wiphy, BIT(NL80211_BAND_6GHZ), IEEE80211_CHAN_NO_HE)) { @@ -4740,3 +4753,69 @@ u16 ieee80211_encode_usf(int listen_interval) return (u16) listen_interval; } + +u8 ieee80211_ie_len_eht_cap(struct ieee80211_sub_if_data *sdata, u8 iftype) +{ + const struct ieee80211_sta_he_cap *he_cap; + const struct ieee80211_sta_eht_cap *eht_cap; + struct ieee80211_supported_band *sband; + u8 n; + + sband = ieee80211_get_sband(sdata); + if (!sband) + return 0; + + he_cap = ieee80211_get_he_iftype_cap(sband, iftype); + eht_cap = ieee80211_get_eht_iftype_cap(sband, iftype); + if (!he_cap || !eht_cap) + return 0; + + n = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, + &eht_cap->eht_cap_elem); + return 2 + 1 + + sizeof(he_cap->he_cap_elem) + n + + ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], + eht_cap->eht_cap_elem.phy_cap_info); + return 0; +} + +u8 *ieee80211_ie_build_eht_cap(u8 *pos, + const struct ieee80211_sta_he_cap *he_cap, + const struct ieee80211_sta_eht_cap *eht_cap, + u8 *end) +{ + u8 mcs_nss_len, ppet_len; + u8 ie_len; + u8 *orig_pos = pos; + + /* Make sure we have place for the IE */ + if (!he_cap || !eht_cap) + return orig_pos; + + mcs_nss_len = ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem, + &eht_cap->eht_cap_elem); + ppet_len = ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0], + eht_cap->eht_cap_elem.phy_cap_info); + + ie_len = 2 + 1 + sizeof(eht_cap->eht_cap_elem) + mcs_nss_len + ppet_len; + if ((end - pos) < ie_len) + return orig_pos; + + *pos++ = WLAN_EID_EXTENSION; + *pos++ = ie_len - 2; + *pos++ = WLAN_EID_EXT_EHT_CAPABILITY; + + /* Fixed data */ + memcpy(pos, &eht_cap->eht_cap_elem, sizeof(eht_cap->eht_cap_elem)); + pos += sizeof(eht_cap->eht_cap_elem); + + memcpy(pos, &eht_cap->eht_mcs_nss_supp, mcs_nss_len); + pos += mcs_nss_len; + + if (ppet_len) { + memcpy(pos, &eht_cap->eht_ppe_thres, ppet_len); + pos += ppet_len; + } + + return pos; +} |