Sfoglia il codice sorgente

qcacmn: Enable wbm2sw_release ring for ppe2tcl ring

Enable wbm2sw_release ring for ppe2tcl ring to
handle tx completions

Change-Id: I38e81bb46e376e3f059f321454aa4d241e6aadb7
CRs-Fixed: 3309444
Pavankumar Nandeshwar 2 anni fa
parent
commit
ab2bd061c2

+ 1 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -113,6 +113,7 @@
 
 #define CDP_MAX_RX_RINGS 8  /* max rx rings */
 #define CDP_MAX_TX_COMP_RINGS 5 /* max tx/completion rings */
+#define CDP_MAX_TX_COMP_PPE_RING (CDP_MAX_TX_COMP_RINGS - 1)
 #define CDP_MAX_RX_WBM_RINGS 1 /* max rx wbm rings */
 
 #define CDP_MAX_TX_TQM_STATUS 9  /* max tx tqm completion status */

+ 98 - 7
dp/wifi3.0/be/dp_be.c

@@ -81,6 +81,8 @@ static void dp_ppeds_rings_status(struct dp_soc *soc)
 
 	dp_print_ring_stat_from_hal(soc, &be_soc->reo2ppe_ring, REO2PPE);
 	dp_print_ring_stat_from_hal(soc, &be_soc->ppe2tcl_ring, PPE2TCL);
+	dp_print_ring_stat_from_hal(soc, &be_soc->ppe_wbm_release_ring,
+				    WBM2SW_RELEASE);
 }
 #endif
 
