aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/scan.c42
2 files changed, 35 insertions, 8 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 54edfb6fc1d1..f56d342c31b8 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1250,6 +1250,7 @@ struct ieee80211_local {
1250 int scan_channel_idx; 1250 int scan_channel_idx;
1251 int scan_ies_len; 1251 int scan_ies_len;
1252 int hw_scan_ies_bufsize; 1252 int hw_scan_ies_bufsize;
1253 struct cfg80211_scan_info scan_info;
1253 1254
1254 struct work_struct sched_scan_stopped_work; 1255 struct work_struct sched_scan_stopped_work;
1255 struct ieee80211_sub_if_data __rcu *sched_scan_sdata; 1256 struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 4ec1c52a1549..8d4a9cd8a39a 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,11 @@ 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 done, so clear
366 * old scan info.
367 */
368 memset(&local->scan_info, 0, sizeof(local->scan_info));
348 } 369 }
349 370
350 kfree(local->hw_scan_req); 371 kfree(local->hw_scan_req);
@@ -354,11 +375,8 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
354 lockdep_is_held(&local->mtx)); 375 lockdep_is_held(&local->mtx));
355 376
356 if (scan_req != local->int_scan_req) { 377 if (scan_req != local->int_scan_req) {
357 struct cfg80211_scan_info info = { 378 local->scan_info.aborted = aborted;
358 .aborted = aborted, 379 cfg80211_scan_done(scan_req, &local->scan_info);
359 };
360
361 cfg80211_scan_done(scan_req, &info);
362 } 380 }
363 RCU_INIT_POINTER(local->scan_req, NULL); 381 RCU_INIT_POINTER(local->scan_req, NULL);
364 382
@@ -396,15 +414,19 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
396 ieee80211_start_next_roc(local); 414 ieee80211_start_next_roc(local);
397} 415}
398 416
399void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) 417void ieee80211_scan_completed(struct ieee80211_hw *hw,
418 struct cfg80211_scan_info *info)
400{ 419{
401 struct ieee80211_local *local = hw_to_local(hw); 420 struct ieee80211_local *local = hw_to_local(hw);
402 421
403 trace_api_scan_completed(local, aborted); 422 trace_api_scan_completed(local, info);
404 423
405 set_bit(SCAN_COMPLETED, &local->scanning); 424 set_bit(SCAN_COMPLETED, &local->scanning);
406 if (aborted) 425 if (info->aborted)
407 set_bit(SCAN_ABORTED, &local->scanning); 426 set_bit(SCAN_ABORTED, &local->scanning);
427
428 memcpy(&local->scan_info, info, sizeof(*info));
429
408 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0); 430 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, 0);
409} 431}
410EXPORT_SYMBOL(ieee80211_scan_completed); 432EXPORT_SYMBOL(ieee80211_scan_completed);
@@ -571,6 +593,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
571 local->hw_scan_req->req.ie = ies; 593 local->hw_scan_req->req.ie = ies;
572 local->hw_scan_req->req.flags = req->flags; 594 local->hw_scan_req->req.flags = req->flags;
573 eth_broadcast_addr(local->hw_scan_req->req.bssid); 595 eth_broadcast_addr(local->hw_scan_req->req.bssid);
596 local->hw_scan_req->req.duration = req->duration;
597 local->hw_scan_req->req.duration_mandatory =
598 req->duration_mandatory;
574 599
575 local->hw_scan_band = 0; 600 local->hw_scan_band = 0;
576 601
@@ -1078,6 +1103,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
1078 */ 1103 */
1079 cancel_delayed_work(&local->scan_work); 1104 cancel_delayed_work(&local->scan_work);
1080 /* and clean up */ 1105 /* and clean up */
1106 memset(&local->scan_info, 0, sizeof(local->scan_info));
1081 __ieee80211_scan_completed(&local->hw, true); 1107 __ieee80211_scan_completed(&local->hw, true);
1082out: 1108out:
1083 mutex_unlock(&local->mtx); 1109 mutex_unlock(&local->mtx);