Commit 39fff759 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Luca Coelho

iwlwifi: pcie: don't init a Tx queue with an SSN > size of the queue

The TVQM tells us the initial write pointer for a queue,
but that write pointer is in WiFi sequence number unit
and not in TFD index unit. Which means that the write
pointer in the TVQM's response can be bigger than the
Tx queue ring size.

Fix that by modulo'ing the write pointer from the TVQM
with the Tx queue size.

Fixes: 66128fa08806 ("iwlwifi: move to TVQM mode")
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 732d06e9
...@@ -1033,6 +1033,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1033,6 +1033,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
.flags = CMD_WANT_SKB, .flags = CMD_WANT_SKB,
}; };
int ret, qid; int ret, qid;
u32 wr_ptr;
txq = kzalloc(sizeof(*txq), GFP_KERNEL); txq = kzalloc(sizeof(*txq), GFP_KERNEL);
if (!txq) if (!txq)
...@@ -1073,6 +1074,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1073,6 +1074,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
rsp = (void *)hcmd.resp_pkt->data; rsp = (void *)hcmd.resp_pkt->data;
qid = le16_to_cpu(rsp->queue_number); qid = le16_to_cpu(rsp->queue_number);
wr_ptr = le16_to_cpu(rsp->write_pointer);
if (qid >= ARRAY_SIZE(trans_pcie->txq)) { if (qid >= ARRAY_SIZE(trans_pcie->txq)) {
WARN_ONCE(1, "queue index %d unsupported", qid); WARN_ONCE(1, "queue index %d unsupported", qid);
...@@ -1088,10 +1090,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1088,10 +1090,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
txq->id = qid; txq->id = qid;
trans_pcie->txq[qid] = txq; trans_pcie->txq[qid] = txq;
wr_ptr &= (TFD_QUEUE_SIZE_MAX - 1);
/* Place first TFD at index corresponding to start sequence number */ /* Place first TFD at index corresponding to start sequence number */
txq->read_ptr = le16_to_cpu(rsp->write_pointer); txq->read_ptr = wr_ptr;
txq->write_ptr = le16_to_cpu(rsp->write_pointer); txq->write_ptr = wr_ptr;
iwl_write_direct32(trans, HBUS_TARG_WRPTR, iwl_write_direct32(trans, HBUS_TARG_WRPTR,
(txq->write_ptr) | (qid << 16)); (txq->write_ptr) | (qid << 16));
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
......
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