@@ -935,6 +937,69 @@ dp_rxdma_ring_wmask_cfg_be(struct dp_soc *soc,
 {
 }
 #endif
+#ifdef WLAN_SUPPORT_PPEDS
+static
+void dp_free_ppeds_interrupts(struct dp_soc *soc, struct dp_srng *srng,
+			      int ring_type, int ring_num)
+{
+	if (srng->irq >= 0) {
+		if (ring_type == WBM2SW_RELEASE &&
+		    ring_num == WBM2_SW_PPE_REL_RING_ID)
+			pld_pfrm_free_irq(soc->osdev->dev, srng->irq, soc);
+	}
+}
+
+static
+int dp_register_ppeds_interrupts(struct dp_soc *soc, struct dp_srng *srng,
+				 int vector, int ring_type, int ring_num)
+{
+	int irq, ret = 0;
+	struct dp_soc_be *be_soc = dp_get_be_soc_from_dp_soc(soc);
+	int pci_slot = pld_get_pci_slot(soc->osdev->dev);
+	void *ctxt;
+
+	if (ring_type == WBM2SW_RELEASE &&
+	    ring_num == WBM2_SW_PPE_REL_RING_ID) {
+		irq = pld_get_msi_irq(soc->osdev->dev, vector);
+		snprintf(be_soc->irq_name[2], DP_PPE_INTR_STRNG_LEN,
+			 "pci%d_ppe_wbm_rel", pci_slot);
+
+		ret = pld_pfrm_request_irq(soc->osdev->dev, irq,
+					   dp_ppeds_handle_tx_comp,
+					   IRQF_SHARED | IRQF_NO_SUSPEND,
+					   be_soc->irq_name[2], (void *)soc);
+
+		if (ret)
+			goto fail;
+	} else {
+		return 0;
+	}
+
+	srng->irq = irq;
+
+	dp_info("Registered irq %d for soc %pK ring type %d",
+		irq, soc, ring_type);
+
+	return 0;
+fail:
+	dp_err("Unable to config irq : ring type %d irq %d vector %d ctxt %pK",
+	       ring_type, irq, vector, ctxt);
+
+	return ret;
+}
+
+void dp_ppeds_disable_irq(struct dp_soc *soc, struct dp_srng *srng)
+{
+	if (srng->irq >= 0)
+		pld_pfrm_disable_irq_nosync(soc->osdev->dev, srng->irq);
+}
+
+void dp_ppeds_enable_irq(struct dp_soc *soc, struct dp_srng *srng)
+{
+	if (srng->irq >= 0)
+		pld_pfrm_enable_irq(soc->osdev->dev, srng->irq);
+}
+#endif
 
 #ifdef NO_RX_PKT_HDR_TLV
 /**
@@ -1317,6 +1382,15 @@ static void dp_soc_ppe_srng_deinit(struct dp_soc *soc)
 			     soc->ctrl_psoc,
 			     WLAN_MD_DP_SRNG_REO2PPE,
 			     "reo2ppe_ring");
+
+	dp_srng_deinit(soc, &be_soc->ppe_wbm_release_ring, WBM2SW_RELEASE,
+		       WBM2_SW_PPE_REL_RING_ID);
+	wlan_minidump_remove(be_soc->ppe_wbm_release_ring.base_vaddr_unaligned,
+			     be_soc->ppe_wbm_release_ring.alloc_size,
+			     soc->ctrl_psoc,
+			     WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE,
+			     "ppe_wbm_release_ring");
+
 }
 
 static void dp_soc_ppe_srng_free(struct dp_soc *soc)
@@ -1331,6 +1405,8 @@ static void dp_soc_ppe_srng_free(struct dp_soc *soc)
 
 	dp_srng_free(soc, &be_soc->ppe_release_ring);
 
+	dp_srng_free(soc, &be_soc->ppe_wbm_release_ring);
+
 	dp_srng_free(soc, &be_soc->ppe2tcl_ring);
 
 	dp_srng_free(soc, &be_soc->reo2ppe_ring);
@@ -1369,6 +1445,13 @@ static QDF_STATUS dp_soc_ppe_srng_alloc(struct dp_soc *soc)
 		goto fail;
 	}
 
+	entries = wlan_cfg_tx_comp_ring_size(soc_cfg_ctx);
+	if (dp_srng_alloc(soc, &be_soc->ppe_wbm_release_ring, WBM2SW_RELEASE,
+			  entries, 1)) {
+		dp_err("%pK: dp_srng_alloc failed for ppe_release_ring", soc);
+		goto fail;
+	}
+
 	return QDF_STATUS_SUCCESS;
 fail:
 	dp_soc_ppe_srng_free(soc);
@@ -1420,12 +1503,23 @@ static QDF_STATUS dp_soc_ppe_srng_init(struct dp_soc *soc)
 			  soc->ctrl_psoc,
 			  WLAN_MD_DP_SRNG_PPE_RELEASE,
 			  "ppe_release_ring");
-#ifdef WLAN_SUPPORT_PPEDS
+
+	if (dp_srng_init(soc, &be_soc->ppe_wbm_release_ring, WBM2SW_RELEASE,
+			 WBM2_SW_PPE_REL_RING_ID, 0)) {
+		dp_err("%pK: dp_srng_init failed for ppe_release_ring", soc);
+		goto fail;
+	}
+
+	wlan_minidump_remove(be_soc->ppe_wbm_release_ring.base_vaddr_unaligned,
+			     be_soc->ppe_wbm_release_ring.alloc_size,
+			     soc->ctrl_psoc,
+			     WLAN_MD_DP_SRNG_PPE_WBM2SW_RELEASE,
+			     "ppe_wbm_release_ring");
+
 	if (dp_ppeds_register_soc_be(be_soc)) {
 		dp_err("%pK: ppeds registration failed", soc);
 		goto fail;
 	}
-#endif
 
 	return QDF_STATUS_SUCCESS;
 fail:
@@ -2233,12 +2327,9 @@ void dp_initialize_arch_ops_be(struct dp_arch_ops *arch_ops)
 	arch_ops->dp_txrx_ppeds_rings_status = dp_ppeds_rings_status;
 	arch_ops->txrx_soc_ppeds_start = dp_ppeds_start_soc_be;
 	arch_ops->txrx_soc_ppeds_stop = dp_ppeds_stop_soc_be;
-#else
-	arch_ops->dp_txrx_ppeds_rings_status = NULL;
-	arch_ops->txrx_soc_ppeds_start = NULL;
-	arch_ops->txrx_soc_ppeds_stop = NULL;
+	arch_ops->dp_register_ppeds_interrupts = dp_register_ppeds_interrupts;
+	arch_ops->dp_free_ppeds_interrupts = dp_free_ppeds_interrupts;
 #endif
-
 	dp_init_near_full_arch_ops_be(arch_ops);
 	arch_ops->get_reo_qdesc_addr = dp_rx_get_reo_qdesc_addr_be;
 	arch_ops->get_rx_hash_key = dp_get_rx_hash_key_be;

+ 22 - 0
dp/wifi3.0/be/dp_be.h

@@ -113,9 +113,15 @@ enum CMEM_MEM_CLIENTS {
 
 #define PEER_ROUTING_USE_PPE 1
 #define PEER_ROUTING_ENABLED 1
+#define DP_PPE_INTR_STRNG_LEN 32
+#define DP_PPE_INTR_MAX 3
+
 #else
 #define DP_TX_PPEDS_DESC_CMEM_OFFSET 0
 #define DP_TX_PPEDS_DESC_POOL_CMEM_SIZE 0
+
+#define DP_PPE_INTR_STRNG_LEN 0
+#define DP_PPE_INTR_MAX 0
 #endif
 
 /* tx descriptor are programmed at start of CMEM region*/
@@ -250,6 +256,16 @@ struct dp_ppe_tx_desc_pool_s {
 };
 #endif
 
+/**
+ * struct dp_ppeds_napi - napi parameters for ppe ds
+ * @napi: napi structure to register with napi infra
+ * @ndev: net_dev structure
+ */
+struct dp_ppeds_napi {
+	struct napi_struct napi;
+	struct net_device ndev;
+};
+
 /**
  * struct dp_soc_be - Extended DP soc for BE targets
  * @soc: dp soc structure
@@ -295,12 +311,15 @@ struct dp_soc_be {
 	struct dp_srng reo2ppe_ring;
 	struct dp_srng ppe2tcl_ring;
 	struct dp_srng ppe_release_ring;
+	struct dp_srng ppe_wbm_release_ring;
 	struct dp_ppe_vp_tbl_entry *ppe_vp_tbl;
 	struct dp_hw_cookie_conversion_t ppeds_tx_cc_ctx;
 	struct dp_ppe_tx_desc_pool_s ppeds_tx_desc;
+	struct dp_ppeds_napi ppeds_napi_ctxt;
 	void *ppeds_handle;
 	qdf_mutex_t ppe_vp_tbl_lock;
 	uint8_t num_ppe_vp_entries;
+	char irq_name[DP_PPE_INTR_MAX][DP_PPE_INTR_STRNG_LEN];
 #endif
 #ifdef WLAN_FEATURE_11BE_MLO
 #ifdef WLAN_MLO_MULTI_CHIP
@@ -577,6 +596,9 @@ struct dp_peer_be *dp_get_be_peer_from_dp_peer(struct dp_peer *peer)
 	return (struct dp_peer_be *)peer;
 }
 
+void dp_ppeds_disable_irq(struct dp_soc *soc, struct dp_srng *srng);
+void dp_ppeds_enable_irq(struct dp_soc *soc, struct dp_srng *srng);
+
 QDF_STATUS
 dp_hw_cookie_conversion_attach(struct dp_soc_be *be_soc,
 			       struct dp_hw_cookie_conversion_t *cc_ctx,

+ 107 - 0
dp/wifi3.0/be/dp_be_tx.c

@@ -784,6 +784,113 @@ QDF_STATUS dp_sawf_tx_enqueue_fail_peer_stats(struct dp_soc *soc,
 }
 #endif
 
+#ifdef WLAN_SUPPORT_PPEDS
+/**
+ * dp_ppeds_tx_comp_handler()- Handle tx completions for ppe2tcl ring
+ * @soc: Handle to DP Soc structure
+ * @quota: Max number of tx completions to process
+ *
+ * Return: Number of tx completions processed
+ */
+int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota)
+{
+	uint32_t num_avail_for_reap = 0;
+	void *tx_comp_hal_desc;
+	uint8_t buf_src;
+	uint32_t count = 0;
+	struct dp_tx_desc_s *tx_desc = NULL;
+	struct dp_tx_desc_s *head_desc = NULL;
+	struct dp_tx_desc_s *tail_desc = NULL;
+	struct dp_soc *soc = &be_soc->soc;
+	void *last_prefetch_hw_desc = NULL;
+	struct dp_tx_desc_s *last_prefetch_sw_desc = NULL;
+	hal_soc_handle_t hal_soc = soc->hal_soc;
+	hal_ring_handle_t hal_ring_hdl = be_soc->ppe_wbm_release_ring.hal_srng;
+
+	if (qdf_unlikely(dp_srng_access_start(NULL, soc, hal_ring_hdl))) {
+		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
+		return 0;
+	}
+
+	num_avail_for_reap = hal_srng_dst_num_valid(hal_soc, hal_ring_hdl, 0);
+
+	if (num_avail_for_reap >= quota)
+		num_avail_for_reap = quota;
+
+	dp_srng_dst_inv_cached_descs(soc, hal_ring_hdl, num_avail_for_reap);
+
+	last_prefetch_hw_desc = dp_srng_dst_prefetch(hal_soc, hal_ring_hdl,
+						     num_avail_for_reap);
+
+	while (qdf_likely(num_avail_for_reap--)) {
+		tx_comp_hal_desc =  dp_srng_dst_get_next(soc, hal_ring_hdl);
+		if (qdf_unlikely(!tx_comp_hal_desc))
+			break;
+
+		buf_src = hal_tx_comp_get_buffer_source(hal_soc,
+							tx_comp_hal_desc);
+
+		if (qdf_unlikely(buf_src != HAL_TX_COMP_RELEASE_SOURCE_TQM &&
+				 buf_src != HAL_TX_COMP_RELEASE_SOURCE_FW)) {
+			dp_err("Tx comp release_src != TQM | FW but from %d",
+			       buf_src);
+			qdf_assert_always(0);
+		}
+
+		dp_tx_comp_get_params_from_hal_desc_be(soc, tx_comp_hal_desc,
+						       &tx_desc);
+
+		if (!tx_desc) {
+			dp_err("unable to retrieve tx_desc!");
+			qdf_assert_always(0);
+			continue;
+		}
+
+		if (qdf_unlikely(!(tx_desc->flags &
+				   DP_TX_DESC_FLAG_ALLOCATED) ||
+				 !(tx_desc->flags & DP_TX_DESC_FLAG_PPEDS))) {
+			qdf_assert_always(0);
+			continue;
+		}
+
+		tx_desc->buffer_src = buf_src;
+
+		if (qdf_unlikely(buf_src == HAL_TX_COMP_RELEASE_SOURCE_FW)) {
+			qdf_nbuf_free(tx_desc->nbuf);
+			dp_ppeds_tx_desc_free(soc, tx_desc);
+		} else {
+			tx_desc->tx_status =
+				hal_tx_comp_get_tx_status(tx_comp_hal_desc);
+
+			if (!head_desc) {
+				head_desc = tx_desc;
+				tail_desc = tx_desc;
+			}
+
+			tail_desc->next = tx_desc;
+			tx_desc->next = NULL;
+			tail_desc = tx_desc;
+
+			count++;
+
+			dp_tx_prefetch_hw_sw_nbuf_desc(soc, hal_soc,
+						       num_avail_for_reap,
+						       hal_ring_hdl,
+						       &last_prefetch_hw_desc,
+						       &last_prefetch_sw_desc);
+		}
+	}
+
+	dp_srng_access_end(NULL, soc, hal_ring_hdl);
+
+	if (head_desc)
+		dp_tx_comp_process_desc_list(soc, head_desc,
+					     CDP_MAX_TX_COMP_PPE_RING);
+
+	return count;
+}
+#endif
+
 QDF_STATUS
 dp_tx_hw_enqueue_be(struct dp_soc *soc, struct dp_vdev *vdev,
 		    struct dp_tx_desc_s *tx_desc, uint16_t fw_metadata,

+ 10 - 0
dp/wifi3.0/be/dp_be_tx.h

@@ -191,6 +191,16 @@ void dp_tx_desc_pool_deinit_be(struct dp_soc *soc,
 			       struct dp_tx_desc_pool_s *tx_desc_pool,
 			       uint8_t pool_id);
 
+#ifdef WLAN_SUPPORT_PPEDS
+/**
+ * dp_ppeds_tx_comp_handler()- Handle tx completions for ppe2tcl ring
+ * @soc: Handle to DP Soc structure
+ * @quota: Max number of tx completions to process
+ *
+ * Return: Number of tx completions processed
+ */
+int dp_ppeds_tx_comp_handler(struct dp_soc_be *be_soc, uint32_t quota);
+#endif
 #ifdef WLAN_FEATURE_11BE_MLO
 /**
  * dp_tx_mlo_mcast_handler_be() - Tx handler for Mcast packets

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

@@ -28,7 +28,8 @@
 #define DP_PEER_WDS_COUNT_INVALID UINT_MAX
 
 #define DP_BLOCKMEM_SIZE 4096
-
+#define WBM2_SW_PPE_REL_RING_ID 6
+#define WBM2_SW_PPE_REL_MAP_ID 11
 /* Alignment for consistent memory for DP rings*/
 #define DP_RING_BASE_ALIGN 32
 

+ 23 - 5
dp/wifi3.0/dp_main.c

@@ -1489,7 +1489,10 @@ static int dp_srng_calculate_msi_group(struct dp_soc *soc,
 			/* dp_rx_wbm_err_process - soc->rx_rel_ring */
 			grp_mask = &cfg_ctx->int_rx_wbm_rel_ring_mask[0];
 			ring_num = 0;
-		} else { /* dp_tx_comp_handler - soc->tx_comp_ring */
+		} else if (ring_num == WBM2_SW_PPE_REL_RING_ID) {
+			grp_mask = &cfg_ctx->int_ppeds_wbm_release_ring_mask[0];
+			ring_num = 0;
+		}  else { /* dp_tx_comp_handler - soc->tx_comp_ring */
 			grp_mask = &soc->wlan_cfg_ctx->int_tx_ring_mask[0];
 			nf_irq_mask = dp_srng_get_near_full_irq_mask(soc,
 								     ring_type,
@@ -1635,8 +1638,9 @@ static int dp_get_num_msi_available(struct dp_soc *soc, int interrupt_mode)
 }
 #endif
 
-static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params
-			      *ring_params, int ring_type, int ring_num)
+static void dp_srng_msi_setup(struct dp_soc *soc, struct dp_srng *srng,
+			      struct hal_srng_params *ring_params,
+			      int ring_type, int ring_num)
 {
 	int reg_msi_grp_num;
 	/*
@@ -1648,6 +1652,7 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params
 	int ret;
 	uint32_t msi_data_start, msi_irq_start, addr_low, addr_high;
 	bool nf_irq_support;
+	int vector;
 
 	ret = pld_get_user_msi_assignment(soc->osdev->dev, "DP",
 					    &msi_data_count, &msi_data_start,
@@ -1699,6 +1704,14 @@ static void dp_srng_msi_setup(struct dp_soc *soc, struct hal_srng_params
 		 ring_type, ring_num, ring_params->msi_data,
 		 (uint64_t)ring_params->msi_addr);
 
+	vector = msi_irq_start + (reg_msi_grp_num % msi_data_count);
+	if (soc->arch_ops.dp_register_ppeds_interrupts)
+		if (soc->arch_ops.dp_register_ppeds_interrupts(soc, srng,
+							       vector,
+							       ring_type,
+							       ring_num))
+			return;
+
 configure_msi2:
 	if (!nf_irq_support) {
 		dp_srng_set_msi2_ring_params(soc, ring_params, 0, 0);
@@ -1916,7 +1929,8 @@ dp_srng_configure_interrupt_thresholds(struct dp_soc *soc,
 			wlan_cfg_get_int_batch_threshold_rx(soc->wlan_cfg_ctx);
 	} else if (ring_type == WBM2SW_RELEASE &&
 		   (ring_num < wbm2_sw_rx_rel_ring_id ||
-		   ring_num == WBM2SW_TXCOMP_RING4_NUM)) {
+		   ring_num == WBM2SW_TXCOMP_RING4_NUM ||
+		   ring_num == WBM2_SW_PPE_REL_RING_ID)) {
 		ring_params->intr_timer_thres_us =
 			wlan_cfg_get_int_timer_threshold_tx(soc->wlan_cfg_ctx);
 		ring_params->intr_batch_cntr_thres_entries =
@@ -2356,7 +2370,7 @@ QDF_STATUS dp_srng_init(struct dp_soc *soc, struct dp_srng *srng,
 		ring_params.num_entries);
 
 	if (soc->intr_mode == DP_INTR_MSI && !dp_skip_msi_cfg(soc, ring_type)) {
-		dp_srng_msi_setup(soc, &ring_params, ring_type, ring_num);
+		dp_srng_msi_setup(soc, srng, &ring_params, ring_type, ring_num);
 		dp_verbose_debug("Using MSI for ring_type: %d, ring_num %d",
 				 ring_type, ring_num);
 	} else {
@@ -2461,6 +2475,10 @@ void dp_srng_deinit(struct dp_soc *soc, struct dp_srng *srng,
 		return;
 	}
 
+	if (soc->arch_ops.dp_free_ppeds_interrupts)
+		soc->arch_ops.dp_free_ppeds_interrupts(soc, srng, ring_type,
+						       ring_num);
+
 	hal_srng_cleanup(soc->hal_soc, srng->hal_srng);
 	srng->hal_srng = NULL;
 }

+ 1 - 1
dp/wifi3.0/dp_tx.c

@@ -5471,7 +5471,7 @@ dp_tx_mcast_reinject_handler(struct dp_soc *soc, struct dp_tx_desc_s *desc)
  *
  * Return: none
  */
-static void
+void
 dp_tx_comp_process_desc_list(struct dp_soc *soc,
 			     struct dp_tx_desc_s *comp_head, uint8_t ring_id)
 {

+ 3 - 0
dp/wifi3.0/dp_tx.h

@@ -247,6 +247,9 @@ struct dp_tx_msdu_info_s {
 void dp_tx_deinit_pair_by_index(struct dp_soc *soc, int index);
 #endif /* QCA_HOST_MODE_WIFI_DISABLED */
 
+void
+dp_tx_comp_process_desc_list(struct dp_soc *soc,
+			     struct dp_tx_desc_s *comp_head, uint8_t ring_id);
 void dp_tx_tso_cmn_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool);
 void dp_tx_tso_cmn_desc_pool_free(struct dp_soc *soc, uint8_t num_pool);
 void dp_tx_tso_cmn_desc_pool_deinit(struct dp_soc *soc, uint8_t num_pool);

+ 8 - 0
dp/wifi3.0/dp_types.h

@@ -2016,9 +2016,17 @@ struct dp_arch_ops {
 #ifdef IPA_OFFLOAD
 	int8_t (*ipa_get_bank_id)(struct dp_soc *soc);
 #endif
+#ifdef WLAN_SUPPORT_PPEDS
 	void (*dp_txrx_ppeds_rings_status)(struct dp_soc *soc);
+#endif
 	QDF_STATUS (*txrx_soc_ppeds_start)(struct dp_soc *soc);
 	void (*txrx_soc_ppeds_stop)(struct dp_soc *soc);
+	int (*dp_register_ppeds_interrupts)(struct dp_soc *soc,
+					    struct dp_srng *srng, int vector,
+					    int ring_type, int ring_num);
+	void (*dp_free_ppeds_interrupts)(struct dp_soc *soc,
+					 struct dp_srng *srng, int ring_type,
+					 int ring_num);
 };
 
 /**

+ 0 - 3
dp/wifi3.0/li/dp_li.c

@@ -642,9 +642,6 @@ void dp_initialize_arch_ops_li(struct dp_arch_ops *arch_ops)
 	arch_ops->peer_get_reo_hash = dp_peer_get_reo_hash_li;
 	arch_ops->reo_remap_config = dp_reo_remap_config_li;
 	arch_ops->dp_rx_replenish_soc_get = dp_rx_replensih_soc_get_li;
-	arch_ops->dp_txrx_ppeds_rings_status = NULL;
-	arch_ops->txrx_soc_ppeds_start = NULL;
-	arch_ops->txrx_soc_ppeds_stop = NULL;
 	arch_ops->get_reo_qdesc_addr = dp_rx_get_reo_qdesc_addr_li;
 }
 

+ 12 - 0
wlan_cfg/cfg_dp.h

@@ -1612,6 +1612,10 @@
 #define WLAN_CFG_NUM_PPEDS_TX_DESC_MAX 0x8000
 #define WLAN_CFG_NUM_PPEDS_TX_DESC 0x8000
 
+#define WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI_MIN 8
+#define WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI_MAX 256
+#define WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI 64
+
 #define CFG_DP_PPEDS_TX_DESC \
 		CFG_INI_UINT("dp_ppeds_tx_desc", \
 		WLAN_CFG_NUM_PPEDS_TX_DESC_MIN, \
@@ -1619,6 +1623,13 @@
 		WLAN_CFG_NUM_PPEDS_TX_DESC, \
 		CFG_VALUE_OR_DEFAULT, "DP PPEDS Tx Descriptors")
 
+#define CFG_DP_PPEDS_TX_CMP_NAPI_BUDGET \
+		CFG_INI_UINT("dp_ppeds_tx_cmp_napi_budget", \
+		WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI_MIN, \
+		WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI_MAX, \
+		WLAN_CFG_NUM_PPEDS_TX_CMP_NAPI, \
+		CFG_VALUE_OR_DEFAULT, "DP PPEDS Tx Comp handler napi budget")
+
 #define CFG_DP_PPE_ENABLE \
 	CFG_INI_BOOL("ppe_ds_enable", true, \
 	"DP ppe enable flag")
@@ -1645,6 +1656,7 @@
 		CFG_VALUE_OR_DEFAULT, "DP PPE Release Ring")
 
 #define CFG_DP_PPE_CONFIG \
+		CFG(CFG_DP_PPEDS_TX_CMP_NAPI_BUDGET) \
 		CFG(CFG_DP_PPEDS_TX_DESC) \
 		CFG(CFG_DP_PPE_ENABLE) \
 		CFG(CFG_DP_REO2PPE_RING) \

+ 49 - 0
wlan_cfg/wlan_cfg.c

@@ -95,6 +95,8 @@
 
 #define WLAN_CFG_UMAC_RESET_INTR_MASK_0 0x1
 
+#define WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0 0x1
+
 struct dp_int_mask_assignment {
 	uint8_t tx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t rx_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
@@ -111,6 +113,7 @@ struct dp_int_mask_assignment {
 	uint8_t tx_ring_near_full_irq_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t host2txmon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t tx_mon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
+	uint8_t ppeds_wbm_release_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t umac_reset_intr_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 };
 
@@ -1258,6 +1261,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0,
 		 0, 0, 0, 0, 0, 0, 0, 0},
@@ -1335,6 +1341,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0,
 		 0, 0, 0, 0, 0, 0, 0, 0},
@@ -1420,6 +1429,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0,
 		 0, 0, 0, 0, 0, 0, 0, 0},
@@ -1505,6 +1517,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0,
 		 0, 0, 0, 0, 0, 0, 0, 0},
@@ -1590,6 +1605,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0, 0, 0, 0, 0},
@@ -1675,6 +1693,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0, 0, 0, 0},
@@ -1760,6 +1781,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		{ WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+		/* ppe wbm ds release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0,
+		 0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0, 0, 0},
@@ -1836,6 +1860,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		  WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, 0,
+		  WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0, 0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0, 0},
@@ -1912,6 +1939,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		  WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		  WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0, 0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0, 0},
@@ -1988,6 +2018,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		  WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		  WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0, 0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0, 0},
@@ -2064,6 +2097,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		  WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		  WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0, 0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0, 0},
@@ -2140,6 +2176,9 @@ static struct dp_int_mask_assignment dp_mask_assignment[NUM_INTERRUPT_COMBINATIO
 		  WLAN_CFG_TX_MON_RING_MASK_0,
 		  WLAN_CFG_TX_MON_RING_MASK_1,
 		  0, 0, 0, 0, 0},
+		/* ppe ds wbm release ring ring mask */
+		{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+		  0, WLAN_CFG_PPEDS_WBM_RELEASE_RING_MASK_0, 0, 0, 0},
 		/* umac reset mask */
 		{0, 0, 0, 0, 0, 0, 0, 0,
 		 0, 0, 0, 0, 0, 0, 0, WLAN_CFG_UMAC_RESET_INTR_MASK_0},
@@ -2348,6 +2387,8 @@ void wlan_cfg_fill_interrupt_mask(struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx,
 			dp_mask_assignment[interrupt_index].rx_wbm_rel_ring_mask[i];
 		wlan_cfg_ctx->int_reo_status_ring_mask[i] =
 			dp_mask_assignment[interrupt_index].reo_status_ring_mask[i];
+		wlan_cfg_ctx->int_ppeds_wbm_release_ring_mask[i] =
+			dp_mask_assignment[interrupt_index].ppeds_wbm_release_ring_mask[i];
 		if (is_monitor_mode) {
 			wlan_cfg_ctx->int_rx_ring_mask[i] = 0;
 			wlan_cfg_ctx->int_rxdma2host_ring_mask[i] = 0;
@@ -2503,6 +2544,8 @@ wlan_soc_ppe_cfg_attach(struct cdp_ctrl_objmgr_psoc *psoc,
 	wlan_cfg_ctx->ppe_release_ring = cfg_get(psoc,
 						 CFG_DP_PPE_RELEASE_RING);
 	wlan_cfg_ctx->ppe_num_tx_desc = cfg_get(psoc, CFG_DP_PPEDS_TX_DESC);
+	wlan_cfg_ctx->ppe_tx_comp_napi_budget =
+				cfg_get(psoc, CFG_DP_PPEDS_TX_CMP_NAPI_BUDGET);
 }
 #else
 static inline void
@@ -4005,6 +4048,12 @@ wlan_cfg_get_dp_soc_ppe_num_tx_desc(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
 	return cfg->ppe_num_tx_desc;
 }
+
+int
+wlan_cfg_get_dp_soc_ppe_tx_comp_napi_budget(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->ppe_tx_comp_napi_budget;
+}
 #endif
 
 void

+ 18 - 0
wlan_cfg/wlan_cfg.h

@@ -318,6 +318,7 @@ struct wlan_cfg_dp_soc_ctxt {
 	uint8_t int_rx_ring_near_full_irq_2_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t int_tx_ring_near_full_irq_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t int_host2txmon_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
+	uint8_t int_ppeds_wbm_release_ring_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	uint8_t int_umac_reset_intr_mask[WLAN_CFG_INT_NUM_CONTEXTS];
 	int hw_macid[MAX_PDEV_CNT];
 	int hw_macid_pdev_id_map[MAX_NUM_LMAC_HW];
@@ -419,7 +420,9 @@ struct wlan_cfg_dp_soc_ctxt {
 	int reo2ppe_ring;
 	int ppe2tcl_ring;
 	int ppe_release_ring;
+	int ppe_wbm_release_ring;
 	int ppe_num_tx_desc;
+	int ppe_tx_comp_napi_budget;
 #endif
 #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
 	uint32_t pkt_capture_mode;
@@ -2008,6 +2011,15 @@ wlan_cfg_get_dp_soc_ppe_release_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg);
  */
 int
 wlan_cfg_get_dp_soc_ppe_num_tx_desc(struct wlan_cfg_dp_soc_ctxt *cfg);
+
+/*
+ * wlan_cfg_get_dp_soc_ppe_tx_comp_napi_budget() - ppeds Tx comp napi budget
+ * @ctx - Configuration Handle
+ *
+ * Return: napi budget
+ */
+int
+wlan_cfg_get_dp_soc_ppe_tx_comp_napi_budget(struct wlan_cfg_dp_soc_ctxt *cfg);
 #else
 static inline bool
 wlan_cfg_get_dp_soc_is_ppe_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
@@ -2038,6 +2050,12 @@ wlan_cfg_get_dp_soc_ppe_num_tx_desc(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
 	return 0;
 }
+
+static inline int
+wlan_cfg_get_dp_soc_ppe_tx_comp_napi_budget(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return 0;
+}
 #endif
 
 /**