aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 23e5667108e2..fb63a03a395e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -222,13 +222,8 @@ void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
222 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); 222 scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
223} 223}
224 224
225static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, 225static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
226 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
227{ 226{
228 unsigned long flags;
229 u16 ra_tid;
230 int ret;
231
232 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || 227 if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
233 (IWLAGN_FIRST_AMPDU_QUEUE + 228 (IWLAGN_FIRST_AMPDU_QUEUE +
234 priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) { 229 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,
240 return -EINVAL; 235 return -EINVAL;
241 } 236 }
242 237
243 ra_tid = BUILD_RAxTID(sta_id, tid);
244
245 /* Modify device's station table to Tx this TID */ 238 /* Modify device's station table to Tx this TID */
246 ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid); 239 return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
247 if (ret) 240}
248 return ret; 241
242void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
243 struct ieee80211_sta *sta,
244 int tid, int frame_limit)
245{
246 int sta_id, tx_fifo, txq_id, ssn_idx;
247 u16 ra_tid;
248 unsigned long flags;
249 struct iwl_tid_data *tid_data;
250
251 sta_id = iwl_sta_id(sta);
252 if (WARN_ON(sta_id == IWL_INVALID_STATION))
253 return;
254 if (WARN_ON(tid >= MAX_TID_COUNT))
255 return;
256
257 spin_lock_irqsave(&priv->sta_lock, flags);
258 tid_data = &priv->stations[sta_id].tid[tid];
259 ssn_idx = SEQ_TO_SN(tid_data->seq_number);
260 txq_id = tid_data->agg.txq_id;
261 tx_fifo = tid_data->agg.tx_fifo;
262 spin_unlock_irqrestore(&priv->sta_lock, flags);
263
264 ra_tid = BUILD_RAxTID(sta_id, tid);
249 265
250 spin_lock_irqsave(&priv->lock, flags); 266 spin_lock_irqsave(&priv->lock, flags);
251 267
@@ -271,10 +287,10 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
271 iwl_write_targ_mem(priv, priv->scd_base_addr + 287 iwl_write_targ_mem(priv, priv->scd_base_addr +
272 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + 288 IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
273 sizeof(u32), 289 sizeof(u32),
274 ((SCD_WIN_SIZE << 290 ((frame_limit <<
275 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) & 291 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
276 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) | 292 IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
277 ((SCD_FRAME_LIMIT << 293 ((frame_limit <<
278 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & 294 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
279 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); 295 IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
280 296
@@ -284,8 +300,6 @@ static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
284 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1); 300 iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
285 301
286 spin_unlock_irqrestore(&priv->lock, flags); 302 spin_unlock_irqrestore(&priv->lock, flags);
287
288 return 0;
289} 303}
290 304
291static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 305static 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,
1034 tid_data = &priv->stations[sta_id].tid[tid]; 1048 tid_data = &priv->stations[sta_id].tid[tid];
1035 *ssn = SEQ_TO_SN(tid_data->seq_number); 1049 *ssn = SEQ_TO_SN(tid_data->seq_number);
1036 tid_data->agg.txq_id = txq_id; 1050 tid_data->agg.txq_id = txq_id;
1051 tid_data->agg.tx_fifo = tx_fifo;
1037 iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id); 1052 iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
1038 spin_unlock_irqrestore(&priv->sta_lock, flags); 1053 spin_unlock_irqrestore(&priv->sta_lock, flags);
1039 1054
1040 ret = iwlagn_txq_agg_enable(priv, txq_id, tx_fifo, sta_id, tid, *ssn); 1055 ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
1041 if (ret) 1056 if (ret)
1042 return ret; 1057 return ret;
1043 1058