| From bbcbb9ef9735c67da303d30bd6beb9e699f0f508 Mon Sep 17 00:00:00 2001 |
| From: Reinette Chatre <reinette.chatre@intel.com> |
| Date: Tue, 2 Feb 2010 10:57:12 -0800 |
| Subject: iwlwifi: fix scan race |
| |
| From: Reinette Chatre <reinette.chatre@intel.com> |
| |
| commit bbcbb9ef9735c67da303d30bd6beb9e699f0f508 upstream. |
| |
| 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> |
| Cc: maximilian attems <max@stro.at> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/wireless/iwlwifi/iwl-scan.c | 27 ++++++++++++--------------- |
| 1 file changed, 12 insertions(+), 15 deletions(-) |
| |
| --- a/drivers/net/wireless/iwlwifi/iwl-scan.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c |
| @@ -405,21 +405,6 @@ void iwl_init_scan_params(struct iwl_pri |
| |
| static int iwl_scan_initiate(struct iwl_priv *priv) |
| { |
| - if (!iwl_is_ready_rf(priv)) { |
| - IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n"); |
| - return -EIO; |
| - } |
| - |
| - if (test_bit(STATUS_SCANNING, &priv->status)) { |
| - IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); |
| - return -EAGAIN; |
| - } |
| - |
| - if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
| - IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); |
| - return -EAGAIN; |
| - } |
| - |
| IWL_DEBUG_INFO(priv, "Starting scan...\n"); |
| set_bit(STATUS_SCANNING, &priv->status); |
| priv->scan_start = jiffies; |
| @@ -450,6 +435,18 @@ int iwl_mac_hw_scan(struct ieee80211_hw |
| goto out_unlock; |
| } |
| |
| + if (test_bit(STATUS_SCANNING, &priv->status)) { |
| + IWL_DEBUG_SCAN(priv, "Scan already in progress.\n"); |
| + ret = -EAGAIN; |
| + goto out_unlock; |
| + } |
| + |
| + if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { |
| + IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n"); |
| + ret = -EAGAIN; |
| + goto out_unlock; |
| + } |
| + |
| /* We don't schedule scan within next_scan_jiffies period. |
| * Avoid scanning during possible EAPOL exchange, return |
| * success immediately. |