static u8 ieee80211_eht_mcs_set_size(enum hostapd_hw_mode mode, u8 opclass,
- const u8 *he_phy_cap,
+ u8 he_oper_chwidth, const u8 *he_phy_cap,
const u8 *eht_phy_cap)
{
u8 sz = EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS;
bool band24, band5, band6;
+ u8 he_phy_cap_chwidth = ~HE_PHYCAP_CHANNEL_WIDTH_MASK;
+
+ switch (he_oper_chwidth) {
+ case CONF_OPER_CHWIDTH_80P80MHZ:
+ he_phy_cap_chwidth |=
+ HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G;
+ /* fall through */
+ case CONF_OPER_CHWIDTH_160MHZ:
+ he_phy_cap_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
+ /* fall through */
+ case CONF_OPER_CHWIDTH_80MHZ:
+ case CONF_OPER_CHWIDTH_USE_HT:
+ he_phy_cap_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G |
+ HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G;
+ break;
+ }
+
+ he_phy_cap_chwidth &= he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX];
band24 = mode == HOSTAPD_MODE_IEEE80211B ||
mode == HOSTAPD_MODE_IEEE80211G ||
band6 = is_6ghz_op_class(opclass);
if (band24 &&
- (he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
- HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G) == 0)
+ (he_phy_cap_chwidth & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G) == 0)
return EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY;
if (band5 &&
- (he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ (he_phy_cap_chwidth &
(HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) == 0)
return EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY;
if (band5 &&
- (he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ (he_phy_cap_chwidth &
(HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)))
sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS;
return 0;
len += ieee80211_eht_mcs_set_size(mode->mode, hapd->iconf->op_class,
+ hapd->iconf->he_oper_chwidth,
mode->he_capab[opmode].phy_cap,
eht_cap->phy_cap);
len += ieee80211_eht_ppet_size(WPA_GET_LE16(&eht_cap->ppet[0]),
mcs_nss_len = ieee80211_eht_mcs_set_size(mode->mode,
hapd->iconf->op_class,
+ hapd->iconf->he_oper_chwidth,
mode->he_capab[opmode].phy_cap,
eht_cap->phy_cap);
if (mcs_nss_len) {
sta_mcs = capab->optional;
if (ieee80211_eht_mcs_set_size(mode->mode, hapd->iconf->op_class,
+ hapd->iconf->he_oper_chwidth,
mode->he_capab[opmode].phy_cap,
mode->eht_capab[opmode].phy_cap) ==
EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY)
static bool ieee80211_invalid_eht_cap_size(enum hostapd_hw_mode mode,
- u8 opclass,
+ u8 opclass, u8 he_oper_chwidth,
const u8 *he_cap, const u8 *eht_cap,
size_t len)
{
if (len < cap_len)
return true;
- cap_len += ieee80211_eht_mcs_set_size(mode, opclass, he_phy_cap,
- cap->phy_cap);
+ cap_len += ieee80211_eht_mcs_set_size(mode, opclass, he_oper_chwidth,
+ he_phy_cap, cap->phy_cap);
if (len < cap_len)
return true;
!he_capab || he_capab_len < IEEE80211_HE_CAPAB_MIN_LEN ||
!eht_capab ||
ieee80211_invalid_eht_cap_size(mode, hapd->iconf->op_class,
+ hapd->iconf->he_oper_chwidth,
he_capab, eht_capab,
eht_capab_len) ||
!check_valid_eht_mcs(hapd, eht_capab, opmode)) {