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