aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-11-17 17:17:53 -0500
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-12-02 11:34:54 -0500
commit40b97c2fe96a476f1c228345f0c6a2d135a8b226 (patch)
tree979c349b71b6de6c1d9150e2b6a8035cddc339e7 /drivers/net/wireless/iwlwifi
parent61790c5f3c5f158821821a00797d94504531839f (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.c13
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