This cleans up, fixes and adds missing rates and modulations defines. It should make some interesting (and important) features possible (like selecting of allowed modulations and rates, etc.). - Added modulations enum. Rewritten rates constants to enum too. - Rewritten arrays of supported rates in network struct to bitfields - this should ease operations with them. Also meaning of these two fields was slightly modified for easy identification of the Basic Rate Set. - Removed a/b/g mode flags and variables as they are not needed for anything (except reporting to userspace - and in such a case they can be easily determined from modulations). Signed-off-by: Jiri Benc Signed-off-by: Jirka Bohac Index: netdev/net/ieee80211/ieee80211_wx.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_wx.c 2005-09-17 14:52:53.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_wx.c 2005-09-17 14:59:05.000000000 +0200 @@ -36,10 +36,6 @@ #include #include -static const char *ieee80211_modes[] = { - "?", "a", "b", "ab", "g", "ag", "bg", "abg" -}; - #define MAX_CUSTOM_LEN 64 static inline char *ipw2100_translate_scan(struct ieee80211_device *ieee, char *start, char *stop, @@ -48,8 +44,9 @@ static inline char *ipw2100_translate_sc char custom[MAX_CUSTOM_LEN]; char *p; struct iw_event iwe; - int i, j; + int i; u8 max_rate, rate; + char mode[4]; /* First entry *MUST* be the AP MAC address */ iwe.cmd = SIOCGIWAP; @@ -72,8 +69,14 @@ static inline char *ipw2100_translate_sc /* Add the protocol name */ iwe.cmd = SIOCGIWNAME; - snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", - ieee80211_modes[network->mode]); + mode[0] = '\0'; + if (network->modulations & IEEE80211_A_MANDATORY_MODULATIONS) + strcat(mode, "a"); + if (network->modulations & IEEE80211_B_MANDATORY_MODULATIONS) + strcat(mode, "b"); + if (network->modulations & IEEE80211_G_MANDATORY_MODULATIONS) + strcat(mode, "g"); + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", mode); start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN); /* Add mode */ @@ -109,25 +112,15 @@ static inline char *ipw2100_translate_sc max_rate = 0; p = custom; p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); - for (i = 0, j = 0; i < network->rates_len;) { - if (j < network->rates_ex_len && - ((network->rates_ex[j] & 0x7F) < - (network->rates[i] & 0x7F))) - rate = network->rates_ex[j++] & 0x7F; - else - rate = network->rates[i++] & 0x7F; + for (i = 0; i < IEEE80211_NUM_RATES; i++) { + if (((network->rates | network->rates_ex) & (1 << i)) == 0) + continue; + rate = ieee80211_rate_values[i]; if (rate > max_rate) max_rate = rate; p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); } - for (; j < network->rates_ex_len; j++) { - rate = network->rates_ex[j] & 0x7F; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - if (rate > max_rate) - max_rate = rate; - } iwe.cmd = SIOCGIWRATE; iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; Index: netdev/net/ieee80211/ieee80211_proto.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_proto.c 2005-09-17 14:58:56.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_proto.c 2005-09-17 14:59:05.000000000 +0200 @@ -32,6 +32,17 @@ #include +/* Table for converting internally used rate constants (enum ieee80211_rate) + * to (and from) values used in Supported Rates Information Elements. */ +u8 ieee80211_rate_values[IEEE80211_NUM_RATES] = { + 0x02, 0x04, + 0x0b, 0x16, + 0x2c, 0x42, + 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c +}; +EXPORT_SYMBOL(ieee80211_rate_values); + + static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) { if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN - 8 - SNAP_SIZE)) Index: netdev/include/net/ieee80211.h =================================================================== --- netdev.orig/include/net/ieee80211.h 2005-09-17 14:58:51.000000000 +0200 +++ netdev/include/net/ieee80211.h 2005-09-17 15:04:03.000000000 +0200 @@ -263,7 +263,7 @@ static inline u8 *ieee80211_get_saddr(st #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) -#define WLAN_CAPABILITY_OSSS_OFDM (1<<13) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) /* Status codes */ enum ieee80211_statuscode { @@ -287,7 +287,7 @@ enum ieee80211_statuscode { WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, /* 802.11g */ - WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, + WLAN_STATUS_ASSOC_DENIED_NOSHORTSLOT = 25, WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, /* 802.11i */ WLAN_STATUS_INVALID_IE = 40, @@ -334,62 +334,115 @@ enum ieee80211_reasoncode { #define IEEE80211_STATMASK_RATE (1<<3) #define IEEE80211_STATMASK_WEMASK 0x7 -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) +enum ieee80211_modulation { + IEEE80211_DSSS_MODULATION, + /* 802.11a */ + IEEE80211_OFDM_MODULATION, + /* 802.11b */ + IEEE80211_PBCC_MODULATION, + /* 802.11g */ + IEEE80211_ERP_OFDM_MODULATION, + IEEE80211_DSSS_OFDM_MODULATION, +}; -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) +#define IEEE80211_DSSS_MODULATION_MASK (1 << IEEE80211_DSSS_MODULATION) +#define IEEE80211_OFDM_MODULATION_MASK (1 << IEEE80211_OFDM_MODULATION) +#define IEEE80211_PBCC_MODULATION_MASK (1 << IEEE80211_PBCC_MODULATION) +#define IEEE80211_ERP_OFDM_MODULATION_MASK (1 << IEEE80211_ERP_OFDM_MODULATION) +#define IEEE80211_DSSS_OFDM_MODULATION_MASK (1 << IEEE80211_DSSS_OFDM_MODULATION) + +#define IEEE80211_A_MANDATORY_MODULATIONS IEEE80211_OFDM_MODULATION_MASK +#define IEEE80211_B_MANDATORY_MODULATIONS IEEE80211_DSSS_MODULATION_MASK +#define IEEE80211_G_MANDATORY_MODULATIONS (IEEE80211_DSSS_MODULATION_MASK | \ + IEEE80211_ERP_OFDM_MODULATION_MASK) +#define IEEE80211_A_MODULATIONS IEEE80211_OFDM_MODULATION_MASK +#define IEEE80211_B_MODULATIONS (IEEE80211_DSSS_MODULATION_MASK | \ + IEEE80211_PBCC_MODULATION_MASK) +#define IEEE80211_G_MODULATIONS (IEEE80211_DSSS_MODULATION_MASK | \ + IEEE80211_PBCC_MODULATION_MASK | \ + IEEE80211_ERP_OFDM_MODULATION_MASK | \ + IEEE80211_DSSS_OFDM_MODULATION_MASK) + +#define IEEE80211_A_MODE(modulations) (((modulations) & IEEE80211_A_MANDATORY_MODULATIONS) \ + == IEEE80211_A_MANDATORY_MODULATIONS) +#define IEEE80211_B_OR_G_MODE(mods) (((mods) & IEEE80211_B_MANDATORY_MODULATIONS) \ + == IEEE80211_B_MANDATORY_MODULATIONS) +#define IEEE80211_G_MODE(modulations) (((modulations) & IEEE80211_G_MANDATORY_MODULATIONS) \ + == IEEE80211_G_MANDATORY_MODULATIONS) +#define IEEE80211_B_MODE(modulations) (IEEE80211_B_OR_G_MODE(modulations) \ + && !IEEE80211_G_MODE(modulations)) + +#define IEEE80211_HAS_24GHZ_MODE(mods) (((mods) & \ + (IEEE80211_DSSS_MODULATION_MASK | \ + IEEE80211_PBCC_MODULATION_MASK | \ + IEEE80211_ERP_OFDM_MODULATION_MASK | \ + IEEE80211_DSSS_OFDM_MODULATION_MASK)) \ + != 0) +#define IEEE80211_HAS_52GHZ_MODE(mods) (((mods) & IEEE80211_OFDM_MODULATION_MASK) != 0) + +enum ieee80211_rate { + /* DSSS (DBPSK, DQPSK) rates */ + IEEE80211_RATE_1MB, + IEEE80211_RATE_2MB, + /* DSSS (CCK) and PBCC rates */ + IEEE80211_RATE_5MB, + IEEE80211_RATE_11MB, + /* (ERP-)PBCC rates */ + IEEE80211_RATE_22MB, + IEEE80211_RATE_33MB, + /* OFDM, ERP-OFDM and DSSS-OFDM rates */ + IEEE80211_RATE_6MB, + IEEE80211_RATE_9MB, + IEEE80211_RATE_12MB, + IEEE80211_RATE_18MB, + IEEE80211_RATE_24MB, + IEEE80211_RATE_36MB, + IEEE80211_RATE_48MB, + IEEE80211_RATE_54MB, +}; +#define IEEE80211_NUM_RATES (IEEE80211_RATE_54MB + 1) -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C +/* Values for Supported Rates Information Elements; indexed by + * ieee80211_rate enum */ +extern u8 ieee80211_rate_values[IEEE80211_NUM_RATES]; #define IEEE80211_BASIC_RATE_MASK 0x80 -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - -#define IEEE80211_NUM_OFDM_RATES 8 -#define IEEE80211_NUM_CCK_RATES 4 -#define IEEE80211_OFDM_SHIFT_MASK_A 4 +#define IEEE80211_RATE_1MB_MASK (1 << IEEE80211_RATE_1MB) +#define IEEE80211_RATE_2MB_MASK (1 << IEEE80211_RATE_2MB) +#define IEEE80211_RATE_5MB_MASK (1 << IEEE80211_RATE_5MB) +#define IEEE80211_RATE_11MB_MASK (1 << IEEE80211_RATE_11MB) +#define IEEE80211_RATE_22MB_MASK (1 << IEEE80211_RATE_22MB) +#define IEEE80211_RATE_33MB_MASK (1 << IEEE80211_RATE_33MB) +#define IEEE80211_RATE_6MB_MASK (1 << IEEE80211_RATE_6MB) +#define IEEE80211_RATE_9MB_MASK (1 << IEEE80211_RATE_9MB) +#define IEEE80211_RATE_12MB_MASK (1 << IEEE80211_RATE_12MB) +#define IEEE80211_RATE_18MB_MASK (1 << IEEE80211_RATE_18MB) +#define IEEE80211_RATE_24MB_MASK (1 << IEEE80211_RATE_24MB) +#define IEEE80211_RATE_36MB_MASK (1 << IEEE80211_RATE_36MB) +#define IEEE80211_RATE_48MB_MASK (1 << IEEE80211_RATE_48MB) +#define IEEE80211_RATE_54MB_MASK (1 << IEEE80211_RATE_54MB) + +#define IEEE80211_DSSS_RATES_MASK (IEEE80211_RATE_1MB_MASK | \ + IEEE80211_RATE_2MB_MASK | \ + IEEE80211_RATE_5MB_MASK | \ + IEEE80211_RATE_11MB_MASK) +#define IEEE80211_PBCC_RATES_MASK (IEEE80211_RATE_5MB_MASK | \ + IEEE80211_RATE_11MB_MASK | \ + IEEE80211_RATE_22MB_MASK | \ + IEEE80211_RATE_33MB_MASK) +#define IEEE80211_OFDM_RATES_MASK (IEEE80211_RATE_6MB_MASK | \ + IEEE80211_RATE_9MB_MASK | \ + IEEE80211_RATE_12MB_MASK | \ + IEEE80211_RATE_18MB_MASK | \ + IEEE80211_RATE_24MB_MASK | \ + IEEE80211_RATE_36MB_MASK | \ + IEEE80211_RATE_48MB_MASK | \ + IEEE80211_RATE_54MB_MASK) + +#define IEEE80211_DSSS_MANDATORY_RATES IEEE80211_DSSS_RATES_MASK +#define IEEE80211_OFDM_MANDATORY_RATES (IEEE80211_RATE_6MB_MASK | \ + IEEE80211_RATE_12MB_MASK | \ + IEEE80211_RATE_24MB_MASK) /* NOTE: This data is for statistical purposes; not all hardware provides this * information for frames received. Not setting these will not cause @@ -399,11 +452,11 @@ struct ieee80211_rx_stats { s8 rssi; u8 signal; u8 noise; - u16 rate; /* in 100 kbps */ + int modulation; /* ieee80211_modulation constant */ + int rate; /* ieee80211_rate constant */ u8 received_channel; u8 control; u8 mask; - u8 freq; u16 len; }; @@ -613,24 +666,14 @@ struct ieee80211_txb { struct sk_buff *fragments[0]; }; -/* SWEEP TABLE ENTRIES NUMBER */ -#define MAX_SWEEP_TAB_ENTRIES 42 -#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) #define MAX_NETWORK_COUNT 128 #define CRC_LENGTH 4U #define MAX_WPA_IE_LEN 64 +/* ieee80211_network.flags */ #define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) struct ieee80211_network { /* These entries are used to identify a unique network */ @@ -643,12 +686,10 @@ struct ieee80211_network { /* These are network statistics */ struct ieee80211_rx_stats stats; u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; + unsigned modulations; /* modulations supported by the network */ + u32 rates; /* rates belonging to the basic rate set */ + u32 rates_ex; /* extra rates supported by the network */ unsigned long last_scanned; - u8 mode; u8 flags; u32 last_associate; u32 time_stamp[2]; @@ -719,6 +760,9 @@ struct ieee80211_device { u32 config; /* Determines what is done by the layer and what is * left to the driver */ + /* Modulations and rates supported by the device */ + unsigned supported_modulations; + u32 supported_rates; /* WEP and other encryption related settings at the device level */ int open_wep; /* Set to 1 to allow unencrypted frames */ @@ -756,10 +800,9 @@ struct ieee80211_device { enum ieee80211_state state; - int mode; /* A, B, G */ - int modulation; /* CCK, OFDM */ - int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ - int abg_true; /* ABG flag */ + /* Enabled modulations and rates */ + unsigned modulations; + u32 rates; int perfect_rssi; int worst_rssi; @@ -774,11 +817,6 @@ struct ieee80211_device { void *priv; }; -#define IEEE_A (1<<0) -#define IEEE_B (1<<1) -#define IEEE_G (1<<2) -#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) - static inline void *ieee80211_priv(struct ieee80211_device *ieee) { return (char *)ieee + @@ -823,31 +861,27 @@ extern inline int ieee80211_is_empty_ess return 1; } -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, - int mode) +static inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, + struct ieee80211_network *network) { /* * It is possible for both access points and our device to support * combinations of modes, so as long as there is one valid combination * of ap/device supported modes, then return success - * */ - if ((mode & IEEE_A) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_52GHZ_BAND)) - return 1; - - if ((mode & IEEE_G) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; + return (ieee->modulations & network->modulations) && + ((ieee->rates & network->rates) == network->rates); +} - if ((mode & IEEE_B) && - (ieee->modulation & IEEE80211_CCK_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; +static inline int ieee80211_value_to_rate(u8 value) +{ + int i; - return 0; + for (i = 0; i < IEEE80211_NUM_RATES; i++) { + if (ieee80211_rate_values[i] == (value & 0x7f)) + return i; + } + return -1; } extern inline int __ieee80211_get_hdrlen(u16 fc) Index: netdev/net/ieee80211/ieee80211_rx.c =================================================================== --- netdev.orig/net/ieee80211/ieee80211_rx.c 2005-09-17 14:58:56.000000000 +0200 +++ netdev/net/ieee80211/ieee80211_rx.c 2005-09-17 15:05:51.000000000 +0200 @@ -783,22 +783,6 @@ int ieee80211_rx(struct ieee80211_device #define MGMT_FRAME_FIXED_PART_LENGTH 0x24 -static inline int ieee80211_is_ofdm_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_OFDM_RATE_6MB: - case IEEE80211_OFDM_RATE_9MB: - case IEEE80211_OFDM_RATE_12MB: - case IEEE80211_OFDM_RATE_18MB: - case IEEE80211_OFDM_RATE_24MB: - case IEEE80211_OFDM_RATE_36MB: - case IEEE80211_OFDM_RATE_48MB: - case IEEE80211_OFDM_RATE_54MB: - return 1; - } - return 0; -} - static inline int ieee80211_network_init(struct ieee80211_device *ieee, struct ieee80211_probe_response *beacon, struct ieee80211_network *network, @@ -811,27 +795,28 @@ static inline int ieee80211_network_init struct ieee80211_info_element *info_element; u16 left; u8 i; + int rate; /* Pull out fixed field data */ memcpy(network->bssid, beacon->header.addr3, IEEE80211_ALEN); network->capability = le16_to_cpu(beacon->capability); + network->rates = network->rates_ex = 0; network->last_scanned = jiffies; network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); network->beacon_interval = le16_to_cpu(beacon->beacon_interval); /* Where to pull this? beacon->listen_interval; */ network->listen_interval = 0x0A; - network->rates_len = network->rates_ex_len = 0; network->last_associate = 0; network->ssid_len = 0; network->flags = 0; network->atim_window = 0; - if (stats->freq == IEEE80211_52GHZ_BAND) { + network->modulations = 1 << stats->modulation; + if (IEEE80211_HAS_52GHZ_MODE(network->modulations)) { /* for A band (No DS info) */ network->channel = stats->received_channel; - } else - network->flags |= NETWORK_HAS_CCK; + } network->wpa_ie_len = 0; network->rsn_ie_len = 0; @@ -869,65 +854,38 @@ static inline int ieee80211_network_init break; case MFIE_TYPE_RATES: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_len = - min(info_element->len, MAX_RATES_LENGTH); - for (i = 0; i < network->rates_len; i++) { - network->rates[i] = info_element->data[i]; -#ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, - sizeof(rates_str) - (p - - rates_str), - "%02X ", network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); - break; - case MFIE_TYPE_RATES_EX: #ifdef CONFIG_IEEE80211_DEBUG p = rates_str; #endif - network->rates_ex_len = - min(info_element->len, MAX_RATES_EX_LENGTH); - for (i = 0; i < network->rates_ex_len; i++) { - network->rates_ex[i] = info_element->data[i]; + for (i = 0; i < info_element->len; i++) { + rate = ieee80211_value_to_rate(info_element->data[i]); + if (rate < 0) { + IEEE80211_DEBUG_SCAN("unknown rate (%02x)\n", + info_element->data[i]); + continue; + } + if (info_element->data[i] & IEEE80211_BASIC_RATE_MASK) + network->rates |= 1 << rate; + else + network->rates_ex |= 1 << rate; #ifdef CONFIG_IEEE80211_DEBUG p += snprintf(p, sizeof(rates_str) - (p - rates_str), - "%02X ", network->rates[i]); + "%02X ", info_element->data[i]); #endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } } - IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES%s: '%s'\n", + info_element->id == MFIE_TYPE_RATES ? "" : "_EX", + rates_str); break; case MFIE_TYPE_DS_SET: IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n", info_element->data[0]); - if (stats->freq == IEEE80211_24GHZ_BAND) + if (IEEE80211_HAS_24GHZ_MODE(network->modulations)) network->channel = info_element->data[0]; break; @@ -987,23 +945,14 @@ static inline int ieee80211_network_init &info_element->data[info_element->len]; } - network->mode = 0; - if (stats->freq == IEEE80211_52GHZ_BAND) - network->mode = IEEE_A; - else { - if (network->flags & NETWORK_HAS_OFDM) - network->mode |= IEEE_G; - if (network->flags & NETWORK_HAS_CCK) - network->mode |= IEEE_B; - } - - if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' " - "network.\n", - escape_essid(network->ssid, - network->ssid_len), - MAC_ARG(network->bssid)); - return 1; + if (IEEE80211_HAS_24GHZ_MODE(network->modulations)) { + network->modulations |= IEEE80211_DSSS_MODULATION_MASK; + if ((network->rates | network->rates_ex) & IEEE80211_OFDM_RATES_MASK) + network->modulations |= IEEE80211_ERP_OFDM_MODULATION_MASK; + if (network->capability & WLAN_CAPABILITY_PBCC) + network->modulations |= IEEE80211_PBCC_MODULATION_MASK; + if (network->capability & WLAN_CAPABILITY_DSSS_OFDM) + network->modulations |= IEEE80211_DSSS_OFDM_MODULATION_MASK; } if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) @@ -1031,12 +980,10 @@ static inline void update_network(struct { memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); dst->capability = src->capability; - memcpy(dst->rates, src->rates, src->rates_len); - dst->rates_len = src->rates_len; - memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); - dst->rates_ex_len = src->rates_ex_len; + dst->modulations = src->modulations; + dst->rates = src->rates; + dst->rates_ex = src->rates_ex; - dst->mode = src->mode; dst->flags = src->flags; dst->time_stamp[0] = src->time_stamp[0]; dst->time_stamp[1] = src->time_stamp[1];