]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Populate iface->freq before starting AP
authorAnkita Bajaj <bankita@codeaurora.org>
Mon, 18 Nov 2019 09:09:04 +0000 (14:39 +0530)
committerJouni Malinen <j@w1.fi>
Fri, 20 Dec 2019 10:42:47 +0000 (12:42 +0200)
Using channel field while starting AP will cause issues with the new
6GHz band as the channel numbers are duplicated between the different
bands. Populate iface->freq before starting AP so that it can be used
instead of the channel number for all validations that need to be done
while starting AP.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/acs.c
src/ap/hostapd.c
src/ap/hw_features.c

index f12539fcd6b80d49bb6bfa6503f11fbd8b6046e7..232afa8903abf4e1baf342369fbd18855a177094 100644 (file)
@@ -862,6 +862,7 @@ 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)
                acs_adjust_center_freq(iface);
index 368643867f38c0b5eb03a3082ee56bd9a75a8a13..b428bb1639a370da373b0b3bbc0bf5427e3879f0 100644 (file)
@@ -1572,6 +1572,51 @@ static int setup_interface(struct hostapd_iface *iface)
 }
 
 
+static int configured_fixed_chan_to_freq(struct hostapd_iface *iface)
+{
+       int freq, i, j;
+
+       if (!iface->conf->channel)
+               return 0;
+       if (iface->conf->op_class) {
+               freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
+                                             iface->conf->channel);
+               if (freq < 0) {
+                       wpa_printf(MSG_INFO,
+                                  "Could not convert op_class %u channel %u to operating frequency",
+                                  iface->conf->op_class, iface->conf->channel);
+                       return -1;
+               }
+               iface->freq = freq;
+               return 0;
+       }
+
+       /* Old configurations using only 2.4/5/60 GHz bands may not specify the
+        * op_class parameter. Select a matching channel from the configured
+        * mode using the channel parameter for these cases.
+        */
+       for (j = 0; j < iface->num_hw_features; j++) {
+               struct hostapd_hw_modes *mode = &iface->hw_features[j];
+
+               if (iface->conf->hw_mode != HOSTAPD_MODE_IEEE80211ANY &&
+                   iface->conf->hw_mode != mode->mode)
+                       continue;
+               for (i = 0; i < mode->num_channels; i++) {
+                       struct hostapd_channel_data *chan = &mode->channels[i];
+
+                       if (chan->chan == iface->conf->channel &&
+                           !is_6ghz_freq(chan->freq)) {
+                               iface->freq = chan->freq;
+                               return 0;
+                       }
+               }
+       }
+
+       wpa_printf(MSG_INFO, "Could not determine operating frequency");
+       return -1;
+}
+
+
 static int setup_interface2(struct hostapd_iface *iface)
 {
        iface->wait_channel_update = 0;
@@ -1580,7 +1625,13 @@ static int setup_interface2(struct hostapd_iface *iface)
                /* Not all drivers support this yet, so continue without hw
                 * feature data. */
        } else {
-               int ret = hostapd_select_hw_mode(iface);
+               int ret;
+
+               ret = configured_fixed_chan_to_freq(iface);
+               if (ret < 0)
+                       goto fail;
+
+               ret = hostapd_select_hw_mode(iface);
                if (ret < 0) {
                        wpa_printf(MSG_ERROR, "Could not select hw_mode and "
                                   "channel. (%d)", ret);
@@ -1869,7 +1920,6 @@ static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
                int res;
 #endif /* NEED_AP_MLME */
 
-               iface->freq = hostapd_hw_get_freq(hapd, iface->conf->channel);
                wpa_printf(MSG_DEBUG, "Mode: %s  Channel: %d  "
                           "Frequency: %d MHz",
                           hostapd_hw_mode_txt(iface->conf->hw_mode),
index d8accc51abac06513406727cdc5ec8634b85ab7f..a8bec4fcd5fa421108f17521f47d685c04bcc552 100644 (file)
@@ -922,9 +922,7 @@ int hostapd_acs_completed(struct hostapd_iface *iface, int err)
        case HOSTAPD_CHAN_VALID:
                wpa_msg(iface->bss[0]->msg_ctx, MSG_INFO,
                        ACS_EVENT_COMPLETED "freq=%d channel=%d",
-                       hostapd_hw_get_freq(iface->bss[0],
-                                           iface->conf->channel),
-                       iface->conf->channel);
+                       iface->freq, iface->conf->channel);
                break;
        case HOSTAPD_CHAN_ACS:
                wpa_printf(MSG_ERROR, "ACS error - reported complete, but no result available");
@@ -964,7 +962,6 @@ out:
 int hostapd_select_hw_mode(struct hostapd_iface *iface)
 {
        int i;
-       int freq = -1;
 
        if (iface->num_hw_features < 1)
                return -1;
@@ -981,15 +978,13 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
        }
 
        iface->current_mode = NULL;
-       if (iface->conf->channel && iface->conf->op_class)
-               freq = ieee80211_chan_to_freq(NULL, iface->conf->op_class,
-                                             iface->conf->channel);
        for (i = 0; i < iface->num_hw_features; i++) {
                struct hostapd_hw_modes *mode = &iface->hw_features[i];
                if (mode->mode == iface->conf->hw_mode) {
-                       if (freq > 0 && !hw_get_chan(mode->mode, freq,
-                                                    iface->hw_features,
-                                                    iface->num_hw_features))
+                       if (iface->freq > 0 &&
+                           !hw_get_chan(mode->mode, iface->freq,
+                                        iface->hw_features,
+                                        iface->num_hw_features))
                                continue;
                        iface->current_mode = mode;
                        break;