소스 검색

qcacld-3.0: add periodic data traffic stats

Add support for periodic stats for data packets to be displayed in
wlan driver logs.

Change-Id: Iee6759ae75657ae93e94ea1bb1343f2ea489c087
CRs-Fixed: 2120047
Mohit Khanna 7 년 전
부모
커밋
ca4173ba74

+ 8 - 8
core/cds/src/cds_sched.c

@@ -133,9 +133,9 @@ static int cds_sched_find_attach_cpu(p_cds_sched_context pSchedContext,
 	int i;
 #endif
 
-	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_LOW,
-		"%s: num possible cpu %d",
-		__func__, num_possible_cpus());
+	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: num possible cpu %d",
+		 __func__, num_possible_cpus());
 
 	online_perf_cpu = qdf_mem_malloc(
 		num_possible_cpus() * sizeof(unsigned long));
@@ -240,11 +240,11 @@ static int cds_sched_find_attach_cpu(p_cds_sched_context pSchedContext,
 #endif /* WLAN_OPEN_SOURCE */
 	}
 
-	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_LOW,
-		"%s: NUM PERF CORE %d, HIGH TPUTR REQ %d, RX THRE CPU %lu",
-		__func__, perf_core_count,
-		(int)pSchedContext->high_throughput_required,
-		pSchedContext->rx_thread_cpu);
+	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
+		  "%s: NUM PERF CORE %d, HIGH TPUTR REQ %d, RX THRE CPU %lu",
+		 __func__, perf_core_count,
+		 (int)pSchedContext->high_throughput_required,
+		 pSchedContext->rx_thread_cpu);
 
 success:
 	qdf_mem_free(online_perf_cpu);

+ 9 - 2
core/dp/ol/inc/ol_txrx_dbg.h

@@ -73,8 +73,15 @@ void ol_txrx_peer_display(ol_txrx_peer_handle peer, int indent);
 
 /*--- txrx stats display debug functions ---*/
 
-
-void ol_txrx_stats_display(ol_txrx_pdev_handle pdev);
+/**
+ * ol_txrx_stats_display() - display tx rx stats
+ * @pdev: pdev handle
+ * @level: verbosity level for logs
+ *
+ * Return: none
+ */
+void ol_txrx_stats_display(ol_txrx_pdev_handle pdev,
+			   enum qdf_stats_verbosity_level level);
 
 void ol_txrx_stats_clear(ol_txrx_pdev_handle pdev);
 

+ 3 - 0
core/dp/ol/inc/ol_txrx_stats.h

@@ -86,6 +86,9 @@ struct ol_txrx_stats_tx_dropped {
 	 * couldn't get an ack for
 	 */
 	struct ol_txrx_stats_elem no_ack;
+
+	/* MSDU which were dropped for other reasons */
+	struct ol_txrx_stats_elem others;
 };
 
 struct ol_txrx_tso_histogram {

+ 108 - 72
core/dp/txrx/ol_txrx.c

@@ -1064,43 +1064,43 @@ static void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev)
 	int msdu_idx;
 	int seg_idx;
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-		"TSO Statistics:");
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-		"TSO pkts %lld, bytes %lld\n",
-		pdev->stats.pub.tx.tso.tso_pkts.pkts,
-		pdev->stats.pub.tx.tso.tso_pkts.bytes);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "TSO Statistics:");
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "TSO pkts %lld, bytes %lld\n",
+		 pdev->stats.pub.tx.tso.tso_pkts.pkts,
+		 pdev->stats.pub.tx.tso.tso_pkts.bytes);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			"TSO Histogram for numbers of segments:\n"
-			"Single segment	%d\n"
-			"  2-5 segments	%d\n"
-			" 6-10 segments	%d\n"
-			"11-15 segments	%d\n"
-			"16-20 segments	%d\n"
-			"  20+ segments	%d\n",
-			pdev->stats.pub.tx.tso.tso_hist.pkts_1,
-			pdev->stats.pub.tx.tso.tso_hist.pkts_2_5,
-			pdev->stats.pub.tx.tso.tso_hist.pkts_6_10,
-			pdev->stats.pub.tx.tso.tso_hist.pkts_11_15,
-			pdev->stats.pub.tx.tso.tso_hist.pkts_16_20,
-			pdev->stats.pub.tx.tso.tso_hist.pkts_20_plus);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "TSO Histogram for numbers of segments:\n"
+		 "Single segment	%d\n"
+		 "  2-5 segments	%d\n"
+		 " 6-10 segments	%d\n"
+		 "11-15 segments	%d\n"
+		 "16-20 segments	%d\n"
+		 "  20+ segments	%d\n",
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_1,
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_2_5,
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_6_10,
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_11_15,
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_16_20,
+		 pdev->stats.pub.tx.tso.tso_hist.pkts_20_plus);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			"TSO History Buffer: Total size %d, current_index %d",
-			NUM_MAX_TSO_MSDUS,
-			TXRX_STATS_TSO_MSDU_IDX(pdev));
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "TSO History Buffer: Total size %d, current_index %d",
+		 NUM_MAX_TSO_MSDUS,
+		 TXRX_STATS_TSO_MSDU_IDX(pdev));
 
 	for (msdu_idx = 0; msdu_idx < NUM_MAX_TSO_MSDUS; msdu_idx++) {
 		if (TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx) == 0)
 			continue;
