compat-wireless-2010-03-10
[pandora-wifi.git] / net / mac80211 / util.c
1 /*
2  * Copyright 2002-2005, Instant802 Networks, Inc.
3  * Copyright 2005-2006, Devicescape Software, Inc.
4  * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
5  * Copyright 2007       Johannes Berg <johannes@sipsolutions.net>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * utilities for mac80211
12  */
13
14 #include <net/mac80211.h>
15 #include <linux/netdevice.h>
16 #include <linux/types.h>
17 #include <linux/slab.h>
18 #include <linux/skbuff.h>
19 #include <linux/etherdevice.h>
20 #include <linux/if_arp.h>
21 #include <linux/bitmap.h>
22 #include <linux/crc32.h>
23 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24))
24 #include <net/net_namespace.h>
25 #endif
26 #include <net/cfg80211.h>
27 #include <net/rtnetlink.h>
28
29 #include "ieee80211_i.h"
30 #include "driver-ops.h"
31 #include "rate.h"
32 #include "mesh.h"
33 #include "wme.h"
34 #include "led.h"
35 #include "wep.h"
36
37 /* privid for wiphys to determine whether they belong to us or not */
38 void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
39
40 struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
41 {
42         struct ieee80211_local *local;
43         BUG_ON(!wiphy);
44
45         local = wiphy_priv(wiphy);
46         return &local->hw;
47 }
48 EXPORT_SYMBOL(wiphy_to_ieee80211_hw);
49
50 u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
51                         enum nl80211_iftype type)
52 {
53         __le16 fc = hdr->frame_control;
54
55          /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
56         if (len < 16)
57                 return NULL;
58
59         if (ieee80211_is_data(fc)) {
60                 if (len < 24) /* drop incorrect hdr len (data) */
61                         return NULL;
62
63                 if (ieee80211_has_a4(fc))
64                         return NULL;
65                 if (ieee80211_has_tods(fc))
66                         return hdr->addr1;
67                 if (ieee80211_has_fromds(fc))
68                         return hdr->addr2;
69
70                 return hdr->addr3;
71         }
72
73         if (ieee80211_is_mgmt(fc)) {
74                 if (len < 24) /* drop incorrect hdr len (mgmt) */
75                         return NULL;
76                 return hdr->addr3;
77         }
78
79         if (ieee80211_is_ctl(fc)) {
80                 if(ieee80211_is_pspoll(fc))
81                         return hdr->addr1;
82
83                 if (ieee80211_is_back_req(fc)) {
84                         switch (type) {
85                         case NL80211_IFTYPE_STATION:
86                                 return hdr->addr2;
87                         case NL80211_IFTYPE_AP:
88                         case NL80211_IFTYPE_AP_VLAN:
89                                 return hdr->addr1;
90                         default:
91                                 break; /* fall through to the return */
92                         }
93                 }
94         }
95
96         return NULL;
97 }
98
99 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
100 {
101         struct sk_buff *skb = tx->skb;
102         struct ieee80211_hdr *hdr;
103
104         do {
105                 hdr = (struct ieee80211_hdr *) skb->data;
106                 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
107         } while ((skb = skb->next));
108 }
109
110 int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
111                              int rate, int erp, int short_preamble)
112 {
113         int dur;
114
115         /* calculate duration (in microseconds, rounded up to next higher
116          * integer if it includes a fractional microsecond) to send frame of
117          * len bytes (does not include FCS) at the given rate. Duration will
118          * also include SIFS.
119          *
120          * rate is in 100 kbps, so divident is multiplied by 10 in the
121          * DIV_ROUND_UP() operations.
122          */
123
124         if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ || erp) {
125                 /*
126                  * OFDM:
127                  *
128                  * N_DBPS = DATARATE x 4
129                  * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS)
130                  *      (16 = SIGNAL time, 6 = tail bits)
131                  * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext
132                  *
133                  * T_SYM = 4 usec
134                  * 802.11a - 17.5.2: aSIFSTime = 16 usec
135                  * 802.11g - 19.8.4: aSIFSTime = 10 usec +
136                  *      signal ext = 6 usec
137                  */
138                 dur = 16; /* SIFS + signal ext */
139                 dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */
140                 dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */
141                 dur += 4 * DIV_ROUND_UP((16 + 8 * (len + 4) + 6) * 10,
142                                         4 * rate); /* T_SYM x N_SYM */
143         } else {
144                 /*
145                  * 802.11b or 802.11g with 802.11b compatibility:
146                  * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime +
147                  * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0.
148                  *
149                  * 802.11 (DS): 15.3.3, 802.11b: 18.3.4
150                  * aSIFSTime = 10 usec
151                  * aPreambleLength = 144 usec or 72 usec with short preamble
152                  * aPLCPHeaderLength = 48 usec or 24 usec with short preamble
153                  */
154                 dur = 10; /* aSIFSTime = 10 usec */
155                 dur += short_preamble ? (72 + 24) : (144 + 48);
156
157                 dur += DIV_ROUND_UP(8 * (len + 4) * 10, rate);
158         }
159
160         return dur;
161 }
162
163 /* Exported duration function for driver use */
164 __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
165                                         struct ieee80211_vif *vif,
166                                         size_t frame_len,
167                                         struct ieee80211_rate *rate)
168 {
169         struct ieee80211_local *local = hw_to_local(hw);
170         struct ieee80211_sub_if_data *sdata;
171         u16 dur;
172         int erp;
173         bool short_preamble = false;
174
175         erp = 0;
176         if (vif) {
177                 sdata = vif_to_sdata(vif);
178                 short_preamble = sdata->vif.bss_conf.use_short_preamble;
179                 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
180                         erp = rate->flags & IEEE80211_RATE_ERP_G;
181         }
182
183         dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
184                                        short_preamble);
185
186         return cpu_to_le16(dur);
187 }
188 EXPORT_SYMBOL(ieee80211_generic_frame_duration);
189
190 __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
191                               struct ieee80211_vif *vif, size_t frame_len,
192                               const struct ieee80211_tx_info *frame_txctl)
193 {
194         struct ieee80211_local *local = hw_to_local(hw);
195         struct ieee80211_rate *rate;
196         struct ieee80211_sub_if_data *sdata;
197         bool short_preamble;
198         int erp;
199         u16 dur;
200         struct ieee80211_supported_band *sband;
201
202         sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
203
204         short_preamble = false;
205
206         rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
207
208         erp = 0;
209         if (vif) {
210                 sdata = vif_to_sdata(vif);
211                 short_preamble = sdata->vif.bss_conf.use_short_preamble;
212                 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
213                         erp = rate->flags & IEEE80211_RATE_ERP_G;
214         }
215
216         /* CTS duration */
217         dur = ieee80211_frame_duration(local, 10, rate->bitrate,
218                                        erp, short_preamble);
219         /* Data frame duration */
220         dur += ieee80211_frame_duration(local, frame_len, rate->bitrate,
221                                         erp, short_preamble);
222         /* ACK duration */
223         dur += ieee80211_frame_duration(local, 10, rate->bitrate,
224                                         erp, short_preamble);
225
226         return cpu_to_le16(dur);
227 }
228 EXPORT_SYMBOL(ieee80211_rts_duration);
229
230 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
231                                     struct ieee80211_vif *vif,
232                                     size_t frame_len,
233                                     const struct ieee80211_tx_info *frame_txctl)
234 {
235         struct ieee80211_local *local = hw_to_local(hw);
236         struct ieee80211_rate *rate;
237         struct ieee80211_sub_if_data *sdata;
238         bool short_preamble;
239         int erp;
240         u16 dur;
241         struct ieee80211_supported_band *sband;
242
243         sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
244
245         short_preamble = false;
246
247         rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
248         erp = 0;
249         if (vif) {
250                 sdata = vif_to_sdata(vif);
251                 short_preamble = sdata->vif.bss_conf.use_short_preamble;
252                 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
253                         erp = rate->flags & IEEE80211_RATE_ERP_G;
254         }
255
256         /* Data frame duration */
257         dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
258                                        erp, short_preamble);
259         if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) {
260                 /* ACK duration */
261                 dur += ieee80211_frame_duration(local, 10, rate->bitrate,
262                                                 erp, short_preamble);
263         }
264
265         return cpu_to_le16(dur);
266 }
267 EXPORT_SYMBOL(ieee80211_ctstoself_duration);
268
269 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23))
270 static bool ieee80211_all_queues_started(struct ieee80211_hw *hw)
271 {
272         unsigned int queue;
273
274         for (queue = 0; queue < hw->queues; queue++)
275                 if (ieee80211_queue_stopped(hw, queue))
276                         return false;
277         return true;
278 }
279 #endif
280
281 static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
282                                    enum queue_stop_reason reason)
283 {
284         struct ieee80211_local *local = hw_to_local(hw);
285         struct ieee80211_sub_if_data *sdata;
286
287         if (WARN_ON(queue >= hw->queues))
288                 return;
289
290         __clear_bit(reason, &local->queue_stop_reasons[queue]);
291
292         if (local->queue_stop_reasons[queue] != 0)
293                 /* someone still has this queue stopped */
294                 return;
295
296         if (!skb_queue_empty(&local->pending[queue]))
297                 tasklet_schedule(&local->tx_pending_tasklet);
298
299         rcu_read_lock();
300         list_for_each_entry_rcu(sdata, &local->interfaces, list)
301 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
302                 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
303 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
304                 netif_start_subqueue(sdata->dev, queue);
305 #else
306                 if (ieee80211_all_queues_started(hw))
307                         netif_wake_queue(sdata->dev);
308 #endif
309         rcu_read_unlock();
310 }
311
312 void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
313                                     enum queue_stop_reason reason)
314 {
315         struct ieee80211_local *local = hw_to_local(hw);
316         unsigned long flags;
317
318         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
319         __ieee80211_wake_queue(hw, queue, reason);
320         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
321 }
322
323 void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue)
324 {
325         ieee80211_wake_queue_by_reason(hw, queue,
326                                        IEEE80211_QUEUE_STOP_REASON_DRIVER);
327 }
328 EXPORT_SYMBOL(ieee80211_wake_queue);
329
330 static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
331                                    enum queue_stop_reason reason)
332 {
333         struct ieee80211_local *local = hw_to_local(hw);
334         struct ieee80211_sub_if_data *sdata;
335
336         if (WARN_ON(queue >= hw->queues))
337                 return;
338
339         __set_bit(reason, &local->queue_stop_reasons[queue]);
340
341         rcu_read_lock();
342         list_for_each_entry_rcu(sdata, &local->interfaces, list)
343 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
344                 netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue));
345 #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
346                 netif_stop_subqueue(sdata->dev, queue);
347 #else
348                 netif_stop_queue(sdata->dev);
349 #endif
350         rcu_read_unlock();
351 }
352
353 void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
354                                     enum queue_stop_reason reason)
355 {
356         struct ieee80211_local *local = hw_to_local(hw);
357         unsigned long flags;
358
359         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
360         __ieee80211_stop_queue(hw, queue, reason);
361         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
362 }
363
364 void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
365 {
366         ieee80211_stop_queue_by_reason(hw, queue,
367                                        IEEE80211_QUEUE_STOP_REASON_DRIVER);
368 }
369 EXPORT_SYMBOL(ieee80211_stop_queue);
370
371 void ieee80211_add_pending_skb(struct ieee80211_local *local,
372                                struct sk_buff *skb)
373 {
374         struct ieee80211_hw *hw = &local->hw;
375         unsigned long flags;
376         int queue = skb_get_queue_mapping(skb);
377         struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
378
379         if (WARN_ON(!info->control.vif)) {
380                 kfree_skb(skb);
381                 return;
382         }
383
384         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
385         __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
386         __skb_queue_tail(&local->pending[queue], skb);
387         __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
388         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
389 }
390
391 int ieee80211_add_pending_skbs(struct ieee80211_local *local,
392                                struct sk_buff_head *skbs)
393 {
394         struct ieee80211_hw *hw = &local->hw;
395         struct sk_buff *skb;
396         unsigned long flags;
397         int queue, ret = 0, i;
398
399         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
400         for (i = 0; i < hw->queues; i++)
401                 __ieee80211_stop_queue(hw, i,
402                         IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
403
404         while ((skb = skb_dequeue(skbs))) {
405                 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
406
407                 if (WARN_ON(!info->control.vif)) {
408                         kfree_skb(skb);
409                         continue;
410                 }
411
412                 ret++;
413                 queue = skb_get_queue_mapping(skb);
414                 __skb_queue_tail(&local->pending[queue], skb);
415         }
416
417         for (i = 0; i < hw->queues; i++)
418                 __ieee80211_wake_queue(hw, i,
419                         IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
420         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
421
422         return ret;
423 }
424
425 void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
426                                     enum queue_stop_reason reason)
427 {
428         struct ieee80211_local *local = hw_to_local(hw);
429         unsigned long flags;
430         int i;
431
432         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
433
434         for (i = 0; i < hw->queues; i++)
435                 __ieee80211_stop_queue(hw, i, reason);
436
437         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
438 }
439
440 void ieee80211_stop_queues(struct ieee80211_hw *hw)
441 {
442         ieee80211_stop_queues_by_reason(hw,
443                                         IEEE80211_QUEUE_STOP_REASON_DRIVER);
444 }
445 EXPORT_SYMBOL(ieee80211_stop_queues);
446
447 int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
448 {
449         struct ieee80211_local *local = hw_to_local(hw);
450         unsigned long flags;
451         int ret;
452
453         if (WARN_ON(queue >= hw->queues))
454                 return true;
455
456         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
457         ret = !!local->queue_stop_reasons[queue];
458         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
459         return ret;
460 }
461 EXPORT_SYMBOL(ieee80211_queue_stopped);
462
463 void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
464                                      enum queue_stop_reason reason)
465 {
466         struct ieee80211_local *local = hw_to_local(hw);
467         unsigned long flags;
468         int i;
469
470         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
471
472         for (i = 0; i < hw->queues; i++)
473                 __ieee80211_wake_queue(hw, i, reason);
474
475         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
476 }
477
478 void ieee80211_wake_queues(struct ieee80211_hw *hw)
479 {
480         ieee80211_wake_queues_by_reason(hw, IEEE80211_QUEUE_STOP_REASON_DRIVER);
481 }
482 EXPORT_SYMBOL(ieee80211_wake_queues);
483
484 void ieee80211_iterate_active_interfaces(
485         struct ieee80211_hw *hw,
486         void (*iterator)(void *data, u8 *mac,
487                          struct ieee80211_vif *vif),
488         void *data)
489 {
490         struct ieee80211_local *local = hw_to_local(hw);
491         struct ieee80211_sub_if_data *sdata;
492
493         mutex_lock(&local->iflist_mtx);
494
495         list_for_each_entry(sdata, &local->interfaces, list) {
496                 switch (sdata->vif.type) {
497                 case __NL80211_IFTYPE_AFTER_LAST:
498                 case NL80211_IFTYPE_UNSPECIFIED:
499                 case NL80211_IFTYPE_MONITOR:
500                 case NL80211_IFTYPE_AP_VLAN:
501                         continue;
502                 case NL80211_IFTYPE_AP:
503                 case NL80211_IFTYPE_STATION:
504                 case NL80211_IFTYPE_ADHOC:
505                 case NL80211_IFTYPE_WDS:
506                 case NL80211_IFTYPE_MESH_POINT:
507                         break;
508                 }
509                 if (ieee80211_sdata_running(sdata))
510                         iterator(data, sdata->vif.addr,
511                                  &sdata->vif);
512         }
513
514         mutex_unlock(&local->iflist_mtx);
515 }
516 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);
517
518 void ieee80211_iterate_active_interfaces_atomic(
519         struct ieee80211_hw *hw,
520         void (*iterator)(void *data, u8 *mac,
521                          struct ieee80211_vif *vif),
522         void *data)
523 {
524         struct ieee80211_local *local = hw_to_local(hw);
525         struct ieee80211_sub_if_data *sdata;
526
527         rcu_read_lock();
528
529         list_for_each_entry_rcu(sdata, &local->interfaces, list) {
530                 switch (sdata->vif.type) {
531                 case __NL80211_IFTYPE_AFTER_LAST:
532                 case NL80211_IFTYPE_UNSPECIFIED:
533                 case NL80211_IFTYPE_MONITOR:
534                 case NL80211_IFTYPE_AP_VLAN:
535                         continue;
536                 case NL80211_IFTYPE_AP:
537                 case NL80211_IFTYPE_STATION:
538                 case NL80211_IFTYPE_ADHOC:
539                 case NL80211_IFTYPE_WDS:
540                 case NL80211_IFTYPE_MESH_POINT:
541                         break;
542                 }
543                 if (ieee80211_sdata_running(sdata))
544                         iterator(data, sdata->vif.addr,
545                                  &sdata->vif);
546         }
547
548         rcu_read_unlock();
549 }
550 EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
551
552 /*
553  * Nothing should have been stuffed into the workqueue during
554  * the suspend->resume cycle. If this WARN is seen then there
555  * is a bug with either the driver suspend or something in
556  * mac80211 stuffing into the workqueue which we haven't yet
557  * cleared during mac80211's suspend cycle.
558  */
559 static bool ieee80211_can_queue_work(struct ieee80211_local *local)
560 {
561         if (WARN(local->suspended && !local->resuming,
562                  "queueing ieee80211 work while going to suspend\n"))
563                 return false;
564
565         return true;
566 }
567
568 void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
569 {
570         struct ieee80211_local *local = hw_to_local(hw);
571
572         if (!ieee80211_can_queue_work(local))
573                 return;
574
575         queue_work(local->workqueue, work);
576 }
577 EXPORT_SYMBOL(ieee80211_queue_work);
578
579 void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
580                                   struct delayed_work *dwork,
581                                   unsigned long delay)
582 {
583         struct ieee80211_local *local = hw_to_local(hw);
584
585         if (!ieee80211_can_queue_work(local))
586                 return;
587
588         queue_delayed_work(local->workqueue, dwork, delay);
589 }
590 EXPORT_SYMBOL(ieee80211_queue_delayed_work);
591
592 void ieee802_11_parse_elems(u8 *start, size_t len,
593                             struct ieee802_11_elems *elems)
594 {
595         ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
596 }
597
598 u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
599                                struct ieee802_11_elems *elems,
600                                u64 filter, u32 crc)
601 {
602         size_t left = len;
603         u8 *pos = start;
604         bool calc_crc = filter != 0;
605
606         memset(elems, 0, sizeof(*elems));
607         elems->ie_start = start;
608         elems->total_len = len;
609
610         while (left >= 2) {
611                 u8 id, elen;
612
613                 id = *pos++;
614                 elen = *pos++;
615                 left -= 2;
616
617                 if (elen > left)
618                         break;
619
620                 if (calc_crc && id < 64 && (filter & (1ULL << id)))
621                         crc = crc32_be(crc, pos - 2, elen + 2);
622
623                 switch (id) {
624                 case WLAN_EID_SSID:
625                         elems->ssid = pos;
626                         elems->ssid_len = elen;
627                         break;
628                 case WLAN_EID_SUPP_RATES:
629                         elems->supp_rates = pos;
630                         elems->supp_rates_len = elen;
631                         break;
632                 case WLAN_EID_FH_PARAMS:
633                         elems->fh_params = pos;
634                         elems->fh_params_len = elen;
635                         break;
636                 case WLAN_EID_DS_PARAMS:
637                         elems->ds_params = pos;
638                         elems->ds_params_len = elen;
639                         break;
640                 case WLAN_EID_CF_PARAMS:
641                         elems->cf_params = pos;
642                         elems->cf_params_len = elen;
643                         break;
644                 case WLAN_EID_TIM:
645                         if (elen >= sizeof(struct ieee80211_tim_ie)) {
646                                 elems->tim = (void *)pos;
647                                 elems->tim_len = elen;
648                         }
649                         break;
650                 case WLAN_EID_IBSS_PARAMS:
651                         elems->ibss_params = pos;
652                         elems->ibss_params_len = elen;
653                         break;
654                 case WLAN_EID_CHALLENGE:
655                         elems->challenge = pos;
656                         elems->challenge_len = elen;
657                         break;
658                 case WLAN_EID_VENDOR_SPECIFIC:
659                         if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
660                             pos[2] == 0xf2) {
661                                 /* Microsoft OUI (00:50:F2) */
662
663                                 if (calc_crc)
664                                         crc = crc32_be(crc, pos - 2, elen + 2);
665
666                                 if (pos[3] == 1) {
667                                         /* OUI Type 1 - WPA IE */
668                                         elems->wpa = pos;
669                                         elems->wpa_len = elen;
670                                 } else if (elen >= 5 && pos[3] == 2) {
671                                         /* OUI Type 2 - WMM IE */
672                                         if (pos[4] == 0) {
673                                                 elems->wmm_info = pos;
674                                                 elems->wmm_info_len = elen;
675                                         } else if (pos[4] == 1) {
676                                                 elems->wmm_param = pos;
677                                                 elems->wmm_param_len = elen;
678                                         }
679                                 }
680                         }
681                         break;
682                 case WLAN_EID_RSN:
683                         elems->rsn = pos;
684                         elems->rsn_len = elen;
685                         break;
686                 case WLAN_EID_ERP_INFO:
687                         elems->erp_info = pos;
688                         elems->erp_info_len = elen;
689                         break;
690                 case WLAN_EID_EXT_SUPP_RATES:
691                         elems->ext_supp_rates = pos;
692                         elems->ext_supp_rates_len = elen;
693                         break;
694                 case WLAN_EID_HT_CAPABILITY:
695                         if (elen >= sizeof(struct ieee80211_ht_cap))
696                                 elems->ht_cap_elem = (void *)pos;
697                         break;
698                 case WLAN_EID_HT_INFORMATION:
699                         if (elen >= sizeof(struct ieee80211_ht_info))
700                                 elems->ht_info_elem = (void *)pos;
701                         break;
702                 case WLAN_EID_MESH_ID:
703                         elems->mesh_id = pos;
704                         elems->mesh_id_len = elen;
705                         break;
706                 case WLAN_EID_MESH_CONFIG:
707                         if (elen >= sizeof(struct ieee80211_meshconf_ie))
708                                 elems->mesh_config = (void *)pos;
709                         break;
710                 case WLAN_EID_PEER_LINK:
711                         elems->peer_link = pos;
712                         elems->peer_link_len = elen;
713                         break;
714                 case WLAN_EID_PREQ:
715                         elems->preq = pos;
716                         elems->preq_len = elen;
717                         break;
718                 case WLAN_EID_PREP:
719                         elems->prep = pos;
720                         elems->prep_len = elen;
721                         break;
722                 case WLAN_EID_PERR:
723                         elems->perr = pos;
724                         elems->perr_len = elen;
725                         break;
726                 case WLAN_EID_RANN:
727                         if (elen >= sizeof(struct ieee80211_rann_ie))
728                                 elems->rann = (void *)pos;
729                         break;
730                 case WLAN_EID_CHANNEL_SWITCH:
731                         elems->ch_switch_elem = pos;
732                         elems->ch_switch_elem_len = elen;
733                         break;
734                 case WLAN_EID_QUIET:
735                         if (!elems->quiet_elem) {
736                                 elems->quiet_elem = pos;
737                                 elems->quiet_elem_len = elen;
738                         }
739                         elems->num_of_quiet_elem++;
740                         break;
741                 case WLAN_EID_COUNTRY:
742                         elems->country_elem = pos;
743                         elems->country_elem_len = elen;
744                         break;
745                 case WLAN_EID_PWR_CONSTRAINT:
746                         elems->pwr_constr_elem = pos;
747                         elems->pwr_constr_elem_len = elen;
748                         break;
749                 case WLAN_EID_TIMEOUT_INTERVAL:
750                         elems->timeout_int = pos;
751                         elems->timeout_int_len = elen;
752                         break;
753                 default:
754                         break;
755                 }
756
757                 left -= elen;
758                 pos += elen;
759         }
760
761         return crc;
762 }
763
764 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
765 {
766         struct ieee80211_local *local = sdata->local;
767         struct ieee80211_tx_queue_params qparam;
768         int queue;
769         bool use_11b;
770         int aCWmin, aCWmax;
771
772         if (!local->ops->conf_tx)
773                 return;
774
775         memset(&qparam, 0, sizeof(qparam));
776
777         use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
778                  !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
779
780         for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
781                 /* Set defaults according to 802.11-2007 Table 7-37 */
782                 aCWmax = 1023;
783                 if (use_11b)
784                         aCWmin = 31;
785                 else
786                         aCWmin = 15;
787
788                 switch (queue) {
789                 case 3: /* AC_BK */
790                         qparam.cw_max = aCWmax;
791                         qparam.cw_min = aCWmin;
792                         qparam.txop = 0;
793                         qparam.aifs = 7;
794                         break;
795                 default: /* never happens but let's not leave undefined */
796                 case 2: /* AC_BE */
797                         qparam.cw_max = aCWmax;
798                         qparam.cw_min = aCWmin;
799                         qparam.txop = 0;
800                         qparam.aifs = 3;
801                         break;
802                 case 1: /* AC_VI */
803                         qparam.cw_max = aCWmin;
804                         qparam.cw_min = (aCWmin + 1) / 2 - 1;
805                         if (use_11b)
806                                 qparam.txop = 6016/32;
807                         else
808                                 qparam.txop = 3008/32;
809                         qparam.aifs = 2;
810                         break;
811                 case 0: /* AC_VO */
812                         qparam.cw_max = (aCWmin + 1) / 2 - 1;
813                         qparam.cw_min = (aCWmin + 1) / 4 - 1;
814                         if (use_11b)
815                                 qparam.txop = 3264/32;
816                         else
817                                 qparam.txop = 1504/32;
818                         qparam.aifs = 2;
819                         break;
820                 }
821
822                 qparam.uapsd = false;
823
824                 drv_conf_tx(local, queue, &qparam);
825         }
826 }
827
828 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
829                                   const size_t supp_rates_len,
830                                   const u8 *supp_rates)
831 {
832         struct ieee80211_local *local = sdata->local;
833         int i, have_higher_than_11mbit = 0;
834
835         /* cf. IEEE 802.11 9.2.12 */
836         for (i = 0; i < supp_rates_len; i++)
837                 if ((supp_rates[i] & 0x7f) * 5 > 110)
838                         have_higher_than_11mbit = 1;
839
840         if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
841             have_higher_than_11mbit)
842                 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
843         else
844                 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
845
846         ieee80211_set_wmm_default(sdata);
847 }
848
849 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
850                               enum ieee80211_band band)
851 {
852         struct ieee80211_supported_band *sband;
853         struct ieee80211_rate *bitrates;
854         u32 mandatory_rates;
855         enum ieee80211_rate_flags mandatory_flag;
856         int i;
857
858         sband = local->hw.wiphy->bands[band];
859         if (!sband) {
860                 WARN_ON(1);
861                 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
862         }
863
864         if (band == IEEE80211_BAND_2GHZ)
865                 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
866         else
867                 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
868
869         bitrates = sband->bitrates;
870         mandatory_rates = 0;
871         for (i = 0; i < sband->n_bitrates; i++)
872                 if (bitrates[i].flags & mandatory_flag)
873                         mandatory_rates |= BIT(i);
874         return mandatory_rates;
875 }
876
877 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
878                          u16 transaction, u16 auth_alg,
879                          u8 *extra, size_t extra_len, const u8 *bssid,
880                          const u8 *key, u8 key_len, u8 key_idx)
881 {
882         struct ieee80211_local *local = sdata->local;
883         struct sk_buff *skb;
884         struct ieee80211_mgmt *mgmt;
885         int err;
886
887         skb = dev_alloc_skb(local->hw.extra_tx_headroom +
888                             sizeof(*mgmt) + 6 + extra_len);
889         if (!skb) {
890                 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
891                        "frame\n", sdata->name);
892                 return;
893         }
894         skb_reserve(skb, local->hw.extra_tx_headroom);
895
896         mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
897         memset(mgmt, 0, 24 + 6);
898         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
899                                           IEEE80211_STYPE_AUTH);
900         memcpy(mgmt->da, bssid, ETH_ALEN);
901         memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
902         memcpy(mgmt->bssid, bssid, ETH_ALEN);
903         mgmt->u.auth.auth_alg = cpu_to_le16(auth_alg);
904         mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
905         mgmt->u.auth.status_code = cpu_to_le16(0);
906         if (extra)
907                 memcpy(skb_put(skb, extra_len), extra, extra_len);
908
909         if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
910                 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
911                 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
912                 WARN_ON(err);
913         }
914
915         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
916         ieee80211_tx_skb(sdata, skb);
917 }
918
919 int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
920                              const u8 *ie, size_t ie_len,
921                              enum ieee80211_band band)
922 {
923         struct ieee80211_supported_band *sband;
924         u8 *pos;
925         size_t offset = 0, noffset;
926         int supp_rates_len, i;
927
928         sband = local->hw.wiphy->bands[band];
929
930         pos = buffer;
931
932         supp_rates_len = min_t(int, sband->n_bitrates, 8);
933
934         *pos++ = WLAN_EID_SUPP_RATES;
935         *pos++ = supp_rates_len;
936
937         for (i = 0; i < supp_rates_len; i++) {
938                 int rate = sband->bitrates[i].bitrate;
939                 *pos++ = (u8) (rate / 5);
940         }
941
942         /* insert "request information" if in custom IEs */
943         if (ie && ie_len) {
944                 static const u8 before_extrates[] = {
945                         WLAN_EID_SSID,
946                         WLAN_EID_SUPP_RATES,
947                         WLAN_EID_REQUEST,
948                 };
949                 noffset = ieee80211_ie_split(ie, ie_len,
950                                              before_extrates,
951                                              ARRAY_SIZE(before_extrates),
952                                              offset);
953                 memcpy(pos, ie + offset, noffset - offset);
954                 pos += noffset - offset;
955                 offset = noffset;
956         }
957
958         if (sband->n_bitrates > i) {
959                 *pos++ = WLAN_EID_EXT_SUPP_RATES;
960                 *pos++ = sband->n_bitrates - i;
961
962                 for (; i < sband->n_bitrates; i++) {
963                         int rate = sband->bitrates[i].bitrate;
964                         *pos++ = (u8) (rate / 5);
965                 }
966         }
967
968         /* insert custom IEs that go before HT */
969         if (ie && ie_len) {
970                 static const u8 before_ht[] = {
971                         WLAN_EID_SSID,
972                         WLAN_EID_SUPP_RATES,
973                         WLAN_EID_REQUEST,
974                         WLAN_EID_EXT_SUPP_RATES,
975                         WLAN_EID_DS_PARAMS,
976                         WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
977                 };
978                 noffset = ieee80211_ie_split(ie, ie_len,
979                                              before_ht, ARRAY_SIZE(before_ht),
980                                              offset);
981                 memcpy(pos, ie + offset, noffset - offset);
982                 pos += noffset - offset;
983                 offset = noffset;
984         }
985
986         if (sband->ht_cap.ht_supported) {
987                 u16 cap = sband->ht_cap.cap;
988                 __le16 tmp;
989
990                 if (ieee80211_disable_40mhz_24ghz &&
991                     sband->band == IEEE80211_BAND_2GHZ) {
992                         cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
993                         cap &= ~IEEE80211_HT_CAP_SGI_40;
994                 }
995
996                 *pos++ = WLAN_EID_HT_CAPABILITY;
997                 *pos++ = sizeof(struct ieee80211_ht_cap);
998                 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
999                 tmp = cpu_to_le16(cap);
1000                 memcpy(pos, &tmp, sizeof(u16));
1001                 pos += sizeof(u16);
1002                 *pos++ = sband->ht_cap.ampdu_factor |
1003                          (sband->ht_cap.ampdu_density <<
1004                                 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT);
1005                 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
1006                 pos += sizeof(sband->ht_cap.mcs);
1007                 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
1008         }
1009
1010         /*
1011          * If adding more here, adjust code in main.c
1012          * that calculates local->scan_ies_len.
1013          */
1014
1015         /* add any remaining custom IEs */
1016         if (ie && ie_len) {
1017                 noffset = ie_len;
1018                 memcpy(pos, ie + offset, noffset - offset);
1019                 pos += noffset - offset;
1020         }
1021
1022         return pos - buffer;
1023 }
1024
1025 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1026                               const u8 *ssid, size_t ssid_len,
1027                               const u8 *ie, size_t ie_len)
1028 {
1029         struct ieee80211_local *local = sdata->local;
1030         struct sk_buff *skb;
1031         struct ieee80211_mgmt *mgmt;
1032         size_t buf_len;
1033         u8 *buf;
1034
1035         /* FIXME: come up with a proper value */
1036         buf = kmalloc(200 + ie_len, GFP_KERNEL);
1037         if (!buf) {
1038                 printk(KERN_DEBUG "%s: failed to allocate temporary IE "
1039                        "buffer\n", sdata->name);
1040                 return;
1041         }
1042
1043         buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1044                                            local->hw.conf.channel->band);
1045
1046         skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1047                                      ssid, ssid_len,
1048                                      buf, buf_len);
1049
1050         if (dst) {
1051                 mgmt = (struct ieee80211_mgmt *) skb->data;
1052                 memcpy(mgmt->da, dst, ETH_ALEN);
1053                 memcpy(mgmt->bssid, dst, ETH_ALEN);
1054         }
1055
1056         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1057         ieee80211_tx_skb(sdata, skb);
1058         kfree(buf);
1059 }
1060
1061 u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
1062                             struct ieee802_11_elems *elems,
1063                             enum ieee80211_band band)
1064 {
1065         struct ieee80211_supported_band *sband;
1066         struct ieee80211_rate *bitrates;
1067         size_t num_rates;
1068         u32 supp_rates;
1069         int i, j;
1070         sband = local->hw.wiphy->bands[band];
1071
1072         if (!sband) {
1073                 WARN_ON(1);
1074                 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1075         }
1076
1077         bitrates = sband->bitrates;
1078         num_rates = sband->n_bitrates;
1079         supp_rates = 0;
1080         for (i = 0; i < elems->supp_rates_len +
1081                      elems->ext_supp_rates_len; i++) {
1082                 u8 rate = 0;
1083                 int own_rate;
1084                 if (i < elems->supp_rates_len)
1085                         rate = elems->supp_rates[i];
1086                 else if (elems->ext_supp_rates)
1087                         rate = elems->ext_supp_rates
1088                                 [i - elems->supp_rates_len];
1089                 own_rate = 5 * (rate & 0x7f);
1090                 for (j = 0; j < num_rates; j++)
1091                         if (bitrates[j].bitrate == own_rate)
1092                                 supp_rates |= BIT(j);
1093         }
1094         return supp_rates;
1095 }
1096
1097 void ieee80211_stop_device(struct ieee80211_local *local)
1098 {
1099         ieee80211_led_radio(local, false);
1100
1101         cancel_work_sync(&local->reconfig_filter);
1102
1103         flush_workqueue(local->workqueue);
1104         drv_stop(local);
1105 }
1106
1107 int ieee80211_reconfig(struct ieee80211_local *local)
1108 {
1109         struct ieee80211_hw *hw = &local->hw;
1110         struct ieee80211_sub_if_data *sdata;
1111         struct sta_info *sta;
1112         int res;
1113
1114         if (local->suspended)
1115                 local->resuming = true;
1116
1117         /* restart hardware */
1118         if (local->open_count) {
1119                 /*
1120                  * Upon resume hardware can sometimes be goofy due to
1121                  * various platform / driver / bus issues, so restarting
1122                  * the device may at times not work immediately. Propagate
1123                  * the error.
1124                  */
1125                 res = drv_start(local);
1126                 if (res) {
1127                         WARN(local->suspended, "Harware became unavailable "
1128                              "upon resume. This is could be a software issue"
1129                              "prior to suspend or a hardware issue\n");
1130                         return res;
1131                 }
1132
1133                 ieee80211_led_radio(local, true);
1134         }
1135
1136         /* add interfaces */
1137         list_for_each_entry(sdata, &local->interfaces, list) {
1138                 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1139                     sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1140                     ieee80211_sdata_running(sdata))
1141                         res = drv_add_interface(local, &sdata->vif);
1142         }
1143
1144         /* add STAs back */
1145         mutex_lock(&local->sta_mtx);
1146         list_for_each_entry(sta, &local->sta_list, list) {
1147                 if (sta->uploaded) {
1148                         sdata = sta->sdata;
1149                         if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1150                                 sdata = container_of(sdata->bss,
1151                                              struct ieee80211_sub_if_data,
1152                                              u.ap);
1153
1154                         WARN_ON(drv_sta_add(local, sdata, &sta->sta));
1155                 }
1156         }
1157         mutex_unlock(&local->sta_mtx);
1158
1159         /* Clear Suspend state so that ADDBA requests can be processed */
1160
1161         rcu_read_lock();
1162
1163         if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1164                 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1165                         clear_sta_flags(sta, WLAN_STA_SUSPEND);
1166                 }
1167         }
1168
1169         rcu_read_unlock();
1170
1171         /* setup RTS threshold */
1172         drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1173
1174         /* reconfigure hardware */
1175         ieee80211_hw_config(local, ~0);
1176
1177         ieee80211_configure_filter(local);
1178
1179         /* Finally also reconfigure all the BSS information */
1180         list_for_each_entry(sdata, &local->interfaces, list) {
1181                 u32 changed = ~0;
1182                 if (!ieee80211_sdata_running(sdata))
1183                         continue;
1184                 switch (sdata->vif.type) {
1185                 case NL80211_IFTYPE_STATION:
1186                         /* disable beacon change bits */
1187                         changed &= ~(BSS_CHANGED_BEACON |
1188                                      BSS_CHANGED_BEACON_ENABLED);
1189                         /* fall through */
1190                 case NL80211_IFTYPE_ADHOC:
1191                 case NL80211_IFTYPE_AP:
1192                 case NL80211_IFTYPE_MESH_POINT:
1193                         ieee80211_bss_info_change_notify(sdata, changed);
1194                         break;
1195                 case NL80211_IFTYPE_WDS:
1196                         break;
1197                 case NL80211_IFTYPE_AP_VLAN:
1198                 case NL80211_IFTYPE_MONITOR:
1199                         /* ignore virtual */
1200                         break;
1201                 case NL80211_IFTYPE_UNSPECIFIED:
1202                 case __NL80211_IFTYPE_AFTER_LAST:
1203                         WARN_ON(1);
1204                         break;
1205                 }
1206         }
1207
1208         rcu_read_lock();
1209         if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1210                 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1211                         ieee80211_sta_tear_down_BA_sessions(sta);
1212                 }
1213         }
1214         rcu_read_unlock();
1215
1216         /* add back keys */
1217         list_for_each_entry(sdata, &local->interfaces, list)
1218                 if (ieee80211_sdata_running(sdata))
1219                         ieee80211_enable_keys(sdata);
1220
1221         ieee80211_wake_queues_by_reason(hw,
1222                         IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1223
1224         /*
1225          * If this is for hw restart things are still running.
1226          * We may want to change that later, however.
1227          */
1228         if (!local->suspended)
1229                 return 0;
1230
1231 #ifdef CONFIG_PM
1232         /* first set suspended false, then resuming */
1233         local->suspended = false;
1234         mb();
1235         local->resuming = false;
1236
1237         list_for_each_entry(sdata, &local->interfaces, list) {
1238                 switch(sdata->vif.type) {
1239                 case NL80211_IFTYPE_STATION:
1240                         ieee80211_sta_restart(sdata);
1241                         break;
1242                 case NL80211_IFTYPE_ADHOC:
1243                         ieee80211_ibss_restart(sdata);
1244                         break;
1245                 case NL80211_IFTYPE_MESH_POINT:
1246                         ieee80211_mesh_restart(sdata);
1247                         break;
1248                 default:
1249                         break;
1250                 }
1251         }
1252
1253         add_timer(&local->sta_cleanup);
1254
1255         mutex_lock(&local->sta_mtx);
1256         list_for_each_entry(sta, &local->sta_list, list)
1257                 mesh_plink_restart(sta);
1258         mutex_unlock(&local->sta_mtx);
1259 #else
1260         WARN_ON(1);
1261 #endif
1262         return 0;
1263 }
1264
1265 static int check_mgd_smps(struct ieee80211_if_managed *ifmgd,
1266                           enum ieee80211_smps_mode *smps_mode)
1267 {
1268         if (ifmgd->associated) {
1269                 *smps_mode = ifmgd->ap_smps;
1270
1271                 if (*smps_mode == IEEE80211_SMPS_AUTOMATIC) {
1272                         if (ifmgd->powersave)
1273                                 *smps_mode = IEEE80211_SMPS_DYNAMIC;
1274                         else
1275                                 *smps_mode = IEEE80211_SMPS_OFF;
1276                 }
1277
1278                 return 1;
1279         }
1280
1281         return 0;
1282 }
1283
1284 /* must hold iflist_mtx */
1285 void ieee80211_recalc_smps(struct ieee80211_local *local,
1286                            struct ieee80211_sub_if_data *forsdata)
1287 {
1288         struct ieee80211_sub_if_data *sdata;
1289         enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_OFF;
1290         int count = 0;
1291
1292         if (forsdata)
1293                 WARN_ON(!mutex_is_locked(&forsdata->u.mgd.mtx));
1294
1295         WARN_ON(!mutex_is_locked(&local->iflist_mtx));
1296
1297         /*
1298          * This function could be improved to handle multiple
1299          * interfaces better, but right now it makes any
1300          * non-station interfaces force SM PS to be turned
1301          * off. If there are multiple station interfaces it
1302          * could also use the best possible mode, e.g. if
1303          * one is in static and the other in dynamic then
1304          * dynamic is ok.
1305          */
1306
1307         list_for_each_entry(sdata, &local->interfaces, list) {
1308                 if (!netif_running(sdata->dev))
1309                         continue;
1310                 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1311                         goto set;
1312                 if (sdata != forsdata) {
1313                         /*
1314                          * This nested is ok -- we are holding the iflist_mtx
1315                          * so can't get here twice or so. But it's required
1316                          * since normally we acquire it first and then the
1317                          * iflist_mtx.
1318                          */
1319                         mutex_lock_nested(&sdata->u.mgd.mtx, SINGLE_DEPTH_NESTING);
1320                         count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1321                         mutex_unlock(&sdata->u.mgd.mtx);
1322                 } else
1323                         count += check_mgd_smps(&sdata->u.mgd, &smps_mode);
1324
1325                 if (count > 1) {
1326                         smps_mode = IEEE80211_SMPS_OFF;
1327                         break;
1328                 }
1329         }
1330
1331         if (smps_mode == local->smps_mode)
1332                 return;
1333
1334  set:
1335         local->smps_mode = smps_mode;
1336         /* changed flag is auto-detected for this */
1337         ieee80211_hw_config(local, 0);
1338 }
1339
1340 static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
1341 {
1342         int i;
1343
1344         for (i = 0; i < n_ids; i++)
1345                 if (ids[i] == id)
1346                         return true;
1347         return false;
1348 }
1349
1350 /**
1351  * ieee80211_ie_split - split an IE buffer according to ordering
1352  *
1353  * @ies: the IE buffer
1354  * @ielen: the length of the IE buffer
1355  * @ids: an array with element IDs that are allowed before
1356  *      the split
1357  * @n_ids: the size of the element ID array
1358  * @offset: offset where to start splitting in the buffer
1359  *
1360  * This function splits an IE buffer by updating the @offset
1361  * variable to point to the location where the buffer should be
1362  * split.
1363  *
1364  * It assumes that the given IE buffer is well-formed, this
1365  * has to be guaranteed by the caller!
1366  *
1367  * It also assumes that the IEs in the buffer are ordered
1368  * correctly, if not the result of using this function will not
1369  * be ordered correctly either, i.e. it does no reordering.
1370  *
1371  * The function returns the offset where the next part of the
1372  * buffer starts, which may be @ielen if the entire (remainder)
1373  * of the buffer should be used.
1374  */
1375 size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
1376                           const u8 *ids, int n_ids, size_t offset)
1377 {
1378         size_t pos = offset;
1379
1380         while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos]))
1381                 pos += 2 + ies[pos + 1];
1382
1383         return pos;
1384 }
1385
1386 size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset)
1387 {
1388         size_t pos = offset;
1389
1390         while (pos < ielen && ies[pos] != WLAN_EID_VENDOR_SPECIFIC)
1391                 pos += 2 + ies[pos + 1];
1392
1393         return pos;
1394 }