diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-11-17 17:17:53 -0500 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-12-02 11:34:54 -0500 |
commit | 40b97c2fe96a476f1c228345f0c6a2d135a8b226 (patch) | |
tree | 979c349b71b6de6c1d9150e2b6a8035cddc339e7 /drivers/net/wireless/iwlwifi | |
parent | 61790c5f3c5f158821821a00797d94504531839f (diff) |
iwlagn: fix race condition when reprogram sta
During reprogram stations, do not send link quality command.
uCode will crash if receive link quality command for invalid station
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 0a67b2fa52a1..4776323b1eba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -647,6 +647,7 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
647 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); | 647 | memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq)); |
648 | 648 | ||
649 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; | 649 | active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE; |
650 | priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; | ||
650 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 651 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
651 | 652 | ||
652 | if (active) { | 653 | if (active) { |
@@ -657,6 +658,10 @@ void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
657 | IWL_ERR(priv, "failed to remove STA %pM (%d)\n", | 658 | IWL_ERR(priv, "failed to remove STA %pM (%d)\n", |
658 | priv->stations[sta_id].sta.sta.addr, ret); | 659 | priv->stations[sta_id].sta.sta.addr, ret); |
659 | } | 660 | } |
661 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
662 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | ||
663 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
664 | |||
660 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); | 665 | ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC); |
661 | if (ret) | 666 | if (ret) |
662 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", | 667 | IWL_ERR(priv, "failed to re-add STA %pM (%d)\n", |
@@ -777,6 +782,14 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
777 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) | 782 | if (WARN_ON(lq->sta_id == IWL_INVALID_STATION)) |
778 | return -EINVAL; | 783 | return -EINVAL; |
779 | 784 | ||
785 | |||
786 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | ||
787 | if (!(priv->stations[lq->sta_id].used & IWL_STA_DRIVER_ACTIVE)) { | ||
788 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
789 | return -EINVAL; | ||
790 | } | ||
791 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | ||
792 | |||
780 | iwl_dump_lq_cmd(priv, lq); | 793 | iwl_dump_lq_cmd(priv, lq); |
781 | BUG_ON(init && (cmd.flags & CMD_ASYNC)); | 794 | BUG_ON(init && (cmd.flags & CMD_ASYNC)); |
782 | 795 | ||