From: Aditya Kumar Singh Date: Mon, 29 Sep 2025 09:45:36 +0000 (+0530) Subject: AP: Fix Supported EHT-MCS And NSS Set field advertisement X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3e9aa453eb2a7da0a509ee06f9aa850364857c09;p=thirdparty%2Fhostap.git AP: Fix Supported EHT-MCS And NSS Set field advertisement The current implementation incorrectly derives the 'Supported EHT-MCS and NSS Set' field based on the operating HE bandwidth. This is inaccurate, as the field is part of the EHT Capabilities element and should represent the full hardware capabilities, not the current operating configuration. Runtime parameters already have dedicated fields within the EHT Operation element for their representation. Hence, resolve the issue by referencing the bandwidth from the HE PHY Capabilities and using it to correctly derive the Supported EHT-MCS and NSS Set values. Signed-off-by: Aditya Kumar Singh --- diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c index 3f4d06735..eb71a7df8 100644 --- a/src/ap/ieee802_11_eht.c +++ b/src/ap/ieee802_11_eht.c @@ -48,34 +48,14 @@ static u16 ieee80211_eht_ppet_size(u16 ppe_thres_hdr, const u8 *phy_cap_info) static u8 ieee80211_eht_mcs_set_size(enum hostapd_hw_mode mode, u8 opclass, - int he_oper_chwidth, const u8 *he_phy_cap, + 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; u8 cap_chwidth; - 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; - } - cap_chwidth = he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX]; - if (he_oper_chwidth != -1) - he_phy_cap_chwidth &= cap_chwidth; - else - he_phy_cap_chwidth = cap_chwidth; band24 = mode == HOSTAPD_MODE_IEEE80211B || mode == HOSTAPD_MODE_IEEE80211G || @@ -85,18 +65,18 @@ static u8 ieee80211_eht_mcs_set_size(enum hostapd_hw_mode mode, u8 opclass, band6 = is_6ghz_op_class(opclass); if (band24 && - (he_phy_cap_chwidth & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G) == 0) + (cap_chwidth & HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G) == 0) return EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY; if (band5 && - (he_phy_cap_chwidth & + (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_chwidth & + (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; @@ -126,7 +106,6 @@ size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, 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]), @@ -181,7 +160,6 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, 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) { @@ -336,7 +314,6 @@ static bool check_valid_eht_mcs(struct hostapd_data *hapd, 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) @@ -378,7 +355,7 @@ static bool ieee80211_invalid_eht_cap_size(enum hostapd_hw_mode mode, if (len < cap_len) return true; - cap_len += ieee80211_eht_mcs_set_size(mode, opclass, -1, he_phy_cap, + cap_len += ieee80211_eht_mcs_set_size(mode, opclass, he_phy_cap, cap->phy_cap); if (len < cap_len) return true;