All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions
@ 2010-09-13 12:46 Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 01/14] iwlwifi: remove unused conf variables Stanislaw Gruszka
                   ` (14 more replies)
  0 siblings, 15 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Avoid iwlwifi hardware scanning race conditions
that may lead to not call ieee80211_scan_completed() (what in
consequences gives "WARNING: at net/wireless/core.c:614
wdev_cleanup_work+0xb7/0xf0"), or call iee80211_scan_completed() more
then once (what gives " WARNING: at net/mac80211/scan.c:312
ieee80211_scan_completed+0x5f/0x1f1").

First problem (warning in wdev_cleanup_work) make any further scan
request from cfg80211 are ignored by mac80211 with EBUSY error,
hence NetworkManager can not perform successful scan and not allow
to establish a new connection. So after suspend/resume (but maybe
not only then) user is not able to connect to wireless network again.

We can not rely on that the commands (start and abort scan) are
successful. Even if they are successfully send to the hardware, we can
not get back notification from firmware (i.e. firmware hung or was
reseted), or we can get notification when we actually perform abort
scan in driver code or after that.

To assure we call ieee80211_scan_completed() only once when scan
was started we use SCAN_SCANNING bit. Code path, which first clear
STATUS_SCANNING bit will call ieee80211_scan_completed().
We do this in many cases, in scan complete notification, scan
abort, device down, etc. Each time we check SCANNING bit.

Tested on 3945, 4965 and 5300 adapters. Tested normal work
functionality and doing scan stress testing using scripts:
http://people.redhat.com/sgruszka/misc/test_wifi_scan_reboot.sh
http://people.redhat.com/sgruszka/misc/test_wifi_scan_updown.sh

v1 -> v2:
- fix not cleared STATUS_SCAN_HW bit in patch 2
- merged patch 7 and 8
- add 3 new patches

v2 -> v3:
- merged patch 5 and 14
- merged patch 2 and 16
- add bugzilla reference into 3 most important patches
- not use cancel_delayed_work_sync in work function (patch 10)

v3 -> v4:
- add additional changelog comments in patch 9 and 13 and Wey acks
  in other patches

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/14] iwlwifi: remove unused conf variables
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 02/14] iwlwifi: unify scan start checks Stanislaw Gruszka
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

There are a number of conf variables that are
unused, remove them.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c  |    3 ---
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    6 ------
 2 files changed, 0 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index a8f2adf..51a8d7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1162,7 +1162,6 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		.flags = CMD_SIZE_HUGE,
 	};
 	struct iwl_scan_cmd *scan;
-	struct ieee80211_conf *conf = NULL;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 	u32 rate_flags = 0;
 	u16 cmd_len;
@@ -1179,8 +1178,6 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	if (vif)
 		ctx = iwl_rxon_ctx_from_vif(vif);
 
-	conf = ieee80211_get_hw_conf(priv->hw);
-
 	cancel_delayed_work(&priv->scan_check);
 
 	if (!iwl_is_ready(priv)) {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 68e624a..5b742eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2569,12 +2569,9 @@ static void __iwl3945_down(struct iwl_priv *priv)
 {
 	unsigned long flags;
 	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
-	struct ieee80211_conf *conf = NULL;
 
 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
-	conf = ieee80211_get_hw_conf(priv->hw);
-
 	if (!exit_pending)
 		set_bit(STATUS_EXIT_PENDING, &priv->status);
 
@@ -2828,13 +2825,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		.flags = CMD_SIZE_HUGE,
 	};
 	struct iwl3945_scan_cmd *scan;
-	struct ieee80211_conf *conf = NULL;
 	u8 n_probes = 0;
 	enum ieee80211_band band;
 	bool is_active = false;
 
-	conf = ieee80211_get_hw_conf(priv->hw);
-
 	cancel_delayed_work(&priv->scan_check);
 
 	if (!iwl_is_ready(priv)) {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/14] iwlwifi: unify scan start checks
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 01/14] iwlwifi: remove unused conf variables Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 03/14] iwlwifi: move scan completed flags handling Stanislaw Gruszka
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Rather than duplicating all the checks and even
in case of errors accepting the scan request
from mac80211, we can push the checks to the
caller and in all error cases reject the scan
request right away (rather than accepting and
then saying it was aborted).

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-3945.h     |    2 +-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c  |   88 +++++--------------
 drivers/net/wireless/iwlwifi/iwl-agn.h      |    2 +-
 drivers/net/wireless/iwlwifi/iwl-core.h     |    2 +-
 drivers/net/wireless/iwlwifi/iwl-scan.c     |  127 ++++++++++++++++-----------
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   74 ++--------------
 6 files changed, 108 insertions(+), 187 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index bb2aeeb..98509c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -295,7 +295,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
 extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
 
 /* scanning */
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
 
 /* Requires full declaration of iwl_priv before including */
 #include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 51a8d7e..f89dd81 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1154,7 +1154,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
 	return added;
 }
 
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
@@ -1174,57 +1174,20 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	int  chan_mod;
 	u8 active_chains;
 	u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
+	int ret;
+
+	lockdep_assert_held(&priv->mutex);
 
 	if (vif)
 		ctx = iwl_rxon_ctx_from_vif(vif);
 
-	cancel_delayed_work(&priv->scan_check);
-
-	if (!iwl_is_ready(priv)) {
-		IWL_WARN(priv, "request scan called when driver not ready.\n");
-		goto done;
-	}
-
-	/* Make sure the scan wasn't canceled before this queued work
-	 * was given the chance to run... */
-	if (!test_bit(STATUS_SCANNING, &priv->status))
-		goto done;
-
-	/* This should never be called or scheduled if there is currently
-	 * a scan active in the hardware. */
-	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests in parallel. "
-			       "Ignoring second request.\n");
-		goto done;
-	}
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
-		goto done;
-	}
-
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC(priv, "Scan request while abort pending.  Queuing.\n");
-		goto done;
-	}
-
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
-		goto done;
-	}
-
-	if (!test_bit(STATUS_READY, &priv->status)) {
-		IWL_DEBUG_HC(priv, "Scan request while uninitialized.  Queuing.\n");
-		goto done;
-	}
-
 	if (!priv->scan_cmd) {
 		priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
 					 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
 		if (!priv->scan_cmd) {
 			IWL_DEBUG_SCAN(priv,
 				       "fail to allocate memory for scan\n");
-			goto done;
+			return -ENOMEM;
 		}
 	}
 	scan = priv->scan_cmd;
@@ -1331,8 +1294,8 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 						IWL_GOOD_CRC_TH_NEVER;
 		break;
 	default:
-		IWL_WARN(priv, "Invalid scan band count\n");
-		goto done;
+		IWL_WARN(priv, "Invalid scan band\n");
+		return -EIO;
 	}
 
 	band = priv->scan_band;
@@ -1412,7 +1375,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	}
 	if (scan->channel_count == 0) {
 		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
-		goto done;
+		return -EIO;
 	}
 
 	cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -1420,30 +1383,21 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	cmd.data = scan;
 	scan->len = cpu_to_le16(cmd.len);
 
-	set_bit(STATUS_SCAN_HW, &priv->status);
-
-	if (priv->cfg->ops->hcmd->set_pan_params &&
-	    priv->cfg->ops->hcmd->set_pan_params(priv))
-		goto done;
+	if (priv->cfg->ops->hcmd->set_pan_params) {
+		ret = priv->cfg->ops->hcmd->set_pan_params(priv);
+		if (ret)
+			return ret;
+	}
 
-	if (iwl_send_cmd_sync(priv, &cmd))
-		goto done;
+	set_bit(STATUS_SCAN_HW, &priv->status);
+	ret = iwl_send_cmd_sync(priv, &cmd);
+	if (ret) {
+		clear_bit(STATUS_SCAN_HW, &priv->status);
+		if (priv->cfg->ops->hcmd->set_pan_params)
+			priv->cfg->ops->hcmd->set_pan_params(priv);
+	}
 
-	queue_delayed_work(priv->workqueue, &priv->scan_check,
-			   IWL_SCAN_CHECK_WATCHDOG);
-
-	return;
-
- done:
-	/* Cannot perform scan. Make sure we clear scanning
-	* bits from status so next scan request can be performed.
-	* If we don't clear scanning status bit here all next scan
-	* will fail
-	*/
-	clear_bit(STATUS_SCAN_HW, &priv->status);
-	clear_bit(STATUS_SCANNING, &priv->status);
-	/* inform mac80211 scan aborted */
-	queue_work(priv->workqueue, &priv->scan_completed);
+	return ret;
 }
 
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index ab7c16f..e1f85ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -219,7 +219,7 @@ void iwl_reply_statistics(struct iwl_priv *priv,
 			  struct iwl_rx_mem_buffer *rxb);
 
 /* scan */
-void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
+int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
 
 /* station mgmt */
 int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index f7b57ed..8dab074 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -111,7 +111,7 @@ struct iwl_hcmd_utils_ops {
 				  __le16 fc, __le32 *tx_flags);
 	int  (*calc_rssi)(struct iwl_priv *priv,
 			  struct iwl_rx_phy_res *rx_resp);
-	void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
+	int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
 };
 
 struct iwl_apm_ops {
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 7727f09..6bd14bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -324,19 +324,68 @@ void iwl_init_scan_params(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_init_scan_params);
 
-static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
+static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
+					  struct ieee80211_vif *vif,
+					  bool internal,
+					  enum nl80211_band band)
 {
+	int ret;
+
 	lockdep_assert_held(&priv->mutex);
 
-	IWL_DEBUG_INFO(priv, "Starting scan...\n");
+	if (WARN_ON(!priv->cfg->ops->utils->request_scan))
+		return -EOPNOTSUPP;
+
+	cancel_delayed_work(&priv->scan_check);
+
+	if (!iwl_is_ready(priv)) {
+		IWL_WARN(priv, "request scan called when driver not ready.\n");
+		return -EIO;
+	}
+
+	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
+		IWL_DEBUG_INFO(priv,
+			"Multiple concurrent scan requests in parallel.\n");
+		return -EBUSY;
+	}
+
+	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
+		return -EIO;
+	}
+
+	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
+		return -EBUSY;
+	}
+
+	if (iwl_is_rfkill(priv)) {
+		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
+		return -EIO;
+	}
+
+	if (!test_bit(STATUS_READY, &priv->status)) {
+		IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n");
+		return -EBUSY;
+	}
+
+	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
+			internal ? "internal short " : "");
+
 	set_bit(STATUS_SCANNING, &priv->status);
-	priv->is_internal_short_scan = false;
+	priv->is_internal_short_scan = internal;
 	priv->scan_start = jiffies;
+	priv->scan_band = band;
 
-	if (WARN_ON(!priv->cfg->ops->utils->request_scan))
-		return -EOPNOTSUPP;
+	ret = priv->cfg->ops->utils->request_scan(priv, vif);
+	if (ret) {
+		clear_bit(STATUS_SCANNING, &priv->status);
+		priv->is_internal_short_scan = false;
+		return ret;
+	}
 
-	priv->cfg->ops->utils->request_scan(priv, vif);
+	queue_delayed_work(priv->workqueue, &priv->scan_check,
+			   IWL_SCAN_CHECK_WATCHDOG);
 
 	return 0;
 }
@@ -355,12 +404,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 
 	mutex_lock(&priv->mutex);
 
-	if (!iwl_is_ready_rf(priv)) {
-		ret = -EIO;
-		IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");
-		goto out_unlock;
-	}
-
 	if (test_bit(STATUS_SCANNING, &priv->status) &&
 	    !priv->is_internal_short_scan) {
 		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
@@ -368,14 +411,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 		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;
-	}
-
 	/* 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;
 
@@ -386,7 +422,8 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 	if (priv->is_internal_short_scan)
 		ret = 0;
 	else
-		ret = iwl_scan_initiate(priv, vif);
+		ret = iwl_scan_initiate(priv, vif, false,
+					req->channels[0]->band);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 
@@ -418,31 +455,13 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
 		goto unlock;
 	}
 
-	if (!iwl_is_ready_rf(priv)) {
-		IWL_DEBUG_SCAN(priv, "not ready or exit pending\n");
-		goto unlock;
-	}
-
 	if (test_bit(STATUS_SCANNING, &priv->status)) {
 		IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");
 		goto unlock;
 	}
 
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");
-		goto unlock;
-	}
-
-	priv->scan_band = priv->band;
-
-	IWL_DEBUG_SCAN(priv, "Start internal short scan...\n");
-	set_bit(STATUS_SCANNING, &priv->status);
-	priv->is_internal_short_scan = true;
-
-	if (WARN_ON(!priv->cfg->ops->utils->request_scan))
-		goto unlock;
-
-	priv->cfg->ops->utils->request_scan(priv, NULL);
+	if (iwl_scan_initiate(priv, NULL, true, priv->band))
+		IWL_DEBUG_SCAN(priv, "failed to start internal short scan\n");
  unlock:
 	mutex_unlock(&priv->mutex);
 }
@@ -536,7 +555,6 @@ 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;
-	bool scan_completed = false;
 	struct iwl_rxon_context *ctx;
 
 	IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
@@ -549,16 +567,27 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 		IWL_DEBUG_SCAN(priv, "internal short scan completed\n");
 		internal = true;
 	} else if (priv->scan_request) {
-		scan_completed = true;
 		priv->scan_request = NULL;
 		priv->scan_vif = NULL;
+		ieee80211_scan_completed(priv->hw, false);
 	}
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		goto out;
 
-	if (internal && priv->scan_request)
-		iwl_scan_initiate(priv, priv->scan_vif);
+	if (internal && priv->scan_request) {
+		int 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;
+	}
 
 	/* Since setting the TXPOWER may have been deferred while
 	 * performing the scan, fire one off */
@@ -571,19 +600,11 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	for_each_context(priv, ctx)
 		iwlcore_commit_rxon(priv, ctx);
 
- out:
 	if (priv->cfg->ops->hcmd->set_pan_params)
 		priv->cfg->ops->hcmd->set_pan_params(priv);
 
+ out:
 	mutex_unlock(&priv->mutex);
-
-	/*
-	 * Do not hold mutex here since this will cause mac80211 to call
-	 * into driver again into functions that will attempt to take
-	 * mutex.
-	 */
-	if (scan_completed)
-		ieee80211_scan_completed(priv->hw, false);
 }
 
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5b742eb..3b3686b 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2817,7 +2817,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
 
 }
 
-void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
+int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 {
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
@@ -2828,55 +2828,16 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	u8 n_probes = 0;
 	enum ieee80211_band band;
 	bool is_active = false;
+	int ret;
 
-	cancel_delayed_work(&priv->scan_check);
-
-	if (!iwl_is_ready(priv)) {
-		IWL_WARN(priv, "request scan called when driver not ready.\n");
-		goto done;
-	}
-
-	/* Make sure the scan wasn't canceled before this queued work
-	 * was given the chance to run... */
-	if (!test_bit(STATUS_SCANNING, &priv->status))
-		goto done;
-
-	/* This should never be called or scheduled if there is currently
-	 * a scan active in the hardware. */
-	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Multiple concurrent scan requests  "
-				"Ignoring second request.\n");
-		goto done;
-	}
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
-		goto done;
-	}
-
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC(priv,
-			"Scan request while abort pending. Queuing.\n");
-		goto done;
-	}
-
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
-		goto done;
-	}
-
-	if (!test_bit(STATUS_READY, &priv->status)) {
-		IWL_DEBUG_HC(priv,
-			"Scan request while uninitialized. Queuing.\n");
-		goto done;
-	}
+	lockdep_assert_held(&priv->mutex);
 
 	if (!priv->scan_cmd) {
 		priv->scan_cmd = kmalloc(sizeof(struct iwl3945_scan_cmd) +
 					 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
 		if (!priv->scan_cmd) {
 			IWL_DEBUG_SCAN(priv, "Fail to allocate scan memory\n");
-			goto done;
+			return -ENOMEM;
 		}
 	}
 	scan = priv->scan_cmd;
@@ -2971,7 +2932,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 		break;
 	default:
 		IWL_WARN(priv, "Invalid scan band\n");
-		goto done;
+		return -EIO;
 	}
 
 	if (!priv->is_internal_short_scan) {
@@ -3006,7 +2967,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 
 	if (scan->channel_count == 0) {
 		IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
-		goto done;
+		return -EIO;
 	}
 
 	cmd.len += le16_to_cpu(scan->tx_cmd.len) +
@@ -3015,25 +2976,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
 	scan->len = cpu_to_le16(cmd.len);
 
 	set_bit(STATUS_SCAN_HW, &priv->status);
-	if (iwl_send_cmd_sync(priv, &cmd))
-		goto done;
-
-	queue_delayed_work(priv->workqueue, &priv->scan_check,
-			   IWL_SCAN_CHECK_WATCHDOG);
-
-	return;
-
- done:
-	/* can not perform scan make sure we clear scanning
-	 * bits from status so next scan request can be performed.
-	 * if we dont clear scanning status bit here all next scan
-	 * will fail
-	*/
-	clear_bit(STATUS_SCAN_HW, &priv->status);
-	clear_bit(STATUS_SCANNING, &priv->status);
-
-	/* inform mac80211 scan aborted */
-	queue_work(priv->workqueue, &priv->scan_completed);
+	ret = iwl_send_cmd_sync(priv, &cmd);
+	if (ret)
+		clear_bit(STATUS_SCAN_HW, &priv->status);
+	return ret;
 }
 
 static void iwl3945_bg_restart(struct work_struct *data)
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/14] iwlwifi: move scan completed flags handling
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 01/14] iwlwifi: remove unused conf variables Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 02/14] iwlwifi: unify scan start checks Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 04/14] iwlwifi: cancel scan when down the device Stanislaw Gruszka
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Move the scan completed flags handling so that we
can notify mac80211 about aborted scans with the
correct status. Also queue the scan_completed work
before the BT status update so that it won't see
the bits still set (unless a new scan was started
in which case that's fine.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   30 ++++++++++++++----------------
 1 files changed, 14 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 6bd14bc..22bdc98 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -222,21 +222,11 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
 		       jiffies_to_msecs(elapsed_jiffies
 					(priv->scan_start, jiffies)));
 
-	/*
-	 * If a request to abort was given, or the scan did not succeed
-	 * then we reset the scan state machine and terminate,
-	 * re-queuing another scan if one has been requested
-	 */
-	if (test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status))
-		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
-
-	IWL_DEBUG_INFO(priv, "Setting scan to off\n");
-
-	clear_bit(STATUS_SCANNING, &priv->status);
+	queue_work(priv->workqueue, &priv->scan_completed);
 
 	if (priv->iw_mode != NL80211_IFTYPE_ADHOC &&
-	    priv->cfg->advanced_bt_coexist && priv->bt_status !=
-	    scan_notif->bt_status) {
+	    priv->cfg->advanced_bt_coexist &&
+	    priv->bt_status != scan_notif->bt_status) {
 		if (scan_notif->bt_status) {
 			/* BT on */
 			if (!priv->bt_ch_announce)
@@ -254,7 +244,6 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
 		priv->bt_status = scan_notif->bt_status;
 		queue_work(priv->workqueue, &priv->bt_traffic_change_work);
 	}
-	queue_work(priv->workqueue, &priv->scan_completed);
 }
 
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
@@ -554,7 +543,7 @@ 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;
+	bool internal = false, aborted;
 	struct iwl_rxon_context *ctx;
 
 	IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
@@ -562,6 +551,15 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	cancel_delayed_work(&priv->scan_check);
 
 	mutex_lock(&priv->mutex);
+
+	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+	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");
@@ -569,7 +567,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	} else if (priv->scan_request) {
 		priv->scan_request = NULL;
 		priv->scan_vif = NULL;
-		ieee80211_scan_completed(priv->hw, false);
+		ieee80211_scan_completed(priv->hw, aborted);
 	}
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/14] iwlwifi: cancel scan when down the device
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (2 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 03/14] iwlwifi: move scan completed flags handling Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 05/14] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Always cancel scan when stooping device and scan is currently pending,
we should newer have scan running after down device.

To assure we start scan cancel from restart work we have to schedule
abort_scan to different workqueue than priv->workqueue.

Patch fix not cancel scanning when restarting firmware, what is
one of the causes of wdev_cleanup_work warning (together with permanent
network connection lost) reported at
https://bugzilla.redhat.com/show_bug.cgi?id=593566

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |   14 +++-----------
 drivers/net/wireless/iwlwifi/iwl-scan.c     |    2 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c |   16 ++++------------
 3 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c8a2ec8..25b3540 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2891,8 +2891,9 @@ static void __iwl_down(struct iwl_priv *priv)
 
 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
-	if (!exit_pending)
-		set_bit(STATUS_EXIT_PENDING, &priv->status);
+	iwl_scan_cancel_timeout(priv, 200);
+
+	exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
 
 	/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
 	 * to prevent rearm timer */
@@ -3502,15 +3503,6 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
 
 	priv->is_open = 0;
 
-	if (iwl_is_ready_rf(priv) || test_bit(STATUS_SCAN_HW, &priv->status)) {
-		/* stop mac, cancel any scan request and clear
-		 * RXON_FILTER_ASSOC_MSK BIT
-		 */
-		mutex_lock(&priv->mutex);
-		iwl_scan_cancel_timeout(priv, 100);
-		mutex_unlock(&priv->mutex);
-	}
-
 	iwl_down(priv);
 
 	flush_workqueue(priv->workqueue);
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 22bdc98..ea33849 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -71,7 +71,7 @@ int iwl_scan_cancel(struct iwl_priv *priv)
 	if (test_bit(STATUS_SCANNING, &priv->status)) {
 		if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
 			IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
-			queue_work(priv->workqueue, &priv->abort_scan);
+			schedule_work(&priv->abort_scan);
 
 		} else
 			IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 3b3686b..fb894d8 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2568,12 +2568,13 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv);
 static void __iwl3945_down(struct iwl_priv *priv)
 {
 	unsigned long flags;
-	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+	int exit_pending;
 
 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
-	if (!exit_pending)
-		set_bit(STATUS_EXIT_PENDING, &priv->status);
+	iwl_scan_cancel_timeout(priv, 200);
+
+	exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
 
 	/* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
 	 * to prevent rearm timer */
@@ -3173,15 +3174,6 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
 
 	priv->is_open = 0;
 
-	if (iwl_is_ready_rf(priv)) {
-		/* stop mac, cancel any scan request and clear
-		 * RXON_FILTER_ASSOC_MSK BIT
-		 */
-		mutex_lock(&priv->mutex);
-		iwl_scan_cancel_timeout(priv, 100);
-		mutex_unlock(&priv->mutex);
-	}
-
 	iwl3945_down(priv);
 
 	flush_workqueue(priv->workqueue);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/14] iwlwifi: report scan completion when abort fail
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (3 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 04/14] iwlwifi: cancel scan when down the device Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 06/14] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

When we are not able to send abort command to firmware, notify mac80211
that we complete scan, as we will newer do it lately. Check for all
possible errors that low level sending command procedure does not check,
to assure we catch all failures cases.

Patch fix one of the causes of wdev_cleanup_work warning reported at
https://bugzilla.redhat.com/show_bug.cgi?id=593566

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |  131 ++++++++++++++++---------------
 1 files changed, 67 insertions(+), 64 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index ea33849..dbb07e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -54,34 +54,83 @@
 #define IWL_PASSIVE_DWELL_BASE      (100)
 #define IWL_CHANNEL_TUNE_TIME       5
 
+static int iwl_send_scan_abort(struct iwl_priv *priv)
+{
+	int ret;
+	struct iwl_rx_packet *pkt;
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_SCAN_ABORT_CMD,
+		.flags = CMD_WANT_SKB,
+	};
 
+	/* Exit instantly with error when device is not ready
+	 * to receive scan abort command or it does not perform
+	 * hardware scan currently */
+	if (!test_bit(STATUS_READY, &priv->status) ||
+	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status) ||
+	    !test_bit(STATUS_SCAN_HW, &priv->status) ||
+	    test_bit(STATUS_FW_ERROR, &priv->status) ||
+	    test_bit(STATUS_EXIT_PENDING, &priv->status))
+		return -EIO;
 
-/**
- * iwl_scan_cancel - Cancel any currently executing HW scan
- *
- * NOTE: priv->mutex is not required before calling this function
- */
-int iwl_scan_cancel(struct iwl_priv *priv)
-{
-	if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
-		clear_bit(STATUS_SCANNING, &priv->status);
-		return 0;
+	ret = iwl_send_cmd_sync(priv, &cmd);
+	if (ret)
+		return ret;
+
+	pkt = (struct iwl_rx_packet *)cmd.reply_page;
+	if (pkt->u.status != CAN_ABORT_STATUS) {
+		/* The scan abort will return 1 for success or
+		 * 2 for "failure".  A failure condition can be
+		 * due to simply not being in an active scan which
+		 * can occur if we send the scan abort before we
+		 * the microcode has notified us that a scan is
+		 * completed. */
+		IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+		ret = -EIO;
 	}
 
-	if (test_bit(STATUS_SCANNING, &priv->status)) {
-		if (!test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-			IWL_DEBUG_SCAN(priv, "Queuing scan abort.\n");
-			schedule_work(&priv->abort_scan);
+	iwl_free_pages(priv, cmd.reply_page);
+	return ret;
+}
 
-		} else
-			IWL_DEBUG_SCAN(priv, "Scan abort already in progress.\n");
+static void iwl_do_scan_abort(struct iwl_priv *priv)
+{
+	int ret;
 
-		return test_bit(STATUS_SCANNING, &priv->status);
+	lockdep_assert_held(&priv->mutex);
+
+	if (!test_bit(STATUS_SCANNING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Not performing scan to abort\n");
+		return;
 	}
 
+	if (test_and_set_bit(STATUS_SCAN_ABORTING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Scan abort in progress\n");
+		return;
+	}
+
+	ret = iwl_send_scan_abort(priv);
+	if (ret) {
+		IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret);
+		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);
+	} else
+		IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
+}
+
+/**
+ * iwl_scan_cancel - Cancel any currently executing HW scan
+ */
+int iwl_scan_cancel(struct iwl_priv *priv)
+{
+	IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
+	schedule_work(&priv->abort_scan);
 	return 0;
 }
 EXPORT_SYMBOL(iwl_scan_cancel);
+
 /**
  * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
  * @ms: amount of time to wait (in milliseconds) for scan to abort
@@ -108,47 +157,6 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
-static int iwl_send_scan_abort(struct iwl_priv *priv)
-{
-	int ret = 0;
-	struct iwl_rx_packet *pkt;
-	struct iwl_host_cmd cmd = {
-		.id = REPLY_SCAN_ABORT_CMD,
-		.flags = CMD_WANT_SKB,
-	};
-
-	/* If there isn't a scan actively going on in the hardware
-	 * then we are in between scan bands and not actually
-	 * actively scanning, so don't send the abort command */
-	if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		return 0;
-	}
-
-	ret = iwl_send_cmd_sync(priv, &cmd);
-	if (ret) {
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		return ret;
-	}
-
-	pkt = (struct iwl_rx_packet *)cmd.reply_page;
-	if (pkt->u.status != CAN_ABORT_STATUS) {
-		/* The scan abort will return 1 for success or
-		 * 2 for "failure".  A failure condition can be
-		 * due to simply not being in an active scan which
-		 * can occur if we send the scan abort before we
-		 * the microcode has notified us that a scan is
-		 * completed. */
-		IWL_DEBUG_INFO(priv, "SCAN_ABORT returned %d.\n", pkt->u.status);
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		clear_bit(STATUS_SCAN_HW, &priv->status);
-	}
-
-	iwl_free_pages(priv, cmd.reply_page);
-
-	return ret;
-}
-
 /* Service response to REPLY_SCAN_CMD (0x80) */
 static void iwl_rx_reply_scan(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb)
@@ -527,15 +535,10 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
-	if (!test_bit(STATUS_READY, &priv->status) ||
-	    !test_bit(STATUS_GEO_CONFIGURED, &priv->status))
-		return;
-
 	cancel_delayed_work(&priv->scan_check);
 
 	mutex_lock(&priv->mutex);
-	if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
-		iwl_send_scan_abort(priv);
+	iwl_do_scan_abort(priv);
 	mutex_unlock(&priv->mutex);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/14] iwlwifi: rework iwl_scan_cancel_timeout
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (4 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 05/14] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 07/14] iwlwifi: rewrite scan completion Stanislaw Gruszka
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Since on timeout version of iwl_scan_cancel procedure we can sleep,
do not have to schedule abort_scan work to begin and perform scanning,
can do this directly. Also now, as we do not queue abort_scan from
restart work anymore, we can queue abort_scan to priv->workqueue.

Don't drop mutex when waiting for scan complete. Use STATUS_HW_SCAN bit
to check if scanning is currently pending, because STATUS_SCANNING will
be cleared only with priv->mutex taken.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   25 ++++++++++++-------------
 1 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index dbb07e8..6d02f41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -126,7 +126,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 int iwl_scan_cancel(struct iwl_priv *priv)
 {
 	IWL_DEBUG_SCAN(priv, "Queuing abort scan\n");
-	schedule_work(&priv->abort_scan);
+	queue_work(priv->workqueue, &priv->abort_scan);
 	return 0;
 }
 EXPORT_SYMBOL(iwl_scan_cancel);
@@ -135,25 +135,24 @@ EXPORT_SYMBOL(iwl_scan_cancel);
  * iwl_scan_cancel_timeout - Cancel any currently executing HW scan
  * @ms: amount of time to wait (in milliseconds) for scan to abort
  *
- * NOTE: priv->mutex must be held before calling this function
  */
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 {
-	unsigned long now = jiffies;
-	int ret;
+	unsigned long timeout = jiffies + msecs_to_jiffies(ms);
+
+	lockdep_assert_held(&priv->mutex);
 
-	ret = iwl_scan_cancel(priv);
-	if (ret && ms) {
-		mutex_unlock(&priv->mutex);
-		while (!time_after(jiffies, now + msecs_to_jiffies(ms)) &&
-				test_bit(STATUS_SCANNING, &priv->status))
-			msleep(1);
-		mutex_lock(&priv->mutex);
+	IWL_DEBUG_SCAN(priv, "Scan cancel timeout\n");
 
-		return test_bit(STATUS_SCANNING, &priv->status);
+	iwl_do_scan_abort(priv);
+
+	while (time_before_eq(jiffies, timeout)) {
+		if (!test_bit(STATUS_SCAN_HW, &priv->status))
+			break;
+		msleep(20);
 	}
 
-	return ret;
+	return test_bit(STATUS_SCAN_HW, &priv->status);
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/14] iwlwifi: rewrite scan completion
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (5 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 06/14] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 08/14] iwlwifi: force scan complete after timeout Stanislaw Gruszka
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

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>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   65 +++++++++++++++++++------------
 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 6d02f41..e65a98d 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);
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/14] iwlwifi: force scan complete after timeout
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (6 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 07/14] iwlwifi: rewrite scan completion Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

If we do not get notification from hardware about scan complete, after
timeout do mac80211 scan completion anyway. This assure we end scan
in case of firmware hung.

Patch fix one of the causes of wdev_cleanup_work warning reported at
https://bugzilla.redhat.com/show_bug.cgi?id=593566

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-core.c |   15 +++------------
 drivers/net/wireless/iwlwifi/iwl-scan.c |   20 +++++++++++++++-----
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 87a2e40..7c1819f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2041,7 +2041,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 {
 	struct iwl_priv *priv = hw->priv;
 	struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
-	bool scan_completed = false;
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
@@ -2050,15 +2049,10 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 	WARN_ON(ctx->vif != vif);
 	ctx->vif = NULL;
 
-	iwl_scan_cancel_timeout(priv, 100);
+	if (priv->scan_vif == vif)
+		iwl_scan_cancel_timeout(priv, 100);
 	iwl_set_mode(priv, vif);
 
-	if (priv->scan_vif == vif) {
-		scan_completed = true;
-		priv->scan_vif = NULL;
-		priv->scan_request = NULL;
-	}
-
 	/*
 	 * When removing the IBSS interface, overwrite the
 	 * BT traffic load with the stored one from the last
@@ -2072,9 +2066,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 	memset(priv->bssid, 0, ETH_ALEN);
 	mutex_unlock(&priv->mutex);
 
-	if (scan_completed)
-		ieee80211_scan_completed(priv->hw, true);
-
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 
 }
@@ -2255,6 +2246,7 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
+	iwl_scan_cancel_timeout(priv, 100);
 	if (!iwl_is_ready_rf(priv)) {
 		IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
 		mutex_unlock(&priv->mutex);
@@ -2264,7 +2256,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 	/* we are restarting association process
 	 * clear RXON_FILTER_ASSOC_MSK bit
 	 */
-	iwl_scan_cancel_timeout(priv, 100);
 	ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	iwlcore_commit_rxon(priv, ctx);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e65a98d..ce605e0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -106,6 +106,15 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
 	priv->scan_request = NULL;
 }
 
+static void iwl_force_scan_end(struct iwl_priv *priv)
+{
+	IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
+	clear_bit(STATUS_SCANNING, &priv->status);
+	clear_bit(STATUS_SCAN_HW, &priv->status);
+	clear_bit(STATUS_SCAN_ABORTING, &priv->status);
+	iwl_complete_scan(priv, true);
+}
+
 static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
 	int ret;
@@ -125,10 +134,7 @@ static void iwl_do_scan_abort(struct iwl_priv *priv)
 	ret = iwl_send_scan_abort(priv);
 	if (ret) {
 		IWL_DEBUG_SCAN(priv, "Send scan abort failed %d\n", ret);
-		clear_bit(STATUS_SCANNING, &priv->status);
-		clear_bit(STATUS_SCAN_HW, &priv->status);
-		clear_bit(STATUS_SCAN_ABORTING, &priv->status);
-		iwl_complete_scan(priv, true);
+		iwl_force_scan_end(priv);
 	} else
 		IWL_DEBUG_SCAN(priv, "Sucessfully send scan abort\n");
 }
@@ -151,6 +157,7 @@ EXPORT_SYMBOL(iwl_scan_cancel);
  */
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 {
+	int ret;
 	unsigned long timeout = jiffies + msecs_to_jiffies(ms);
 
 	lockdep_assert_held(&priv->mutex);
@@ -165,7 +172,10 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 		msleep(20);
 	}
 
-	return test_bit(STATUS_SCAN_HW, &priv->status);
+	ret = test_bit(STATUS_SCAN_HW, &priv->status);
+	if (ret)
+		iwl_force_scan_end(priv);
+	return ret;
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (7 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 08/14] iwlwifi: force scan complete after timeout Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 14:07   ` Guy, Wey-Yi
  2010-09-13 12:46 ` [PATCH 10/14] iwlwifi: do not force complete scan too early Stanislaw Gruszka
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Assure we complete scan in mac80211 when we abort scanning (scan_abort
work) or scan timeout occurs (scan_check work). Currently
iwl_scan_cancel_timeout() procedure force scan finish in mac80211
at the end of timeout loop, so we can use it in proper work functions.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   14 ++------------
 1 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index ce605e0..da037b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -490,18 +490,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, scan_check.work);
 
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
 	mutex_lock(&priv->mutex);
-	if (test_bit(STATUS_SCANNING, &priv->status) &&
-	    !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
-			       jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
-		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-			iwl_send_scan_abort(priv);
-	}
+	iwl_scan_cancel_timeout(priv, 200);
 	mutex_unlock(&priv->mutex);
 }
 
@@ -560,7 +550,7 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 	cancel_delayed_work(&priv->scan_check);
 
 	mutex_lock(&priv->mutex);
-	iwl_do_scan_abort(priv);
+	iwl_scan_cancel_timeout(priv, 200);
 	mutex_unlock(&priv->mutex);
 }
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/14] iwlwifi: do not force complete scan too early
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (8 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 11/14] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Currently we force scan complete at the end of iwl_scan_cancel_timeout
function. This cause race condition when we can get a new scan request
from mac80211 and complete it by iwl_bg_complete from older scan. Change
code to force scan complete only when really needed: device goes down,
interface is removed or scan timeout occurs.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-agn.c      |    6 +++-
 drivers/net/wireless/iwlwifi/iwl-core.c     |    6 +++-
 drivers/net/wireless/iwlwifi/iwl-core.h     |    2 +
 drivers/net/wireless/iwlwifi/iwl-scan.c     |   38 ++++++++++++++++++++------
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    4 +-
 5 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 25b3540..4f31f36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4070,13 +4070,15 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 		priv->cfg->ops->lib->cancel_deferred_work(priv);
 
 	cancel_delayed_work_sync(&priv->init_alive_start);
-	cancel_delayed_work(&priv->scan_check);
-	cancel_work_sync(&priv->start_internal_scan);
 	cancel_delayed_work(&priv->alive_start);
 	cancel_work_sync(&priv->run_time_calib_work);
 	cancel_work_sync(&priv->beacon_update);
+
+	iwl_cancel_scan_deferred_work(priv);
+
 	cancel_work_sync(&priv->bt_full_concurrency);
 	cancel_work_sync(&priv->bt_runtime_config);
+
 	del_timer_sync(&priv->statistics_periodic);
 	del_timer_sync(&priv->ucode_trace);
 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 7c1819f..57d157f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2049,8 +2049,10 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
 	WARN_ON(ctx->vif != vif);
 	ctx->vif = NULL;
 
-	if (priv->scan_vif == vif)
-		iwl_scan_cancel_timeout(priv, 100);
+	if (priv->scan_vif == vif) {
+		iwl_scan_cancel_timeout(priv, 200);
+		iwl_force_scan_end(priv);
+	}
 	iwl_set_mode(priv, vif);
 
 	/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 8dab074..f1d40c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -553,6 +553,7 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
 void iwl_init_scan_params(struct iwl_priv *priv);
 int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
+void iwl_force_scan_end(struct iwl_priv *priv);
 int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 		    struct ieee80211_vif *vif,
 		    struct cfg80211_scan_request *req);
@@ -568,6 +569,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
 			       enum ieee80211_band band,
 			       struct ieee80211_vif *vif);
 void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv);
 
 /* For faster active scanning, scan will move to the next channel if fewer than
  * PLCP_QUIET_THRESH packets are heard on this channel within
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index da037b2..af9a836 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -106,14 +106,22 @@ static void iwl_complete_scan(struct iwl_priv *priv, bool aborted)
 	priv->scan_request = NULL;
 }
 
-static void iwl_force_scan_end(struct iwl_priv *priv)
+void iwl_force_scan_end(struct iwl_priv *priv)
 {
+	lockdep_assert_held(&priv->mutex);
+
+	if (!test_bit(STATUS_SCANNING, &priv->status)) {
+		IWL_DEBUG_SCAN(priv, "Forcing scan end while not scanning\n");
+		return;
+	}
+
 	IWL_DEBUG_SCAN(priv, "Forcing scan end\n");
 	clear_bit(STATUS_SCANNING, &priv->status);
 	clear_bit(STATUS_SCAN_HW, &priv->status);
 	clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 	iwl_complete_scan(priv, true);
 }
+EXPORT_SYMBOL(iwl_force_scan_end);
 
 static void iwl_do_scan_abort(struct iwl_priv *priv)
 {
@@ -157,7 +165,6 @@ EXPORT_SYMBOL(iwl_scan_cancel);
  */
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 {
-	int ret;
 	unsigned long timeout = jiffies + msecs_to_jiffies(ms);
 
 	lockdep_assert_held(&priv->mutex);
@@ -172,10 +179,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
 		msleep(20);
 	}
 
-	ret = test_bit(STATUS_SCAN_HW, &priv->status);
-	if (ret)
-		iwl_force_scan_end(priv);
-	return ret;
+	return test_bit(STATUS_SCAN_HW, &priv->status);
 }
 EXPORT_SYMBOL(iwl_scan_cancel_timeout);
 
@@ -490,8 +494,11 @@ static void iwl_bg_scan_check(struct work_struct *data)
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, scan_check.work);
 
+	/* Since we are here firmware does not finish scan and
+	 * most likely is in bad shape, so we don't bother to
+	 * send abort command, just force scan complete to mac80211 */
 	mutex_lock(&priv->mutex);
-	iwl_scan_cancel_timeout(priv, 200);
+	iwl_force_scan_end(priv);
 	mutex_unlock(&priv->mutex);
 }
 
@@ -547,8 +554,8 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
-	cancel_delayed_work(&priv->scan_check);
-
+	/* We keep scan_check work queued in case when firmware will not
+	 * report back scan completed notification */
 	mutex_lock(&priv->mutex);
 	iwl_scan_cancel_timeout(priv, 200);
 	mutex_unlock(&priv->mutex);
@@ -631,3 +638,16 @@ void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_setup_scan_deferred_work);
 
+void iwl_cancel_scan_deferred_work(struct iwl_priv *priv)
+{
+	cancel_work_sync(&priv->start_internal_scan);
+	cancel_work_sync(&priv->abort_scan);
+	cancel_work_sync(&priv->scan_completed);
+
+	if (cancel_delayed_work_sync(&priv->scan_check)) {
+		mutex_lock(&priv->mutex);
+		iwl_force_scan_end(priv);
+		mutex_unlock(&priv->mutex);
+	}
+}
+EXPORT_SYMBOL(iwl_cancel_scan_deferred_work);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index fb894d8..6b8f654 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3763,10 +3763,10 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
 	iwl3945_hw_cancel_deferred_work(priv);
 
 	cancel_delayed_work_sync(&priv->init_alive_start);
-	cancel_delayed_work(&priv->scan_check);
 	cancel_delayed_work(&priv->alive_start);
-	cancel_work_sync(&priv->start_internal_scan);
 	cancel_work_sync(&priv->beacon_update);
+
+	iwl_cancel_scan_deferred_work(priv);
 }
 
 static struct attribute *iwl3945_sysfs_entries[] = {
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 11/14] mac80211: wait for scan work complete before restarting hw
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (9 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 10/14] iwlwifi: do not force complete scan too early Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 12/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

This is needed to avoid warning in ieee80211_restart_hw about hardware
scan in progress.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 net/mac80211/main.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 4935b84..bf0eb6a 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -305,6 +305,9 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw)
 
 	trace_api_restart_hw(local);
 
+	/* wait for scan work complete */
+	flush_workqueue(local->workqueue);
+
 	WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
 		"%s called with hardware scan in progress\n", __func__);
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 12/14] iwlwifi: cleanup scan initiate check
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (10 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 11/14] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 12:46 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Remove redundant checks and use iwl_is_ready_rf().

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   17 +----------------
 1 files changed, 1 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index af9a836..26dd8f3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -361,7 +361,7 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 
 	cancel_delayed_work(&priv->scan_check);
 
-	if (!iwl_is_ready(priv)) {
+	if (!iwl_is_ready_rf(priv)) {
 		IWL_WARN(priv, "request scan called when driver not ready.\n");
 		return -EIO;
 	}
@@ -372,26 +372,11 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 		return -EBUSY;
 	}
 
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG_SCAN(priv, "Aborting scan due to device shutdown\n");
-		return -EIO;
-	}
-
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
 		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
 		return -EBUSY;
 	}
 
-	if (iwl_is_rfkill(priv)) {
-		IWL_DEBUG_HC(priv, "Aborting scan due to RF Kill activation\n");
-		return -EIO;
-	}
-
-	if (!test_bit(STATUS_READY, &priv->status)) {
-		IWL_DEBUG_HC(priv, "Scan request while uninitialized.\n");
-		return -EBUSY;
-	}
-
 	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
 			internal ? "internal short " : "");
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (11 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 12/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 14:07   ` Guy, Wey-Yi
  2010-09-13 12:46 ` [PATCH 14/14] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
  2010-09-13 14:08 ` [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi
  14 siblings, 1 reply; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Replace IWL_DEBUG_{INFO,HC,RC} to IWL_DEBUG_SCAN in iwl-scan.c file. Add
some more IWL_DEBUG_SCAN messages. This will allow to fully debug
scanning using only IWL_DL_SCAN flag.

Also start one message sentence with capital letter, since that
convention in iwl-scan.c file.
  
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   31 +++++++++++++++++++------------
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 26dd8f3..65b7cb4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -85,7 +85,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
 		 * can occur if we send the scan abort before we
 		 * the microcode has notified us that a scan is
 		 * completed. */
-		IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+		IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
 		ret = -EIO;
 	}
 
