linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
@ 2010-09-09 13:52 Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 01/12] iwlwifi: remove unused conf variables Stanislaw Gruszka
                   ` (16 more replies)
  0 siblings, 17 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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 4 more patches

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

* [PATCH 01/12] iwlwifi: remove unused conf variables
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 02/12] iwlwifi: unify scan start checks Stanislaw Gruszka
                   ` (15 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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] 30+ messages in thread

* [PATCH 02/12] iwlwifi: unify scan start checks
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 01/12] iwlwifi: remove unused conf variables Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 03/12] iwlwifi: move scan completed flags handling Stanislaw Gruszka
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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 7c542a8..b0fef62 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -217,7 +217,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..01a4907 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);
+		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] 30+ messages in thread

* [PATCH 03/12] iwlwifi: move scan completed flags handling
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 01/12] iwlwifi: remove unused conf variables Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 02/12] iwlwifi: unify scan start checks Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 04/12] iwlwifi: cancel scan when down the device Stanislaw Gruszka
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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 01a4907..9df8bb8 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] 30+ messages in thread

* [PATCH 04/12] iwlwifi: cancel scan when down the device
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (2 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 03/12] iwlwifi: move scan completed flags handling Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 05/12] iwlwifi: use IWL_DEBUG_SCAN Stanislaw Gruszka
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 ad0e67f..0de2401 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2875,8 +2875,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 */
@@ -3486,15 +3487,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 9df8bb8..d31ed14 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] 30+ messages in thread

* [PATCH 05/12] iwlwifi: use IWL_DEBUG_SCAN
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (3 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 04/12] iwlwifi: cancel scan when down the device Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 06/12] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
                   ` (11 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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 |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index d31ed14..5fb49d2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -158,7 +158,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
 }
 
-- 
1.7.1


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

* [PATCH 06/12] iwlwifi: report scan completion when abort fail
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (4 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 05/12] iwlwifi: use IWL_DEBUG_SCAN Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 07/12] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 5fb49d2..4d2a09b 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] 30+ messages in thread

* [PATCH 07/12] iwlwifi: rework iwl_scan_cancel_timeout
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (5 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 06/12] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 08/12] iwlwifi: rewrite scan completion Stanislaw Gruszka
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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 4d2a09b..7e4faaf 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] 30+ messages in thread

* [PATCH 08/12] iwlwifi: rewrite scan completion
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (6 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 07/12] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 09/12] iwlwifi: force scan complete after timeout Stanislaw Gruszka
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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 7e4faaf..f79fb3e 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] 30+ messages in thread

* [PATCH 09/12] iwlwifi: force scan complete after timeout
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (7 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 08/12] iwlwifi: rewrite scan completion Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 15:50   ` Guy, Wey-Yi W
  2010-09-09 13:52 ` [PATCH 10/12] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
                   ` (7 subsequent siblings)
  16 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 f79fb3e..fcc826e 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] 30+ messages in thread

* [PATCH 10/12] iwlwifi: assure we complete scan in scan_abort and scan_check works
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (8 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 09/12] iwlwifi: force scan complete after timeout Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 11/12] iwlwifi: do not force complete scan too early Stanislaw Gruszka
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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 |   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 fcc826e..df61273 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] 30+ messages in thread

* [PATCH 11/12] iwlwifi: do not force complete scan too early
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (9 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 10/12] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 12/12] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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     |   40 ++++++++++++++++++++-------
 drivers/net/wireless/iwlwifi/iwl3945-base.c |    4 +-
 5 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0de2401..9ef48f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -4054,13 +4054,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 df61273..10b0ccc 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);
@@ -564,7 +571,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
 	IWL_DEBUG_INFO(priv, "Completed %sscan.\n",
 		       priv->is_internal_short_scan ? "internal short " : "");
 
-	cancel_delayed_work(&priv->scan_check);
+	cancel_delayed_work_sync(&priv->scan_check);
 
 	mutex_lock(&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] 30+ messages in thread

