aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2010-02-02 13:57:12 -0500
committerReinette Chatre <reinette.chatre@intel.com>2010-02-11 13:26:40 -0500
commitbbcbb9ef9735c67da303d30bd6beb9e699f0f508 (patch)
tree847e85c99c99be50e3974dc45868c59171ce97a6
parent7bfedc59ee350727b115bbc79780c69b114f162d (diff)
iwlwifi: fix scan race
There is a problem if an "internal short scan" is in progress when a mac80211 requested scan arrives. If this new scan request arrives within the "next_scan_jiffies" period then driver will immediately return success and complete the scan. The problem here is that the scan has not been fully initialized at this time (is_internal_short_scan is still set to true because of the currently running scan), which results in the scan completion never to be sent to mac80211. At this time also, evan though the internal short scan is still running the state (is_internal_short_scan) will be set to false, so when the internal scan does complete then mac80211 will receive a scan completion. Fix this by checking right away if a scan is in progress when a scan request arrives from mac80211. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 501477464e07..dd9ff2ed645a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -469,21 +469,6 @@ EXPORT_SYMBOL(iwl_init_scan_params);
469 469
470static int iwl_scan_initiate(struct iwl_priv *priv) 470static int iwl_scan_initiate(struct iwl_priv *priv)
471{ 471{
472 if (!iwl_is_ready_rf(priv)) {
473 IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");
474 return -EIO;
475 }
476
477 if (test_bit(STATUS_SCANNING, &priv->status)) {
478 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
479 return -EAGAIN;
480 }
481
482 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
483 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
484 return -EAGAIN;
485 }
486
487 IWL_DEBUG_INFO(priv, "Starting scan...\n"); 472 IWL_DEBUG_INFO(priv, "Starting scan...\n");
488 set_bit(STATUS_SCANNING, &priv->status); 473 set_bit(STATUS_SCANNING, &priv->status);
489 priv->is_internal_short_scan = false; 474 priv->is_internal_short_scan = false;
@@ -515,6 +500,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
515 goto out_unlock; 500 goto out_unlock;
516 } 501 }
517 502
503 if (test_bit(STATUS_SCANNING, &priv->status)) {
504 IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
505 ret = -EAGAIN;
506 goto out_unlock;
507 }
508
509 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
510 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
511 ret = -EAGAIN;
512 goto out_unlock;
513 }
514
518 /* We don't schedule scan within next_scan_jiffies period. 515 /* We don't schedule scan within next_scan_jiffies period.
519 * Avoid scanning during possible EAPOL exchange, return 516 * Avoid scanning during possible EAPOL exchange, return
520 * success immediately. 517 * success immediately.