mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
wifi-ax: update hostapd to latest 11.5-cs
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
26
feeds/wifi-ax/hostapd/patches/900-compat.patch
Normal file
26
feeds/wifi-ax/hostapd/patches/900-compat.patch
Normal file
@@ -0,0 +1,26 @@
|
||||
Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h
|
||||
+++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#define WPA_SUPPLICANT_DRIVER_VERSION 4
|
||||
|
||||
+#include "nl80211_copy.h"
|
||||
#include "ap/sta_info.h"
|
||||
#include "common/defs.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
Index: hostapd-2021-02-20-59e9794c/src/ap/ubus.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ubus.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/ubus.c
|
||||
@@ -882,7 +882,8 @@ hostapd_switch_chan(struct ubus_context
|
||||
chwidth, seg0, seg1,
|
||||
iconf->vht_capab,
|
||||
mode ? &mode->he_capab[IEEE80211_MODE_AP] :
|
||||
- NULL);
|
||||
+ NULL,
|
||||
+ iconf->he_6ghz_reg_pwr_type);
|
||||
|
||||
for (i = 0; i < hapd->iface->num_bss; i++) {
|
||||
struct hostapd_data *bss = hapd->iface->bss[i];
|
||||
@@ -2,7 +2,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
|
||||
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
@@ -2458,6 +2458,8 @@ static int hostapd_config_fill(struct ho
|
||||
@@ -2460,6 +2460,8 @@ static int hostapd_config_fill(struct ho
|
||||
conf->ieee80211d = atoi(pos);
|
||||
} else if (os_strcmp(buf, "ieee80211h") == 0) {
|
||||
conf->ieee80211h = atoi(pos);
|
||||
@@ -27,16 +27,17 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/dfs.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/dfs.c
|
||||
@@ -18,6 +18,8 @@
|
||||
@@ -18,7 +18,8 @@
|
||||
#include "drivers/driver.h"
|
||||
#include "dfs.h"
|
||||
#include "crypto/crypto.h"
|
||||
-
|
||||
+#include "beacon.h"
|
||||
+#include "eloop.h"
|
||||
|
||||
|
||||
static int dfs_get_used_n_chans(struct hostapd_iface *iface, int *seg1)
|
||||
@@ -1036,6 +1038,73 @@ static int hostapd_dfs_start_channel_swi
|
||||
{
|
||||
@@ -1036,6 +1037,73 @@ static int hostapd_dfs_start_channel_swi
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -110,7 +111,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
|
||||
|
||||
static int hostapd_dfs_start_channel_switch(struct hostapd_iface *iface)
|
||||
{
|
||||
@@ -1071,6 +1140,9 @@ static int hostapd_dfs_start_channel_swi
|
||||
@@ -1071,6 +1139,9 @@ static int hostapd_dfs_start_channel_swi
|
||||
if (iface->dfs_domain == HOSTAPD_DFS_REGION_ETSI)
|
||||
skip_radar = 0;
|
||||
|
||||
@@ -120,7 +121,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/dfs.c
|
||||
/* Perform channel switch/CSA */
|
||||
channel = dfs_get_valid_channel(iface, &secondary_channel,
|
||||
&oper_centr_freq_seg0_idx,
|
||||
@@ -1208,6 +1280,12 @@ int hostapd_dfs_radar_detected(struct ho
|
||||
@@ -1208,6 +1279,12 @@ int hostapd_dfs_radar_detected(struct ho
|
||||
if (!res)
|
||||
return 0;
|
||||
|
||||
@@ -153,7 +154,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
@@ -2866,6 +2866,7 @@ int hostapd_disable_iface(struct hostapd
|
||||
@@ -2884,6 +2884,7 @@ int hostapd_disable_iface(struct hostapd
|
||||
hostapd_cleanup_cs_params(hapd_iface->bss[j]);
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
||||
|
||||
@@ -22,7 +22,18 @@ Signed-off-by: Karthikeyan Kathirvel <kathirve@codeaurora.org>
|
||||
|
||||
--- a/src/ap/wpa_auth.c
|
||||
+++ b/src/ap/wpa_auth.c
|
||||
@@ -4454,12 +4454,13 @@ void wpa_gtk_rekey(struct wpa_authentica
|
||||
@@ -75,8 +75,10 @@ static const u32 eapol_key_timeout_no_retrans = 4000; /* ms */
|
||||
|
||||
/* TODO: make these configurable */
|
||||
static const int dot11RSNAConfigPMKLifetime = 43200;
|
||||
+#ifdef CONFIG_CTRL_IFACE_MIB
|
||||
static const int dot11RSNAConfigPMKReauthThreshold = 70;
|
||||
static const int dot11RSNAConfigSATimeout = 60;
|
||||
+#endif
|
||||
|
||||
|
||||
static inline int wpa_auth_mic_failure_report(
|
||||
@@ -4454,12 +4456,13 @@ void wpa_gtk_rekey(struct wpa_authentica
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
From 353f9b94d5f8a9a307ae80d62cd5fb503f126563 Mon Sep 17 00:00:00 2001
|
||||
From: John Crispin <john@phrozen.org>
|
||||
Date: Wed, 3 Jun 2020 16:32:11 +0200
|
||||
Subject: [PATCH 1/7] multiple_bssid: add the config file
|
||||
|
||||
This patch adds a new config option to enable this feature.
|
||||
|
||||
Signed-off-by: John Crispin <john@phrozen.org>
|
||||
|
||||
---
|
||||
hostapd/config_file.c | 2 ++
|
||||
src/ap/ap_config.h | 2 ++
|
||||
2 files changed, 4 insertions(+)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
|
||||
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
@@ -4681,6 +4681,8 @@ static int hostapd_config_fill(struct ho
|
||||
@@ -4683,6 +4683,8 @@ static int hostapd_config_fill(struct ho
|
||||
}
|
||||
bss->mka_psk_set |= MKA_PSK_SET_CKN;
|
||||
#endif /* CONFIG_MACSEC */
|
||||
@@ -28,7 +42,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
@@ -87,6 +87,26 @@ int hostapd_for_each_interface(struct ha
|
||||
@@ -89,6 +89,26 @@ int hostapd_for_each_interface(struct ha
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +69,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
void hostapd_reconfig_encryption(struct hostapd_data *hapd)
|
||||
{
|
||||
if (hapd->wpa_auth)
|
||||
@@ -1206,6 +1226,13 @@ static int hostapd_setup_bss(struct host
|
||||
@@ -1208,6 +1228,13 @@ static int hostapd_setup_bss(struct host
|
||||
|
||||
if (!first || first == -1) {
|
||||
u8 *addr = hapd->own_addr;
|
||||
@@ -69,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
|
||||
if (!is_zero_ether_addr(conf->bssid)) {
|
||||
/* Allocate the configured BSSID. */
|
||||
@@ -1233,7 +1260,7 @@ static int hostapd_setup_bss(struct host
|
||||
@@ -1235,7 +1262,7 @@ static int hostapd_setup_bss(struct host
|
||||
conf->iface, addr, hapd,
|
||||
&hapd->drv_priv, force_ifname, if_addr,
|
||||
conf->bridge[0] ? conf->bridge : NULL,
|
||||
@@ -82,7 +96,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
|
||||
@@ -603,6 +603,8 @@ struct hostapd_iface {
|
||||
@@ -621,6 +621,8 @@ struct hostapd_iface {
|
||||
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
|
||||
int (*cb)(struct hostapd_iface *iface,
|
||||
void *ctx), void *ctx);
|
||||
@@ -104,7 +118,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ap_drv_ops.c
|
||||
}
|
||||
|
||||
|
||||
@@ -497,13 +497,15 @@ int hostapd_set_ssid(struct hostapd_data
|
||||
@@ -495,13 +495,15 @@ int hostapd_set_ssid(struct hostapd_data
|
||||
int hostapd_if_add(struct hostapd_data *hapd, enum wpa_driver_if_type type,
|
||||
const char *ifname, const u8 *addr, void *bss_ctx,
|
||||
void **drv_priv, char *force_ifname, u8 *if_addr,
|
||||
@@ -545,7 +559,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/ieee802_11.c
|
||||
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
|
||||
HOSTAPD_LEVEL_INFO, "No room for more AIDs");
|
||||
resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||
@@ -6970,4 +6975,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct
|
||||
@@ -6969,4 +6974,117 @@ u8 * hostapd_eid_wb_chsw_wrapper(struct
|
||||
return eid;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,28 @@
|
||||
From 38823a3ae9fd084ee5822dfb228e109656187e85 Mon Sep 17 00:00:00 2001
|
||||
From: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
Date: Tue, 8 Sep 2020 14:24:37 -0700
|
||||
Subject: [PATCH] hostapd: Enable 6ghz support in 11s mesh
|
||||
|
||||
Enable 6ghz frequencies support in 11s mesh.
|
||||
Configurations are similar to 5G/2G bands.
|
||||
example:
|
||||
network={
|
||||
ssid="pr6gmesh123"
|
||||
key_mgmt=SAE
|
||||
mode=5
|
||||
frequency=6195
|
||||
psk="1234567890"
|
||||
}
|
||||
|
||||
Also, fix assigning secondary channel for only bandwidth greater
|
||||
than 20 MHz.
|
||||
|
||||
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
|
||||
---
|
||||
wpa_supplicant/mesh.c | 6 ++++
|
||||
wpa_supplicant/wpa_supplicant.c | 54 +++++++++++++++++++++------------
|
||||
2 files changed, 41 insertions(+), 21 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/mesh.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/mesh.c
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
From 01845904f9a5cdbd60f6aabdcfc0a8b191d90785 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <ppranees@codeaurora.org>
|
||||
Date: Sun, 27 Sep 2020 00:21:21 +0530
|
||||
Subject: [PATCH] hostapd: Enable 160MHz support for 6G in 11s mesh
|
||||
|
||||
Since 6G has no dfs channel, enable 6G 160MHz bandwidth
|
||||
as a default configuration for 11s mesh.
|
||||
|
||||
example:
|
||||
network={
|
||||
ssid="6gmesh160"
|
||||
key_mgmt=SAE
|
||||
mode=5
|
||||
frequency=6275
|
||||
psk="1234567890"
|
||||
}
|
||||
|
||||
Signed-off-by: P Praneesh <ppranees@codeaurora.org>
|
||||
---
|
||||
wpa_supplicant/wpa_supplicant.c | 15 ++++++++++++++-
|
||||
1 file changed, 14 insertions(+), 1 deletion(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -59,7 +81,7 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
seg0 = freq->channel + 6;
|
||||
seg1 = 0;
|
||||
|
||||
+ /* setup center_freq1 for 6G 160MHz */
|
||||
+/* setup center_freq1 for 6G 160MHz */
|
||||
+ if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
|
||||
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
|
||||
+
|
||||
|
||||
@@ -1,8 +1,29 @@
|
||||
From baf3a982caee59ec08602a9e981d6742abc4fc7b Mon Sep 17 00:00:00 2001
|
||||
From: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
Date: Mon, 28 Sep 2020 23:21:43 +0530
|
||||
Subject: [PATCH] hostapd: Add support to change bss color by user
|
||||
|
||||
|
||||
hostpad_cli command is added to change bss color in runtime,
|
||||
for testing purpose. hostapd_cli status can be used to check
|
||||
updated color.
|
||||
|
||||
Usage: hostapd_cli color_change <color>
|
||||
|
||||
Signed-off-by: Lavanya Suresh <lavaks@codeaurora.org>
|
||||
---
|
||||
hostapd/ctrl_iface.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
hostapd/hostapd_cli.c | 23 +++++++++++++++++++++++
|
||||
src/ap/ctrl_iface_ap.c | 6 ++++--
|
||||
src/ap/hostapd.c | 4 ++--
|
||||
src/ap/hostapd.h | 3 ++-
|
||||
5 files changed, 76 insertions(+), 5 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/hostapd/ctrl_iface.c
|
||||
+++ hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
|
||||
@@ -2673,6 +2673,59 @@ static int hostapd_ctrl_check_freq_param
|
||||
@@ -2679,6 +2679,59 @@ static int hostapd_ctrl_check_freq_param
|
||||
}
|
||||
#endif /* NEED_AP_MLME */
|
||||
|
||||
@@ -62,7 +83,7 @@ Index: hostapd-2021-02-20-59e9794c/hostapd/ctrl_iface.c
|
||||
|
||||
static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
|
||||
char *pos)
|
||||
@@ -3682,6 +3735,9 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
@@ -3688,6 +3741,9 @@ static int hostapd_ctrl_iface_receive_pr
|
||||
} else if (os_strncmp(buf, "CHAN_SWITCH ", 12) == 0) {
|
||||
if (hostapd_ctrl_iface_chan_switch(hapd->iface, buf + 12))
|
||||
reply_len = -1;
|
||||
@@ -136,7 +157,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
@@ -3443,7 +3443,7 @@ int hostapd_csa_in_progress(struct hosta
|
||||
@@ -3461,7 +3461,7 @@ int hostapd_csa_in_progress(struct hosta
|
||||
|
||||
#ifdef NEED_AP_MLME
|
||||
|
||||
@@ -145,7 +166,7 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.c
|
||||
{
|
||||
os_free(beacon->head);
|
||||
beacon->head = NULL;
|
||||
@@ -3833,7 +3833,7 @@ void hostapd_cleanup_cca_params(struct h
|
||||
@@ -3851,7 +3851,7 @@ void hostapd_cleanup_cca_params(struct h
|
||||
}
|
||||
|
||||
|
||||
@@ -158,17 +179,12 @@ Index: hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/hostapd.h
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/hostapd.h
|
||||
@@ -661,11 +661,13 @@ void hostapd_periodic_iface(struct hosta
|
||||
int hostapd_owe_trans_get_info(struct hostapd_data *hapd);
|
||||
void hostapd_ocv_check_csa_sa_query(void *eloop_ctx, void *timeout_ctx);
|
||||
int hostapd_check_max_sta(struct hostapd_data *hapd);
|
||||
@@ -649,6 +649,8 @@ void hostapd_interface_free(struct hosta
|
||||
struct hostapd_iface * hostapd_alloc_iface(void);
|
||||
struct hostapd_iface * hostapd_init(struct hapd_interfaces *interfaces,
|
||||
const char *config_file);
|
||||
+void free_beacon_data(struct beacon_data *beacon);
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211AX
|
||||
void hostapd_switch_color(struct hostapd_data *hapd, u64 bitmap);
|
||||
void hostapd_cleanup_cca_params(struct hostapd_data *hapd);
|
||||
+int hostapd_fill_cca_settings(struct hostapd_data *hapd, struct cca_settings *settings);
|
||||
#endif
|
||||
|
||||
/* utils.c */
|
||||
struct hostapd_iface *
|
||||
hostapd_interface_init_bss(struct hapd_interfaces *interfaces, const char *phy,
|
||||
const char *config_fname, int debug);
|
||||
|
||||
@@ -15,11 +15,9 @@ Signed-off-by: Aloka Dixit <alokad@codeaurora.org>
|
||||
src/ap/ieee802_11.c | 106 +++++++++++++++++++++++++++++++++-----------
|
||||
2 files changed, 85 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
|
||||
index eda20fc0d9df..74ac8584ab5e 100644
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -485,8 +485,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
@@ -485,8 +485,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
||||
buflen += hostapd_eid_multiple_bssid_len(hapd, req_bss, 0,
|
||||
known_bssids,
|
||||
known_bssids_len);
|
||||
@@ -29,7 +27,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
|
||||
|
||||
resp = os_zalloc(buflen);
|
||||
if (resp == NULL)
|
||||
@@ -652,8 +651,7 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
|
||||
@@ -667,8 +666,7 @@ static u8 * hostapd_gen_probe_resp(struc
|
||||
pos = hostapd_eid_mbo(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
pos = hostapd_eid_owe_trans(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
pos = hostapd_eid_dpp_cc(hapd, pos, (u8 *) resp + buflen - pos);
|
||||
@@ -39,7 +37,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
|
||||
|
||||
if (hapd->conf->vendor_elements) {
|
||||
os_memcpy(pos, wpabuf_head(hapd->conf->vendor_elements),
|
||||
@@ -1532,8 +1530,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||
@@ -1527,8 +1525,7 @@ int ieee802_11_build_ap_params(struct ho
|
||||
tail_len += hostapd_mbo_ie_len(hapd);
|
||||
tail_len += hostapd_eid_owe_trans_len(hapd);
|
||||
tail_len += hostapd_eid_dpp_cc_len(hapd);
|
||||
@@ -49,7 +47,7 @@ index eda20fc0d9df..74ac8584ab5e 100644
|
||||
|
||||
tailpos = tail = os_malloc(tail_len);
|
||||
if (head == NULL || tail == NULL) {
|
||||
@@ -1711,8 +1708,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
|
||||
@@ -1713,8 +1710,7 @@ int ieee802_11_build_ap_params(struct ho
|
||||
tailpos = hostapd_eid_owe_trans(hapd, tailpos,
|
||||
tail + tail_len - tailpos);
|
||||
tailpos = hostapd_eid_dpp_cc(hapd, tailpos, tail + tail_len - tailpos);
|
||||
@@ -59,11 +57,9 @@ index eda20fc0d9df..74ac8584ab5e 100644
|
||||
|
||||
if (hapd->conf->vendor_elements) {
|
||||
os_memcpy(tailpos, wpabuf_head(hapd->conf->vendor_elements),
|
||||
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
|
||||
index 97c5b42a7528..488f02f58f63 100644
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -5989,6 +5989,7 @@ size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
||||
@@ -7308,6 +7308,7 @@ size_t hostapd_eid_rnr_iface_len(struct
|
||||
{
|
||||
size_t len = 0;
|
||||
int i;
|
||||
@@ -71,7 +67,7 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
for (i = 0; i < hapd->iface->num_bss; i++) {
|
||||
if (hapd->iface->bss[i] == reporting_hapd ||
|
||||
hapd->iface->bss[i]->conf->ignore_broadcast_ssid)
|
||||
@@ -5999,29 +6000,69 @@ size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
||||
@@ -7318,29 +7319,69 @@ size_t hostapd_eid_rnr_iface_len(struct
|
||||
}
|
||||
|
||||
|
||||
@@ -89,7 +85,7 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
+ for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
+ iface = hapd->iface->interfaces->iface[i];
|
||||
+
|
||||
+ if (iface == hapd->iface || !iface->conf->he_co_locate)
|
||||
+ if (!iface || iface == hapd->iface || !iface->conf->he_co_locate)
|
||||
+ continue;
|
||||
+
|
||||
len += (TBTT_HEADER_LENGTH +
|
||||
@@ -99,7 +95,10 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
+ return len;
|
||||
+}
|
||||
+
|
||||
+
|
||||
|
||||
- if (type != WLAN_FC_STYPE_ACTION) {
|
||||
- for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
- struct hostapd_iface *iface = hapd->iface->interfaces->iface[i];
|
||||
+static bool is_6ghz_colocated(struct hostapd_data *hapd)
|
||||
+{
|
||||
+ u8 i;
|
||||
@@ -124,16 +123,13 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
+ return false;
|
||||
+}
|
||||
|
||||
- if (type != WLAN_FC_STYPE_ACTION) {
|
||||
- for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
- struct hostapd_iface *iface = hapd->iface->interfaces->iface[i];
|
||||
|
||||
- if (iface == hapd->iface || !iface->conf->he_co_locate)
|
||||
- continue;
|
||||
|
||||
+size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
||||
+{
|
||||
+ size_t len = 0;
|
||||
|
||||
+
|
||||
+ if (hapd->conf->rnr_beacon) {
|
||||
+ if (hapd->iface->num_bss > 1)
|
||||
len += (TBTT_HEADER_LENGTH +
|
||||
@@ -153,7 +149,7 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
|
||||
if (len)
|
||||
len += 2; /* Element ID and length */
|
||||
@@ -6096,6 +6137,27 @@ static u8 *hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
||||
@@ -7415,6 +7456,27 @@ static u8 *hostapd_eid_rnr_iface(struct
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +165,7 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
+ for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
+ iface = hapd->iface->interfaces->iface[i];
|
||||
+
|
||||
+ if (iface == hapd->iface || !iface->conf->he_co_locate)
|
||||
+ if (!iface || iface == hapd->iface || !iface->conf->he_co_locate)
|
||||
+ continue;
|
||||
+
|
||||
+ eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid, count);
|
||||
@@ -181,7 +177,7 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
static u8 *hostapd_eid_neighbor_report_db(struct hostapd_data *hapd, u8 *eid,
|
||||
int *count)
|
||||
{
|
||||
@@ -6138,22 +6200,16 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
||||
@@ -7457,22 +7519,16 @@ u8 * hostapd_eid_rnr(struct hostapd_data
|
||||
*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
|
||||
size_offset = eid++;
|
||||
|
||||
@@ -211,6 +207,3 @@ index 97c5b42a7528..488f02f58f63 100644
|
||||
|
||||
if (!count)
|
||||
eid -= 2;
|
||||
--
|
||||
2.25.0
|
||||
|
||||
|
||||
@@ -1,8 +1,35 @@
|
||||
From a1d4da59739c2054eb46cf634320c8bd323a8069 Mon Sep 17 00:00:00 2001
|
||||
From: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
||||
Date: Tue, 12 Jan 2021 18:12:37 +0530
|
||||
Subject: [PATCH] hostapd: Add support for beacon tx mode
|
||||
|
||||
User can configure the beacon tx mode while bring-up the
|
||||
AP via hostapd configuration and while bring-up MESH via
|
||||
wpa_supplicant configuration.
|
||||
|
||||
Use the below configuration in the hostapd/wpa_supplicant
|
||||
to configure the beacon tx mode.
|
||||
|
||||
"beacon_tx_mode=N", where N = 1 for STAGGERED beacon mode
|
||||
and N = 2 for BURST beacon mode.
|
||||
|
||||
Signed-off-by: Maharaja Kennadyrajan <mkenna@codeaurora.org>
|
||||
---
|
||||
hostapd/config_file.c | 9 +++++++++
|
||||
src/ap/ap_config.c | 2 ++
|
||||
src/ap/ap_config.h | 1 +
|
||||
src/ap/beacon.c | 2 ++
|
||||
src/ap/ctrl_iface_ap.c | 6 ++++--
|
||||
src/drivers/driver.h | 5 +++++
|
||||
src/drivers/driver_nl80211.c | 16 +++++++++++++++-
|
||||
src/drivers/nl80211_copy.h | 4 ++++
|
||||
8 files changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
|
||||
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
@@ -4590,6 +4590,15 @@ static int hostapd_config_fill(struct ho
|
||||
@@ -4592,6 +4592,15 @@ static int hostapd_config_fill(struct ho
|
||||
bss->disable_11ac = !!atoi(pos);
|
||||
} else if (os_strcmp(buf, "disable_11ax") == 0) {
|
||||
bss->disable_11ax = !!atoi(pos);
|
||||
|
||||
@@ -1,3 +1,18 @@
|
||||
From b6bb46ef161e1c3890f517fdb04f081926fc1a08 Mon Sep 17 00:00:00 2001
|
||||
From: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
Date: Tue, 23 Mar 2021 19:57:43 +0530
|
||||
Subject: [PATCH] hostapd: update missing 5.9GHz channels
|
||||
|
||||
Update channel 165 and 173 in allowed channel.
|
||||
This fixes below upstream commit,
|
||||
833cdbe - "Add support for new 5 GHz channels 173 and 177"
|
||||
|
||||
Signed-off-by: Seevalamuthu Mariappan <seevalam@codeaurora.org>
|
||||
---
|
||||
src/common/hw_features_common.c | 2 +-
|
||||
wpa_supplicant/wpa_supplicant.c | 4 ++--
|
||||
2 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/src/common/hw_features_common.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/common/hw_features_common.c
|
||||
@@ -26,3 +41,42 @@ Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
6035, 6115, 6195, 6275, 6355, 6435, 6515,
|
||||
6595, 6675, 6755, 6835, 6915, 6995 };
|
||||
unsigned int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
Index: hostapd-2021-02-20-59e9794c/src/ap/acs.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/acs.c
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/acs.c
|
||||
@@ -369,9 +369,10 @@ acs_survey_chan_interference_factor(stru
|
||||
static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
|
||||
{
|
||||
const int allowed[] = { 5180, 5220, 5260, 5300, 5500, 5540, 5580, 5620, 5660, 5745,
|
||||
- 5785, 5955, 5995, 6035, 6075, 6115, 6155, 6195, 6235, 6275,
|
||||
- 6315, 6355, 6395, 6435, 6475, 6515, 6555, 6595, 6635, 6675,
|
||||
- 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995, 7035, 7075 };
|
||||
+ 5785, 5825, 5865, 5955, 5995, 6035, 6075, 6115, 6155, 6195,
|
||||
+ 6235, 6275, 6315, 6355, 6395, 6435, 6475, 6515, 6555, 6595,
|
||||
+ 6635, 6675, 6715, 6755, 6795, 6835, 6875, 6915, 6955, 6995,
|
||||
+ 7035, 7075 };
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allowed); i++)
|
||||
@@ -384,9 +385,8 @@ static int acs_usable_bw40_chan(const st
|
||||
|
||||
static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
|
||||
{
|
||||
- const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 6035, 6115, 6195,
|
||||
- 6275, 6355, 6435, 6515, 6595, 6675, 6755, 6835, 6915,
|
||||
- 6995 };
|
||||
+ const int allowed[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 6035, 6115, 6195,
|
||||
+ 6275, 6355, 6435, 6515, 6595, 6675, 6755, 6835, 6915, 6995 };
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allowed); i++)
|
||||
@@ -399,7 +399,7 @@ static int acs_usable_bw80_chan(const st
|
||||
|
||||
static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
|
||||
{
|
||||
- const int allowed[] = { 5180, 5500, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
+ const int allowed[] = { 5180, 5500, 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(allowed); i++)
|
||||
|
||||
@@ -1,459 +0,0 @@
|
||||
From 1c3438fec4bad13a676617915ff56af54e7b4542 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Sat, 2 Apr 2022 13:12:43 +0300
|
||||
Subject: [PATCH] RADIUS ACL/PSK check during 4-way handshake
|
||||
|
||||
Add an alternative sequence for performing the RADIUS ACL check and PSK
|
||||
fetch. The previously used (macaddr_acl=2, wpa_psk_radius=2) combination
|
||||
does this during IEEE 802.11 Authentication frame exchange while the new
|
||||
option (wpa_psk_radius=3) does this during the 4-way handshake. This
|
||||
allows some more information to be provided to the RADIUS authentication
|
||||
server.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
hostapd/config_file.c | 3 +-
|
||||
hostapd/hostapd.conf | 5 ++-
|
||||
src/ap/ap_config.c | 4 ++-
|
||||
src/ap/ap_config.h | 5 +--
|
||||
src/ap/ieee802_11.c | 5 ++-
|
||||
src/ap/ieee802_11.h | 2 ++
|
||||
src/ap/ieee802_11_auth.c | 76 ++++++++++++++++++++++++++++++++++++----
|
||||
src/ap/ieee802_11_auth.h | 5 ++-
|
||||
src/ap/wpa_auth.c | 51 ++++++++++++++++++++++++++-
|
||||
src/ap/wpa_auth.h | 9 ++++-
|
||||
src/ap/wpa_auth_glue.c | 25 ++++++++++++-
|
||||
src/ap/wpa_auth_i.h | 1 +
|
||||
12 files changed, 172 insertions(+), 19 deletions(-)
|
||||
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -2858,7 +2858,8 @@ static int hostapd_config_fill(struct ho
|
||||
bss->wpa_psk_radius = atoi(pos);
|
||||
if (bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
|
||||
bss->wpa_psk_radius != PSK_RADIUS_ACCEPTED &&
|
||||
- bss->wpa_psk_radius != PSK_RADIUS_REQUIRED) {
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_REQUIRED &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"Line %d: unknown wpa_psk_radius %d",
|
||||
line, bss->wpa_psk_radius);
|
||||
--- a/hostapd/hostapd.conf
|
||||
+++ b/hostapd/hostapd.conf
|
||||
@@ -1635,12 +1635,15 @@ own_ip_addr=127.0.0.1
|
||||
#wpa_psk_file=/etc/hostapd.wpa_psk
|
||||
|
||||
# Optionally, WPA passphrase can be received from RADIUS authentication server
|
||||
-# This requires macaddr_acl to be set to 2 (RADIUS)
|
||||
+# This requires macaddr_acl to be set to 2 (RADIUS) for wpa_psk_radius values
|
||||
+# 1 and 2.
|
||||
# 0 = disabled (default)
|
||||
# 1 = optional; use default passphrase/psk if RADIUS server does not include
|
||||
# Tunnel-Password
|
||||
# 2 = required; reject authentication if RADIUS server does not include
|
||||
# Tunnel-Password
|
||||
+# 3 = ask RADIUS server during 4-way handshake if there is no locally
|
||||
+# configured PSK/passphrase for the STA
|
||||
#wpa_psk_radius=0
|
||||
|
||||
# Set of accepted key management algorithms (WPA-PSK, WPA-EAP, or both). The
|
||||
--- a/src/ap/ap_config.c
|
||||
+++ b/src/ap/ap_config.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / Configuration helper functions
|
||||
- * Copyright (c) 2003-2014, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -1245,6 +1245,7 @@ static int hostapd_config_check_bss(stru
|
||||
|
||||
if (full_config && bss->wpa &&
|
||||
bss->wpa_psk_radius != PSK_RADIUS_IGNORED &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
|
||||
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH) {
|
||||
wpa_printf(MSG_ERROR, "WPA-PSK using RADIUS enabled, but no "
|
||||
"RADIUS checking (macaddr_acl=2) enabled.");
|
||||
@@ -1254,6 +1255,7 @@ static int hostapd_config_check_bss(stru
|
||||
if (full_config && bss->wpa && (bss->wpa_key_mgmt & WPA_KEY_MGMT_PSK) &&
|
||||
bss->ssid.wpa_psk == NULL && bss->ssid.wpa_passphrase == NULL &&
|
||||
bss->ssid.wpa_psk_file == NULL &&
|
||||
+ bss->wpa_psk_radius != PSK_RADIUS_DURING_4WAY_HS &&
|
||||
(bss->wpa_psk_radius != PSK_RADIUS_REQUIRED ||
|
||||
bss->macaddr_acl != USE_EXTERNAL_RADIUS_AUTH)) {
|
||||
wpa_printf(MSG_ERROR, "WPA-PSK enabled, but PSK or passphrase "
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / Configuration definitions and helpers functions
|
||||
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -367,7 +367,8 @@ struct hostapd_bss_config {
|
||||
enum {
|
||||
PSK_RADIUS_IGNORED = 0,
|
||||
PSK_RADIUS_ACCEPTED = 1,
|
||||
- PSK_RADIUS_REQUIRED = 2
|
||||
+ PSK_RADIUS_REQUIRED = 2,
|
||||
+ PSK_RADIUS_DURING_4WAY_HS = 3,
|
||||
} wpa_psk_radius;
|
||||
int wpa_pairwise;
|
||||
int group_cipher; /* wpa_group value override from configuation */
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -2348,9 +2348,8 @@ static int ieee802_11_allowed_address(st
|
||||
}
|
||||
|
||||
|
||||
-static int
|
||||
-ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
- int res, struct radius_sta *info)
|
||||
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
+ int res, struct radius_sta *info)
|
||||
{
|
||||
u32 session_timeout = info->session_timeout;
|
||||
u32 acct_interim_interval = info->acct_interim_interval;
|
||||
--- a/src/ap/ieee802_11.h
|
||||
+++ b/src/ap/ieee802_11.h
|
||||
@@ -220,4 +220,6 @@ void auth_sae_process_commit(void *eloop
|
||||
u8 * hostapd_eid_rsnxe(struct hostapd_data *hapd, u8 *eid, size_t len);
|
||||
u8 * hostapd_get_rsne(struct hostapd_data *hapd, u8 *pos, size_t len);
|
||||
u8 * hostapd_get_rsnxe(struct hostapd_data *hapd, u8 *pos, size_t len);
|
||||
+int ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
|
||||
+ int res, struct radius_sta *info);
|
||||
#endif /* IEEE802_11_H */
|
||||
--- a/src/ap/ieee802_11_auth.c
|
||||
+++ b/src/ap/ieee802_11_auth.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
- * Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -20,6 +20,8 @@
|
||||
#include "hostapd.h"
|
||||
#include "ap_config.h"
|
||||
#include "ap_drv_ops.h"
|
||||
+#include "sta_info.h"
|
||||
+#include "wpa_auth.h"
|
||||
#include "ieee802_11.h"
|
||||
#include "ieee802_1x.h"
|
||||
#include "ieee802_11_auth.h"
|
||||
@@ -43,6 +45,8 @@ struct hostapd_acl_query_data {
|
||||
u8 *auth_msg; /* IEEE 802.11 authentication frame from station */
|
||||
size_t auth_msg_len;
|
||||
struct hostapd_acl_query_data *next;
|
||||
+ bool radius_psk;
|
||||
+ int akm;
|
||||
};
|
||||
|
||||
|
||||
@@ -153,6 +157,13 @@ static int hostapd_radius_acl_query(stru
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (query->akm &&
|
||||
+ !radius_msg_add_attr_int32(msg, RADIUS_ATTR_WLAN_AKM_SUITE,
|
||||
+ wpa_akm_to_suite(query->akm))) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add WLAN-AKM-Suite");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
|
||||
goto fail;
|
||||
return 0;
|
||||
@@ -566,17 +577,40 @@ hostapd_acl_recv_radius(struct radius_ms
|
||||
cache->next = hapd->acl_cache;
|
||||
hapd->acl_cache = cache;
|
||||
|
||||
+ if (query->radius_psk) {
|
||||
+ struct sta_info *sta;
|
||||
+ bool success = cache->accepted == HOSTAPD_ACL_ACCEPT;
|
||||
+
|
||||
+ sta = ap_get_sta(hapd, query->addr);
|
||||
+ if (!sta || !sta->wpa_sm) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "No STA/SM entry found for the RADIUS PSK response");
|
||||
+ goto done;
|
||||
+ }
|
||||
+#ifdef NEED_AP_MLME
|
||||
+ if (success &&
|
||||
+ (ieee802_11_set_radius_info(hapd, sta, cache->accepted,
|
||||
+ info) < 0 ||
|
||||
+ ap_sta_bind_vlan(hapd, sta) < 0))
|
||||
+ success = false;
|
||||
+#endif /* NEED_AP_MLME */
|
||||
+ wpa_auth_sta_radius_psk_resp(sta->wpa_sm, success);
|
||||
+ } else {
|
||||
#ifdef CONFIG_DRIVER_RADIUS_ACL
|
||||
- hostapd_drv_set_radius_acl_auth(hapd, query->addr, cache->accepted,
|
||||
- info->session_timeout);
|
||||
+ hostapd_drv_set_radius_acl_auth(hapd, query->addr,
|
||||
+ cache->accepted,
|
||||
+ info->session_timeout);
|
||||
#else /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
#ifdef NEED_AP_MLME
|
||||
- /* Re-send original authentication frame for 802.11 processing */
|
||||
- wpa_printf(MSG_DEBUG, "Re-sending authentication frame after "
|
||||
- "successful RADIUS ACL query");
|
||||
- ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL);
|
||||
+ /* Re-send original authentication frame for 802.11 processing
|
||||
+ */
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Re-sending authentication frame after successful RADIUS ACL query");
|
||||
+ ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len,
|
||||
+ NULL);
|
||||
#endif /* NEED_AP_MLME */
|
||||
#endif /* CONFIG_DRIVER_RADIUS_ACL */
|
||||
+ }
|
||||
|
||||
done:
|
||||
if (prev == NULL)
|
||||
@@ -658,3 +692,31 @@ void hostapd_free_psk_list(struct hostap
|
||||
os_free(prev);
|
||||
}
|
||||
}
|
||||
+
|
||||
+
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
+ int key_mgmt, const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len)
|
||||
+{
|
||||
+ struct hostapd_acl_query_data *query;
|
||||
+
|
||||
+ query = os_zalloc(sizeof(*query));
|
||||
+ if (!query)
|
||||
+ return;
|
||||
+
|
||||
+ query->radius_psk = true;
|
||||
+ query->akm = key_mgmt;
|
||||
+ os_get_reltime(&query->timestamp);
|
||||
+ os_memcpy(query->addr, addr, ETH_ALEN);
|
||||
+ if (hostapd_radius_acl_query(hapd, addr, query)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Failed to send Access-Request for RADIUS PSK/ACL query");
|
||||
+ hostapd_acl_query_free(query);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ query->next = hapd->acl_queries;
|
||||
+ hapd->acl_queries = query;
|
||||
+}
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
--- a/src/ap/ieee802_11_auth.h
|
||||
+++ b/src/ap/ieee802_11_auth.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / IEEE 802.11 authentication (ACL)
|
||||
- * Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2003-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -36,5 +36,8 @@ void hostapd_free_psk_list(struct hostap
|
||||
void hostapd_acl_expire(struct hostapd_data *hapd);
|
||||
void hostapd_copy_psk_list(struct hostapd_sta_wpa_psk_short **psk,
|
||||
struct hostapd_sta_wpa_psk_short *src);
|
||||
+void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
+ int key_mgmt, const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len);
|
||||
|
||||
#endif /* IEEE802_11_AUTH_H */
|
||||
--- a/src/ap/wpa_auth.c
|
||||
+++ b/src/ap/wpa_auth.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* IEEE 802.11 RSN / WPA Authenticator
|
||||
- * Copyright (c) 2004-2019, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -1465,6 +1465,12 @@ static void wpa_send_eapol_timeout(void
|
||||
struct wpa_authenticator *wpa_auth = eloop_ctx;
|
||||
struct wpa_state_machine *sm = timeout_ctx;
|
||||
|
||||
+ if (sm->waiting_radius_psk) {
|
||||
+ wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG,
|
||||
+ "Ignore EAPOL-Key timeout while waiting for RADIUS PSK");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
sm->pending_1_of_4_timeout = 0;
|
||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, "EAPOL-Key timeout");
|
||||
sm->TimeoutEvt = true;
|
||||
@@ -3003,6 +3009,19 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
||||
break;
|
||||
}
|
||||
|
||||
+ if (!ok && wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
|
||||
+ wpa_auth->conf.radius_psk && wpa_auth->cb->request_radius_psk &&
|
||||
+ !sm->waiting_radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG, "No PSK available - ask RADIUS server");
|
||||
+ wpa_auth->cb->request_radius_psk(wpa_auth->cb_ctx, sm->addr,
|
||||
+ sm->wpa_key_mgmt,
|
||||
+ sm->ANonce,
|
||||
+ sm->last_rx_eapol_key,
|
||||
+ sm->last_rx_eapol_key_len);
|
||||
+ sm->waiting_radius_psk = 1;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (!ok) {
|
||||
wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
|
||||
"invalid MIC in msg 2/4 of 4-Way Handshake");
|
||||
@@ -3758,6 +3777,11 @@ SM_STEP(WPA_PTK)
|
||||
} else if (wpa_auth_uses_sae(sm) && sm->pmksa) {
|
||||
SM_ENTER(WPA_PTK, PTKSTART);
|
||||
#endif /* CONFIG_SAE */
|
||||
+ } else if (wpa_key_mgmt_wpa_psk_no_sae(sm->wpa_key_mgmt) &&
|
||||
+ wpa_auth->conf.radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "INITPSK: No PSK yet available for STA - use RADIUS later");
|
||||
+ SM_ENTER(WPA_PTK, PTKSTART);
|
||||
} else {
|
||||
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||
"no PSK configured for the STA");
|
||||
@@ -5661,3 +5685,28 @@ void wpa_auth_set_ocv_override_freq(stru
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
+
|
||||
+
|
||||
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success)
|
||||
+{
|
||||
+ if (!sm->waiting_radius_psk) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "Ignore RADIUS PSK response for " MACSTR
|
||||
+ " that did not wait one",
|
||||
+ MAC2STR(sm->addr));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "RADIUS PSK response for " MACSTR " (%s)",
|
||||
+ MAC2STR(sm->addr), success ? "success" : "fail");
|
||||
+ sm->waiting_radius_psk = 0;
|
||||
+
|
||||
+ if (success) {
|
||||
+ /* Try to process the EAPOL-Key msg 2/4 again */
|
||||
+ sm->EAPOLKeyReceived = true;
|
||||
+ } else {
|
||||
+ sm->Disconnect = true;
|
||||
+ }
|
||||
+
|
||||
+ eloop_register_timeout(0, 0, wpa_sm_call_step, sm, NULL);
|
||||
+}
|
||||
--- a/src/ap/wpa_auth.h
|
||||
+++ b/src/ap/wpa_auth.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd - IEEE 802.11i-2004 / WPA Authenticator
|
||||
- * Copyright (c) 2004-2017, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2004-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -273,6 +273,8 @@ struct wpa_auth_config {
|
||||
* PTK derivation regardless of advertised capabilities.
|
||||
*/
|
||||
bool force_kdk_derivation;
|
||||
+
|
||||
+ bool radius_psk;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -320,6 +322,9 @@ struct wpa_auth_callbacks {
|
||||
void (*store_ptksa)(void *ctx, const u8 *addr, int cipher,
|
||||
u32 life_time, const struct wpa_ptk *ptk);
|
||||
void (*clear_ptksa)(void *ctx, const u8 *addr, int cipher);
|
||||
+ void (*request_radius_psk)(void *ctx, const u8 *addr, int key_mgmt,
|
||||
+ const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len);
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
|
||||
int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
|
||||
@@ -567,4 +572,6 @@ void wpa_auth_set_ocv_override_freq(stru
|
||||
enum wpa_auth_ocv_override_frame frame,
|
||||
unsigned int freq);
|
||||
|
||||
+void wpa_auth_sta_radius_psk_resp(struct wpa_state_machine *sm, bool success);
|
||||
+
|
||||
#endif /* WPA_AUTH_H */
|
||||
--- a/src/ap/wpa_auth_glue.c
|
||||
+++ b/src/ap/wpa_auth_glue.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* hostapd / WPA authenticator glue code
|
||||
- * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "ap_drv_ops.h"
|
||||
#include "ap_config.h"
|
||||
#include "ieee802_11.h"
|
||||
+#include "ieee802_11_auth.h"
|
||||
#include "pmksa_cache_auth.h"
|
||||
#include "wpa_auth.h"
|
||||
#include "wpa_auth_glue.h"
|
||||
@@ -214,6 +215,8 @@ static void hostapd_wpa_auth_conf(struct
|
||||
wconf->force_kdk_derivation = conf->force_kdk_derivation;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
#endif /* CONFIG_PASN */
|
||||
+
|
||||
+ wconf->radius_psk = conf->wpa_psk_radius == PSK_RADIUS_DURING_4WAY_HS;
|
||||
}
|
||||
|
||||
|
||||
@@ -1435,6 +1438,23 @@ static void hostapd_wpa_unregister_ft_ou
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
|
||||
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+static void hostapd_request_radius_psk(void *ctx, const u8 *addr, int key_mgmt,
|
||||
+ const u8 *anonce,
|
||||
+ const u8 *eapol, size_t eapol_len)
|
||||
+{
|
||||
+ struct hostapd_data *hapd = ctx;
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "RADIUS PSK request for " MACSTR " key_mgmt=0x%x",
|
||||
+ MAC2STR(addr), key_mgmt);
|
||||
+ wpa_hexdump(MSG_DEBUG, "ANonce", anonce, WPA_NONCE_LEN);
|
||||
+ wpa_hexdump(MSG_DEBUG, "EAPOL", eapol, eapol_len);
|
||||
+ hostapd_acl_req_radius_psk(hapd, addr, key_mgmt, anonce, eapol,
|
||||
+ eapol_len);
|
||||
+}
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
+
|
||||
+
|
||||
int hostapd_setup_wpa(struct hostapd_data *hapd)
|
||||
{
|
||||
struct wpa_auth_config _conf;
|
||||
@@ -1478,6 +1498,9 @@ int hostapd_setup_wpa(struct hostapd_dat
|
||||
.set_session_timeout = hostapd_wpa_auth_set_session_timeout,
|
||||
.get_session_timeout = hostapd_wpa_auth_get_session_timeout,
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
+#ifndef CONFIG_NO_RADIUS
|
||||
+ .request_radius_psk = hostapd_request_radius_psk,
|
||||
+#endif /* CONFIG_NO_RADIUS */
|
||||
};
|
||||
const u8 *wpa_ie;
|
||||
size_t wpa_ie_len;
|
||||
--- a/src/ap/wpa_auth_i.h
|
||||
+++ b/src/ap/wpa_auth_i.h
|
||||
@@ -89,6 +89,7 @@ struct wpa_state_machine {
|
||||
unsigned int rx_eapol_key_secure:1;
|
||||
unsigned int update_snonce:1;
|
||||
unsigned int alt_snonce_valid:1;
|
||||
+ unsigned int waiting_radius_psk:1;
|
||||
#ifdef CONFIG_IEEE80211R_AP
|
||||
unsigned int ft_completed:1;
|
||||
unsigned int pmk_r1_name_valid:1;
|
||||
@@ -0,0 +1,716 @@
|
||||
From 57342b4c68d80754c3b6e1df4af1a46afc936a90 Mon Sep 17 00:00:00 2001
|
||||
From: Hari Chandrakanthan <quic_haric@quicinc.com>
|
||||
Date: Wed, 1 Dec 2021 21:27:36 +0530
|
||||
Subject: [PATCH] hostapd : Add support to awgn mitigation for 6Ghz
|
||||
|
||||
when awgn interference is detected on operating channel,
|
||||
AP is supposed to stop transmitting in that channel.
|
||||
AP can reduce it's operating bandwidth or
|
||||
completely move to another channel based on the
|
||||
interference segment.
|
||||
|
||||
hostapd receives awgn notification through NL80211_CMD_AWGN_DETECT
|
||||
cmd and the NL attribute NL80211_ATTR_AWGN_INTERFERENCE_BITMAP
|
||||
provides the channel interference information.
|
||||
|
||||
Eg: For 80Mhz operating bandwidth, the chan bw interference
|
||||
bitmap can be as follows.
|
||||
segment chan_bw_interference_bitmap
|
||||
0 0x01
|
||||
1 0x02
|
||||
2 0x04
|
||||
3 0x08
|
||||
|
||||
segment 0 - primary 20Mhz
|
||||
segment 1 - secondary 20Mhz
|
||||
segment 2 - secondary 40Mhz lower
|
||||
segment 3 - secondary 40Mhz upper
|
||||
|
||||
Signed-off-by: Hari Chandrakanthan <quic_haric@quicinc.com>
|
||||
---
|
||||
hostapd/Makefile | 1 +
|
||||
src/ap/Makefile | 1 +
|
||||
src/ap/drv_callbacks.c | 13 ++
|
||||
src/ap/interference.c | 387 +++++++++++++++++++++++++++++++++++++
|
||||
src/ap/interference.h | 41 ++++
|
||||
src/drivers/driver.h | 13 ++
|
||||
src/drivers/driver_common.c | 1 +
|
||||
src/drivers/driver_nl80211_event.c | 30 +++
|
||||
src/drivers/nl80211_copy.h | 13 ++
|
||||
wpa_supplicant/Makefile | 1 +
|
||||
10 files changed, 501 insertions(+)
|
||||
create mode 100644 src/ap/interference.c
|
||||
create mode 100644 src/ap/interference.h
|
||||
|
||||
--- a/hostapd/Makefile
|
||||
+++ b/hostapd/Makefile
|
||||
@@ -1186,6 +1186,7 @@ OBJS += ../src/ap/ap_list.o
|
||||
OBJS += ../src/ap/ieee802_11.o
|
||||
OBJS += ../src/ap/hw_features.o
|
||||
OBJS += ../src/ap/dfs.o
|
||||
+OBJS += ../src/ap/interference.o
|
||||
CFLAGS += -DNEED_AP_MLME
|
||||
endif
|
||||
OBJS += ../src/ap/ieee802_11_ht.o
|
||||
--- a/src/ap/Makefile
|
||||
+++ b/src/ap/Makefile
|
||||
@@ -36,6 +36,7 @@ LIB_OBJS= \
|
||||
ieee802_11_shared.o \
|
||||
ieee802_11_vht.o \
|
||||
ieee802_1x.o \
|
||||
+ interference.o \
|
||||
neighbor_db.o \
|
||||
ndisc_snoop.o \
|
||||
p2p_hostapd.o \
|
||||
--- a/src/ap/drv_callbacks.c
|
||||
+++ b/src/ap/drv_callbacks.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "dpp_hostapd.h"
|
||||
#include "fils_hlp.h"
|
||||
#include "neighbor_db.h"
|
||||
+#include "interference.h"
|
||||
|
||||
#ifdef CONFIG_FILS
|
||||
void hostapd_notify_assoc_fils_finish(struct hostapd_data *hapd,
|
||||
@@ -1685,6 +1686,13 @@ static void hostapd_event_dfs_radar_dete
|
||||
radar->cf1, radar->cf2);
|
||||
}
|
||||
|
||||
+static void hostapd_event_awgn_detected(struct hostapd_data *hapd,
|
||||
+ struct awgn_event *awgn_info)
|
||||
+{
|
||||
+ hostapd_intf_awgn_detected(hapd->iface, awgn_info->freq, awgn_info->chan_width,
|
||||
+ awgn_info->cf1, awgn_info->cf2,
|
||||
+ awgn_info->chan_bw_interference_bitmap);
|
||||
+}
|
||||
|
||||
static void hostapd_event_dfs_pre_cac_expired(struct hostapd_data *hapd,
|
||||
struct dfs_event *radar)
|
||||
@@ -2069,6 +2077,11 @@ void hostapd_wpa_event(void *ctx, enum w
|
||||
break;
|
||||
hostapd_event_dfs_radar_detected(hapd, &data->dfs_event);
|
||||
break;
|
||||
+ case EVENT_AWGN_DETECTED:
|
||||
+ if (!data)
|
||||
+ break;
|
||||
+ hostapd_event_awgn_detected(hapd, &data->awgn_event);
|
||||
+ break;
|
||||
case EVENT_DFS_PRE_CAC_EXPIRED:
|
||||
if (!data)
|
||||
break;
|
||||
--- /dev/null
|
||||
+++ b/src/ap/interference.c
|
||||
@@ -0,0 +1,393 @@
|
||||
+/*
|
||||
+ * AWGN - Additive white Gaussian Noise
|
||||
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc.
|
||||
+ *
|
||||
+ * This software may be distributed under the terms of the BSD license.
|
||||
+ * See README for more details.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without modification,
|
||||
+ * are permitted (subject to the limitations in the disclaimer below) provided that
|
||||
+ * the following conditions are met:
|
||||
+ * * Redistributions of source code must retain the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer.
|
||||
+ * * Redistributions in binary form must reproduce the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer in the documentation and/or
|
||||
+ * other materials provided with the distribution.
|
||||
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors
|
||||
+ * may be used to endorse or promote products derived from this software without specific
|
||||
+ * prior written permission.
|
||||
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+#include "utils/includes.h"
|
||||
+
|
||||
+#include "utils/common.h"
|
||||
+#include "common/ieee802_11_defs.h"
|
||||
+#include "common/hw_features_common.h"
|
||||
+#include "common/wpa_ctrl.h"
|
||||
+#include "hostapd.h"
|
||||
+#include "ap_drv_ops.h"
|
||||
+#include "drivers/driver.h"
|
||||
+#include "beacon.h"
|
||||
+#include "eloop.h"
|
||||
+#include "hw_features.h"
|
||||
+
|
||||
+/*
|
||||
+ * intf_awgn_chan_range_available - check whether the channel can operate
|
||||
+ * in the given bandwidth in 6Ghz
|
||||
+ * @first_chan_idx - channel index of the first 20Mhz channel in a segment
|
||||
+ * @num_chans - number of 20Mhz channels needed for the operating bandwidth
|
||||
+ */
|
||||
+static int intf_awgn_chan_range_available(struct hostapd_hw_modes *mode,
|
||||
+ int first_chan_idx, int num_chans)
|
||||
+{
|
||||
+ struct hostapd_channel_data *first_chan = NULL;
|
||||
+ int allowed_40_6g[] = {1, 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105,
|
||||
+ 113, 121, 129, 137, 145, 153, 161, 169, 177, 185, 193,
|
||||
+ 201, 209, 217, 225, 233};
|
||||
+ int allowed_80_6g[] = {1, 17, 33, 49, 65, 81, 97, 113, 129, 145, 161, 177,
|
||||
+ 193, 209};
|
||||
+ int allowed_160_6g[] = {1, 33, 65, 97, 129, 161, 193};
|
||||
+ int chan_idx_match = 0;
|
||||
+ int i;
|
||||
+
|
||||
+ first_chan = &mode->channels[first_chan_idx];
|
||||
+
|
||||
+ if (!first_chan || !chan_pri_allowed(first_chan)) {
|
||||
+ wpa_printf(MSG_DEBUG, "AWGN: primary channel not allowed");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* 20Mhz channel, so no need to check the range */
|
||||
+ if (num_chans == 1)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (num_chans == 2) { /* 40Mhz channel */
|
||||
+ for (i = 0; i < ARRAY_SIZE(allowed_40_6g); i++) {
|
||||
+ if (first_chan->chan == allowed_40_6g[i]) {
|
||||
+ chan_idx_match = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (num_chans == 4) { /* 80Mhz channel */
|
||||
+ for (i = 0; i < ARRAY_SIZE(allowed_80_6g); i++) {
|
||||
+ if (first_chan->chan == allowed_80_6g[i]) {
|
||||
+ chan_idx_match = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ } else if (num_chans == 8) { /* 160Mhz channel */
|
||||
+ for (i = 0; i < ARRAY_SIZE(allowed_160_6g); i++) {
|
||||
+ if (first_chan->chan == allowed_160_6g[i]) {
|
||||
+ chan_idx_match = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (chan_idx_match == 1)
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int is_in_chanlist(struct hostapd_iface *iface,
|
||||
+ struct hostapd_channel_data *chan)
|
||||
+{
|
||||
+ if (!iface->conf->acs_ch_list.num)
|
||||
+ return 1;
|
||||
+
|
||||
+ return freq_range_list_includes(&iface->conf->acs_ch_list, chan->chan);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ *intf_awgn_find_channel - find the channel that can operate with bandwidth chan_width.
|
||||
+ If idx doesn't match with index of any of the existing channel, then the api
|
||||
+ returns the total number of available chandefs that supports the provided bandwidth
|
||||
+ * @idx - index of the channel
|
||||
+ * @chan_width - bandwidth of the channel
|
||||
+ */
|
||||
+static int intf_awgn_find_channel(struct hostapd_iface *iface,
|
||||
+ struct hostapd_channel_data **ret_chan,
|
||||
+ int idx, int chan_width)
|
||||
+{
|
||||
+ struct hostapd_hw_modes *mode = iface->current_mode;
|
||||
+ struct hostapd_channel_data *chan;
|
||||
+ int i, channel_idx = 0, n_chans;
|
||||
+
|
||||
+ switch (chan_width) {
|
||||
+ case CHAN_WIDTH_20_NOHT:
|
||||
+ case CHAN_WIDTH_20:
|
||||
+ n_chans = 1;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_40:
|
||||
+ n_chans = 2;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_80:
|
||||
+ n_chans = 4;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_80P80:
|
||||
+ case CHAN_WIDTH_160:
|
||||
+ n_chans = 8;
|
||||
+ break;
|
||||
+ default:
|
||||
+ n_chans = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mode->num_channels; i++) {
|
||||
+ chan = &mode->channels[i];
|
||||
+
|
||||
+ /* Skip incompatible chandefs */
|
||||
+ if (!intf_awgn_chan_range_available(mode, i, n_chans)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "AWGN: range not available for %d (%d)",
|
||||
+ chan->freq, chan->chan);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (!is_in_chanlist(iface, chan)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "AWGN: channel %d (%d) not in chanlist",
|
||||
+ chan->freq, chan->chan);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (ret_chan && idx == channel_idx) {
|
||||
+ wpa_printf(MSG_DEBUG, "AWGN: Selected channel %d (%d)",
|
||||
+ chan->freq, chan->chan);
|
||||
+ *ret_chan = chan;
|
||||
+ return idx;
|
||||
+ }
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "AWGN: Adding channel %d (%d)",
|
||||
+ chan->freq, chan->chan);
|
||||
+ channel_idx++;
|
||||
+ }
|
||||
+ return channel_idx;
|
||||
+}
|
||||
+
|
||||
+enum chan_seg {
|
||||
+ SEG_PRI20 = 0x1,
|
||||
+ SEG_SEC20 = 0x2,
|
||||
+ SEG_SEC40_LOWER = 0x4,
|
||||
+ SEG_SEC40_UPPER = 0x8,
|
||||
+ SEG_SEC40 = 0xC,
|
||||
+ SEG_SEC80_LOWER = 0x10,
|
||||
+ SEG_SEC80_LOWER_UPPER = 0x20,
|
||||
+ SEG_SEC80_UPPER_LOWER = 0x40,
|
||||
+ SEG_SEC80_UPPER = 0x80,
|
||||
+ SEG_SEC80 = 0xF0,
|
||||
+};
|
||||
+
|
||||
+#define BASE_6G_FREQ 5950
|
||||
+
|
||||
+int get_centre_freq_6g(int chan_idx, int chan_width, int *centre_freq)
|
||||
+{
|
||||
+ if (!centre_freq)
|
||||
+ return -1;
|
||||
+
|
||||
+ *centre_freq = 0;
|
||||
+
|
||||
+ switch (chan_width) {
|
||||
+ case CHAN_WIDTH_40:
|
||||
+ if (chan_idx >= 1 && chan_idx <= 229)
|
||||
+ *centre_freq = ((chan_idx / 8) * 8 + 3) * 5 + BASE_6G_FREQ;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_80:
|
||||
+ if (chan_idx >= 1 && chan_idx <= 221)
|
||||
+ *centre_freq = ((chan_idx / 16) * 16 + 7) * 5 + BASE_6G_FREQ;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_160:
|
||||
+ if (chan_idx >= 1 && chan_idx <= 221)
|
||||
+ *centre_freq = ((chan_idx / 32) * 32 + 15) * 5 + BASE_6G_FREQ;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (*centre_freq == 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * hostapd_intf_awgn_detected - awgn interference is detected in the operating channel.
|
||||
+ * The interference channel information is available as a
|
||||
+ * bitmap(chan_bw_interference_bitmap). If interference has occurred in the
|
||||
+ * primary channel, do a complete channel switch to a different channel else
|
||||
+ * reduce the operating bandwidth and continue ap operation in the same channel.
|
||||
+ */
|
||||
+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq, int chan_width,
|
||||
+ int cf1, int cf2, u32 chan_bw_interference_bitmap)
|
||||
+{
|
||||
+ struct csa_settings settings;
|
||||
+ struct hostapd_channel_data *chan_data = NULL;
|
||||
+ struct hostapd_channel_data *chan_temp = NULL;
|
||||
+ int ret;
|
||||
+ unsigned int i;
|
||||
+ u32 _rand;
|
||||
+ u32 chan_idx;
|
||||
+ int num_available_chandefs;
|
||||
+ u8 channel_switch = 0;
|
||||
+ int new_chan_width;
|
||||
+ int new_centre_freq;
|
||||
+ struct hostapd_hw_modes *mode = iface->current_mode;
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "input freq=%d, chan_width=%d, cf1=%d cf2=%d"
|
||||
+ " chan_bw_interference_bitmap=0x%x",
|
||||
+ freq,
|
||||
+ chan_width,
|
||||
+ cf1, cf2, chan_bw_interference_bitmap);
|
||||
+
|
||||
+ if (iface->conf->discard_6g_awgn_event) {
|
||||
+ wpa_printf(MSG_DEBUG, "discard_6g_awgn_event set ignoring"
|
||||
+ "AWGN DETECT event from driver");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* check whether interference has occurred in primary 20Mhz channel */
|
||||
+ if (!chan_bw_interference_bitmap || (chan_bw_interference_bitmap & SEG_PRI20))
|
||||
+ channel_switch = 1;
|
||||
+
|
||||
+ if (channel_switch) {
|
||||
+ /* Find a random channel to be switched */
|
||||
+ num_available_chandefs = intf_awgn_find_channel(iface, NULL, 0,
|
||||
+ chan_width);
|
||||
+ if (num_available_chandefs == 0) {
|
||||
+ wpa_printf(MSG_ERROR, "AWGN: no available_chandefs");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (os_get_random((u8 *)&_rand, sizeof(_rand)) < 0) {
|
||||
+ wpa_printf(MSG_ERROR, "AWGN: couldn't get random number");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ chan_idx = _rand % num_available_chandefs;
|
||||
+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width);
|
||||
+
|
||||
+ if (!chan_data) {
|
||||
+ wpa_printf(MSG_ERROR, "AWGN: no random channel found, chan idx : %d",
|
||||
+ chan_idx);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if(chan_data->freq == freq) {
|
||||
+ /* New random channel is same as operating channel
|
||||
+ * so choose another channel
|
||||
+ */
|
||||
+ chan_data = NULL;
|
||||
+ chan_idx = (chan_idx + 1) % num_available_chandefs;
|
||||
+ intf_awgn_find_channel(iface, &chan_data, chan_idx, chan_width);
|
||||
+ if (!chan_data) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "AWGN: random channel not found, chan idx : %d",
|
||||
+ chan_idx);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "AWGN: got random channel %d (%d)",
|
||||
+ chan_data->freq, chan_data->chan);
|
||||
+ new_chan_width = chan_width;
|
||||
+ } else {
|
||||
+ /* interference is not present in the primary 20Mhz, so reduce bandwidth*/
|
||||
+ for (i = 0; i < mode->num_channels; i++) {
|
||||
+ chan_temp = &mode->channels[i];
|
||||
+ if (chan_temp->freq == freq)
|
||||
+ chan_data = chan_temp;
|
||||
+ }
|
||||
+ if (!chan_data) {
|
||||
+ wpa_printf(MSG_ERROR, "AWGN : no channel found");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((chan_width > CHAN_WIDTH_80) &&
|
||||
+ !(chan_bw_interference_bitmap & SEG_SEC40) &&
|
||||
+ !(chan_bw_interference_bitmap & SEG_SEC20))
|
||||
+ new_chan_width = CHAN_WIDTH_80;
|
||||
+ else if (chan_width > CHAN_WIDTH_40 &&
|
||||
+ !(chan_bw_interference_bitmap & SEG_SEC20))
|
||||
+ new_chan_width = CHAN_WIDTH_40;
|
||||
+ else
|
||||
+ new_chan_width = CHAN_WIDTH_20;
|
||||
+ }
|
||||
+
|
||||
+ if (new_chan_width > CHAN_WIDTH_20) {
|
||||
+ ret = get_centre_freq_6g(chan_data->chan, new_chan_width,
|
||||
+ &new_centre_freq);
|
||||
+ if (ret) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "AWGN : couldn't find centre freq for chan : %d"
|
||||
+ " chan_width : %d", chan_data->chan, new_chan_width);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ } else {
|
||||
+ new_centre_freq = chan_data->freq;
|
||||
+ }
|
||||
+
|
||||
+ os_memset(&settings, 0, sizeof(settings));
|
||||
+ settings.cs_count = 5;
|
||||
+ settings.freq_params.freq = chan_data->freq;
|
||||
+
|
||||
+ switch (new_chan_width) {
|
||||
+ case CHAN_WIDTH_40:
|
||||
+ settings.freq_params.bandwidth = 40;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_80P80:
|
||||
+ case CHAN_WIDTH_80:
|
||||
+ settings.freq_params.bandwidth = 80;
|
||||
+ break;
|
||||
+ case CHAN_WIDTH_160:
|
||||
+ settings.freq_params.bandwidth = 160;
|
||||
+ break;
|
||||
+ default:
|
||||
+ settings.freq_params.bandwidth = 20;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ settings.freq_params.center_freq1 = new_centre_freq;
|
||||
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
|
||||
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
|
||||
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
|
||||
+
|
||||
+ for (i = 0; i < iface->num_bss; i++) {
|
||||
+ /* Save CHAN_SWITCH VHT and HE config */
|
||||
+ hostapd_chan_switch_config(iface->bss[i],
|
||||
+ &settings.freq_params);
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "channel=%u, freq=%d, bw=%d, center_freq1=%d",
|
||||
+ settings.freq_params.channel,
|
||||
+ settings.freq_params.freq,
|
||||
+ settings.freq_params.bandwidth,
|
||||
+ settings.freq_params.center_freq1);
|
||||
+
|
||||
+ ret = hostapd_switch_channel(iface->bss[i], &settings);
|
||||
+ if (ret) {
|
||||
+ /* FIX: What do we do if CSA fails in the middle of
|
||||
+ * submitting multi-BSS CSA requests?
|
||||
+ */
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/src/ap/interference.h
|
||||
@@ -0,0 +1,41 @@
|
||||
+/*
|
||||
+ * INTF - Interference
|
||||
+ * AWGN - Additive white Gaussian Noise
|
||||
+ * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2013-2017, Qualcomm Atheros, Inc.
|
||||
+ *
|
||||
+ * This software may be distributed under the terms of the BSD license.
|
||||
+ * See README for more details.
|
||||
+ */
|
||||
+
|
||||
+/*
|
||||
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * Redistribution and use in source and binary forms, with or without modification,
|
||||
+ * are permitted (subject to the limitations in the disclaimer below) provided that
|
||||
+ * the following conditions are met:
|
||||
+ * * Redistributions of source code must retain the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer.
|
||||
+ * * Redistributions in binary form must reproduce the above copyright notice,
|
||||
+ * this list of conditions and the following disclaimer in the documentation and/or
|
||||
+ * other materials provided with the distribution.
|
||||
+ * * Neither the name of Qualcomm Innovation Center, Inc. nor the names of its contributors
|
||||
+ * may be used to endorse or promote products derived from this software without specific
|
||||
+ * prior written permission.
|
||||
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
|
||||
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
||||
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+ */
|
||||
+
|
||||
+int hostapd_intf_awgn_detected(struct hostapd_iface *iface, int freq,
|
||||
+ int chan_width,
|
||||
+ int cf1, int cf2,
|
||||
+ u32 chan_bw_interference_bitmap);
|
||||
+
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -5264,6 +5264,7 @@ enum wpa_event_type {
|
||||
* EVENT_CCA_NOTIFY - Notification that CCA has completed
|
||||
*/
|
||||
EVENT_CCA_NOTIFY,
|
||||
+ EVENT_AWGN_DETECTED,
|
||||
};
|
||||
|
||||
|
||||
@@ -6173,6 +6174,18 @@ union wpa_event_data {
|
||||
struct bss_color_collision {
|
||||
u64 bitmap;
|
||||
} bss_color_collision;
|
||||
+
|
||||
+ /**
|
||||
+ * Data for EVENT_AWGN
|
||||
+ */
|
||||
+ struct awgn_event {
|
||||
+ int freq;
|
||||
+ enum chan_width chan_width;
|
||||
+ int cf1;
|
||||
+ int cf2;
|
||||
+ u32 chan_bw_interference_bitmap;
|
||||
+ } awgn_event;
|
||||
+
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/src/drivers/driver_common.c
|
||||
+++ b/src/drivers/driver_common.c
|
||||
@@ -95,6 +95,7 @@ const char * event_to_string(enum wpa_ev
|
||||
E2S(CCA_STARTED_NOTIFY);
|
||||
E2S(CCA_ABORTED_NOTIFY);
|
||||
E2S(CCA_NOTIFY);
|
||||
+ E2S(AWGN_DETECTED);
|
||||
}
|
||||
|
||||
return "UNKNOWN";
|
||||
--- a/src/drivers/driver_nl80211_event.c
|
||||
+++ b/src/drivers/driver_nl80211_event.c
|
||||
@@ -149,6 +149,7 @@ static const char * nl80211_command_to_s
|
||||
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_STARTED)
|
||||
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED)
|
||||
C2S(NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED)
|
||||
+ C2S(NL80211_CMD_AWGN_DETECT)
|
||||
default:
|
||||
return "NL80211_CMD_UNKNOWN";
|
||||
}
|
||||
@@ -1821,6 +1822,32 @@ static void nl80211_radar_event(struct w
|
||||
}
|
||||
}
|
||||
|
||||
+static void nl80211_awgn_event(struct wpa_driver_nl80211_data *drv,
|
||||
+ struct nlattr **tb)
|
||||
+{
|
||||
+ union wpa_event_data data;
|
||||
+
|
||||
+ os_memset(&data, 0, sizeof(data));
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_WIPHY_FREQ])
|
||||
+ data.awgn_event.freq = nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]);
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_CHANNEL_WIDTH])
|
||||
+ data.awgn_event.chan_width =
|
||||
+ convert2width(nla_get_u32(tb[NL80211_ATTR_CHANNEL_WIDTH]));
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_CENTER_FREQ1])
|
||||
+ data.awgn_event.cf1 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ1]);
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_CENTER_FREQ2])
|
||||
+ data.awgn_event.cf2 = nla_get_u32(tb[NL80211_ATTR_CENTER_FREQ2]);
|
||||
+
|
||||
+ if (tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP])
|
||||
+ data.awgn_event.chan_bw_interference_bitmap =
|
||||
+ nla_get_u32(tb[NL80211_ATTR_AWGN_INTERFERENCE_BITMAP]);
|
||||
+
|
||||
+ wpa_supplicant_event(drv->ctx, EVENT_AWGN_DETECTED, &data);
|
||||
+}
|
||||
|
||||
static void nl80211_spurious_frame(struct i802_bss *bss, struct nlattr **tb,
|
||||
int wds)
|
||||
@@ -3077,6 +3104,9 @@ static void do_process_drv_event(struct
|
||||
mlme_event_color_change_announcement_completed(drv);
|
||||
break;
|
||||
#endif
|
||||
+ case NL80211_CMD_AWGN_DETECT:
|
||||
+ nl80211_awgn_event(drv, tb);
|
||||
+ break;
|
||||
default:
|
||||
wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event "
|
||||
"(cmd=%d)", cmd);
|
||||
--- a/src/drivers/nl80211_copy.h
|
||||
+++ b/src/drivers/nl80211_copy.h
|
||||
@@ -1192,6 +1192,9 @@
|
||||
*
|
||||
* @NL80211_CMD_SET_UNSOL_BCAST_PROBE_RESP: Command to set unsolicited
|
||||
* broadcast probe response transmission parameters.
|
||||
+ * @NL80211_CMD_AWGN_DETECT: Once AWGN interference is detected on the operating
|
||||
+ * channel, userspace is notified with the interference bitmap using
|
||||
+ * %NL80211_ATTR_AWGN_INTERFERENCE_BITMAP
|
||||
*
|
||||
* @NL80211_CMD_MAX: highest used command number
|
||||
* @__NL80211_CMD_AFTER_LAST: internal use
|
||||
@@ -1437,6 +1440,7 @@ enum nl80211_commands {
|
||||
NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_ABORTED,
|
||||
NL80211_CMD_COLOR_CHANGE_ANNOUNCEMENT_COMPLETED,
|
||||
|
||||
+ NL80211_CMD_AWGN_DETECT,
|
||||
|
||||
/* add new commands above here */
|
||||
|
||||
@@ -2612,6 +2616,9 @@ enum nl80211_commands {
|
||||
* staggered mode or burst mode in %NL80211_CMD_START_AP from
|
||||
* user-space.
|
||||
*
|
||||
+ * @NL80211_ATTR_AWGN_INTERFERENCE_BITMAP: u32 attribute specifying the
|
||||
+ * interference bitmap of operating bandwidth for %NL80211_CMD_AWGN_DETECT
|
||||
+ *
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@@ -3127,6 +3134,12 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_BEACON_TX_MODE,
|
||||
|
||||
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
|
||||
+
|
||||
+ NL80211_ATTR_STA_MGMT_RTS_CTS_CONFIG,
|
||||
+
|
||||
+ NL80211_ATTR_AWGN_INTERFERENCE_BITMAP,
|
||||
+
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
--- a/wpa_supplicant/Makefile
|
||||
+++ b/wpa_supplicant/Makefile
|
||||
@@ -964,6 +964,7 @@ OBJS += ../src/ap/ap_list.o
|
||||
OBJS += ../src/ap/ieee802_11.o
|
||||
OBJS += ../src/ap/hw_features.o
|
||||
OBJS += ../src/ap/dfs.o
|
||||
+OBJS += ../src/ap/interference.o
|
||||
CFLAGS += -DNEED_AP_MLME
|
||||
endif
|
||||
ifdef CONFIG_WPS
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3536,6 +3536,8 @@ static int hostapd_config_fill(struct ho
|
||||
bss->unsol_bcast_probe_resp_interval = val;
|
||||
} else if (os_strcmp(buf, "he_co_locate") == 0) {
|
||||
conf->he_co_locate = atoi(pos);
|
||||
+ } else if (os_strcmp(buf, "discard_6g_awgn_event") == 0) {
|
||||
+ conf->discard_6g_awgn_event = atoi(pos);
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
} else if (os_strcmp(buf, "max_listen_interval") == 0) {
|
||||
bss->max_listen_interval = atoi(pos);
|
||||
--- a/src/ap/ap_config.c
|
||||
+++ b/src/ap/ap_config.c
|
||||
@@ -277,6 +277,7 @@ struct hostapd_config * hostapd_config_d
|
||||
conf->he_6ghz_max_ampdu_len_exp = 7;
|
||||
conf->he_6ghz_rx_ant_pat = 1;
|
||||
conf->he_6ghz_tx_ant_pat = 1;
|
||||
+ conf->discard_6g_awgn_event = 0;
|
||||
#endif /* CONFIG_IEEE80211AX */
|
||||
|
||||
/* The third octet of the country string uses an ASCII space character
|
||||
--- a/src/ap/ap_config.h
|
||||
+++ b/src/ap/ap_config.h
|
||||
@@ -1077,6 +1077,7 @@ struct hostapd_config {
|
||||
u8 he_6ghz_rx_ant_pat;
|
||||
u8 he_6ghz_tx_ant_pat;
|
||||
bool he_co_locate;
|
||||
+ bool discard_6g_awgn_event;
|
||||
#define AP_TYPE_6GHZ_INDOOR_AP 0
|
||||
#define AP_TYPE_6GHZ_STANDARD_POWER_AP 1
|
||||
#define AP_TYPE_6GHZ_VERY_LOW_POWER_AP 2
|
||||
@@ -0,0 +1,564 @@
|
||||
From 404211da041eef5ddfc52515048b04c70ef8579c Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Thu, 21 Oct 2021 12:51:38 +0530
|
||||
Subject: [PATCH] hostapd: add support for 6GHz operation
|
||||
|
||||
6 GHz gives users ability to select the AP mode from LPI, SP and
|
||||
VLP modes. This mode needs to be passed on to the cfg80211
|
||||
for further processing during AP bring up. Also, the regulatory
|
||||
rules received by hostapd contains psd values for 6G rules.
|
||||
Hostapd needs to store these values in order to later advertise
|
||||
it in the tx power element in the beacon.
|
||||
|
||||
This patch adds the support to send the user configured 6g power
|
||||
type during set_channel command and as well to get and store the
|
||||
psd values from reg rules which will be later on used in tpe
|
||||
advertisement during beacon formation.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
---
|
||||
src/ap/ap_drv_ops.c | 9 ++++++---
|
||||
src/ap/beacon.c | 9 +++++++--
|
||||
src/ap/dfs.c | 6 ++++--
|
||||
src/ap/hostapd.c | 2 +-
|
||||
src/ap/ieee802_11.c | 13 ++++++++++++-
|
||||
src/ap/ieee802_11_he.c | 10 ++++++++--
|
||||
src/common/hw_features_common.c | 4 +++-
|
||||
src/common/hw_features_common.h | 2 +-
|
||||
src/common/ieee802_11_defs.h | 14 ++++++++++++++
|
||||
src/drivers/driver.h | 20 +++++++++++++++++++-
|
||||
src/drivers/driver_hostap.c | 3 ++-
|
||||
src/drivers/driver_nl80211.c | 15 ++++++++++++++-
|
||||
src/drivers/driver_nl80211.h | 2 +-
|
||||
src/drivers/driver_nl80211_capa.c | 28 +++++++++++++++++++++++-----
|
||||
src/drivers/driver_nl80211_event.c | 2 +-
|
||||
src/drivers/nl80211_copy.h | 19 +++++++++++++++++++
|
||||
wpa_supplicant/driver_i.h | 2 +-
|
||||
wpa_supplicant/mesh.c | 2 +-
|
||||
wpa_supplicant/wpa_supplicant.c | 2 +-
|
||||
19 files changed, 138 insertions(+), 26 deletions(-)
|
||||
|
||||
--- a/src/ap/ap_drv_ops.c
|
||||
+++ b/src/ap/ap_drv_ops.c
|
||||
@@ -563,7 +563,8 @@ int hostapd_set_freq(struct hostapd_data
|
||||
center_segment0, center_segment1,
|
||||
cmode ? cmode->vht_capab : 0,
|
||||
cmode ?
|
||||
- &cmode->he_capab[IEEE80211_MODE_AP] : NULL))
|
||||
+ &cmode->he_capab[IEEE80211_MODE_AP] : NULL,
|
||||
+ hapd->iconf->he_6ghz_reg_pwr_type))
|
||||
return -1;
|
||||
|
||||
if (hapd->driver == NULL)
|
||||
@@ -636,7 +637,8 @@ hostapd_get_hw_feature_data(struct hosta
|
||||
hapd->driver->get_hw_feature_data == NULL)
|
||||
return NULL;
|
||||
return hapd->driver->get_hw_feature_data(hapd->drv_priv, num_modes,
|
||||
- flags, dfs_domain);
|
||||
+ flags, dfs_domain,
|
||||
+ hapd->iconf->he_6ghz_reg_pwr_type);
|
||||
}
|
||||
|
||||
|
||||
@@ -836,7 +838,8 @@ int hostapd_start_dfs_cac(struct hostapd
|
||||
oper_chwidth, center_segment0,
|
||||
center_segment1,
|
||||
cmode->vht_capab,
|
||||
- &cmode->he_capab[IEEE80211_MODE_AP])) {
|
||||
+ &cmode->he_capab[IEEE80211_MODE_AP],
|
||||
+ hapd->iconf->he_6ghz_reg_pwr_type)) {
|
||||
wpa_printf(MSG_ERROR, "Can't set freq params");
|
||||
return -1;
|
||||
}
|
||||
--- a/src/ap/beacon.c
|
||||
+++ b/src/ap/beacon.c
|
||||
@@ -1571,7 +1571,11 @@ int ieee802_11_build_ap_params(struct ho
|
||||
if (is_6ghz_op_class(hapd->iconf->op_class)) {
|
||||
tail_len += sizeof(struct ieee80211_he_6ghz_oper_info) +
|
||||
3 + sizeof(struct ieee80211_he_6ghz_band_cap);
|
||||
- /* Additional TX Power envelope for subordinate client */
|
||||
+ /* Additional TX Power envelope for subordinate client
|
||||
+ * Currently as per the spec, only AP LP mode should send
|
||||
+ * the tpe for subordinate client. SP mode should not and
|
||||
+ * no standard set yet for VLP mode.
|
||||
+ */
|
||||
if (hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf) ==
|
||||
AP_TYPE_6GHZ_INDOOR_AP)
|
||||
tail_len += 4;
|
||||
@@ -2012,7 +2016,8 @@ static int __ieee802_11_set_beacon(struc
|
||||
hostapd_get_oper_centr_freq_seg0_idx(iconf),
|
||||
hostapd_get_oper_centr_freq_seg1_idx(iconf),
|
||||
cmode->vht_capab,
|
||||
- &cmode->he_capab[IEEE80211_MODE_AP]) == 0)
|
||||
+ &cmode->he_capab[IEEE80211_MODE_AP],
|
||||
+ iconf->he_6ghz_reg_pwr_type) == 0)
|
||||
params.freq = &freq;
|
||||
|
||||
res = hostapd_drv_set_ap(hapd, ¶ms);
|
||||
--- a/src/ap/dfs.c
|
||||
+++ b/src/ap/dfs.c
|
||||
@@ -1086,7 +1086,8 @@ static int hostapd_dfs_testmode_set_beac
|
||||
vht_oper_centr_freq_seg0_idx,
|
||||
vht_oper_centr_freq_seg1_idx,
|
||||
iface->current_mode->vht_capab,
|
||||
- &iface->current_mode->he_capab[IEEE80211_MODE_AP]);
|
||||
+ &iface->current_mode->he_capab[IEEE80211_MODE_AP],
|
||||
+ hapd->iconf->he_6ghz_reg_pwr_type);
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
|
||||
@@ -1227,7 +1228,8 @@ static int hostapd_dfs_start_channel_swi
|
||||
oper_centr_freq_seg0_idx,
|
||||
oper_centr_freq_seg1_idx,
|
||||
cmode->vht_capab,
|
||||
- &cmode->he_capab[ieee80211_mode]);
|
||||
+ &cmode->he_capab[ieee80211_mode],
|
||||
+ iface->conf->he_6ghz_reg_pwr_type);
|
||||
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR, "DFS failed to calculate CSA freq params");
|
||||
--- a/src/ap/hostapd.c
|
||||
+++ b/src/ap/hostapd.c
|
||||
@@ -3503,7 +3503,7 @@ static int hostapd_change_config_freq(st
|
||||
hostapd_get_oper_centr_freq_seg1_idx(conf),
|
||||
conf->vht_capab,
|
||||
mode ? &mode->he_capab[IEEE80211_MODE_AP] :
|
||||
- NULL))
|
||||
+ NULL, hapd->iconf->he_6ghz_reg_pwr_type))
|
||||
return -1;
|
||||
|
||||
switch (params->bandwidth) {
|
||||
--- a/src/ap/ieee802_11.c
|
||||
+++ b/src/ap/ieee802_11.c
|
||||
@@ -6927,6 +6927,8 @@ u8 * hostapd_eid_txpower_envelope(struct
|
||||
int dfs, i;
|
||||
u8 channel, tx_pwr_count, local_pwr_constraint;
|
||||
u8 tx_pwr, tx_pwr_intrpn, tx_pwr_cat, ap_type;
|
||||
+ s8 psd;
|
||||
+
|
||||
int max_tx_power;
|
||||
|
||||
if (!mode)
|
||||
@@ -6963,15 +6965,24 @@ u8 * hostapd_eid_txpower_envelope(struct
|
||||
*/
|
||||
if (ap_type == AP_TYPE_6GHZ_INDOOR_AP) {
|
||||
tx_pwr_cat = REG_SUBORDINATE_CLIENT;
|
||||
- /* TODO: extract psd limits from channel data */
|
||||
+ psd = mode->psd_values[NL80211_REG_SUBORDINATE_CLIENT_LPI + ap_type];
|
||||
+#ifdef REG_DOM_SUPPORT_TX_POWER
|
||||
+ tx_pwr = psd * 2;
|
||||
+#else
|
||||
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
|
||||
+#endif /* REG_DOM_SUPPORT_TX_POWER */
|
||||
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn,
|
||||
tx_pwr_cat, tx_pwr);
|
||||
}
|
||||
|
||||
/* Default Tx Power envelope for Global Operating class */
|
||||
tx_pwr_cat = REG_DEFAULT_CLIENT;
|
||||
+ psd = mode->psd_values[NL80211_REG_REGULAR_CLIENT_LPI + ap_type];
|
||||
+#ifdef REG_DOM_SUPPORT_TX_POWER
|
||||
+ tx_pwr = psd * 2;
|
||||
+#else
|
||||
tx_pwr = (hostapd_get_6g_tx_power(hapd, ap_type, tx_pwr_cat) * 2);
|
||||
+#endif /* REG_DOM_SUPPORT_TX_POWER */
|
||||
eid = hostapd_add_tpe_info(eid, tx_pwr_count, tx_pwr_intrpn, tx_pwr_cat, tx_pwr);
|
||||
|
||||
return eid;
|
||||
--- a/src/ap/ieee802_11_he.c
|
||||
+++ b/src/ap/ieee802_11_he.c
|
||||
@@ -235,10 +235,16 @@ u8 * hostapd_eid_he_operation(struct hos
|
||||
* - 1 (Standard Power Access Point)
|
||||
* - Reserved in 5GHz and 2Ghz bands
|
||||
*/
|
||||
+
|
||||
+ u8 ap_type = hostapd_get_he_6ghz_reg_pwr_type(hapd->iconf);
|
||||
+
|
||||
if (seg1)
|
||||
- *pos++ = 3;
|
||||
+ *pos++ = 3 | (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
|
||||
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
|
||||
else
|
||||
- *pos++ = center_idx_to_bw_6ghz(seg0);
|
||||
+ *pos++ = center_idx_to_bw_6ghz(seg0) |
|
||||
+ (IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO &
|
||||
+ (ap_type << IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB));
|
||||
|
||||
/* Channel Center Freq Seg0/Seg1 */
|
||||
if (hapd->iconf->he_oper_chwidth == 2) {
|
||||
--- a/src/common/hw_features_common.c
|
||||
+++ b/src/common/hw_features_common.c
|
||||
@@ -403,7 +403,7 @@ int hostapd_set_freq_params(struct hosta
|
||||
int sec_channel_offset,
|
||||
int oper_chwidth, int center_segment0,
|
||||
int center_segment1, u32 vht_caps,
|
||||
- struct he_capabilities *he_cap)
|
||||
+ struct he_capabilities *he_cap, u8 reg_6g_pwr_mode)
|
||||
{
|
||||
if (!he_cap)
|
||||
he_enabled = 0;
|
||||
@@ -486,6 +486,8 @@ int hostapd_set_freq_params(struct hosta
|
||||
data->ht_enabled = 0;
|
||||
data->vht_enabled = 0;
|
||||
|
||||
+ /* Append 6G reg power info */
|
||||
+ data->he_6ghz_reg_pwr_type = reg_6g_pwr_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/src/common/hw_features_common.h
|
||||
+++ b/src/common/hw_features_common.h
|
||||
@@ -44,7 +44,7 @@ int hostapd_set_freq_params(struct hosta
|
||||
int sec_channel_offset,
|
||||
int oper_chwidth, int center_segment0,
|
||||
int center_segment1, u32 vht_caps,
|
||||
- struct he_capabilities *he_caps);
|
||||
+ struct he_capabilities *he_caps, u8 reg_6g_pwr_mode);
|
||||
void set_disable_ht40(struct ieee80211_ht_capabilities *htcaps,
|
||||
int disabled);
|
||||
int ieee80211ac_cap_check(u32 hw, u32 conf);
|
||||
--- a/src/common/ieee802_11_defs.h
|
||||
+++ b/src/common/ieee802_11_defs.h
|
||||
@@ -1963,6 +1963,17 @@ enum reg_6g_client_type {
|
||||
|
||||
/* same Max Tx Pwr for all 20MHz bands */
|
||||
#define DEFAULT_MAX_TX_POWER_COUNT_6G 0
|
||||
+
|
||||
+/*
|
||||
+ * REG_DOM_SUPPORT_TX_POWER - regulatory domain
|
||||
+ * supports tx power values or not.
|
||||
+ *
|
||||
+ * If this macro is undefined, tx-power macros will be used to
|
||||
+ * get the tx-power, otherwise psd values from regulatory domain
|
||||
+ * will be taken
|
||||
+ */
|
||||
+#define REG_DOM_SUPPORT_TX_POWER 1
|
||||
+
|
||||
/*
|
||||
* These tx-power macros are present till the 6G regdomains are defined to
|
||||
* support tx-power values for various client types.
|
||||
@@ -2350,6 +2361,9 @@ struct ieee80211_spatial_reuse {
|
||||
#define HE_OPERATION_BSS_COLOR_OFFSET 24
|
||||
#define HE_OPERATION_BSS_COLOR_MAX 64
|
||||
|
||||
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO 0x38
|
||||
+#define IEEE80211_HE_6GHZ_OPER_CTRL_REG_INFO_LSB 3
|
||||
+
|
||||
/* Spatial Reuse defines */
|
||||
#define SPATIAL_REUSE_SRP_DISALLOWED BIT(0)
|
||||
#define SPATIAL_REUSE_NON_SRG_OBSS_PD_SR_DISALLOWED BIT(1)
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -299,6 +299,12 @@ struct hostapd_hw_modes {
|
||||
* for IEEE 802.11ay EDMG configuration.
|
||||
*/
|
||||
struct ieee80211_edmg_config edmg;
|
||||
+
|
||||
+ /**
|
||||
+ * This array is used to store the psd value of each power mode
|
||||
+ * supported in 6G band.
|
||||
+ */
|
||||
+ s8 psd_values[NL80211_REG_NUM_POWER_MODES];
|
||||
};
|
||||
|
||||
|
||||
@@ -777,6 +783,17 @@ struct hostapd_freq_params {
|
||||
* for IEEE 802.11ay EDMG configuration.
|
||||
*/
|
||||
struct ieee80211_edmg_config edmg;
|
||||
+
|
||||
+ /**
|
||||
+ * he_6ghz_reg_pwr_type - 6G regulatory power mode
|
||||
+ * Since many operation related to channel for 6G depends on the
|
||||
+ * power mode, this parameter is added here.
|
||||
+ *
|
||||
+ * 0 - LPI_AP
|
||||
+ * 1 - SP_AP
|
||||
+ * 2 - VLP_AP
|
||||
+ */
|
||||
+ u8 he_6ghz_reg_pwr_type;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2938,12 +2955,13 @@ struct wpa_driver_ops {
|
||||
* @num_modes: Variable for returning the number of returned modes
|
||||
* flags: Variable for returning hardware feature flags
|
||||
* @dfs: Variable for returning DFS region (HOSTAPD_DFS_REGION_*)
|
||||
+ * @pwr_mode: Variable required for processing the support data for 6G
|
||||
* Returns: Pointer to allocated hardware data on success or %NULL on
|
||||
* failure. Caller is responsible for freeing this.
|
||||
*/
|
||||
struct hostapd_hw_modes * (*get_hw_feature_data)(void *priv,
|
||||
u16 *num_modes,
|
||||
- u16 *flags, u8 *dfs);
|
||||
+ u16 *flags, u8 *dfs, u8 pwr_mode);
|
||||
|
||||
/**
|
||||
* send_mlme - Send management frame from MLME
|
||||
--- a/src/drivers/driver_hostap.c
|
||||
+++ b/src/drivers/driver_hostap.c
|
||||
@@ -1099,7 +1099,8 @@ static int hostap_sta_disassoc(void *pri
|
||||
|
||||
static struct hostapd_hw_modes * hostap_get_hw_feature_data(void *priv,
|
||||
u16 *num_modes,
|
||||
- u16 *flags, u8 *dfs)
|
||||
+ u16 *flags, u8 *dfs,
|
||||
+ u8 pwr_mode)
|
||||
{
|
||||
struct hostapd_hw_modes *mode;
|
||||
int i, clen, rlen;
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -5038,6 +5038,19 @@ static int nl80211_set_channel(struct i8
|
||||
return -1;
|
||||
}
|
||||
|
||||
+#ifdef CONFIG_IEEE80211AX
|
||||
+ if (freq->freq && is_6ghz_freq(freq->freq)) {
|
||||
+ wpa_printf(MSG_DEBUG, "%s: 6g_reg_pwr_mode=%d",
|
||||
+ __func__, freq->he_6ghz_reg_pwr_type);
|
||||
+ if (nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE,
|
||||
+ freq->he_6ghz_reg_pwr_type)) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "%s: Failed to put 6g_reg_pwr_mode", __func__);
|
||||
+ nlmsg_free(msg);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+#endif /* CONFIG_IEEE80211AX */
|
||||
ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
if (ret == 0) {
|
||||
bss->freq = freq->freq;
|
||||
@@ -8303,7 +8316,7 @@ static int wpa_driver_nl80211_send_actio
|
||||
int i;
|
||||
|
||||
modes = nl80211_get_hw_feature_data(bss, &num_modes,
|
||||
- &flags, &dfs_domain);
|
||||
+ &flags, &dfs_domain, 0);
|
||||
if (dfs_domain != HOSTAPD_DFS_REGION_ETSI &&
|
||||
ieee80211_is_dfs(bss->freq, modes, num_modes))
|
||||
offchanok = 0;
|
||||
--- a/src/drivers/driver_nl80211.h
|
||||
+++ b/src/drivers/driver_nl80211.h
|
||||
@@ -285,7 +285,7 @@ int nl80211_send_monitor(struct wpa_driv
|
||||
int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv);
|
||||
struct hostapd_hw_modes *
|
||||
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
|
||||
- u8 *dfs_domain);
|
||||
+ u8 *dfs_domain, u8 pwr_mode);
|
||||
|
||||
int process_global_event(struct nl_msg *msg, void *arg);
|
||||
int process_bss_event(struct nl_msg *msg, void *arg);
|
||||
--- a/src/drivers/driver_nl80211_capa.c
|
||||
+++ b/src/drivers/driver_nl80211_capa.c
|
||||
@@ -1454,6 +1454,7 @@ struct phy_info_arg {
|
||||
int last_mode, last_chan_idx;
|
||||
int failed;
|
||||
u8 dfs_domain;
|
||||
+ u8 pwr_mode;
|
||||
};
|
||||
|
||||
static void phy_info_ht_capa(struct hostapd_hw_modes *mode, struct nlattr *capa,
|
||||
@@ -2102,7 +2103,9 @@ static void nl80211_set_ht40_mode_sec(st
|
||||
|
||||
|
||||
static void nl80211_reg_rule_max_eirp(u32 start, u32 end, u32 max_eirp,
|
||||
- struct phy_info_arg *results)
|
||||
+ struct phy_info_arg *results,
|
||||
+ u8 config_pwr_mode, u8 pwr_mode,
|
||||
+ s8 psd)
|
||||
{
|
||||
u16 m;
|
||||
|
||||
@@ -2112,10 +2115,16 @@ static void nl80211_reg_rule_max_eirp(u3
|
||||
|
||||
for (c = 0; c < mode->num_channels; c++) {
|
||||
struct hostapd_channel_data *chan = &mode->channels[c];
|
||||
+
|
||||
+ if (is_6ghz_freq(chan->freq) && config_pwr_mode != pwr_mode)
|
||||
+ continue;
|
||||
+
|
||||
if ((u32) chan->freq - 10 >= start &&
|
||||
(u32) chan->freq + 10 <= end)
|
||||
chan->max_tx_power = max_eirp;
|
||||
}
|
||||
+ /* Update the psd rules */
|
||||
+ mode->psd_values[pwr_mode] = psd;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2288,6 +2297,7 @@ static int nl80211_get_reg(struct nl_msg
|
||||
[NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
+ u8 config_pwr_mode = results->pwr_mode;
|
||||
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
if (!tb_msg[NL80211_ATTR_REG_ALPHA2] ||
|
||||
@@ -2312,6 +2322,8 @@ static int nl80211_get_reg(struct nl_msg
|
||||
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
|
||||
{
|
||||
u32 start, end, max_eirp = 0, max_bw = 0, flags = 0;
|
||||
+ u8 pwr_mode = 0;
|
||||
+ s8 psd = 0;
|
||||
nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX,
|
||||
nla_data(nl_rule), nla_len(nl_rule), reg_policy);
|
||||
if (tb_rule[NL80211_ATTR_FREQ_RANGE_START] == NULL ||
|
||||
@@ -2325,9 +2337,13 @@ static int nl80211_get_reg(struct nl_msg
|
||||
max_bw = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]) / 1000;
|
||||
if (tb_rule[NL80211_ATTR_REG_RULE_FLAGS])
|
||||
flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]);
|
||||
+ if (tb_rule[NL80211_ATTR_REG_POWER_MODE])
|
||||
+ pwr_mode = nla_get_u8(tb_rule[NL80211_ATTR_REG_POWER_MODE]);
|
||||
+ if (tb_rule[NL80211_ATTR_POWER_RULE_PSD])
|
||||
+ psd = (s8) nla_get_u8(tb_rule[NL80211_ATTR_POWER_RULE_PSD]);
|
||||
|
||||
- wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm%s%s%s%s%s%s%s%s",
|
||||
- start, end, max_bw, max_eirp,
|
||||
+ wpa_printf(MSG_DEBUG, "nl80211: %u-%u @ %u MHz %u mBm pwr_mode: %u psd: %d%s%s%s%s%s%s%s%s",
|
||||
+ start, end, max_bw, max_eirp, pwr_mode, psd,
|
||||
flags & NL80211_RRF_NO_OFDM ? " (no OFDM)" : "",
|
||||
flags & NL80211_RRF_NO_CCK ? " (no CCK)" : "",
|
||||
flags & NL80211_RRF_NO_INDOOR ? " (no indoor)" : "",
|
||||
@@ -2341,7 +2357,8 @@ static int nl80211_get_reg(struct nl_msg
|
||||
nl80211_reg_rule_ht40(start, end, results);
|
||||
if (tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP])
|
||||
nl80211_reg_rule_max_eirp(start, end, max_eirp,
|
||||
- results);
|
||||
+ results, config_pwr_mode,
|
||||
+ pwr_mode, psd);
|
||||
}
|
||||
|
||||
nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule)
|
||||
@@ -2441,7 +2458,7 @@ static void nl80211_dump_chan_list(struc
|
||||
|
||||
struct hostapd_hw_modes *
|
||||
nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags,
|
||||
- u8 *dfs_domain)
|
||||
+ u8 *dfs_domain, u8 pwr_mode)
|
||||
{
|
||||
u32 feat;
|
||||
struct i802_bss *bss = priv;
|
||||
@@ -2454,6 +2471,7 @@ nl80211_get_hw_feature_data(void *priv,
|
||||
.last_mode = -1,
|
||||
.failed = 0,
|
||||
.dfs_domain = 0,
|
||||
+ .pwr_mode = pwr_mode
|
||||
};
|
||||
|
||||
*num_modes = 0;
|
||||
--- a/src/drivers/driver_nl80211_event.c
|
||||
+++ b/src/drivers/driver_nl80211_event.c
|
||||
@@ -1919,7 +1919,7 @@ static unsigned int chan_to_freq(struct
|
||||
int i;
|
||||
|
||||
modes = nl80211_get_hw_feature_data(drv->first_bss, &num_modes,
|
||||
- &flags, &dfs_domain);
|
||||
+ &flags, &dfs_domain, 0);
|
||||
if (!modes) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"nl80211: Fetching hardware mode failed");
|
||||
--- a/src/drivers/nl80211_copy.h
|
||||
+++ b/src/drivers/nl80211_copy.h
|
||||
@@ -3127,6 +3127,8 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_BEACON_TX_MODE,
|
||||
|
||||
+ NL80211_ATTR_6G_REG_POWER_MODE,
|
||||
+
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@@ -3791,6 +3797,20 @@ enum nl80211_band_attr {
|
||||
|
||||
#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA
|
||||
|
||||
+enum nl80211_regulatory_power_modes {
|
||||
+ NL80211_REG_AP_LPI,
|
||||
+ NL80211_REG_AP_SP,
|
||||
+ NL80211_REG_AP_VLP,
|
||||
+ NL80211_REG_REGULAR_CLIENT_LPI,
|
||||
+ NL80211_REG_REGULAR_CLIENT_SP,
|
||||
+ NL80211_REG_REGULAR_CLIENT_VLP,
|
||||
+ NL80211_REG_SUBORDINATE_CLIENT_LPI,
|
||||
+ NL80211_REG_SUBORDINATE_CLIENT_SP,
|
||||
+ NL80211_REG_SUBORDINATE_CLIENT_VLP,
|
||||
+
|
||||
+ NL80211_REG_NUM_POWER_MODES,
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* enum nl80211_wmm_rule - regulatory wmm rule
|
||||
*
|
||||
@@ -4015,6 +4035,9 @@ enum nl80211_reg_type {
|
||||
* a given frequency range. The value is in mBm (100 * dBm).
|
||||
* @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
|
||||
* If not present or 0 default CAC time will be used.
|
||||
+ * @NL80211_ATTR_POWER_RULE_PSD: power spectral density (in dBm).
|
||||
+ * This could be negative.
|
||||
+ * @NL80211_ATTR_REG_POWER_MODE: the regulatory power mode for 6G rules
|
||||
* @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number
|
||||
* currently defined
|
||||
* @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use
|
||||
@@ -4032,6 +4055,10 @@ enum nl80211_reg_rule_attr {
|
||||
|
||||
NL80211_ATTR_DFS_CAC_TIME,
|
||||
|
||||
+ NL80211_ATTR_POWER_RULE_PSD,
|
||||
+
|
||||
+ NL80211_ATTR_REG_POWER_MODE,
|
||||
+
|
||||
/* keep last */
|
||||
__NL80211_REG_RULE_ATTR_AFTER_LAST,
|
||||
NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1
|
||||
--- a/wpa_supplicant/driver_i.h
|
||||
+++ b/wpa_supplicant/driver_i.h
|
||||
@@ -305,7 +305,7 @@ wpa_drv_get_hw_feature_data(struct wpa_s
|
||||
if (wpa_s->driver->get_hw_feature_data)
|
||||
return wpa_s->driver->get_hw_feature_data(wpa_s->drv_priv,
|
||||
num_modes, flags,
|
||||
- dfs_domain);
|
||||
+ dfs_domain, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
--- a/wpa_supplicant/mesh.c
|
||||
+++ b/wpa_supplicant/mesh.c
|
||||
@@ -231,7 +231,7 @@ static int wpas_mesh_update_freq_params(
|
||||
hostapd_get_oper_centr_freq_seg0_idx(ifmsh->conf),
|
||||
hostapd_get_oper_centr_freq_seg1_idx(ifmsh->conf),
|
||||
ifmsh->conf->vht_capab,
|
||||
- he_capab)) {
|
||||
+ he_capab, ifmsh->conf->he_6ghz_reg_pwr_type)) {
|
||||
wpa_printf(MSG_ERROR, "Error updating mesh frequency params");
|
||||
wpa_supplicant_mesh_deinit(wpa_s, true);
|
||||
return -1;
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2788,7 +2788,7 @@ skip_to_6ghz:
|
||||
vht_freq.vht_enabled, vht_freq.he_enabled,
|
||||
freq->sec_channel_offset,
|
||||
chwidth, seg0, seg1, vht_caps,
|
||||
- &mode->he_capab[ieee80211_mode]) != 0)
|
||||
+ &mode->he_capab[ieee80211_mode], 0) != 0)
|
||||
return;
|
||||
|
||||
*freq = vht_freq;
|
||||
--- a/hostapd/config_file.c
|
||||
+++ b/hostapd/config_file.c
|
||||
@@ -3510,6 +3510,15 @@ static int hostapd_config_fill(struct ho
|
||||
}
|
||||
} else if (os_strcmp(buf, "he_6ghz_reg_pwr_type") == 0) {
|
||||
conf->he_6ghz_reg_pwr_type = atoi(pos);
|
||||
+ if (conf->he_6ghz_reg_pwr_type > AP_TYPE_6GHZ_VERY_LOW_POWER_AP ||
|
||||
+ conf->he_6ghz_reg_pwr_type < AP_TYPE_6GHZ_INDOOR_AP) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "Line %d: Invalid 6ghz regulatory power type('%s') "
|
||||
+ "[min: %d and max: %d]",
|
||||
+ line, pos, AP_TYPE_6GHZ_INDOOR_AP,
|
||||
+ AP_TYPE_6GHZ_VERY_LOW_POWER_AP);
|
||||
+ return 1;
|
||||
+ }
|
||||
} else if (os_strcmp(buf, "he_oper_chwidth") == 0) {
|
||||
conf->he_oper_chwidth = atoi(pos);
|
||||
} else if (os_strcmp(buf, "he_oper_centr_freq_seg0_idx") == 0) {
|
||||
@@ -1,350 +0,0 @@
|
||||
From 24763e3cd0a564eb71f3c501bbb4fbb0d7070762 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Fri, 15 Apr 2022 17:31:48 +0300
|
||||
Subject: [PATCH] RADIUS: Attributes with Extended Types (RFC 6929)
|
||||
|
||||
Supported extended types for RADIUS attributes for the cases defined in
|
||||
RFC 6929.
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/radius/radius.c | 195 ++++++++++++++++++++++++++++++++++++++------
|
||||
src/radius/radius.h | 26 +++++-
|
||||
2 files changed, 193 insertions(+), 28 deletions(-)
|
||||
|
||||
diff --git a/src/radius/radius.c b/src/radius/radius.c
|
||||
index be16e27b9..a64228067 100644
|
||||
--- a/src/radius/radius.c
|
||||
+++ b/src/radius/radius.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* RADIUS message processing
|
||||
- * Copyright (c) 2002-2009, 2011-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2009, 2011-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -159,7 +159,8 @@ static const char *radius_code_string(u8 code)
|
||||
|
||||
|
||||
struct radius_attr_type {
|
||||
- u8 type;
|
||||
+ u16 type; /* 0..255 for basic types;
|
||||
+ * (241 << 8) | <ext-type> for extended types */
|
||||
char *name;
|
||||
enum {
|
||||
RADIUS_ATTR_UNDIST, RADIUS_ATTR_TEXT, RADIUS_ATTR_IP,
|
||||
@@ -260,11 +261,31 @@ static const struct radius_attr_type radius_attrs[] =
|
||||
RADIUS_ATTR_HEXDUMP },
|
||||
{ RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER, "WLAN-Group-Mgmt-Pairwise-Cipher",
|
||||
RADIUS_ATTR_HEXDUMP },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_1, "Extended-Type-1", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_2, "Extended-Type-2", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_3, "Extended-Type-3", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_TYPE_4, "Extended-Type-4", RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_LONG_EXT_TYPE_1, "Long-Extended-Type-1",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_LONG_EXT_TYPE_2, "Long-Extended-Type-2",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1, "Extended-Vendor-Specific-1",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2, "Extended-Vendor-Specific-2",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3, "Extended-Vendor-Specific-3",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4, "Extended-Vendor-Specific-4",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5, "Extended-Vendor-Specific-5",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
+ { RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6, "Extended-Vendor-Specific-6",
|
||||
+ RADIUS_ATTR_UNDIST },
|
||||
};
|
||||
#define RADIUS_ATTRS ARRAY_SIZE(radius_attrs)
|
||||
|
||||
|
||||
-static const struct radius_attr_type *radius_get_attr_type(u8 type)
|
||||
+static const struct radius_attr_type * radius_get_attr_type(u16 type)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
@@ -277,23 +298,60 @@ static const struct radius_attr_type *radius_get_attr_type(u8 type)
|
||||
}
|
||||
|
||||
|
||||
+static bool radius_is_long_ext_type(u8 type)
|
||||
+{
|
||||
+ return type == RADIUS_ATTR_LONG_EXT_TYPE_1 ||
|
||||
+ type == RADIUS_ATTR_LONG_EXT_TYPE_2;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static bool radius_is_ext_type(u8 type)
|
||||
+{
|
||||
+ return type >= RADIUS_ATTR_EXT_TYPE_1 &&
|
||||
+ type <= RADIUS_ATTR_LONG_EXT_TYPE_2;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static void radius_msg_dump_attr(struct radius_attr_hdr *hdr)
|
||||
{
|
||||
+ struct radius_attr_hdr_ext *ext = NULL;
|
||||
const struct radius_attr_type *attr;
|
||||
int len;
|
||||
unsigned char *pos;
|
||||
char buf[1000];
|
||||
|
||||
- attr = radius_get_attr_type(hdr->type);
|
||||
+ if (hdr->length < sizeof(struct radius_attr_hdr))
|
||||
+ return;
|
||||
|
||||
- wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
|
||||
- hdr->type, attr ? attr->name : "?Unknown?", hdr->length);
|
||||
+ if (radius_is_ext_type(hdr->type)) {
|
||||
+ if (hdr->length < 4) {
|
||||
+ wpa_printf(MSG_INFO,
|
||||
+ " Invalid attribute %d (too short for extended type)",
|
||||
+ hdr->type);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (attr == NULL || hdr->length < sizeof(struct radius_attr_hdr))
|
||||
- return;
|
||||
+ ext = (struct radius_attr_hdr_ext *) hdr;
|
||||
+ }
|
||||
+
|
||||
+ if (ext) {
|
||||
+ attr = radius_get_attr_type((ext->type << 8) | ext->ext_type);
|
||||
+ wpa_printf(MSG_INFO, " Attribute %d.%d (%s) length=%d",
|
||||
+ ext->type, ext->ext_type,
|
||||
+ attr ? attr->name : "?Unknown?", ext->length);
|
||||
+ pos = (unsigned char *) (ext + 1);
|
||||
+ len = ext->length - sizeof(struct radius_attr_hdr_ext);
|
||||
+ } else {
|
||||
+ attr = radius_get_attr_type(hdr->type);
|
||||
+ wpa_printf(MSG_INFO, " Attribute %d (%s) length=%d",
|
||||
+ hdr->type, attr ? attr->name : "?Unknown?",
|
||||
+ hdr->length);
|
||||
+ pos = (unsigned char *) (hdr + 1);
|
||||
+ len = hdr->length - sizeof(struct radius_attr_hdr);
|
||||
+ }
|
||||
|
||||
- len = hdr->length - sizeof(struct radius_attr_hdr);
|
||||
- pos = (unsigned char *) (hdr + 1);
|
||||
+ if (!attr)
|
||||
+ return;
|
||||
|
||||
switch (attr->data_type) {
|
||||
case RADIUS_ATTR_TEXT:
|
||||
@@ -627,22 +685,54 @@ static int radius_msg_add_attr_to_array(struct radius_msg *msg,
|
||||
}
|
||||
|
||||
|
||||
-struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
- const u8 *data, size_t data_len)
|
||||
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
|
||||
+ const u8 *data, size_t data_len)
|
||||
{
|
||||
- size_t buf_needed;
|
||||
- struct radius_attr_hdr *attr;
|
||||
+ size_t buf_needed, max_len;
|
||||
+ struct radius_attr_hdr *attr = NULL;
|
||||
+ struct radius_attr_hdr_ext *ext;
|
||||
+ u8 ext_type = 0;
|
||||
|
||||
if (TEST_FAIL())
|
||||
return NULL;
|
||||
|
||||
- if (data_len > RADIUS_MAX_ATTR_LEN) {
|
||||
- wpa_printf(MSG_ERROR, "radius_msg_add_attr: too long attribute (%lu bytes)",
|
||||
- (unsigned long) data_len);
|
||||
- return NULL;
|
||||
+ if (type > 255) {
|
||||
+ if (!radius_is_ext_type(type >> 8)) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "%s: Undefined extended type %d.%d",
|
||||
+ __func__, type >> 8, type & 0xff);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ ext_type = type & 0xff;
|
||||
+ type >>= 8;
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ wpa_printf(MSG_ERROR, "%s: Unexpected extended type use for %d",
|
||||
+ __func__, type);
|
||||
}
|
||||
|
||||
- buf_needed = sizeof(*attr) + data_len;
|
||||
+ if (radius_is_long_ext_type(type)) {
|
||||
+ size_t hdr_len = sizeof(struct radius_attr_hdr_ext) + 1;
|
||||
+ size_t plen = 255 - hdr_len;
|
||||
+ size_t num;
|
||||
+
|
||||
+ max_len = 4096;
|
||||
+ num = (data_len + plen - 1) / plen;
|
||||
+ if (num == 0)
|
||||
+ num = 1;
|
||||
+ buf_needed = num * hdr_len + data_len;
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ max_len = RADIUS_MAX_EXT_ATTR_LEN;
|
||||
+ buf_needed = sizeof(struct radius_attr_hdr_ext) + data_len;
|
||||
+ } else {
|
||||
+ max_len = RADIUS_MAX_ATTR_LEN;
|
||||
+ buf_needed = sizeof(*attr) + data_len;
|
||||
+ }
|
||||
+ if (data_len > max_len) {
|
||||
+ wpa_printf(MSG_ERROR,
|
||||
+ "%s: too long attribute (%zu > %zu bytes)",
|
||||
+ __func__, data_len, max_len);
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
if (wpabuf_tailroom(msg->buf) < buf_needed) {
|
||||
/* allocate more space for message buffer */
|
||||
@@ -651,13 +741,44 @@ struct radius_attr_hdr *radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
msg->hdr = wpabuf_mhead(msg->buf);
|
||||
}
|
||||
|
||||
- attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
|
||||
- attr->type = type;
|
||||
- attr->length = sizeof(*attr) + data_len;
|
||||
- wpabuf_put_data(msg->buf, data, data_len);
|
||||
-
|
||||
- if (radius_msg_add_attr_to_array(msg, attr))
|
||||
- return NULL;
|
||||
+ if (radius_is_long_ext_type(type)) {
|
||||
+ size_t plen = 255 - sizeof(struct radius_attr_hdr_ext) - 1;
|
||||
+ size_t alen;
|
||||
+
|
||||
+ do {
|
||||
+ alen = data_len > plen ? plen : data_len;
|
||||
+ ext = wpabuf_put(msg->buf,
|
||||
+ sizeof(struct radius_attr_hdr_ext));
|
||||
+ if (!attr)
|
||||
+ attr = (struct radius_attr_hdr *) ext;
|
||||
+ ext->type = type;
|
||||
+ ext->length = sizeof(*ext) + 1 + alen;
|
||||
+ ext->ext_type = ext_type;
|
||||
+ wpabuf_put_u8(msg->buf, data_len > alen ? 0x80 : 0);
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ data += alen;
|
||||
+ data_len -= alen;
|
||||
+ if (radius_msg_add_attr_to_array(
|
||||
+ msg, (struct radius_attr_hdr *) ext))
|
||||
+ return NULL;
|
||||
+ } while (data_len > 0);
|
||||
+ } else if (radius_is_ext_type(type)) {
|
||||
+ ext = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr_ext));
|
||||
+ attr = (struct radius_attr_hdr *) ext;
|
||||
+ ext->type = type;
|
||||
+ ext->length = sizeof(*ext) + data_len;
|
||||
+ ext->ext_type = ext_type;
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ if (radius_msg_add_attr_to_array(msg, attr))
|
||||
+ return NULL;
|
||||
+ } else {
|
||||
+ attr = wpabuf_put(msg->buf, sizeof(struct radius_attr_hdr));
|
||||
+ attr->type = type;
|
||||
+ attr->length = sizeof(*attr) + data_len;
|
||||
+ wpabuf_put_data(msg->buf, data, data_len);
|
||||
+ if (radius_msg_add_attr_to_array(msg, attr))
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
return attr;
|
||||
}
|
||||
@@ -1285,6 +1406,28 @@ int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
|
||||
}
|
||||
|
||||
|
||||
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
|
||||
+ u8 vendor_type, const u8 *data, size_t len)
|
||||
+{
|
||||
+ struct radius_attr_hdr *attr;
|
||||
+ u8 *buf, *pos;
|
||||
+ size_t alen;
|
||||
+
|
||||
+ alen = 4 + 1 + len;
|
||||
+ buf = os_malloc(alen);
|
||||
+ if (!buf)
|
||||
+ return 0;
|
||||
+ pos = buf;
|
||||
+ WPA_PUT_BE32(pos, vendor_id);
|
||||
+ pos += 4;
|
||||
+ *pos++ = vendor_type;
|
||||
+ os_memcpy(pos, data, len);
|
||||
+ attr = radius_msg_add_attr(msg, type, buf, alen);
|
||||
+ os_free(buf);
|
||||
+ return attr != NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int radius_user_password_hide(struct radius_msg *msg,
|
||||
const u8 *data, size_t data_len,
|
||||
const u8 *secret, size_t secret_len,
|
||||
diff --git a/src/radius/radius.h b/src/radius/radius.h
|
||||
index fb8148180..490c8d1f6 100644
|
||||
--- a/src/radius/radius.h
|
||||
+++ b/src/radius/radius.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* RADIUS message processing
|
||||
- * Copyright (c) 2002-2009, 2012, 2014-2015, Jouni Malinen <j@w1.fi>
|
||||
+ * Copyright (c) 2002-2009, 2012, 2014-2022, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
@@ -46,7 +46,15 @@ struct radius_attr_hdr {
|
||||
/* followed by length-2 octets of attribute value */
|
||||
} STRUCT_PACKED;
|
||||
|
||||
+struct radius_attr_hdr_ext {
|
||||
+ u8 type;
|
||||
+ u8 length; /* including this header */
|
||||
+ u8 ext_type;
|
||||
+ /* followed by length-3 octets of attribute value */
|
||||
+} STRUCT_PACKED;
|
||||
+
|
||||
#define RADIUS_MAX_ATTR_LEN (255 - sizeof(struct radius_attr_hdr))
|
||||
+#define RADIUS_MAX_EXT_ATTR_LEN (255 - sizeof(struct radius_attr_hdr_ext))
|
||||
|
||||
enum { RADIUS_ATTR_USER_NAME = 1,
|
||||
RADIUS_ATTR_USER_PASSWORD = 2,
|
||||
@@ -113,6 +121,18 @@ enum { RADIUS_ATTR_USER_NAME = 1,
|
||||
RADIUS_ATTR_WLAN_GROUP_CIPHER = 187,
|
||||
RADIUS_ATTR_WLAN_AKM_SUITE = 188,
|
||||
RADIUS_ATTR_WLAN_GROUP_MGMT_CIPHER = 189,
|
||||
+ RADIUS_ATTR_EXT_TYPE_1 = 241,
|
||||
+ RADIUS_ATTR_EXT_TYPE_2 = 242,
|
||||
+ RADIUS_ATTR_EXT_TYPE_3 = 243,
|
||||
+ RADIUS_ATTR_EXT_TYPE_4 = 244,
|
||||
+ RADIUS_ATTR_LONG_EXT_TYPE_1 = 245,
|
||||
+ RADIUS_ATTR_LONG_EXT_TYPE_2 = 246,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_1 = (241 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_2 = (242 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_3 = (243 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_4 = (244 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5 = (245 << 8) | 26,
|
||||
+ RADIUS_ATTR_EXT_VENDOR_SPECIFIC_6 = (246 << 8) | 26,
|
||||
};
|
||||
|
||||
|
||||
@@ -257,7 +277,7 @@ int radius_msg_verify_acct_req(struct radius_msg *msg, const u8 *secret,
|
||||
int radius_msg_verify_das_req(struct radius_msg *msg, const u8 *secret,
|
||||
size_t secret_len,
|
||||
int require_message_authenticator);
|
||||
-struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u8 type,
|
||||
+struct radius_attr_hdr * radius_msg_add_attr(struct radius_msg *msg, u16 type,
|
||||
const u8 *data, size_t data_len);
|
||||
struct radius_msg * radius_msg_parse(const u8 *data, size_t len);
|
||||
int radius_msg_add_eap(struct radius_msg *msg, const u8 *data,
|
||||
@@ -284,6 +304,8 @@ int radius_msg_add_mppe_keys(struct radius_msg *msg,
|
||||
const u8 *recv_key, size_t recv_key_len);
|
||||
int radius_msg_add_wfa(struct radius_msg *msg, u8 subtype, const u8 *data,
|
||||
size_t len);
|
||||
+int radius_msg_add_ext_vs(struct radius_msg *msg, u16 type, u32 vendor_id,
|
||||
+ u8 vendor_type, const u8 *data, size_t len);
|
||||
int radius_user_password_hide(struct radius_msg *msg,
|
||||
const u8 *data, size_t data_len,
|
||||
const u8 *secret, size_t secret_len,
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
From 2a556ebff47bebcda6a1c7c8cd760bd38de54ff4 Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 22 Oct 2021 22:50:37 +0530
|
||||
Subject: [PATCH] hostapd: add support for 6g client type
|
||||
|
||||
IEEE Std 802.11ax™‐2021 introduces two types of client
|
||||
namely DEFAULT and SUBORDINATE client for 6GHz device.
|
||||
|
||||
This patch -
|
||||
* add u8 he_6ghz_reg_client_type member in struct wpa_config
|
||||
to store the 6g configured mode.
|
||||
* add new nl80211 ops - set_6gclient_type, which will be used
|
||||
to send the 6G client type via existing NL80211_CMD_SET_INTERFACE
|
||||
command.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
---
|
||||
src/drivers/driver.h | 8 ++++++++
|
||||
src/drivers/driver_nl80211.c | 26 ++++++++++++++++++++++++++
|
||||
wpa_supplicant/config.c | 2 ++
|
||||
wpa_supplicant/config.h | 11 +++++++++++
|
||||
wpa_supplicant/driver_i.h | 8 ++++++++
|
||||
wpa_supplicant/wpa_supplicant.c | 9 +++++++++
|
||||
6 files changed, 64 insertions(+)
|
||||
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -4694,6 +4694,14 @@ struct wpa_driver_ops {
|
||||
* explicitly allow reception of broadcast Public Action frames.
|
||||
*/
|
||||
int (*dpp_listen)(void *priv, bool enable);
|
||||
+
|
||||
+ /**
|
||||
+ * set_6gclient_type - Set the client type for 6G interface
|
||||
+ * @priv: Private driver interface data
|
||||
+ * @client_type_6g: 0 - Default Client, 1 - Subordinate Client
|
||||
+ * Returns: 0 on success, < 0 on failure
|
||||
+ */
|
||||
+ int (*set_6gclient_type)(void *priv, u8 client_type_6g);
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -12173,6 +12173,31 @@ static int nl80211_dpp_listen(void *priv
|
||||
}
|
||||
#endif /* CONFIG_DPP */
|
||||
|
||||
+static int nl80211_set_6gclient_type(void *priv, u8 client_type_6g)
|
||||
+{
|
||||
+ struct i802_bss *bss = priv;
|
||||
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
+ struct nl_msg *msg;
|
||||
+ int ret = -ENOBUFS;
|
||||
+
|
||||
+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type: %d",
|
||||
+ client_type_6g);
|
||||
+
|
||||
+ msg = nl80211_cmd_msg(drv->first_bss, 0, NL80211_CMD_SET_INTERFACE);
|
||||
+ if (!msg || nla_put_u8(msg, NL80211_ATTR_6G_REG_POWER_MODE,
|
||||
+ client_type_6g))
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
||||
+
|
||||
+ if(ret)
|
||||
+ wpa_printf(MSG_DEBUG, "nl80211: 6g client type could not be set (%d)",
|
||||
+ ret);
|
||||
+ return ret;
|
||||
+fail:
|
||||
+ nlmsg_free(msg);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||
.name = "nl80211",
|
||||
@@ -12315,4 +12340,5 @@ const struct wpa_driver_ops wpa_driver_n
|
||||
#ifdef CONFIG_DPP
|
||||
.dpp_listen = nl80211_dpp_listen,
|
||||
#endif /* CONFIG_DPP */
|
||||
+ .set_6gclient_type = nl80211_set_6gclient_type,
|
||||
};
|
||||
--- a/wpa_supplicant/config.c
|
||||
+++ b/wpa_supplicant/config.c
|
||||
@@ -5394,6 +5394,8 @@ static const struct global_parse_data gl
|
||||
{ INT_RANGE(force_kdk_derivation, 0, 1), 0 },
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
#endif /* CONFIG_PASN */
|
||||
+ { INT_RANGE(he_6ghz_reg_client_type, 1, 2),
|
||||
+ CFG_CHANGED_HE_6GHZ_CLIENT_TYPE},
|
||||
};
|
||||
|
||||
#undef FUNC
|
||||
--- a/wpa_supplicant/config.h
|
||||
+++ b/wpa_supplicant/config.h
|
||||
@@ -378,6 +378,7 @@ struct wpa_cred {
|
||||
#define CFG_CHANGED_WOWLAN_TRIGGERS BIT(18)
|
||||
#define CFG_CHANGED_DISABLE_BTM BIT(19)
|
||||
#define CFG_CHANGED_BGSCAN BIT(20)
|
||||
+#define CFG_CHANGED_HE_6GHZ_CLIENT_TYPE BIT(21)
|
||||
|
||||
/**
|
||||
* struct wpa_config - wpa_supplicant configuration data
|
||||
@@ -1650,6 +1651,16 @@ struct wpa_config {
|
||||
int force_kdk_derivation;
|
||||
#endif /* CONFIG_TESTING_OPTIONS */
|
||||
#endif /* CONFIG_PASN*/
|
||||
+
|
||||
+ /**
|
||||
+ * he_6ghz_reg_client_type - Type of client in 6GHz band
|
||||
+ *
|
||||
+ * IEEE Std 802.11ax™‐2021 allows two kinds of client
|
||||
+ *
|
||||
+ * 1 = DEFAULT or REGULAR CLIENT
|
||||
+ * 2 = SUBORDINATE CLIENT
|
||||
+ */
|
||||
+ u8 he_6ghz_reg_client_type;
|
||||
};
|
||||
|
||||
|
||||
--- a/wpa_supplicant/driver_i.h
|
||||
+++ b/wpa_supplicant/driver_i.h
|
||||
@@ -1117,4 +1117,12 @@ static inline int wpa_drv_dpp_listen(str
|
||||
return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
|
||||
}
|
||||
|
||||
+static inline int wpa_drv_set_6gclient_type(struct wpa_supplicant *wpa_s,
|
||||
+ u8 he_6ghz_reg_client_type)
|
||||
+{
|
||||
+ if (!wpa_s->driver->set_6gclient_type)
|
||||
+ return -1;
|
||||
+ return wpa_s->driver->set_6gclient_type(wpa_s->drv_priv,
|
||||
+ he_6ghz_reg_client_type);
|
||||
+}
|
||||
#endif /* DRIVER_I_H */
|
||||
--- a/wpa_supplicant/wpa_supplicant.c
|
||||
+++ b/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -5212,6 +5212,15 @@ int wpa_supplicant_driver_init(struct wp
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "RSN: flushing PMKID list in the driver");
|
||||
wpa_drv_flush_pmkid(wpa_s);
|
||||
|
||||
+ /* Before starting scan, for 6g interface, set the client type */
|
||||
+ if (wpa_s->conf->changed_parameters & CFG_CHANGED_HE_6GHZ_CLIENT_TYPE) {
|
||||
+ u8 he_6ghz_reg_client_type = wpa_s->conf->he_6ghz_reg_client_type;
|
||||
+ /**
|
||||
+ * Subtract 1 to map the client type with 0 indexing
|
||||
+ */
|
||||
+ wpa_drv_set_6gclient_type(wpa_s, he_6ghz_reg_client_type - 1);
|
||||
+ }
|
||||
+
|
||||
wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
|
||||
wpa_s->prev_scan_wildcard = 0;
|
||||
|
||||
--- a/wpa_supplicant/wpa_supplicant.conf
|
||||
+++ b/wpa_supplicant/wpa_supplicant.conf
|
||||
@@ -589,6 +589,15 @@ fast_reauth=1
|
||||
# 1 = Publish
|
||||
#ftm_initiator=0
|
||||
|
||||
+# 6GHz regulatory client type
|
||||
+# This sets the 6GHz client type. Possible options are
|
||||
+# 1 = Default Client
|
||||
+# 2 = Subordinate Client
|
||||
+# Note that value 0 is reserved and can not be used. For 6GHz operation
|
||||
+# user has to choose from either 1 or 2. If not mentioned, no type will
|
||||
+# be set from user side. Wireless stack will handle its own default case.
|
||||
+#he_6ghz_reg_client_type=1
|
||||
+
|
||||
# credential block
|
||||
#
|
||||
# Each credential used for automatic network selection is configured as a set
|
||||
@@ -1,102 +0,0 @@
|
||||
From b94371af8402f60218716552e571ca72cff4e3c0 Mon Sep 17 00:00:00 2001
|
||||
From: Jouni Malinen <j@w1.fi>
|
||||
Date: Fri, 15 Apr 2022 17:36:25 +0300
|
||||
Subject: [PATCH] RADIUS attributes for EAPOL-Key message details
|
||||
|
||||
Use vendor specific RADIUS attributes for sending ANonce and EAPOL-Key
|
||||
msg 2/4 for the wpa_psk_radius=3 case. The vendor specific attributes
|
||||
for this are defined in FreeRADIUS as follows:
|
||||
|
||||
BEGIN-VENDOR FreeRADIUS format=Extended-Vendor-Specific-5
|
||||
ATTRIBUTE FreeRADIUS-802.1X-Anonce 1 octets[32]
|
||||
ATTRIBUTE FreeRADIUS-802.1X-EAPoL-Key-Msg 2 octets
|
||||
END-VENDOR FreeRADIUS
|
||||
|
||||
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||
---
|
||||
src/ap/ieee802_11_auth.c | 29 +++++++++++++++++++++++++++++
|
||||
src/radius/radius.h | 7 +++++++
|
||||
2 files changed, 36 insertions(+)
|
||||
|
||||
diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
|
||||
index a54d7616e..4277d82cb 100644
|
||||
--- a/src/ap/ieee802_11_auth.c
|
||||
+++ b/src/ap/ieee802_11_auth.c
|
||||
@@ -47,6 +47,9 @@ struct hostapd_acl_query_data {
|
||||
struct hostapd_acl_query_data *next;
|
||||
bool radius_psk;
|
||||
int akm;
|
||||
+ u8 *anonce;
|
||||
+ u8 *eapol;
|
||||
+ size_t eapol_len;
|
||||
};
|
||||
|
||||
|
||||
@@ -102,6 +105,8 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
|
||||
if (!query)
|
||||
return;
|
||||
os_free(query->auth_msg);
|
||||
+ os_free(query->anonce);
|
||||
+ os_free(query->eapol);
|
||||
os_free(query);
|
||||
}
|
||||
|
||||
@@ -164,6 +169,24 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (query->anonce &&
|
||||
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
|
||||
+ RADIUS_VENDOR_ID_FREERADIUS,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE,
|
||||
+ query->anonce, WPA_NONCE_LEN)) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-Anonce");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (query->eapol &&
|
||||
+ !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
|
||||
+ RADIUS_VENDOR_ID_FREERADIUS,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG,
|
||||
+ query->eapol, query->eapol_len)) {
|
||||
+ wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-EAPoL-Key-Msg");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
|
||||
goto fail;
|
||||
return 0;
|
||||
@@ -703,6 +726,12 @@ void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
|
||||
query->akm = key_mgmt;
|
||||
os_get_reltime(&query->timestamp);
|
||||
os_memcpy(query->addr, addr, ETH_ALEN);
|
||||
+ if (anonce)
|
||||
+ query->anonce = os_memdup(anonce, WPA_NONCE_LEN);
|
||||
+ if (eapol) {
|
||||
+ query->eapol = os_memdup(eapol, eapol_len);
|
||||
+ query->eapol_len = eapol_len;
|
||||
+ }
|
||||
if (hostapd_radius_acl_query(hapd, addr, query)) {
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"Failed to send Access-Request for RADIUS PSK/ACL query");
|
||||
diff --git a/src/radius/radius.h b/src/radius/radius.h
|
||||
index 490c8d1f6..177c64a66 100644
|
||||
--- a/src/radius/radius.h
|
||||
+++ b/src/radius/radius.h
|
||||
@@ -208,6 +208,13 @@ enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
|
||||
RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
|
||||
};
|
||||
|
||||
+/* FreeRADIUS vendor-specific attributes */
|
||||
+#define RADIUS_VENDOR_ID_FREERADIUS 11344
|
||||
+/* Extended-Vendor-Specific-5 (245.26; long extended header) */
|
||||
+enum {
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE = 1,
|
||||
+ RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG = 2,
|
||||
+};
|
||||
|
||||
/* Hotspot 2.0 - WFA Vendor-specific RADIUS Attributes */
|
||||
#define RADIUS_VENDOR_ID_WFA 40808
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
From bd267ee2e6c1ce5165bf8be9411b398709f83a8f Mon Sep 17 00:00:00 2001
|
||||
From: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
Date: Fri, 19 Nov 2021 19:51:04 +0530
|
||||
Subject: [PATCH] hostapd: fix 6GHz chan switch issue
|
||||
|
||||
If user doesnt provide HE parameter in the hostapd_cli chan_switch
|
||||
command, by default HE should be enabled for 6 GHz frequency range.
|
||||
This is because, 6 GHz does not support legacy mode. Similarly, if
|
||||
bandwidth isnt provided, 20 MHz should be taken as default bandwidth.
|
||||
|
||||
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
|
||||
---
|
||||
hostapd/ctrl_iface.c | 24 ++++++++++++++++++------
|
||||
1 file changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
|
||||
index 664711d..3c2d51c 100644
|
||||
--- a/hostapd/ctrl_iface.c
|
||||
+++ b/hostapd/ctrl_iface.c
|
||||
@@ -2530,12 +2530,24 @@ static int hostapd_ctrl_check_freq_params(struct hostapd_freq_params *params)
|
||||
{
|
||||
int idx, bw, bw_idx[] = { 20, 40, 80, 160 };
|
||||
|
||||
- if (is_6ghz_freq(params->freq) && params->center_freq1) {
|
||||
- idx = (params->center_freq1 - 5950) / 5;
|
||||
- bw = center_idx_to_bw_6ghz(idx);
|
||||
-
|
||||
- if (bw < 0 || (bw_idx[bw] != params->bandwidth))
|
||||
- return -1;
|
||||
+ if (is_6ghz_freq(params->freq)) {
|
||||
+ /* Verify if HE was enabled by user or not. 6 GHz does not
|
||||
+ * support legacy mode. Hence, enable HE if not given */
|
||||
+ if (!params->he_enabled)
|
||||
+ params->he_enabled = 1;
|
||||
+
|
||||
+ /* By default in 6 GHz, HE 20 mode should be selected */
|
||||
+ if (!params->center_freq1 && params->bandwidth == 0) {
|
||||
+ params->center_freq1 = params->freq;
|
||||
+ /* If bw is not given by user, by default assuming 20 */
|
||||
+ params->bandwidth = 20;
|
||||
+ } else {
|
||||
+ idx = (params->center_freq1 - 5950) / 5;
|
||||
+ bw = center_idx_to_bw_6ghz(idx);
|
||||
+
|
||||
+ if (bw < 0 || (bw_idx[bw] != params->bandwidth))
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
|
||||
switch (params->bandwidth) {
|
||||
--
|
||||
2.7.4
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 473175ab3030092aa75c9e4e3daf81eb50da0278 Mon Sep 17 00:00:00 2001
|
||||
From: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
|
||||
Date: Tue, 4 Jan 2022 13:22:18 +0530
|
||||
Subject: [PATCH] wpa_supplicant: support 5.9 channels in mesh 160mhz
|
||||
|
||||
currently, mesh supported 5.9 channels on 80Mhz. This patch supports
|
||||
5.9 channels to bring up at 160mhz based on channel availability.
|
||||
|
||||
Signed-off-by: Thiraviyam Mariyappan <quic_tmariyap@quicinc.com>
|
||||
---
|
||||
wpa_supplicant/wpa_supplicant.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2511,7 +2511,7 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
unsigned int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955,
|
||||
6035, 6115, 6195, 6275, 6355, 6435, 6515,
|
||||
6595, 6675, 6755, 6835, 6915, 6995 };
|
||||
- unsigned int bw160[] = { 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
+ unsigned int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
|
||||
u8 channel;
|
||||
int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan);
|
||||
@@ -2767,9 +2767,9 @@ skip_to_6ghz:
|
||||
seg0 = freq->channel + 6;
|
||||
seg1 = 0;
|
||||
|
||||
-/* setup center_freq1 for 6G 160MHz */
|
||||
+ /* setup center_freq1 for 160MHz */
|
||||
if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
|
||||
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && is_6ghz) {
|
||||
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) {
|
||||
|
||||
for (j = 0; j < ARRAY_SIZE(bw160); j++) {
|
||||
if (freq->freq == bw160[j]) {
|
||||
@@ -2779,7 +2779,7 @@ skip_to_6ghz:
|
||||
int channel = freq->channel + 16;
|
||||
|
||||
if (!ibss_mesh_is_80mhz_avail(channel, mode))
|
||||
- return;
|
||||
+ break;
|
||||
|
||||
chwidth = CHANWIDTH_160MHZ;
|
||||
seg0 = freq->channel + 14;
|
||||
@@ -0,0 +1,250 @@
|
||||
From d6e52c4ef2bb8e915cae088564c412583f1794c9 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Fri, 21 Jan 2022 09:44:15 +0530
|
||||
Subject: [PATCH] mesh: enable more 160MHz channels in 6GHz
|
||||
|
||||
Current 160MHz implementation supports mesh bringup in limited channels.
|
||||
Allow all the 6GHz 80MHz channels to support 160MHz if the secondary 80MHz
|
||||
is available.
|
||||
|
||||
Ex: User can bringup 160MHz in 49th channel (primary 80MHz) based on 33rd
|
||||
channel(secondary 80MHz) availablity.
|
||||
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
---
|
||||
wpa_supplicant/wpa_supplicant.c | 21 ++++++++++++++++++---
|
||||
1 file changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.c
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.c
|
||||
@@ -2508,12 +2508,20 @@ void ibss_mesh_setup_freq(struct wpa_sup
|
||||
struct hostapd_hw_modes *mode = NULL;
|
||||
int ht40plus[] = { 1, 2, 3, 4, 5, 6, 36, 44, 52, 60, 100, 108, 116, 124, 132, 149, 157,
|
||||
165, 173, 184, 192 };
|
||||
- unsigned int bw80[] = { 5180, 5260, 5500, 5580, 5660, 5745, 5825, 5955,
|
||||
- 6035, 6115, 6195, 6275, 6355, 6435, 6515,
|
||||
- 6595, 6675, 6755, 6835, 6915, 6995 };
|
||||
- unsigned int bw160[] = { 5745, 5955, 6115, 6275, 6435, 6595, 6755, 6915 };
|
||||
+ /* bw_80_160 array members are 80MHz start freq, 80MHz end freq and so on
|
||||
+ */
|
||||
+ unsigned int bw_80_160[] = { 5180, 5240, 5260, 5320,
|
||||
+ 5500, 5560, 5580, 5660,
|
||||
+ 5745, 5805, 5825, 5885,
|
||||
+ 5955, 6015, 6035, 6095,
|
||||
+ 6115, 6175, 6195, 6255,
|
||||
+ 6275, 6335, 6355, 6415,
|
||||
+ 6435, 6495, 6515, 6575,
|
||||
+ 6595, 6655, 6675, 6735,
|
||||
+ 6755, 6815, 6835, 6895,
|
||||
+ 6915, 6975, 6995, 7055 };
|
||||
struct hostapd_channel_data *pri_chan = NULL, *sec_chan = NULL;
|
||||
- u8 channel;
|
||||
+ u8 channel, chan_80mhz;
|
||||
int i, chan_idx, ht40 = -1, res, obss_scan = !(ssid->noscan);
|
||||
unsigned int j, k;
|
||||
struct hostapd_freq_params vht_freq;
|
||||
@@ -2752,49 +2760,72 @@ skip_to_6ghz:
|
||||
#endif /* CONFIG_HE_OVERRIDES */
|
||||
|
||||
/* setup center_freq1, bandwidth */
|
||||
- for (j = 0; j < ARRAY_SIZE(bw80); j++)
|
||||
- if (freq->freq == bw80[j])
|
||||
+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) {
|
||||
+ /* If the config provided freq available between any of two indices
|
||||
+ * get the starting range of the channel to check chan availability
|
||||
+ */
|
||||
+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) {
|
||||
+ ieee80211_freq_to_chan(bw_80_160[j], &chan_80mhz);
|
||||
+ seg0 = chan_80mhz + 6;
|
||||
break;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (j == ARRAY_SIZE(bw80))
|
||||
+ if (j == ARRAY_SIZE(bw_80_160))
|
||||
return;
|
||||
|
||||
/* Back to HT configuration if channel not usable */
|
||||
- if (!ibss_mesh_is_80mhz_avail(freq->channel, mode))
|
||||
+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode))
|
||||
return;
|
||||
|
||||
chwidth = CHANWIDTH_80MHZ;
|
||||
- seg0 = freq->channel + 6;
|
||||
seg1 = 0;
|
||||
|
||||
/* setup center_freq1 for 160MHz */
|
||||
if ((mode->he_capab[ieee80211_mode].phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
|
||||
- HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)) {
|
||||
-
|
||||
- for (j = 0; j < ARRAY_SIZE(bw160); j++) {
|
||||
- if (freq->freq == bw160[j]) {
|
||||
- /* In 160MHz, Initial four 20MHz channels validated before,
|
||||
- * check remaining four 20MHz channels in total 160MHz bandwidth
|
||||
- */
|
||||
- int channel = freq->channel + 16;
|
||||
-
|
||||
- if (!ibss_mesh_is_80mhz_avail(channel, mode))
|
||||
- break;
|
||||
-
|
||||
- chwidth = CHANWIDTH_160MHZ;
|
||||
- seg0 = freq->channel + 14;
|
||||
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G) && (ssid->enable_160mhz_bw)) {
|
||||
+ chan_80mhz = freq->channel + 16;
|
||||
+ for (j = 0; j < ARRAY_SIZE(bw_80_160); j+=2) {
|
||||
+ if (freq->freq >= bw_80_160[j] && freq->freq <= bw_80_160[j+1]) {
|
||||
+ if (j % 4 == 0) {
|
||||
+ ieee80211_freq_to_chan(bw_80_160[j],
|
||||
+ &chan_80mhz);
|
||||
+ seg0 = chan_80mhz + 14;
|
||||
+
|
||||
+ /* Get secondary 80MHz channel using freq by
|
||||
+ * adding 16*5 ie., 80MHz.
|
||||
+ */
|
||||
+ ieee80211_freq_to_chan((bw_80_160[j] + 16*5),
|
||||
+ &chan_80mhz);
|
||||
+ } else {
|
||||
+ ieee80211_freq_to_chan(bw_80_160[j],
|
||||
+ &chan_80mhz);
|
||||
+ seg0 = chan_80mhz - 2;
|
||||
+ /* Get secondary 80MHz channel using freq by
|
||||
+ * subtracting 16*5 ie., 80MHz.
|
||||
+ */
|
||||
+ ieee80211_freq_to_chan((bw_80_160[j] - 16*5),
|
||||
+ &chan_80mhz);
|
||||
+ }
|
||||
+
|
||||
+ if (!ibss_mesh_is_80mhz_avail(chan_80mhz, mode))
|
||||
+ seg0 = freq->channel + 6;
|
||||
+ else
|
||||
+ chwidth = CHANWIDTH_160MHZ;
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ssid->max_oper_chwidth == CHANWIDTH_80P80MHZ) {
|
||||
/* setup center_freq2, bandwidth */
|
||||
- for (k = 0; k < ARRAY_SIZE(bw80); k++) {
|
||||
+ for (k = 0; k < ARRAY_SIZE(bw_80_160); k++) {
|
||||
/* Only accept 80 MHz segments separated by a gap */
|
||||
- if (j == k || abs(bw80[j] - bw80[k]) == 80)
|
||||
+ if (j == k || abs(bw_80_160[j] - bw_80_160[k]) == 80)
|
||||
continue;
|
||||
|
||||
- if (ieee80211_freq_to_chan(bw80[k], &channel) == NUM_HOSTAPD_MODES)
|
||||
+ if (ieee80211_freq_to_chan(bw_80_160[k],
|
||||
+ &channel) == NUM_HOSTAPD_MODES)
|
||||
return;
|
||||
|
||||
for (i = channel; i < channel + 16; i += 4) {
|
||||
Index: hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/hostapd/config_file.c
|
||||
+++ hostapd-2021-02-20-59e9794c/hostapd/config_file.c
|
||||
@@ -4245,6 +4245,8 @@ static int hostapd_config_fill(struct ho
|
||||
} else if (os_strcmp(buf, "wowlan_triggers") == 0) {
|
||||
os_free(bss->wowlan_triggers);
|
||||
bss->wowlan_triggers = os_strdup(pos);
|
||||
+ } else if (os_strcmp(buf, "enable_160mhz_bw") == 0) {
|
||||
+ conf->enable_160mhz_bw = atoi(pos);
|
||||
} else if (os_strcmp(buf, "disable_40mhz_scan") == 0) {
|
||||
conf->disable_40mhz_scan = atoi(pos);
|
||||
#ifdef CONFIG_FST
|
||||
Index: hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/ap/ap_config.h
|
||||
+++ hostapd-2021-02-20-59e9794c/src/ap/ap_config.h
|
||||
@@ -1067,6 +1067,7 @@ struct hostapd_config {
|
||||
} *acs_chan_bias;
|
||||
unsigned int num_acs_chan_bias;
|
||||
#endif /* CONFIG_ACS */
|
||||
+ int enable_160mhz_bw;
|
||||
int disable_40mhz_scan;
|
||||
|
||||
struct wpabuf *lci;
|
||||
Index: hostapd-2021-02-20-59e9794c/src/drivers/driver.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/src/drivers/driver.h
|
||||
+++ hostapd-2021-02-20-59e9794c/src/drivers/driver.h
|
||||
@@ -1229,6 +1229,10 @@ struct wpa_driver_associate_params {
|
||||
* 2 = BURST beacon tx mode
|
||||
*/
|
||||
int beacon_tx_mode;
|
||||
+ /**
|
||||
+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G
|
||||
+ */
|
||||
+ int enable_160mhz_bw;
|
||||
};
|
||||
|
||||
enum hide_ssid {
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config.c
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config.c
|
||||
@@ -2742,6 +2742,7 @@ static const struct parse_data ssid_fiel
|
||||
{ INT_RANGE(sae_pk, 0, 2) },
|
||||
{ INT_RANGE(disable_40mhz_scan, 0, 1)},
|
||||
{ INT_RANGE(beacon_tx_mode, 1, 2)},
|
||||
+ { INT_RANGE(enable_160mhz_bw, 0, 1)},
|
||||
};
|
||||
|
||||
#undef OFFSET
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config_file.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config_file.c
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config_file.c
|
||||
@@ -889,6 +889,7 @@ static void wpa_config_write_network(FIL
|
||||
#endif /* CONFIG_HE_OVERRIDES */
|
||||
INT(disable_40mhz_scan);
|
||||
INT(beacon_tx_mode);
|
||||
+ INT(enable_160mhz_bw);
|
||||
#undef STR
|
||||
#undef INT
|
||||
#undef INT_DEF
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/config_ssid.h
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/config_ssid.h
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/config_ssid.h
|
||||
@@ -1192,6 +1192,11 @@ struct wpa_ssid {
|
||||
* 2 = BURST MODE
|
||||
*/
|
||||
int beacon_tx_mode;
|
||||
+
|
||||
+ /**
|
||||
+ * Enable 160MHz BW - set it 1 to enable mesh 160MHz 6G
|
||||
+ */
|
||||
+ int enable_160mhz_bw;
|
||||
};
|
||||
|
||||
#endif /* CONFIG_SSID_H */
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_cli.c
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_cli.c
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_cli.c
|
||||
@@ -1490,6 +1490,7 @@ static const char *network_fields[] = {
|
||||
"mac_addr", "pbss", "wps_disabled",
|
||||
"disable_40mhz_scan",
|
||||
"beacon_tx_mode",
|
||||
+ "enable_160mhz_bw",
|
||||
};
|
||||
|
||||
|
||||
Index: hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.conf
|
||||
===================================================================
|
||||
--- hostapd-2021-02-20-59e9794c.orig/wpa_supplicant/wpa_supplicant.conf
|
||||
+++ hostapd-2021-02-20-59e9794c/wpa_supplicant/wpa_supplicant.conf
|
||||
@@ -1699,6 +1699,11 @@ fast_reauth=1
|
||||
# In STA mode it defines the EDMG channel for connection (if supported by AP).
|
||||
#edmg_channel=9
|
||||
|
||||
+#To configure 80MHz and 160MHz in Mesh mode.
|
||||
+#Set 0 to enable 80MHz in Mesh mode
|
||||
+#Set 1 to enable 160MHz in Mesh mode
|
||||
+#enable_160mhz_bw=1
|
||||
+
|
||||
# Example blocks:
|
||||
|
||||
# Simple case: WPA-PSK, PSK as an ASCII passphrase, allow all valid ciphers
|
||||
@@ -0,0 +1,65 @@
|
||||
From 29818cbd2d4fc8aee50d632335a31028b614ae1a Mon Sep 17 00:00:00 2001
|
||||
From: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
|
||||
Date: Thu, 10 Feb 2022 12:30:25 +0530
|
||||
Subject: [PATCH] hostapd:Fix race condition in four way handshake
|
||||
|
||||
When there is multiple delayed m2 from the station,
|
||||
after ap has tried m3 multiple times, ap tends to
|
||||
send m3 again for the later received m2 incrementing
|
||||
the replay counter. Here station replies with m4 only
|
||||
for the first m3, but replay counter would have advanced
|
||||
to higher number due to multiple m3 retries. Due to
|
||||
replay counter mismatch m4 is discarded and station
|
||||
association fails.
|
||||
|
||||
Added a flag to stop processing m2 if state machine has
|
||||
already advanced to m3 state, this prevent m3 triggered
|
||||
in response for m2 there by preventing the race condition
|
||||
with respect to replay counter
|
||||
Signed-off-by: Sowmiya Sree Elavalagan <quic_ssreeela@quicinc.com>
|
||||
---
|
||||
src/ap/wpa_auth.c | 3 ++-
|
||||
src/ap/wpa_auth_i.h | 1 +
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/ap/wpa_auth.c
|
||||
+++ b/src/ap/wpa_auth.c
|
||||
@@ -1150,7 +1150,7 @@ void wpa_receive(struct wpa_authenticato
|
||||
!wpa_replay_counter_valid(sm->key_replay, key->replay_counter)) {
|
||||
int i;
|
||||
|
||||
- if (msg == PAIRWISE_2 &&
|
||||
+ if (msg == PAIRWISE_2 && !sm->m3_retried &&
|
||||
wpa_replay_counter_valid(sm->prev_key_replay,
|
||||
key->replay_counter) &&
|
||||
sm->wpa_ptk_state == WPA_PTK_PTKINITNEGOTIATING &&
|
||||
@@ -3753,6 +3753,7 @@ SM_STEP(WPA_PTK)
|
||||
}
|
||||
break;
|
||||
case WPA_PTK_INITPSK:
|
||||
+ sm->m3_retried = 0;
|
||||
if (wpa_auth_get_psk(wpa_auth, sm->addr, sm->p2p_dev_addr,
|
||||
NULL, NULL, NULL)) {
|
||||
SM_ENTER(WPA_PTK, PTKSTART);
|
||||
@@ -3811,8 +3812,10 @@ SM_STEP(WPA_PTK)
|
||||
sm->disconnect_reason =
|
||||
WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT;
|
||||
SM_ENTER(WPA_PTK, DISCONNECT);
|
||||
- } else if (sm->TimeoutEvt)
|
||||
+ } else if (sm->TimeoutEvt) {
|
||||
+ sm->m3_retried = 1;
|
||||
SM_ENTER(WPA_PTK, PTKINITNEGOTIATING);
|
||||
+ }
|
||||
break;
|
||||
case WPA_PTK_PTKINITDONE:
|
||||
break;
|
||||
--- a/src/ap/wpa_auth_i.h
|
||||
+++ b/src/ap/wpa_auth_i.h
|
||||
@@ -95,6 +95,7 @@ struct wpa_state_machine {
|
||||
#endif /* CONFIG_IEEE80211R_AP */
|
||||
unsigned int is_wnmsleep:1;
|
||||
unsigned int pmkid_set:1;
|
||||
+ unsigned int m3_retried:1;
|
||||
|
||||
#ifdef CONFIG_OCV
|
||||
int ocv_enabled;
|
||||
@@ -0,0 +1,369 @@
|
||||
From daf67e765bcfa6ff6affb1a916696271014303b2 Mon Sep 17 00:00:00 2001
|
||||
From: P Praneesh <quic_ppranees@quicinc.com>
|
||||
Date: Mon, 21 Feb 2022 11:49:50 +0530
|
||||
Subject: [PATCH] hostapd: add acs_exclude_6ghz_non_psc option for acs non
|
||||
offload driver
|
||||
|
||||
Hostapd configuration "acs_exclude_6ghz_non_psc" is supported for ACS
|
||||
offloaded driver alone. Extend the support to ACS non offload driver
|
||||
by adding 6G Preferred Scan Channel check and hostapd config flag
|
||||
during scan and survey dump.
|
||||
|
||||
Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
|
||||
---
|
||||
src/ap/acs.c | 141 ++++++++++++++++++++++++++++++++++++++++---
|
||||
src/ap/ap_drv_ops.h | 6 +-
|
||||
src/ap/bss_load.c | 3 +-
|
||||
src/drivers/driver.h | 4 +-
|
||||
src/drivers/driver_nl80211.c | 30 ++++++---
|
||||
5 files changed, 166 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/src/ap/acs.c
|
||||
+++ b/src/ap/acs.c
|
||||
@@ -641,6 +641,112 @@ static int is_common_24ghz_chan(int chan
|
||||
#endif /* ACS_24GHZ_PREFER_1_6_11 */
|
||||
|
||||
static void
|
||||
+acs_find_6g_psc_chan_mode(struct hostapd_iface *iface,
|
||||
+ struct hostapd_hw_modes *mode,
|
||||
+ int n_chans, u32 bw,
|
||||
+ struct hostapd_channel_data **rand_chan,
|
||||
+ struct hostapd_channel_data **ideal_chan,
|
||||
+ long double *ideal_factor)
|
||||
+{
|
||||
+ struct hostapd_channel_data *chan, *adj_chan = NULL;
|
||||
+ long double factor;
|
||||
+ int i, j;
|
||||
+ unsigned int k;
|
||||
+
|
||||
+ for (i = 0; i < mode->num_channels; i++) {
|
||||
+ double total_weight;
|
||||
+ struct acs_bias *bias;
|
||||
+
|
||||
+ chan = &mode->channels[i];
|
||||
+ if (!chan_pri_allowed(chan))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!is_in_chanlist(iface, chan))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!is_in_freqlist(iface, chan))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!is_6ghz_psc_frequency(chan->freq))
|
||||
+ continue;
|
||||
+
|
||||
+ if (!chan_bw_allowed(chan, bw, 1, 1)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "ACS: Channel %d: BW %u is not supported",
|
||||
+ chan->chan, bw);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ factor = 0;
|
||||
+ if (acs_usable_chan(chan))
|
||||
+ factor = chan->interference_factor;
|
||||
+ total_weight = 1;
|
||||
+
|
||||
+ /* Start index from -1 because all the PSC channels are located in
|
||||
+ * secondary 20MHz of primary 40MHz. Ex: CH33 - CH61 has 160MHz BW, PSC
|
||||
+ * CH37 which is secondary 20MHz of primary 40MHz.
|
||||
+ */
|
||||
+
|
||||
+ for (j = -1; j < n_chans; j++) {
|
||||
+ adj_chan = acs_find_chan(iface, chan->freq + (j * 20));
|
||||
+ if (!adj_chan)
|
||||
+ break;
|
||||
+
|
||||
+ if (!chan_bw_allowed(adj_chan, bw, 1, 0)) {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "ACS: PRI Channel %d: secondary channel %d BW %u is not supported",
|
||||
+ chan->chan, adj_chan->chan, bw);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ if (acs_usable_chan(adj_chan)) {
|
||||
+ factor += adj_chan->interference_factor;
|
||||
+ total_weight += 1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (j != n_chans) {
|
||||
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not enough bandwidth",
|
||||
+ chan->chan);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ factor /= total_weight;
|
||||
+
|
||||
+ bias = NULL;
|
||||
+ if (iface->conf->acs_chan_bias) {
|
||||
+ for (k = 0; k < iface->conf->num_acs_chan_bias; k++) {
|
||||
+ bias = &iface->conf->acs_chan_bias[k];
|
||||
+ if (bias->channel == chan->chan)
|
||||
+ break;
|
||||
+ bias = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (bias) {
|
||||
+ factor *= bias->bias;
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "ACS: * channel %d: total interference = %Lg (%f bias)",
|
||||
+ chan->chan, factor, bias->bias);
|
||||
+ } else {
|
||||
+ wpa_printf(MSG_DEBUG,
|
||||
+ "ACS: * channel %d: total interference = %Lg",
|
||||
+ chan->chan, factor);
|
||||
+ }
|
||||
+
|
||||
+ if (acs_usable_chan(chan) &&
|
||||
+ (!*ideal_chan || factor < *ideal_factor)) {
|
||||
+ *ideal_factor = factor;
|
||||
+ *ideal_chan = chan;
|
||||
+ }
|
||||
+
|
||||
+ /* This channel would at least be usable */
|
||||
+ if (!(*rand_chan))
|
||||
+ *rand_chan = chan;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
acs_find_ideal_chan_mode(struct hostapd_iface *iface,
|
||||
struct hostapd_hw_modes *mode,
|
||||
int n_chans, u32 bw,
|
||||
@@ -874,10 +980,17 @@ bw_selected:
|
||||
|
||||
for (i = 0; i < iface->num_hw_features; i++) {
|
||||
mode = &iface->hw_features[i];
|
||||
- if (!hostapd_hw_skip_mode(iface, mode))
|
||||
- acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
|
||||
- &rand_chan, &ideal_chan,
|
||||
- &ideal_factor);
|
||||
+ if (!hostapd_hw_skip_mode(iface, mode)) {
|
||||
+ if (iface->conf->acs_exclude_6ghz_non_psc) {
|
||||
+ acs_find_6g_psc_chan_mode(iface, mode, n_chans, bw,
|
||||
+ &rand_chan, &ideal_chan,
|
||||
+ &ideal_factor);
|
||||
+ } else {
|
||||
+ acs_find_ideal_chan_mode(iface, mode, n_chans, bw,
|
||||
+ &rand_chan, &ideal_chan,
|
||||
+ &ideal_factor);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
if (ideal_chan) {
|
||||
@@ -892,19 +1005,42 @@ bw_selected:
|
||||
|
||||
static void acs_adjust_center_freq(struct hostapd_iface *iface)
|
||||
{
|
||||
- int offset;
|
||||
+ int psc_chan[] = {37, 53, 69, 85, 101, 117,
|
||||
+ 133, 149, 165, 181, 197, 213} ;
|
||||
+ int offset, i;
|
||||
+ u8 bw = hostapd_get_oper_chwidth(iface->conf);
|
||||
+ bool acs_exclude_6ghz_non_psc = iface->conf->acs_exclude_6ghz_non_psc;
|
||||
+ bool is_sec_psc_chan = false;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
|
||||
|
||||
- switch (hostapd_get_oper_chwidth(iface->conf)) {
|
||||
+ if (acs_exclude_6ghz_non_psc && (bw == CHANWIDTH_160MHZ)) {
|
||||
+ for (i = 0; i < ARRAY_SIZE(psc_chan); i++) {
|
||||
+ if (psc_chan[i] == iface->conf->channel) {
|
||||
+ is_sec_psc_chan = (i%2) ? true : false;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ switch (bw) {
|
||||
case CHANWIDTH_USE_HT:
|
||||
offset = 2 * iface->conf->secondary_channel;
|
||||
break;
|
||||
case CHANWIDTH_80MHZ:
|
||||
- offset = 6;
|
||||
+ if (acs_exclude_6ghz_non_psc)
|
||||
+ offset = 2;
|
||||
+ else
|
||||
+ offset = 6;
|
||||
break;
|
||||
case CHANWIDTH_160MHZ:
|
||||
- offset = 14;
|
||||
+ /* In 160MHz, if primary 20MHz present in secondary 80MHz, then
|
||||
+ * subtract with -6 to find the center frequency of the 160MHz
|
||||
+ */
|
||||
+ if (acs_exclude_6ghz_non_psc)
|
||||
+ offset = is_sec_psc_chan ? -6 : 10;
|
||||
+ else
|
||||
+ offset = 14;
|
||||
break;
|
||||
default:
|
||||
/* TODO: How can this be calculated? Adjust
|
||||
@@ -1001,7 +1137,8 @@ static void acs_scan_complete(struct hos
|
||||
wpa_printf(MSG_DEBUG, "ACS: Using survey based algorithm (acs_num_scans=%d)",
|
||||
iface->conf->acs_num_scans);
|
||||
|
||||
- err = hostapd_drv_get_survey(iface->bss[0], 0);
|
||||
+ err = hostapd_drv_get_survey(iface->bss[0], 0,
|
||||
+ iface->conf->acs_exclude_6ghz_non_psc);
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR, "ACS: Failed to get survey data");
|
||||
goto fail;
|
||||
@@ -1043,6 +1180,11 @@ static int * acs_request_scan_add_freqs(
|
||||
if (!is_in_freqlist(iface, chan))
|
||||
continue;
|
||||
|
||||
+ if (is_6ghz_freq(chan->freq) &&
|
||||
+ iface->conf->acs_exclude_6ghz_non_psc &&
|
||||
+ !is_6ghz_psc_frequency(chan->freq))
|
||||
+ continue;
|
||||
+
|
||||
*freq++ = chan->freq;
|
||||
}
|
||||
|
||||
--- a/src/ap/ap_drv_ops.h
|
||||
+++ b/src/ap/ap_drv_ops.h
|
||||
@@ -266,13 +266,15 @@ static inline void hostapd_drv_poll_clie
|
||||
}
|
||||
|
||||
static inline int hostapd_drv_get_survey(struct hostapd_data *hapd,
|
||||
- unsigned int freq)
|
||||
+ unsigned int freq,
|
||||
+ bool acs_exclude_6ghz_non_psc)
|
||||
{
|
||||
if (hapd->driver == NULL)
|
||||
return -1;
|
||||
if (!hapd->driver->get_survey)
|
||||
return -1;
|
||||
- return hapd->driver->get_survey(hapd->drv_priv, freq);
|
||||
+ return hapd->driver->get_survey(hapd->drv_priv, freq,
|
||||
+ acs_exclude_6ghz_non_psc);
|
||||
}
|
||||
|
||||
static inline int hostapd_get_country(struct hostapd_data *hapd, char *alpha2)
|
||||
--- a/src/ap/bss_load.c
|
||||
+++ b/src/ap/bss_load.c
|
||||
@@ -49,7 +49,8 @@ static void update_channel_utilization(v
|
||||
if (!(hapd->beacon_set_done && hapd->started))
|
||||
return;
|
||||
|
||||
- err = hostapd_drv_get_survey(hapd, hapd->iface->freq);
|
||||
+ err = hostapd_drv_get_survey(hapd, hapd->iface->freq,
|
||||
+ hapd->iface->conf->acs_exclude_6ghz_non_psc);
|
||||
if (err) {
|
||||
wpa_printf(MSG_ERROR, "BSS Load: Failed to get survey data");
|
||||
return;
|
||||
--- a/src/drivers/driver.h
|
||||
+++ b/src/drivers/driver.h
|
||||
@@ -4186,6 +4186,8 @@ struct wpa_driver_ops {
|
||||
* @priv: Private driver interface data
|
||||
* @freq: If set, survey data for the specified frequency is only
|
||||
* being requested. If not set, all survey data is requested.
|
||||
+ * @acs_exclude_6ghz_non_psc: If set Include only preferred scan
|
||||
+ * channels from 6 GHz band for ACS
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Use this to retrieve:
|
||||
@@ -4204,7 +4206,7 @@ struct wpa_driver_ops {
|
||||
* for each survey. The min_nf of the channel is updated for each
|
||||
* survey.
|
||||
*/
|
||||
- int (*get_survey)(void *priv, unsigned int freq);
|
||||
+ int (*get_survey)(void *priv, unsigned int freq, bool acs_exclude_6ghz_non_psc);
|
||||
|
||||
/**
|
||||
* status - Get driver interface status information
|
||||
--- a/src/drivers/driver_nl80211.c
|
||||
+++ b/src/drivers/driver_nl80211.c
|
||||
@@ -9033,6 +9033,10 @@ static int check_survey_ok(struct nlattr
|
||||
return freq_filter == surveyed_freq;
|
||||
}
|
||||
|
||||
+struct nl80211_get_survey_arg {
|
||||
+ struct survey_results *survey_results;
|
||||
+ bool acs_exclude_6ghz_non_psc;
|
||||
+};
|
||||
|
||||
static int survey_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
@@ -9040,15 +9044,19 @@ static int survey_handler(struct nl_msg
|
||||
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
|
||||
struct survey_results *survey_results;
|
||||
+ struct nl80211_get_survey_arg *arg_survey =
|
||||
+ (struct nl80211_get_survey_arg *)arg;
|
||||
u32 surveyed_freq = 0;
|
||||
u32 ifidx;
|
||||
+ bool acs_exclude_6ghz_non_psc;
|
||||
|
||||
static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
|
||||
[NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
|
||||
[NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
- survey_results = (struct survey_results *) arg;
|
||||
+ survey_results = arg_survey->survey_results;
|
||||
+ acs_exclude_6ghz_non_psc = arg_survey->acs_exclude_6ghz_non_psc;
|
||||
|
||||
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
@@ -9077,6 +9085,11 @@ static int survey_handler(struct nl_msg
|
||||
survey_results->freq_filter))
|
||||
return NL_SKIP;
|
||||
|
||||
+ if (is_6ghz_freq(surveyed_freq) &&
|
||||
+ acs_exclude_6ghz_non_psc &&
|
||||
+ !is_6ghz_psc_frequency(surveyed_freq))
|
||||
+ return NL_SKIP;
|
||||
+
|
||||
if (survey_results->freq_filter &&
|
||||
survey_results->freq_filter != surveyed_freq) {
|
||||
wpa_printf(MSG_EXCESSIVE, "nl80211: Ignoring survey data for freq %d MHz",
|
||||
@@ -9090,19 +9103,22 @@ static int survey_handler(struct nl_msg
|
||||
}
|
||||
|
||||
|
||||
-static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq)
|
||||
+static int wpa_driver_nl80211_get_survey(void *priv, unsigned int freq,
|
||||
+ bool acs_exclude_6ghz_non_psc)
|
||||
{
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
struct nl_msg *msg;
|
||||
int err;
|
||||
union wpa_event_data data;
|
||||
- struct survey_results *survey_results;
|
||||
+ struct nl80211_get_survey_arg arg;
|
||||
|
||||
os_memset(&data, 0, sizeof(data));
|
||||
- survey_results = &data.survey_results;
|
||||
+ os_memset(&arg, 0, sizeof(arg));
|
||||
+ arg.survey_results = &data.survey_results;
|
||||
+ arg.acs_exclude_6ghz_non_psc = acs_exclude_6ghz_non_psc;
|
||||
|
||||
- dl_list_init(&survey_results->survey_list);
|
||||
+ dl_list_init(&arg.survey_results->survey_list);
|
||||
|
||||
msg = nl80211_drv_msg(drv, NLM_F_DUMP, NL80211_CMD_GET_SURVEY);
|
||||
if (!msg)
|
||||
@@ -9114,7 +9130,7 @@ static int wpa_driver_nl80211_get_survey
|
||||
do {
|
||||
wpa_printf(MSG_DEBUG, "nl80211: Fetch survey data");
|
||||
err = send_and_recv_msgs(drv, msg, survey_handler,
|
||||
- survey_results, NULL, NULL);
|
||||
+ &arg, NULL, NULL);
|
||||
} while (err > 0);
|
||||
|
||||
if (err)
|
||||
@@ -9122,7 +9138,7 @@ static int wpa_driver_nl80211_get_survey
|
||||
else
|
||||
wpa_supplicant_event(drv->ctx, EVENT_SURVEY, &data);
|
||||
|
||||
- clean_survey_results(survey_results);
|
||||
+ clean_survey_results(arg.survey_results);
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user