mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 02:43:38 +00:00
290 lines
11 KiB
Diff
290 lines
11 KiB
Diff
From 7377742385c93887bc125cecc21204387112517d Mon Sep 17 00:00:00 2001
|
|
From: Balamurugan Mahalingam <quic_bmahalin@quicinc.com>
|
|
Date: Tue, 16 Aug 2022 17:53:38 -0700
|
|
Subject: [PATCH] hostapd: Update 11be EHT elements to Draft 2.0 version
|
|
|
|
Update the EHT operations elements to Draft 2.0 and fix interop
|
|
issues with stations
|
|
|
|
Signed-off-by: Balamurugan Mahalingam <quic_bmahalin@quicinc.com>
|
|
---
|
|
hostapd/config_file.c | 2 ++
|
|
src/ap/ap_config.h | 9 +++++++++
|
|
src/ap/beacon.c | 5 +++++
|
|
src/ap/ctrl_iface_ap.c | 6 ++++--
|
|
src/ap/ieee802_11.c | 2 ++
|
|
src/ap/ieee802_11_eht.c | 34 ++++++++++++++++++++++++++++------
|
|
src/common/ieee802_11_defs.h | 35 +++++++++++++++++++++++------------
|
|
wpa_supplicant/mesh_mpm.c | 10 +++++-----
|
|
8 files changed, 78 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
|
|
index 501d30c..d896d67 100644
|
|
--- a/hostapd/config_file.c
|
|
+++ b/hostapd/config_file.c
|
|
@@ -4689,6 +4689,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
|
conf->eht_oper_chwidth = atoi(pos);
|
|
} else if (os_strcmp(buf, "eht_oper_centr_freq_seg0_idx") == 0) {
|
|
conf->eht_oper_centr_freq_seg0_idx = atoi(pos);
|
|
+ } else if (os_strcmp(buf, "eht_oper_centr_freq_seg1_idx") == 0) {
|
|
+ conf->eht_oper_centr_freq_seg1_idx = atoi(pos);
|
|
} else if (os_strcmp(buf, "eht_su_beamformer") == 0) {
|
|
conf->eht_phy_capab.su_beamformer = atoi(pos);
|
|
} else if (os_strcmp(buf, "eht_su_beamformee") == 0) {
|
|
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
|
|
index f6d1d56..83ba76c 100644
|
|
--- a/src/ap/ap_config.h
|
|
+++ b/src/ap/ap_config.h
|
|
@@ -1144,6 +1144,7 @@ struct hostapd_config {
|
|
#ifdef CONFIG_IEEE80211BE
|
|
u8 eht_oper_chwidth;
|
|
u8 eht_oper_centr_freq_seg0_idx;
|
|
+ u8 eht_oper_centr_freq_seg1_idx;
|
|
struct eht_phy_capabilities_info eht_phy_capab;
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
@@ -1227,6 +1228,10 @@ hostapd_set_oper_centr_freq_seg0_idx(struct hostapd_config *conf,
|
|
static inline u8
|
|
hostapd_get_oper_centr_freq_seg1_idx(struct hostapd_config *conf)
|
|
{
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ if (conf->ieee80211be)
|
|
+ return conf->eht_oper_centr_freq_seg1_idx;
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
#ifdef CONFIG_IEEE80211AX
|
|
if (conf->ieee80211ax)
|
|
return conf->he_oper_centr_freq_seg1_idx;
|
|
@@ -1238,6 +1243,10 @@ static inline void
|
|
hostapd_set_oper_centr_freq_seg1_idx(struct hostapd_config *conf,
|
|
u8 oper_centr_freq_seg1_idx)
|
|
{
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ if (conf->ieee80211be)
|
|
+ conf->eht_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
#ifdef CONFIG_IEEE80211AX
|
|
if (conf->ieee80211ax)
|
|
conf->he_oper_centr_freq_seg1_idx = oper_centr_freq_seg1_idx;
|
|
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
|
|
index 023729c..9536e76 100644
|
|
--- a/src/ap/beacon.c
|
|
+++ b/src/ap/beacon.c
|
|
@@ -643,6 +643,9 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
|
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
|
|
buflen += (3 + sizeof(struct ieee80211_eht_operation));
|
|
+ if (hapd->iconf->ru_punct_bitmap)
|
|
+ buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE;
|
|
+
|
|
}
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
@@ -1759,6 +1762,8 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
|
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
|
|
tail_len += (3 + sizeof(struct ieee80211_eht_operation));
|
|
+ if (hapd->iconf->ru_punct_bitmap)
|
|
+ tail_len += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE;
|
|
}
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c
|
|
index 62db273..b697ad2 100644
|
|
--- a/src/ap/ctrl_iface_ap.c
|
|
+++ b/src/ap/ctrl_iface_ap.c
|
|
@@ -1065,9 +1065,11 @@ int hostapd_ctrl_iface_status(struct hostapd_data *hapd, char *buf,
|
|
if (iface->conf->ieee80211be && !hapd->conf->disable_11be) {
|
|
ret = os_snprintf(buf + len, buflen - len,
|
|
"eht_oper_chwidth=%d\n"
|
|
- "eht_oper_centr_freq_seg0_idx=%d\n",
|
|
+ "eht_oper_centr_freq_seg0_idx=%d\n"
|
|
+ "eht_oper_centr_freq_seg1_idx=%d\n",
|
|
iface->conf->eht_oper_chwidth,
|
|
- iface->conf->eht_oper_centr_freq_seg0_idx);
|
|
+ iface->conf->eht_oper_centr_freq_seg0_idx,
|
|
+ iface->conf->eht_oper_centr_freq_seg1_idx);
|
|
if (os_snprintf_error(buflen - len, ret))
|
|
return len;
|
|
len += ret;
|
|
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
|
|
index b4efc17..8a6fed8 100644
|
|
--- a/src/ap/ieee802_11.c
|
|
+++ b/src/ap/ieee802_11.c
|
|
@@ -5106,6 +5106,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
|
|
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
|
|
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
|
|
buflen += (3 + sizeof(struct ieee80211_eht_operation));
|
|
+ if (hapd->iconf->ru_punct_bitmap)
|
|
+ buflen += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE;
|
|
}
|
|
#endif /* CONFIG_IEEE80211BE */
|
|
|
|
diff --git a/src/ap/ieee802_11_eht.c b/src/ap/ieee802_11_eht.c
|
|
index c7586ec..f54fee3 100644
|
|
--- a/src/ap/ieee802_11_eht.c
|
|
+++ b/src/ap/ieee802_11_eht.c
|
|
@@ -174,6 +174,7 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid,
|
|
{
|
|
struct hostapd_hw_modes *mode;
|
|
struct ieee80211_eht_operation *oper;
|
|
+ struct eht_capabilities *eht_cap;
|
|
u8 *pos = eid, oper_size = 0, chwidth;
|
|
|
|
mode = hapd->iface->current_mode;
|
|
@@ -185,15 +186,26 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid,
|
|
|
|
oper_size = sizeof(struct ieee80211_eht_operation);
|
|
*pos++ = WLAN_EID_EXTENSION;
|
|
- *pos++ = 1 + oper_size;
|
|
+
|
|
+ if (hapd->iconf->ru_punct_bitmap)
|
|
+ *pos++ = 1 + oper_size + DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE;
|
|
+ else
|
|
+ *pos++ = 1 + oper_size;
|
|
+
|
|
*pos++ = WLAN_EID_EXT_EHT_OPERATION;
|
|
|
|
oper = (struct ieee80211_eht_operation *) pos;
|
|
os_memset(oper, 0, sizeof(*oper));
|
|
|
|
- oper->ccfs = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf);
|
|
- if (!oper->ccfs)
|
|
- oper->ccfs = hapd->iconf->channel;
|
|
+ eht_cap = &mode->eht_capab[opmode];
|
|
+ oper->ehtop_params |= EHTOP_PARAMS_EHTOP_INFORMATION_PRESENT;
|
|
+ oper->ccfs0 = hostapd_get_oper_centr_freq_seg0_idx(hapd->iconf);
|
|
+ oper->ccfs1 = hostapd_get_oper_centr_freq_seg1_idx(hapd->iconf);
|
|
+ memcpy(&oper->mcs_nss_supported, &eht_cap->mcs,
|
|
+ EHT_PHYCAP_MCS_NSS_LEN_20MHZ_ONLY);
|
|
+
|
|
+ if (!oper->ccfs0)
|
|
+ oper->ccfs0 = hapd->iconf->channel;
|
|
|
|
if (is_6ghz_op_class(hapd->iconf->op_class))
|
|
chwidth = op_class_to_ch_width(hapd->iconf->op_class);
|
|
@@ -209,6 +221,14 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid,
|
|
switch (chwidth) {
|
|
case CHANWIDTH_320MHZ:
|
|
oper->width = EHT_OPERATION_CHANNEL_WIDTH_320MHZ;
|
|
+ if (!oper->ccfs1) {
|
|
+ /* CCFS0 points to center channel frequency in config */
|
|
+ oper->ccfs1 = oper->ccfs0;
|
|
+ if (hapd->iconf->channel < oper->ccfs0)
|
|
+ oper->ccfs0 = oper->ccfs1 - 16;
|
|
+ else
|
|
+ oper->ccfs0 = oper->ccfs1 + 16;
|
|
+ }
|
|
break;
|
|
case CHANWIDTH_160MHZ:
|
|
oper->width = EHT_OPERATION_CHANNEL_WIDTH_160MHZ;
|
|
@@ -246,8 +266,10 @@ u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid,
|
|
}
|
|
|
|
if (hapd->iconf->ru_punct_bitmap) {
|
|
- oper->disable_sub_chan_bitmap_present = 1;
|
|
- oper->disabled_subchannel_bitmap = host_to_le16(hapd->iconf->ru_punct_bitmap);
|
|
+ oper->ehtop_params |= EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT;
|
|
+ oper->disabled_subchannel_bitmap[0] =
|
|
+ host_to_le16(hapd->iconf->ru_punct_bitmap);
|
|
+ pos += DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE;
|
|
}
|
|
|
|
pos += oper_size;
|
|
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
|
|
index 752f65f..766ec1d 100644
|
|
--- a/src/common/ieee802_11_defs.h
|
|
+++ b/src/common/ieee802_11_defs.h
|
|
@@ -2462,28 +2462,39 @@ struct ieee80211_eht_capabilities {
|
|
u8 optional[71];
|
|
} STRUCT_PACKED;
|
|
|
|
-#define EHT_OPERATION_CCFS_SHIFT 4
|
|
/*
|
|
* struct ieee80211_eht_operation - eht operation element
|
|
*
|
|
* This structure is the "EHT Operation Element" fields as
|
|
- * described in P802.11be_D1.4 section 9.4.2.311
|
|
- *
|
|
- * FIXME: The spec is unclear how big the fields are, and doesn't
|
|
- * indicate the "Disabled Subchannel Bitmap Present" in the
|
|
- * structure (Figure 9-1002a) at all ...
|
|
+ * described in P802.11be_D2.0 section 9.4.2.311
|
|
*/
|
|
+
|
|
+#define EHTOP_PARAMS_EHTOP_INFORMATION_PRESENT BIT(0)
|
|
+#define EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT BIT(1)
|
|
+#define EHTOP_PARAMS_EHT_DEFAULT_PE_DURATION BIT(2)
|
|
+#define EHTOP_PARAMS_GROUP_ADDRESSED_BU_INDICATION_LIMIT BIT(3)
|
|
+#define EHTOP_PARAMS_GROUP_ADDRESSED_BU_INDICATION_EXPONENT BIT(4)
|
|
+
|
|
+#define DISABLED_SUBCHANNEL_BITMAP_BYTES_SIZE 2
|
|
+
|
|
+struct ieee80211_eht_mcs_nss_set {
|
|
+ u8 max_tx_mcs_nss_0_7;
|
|
+ u8 max_tx_mcs_nss_8_9;
|
|
+ u8 max_tx_mcs_nss_10_11;
|
|
+ u8 max_tx_mcs_nss_12_13;
|
|
+} STRUCT_PACKED;
|
|
+
|
|
struct ieee80211_eht_operation {
|
|
+ u8 ehtop_params;
|
|
+ struct ieee80211_eht_mcs_nss_set mcs_nss_supported;
|
|
u8 width:3,
|
|
reserved:5;
|
|
- u8 ccfs;
|
|
- u8 disable_sub_chan_bitmap_present:1,
|
|
- reserved2:7;
|
|
- le16 disabled_subchannel_bitmap;
|
|
-
|
|
- /* Add puncture pattern here when supported */
|
|
+ u8 ccfs0;
|
|
+ u8 ccfs1;
|
|
+ le16 disabled_subchannel_bitmap[0];
|
|
} STRUCT_PACKED;
|
|
|
|
+
|
|
#define EHT_OPERATION_CHANNEL_WIDTH_20MHZ 0
|
|
#define EHT_OPERATION_CHANNEL_WIDTH_40MHZ 1
|
|
#define EHT_OPERATION_CHANNEL_WIDTH_80MHZ 2
|
|
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
|
|
index b527a77..c56801f 100644
|
|
--- a/wpa_supplicant/mesh_mpm.c
|
|
+++ b/wpa_supplicant/mesh_mpm.c
|
|
@@ -820,28 +820,28 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
|
|
|
|
eht_oper_ie = (struct ieee80211_eht_operation *)elems->eht_operation;
|
|
if (eht_oper_ie->width >= EHT_OPERATION_CHANNEL_WIDTH_80MHZ &&
|
|
- eht_oper_ie->disable_sub_chan_bitmap_present &&
|
|
+ eht_oper_ie->ehtop_params & EHTOP_PARAMS_DISABLED_SUBCHANNEL_BITMAP_PRESENT &&
|
|
eht_oper_ie->disabled_subchannel_bitmap) {
|
|
- params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap;
|
|
+ params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap[0];
|
|
/* Validate Peer's puncture bitmap and reset if invalid */
|
|
switch (eht_oper_ie->width) {
|
|
case EHT_OPERATION_CHANNEL_WIDTH_80MHZ:
|
|
bw = 80;
|
|
- start_chan = eht_oper_ie->ccfs - 6;
|
|
+ start_chan = eht_oper_ie->ccfs0 - 6;
|
|
if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4,
|
|
params.ru_punct_bitmap, 0))
|
|
params.ru_punct_bitmap = 0;
|
|
break;
|
|
case EHT_OPERATION_CHANNEL_WIDTH_160MHZ:
|
|
bw = 160;
|
|
- start_chan = eht_oper_ie->ccfs - 14;
|
|
+ start_chan = eht_oper_ie->ccfs0 - 14;
|
|
if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4,
|
|
params.ru_punct_bitmap, 0))
|
|
params.ru_punct_bitmap = 0;
|
|
break;
|
|
case EHT_OPERATION_CHANNEL_WIDTH_320MHZ:
|
|
bw = 320;
|
|
- start_chan = eht_oper_ie->ccfs - 30;
|
|
+ start_chan = eht_oper_ie->ccfs0 - 30;
|
|
if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4,
|
|
params.ru_punct_bitmap, 0))
|
|
params.ru_punct_bitmap = 0;
|
|
--
|
|
2.17.1
|
|
|