@@ -192,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
 	struct iwl_scanreq_notification *notif =
 	    (struct iwl_scanreq_notification *)pkt->u.raw;
 
-	IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
+	IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
 }
 
@@ -251,7 +251,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
 	/* The HW is no longer scanning */
 	clear_bit(STATUS_SCAN_HW, &priv->status);
 
-	IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
+	IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
 		       (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
 		       jiffies_to_msecs(elapsed_jiffies
 					(priv->scan_start, jiffies)));
@@ -362,22 +362,22 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 	cancel_delayed_work(&priv->scan_check);
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_WARN(priv, "request scan called when driver not ready.\n");
+		IWL_WARN(priv, "Request scan called when driver not ready.\n");
 		return -EIO;
 	}
 
 	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO(priv,
+		IWL_DEBUG_SCAN(priv,
 			"Multiple concurrent scan requests in parallel.\n");
 		return -EBUSY;
 	}
 
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
+		IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
 		return -EBUSY;
 	}
 
-	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
+	IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
 			internal ? "internal short " : "");
 
 	set_bit(STATUS_SCANNING, &priv->status);
@@ -427,9 +427,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 	 * If an internal scan is in progress, just set
 	 * up the scan_request as per above.
 	 */
-	if (priv->is_internal_short_scan)
+	if (priv->is_internal_short_scan) {
+		IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
 		ret = 0;
-	else
+	} else
 		ret = iwl_scan_initiate(priv, vif, false,
 					req->channels[0]->band);
 
