]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ACS: Allow selecting a better channel when using 40/80/160 MHz
authorNicolas Escande <nico.escande@gmail.com>
Wed, 27 Apr 2022 13:37:02 +0000 (15:37 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 28 Nov 2022 21:31:33 +0000 (23:31 +0200)
When considering a channel for a bandwidth of 40/80/160 MHZ on the 5 GHz
or 6 GHz band, allow selecting one of the other channels in the segment
instead of the first one. This is done only if the other channel's
interference_factor is lower than the first one's.

Signed-off-by: Nicolas Escande <nico.escande@gmail.com>
src/ap/acs.c

index 55818a4bc0ff99b7fce6d6d94a36f84afdf254ad..8cb5813e99f406caebc1128a2da967fa9e0398a6 100644 (file)
@@ -719,7 +719,7 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
                         struct hostapd_channel_data **ideal_chan,
                         long double *ideal_factor)
 {
-       struct hostapd_channel_data *chan, *adj_chan = NULL;
+       struct hostapd_channel_data *chan, *adj_chan = NULL, *best;
        long double factor;
        int i, j;
        unsigned int k;
@@ -727,8 +727,9 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
        for (i = 0; i < mode->num_channels; i++) {
                double total_weight;
                struct acs_bias *bias, tmp_bias;
+               bool update_best = true;
 
-               chan = &mode->channels[i];
+               best = chan = &mode->channels[i];
 
                /* Since in the current ACS implementation the first channel is
                 * always a primary channel, skip channels not available as
@@ -815,7 +816,15 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
                        if (acs_usable_chan(adj_chan)) {
                                factor += adj_chan->interference_factor;
                                total_weight += 1;
+                       } else {
+                               update_best = false;
                        }
+
+                       /* find the best channel in this segment */
+                       if (update_best &&
+                           adj_chan->interference_factor <
+                           best->interference_factor)
+                               best = adj_chan;
                }
 
                if (j != n_chans) {
@@ -824,6 +833,18 @@ acs_find_ideal_chan_mode(struct hostapd_iface *iface,
                        continue;
                }
 
+               /* If the AP is in the 5 GHz or 6 GHz band, lets prefer a less
+                * crowded primary channel if one was found in the segment */
+               if (iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
+                   chan != best) {
+                       wpa_printf(MSG_DEBUG,
+                                  "ACS: promoting channel %d over %d (less interference %Lg/%Lg)",
+                                  best->chan, chan->chan,
+                                  chan->interference_factor,
+                                  best->interference_factor);
+                       chan = best;
+               }
+
                /* 2.4 GHz has overlapping 20 MHz channels. Include adjacent
                 * channel interference factor. */
                if (is_24ghz_mode(mode->mode)) {