aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-03-31 11:36:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-04-07 15:34:11 -0400
commitdc1a4068fce2657991c5c3b1f6849f7fc466c69f (patch)
tree8463f06bbbc582f7afa6d8869350dc1f67f8732e /drivers/net/wireless/iwlwifi/iwl-agn.c
parent3598e1774c94e55c71b585340e7dc4538f310e3f (diff)
iwlwifi: more priv->mutex serialization
Check status bits with mutex taken, because when we wait for mutex unlock, status can change. Patch should also make remaining sync commands be send with priv->mutex taken. That will prevent execute these commands when we are currently reset firmware, what could possibly cause troubles. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c34
1 files changed, 20 insertions, 14 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 28ac0d44555e..70428e9b9f76 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -483,12 +483,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
483 container_of(work, struct iwl_priv, bt_full_concurrency); 483 container_of(work, struct iwl_priv, bt_full_concurrency);
484 struct iwl_rxon_context *ctx; 484 struct iwl_rxon_context *ctx;
485 485
486 mutex_lock(&priv->mutex);
487
486 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 488 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
487 return; 489 goto out;
488 490
489 /* dont send host command if rf-kill is on */ 491 /* dont send host command if rf-kill is on */
490 if (!iwl_is_ready_rf(priv)) 492 if (!iwl_is_ready_rf(priv))
491 return; 493 goto out;
492 494
493 IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", 495 IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
494 priv->bt_full_concurrent ? 496 priv->bt_full_concurrent ?
@@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
498 * LQ & RXON updated cmds must be sent before BT Config cmd 500 * LQ & RXON updated cmds must be sent before BT Config cmd
499 * to avoid 3-wire collisions 501 * to avoid 3-wire collisions
500 */ 502 */
501 mutex_lock(&priv->mutex);
502 for_each_context(priv, ctx) { 503 for_each_context(priv, ctx) {
503 if (priv->cfg->ops->hcmd->set_rxon_chain) 504 if (priv->cfg->ops->hcmd->set_rxon_chain)
504 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); 505 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
505 iwlcore_commit_rxon(priv, ctx); 506 iwlcore_commit_rxon(priv, ctx);
506 } 507 }
507 mutex_unlock(&priv->mutex);
508 508
509 priv->cfg->ops->hcmd->send_bt_config(priv); 509 priv->cfg->ops->hcmd->send_bt_config(priv);
510out:
511 mutex_unlock(&priv->mutex);
510} 512}
511 513
512/** 514/**
@@ -2620,10 +2622,13 @@ static void iwl_bg_init_alive_start(struct work_struct *data)
2620 struct iwl_priv *priv = 2622 struct iwl_priv *priv =
2621 container_of(data, struct iwl_priv, init_alive_start.work); 2623 container_of(data, struct iwl_priv, init_alive_start.work);
2622 2624
2623 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2625 mutex_lock(&priv->mutex);
2626
2627 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2628 mutex_unlock(&priv->mutex);
2624 return; 2629 return;
2630 }
2625 2631
2626 mutex_lock(&priv->mutex);
2627 priv->cfg->ops->lib->init_alive_start(priv); 2632 priv->cfg->ops->lib->init_alive_start(priv);
2628 mutex_unlock(&priv->mutex); 2633 mutex_unlock(&priv->mutex);
2629} 2634}
@@ -2633,15 +2638,16 @@ static void iwl_bg_alive_start(struct work_struct *data)
2633 struct iwl_priv *priv = 2638 struct iwl_priv *priv =
2634 container_of(data, struct iwl_priv, alive_start.work); 2639 container_of(data, struct iwl_priv, alive_start.work);
2635 2640
2641 mutex_lock(&priv->mutex);
2636 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2642 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2637 return; 2643 goto unlock;
2638 2644
2639 /* enable dram interrupt */ 2645 /* enable dram interrupt */
2640 if (priv->cfg->ops->lib->isr_ops.reset) 2646 if (priv->cfg->ops->lib->isr_ops.reset)
2641 priv->cfg->ops->lib->isr_ops.reset(priv); 2647 priv->cfg->ops->lib->isr_ops.reset(priv);
2642 2648
2643 mutex_lock(&priv->mutex);
2644 iwl_alive_start(priv); 2649 iwl_alive_start(priv);
2650unlock:
2645 mutex_unlock(&priv->mutex); 2651 mutex_unlock(&priv->mutex);
2646} 2652}
2647 2653
@@ -3267,21 +3273,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3267 3273
3268 IWL_DEBUG_MAC80211(priv, "enter\n"); 3274 IWL_DEBUG_MAC80211(priv, "enter\n");
3269 3275
3276 mutex_lock(&priv->mutex);
3277
3270 if (iwl_is_rfkill(priv)) 3278 if (iwl_is_rfkill(priv))
3271 goto out_exit; 3279 goto out;
3272 3280
3273 if (test_bit(STATUS_EXIT_PENDING, &priv->status) || 3281 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
3274 test_bit(STATUS_SCANNING, &priv->status)) 3282 test_bit(STATUS_SCANNING, &priv->status))
3275 goto out_exit; 3283 goto out;
3276 3284
3277 if (!iwl_is_associated_ctx(ctx)) 3285 if (!iwl_is_associated_ctx(ctx))
3278 goto out_exit; 3286 goto out;
3279 3287
3280 /* channel switch in progress */ 3288 /* channel switch in progress */
3281 if (priv->switch_rxon.switch_in_progress == true) 3289 if (priv->switch_rxon.switch_in_progress == true)
3282 goto out_exit; 3290 goto out;
3283 3291
3284 mutex_lock(&priv->mutex);
3285 if (priv->cfg->ops->lib->set_channel_switch) { 3292 if (priv->cfg->ops->lib->set_channel_switch) {
3286 3293
3287 ch = channel->hw_value; 3294 ch = channel->hw_value;
@@ -3337,7 +3344,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
3337 } 3344 }
3338out: 3345out:
3339 mutex_unlock(&priv->mutex); 3346 mutex_unlock(&priv->mutex);
3340out_exit:
3341 if (!priv->switch_rxon.switch_in_progress) 3347 if (!priv->switch_rxon.switch_in_progress)
3342 ieee80211_chswitch_done(ctx->vif, false); 3348 ieee80211_chswitch_done(ctx->vif, false);
3343 IWL_DEBUG_MAC80211(priv, "leave\n"); 3349 IWL_DEBUG_MAC80211(priv, "leave\n");