aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2010-02-03 04:22:31 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-02-08 16:07:23 -0500
commitc0ce77b8323c1a0d4eeef97caf16c0ea971222a9 (patch)
tree933f730f9df8f969495d1cbf7b2ddd40bfc40906
parent098dfded5b1b09927995e89c6d689f85a0f53384 (diff)
mac80211: fix deferred hardware scan requests
Reinette found the reason for the warnings that happened occasionally when a hw-offloaded scan finished; her description of the problem: mac80211 will defer the handling of scan requests if it is busy with management work at the time. The scan requests are deferred and run after the work has completed. When this occurs there are currently two problems. * The scan request for hardware scan is not fully populated with the band and channels to scan not initialized. * When the scan is queued the state is not correctly updated to reflect that a scan is in progress. The problem here is that when the driver completes the scan and calls ieee80211_scan_completed() a warning will be triggered since mac80211 was not aware that a scan was in progress. The reason is that the queued scan work will start the hw scan right away when the hw_scan_req struct has already been allocated. However, in the first pass it will not have been filled, which happens at the same time as setting the bits. To fix this, simply move the allocation after the pending work test as well, so that the first iteration of the scan work will call __ieee80211_start_scan() even in the hardware scan case. Bug-identified-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/scan.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f934c9620b73..bc17cf7d68db 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -439,6 +439,16 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
439 if (local->scan_req) 439 if (local->scan_req)
440 return -EBUSY; 440 return -EBUSY;
441 441
442 if (req != local->int_scan_req &&
443 sdata->vif.type == NL80211_IFTYPE_STATION &&
444 !list_empty(&ifmgd->work_list)) {
445 /* actually wait for the work it's doing to finish/time out */
446 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
447 local->scan_req = req;
448 local->scan_sdata = sdata;
449 return 0;
450 }
451
442 if (local->ops->hw_scan) { 452 if (local->ops->hw_scan) {
443 u8 *ies; 453 u8 *ies;
444 454
@@ -463,14 +473,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
463 local->scan_req = req; 473 local->scan_req = req;
464 local->scan_sdata = sdata; 474 local->scan_sdata = sdata;
465 475
466 if (req != local->int_scan_req &&
467 sdata->vif.type == NL80211_IFTYPE_STATION &&
468 !list_empty(&ifmgd->work_list)) {
469 /* actually wait for the work it's doing to finish/time out */
470 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
471 return 0;
472 }
473
474 if (local->ops->hw_scan) 476 if (local->ops->hw_scan)
475 __set_bit(SCAN_HW_SCANNING, &local->scanning); 477 __set_bit(SCAN_HW_SCANNING, &local->scanning);
476 else 478 else