iwlwifi: queue user-initiated scan when doing internal scan
authorJohannes Berg <johannes.berg@intel.com>
Tue, 18 May 2010 09:29:13 +0000 (02:29 -0700)
committerReinette Chatre <reinette.chatre@intel.com>
Sun, 6 Jun 2010 06:20:08 +0000 (23:20 -0700)
The internal scanning created a problem where
when userspace tries to scan, the scan gets
rejected. Instead of doing that, queue up the
user-initiated scan when doing an internal
scan.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-scan.c

index 00b2cdd..6cd8d20 100644 (file)
@@ -1960,6 +1960,11 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
        }
        if (priv->vif == vif) {
                priv->vif = NULL;
+               if (priv->scan_vif == vif) {
+                       ieee80211_scan_completed(priv->hw, true);
+                       priv->scan_vif = NULL;
+                       priv->scan_request = NULL;
+               }
                memset(priv->bssid, 0, ETH_ALEN);
        }
        mutex_unlock(&priv->mutex);
index de326a6..45ceb27 100644 (file)
@@ -1130,6 +1130,7 @@ struct iwl_priv {
        void *scan_cmd;
        enum ieee80211_band scan_band;
        struct cfg80211_scan_request *scan_request;
+       struct ieee80211_vif *scan_vif;
        bool is_internal_short_scan;
        u8 scan_tx_ant[IEEE80211_NUM_BANDS];
        u8 mgmt_tx_ant;
index 0f9cbc2..b8bcd48 100644 (file)
@@ -333,7 +333,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
                goto out_unlock;
        }
 
-       if (test_bit(STATUS_SCANNING, &priv->status)) {
+       if (test_bit(STATUS_SCANNING, &priv->status) &&
+           !priv->is_internal_short_scan) {
                IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
                ret = -EAGAIN;
                goto out_unlock;
@@ -348,8 +349,16 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
        /* mac80211 will only ask for one band at a time */
        priv->scan_band = req->channels[0]->band;
        priv->scan_request = req;
+       priv->scan_vif = vif;
 
-       ret = iwl_scan_initiate(priv, vif);
+       /*
+        * If an internal scan is in progress, just set
+        * up the scan_request as per above.
+        */
+       if (priv->is_internal_short_scan)
+               ret = 0;
+       else
+               ret = iwl_scan_initiate(priv, vif);
 
        IWL_DEBUG_MAC80211(priv, "leave\n");
 
@@ -513,7 +522,21 @@ void iwl_bg_scan_completed(struct work_struct *work)
                priv->is_internal_short_scan = false;
                IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
                internal = true;
+       } else {
+               priv->scan_request = NULL;
+               priv->scan_vif = NULL;
        }
+
+       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+               goto out;
+
+       if (internal && priv->scan_request)
+               iwl_scan_initiate(priv, priv->scan_vif);
+
+       /* Since setting the TXPOWER may have been deferred while
+        * performing the scan, fire one off */
+       iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+ out:
        mutex_unlock(&priv->mutex);
 
        /*
@@ -523,15 +546,6 @@ void iwl_bg_scan_completed(struct work_struct *work)
         */
        if (!internal)
                ieee80211_scan_completed(priv->hw, false);
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return;
-
-       /* Since setting the TXPOWER may have been deferred while
-        * performing the scan, fire one off */
-       mutex_lock(&priv->mutex);
-       iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
-       mutex_unlock(&priv->mutex);
 }
 EXPORT_SYMBOL(iwl_bg_scan_completed);