[PATCH] AP: Avoid disabling HT/VHT/HE/EHT during CSA
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Thu Dec 28 06:01:04 PST 2023
From: Ilan Peer <ilan.peer at intel.com>
During CSA an AP should not disable its HT/VHT/HE/EHT capabilities
as it is not allowed by the IEEE80211 specification.
- Modify the CSA flow to preserve the current HT/VHT/HE/EHT
capabilities allowing only to add additional ones.
- Update the DFS CSA flow to also preserve the HT/VHT/HE/EHT
capabilities.
Modify one of the hwsim tests that verified that VHT capabilities
are disabled during CSA, to verify that they are kept.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
hostapd/ctrl_iface.c | 34 +++++++++++++++++++++--
src/ap/ap_config.h | 23 ++++++----------
src/ap/dfs.c | 9 ++++++
src/ap/drv_callbacks.c | 56 +++++++++-----------------------------
src/ap/hostapd.c | 25 ++++++-----------
tests/hwsim/test_ap_vht.py | 8 +++---
6 files changed, 74 insertions(+), 81 deletions(-)
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index f9a78651ca..e654d932c7 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -2603,6 +2603,26 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
break;
}
+ if (!settings.freq_params.ht_enabled && iface->conf->ieee80211n) {
+ wpa_printf(MSG_WARNING, "CSA: Cannot disable HT. Ignore");
+ settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ }
+
+ if (!settings.freq_params.vht_enabled && iface->conf->ieee80211ac) {
+ wpa_printf(MSG_WARNING, "CSA: Cannot disable VHT. Ignore");
+ settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ }
+
+ if (!settings.freq_params.he_enabled && iface->conf->ieee80211ax) {
+ wpa_printf(MSG_WARNING, "CSA: Cannot disable HE. Ignore");
+ settings.freq_params.he_enabled = iface->conf->ieee80211ax;
+ }
+
+ if (!settings.freq_params.eht_enabled && iface->conf->ieee80211be) {
+ wpa_printf(MSG_WARNING, "CSA: Cannot disable EHT. Ignore");
+ settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+ }
+
if (settings.freq_params.center_freq1)
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq1);
@@ -2614,6 +2634,18 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
dfs_range += hostapd_is_dfs_overlap(
iface, bandwidth, settings.freq_params.center_freq2);
+ /* If VHT/HE/EHT was enabled, we must also set the bandwidth and center
+ * frequency
+ */
+ if ((settings.freq_params.vht_enabled ||
+ settings.freq_params.he_enabled ||
+ settings.freq_params.eht_enabled) &&
+ (!settings.freq_params.bandwidth ||
+ !settings.freq_params.center_freq1)) {
+ settings.freq_params.bandwidth = 20;
+ settings.freq_params.center_freq1 = settings.freq_params.freq;
+ }
+
if (dfs_range) {
ret = ieee80211_freq_to_chan(settings.freq_params.freq, &chan);
if (ret == NUM_HOSTAPD_MODES) {
@@ -2641,8 +2673,6 @@ static int hostapd_ctrl_iface_chan_switch(struct hostapd_iface *iface,
}
for (i = 0; i < iface->num_bss; i++) {
-
- /* Save CHAN_SWITCH VHT, HE, and EHT config */
hostapd_chan_switch_config(iface->bss[i],
&settings.freq_params);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 1d39495595..baf2ebb8bf 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1164,16 +1164,14 @@ struct hostapd_config {
bool require_he;
#endif /* CONFIG_IEEE80211AX */
-
- /* VHT enable/disable config from CHAN_SWITCH */
-#define CH_SWITCH_VHT_ENABLED BIT(0)
-#define CH_SWITCH_VHT_DISABLED BIT(1)
- unsigned int ch_switch_vht_config;
-
- /* HE enable/disable config from CHAN_SWITCH */
-#define CH_SWITCH_HE_ENABLED BIT(0)
-#define CH_SWITCH_HE_DISABLED BIT(1)
- unsigned int ch_switch_he_config;
+ /*
+ * Save the expected HT/VHT/HE/EHT configuration so it could be used
+ * once CSA is done
+ */
+ unsigned int ch_switch_ht_config:1;
+ unsigned int ch_switch_vht_config:1;
+ unsigned int ch_switch_he_config:1;
+ unsigned int ch_switch_eht_config:1;
int rssi_reject_assoc_rssi;
int rssi_reject_assoc_timeout;
@@ -1202,11 +1200,6 @@ struct hostapd_config {
u8 eht_bw320_offset;
#endif /* CONFIG_IEEE80211BE */
- /* EHT enable/disable config from CHAN_SWITCH */
-#define CH_SWITCH_EHT_ENABLED BIT(0)
-#define CH_SWITCH_EHT_DISABLED BIT(1)
- unsigned int ch_switch_eht_config;
-
enum mbssid {
MBSSID_DISABLED = 0,
MBSSID_ENABLED = 1,
diff --git a/src/ap/dfs.c b/src/ap/dfs.c
index 18cb355a75..a91eb22475 100644
--- a/src/ap/dfs.c
+++ b/src/ap/dfs.c
@@ -1016,7 +1016,16 @@ static int hostapd_dfs_request_channel_switch(struct hostapd_iface *iface,
return err;
}
+ /* preserve the HT/VHT/HE/EHT configuration */
+ csa_settings.freq_params.ht_enabled = iface->conf->ieee80211n;
+ csa_settings.freq_params.vht_enabled = iface->conf->ieee80211ac;
+ csa_settings.freq_params.he_enabled = iface->conf->ieee80211ax;
+ csa_settings.freq_params.eht_enabled = iface->conf->ieee80211be;
+
for (i = 0; i < iface->num_bss; i++) {
+ hostapd_chan_switch_config(iface->bss[i],
+ &csa_settings.freq_params);
+
err = hostapd_switch_channel(iface->bss[i], &csa_settings);
if (err)
break;
diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c
index 210068a94d..f30fa364da 100644
--- a/src/ap/drv_callbacks.c
+++ b/src/ap/drv_callbacks.c
@@ -1036,7 +1036,9 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
"driver %s channel switch: iface->freq=%d, freq=%d, ht=%d, vht_ch=0x%x, he_ch=0x%x, eht_ch=0x%x, offset=%d, width=%d (%s), cf1=%d, cf2=%d, puncturing_bitmap=0x%x",
finished ? "had" : "starting",
hapd->iface->freq,
- freq, ht, hapd->iconf->ch_switch_vht_config,
+ freq,
+ hapd->iconf->ch_switch_ht_config,
+ hapd->iconf->ch_switch_vht_config,
hapd->iconf->ch_switch_he_config,
hapd->iconf->ch_switch_eht_config, offset,
width, channel_width_to_string(width), cf1, cf2,
@@ -1111,49 +1113,17 @@ void hostapd_event_ch_switch(struct hostapd_data *hapd, int freq, int ht,
}
hapd->iconf->channel = channel;
- hapd->iconf->ieee80211n = ht;
- if (!ht)
- hapd->iconf->ieee80211ac = 0;
- if (hapd->iconf->ch_switch_vht_config) {
- /* CHAN_SWITCH VHT config */
- if (hapd->iconf->ch_switch_vht_config &
- CH_SWITCH_VHT_ENABLED)
- hapd->iconf->ieee80211ac = 1;
- else if (hapd->iconf->ch_switch_vht_config &
- CH_SWITCH_VHT_DISABLED)
- hapd->iconf->ieee80211ac = 0;
- }
- if (hapd->iconf->ch_switch_he_config) {
- /* CHAN_SWITCH HE config */
- if (hapd->iconf->ch_switch_he_config &
- CH_SWITCH_HE_ENABLED) {
- hapd->iconf->ieee80211ax = 1;
- if (hapd->iface->freq > 4000 &&
- hapd->iface->freq < 5895)
- hapd->iconf->ieee80211ac = 1;
- }
- else if (hapd->iconf->ch_switch_he_config &
- CH_SWITCH_HE_DISABLED)
- hapd->iconf->ieee80211ax = 0;
- }
-#ifdef CONFIG_IEEE80211BE
- if (hapd->iconf->ch_switch_eht_config) {
- /* CHAN_SWITCH EHT config */
- if (hapd->iconf->ch_switch_eht_config &
- CH_SWITCH_EHT_ENABLED) {
- hapd->iconf->ieee80211be = 1;
- hapd->iconf->ieee80211ax = 1;
- if (!is_6ghz_freq(hapd->iface->freq) &&
- hapd->iface->freq > 4000)
- hapd->iconf->ieee80211ac = 1;
- } else if (hapd->iconf->ch_switch_eht_config &
- CH_SWITCH_EHT_DISABLED)
- hapd->iconf->ieee80211be = 0;
+ hapd->iconf->ieee80211n = hapd->iconf->ch_switch_ht_config;
+ hapd->iconf->ieee80211ac = hapd->iconf->ch_switch_vht_config;
+ hapd->iconf->ieee80211ax = hapd->iconf->ch_switch_he_config;
+ hapd->iconf->ieee80211be = hapd->iconf->ch_switch_eht_config;
+
+ if (finished) {
+ hapd->iconf->ch_switch_ht_config = 0;
+ hapd->iconf->ch_switch_vht_config = 0;
+ hapd->iconf->ch_switch_he_config = 0;
+ hapd->iconf->ch_switch_eht_config = 0;
}
-#endif /* CONFIG_IEEE80211BE */
- hapd->iconf->ch_switch_vht_config = 0;
- hapd->iconf->ch_switch_he_config = 0;
- hapd->iconf->ch_switch_eht_config = 0;
if (width == CHAN_WIDTH_40 || width == CHAN_WIDTH_80 ||
width == CHAN_WIDTH_80P80 || width == CHAN_WIDTH_160 ||
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 6a9b07e864..83ec043ba1 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -4034,27 +4034,18 @@ void hostapd_cleanup_cs_params(struct hostapd_data *hapd)
void hostapd_chan_switch_config(struct hostapd_data *hapd,
struct hostapd_freq_params *freq_params)
{
- if (freq_params->eht_enabled)
- hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_ENABLED;
- else
- hapd->iconf->ch_switch_eht_config |= CH_SWITCH_EHT_DISABLED;
-
- if (freq_params->he_enabled)
- hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_ENABLED;
- else
- hapd->iconf->ch_switch_he_config |= CH_SWITCH_HE_DISABLED;
-
- if (freq_params->vht_enabled)
- hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_ENABLED;
- else
- hapd->iconf->ch_switch_vht_config |= CH_SWITCH_VHT_DISABLED;
+ hapd->iconf->ch_switch_ht_config = freq_params->ht_enabled;
+ hapd->iconf->ch_switch_vht_config = freq_params->vht_enabled;
+ hapd->iconf->ch_switch_he_config = freq_params->he_enabled;
+ hapd->iconf->ch_switch_eht_config = freq_params->eht_enabled;
hostapd_logger(hapd, NULL, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_INFO,
- "CHAN_SWITCH EHT config 0x%x HE config 0x%x VHT config 0x%x",
- hapd->iconf->ch_switch_eht_config,
+ "CHAN_SWITCH: config: ht=%u, vht=%u, he=%u, eht=%u",
+ hapd->iconf->ch_switch_ht_config,
+ hapd->iconf->ch_switch_vht_config,
hapd->iconf->ch_switch_he_config,
- hapd->iconf->ch_switch_vht_config);
+ hapd->iconf->ch_switch_eht_config);
}
diff --git a/tests/hwsim/test_ap_vht.py b/tests/hwsim/test_ap_vht.py
index 2a7da8f68c..a6ef121229 100644
--- a/tests/hwsim/test_ap_vht.py
+++ b/tests/hwsim/test_ap_vht.py
@@ -969,8 +969,8 @@ def test_ap_vht_csa_vht20(dev, apdev):
dev[0].flush_scan_cache()
dev[1].flush_scan_cache()
-def test_ap_vht_csa_vht40_disable(dev, apdev):
- """VHT CSA with VHT40 getting disabled"""
+def test_ap_vht_csa_vht40_unchanged(dev, apdev):
+ """VHT CSA with VHT not specified. Verify the VHT was not disabled"""
csa_supported(dev[0])
try:
hapd = None
@@ -1014,8 +1014,8 @@ def test_ap_vht_csa_vht40_disable(dev, apdev):
dev[1].connect("vht", key_mgmt="NONE", scan_freq="5200")
hwsim_utils.test_connectivity(dev[1], hapd)
- if dev[1].get_status_field("ieee80211ac") == '1':
- raise Exception("VHT not disabled as part of channel switch")
+ if dev[1].get_status_field("ieee80211ac") != '1':
+ raise Exception("VHT unexpectedly disabled as part of channel switch")
finally:
dev[0].request("DISCONNECT")
dev[1].request("DISCONNECT")
--
2.43.0
More information about the Hostap
mailing list