-		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-			"jumbo pkt idx: %d num segs %d gso_len %d total_len %d nr_frags %d",
-			msdu_idx,
-			TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, msdu_idx),
-			TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, msdu_idx),
-			TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx),
-			TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, msdu_idx));
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+			  "jumbo pkt idx: %d num segs %d gso_len %d total_len %d nr_frags %d",
+			 msdu_idx,
+			 TXRX_STATS_TSO_MSDU_NUM_SEG(pdev, msdu_idx),
+			 TXRX_STATS_TSO_MSDU_GSO_SIZE(pdev, msdu_idx),
+			 TXRX_STATS_TSO_MSDU_TOTAL_LEN(pdev, msdu_idx),
+			 TXRX_STATS_TSO_MSDU_NR_FRAGS(pdev, msdu_idx));
 
 		for (seg_idx = 0;
 			 ((seg_idx < TXRX_STATS_TSO_MSDU_NUM_SEG(pdev,
@@ -1109,22 +1109,22 @@ static void ol_txrx_stats_display_tso(ol_txrx_pdev_handle pdev)
 			struct qdf_tso_seg_t tso_seg =
 				 TXRX_STATS_TSO_SEG(pdev, msdu_idx, seg_idx);
 
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-				 "seg idx: %d", seg_idx);
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-				 "tso_enable: %d",
-				 tso_seg.tso_flags.tso_enable);
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-				 "fin %d syn %d rst %d psh %d ack %d urg %d ece %d cwr %d ns %d",
-				 tso_seg.tso_flags.fin, tso_seg.tso_flags.syn,
-				 tso_seg.tso_flags.rst, tso_seg.tso_flags.psh,
-				 tso_seg.tso_flags.ack, tso_seg.tso_flags.urg,
-				 tso_seg.tso_flags.ece, tso_seg.tso_flags.cwr,
-				 tso_seg.tso_flags.ns);
-			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_DEBUG,
-				 "tcp_seq_num: 0x%x ip_id: %d",
-				 tso_seg.tso_flags.tcp_seq_num,
-				 tso_seg.tso_flags.ip_id);
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "seg idx: %d", seg_idx);
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "tso_enable: %d",
+				  tso_seg.tso_flags.tso_enable);
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "fin %d syn %d rst %d psh %d ack %d urg %d ece %d cwr %d ns %d",
+				  tso_seg.tso_flags.fin, tso_seg.tso_flags.syn,
+				  tso_seg.tso_flags.rst, tso_seg.tso_flags.psh,
+				  tso_seg.tso_flags.ack, tso_seg.tso_flags.urg,
+				  tso_seg.tso_flags.ece, tso_seg.tso_flags.cwr,
+				  tso_seg.tso_flags.ns);
+			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+				  "tcp_seq_num: 0x%x ip_id: %d",
+				  tso_seg.tso_flags.tcp_seq_num,
+				  tso_seg.tso_flags.ip_id);
 		}
 	}
 }
