diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2011-08-25 23:11:22 -0700 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-08-29 15:30:31 -0400 |
commit | ba562f71198a2cb03bb8d20640ffdf996275c3f0 (patch) | |
tree | 290875852ea56b90190e92db0a77017b01ca4d6a /drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | |
parent | 2c452297ff3eaafad41d24fa03d54a169ced8de1 (diff) |
iwlagn: set tx_fifo for ampdu in transport layer
the mapping tx_queue -> fifo is really transport related. The upper
layer should be involved in such things.
Note that upon agg_disable, the queue is always mapped to fifo 0, but
this doesn't matter since when the queue will be setup again for a
new BA session, it will be configured to the good fifo anyway.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c index cc518afd39e..96ad0afd185 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c @@ -424,8 +424,18 @@ void iwl_trans_tx_queue_set_status(struct iwl_priv *priv, scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); } -void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid, - int frame_limit) +static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid) +{ + if (likely(tid < ARRAY_SIZE(tid_to_ac))) + return ctx->ac_to_fifo[tid_to_ac[tid]]; + + /* no support for TIDs 8-15 yet */ + return -EINVAL; +} + +void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv, + enum iwl_rxon_context_id ctx, int sta_id, + int tid, int frame_limit) { int tx_fifo, txq_id, ssn_idx; u16 ra_tid; @@ -441,11 +451,16 @@ void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid, if (WARN_ON(tid >= IWL_MAX_TID_COUNT)) return; + tx_fifo = get_fifo_from_tid(&priv->contexts[ctx], tid); + if (WARN_ON(tx_fifo < 0)) { + IWL_ERR(trans, "txq_agg_setup, bad fifo: %d\n", tx_fifo); + return; + } + spin_lock_irqsave(&priv->shrd->sta_lock, flags); tid_data = &priv->shrd->tid_data[sta_id][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->shrd->sta_lock, flags); ra_tid = BUILD_RAxTID(sta_id, tid); @@ -492,8 +507,7 @@ void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid, spin_unlock_irqrestore(&priv->shrd->lock, flags); } -int iwl_trans_pcie_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, - u16 ssn_idx, u8 tx_fifo) +int iwl_trans_pcie_txq_agg_disable(struct iwl_priv *priv, u16 txq_id) { struct iwl_trans *trans = trans(priv); if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) || @@ -511,14 +525,14 @@ int iwl_trans_pcie_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, iwl_clear_bits_prph(bus(priv), SCD_AGGR_SEL, (1 << txq_id)); - priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff); - priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff); + priv->txq[txq_id].q.read_ptr = 0; + priv->txq[txq_id].q.write_ptr = 0; /* supposes that ssn_idx is valid (!= 0xFFF) */ - iwl_trans_set_wr_ptrs(trans, txq_id, ssn_idx); + iwl_trans_set_wr_ptrs(trans, txq_id, 0); iwl_clear_bits_prph(bus(priv), SCD_INTERRUPT_MASK, (1 << txq_id)); iwl_txq_ctx_deactivate(priv, txq_id); - iwl_trans_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0); + iwl_trans_tx_queue_set_status(priv, &priv->txq[txq_id], 0, 0); return 0; } |