Skip to content

Commit

Permalink
iwl3945: Use iwlcore TX queue management routines
Browse files Browse the repository at this point in the history
By adding an additional hw_params (tfd_size) and a new iwl_lib ops (txq_init),
we can now use the iwlcore TX queue management routines.
We had to add a new hw_params because we need to allocate the right DMA buffer
for TFDs, and those have a different sizes depending if you're on 3945 or agn.

Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Samuel Ortiz authored and John W. Linville committed Jan 29, 2009
1 parent 59606ff commit a8e74e2
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 246 deletions.
8 changes: 5 additions & 3 deletions drivers/net/wireless/iwlwifi/iwl-3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -1068,8 +1068,8 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
txq_id);
if (rc) {
IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
Expand Down Expand Up @@ -1258,7 +1258,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)

/* Tx queues */
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
iwl_tx_queue_free(priv, txq_id);
}

void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
Expand Down Expand Up @@ -2491,6 +2491,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
return -ENOMEM;
}

priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
priv->hw_params.max_pkt_size = 2342;
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
Expand Down Expand Up @@ -2705,6 +2706,7 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
static struct iwl_lib_ops iwl3945_lib = {
.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl3945_hw_txq_free_tfd,
.txq_init = iwl3945_hw_tx_queue_init,
.load_ucode = iwl3945_load_bsm,
.apm_ops = {
.init = iwl3945_apm_init,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
Expand Down Expand Up @@ -2297,6 +2298,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_agg_disable = iwl4965_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl4965_rx_handler_setup,
.setup_deferred_work = iwl4965_setup_deferred_work,
.cancel_deferred_work = iwl4965_cancel_deferred_work,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
Expand Down Expand Up @@ -1494,6 +1495,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_agg_disable = iwl5000_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
.txq_init = iwl_hw_tx_queue_init,
.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,
Expand Down
32 changes: 32 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,38 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
return 0;
}

/*
* Tell nic where to find circular buffer of Tx Frame Descriptors for
* given Tx queue, and enable the DMA channel used for that queue.
*
* 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
* channels supported in hardware.
*/
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{
int ret;
unsigned long flags;
int txq_id = txq->q.id;

spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}

/* Circular buffer (TFD queue in DRAM) physical base address */
iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
txq->q.dma_addr >> 8);

iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);

return 0;
}


/******************************************************************************
*
* Misc. internal state and helper functions
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ struct iwl_lib_ops {
u16 len, u8 reset, u8 pad);
void (*txq_free_tfd)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
int (*txq_init)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
Expand Down Expand Up @@ -264,7 +266,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id);
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,7 @@ struct iwl_sensitivity_ranges {
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
* @tfd_size: TFD size
* @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
Expand All @@ -587,6 +588,7 @@ struct iwl_hw_params {
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
u32 tfd_size;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
Expand Down
49 changes: 10 additions & 39 deletions drivers/net/wireless/iwlwifi/iwl-tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
Expand All @@ -154,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)

/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
pci_free_consistent(dev, sizeof(struct iwl_tfd) *
pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);

/* De-alloc array of per-TFD driver data */
Expand All @@ -164,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}

EXPORT_SYMBOL(iwl_tx_queue_free);

/**
* iwl_cmd_queue_free - Deallocate DMA queue.
Expand Down Expand Up @@ -295,12 +295,12 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
txq->tfds = pci_alloc_consistent(dev,
sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX,
priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX,
&txq->q.dma_addr);

if (!txq->tfds) {
IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX);
priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX);
goto error;
}
txq->q.id = id;
Expand All @@ -314,42 +314,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
return -ENOMEM;
}

/*
* Tell nic where to find circular buffer of Tx Frame Descriptors for
* given Tx queue, and enable the DMA channel used for that queue.
*
* 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
* channels supported in hardware.
*/
static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
struct iwl_tx_queue *txq)
{
int ret;
unsigned long flags;
int txq_id = txq->q.id;

spin_lock_irqsave(&priv->lock, flags);
ret = iwl_grab_nic_access(priv);
if (ret) {
spin_unlock_irqrestore(&priv->lock, flags);
return ret;
}

/* Circular buffer (TFD queue in DRAM) physical base address */
iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
txq->q.dma_addr >> 8);

iwl_release_nic_access(priv);
spin_unlock_irqrestore(&priv->lock, flags);

return 0;
}

/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id)
int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
int slots_num, u32 txq_id)
{
int i, len;
int ret;
Expand Down Expand Up @@ -391,7 +360,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);

/* Tell device where to find queue */
iwl_hw_tx_queue_init(priv, txq);
priv->cfg->ops->lib->txq_init(priv, txq);

return 0;
err:
Expand All @@ -406,6 +375,8 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
}
return -ENOMEM;
}
EXPORT_SYMBOL(iwl_tx_queue_init);

/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
Expand Down
Loading

0 comments on commit a8e74e2

Please sign in to comment.