@@ -4152,7 +4152,8 @@ int ol_txrx_debug(ol_txrx_vdev_handle vdev, int debug_specs)
 #endif
 	}
 	if (debug_specs & TXRX_DBG_MASK_STATS)
-		ol_txrx_stats_display(vdev->pdev);
+		ol_txrx_stats_display(vdev->pdev,
+				      QDF_STATS_VERBOSITY_LEVEL_HIGH);
 	if (debug_specs & TXRX_DBG_MASK_PROT_ANALYZE) {
 #if defined(ENABLE_TXRX_PROT_ANALYZE)
 		ol_txrx_prot_ans_display(vdev->pdev);
@@ -4287,13 +4288,13 @@ ol_txrx_stats(uint8_t vdev_id, char *buffer, unsigned int buf_len)
  */
 static void ol_txrx_disp_peer_cached_bufq_stats(struct ol_txrx_peer_t *peer)
 {
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-		"cached_bufq: curr %d drops %d hwm %d whatifs %d thresh %d",
-		peer->bufq_info.curr,
-		peer->bufq_info.dropped,
-		peer->bufq_info.high_water_mark,
-		peer->bufq_info.qdepth_no_thresh,
-		peer->bufq_info.thresh);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "cached_bufq: curr %d drops %d hwm %d whatifs %d thresh %d",
+		  peer->bufq_info.curr,
+		  peer->bufq_info.dropped,
+		  peer->bufq_info.high_water_mark,
+		  peer->bufq_info.qdepth_no_thresh,
+		  peer->bufq_info.thresh);
 }
 
 /**
@@ -4329,28 +4330,59 @@ static void ol_txrx_disp_peer_stats(ol_txrx_pdev_handle pdev)
 static void ol_txrx_disp_peer_stats(ol_txrx_pdev_handle pdev)
 {
 	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-		"peer stats not supported w/o QCA_SUPPORT_TXRX_LOCAL_PEER_ID");
+		  "peer stats not supported w/o QCA_SUPPORT_TXRX_LOCAL_PEER_ID");
 }
 #endif
 
-void ol_txrx_stats_display(ol_txrx_pdev_handle pdev)
+void ol_txrx_stats_display(ol_txrx_pdev_handle pdev,
+			   enum qdf_stats_verbosity_level level)
 {
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	u64 tx_dropped =
+		pdev->stats.pub.tx.dropped.download_fail.pkts
+		  + pdev->stats.pub.tx.dropped.target_discard.pkts
+		  + pdev->stats.pub.tx.dropped.no_ack.pkts
+		  + pdev->stats.pub.tx.dropped.others.pkts;
+
+	if (level == QDF_STATS_VERBOSITY_LEVEL_LOW) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+			  "STATS |%u %u|TX: %lld tso %lld ok %lld drops(%u-%lld %u-%lld %u-%lld ?-%lld hR-%lld)|RX: %lld drops(E %lld PI %lld ME %lld) fwd(S %d F %d SF %d)|",
+			  pdev->tx_desc.num_free,
+			  pdev->tx_desc.pool_size,
+			  pdev->stats.pub.tx.from_stack.pkts,
+			  pdev->stats.pub.tx.tso.tso_pkts.pkts,
+			  pdev->stats.pub.tx.delivered.pkts,
+			  htt_tx_status_download_fail,
+			  pdev->stats.pub.tx.dropped.download_fail.pkts,
+			  htt_tx_status_discard,
+			  pdev->stats.pub.tx.dropped.target_discard.pkts,
+			  htt_tx_status_no_ack,
+			  pdev->stats.pub.tx.dropped.no_ack.pkts,
+			  pdev->stats.pub.tx.dropped.others.pkts,
+			  pdev->stats.pub.tx.dropped.host_reject.pkts,
+			  pdev->stats.pub.rx.delivered.pkts,
+			  pdev->stats.pub.rx.dropped_err.pkts,
+			  pdev->stats.pub.rx.dropped_peer_invalid.pkts,
+			  pdev->stats.pub.rx.dropped_mic_err.pkts,
+			  pdev->stats.pub.rx.intra_bss_fwd.packets_stack,
+			  pdev->stats.pub.rx.intra_bss_fwd.packets_fwd,
+			  pdev->stats.pub.rx.intra_bss_fwd.packets_stack_n_fwd);
+		return;
+	}
+
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "TX PATH Statistics:");
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "sent %lld msdus (%lld B), host rejected %lld (%lld B), dropped %lld (%lld B)",
 		  pdev->stats.pub.tx.from_stack.pkts,
 		  pdev->stats.pub.tx.from_stack.bytes,
 		  pdev->stats.pub.tx.dropped.host_reject.pkts,
 		  pdev->stats.pub.tx.dropped.host_reject.bytes,
-		  pdev->stats.pub.tx.dropped.download_fail.pkts
-		  + pdev->stats.pub.tx.dropped.target_discard.pkts
-		  + pdev->stats.pub.tx.dropped.no_ack.pkts,
+		  tx_dropped,
 		  pdev->stats.pub.tx.dropped.download_fail.bytes
 		  + pdev->stats.pub.tx.dropped.target_discard.bytes
 		  + pdev->stats.pub.tx.dropped.no_ack.bytes);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
-		  "successfully delivered: %lld (%lld B), download fail: %lld (%lld B), target discard: %lld (%lld B), no ack: %lld (%lld B)",
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
+		  "successfully delivered: %lld (%lld B), download fail: %lld (%lld B), target discard: %lld (%lld B), no ack: %lld (%lld B) others: %lld (%lld B)",
 		  pdev->stats.pub.tx.delivered.pkts,
 		  pdev->stats.pub.tx.delivered.bytes,
 		  pdev->stats.pub.tx.dropped.download_fail.pkts,
@@ -4358,8 +4390,10 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev)
 		  pdev->stats.pub.tx.dropped.target_discard.pkts,
 		  pdev->stats.pub.tx.dropped.target_discard.bytes,
 		  pdev->stats.pub.tx.dropped.no_ack.pkts,
-		  pdev->stats.pub.tx.dropped.no_ack.bytes);
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+		  pdev->stats.pub.tx.dropped.no_ack.bytes,
+		  pdev->stats.pub.tx.dropped.others.pkts,
+		  pdev->stats.pub.tx.dropped.others.bytes);
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "Tx completions per HTT message:\n"
 		  "Single Packet  %d\n"
 		  " 2-10 Packets  %d\n"
@@ -4378,9 +4412,9 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev)
 		  pdev->stats.pub.tx.comp_histogram.pkts_51_60,
 		  pdev->stats.pub.tx.comp_histogram.pkts_61_plus);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "RX PATH Statistics:");
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "%lld ppdus, %lld mpdus, %lld msdus, %lld bytes\n"
 		  "dropped: err %lld (%lld B), peer_invalid %lld (%lld B), mic_err %lld (%lld B)\n"
 		  "msdus with frag_ind: %d msdus with offload_ind: %d",
@@ -4397,13 +4431,13 @@ void ol_txrx_stats_display(ol_txrx_pdev_handle pdev)
 		  pdev->stats.pub.rx.msdus_with_frag_ind,
 		  pdev->stats.pub.rx.msdus_with_offload_ind);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "  fwd to stack %d, fwd to fw %d, fwd to stack & fw  %d\n",
 		  pdev->stats.pub.rx.intra_bss_fwd.packets_stack,
 		  pdev->stats.pub.rx.intra_bss_fwd.packets_fwd,
 		  pdev->stats.pub.rx.intra_bss_fwd.packets_stack_n_fwd);
 
-	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+	QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
 		  "Rx packets per HTT message:\n"
 		  "Single Packet  %d\n"
 		  " 2-10 Packets  %d\n"
@@ -4661,7 +4695,9 @@ ol_txrx_ll_set_tx_pause_q_depth(uint8_t vdev_id, int pause_q_depth)
  *
  * Return: status
  */
