summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-scan.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2010-09-13 14:46:38 +0200
committerJohn W. Linville <linville@tuxdriver.com>2010-09-14 22:08:04 +0200
commit02d8c14b590f583fd6e8c16fe779f845845effd9 (patch)
tree411501fe288e0958dee12d21ab8b24163fee89c9 /drivers/net/wireless/iwlwifi/iwl-scan.c
parentiwlwifi: rework iwl_scan_cancel_timeout (diff)
downloadlinux-02d8c14b590f583fd6e8c16fe779f845845effd9.tar.xz
linux-02d8c14b590f583fd6e8c16fe779f845845effd9.zip
iwlwifi: rewrite scan completion
Assure (partially) we call ieee80211_scan_completed() only once when scan was requested from mac80211. Code path that first clear STATUS_SCANNING bit is responsible to call ieee80211_scan_completed(). Before the call, we check if mac80211 really request the scan. Still persist some cases when we behave wrong, that will be addressed in the next patches. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-scan.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c65
1 files changed, 40 insertions, 25 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 6d02f41e8caa..e65a98d5d07f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -93,6 +93,19 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
return ret;
}
+static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
+{
+ /* check if scan was requested from mac80211 */
+ if (priv->scan_request) {
+ IWL_DEBUG_SCAN(priv, "Complete scan in mac80211\n");
+ ieee80211_scan_completed(priv->hw, aborted);
+ }
+
+ priv->is_internal_short_scan = false;
+ priv->scan_vif = NULL;
+ priv->scan_request = NULL;
+}
+
static void iwl_do_scan_abort(struct iwl_priv *priv)
{
int ret;
@@ -115,7 +128,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
clear_bit(STATUS_SCANNING, &priv->status);
clear_bit(STATUS_SCAN_HW, &priv->status);
clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- ieee80211_scan_completed(priv->hw, true);
+ iwl_complete_scan(priv, true);
} else
IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
}
@@ -545,10 +558,11 @@ static void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
- bool internal = false, aborted;
+ bool aborted;
struct iwl_rxon_context *ctx;
- IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
+ IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
+ priv->is_internal_short_scan ? "internal short " : "");
cancel_delayed_work(&priv->scan_check);
@@ -558,37 +572,38 @@ static void iwl_bg_scan_completed(struct work_struct *work)
if (aborted)
IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
- IWL_DEBUG_INFO(priv, "Setting scan to off\n");
-
- clear_bit(STATUS_SCANNING, &priv->status);
-
- if (priv->is_internal_short_scan) {
- priv->is_internal_short_scan = false;
- IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
- internal = true;
- } else if (priv->scan_request) {
- priv->scan_request = NULL;
- priv->scan_vif = NULL;
- ieee80211_scan_completed(priv->hw, aborted);
+ if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
+ IWL_DEBUG_INFO(priv, "Scan already completed.\n");
+ goto out;
}
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- goto out;
+ if (priv->is_internal_short_scan && !aborted) {
+ int err;
- if (internal && priv->scan_request) {
- int err = iwl_scan_initiate(priv, priv->scan_vif, false,
- priv->scan_request->channels[0]->band);
+ /* Check if mac80211 requested scan during our internal scan */
+ if (priv->scan_request == NULL)
+ goto out_complete;
+ /* If so request a new scan */
+ err = iwl_scan_initiate(priv, priv->scan_vif, false,
+ priv->scan_request->channels[0]->band);
if (err) {
IWL_DEBUG_SCAN(priv,
"failed to initiate pending scan: %d\n", err);
- priv->scan_request = NULL;
- priv->scan_vif = NULL;
- ieee80211_scan_completed(priv->hw, true);
- } else
- goto out;
+ aborted = true;
+ goto out_complete;
+ }
+
+ goto out;
}
+out_complete:
+ iwl_complete_scan(priv, aborted);
+
+ /* Can we still talk to firmware ? */
+ if (!iwl_is_ready_rf(priv))
+ goto out;
+
/* 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);