aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRon Rindjunsky <ron.rindjunsky@intel.com>2008-03-06 20:36:56 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-07 16:03:02 -0500
commitb095d03a7d724db7379b73f64b6035f7be2e0a7c (patch)
treed1a5eb99c7e67b04b1e4fb320bd8771c9a18f09d
parent91c066f27b6dacb6589fb5190af373fb9f993397 (diff)
iwlwifi: grab NIC access when disabling aggregations
This patch grabs NIC access inside iwl4965_tx_queue_agg_disable, instead of the caller doing it. The caller must still hold priv->lock when calling the function. Signed-off-by: Max Stepanov <max.stepanov@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 3e122a931f2d..4a7167dbc217 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -4138,16 +4138,23 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv,
4138 4138
4139/** 4139/**
4140 * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID 4140 * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
4141 * priv->lock must be held by the caller
4141 */ 4142 */
4142static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, 4143static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
4143 u16 ssn_idx, u8 tx_fifo) 4144 u16 ssn_idx, u8 tx_fifo)
4144{ 4145{
4146 int ret = 0;
4147
4145 if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { 4148 if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {
4146 IWL_WARNING("queue number too small: %d, must be > %d\n", 4149 IWL_WARNING("queue number too small: %d, must be > %d\n",
4147 txq_id, IWL_BACK_QUEUE_FIRST_ID); 4150 txq_id, IWL_BACK_QUEUE_FIRST_ID);
4148 return -EINVAL; 4151 return -EINVAL;
4149 } 4152 }
4150 4153
4154 ret = iwl4965_grab_nic_access(priv);
4155 if (ret)
4156 return ret;
4157
4151 iwl4965_tx_queue_stop_scheduler(priv, txq_id); 4158 iwl4965_tx_queue_stop_scheduler(priv, txq_id);
4152 4159
4153 iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); 4160 iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id));
@@ -4161,6 +4168,8 @@ static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
4161 iwl4965_txq_ctx_deactivate(priv, txq_id); 4168 iwl4965_txq_ctx_deactivate(priv, txq_id);
4162 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); 4169 iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
4163 4170
4171 iwl4965_release_nic_access(priv);
4172
4164 return 0; 4173 return 0;
4165} 4174}
4166 4175
@@ -4630,7 +4639,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4630 int tx_fifo; 4639 int tx_fifo;
4631 int txq_id; 4640 int txq_id;
4632 int ssn = -1; 4641 int ssn = -1;
4633 int rc = 0; 4642 int ret = 0;
4634 unsigned long flags; 4643 unsigned long flags;
4635 struct iwl4965_tid_data *tid_data; 4644 struct iwl4965_tid_data *tid_data;
4636 DECLARE_MAC_BUF(mac); 4645 DECLARE_MAC_BUF(mac);
@@ -4663,12 +4672,12 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4663 spin_unlock_irqrestore(&priv->sta_lock, flags); 4672 spin_unlock_irqrestore(&priv->sta_lock, flags);
4664 4673
4665 *start_seq_num = ssn; 4674 *start_seq_num = ssn;
4666 rc = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, 4675 ret = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo,
4667 sta_id, tid, ssn); 4676 sta_id, tid, ssn);
4668 if (rc) 4677 if (ret)
4669 return rc; 4678 return ret;
4670 4679
4671 rc = 0; 4680 ret = 0;
4672 if (tid_data->tfds_in_queue == 0) { 4681 if (tid_data->tfds_in_queue == 0) {
4673 printk(KERN_ERR "HW queue is empty\n"); 4682 printk(KERN_ERR "HW queue is empty\n");
4674 tid_data->agg.state = IWL_AGG_ON; 4683 tid_data->agg.state = IWL_AGG_ON;
@@ -4678,7 +4687,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
4678 tid_data->tfds_in_queue); 4687 tid_data->tfds_in_queue);
4679 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; 4688 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
4680 } 4689 }
4681 return rc; 4690 return ret;
4682} 4691}
4683 4692
4684static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, 4693static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
@@ -4688,7 +4697,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
4688 struct iwl4965_priv *priv = hw->priv; 4697 struct iwl4965_priv *priv = hw->priv;
4689 int tx_fifo_id, txq_id, sta_id, ssn = -1; 4698 int tx_fifo_id, txq_id, sta_id, ssn = -1;
4690 struct iwl4965_tid_data *tid_data; 4699 struct iwl4965_tid_data *tid_data;
4691 int rc, write_ptr, read_ptr; 4700 int ret, write_ptr, read_ptr;
4692 unsigned long flags; 4701 unsigned long flags;
4693 DECLARE_MAC_BUF(mac); 4702 DECLARE_MAC_BUF(mac);
4694 4703
@@ -4728,17 +4737,11 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
4728 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 4737 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
4729 4738
4730 spin_lock_irqsave(&priv->lock, flags); 4739 spin_lock_irqsave(&priv->lock, flags);
4731 rc = iwl4965_grab_nic_access(priv); 4740 ret = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
4732 if (rc) {
4733 spin_unlock_irqrestore(&priv->lock, flags);
4734 return rc;
4735 }
4736 rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
4737 iwl4965_release_nic_access(priv);
4738 spin_unlock_irqrestore(&priv->lock, flags); 4741 spin_unlock_irqrestore(&priv->lock, flags);
4739 4742
4740 if (rc) 4743 if (ret)
4741 return rc; 4744 return ret;
4742 4745
4743 ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid); 4746 ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid);
4744 4747