[PATCH 4/4] ACS: Extend the 320 MHz support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There are bandwidth 320 MHz-1 and 320 MHz-2 channelization in EHT mode.
When using ACS, user might prefer one of the channelization or both, but
original ACS was unable to take such perference.

Another problem is that the original ACS returns only the ideal channel
but no 320 MHz channelization. The function acs_get_bw_center_chan()
also could not correctly returns the center frequency of bandwidth 320
MHz that is decided by ACS.

For example, if ACS decide the ideal channel is channel 37 with
channelization 320 MHz-2 (center frequency 6265 MHz),
acs_get_bw_center_chan() returns 6105 MHz, which is 320 MHz-1.

This patch extends the support for 320 MHz so that ACS can choose the
best channel according to the user's preference. Also, after calling
acs_find_ideal_chan_mode(), the best channel and bandwidth can be
derived.

The changes of this patch are:
- bw_type ACS_BW320 is divided into ACS_BW320_1 and ACS_BW320_2
- in bandwidth 320 MHz, find the best channel and bandwidth according to
  user's perference (320 MHz-1, 320 Mhz-2 or both are OK)
- before acs_find_ideal_chan_mode() returns, update bw320_offset in
  iface->conf so that the best channel's channelization is recorded.
- get the best center frequency from bw320_offset

Co-developed-by: Money Wang <money.wang@xxxxxxxxxxxx>
Signed-off-by: Michael-CY Lee <michael-cy.lee@xxxxxxxxxxxx>
---
 src/ap/acs.c | 90 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 73 insertions(+), 17 deletions(-)

diff --git a/src/ap/acs.c b/src/ap/acs.c
index b571459af..a5a870c1b 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -245,7 +245,8 @@ enum bw_type {
 	ACS_BW40,
 	ACS_BW80,
 	ACS_BW160,
-	ACS_BW320,
+	ACS_BW320_1,
+	ACS_BW320_2
 };
 
 struct bw_item {
@@ -287,16 +288,20 @@ static const struct bw_item bw_160[] = {
 	{ 6435, 6575, 111 }, { 6595, 6735, 143 },
 	{ 6755, 6895, 175 }, { 6915, 7055, 207 }, { -1, -1, -1 }
 };
-static const struct bw_item bw_320[] = {
-	{ 5955, 6255, 31 },  { 6115, 6415, 63 }, { 6275, 6575, 95 },
-	{ 6435, 6735, 127 }, { 6595, 6895, 159}, { 6755, 7055, 191 },
+static const struct bw_item bw_320_1[] = {
+	{ 5955, 6255, 31 }, { 6275, 6575, 95 }, { 6595, 6895, 159 },
+	{ -1, -1, -1 }
+};
+static const struct bw_item bw_320_2[] = {
+	{ 6115, 6415, 63 }, { 6435, 6735, 127 }, { 6755, 7055, 191 },
 	{ -1, -1, -1 }
 };
 static const struct bw_item *bw_desc[] = {
 	[ACS_BW40] = bw_40,
 	[ACS_BW80] = bw_80,
 	[ACS_BW160] = bw_160,
-	[ACS_BW320] = bw_320,
+	[ACS_BW320_1] = bw_320_1,
+	[ACS_BW320_2] = bw_320_2,
 };
 
 
@@ -775,6 +780,42 @@ static void acs_update_puncturing_bitmap(struct hostapd_iface *iface,
 #endif /* CONFIG_IEEE80211BE */
 
 
+static bool
+acs_usable_bw320_chan(struct hostapd_iface *iface,
+		      struct hostapd_channel_data *chan, int *bw320_offset)
+{
+	char *bw320_str[] = { "320 MHz", "320 MHz-1", "320 MHz-2" };
+	int conf_bw320_offset = hostapd_get_bw320_offset(iface->conf);
+
+	*bw320_offset = 0;
+	switch (conf_bw320_offset) {
+	case 2:
+		if (acs_usable_bw_chan(chan, ACS_BW320_2))
+			*bw320_offset = 2;
+		break;
+	case 1:
+		if (acs_usable_bw_chan(chan, ACS_BW320_1))
+			*bw320_offset = 1;
+		break;
+	case 0:
+	default:
+		conf_bw320_offset = 0;
+		if (acs_usable_bw_chan(chan, ACS_BW320_1))
+			*bw320_offset = 1;
+		else if (acs_usable_bw_chan(chan, ACS_BW320_2))
+			*bw320_offset = 2;
+		break;
+	}
+
+	if (!*bw320_offset)
+		wpa_printf(MSG_DEBUG,
+			   "ACS: Channel %d: not allowed as primary channel for %s bandwidth",
+			   chan->chan, bw320_str[conf_bw320_offset]);
+
+	return *bw320_offset != 0;
+}
+
+
 static void
 acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 			 struct hostapd_hw_modes *mode,
@@ -785,9 +826,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 {
 	struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
 	long double factor;
-	int i, j;
+	int i, j, secondary_channel = 1;
+	int freq_offset, bw320_offset = 0, ideal_bw320_offset = 0;
 	unsigned int k;
-	int secondary_channel = 1, freq_offset;
 
 	if (is_24ghz_mode(mode->mode))
 		secondary_channel = iface->conf->secondary_channel;
@@ -849,7 +890,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 		}
 
 		if (mode->mode == HOSTAPD_MODE_IEEE80211A &&
-		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax)) {
+		    (iface->conf->ieee80211ac || iface->conf->ieee80211ax ||
+		     iface->conf->ieee80211be)) {
 			if (hostapd_get_oper_chwidth(iface->conf) ==
 			    CONF_OPER_CHWIDTH_80MHZ &&
 			    !acs_usable_bw_chan(chan, ACS_BW80)) {
@@ -873,12 +915,8 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 		    iface->conf->ieee80211be) {
 			if (hostapd_get_oper_chwidth(iface->conf) ==
 			    CONF_OPER_CHWIDTH_320MHZ &&
-			    !acs_usable_bw_chan(chan, ACS_BW320)) {
-				wpa_printf(MSG_DEBUG,
-					   "ACS: Channel %d: not allowed as primary channel for 320 MHz bandwidth",
-					   chan->chan);
+			    !acs_usable_bw320_chan(iface, chan, &bw320_offset))
 				continue;
-			}
 		}
 
 		factor = 0;
@@ -1011,6 +1049,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 
 			*ideal_factor = factor;
 			*ideal_chan = chan;
+			ideal_bw320_offset = bw320_offset;
 
 #ifdef CONFIG_IEEE80211BE
 			if (iface->conf->ieee80211be)
@@ -1021,9 +1060,13 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
 		}
 
 		/* This channel would at least be usable */
-		if (!(*rand_chan))
+		if (!(*rand_chan)) {
 			*rand_chan = chan;
+			ideal_bw320_offset = bw320_offset;
+		}
 	}
