Upgrade b43 and mac80211.
[openwrt.git] / package / mac80211 / patches / 000-mac80211_update.patch
diff --git a/package/mac80211/patches/000-mac80211_update.patch b/package/mac80211/patches/000-mac80211_update.patch
deleted file mode 100644 (file)
index 7a1a1e2..0000000
+++ /dev/null
@@ -1,933 +0,0 @@
-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 <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/crypto.h>
- #include <linux/err.h>
--#include <asm/scatterlist.h>
- #include <net/mac80211.h>
- #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 <BSSID,SSID> 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 <linux/module.h>
- #include <linux/init.h>
- #include <linux/netdevice.h>
- #include <linux/types.h>
-@@ -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 <linux/crypto.h>
- #include <linux/err.h>
- #include <linux/mm.h>
--#include <asm/scatterlist.h>
-+#include <linux/scatterlist.h>
- #include <net/mac80211.h>
- #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