diff mbox series

[6/6] wifi: iwlwifi: limit queue use independent of allocation

Message ID 20230601171633.1976517dabef.I87b84456adf6dcace25c1f663b4db752f9af67b7@changeid
State New
Headers show
Series wifi: iwlwifi: updates intended for v6.5 2023-06-01 | expand

Commit Message

Greenman, Gregory June 1, 2023, 2:20 p.m. UTC
From: Johannes Berg <johannes.berg@intel.com>

When using large queue sizes because of hardware workarounds, we
then shouldn't fill the queue according to the allocate size but
according to the desired size to avoid extra latency and lack of
A-MSDU aggregation.

This isn't pretty, but we can hopefully revert it once B-step is
there and we phase out A-step devices.

Fixes: bb16ffd561b6 ("iwlwifi: use 4k queue size for Bz A-step")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
---
 .../net/wireless/intel/iwlwifi/iwl-trans.h    |  2 ++
 drivers/net/wireless/intel/iwlwifi/queue/tx.c | 23 ++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
index 885581e636c7..7d0fa5eee4ea 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-trans.h
@@ -894,6 +894,7 @@  struct iwl_pcie_first_tb_buf {
  * @read_ptr: last used entry (index) host_r
  * @dma_addr:  physical addr for BD's
  * @n_window: safe queue window
+ * @n_reduced_win: reduced @n_window in case of HW allocation workarounds
  * @id: queue id
  * @low_mark: low watermark, resume queue if free space more than this
  * @high_mark: high watermark, stop queue if free space less than this
@@ -936,6 +937,7 @@  struct iwl_txq {
 	int read_ptr;
 	dma_addr_t dma_addr;
 	int n_window;
+	int n_reduced_win;
 	u32 id;
 	int low_mark;
 	int high_mark;
diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
index d1c39c214f95..a2d83c1201d5 100644
--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c
+++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c
@@ -685,8 +685,8 @@  int iwl_txq_space(struct iwl_trans *trans, const struct iwl_txq *q)
 	 * If q->n_window is smaller than max_tfd_queue_size, there is no need
 	 * to reserve any queue entries for this purpose.
 	 */
-	if (q->n_window < trans->trans_cfg->base_params->max_tfd_queue_size)
-		max = q->n_window;
+	if (q->n_reduced_win < trans->trans_cfg->base_params->max_tfd_queue_size)
+		max = q->n_reduced_win;
 	else
 		max = trans->trans_cfg->base_params->max_tfd_queue_size - 1;
 
@@ -899,6 +899,7 @@  static void iwl_txq_gen2_free(struct iwl_trans *trans, int txq_id)
 static int iwl_queue_init(struct iwl_txq *q, int slots_num)
 {
 	q->n_window = slots_num;
+	q->n_reduced_win = slots_num;
 
 	/* slots_num must be power-of-two size, otherwise
 	 * iwl_txq_get_cmd_index is broken. */
@@ -1037,6 +1038,7 @@  int iwl_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num,
 	txq->trans = trans;
 
 	txq->n_window = slots_num;
+	txq->n_reduced_win = slots_num;
 
 	txq->entries = kcalloc(slots_num,
 			       sizeof(struct iwl_pcie_txq_entry),
@@ -1197,16 +1199,31 @@  int iwl_txq_dyn_alloc(struct iwl_trans *trans, u32 flags, u32 sta_mask,
 	struct iwl_host_cmd hcmd = {
 		.flags = CMD_WANT_SKB,
 	};
+	int org_size = 0;
 	int ret;
 
 	if (trans->trans_cfg->device_family == IWL_DEVICE_FAMILY_BZ &&
-	    trans->hw_rev_step == SILICON_A_STEP)
+	    trans->hw_rev_step == SILICON_A_STEP) {
+		org_size = size;
 		size = 4096;
+	}
 
 	txq = iwl_txq_dyn_alloc_dma(trans, size, timeout);
 	if (IS_ERR(txq))
 		return PTR_ERR(txq);
 
+	if (org_size) {
+		txq->n_reduced_win = org_size;
+
+		txq->low_mark = org_size / 4;
+		if (txq->low_mark < 4)
+			txq->low_mark = 4;
+
+		txq->high_mark = org_size / 8;
+		if (txq->high_mark < 2)
+			txq->high_mark = 2;
+	}
+
 	if (trans->txqs.queue_alloc_cmd_ver == 0) {
 		memset(&cmd.old, 0, sizeof(cmd.old));
 		cmd.old.tfdq_addr = cpu_to_le64(txq->dma_addr);