[PATCH] Fix ACS when using 20MHz channels in 6GHz
Matej Vrba
Matej.Vrba at advantech.cz
Tue Mar 25 06:25:09 PDT 2025
When configured to use ACS with 20MHz channels, hostapd incorrectly rejects
half of the available channels with an error messages "Channel XX: not
allowed as primary channel for 40 MHz bandwidth." This includes all PSC
channels.
Signed-off-by: Matěj Vrba <matej.vrba at advantech.cz>
---
src/ap/acs.c | 59 ++++++++++++++++++++++++++++++++--------------------
1 file changed, 36 insertions(+), 23 deletions(-)
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 44d083684..4eb44780c 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -242,6 +242,12 @@
* [1] http://en.wikipedia.org/wiki/Near_and_far_field
*/
+// Corresponds to "Behavior limits set" in 802.11-2020 annex E
+enum behavior_limitation {
+ BLIMIT_NONE,
+ BLIMIT_PRIMARY_CH_LOWER,
+};
+
enum bw_type {
ACS_BW40,
ACS_BW80,
@@ -439,17 +445,22 @@ acs_survey_chan_interference_factor(struct hostapd_iface *iface,
static bool acs_usable_bw_chan(const struct hostapd_channel_data *chan,
- enum bw_type bw)
+ enum bw_type bw, enum behavior_limitation limit)
{
- unsigned int i = 0;
-
- while (bw_desc[bw][i].first != -1) {
- if (chan->freq == bw_desc[bw][i].first)
- return true;
- i++;
+ switch (limit) {
+ case BLIMIT_NONE:
+ for (unsigned int i = 0; bw_desc[bw][i].first != -1; i++)
+ if (chan->freq == bw_desc[bw][i].first || chan->freq == bw_desc[bw][i].last)
+ return true;
+ break;
+ case BLIMIT_PRIMARY_CH_LOWER:
+ for (unsigned int i = 0; bw_desc[bw][i].first != -1; i++)
+ if (chan->freq == bw_desc[bw][i].first)
+ return true;
+ break;
}
- return false;
+ return false;
}
@@ -797,19 +808,19 @@ acs_usable_bw320_chan(struct hostapd_iface *iface,
*bw320_offset = 0;
switch (conf_bw320_offset) {
case 1:
- if (acs_usable_bw_chan(chan, ACS_BW320_1))
+ if (acs_usable_bw_chan(chan, ACS_BW320_1, BLIMIT_PRIMARY_CH_LOWER))
*bw320_offset = 1;
break;
case 2:
- if (acs_usable_bw_chan(chan, ACS_BW320_2))
+ if (acs_usable_bw_chan(chan, ACS_BW320_2, BLIMIT_PRIMARY_CH_LOWER))
*bw320_offset = 2;
break;
case 0:
default:
conf_bw320_offset = 0;
- if (acs_usable_bw_chan(chan, ACS_BW320_1))
+ if (acs_usable_bw_chan(chan, ACS_BW320_1, BLIMIT_PRIMARY_CH_LOWER))
*bw320_offset = 1;
- else if (acs_usable_bw_chan(chan, ACS_BW320_2))
+ else if (acs_usable_bw_chan(chan, ACS_BW320_2, BLIMIT_PRIMARY_CH_LOWER))
*bw320_offset = 2;
break;
}
@@ -889,15 +900,17 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
/* HT40 on 5 GHz has a limited set of primary channels as per
* 11n Annex J */
- if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
- ((iface->conf->ieee80211n &&
- iface->conf->secondary_channel) ||
- is_6ghz_freq(chan->freq)) &&
- !acs_usable_bw_chan(chan, ACS_BW40)) {
- wpa_printf(MSG_DEBUG,
- "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth",
- chan->chan);
- continue;
+ if (is_6ghz_freq(chan->freq)) {
+ if (iface->conf->op_class == 132 && !acs_usable_bw_chan(chan, ACS_BW40, BLIMIT_NONE)) {
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth in 6Ghz band", chan->chan);
+ continue;
+ }
+ } else {
+ if (mode->mode == HOSTAPD_MODE_IEEE80211A && ((iface->conf->ieee80211n && iface->conf->secondary_channel)) &&
+ !acs_usable_bw_chan(chan, ACS_BW40, BLIMIT_PRIMARY_CH_LOWER)) {
+ wpa_printf(MSG_DEBUG, "ACS: Channel %d: not allowed as primary channel for 40 MHz bandwidth", chan->chan);
+ continue;
+ }
}
if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
@@ -905,7 +918,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
iface->conf->ieee80211be)) {
if (hostapd_get_oper_chwidth(iface->conf) ==
CONF_OPER_CHWIDTH_80MHZ &&
- !acs_usable_bw_chan(chan, ACS_BW80)) {
+ !acs_usable_bw_chan(chan, ACS_BW80, BLIMIT_PRIMARY_CH_LOWER)) {
wpa_printf(MSG_DEBUG,
"ACS: Channel %d: not allowed as primary channel for 80 MHz bandwidth",
chan->chan);
@@ -914,7 +927,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
if (hostapd_get_oper_chwidth(iface->conf) ==
CONF_OPER_CHWIDTH_160MHZ &&
- !acs_usable_bw_chan(chan, ACS_BW160)) {
+ !acs_usable_bw_chan(chan, ACS_BW160, BLIMIT_PRIMARY_CH_LOWER)) {
wpa_printf(MSG_DEBUG,
"ACS: Channel %d: not allowed as primary channel for 160 MHz bandwidth",
chan->chan);
--
2.49.0
More information about the Hostap
mailing list