diff mbox series

[RFC,2/4] ACS: introduce acs_get_bwXXX_center_chan

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

Commit Message

Nicolas Escande March 24, 2022, 2:19 p.m. UTC
When using 40/80/160MHz, instead of computing the segment center freq
based on the selected channel, lets look it up in the bwXXX_seg table.

This is preparative work to allow selecting a primary channel which is
not the first of the segment.

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

Patch

diff --git a/src/ap/acs.c b/src/ap/acs.c
index 40df377f0..30f2e8d08 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -403,6 +403,19 @@  static int acs_usable_bw40_chan(const struct hostapd_channel_data *chan)
 }
 
 
+static int acs_get_bw40_center_chan(int freq)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(bw40_seg); i++)
+		if (freq >= bw40_seg[i].first &&
+		    freq < bw40_seg[i].last + 1)
+			return bw40_seg[i].center_chan;
+
+	return 0;
+}
+
+
 const struct {
 	int first;
 	int last;
@@ -429,6 +442,19 @@  static int acs_usable_bw80_chan(const struct hostapd_channel_data *chan)
 }
 
 
+static int acs_get_bw80_center_chan(int freq)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(bw80_seg); i++)
+		if (freq >= bw80_seg[i].first &&
+		    freq < bw80_seg[i].last + 1)
+			return bw80_seg[i].center_chan;
+
+	return 0;
+}
+
+
 const struct {
 	int first;
 	int last;
@@ -451,6 +477,19 @@  static int acs_usable_bw160_chan(const struct hostapd_channel_data *chan)
 }
 
 
+static int acs_get_bw160_center_chan(int freq)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(bw160_seg); i++)
+		if (freq >= bw160_seg[i].first &&
+		    freq < bw160_seg[i].last + 1)
+			return bw160_seg[i].center_chan;
+
+	return 0;
+}
+
+
 static int acs_survey_is_sufficient(struct freq_survey *survey)
 {
 	if (!(survey->filled & SURVEY_HAS_NF)) {
@@ -944,19 +983,21 @@  bw_selected:
 
 static void acs_adjust_center_freq(struct hostapd_iface *iface)
 {
-	int offset;
+	int center;
 
 	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
 
 	switch (hostapd_get_oper_chwidth(iface->conf)) {
 	case CHANWIDTH_USE_HT:
-		offset = 2 * iface->conf->secondary_channel;
+		center = (iface->conf->secondary_channel) ?
+			  acs_get_bw40_center_chan(iface->freq):
+			  iface->conf->channel;
 		break;
 	case CHANWIDTH_80MHZ:
-		offset = 6;
+		center = acs_get_bw80_center_chan(iface->freq);
 		break;
 	case CHANWIDTH_160MHZ:
-		offset = 14;
+		center = acs_get_bw160_center_chan(iface->freq);
 		break;
 	default:
 		/* TODO: How can this be calculated? Adjust
@@ -966,8 +1007,7 @@  static void acs_adjust_center_freq(struct hostapd_iface *iface)
 		return;
 	}
 
-	hostapd_set_oper_centr_freq_seg0_idx(iface->conf,
-					     iface->conf->channel + offset);
+	hostapd_set_oper_centr_freq_seg0_idx(iface->conf, center);
 }