Index: mac80211/include/linux/ieee80211.h =================================================================== --- mac80211.orig/include/linux/ieee80211.h 2007-11-11 15:45:23.153490050 +0100 +++ mac80211/include/linux/ieee80211.h 2007-11-11 15:45:30.417904025 +0100 @@ -81,18 +81,18 @@ /* miscellaneous IEEE 802.11 constants */ -#define IEEE80211_MAX_FRAG_THRESHOLD 2346 -#define IEEE80211_MAX_RTS_THRESHOLD 2347 +#define IEEE80211_MAX_FRAG_THRESHOLD 2352 +#define IEEE80211_MAX_RTS_THRESHOLD 2353 #define IEEE80211_MAX_AID 2007 #define IEEE80211_MAX_TIM_LEN 251 -#define IEEE80211_MAX_DATA_LEN 2304 /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section 6.2.1.1.2. - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ + 802.11e clarifies the figure in section 7.1.2. The frame body is + up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */ +#define IEEE80211_MAX_DATA_LEN 2304 +/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */ +#define IEEE80211_MAX_FRAME_LEN 2352 #define IEEE80211_MAX_SSID_LEN 32 Index: mac80211/include/linux/nl80211.h =================================================================== --- mac80211.orig/include/linux/nl80211.h 2007-11-11 15:45:23.161490506 +0100 +++ mac80211/include/linux/nl80211.h 2007-11-11 15:45:30.421904255 +0100 @@ -25,7 +25,7 @@ * either a dump request on a %NL80211_ATTR_WIPHY or a specific get * on an %NL80211_ATTR_IFINDEX is supported. * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires - %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also Index: mac80211/include/net/mac80211.h =================================================================== --- mac80211.orig/include/net/mac80211.h 2007-11-11 15:45:23.169490961 +0100 +++ mac80211/include/net/mac80211.h 2007-11-11 15:45:30.429904707 +0100 @@ -706,11 +706,16 @@ * * @queues: number of available hardware transmit queues for * data packets. WMM/QoS requires at least four. + * + * @rate_control_algorithm: rate control algorithm for this hardware. + * If unset (NULL), the default algorithm will be used. Must be + * set before calling ieee80211_register_hw(). */ struct ieee80211_hw { struct ieee80211_conf conf; struct wiphy *wiphy; struct workqueue_struct *workqueue; + const char *rate_control_algorithm; void *priv; u32 flags; unsigned int extra_tx_headroom; @@ -936,27 +941,11 @@ * and remove_interface calls, i.e. while the interface with the * given local_address is enabled. * - * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card - * to pass unencrypted EAPOL-Key frames even when encryption is - * configured. If the wlan card does not require such a configuration, - * this function pointer can be set to NULL. - * - * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be - * authorized (@authorized=1) or unauthorized (=0). This function can be - * used if the wlan hardware or low-level driver implements PAE. - * mac80211 will filter frames based on authorization state in any case, - * so this function pointer can be NULL if low-level driver does not - * require event notification about port state changes. - * * @hw_scan: Ask the hardware to service the scan request, no need to start * the scan state machine in stack. * * @get_stats: return low-level statistics * - * @set_privacy_invoked: For devices that generate their own beacons and probe - * response or association responses this updates the state of privacy_invoked - * returns 0 for success or an error number. - * * @get_sequence_counter: For devices that have internal sequence counters this * callback allows mac80211 to access the current value of a counter. * This callback seems not well-defined, tell us if you need it. @@ -1029,14 +1018,9 @@ int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, const u8 *local_address, const u8 *address, struct ieee80211_key_conf *key); - int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x); - int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr, - int authorized); int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len); int (*get_stats)(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats); - int (*set_privacy_invoked)(struct ieee80211_hw *hw, - int privacy_invoked); int (*get_sequence_counter)(struct ieee80211_hw *hw, u8* addr, u8 keyidx, u8 txrx, u32* iv32, u16* iv16); Index: mac80211/net/mac80211/aes_ccm.c =================================================================== --- mac80211.orig/net/mac80211/aes_ccm.c 2007-11-11 15:45:23.177491419 +0100 +++ mac80211/net/mac80211/aes_ccm.c 2007-11-11 15:45:30.433904936 +0100 @@ -7,10 +7,10 @@ * published by the Free Software Foundation. */ +#include #include #include #include -#include #include #include "ieee80211_key.h" @@ -63,7 +63,7 @@ s_0 = scratch + AES_BLOCK_LEN; e = scratch + 2 * AES_BLOCK_LEN; - num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); last_len = data_len % AES_BLOCK_LEN; aes_ccm_prepare(tfm, b_0, aad, b, s_0, b); @@ -102,7 +102,7 @@ s_0 = scratch + AES_BLOCK_LEN; a = scratch + 2 * AES_BLOCK_LEN; - num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; + num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN); last_len = data_len % AES_BLOCK_LEN; aes_ccm_prepare(tfm, b_0, aad, b, s_0, a); Index: mac80211/net/mac80211/ieee80211.c =================================================================== --- mac80211.orig/net/mac80211/ieee80211.c 2007-11-11 15:45:23.185491871 +0100 +++ mac80211/net/mac80211/ieee80211.c 2007-11-11 15:45:30.437905164 +0100 @@ -1061,7 +1061,8 @@ ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP); - result = ieee80211_init_rate_ctrl_alg(local, NULL); + result = ieee80211_init_rate_ctrl_alg(local, + hw->rate_control_algorithm); if (result < 0) { printk(KERN_DEBUG "%s: Failed to initialize rate control " "algorithm\n", wiphy_name(local->hw.wiphy)); @@ -1222,8 +1223,17 @@ BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); +#ifdef CONFIG_MAC80211_RCSIMPLE + ret = ieee80211_rate_control_register(&mac80211_rcsimple); + if (ret) + return ret; +#endif + ret = ieee80211_wme_register(); if (ret) { +#ifdef CONFIG_MAC80211_RCSIMPLE + ieee80211_rate_control_unregister(&mac80211_rcsimple); +#endif printk(KERN_DEBUG "ieee80211_init: failed to " "initialize WME (err=%d)\n", ret); return ret; @@ -1237,6 +1247,10 @@ static void __exit ieee80211_exit(void) { +#ifdef CONFIG_MAC80211_RCSIMPLE + ieee80211_rate_control_unregister(&mac80211_rcsimple); +#endif + ieee80211_wme_unregister(); ieee80211_debugfs_netdev_exit(); } Index: mac80211/net/mac80211/ieee80211_i.h =================================================================== --- mac80211.orig/net/mac80211/ieee80211_i.h 2007-11-11 15:45:23.189492100 +0100 +++ mac80211/net/mac80211/ieee80211_i.h 2007-11-11 15:45:30.441905395 +0100 @@ -232,6 +232,7 @@ #define IEEE80211_STA_AUTO_SSID_SEL BIT(10) #define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) +#define IEEE80211_STA_PRIVACY_INVOKED BIT(13) struct ieee80211_if_sta { enum { IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, @@ -261,7 +262,6 @@ unsigned long request; struct sk_buff_head skb_queue; - int key_management_enabled; unsigned long last_probe; #define IEEE80211_AUTH_ALG_OPEN BIT(0) Index: mac80211/net/mac80211/ieee80211_ioctl.c =================================================================== --- mac80211.orig/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:45:23.197492559 +0100 +++ mac80211/net/mac80211/ieee80211_ioctl.c 2007-11-11 15:45:30.441905395 +0100 @@ -305,9 +305,12 @@ ((chan->chan == channel) || (chan->freq == freq))) { local->oper_channel = chan; local->oper_hw_mode = mode; - set++; + set = 1; + break; } } + if (set) + break; } if (set) { @@ -507,10 +510,11 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev, struct iw_request_info *info, - struct iw_point *data, char *extra) + union iwreq_data *wrqu, char *extra) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); + struct iw_scan_req *req = NULL; u8 *ssid = NULL; size_t ssid_len = 0; @@ -535,6 +539,14 @@ return -EOPNOTSUPP; } + /* if SSID was specified explicitly then use that */ + if (wrqu->data.length == sizeof(struct iw_scan_req) && + wrqu->data.flags & IW_SCAN_THIS_ESSID) { + req = (struct iw_scan_req *)extra; + ssid = req->essid; + ssid_len = req->essid_len; + } + return ieee80211_sta_req_scan(dev, ssid, ssid_len); } @@ -621,22 +633,35 @@ { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); bool need_reconfig = 0; + u8 new_power_level; if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM) return -EINVAL; if (data->txpower.flags & IW_TXPOW_RANGE) return -EINVAL; - if (!data->txpower.fixed) - return -EINVAL; - if (local->hw.conf.power_level != data->txpower.value) { - local->hw.conf.power_level = data->txpower.value; + if (data->txpower.fixed) { + new_power_level = data->txpower.value; + } else { + /* Automatic power level. Get the px power from the current + * channel. */ + struct ieee80211_channel* chan = local->oper_channel; + if (!chan) + return -EINVAL; + + new_power_level = chan->power_level; + } + + if (local->hw.conf.power_level != new_power_level) { + local->hw.conf.power_level = new_power_level; need_reconfig = 1; } + if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { local->hw.conf.radio_enabled = !(data->txpower.disabled); need_reconfig = 1; } + if (need_reconfig) { ieee80211_hw_config(local); /* The return value of hw_config is not of big interest here, @@ -904,7 +929,6 @@ struct iw_request_info *info, struct iw_param *data, char *extra) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); int ret = 0; @@ -914,18 +938,21 @@ case IW_AUTH_CIPHER_GROUP: case IW_AUTH_WPA_ENABLED: case IW_AUTH_RX_UNENCRYPTED_EAPOL: - break; case IW_AUTH_KEY_MGMT: + break; + case IW_AUTH_PRIVACY_INVOKED: if (sdata->type != IEEE80211_IF_TYPE_STA) ret = -EINVAL; else { + sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; /* - * Key management was set by wpa_supplicant, - * we only need this to associate to a network - * that has privacy enabled regardless of not - * having a key. + * Privacy invoked by wpa_supplicant, store the + * value and allow associating to a protected + * network without having a key up front. */ - sdata->u.sta.key_management_enabled = !!data->value; + if (data->value) + sdata->u.sta.flags |= + IEEE80211_STA_PRIVACY_INVOKED; } break; case IW_AUTH_80211_AUTH_ALG: @@ -935,11 +962,6 @@ else ret = -EOPNOTSUPP; break; - case IW_AUTH_PRIVACY_INVOKED: - if (local->ops->set_privacy_invoked) - ret = local->ops->set_privacy_invoked( - local_to_hw(local), data->value); - break; default: ret = -EOPNOTSUPP; break; Index: mac80211/net/mac80211/ieee80211_rate.c =================================================================== --- mac80211.orig/net/mac80211/ieee80211_rate.c 2007-11-11 15:45:23.205493011 +0100 +++ mac80211/net/mac80211/ieee80211_rate.c 2007-11-11 15:45:30.441905395 +0100 @@ -25,13 +25,25 @@ { struct rate_control_alg *alg; + if (!ops->name) + return -EINVAL; + + mutex_lock(&rate_ctrl_mutex); + list_for_each_entry(alg, &rate_ctrl_algs, list) { + if (!strcmp(alg->ops->name, ops->name)) { + /* don't register an algorithm twice */ + WARN_ON(1); + return -EALREADY; + } + } + alg = kzalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) { + mutex_unlock(&rate_ctrl_mutex); return -ENOMEM; } alg->ops = ops; - mutex_lock(&rate_ctrl_mutex); list_add_tail(&alg->list, &rate_ctrl_algs); mutex_unlock(&rate_ctrl_mutex); @@ -61,9 +73,12 @@ struct rate_control_alg *alg; struct rate_control_ops *ops = NULL; + if (!name) + return NULL; + mutex_lock(&rate_ctrl_mutex); list_for_each_entry(alg, &rate_ctrl_algs, list) { - if (!name || !strcmp(alg->ops->name, name)) + if (!strcmp(alg->ops->name, name)) if (try_module_get(alg->ops->module)) { ops = alg->ops; break; @@ -80,9 +95,12 @@ { struct rate_control_ops *ops; + if (!name) + name = "simple"; + ops = ieee80211_try_rate_control_ops_get(name); if (!ops) { - request_module("rc80211_%s", name ? name : "default"); + request_module("rc80211_%s", name); ops = ieee80211_try_rate_control_ops_get(name); } return ops; Index: mac80211/net/mac80211/ieee80211_rate.h =================================================================== --- mac80211.orig/net/mac80211/ieee80211_rate.h 2007-11-11 15:45:23.213493469 +0100 +++ mac80211/net/mac80211/ieee80211_rate.h 2007-11-11 15:45:30.445905621 +0100 @@ -65,6 +65,9 @@ struct kref kref; }; +/* default 'simple' algorithm */ +extern struct rate_control_ops mac80211_rcsimple; + int ieee80211_rate_control_register(struct rate_control_ops *ops); void ieee80211_rate_control_unregister(struct rate_control_ops *ops); Index: mac80211/net/mac80211/ieee80211_sta.c =================================================================== --- mac80211.orig/net/mac80211/ieee80211_sta.c 2007-11-11 15:45:23.217493699 +0100 +++ mac80211/net/mac80211/ieee80211_sta.c 2007-11-11 15:46:32.885463850 +0100 @@ -12,7 +12,6 @@ */ /* TODO: - * BSS table: use as the key to support multi-SSID APs * order BSS list by RSSI(?) ("quality of AP") * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, * SSID) @@ -61,7 +60,8 @@ static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, u8 *ssid, size_t ssid_len); static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len); static void ieee80211_rx_bss_put(struct net_device *dev, struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev, @@ -108,14 +108,11 @@ u8 wmm_param_len; }; -enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 }; - -static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems) +static void ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems) { size_t left = len; u8 *pos = start; - int unknown = 0; memset(elems, 0, sizeof(*elems)); @@ -126,15 +123,8 @@ elen = *pos++; left -= 2; - if (elen > left) { -#if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "IEEE 802.11 element parse " - "failed (id=%d elen=%d left=%d)\n", - id, elen, left); -#endif - return ParseFailed; - } + if (elen > left) + return; switch (id) { case WLAN_EID_SSID: @@ -201,28 +191,15 @@ elems->ext_supp_rates_len = elen; break; default: -#if 0 - printk(KERN_DEBUG "IEEE 802.11 element parse ignored " - "unknown element (id=%d elen=%d)\n", - id, elen); -#endif - unknown++; break; } left -= elen; pos += elen; } - - /* Do not trigger error if left == 1 as Apple Airport base stations - * send AssocResps that are one spurious byte too long. */ - - return unknown ? ParseUnknown : ParseOK; } - - static int ecw2cw(int ecw) { int cw = 1; @@ -426,7 +403,9 @@ if (sdata->type != IEEE80211_IF_TYPE_STA) return; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { if (bss->has_erp_value) ieee80211_handle_erp_ie(dev, bss->erp_value); @@ -571,7 +550,8 @@ capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | WLAN_CAPABILITY_SHORT_PREAMBLE; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { if (bss->capability & WLAN_CAPABILITY_PRIVACY) capab |= WLAN_CAPABILITY_PRIVACY; @@ -719,24 +699,30 @@ static int ieee80211_privacy_mismatch(struct net_device *dev, struct ieee80211_if_sta *ifsta) { + struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; - int res = 0; + int bss_privacy; + int wep_privacy; + int privacy_invoked; - if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) || - ifsta->key_management_enabled) + if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) return 0; - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (!bss) return 0; - if (ieee80211_sta_wep_configured(dev) != - !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) - res = 1; + bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); + wep_privacy = !!ieee80211_sta_wep_configured(dev); + privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); ieee80211_rx_bss_put(dev, bss); - return res; + if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) + return 0; + + return 1; } @@ -920,12 +906,7 @@ printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); pos = mgmt->u.auth.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.challenge) { printk(KERN_DEBUG "%s: no challenge IE in shared key auth " "frame\n", dev->name); @@ -1214,12 +1195,7 @@ } pos = mgmt->u.assoc_resp.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse AssocResp\n", - dev->name); - return; - } + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); if (!elems.supp_rates) { printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", @@ -1231,7 +1207,9 @@ * update our stored copy */ if (elems.erp_info && elems.erp_info_len >= 1) { struct ieee80211_sta_bss *bss - = ieee80211_rx_bss_get(dev, ifsta->bssid); + = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { bss->erp_value = elems.erp_info[0]; bss->has_erp_value = 1; @@ -1261,7 +1239,9 @@ " AP\n", dev->name); return; } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); + bss = ieee80211_rx_bss_get(dev, ifsta->bssid, + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len); if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal; @@ -1337,7 +1317,8 @@ static struct ieee80211_sta_bss * -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) +ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1348,6 +1329,11 @@ atomic_inc(&bss->users); atomic_inc(&bss->users); memcpy(bss->bssid, bssid, ETH_ALEN); + bss->channel = channel; + if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) { + memcpy(bss->ssid, ssid, ssid_len); + bss->ssid_len = ssid_len; + } spin_lock_bh(&local->sta_bss_lock); /* TODO: order by RSSI? */ @@ -1359,7 +1345,8 @@ static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel, + u8 *ssid, u8 ssid_len) { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; @@ -1367,7 +1354,10 @@ spin_lock_bh(&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH(bssid)]; while (bss) { - if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { + if (!memcmp(bss->bssid, bssid, ETH_ALEN) && + bss->channel == channel && + bss->ssid_len == ssid_len && + (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) { atomic_inc(&bss->users); break; } @@ -1429,7 +1419,7 @@ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee802_11_elems elems; size_t baselen; - int channel, invalid = 0, clen; + int channel, clen; struct ieee80211_sta_bss *bss; struct sta_info *sta; struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); @@ -1473,9 +1463,7 @@ #endif /* CONFIG_MAC80211_IBSS_DEBUG */ } - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - invalid = 1; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && @@ -1533,9 +1521,11 @@ else channel = rx_status->channel; - bss = ieee80211_rx_bss_get(dev, mgmt->bssid); + bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len); if (!bss) { - bss = ieee80211_rx_bss_add(dev, mgmt->bssid); + bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len); if (!bss) return; } else { @@ -1561,10 +1551,6 @@ bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); - if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { - memcpy(bss->ssid, elems.ssid, elems.ssid_len); - bss->ssid_len = elems.ssid_len; - } bss->supp_rates_len = 0; if (elems.supp_rates) { @@ -1635,7 +1621,6 @@ bss->hw_mode = rx_status->phymode; - bss->channel = channel; bss->freq = rx_status->freq; if (channel != rx_status->channel && (bss->hw_mode == MODE_IEEE80211G || @@ -1695,9 +1680,7 @@ if (baselen > len) return; - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - return; + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); if (elems.erp_info && elems.erp_info_len >= 1) ieee80211_handle_erp_ie(dev, elems.erp_info[0]); @@ -2098,7 +2081,8 @@ { int tmp, hidden_ssid; - if (!memcmp(ifsta->ssid, ssid, ssid_len)) + if (ssid_len == ifsta->ssid_len && + !memcmp(ifsta->ssid, ssid, ssid_len)) return 1; if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) @@ -2357,7 +2341,7 @@ { struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_sta_bss *bss; - struct ieee80211_sub_if_data *sdata; + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_hw_mode *mode; u8 bssid[ETH_ALEN], *pos; int i; @@ -2379,18 +2363,17 @@ printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n", dev->name, MAC_ARG(bssid)); - bss = ieee80211_rx_bss_add(dev, bssid); + bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel, + sdata->u.sta.ssid, sdata->u.sta.ssid_len); if (!bss) return -ENOMEM; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); mode = local->oper_hw_mode; if (local->hw.conf.beacon_int == 0) local->hw.conf.beacon_int = 100; bss->beacon_int = local->hw.conf.beacon_int; bss->hw_mode = local->hw.conf.phymode; - bss->channel = local->hw.conf.channel; bss->freq = local->hw.conf.freq; bss->last_update = jiffies; bss->capability = WLAN_CAPABILITY_IBSS; @@ -2448,7 +2431,8 @@ MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid))) { + (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len))) { printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT " based on configured SSID\n", dev->name, MAC_ARG(bssid)); Index: mac80211/net/mac80211/Kconfig =================================================================== --- mac80211.orig/net/mac80211/Kconfig 2007-11-11 15:45:23.225494151 +0100 +++ mac80211/net/mac80211/Kconfig 2007-11-11 15:45:30.449905846 +0100 @@ -13,6 +13,18 @@ This option enables the hardware independent IEEE 802.11 networking stack. +config MAC80211_RCSIMPLE + bool "'simple' rate control algorithm" if EMBEDDED + default y + depends on MAC80211 + help + This option allows you to turn off the 'simple' rate + control algorithm in mac80211. If you do turn it off, + you absolutely need another rate control algorithm. + + Say Y unless you know you will have another algorithm + available. + config MAC80211_LEDS bool "Enable LED triggers" depends on MAC80211 && LEDS_TRIGGERS Index: mac80211/net/mac80211/Makefile =================================================================== --- mac80211.orig/net/mac80211/Makefile 2007-11-11 15:45:23.233494609 +0100 +++ mac80211/net/mac80211/Makefile 2007-11-11 15:45:30.449905846 +0100 @@ -1,8 +1,9 @@ -obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o +obj-$(CONFIG_MAC80211) += mac80211.o mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o mac80211-objs-$(CONFIG_NET_SCHED) += wme.o +mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o mac80211-objs := \ ieee80211.o \ Index: mac80211/net/mac80211/rc80211_simple.c =================================================================== --- mac80211.orig/net/mac80211/rc80211_simple.c 2007-11-11 15:45:23.237494839 +0100 +++ mac80211/net/mac80211/rc80211_simple.c 2007-11-11 15:45:30.449905846 +0100 @@ -7,7 +7,6 @@ * published by the Free Software Foundation. */ -#include #include #include #include @@ -29,8 +28,6 @@ #define RATE_CONTROL_INTERVAL (HZ / 20) #define RATE_CONTROL_MIN_TX 10 -MODULE_ALIAS("rc80211_default"); - static void rate_control_rate_inc(struct ieee80211_local *local, struct sta_info *sta) { @@ -393,8 +390,7 @@ } #endif -static struct rate_control_ops rate_control_simple = { - .module = THIS_MODULE, +struct rate_control_ops mac80211_rcsimple = { .name = "simple", .tx_status = rate_control_simple_tx_status, .get_rate = rate_control_simple_get_rate, @@ -409,22 +405,3 @@ .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs, #endif }; - - -static int __init rate_control_simple_init(void) -{ - return ieee80211_rate_control_register(&rate_control_simple); -} - - -static void __exit rate_control_simple_exit(void) -{ - ieee80211_rate_control_unregister(&rate_control_simple); -} - - -subsys_initcall(rate_control_simple_init); -module_exit(rate_control_simple_exit); - -MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211"); -MODULE_LICENSE("GPL"); Index: mac80211/net/mac80211/rx.c =================================================================== --- mac80211.orig/net/mac80211/rx.c 2007-11-11 15:45:23.245495291 +0100 +++ mac80211/net/mac80211/rx.c 2007-11-11 15:45:30.449905846 +0100 @@ -509,9 +509,11 @@ rx->key->tx_rx_count++; /* TODO: add threshold stuff again */ } else { +#ifdef CONFIG_MAC80211_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "%s: RX protected frame," " but have no key\n", rx->dev->name); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } Index: mac80211/net/mac80211/wep.c =================================================================== --- mac80211.orig/net/mac80211/wep.c 2007-11-11 15:45:23.253495749 +0100 +++ mac80211/net/mac80211/wep.c 2007-11-11 15:45:30.449905846 +0100 @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include "ieee80211_i.h" @@ -138,9 +138,7 @@ *icv = cpu_to_le32(~crc32_le(~0, data, data_len)); crypto_blkcipher_setkey(tfm, rc4key, klen); - sg.page = virt_to_page(data); - sg.offset = offset_in_page(data); - sg.length = data_len + WEP_ICV_LEN; + sg_init_one(&sg, data, data_len + WEP_ICV_LEN); crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length); } @@ -204,9 +202,7 @@ __le32 crc; crypto_blkcipher_setkey(tfm, rc4key, klen); - sg.page = virt_to_page(data); - sg.offset = offset_in_page(data); - sg.length = data_len + WEP_ICV_LEN; + sg_init_one(&sg, data, data_len + WEP_ICV_LEN); crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length); crc = cpu_to_le32(~crc32_le(~0, data, data_len)); @@ -318,9 +314,11 @@ if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) { if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { +#ifdef CONFIG_MAC80211_DEBUG if (net_ratelimit()) printk(KERN_DEBUG "%s: RX WEP frame, decrypt " "failed\n", rx->dev->name); +#endif /* CONFIG_MAC80211_DEBUG */ return TXRX_DROP; } } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) { Index: mac80211/net/wireless/Kconfig =================================================================== --- mac80211.orig/net/wireless/Kconfig 2007-11-11 15:45:23.261496205 +0100 +++ mac80211/net/wireless/Kconfig 2007-11-11 15:45:30.453906075 +0100 @@ -3,7 +3,7 @@ config NL80211 bool "nl80211 new netlink interface support" - depends CFG80211 + depends on CFG80211 default y ---help--- This option turns on the new netlink interface