|
@@ -222,13 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
|
|
|
scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
|
|
|
}
|
|
|
|
|
|
-static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
|
|
- int tx_fifo, int sta_id, int tid, u16 ssn_idx)
|
|
|
+static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
|
|
|
{
|
|
|
- unsigned long flags;
|
|
|
- u16 ra_tid;
|
|
|
- int ret;
|
|
|
-
|
|
|
if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
|
|
|
(IWLAGN_FIRST_AMPDU_QUEUE +
|
|
|
priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
|
|
@@ -240,12 +235,33 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- ra_tid = BUILD_RAxTID(sta_id, tid);
|
|
|
-
|
|
|
/* Modify device's station table to Tx this TID */
|
|
|
- ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
|
|
|
- if (ret)
|
|
|
- return ret;
|
|
|
+ return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
|
|
|
+}
|
|
|
+
|
|
|
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
|
|
|
+ struct ieee80211_sta *sta,
|
|
|
+ int tid, int frame_limit)
|
|
|
+{
|
|
|
+ int sta_id, tx_fifo, txq_id, ssn_idx;
|
|
|
+ u16 ra_tid;
|
|
|
+ unsigned long flags;
|
|
|
+ struct iwl_tid_data *tid_data;
|
|
|
+
|
|
|
+ sta_id = iwl_sta_id(sta);
|
|
|
+ if (WARN_ON(sta_id == IWL_INVALID_STATION))
|
|
|
+ return;
|
|
|
+ if (WARN_ON(tid >= MAX_TID_COUNT))
|
|
|
+ return;
|
|
|
+
|
|
|
+ spin_lock_irqsave(&priv->sta_lock, flags);
|
|
|
+ tid_data = &priv->stations[sta_id].tid[tid];
|
|
|
+ ssn_idx = SEQ_TO_SN(tid_data->seq_number);
|
|
|
+ txq_id = tid_data->agg.txq_id;
|
|
|
+ tx_fifo = tid_data->agg.tx_fifo;
|
|
|
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
|
|
|
+
|
|
|
+ ra_tid = BUILD_RAxTID(sta_id, tid);
|
|
|
|
|
|
spin_lock_irqsave(&priv->lock, flags);
|
|
|
|
|
@@ -271,10 +287,10 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
|
|
iwl_write_targ_mem(priv, priv->scd_base_addr +
|
|
|
IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
|
|
|
sizeof(u32),
|
|
|
- ((SCD_WIN_SIZE <<
|
|
|
+ ((frame_limit <<
|
|
|
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
|
|
|
IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
|
|
|
- ((SCD_FRAME_LIMIT <<
|
|
|
+ ((frame_limit <<
|
|
|
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
|
|
|
IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
|
|
|
|
|
@@ -284,8 +300,6 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
|
|
|
iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
|
|
|
|
|
|
spin_unlock_irqrestore(&priv->lock, flags);
|
|
|
-
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
|
|
@@ -1034,10 +1048,11 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
|
|
|
tid_data = &priv->stations[sta_id].tid[tid];
|
|
|
*ssn = SEQ_TO_SN(tid_data->seq_number);
|
|
|
tid_data->agg.txq_id = txq_id;
|
|
|
+ tid_data->agg.tx_fifo = tx_fifo;
|
|
|
iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
|
|
|
spin_unlock_irqrestore(&priv->sta_lock, flags);
|
|
|
|
|
|
- ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn);
|
|
|
+ ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
|
|
|
if (ret)
|
|
|
return ret;
|
|
|
|