+
+	hostapd_set_and_check_bw320_offset(iface->conf, ideal_bw320_offset);
 }
 
 
@@ -1115,7 +1158,7 @@ static void acs_adjust_secondary(struct hostapd_iface *iface)
 	    acs_find_mode(iface, iface->freq) != HOSTAPD_MODE_IEEE80211A)
 		return;
 
-	wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE secondary frequency");
+	wpa_printf(MSG_DEBUG, "ACS: Adjusting HT/VHT/HE/EHT secondary frequency");
 
 	for (i = 0; bw_desc[ACS_BW40][i].first != -1; i++) {
 		if (iface->freq == bw_desc[ACS_BW40][i].first)
@@ -1130,7 +1173,7 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
 {
 	int center;
 
-	wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
+	wpa_printf(MSG_DEBUG, "ACS: Adjusting center frequency");
 
 	switch (hostapd_get_oper_chwidth(iface->conf)) {
 	case CONF_OPER_CHWIDTH_USE_HT:
@@ -1150,7 +1193,20 @@ static void acs_adjust_center_freq(struct hostapd_iface *iface)
 		center = acs_get_bw_center_chan(iface->freq, ACS_BW160);
 		break;
 	case CONF_OPER_CHWIDTH_320MHZ:
-		center = acs_get_bw_center_chan(iface->freq, ACS_BW320);
+		switch (hostapd_get_bw320_offset(iface->conf)) {
+		case 2:
+			center = acs_get_bw_center_chan(iface->freq,
+							ACS_BW320_2);
+			break;
+		case 1:
+			center = acs_get_bw_center_chan(iface->freq,
+							ACS_BW320_1);
+			break;
+		default:
+			wpa_printf(MSG_INFO, "ACS: BW320 offset is not selected");
+			break;
+		}
+
 		break;
 	default:
 		/* TODO: How can this be calculated? Adjust
-- 
2.25.1


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux