Prechádzať zdrojové kódy

qcacmn: Add option to enable or disable accounting of Tx in NAPI budget

Add a division factor for number of tx completions to be accounted for in NAPI
budget. Fix the data type of budget to int to account for negative values.

Change-Id: I620af5537c5c1cdf3161da3a3c053a2c8bf777e8
CRs-Fixed: 2092526
Pamidipati, Vijay 7 rokov pred
rodič
commit
9e34025ada
5 zmenil súbory, kde vykonal 76 pridanie a 59 odobranie
  1. 48 34
      dp/wifi3.0/dp_main.c
  2. 0 1
      dp/wifi3.0/dp_rx_mon.h
  3. 17 22
      dp/wifi3.0/dp_tx.c
  4. 1 2
      dp/wifi3.0/dp_tx.h
  5. 10 0
      wlan_cfg/wlan_cfg.h

+ 48 - 34
dp/wifi3.0/dp_main.c

@@ -733,60 +733,70 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 	struct dp_soc *soc = int_ctx->soc;
 	int ring = 0;
 	uint32_t work_done  = 0;
-	uint32_t budget = dp_budget;
+	int budget = dp_budget;
 	uint8_t tx_mask = int_ctx->tx_ring_mask;
 	uint8_t rx_mask = int_ctx->rx_ring_mask;
 	uint8_t rx_err_mask = int_ctx->rx_err_ring_mask;
 	uint8_t rx_wbm_rel_mask = int_ctx->rx_wbm_rel_ring_mask;
 	uint8_t reo_status_mask = int_ctx->reo_status_ring_mask;
+	uint32_t remaining_quota = dp_budget;
 
 	/* Process Tx completion interrupts first to return back buffers */
-	if (tx_mask) {
-		for (ring = 0; ring < soc->num_tcl_data_rings; ring++) {
-			if (tx_mask & (1 << ring)) {
-				work_done =
-					dp_tx_comp_handler(soc, ring, budget);
-				budget -= work_done;
-				if (work_done)
-					QDF_TRACE(QDF_MODULE_ID_DP,
-						QDF_TRACE_LEVEL_INFO,
-						"tx mask 0x%x ring %d,"
-						"budget %d",
-						tx_mask, ring, budget);
-				if (budget <= 0)
-					goto budget_done;
-			}
+	while (tx_mask) {
+		if (tx_mask & 0x1) {
+			work_done =
+				dp_tx_comp_handler(soc,
+					soc->tx_comp_ring[ring].hal_srng,
+					remaining_quota);
+
+			QDF_TRACE(QDF_MODULE_ID_DP,
+					QDF_TRACE_LEVEL_INFO,
+					"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;
 		}
+		tx_mask = tx_mask >> 1;
+		ring++;
 	}
 
+
 	/* Process REO Exception ring interrupt */
 	if (rx_err_mask) {
 		work_done = dp_rx_err_process(soc,
-				soc->reo_exception_ring.hal_srng, budget);
-		budget -=  work_done;
+				soc->reo_exception_ring.hal_srng,
+				remaining_quota);
 
-		if (work_done)
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
 				"REO Exception Ring: work_done %d budget %d",
 				work_done, budget);
+
+		budget -=  work_done;
 		if (budget <= 0) {
 			goto budget_done;
 		}
+		remaining_quota = budget;
 	}
 
 	/* Process Rx WBM release ring interrupt */
 	if (rx_wbm_rel_mask) {
 		work_done = dp_rx_wbm_err_process(soc,
-				soc->rx_rel_ring.hal_srng, budget);
-		budget -=  work_done;
+				soc->rx_rel_ring.hal_srng, remaining_quota);
 
-		if (work_done)
-			QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
+		QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO,
 				"WBM Release Ring: work_done %d budget %d",
 				work_done, budget);
+
+		budget -=  work_done;
 		if (budget <= 0) {
 			goto budget_done;
 		}
+		remaining_quota = budget;
 	}
 
 	/* Process Rx interrupts */
@@ -796,16 +806,19 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 				work_done =
 					dp_rx_process(int_ctx,
 					    soc->reo_dest_ring[ring].hal_srng,
-					    budget);
-				budget -=  work_done;
-				if (work_done)
-					QDF_TRACE(QDF_MODULE_ID_DP,
+					    remaining_quota);
+
+				QDF_TRACE(QDF_MODULE_ID_DP,
 						QDF_TRACE_LEVEL_INFO,
 						"rx mask 0x%x ring %d,"
-						"budget %d",
-						tx_mask, ring, budget);
+						"work_done %d budget %d",
+						rx_mask, ring, work_done,
+						budget);
+
+				budget -=  work_done;
 				if (budget <= 0)
 					goto budget_done;
+				remaining_quota = budget;
 			}
 		}
 	}
@@ -819,16 +832,17 @@ static uint32_t dp_service_srngs(void *dp_ctx, uint32_t dp_budget)
 			continue;
 		if (int_ctx->rx_mon_ring_mask & (1 << ring)) {
 			work_done =
-				dp_mon_process(soc, ring, budget);
-			budget -=  work_done;
+				dp_mon_process(soc, ring, remaining_quota);
+			budget -= work_done;
+			remaining_quota = budget;
 		}
 
 		if (int_ctx->rxdma2host_ring_mask & (1 << ring)) {
 			work_done =
-				dp_rxdma_err_process(soc, ring, budget);
+				dp_rxdma_err_process(soc, ring,
+						remaining_quota);
 			budget -=  work_done;
 		}
-
 	}
 
 	qdf_lro_flush(int_ctx->lro_ctx);

+ 0 - 1
dp/wifi3.0/dp_rx_mon.h

@@ -38,7 +38,6 @@
 void dp_rx_mon_dest_process(struct dp_soc *soc, uint32_t mac_id,
 	uint32_t quota);
 
-
 QDF_STATUS dp_rx_pdev_mon_attach(struct dp_pdev *pdev);
 QDF_STATUS dp_rx_pdev_mon_detach(struct dp_pdev *pdev);
 

+ 17 - 22
dp/wifi3.0/dp_tx.c

@@ -2063,7 +2063,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc,
  * dp_tx_comp_handler() - Tx completion handler
  * @soc: core txrx main context
  * @ring_id: completion ring id
- * @budget: No. of packets/descriptors that can be serviced in one loop
+ * @quota: No. of packets/descriptors that can be serviced in one loop
  *
  * This function will collect hardware release ring element contents and
  * handle descriptor contents. Based on contents, free packet or handle error
@@ -2071,8 +2071,7 @@ static void dp_tx_comp_process_desc(struct dp_soc *soc,
  *
  * Return: none
  */
-uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
-			uint32_t budget)
+uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota)
 {
 	void *tx_comp_hal_desc;
 	uint8_t buffer_src;
@@ -2082,7 +2081,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 	struct dp_tx_desc_s *head_desc = NULL;
 	struct dp_tx_desc_s *tail_desc = NULL;
 	uint32_t num_processed;
-	void *hal_srng = soc->tx_comp_ring[ring_id].hal_srng;
+	uint32_t count;
 
 	if (qdf_unlikely(hal_srng_access_start(soc->hal_soc, hal_srng))) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
@@ -2092,6 +2091,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 	}
 
 	num_processed = 0;