@@ -456,6 +457,8 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
 	struct iwl_priv *priv =
 		container_of(work, struct iwl_priv, start_internal_scan);
 
+	IWL_DEBUG_SCAN(priv, "Start internal scan\n");
+
 	mutex_lock(&priv->mutex);
 
 	if (priv->is_internal_short_scan == true) {
@@ -479,6 +482,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, scan_check.work);
 
+	IWL_DEBUG_SCAN(priv, "Scan check work\n");
+
 	/* Since we are here firmware does not finish scan and
 	 * most likely is in bad shape, so we don't bother to
 	 * send abort command, just force scan complete to mac80211 */
@@ -539,6 +544,8 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
+	IWL_DEBUG_SCAN(priv, "Abort scan work\n");
+
 	/* We keep scan_check work queued in case when firmware will not
 	 * report back scan completed notification */
 	mutex_lock(&priv->mutex);
@@ -553,7 +560,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	bool aborted;
 	struct iwl_rxon_context *ctx;
 
-	IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
+	IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
 		       priv->is_internal_short_scan ? "internal short " : "");
 
 	cancel_delayed_work(&priv->scan_check);
@@ -562,10 +569,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 
 	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 	if (aborted)
-		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
+		IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
 
 	if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Scan already completed.\n");
+		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
 		goto out;
 	}
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 14/14] iwlwifi: apply settings when finishing scan
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (12 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
@ 2010-09-13 12:46 ` Stanislaw Gruszka
  2010-09-13 14:08 ` [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi
  14 siblings, 0 replies; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-13 12:46 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Even is someone else complete scanning in mac80211, apply rxon and
tx power settings if gets scan complete notification from hardware.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi W Guy <wey-yi.w.guy@intel.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 65b7cb4..599573f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -573,7 +573,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 
 	if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
 		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
-		goto out;
+		goto out_settings;
 	}
 
 	if (priv->is_internal_short_scan && !aborted) {
@@ -599,6 +599,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 out_complete:
 	iwl_complete_scan(priv, aborted);
 
+out_settings:
 	/* Can we still talk to firmware ? */
 	if (!iwl_is_ready_rf(priv))
 		goto out;
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works
  2010-09-13 12:46 ` [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
@ 2010-09-13 14:07   ` Guy, Wey-Yi
  0 siblings, 0 replies; 20+ messages in thread
From: Guy, Wey-Yi @ 2010-09-13 14:07 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville, linux-wireless

On Mon, 2010-09-13 at 05:46 -0700, Stanislaw Gruszka wrote:
> Assure we complete scan in mac80211 when we abort scanning (scan_abort
> work) or scan timeout occurs (scan_check work). Currently
> iwl_scan_cancel_timeout() procedure force scan finish in mac80211
> at the end of timeout loop, so we can use it in proper work functions.
> 
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
>  drivers/net/wireless/iwlwifi/iwl-scan.c |   14 ++------------
>  1 files changed, 2 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
> index ce605e0..da037b2 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-scan.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
> @@ -490,18 +490,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
>  	struct iwl_priv *priv =
>  	    container_of(data, struct iwl_priv, scan_check.work);
>  
> -	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
> -		return;
> -
>  	mutex_lock(&priv->mutex);
> -	if (test_bit(STATUS_SCANNING, &priv->status) &&
> -	    !test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
> -		IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
> -			       jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
> -
> -		if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
> -			iwl_send_scan_abort(priv);
> -	}
> +	iwl_scan_cancel_timeout(priv, 200);
>  	mutex_unlock(&priv->mutex);
>  }
>  
> @@ -560,7 +550,7 @@ static void iwl_bg_abort_scan(struct work_struct *work)
>  	cancel_delayed_work(&priv->scan_check);
>  
>  	mutex_lock(&priv->mutex);
> -	iwl_do_scan_abort(priv);
> +	iwl_scan_cancel_timeout(priv, 200);
>  	mutex_unlock(&priv->mutex);
>  }
>  


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning
  2010-09-13 12:46 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
