From 6f213ff1919fab6f8244ceae55631b5d6ef750a7 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 2 Jun 2011 18:17:15 +0200 Subject: iwlagn: fix channel switch locking We use priv->mutex to avoid race conditions between iwl_chswitch_done() and iwlagn_mac_channel_switch(), when marking channel switch in progress. But iwl_chswitch_done() can be called in atomic context from iwl_rx_csa() or with mutex already taken from iwlagn_commit_rxon(). These bugs were introduced by: commit 79d07325502e73508f917475bc1617b60979dd94 Author: Wey-Yi Guy Date: Thu May 6 08:54:11 2010 -0700 iwlwifi: support channel switch offload in driver To fix remove mutex from iwl_chswitch_done() and use atomic bitops for marking channel switch pending. Also remove iwl2030_hw_channel_switch() since 2000 series adapters are 2.4GHz only devices. Cc: stable@kernel.org # 2.6.36+ Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-rx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'drivers/net/wireless/iwlwifi/iwl-rx.c') diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 0053e9ea9021..b774517aa9fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -250,19 +250,19 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; struct iwl_rxon_cmd *rxon = (void *)&ctx->active; - if (priv->switch_rxon.switch_in_progress) { - if (!le32_to_cpu(csa->status) && - (csa->channel == priv->switch_rxon.channel)) { - rxon->channel = csa->channel; - ctx->staging.channel = csa->channel; - IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", - le16_to_cpu(csa->channel)); - iwl_chswitch_done(priv, true); - } else { - IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) + return; + + if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { + rxon->channel = csa->channel; + ctx->staging.channel = csa->channel; + IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", le16_to_cpu(csa->channel)); - iwl_chswitch_done(priv, false); - } + iwl_chswitch_done(priv, true); + } else { + IWL_ERR(priv, "CSA notif (fail) : channel %d\n", + le16_to_cpu(csa->channel)); + iwl_chswitch_done(priv, false); } } -- cgit v1.2.3-55-g7522