]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
ACS: introduce acs_adjust_secondary
authorNicolas Escande <nico.escande@gmail.com>
Wed, 27 Apr 2022 13:37:01 +0000 (15:37 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 28 Nov 2022 21:23:13 +0000 (23:23 +0200)
When using 40/80/160 MHz bandwidth on the 5 GHz or 6 GHz band, enforce
the secondary channel to be the other channel of the corresponding 40
MHz 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 its segment.

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

index 703a7a80c81a7529c9db4f73e6e128627a6bdefb..55818a4bc0ff99b7fce6d6d94a36f84afdf254ad 100644 (file)
@@ -641,6 +641,26 @@ acs_find_chan_mode(struct hostapd_hw_modes *mode, int freq)
 }
 
 
+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)
 {
@@ -957,6 +977,28 @@ bw_selected:
 }
 
 
+static void acs_adjust_secondary(struct hostapd_iface *iface)
+{
+       unsigned int i;
+
+       /* When working with bandwidth over 20 MHz on the 5 GHz or 6 GHz band,
+        * ACS can return a secondary channel which is not the first channel of
+        * the segment and we need to adjust. */
+       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][i].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;
@@ -1044,8 +1086,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 = hostapd_select_hw_mode(iface);
        if (err) {