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