Эх сурвалжийг харах

qcacmn: Add near-full irq handler for TX completion ring

Add the handler to process the near-full condition
on the tx completion ring.

Change-Id: I547cd27d2a8a347fca1cebc6b27072f2d1d8a99d
CRs-Fixed: 2965081
Rakesh Pillai 4 жил өмнө
parent
commit
813b3bb474

+ 30 - 0
dp/wifi3.0/be/dp_be.c

@@ -570,11 +570,41 @@ budget_done:
 	return dp_budget - budget;
 	return dp_budget - budget;
 }
 }
 
 
+/**
+ * dp_srng_test_and_update_nf_params_be() - Check if the srng is in near full
+ *				state and set the reap_limit appropriately
+ *				as per the near full state
+ * @soc: Datapath soc handle
+ * @dp_srng: Datapath handle for SRNG
+ * @max_reap_limit: [Output Buffer] Buffer to set the max reap limit as per
+ *			the srng near-full state
+ *
+ * Return: 1, if the srng is in near-full state
+ *	   0, if the srng is not in near-full state
+ */
+static int
+dp_srng_test_and_update_nf_params_be(struct dp_soc *soc,
+				     struct dp_srng *dp_srng,
+				     int *max_reap_limit)
+{
+	return _dp_srng_test_and_update_nf_params(soc, dp_srng, max_reap_limit);
+}
+
+/**
+ * dp_init_near_full_arch_ops_be() - Initialize the arch ops handler for the
+ *			near full IRQ handling operations.
+ * @arch_ops: arch ops handle
+ *
+ * Return: none
+ */
 static inline void
 static inline void
 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
 {
 {
 	arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be;
 	arch_ops->dp_service_near_full_srngs = dp_service_near_full_srngs_be;
+	arch_ops->dp_srng_test_and_update_nf_params =
+					dp_srng_test_and_update_nf_params_be;
 }
 }
+
 #else
 #else
 static inline void
 static inline void
 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)
 dp_init_near_full_arch_ops_be(struct dp_arch_ops *arch_ops)

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

@@ -441,9 +441,9 @@ dp_srng_get_near_full_level(struct dp_soc *soc, struct dp_srng *dp_srng)
  *	   0, if the srng is not near full
  *	   0, if the srng is not near full
  */
  */
 static inline int
 static inline int