* [PATCH 12/12] mac80211: wait for scan work complete before restarting hw
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (10 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 11/12] iwlwifi: do not force complete scan too early Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 13/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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] 30+ messages in thread

* [PATCH 13/14] iwlwifi: cleanup scan initiate check
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (11 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 12/12] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 15:46   ` Guy, Wey-Yi W
  2010-09-09 13:52 ` [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN Stanislaw Gruszka
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

Remove redundand checks and use iwl_is_ready_rf().

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 10b0ccc..9cc4901 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] 30+ messages in thread

* [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (12 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 13/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 15:52   ` Guy, Wey-Yi W
  2010-09-09 13:52 ` [PATCH 15/15] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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 |   29 ++++++++++++++++++-----------
 1 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 9cc4901..a214f79 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;
 	}
 
@@ -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_sync(&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] 30+ messages in thread

* [PATCH 15/15] iwlwifi: apply settings when finishing scan
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (13 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 13:52 ` [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan Stanislaw Gruszka
  2010-09-09 15:32 ` [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi W
  16 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 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>
---
 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 a214f79..b841016 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] 30+ messages in thread

* [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (14 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 15/15] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
@ 2010-09-09 13:52 ` Stanislaw Gruszka
  2010-09-09 15:35   ` Guy, Wey-Yi W
  2010-09-09 15:32 ` [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi W
  16 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 13:52 UTC (permalink / raw)
  To: Johannes Berg, Wey-Yi Guy, Reinette Chatre, John W. Linville
  Cc: linux-wireless, Stanislaw Gruszka

In case we fail to request scan we need to clear
priv->is_internal_short_scan. Otherwise we pretend we perform internal
short scan. Next external scan request will be differed, but never
performed nor canceled because STATUS_SCANNING bit is cleared.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 b841016..c3f2957 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -381,14 +381,15 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
 			internal ? "internal short " : "");
 
 	set_bit(STATUS_SCANNING, &priv->status);
-
 	priv->is_internal_short_scan = internal;
+
 	priv->scan_start = jiffies;
 	priv->scan_band = band;
 
 	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;
 	}
 
-- 
1.7.1


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

* RE: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
                   ` (15 preceding siblings ...)
  2010-09-09 13:52 ` [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan Stanislaw Gruszka
@ 2010-09-09 15:32 ` Guy, Wey-Yi W
  2010-09-09 15:55   ` Stanislaw Gruszka
  16 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:32 UTC (permalink / raw)
  To: Stanislaw Gruszka, Johannes Berg, Chatre, Reinette,
	John W. Linville
  Cc: linux-wireless@vger.kernel.org

Hi Gruszka,

Do we have any bugzilla bug# can associated to this set of patches?

Thanks
Wey

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 6:52 AM
To: Johannes Berg; Guy, Wey-Yi W; Chatre, Reinette; John W. Linville
Cc: linux-wireless@vger.kernel.org; Stanislaw Gruszka
Subject: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions

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 4 more patches

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

* RE: [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan
  2010-09-09 13:52 ` [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan Stanislaw Gruszka
@ 2010-09-09 15:35   ` Guy, Wey-Yi W
  2010-09-10  5:17     ` Stanislaw Gruszka
  0 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:35 UTC (permalink / raw)
  To: Stanislaw Gruszka, Johannes Berg, Chatre, Reinette,
	John W. Linville
  Cc: linux-wireless@vger.kernel.org

Hi Gruszka,

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 6:53 AM
To: Johannes Berg; Guy, Wey-Yi W; Chatre, Reinette; John W. Linville
Cc: linux-wireless@vger.kernel.org; Stanislaw Gruszka
Subject: [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan

In case we fail to request scan we need to clear
priv->is_internal_short_scan. Otherwise we pretend we perform internal
short scan. Next external scan request will be differed, but never
performed nor canceled because STATUS_SCANNING bit is cleared.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 b841016..c3f2957 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -381,14 +381,15 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
                        internal ? "internal short " : "");

        set_bit(STATUS_SCANNING, &priv->status);
-
        priv->is_internal_short_scan = internal;
+
Not needed

Thanks
Wey

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

* RE: [PATCH 13/14] iwlwifi: cleanup scan initiate check
  2010-09-09 13:52 ` [PATCH 13/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
@ 2010-09-09 15:46   ` Guy, Wey-Yi W
  2010-09-10  5:03     ` Stanislaw Gruszka
  0 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:46 UTC (permalink / raw)
  To: Stanislaw Gruszka, Johannes Berg, Chatre, Reinette,
	John W. Linville
  Cc: linux-wireless@vger.kernel.org

Hi Gruszka,

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 6:53 AM
To: Johannes Berg; Guy, Wey-Yi W; Chatre, Reinette; John W. Linville
Cc: linux-wireless@vger.kernel.org; Stanislaw Gruszka
Subject: [PATCH 13/14] iwlwifi: cleanup scan initiate check

Remove redundand checks and use iwl_is_ready_rf().

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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 10b0ccc..9cc4901 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 " : "");


Same cleanup for 3945?

Thanks
Wey


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

* RE: [PATCH 09/12] iwlwifi: force scan complete after timeout
  2010-09-09 13:52 ` [PATCH 09/12] iwlwifi: force scan complete after timeout Stanislaw Gruszka
@ 2010-09-09 15:50   ` Guy, Wey-Yi W
  2010-09-10  5:15     ` Stanislaw Gruszka
  0 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:50 UTC (permalink / raw)
  To: Stanislaw Gruszka, Johannes Berg, Chatre, Reinette,
	John W. Linville
  Cc: linux-wireless@vger.kernel.org

Hi Gruszka,

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 6:52 AM
To: Johannes Berg; Guy, Wey-Yi W; Chatre, Reinette; John W. Linville
Cc: linux-wireless@vger.kernel.org; Stanislaw Gruszka
Subject: [PATCH 09/12] iwlwifi: force scan complete after timeout

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.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.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);

Not sure, do we need to check vif match?

Thanks
Wey


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

* RE: [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN
  2010-09-09 13:52 ` [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN Stanislaw Gruszka
@ 2010-09-09 15:52   ` Guy, Wey-Yi W
  0 siblings, 0 replies; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:52 UTC (permalink / raw)
  To: Stanislaw Gruszka, Johannes Berg, Chatre, Reinette,
	John W. Linville
  Cc: linux-wireless@vger.kernel.org

Hi Gruszka,

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 6:53 AM
To: Johannes Berg; Guy, Wey-Yi W; Chatre, Reinette; John W. Linville
Cc: linux-wireless@vger.kernel.org; Stanislaw Gruszka
Subject: [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN

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

Should this patch merge with patch#5?

Thanks
Wey

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

* Re: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 15:32 ` [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi W
@ 2010-09-09 15:55   ` Stanislaw Gruszka
  2010-09-09 15:57     ` Guy, Wey-Yi W
  0 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 15:55 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

Hi.

On Thu, Sep 09, 2010 at 08:32:56AM -0700, Guy, Wey-Yi W wrote:
> Do we have any bugzilla bug# can associated to this set of patches?

Yes, I'm doing this for RHEL6 bug:
https://bugzilla.redhat.com/show_bug.cgi?id=593566

I'm pretty sure there are lot's of other "WARNING: at
net/wireless/core.c:614 wdev_cleanup_work" bug reports, which will
be most likely fixed by this patchset.
 
Stanislaw

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

* RE: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 15:55   ` Stanislaw Gruszka
@ 2010-09-09 15:57     ` Guy, Wey-Yi W
  2010-09-09 16:06       ` Stanislaw Gruszka
  0 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 15:57 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

Hi Gruszka,

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 8:55 AM
To: Guy, Wey-Yi W
Cc: Johannes Berg; Chatre, Reinette; John W. Linville; linux-wireless@vger.kernel.org
Subject: Re: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions

Hi.

On Thu, Sep 09, 2010 at 08:32:56AM -0700, Guy, Wey-Yi W wrote:
> Do we have any bugzilla bug# can associated to this set of patches?

Yes, I'm doing this for RHEL6 bug:
https://bugzilla.redhat.com/show_bug.cgi?id=593566

I'm pretty sure there are lot's of other "WARNING: at
net/wireless/core.c:614 wdev_cleanup_work" bug reports, which will
be most likely fixed by this patchset.


Could these bug# be part of description which can help us keep track of the bugs status

Thanks
Wey

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

* Re: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 15:57     ` Guy, Wey-Yi W
@ 2010-09-09 16:06       ` Stanislaw Gruszka
  2010-09-09 16:09         ` Guy, Wey-Yi W
  0 siblings, 1 reply; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-09 16:06 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

On Thu, Sep 09, 2010 at 08:57:10AM -0700, Guy, Wey-Yi W wrote:
> > Do we have any bugzilla bug# can associated to this set of patches?
> 
> Yes, I'm doing this for RHEL6 bug:
> https://bugzilla.redhat.com/show_bug.cgi?id=593566
> 
> I'm pretty sure there are lot's of other "WARNING: at
> net/wireless/core.c:614 wdev_cleanup_work" bug reports, which will
> be most likely fixed by this patchset.
> 
> 
> Could these bug# be part of description which can help us keep track of the bugs status

Sure. But you mean patch 0 description ? That text does not go to
changelog, but at least is keep on mailing list archives ...

Stanislaw

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

* RE: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 16:06       ` Stanislaw Gruszka
@ 2010-09-09 16:09         ` Guy, Wey-Yi W
  2010-09-10  5:36           ` Stanislaw Gruszka
  0 siblings, 1 reply; 30+ messages in thread
From: Guy, Wey-Yi W @ 2010-09-09 16:09 UTC (permalink / raw)
  To: Stanislaw Gruszka
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

Hi Gruszka,

Understand, I was thinking adding the bug# to the key patch(es) which address the problem such as #4, #6, ...etc

Thanks
Wey

-----Original Message-----
From: Stanislaw Gruszka [mailto:sgruszka@redhat.com]
Sent: Thursday, September 09, 2010 9:07 AM
To: Guy, Wey-Yi W
Cc: Johannes Berg; Chatre, Reinette; John W. Linville; linux-wireless@vger.kernel.org
Subject: Re: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions

On Thu, Sep 09, 2010 at 08:57:10AM -0700, Guy, Wey-Yi W wrote:
> > Do we have any bugzilla bug# can associated to this set of patches?
>
> Yes, I'm doing this for RHEL6 bug:
> https://bugzilla.redhat.com/show_bug.cgi?id=593566
>
> I'm pretty sure there are lot's of other "WARNING: at
> net/wireless/core.c:614 wdev_cleanup_work" bug reports, which will
> be most likely fixed by this patchset.
>
>
> Could these bug# be part of description which can help us keep track of the bugs status

Sure. But you mean patch 0 description ? That text does not go to
changelog, but at least is keep on mailing list archives ...

Stanislaw

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

* Re: [PATCH 13/14] iwlwifi: cleanup scan initiate check
  2010-09-09 15:46   ` Guy, Wey-Yi W
@ 2010-09-10  5:03     ` Stanislaw Gruszka
  0 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-10  5:03 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

Hi Wey

On Thu, Sep 09, 2010 at 08:46:57AM -0700, Guy, Wey-Yi W wrote:
> --- 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 " : "");
> 
> 
> Same cleanup for 3945?

It's common code, we merge it in patch 2.

Stanislaw

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

* Re: [PATCH 09/12] iwlwifi: force scan complete after timeout
  2010-09-09 15:50   ` Guy, Wey-Yi W
@ 2010-09-10  5:15     ` Stanislaw Gruszka
  0 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-10  5:15 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

On Thu, Sep 09, 2010 at 08:50:03AM -0700, Guy, Wey-Yi W wrote:
> --- 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;
> -       }
> -
[snip]
> Not sure, do we need to check vif match?

I think it is. We should not cancel scan requested by vif0 if vif1 is
removing. Previously we also check vif match before complete scan in
mac.

Stanislaw

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

* Re: [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan
  2010-09-09 15:35   ` Guy, Wey-Yi W
@ 2010-09-10  5:17     ` Stanislaw Gruszka
  0 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-10  5:17 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

On Thu, Sep 09, 2010 at 08:35:51AM -0700, Guy, Wey-Yi W wrote:
> diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
> index b841016..c3f2957 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-scan.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
> @@ -381,14 +381,15 @@ static int __must_check iwl_scan_initiate(struct iwl_priv *priv,
>                         internal ? "internal short " : "");
> 
>         set_bit(STATUS_SCANNING, &priv->status);
> -
>         priv->is_internal_short_scan = internal;
> +
> Not needed

Ok. I will merge that patch with patch 2.

Stanislaw

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

* Re: [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions
  2010-09-09 16:09         ` Guy, Wey-Yi W
@ 2010-09-10  5:36           ` Stanislaw Gruszka
  0 siblings, 0 replies; 30+ messages in thread
From: Stanislaw Gruszka @ 2010-09-10  5:36 UTC (permalink / raw)
  To: Guy, Wey-Yi W
  Cc: Johannes Berg, Chatre, Reinette, John W. Linville,
	linux-wireless@vger.kernel.org

On Thu, Sep 09, 2010 at 09:09:43AM -0700, Guy, Wey-Yi W wrote:
> Understand, I was thinking adding the bug# to the key patch(es) which address the problem such as #4, #6, ...etc

Actually most patches, maybe except 3, fix some aspect of problem.
I'll put reference to bug report in 3 or 4 most important patches.

Stanislaw

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

end of thread, other threads:[~2010-09-10  5:41 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-09 13:52 [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 01/12] iwlwifi: remove unused conf variables Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 02/12] iwlwifi: unify scan start checks Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 03/12] iwlwifi: move scan completed flags handling Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 04/12] iwlwifi: cancel scan when down the device Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 05/12] iwlwifi: use IWL_DEBUG_SCAN Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 06/12] iwlwifi: report scan completion when abort fail Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 07/12] iwlwifi: rework iwl_scan_cancel_timeout Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 08/12] iwlwifi: rewrite scan completion Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 09/12] iwlwifi: force scan complete after timeout Stanislaw Gruszka
2010-09-09 15:50   ` Guy, Wey-Yi W
2010-09-10  5:15     ` Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 10/12] iwlwifi: assure we complete scan in scan_abort and scan_check works Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 11/12] iwlwifi: do not force complete scan too early Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 12/12] mac80211: wait for scan work complete before restarting hw Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 13/14] iwlwifi: cleanup scan initiate check Stanislaw Gruszka
2010-09-09 15:46   ` Guy, Wey-Yi W
2010-09-10  5:03     ` Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 14/16] iwlwifi: replace and add IWL_DEBUG_SCAN Stanislaw Gruszka
2010-09-09 15:52   ` Guy, Wey-Yi W
2010-09-09 13:52 ` [PATCH 15/15] iwlwifi: apply settings when finishing scan Stanislaw Gruszka
2010-09-09 13:52 ` [PATCH 16/16] iwlwifi: clear is_internal_short_scan when fail to initiate scan Stanislaw Gruszka
2010-09-09 15:35   ` Guy, Wey-Yi W
2010-09-10  5:17     ` Stanislaw Gruszka
2010-09-09 15:32 ` [PATCH 0/16 v2] iwlwifi: rewrite iwl-scan.c to avoid race conditions Guy, Wey-Yi W
2010-09-09 15:55   ` Stanislaw Gruszka
2010-09-09 15:57     ` Guy, Wey-Yi W
2010-09-09 16:06       ` Stanislaw Gruszka
2010-09-09 16:09         ` Guy, Wey-Yi W
2010-09-10  5:36           ` Stanislaw Gruszka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).