diff options
Diffstat (limited to 'net/mac80211/scan.c')
-rw-r--r-- | net/mac80211/scan.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index f9648ef9e31f..070b40f15850 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright 2013-2015 Intel Mobile Communications GmbH | 9 | * Copyright 2013-2015 Intel Mobile Communications GmbH |
10 | * Copyright 2016 Intel Deutschland GmbH | ||
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
@@ -70,6 +71,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
70 | .boottime_ns = rx_status->boottime_ns, | 71 | .boottime_ns = rx_status->boottime_ns, |
71 | }; | 72 | }; |
72 | bool signal_valid; | 73 | bool signal_valid; |
74 | struct ieee80211_sub_if_data *scan_sdata; | ||
73 | 75 | ||
74 | if (ieee80211_hw_check(&local->hw, SIGNAL_DBM)) | 76 | if (ieee80211_hw_check(&local->hw, SIGNAL_DBM)) |
75 | bss_meta.signal = rx_status->signal * 100; | 77 | bss_meta.signal = rx_status->signal * 100; |
@@ -83,6 +85,20 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
83 | bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_10; | 85 | bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_10; |
84 | 86 | ||
85 | bss_meta.chan = channel; | 87 | bss_meta.chan = channel; |
88 | |||
89 | rcu_read_lock(); | ||
90 | scan_sdata = rcu_dereference(local->scan_sdata); | ||
91 | if (scan_sdata && scan_sdata->vif.type == NL80211_IFTYPE_STATION && | ||
92 | scan_sdata->vif.bss_conf.assoc && | ||
93 | ieee80211_have_rx_timestamp(rx_status)) { | ||
94 | bss_meta.parent_tsf = | ||
95 | ieee80211_calculate_rx_timestamp(local, rx_status, | ||
96 | len + FCS_LEN, 24); | ||
97 | ether_addr_copy(bss_meta.parent_bssid, | ||
98 | scan_sdata->vif.bss_conf.bssid); | ||
99 | } | ||
100 | rcu_read_unlock(); | ||
101 | |||
86 | cbss = cfg80211_inform_bss_frame_data(local->hw.wiphy, &bss_meta, | 102 | cbss = cfg80211_inform_bss_frame_data(local->hw.wiphy, &bss_meta, |
87 | mgmt, len, GFP_ATOMIC); | 103 | mgmt, len, GFP_ATOMIC); |
88 | if (!cbss) | 104 | if (!cbss) |
@@ -345,6 +361,12 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
345 | 361 | ||
346 | if (rc == 0) | 362 | if (rc == 0) |
347 | return; | 363 | return; |
364 | |||
365 | /* HW scan failed and is going to be reported as aborted, | ||
366 | * so clear old scan info. | ||
367 | */ | ||
368 | memset(&local->scan_info, 0, sizeof(local->scan_info)); | ||
369 | aborted = true; | ||
348 | } | 370 | } |
349 | 371 | ||
350 | kfree(local->hw_scan_req); | 372 | kfree(local->hw_scan_req); |
@@ -353,8 +375,10 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
353 | scan_req = rcu_dereference_protected(local->scan_req, | 375 | scan_req = rcu_dereference_protected(local->scan_req, |
354 | lockdep_is_held(&local->mtx)); | 376 | lockdep_is_held(&local->mtx)); |
355 | 377 | ||
356 | if (scan_req != local->int_scan_req) | 378 | if (scan_req != local->int_scan_req) { |
357 | cfg80211_scan_done(scan_req, aborted); | 379 | local->scan_info.aborted = aborted; |
380 | cfg80211_scan_done(scan_req, &local->scan_info); | ||
381 | } | ||
358 | RCU_INIT_POINTER(local->scan_req, NULL); | 382 | RCU_INIT_POINTER(local->scan_req, NULL); |
359 | 383 | ||
360 | scan_sdata = rcu_dereference_protected(local->scan_sdata, | 384 | scan_sdata = rcu_dereference_protected(local->scan_sdata, |
@@ -391,15 +415,19 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
391 | ieee80211_start_next_roc(local); | 415 | ieee80211_start_next_roc(local); |
392 | } | 416 | } |
393 | 417 | ||
394 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 418 | void ieee80211_scan_completed(struct ieee80211_hw *hw, |
419 | struct cfg80211_scan_info *info) | ||
395 | { | 420 | { |
396 | struct ieee80211_local *local = hw_to_local(hw); | 421 | struct ieee80211_local *local = hw_to_local(hw); |
397 | 422 | ||
398 | trace_api_scan_completed(local, aborted); | 423 | trace_api_scan_completed(local, info); |
399 | 424 | ||
400 | set_bit(SCAN_COMPLETED, &local->scanning); | 425 | set_bit(SCAN_COMPLETED, &local->scanning); |
401 | if (aborted) | 426 | if (info->aborted) |
402 | set_bit(SCAN_ABORTED, &local->scanning); | 427 | set_bit(SCAN_ABORTED, &local->scanning); |
428 | |||
429 | memcpy(&local->scan_info, info, sizeof(*info)); | ||
430 | |||
403 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); | 431 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); |
404 | } | 432 | } |
405 | EXPORT_SYMBOL(ieee80211_scan_completed); | 433 | EXPORT_SYMBOL(ieee80211_scan_completed); |
@@ -566,6 +594,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
566 | local->hw_scan_req->req.ie = ies; | 594 | local->hw_scan_req->req.ie = ies; |
567 | local->hw_scan_req->req.flags = req->flags; | 595 | local->hw_scan_req->req.flags = req->flags; |
568 | eth_broadcast_addr(local->hw_scan_req->req.bssid); | 596 | eth_broadcast_addr(local->hw_scan_req->req.bssid); |
597 | local->hw_scan_req->req.duration = req->duration; | ||
598 | local->hw_scan_req->req.duration_mandatory = | ||
599 | req->duration_mandatory; | ||
569 | 600 | ||
570 | local->hw_scan_band = 0; | 601 | local->hw_scan_band = 0; |
571 | 602 | ||
@@ -1073,6 +1104,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
1073 | */ | 1104 | */ |
1074 | cancel_delayed_work(&local->scan_work); | 1105 | cancel_delayed_work(&local->scan_work); |
1075 | /* and clean up */ | 1106 | /* and clean up */ |
1107 | memset(&local->scan_info, 0, sizeof(local->scan_info)); | ||
1076 | __ieee80211_scan_completed(&local->hw, true); | 1108 | __ieee80211_scan_completed(&local->hw, true); |
1077 | out: | 1109 | out: |
1078 | mutex_unlock(&local->mtx); | 1110 | mutex_unlock(&local->mtx); |