57 lines
1.9 KiB
Diff
57 lines
1.9 KiB
Diff
|
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||
|
|
||
|
When a queue is disabled, it frees all its entries. Later,
|
||
|
the op_mode might still get notifications from the firmware
|
||
|
that triggers to free entries in the tx queue. The transport
|
||
|
should be prepared for these races and know to ignore
|
||
|
reclaim calls on queues that have been disabled and whose
|
||
|
entries have been freed.
|
||
|
|
||
|
Cc: stable@vger.kernel.org
|
||
|
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||
|
---
|
||
|
drivers/net/wireless/iwlwifi/pcie/tx.c | 10 ++++++++++
|
||
|
1 file changed, 10 insertions(+)
|
||
|
|
||
|
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
|
||
|
index cb5c679..faaf77c 100644
|
||
|
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
|
||
|
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
|
||
|
@@ -578,9 +578,12 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
|
||
|
|
||
|
spin_lock_bh(&txq->lock);
|
||
|
while (q->write_ptr != q->read_ptr) {
|
||
|
+ IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
|
||
|
+ txq_id, q->read_ptr);
|
||
|
iwl_pcie_txq_free_tfd(trans, txq);
|
||
|
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
|
||
|
}
|
||
|
+ txq->active = false;
|
||
|
spin_unlock_bh(&txq->lock);
|
||
|
}
|
||
|
|
||
|
@@ -929,6 +932,12 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
|
||
|
|
||
|
spin_lock_bh(&txq->lock);
|
||
|
|
||
|
+ if (!txq->active) {
|
||
|
+ IWL_DEBUG_TX_QUEUES(trans, "Q %d inactive - ignoring idx %d\n",
|
||
|
+ txq_id, ssn);
|
||
|
+ goto out;
|
||
|
+ }
|
||
|
+
|
||
|
if (txq->q.read_ptr == tfd_num)
|
||
|
goto out;
|
||
|
|
||
|
@@ -1105,6 +1114,7 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,
|
||
|
(fifo << SCD_QUEUE_STTS_REG_POS_TXF) |
|
||
|
(1 << SCD_QUEUE_STTS_REG_POS_WSL) |
|
||
|
SCD_QUEUE_STTS_REG_MSK);
|
||
|
+ trans_pcie->txq[txq_id].active = true;
|
||
|
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d on FIFO %d WrPtr: %d\n",
|
||
|
txq_id, fifo, ssn & 0xff);
|
||
|
}
|
||
|
--
|
||
|
1.7.11.7
|