From: Aloka Dixit Date: Tue, 19 Apr 2022 18:04:08 +0000 (-0700) Subject: EHT: Add capabilities element in AP mode Management frames X-Git-Tag: hostap_2_11~1993 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b7202d665e91d87166b40a35d843e958ef24e92;p=thirdparty%2Fhostap.git EHT: Add capabilities element in AP mode Management frames Add EHT Capabilities element in Beacon, Probe Response, and (Re)Association Response frames. Signed-off-by: Aloka Dixit Signed-off-by: Pradeep Kumar Chitrapu --- diff --git a/hostapd/Android.mk b/hostapd/Android.mk index f36957594..885dae7f6 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -297,6 +297,7 @@ endif ifdef CONFIG_IEEE80211BE CONFIG_IEEE80211AX=y L_CFLAGS += -DCONFIG_IEEE80211BE +OBJS += src/ap/ieee802_11_eht.c endif ifdef CONFIG_IEEE80211AX diff --git a/hostapd/Makefile b/hostapd/Makefile index 25d6530d3..9967e270c 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -342,6 +342,7 @@ endif ifdef CONFIG_IEEE80211BE CONFIG_IEEE80211AX=y CFLAGS += -DCONFIG_IEEE80211BE +OBJS += ../src/ap/ieee802_11_eht.o endif ifdef CONFIG_IEEE80211AX diff --git a/src/ap/beacon.c b/src/ap/beacon.c index 3ff03f845..270b28b71 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -509,6 +509,11 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP); buflen += hostapd_mbo_ie_len(hapd); buflen += hostapd_eid_owe_trans_len(hapd); @@ -635,6 +640,11 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + #ifdef CONFIG_IEEE80211AC if (hapd->conf->vendor_vht) pos = hostapd_eid_vendor_vht(hapd, pos); @@ -1538,6 +1548,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON); tail_len += hostapd_mbo_ie_len(hapd); tail_len += hostapd_eid_owe_trans_len(hapd); @@ -1685,6 +1700,12 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd, } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + tailpos = hostapd_eid_eht_capab(hapd, tailpos, + IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + #ifdef CONFIG_IEEE80211AC if (hapd->conf->vendor_vht) tailpos = hostapd_eid_vendor_vht(hapd, tailpos); diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index e25b6804c..c7ee3e126 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -5044,6 +5044,11 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, if (sta && sta->dpp_pfs) buflen += 5 + sta->dpp_pfs->curve->prime_len; #endif /* CONFIG_DPP2 */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + buf = os_zalloc(buflen); if (!buf) { res = WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -5190,6 +5195,11 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, rsnxe_done: #endif /* CONFIG_TESTING_OPTIONS */ +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) + p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP); +#endif /* CONFIG_IEEE80211BE */ + #ifdef CONFIG_OWE if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) && sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS && diff --git a/src/ap/ieee802_11.h b/src/ap/ieee802_11.h index ec0fc4396..b8fcfae0d 100644 --- a/src/ap/ieee802_11.h +++ b/src/ap/ieee802_11.h @@ -201,5 +201,9 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type); u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type); int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta, int res, struct radius_sta *info); +size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, + enum ieee80211_op_mode opmode); +u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, + enum ieee80211_op_mode opmode); #endif /* IEEE802_11_H */ diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c new file mode 100644 index 000000000..f4807d081 --- /dev/null +++ b/src/ap/ieee802_11_eht.c @@ -0,0 +1,157 @@ +/* + * hostapd / IEEE 802.11be EHT + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "utils/includes.h" +#include "utils/common.h" +#include "hostapd.h" +#include "ieee802_11.h" + + +static u8 ieee80211_eht_ppet_size(const u8 *ppe_thres, const u8 *phy_cap_info) +{ + u8 sz = 0, nss, num_nss = 0; + u32 ru; + + if ((phy_cap_info[EHT_PHYCAP_PPE_THRESHOLD_PRESENT_IDX] & + EHT_PHYCAP_PPE_THRESHOLD_PRESENT) == 0) + return 0; + + ru = (u32) ppe_thres[0]; + ru = (ru & EHT_PPE_THRES_RU_INDEX_MASK) >> EHT_PPE_THRES_RU_INDEX_SHIFT; + while (ru) { + if (ru & 0x1) + sz++; + ru >>= 1; + } + + nss = (ppe_thres[0] & EHT_PPE_THRES_NSS_MASK) >> + EHT_PPE_THRES_NSS_SHIFT; + while (nss) { + if (nss & 0x1) + num_nss++; + nss >>= 1; + } + + sz = sz * (1 + num_nss); + sz = (sz * 6) + 9; + if (sz % 8) + sz += 8; + sz /= 8; + + return sz; +} + + +static u8 ieee80211_eht_mcs_set_size(const u8 *he_phy_cap, + const u8 *eht_phy_cap) +{ + u8 sz = EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; + + if ((he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & + (HE_PHYCAP_CHANNEL_WIDTH_SET_40MHZ_IN_2G | + 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 (he_phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] & + (HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G | + HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G)) + sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; + + if (eht_phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] & + EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK) + sz += EHT_PHYCAP_MCS_NSS_LEN_20MHZ_PLUS; + + return sz; +} + + +size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd, + enum ieee80211_op_mode opmode) +{ + struct hostapd_hw_modes *mode; + struct eht_capabilities *eht_cap; + size_t len = 3 + 2 + EHT_PHY_CAPAB_LEN; + + mode = hapd->iface->current_mode; + if (!mode) + return 0; + + eht_cap = &mode->eht_capab[opmode]; + if (!eht_cap->eht_supported) + return 0; + + len += ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, + eht_cap->phy_cap); + len += ieee80211_eht_ppet_size(eht_cap->ppet, eht_cap->phy_cap); + + return len; +} + + +u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid, + enum ieee80211_op_mode opmode) +{ + struct hostapd_hw_modes *mode; + struct eht_capabilities *eht_cap; + struct ieee80211_eht_capabilities *cap; + size_t mcs_nss_len, ppe_thresh_len; + u8 *pos = eid, *length_pos; + + mode = hapd->iface->current_mode; + if (!mode) + return eid; + + eht_cap = &mode->eht_capab[opmode]; + if (!eht_cap->eht_supported) + return eid; + + *pos++ = WLAN_EID_EXTENSION; + length_pos = pos++; + *pos++ = WLAN_EID_EXT_EHT_CAPABILITIES; + + cap = (struct ieee80211_eht_capabilities *) pos; + os_memset(cap, 0, sizeof(*cap)); + cap->mac_cap = host_to_le16(eht_cap->mac_cap); + os_memcpy(cap->phy_cap, eht_cap->phy_cap, EHT_PHY_CAPAB_LEN); + + if (!is_6ghz_op_class(hapd->iconf->op_class)) + cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &= + ~EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK; + if (!hapd->iface->conf->eht_phy_capab.su_beamformer) + cap->phy_cap[EHT_PHYCAP_SU_BEAMFORMER_IDX] &= + ~EHT_PHYCAP_SU_BEAMFORMER; + + if (!hapd->iface->conf->eht_phy_capab.su_beamformee) + cap->phy_cap[EHT_PHYCAP_SU_BEAMFORMEE_IDX] &= + ~EHT_PHYCAP_SU_BEAMFORMEE; + + if (!hapd->iface->conf->eht_phy_capab.mu_beamformer) + cap->phy_cap[EHT_PHYCAP_MU_BEAMFORMER_IDX] &= + ~EHT_PHYCAP_MU_BEAMFORMER_MASK; + + pos = cap->optional; + + mcs_nss_len = ieee80211_eht_mcs_set_size(mode->he_capab[opmode].phy_cap, + eht_cap->phy_cap); + if (mcs_nss_len) { + os_memcpy(pos, eht_cap->mcs, mcs_nss_len); + pos += mcs_nss_len; + } + + ppe_thresh_len = ieee80211_eht_ppet_size(eht_cap->ppet, + eht_cap->phy_cap); + if (ppe_thresh_len) { + os_memcpy(pos, eht_cap->ppet, ppe_thresh_len); + pos += ppe_thresh_len; + } + + *length_pos = pos - (eid + 2); + return pos; +} diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index bddeaf526..5d68ffa1d 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -911,6 +911,9 @@ endif ifdef CONFIG_IEEE80211AX OBJS += src/ap/ieee802_11_he.c endif +ifdef CONFIG_IEEE80211BE +OBJS += src/ap/ieee802_11_eht.c +endif ifdef CONFIG_WNM_AP L_CFLAGS += -DCONFIG_WNM_AP OBJS += src/ap/wnm_ap.c diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index 575d22340..ead9205ff 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -946,6 +946,9 @@ endif ifdef CONFIG_IEEE80211AX OBJS += ../src/ap/ieee802_11_he.o endif +ifdef CONFIG_IEEE80211BE +OBJS += ../src/ap/ieee802_11_eht.o +endif ifdef CONFIG_WNM_AP CFLAGS += -DCONFIG_WNM_AP OBJS += ../src/ap/wnm_ap.o