-static QDF_STATUS ol_txrx_display_stats(void *soc, uint16_t value)
+static QDF_STATUS
+ol_txrx_display_stats(void *soc, uint16_t value,
+		      enum qdf_stats_verbosity_level verb_level)
 {
 	ol_txrx_pdev_handle pdev;
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
@@ -4675,7 +4711,7 @@ static QDF_STATUS ol_txrx_display_stats(void *soc, uint16_t value)
 
 	switch (value) {
 	case CDP_TXRX_PATH_STATS:
-		ol_txrx_stats_display(pdev);
+		ol_txrx_stats_display(pdev, verb_level);
 		break;
 	case CDP_TXRX_TSO_STATS:
 		ol_txrx_stats_display_tso(pdev);

+ 4 - 0
core/dp/txrx/ol_txrx_internal.h

@@ -269,6 +269,10 @@ ol_rx_mpdu_list_next(struct ol_txrx_pdev_t *pdev,
 				 pub.tx.dropped.download_fail.bytes, _b_cntrs);\
 			break;                                                 \
 		default:                                                       \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.others.pkts, _p_cntrs);        \
+			TXRX_STATS_ADD(_pdev,				       \
+				 pub.tx.dropped.others.bytes, _b_cntrs);       \
 			break;                                                 \
 		}                                                              \
 		TXRX_STATS_UPDATE_TX_COMP_HISTOGRAM(_pdev, _p_cntrs);          \

