blob: b4ac1f08881bc00f91518418ed3755945fd6b1dc [file] [log] [blame]
From 03dd213b918218fec270e781d284ec394fb63ef1 Mon Sep 17 00:00:00 2001
From: Nicolas Escande <nico.escande@gmail.com>
Date: Wed, 27 Apr 2022 15:37:01 +0200
Subject: [PATCH 03/50] ACS: introduce acs_adjust_secondary
When using 40/80/160 MHz bandwidth on the 5 GHz or 6 GHz band, enforce
the secondary channel to be the other channel of the corresponding 40
MHz segment.
Even if this is useless for now, this is preparatory work to allow ACS
to select a primary channel which is not the first of its segment.
Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
---
src/ap/acs.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/src/ap/acs.c b/src/ap/acs.c
index 511200d..78d1feb 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -634,6 +634,26 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
}
+static enum hostapd_hw_mode
+acs_find_mode(struct hostapd_iface *iface, int freq)
+{
+ int i;
+ struct hostapd_hw_modes *mode;
+ struct hostapd_channel_data *chan;
+
+ for (i = 0; i < iface->num_hw_features; i++) {
+ mode = &iface->hw_features[i];
+ if (!hostapd_hw_skip_mode(iface, mode)) {
+ chan = acs_find_chan_mode(mode, freq);
+ if (chan)
+ return mode->mode;
+ }
+ }
+
+ return HOSTAPD_MODE_IEEE80211ANY;
+}
+
+
static struct hostapd_channel_data *
acs_find_chan(struct hostapd_iface *iface, int freq)
{
@@ -949,6 +969,28 @@ bw_selected:
}
+static void acs_adjust_secondary(struct hostapd_iface *iface)
+{
+ unsigned int i;
+
+ /* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
+ * ACS can return a secondary channel which is not the first channel of
+ * the segment and we need to adjust. */
+ if (!iface->conf->secondary_channel ||
+ acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
+ return;
+
+ wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
+
+ for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
+ if (iface->freq == bw_desc[ACS_BW40][i].first)
+ iface->conf->secondary_channel = 1;
+ else if (iface->freq == bw_desc[ACS_BW40][i].last)
+ iface->conf->secondary_channel = -1;
+ }
+}
+
+
static void acs_adjust_center_freq(struct hostapd_iface *iface)
{
int center;
@@ -1036,8 +1078,10 @@ static void acs_study(struct hostapd_iface *iface)
iface->conf->channel = ideal_chan->chan;
iface->freq = ideal_chan->freq;
- if (iface->conf->ieee80211ac || iface->conf->ieee80211ax)
+ if (iface->conf->ieee80211ac || iface->conf->ieee80211ax) {
+ acs_adjust_secondary(iface);
acs_adjust_center_freq(iface);
+ }
err = 0;
fail:
--
2.18.0