From: Aditya Kumar Singh Date: Mon, 29 Sep 2025 09:45:35 +0000 (+0530) Subject: AP: Fix HE capability advertisement X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e75347fd1636851632cd2c23de60e62a1ce61bc0;p=thirdparty%2Fhostap.git AP: Fix HE capability advertisement The current implementation incorrectly derives the 'Supported Channel Width Set' in the HE PHY Capabilities Information field based on the operating bandwidth. This, in turn, affects the advertisement of the 'Supported HE-MCS and NSS Set' field. Such behavior is flawed, as capability advertisement should reflect the full hardware capabilities, not the current operating configuration. Runtime parameters already have designated fields in the HE Operation element for their representation. Hence, fix this now by using the HE PHY Capabilities and Supported HE-MCS and NSS Set values as advertised by the driver. Signed-off-by: Aditya Kumar Singh --- diff --git a/src/ap/ieee802_11_he.c b/src/ap/ieee802_11_he.c index f4adeada9..e072fb831 100644 --- a/src/ap/ieee802_11_he.c +++ b/src/ap/ieee802_11_he.c @@ -91,49 +91,20 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, { struct ieee80211_he_capabilities *cap; struct hostapd_hw_modes *mode = hapd->iface->current_mode; - u8 he_oper_chwidth = 0; + const struct he_capabilities *he_capab; u8 *pos = eid; - u8 ie_size = 0, mcs_nss_size = 4, ppet_size = 0; + u8 ie_size = 0, mcs_nss_size, ppet_size; if (!mode) return eid; - ie_size = sizeof(*cap) - sizeof(cap->optional); - ppet_size = ieee80211_he_ppet_size(mode->he_capab[opmode].ppet[0], - mode->he_capab[opmode].phy_cap); - - if (mode->mode == HOSTAPD_MODE_IEEE80211A) { - switch (hapd->iface->conf->he_oper_chwidth) { - case CONF_OPER_CHWIDTH_80P80MHZ: - he_oper_chwidth |= - HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G; - mcs_nss_size += 4; - /* fall through */ - case CONF_OPER_CHWIDTH_160MHZ: - he_oper_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G; - mcs_nss_size += 4; - /* fall through */ - case CONF_OPER_CHWIDTH_80MHZ: - case CONF_OPER_CHWIDTH_USE_HT: - he_oper_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G; - break; - default: - break; - } - } else { - switch (hapd->iface->conf->he_oper_chwidth) { - case CONF_OPER_CHWIDTH_80P80MHZ: - case CONF_OPER_CHWIDTH_160MHZ: - case CONF_OPER_CHWIDTH_80MHZ: - case CONF_OPER_CHWIDTH_USE_HT: - he_oper_chwidth |= HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G; - break; - default: - break; - } - } + he_capab = &mode->he_capab[opmode]; + + mcs_nss_size = ieee80211_he_mcs_set_size(he_capab->phy_cap); + ppet_size = ieee80211_he_ppet_size(he_capab->ppet[0], + he_capab->phy_cap); - ie_size += mcs_nss_size + ppet_size; + ie_size = IEEE80211_HE_CAPAB_MIN_LEN + mcs_nss_size + ppet_size; *pos++ = WLAN_EID_EXTENSION; *pos++ = 1 + ie_size; @@ -142,14 +113,15 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, cap = (struct ieee80211_he_capabilities *) pos; os_memset(cap, 0, sizeof(*cap)); - os_memcpy(cap->he_mac_capab_info, mode->he_capab[opmode].mac_cap, + os_memcpy(cap->he_mac_capab_info, he_capab->mac_cap, HE_MAX_MAC_CAPAB_SIZE); - os_memcpy(cap->he_phy_capab_info, mode->he_capab[opmode].phy_cap, + os_memcpy(cap->he_phy_capab_info, he_capab->phy_cap, HE_MAX_PHY_CAPAB_SIZE); - os_memcpy(cap->optional, mode->he_capab[opmode].mcs, mcs_nss_size); + os_memcpy(cap->optional, he_capab->mcs, mcs_nss_size); + if (ppet_size) - os_memcpy(&cap->optional[mcs_nss_size], - mode->he_capab[opmode].ppet, ppet_size); + os_memcpy(&cap->optional[mcs_nss_size], he_capab->ppet, + ppet_size); if (hapd->iface->conf->he_phy_capab.he_su_beamformer) cap->he_phy_capab_info[HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX] |= @@ -172,9 +144,6 @@ u8 * hostapd_eid_he_capab(struct hostapd_data *hapd, u8 *eid, cap->he_phy_capab_info[HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX] &= ~HE_PHYCAP_MU_BEAMFORMER_CAPAB; - cap->he_phy_capab_info[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &= - he_oper_chwidth; - pos += ie_size; return pos;