+ 20 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -8154,6 +8154,25 @@ enum hdd_link_speed_rpt_type {
 #define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN          (0)
 #define CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX          (16000)
 
+/*
+ * <ini>
+ * periodic_stats_display_time - time(seconds) after which stats will be printed
+ * @Min: 0
+ * @Max: 256
+ * @Default: 10
+ *
+ * This values specifies the recurring time period after which stats will be
+ * printed in wlan driver logs.
+ *
+ * Usage: Internal / External
+ *
+ * </ini>
+ */
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_NAME       "periodic_stats_display_time"
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_DEFAULT    (10)
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_MIN        (0)
+#define CFG_PERIODIC_STATS_DISPLAY_TIME_MAX        (256)
+
 #endif /* MSM_PLATFORM */
 
 #ifdef WLAN_FEATURE_11W
@@ -14064,6 +14083,7 @@ struct hdd_config {
 	uint32_t tcpDelackThresholdLow;
 	uint32_t tcp_tx_high_tput_thres;
 	uint32_t tcp_delack_timer_count;
+	u8  periodic_stats_disp_time;
 #endif /* MSM_PLATFORM */
 
 	/* FW debug log parameters */

+ 5 - 3
core/hdd/inc/wlan_hdd_main.h

@@ -897,8 +897,8 @@ struct hdd_multicast_addr_list {
  * @unpause_count - unpause counter
  */
 struct hdd_netif_queue_stats {
-	uint16_t pause_count;
-	uint16_t unpause_count;
+	u32 pause_count;
+	u32 unpause_count;
 	qdf_time_t total_pause_time;
 };
 
@@ -2233,7 +2233,9 @@ int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value);
 void wlan_hdd_deinit_tx_rx_histogram(struct hdd_context *hdd_ctx);
 void wlan_hdd_display_tx_rx_histogram(struct hdd_context *hdd_ctx);
 void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx);
-void wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx);
+void
+wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
+				     enum qdf_stats_verbosity_level verb_lvl);
 void wlan_hdd_clear_netif_queue_history(struct hdd_context *hdd_ctx);
 const char *hdd_get_fwpath(void);
 void hdd_indicate_mgmt_frame(tSirSmeMgmtFrameInd *frame_ind);

+ 9 - 1
core/hdd/src/wlan_hdd_cfg.c

@@ -3251,6 +3251,12 @@ struct reg_table_entry g_registry_table[] = {
 		     CFG_TCP_TX_HIGH_TPUT_THRESHOLD_DEFAULT,
 		     CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MIN,
 		     CFG_TCP_TX_HIGH_TPUT_THRESHOLD_MAX),
