aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r--net/wireless/scan.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 1f260c40b6ca..e95b638b919f 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -29,13 +29,14 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
29 goto out; 29 goto out;
30 30
31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 31 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
32 wiphy_to_dev(request->wiphy)->scan_req = NULL;
33 32
34 if (aborted) 33 if (aborted)
35 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev); 34 nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
36 else 35 else
37 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev); 36 nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
38 37
38 wiphy_to_dev(request->wiphy)->scan_req = NULL;
39
39#ifdef CONFIG_WIRELESS_EXT 40#ifdef CONFIG_WIRELESS_EXT
40 if (!aborted) { 41 if (!aborted) {
41 memset(&wrqu, 0, sizeof(wrqu)); 42 memset(&wrqu, 0, sizeof(wrqu));
@@ -377,18 +378,16 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
377 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 378 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
378 size_t ielen = res->pub.len_information_elements; 379 size_t ielen = res->pub.len_information_elements;
379 380
380 if (ksize(found) >= used + ielen) { 381 if (!found->ies_allocated && ksize(found) >= used + ielen) {
381 memcpy(found->pub.information_elements, 382 memcpy(found->pub.information_elements,
382 res->pub.information_elements, ielen); 383 res->pub.information_elements, ielen);
383 found->pub.len_information_elements = ielen; 384 found->pub.len_information_elements = ielen;
384 } else { 385 } else {
385 u8 *ies = found->pub.information_elements; 386 u8 *ies = found->pub.information_elements;
386 387
387 if (found->ies_allocated) { 388 if (found->ies_allocated)
388 if (ksize(ies) < ielen) 389 ies = krealloc(ies, ielen, GFP_ATOMIC);
389 ies = krealloc(ies, ielen, 390 else
390 GFP_ATOMIC);
391 } else
392 ies = kmalloc(ielen, GFP_ATOMIC); 391 ies = kmalloc(ielen, GFP_ATOMIC);
393 392
394 if (ies) { 393 if (ies) {
@@ -415,6 +414,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
415 return found; 414 return found;
416} 415}
417 416
417struct cfg80211_bss*
418cfg80211_inform_bss(struct wiphy *wiphy,
419 struct ieee80211_channel *channel,
420 const u8 *bssid,
421 u64 timestamp, u16 capability, u16 beacon_interval,
422 const u8 *ie, size_t ielen,
423 s32 signal, gfp_t gfp)
424{
425 struct cfg80211_internal_bss *res;
426 size_t privsz;
427
428 if (WARN_ON(!wiphy))
429 return NULL;
430
431 privsz = wiphy->bss_priv_size;
432
433 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
434 (signal < 0 || signal > 100)))
435 return NULL;
436
437 res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
438 if (!res)
439 return NULL;
440
441 memcpy(res->pub.bssid, bssid, ETH_ALEN);
442 res->pub.channel = channel;
443 res->pub.signal = signal;
444 res->pub.tsf = timestamp;
445 res->pub.beacon_interval = beacon_interval;
446 res->pub.capability = capability;
447 /* point to after the private area */
448 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
449 memcpy(res->pub.information_elements, ie, ielen);
450 res->pub.len_information_elements = ielen;
451
452 kref_init(&res->ref);
453
454 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
455 if (!res)
456 return NULL;
457
458 if (res->pub.capability & WLAN_CAPABILITY_ESS)
459 regulatory_hint_found_beacon(wiphy, channel, gfp);
460
461 /* cfg80211_bss_update gives us a referenced result */
462 return &res->pub;
463}
464EXPORT_SYMBOL(cfg80211_inform_bss);
465
418struct cfg80211_bss * 466struct cfg80211_bss *
419cfg80211_inform_bss_frame(struct wiphy *wiphy, 467cfg80211_inform_bss_frame(struct wiphy *wiphy,
420 struct ieee80211_channel *channel, 468 struct ieee80211_channel *channel,
@@ -605,7 +653,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
605 cfg80211_put_dev(rdev); 653 cfg80211_put_dev(rdev);
606 return err; 654 return err;
607} 655}
608EXPORT_SYMBOL(cfg80211_wext_siwscan); 656EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
609 657
610static void ieee80211_scan_add_ies(struct iw_request_info *info, 658static void ieee80211_scan_add_ies(struct iw_request_info *info,
611 struct cfg80211_bss *bss, 659 struct cfg80211_bss *bss,
@@ -914,5 +962,5 @@ int cfg80211_wext_giwscan(struct net_device *dev,
914 cfg80211_put_dev(rdev); 962 cfg80211_put_dev(rdev);
915 return res; 963 return res;
916} 964}
917EXPORT_SYMBOL(cfg80211_wext_giwscan); 965EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
918#endif 966#endif