-dp_srng_test_and_update_nf_params(struct dp_soc *soc,
-				  struct dp_srng *srng,
-				  int *max_reap_limit)
+_dp_srng_test_and_update_nf_params(struct dp_soc *soc,
+				   struct dp_srng *srng,
+				   int *max_reap_limit)
 {
 {
 	int ring_near_full = 0, near_full_level;
 	int ring_near_full = 0, near_full_level;
 
 
@@ -471,9 +471,9 @@ dp_srng_test_and_update_nf_params(struct dp_soc *soc,
 }
 }
 #else
 #else
 static inline int
 static inline int
-dp_srng_test_and_update_nf_params(struct dp_soc *soc,
-				  struct dp_srng *srng,
-				  int *max_reap_limit)
+_dp_srng_test_and_update_nf_params(struct dp_soc *soc,
+				   struct dp_srng *srng,
+				   int *max_reap_limit)
 {
 {
 	return 0;
 	return 0;
 }
 }

+ 2 - 2
dp/wifi3.0/be/dp_be_rx.c

@@ -134,8 +134,8 @@ more_data:
 	qdf_mem_zero(head, sizeof(head));
 	qdf_mem_zero(head, sizeof(head));
 	qdf_mem_zero(tail, sizeof(tail));
 	qdf_mem_zero(tail, sizeof(tail));
 
 
-	ring_near_full = dp_srng_test_and_update_nf_params(soc, rx_ring,
-							   &max_reap_limit);
+	ring_near_full = _dp_srng_test_and_update_nf_params(soc, rx_ring,
+							    &max_reap_limit);
 
 
 	if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
 	if (qdf_unlikely(dp_rx_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
 		/*
 		/*

+ 11 - 1
dp/wifi3.0/be/dp_be_tx.c

@@ -435,6 +435,16 @@ uint32_t dp_tx_comp_nf_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
 			       hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
 			       hal_ring_handle_t hal_ring_hdl, uint8_t ring_id,
 			       uint32_t quota)
 			       uint32_t quota)
 {
 {
-	return 0;
+	struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id];
+	uint32_t work_done = 0;
+
+	if (dp_srng_get_near_full_level(soc, tx_comp_ring) <
+			DP_SRNG_THRESH_NEAR_FULL)
+		return 0;
+
+	qdf_atomic_set(&tx_comp_ring->near_full, 1);
+	work_done++;
+
+	return work_done;
 }
 }
 #endif
 #endif

+ 52 - 5
dp/wifi3.0/dp_tx.c

@@ -4355,13 +4355,13 @@ void dp_tx_process_htt_completion(struct dp_soc *soc,
 
 
 #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
 #ifdef WLAN_FEATURE_RX_SOFTIRQ_TIME_LIMIT
 static inline
 static inline
-bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped)
+bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped,
+				   int max_reap_limit)
 {
 {
 	bool limit_hit = false;
 	bool limit_hit = false;
-	struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
 
 
 	limit_hit =
 	limit_hit =
-		(num_reaped >= cfg->tx_comp_loop_pkt_limit) ? true : false;
+		(num_reaped >= max_reap_limit) ? true : false;
 
 
 	if (limit_hit)
 	if (limit_hit)
 		DP_STATS_INC(soc, tx.tx_comp_loop_pkt_limit_hit, 1);
 		DP_STATS_INC(soc, tx.tx_comp_loop_pkt_limit_hit, 1);
@@ -4373,9 +4373,17 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc)
 {
 {
 	return soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check;
 	return soc->wlan_cfg_ctx->tx_comp_enable_eol_data_check;
 }
 }
+
+static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc)
+{
+	struct wlan_cfg_dp_soc_ctxt *cfg = soc->wlan_cfg_ctx;
+
+	return cfg->tx_comp_loop_pkt_limit;
+}
 #else
 #else
 static inline
 static inline
-bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped)
+bool dp_tx_comp_loop_pkt_limit_hit(struct dp_soc *soc, int num_reaped,
+				   int max_reap_limit)
 {
 {
 	return false;
 	return false;
 }
 }
@@ -4384,6 +4392,28 @@ static inline bool dp_tx_comp_enable_eol_data_check(struct dp_soc *soc)
 {
 {
 	return false;
 	return false;
 }
 }
+
+static inline int dp_tx_comp_get_loop_pkt_limit(struct dp_soc *soc)
+{
+	return 0;
+}
+#endif
+
+#ifdef WLAN_FEATURE_NEAR_FULL_IRQ
+static inline int
+dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng,
+				  int *max_reap_limit)
+{
+	return soc->arch_ops.dp_srng_test_and_update_nf_params(soc, dp_srng,
+							       max_reap_limit);
+}
+#else
+static inline int
+dp_srng_test_and_update_nf_params(struct dp_soc *soc, struct dp_srng *dp_srng,
+				  int *max_reap_limit)
+{
+	return 0;
+}
 #endif
 #endif
 
 
 uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
 uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
@@ -4399,6 +4429,8 @@ uint32_t dp_tx_comp_handler(struct dp_intr *int_ctx, struct dp_soc *soc,
 	uint32_t count;
 	uint32_t count;
 	uint32_t num_avail_for_reap = 0;
 	uint32_t num_avail_for_reap = 0;
 	bool force_break = false;
 	bool force_break = false;
+	struct dp_srng *tx_comp_ring = &soc->tx_comp_ring[ring_id];
+	int max_reap_limit, ring_near_full;
 
 
 	DP_HIST_INIT();
 	DP_HIST_INIT();
 
 
@@ -4407,6 +4439,10 @@ more_data:
 	head_desc = NULL;
 	head_desc = NULL;
 	tail_desc = NULL;
 	tail_desc = NULL;
 	count = 0;
 	count = 0;
+	max_reap_limit = dp_tx_comp_get_loop_pkt_limit(soc);
+
+	ring_near_full = dp_srng_test_and_update_nf_params(soc, tx_comp_ring,
+							   &max_reap_limit);
 
 
 	if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
 	if (qdf_unlikely(dp_srng_access_start(int_ctx, soc, hal_ring_hdl))) {
 		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
 		dp_err("HAL RING Access Failed -- %pK", hal_ring_hdl);
@@ -4561,7 +4597,7 @@ next_desc:
 
 
 		count++;
 		count++;
 
 
-		if (dp_tx_comp_loop_pkt_limit_hit(soc, count))
+		if (dp_tx_comp_loop_pkt_limit_hit(soc, count, max_reap_limit))
 			break;
 			break;
 	}
 	}
 
 
@@ -4571,6 +4607,17 @@ next_desc:
 	if (head_desc)
 	if (head_desc)
 		dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
 		dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
 
 
+	/*
+	 * If we are processing in near-full condition, there are 3 scenario
+	 * 1) Ring entries has reached critical state
+	 * 2) Ring entries are still near high threshold
+	 * 3) Ring entries are below the safe level
+	 *
+	 * One more loop will move te state to normal processing and yield
+	 */
+	if (ring_near_full)
+		goto more_data;
+
 	if (dp_tx_comp_enable_eol_data_check(soc)) {
 	if (dp_tx_comp_enable_eol_data_check(soc)) {
 
 
 		if (num_processed >= quota)
 		if (num_processed >= quota)

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

@@ -1557,6 +1557,8 @@ enum dp_context_type {
  * 				      source from HAL desc for wbm release ring
  * 				      source from HAL desc for wbm release ring
  * @dp_service_near_full_srngs: Handler for servicing the near full IRQ
  * @dp_service_near_full_srngs: Handler for servicing the near full IRQ
  * @txrx_set_vdev_param: target specific ops while setting vdev params
  * @txrx_set_vdev_param: target specific ops while setting vdev params
+ * @dp_srng_test_and_update_nf_params: Check if the srng is in near full state
+ *				and set the near-full params.
  */
  */
 struct dp_arch_ops {
 struct dp_arch_ops {
 	/* INIT/DEINIT Arch Ops */
 	/* INIT/DEINIT Arch Ops */
@@ -1620,6 +1622,9 @@ struct dp_arch_ops {
 
 
 	/* Misc Arch Ops */
 	/* Misc Arch Ops */
 	qdf_size_t (*txrx_get_context_size)(enum dp_context_type);
 	qdf_size_t (*txrx_get_context_size)(enum dp_context_type);
+	int (*dp_srng_test_and_update_nf_params)(struct dp_soc *soc,
+						 struct dp_srng *dp_srng,
+						 int *max_reap_limit);
 };
 };
 
 
 /* SOC level structure for data path */
 /* SOC level structure for data path */