diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2008-03-06 20:36:56 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-03-07 16:03:02 -0500 |
commit | b095d03a7d724db7379b73f64b6035f7be2e0a7c (patch) | |
tree | d1a5eb99c7e67b04b1e4fb320bd8771c9a18f09d | |
parent | 91c066f27b6dacb6589fb5190af373fb9f993397 (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.c | 37 |
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 | */ |
4142 | static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, | 4143 | static 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 | ||
4684 | static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, | 4693 | static 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 | ||