Browse Source

qcacmn: Support multiple TX rings in DP interrupt handler

In dp_service_srngs, the current logic assumes that WBM2SWRELEASE ring
number as obtained from interrupt_ctx->tx_mask matches the index of
soc->tx_comp[] array. However this may not be true, esp for HMT.
Add logic to fix the same.

Use a separate macro to enable use of single TX ring.

Change-Id: I1bee27b800ad4e4ab1a1fe5e2b01b5b43acfe1f7
CRs-Fixed: 2984362
Mohit Khanna 4 years ago
parent
commit
c75f9cc178
3 changed files with 25 additions and 23 deletions
  1. 5 1
      dp/inc/cdp_txrx_mob_def.h
  2. 19 21
      dp/wifi3.0/dp_main.c
  3. 1 1
      wlan_cfg/wlan_cfg.c

+ 5 - 1
dp/inc/cdp_txrx_mob_def.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -24,6 +24,10 @@
 #define TX_WMM_AC_NUM	4
 #define ENABLE_DP_HIST_STATS
 #define DP_MEMORY_OPT
+#ifndef CONFIG_BERYLLIUM
+#define DP_USE_SINGLE_TCL
+#endif
+
 #define DP_RX_DISABLE_NDI_MDNS_FORWARDING
 
 #define OL_TXQ_PAUSE_REASON_FW                (1 << 0)

+ 19 - 21
dp/wifi3.0/dp_main.c

@@ -2321,6 +2321,7 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 	struct dp_intr_stats *intr_stats = &int_ctx->intr_stats;
 	struct dp_soc *soc = int_ctx->soc;
 	int ring = 0;
+	int index;
 	uint32_t work_done  = 0;
 	int budget = dp_budget;
 	uint8_t tx_mask = int_ctx->tx_ring_mask;
@@ -2338,28 +2339,25 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 			 int_ctx->rxdma2host_ring_mask);
 
 	/* Process Tx completion interrupts first to return back buffers */
-	while (tx_mask) {
-		if (tx_mask & 0x1) {
-			work_done = dp_tx_comp_handler(int_ctx,
-						       soc,
-						       soc->tx_comp_ring[ring].hal_srng,
-						       ring, remaining_quota);
-
-			if (work_done) {
-				intr_stats->num_tx_ring_masks[ring]++;
-				dp_verbose_debug("tx mask 0x%x ring %d, budget %d, work_done %d",
-						 tx_mask, ring, budget,
-						 work_done);
-			}
-
-			budget -= work_done;
-			if (budget <= 0)
-				goto budget_done;
-
-			remaining_quota = budget;
+	for (index = 0; index < soc->num_tcl_data_rings; index++) {
+		if (!((1 << wlan_cfg_get_wbm_ring_num_for_index(index)) &
+		       tx_mask))
+			continue;
+		work_done = dp_tx_comp_handler(int_ctx,
+					       soc,
+					       soc->tx_comp_ring[index].hal_srng,
+					       index, remaining_quota);
+		if (work_done) {
+			intr_stats->num_tx_ring_masks[index]++;
+			dp_verbose_debug("tx mask 0x%x index %d, budget %d, work_done %d",
+					 tx_mask, index, budget,
+					 work_done);
 		}
-		tx_mask = tx_mask >> 1;
-		ring++;
+		budget -= work_done;
+		if (budget <= 0)
+			goto budget_done;
+
+		remaining_quota = budget;
 	}
 
 	/* Process REO Exception ring interrupt */

+ 1 - 1
wlan_cfg/wlan_cfg.c

@@ -1559,7 +1559,7 @@ int wlan_cfg_per_pdev_lmac_ring(struct wlan_cfg_dp_soc_ctxt *cfg)
 
 qdf_export_symbol(wlan_cfg_per_pdev_lmac_ring);
 
-#ifdef DP_MEMORY_OPT
+#if defined(DP_USE_SINGLE_TCL)
 int wlan_cfg_num_tcl_data_rings(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
 	return 1;