From: Zhu Yi <yi.zhu@intel.com>
To: linville@tuxdriver.com
Cc: linux-wireless@vger.kernel.org, Tomas Winkler <tomas.winkler@intel.com>
Subject: [PATCH 06/29] iwlwifi: add TX aggregation code for 5000 HW
Date: Thu, 12 Jun 2008 09:46:56 +0800 [thread overview]
Message-ID: <1213235239-2954-7-git-send-email-yi.zhu@intel.com> (raw)
In-Reply-To: <1213235239-2954-6-git-send-email-yi.zhu@intel.com>
From: Tomas Winkler <tomas.winkler@intel.com>
This patch adds TX aggregation handler for 5000 HW.
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
---
drivers/net/wireless/iwlwifi/iwl-5000.c | 132 +++++++++++++++++++++++++++++++
1 files changed, 132 insertions(+), 0 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 0ae5421..d3c0e10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -41,6 +41,7 @@
#include "iwl-dev.h"
#include "iwl-core.h"
#include "iwl-io.h"
+#include "iwl-sta.h"
#include "iwl-helpers.h"
#include "iwl-5000-hw.h"
@@ -976,6 +977,135 @@ static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
}
}
+static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
+ u16 txq_id)
+{
+ u32 tbl_dw_addr;
+ u32 tbl_dw;
+ u16 scd_q2ratid;
+
+ scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
+
+ tbl_dw_addr = priv->scd_base_addr +
+ IWL50_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
+
+ tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
+
+ if (txq_id & 0x1)
+ tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
+ else
+ tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
+
+ iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
+
+ return 0;
+}
+static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
+{
+ /* Simply stop the queue, but don't change any configuration;
+ * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
+ iwl_write_prph(priv,
+ IWL50_SCD_QUEUE_STATUS_BITS(txq_id),
+ (0 << IWL50_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
+ (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
+}
+
+static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
+ int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+{
+ unsigned long flags;
+ int ret;
+ u16 ra_tid;
+
+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id)
+ IWL_WARNING("queue number too small: %d, must be > %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE);
+
+ ra_tid = BUILD_RAxTID(sta_id, tid);
+
+ /* Modify device's station table to Tx this TID */
+ iwl_sta_modify_enable_tid_tx(priv, sta_id, tid);
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Stop this Tx queue before configuring it */
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ /* Map receiver-address / traffic-ID to this queue */
+ iwl5000_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
+
+ /* Set this queue as a chain-building queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_QUEUECHAIN_SEL, (1<<txq_id));
+
+ /* enable aggregations for the queue */
+ iwl_set_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1<<txq_id));
+
+ /* Place first TFD at index corresponding to start sequence number.
+ * Assumes that ssn_idx is valid (!= 0xFFF) */
+ priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
+ priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ /* Set up Tx window size and frame limit for this queue */
+ iwl_write_targ_mem(priv, priv->scd_base_addr +
+ IWL50_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
+ sizeof(u32),
+ ((SCD_WIN_SIZE <<
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
+ ((SCD_FRAME_LIMIT <<
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
+ IWL50_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
+
+ iwl_set_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+
+ /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+ u16 ssn_idx, u8 tx_fifo)
+{
+ int ret;
+
+ if (IWL50_FIRST_AMPDU_QUEUE > txq_id) {
+ IWL_WARNING("queue number too small: %d, must be > %d\n",
+ txq_id, IWL50_FIRST_AMPDU_QUEUE);
+ return -EINVAL;
+ }
+
+ ret = iwl_grab_nic_access(priv);
+ if (ret)
+ return ret;
+
+ iwl5000_tx_queue_stop_scheduler(priv, txq_id);
+
+ iwl_clear_bits_prph(priv, IWL50_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);
+ /* supposes that ssn_idx is valid (!= 0xFFF) */
+ iwl5000_set_wr_ptrs(priv, txq_id, ssn_idx);
+
+ iwl_clear_bits_prph(priv, IWL50_SCD_INTERRUPT_MASK, (1 << txq_id));
+ iwl_txq_ctx_deactivate(priv, txq_id);
+ iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
+
+ iwl_release_nic_access(priv);
+
+ return 0;
+}
+
static u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
{
u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -1319,6 +1449,8 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
.txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
.txq_set_sched = iwl5000_txq_set_sched,
+ .txq_agg_enable = iwl5000_txq_agg_enable,
+ .txq_agg_disable = iwl5000_txq_agg_disable,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
--
1.5.3.6
next prev parent reply other threads:[~2008-06-12 1:49 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-12 1:46 [PATCH 00/29] iwlwifi driver 06/12 updates Zhu Yi
2008-06-12 1:46 ` [PATCH 01/29] iwlwifi: removing IWL4965_HT config Zhu Yi
2008-06-12 1:46 ` [PATCH 02/29] iwlwifi: removes the RUN_TIME_CALIB ifdef Zhu Yi
2008-06-12 1:46 ` [PATCH 03/29] iwlwifi: clean up in setup/cancel deferred work Zhu Yi
2008-06-12 1:46 ` [PATCH 04/29] iwlwifi: add possibility to disable tx_power calibration Zhu Yi
2008-06-12 1:46 ` [PATCH 05/29] iwlwifi: map sw and hw ampdu queues Zhu Yi
2008-06-12 1:46 ` Zhu Yi [this message]
2008-06-12 1:46 ` [PATCH 07/29] iwlwifi: use ieee80211_conf to examine rate capabilities Zhu Yi
2008-06-12 1:46 ` [PATCH 08/29] iwlwifi: fix allow iwlwifi to aggregate according to tid load Zhu Yi
2008-06-12 1:46 ` [PATCH 09/29] iwlwifi: remove unused flag Zhu Yi
2008-06-12 1:47 ` [PATCH 10/29] iwlwifi: remove redundant flags regarding to FAT channel Zhu Yi
2008-06-12 1:47 ` [PATCH 11/29] iwlwifi: fix bug when moving from 11gn to 11a or 11an to 11g Zhu Yi
2008-06-12 1:47 ` [PATCH 12/29] iwlwifi: format log prints for easier parsing Zhu Yi
2008-06-12 1:47 ` [PATCH 13/29] iwlwifi: fix resume SW RF-kill Zhu Yi
2008-06-12 1:47 ` [PATCH 14/29] iwlwifi: fix resart flow after fw error Zhu Yi
2008-06-12 1:47 ` [PATCH 15/29] iwlwifi enabling IBSS (Ad-Hoc) mode Zhu Yi
2008-06-12 1:47 ` [PATCH 16/29] iwlwifi: Fix mode changes (ad-hoc <--> managed) Zhu Yi
2008-06-12 1:47 ` [PATCH 17/29] iwlwifi: refactor tx aggregation response flow Zhu Yi
2008-06-12 1:47 ` [PATCH 18/29] iwlwifi: refactor setting tx power Zhu Yi
2008-06-12 1:47 ` [PATCH 19/29] iwlwifi: add bad length check for WEP keys Zhu Yi
2008-06-12 1:47 ` [PATCH 20/29] iwlwifi: move scan to iwl-scan.c iwlcore Zhu Yi
2008-06-12 1:47 ` [PATCH 21/29] iwlwifi: move rate helpers to iwlcore Zhu Yi
2008-06-12 1:47 ` [PATCH 22/29] iwlwifi: cleans up scanning code Zhu Yi
2008-06-12 1:47 ` [PATCH 23/29] iwlwifi: move iwl4965_rf_kill_ct_config to iwl-core.c Zhu Yi
2008-06-12 1:47 ` [PATCH 24/29] iwlwifi: retfactor get_temperature functions Zhu Yi
2008-06-12 1:47 ` [PATCH 25/29] iwlwifi: remove dead code iwl4965_calc_db_from_ratio Zhu Yi
2008-06-12 1:47 ` [PATCH 26/29] mac80211 : fix for iwconfig in ad-hoc mode Zhu Yi
2008-06-12 1:47 ` [PATCH 27/29] iwlwifi: fix software rf_kill problem when interface is down Zhu Yi
2008-06-12 1:47 ` [PATCH 28/29] iwlwifi: general code clean up Zhu Yi
2008-06-12 1:47 ` [PATCH 29/29] iwlwifi: remove iwlcore_low_level_notify Zhu Yi
2008-06-12 2:14 ` [PATCH 26/29] mac80211 : fix for iwconfig in ad-hoc mode Dan Williams
2008-06-12 5:15 ` [PATCH 00/29] iwlwifi driver 06/12 updates Harvey Harrison
2008-06-12 5:26 ` Zhu Yi
2008-06-12 14:00 ` John W. Linville
2008-06-13 1:30 ` Zhu Yi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1213235239-2954-7-git-send-email-yi.zhu@intel.com \
--to=yi.zhu@intel.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=tomas.winkler@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).