@ 2010-09-13 14:07   ` Guy, Wey-Yi
  0 siblings, 0 replies; 20+ messages in thread
From: Guy, Wey-Yi @ 2010-09-13 14:07 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville, linux-wireless

On Mon, 2010-09-13 at 05:46 -0700, Stanislaw Gruszka wrote:
> Replace IWL_DEBUG_{INFO,HC,RC} to IWL_DEBUG_SCAN in iwl-scan.c file. Add
> some more IWL_DEBUG_SCAN messages. This will allow to fully debug
> scanning using only IWL_DL_SCAN flag.
> 
> Also start one message sentence with capital letter, since that
> convention in iwl-scan.c file.
>   
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
> ---
>  drivers/net/wireless/iwlwifi/iwl-scan.c |   31 +++++++++++++++++++------------
>  1 files changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
> index 26dd8f3..65b7cb4 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-scan.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
> @@ -85,7 +85,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
>  		 * can occur if we send the scan abort before we
>  		 * the microcode has notified us that a scan is
>  		 * completed. */
> -		IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
> +		IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
>  		ret = -EIO;
>  	}
>  
> @@ -192,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
>  	struct iwl_scanreq_notification *notif =
>  	    (struct iwl_scanreq_notification *)pkt->u.raw;
>  
> -	IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
> +	IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
>  #endif
>  }
>  
> @@ -251,7 +251,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
>  	/* The HW is no longer scanning */
>  	clear_bit(STATUS_SCAN_HW, &priv->status);
>  
> -	IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
> +	IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
>  		       (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
>  		       jiffies_to_msecs(elapsed_jiffies
>  					(priv->scan_start, jiffies)));
> @@ -362,22 +362,22 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
>  	cancel_delayed_work(&priv->scan_check);
>  
>  	if (!iwl_is_ready_rf(priv)) {
> -		IWL_WARN(priv, "request scan called when driver not ready.\n");
> +		IWL_WARN(priv, "Request scan called when driver not ready.\n");
>  		return -EIO;
>  	}
>  
>  	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
> -		IWL_DEBUG_INFO(priv,
> +		IWL_DEBUG_SCAN(priv,
>  			"Multiple concurrent scan requests in parallel.\n");
>  		return -EBUSY;
>  	}
>  
>  	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
> -		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
> +		IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
>  		return -EBUSY;
>  	}
>  
> -	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
> +	IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
>  			internal ? "internal short " : "");
>  
>  	set_bit(STATUS_SCANNING, &priv->status);
> @@ -427,9 +427,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
>  	 * If an internal scan is in progress, just set
>  	 * up the scan_request as per above.
>  	 */
> -	if (priv->is_internal_short_scan)
> +	if (priv->is_internal_short_scan) {
> +		IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
>  		ret = 0;
> -	else
> +	} else
>  		ret = iwl_scan_initiate(priv, vif, false,
>  					req->channels[0]->band);
>  
> @@ -456,6 +457,8 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
>  	struct iwl_priv *priv =
>  		container_of(work, struct iwl_priv, start_internal_scan);
>  
> +	IWL_DEBUG_SCAN(priv, "Start internal scan\n");
> +
>  	mutex_lock(&priv->mutex);
>  
>  	if (priv->is_internal_short_scan == true) {
> @@ -479,6 +482,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
>  	struct iwl_priv *priv =
>  	    container_of(data, struct iwl_priv, scan_check.work);
>  
> +	IWL_DEBUG_SCAN(priv, "Scan check work\n");
> +
>  	/* Since we are here firmware does not finish scan and
>  	 * most likely is in bad shape, so we don't bother to
>  	 * send abort command, just force scan complete to mac80211 */
> @@ -539,6 +544,8 @@ static void iwl_bg_abort_scan(struct work_struct *work)
>  {
>  	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
>  
> +	IWL_DEBUG_SCAN(priv, "Abort scan work\n");
> +
>  	/* We keep scan_check work queued in case when firmware will not
>  	 * report back scan completed notification */
>  	mutex_lock(&priv->mutex);
> @@ -553,7 +560,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
>  	bool aborted;
>  	struct iwl_rxon_context *ctx;
>  
> -	IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
> +	IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
>  		       priv->is_internal_short_scan ? "internal short " : "");
>  
>  	cancel_delayed_work(&priv->scan_check);
> @@ -562,10 +569,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
>  
>  	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
>  	if (aborted)
> -		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
> +		IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
>  
>  	if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
> -		IWL_DEBUG_INFO(priv, "Scan already completed.\n");
> +		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
>  		goto out;
>  	}
>  


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (13 preceding siblings ...)
  2010-09-13 12:46 ` [PATCH 14/14] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
