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 <quic_alokad@quicinc.com> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
This commit is contained in:
parent
a7ea721889
commit
9b7202d665
8 changed files with 200 additions and 0 deletions
|
@ -297,6 +297,7 @@ endif
|
||||||
ifdef CONFIG_IEEE80211BE
|
ifdef CONFIG_IEEE80211BE
|
||||||
CONFIG_IEEE80211AX=y
|
CONFIG_IEEE80211AX=y
|
||||||
L_CFLAGS += -DCONFIG_IEEE80211BE
|
L_CFLAGS += -DCONFIG_IEEE80211BE
|
||||||
|
OBJS += src/ap/ieee802_11_eht.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211AX
|
ifdef CONFIG_IEEE80211AX
|
||||||
|
|
|
@ -342,6 +342,7 @@ endif
|
||||||
ifdef CONFIG_IEEE80211BE
|
ifdef CONFIG_IEEE80211BE
|
||||||
CONFIG_IEEE80211AX=y
|
CONFIG_IEEE80211AX=y
|
||||||
CFLAGS += -DCONFIG_IEEE80211BE
|
CFLAGS += -DCONFIG_IEEE80211BE
|
||||||
|
OBJS += ../src/ap/ieee802_11_eht.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_IEEE80211AX
|
ifdef CONFIG_IEEE80211AX
|
||||||
|
|
|
@ -509,6 +509,11 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211AX */
|
#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_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
|
||||||
buflen += hostapd_mbo_ie_len(hapd);
|
buflen += hostapd_mbo_ie_len(hapd);
|
||||||
buflen += hostapd_eid_owe_trans_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 */
|
#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
|
#ifdef CONFIG_IEEE80211AC
|
||||||
if (hapd->conf->vendor_vht)
|
if (hapd->conf->vendor_vht)
|
||||||
pos = hostapd_eid_vendor_vht(hapd, pos);
|
pos = hostapd_eid_vendor_vht(hapd, pos);
|
||||||
|
@ -1538,6 +1548,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211AX */
|
#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_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
|
||||||
tail_len += hostapd_mbo_ie_len(hapd);
|
tail_len += hostapd_mbo_ie_len(hapd);
|
||||||
tail_len += hostapd_eid_owe_trans_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 */
|
#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
|
#ifdef CONFIG_IEEE80211AC
|
||||||
if (hapd->conf->vendor_vht)
|
if (hapd->conf->vendor_vht)
|
||||||
tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
|
tailpos = hostapd_eid_vendor_vht(hapd, tailpos);
|
||||||
|
|
|
@ -5044,6 +5044,11 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
if (sta && sta->dpp_pfs)
|
if (sta && sta->dpp_pfs)
|
||||||
buflen += 5 + sta->dpp_pfs->curve->prime_len;
|
buflen += 5 + sta->dpp_pfs->curve->prime_len;
|
||||||
#endif /* CONFIG_DPP2 */
|
#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);
|
buf = os_zalloc(buflen);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
res = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
res = WLAN_STATUS_UNSPECIFIED_FAILURE;
|
||||||
|
@ -5190,6 +5195,11 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
rsnxe_done:
|
rsnxe_done:
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#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
|
#ifdef CONFIG_OWE
|
||||||
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
|
if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
|
||||||
sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
|
sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
|
||||||
|
|
|
@ -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);
|
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 ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
int res, struct radius_sta *info);
|
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 */
|
#endif /* IEEE802_11_H */
|
||||||
|
|
157
src/ap/ieee802_11_eht.c
Normal file
157
src/ap/ieee802_11_eht.c
Normal file
|
@ -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;
|
||||||
|
}
|
|
@ -911,6 +911,9 @@ endif
|
||||||
ifdef CONFIG_IEEE80211AX
|
ifdef CONFIG_IEEE80211AX
|
||||||
OBJS += src/ap/ieee802_11_he.c
|
OBJS += src/ap/ieee802_11_he.c
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_IEEE80211BE
|
||||||
|
OBJS += src/ap/ieee802_11_eht.c
|
||||||
|
endif
|
||||||
ifdef CONFIG_WNM_AP
|
ifdef CONFIG_WNM_AP
|
||||||
L_CFLAGS += -DCONFIG_WNM_AP
|
L_CFLAGS += -DCONFIG_WNM_AP
|
||||||
OBJS += src/ap/wnm_ap.c
|
OBJS += src/ap/wnm_ap.c
|
||||||
|
|
|
@ -946,6 +946,9 @@ endif
|
||||||
ifdef CONFIG_IEEE80211AX
|
ifdef CONFIG_IEEE80211AX
|
||||||
OBJS += ../src/ap/ieee802_11_he.o
|
OBJS += ../src/ap/ieee802_11_he.o
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_IEEE80211BE
|
||||||
|
OBJS += ../src/ap/ieee802_11_eht.o
|
||||||
|
endif
|
||||||
ifdef CONFIG_WNM_AP
|
ifdef CONFIG_WNM_AP
|
||||||
CFLAGS += -DCONFIG_WNM_AP
|
CFLAGS += -DCONFIG_WNM_AP
|
||||||
OBJS += ../src/ap/wnm_ap.o
|
OBJS += ../src/ap/wnm_ap.o
|
||||||
|
|
Loading…
Add table
Reference in a new issue