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