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>
This commit is contained in:
committed by
John W. Linville
parent
91c066f27b
commit
b095d03a7d
@@ -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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user