]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Fix mode settings with split wiphy dump
authorJohannes Berg <johannes.berg@intel.com>
Tue, 19 Mar 2013 00:01:46 +0000 (02:01 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 19 Mar 2013 00:01:46 +0000 (02:01 +0200)
When the wiphy information is split, there's no guarantee that the
channels are processed before the bitrates; in fact, with the current
kernel it happens the other way around. Therefore, the mode information
isn't set up correctly and there's no 11g mode.

Fix this by doing the 11b/11g determination as part of the
postprocessing.

Signed-hostap: Johannes Berg <johannes.berg@intel.com>

src/drivers/driver_nl80211.c

index 0c7098d047afa726558eb2e2179d4052ba5bee21..ebc3f6fbd0126cbf9e40ee0f52e61c6ad4ecfb34 100644 (file)
@@ -5082,21 +5082,19 @@ static void phy_info_freq(struct hostapd_hw_modes *mode,
                          struct hostapd_channel_data *chan,
                          struct nlattr *tb_freq[])
 {
+       enum hostapd_hw_mode m;
+
        chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
        chan->flag = 0;
 
-       /* mode is not set */
-       if (mode->mode >= NUM_HOSTAPD_MODES) {
-               /* crude heuristic */
-               if (chan->freq < 4000)
-                       mode->mode = HOSTAPD_MODE_IEEE80211B;
-               else if (chan->freq > 50000)
-                       mode->mode = HOSTAPD_MODE_IEEE80211AD;
-               else
-                       mode->mode = HOSTAPD_MODE_IEEE80211A;
-       }
+       if (chan->freq < 4000)
+               m = HOSTAPD_MODE_IEEE80211B;
+       else if (chan->freq > 50000)
+               m = HOSTAPD_MODE_IEEE80211AD;
+       else
+               m = HOSTAPD_MODE_IEEE80211A;
 
-       switch (mode->mode) {
+       switch (m) {
        case HOSTAPD_MODE_IEEE80211AD:
                chan->chan = (chan->freq - 56160) / 2160;
                break;
@@ -5220,12 +5218,6 @@ static int phy_info_rates(struct hostapd_hw_modes *mode, struct nlattr *tb)
                        continue;
                mode->rates[idx] = nla_get_u32(
                        tb_rate[NL80211_BITRATE_ATTR_RATE]);
-
-               /* crude heuristic */
-               if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
-                   mode->rates[idx] > 200)
-                       mode->mode = HOSTAPD_MODE_IEEE80211G;
-
                idx++;
        }
 
@@ -5303,12 +5295,31 @@ static int phy_info_handler(struct nl_msg *msg, void *arg)
 
 
 static struct hostapd_hw_modes *
-wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
+wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
+                                    u16 *num_modes)
 {
        u16 m;
        struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
        int i, mode11g_idx = -1;
 
+       /* heuristic to set up modes */
+       for (m = 0; m < *num_modes; m++) {
+               if (!modes[m].num_channels)
+                       continue;
+               if (modes[m].channels[0].freq < 4000) {
+                       modes[m].mode = HOSTAPD_MODE_IEEE80211B;
+                       for (i = 0; i < modes[m].num_rates; i++) {
+                               if (modes[m].rates[i] > 200) {
+                                       modes[m].mode = HOSTAPD_MODE_IEEE80211G;
+                                       break;
+                               }
+                       }
+               } else if (modes[m].channels[0].freq > 50000)
+                       modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
+               else
+                       modes[m].mode = HOSTAPD_MODE_IEEE80211A;
+       }
+
        /* If only 802.11g mode is included, use it to construct matching
         * 802.11b mode data. */
 
@@ -5554,7 +5565,8 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
 
        if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
                nl80211_set_ht40_flags(drv, &result);
-               return wpa_driver_nl80211_add_11b(result.modes, num_modes);
+               return wpa_driver_nl80211_postprocess_modes(result.modes,
+                                                           num_modes);
        }
        msg = NULL;
  nla_put_failure: