]> git.karo-electronics.de Git - mv-sheeva.git/blob - net/wireless/util.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[mv-sheeva.git] / net / wireless / util.c
1 /*
2  * Wireless utility functions
3  *
4  * Copyright 2007-2009  Johannes Berg <johannes@sipsolutions.net>
5  */
6 #include <linux/bitops.h>
7 #include <linux/etherdevice.h>
8 #include <linux/slab.h>
9 #include <net/cfg80211.h>
10 #include <net/ip.h>
11 #include "core.h"
12
13 struct ieee80211_rate *
14 ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
15                             u32 basic_rates, int bitrate)
16 {
17         struct ieee80211_rate *result = &sband->bitrates[0];
18         int i;
19
20         for (i = 0; i < sband->n_bitrates; i++) {
21                 if (!(basic_rates & BIT(i)))
22                         continue;
23                 if (sband->bitrates[i].bitrate > bitrate)
24                         continue;
25                 result = &sband->bitrates[i];
26         }
27
28         return result;
29 }
30 EXPORT_SYMBOL(ieee80211_get_response_rate);
31
32 int ieee80211_channel_to_frequency(int chan)
33 {
34         if (chan < 14)
35                 return 2407 + chan * 5;
36
37         if (chan == 14)
38                 return 2484;
39
40         /* FIXME: 802.11j 17.3.8.3.2 */
41         return (chan + 1000) * 5;
42 }
43 EXPORT_SYMBOL(ieee80211_channel_to_frequency);
44
45 int ieee80211_frequency_to_channel(int freq)
46 {
47         if (freq == 2484)
48                 return 14;
49
50         if (freq < 2484)
51                 return (freq - 2407) / 5;
52
53         /* FIXME: 802.11j 17.3.8.3.2 */
54         return freq/5 - 1000;
55 }
56 EXPORT_SYMBOL(ieee80211_frequency_to_channel);
57
58 struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
59                                                   int freq)
60 {
61         enum ieee80211_band band;
62         struct ieee80211_supported_band *sband;
63         int i;
64
65         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
66                 sband = wiphy->bands[band];
67
68                 if (!sband)
69                         continue;
70
71                 for (i = 0; i < sband->n_channels; i++) {
72                         if (sband->channels[i].center_freq == freq)
73                                 return &sband->channels[i];
74                 }
75         }
76
77         return NULL;
78 }
79 EXPORT_SYMBOL(__ieee80211_get_channel);
80
81 static void set_mandatory_flags_band(struct ieee80211_supported_band *sband,
82                                      enum ieee80211_band band)
83 {
84         int i, want;
85
86         switch (band) {
87         case IEEE80211_BAND_5GHZ:
88                 want = 3;
89                 for (i = 0; i < sband->n_bitrates; i++) {
90                         if (sband->bitrates[i].bitrate == 60 ||
91                             sband->bitrates[i].bitrate == 120 ||
92                             sband->bitrates[i].bitrate == 240) {
93                                 sband->bitrates[i].flags |=
94                                         IEEE80211_RATE_MANDATORY_A;
95                                 want--;
96                         }
97                 }
98                 WARN_ON(want);
99                 break;
100         case IEEE80211_BAND_2GHZ:
101                 want = 7;
102                 for (i = 0; i < sband->n_bitrates; i++) {
103                         if (sband->bitrates[i].bitrate == 10) {
104                                 sband->bitrates[i].flags |=
105                                         IEEE80211_RATE_MANDATORY_B |
106                                         IEEE80211_RATE_MANDATORY_G;
107                                 want--;
108                         }
109
110                         if (sband->bitrates[i].bitrate == 20 ||
111                             sband->bitrates[i].bitrate == 55 ||
112                             sband->bitrates[i].bitrate == 110 ||
113                             sband->bitrates[i].bitrate == 60 ||
114                             sband->bitrates[i].bitrate == 120 ||
115                             sband->bitrates[i].bitrate == 240) {
116                                 sband->bitrates[i].flags |=
117                                         IEEE80211_RATE_MANDATORY_G;
118                                 want--;
119                         }
120
121                         if (sband->bitrates[i].bitrate != 10 &&
122                             sband->bitrates[i].bitrate != 20 &&
123                             sband->bitrates[i].bitrate != 55 &&
124                             sband->bitrates[i].bitrate != 110)
125                                 sband->bitrates[i].flags |=
126                                         IEEE80211_RATE_ERP_G;
127                 }
128                 WARN_ON(want != 0 && want != 3 && want != 6);
129                 break;
130         case IEEE80211_NUM_BANDS:
131                 WARN_ON(1);
132                 break;
133         }
134 }
135
136 void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
137 {
138         enum ieee80211_band band;
139
140         for (band = 0; band < IEEE80211_NUM_BANDS; band++)
141                 if (wiphy->bands[band])
142                         set_mandatory_flags_band(wiphy->bands[band], band);
143 }
144
145 int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
146                                    struct key_params *params, int key_idx,
147                                    const u8 *mac_addr)
148 {
149         int i;
150
151         if (key_idx > 5)
152                 return -EINVAL;
153
154         /*
155          * Disallow pairwise keys with non-zero index unless it's WEP
156          * (because current deployments use pairwise WEP keys with
157          * non-zero indizes but 802.11i clearly specifies to use zero)
158          */
159         if (mac_addr && key_idx &&
160             params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
161             params->cipher != WLAN_CIPHER_SUITE_WEP104)
162                 return -EINVAL;
163
164         switch (params->cipher) {
165         case WLAN_CIPHER_SUITE_WEP40:
166                 if (params->key_len != WLAN_KEY_LEN_WEP40)
167                         return -EINVAL;
168                 break;
169         case WLAN_CIPHER_SUITE_TKIP:
170                 if (params->key_len != WLAN_KEY_LEN_TKIP)
171                         return -EINVAL;
172                 break;
173         case WLAN_CIPHER_SUITE_CCMP:
174                 if (params->key_len != WLAN_KEY_LEN_CCMP)
175                         return -EINVAL;
176                 break;
177         case WLAN_CIPHER_SUITE_WEP104:
178                 if (params->key_len != WLAN_KEY_LEN_WEP104)
179                         return -EINVAL;
180                 break;
181         case WLAN_CIPHER_SUITE_AES_CMAC:
182                 if (params->key_len != WLAN_KEY_LEN_AES_CMAC)
183                         return -EINVAL;
184                 break;
185         default:
186                 return -EINVAL;
187         }
188
189         if (params->seq) {
190                 switch (params->cipher) {
191                 case WLAN_CIPHER_SUITE_WEP40:
192                 case WLAN_CIPHER_SUITE_WEP104:
193                         /* These ciphers do not use key sequence */
194                         return -EINVAL;
195                 case WLAN_CIPHER_SUITE_TKIP:
196                 case WLAN_CIPHER_SUITE_CCMP:
197                 case WLAN_CIPHER_SUITE_AES_CMAC:
198                         if (params->seq_len != 6)
199                                 return -EINVAL;
200                         break;
201                 }
202         }
203
204         for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
205                 if (params->cipher == rdev->wiphy.cipher_suites[i])
206                         break;
207         if (i == rdev->wiphy.n_cipher_suites)
208                 return -EINVAL;
209
210         return 0;
211 }
212
213 /* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
214 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
215 const unsigned char rfc1042_header[] __aligned(2) =
216         { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
217 EXPORT_SYMBOL(rfc1042_header);
218
219 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
220 const unsigned char bridge_tunnel_header[] __aligned(2) =
221         { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
222 EXPORT_SYMBOL(bridge_tunnel_header);
223
224 unsigned int ieee80211_hdrlen(__le16 fc)
225 {
226         unsigned int hdrlen = 24;
227
228         if (ieee80211_is_data(fc)) {
229                 if (ieee80211_has_a4(fc))
230                         hdrlen = 30;
231                 if (ieee80211_is_data_qos(fc)) {
232                         hdrlen += IEEE80211_QOS_CTL_LEN;
233                         if (ieee80211_has_order(fc))
234                                 hdrlen += IEEE80211_HT_CTL_LEN;
235                 }
236                 goto out;
237         }
238
239         if (ieee80211_is_ctl(fc)) {
240                 /*
241                  * ACK and CTS are 10 bytes, all others 16. To see how
242                  * to get this condition consider
243                  *   subtype mask:   0b0000000011110000 (0x00F0)
244                  *   ACK subtype:    0b0000000011010000 (0x00D0)
245                  *   CTS subtype:    0b0000000011000000 (0x00C0)
246                  *   bits that matter:         ^^^      (0x00E0)
247                  *   value of those: 0b0000000011000000 (0x00C0)
248                  */
249                 if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0))
250                         hdrlen = 10;
251                 else
252                         hdrlen = 16;
253         }
254 out:
255         return hdrlen;
256 }
257 EXPORT_SYMBOL(ieee80211_hdrlen);
258
259 unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
260 {
261         const struct ieee80211_hdr *hdr =
262                         (const struct ieee80211_hdr *)skb->data;
263         unsigned int hdrlen;
264
265         if (unlikely(skb->len < 10))
266                 return 0;
267         hdrlen = ieee80211_hdrlen(hdr->frame_control);
268         if (unlikely(hdrlen > skb->len))
269                 return 0;
270         return hdrlen;
271 }
272 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
273
274 static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
275 {
276         int ae = meshhdr->flags & MESH_FLAGS_AE;
277         /* 7.1.3.5a.2 */
278         switch (ae) {
279         case 0:
280                 return 6;
281         case MESH_FLAGS_AE_A4:
282                 return 12;
283         case MESH_FLAGS_AE_A5_A6:
284                 return 18;
285         case (MESH_FLAGS_AE_A4 | MESH_FLAGS_AE_A5_A6):
286                 return 24;
287         default:
288                 return 6;
289         }
290 }
291
292 int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
293                            enum nl80211_iftype iftype)
294 {
295         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
296         u16 hdrlen, ethertype;
297         u8 *payload;
298         u8 dst[ETH_ALEN];
299         u8 src[ETH_ALEN] __aligned(2);
300
301         if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
302                 return -1;
303
304         hdrlen = ieee80211_hdrlen(hdr->frame_control);
305
306         /* convert IEEE 802.11 header + possible LLC headers into Ethernet
307          * header
308          * IEEE 802.11 address fields:
309          * ToDS FromDS Addr1 Addr2 Addr3 Addr4
310          *   0     0   DA    SA    BSSID n/a
311          *   0     1   DA    BSSID SA    n/a
312          *   1     0   BSSID SA    DA    n/a
313          *   1     1   RA    TA    DA    SA
314          */
315         memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
316         memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN);
317
318         switch (hdr->frame_control &
319                 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
320         case cpu_to_le16(IEEE80211_FCTL_TODS):
321                 if (unlikely(iftype != NL80211_IFTYPE_AP &&
322                              iftype != NL80211_IFTYPE_AP_VLAN))
323                         return -1;
324                 break;
325         case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
326                 if (unlikely(iftype != NL80211_IFTYPE_WDS &&
327                              iftype != NL80211_IFTYPE_MESH_POINT &&
328                              iftype != NL80211_IFTYPE_AP_VLAN &&
329                              iftype != NL80211_IFTYPE_STATION))
330                         return -1;
331                 if (iftype == NL80211_IFTYPE_MESH_POINT) {
332                         struct ieee80211s_hdr *meshdr =
333                                 (struct ieee80211s_hdr *) (skb->data + hdrlen);
334                         hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
335                         if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
336                                 memcpy(dst, meshdr->eaddr1, ETH_ALEN);
337                                 memcpy(src, meshdr->eaddr2, ETH_ALEN);
338                         }
339                 }
340                 break;
341         case cpu_to_le16(IEEE80211_FCTL_FROMDS):
342                 if ((iftype != NL80211_IFTYPE_STATION &&
343                     iftype != NL80211_IFTYPE_MESH_POINT) ||
344                     (is_multicast_ether_addr(dst) &&
345                      !compare_ether_addr(src, addr)))
346                         return -1;
347                 if (iftype == NL80211_IFTYPE_MESH_POINT) {
348                         struct ieee80211s_hdr *meshdr =
349                                 (struct ieee80211s_hdr *) (skb->data + hdrlen);
350                         hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
351                         if (meshdr->flags & MESH_FLAGS_AE_A4)
352                                 memcpy(src, meshdr->eaddr1, ETH_ALEN);
353                 }
354                 break;
355         case cpu_to_le16(0):
356                 if (iftype != NL80211_IFTYPE_ADHOC)
357                         return -1;
358                 break;
359         }
360
361         if (unlikely(skb->len - hdrlen < 8))
362                 return -1;
363
364         payload = skb->data + hdrlen;
365         ethertype = (payload[6] << 8) | payload[7];
366
367         if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
368                     ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
369                    compare_ether_addr(payload, bridge_tunnel_header) == 0)) {
370                 /* remove RFC1042 or Bridge-Tunnel encapsulation and
371                  * replace EtherType */
372                 skb_pull(skb, hdrlen + 6);
373                 memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
374                 memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
375         } else {
376                 struct ethhdr *ehdr;
377                 __be16 len;
378
379                 skb_pull(skb, hdrlen);
380                 len = htons(skb->len);
381                 ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
382                 memcpy(ehdr->h_dest, dst, ETH_ALEN);
383                 memcpy(ehdr->h_source, src, ETH_ALEN);
384                 ehdr->h_proto = len;
385         }
386         return 0;
387 }
388 EXPORT_SYMBOL(ieee80211_data_to_8023);
389
390 int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
391                              enum nl80211_iftype iftype, u8 *bssid, bool qos)
392 {
393         struct ieee80211_hdr hdr;
394         u16 hdrlen, ethertype;
395         __le16 fc;
396         const u8 *encaps_data;
397         int encaps_len, skip_header_bytes;
398         int nh_pos, h_pos;
399         int head_need;
400
401         if (unlikely(skb->len < ETH_HLEN))
402                 return -EINVAL;
403
404         nh_pos = skb_network_header(skb) - skb->data;
405         h_pos = skb_transport_header(skb) - skb->data;
406
407         /* convert Ethernet header to proper 802.11 header (based on
408          * operation mode) */
409         ethertype = (skb->data[12] << 8) | skb->data[13];
410         fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
411
412         switch (iftype) {
413         case NL80211_IFTYPE_AP:
414         case NL80211_IFTYPE_AP_VLAN:
415                 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
416                 /* DA BSSID SA */
417                 memcpy(hdr.addr1, skb->data, ETH_ALEN);
418                 memcpy(hdr.addr2, addr, ETH_ALEN);
419                 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
420                 hdrlen = 24;
421                 break;
422         case NL80211_IFTYPE_STATION:
423                 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
424                 /* BSSID SA DA */
425                 memcpy(hdr.addr1, bssid, ETH_ALEN);
426                 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
427                 memcpy(hdr.addr3, skb->data, ETH_ALEN);
428                 hdrlen = 24;
429                 break;
430         case NL80211_IFTYPE_ADHOC:
431                 /* DA SA BSSID */
432                 memcpy(hdr.addr1, skb->data, ETH_ALEN);
433                 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
434                 memcpy(hdr.addr3, bssid, ETH_ALEN);
435                 hdrlen = 24;
436                 break;
437         default:
438                 return -EOPNOTSUPP;
439         }
440
441         if (qos) {
442                 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
443                 hdrlen += 2;
444         }
445
446         hdr.frame_control = fc;
447         hdr.duration_id = 0;
448         hdr.seq_ctrl = 0;
449
450         skip_header_bytes = ETH_HLEN;
451         if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
452                 encaps_data = bridge_tunnel_header;
453                 encaps_len = sizeof(bridge_tunnel_header);
454                 skip_header_bytes -= 2;
455         } else if (ethertype > 0x600) {
456                 encaps_data = rfc1042_header;
457                 encaps_len = sizeof(rfc1042_header);
458                 skip_header_bytes -= 2;
459         } else {
460                 encaps_data = NULL;
461                 encaps_len = 0;
462         }
463
464         skb_pull(skb, skip_header_bytes);
465         nh_pos -= skip_header_bytes;
466         h_pos -= skip_header_bytes;
467
468         head_need = hdrlen + encaps_len - skb_headroom(skb);
469
470         if (head_need > 0 || skb_cloned(skb)) {
471                 head_need = max(head_need, 0);
472                 if (head_need)
473                         skb_orphan(skb);
474
475                 if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) {
476                         printk(KERN_ERR "failed to reallocate Tx buffer\n");
477                         return -ENOMEM;
478                 }
479                 skb->truesize += head_need;
480         }
481
482         if (encaps_data) {
483                 memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
484                 nh_pos += encaps_len;
485                 h_pos += encaps_len;
486         }
487
488         memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
489
490         nh_pos += hdrlen;
491         h_pos += hdrlen;
492
493         /* Update skb pointers to various headers since this modified frame
494          * is going to go through Linux networking code that may potentially
495          * need things like pointer to IP header. */
496         skb_set_mac_header(skb, 0);
497         skb_set_network_header(skb, nh_pos);
498         skb_set_transport_header(skb, h_pos);
499
500         return 0;
501 }
502 EXPORT_SYMBOL(ieee80211_data_from_8023);
503
504
505 void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list,
506                               const u8 *addr, enum nl80211_iftype iftype,
507                               const unsigned int extra_headroom)
508 {
509         struct sk_buff *frame = NULL;
510         u16 ethertype;
511         u8 *payload;
512         const struct ethhdr *eth;
513         int remaining, err;
514         u8 dst[ETH_ALEN], src[ETH_ALEN];
515
516         err = ieee80211_data_to_8023(skb, addr, iftype);
517         if (err)
518                 goto out;
519
520         /* skip the wrapping header */
521         eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr));
522         if (!eth)
523                 goto out;
524
525         while (skb != frame) {
526                 u8 padding;
527                 __be16 len = eth->h_proto;
528                 unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len);
529
530                 remaining = skb->len;
531                 memcpy(dst, eth->h_dest, ETH_ALEN);
532                 memcpy(src, eth->h_source, ETH_ALEN);
533
534                 padding = (4 - subframe_len) & 0x3;
535                 /* the last MSDU has no padding */
536                 if (subframe_len > remaining)
537                         goto purge;
538
539                 skb_pull(skb, sizeof(struct ethhdr));
540                 /* reuse skb for the last subframe */
541                 if (remaining <= subframe_len + padding)
542                         frame = skb;
543                 else {
544                         unsigned int hlen = ALIGN(extra_headroom, 4);
545                         /*
546                          * Allocate and reserve two bytes more for payload
547                          * alignment since sizeof(struct ethhdr) is 14.
548                          */
549                         frame = dev_alloc_skb(hlen + subframe_len + 2);
550                         if (!frame)
551                                 goto purge;
552
553                         skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
554                         memcpy(skb_put(frame, ntohs(len)), skb->data,
555                                 ntohs(len));
556
557                         eth = (struct ethhdr *)skb_pull(skb, ntohs(len) +
558                                                         padding);
559                         if (!eth) {
560                                 dev_kfree_skb(frame);
561                                 goto purge;
562                         }
563                 }
564
565                 skb_reset_network_header(frame);
566                 frame->dev = skb->dev;
567                 frame->priority = skb->priority;
568
569                 payload = frame->data;
570                 ethertype = (payload[6] << 8) | payload[7];
571
572                 if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
573                             ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
574                            compare_ether_addr(payload,
575                                               bridge_tunnel_header) == 0)) {
576                         /* remove RFC1042 or Bridge-Tunnel
577                          * encapsulation and replace EtherType */
578                         skb_pull(frame, 6);
579                         memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
580                         memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
581                 } else {
582                         memcpy(skb_push(frame, sizeof(__be16)), &len,
583                                 sizeof(__be16));
584                         memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN);
585                         memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
586                 }
587                 __skb_queue_tail(list, frame);
588         }
589
590         return;
591
592  purge:
593         __skb_queue_purge(list);
594  out:
595         dev_kfree_skb(skb);
596 }
597 EXPORT_SYMBOL(ieee80211_amsdu_to_8023s);
598
599 /* Given a data frame determine the 802.1p/1d tag to use. */
600 unsigned int cfg80211_classify8021d(struct sk_buff *skb)
601 {
602         unsigned int dscp;
603
604         /* skb->priority values from 256->263 are magic values to
605          * directly indicate a specific 802.1d priority.  This is used
606          * to allow 802.1d priority to be passed directly in from VLAN
607          * tags, etc.
608          */
609         if (skb->priority >= 256 && skb->priority <= 263)
610                 return skb->priority - 256;
611
612         switch (skb->protocol) {
613         case htons(ETH_P_IP):
614                 dscp = ip_hdr(skb)->tos & 0xfc;
615                 break;
616         default:
617                 return 0;
618         }
619
620         return dscp >> 5;
621 }
622 EXPORT_SYMBOL(cfg80211_classify8021d);
623
624 const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
625 {
626         u8 *end, *pos;
627
628         pos = bss->information_elements;
629         if (pos == NULL)
630                 return NULL;
631         end = pos + bss->len_information_elements;
632
633         while (pos + 1 < end) {
634                 if (pos + 2 + pos[1] > end)
635                         break;
636                 if (pos[0] == ie)
637                         return pos;
638                 pos += 2 + pos[1];
639         }
640
641         return NULL;
642 }
643 EXPORT_SYMBOL(ieee80211_bss_get_ie);
644
645 void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
646 {
647         struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
648         struct net_device *dev = wdev->netdev;
649         int i;
650
651         if (!wdev->connect_keys)
652                 return;
653
654         for (i = 0; i < 6; i++) {
655                 if (!wdev->connect_keys->params[i].cipher)
656                         continue;
657                 if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL,
658                                         &wdev->connect_keys->params[i])) {
659                         printk(KERN_ERR "%s: failed to set key %d\n",
660                                 dev->name, i);
661                         continue;
662                 }
663                 if (wdev->connect_keys->def == i)
664                         if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
665                                 printk(KERN_ERR "%s: failed to set defkey %d\n",
666                                         dev->name, i);
667                                 continue;
668                         }
669                 if (wdev->connect_keys->defmgmt == i)
670                         if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i))
671                                 printk(KERN_ERR "%s: failed to set mgtdef %d\n",
672                                         dev->name, i);
673         }
674
675         kfree(wdev->connect_keys);
676         wdev->connect_keys = NULL;
677 }
678
679 static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
680 {
681         struct cfg80211_event *ev;
682         unsigned long flags;
683         const u8 *bssid = NULL;
684
685         spin_lock_irqsave(&wdev->event_lock, flags);
686         while (!list_empty(&wdev->event_list)) {
687                 ev = list_first_entry(&wdev->event_list,
688                                       struct cfg80211_event, list);
689                 list_del(&ev->list);
690                 spin_unlock_irqrestore(&wdev->event_lock, flags);
691
692                 wdev_lock(wdev);
693                 switch (ev->type) {
694                 case EVENT_CONNECT_RESULT:
695                         if (!is_zero_ether_addr(ev->cr.bssid))
696                                 bssid = ev->cr.bssid;
697                         __cfg80211_connect_result(
698                                 wdev->netdev, bssid,
699                                 ev->cr.req_ie, ev->cr.req_ie_len,
700                                 ev->cr.resp_ie, ev->cr.resp_ie_len,
701                                 ev->cr.status,
702                                 ev->cr.status == WLAN_STATUS_SUCCESS,
703                                 NULL);
704                         break;
705                 case EVENT_ROAMED:
706                         __cfg80211_roamed(wdev, ev->rm.bssid,
707                                           ev->rm.req_ie, ev->rm.req_ie_len,
708                                           ev->rm.resp_ie, ev->rm.resp_ie_len);
709                         break;
710                 case EVENT_DISCONNECTED:
711                         __cfg80211_disconnected(wdev->netdev,
712                                                 ev->dc.ie, ev->dc.ie_len,
713                                                 ev->dc.reason, true);
714                         break;
715                 case EVENT_IBSS_JOINED:
716                         __cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
717                         break;
718                 }
719                 wdev_unlock(wdev);
720
721                 kfree(ev);
722
723                 spin_lock_irqsave(&wdev->event_lock, flags);
724         }
725         spin_unlock_irqrestore(&wdev->event_lock, flags);
726 }
727
728 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
729 {
730         struct wireless_dev *wdev;
731
732         ASSERT_RTNL();
733         ASSERT_RDEV_LOCK(rdev);
734
735         mutex_lock(&rdev->devlist_mtx);
736
737         list_for_each_entry(wdev, &rdev->netdev_list, list)
738                 cfg80211_process_wdev_events(wdev);
739
740         mutex_unlock(&rdev->devlist_mtx);
741 }
742
743 int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
744                           struct net_device *dev, enum nl80211_iftype ntype,
745                           u32 *flags, struct vif_params *params)
746 {
747         int err;
748         enum nl80211_iftype otype = dev->ieee80211_ptr->iftype;
749
750         ASSERT_RDEV_LOCK(rdev);
751
752         /* don't support changing VLANs, you just re-create them */
753         if (otype == NL80211_IFTYPE_AP_VLAN)
754                 return -EOPNOTSUPP;
755
756         if (!rdev->ops->change_virtual_intf ||
757             !(rdev->wiphy.interface_modes & (1 << ntype)))
758                 return -EOPNOTSUPP;
759
760         /* if it's part of a bridge, reject changing type to station/ibss */
761         if (dev->br_port && (ntype == NL80211_IFTYPE_ADHOC ||
762                              ntype == NL80211_IFTYPE_STATION))
763                 return -EBUSY;
764
765         if (ntype != otype) {
766                 dev->ieee80211_ptr->use_4addr = false;
767
768                 switch (otype) {
769                 case NL80211_IFTYPE_ADHOC:
770                         cfg80211_leave_ibss(rdev, dev, false);
771                         break;
772                 case NL80211_IFTYPE_STATION:
773                         cfg80211_disconnect(rdev, dev,
774                                             WLAN_REASON_DEAUTH_LEAVING, true);
775                         break;
776                 case NL80211_IFTYPE_MESH_POINT:
777                         /* mesh should be handled? */
778                         break;
779                 default:
780                         break;
781                 }
782
783                 cfg80211_process_rdev_events(rdev);
784         }
785
786         err = rdev->ops->change_virtual_intf(&rdev->wiphy, dev,
787                                              ntype, flags, params);
788
789         WARN_ON(!err && dev->ieee80211_ptr->iftype != ntype);
790
791         if (!err && params && params->use_4addr != -1)
792                 dev->ieee80211_ptr->use_4addr = params->use_4addr;
793
794         if (!err) {
795                 dev->priv_flags &= ~IFF_DONT_BRIDGE;
796                 switch (ntype) {
797                 case NL80211_IFTYPE_STATION:
798                         if (dev->ieee80211_ptr->use_4addr)
799                                 break;
800                         /* fall through */
801                 case NL80211_IFTYPE_ADHOC:
802                         dev->priv_flags |= IFF_DONT_BRIDGE;
803                         break;
804                 case NL80211_IFTYPE_AP:
805                 case NL80211_IFTYPE_AP_VLAN:
806                 case NL80211_IFTYPE_WDS:
807                 case NL80211_IFTYPE_MESH_POINT:
808                         /* bridging OK */
809                         break;
810                 case NL80211_IFTYPE_MONITOR:
811                         /* monitor can't bridge anyway */
812                         break;
813                 case NL80211_IFTYPE_UNSPECIFIED:
814                 case __NL80211_IFTYPE_AFTER_LAST:
815                         /* not happening */
816                         break;
817                 }
818         }
819
820         return err;
821 }
822
823 u16 cfg80211_calculate_bitrate(struct rate_info *rate)
824 {
825         int modulation, streams, bitrate;
826
827         if (!(rate->flags & RATE_INFO_FLAGS_MCS))
828                 return rate->legacy;
829
830         /* the formula below does only work for MCS values smaller than 32 */
831         if (rate->mcs >= 32)
832                 return 0;
833
834         modulation = rate->mcs & 7;
835         streams = (rate->mcs >> 3) + 1;
836
837         bitrate = (rate->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH) ?
838                         13500000 : 6500000;
839
840         if (modulation < 4)
841                 bitrate *= (modulation + 1);
842         else if (modulation == 4)
843                 bitrate *= (modulation + 2);
844         else
845                 bitrate *= (modulation + 3);
846
847         bitrate *= streams;
848
849         if (rate->flags & RATE_INFO_FLAGS_SHORT_GI)
850                 bitrate = (bitrate / 9) * 10;
851
852         /* do NOT round down here */
853         return (bitrate + 50000) / 100000;
854 }