Commit 8e08e191 authored by Johannes Berg's avatar Johannes Berg Committed by Luca Coelho

iwlwifi: pcie: remove TR/CR tail allocations

The TR/CR tail data are meant to be per-queue-arrays, however,
we allocate them completely wrong (we have a separate allocation
per queue).

Looking at this more closely, it turns out that the hardware
never uses these - we have a separate free list per RX queue
and maintain a write pointer for that in a register, and the
RX itself is indicated in the RB status (rb_stts) DMA region.

Despite nothing using the tail pointers, the hardware will
unconditionally access them to write updates, even when we aren't
using CRs/TRs.

Give it dummy values that we never use/update so it can do that
without causing trouble.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20210617110647.5f5764e04c46.I4d5de1929be048085767f1234a1e07b517ab6a2d@changeidSigned-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent bef99c7d
...@@ -138,8 +138,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, ...@@ -138,8 +138,15 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
/* Allocate prph information /* Allocate prph information
* currently we don't assign to the prph info anything, but it would get * currently we don't assign to the prph info anything, but it would get
* assigned later */ * assigned later
prph_info = dma_alloc_coherent(trans->dev, sizeof(*prph_info), *
* We also use the second half of this page to give the device some
* dummy TR/CR tail pointers - which shouldn't be necessary as we don't
* use this, but the hardware still reads/writes there and we can't let
* it go do that with a NULL pointer.
*/
BUILD_BUG_ON(sizeof(*prph_info) > PAGE_SIZE / 2);
prph_info = dma_alloc_coherent(trans->dev, PAGE_SIZE,
&trans_pcie->prph_info_dma_addr, &trans_pcie->prph_info_dma_addr,
GFP_KERNEL); GFP_KERNEL);
if (!prph_info) { if (!prph_info) {
...@@ -166,13 +173,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, ...@@ -166,13 +173,9 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
ctxt_info_gen3->cr_head_idx_arr_base_addr = ctxt_info_gen3->cr_head_idx_arr_base_addr =
cpu_to_le64(trans_pcie->rxq->rb_stts_dma); cpu_to_le64(trans_pcie->rxq->rb_stts_dma);
ctxt_info_gen3->tr_tail_idx_arr_base_addr = ctxt_info_gen3->tr_tail_idx_arr_base_addr =
cpu_to_le64(trans_pcie->rxq->tr_tail_dma); cpu_to_le64(trans_pcie->prph_info_dma_addr + PAGE_SIZE / 2);
ctxt_info_gen3->cr_tail_idx_arr_base_addr = ctxt_info_gen3->cr_tail_idx_arr_base_addr =
cpu_to_le64(trans_pcie->rxq->cr_tail_dma); cpu_to_le64(trans_pcie->prph_info_dma_addr + 3 * PAGE_SIZE / 4);
ctxt_info_gen3->cr_idx_arr_size =
cpu_to_le16(IWL_NUM_OF_COMPLETION_RINGS);
ctxt_info_gen3->tr_idx_arr_size =
cpu_to_le16(IWL_NUM_OF_TRANSFER_RINGS);
ctxt_info_gen3->mtr_base_addr = ctxt_info_gen3->mtr_base_addr =
cpu_to_le64(trans->txqs.txq[trans->txqs.cmd.q_id]->dma_addr); cpu_to_le64(trans->txqs.txq[trans->txqs.cmd.q_id]->dma_addr);
ctxt_info_gen3->mcr_base_addr = ctxt_info_gen3->mcr_base_addr =
...@@ -216,9 +219,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans, ...@@ -216,9 +219,7 @@ int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
trans_pcie->ctxt_info_dma_addr); trans_pcie->ctxt_info_dma_addr);
trans_pcie->ctxt_info_gen3 = NULL; trans_pcie->ctxt_info_gen3 = NULL;
err_free_prph_info: err_free_prph_info:
dma_free_coherent(trans->dev, dma_free_coherent(trans->dev, PAGE_SIZE, prph_info,
sizeof(*prph_info),
prph_info,
trans_pcie->prph_info_dma_addr); trans_pcie->prph_info_dma_addr);
err_free_prph_scratch: err_free_prph_scratch:
...@@ -251,8 +252,7 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans) ...@@ -251,8 +252,7 @@ void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
trans_pcie->prph_scratch_dma_addr = 0; trans_pcie->prph_scratch_dma_addr = 0;
trans_pcie->prph_scratch = NULL; trans_pcie->prph_scratch = NULL;
dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_info), dma_free_coherent(trans->dev, PAGE_SIZE, trans_pcie->prph_info,
trans_pcie->prph_info,
trans_pcie->prph_info_dma_addr); trans_pcie->prph_info_dma_addr);
trans_pcie->prph_info_dma_addr = 0; trans_pcie->prph_info_dma_addr = 0;
trans_pcie->prph_info = NULL; trans_pcie->prph_info = NULL;
......
...@@ -111,10 +111,6 @@ struct iwl_rx_completion_desc { ...@@ -111,10 +111,6 @@ struct iwl_rx_completion_desc {
* @bd_dma: bus address of buffer of receive buffer descriptors (rbd) * @bd_dma: bus address of buffer of receive buffer descriptors (rbd)
* @used_bd: driver's pointer to buffer of used receive buffer descriptors (rbd) * @used_bd: driver's pointer to buffer of used receive buffer descriptors (rbd)
* @used_bd_dma: physical address of buffer of used receive buffer descriptors (rbd) * @used_bd_dma: physical address of buffer of used receive buffer descriptors (rbd)
* @tr_tail: driver's pointer to the transmission ring tail buffer
* @tr_tail_dma: physical address of the buffer for the transmission ring tail
* @cr_tail: driver's pointer to the completion ring tail buffer
* @cr_tail_dma: physical address of the buffer for the completion ring tail
* @read: Shared index to newest available Rx buffer * @read: Shared index to newest available Rx buffer
* @write: Shared index to oldest written Rx packet * @write: Shared index to oldest written Rx packet
* @free_count: Number of pre-allocated buffers in rx_free * @free_count: Number of pre-allocated buffers in rx_free
...@@ -142,10 +138,6 @@ struct iwl_rxq { ...@@ -142,10 +138,6 @@ struct iwl_rxq {
struct iwl_rx_completion_desc *cd; struct iwl_rx_completion_desc *cd;
}; };
dma_addr_t used_bd_dma; dma_addr_t used_bd_dma;
__le16 *tr_tail;
dma_addr_t tr_tail_dma;
__le16 *cr_tail;
dma_addr_t cr_tail_dma;
u32 read; u32 read;
u32 write; u32 write;
u32 free_count; u32 free_count;
...@@ -533,9 +525,6 @@ static inline void _iwl_disable_interrupts(struct iwl_trans *trans) ...@@ -533,9 +525,6 @@ static inline void _iwl_disable_interrupts(struct iwl_trans *trans)
IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); IWL_DEBUG_ISR(trans, "Disabled interrupts\n");
} }
#define IWL_NUM_OF_COMPLETION_RINGS 31
#define IWL_NUM_OF_TRANSFER_RINGS 527
static inline int iwl_pcie_get_num_sections(const struct fw_img *fw, static inline int iwl_pcie_get_num_sections(const struct fw_img *fw,
int start) int start)
{ {
......
...@@ -663,7 +663,6 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td) ...@@ -663,7 +663,6 @@ static int iwl_pcie_free_bd_size(struct iwl_trans *trans, bool use_rx_td)
static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
struct iwl_rxq *rxq) struct iwl_rxq *rxq)
{ {
struct device *dev = trans->dev;
bool use_rx_td = (trans->trans_cfg->device_family >= bool use_rx_td = (trans->trans_cfg->device_family >=
IWL_DEVICE_FAMILY_AX210); IWL_DEVICE_FAMILY_AX210);
int free_size = iwl_pcie_free_bd_size(trans, use_rx_td); int free_size = iwl_pcie_free_bd_size(trans, use_rx_td);
...@@ -685,21 +684,6 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans, ...@@ -685,21 +684,6 @@ static void iwl_pcie_free_rxq_dma(struct iwl_trans *trans,
rxq->used_bd, rxq->used_bd_dma); rxq->used_bd, rxq->used_bd_dma);
rxq->used_bd_dma = 0; rxq->used_bd_dma = 0;
rxq->used_bd = NULL; rxq->used_bd = NULL;
if (trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_AX210)
return;
if (rxq->tr_tail)
dma_free_coherent(dev, sizeof(__le16),
rxq->tr_tail, rxq->tr_tail_dma);
rxq->tr_tail_dma = 0;
rxq->tr_tail = NULL;
if (rxq->cr_tail)
dma_free_coherent(dev, sizeof(__le16),
rxq->cr_tail, rxq->cr_tail_dma);
rxq->cr_tail_dma = 0;
rxq->cr_tail = NULL;
} }
static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
...@@ -744,21 +728,6 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans, ...@@ -744,21 +728,6 @@ static int iwl_pcie_alloc_rxq_dma(struct iwl_trans *trans,
rxq->rb_stts_dma = rxq->rb_stts_dma =
trans_pcie->base_rb_stts_dma + rxq->id * rb_stts_size; trans_pcie->base_rb_stts_dma + rxq->id * rb_stts_size;
if (!use_rx_td)
return 0;
/* Allocate the driver's pointer to TR tail */
rxq->tr_tail = dma_alloc_coherent(dev, sizeof(__le16),
&rxq->tr_tail_dma, GFP_KERNEL);
if (!rxq->tr_tail)
goto err;
/* Allocate the driver's pointer to CR tail */
rxq->cr_tail = dma_alloc_coherent(dev, sizeof(__le16),
&rxq->cr_tail_dma, GFP_KERNEL);
if (!rxq->cr_tail)
goto err;
return 0; return 0;
err: err:
...@@ -1590,9 +1559,6 @@ static int iwl_pcie_rx_handle(struct iwl_trans *trans, int queue, int budget) ...@@ -1590,9 +1559,6 @@ static int iwl_pcie_rx_handle(struct iwl_trans *trans, int queue, int budget)
out: out:
/* Backtrack one entry */ /* Backtrack one entry */
rxq->read = i; rxq->read = i;
/* update cr tail with the rxq read pointer */
if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
*rxq->cr_tail = cpu_to_le16(r);
spin_unlock(&rxq->lock); spin_unlock(&rxq->lock);
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment