Przeglądaj źródła

qcacmn: Send cmd to dump FW stats on suspend failure

Add support to send unit test command to FW to dump
stats on suspend failure due to pending tx completions.

Change-Id: I6afb69a862c366c66a1e1f3dc009964272dfb75a
CRs-Fixed: 3151458
Yeshwanth Sriram Guntuka 3 lat temu
rodzic
commit
68116c0a80

+ 4 - 0
dp/inc/cdp_txrx_ops.h

@@ -1327,6 +1327,10 @@ struct ol_if_ops {
 				   uint8_t add_or_sub, uint8_t ac);
 #endif
 	uint32_t (*dp_get_tx_inqueue)(ol_txrx_soc_handle soc);
+	QDF_STATUS(*dp_send_unit_test_cmd)(uint32_t vdev_id,
+					   uint32_t module_id,
+					   uint32_t arg_count, uint32_t *arg);
+
 };
 
 #ifdef DP_PEER_EXTENDED_API

+ 20 - 0
dp/wifi3.0/dp_main.c

@@ -52,6 +52,7 @@
 #include "htt_ppdu_stats.h"
 #include "qdf_mem.h"   /* qdf_mem_malloc,free */
 #include "cfg_ucfg_api.h"
+#include <wlan_module_ids.h>
 
 #ifdef QCA_LL_TX_FLOW_CONTROL_V2
 #include "cdp_txrx_flow_ctrl_v2.h"
@@ -12658,6 +12659,8 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
 	uint16_t num_desc_per_page;
 	struct dp_tx_desc_s *tx_desc = NULL;
 	struct dp_tx_desc_pool_s *tx_desc_pool = NULL;
+	bool send_fw_stats_cmd = false;
+	uint8_t vdev_id;
 
 	for (i = 0; i < MAX_TXDESC_POOLS; i++) {
 		tx_desc_pool = &soc->tx_desc[i];
@@ -12686,6 +12689,11 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
 							tx_desc->timestamp)) {
 					dp_err_rl("Tx completion not rcvd for id: %u",
 						  tx_desc->id);
+
+					if (!send_fw_stats_cmd) {
+						send_fw_stats_cmd = true;
+						vdev_id = i;
+					}
 				}
 			} else {
 				dp_err_rl("tx desc %u corrupted, flags: 0x%x",
@@ -12693,6 +12701,18 @@ static void dp_find_missing_tx_comp(struct dp_soc *soc)
 			}
 		}
 	}
+
+	/*
+	 * The unit test command to dump FW stats is required only once as the
+	 * stats are dumped at pdev level and not vdev level.
+	 */
+	if (send_fw_stats_cmd && soc->cdp_soc.ol_ops->dp_send_unit_test_cmd) {
+		uint32_t fw_stats_args[2] = {533, 1};
+
+		soc->cdp_soc.ol_ops->dp_send_unit_test_cmd(vdev_id,
+							   WLAN_MODULE_TX, 2,
+							   fw_stats_args);
+	}
 }
 #else
 static inline void dp_find_missing_tx_comp(struct dp_soc *soc)

+ 6 - 1
dp/wifi3.0/dp_stats.c

@@ -6319,10 +6319,15 @@ void dp_txrx_path_stats(struct dp_soc *soc)
 		DP_PRINT_STATS("successfully transmitted: %u msdus (%llu bytes)",
 			       pdev->stats.tx.tx_success.num,
 			       pdev->stats.tx.tx_success.bytes);
-		for (i = 0; i < soc->num_tcl_data_rings; i++)
+		for (i = 0; i < soc->num_tcl_data_rings; i++) {
 			DP_PRINT_STATS("Enqueue to SW2TCL%u: %u", i + 1,
 				       soc->stats.tx.tcl_enq[i]);
+			DP_PRINT_STATS("TX completions reaped from ring %u: %u",
+				       i, soc->stats.tx.tx_comp[i]);
+		}
 
+		DP_PRINT_STATS("Invalid release source: %u",
+			       soc->stats.tx.invalid_release_source);
 		DP_PRINT_STATS("Dropped in host:");
 		DP_PRINT_STATS("Total packets dropped: %u,",
 			       pdev->stats.tx_i.dropped.dropped_pkt.num);

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

@@ -5114,6 +5114,8 @@ next_desc:
 	if (head_desc)
 		dp_tx_comp_process_desc_list(soc, head_desc, ring_id);
 
+	DP_STATS_INC(soc, tx.tx_comp[ring_id], count);
+
 	/*
 	 * If we are processing in near-full condition, there are 3 scenario
 	 * 1) Ring entries has reached critical state

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

@@ -1045,6 +1045,8 @@ struct dp_soc_stats {
 		uint32_t tx_comp_exception;
 		/* TQM drops after/during peer delete */
 		uint64_t tqm_drop_no_peer;
+		/* Number of tx completions reaped per WBM2SW release ring */
+		uint32_t tx_comp[MAX_TCL_DATA_RINGS];
 	} tx;
 
 	/* SOC level RX stats */