+	REG_VARIABLE(CFG_PERIODIC_STATS_DISPLAY_TIME_NAME, WLAN_PARAM_Integer,
+		     struct hdd_config, periodic_stats_disp_time,
+		     VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_DEFAULT,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_MIN,
+		     CFG_PERIODIC_STATS_DISPLAY_TIME_MAX),
 #endif
 
 	REG_VARIABLE(CFG_ENABLE_FW_LOG_TYPE, WLAN_PARAM_Integer,
@@ -6594,7 +6600,9 @@ void hdd_cfg_print(struct hdd_context *hdd_ctx)
 	hdd_debug("Name = [%s] Value = [%u] ",
 		  CFG_TCP_TX_HIGH_TPUT_THRESHOLD_NAME,
 		  hdd_ctx->config->tcp_tx_high_tput_thres);
-
+	hdd_debug("Name = [%s] Value = [%u] ",
+		  CFG_PERIODIC_STATS_DISPLAY_TIME_NAME,
+		  hdd_ctx->config->periodic_stats_disp_time);
 #endif
 
 	hdd_debug("Name = [gIgnoreCAC] Value = [%u] ",

+ 148 - 9
core/hdd/src/wlan_hdd_main.c

@@ -59,6 +59,7 @@
 #include "qdf_trace.h"
 #include <cdp_txrx_peer_ops.h>
 #include <cdp_txrx_misc.h>
+#include <cdp_txrx_stats.h>
 
 #include <net/addrconf.h>
 #include <linux/wireless.h>
@@ -6411,6 +6412,53 @@ static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
 	return ret_val;
 }
 
+#ifdef MSM_PLATFORM
+/**
+ * hdd_display_periodic_stats() - Function to display periodic stats
+ * @hdd_ctx - handle to hdd context
+ * @bool data_in_interval - true, if data detected in bw time interval
+ *
+ * The periodicity is determined by hdd_ctx->config->periodic_stats_disp_time.
+ * Stats show up in wlan driver logs.
+ *
+ * Returns: None
+ */
+static inline
+void hdd_display_periodic_stats(struct hdd_context *hdd_ctx,
+				bool data_in_interval)
+{
+	static u32 counter;
+	static bool data_in_time_period;
+	ol_txrx_pdev_handle pdev;
+
+	if (hdd_ctx->config->periodic_stats_disp_time == 0)
+		return;
+
+	pdev = cds_get_context(QDF_MODULE_ID_TXRX);
+	if (!pdev) {
+		hdd_err("pdev is NULL");
+		return;
+	}
+
+	counter++;
+	if (data_in_interval)
+		data_in_time_period = data_in_interval;
+
+	if (counter * hdd_ctx->config->busBandwidthComputeInterval >=
+		hdd_ctx->config->periodic_stats_disp_time * 1000) {
+		if (data_in_time_period) {
+			cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
+					  CDP_TXRX_PATH_STATS,
+					  QDF_STATS_VERBOSITY_LEVEL_LOW);
+			wlan_hdd_display_netif_queue_history
+				(hdd_ctx, QDF_STATS_VERBOSITY_LEVEL_LOW);
+			qdf_dp_trace_dump_stats();
+		}
+		counter = 0;
+		data_in_time_period = false;
+	}
+}
+
 /**
  * hdd_pld_request_bus_bandwidth() - Function to control bus bandwidth
  * @hdd_ctx - handle to hdd context
@@ -6422,12 +6470,12 @@ static int hdd_wiphy_init(struct hdd_context *hdd_ctx)
  *
  * Returns: None
  */
-#ifdef MSM_PLATFORM
+
 static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
 					  const uint64_t tx_packets,
 					  const uint64_t rx_packets)
 {
-	uint64_t total = tx_packets + rx_packets;
+	u64 total_pkts = tx_packets + rx_packets;
 	uint64_t temp_rx = 0;
 	uint64_t temp_tx = 0;
 	enum pld_bus_width_type next_vote_level = PLD_BUS_WIDTH_NONE;
@@ -6439,11 +6487,11 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
 	bool rx_level_change = false;
 	bool tx_level_change = false;
 
-	if (total > hdd_ctx->config->busBandwidthHighThreshold)
+	if (total_pkts > hdd_ctx->config->busBandwidthHighThreshold)
 		next_vote_level = PLD_BUS_WIDTH_HIGH;
-	else if (total > hdd_ctx->config->busBandwidthMediumThreshold)
+	else if (total_pkts > hdd_ctx->config->busBandwidthMediumThreshold)
 		next_vote_level = PLD_BUS_WIDTH_MEDIUM;
-	else if (total > hdd_ctx->config->busBandwidthLowThreshold)
+	else if (total_pkts > hdd_ctx->config->busBandwidthLowThreshold)
 		next_vote_level = PLD_BUS_WIDTH_LOW;
 	else
 		next_vote_level = PLD_BUS_WIDTH_NONE;
@@ -6540,7 +6588,6 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
 	}
 
 	index = hdd_ctx->hdd_txrx_hist_idx;
