diff mbox series

[v2,3/4] ACS: introduce acs_adjust_secondary

Message ID 20220427133702.595475-4-nico.escande@gmail.com
State Accepted
Headers show
Series ACS: better channel selection for 40/80/160 MHz | expand

Commit Message

Nicolas Escande April 27, 2022, 1:37 p.m. UTC
When using 40/80/160MHz over 5G/6G, enforce the secondary channel to be
the other channel of the corresponding 40MHz 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 it's segment.

Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
---
 src/ap/acs.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 42 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/ap/acs.c b/src/ap/acs.c
index a6cdfb962..176b22e67 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -631,6 +631,24 @@  acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
 	return NULL;
 }
 
+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)
@@ -942,6 +960,27 @@  bw_selected:
 }
 
 
+static void acs_adjust_secondary(struct hostapd_iface *iface)
+{
+	unsigned int i;
+
+	/* When working with bw > 20 on 5G/6G, ACS can return a secondary wich
+	 * is not channel the first of the segment & wee need to abjust */
+	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].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;
@@ -1024,8 +1063,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: