media: video: tegra: Focuser range tuning support
[linux-2.6.git] / net / wireless / scan.c
1 /*
2  * cfg80211 scan result handling
3  *
4  * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
5  */
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/module.h>
9 #include <linux/netdevice.h>
10 #include <linux/wireless.h>
11 #include <linux/nl80211.h>
12 #include <linux/etherdevice.h>
13 #include <net/arp.h>
14 #include <net/cfg80211.h>
15 #include <net/iw_handler.h>
16 #include "core.h"
17 #include "nl80211.h"
18 #include "wext-compat.h"
19
20 #define IEEE80211_SCAN_RESULT_EXPIRE    (3 * HZ)
21
22 void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak)
23 {
24         struct cfg80211_scan_request *request;
25         struct net_device *dev;
26 #ifdef CONFIG_CFG80211_WEXT
27         union iwreq_data wrqu;
28 #endif
29
30         ASSERT_RDEV_LOCK(rdev);
31
32         request = rdev->scan_req;
33
34         if (!request)
35                 return;
36
37         dev = request->dev;
38
39         /*
40          * This must be before sending the other events!
41          * Otherwise, wpa_supplicant gets completely confused with
42          * wext events.
43          */
44         cfg80211_sme_scan_done(dev);
45
46         if (request->aborted)
47                 nl80211_send_scan_aborted(rdev, dev);
48         else
49                 nl80211_send_scan_done(rdev, dev);
50
51 #ifdef CONFIG_CFG80211_WEXT
52         if (!request->aborted) {
53                 memset(&wrqu, 0, sizeof(wrqu));
54
55                 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
56         }
57 #endif
58
59         dev_put(dev);
60
61         rdev->scan_req = NULL;
62
63         /*
64          * OK. If this is invoked with "leak" then we can't
65          * free this ... but we've cleaned it up anyway. The
66          * driver failed to call the scan_done callback, so
67          * all bets are off, it might still be trying to use
68          * the scan request or not ... if it accesses the dev
69          * in there (it shouldn't anyway) then it may crash.
70          */
71         if (!leak)
72                 kfree(request);
73 }
74
75 void __cfg80211_scan_done(struct work_struct *wk)
76 {
77         struct cfg80211_registered_device *rdev;
78
79         rdev = container_of(wk, struct cfg80211_registered_device,
80                             scan_done_wk);
81
82         cfg80211_lock_rdev(rdev);
83         ___cfg80211_scan_done(rdev, false);
84         cfg80211_unlock_rdev(rdev);
85 }
86
87 void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
88 {
89         WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
90
91         request->aborted = aborted;
92         queue_work(cfg80211_wq, &wiphy_to_dev(request->wiphy)->scan_done_wk);
93 }
94 EXPORT_SYMBOL(cfg80211_scan_done);
95
96 void __cfg80211_sched_scan_results(struct work_struct *wk)
97 {
98         struct cfg80211_registered_device *rdev;
99
100         rdev = container_of(wk, struct cfg80211_registered_device,
101                             sched_scan_results_wk);
102
103         mutex_lock(&rdev->sched_scan_mtx);
104
105         /* we don't have sched_scan_req anymore if the scan is stopping */
106         if (rdev->sched_scan_req)
107                 nl80211_send_sched_scan_results(rdev,
108                                                 rdev->sched_scan_req->dev);
109
110         mutex_unlock(&rdev->sched_scan_mtx);
111 }
112
113 void cfg80211_sched_scan_results(struct wiphy *wiphy)
114 {
115         /* ignore if we're not scanning */
116         if (wiphy_to_dev(wiphy)->sched_scan_req)
117                 queue_work(cfg80211_wq,
118                            &wiphy_to_dev(wiphy)->sched_scan_results_wk);
119 }
120 EXPORT_SYMBOL(cfg80211_sched_scan_results);
121
122 void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
123 {
124         struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
125
126         mutex_lock(&rdev->sched_scan_mtx);
127         __cfg80211_stop_sched_scan(rdev, true);
128         mutex_unlock(&rdev->sched_scan_mtx);
129 }
130 EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
131
132 int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
133                                bool driver_initiated)
134 {
135         struct net_device *dev;
136
137         lockdep_assert_held(&rdev->sched_scan_mtx);
138
139         if (!rdev->sched_scan_req)
140                 return -ENOENT;
141
142         dev = rdev->sched_scan_req->dev;
143
144         if (!driver_initiated) {
145                 int err = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
146                 if (err)
147                         return err;
148         }
149
150         nl80211_send_sched_scan(rdev, dev, NL80211_CMD_SCHED_SCAN_STOPPED);
151
152         kfree(rdev->sched_scan_req);
153         rdev->sched_scan_req = NULL;
154
155         return 0;
156 }
157
158 static void bss_release(struct kref *ref)
159 {
160         struct cfg80211_internal_bss *bss;
161
162         bss = container_of(ref, struct cfg80211_internal_bss, ref);
163         if (bss->pub.free_priv)
164                 bss->pub.free_priv(&bss->pub);
165
166         if (bss->beacon_ies_allocated)
167                 kfree(bss->pub.beacon_ies);
168         if (bss->proberesp_ies_allocated)
169                 kfree(bss->pub.proberesp_ies);
170
171         BUG_ON(atomic_read(&bss->hold));
172
173         kfree(bss);
174 }
175
176 /* must hold dev->bss_lock! */
177 void cfg80211_bss_age(struct cfg80211_registered_device *dev,
178                       unsigned long age_secs)
179 {
180         struct cfg80211_internal_bss *bss;
181         unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
182
183         list_for_each_entry(bss, &dev->bss_list, list) {
184                 bss->ts -= age_jiffies;
185         }
186 }
187
188 /* must hold dev->bss_lock! */
189 static void __cfg80211_unlink_bss(struct cfg80211_registered_device *dev,
190                                   struct cfg80211_internal_bss *bss)
191 {
192         list_del_init(&bss->list);
193         rb_erase(&bss->rbn, &dev->bss_tree);
194         kref_put(&bss->ref, bss_release);
195 }
196
197 /* must hold dev->bss_lock! */
198 void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
199 {
200         struct cfg80211_internal_bss *bss, *tmp;
201         bool expired = false;
202
203         list_for_each_entry_safe(bss, tmp, &dev->bss_list, list) {
204                 if (atomic_read(&bss->hold))
205                         continue;
206                 if (!time_after(jiffies, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE))
207                         continue;
208                 __cfg80211_unlink_bss(dev, bss);
209                 expired = true;
210         }
211
212         if (expired)
213                 dev->bss_generation++;
214 }
215
216 const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
217 {
218         while (len > 2 && ies[0] != eid) {
219                 len -= ies[1] + 2;
220                 ies += ies[1] + 2;
221         }
222         if (len < 2)
223                 return NULL;
224         if (len < 2 + ies[1])
225                 return NULL;
226         return ies;
227 }
228 EXPORT_SYMBOL(cfg80211_find_ie);
229
230 static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
231 {
232         const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
233         const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
234         int r;
235
236         if (!ie1 && !ie2)
237                 return 0;
238         if (!ie1 || !ie2)
239                 return -1;
240
241         r = memcmp(ie1 + 2, ie2 + 2, min(ie1[1], ie2[1]));
242         if (r == 0 && ie1[1] != ie2[1])
243                 return ie2[1] - ie1[1];
244         return r;
245 }
246
247 static bool is_bss(struct cfg80211_bss *a,
248                    const u8 *bssid,
249                    const u8 *ssid, size_t ssid_len)
250 {
251         const u8 *ssidie;
252
253         if (bssid && compare_ether_addr(a->bssid, bssid))
254                 return false;
255
256         if (!ssid)
257                 return true;
258
259         ssidie = cfg80211_find_ie(WLAN_EID_SSID,
260                                   a->information_elements,
261                                   a->len_information_elements);
262         if (!ssidie)
263                 return false;
264         if (ssidie[1] != ssid_len)
265                 return false;
266         return memcmp(ssidie + 2, ssid, ssid_len) == 0;
267 }
268
269 static bool is_mesh_bss(struct cfg80211_bss *a)
270 {
271         const u8 *ie;
272
273         if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
274                 return false;
275
276         ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
277                               a->information_elements,
278                               a->len_information_elements);
279         if (!ie)
280                 return false;
281
282         ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
283                               a->information_elements,
284                               a->len_information_elements);
285         if (!ie)
286                 return false;
287
288         return true;
289 }
290
291 static bool is_mesh(struct cfg80211_bss *a,
292                     const u8 *meshid, size_t meshidlen,
293                     const u8 *meshcfg)
294 {
295         const u8 *ie;
296
297         if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
298                 return false;
299
300         ie = cfg80211_find_ie(WLAN_EID_MESH_ID,
301                               a->information_elements,
302                               a->len_information_elements);
303         if (!ie)
304                 return false;
305         if (ie[1] != meshidlen)
306                 return false;
307         if (memcmp(ie + 2, meshid, meshidlen))
308                 return false;
309
310         ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG,
311                               a->information_elements,
312                               a->len_information_elements);
313         if (!ie)
314                 return false;
315         if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
316                 return false;
317
318         /*
319          * Ignore mesh capability (last two bytes of the IE) when
320          * comparing since that may differ between stations taking
321          * part in the same mesh.
322          */
323         return memcmp(ie + 2, meshcfg,
324             sizeof(struct ieee80211_meshconf_ie) - 2) == 0;
325 }
326
327 static int cmp_bss(struct cfg80211_bss *a,
328                    struct cfg80211_bss *b)
329 {
330         int r;
331
332         if (a->channel != b->channel)
333                 return b->channel->center_freq - a->channel->center_freq;
334
335         if (is_mesh_bss(a) && is_mesh_bss(b)) {
336                 r = cmp_ies(WLAN_EID_MESH_ID,
337                             a->information_elements,
338                             a->len_information_elements,
339                             b->information_elements,
340                             b->len_information_elements);
341                 if (r)
342                         return r;
343                 return cmp_ies(WLAN_EID_MESH_CONFIG,
344                                a->information_elements,
345                                a->len_information_elements,
346                                b->information_elements,
347                                b->len_information_elements);
348         }
349
350         r = memcmp(a->bssid, b->bssid, ETH_ALEN);
351         if (r)
352                 return r;
353
354         return cmp_ies(WLAN_EID_SSID,
355                        a->information_elements,
356                        a->len_information_elements,
357                        b->information_elements,
358                        b->len_information_elements);
359 }
360
361 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
362                                       struct ieee80211_channel *channel,
363                                       const u8 *bssid,
364                                       const u8 *ssid, size_t ssid_len,
365                                       u16 capa_mask, u16 capa_val)
366 {
367         struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
368         struct cfg80211_internal_bss *bss, *res = NULL;
369         unsigned long now = jiffies;
370
371         spin_lock_bh(&dev->bss_lock);
372
373         list_for_each_entry(bss, &dev->bss_list, list) {
374                 if ((bss->pub.capability & capa_mask) != capa_val)
375                         continue;
376                 if (channel && bss->pub.channel != channel)
377                         continue;
378                 /* Don't get expired BSS structs */
379                 if (time_after(now, bss->ts + IEEE80211_SCAN_RESULT_EXPIRE) &&
380                     !atomic_read(&bss->hold))
381                         continue;
382                 if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {
383                         res = bss;
384                         kref_get(&res->ref);
385                         break;
386                 }
387         }
388
389         spin_unlock_bh(&dev->bss_lock);
390         if (!res)
391                 return NULL;
392         return &res->pub;
393 }
394 EXPORT_SYMBOL(cfg80211_get_bss);
395
396 struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
397                                        struct ieee80211_channel *channel,
398                                        const u8 *meshid, size_t meshidlen,
399                                        const u8 *meshcfg)
400 {
401         struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
402         struct cfg80211_internal_bss *bss, *res = NULL;
403
404         spin_lock_bh(&dev->bss_lock);
405
406         list_for_each_entry(bss, &dev->bss_list, list) {
407                 if (channel && bss->pub.channel != channel)
408                         continue;
409                 if (is_mesh(&bss->pub, meshid, meshidlen, meshcfg)) {
410                         res = bss;
411                         kref_get(&res->ref);
412                         break;
413                 }
414         }
415
416         spin_unlock_bh(&dev->bss_lock);
417         if (!res)
418                 return NULL;
419         return &res->pub;
420 }
421 EXPORT_SYMBOL(cfg80211_get_mesh);
422
423
424 static void rb_insert_bss(struct cfg80211_registered_device *dev,
425                           struct cfg80211_internal_bss *bss)
426 {
427         struct rb_node **p = &dev->bss_tree.rb_node;
428         struct rb_node *parent = NULL;
429         struct cfg80211_internal_bss *tbss;
430         int cmp;
431
432         while (*p) {
433                 parent = *p;
434                 tbss = rb_entry(parent, struct cfg80211_internal_bss, rbn);
435
436                 cmp = cmp_bss(&bss->pub, &tbss->pub);
437
438                 if (WARN_ON(!cmp)) {
439                         /* will sort of leak this BSS */
440                         return;
441                 }
442
443                 if (cmp < 0)
444                         p = &(*p)->rb_left;
445                 else
446                         p = &(*p)->rb_right;
447         }
448
449         rb_link_node(&bss->rbn, parent, p);
450         rb_insert_color(&bss->rbn, &dev->bss_tree);
451 }
452
453 static struct cfg80211_internal_bss *
454 rb_find_bss(struct cfg80211_registered_device *dev,
455             struct cfg80211_internal_bss *res)
456 {
457         struct rb_node *n = dev->bss_tree.rb_node;
458         struct cfg80211_internal_bss *bss;
459         int r;
460
461         while (n) {
462                 bss = rb_entry(n, struct cfg80211_internal_bss, rbn);
463                 r = cmp_bss(&res->pub, &bss->pub);
464
465                 if (r == 0)
466                         return bss;
467                 else if (r < 0)
468                         n = n->rb_left;
469                 else
470                         n = n->rb_right;
471         }
472
473         return NULL;
474 }
475
476 static struct cfg80211_internal_bss *
477 cfg80211_bss_update(struct cfg80211_registered_device *dev,
478                     struct cfg80211_internal_bss *res)
479 {
480         struct cfg80211_internal_bss *found = NULL;
481
482         /*
483          * The reference to "res" is donated to this function.
484          */
485
486         if (WARN_ON(!res->pub.channel)) {
487                 kref_put(&res->ref, bss_release);
488                 return NULL;
489         }
490
491         res->ts = jiffies;
492
493         spin_lock_bh(&dev->bss_lock);
494
495         found = rb_find_bss(dev, res);
496
497         if (found) {
498                 found->pub.beacon_interval = res->pub.beacon_interval;
499                 found->pub.tsf = res->pub.tsf;
500                 found->pub.signal = res->pub.signal;
501                 found->pub.capability = res->pub.capability;
502                 found->ts = res->ts;
503
504                 /* Update IEs */
505                 if (res->pub.proberesp_ies) {
506                         size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
507                         size_t ielen = res->pub.len_proberesp_ies;
508
509                         if (found->pub.proberesp_ies &&
510                             !found->proberesp_ies_allocated &&
511                             ksize(found) >= used + ielen) {
512                                 memcpy(found->pub.proberesp_ies,
513                                        res->pub.proberesp_ies, ielen);
514                                 found->pub.len_proberesp_ies = ielen;
515                         } else {
516                                 u8 *ies = found->pub.proberesp_ies;
517
518                                 if (found->proberesp_ies_allocated)
519                                         ies = krealloc(ies, ielen, GFP_ATOMIC);
520                                 else
521                                         ies = kmalloc(ielen, GFP_ATOMIC);
522
523                                 if (ies) {
524                                         memcpy(ies, res->pub.proberesp_ies,
525                                                ielen);
526                                         found->proberesp_ies_allocated = true;
527                                         found->pub.proberesp_ies = ies;
528                                         found->pub.len_proberesp_ies = ielen;
529                                 }
530                         }
531
532                         /* Override possible earlier Beacon frame IEs */
533                         found->pub.information_elements =
534                                 found->pub.proberesp_ies;
535                         found->pub.len_information_elements =
536                                 found->pub.len_proberesp_ies;
537                 }
538                 if (res->pub.beacon_ies) {
539                         size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
540                         size_t ielen = res->pub.len_beacon_ies;
541                         bool information_elements_is_beacon_ies =
542                                 (found->pub.information_elements ==
543                                  found->pub.beacon_ies);
544
545                         if (found->pub.beacon_ies &&
546                             !found->beacon_ies_allocated &&
547                             ksize(found) >= used + ielen) {
548                                 memcpy(found->pub.beacon_ies,
549                                        res->pub.beacon_ies, ielen);
550                                 found->pub.len_beacon_ies = ielen;
551                         } else {
552                                 u8 *ies = found->pub.beacon_ies;
553
554                                 if (found->beacon_ies_allocated)
555                                         ies = krealloc(ies, ielen, GFP_ATOMIC);
556                                 else
557                                         ies = kmalloc(ielen, GFP_ATOMIC);
558
559                                 if (ies) {
560                                         memcpy(ies, res->pub.beacon_ies,
561                                                ielen);
562                                         found->beacon_ies_allocated = true;
563                                         found->pub.beacon_ies = ies;
564                                         found->pub.len_beacon_ies = ielen;
565                                 }
566                         }
567
568                         /* Override IEs if they were from a beacon before */
569                         if (information_elements_is_beacon_ies) {
570                                 found->pub.information_elements =
571                                         found->pub.beacon_ies;
572                                 found->pub.len_information_elements =
573                                         found->pub.len_beacon_ies;
574                         }
575                 }
576
577                 kref_put(&res->ref, bss_release);
578         } else {
579                 /* this "consumes" the reference */
580                 list_add_tail(&res->list, &dev->bss_list);
581                 rb_insert_bss(dev, res);
582                 found = res;
583         }
584
585         dev->bss_generation++;
586         spin_unlock_bh(&dev->bss_lock);
587
588         kref_get(&found->ref);
589         return found;
590 }
591
592 struct cfg80211_bss*
593 cfg80211_inform_bss(struct wiphy *wiphy,
594                     struct ieee80211_channel *channel,
595                     const u8 *bssid,
596                     u64 timestamp, u16 capability, u16 beacon_interval,
597                     const u8 *ie, size_t ielen,
598                     s32 signal, gfp_t gfp)
599 {
600         struct cfg80211_internal_bss *res;
601         size_t privsz;
602
603         if (WARN_ON(!wiphy))
604                 return NULL;
605
606         privsz = wiphy->bss_priv_size;
607
608         if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
609                         (signal < 0 || signal > 100)))
610                 return NULL;
611
612         res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
613         if (!res)
614                 return NULL;
615
616         memcpy(res->pub.bssid, bssid, ETH_ALEN);
617         res->pub.channel = channel;
618         res->pub.signal = signal;
619         res->pub.tsf = timestamp;
620         res->pub.beacon_interval = beacon_interval;
621         res->pub.capability = capability;
622         /*
623          * Since we do not know here whether the IEs are from a Beacon or Probe
624          * Response frame, we need to pick one of the options and only use it
625          * with the driver that does not provide the full Beacon/Probe Response
626          * frame. Use Beacon frame pointer to avoid indicating that this should
627          * override the information_elements pointer should we have received an
628          * earlier indication of Probe Response data.
629          *
630          * The initial buffer for the IEs is allocated with the BSS entry and
631          * is located after the private area.
632          */
633         res->pub.beacon_ies = (u8 *)res + sizeof(*res) + privsz;
634         memcpy(res->pub.beacon_ies, ie, ielen);
635         res->pub.len_beacon_ies = ielen;
636         res->pub.information_elements = res->pub.beacon_ies;
637         res->pub.len_information_elements = res->pub.len_beacon_ies;
638
639         kref_init(&res->ref);
640
641         res = cfg80211_bss_update(wiphy_to_dev(wiphy), res);
642         if (!res)
643                 return NULL;
644
645         if (res->pub.capability & WLAN_CAPABILITY_ESS)
646                 regulatory_hint_found_beacon(wiphy, channel, gfp);
647
648         /* cfg80211_bss_update gives us a referenced result */
649         return &res->pub;
650 }
651 EXPORT_SYMBOL(cfg80211_inform_bss);
652
653 struct cfg80211_bss *
654 cfg80211_inform_bss_frame(struct wiphy *wiphy,
655                           struct ieee80211_channel *channel,
656                           struct ieee80211_mgmt *mgmt, size_t len,
657                           s32 signal, gfp_t gfp)
658 {
659         struct cfg80211_internal_bss *res;
660         size_t ielen = len - offsetof(struct ieee80211_mgmt,
661                                       u.probe_resp.variable);
662         size_t privsz;
663
664         if (WARN_ON(!mgmt))
665                 return NULL;
666
667         if (WARN_ON(!wiphy))
668                 return NULL;
669
670         if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
671                     (signal < 0 || signal > 100)))
672                 return NULL;
673
674         if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
675                 return NULL;
676
677         privsz = wiphy->bss_priv_size;
678
679         res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
680         if (!res)
681                 return NULL;
682
683         memcpy(res->pub.bssid, mgmt->bssid, ETH_ALEN);
684         res->pub.channel = channel;
685         res->pub.signal = signal;
686         res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
687         res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
688         res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
689         /*
690          * The initial buffer for the IEs is allocated with the BSS entry and
691          * is located after the private area.
692          */
693         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
694                 res->pub.proberesp_ies = (u8 *) res + sizeof(*res) + privsz;
695                 memcpy(res->pub.proberesp_ies, mgmt->u.probe_resp.variable,
696                        ielen);
697                 res->pub.len_proberesp_ies = ielen;
698                 res->pub.information_elements = res->pub.proberesp_ies;
699                 res->pub.len_information_elements = res->pub.len_proberesp_ies;
700         } else {
701                 res->pub.beacon_ies = (u8 *) res + sizeof(*res) + privsz;
702                 memcpy(res->pub.beacon_ies, mgmt->u.beacon.variable, ielen);
703                 res->pub.len_beacon_ies = ielen;
704                 res->pub.information_elements = res->pub.beacon_ies;
705                 res->pub.len_information_elements = res->pub.len_beacon_ies;
706         }
707
708         kref_init(&res->ref);
709
710         res = cfg80211_bss_update(wiphy_to_dev(wiphy), res);
711         if (!res)
712                 return NULL;
713
714         if (res->pub.capability & WLAN_CAPABILITY_ESS)
715                 regulatory_hint_found_beacon(wiphy, channel, gfp);
716
717         /* cfg80211_bss_update gives us a referenced result */
718         return &res->pub;
719 }
720 EXPORT_SYMBOL(cfg80211_inform_bss_frame);
721
722 void cfg80211_put_bss(struct cfg80211_bss *pub)
723 {
724         struct cfg80211_internal_bss *bss;
725
726         if (!pub)
727                 return;
728
729         bss = container_of(pub, struct cfg80211_internal_bss, pub);
730         kref_put(&bss->ref, bss_release);
731 }
732 EXPORT_SYMBOL(cfg80211_put_bss);
733
734 void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *pub)
735 {
736         struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
737         struct cfg80211_internal_bss *bss;
738
739         if (WARN_ON(!pub))
740                 return;
741
742         bss = container_of(pub, struct cfg80211_internal_bss, pub);
743
744         spin_lock_bh(&dev->bss_lock);
745         if (!list_empty(&bss->list)) {
746                 __cfg80211_unlink_bss(dev, bss);
747                 dev->bss_generation++;
748         }
749         spin_unlock_bh(&dev->bss_lock);
750 }
751 EXPORT_SYMBOL(cfg80211_unlink_bss);
752
753 #ifdef CONFIG_CFG80211_WEXT
754 int cfg80211_wext_siwscan(struct net_device *dev,
755                           struct iw_request_info *info,
756                           union iwreq_data *wrqu, char *extra)
757 {
758         struct cfg80211_registered_device *rdev;
759         struct wiphy *wiphy;
760         struct iw_scan_req *wreq = NULL;
761         struct cfg80211_scan_request *creq = NULL;
762         int i, err, n_channels = 0;
763         enum ieee80211_band band;
764
765         if (!netif_running(dev))
766                 return -ENETDOWN;
767
768         if (wrqu->data.length == sizeof(struct iw_scan_req))
769                 wreq = (struct iw_scan_req *)extra;
770
771         rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
772
773         if (IS_ERR(rdev))
774                 return PTR_ERR(rdev);
775
776         if (rdev->scan_req) {
777                 err = -EBUSY;
778                 goto out;
779         }
780
781         wiphy = &rdev->wiphy;
782
783         /* Determine number of channels, needed to allocate creq */
784         if (wreq && wreq->num_channels)
785                 n_channels = wreq->num_channels;
786         else {
787                 for (band = 0; band < IEEE80211_NUM_BANDS; band++)
788                         if (wiphy->bands[band])
789                                 n_channels += wiphy->bands[band]->n_channels;
790         }
791
792         creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
793                        n_channels * sizeof(void *),
794                        GFP_ATOMIC);
795         if (!creq) {
796                 err = -ENOMEM;
797                 goto out;
798         }
799
800         creq->wiphy = wiphy;
801         creq->dev = dev;
802         /* SSIDs come after channels */
803         creq->ssids = (void *)&creq->channels[n_channels];
804         creq->n_channels = n_channels;
805         creq->n_ssids = 1;
806
807         /* translate "Scan on frequencies" request */
808         i = 0;
809         for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
810                 int j;
811
812                 if (!wiphy->bands[band])
813                         continue;
814
815                 for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
816                         /* ignore disabled channels */
817                         if (wiphy->bands[band]->channels[j].flags &
818                                                 IEEE80211_CHAN_DISABLED)
819                                 continue;
820
821                         /* If we have a wireless request structure and the
822                          * wireless request specifies frequencies, then search
823                          * for the matching hardware channel.
824                          */
825                         if (wreq && wreq->num_channels) {
826                                 int k;
827                                 int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
828                                 for (k = 0; k < wreq->num_channels; k++) {
829                                         int wext_freq = cfg80211_wext_freq(wiphy, &wreq->channel_list[k]);
830                                         if (wext_freq == wiphy_freq)
831                                                 goto wext_freq_found;
832                                 }
833                                 goto wext_freq_not_found;
834                         }
835
836                 wext_freq_found:
837                         creq->channels[i] = &wiphy->bands[band]->channels[j];
838                         i++;
839                 wext_freq_not_found: ;
840                 }
841         }
842         /* No channels found? */
843         if (!i) {
844                 err = -EINVAL;
845                 goto out;
846         }
847
848         /* Set real number of channels specified in creq->channels[] */
849         creq->n_channels = i;
850
851         /* translate "Scan for SSID" request */
852         if (wreq) {
853                 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
854                         if (wreq->essid_len > IEEE80211_MAX_SSID_LEN) {
855                                 err = -EINVAL;
856                                 goto out;
857                         }
858                         memcpy(creq->ssids[0].ssid, wreq->essid, wreq->essid_len);
859                         creq->ssids[0].ssid_len = wreq->essid_len;
860                 }
861                 if (wreq->scan_type == IW_SCAN_TYPE_PASSIVE)
862                         creq->n_ssids = 0;
863         }
864
865         for (i = 0; i < IEEE80211_NUM_BANDS; i++)
866                 if (wiphy->bands[i])
867                         creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
868
869         rdev->scan_req = creq;
870         err = rdev->ops->scan(wiphy, dev, creq);
871         if (err) {
872                 rdev->scan_req = NULL;
873                 /* creq will be freed below */
874         } else {
875                 nl80211_send_scan_start(rdev, dev);
876                 /* creq now owned by driver */
877                 creq = NULL;
878                 dev_hold(dev);
879         }
880  out:
881         kfree(creq);
882         cfg80211_unlock_rdev(rdev);
883         return err;
884 }
885 EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
886
887 static void ieee80211_scan_add_ies(struct iw_request_info *info,
888                                    struct cfg80211_bss *bss,
889                                    char **current_ev, char *end_buf)
890 {
891         u8 *pos, *end, *next;
892         struct iw_event iwe;
893
894         if (!bss->information_elements ||
895             !bss->len_information_elements)
896                 return;
897
898         /*
899          * If needed, fragment the IEs buffer (at IE boundaries) into short
900          * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
901          */
902         pos = bss->information_elements;
903         end = pos + bss->len_information_elements;
904
905         while (end - pos > IW_GENERIC_IE_MAX) {
906                 next = pos + 2 + pos[1];
907                 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
908                         next = next + 2 + next[1];
909
910                 memset(&iwe, 0, sizeof(iwe));
911                 iwe.cmd = IWEVGENIE;
912                 iwe.u.data.length = next - pos;
913                 *current_ev = iwe_stream_add_point(info, *current_ev,
914                                                    end_buf, &iwe, pos);
915
916                 pos = next;
917         }
918
919         if (end > pos) {
920                 memset(&iwe, 0, sizeof(iwe));
921                 iwe.cmd = IWEVGENIE;
922                 iwe.u.data.length = end - pos;
923                 *current_ev = iwe_stream_add_point(info, *current_ev,
924                                                    end_buf, &iwe, pos);
925         }
926 }
927
928 static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
929 {
930         unsigned long end = jiffies;
931
932         if (end >= start)
933                 return jiffies_to_msecs(end - start);
934
935         return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
936 }
937
938 static char *
939 ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
940               struct cfg80211_internal_bss *bss, char *current_ev,
941               char *end_buf)
942 {
943         struct iw_event iwe;
944         u8 *buf, *cfg, *p;
945         u8 *ie = bss->pub.information_elements;
946         int rem = bss->pub.len_information_elements, i, sig;
947         bool ismesh = false;
948
949         memset(&iwe, 0, sizeof(iwe));
950         iwe.cmd = SIOCGIWAP;
951         iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
952         memcpy(iwe.u.ap_addr.sa_data, bss->pub.bssid, ETH_ALEN);
953         current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
954                                           IW_EV_ADDR_LEN);
955
956         memset(&iwe, 0, sizeof(iwe));
957         iwe.cmd = SIOCGIWFREQ;
958         iwe.u.freq.m = ieee80211_frequency_to_channel(bss->pub.channel->center_freq);
959         iwe.u.freq.e = 0;
960         current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
961                                           IW_EV_FREQ_LEN);
962
963         memset(&iwe, 0, sizeof(iwe));
964         iwe.cmd = SIOCGIWFREQ;
965         iwe.u.freq.m = bss->pub.channel->center_freq;
966         iwe.u.freq.e = 6;
967         current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
968                                           IW_EV_FREQ_LEN);
969
970         if (wiphy->signal_type != CFG80211_SIGNAL_TYPE_NONE) {
971                 memset(&iwe, 0, sizeof(iwe));
972                 iwe.cmd = IWEVQUAL;
973                 iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED |
974                                      IW_QUAL_NOISE_INVALID |
975                                      IW_QUAL_QUAL_UPDATED;
976                 switch (wiphy->signal_type) {
977                 case CFG80211_SIGNAL_TYPE_MBM:
978                         sig = bss->pub.signal / 100;
979                         iwe.u.qual.level = sig;
980                         iwe.u.qual.updated |= IW_QUAL_DBM;
981                         if (sig < -110)         /* rather bad */
982                                 sig = -110;
983                         else if (sig > -40)     /* perfect */
984                                 sig = -40;
985                         /* will give a range of 0 .. 70 */
986                         iwe.u.qual.qual = sig + 110;
987                         break;
988                 case CFG80211_SIGNAL_TYPE_UNSPEC:
989                         iwe.u.qual.level = bss->pub.signal;
990                         /* will give range 0 .. 100 */
991                         iwe.u.qual.qual = bss->pub.signal;
992                         break;
993                 default:
994                         /* not reached */
995                         break;
996                 }
997                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
998                                                   &iwe, IW_EV_QUAL_LEN);
999         }
1000
1001         memset(&iwe, 0, sizeof(iwe));
1002         iwe.cmd = SIOCGIWENCODE;
1003         if (bss->pub.capability & WLAN_CAPABILITY_PRIVACY)
1004                 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1005         else
1006                 iwe.u.data.flags = IW_ENCODE_DISABLED;
1007         iwe.u.data.length = 0;
1008         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1009                                           &iwe, "");
1010
1011         while (rem >= 2) {
1012                 /* invalid data */
1013                 if (ie[1] > rem - 2)
1014                         break;
1015
1016                 switch (ie[0]) {
1017                 case WLAN_EID_SSID:
1018                         memset(&iwe, 0, sizeof(iwe));
1019                         iwe.cmd = SIOCGIWESSID;
1020                         iwe.u.data.length = ie[1];
1021                         iwe.u.data.flags = 1;
1022                         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1023                                                           &iwe, ie + 2);
1024                         break;
1025                 case WLAN_EID_MESH_ID:
1026                         memset(&iwe, 0, sizeof(iwe));
1027                         iwe.cmd = SIOCGIWESSID;
1028                         iwe.u.data.length = ie[1];
1029                         iwe.u.data.flags = 1;
1030                         current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1031                                                           &iwe, ie + 2);
1032                         break;
1033                 case WLAN_EID_MESH_CONFIG:
1034                         ismesh = true;
1035                         if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
1036                                 break;
1037                         buf = kmalloc(50, GFP_ATOMIC);
1038                         if (!buf)
1039                                 break;
1040                         cfg = ie + 2;
1041                         memset(&iwe, 0, sizeof(iwe));
1042                         iwe.cmd = IWEVCUSTOM;
1043                         sprintf(buf, "Mesh Network Path Selection Protocol ID: "
1044                                 "0x%02X", cfg[0]);
1045                         iwe.u.data.length = strlen(buf);
1046                         current_ev = iwe_stream_add_point(info, current_ev,
1047                                                           end_buf,
1048                                                           &iwe, buf);
1049                         sprintf(buf, "Path Selection Metric ID: 0x%02X",
1050                                 cfg[1]);
1051                         iwe.u.data.length = strlen(buf);
1052                         current_ev = iwe_stream_add_point(info, current_ev,
1053                                                           end_buf,
1054                                                           &iwe, buf);
1055                         sprintf(buf, "Congestion Control Mode ID: 0x%02X",
1056                                 cfg[2]);
1057                         iwe.u.data.length = strlen(buf);
1058                         current_ev = iwe_stream_add_point(info, current_ev,
1059                                                           end_buf,
1060                                                           &iwe, buf);
1061                         sprintf(buf, "Synchronization ID: 0x%02X", cfg[3]);
1062                         iwe.u.data.length = strlen(buf);
1063                         current_ev = iwe_stream_add_point(info, current_ev,
1064                                                           end_buf,
1065                                                           &iwe, buf);
1066                         sprintf(buf, "Authentication ID: 0x%02X", cfg[4]);
1067                         iwe.u.data.length = strlen(buf);
1068                         current_ev = iwe_stream_add_point(info, current_ev,
1069                                                           end_buf,
1070                                                           &iwe, buf);
1071                         sprintf(buf, "Formation Info: 0x%02X", cfg[5]);
1072                         iwe.u.data.length = strlen(buf);
1073                         current_ev = iwe_stream_add_point(info, current_ev,
1074                                                           end_buf,
1075                                                           &iwe, buf);
1076                         sprintf(buf, "Capabilities: 0x%02X", cfg[6]);
1077                         iwe.u.data.length = strlen(buf);
1078                         current_ev = iwe_stream_add_point(info, current_ev,
1079                                                           end_buf,
1080                                                           &iwe, buf);
1081                         kfree(buf);
1082                         break;
1083                 case WLAN_EID_SUPP_RATES:
1084                 case WLAN_EID_EXT_SUPP_RATES:
1085                         /* display all supported rates in readable format */
1086                         p = current_ev + iwe_stream_lcp_len(info);
1087
1088                         memset(&iwe, 0, sizeof(iwe));
1089                         iwe.cmd = SIOCGIWRATE;
1090                         /* Those two flags are ignored... */
1091                         iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
1092
1093                         for (i = 0; i < ie[1]; i++) {
1094                                 iwe.u.bitrate.value =
1095                                         ((ie[i + 2] & 0x7f) * 500000);
1096                                 p = iwe_stream_add_value(info, current_ev, p,
1097                                                 end_buf, &iwe, IW_EV_PARAM_LEN);
1098                         }
1099                         current_ev = p;
1100                         break;
1101                 }
1102                 rem -= ie[1] + 2;
1103                 ie += ie[1] + 2;
1104         }
1105
1106         if (bss->pub.capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) ||
1107             ismesh) {
1108                 memset(&iwe, 0, sizeof(iwe));
1109                 iwe.cmd = SIOCGIWMODE;
1110                 if (ismesh)
1111                         iwe.u.mode = IW_MODE_MESH;
1112                 else if (bss->pub.capability & WLAN_CAPABILITY_ESS)
1113                         iwe.u.mode = IW_MODE_MASTER;
1114                 else
1115                         iwe.u.mode = IW_MODE_ADHOC;
1116                 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1117                                                   &iwe, IW_EV_UINT_LEN);
1118         }
1119
1120         buf = kmalloc(30, GFP_ATOMIC);
1121         if (buf) {
1122                 memset(&iwe, 0, sizeof(iwe));
1123                 iwe.cmd = IWEVCUSTOM;
1124                 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf));
1125                 iwe.u.data.length = strlen(buf);
1126                 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1127                                                   &iwe, buf);
1128                 memset(&iwe, 0, sizeof(iwe));
1129                 iwe.cmd = IWEVCUSTOM;
1130                 sprintf(buf, " Last beacon: %ums ago",
1131                         elapsed_jiffies_msecs(bss->ts));
1132                 iwe.u.data.length = strlen(buf);
1133                 current_ev = iwe_stream_add_point(info, current_ev,
1134                                                   end_buf, &iwe, buf);
1135                 kfree(buf);
1136         }
1137
1138         ieee80211_scan_add_ies(info, &bss->pub, &current_ev, end_buf);
1139
1140         return current_ev;
1141 }
1142
1143
1144 static int ieee80211_scan_results(struct cfg80211_registered_device *dev,
1145                                   struct iw_request_info *info,
1146                                   char *buf, size_t len)
1147 {
1148         char *current_ev = buf;
1149         char *end_buf = buf + len;
1150         struct cfg80211_internal_bss *bss;
1151
1152         spin_lock_bh(&dev->bss_lock);
1153         cfg80211_bss_expire(dev);
1154
1155         list_for_each_entry(bss, &dev->bss_list, list) {
1156                 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
1157                         spin_unlock_bh(&dev->bss_lock);
1158                         return -E2BIG;
1159                 }
1160                 current_ev = ieee80211_bss(&dev->wiphy, info, bss,
1161                                            current_ev, end_buf);
1162         }
1163         spin_unlock_bh(&dev->bss_lock);
1164         return current_ev - buf;
1165 }
1166
1167
1168 int cfg80211_wext_giwscan(struct net_device *dev,
1169                           struct iw_request_info *info,
1170                           struct iw_point *data, char *extra)
1171 {
1172         struct cfg80211_registered_device *rdev;
1173         int res;
1174
1175         if (!netif_running(dev))
1176                 return -ENETDOWN;
1177
1178         rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
1179
1180         if (IS_ERR(rdev))
1181                 return PTR_ERR(rdev);
1182
1183         if (rdev->scan_req) {
1184                 res = -EAGAIN;
1185                 goto out;
1186         }
1187
1188         res = ieee80211_scan_results(rdev, info, extra, data->length);
1189         data->length = 0;
1190         if (res >= 0) {
1191                 data->length = res;
1192                 res = 0;
1193         }
1194
1195  out:
1196         cfg80211_unlock_rdev(rdev);
1197         return res;
1198 }
1199 EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
1200 #endif