-
 	if (vote_level_change || tx_level_change || rx_level_change) {
 		hdd_ctx->hdd_txrx_hist[index].next_tx_level = next_tx_level;
 		hdd_ctx->hdd_txrx_hist[index].next_rx_level = next_rx_level;
@@ -6551,6 +6598,8 @@ static void hdd_pld_request_bus_bandwidth(struct hdd_context *hdd_ctx,
 		hdd_ctx->hdd_txrx_hist_idx++;
 		hdd_ctx->hdd_txrx_hist_idx &= NUM_TX_RX_HISTOGRAM_MASK;
 	}
+
+	hdd_display_periodic_stats(hdd_ctx, (total_pkts > 0) ? true : false);
 }
 
 #define HDD_BW_GET_DIFF(_x, _y) (unsigned long)((ULONG_MAX - (_y)) + (_x) + 1)
@@ -6852,13 +6901,100 @@ void wlan_hdd_clear_tx_rx_histogram(struct hdd_context *hdd_ctx)
 		(sizeof(struct hdd_tx_rx_histogram) * NUM_TX_RX_HISTOGRAM));
 }
 
+/* length of the netif queue log needed per adapter */
+#define ADAP_NETIFQ_LOG_LEN ((20 * WLAN_REASON_TYPE_MAX) + 50)
+
+/**
+ *
+ * hdd_display_netif_queue_history_compact() - display compact netifq history
+ * @hdd_ctx: hdd context
+ *
+ * Return: none
+ */
+static void
+hdd_display_netif_queue_history_compact(struct hdd_context *hdd_ctx)
+{
+	int adapter_num = 0;
+	int i;
+	int bytes_written;
+	u32 tbytes;
+	qdf_time_t total, pause, unpause, curr_time, delta;
+	QDF_STATUS status;
+	char temp_str[20 * WLAN_REASON_TYPE_MAX];
+	char comb_log_str[(ADAP_NETIFQ_LOG_LEN * MAX_NUMBER_OF_ADAPTERS) + 1];
+	struct hdd_adapter *adapter = NULL;
+	hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
+
+	bytes_written = 0;
+	qdf_mem_set(comb_log_str, 0, sizeof(comb_log_str));
+	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
+	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
+		adapter = adapter_node->adapter;
+
+		curr_time = qdf_system_ticks();
+		total = curr_time - adapter->start_time;
+		delta = curr_time - adapter->last_time;
+
+		if (adapter->pause_map) {
+			pause = adapter->total_pause_time + delta;
+			unpause = adapter->total_unpause_time;
+		} else {
+			unpause = adapter->total_unpause_time + delta;
+			pause = adapter->total_pause_time;
+		}
+
+		tbytes = 0;
+		qdf_mem_set(temp_str, 0, sizeof(temp_str));
+		for (i = WLAN_CONTROL_PATH; i < WLAN_REASON_TYPE_MAX; i++) {
+			if (adapter->queue_oper_stats[i].pause_count == 0)
+				continue;
+			tbytes +=
+				snprintf(
+					&temp_str[tbytes],
+					(tbytes >= sizeof(temp_str) ?
+					0 : sizeof(temp_str) - tbytes),
+					"%d(%d,%d) ",
+					i,
+					adapter->queue_oper_stats[i].
+								pause_count,
+					adapter->queue_oper_stats[i].
+								unpause_count);
+		}
+		if (tbytes >= sizeof(temp_str))
+			hdd_warn("log truncated");
+
+		bytes_written += snprintf(&comb_log_str[bytes_written],
+			bytes_written >= sizeof(comb_log_str) ? 0 :
+					sizeof(comb_log_str) - bytes_written,
+			"[%d %d] (%d) %u/%ums %s|",
+			adapter->session_id, adapter->device_mode,
+			adapter->pause_map,
+			qdf_system_ticks_to_msecs(pause),
+			qdf_system_ticks_to_msecs(total),
+			temp_str);
+
+		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
+		adapter_node = next;
+		adapter_num++;
+	}
+
+	/* using QDF_TRACE to avoid printing function name */
+	QDF_TRACE(QDF_MODULE_ID_HDD, QDF_TRACE_LEVEL_INFO_LOW,
+		  "STATS |%s", comb_log_str);
+
+	if (bytes_written >= sizeof(comb_log_str))
+		hdd_warn("log string truncated");
+}
+
 /**
  * wlan_hdd_display_netif_queue_history() - display netif queue history
  * @hdd_ctx: hdd context
  *
  * Return: none
  */
