diff mbox series

[RFC,3/4] ACS: introduce acs_adjust_secondary

Message ID 20220324141920.317515-4-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 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(-)

Comments

Nicolas Escande March 25, 2022, 3:26 p.m. UTC | #1
On Thu Mar 24, 2022 at 3:19 PM CET, Nicolas Escande wrote:
> 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 --git a/src/ap/acs.c b/src/ap/acs.c
> index 30f2e8d08..9e1810901 100644
> --- a/src/ap/acs.c
> +++ b/src/ap/acs.c
> @@ -670,6 +670,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)
> @@ -981,6 +999,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; i < ARRAY_SIZE(bw40_seg); i++) {
> +		if (iface->freq == bw40_seg[i].first)
> +			iface->conf->secondary_channel = 1;
> +		else /* (iface->freq == bw40_seg[i].last) */

This one should read else if (iface->freq == bw40_seg[i].last)
I'll send and updated V2 later on with other remarks if any

> +			iface->conf->secondary_channel = -1;
> +	}
> +}
> +
> +
>  static void acs_adjust_center_freq(struct hostapd_iface *iface)
>  {
>  	int center;
> @@ -1063,8 +1102,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.35.1
diff mbox series

Patch

diff --git a/src/ap/acs.c b/src/ap/acs.c
index 30f2e8d08..9e1810901 100644
--- a/src/ap/acs.c
+++ b/src/ap/acs.c
@@ -670,6 +670,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)
@@ -981,6 +999,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; i < ARRAY_SIZE(bw40_seg); i++) {
+		if (iface->freq == bw40_seg[i].first)
+			iface->conf->secondary_channel = 1;
+		else /* (iface->freq == bw40_seg[i].last) */
+			iface->conf->secondary_channel = -1;
+	}
+}
+
+
 static void acs_adjust_center_freq(struct hostapd_iface *iface)
 {
 	int center;
@@ -1063,8 +1102,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: