aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2014-01-27 09:40:53 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2014-02-03 15:43:50 -0500
commita6623e84c4242942a988a810d1f5e6e7e2a36858 (patch)
tree602f5d93ffd2757f83b113f8e43d6edfd133284b /drivers
parent84b0312eee685bd0b2ca250dcea7049c8be4b655 (diff)
iwlwifi: mvm: abort scheduled scan on scan request
Some older versions of wpa_supplicant don't necessarily stop scheduled scan before starting a regular scan, and there's nothing in the API that requires it either. As a consequence our driver's behaviour of not allowing scan while scheduled scan was in progress broke userspace. However, it is valid to unilaterally stop scheduled scan at any point in time, so when a regular scan request comes just abort the scheduled scan and run the regular scan. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Reviewed-by: Alexander Bondar <alexander.bondar@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c25
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c7
3 files changed, 31 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 59b5b7a80d12..9d9a2d061cbb 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -1449,6 +1449,8 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1449 struct cfg80211_scan_request *req) 1449 struct cfg80211_scan_request *req)
1450{ 1450{
1451 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1451 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1452 struct iwl_notification_wait wait_scan_done;
1453 static const u8 scan_done_notif[] = { SCAN_OFFLOAD_COMPLETE, };
1452 int ret; 1454 int ret;
1453 1455
1454 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS) 1456 if (req->n_channels == 0 || req->n_channels > MAX_NUM_SCAN_CHANNELS)
@@ -1456,7 +1458,28 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
1456 1458
1457 mutex_lock(&mvm->mutex); 1459 mutex_lock(&mvm->mutex);
1458 1460
1459 if (mvm->scan_status != IWL_MVM_SCAN_NONE) { 1461 switch (mvm->scan_status) {
1462 case IWL_MVM_SCAN_SCHED:
1463 iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
1464 scan_done_notif,
1465 ARRAY_SIZE(scan_done_notif),
1466 NULL, NULL);
1467 iwl_mvm_sched_scan_stop(mvm);
1468 ret = iwl_wait_notification(&mvm->notif_wait,
1469 &wait_scan_done, HZ);
1470 if (ret) {
1471 ret = -EBUSY;
1472 goto out;
1473 }
1474 /* iwl_mvm_rx_scan_offload_complete_notif() will be called
1475 * soon but will not reset the scan status as it won't be
1476 * IWL_MVM_SCAN_SCHED any more since we queue the next scan
1477 * immediately (below)
1478 */
1479 break;
1480 case IWL_MVM_SCAN_NONE:
1481 break;
1482 default:
1460 ret = -EBUSY; 1483 ret = -EBUSY;
1461 goto out; 1484 goto out;
1462 } 1485 }
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 4b7fa7a55c1c..e268c15e5fea 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -228,7 +228,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
228 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 228 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
229 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 229 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
230 RX_HANDLER(SCAN_OFFLOAD_COMPLETE, 230 RX_HANDLER(SCAN_OFFLOAD_COMPLETE,
231 iwl_mvm_rx_scan_offload_complete_notif, false), 231 iwl_mvm_rx_scan_offload_complete_notif, true),
232 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results, 232 RX_HANDLER(MATCH_FOUND_NOTIFICATION, iwl_mvm_rx_sched_scan_results,
233 false), 233 false),
234 234
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 8477902a9183..a827a13f9873 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -511,11 +511,16 @@ int iwl_mvm_rx_scan_offload_complete_notif(struct iwl_mvm *mvm,
511 struct iwl_rx_packet *pkt = rxb_addr(rxb); 511 struct iwl_rx_packet *pkt = rxb_addr(rxb);
512 struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data; 512 struct iwl_scan_offload_complete *scan_notif = (void *)pkt->data;
513 513
514 /* scan status must be locked for proper checking */
515 lockdep_assert_held(&mvm->mutex);
516
514 IWL_DEBUG_SCAN(mvm, "Scheduled scan completed, status %s\n", 517 IWL_DEBUG_SCAN(mvm, "Scheduled scan completed, status %s\n",
515 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ? 518 scan_notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
516 "completed" : "aborted"); 519 "completed" : "aborted");
517 520
518 mvm->scan_status = IWL_MVM_SCAN_NONE; 521 /* might already be something else again, don't reset if so */
522 if (mvm->scan_status == IWL_MVM_SCAN_SCHED)
523 mvm->scan_status = IWL_MVM_SCAN_NONE;
519 ieee80211_sched_scan_stopped(mvm->hw); 524 ieee80211_sched_scan_stopped(mvm->hw);
520 525
521 return 0; 526 return 0;