]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wpa_supplicant: Handle HT40 and mode downgrade in AP mode
authorMarkus Theil <markus.theil@tu-ilmenau.de>
Tue, 30 Jun 2020 11:53:19 +0000 (13:53 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 14 Oct 2020 09:49:28 +0000 (12:49 +0300)
Add some missing pieces to the interface configuration of AP/mesh mode
in wpa_supplicant.
 - check for secondary channel and HT40 capability
 - try to downgrade to IEEE 802.11b if 802.11g is not available
Especially with the HT40 check, this code now performs all settings,
which the deleted/duplicated mesh code did.

Signed-off-by: Markus Theil <markus.theil@tu-ilmenau.de>
wpa_supplicant/ap.c

index 895b62ae3479f171e0b2a7e84267cd220eb4457f..bac79b2e430e9979693c492a0de7b87bae62f2f0 100644 (file)
@@ -134,6 +134,24 @@ no_vht:
 }
 
 
+static struct hostapd_hw_modes *
+wpa_supplicant_find_hw_mode(struct wpa_supplicant *wpa_s,
+                           enum hostapd_hw_mode hw_mode)
+{
+       struct hostapd_hw_modes *mode = NULL;
+       int i;
+
+       for (i = 0; i < wpa_s->hw.num_modes; i++) {
+               if (wpa_s->hw.modes[i].mode == hw_mode) {
+                       mode = &wpa_s->hw.modes[i];
+                       break;
+               }
+       }
+
+       return mode;
+}
+
+
 int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
                              struct wpa_ssid *ssid,
                              struct hostapd_config *conf)
@@ -147,9 +165,6 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       /* TODO: enable HT40 if driver supports it;
-        * drop to 11b if driver does not support 11g */
-
        /*
         * Enable HT20 if the driver supports it, by setting conf->ieee80211n
         * and a mask of allowed capabilities within conf->ht_capab.
@@ -158,17 +173,28 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
         */
        if (wpa_s->hw.modes) {
                struct hostapd_hw_modes *mode = NULL;
-               int i, no_ht = 0;
+               int no_ht = 0;
 
                wpa_printf(MSG_DEBUG,
                           "Determining HT/VHT options based on driver capabilities (freq=%u chan=%u)",
                           ssid->frequency, conf->channel);
 
-               for (i = 0; i < wpa_s->hw.num_modes; i++) {
-                       if (wpa_s->hw.modes[i].mode == conf->hw_mode) {
-                               mode = &wpa_s->hw.modes[i];
-                               break;
-                       }
+               mode = wpa_supplicant_find_hw_mode(wpa_s, conf->hw_mode);
+
+               /* May drop to IEEE 802.11b if the driver does not support IEEE
+                * 802.11g */
+               if (!mode && conf->hw_mode == HOSTAPD_MODE_IEEE80211G) {
+                       conf->hw_mode = HOSTAPD_MODE_IEEE80211B;
+                       wpa_printf(MSG_INFO,
+                                  "Try downgrade to IEEE 802.11b as 802.11g is not supported by the current hardware");
+                       mode = wpa_supplicant_find_hw_mode(wpa_s,
+                                                          conf->hw_mode);
+               }
+
+               if (!mode) {
+                       wpa_printf(MSG_ERROR,
+                                  "No match between requested and supported hw modes found");
+                       return -1;
                }
 
 #ifdef CONFIG_HT_OVERRIDES
@@ -193,6 +219,14 @@ int wpa_supplicant_conf_ap_ht(struct wpa_supplicant *wpa_s,
                                      HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET),
                                   ssid->ht40);
                        conf->ieee80211n = 1;
+
+                       if (ssid->ht40 &&
+                           (mode->ht_capab &
+                            HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
+                               conf->secondary_channel = ssid->ht40;
+                       else
+                               conf->secondary_channel = 0;
+
 #ifdef CONFIG_P2P
                        if (ssid->p2p_group &&
                            conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&