diff options
Diffstat (limited to 'net/wireless/scan.c')
-rw-r--r-- | net/wireless/scan.c | 66 |
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 | ||
417 | struct cfg80211_bss* | ||
418 | cfg80211_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 | } | ||
464 | EXPORT_SYMBOL(cfg80211_inform_bss); | ||
465 | |||
418 | struct cfg80211_bss * | 466 | struct cfg80211_bss * |
419 | cfg80211_inform_bss_frame(struct wiphy *wiphy, | 467 | cfg80211_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 | } |
608 | EXPORT_SYMBOL(cfg80211_wext_siwscan); | 656 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); |
609 | 657 | ||
610 | static void ieee80211_scan_add_ies(struct iw_request_info *info, | 658 | static 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 | } |
917 | EXPORT_SYMBOL(cfg80211_wext_giwscan); | 965 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan); |
918 | #endif | 966 | #endif |