fix up hostapd for mac80211
[openwrt.git] / package / mac80211 / patches / 000-mac80211_update.patch
1 Index: mac80211/include/linux/ieee80211.h
2 ===================================================================
3 --- mac80211.orig/include/linux/ieee80211.h     2007-11-11 15:45:23.153490050 +0100
4 +++ mac80211/include/linux/ieee80211.h  2007-11-11 15:45:30.417904025 +0100
5 @@ -81,18 +81,18 @@
6  
7  
8  /* miscellaneous IEEE 802.11 constants */
9 -#define IEEE80211_MAX_FRAG_THRESHOLD   2346
10 -#define IEEE80211_MAX_RTS_THRESHOLD    2347
11 +#define IEEE80211_MAX_FRAG_THRESHOLD   2352
12 +#define IEEE80211_MAX_RTS_THRESHOLD    2353
13  #define IEEE80211_MAX_AID              2007
14  #define IEEE80211_MAX_TIM_LEN          251
15 -#define IEEE80211_MAX_DATA_LEN         2304
16  /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
17     6.2.1.1.2.
18  
19 -   The figure in section 7.1.2 suggests a body size of up to 2312
20 -   bytes is allowed, which is a bit confusing, I suspect this
21 -   represents the 2304 bytes of real data, plus a possible 8 bytes of
22 -   WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
23 +   802.11e clarifies the figure in section 7.1.2. The frame body is
24 +   up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */
25 +#define IEEE80211_MAX_DATA_LEN         2304
26 +/* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */
27 +#define IEEE80211_MAX_FRAME_LEN                2352
28  
29  #define IEEE80211_MAX_SSID_LEN         32
30  
31 Index: mac80211/include/linux/nl80211.h
32 ===================================================================
33 --- mac80211.orig/include/linux/nl80211.h       2007-11-11 15:45:23.161490506 +0100
34 +++ mac80211/include/linux/nl80211.h    2007-11-11 15:45:30.421904255 +0100
35 @@ -25,7 +25,7 @@
36   *     either a dump request on a %NL80211_ATTR_WIPHY or a specific get
37   *     on an %NL80211_ATTR_IFINDEX is supported.
38   * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires
39 -       %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
40 + *     %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE.
41   * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response
42   *     to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX,
43   *     %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also
44 Index: mac80211/include/net/mac80211.h
45 ===================================================================
46 --- mac80211.orig/include/net/mac80211.h        2007-11-11 15:45:23.169490961 +0100
47 +++ mac80211/include/net/mac80211.h     2007-11-11 15:45:30.429904707 +0100
48 @@ -706,11 +706,16 @@
49   *
50   * @queues: number of available hardware transmit queues for
51   *     data packets. WMM/QoS requires at least four.
52 + *
53 + * @rate_control_algorithm: rate control algorithm for this hardware.
54 + *     If unset (NULL), the default algorithm will be used. Must be
55 + *     set before calling ieee80211_register_hw().
56   */
57  struct ieee80211_hw {
58         struct ieee80211_conf conf;
59         struct wiphy *wiphy;
60         struct workqueue_struct *workqueue;
61 +       const char *rate_control_algorithm;
62         void *priv;
63         u32 flags;
64         unsigned int extra_tx_headroom;
65 @@ -936,27 +941,11 @@
66   *     and remove_interface calls, i.e. while the interface with the
67   *     given local_address is enabled.
68   *
69 - * @set_ieee8021x: Enable/disable IEEE 802.1X. This item requests wlan card
70 - *     to pass unencrypted EAPOL-Key frames even when encryption is
71 - *     configured. If the wlan card does not require such a configuration,
72 - *     this function pointer can be set to NULL.
73 - *
74 - * @set_port_auth: Set port authorization state (IEEE 802.1X PAE) to be
75 - *     authorized (@authorized=1) or unauthorized (=0). This function can be
76 - *     used if the wlan hardware or low-level driver implements PAE.
77 - *     mac80211 will filter frames based on authorization state in any case,
78 - *     so this function pointer can be NULL if low-level driver does not
79 - *     require event notification about port state changes.
80 - *
81   * @hw_scan: Ask the hardware to service the scan request, no need to start
82   *     the scan state machine in stack.
83   *
84   * @get_stats: return low-level statistics
85   *
86 - * @set_privacy_invoked: For devices that generate their own beacons and probe
87 - *     response or association responses this updates the state of privacy_invoked
88 - *     returns 0 for success or an error number.
89 - *
90   * @get_sequence_counter: For devices that have internal sequence counters this
91   *     callback allows mac80211 to access the current value of a counter.
92   *     This callback seems not well-defined, tell us if you need it.
93 @@ -1029,14 +1018,9 @@
94         int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
95                        const u8 *local_address, const u8 *address,
96                        struct ieee80211_key_conf *key);
97 -       int (*set_ieee8021x)(struct ieee80211_hw *hw, int use_ieee8021x);
98 -       int (*set_port_auth)(struct ieee80211_hw *hw, u8 *addr,
99 -                            int authorized);
100         int (*hw_scan)(struct ieee80211_hw *hw, u8 *ssid, size_t len);
101         int (*get_stats)(struct ieee80211_hw *hw,
102                          struct ieee80211_low_level_stats *stats);
103 -       int (*set_privacy_invoked)(struct ieee80211_hw *hw,
104 -                                  int privacy_invoked);
105         int (*get_sequence_counter)(struct ieee80211_hw *hw,
106                                     u8* addr, u8 keyidx, u8 txrx,
107                                     u32* iv32, u16* iv16);
108 Index: mac80211/net/mac80211/aes_ccm.c
109 ===================================================================
110 --- mac80211.orig/net/mac80211/aes_ccm.c        2007-11-11 15:45:23.177491419 +0100
111 +++ mac80211/net/mac80211/aes_ccm.c     2007-11-11 15:45:30.433904936 +0100
112 @@ -7,10 +7,10 @@
113   * published by the Free Software Foundation.
114   */
115  
116 +#include <linux/kernel.h>
117  #include <linux/types.h>
118  #include <linux/crypto.h>
119  #include <linux/err.h>
120 -#include <asm/scatterlist.h>
121  
122  #include <net/mac80211.h>
123  #include "ieee80211_key.h"
124 @@ -63,7 +63,7 @@
125         s_0 = scratch + AES_BLOCK_LEN;
126         e = scratch + 2 * AES_BLOCK_LEN;
127  
128 -       num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
129 +       num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
130         last_len = data_len % AES_BLOCK_LEN;
131         aes_ccm_prepare(tfm, b_0, aad, b, s_0, b);
132  
133 @@ -102,7 +102,7 @@
134         s_0 = scratch + AES_BLOCK_LEN;
135         a = scratch + 2 * AES_BLOCK_LEN;
136  
137 -       num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
138 +       num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_LEN);
139         last_len = data_len % AES_BLOCK_LEN;
140         aes_ccm_prepare(tfm, b_0, aad, b, s_0, a);
141  
142 Index: mac80211/net/mac80211/ieee80211.c
143 ===================================================================
144 --- mac80211.orig/net/mac80211/ieee80211.c      2007-11-11 15:45:23.185491871 +0100
145 +++ mac80211/net/mac80211/ieee80211.c   2007-11-11 15:45:30.437905164 +0100
146 @@ -1061,7 +1061,8 @@
147         ieee80211_debugfs_add_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
148         ieee80211_if_set_type(local->mdev, IEEE80211_IF_TYPE_AP);
149  
150 -       result = ieee80211_init_rate_ctrl_alg(local, NULL);
151 +       result = ieee80211_init_rate_ctrl_alg(local,
152 +                                             hw->rate_control_algorithm);
153         if (result < 0) {
154                 printk(KERN_DEBUG "%s: Failed to initialize rate control "
155                        "algorithm\n", wiphy_name(local->hw.wiphy));
156 @@ -1222,8 +1223,17 @@
157  
158         BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb));
159  
160 +#ifdef CONFIG_MAC80211_RCSIMPLE
161 +       ret = ieee80211_rate_control_register(&mac80211_rcsimple);
162 +       if (ret)
163 +               return ret;
164 +#endif
165 +
166         ret = ieee80211_wme_register();
167         if (ret) {
168 +#ifdef CONFIG_MAC80211_RCSIMPLE
169 +               ieee80211_rate_control_unregister(&mac80211_rcsimple);
170 +#endif
171                 printk(KERN_DEBUG "ieee80211_init: failed to "
172                        "initialize WME (err=%d)\n", ret);
173                 return ret;
174 @@ -1237,6 +1247,10 @@
175  
176  static void __exit ieee80211_exit(void)
177  {
178 +#ifdef CONFIG_MAC80211_RCSIMPLE
179 +       ieee80211_rate_control_unregister(&mac80211_rcsimple);
180 +#endif
181 +
182         ieee80211_wme_unregister();
183         ieee80211_debugfs_netdev_exit();
184  }
185 Index: mac80211/net/mac80211/ieee80211_i.h
186 ===================================================================
187 --- mac80211.orig/net/mac80211/ieee80211_i.h    2007-11-11 15:45:23.189492100 +0100
188 +++ mac80211/net/mac80211/ieee80211_i.h 2007-11-11 15:45:30.441905395 +0100
189 @@ -232,6 +232,7 @@
190  #define IEEE80211_STA_AUTO_SSID_SEL    BIT(10)
191  #define IEEE80211_STA_AUTO_BSSID_SEL   BIT(11)
192  #define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
193 +#define IEEE80211_STA_PRIVACY_INVOKED  BIT(13)
194  struct ieee80211_if_sta {
195         enum {
196                 IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
197 @@ -261,7 +262,6 @@
198         unsigned long request;
199         struct sk_buff_head skb_queue;
200  
201 -       int key_management_enabled;
202         unsigned long last_probe;
203  
204  #define IEEE80211_AUTH_ALG_OPEN BIT(0)
205 Index: mac80211/net/mac80211/ieee80211_ioctl.c
206 ===================================================================
207 --- mac80211.orig/net/mac80211/ieee80211_ioctl.c        2007-11-11 15:45:23.197492559 +0100
208 +++ mac80211/net/mac80211/ieee80211_ioctl.c     2007-11-11 15:45:30.441905395 +0100
209 @@ -305,9 +305,12 @@
210                             ((chan->chan == channel) || (chan->freq == freq))) {
211                                 local->oper_channel = chan;
212                                 local->oper_hw_mode = mode;
213 -                               set++;
214 +                               set = 1;
215 +                               break;
216                         }
217                 }
218 +               if (set)
219 +                       break;
220         }
221  
222         if (set) {
223 @@ -507,10 +510,11 @@
224  
225  static int ieee80211_ioctl_siwscan(struct net_device *dev,
226                                    struct iw_request_info *info,
227 -                                  struct iw_point *data, char *extra)
228 +                                  union iwreq_data *wrqu, char *extra)
229  {
230         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
231         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
232 +       struct iw_scan_req *req = NULL;
233         u8 *ssid = NULL;
234         size_t ssid_len = 0;
235  
236 @@ -535,6 +539,14 @@
237                 return -EOPNOTSUPP;
238         }
239  
240 +       /* if SSID was specified explicitly then use that */
241 +       if (wrqu->data.length == sizeof(struct iw_scan_req) &&
242 +           wrqu->data.flags & IW_SCAN_THIS_ESSID) {
243 +               req = (struct iw_scan_req *)extra;
244 +               ssid = req->essid;
245 +               ssid_len = req->essid_len;
246 +       }
247 +
248         return ieee80211_sta_req_scan(dev, ssid, ssid_len);
249  }
250  
251 @@ -621,22 +633,35 @@
252  {
253         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
254         bool need_reconfig = 0;
255 +       u8 new_power_level;
256  
257         if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
258                 return -EINVAL;
259         if (data->txpower.flags & IW_TXPOW_RANGE)
260                 return -EINVAL;
261 -       if (!data->txpower.fixed)
262 -               return -EINVAL;
263  
264 -       if (local->hw.conf.power_level != data->txpower.value) {
265 -               local->hw.conf.power_level = data->txpower.value;
266 +       if (data->txpower.fixed) {
267 +               new_power_level = data->txpower.value;
268 +       } else {
269 +               /* Automatic power level. Get the px power from the current
270 +                * channel. */
271 +               struct ieee80211_channel* chan = local->oper_channel;
272 +               if (!chan)
273 +                       return -EINVAL;
274 +
275 +               new_power_level = chan->power_level;
276 +       }
277 +
278 +       if (local->hw.conf.power_level != new_power_level) {
279 +               local->hw.conf.power_level = new_power_level;
280                 need_reconfig = 1;
281         }
282 +
283         if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
284                 local->hw.conf.radio_enabled = !(data->txpower.disabled);
285                 need_reconfig = 1;
286         }
287 +
288         if (need_reconfig) {
289                 ieee80211_hw_config(local);
290                 /* The return value of hw_config is not of big interest here,
291 @@ -904,7 +929,6 @@
292                                    struct iw_request_info *info,
293                                    struct iw_param *data, char *extra)
294  {
295 -       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
296         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
297         int ret = 0;
298  
299 @@ -914,18 +938,21 @@
300         case IW_AUTH_CIPHER_GROUP:
301         case IW_AUTH_WPA_ENABLED:
302         case IW_AUTH_RX_UNENCRYPTED_EAPOL:
303 -               break;
304         case IW_AUTH_KEY_MGMT:
305 +               break;
306 +       case IW_AUTH_PRIVACY_INVOKED:
307                 if (sdata->type != IEEE80211_IF_TYPE_STA)
308                         ret = -EINVAL;
309                 else {
310 +                       sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
311                         /*
312 -                        * Key management was set by wpa_supplicant,
313 -                        * we only need this to associate to a network
314 -                        * that has privacy enabled regardless of not
315 -                        * having a key.
316 +                        * Privacy invoked by wpa_supplicant, store the
317 +                        * value and allow associating to a protected
318 +                        * network without having a key up front.
319                          */
320 -                       sdata->u.sta.key_management_enabled = !!data->value;
321 +                       if (data->value)
322 +                               sdata->u.sta.flags |=
323 +                                       IEEE80211_STA_PRIVACY_INVOKED;
324                 }
325                 break;
326         case IW_AUTH_80211_AUTH_ALG:
327 @@ -935,11 +962,6 @@
328                 else
329                         ret = -EOPNOTSUPP;
330                 break;
331 -       case IW_AUTH_PRIVACY_INVOKED:
332 -               if (local->ops->set_privacy_invoked)
333 -                       ret = local->ops->set_privacy_invoked(
334 -                                       local_to_hw(local), data->value);
335 -               break;
336         default:
337                 ret = -EOPNOTSUPP;
338                 break;
339 Index: mac80211/net/mac80211/ieee80211_rate.c
340 ===================================================================
341 --- mac80211.orig/net/mac80211/ieee80211_rate.c 2007-11-11 15:45:23.205493011 +0100
342 +++ mac80211/net/mac80211/ieee80211_rate.c      2007-11-11 15:45:30.441905395 +0100
343 @@ -25,13 +25,25 @@
344  {
345         struct rate_control_alg *alg;
346  
347 +       if (!ops->name)
348 +               return -EINVAL;
349 +
350 +       mutex_lock(&rate_ctrl_mutex);
351 +       list_for_each_entry(alg, &rate_ctrl_algs, list) {
352 +               if (!strcmp(alg->ops->name, ops->name)) {
353 +                       /* don't register an algorithm twice */
354 +                       WARN_ON(1);
355 +                       return -EALREADY;
356 +               }
357 +       }
358 +
359         alg = kzalloc(sizeof(*alg), GFP_KERNEL);
360         if (alg == NULL) {
361 +               mutex_unlock(&rate_ctrl_mutex);
362                 return -ENOMEM;
363         }
364         alg->ops = ops;
365  
366 -       mutex_lock(&rate_ctrl_mutex);
367         list_add_tail(&alg->list, &rate_ctrl_algs);
368         mutex_unlock(&rate_ctrl_mutex);
369  
370 @@ -61,9 +73,12 @@
371         struct rate_control_alg *alg;
372         struct rate_control_ops *ops = NULL;
373  
374 +       if (!name)
375 +               return NULL;
376 +
377         mutex_lock(&rate_ctrl_mutex);
378         list_for_each_entry(alg, &rate_ctrl_algs, list) {
379 -               if (!name || !strcmp(alg->ops->name, name))
380 +               if (!strcmp(alg->ops->name, name))
381                         if (try_module_get(alg->ops->module)) {
382                                 ops = alg->ops;
383                                 break;
384 @@ -80,9 +95,12 @@
385  {
386         struct rate_control_ops *ops;
387  
388 +       if (!name)
389 +               name = "simple";
390 +
391         ops = ieee80211_try_rate_control_ops_get(name);
392         if (!ops) {
393 -               request_module("rc80211_%s", name ? name : "default");
394 +               request_module("rc80211_%s", name);
395                 ops = ieee80211_try_rate_control_ops_get(name);
396         }
397         return ops;
398 Index: mac80211/net/mac80211/ieee80211_rate.h
399 ===================================================================
400 --- mac80211.orig/net/mac80211/ieee80211_rate.h 2007-11-11 15:45:23.213493469 +0100
401 +++ mac80211/net/mac80211/ieee80211_rate.h      2007-11-11 15:45:30.445905621 +0100
402 @@ -65,6 +65,9 @@
403         struct kref kref;
404  };
405  
406 +/* default 'simple' algorithm */
407 +extern struct rate_control_ops mac80211_rcsimple;
408 +
409  int ieee80211_rate_control_register(struct rate_control_ops *ops);
410  void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
411  
412 Index: mac80211/net/mac80211/ieee80211_sta.c
413 ===================================================================
414 --- mac80211.orig/net/mac80211/ieee80211_sta.c  2007-11-11 15:45:23.217493699 +0100
415 +++ mac80211/net/mac80211/ieee80211_sta.c       2007-11-11 15:46:32.885463850 +0100
416 @@ -12,7 +12,6 @@
417   */
418  
419  /* TODO:
420 - * BSS table: use <BSSID,SSID> as the key to support multi-SSID APs
421   * order BSS list by RSSI(?) ("quality of AP")
422   * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
423   *    SSID)
424 @@ -61,7 +60,8 @@
425  static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
426                                      u8 *ssid, size_t ssid_len);
427  static struct ieee80211_sta_bss *
428 -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid);
429 +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
430 +                    u8 *ssid, u8 ssid_len);
431  static void ieee80211_rx_bss_put(struct net_device *dev,
432                                  struct ieee80211_sta_bss *bss);
433  static int ieee80211_sta_find_ibss(struct net_device *dev,
434 @@ -108,14 +108,11 @@
435         u8 wmm_param_len;
436  };
437  
438 -enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 };
439 -
440 -static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
441 -                                           struct ieee802_11_elems *elems)
442 +static void ieee802_11_parse_elems(u8 *start, size_t len,
443 +                                  struct ieee802_11_elems *elems)
444  {
445         size_t left = len;
446         u8 *pos = start;
447 -       int unknown = 0;
448  
449         memset(elems, 0, sizeof(*elems));
450  
451 @@ -126,15 +123,8 @@
452                 elen = *pos++;
453                 left -= 2;
454  
455 -               if (elen > left) {
456 -#if 0
457 -                       if (net_ratelimit())
458 -                               printk(KERN_DEBUG "IEEE 802.11 element parse "
459 -                                      "failed (id=%d elen=%d left=%d)\n",
460 -                                      id, elen, left);
461 -#endif
462 -                       return ParseFailed;
463 -               }
464 +               if (elen > left)
465 +                       return;
466  
467                 switch (id) {
468                 case WLAN_EID_SSID:
469 @@ -201,28 +191,15 @@
470                         elems->ext_supp_rates_len = elen;
471                         break;
472                 default:
473 -#if 0
474 -                       printk(KERN_DEBUG "IEEE 802.11 element parse ignored "
475 -                                     "unknown element (id=%d elen=%d)\n",
476 -                                     id, elen);
477 -#endif
478 -                       unknown++;
479                         break;
480                 }
481  
482                 left -= elen;
483                 pos += elen;
484         }
485 -
486 -       /* Do not trigger error if left == 1 as Apple Airport base stations
487 -        * send AssocResps that are one spurious byte too long. */
488 -
489 -       return unknown ? ParseUnknown : ParseOK;
490  }
491  
492  
493 -
494 -
495  static int ecw2cw(int ecw)
496  {
497         int cw = 1;
498 @@ -426,7 +403,9 @@
499                 if (sdata->type != IEEE80211_IF_TYPE_STA)
500                         return;
501  
502 -               bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
503 +               bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
504 +                                          local->hw.conf.channel,
505 +                                          ifsta->ssid, ifsta->ssid_len);
506                 if (bss) {
507                         if (bss->has_erp_value)
508                                 ieee80211_handle_erp_ie(dev, bss->erp_value);
509 @@ -571,7 +550,8 @@
510                 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME |
511                         WLAN_CAPABILITY_SHORT_PREAMBLE;
512         }
513 -       bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
514 +       bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
515 +                                  ifsta->ssid, ifsta->ssid_len);
516         if (bss) {
517                 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
518                         capab |= WLAN_CAPABILITY_PRIVACY;
519 @@ -719,24 +699,30 @@
520  static int ieee80211_privacy_mismatch(struct net_device *dev,
521                                       struct ieee80211_if_sta *ifsta)
522  {
523 +       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
524         struct ieee80211_sta_bss *bss;
525 -       int res = 0;
526 +       int bss_privacy;
527 +       int wep_privacy;
528 +       int privacy_invoked;
529  
530 -       if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL) ||
531 -           ifsta->key_management_enabled)
532 +       if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
533                 return 0;
534  
535 -       bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
536 +       bss = ieee80211_rx_bss_get(dev, ifsta->bssid, local->hw.conf.channel,
537 +                                  ifsta->ssid, ifsta->ssid_len);
538         if (!bss)
539                 return 0;
540  
541 -       if (ieee80211_sta_wep_configured(dev) !=
542 -           !!(bss->capability & WLAN_CAPABILITY_PRIVACY))
543 -               res = 1;
544 +       bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
545 +       wep_privacy = !!ieee80211_sta_wep_configured(dev);
546 +       privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
547  
548         ieee80211_rx_bss_put(dev, bss);
549  
550 -       return res;
551 +       if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
552 +               return 0;
553 +
554 +       return 1;
555  }
556  
557  
558 @@ -920,12 +906,7 @@
559  
560         printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name);
561         pos = mgmt->u.auth.variable;
562 -       if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
563 -           == ParseFailed) {
564 -               printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n",
565 -                      dev->name);
566 -               return;
567 -       }
568 +       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
569         if (!elems.challenge) {
570                 printk(KERN_DEBUG "%s: no challenge IE in shared key auth "
571                        "frame\n", dev->name);
572 @@ -1214,12 +1195,7 @@
573         }
574  
575         pos = mgmt->u.assoc_resp.variable;
576 -       if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
577 -           == ParseFailed) {
578 -               printk(KERN_DEBUG "%s: failed to parse AssocResp\n",
579 -                      dev->name);
580 -               return;
581 -       }
582 +       ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
583  
584         if (!elems.supp_rates) {
585                 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
586 @@ -1231,7 +1207,9 @@
587          * update our stored copy */
588         if (elems.erp_info && elems.erp_info_len >= 1) {
589                 struct ieee80211_sta_bss *bss
590 -                       = ieee80211_rx_bss_get(dev, ifsta->bssid);
591 +                       = ieee80211_rx_bss_get(dev, ifsta->bssid,
592 +                                              local->hw.conf.channel,
593 +                                              ifsta->ssid, ifsta->ssid_len);
594                 if (bss) {
595                         bss->erp_value = elems.erp_info[0];
596                         bss->has_erp_value = 1;
597 @@ -1261,7 +1239,9 @@
598                                " AP\n", dev->name);
599                         return;
600                 }
601 -               bss = ieee80211_rx_bss_get(dev, ifsta->bssid);
602 +               bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
603 +                                          local->hw.conf.channel,
604 +                                          ifsta->ssid, ifsta->ssid_len);
605                 if (bss) {
606                         sta->last_rssi = bss->rssi;
607                         sta->last_signal = bss->signal;
608 @@ -1337,7 +1317,8 @@
609  
610  
611  static struct ieee80211_sta_bss *
612 -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid)
613 +ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int channel,
614 +                    u8 *ssid, u8 ssid_len)
615  {
616         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
617         struct ieee80211_sta_bss *bss;
618 @@ -1348,6 +1329,11 @@
619         atomic_inc(&bss->users);
620         atomic_inc(&bss->users);
621         memcpy(bss->bssid, bssid, ETH_ALEN);
622 +       bss->channel = channel;
623 +       if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
624 +               memcpy(bss->ssid, ssid, ssid_len);
625 +               bss->ssid_len = ssid_len;
626 +       }
627  
628         spin_lock_bh(&local->sta_bss_lock);
629         /* TODO: order by RSSI? */
630 @@ -1359,7 +1345,8 @@
631  
632  
633  static struct ieee80211_sta_bss *
634 -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid)
635 +ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int channel,
636 +                    u8 *ssid, u8 ssid_len)
637  {
638         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
639         struct ieee80211_sta_bss *bss;
640 @@ -1367,7 +1354,10 @@
641         spin_lock_bh(&local->sta_bss_lock);
642         bss = local->sta_bss_hash[STA_HASH(bssid)];
643         while (bss) {
644 -               if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) {
645 +               if (!memcmp(bss->bssid, bssid, ETH_ALEN) &&
646 +                   bss->channel == channel &&
647 +                   bss->ssid_len == ssid_len &&
648 +                   (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
649                         atomic_inc(&bss->users);
650                         break;
651                 }
652 @@ -1429,7 +1419,7 @@
653         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
654         struct ieee802_11_elems elems;
655         size_t baselen;
656 -       int channel, invalid = 0, clen;
657 +       int channel, clen;
658         struct ieee80211_sta_bss *bss;
659         struct sta_info *sta;
660         struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
661 @@ -1473,9 +1463,7 @@
662  #endif /* CONFIG_MAC80211_IBSS_DEBUG */
663         }
664  
665 -       if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
666 -                                  &elems) == ParseFailed)
667 -               invalid = 1;
668 +       ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
669  
670         if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates &&
671             memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
672 @@ -1533,9 +1521,11 @@
673         else
674                 channel = rx_status->channel;
675  
676 -       bss = ieee80211_rx_bss_get(dev, mgmt->bssid);
677 +       bss = ieee80211_rx_bss_get(dev, mgmt->bssid, channel,
678 +                                  elems.ssid, elems.ssid_len);
679         if (!bss) {
680 -               bss = ieee80211_rx_bss_add(dev, mgmt->bssid);
681 +               bss = ieee80211_rx_bss_add(dev, mgmt->bssid, channel,
682 +                                          elems.ssid, elems.ssid_len);
683                 if (!bss)
684                         return;
685         } else {
686 @@ -1561,10 +1551,6 @@
687  
688         bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
689         bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
690 -       if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) {
691 -               memcpy(bss->ssid, elems.ssid, elems.ssid_len);
692 -               bss->ssid_len = elems.ssid_len;
693 -       }
694  
695         bss->supp_rates_len = 0;
696         if (elems.supp_rates) {
697 @@ -1635,7 +1621,6 @@
698  
699  
700         bss->hw_mode = rx_status->phymode;
701 -       bss->channel = channel;
702         bss->freq = rx_status->freq;
703         if (channel != rx_status->channel &&
704             (bss->hw_mode == MODE_IEEE80211G ||
705 @@ -1695,9 +1680,7 @@
706         if (baselen > len)
707                 return;
708  
709 -       if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen,
710 -                                  &elems) == ParseFailed)
711 -               return;
712 +       ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
713  
714         if (elems.erp_info && elems.erp_info_len >= 1)
715                 ieee80211_handle_erp_ie(dev, elems.erp_info[0]);
716 @@ -2098,7 +2081,8 @@
717  {
718         int tmp, hidden_ssid;
719  
720 -       if (!memcmp(ifsta->ssid, ssid, ssid_len))
721 +       if (ssid_len == ifsta->ssid_len &&
722 +           !memcmp(ifsta->ssid, ssid, ssid_len))
723                 return 1;
724  
725         if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
726 @@ -2357,7 +2341,7 @@
727  {
728         struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
729         struct ieee80211_sta_bss *bss;
730 -       struct ieee80211_sub_if_data *sdata;
731 +       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
732         struct ieee80211_hw_mode *mode;
733         u8 bssid[ETH_ALEN], *pos;
734         int i;
735 @@ -2379,18 +2363,17 @@
736         printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n",
737                dev->name, MAC_ARG(bssid));
738  
739 -       bss = ieee80211_rx_bss_add(dev, bssid);
740 +       bss = ieee80211_rx_bss_add(dev, bssid, local->hw.conf.channel,
741 +                                  sdata->u.sta.ssid, sdata->u.sta.ssid_len);
742         if (!bss)
743                 return -ENOMEM;
744  
745 -       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
746         mode = local->oper_hw_mode;
747  
748         if (local->hw.conf.beacon_int == 0)
749                 local->hw.conf.beacon_int = 100;
750         bss->beacon_int = local->hw.conf.beacon_int;
751         bss->hw_mode = local->hw.conf.phymode;
752 -       bss->channel = local->hw.conf.channel;
753         bss->freq = local->hw.conf.freq;
754         bss->last_update = jiffies;
755         bss->capability = WLAN_CAPABILITY_IBSS;
756 @@ -2448,7 +2431,8 @@
757                MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));
758  #endif /* CONFIG_MAC80211_IBSS_DEBUG */
759         if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 &&
760 -           (bss = ieee80211_rx_bss_get(dev, bssid))) {
761 +           (bss = ieee80211_rx_bss_get(dev, bssid, local->hw.conf.channel,
762 +                                       ifsta->ssid, ifsta->ssid_len))) {
763                 printk(KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT
764                        " based on configured SSID\n",
765                        dev->name, MAC_ARG(bssid));
766 Index: mac80211/net/mac80211/Kconfig
767 ===================================================================
768 --- mac80211.orig/net/mac80211/Kconfig  2007-11-11 15:45:23.225494151 +0100
769 +++ mac80211/net/mac80211/Kconfig       2007-11-11 15:45:30.449905846 +0100
770 @@ -13,6 +13,18 @@
771         This option enables the hardware independent IEEE 802.11
772         networking stack.
773  
774 +config MAC80211_RCSIMPLE
775 +       bool "'simple' rate control algorithm" if EMBEDDED
776 +       default y
777 +       depends on MAC80211
778 +       help
779 +         This option allows you to turn off the 'simple' rate
780 +         control algorithm in mac80211. If you do turn it off,
781 +         you absolutely need another rate control algorithm.
782 +
783 +         Say Y unless you know you will have another algorithm
784 +         available.
785 +
786  config MAC80211_LEDS
787         bool "Enable LED triggers"
788         depends on MAC80211 && LEDS_TRIGGERS
789 Index: mac80211/net/mac80211/Makefile
790 ===================================================================
791 --- mac80211.orig/net/mac80211/Makefile 2007-11-11 15:45:23.233494609 +0100
792 +++ mac80211/net/mac80211/Makefile      2007-11-11 15:45:30.449905846 +0100
793 @@ -1,8 +1,9 @@
794 -obj-$(CONFIG_MAC80211) += mac80211.o rc80211_simple.o
795 +obj-$(CONFIG_MAC80211) += mac80211.o
796  
797  mac80211-objs-$(CONFIG_MAC80211_LEDS) += ieee80211_led.o
798  mac80211-objs-$(CONFIG_MAC80211_DEBUGFS) += debugfs.o debugfs_sta.o debugfs_netdev.o debugfs_key.o
799  mac80211-objs-$(CONFIG_NET_SCHED) += wme.o
800 +mac80211-objs-$(CONFIG_MAC80211_RCSIMPLE) += rc80211_simple.o
801  
802  mac80211-objs := \
803         ieee80211.o \
804 Index: mac80211/net/mac80211/rc80211_simple.c
805 ===================================================================
806 --- mac80211.orig/net/mac80211/rc80211_simple.c 2007-11-11 15:45:23.237494839 +0100
807 +++ mac80211/net/mac80211/rc80211_simple.c      2007-11-11 15:45:30.449905846 +0100
808 @@ -7,7 +7,6 @@
809   * published by the Free Software Foundation.
810   */
811  
812 -#include <linux/module.h>
813  #include <linux/init.h>
814  #include <linux/netdevice.h>
815  #include <linux/types.h>
816 @@ -29,8 +28,6 @@
817  #define RATE_CONTROL_INTERVAL (HZ / 20)
818  #define RATE_CONTROL_MIN_TX 10
819  
820 -MODULE_ALIAS("rc80211_default");
821 -
822  static void rate_control_rate_inc(struct ieee80211_local *local,
823                                   struct sta_info *sta)
824  {
825 @@ -393,8 +390,7 @@
826  }
827  #endif
828  
829 -static struct rate_control_ops rate_control_simple = {
830 -       .module = THIS_MODULE,
831 +struct rate_control_ops mac80211_rcsimple = {
832         .name = "simple",
833         .tx_status = rate_control_simple_tx_status,
834         .get_rate = rate_control_simple_get_rate,
835 @@ -409,22 +405,3 @@
836         .remove_sta_debugfs = rate_control_simple_remove_sta_debugfs,
837  #endif
838  };
839 -
840 -
841 -static int __init rate_control_simple_init(void)
842 -{
843 -       return ieee80211_rate_control_register(&rate_control_simple);
844 -}
845 -
846 -
847 -static void __exit rate_control_simple_exit(void)
848 -{
849 -       ieee80211_rate_control_unregister(&rate_control_simple);
850 -}
851 -
852 -
853 -subsys_initcall(rate_control_simple_init);
854 -module_exit(rate_control_simple_exit);
855 -
856 -MODULE_DESCRIPTION("Simple rate control algorithm for ieee80211");
857 -MODULE_LICENSE("GPL");
858 Index: mac80211/net/mac80211/rx.c
859 ===================================================================
860 --- mac80211.orig/net/mac80211/rx.c     2007-11-11 15:45:23.245495291 +0100
861 +++ mac80211/net/mac80211/rx.c  2007-11-11 15:45:30.449905846 +0100
862 @@ -509,9 +509,11 @@
863                 rx->key->tx_rx_count++;
864                 /* TODO: add threshold stuff again */
865         } else {
866 +#ifdef CONFIG_MAC80211_DEBUG
867                 if (net_ratelimit())
868                         printk(KERN_DEBUG "%s: RX protected frame,"
869                                " but have no key\n", rx->dev->name);
870 +#endif /* CONFIG_MAC80211_DEBUG */
871                 return TXRX_DROP;
872         }
873  
874 Index: mac80211/net/mac80211/wep.c
875 ===================================================================
876 --- mac80211.orig/net/mac80211/wep.c    2007-11-11 15:45:23.253495749 +0100
877 +++ mac80211/net/mac80211/wep.c 2007-11-11 15:45:30.449905846 +0100
878 @@ -16,7 +16,7 @@
879  #include <linux/crypto.h>
880  #include <linux/err.h>
881  #include <linux/mm.h>
882 -#include <asm/scatterlist.h>
883 +#include <linux/scatterlist.h>
884  
885  #include <net/mac80211.h>
886  #include "ieee80211_i.h"
887 @@ -138,9 +138,7 @@
888         *icv = cpu_to_le32(~crc32_le(~0, data, data_len));
889  
890         crypto_blkcipher_setkey(tfm, rc4key, klen);
891 -       sg.page = virt_to_page(data);
892 -       sg.offset = offset_in_page(data);
893 -       sg.length = data_len + WEP_ICV_LEN;
894 +       sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
895         crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
896  }
897  
898 @@ -204,9 +202,7 @@
899         __le32 crc;
900  
901         crypto_blkcipher_setkey(tfm, rc4key, klen);
902 -       sg.page = virt_to_page(data);
903 -       sg.offset = offset_in_page(data);
904 -       sg.length = data_len + WEP_ICV_LEN;
905 +       sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
906         crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
907  
908         crc = cpu_to_le32(~crc32_le(~0, data, data_len));
909 @@ -318,9 +314,11 @@
910  
911         if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED)) {
912                 if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) {
913 +#ifdef CONFIG_MAC80211_DEBUG
914                         if (net_ratelimit())
915                                 printk(KERN_DEBUG "%s: RX WEP frame, decrypt "
916                                        "failed\n", rx->dev->name);
917 +#endif /* CONFIG_MAC80211_DEBUG */
918                         return TXRX_DROP;
919                 }
920         } else if (!(rx->u.rx.status->flag & RX_FLAG_IV_STRIPPED)) {
921 Index: mac80211/net/wireless/Kconfig
922 ===================================================================
923 --- mac80211.orig/net/wireless/Kconfig  2007-11-11 15:45:23.261496205 +0100
924 +++ mac80211/net/wireless/Kconfig       2007-11-11 15:45:30.453906075 +0100
925 @@ -3,7 +3,7 @@
926  
927  config NL80211
928         bool "nl80211 new netlink interface support"
929 -       depends CFG80211
930 +       depends on CFG80211
931         default y
932         ---help---
933           This option turns on the new netlink interface