@ 2010-09-13 14:08 ` Guy, Wey-Yi
  14 siblings, 0 replies; 20+ messages in thread
From: Guy, Wey-Yi @ 2010-09-13 14:08 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville, linux-wireless

On Mon, 2010-09-13 at 05:46 -0700, Stanislaw Gruszka wrote:
> Avoid iwlwifi hardware scanning race conditions
> that may lead to not call ieee80211_scan_completed() (what in
> consequences gives "WARNING: at net/wireless/core.c:614
> wdev_cleanup_work+0xb7/0xf0"), or call iee80211_scan_completed() more
> then once (what gives " WARNING: at net/mac80211/scan.c:312
> ieee80211_scan_completed+0x5f/0x1f1").
> 
> First problem (warning in wdev_cleanup_work) make any further scan
> request from cfg80211 are ignored by mac80211 with EBUSY error,
> hence NetworkManager can not perform successful scan and not allow
> to establish a new connection. So after suspend/resume (but maybe
> not only then) user is not able to connect to wireless network again.
> 
> We can not rely on that the commands (start and abort scan) are
> successful. Even if they are successfully send to the hardware, we can
> not get back notification from firmware (i.e. firmware hung or was
> reseted), or we can get notification when we actually perform abort
> scan in driver code or after that.
> 
> To assure we call ieee80211_scan_completed() only once when scan
> was started we use SCAN_SCANNING bit. Code path, which first clear
> STATUS_SCANNING bit will call ieee80211_scan_completed().
> We do this in many cases, in scan complete notification, scan
> abort, device down, etc. Each time we check SCANNING bit.
> 
> Tested on 3945, 4965 and 5300 adapters. Tested normal work
> functionality and doing scan stress testing using scripts:
> http://people.redhat.com/sgruszka/misc/test_wifi_scan_reboot.sh
> http://people.redhat.com/sgruszka/misc/test_wifi_scan_updown.sh
> 
> v1 -> v2:
> - fix not cleared STATUS_SCAN_HW bit in patch 2
> - merged patch 7 and 8
> - add 3 new patches
> 
> v2 -> v3:
> - merged patch 5 and 14
> - merged patch 2 and 16
> - add bugzilla reference into 3 most important patches
> - not use cancel_delayed_work_sync in work function (patch 10)
> 
> v3 -> v4:
> - add additional changelog comments in patch 9 and 13 and Wey acks
>   in other patches

Thank you, looks good to me.

Wey


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning
  2010-09-10 14:26 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
@ 2010-09-10 15:56   ` Guy, Wey-Yi
  0 siblings, 0 replies; 20+ messages in thread