+	count = 0;
 
 	/* Find head descriptor from completion ring */
 	while (qdf_likely(tx_comp_hal_desc =
@@ -2100,16 +2100,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 		buffer_src = hal_tx_comp_get_buffer_source(tx_comp_hal_desc);
 
 		/* If this buffer was not released by TQM or FW, then it is not
-		 * Tx completion indication, skip to next descriptor */
+		 * Tx completion indication, assert */
 		if ((buffer_src != HAL_TX_COMP_RELEASE_SOURCE_TQM) &&
 				(buffer_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) {
 
 			QDF_TRACE(QDF_MODULE_ID_DP,
-					QDF_TRACE_LEVEL_ERROR,
+					QDF_TRACE_LEVEL_FATAL,
 					"Tx comp release_src != TQM | FW");
 
-			/* TODO Handle Freeing of the buffer in descriptor */
-			continue;
+			qdf_assert_always(0);
 		}
 
 		/* Get descriptor id */
@@ -2122,12 +2121,10 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 					soc->wlan_cfg_ctx)) {
 			QDF_TRACE(QDF_MODULE_ID_DP,
 					QDF_TRACE_LEVEL_FATAL,
-					"TX COMP pool id %d not valid",
+					"Tx Comp pool id %d not valid",
 					pool_id);
 
-			/* Check if assert aborts execution, if not handle
-			 * return here */
-			QDF_ASSERT(0);
+			qdf_assert_always(0);
 		}
 
 		/* Find Tx descriptor */
@@ -2144,9 +2141,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 					"Tx Comp pool id %d not matched %d",
 					pool_id, tx_desc->pool_id);
 
-			/* Check if assert aborts execution, if not handle
-			 * return here */
-			QDF_ASSERT(0);
+			qdf_assert_always(0);
 		}
 
 		if (!(tx_desc->flags & DP_TX_DESC_FLAG_ALLOCATED) ||
@@ -2160,8 +2155,7 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 		}
 
 		/*
-		 * If the release source is FW, process the HTT
-		 * status
+		 * If the release source is FW, process the HTT status
 		 */
 		if (qdf_unlikely(buffer_src ==
 					HAL_TX_COMP_RELEASE_SOURCE_FW)) {
@@ -2171,15 +2165,15 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 			dp_tx_process_htt_completion(tx_desc,
 					htt_tx_status);
 		} else {
-			tx_desc->next = NULL;
 
 			/* First ring descriptor on the cycle */
 			if (!head_desc) {
 				head_desc = tx_desc;
-			} else {
-				tail_desc->next = tx_desc;
+				tail_desc = tx_desc;
 			}
 
+			tail_desc->next = tx_desc;
+			tx_desc->next = NULL;
 			tail_desc = tx_desc;
 
 			/* Collect hw completion contents */
@@ -2188,15 +2182,16 @@ uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
 
 		}
 
-		num_processed++;
+		num_processed += !(count & DP_TX_NAPI_BUDGET_DIV_MASK);
 
 		/*
 		 * Processed packet count is more than given quota
 		 * stop to processing
 		 */
-		if (num_processed >= budget)
+		if ((num_processed >= quota))
 			break;
 
+		count++;
 	}
 
 	hal_srng_access_end(soc->hal_soc, hal_srng);

+ 1 - 2
dp/wifi3.0/dp_tx.h

@@ -143,8 +143,7 @@ QDF_STATUS dp_tx_pdev_attach(struct dp_pdev *pdev);
 
 qdf_nbuf_t dp_tx_send(void *data_vdev, qdf_nbuf_t nbuf);
 
-uint32_t dp_tx_comp_handler(struct dp_soc *soc, uint32_t ring_id,
-		uint32_t budget);
+uint32_t dp_tx_comp_handler(struct dp_soc *soc, void *hal_srng, uint32_t quota);
 
 int32_t
 dp_tx_prepare_send_me(struct dp_vdev *vdev, qdf_nbuf_t nbuf);

+ 10 - 0
wlan_cfg/wlan_cfg.h

@@ -26,9 +26,19 @@
 #if defined(CONFIG_MCL)
 #define MAX_PDEV_CNT 1
 #define WLAN_CFG_INT_NUM_CONTEXTS 7
+/*
+ * This mask defines how many transmit frames account for 1 NAPI work unit
+ * 0 means each tx completion is 1 unit
+ */
+#define DP_TX_NAPI_BUDGET_DIV_MASK 0
 #else
 #define MAX_PDEV_CNT 3
 #define WLAN_CFG_INT_NUM_CONTEXTS 4
+/*
+ * This mask defines how many transmit frames account for 1 NAPI work unit
+ * 0xFFFF means each 64K tx frame completions account for 1 unit of NAPI budget
+ */
+#define DP_TX_NAPI_BUDGET_DIV_MASK 0xFFFF
 #endif
 
 /* Tx configuration */