提交 b095d03a 编写于 作者: R Ron Rindjunsky 提交者: John W. Linville

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: NMax Stepanov <max.stepanov@intel.com>
Signed-off-by: NEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: NRon Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: NTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 91c066f2
...@@ -4138,16 +4138,23 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv, ...@@ -4138,16 +4138,23 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl4965_priv *priv,
/** /**
* txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID * txq_id must be greater than IWL_BACK_QUEUE_FIRST_ID
* priv->lock must be held by the caller
*/ */
static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id, static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
u16 ssn_idx, u8 tx_fifo) u16 ssn_idx, u8 tx_fifo)
{ {
int ret = 0;
if (IWL_BACK_QUEUE_FIRST_ID > txq_id) { if (IWL_BACK_QUEUE_FIRST_ID > txq_id) {
IWL_WARNING("queue number too small: %d, must be > %d\n", IWL_WARNING("queue number too small: %d, must be > %d\n",
txq_id, IWL_BACK_QUEUE_FIRST_ID); txq_id, IWL_BACK_QUEUE_FIRST_ID);
return -EINVAL; return -EINVAL;
} }
ret = iwl4965_grab_nic_access(priv);
if (ret)
return ret;
iwl4965_tx_queue_stop_scheduler(priv, txq_id); iwl4965_tx_queue_stop_scheduler(priv, txq_id);
iwl4965_clear_bits_prph(priv, KDR_SCD_QUEUECHAIN_SEL, (1 << txq_id)); 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,6 +4168,8 @@ static int iwl4965_tx_queue_agg_disable(struct iwl4965_priv *priv, u16 txq_id,
iwl4965_txq_ctx_deactivate(priv, txq_id); iwl4965_txq_ctx_deactivate(priv, txq_id);
iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
iwl4965_release_nic_access(priv);
return 0; return 0;
} }
...@@ -4630,7 +4639,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da, ...@@ -4630,7 +4639,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
int tx_fifo; int tx_fifo;
int txq_id; int txq_id;
int ssn = -1; int ssn = -1;
int rc = 0; int ret = 0;
unsigned long flags; unsigned long flags;
struct iwl4965_tid_data *tid_data; struct iwl4965_tid_data *tid_data;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
...@@ -4663,12 +4672,12 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da, ...@@ -4663,12 +4672,12 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
spin_unlock_irqrestore(&priv->sta_lock, flags); spin_unlock_irqrestore(&priv->sta_lock, flags);
*start_seq_num = ssn; *start_seq_num = ssn;
rc = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo, ret = iwl4965_tx_queue_agg_enable(priv, txq_id, tx_fifo,
sta_id, tid, ssn); sta_id, tid, ssn);
if (rc) if (ret)
return rc; return ret;
rc = 0; ret = 0;
if (tid_data->tfds_in_queue == 0) { if (tid_data->tfds_in_queue == 0) {
printk(KERN_ERR "HW queue is empty\n"); printk(KERN_ERR "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON; 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,7 +4687,7 @@ static int iwl4965_mac_ht_tx_agg_start(struct ieee80211_hw *hw, const u8 *da,
tid_data->tfds_in_queue); tid_data->tfds_in_queue);
tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
} }
return rc; return ret;
} }
static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, 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,7 +4697,7 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
struct iwl4965_priv *priv = hw->priv; struct iwl4965_priv *priv = hw->priv;
int tx_fifo_id, txq_id, sta_id, ssn = -1; int tx_fifo_id, txq_id, sta_id, ssn = -1;
struct iwl4965_tid_data *tid_data; struct iwl4965_tid_data *tid_data;
int rc, write_ptr, read_ptr; int ret, write_ptr, read_ptr;
unsigned long flags; unsigned long flags;
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
...@@ -4728,17 +4737,11 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da, ...@@ -4728,17 +4737,11 @@ static int iwl4965_mac_ht_tx_agg_stop(struct ieee80211_hw *hw, const u8 *da,
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
rc = iwl4965_grab_nic_access(priv); ret = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
if (rc) {
spin_unlock_irqrestore(&priv->lock, flags);
return rc;
}
rc = iwl4965_tx_queue_agg_disable(priv, txq_id, ssn, tx_fifo_id);
iwl4965_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
if (rc) if (ret)
return rc; return ret;
ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid); ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, da, tid);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册