mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-12-20 02:43:38 +00:00
334 lines
12 KiB
Diff
334 lines
12 KiB
Diff
From 340c9ab10eabb7a962f16cbb0a3abd492942ef57 Mon Sep 17 00:00:00 2001
|
|
From: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
|
Date: Wed, 25 May 2022 11:32:01 +0530
|
|
Subject: [PATCH] wpa_supplicant: add RU puncturing support
|
|
|
|
Retrieve the driver support for RU puncturing which is advertised
|
|
using the attribute NL80211_ATTR_RU_PUNCT_SUPP_BW.
|
|
Value indicates the bandwidths in which puncturing is supported -
|
|
80 MHz, 160 MHz or 320 MHz.
|
|
Absence of the attribute or the value 0 means the driver does not
|
|
support this feature.
|
|
|
|
Add New option 'ru_punct_bitmap' to configure RU puncturing bitmap
|
|
and pass the configured bitmap to kernel via frequency params
|
|
during join mesh if driver supports puncturing pattern for configured
|
|
Bandwidth.
|
|
Kernel will validate the pattern against spec allowed patterns
|
|
(IEEE P802.11be/D1.5, Table 36-30)
|
|
|
|
Parse EHT Operational IE of received mesh beacons and validate &
|
|
and send Peer mesh node's RU puncturing pattern as part of station
|
|
add command (NL80211_CMD_NEW_STATION).
|
|
|
|
Signed-off-by: Rameshkumar Sundaram <quic_ramess@quicinc.com>
|
|
---
|
|
src/ap/hw_features.c | 9 +++++++++
|
|
src/drivers/driver.h | 7 +++++++
|
|
src/drivers/driver_nl80211.c | 6 ++++++
|
|
wpa_supplicant/ap.c | 5 +++--
|
|
wpa_supplicant/config.c | 2 ++
|
|
wpa_supplicant/config_file.c | 1 +
|
|
wpa_supplicant/config_ssid.h | 6 ++++++
|
|
wpa_supplicant/mesh.c | 4 ++++
|
|
wpa_supplicant/mesh_mpm.c | 41 ++++++++++++++++++++++++++++++++++++++
|
|
wpa_supplicant/wpa_supplicant.c | 26 ++++++++++++++++++++++--
|
|
wpa_supplicant/wpa_supplicant.conf | 7 +++++++
|
|
wpa_supplicant/wpa_supplicant_i.h | 2 ++
|
|
12 files changed, 112 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
|
|
index 1dcd0d0..f66c649 100644
|
|
--- a/src/ap/hw_features.c
|
|
+++ b/src/ap/hw_features.c
|
|
@@ -949,6 +949,15 @@ static int hostapd_is_usable_ru_punct_bitmap(struct hostapd_iface *iface)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CONFIG_MESH
|
|
+ if (iface->mconf != NULL) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "%s: Mesh RU bitmap will be validated in kernel while joining the mesh network",
|
|
+ iface->bss[0]->conf->iface);
|
|
+ return 1;
|
|
+ }
|
|
+#endif
|
|
+
|
|
switch (conf->eht_oper_chwidth) {
|
|
case 0:
|
|
wpa_printf(MSG_ERROR,
|
|
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
|
|
index 038379b..3c73e68 100644
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -1291,6 +1291,12 @@ struct wpa_driver_associate_params {
|
|
* Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G
|
|
*/
|
|
int enable_320mhz_bw;
|
|
+
|
|
+ /**
|
|
+ * RU puncturing bitmap - Each bit corresponds to a 20 MHz subchannel,
|
|
+ * lowest bit for the channel with the lowest frequency.
|
|
+ * Bit set to 1 indicates that the subchannel is punctured, otherwise active.*/
|
|
+ u16 ru_punct_bitmap;
|
|
};
|
|
|
|
enum hide_ssid {
|
|
@@ -2381,6 +2387,7 @@ struct hostapd_sta_add_params {
|
|
const u8 *supp_oper_classes;
|
|
size_t supp_oper_classes_len;
|
|
int support_p2p_ps;
|
|
+ u16 ru_punct_bitmap;
|
|
};
|
|
|
|
struct mac_address {
|
|
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
|
index a89097d..44b4330 100644
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -5419,6 +5419,12 @@ static int wpa_driver_nl80211_sta_add(void *priv,
|
|
nla_nest_end(msg, wme);
|
|
}
|
|
|
|
+ if (params->ru_punct_bitmap) {
|
|
+ wpa_printf(MSG_DEBUG, " * eht ru puncturing bitmap=0x%x", params->ru_punct_bitmap);
|
|
+ if (nla_put_u16(msg, NL80211_ATTR_RU_PUNCT_BITMAP, params->ru_punct_bitmap))
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
msg = NULL;
|
|
if (ret)
|
|
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
|
|
index 30f33c4..2c55e95 100644
|
|
--- a/wpa_supplicant/ap.c
|
|
+++ b/wpa_supplicant/ap.c
|
|
@@ -417,9 +417,10 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
|
|
conf->ieee80211ax = 1;
|
|
if (mode->eht_capab[wpas_mode_to_ieee80211_mode(
|
|
ssid->mode)].eht_supported &&
|
|
- ssid->eht)
|
|
+ ssid->eht) {
|
|
conf->ieee80211be = 1;
|
|
-
|
|
+ conf->ru_punct_bitmap = ssid->ru_punct_bitmap;
|
|
+ }
|
|
if (mode->vht_capab && ssid->vht) {
|
|
conf->ieee80211ac = 1;
|
|
conf->vht_capab |= mode->vht_capab;
|
|
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
|
|
index 502d3d6..f8945ee 100644
|
|
--- a/wpa_supplicant/config.c
|
|
+++ b/wpa_supplicant/config.c
|
|
@@ -2813,6 +2813,7 @@ static const struct parse_data ssid_fields[] = {
|
|
{ INT_RANGE(beacon_tx_mode, 1, 2)},
|
|
{ INT_RANGE(enable_160mhz_bw, 0, 1)},
|
|
{ INT_RANGE(enable_320mhz_bw, 0, 1)},
|
|
+ { INT(ru_punct_bitmap) },
|
|
};
|
|
|
|
#undef OFFSET
|
|
@@ -3330,6 +3331,7 @@ void wpa_config_set_network_defaults(struct wpa_ssid *ssid)
|
|
ssid->mac_addr = -1;
|
|
ssid->max_oper_chwidth = DEFAULT_MAX_OPER_CHWIDTH;
|
|
ssid->beacon_tx_mode = DEFAULT_BEACON_TX_MODE;
|
|
+ ssid->ru_punct_bitmap = 0;
|
|
}
|
|
|
|
|
|
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
|
|
index f47973b..f8a519b 100644
|
|
--- a/wpa_supplicant/config_file.c
|
|
+++ b/wpa_supplicant/config_file.c
|
|
@@ -894,6 +894,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
|
|
INT(beacon_tx_mode);
|
|
INT(enable_160mhz_bw);
|
|
INT(enable_320mhz_bw);
|
|
+ INT(ru_punct_bitmap);
|
|
#undef STR
|
|
#undef INT
|
|
#undef INT_DEF
|
|
diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h
|
|
index 1704e0d..fdd40f9 100644
|
|
--- a/wpa_supplicant/config_ssid.h
|
|
+++ b/wpa_supplicant/config_ssid.h
|
|
@@ -1227,6 +1227,12 @@ struct wpa_ssid {
|
|
* Enable 320MHz BW - set it 1 to enable mesh 320MHz 6G
|
|
*/
|
|
int enable_320mhz_bw;
|
|
+
|
|
+ /**
|
|
+ * RU puncturing bitmap - Each bit corresponds to a 20 MHz subchannel,
|
|
+ * lowest bit for the channel with the lowest frequency.
|
|
+ * Bit set to 1 indicates that the subchannel is punctured, otherwise active.*/
|
|
+ u16 ru_punct_bitmap;
|
|
};
|
|
|
|
#endif /* CONFIG_SSID_H */
|
|
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
|
|
index 0372c08..231065d 100644
|
|
--- a/wpa_supplicant/mesh.c
|
|
+++ b/wpa_supplicant/mesh.c
|
|
@@ -411,6 +411,7 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
|
ifmsh->num_bss = 1;
|
|
ifmsh->enable_iface_cb = wpa_supplicant_mesh_enable_iface_cb;
|
|
ifmsh->disable_iface_cb = wpa_supplicant_mesh_disable_iface_cb;
|
|
+ ifmsh->ru_punct_supp_bw = wpa_s->ru_punct_supp_bw;
|
|
ifmsh->bss = os_calloc(wpa_s->ifmsh->num_bss,
|
|
sizeof(struct hostapd_data *));
|
|
if (!ifmsh->bss)
|
|
@@ -493,6 +494,9 @@ static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
|
|
wpa_s->mesh_params->handle_dfs = true;
|
|
}
|
|
|
|
+ if (ssid->eht)
|
|
+ conf->ru_punct_bitmap = freq->ru_punct_bitmap;
|
|
+
|
|
bss->iconf = conf;
|
|
ifmsh->conf = conf;
|
|
|
|
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
|
|
index d69af3f..8899434 100644
|
|
--- a/wpa_supplicant/mesh_mpm.c
|
|
+++ b/wpa_supplicant/mesh_mpm.c
|
|
@@ -728,6 +728,7 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
|
|
struct hostapd_data *data = wpa_s->ifmsh->bss[0];
|
|
struct sta_info *sta;
|
|
struct ieee80211_ht_operation *oper;
|
|
+ struct ieee80211_eht_operation *eht_oper_ie;
|
|
int ret;
|
|
|
|
if (elems->mesh_config_len >= 7 &&
|
|
@@ -811,6 +812,46 @@ static struct sta_info * mesh_mpm_add_peer(struct wpa_supplicant *wpa_s,
|
|
params.he_6ghz_capab = sta->he_6ghz_capab;
|
|
params.eht_capab = sta->eht_capab;
|
|
params.eht_capab_len = sta->eht_capab_len;
|
|
+#ifdef CONFIG_IEEE80211BE
|
|
+ if (elems->eht_operation && elems->eht_operation_len >= sizeof(*eht_oper_ie)) {
|
|
+ u16 bw = 0;
|
|
+ u16 start_chan = 0;
|
|
+ u16 pri_chan = wpa_s->ifmsh->conf->channel;
|
|
+
|
|
+ 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->disabled_subchannel_bitmap) {
|
|
+ params.ru_punct_bitmap = eht_oper_ie->disabled_subchannel_bitmap;
|
|
+ /* 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;
|
|
+ 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;
|
|
+ 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;
|
|
+ if (!is_ru_punct_bitmap_valid(bw, (pri_chan - start_chan) / 4,
|
|
+ params.ru_punct_bitmap, 0))
|
|
+ params.ru_punct_bitmap = 0;
|
|
+ break;
|
|
+ default:
|
|
+ params.ru_punct_bitmap = 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+#endif /* CONFIG_IEEE80211BE */
|
|
params.flags |= WPA_STA_WMM;
|
|
params.flags_mask |= WPA_STA_AUTHENTICATED;
|
|
if (conf->security == MESH_CONF_SEC_NONE) {
|
|
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
|
|
index 226b1c9..e030f79 100644
|
|
--- a/wpa_supplicant/wpa_supplicant.c
|
|
+++ b/wpa_supplicant/wpa_supplicant.c
|
|
@@ -2904,6 +2904,27 @@ skip_to_6ghz:
|
|
freq->eht_enabled = 0;
|
|
}
|
|
#endif /* CONFIG_EHT_OVERRIDES */
|
|
+ freq->ru_punct_bitmap = ssid->ru_punct_bitmap;
|
|
+ freq->ru_punct_ofdma = 0; /* Default to disabled for mesh. */
|
|
+
|
|
+ if (ssid->ru_punct_bitmap && wpa_s->drv_capa_known) {
|
|
+ switch (chwidth) {
|
|
+ case CHANWIDTH_320MHZ:
|
|
+ break;
|
|
+ case CHANWIDTH_160MHZ:
|
|
+ if (wpa_s->ru_punct_supp_bw == CHANWIDTH_320MHZ)
|
|
+ freq->ru_punct_bitmap = 0;
|
|
+ break;
|
|
+ case CHANWIDTH_80MHZ:
|
|
+ if ((wpa_s->ru_punct_supp_bw == CHANWIDTH_160MHZ) ||
|
|
+ (wpa_s->ru_punct_supp_bw == CHANWIDTH_320MHZ))
|
|
+ freq->ru_punct_bitmap = 0;
|
|
+ break;
|
|
+ default:
|
|
+ freq->ru_punct_bitmap = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
if (hostapd_set_freq_params(&vht_freq, mode->mode, freq->freq,
|
|
freq->channel, ssid->enable_edmg,
|
|
ssid->edmg_channel, freq->ht_enabled,
|
|
@@ -2918,8 +2939,8 @@ skip_to_6ghz:
|
|
|
|
*freq = vht_freq;
|
|
|
|
- wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d",
|
|
- freq->center_freq1, freq->center_freq2, freq->bandwidth);
|
|
+ wpa_printf(MSG_DEBUG, "IBSS: VHT setup freq cf1 %d, cf2 %d, bw %d ru_punct_bitmap 0x%x",
|
|
+ freq->center_freq1, freq->center_freq2, freq->bandwidth, freq->ru_punct_bitmap);
|
|
}
|
|
|
|
|
|
@@ -6913,6 +6934,7 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
|
|
wpa_s->num_multichan_concurrent =
|
|
capa.num_multichan_concurrent;
|
|
wpa_s->wmm_ac_supported = capa.wmm_ac_supported;
|
|
+ wpa_s->ru_punct_supp_bw = capa.ru_punct_supp_bw;
|
|
|
|
if (capa.mac_addr_rand_scan_supported)
|
|
wpa_s->mac_addr_rand_supported |= MAC_ADDR_RAND_SCAN;
|
|
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
|
|
index 162e81d..325a19d 100644
|
|
--- a/wpa_supplicant/wpa_supplicant.conf
|
|
+++ b/wpa_supplicant/wpa_supplicant.conf
|
|
@@ -1704,6 +1704,13 @@ fast_reauth=1
|
|
#Set 1 to enable 160MHz in Mesh mode
|
|
#enable_160mhz_bw=1
|
|
|
|
+# RU puncturing bitmap (16 bits) where each bit corresponds to
|
|
+# a 20 MHz channel in the given bandwidth, bit 0 corresponding to the channel
|
|
+# with lowest frequency.
|
|
+# Bit set to 1 indicates that the channel is punctured, otherwise active.
|
|
+# Default value is 0 indicating that no channel is punctured.
|
|
+#ru_punct_bitmap=4
|
|
+
|
|
# Example blocks:
|
|
|
|
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
|
|
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
|
|
index 7888c3f..f642c68 100644
|
|
--- a/wpa_supplicant/wpa_supplicant_i.h
|
|
+++ b/wpa_supplicant/wpa_supplicant_i.h
|
|
@@ -1521,6 +1521,8 @@ struct wpa_supplicant {
|
|
unsigned int enable_dscp_policy_capa:1;
|
|
unsigned int connection_dscp:1;
|
|
unsigned int wait_for_dscp_req:1;
|
|
+ /* Minimum bandwidth the driver supports RU puncturing */
|
|
+ u8 ru_punct_supp_bw;
|
|
};
|
|
|
|
|
|
--
|
|
2.7.4
|
|
|