aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2010-05-05 05:26:06 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-13 13:44:16 -0400
commit9c5ac091b269912cd30fade987f4bc615ef3be90 (patch)
tree698fe77ad1f144ca1c2e3ba9738946a22253399f /drivers/net/wireless/iwlwifi/iwl-agn-lib.c
parent94adfaa406420ae035b1b760e3d5015775fe7b7c (diff)
iwlwifi: fix and add missing sta_lock usage
There are a few places where sta_lock is used, but the station information protected by it is accessed outside of the lock. Address this in two ways, if the access won't sleep then just move the access into the lock, if the access can sleep then copy the needed station information to the stack to be accessed without risk of it changing while access in progress. Additionally, a number of other places access station station information without holding the sta_lock, fix those as well. Signed-off-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 5f07bc2e14e9..4857b5f62481 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -184,6 +184,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
184 int tid; 184 int tid;
185 int sta_id; 185 int sta_id;
186 int freed; 186 int freed;
187 unsigned long flags;
187 188
188 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 189 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
189 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 190 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -199,9 +200,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
199 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; 200 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
200 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; 201 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
201 202
203 spin_lock_irqsave(&priv->sta_lock, flags);
202 if (txq->sched_retry) { 204 if (txq->sched_retry) {
203 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); 205 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
204 struct iwl_ht_agg *agg = NULL; 206 struct iwl_ht_agg *agg;
205 207
206 agg = &priv->stations[sta_id].tid[tid].agg; 208 agg = &priv->stations[sta_id].tid[tid].agg;
207 209
@@ -256,6 +258,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
256 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 258 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
257 259
258 iwl_check_abort_status(priv, tx_resp->frame_count, status); 260 iwl_check_abort_status(priv, tx_resp->frame_count, status);
261 spin_unlock_irqrestore(&priv->sta_lock, flags);
259} 262}
260 263
261void iwlagn_rx_handler_setup(struct iwl_priv *priv) 264void iwlagn_rx_handler_setup(struct iwl_priv *priv)
@@ -1533,6 +1536,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1533void iwl_free_tfds_in_queue(struct iwl_priv *priv, 1536void iwl_free_tfds_in_queue(struct iwl_priv *priv,
1534 int sta_id, int tid, int freed) 1537 int sta_id, int tid, int freed)
1535{ 1538{
1539 WARN_ON(!spin_is_locked(&priv->sta_lock));
1540
1536 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) 1541 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
1537 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1542 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1538 else { 1543 else {