diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2011-06-08 09:26:31 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-06-08 14:19:05 -0400 |
commit | 51e65257142a87fe46a1ce5c35c86c5baf012614 (patch) | |
tree | e5210ffad470c6b7b9c969aac667d5d5b491f76c /drivers/net/wireless/iwlegacy/iwl-4965.c | |
parent | f3209bea110cade12e2b133da8b8499689cb0e2e (diff) |
iwlegacy: fix channel switch locking
We use priv->mutex to avoid race conditions between chswitch_done()
and mac_channel_switch(), when marking channel switch in
progress. But chswitch_done() can be called in atomic context
from rx_csa() or with mutex already taken from commit_rxon().
To fix remove mutex from chswitch_done() and use atomic bitops
for marking channel switch pending.
Cc: stable@kernel.org # 2.6.39+
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlegacy/iwl-4965.c')
-rw-r--r-- | drivers/net/wireless/iwlegacy/iwl-4965.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index e1b89220c18..facc94e74b0 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c | |||
@@ -1218,10 +1218,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c | |||
1218 | * receive commit_rxon request | 1218 | * receive commit_rxon request |
1219 | * abort any previous channel switch if still in process | 1219 | * abort any previous channel switch if still in process |
1220 | */ | 1220 | */ |
1221 | if (priv->switch_rxon.switch_in_progress && | 1221 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && |
1222 | (priv->switch_rxon.channel != ctx->staging.channel)) { | 1222 | (priv->switch_channel != ctx->staging.channel)) { |
1223 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | 1223 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", |
1224 | le16_to_cpu(priv->switch_rxon.channel)); | 1224 | le16_to_cpu(priv->switch_channel)); |
1225 | iwl_legacy_chswitch_done(priv, false); | 1225 | iwl_legacy_chswitch_done(priv, false); |
1226 | } | 1226 | } |
1227 | 1227 | ||
@@ -1404,9 +1404,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, | |||
1404 | return rc; | 1404 | return rc; |
1405 | } | 1405 | } |
1406 | 1406 | ||
1407 | priv->switch_rxon.channel = cmd.channel; | ||
1408 | priv->switch_rxon.switch_in_progress = true; | ||
1409 | |||
1410 | return iwl_legacy_send_cmd_pdu(priv, | 1407 | return iwl_legacy_send_cmd_pdu(priv, |
1411 | REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); | 1408 | REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); |
1412 | } | 1409 | } |