From: Guy, Wey-Yi @ 2010-09-10 15:56 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville, linux-wireless

On Fri, 2010-09-10 at 07:26 -0700, Stanislaw Gruszka wrote:
> Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
> ---
>  drivers/net/wireless/iwlwifi/iwl-scan.c |   31 +++++++++++++++++++------------
>  1 files changed, 19 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
> index 26dd8f3..65b7cb4 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-scan.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
> @@ -85,7 +85,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
>  		 * can occur if we send the scan abort before we
>  		 * the microcode has notified us that a scan is
>  		 * completed. */
> -		IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
> +		IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
>  		ret = -EIO;
>  	}
>  
> @@ -192,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
>  	struct iwl_scanreq_notification *notif =
>  	    (struct iwl_scanreq_notification *)pkt->u.raw;
>  
> -	IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
> +	IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
>  #endif
>  }
>  
> @@ -251,7 +251,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
>  	/* The HW is no longer scanning */
>  	clear_bit(STATUS_SCAN_HW, &priv->status);
>  
> -	IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
> +	IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
>  		       (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
>  		       jiffies_to_msecs(elapsed_jiffies
>  					(priv->scan_start, jiffies)));
> @@ -362,22 +362,22 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
>  	cancel_delayed_work(&priv->scan_check);
>  
>  	if (!iwl_is_ready_rf(priv)) {
> -		IWL_WARN(priv, "request scan called when driver not ready.\n");
> +		IWL_WARN(priv, "Request scan called when driver not ready.\n");
>  		return -EIO;
>  	}
>  
>  	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
> -		IWL_DEBUG_INFO(priv,
> +		IWL_DEBUG_SCAN(priv,
>  			"Multiple concurrent scan requests in parallel.\n");
>  		return -EBUSY;
>  	}
>  
>  	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
> -		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
> +		IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
>  		return -EBUSY;
>  	}
>  
> -	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
> +	IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
>  			internal ? "internal short " : "");
>  
>  	set_bit(STATUS_SCANNING, &priv->status);
> @@ -427,9 +427,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
>  	 * If an internal scan is in progress, just set
>  	 * up the scan_request as per above.
>  	 */
> -	if (priv->is_internal_short_scan)
> +	if (priv->is_internal_short_scan) {
> +		IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
>  		ret = 0;
> -	else
> +	} else
>  		ret = iwl_scan_initiate(priv, vif, false,
>  					req->channels[0]->band);
>  
> @@ -456,6 +457,8 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
>  	struct iwl_priv *priv =
>  		container_of(work, struct iwl_priv, start_internal_scan);
>  
> +	IWL_DEBUG_SCAN(priv, "Start internal scan\n");
> +
>  	mutex_lock(&priv->mutex);
>  
>  	if (priv->is_internal_short_scan == true) {
> @@ -479,6 +482,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
>  	struct iwl_priv *priv =
>  	    container_of(data, struct iwl_priv, scan_check.work);
>  
> +	IWL_DEBUG_SCAN(priv, "Scan check work\n");
> +
>  	/* Since we are here firmware does not finish scan and
>  	 * most likely is in bad shape, so we don't bother to
>  	 * send abort command, just force scan complete to mac80211 */
> @@ -539,6 +544,8 @@ static void iwl_bg_abort_scan(struct work_struct *work)
>  {
>  	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
>  
> +	IWL_DEBUG_SCAN(priv, "Abort scan work\n");
> +
>  	/* We keep scan_check work queued in case when firmware will not
>  	 * report back scan completed notification */
>  	mutex_lock(&priv->mutex);
> @@ -553,7 +560,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
>  	bool aborted;
>  	struct iwl_rxon_context *ctx;
>  
> -	IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
> +	IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
>  		       priv->is_internal_short_scan ? "internal short " : "");
>  
>  	cancel_delayed_work(&priv->scan_check);
> @@ -562,10 +569,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
>  
>  	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
>  	if (aborted)
> -		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
> +		IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
>  
>  	if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
> -		IWL_DEBUG_INFO(priv, "Scan already completed.\n");
> +		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
>  		goto out;
>  	}
>  
Same for this one, can we have some comments?

