Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a8e74e27 authored by Samuel Ortiz's avatar Samuel Ortiz Committed by John W. Linville
Browse files

iwl3945: Use iwlcore TX queue management routines



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: default avatarSamuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 59606ffa
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -1068,7 +1068,7 @@ 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,
		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);
@@ -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)
@@ -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;
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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,
+2 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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,
+32 −0
Original line number Diff line number Diff line
@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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);
@@ -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);
Loading