-void wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx)
+void
+wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx,
+				     enum qdf_stats_verbosity_level verb_lvl)
 {
 
 	struct hdd_adapter *adapter = NULL;
@@ -6867,6 +7003,11 @@ void wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx)
 	int i;
 	qdf_time_t total, pause, unpause, curr_time, delta;
 
+	if (verb_lvl == QDF_STATS_VERBOSITY_LEVEL_LOW) {
+		hdd_display_netif_queue_history_compact(hdd_ctx);
+		return;
+	}
+
 	status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
 	while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
 		adapter = adapter_node->adapter;
@@ -6932,8 +7073,6 @@ void wlan_hdd_display_netif_queue_history(struct hdd_context *hdd_ctx)
 		status = hdd_get_next_adapter(hdd_ctx, adapter_node, &next);
 		adapter_node = next;
 	}
-
-
 }
 
 /**

+ 2 - 1
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -549,7 +549,8 @@ static void __hdd_softap_tx_timeout(struct net_device *dev)
 			  i, netif_tx_queue_stopped(txq), txq->trans_start);
 	}
 
-	wlan_hdd_display_netif_queue_history(hdd_ctx);
+	wlan_hdd_display_netif_queue_history(hdd_ctx,
+					     QDF_STATS_VERBOSITY_LEVEL_HIGH);
 	cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
 	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
 			"carrier state: %d", netif_carrier_ok(dev));

+ 2 - 1
core/hdd/src/wlan_hdd_tx_rx.c

@@ -897,7 +897,8 @@ static void __hdd_tx_timeout(struct net_device *dev)
 	QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_DEBUG,
 		  "carrier state: %d", netif_carrier_ok(dev));
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
-	wlan_hdd_display_netif_queue_history(hdd_ctx);
+	wlan_hdd_display_netif_queue_history(hdd_ctx,
+					     QDF_STATS_VERBOSITY_LEVEL_HIGH);
 	cdp_dump_flow_pool_info(cds_get_context(QDF_MODULE_ID_SOC));
 
 	++adapter->hdd_stats.tx_rx_stats.tx_timeout_cnt;

+ 5 - 2
core/hdd/src/wlan_hdd_wext.c

@@ -3229,7 +3229,9 @@ int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value)
 		wlan_hdd_display_tx_rx_histogram(hdd_ctx);
 		break;
 	case CDP_HDD_NETIF_OPER_HISTORY:
-		wlan_hdd_display_netif_queue_history(hdd_ctx);
+		wlan_hdd_display_netif_queue_history
+					(hdd_ctx,
+					 QDF_STATS_VERBOSITY_LEVEL_HIGH);
 		break;
 	case CDP_HIF_STATS:
 		hdd_display_hif_stats();
@@ -3248,7 +3250,8 @@ int hdd_wlan_dump_stats(struct hdd_adapter *adapter, int value)
 		break;
 	default:
 		status = cdp_display_stats(cds_get_context(QDF_MODULE_ID_SOC),
-							value);
+						value,
+						QDF_STATS_VERBOSITY_LEVEL_HIGH);
 		if (status == QDF_STATUS_E_INVAL) {
 			hdd_display_stats_help();
 			ret = EINVAL;

+ 2 - 1
core/wma/src/wma_data.c

@@ -2804,7 +2804,8 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen,
 			 * WMA_TX_FRAME_COMPLETE_TIMEOUT (1 sec)
 			 */
 			/* display scheduler stats */
-			return cdp_display_stats(soc, CDP_SCHEDULER_STATS);
+			return cdp_display_stats(soc, CDP_SCHEDULER_STATS,
+						QDF_STATS_VERBOSITY_LEVEL_HIGH);
 		}
 	}