Thanks
Wey


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning
  2010-09-10 14:26 [PATCH 0/14 v3] " Stanislaw Gruszka
@ 2010-09-10 14:26 ` Stanislaw Gruszka
  2010-09-10 15:56   ` Guy, Wey-Yi
  0 siblings, 1 reply; 20+ messages in thread
From: Stanislaw Gruszka @ 2010-09-10 14:26 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
 drivers/net/wireless/iwlwifi/iwl-scan.c |   31 +++++++++++++++++++------------
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 26dd8f3..65b7cb4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -85,7 +85,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
 		 * can occur if we send the scan abort before we
 		 * the microcode has notified us that a scan is
 		 * completed. */
-		IWL_DEBUG_INFO(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
+		IWL_DEBUG_SCAN(priv, "SCAN_ABORT ret %d.\n", pkt->u.status);
 		ret = -EIO;
 	}
 
@@ -192,7 +192,7 @@ static void iwl_rx_reply_scan(struct iwl_priv *priv,
 	struct iwl_scanreq_notification *notif =
 	    (struct iwl_scanreq_notification *)pkt->u.raw;
 
-	IWL_DEBUG_RX(priv, "Scan request status = 0x%x\n", notif->status);
+	IWL_DEBUG_SCAN(priv, "Scan request status = 0x%x\n", notif->status);
 #endif
 }
 
