mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-18 06:15:12 +00:00
mac80211: limit bandwidth in HE capabilities
If we're limiting bandwidth for some reason such as regulatory restrictions, then advertise that limitation just like we do for VHT today, so the AP is aware we cannot use the higher BW it might be using. Fixes: 41cbb0f5a295 ("mac80211: add support for HE") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20220202104617.70c8e3e7ee76.If317630de69ff1146bec7d47f5b83038695eb71d@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
b4bb8469e9
commit
1f2c104448
@ -2380,7 +2380,7 @@ u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
|||||||
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
u8 *ieee80211_ie_build_vht_oper(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap,
|
||||||
const struct cfg80211_chan_def *chandef);
|
const struct cfg80211_chan_def *chandef);
|
||||||
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
|
u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype);
|
||||||
u8 *ieee80211_ie_build_he_cap(u8 *pos,
|
u8 *ieee80211_ie_build_he_cap(u32 disable_flags, u8 *pos,
|
||||||
const struct ieee80211_sta_he_cap *he_cap,
|
const struct ieee80211_sta_he_cap *he_cap,
|
||||||
u8 *end);
|
u8 *end);
|
||||||
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
|
void ieee80211_ie_build_he_6ghz_cap(struct ieee80211_sub_if_data *sdata,
|
||||||
|
@ -580,7 +580,7 @@ int mesh_add_he_cap_ie(struct ieee80211_sub_if_data *sdata,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
pos = skb_put(skb, ie_len);
|
pos = skb_put(skb, ie_len);
|
||||||
ieee80211_ie_build_he_cap(pos, he_cap, pos + ie_len);
|
ieee80211_ie_build_he_cap(0, pos, he_cap, pos + ie_len);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -635,7 +635,7 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
|
|||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct ieee80211_supported_band *sband)
|
struct ieee80211_supported_band *sband)
|
||||||
{
|
{
|
||||||
u8 *pos;
|
u8 *pos, *pre_he_pos;
|
||||||
const struct ieee80211_sta_he_cap *he_cap = NULL;
|
const struct ieee80211_sta_he_cap *he_cap = NULL;
|
||||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||||
u8 he_cap_size;
|
u8 he_cap_size;
|
||||||
@ -652,16 +652,21 @@ static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
|
|||||||
|
|
||||||
he_cap = ieee80211_get_he_iftype_cap(sband,
|
he_cap = ieee80211_get_he_iftype_cap(sband,
|
||||||
ieee80211_vif_type_p2p(&sdata->vif));
|
ieee80211_vif_type_p2p(&sdata->vif));
|
||||||
if (!he_cap || !reg_cap)
|
if (!he_cap || !chanctx_conf || !reg_cap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* get a max size estimate */
|
||||||
he_cap_size =
|
he_cap_size =
|
||||||
2 + 1 + sizeof(he_cap->he_cap_elem) +
|
2 + 1 + sizeof(he_cap->he_cap_elem) +
|
||||||
ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) +
|
ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) +
|
||||||
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
|
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
|
||||||
he_cap->he_cap_elem.phy_cap_info);
|
he_cap->he_cap_elem.phy_cap_info);
|
||||||
pos = skb_put(skb, he_cap_size);
|
pos = skb_put(skb, he_cap_size);
|
||||||
ieee80211_ie_build_he_cap(pos, he_cap, pos + he_cap_size);
|
pre_he_pos = pos;
|
||||||
|
pos = ieee80211_ie_build_he_cap(sdata->u.mgd.flags,
|
||||||
|
pos, he_cap, pos + he_cap_size);
|
||||||
|
/* trim excess if any */
|
||||||
|
skb_trim(skb, skb->len - (pre_he_pos + he_cap_size - pos));
|
||||||
|
|
||||||
ieee80211_ie_build_he_6ghz_cap(sdata, skb);
|
ieee80211_ie_build_he_6ghz_cap(sdata, skb);
|
||||||
}
|
}
|
||||||
|
@ -1974,7 +1974,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
|
|||||||
if (he_cap &&
|
if (he_cap &&
|
||||||
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
|
cfg80211_any_usable_channels(local->hw.wiphy, BIT(sband->band),
|
||||||
IEEE80211_CHAN_NO_HE)) {
|
IEEE80211_CHAN_NO_HE)) {
|
||||||
pos = ieee80211_ie_build_he_cap(pos, he_cap, end);
|
pos = ieee80211_ie_build_he_cap(0, pos, he_cap, end);
|
||||||
if (!pos)
|
if (!pos)
|
||||||
goto out_err;
|
goto out_err;
|
||||||
}
|
}
|
||||||
@ -2918,10 +2918,11 @@ u8 ieee80211_ie_len_he_cap(struct ieee80211_sub_if_data *sdata, u8 iftype)
|
|||||||
he_cap->he_cap_elem.phy_cap_info);
|
he_cap->he_cap_elem.phy_cap_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *ieee80211_ie_build_he_cap(u8 *pos,
|
u8 *ieee80211_ie_build_he_cap(u32 disable_flags, u8 *pos,
|
||||||
const struct ieee80211_sta_he_cap *he_cap,
|
const struct ieee80211_sta_he_cap *he_cap,
|
||||||
u8 *end)
|
u8 *end)
|
||||||
{
|
{
|
||||||
|
struct ieee80211_he_cap_elem elem;
|
||||||
u8 n;
|
u8 n;
|
||||||
u8 ie_len;
|
u8 ie_len;
|
||||||
u8 *orig_pos = pos;
|
u8 *orig_pos = pos;
|
||||||
@ -2934,7 +2935,23 @@ u8 *ieee80211_ie_build_he_cap(u8 *pos,
|
|||||||
if (!he_cap)
|
if (!he_cap)
|
||||||
return orig_pos;
|
return orig_pos;
|
||||||
|
|
||||||
n = ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem);
|
/* modify on stack first to calculate 'n' and 'ie_len' correctly */
|
||||||
|
elem = he_cap->he_cap_elem;
|
||||||
|
|
||||||
|
if (disable_flags & IEEE80211_STA_DISABLE_40MHZ)
|
||||||
|
elem.phy_cap_info[0] &=
|
||||||
|
~(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
|
||||||
|
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G);
|
||||||
|
|
||||||
|
if (disable_flags & IEEE80211_STA_DISABLE_160MHZ)
|
||||||
|
elem.phy_cap_info[0] &=
|
||||||
|
~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
|
||||||
|
|
||||||
|
if (disable_flags & IEEE80211_STA_DISABLE_80P80MHZ)
|
||||||
|
elem.phy_cap_info[0] &=
|
||||||
|
~IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
|
||||||
|
|
||||||
|
n = ieee80211_he_mcs_nss_size(&elem);
|
||||||
ie_len = 2 + 1 +
|
ie_len = 2 + 1 +
|
||||||
sizeof(he_cap->he_cap_elem) + n +
|
sizeof(he_cap->he_cap_elem) + n +
|
||||||
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
|
ieee80211_he_ppe_size(he_cap->ppe_thres[0],
|
||||||
@ -2948,8 +2965,8 @@ u8 *ieee80211_ie_build_he_cap(u8 *pos,
|
|||||||
*pos++ = WLAN_EID_EXT_HE_CAPABILITY;
|
*pos++ = WLAN_EID_EXT_HE_CAPABILITY;
|
||||||
|
|
||||||
/* Fixed data */
|
/* Fixed data */
|
||||||
memcpy(pos, &he_cap->he_cap_elem, sizeof(he_cap->he_cap_elem));
|
memcpy(pos, &elem, sizeof(elem));
|
||||||
pos += sizeof(he_cap->he_cap_elem);
|
pos += sizeof(elem);
|
||||||
|
|
||||||
memcpy(pos, &he_cap->he_mcs_nss_supp, n);
|
memcpy(pos, &he_cap->he_mcs_nss_supp, n);
|
||||||
pos += n;
|
pos += n;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user