[PATCH] driver_nl80211: fix mode settings
Johannes Berg
johannes
Mon Mar 18 14:20:57 PDT 2013
From: Johannes Berg <johannes.berg at intel.com>
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 at intel.com>
---
src/drivers/driver_nl80211.c | 50 +++++++++++++++++++++++++++-----------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4cf4e41..b31196c 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5113,21 +5113,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;
@@ -5251,12 +5249,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++;
}
@@ -5334,12 +5326,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. */
@@ -5585,7 +5596,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:
--
1.8.0
More information about the Hostap
mailing list