@@ -251,7 +251,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
 	/* The HW is no longer scanning */
 	clear_bit(STATUS_SCAN_HW, &priv->status);
 
-	IWL_DEBUG_INFO(priv, "Scan on %sGHz took %dms\n",
+	IWL_DEBUG_SCAN(priv, "Scan on %sGHz took %dms\n",
 		       (priv->scan_band == IEEE80211_BAND_2GHZ) ? "2.4" : "5.2",
 		       jiffies_to_msecs(elapsed_jiffies
 					(priv->scan_start, jiffies)));
@@ -362,22 +362,22 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 	cancel_delayed_work(&priv->scan_check);
 
 	if (!iwl_is_ready_rf(priv)) {
-		IWL_WARN(priv, "request scan called when driver not ready.\n");
+		IWL_WARN(priv, "Request scan called when driver not ready.\n");
 		return -EIO;
 	}
 
 	if (test_bit(STATUS_SCAN_HW, &priv->status)) {
-		IWL_DEBUG_INFO(priv,
+		IWL_DEBUG_SCAN(priv,
 			"Multiple concurrent scan requests in parallel.\n");
 		return -EBUSY;
 	}
 
 	if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-		IWL_DEBUG_HC(priv, "Scan request while abort pending.\n");
+		IWL_DEBUG_SCAN(priv, "Scan request while abort pending.\n");
 		return -EBUSY;
 	}
 
-	IWL_DEBUG_INFO(priv, "Starting %sscan...\n",
+	IWL_DEBUG_SCAN(priv, "Starting %sscan...\n",
 			internal ? "internal short " : "");
 
 	set_bit(STATUS_SCANNING, &priv->status);
@@ -427,9 +427,10 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
 	 * If an internal scan is in progress, just set
 	 * up the scan_request as per above.
 	 */
-	if (priv->is_internal_short_scan)
+	if (priv->is_internal_short_scan) {
+		IWL_DEBUG_SCAN(priv, "SCAN request during internal scan\n");
 		ret = 0;
-	else
+	} else
 		ret = iwl_scan_initiate(priv, vif, false,
 					req->channels[0]->band);
 
@@ -456,6 +457,8 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
 	struct iwl_priv *priv =
 		container_of(work, struct iwl_priv, start_internal_scan);
 
+	IWL_DEBUG_SCAN(priv, "Start internal scan\n");
+
 	mutex_lock(&priv->mutex);
 
 	if (priv->is_internal_short_scan == true) {
@@ -479,6 +482,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, scan_check.work);
 
+	IWL_DEBUG_SCAN(priv, "Scan check work\n");
+
 	/* Since we are here firmware does not finish scan and
 	 * most likely is in bad shape, so we don't bother to
 	 * send abort command, just force scan complete to mac80211 */
@@ -539,6 +544,8 @@ static void iwl_bg_abort_scan(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
 
+	IWL_DEBUG_SCAN(priv, "Abort scan work\n");
+
 	/* We keep scan_check work queued in case when firmware will not
 	 * report back scan completed notification */
 	mutex_lock(&priv->mutex);
@@ -553,7 +560,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	bool aborted;
 	struct iwl_rxon_context *ctx;
 
-	IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
+	IWL_DEBUG_SCAN(priv, "Completed %sscan.\n",
 		       priv->is_internal_short_scan ? "internal short " : "");
 
 	cancel_delayed_work(&priv->scan_check);
@@ -562,10 +569,10 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 
 	aborted = test_and_clear_bit(STATUS_SCAN_ABORTING, &priv->status);
 	if (aborted)
-		IWL_DEBUG_INFO(priv, "Aborted scan completed.\n");
+		IWL_DEBUG_SCAN(priv, "Aborted scan completed.\n");
 
 	if (!test_and_clear_bit(STATUS_SCANNING, &priv->status)) {
-		IWL_DEBUG_INFO(priv, "Scan already completed.\n");
+		IWL_DEBUG_SCAN(priv, "Scan already completed.\n");
 		goto out;
 	}
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2010-09-13 14:09 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-13 12:46 [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 01/14] iwlwifi: remove unused conf variables Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 02/14] iwlwifi: unify scan start checks Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 03/14] iwlwifi: move scan completed flags handling Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 04/14] iwlwifi: cancel scan when down the device Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 05/14] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 06/14] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 07/14] iwlwifi: rewrite scan completion Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 08/14] iwlwifi: force scan complete after timeout Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 09/14] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
2010-09-13 14:07   ` Guy, Wey-Yi
2010-09-13 12:46 ` [PATCH 10/14] iwlwifi: do not force complete scan too early Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 11/14] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 12/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
2010-09-13 12:46 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
2010-09-13 14:07   ` Guy, Wey-Yi
2010-09-13 12:46 ` [PATCH 14/14] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
2010-09-13 14:08 ` [PATCH 0/14 v4] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi
  -- strict thread matches above, loose matches on Subject: below --
2010-09-10 14:26 [PATCH 0/14 v3] " Stanislaw Gruszka
2010-09-10 14:26 ` [PATCH 13/14] iwlwifi: use IWL_DEBUG_SCAN for debug scanning Stanislaw Gruszka
2010-09-10 15:56   ` Guy, Wey-Yi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.