xref: /wlan-driver/qcacld-3.0/core/dp/htt/htt_fw_stats.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * @file htt_fw_stats.c
22  * @brief Provide functions to process FW status retrieved from FW.
23  */
24 
25 #include <htc_api.h>            /* HTC_PACKET */
26 #include <htt.h>                /* HTT_T2H_MSG_TYPE, etc. */
27 #include <qdf_nbuf.h>           /* qdf_nbuf_t */
28 #include <qdf_mem.h>         /* qdf_mem_set */
29 #include <ol_fw_tx_dbg.h>       /* ol_fw_tx_dbg_ppdu_base */
30 
31 #include <ol_htt_rx_api.h>
32 #include <ol_txrx_htt_api.h>    /* htt_tx_status */
33 
34 #include <htt_internal.h>
35 
36 #include <wlan_defs.h>
37 
38 static char *bw_str_arr[] = {"20MHz", "40MHz", "80MHz", "160MHz"};
39 
40 /*
41  * Defined the macro tx_rate_stats_print_cmn()
42  * so that this could be used in both
43  * htt_t2h_stats_tx_rate_stats_print() &
44  * htt_t2h_stats_tx_rate_stats_print_v2().
45  * Each of these functions take a different structure as argument,
46  * but with common fields in the structures--so using a macro
47  * to bypass the strong type-checking of a function seems a simple
48  * trick to use to avoid the code duplication.
49  */
50 #define tx_rate_stats_print_cmn(_tx_rate_info, _concise) \
51 	do {							 \
52 		qdf_nofl_info("TX Rate Info:");			 \
53 		\
54 		/* MCS */					 \
55 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
56 				"MCS counts (0..9)",		 \
57 				_tx_rate_info->mcs[0],		 \
58 				_tx_rate_info->mcs[1],		 \
59 				_tx_rate_info->mcs[2],		 \
60 				_tx_rate_info->mcs[3],		 \
61 				_tx_rate_info->mcs[4],		 \
62 				_tx_rate_info->mcs[5],		 \
63 				_tx_rate_info->mcs[6],		 \
64 				_tx_rate_info->mcs[7],		 \
65 				_tx_rate_info->mcs[8],		 \
66 				_tx_rate_info->mcs[9]);		 \
67 		\
68 		/* SGI */					 \
69 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
70 				"SGI counts (0..9)",		 \
71 				_tx_rate_info->sgi[0],		 \
72 				_tx_rate_info->sgi[1],		 \
73 				_tx_rate_info->sgi[2],		 \
74 				_tx_rate_info->sgi[3],		 \
75 				_tx_rate_info->sgi[4],		 \
76 				_tx_rate_info->sgi[5],		 \
77 				_tx_rate_info->sgi[6],		 \
78 				_tx_rate_info->sgi[7],		 \
79 				_tx_rate_info->sgi[8],		 \
80 				_tx_rate_info->sgi[9]);		 \
81 		\
82 		/* NSS */					 \
83 		qdf_nofl_info("NSS  counts: 1x1 %d, 2x2 %d, 3x3 %d", \
84 				_tx_rate_info->nss[0],		 \
85 				_tx_rate_info->nss[1], _tx_rate_info->nss[2]);\
86 		\
87 		/* BW */					 \
88 		if (ARRAY_SIZE(_tx_rate_info->bw) == 3) \
89 			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d", \
90 				bw_str_arr[0], _tx_rate_info->bw[0],	 \
91 				bw_str_arr[1], _tx_rate_info->bw[1],	 \
92 				bw_str_arr[2], _tx_rate_info->bw[2]);	 \
93 		else if (ARRAY_SIZE(_tx_rate_info->bw) == 4) \
94 			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d, %s %d", \
95 				bw_str_arr[0], _tx_rate_info->bw[0],	 \
96 				bw_str_arr[1], _tx_rate_info->bw[1],	 \
97 				bw_str_arr[2], _tx_rate_info->bw[2],     \
98 				bw_str_arr[3], _tx_rate_info->bw[3]);	 \
99 		\
100 		\
101 		/* Preamble */					 \
102 		qdf_nofl_info("Preamble (O C H V) counts: %d, %d, %d, %d",\
103 				_tx_rate_info->pream[0],		 \
104 				_tx_rate_info->pream[1],		 \
105 				_tx_rate_info->pream[2],		 \
106 				_tx_rate_info->pream[3]);		 \
107 		\
108 		/* STBC rate counts */				 \
109 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
110 				"STBC rate counts (0..9)",	 \
111 				_tx_rate_info->stbc[0],		 \
112 				_tx_rate_info->stbc[1],		 \
113 				_tx_rate_info->stbc[2],		 \
114 				_tx_rate_info->stbc[3],		 \
115 				_tx_rate_info->stbc[4],		 \
116 				_tx_rate_info->stbc[5],		 \
117 				_tx_rate_info->stbc[6],		 \
118 				_tx_rate_info->stbc[7],		 \
119 				_tx_rate_info->stbc[8],		 \
120 				_tx_rate_info->stbc[9]);	 \
121 			\
122 		/* LDPC and TxBF counts */			 \
123 		qdf_nofl_info("LDPC Counts: %d", _tx_rate_info->ldpc);\
124 		qdf_nofl_info("RTS Counts: %d", _tx_rate_info->rts_cnt);\
125 		/* RSSI Values for last ack frames */		\
126 		qdf_nofl_info("Ack RSSI: %d", _tx_rate_info->ack_rssi);\
127 	} while (0)
128 
htt_t2h_stats_tx_rate_stats_print(wlan_dbg_tx_rate_info_t * tx_rate_info,int concise)129 static void htt_t2h_stats_tx_rate_stats_print(wlan_dbg_tx_rate_info_t *
130 					      tx_rate_info, int concise)
131 {
132 	tx_rate_stats_print_cmn(tx_rate_info, concise);
133 }
134 
htt_t2h_stats_tx_rate_stats_print_v2(wlan_dbg_tx_rate_info_v2_t * tx_rate_info,int concise)135 static void htt_t2h_stats_tx_rate_stats_print_v2(wlan_dbg_tx_rate_info_v2_t *
136 					      tx_rate_info, int concise)
137 {
138 	tx_rate_stats_print_cmn(tx_rate_info, concise);
139 }
140 
141 /*
142  * Defined the macro rx_rate_stats_print_cmn()
143  * so that this could be used in both
144  * htt_t2h_stats_rx_rate_stats_print() &
145  * htt_t2h_stats_rx_rate_stats_print_v2().
146  * Each of these functions take a different structure as argument,
147  * but with common fields in the structures -- so using a macro
148  * to bypass the strong type-checking of a function seems a simple
149  * trick to use to avoid the code duplication.
150  */
151 #define rx_rate_stats_print_cmn(_rx_phy_info, _concise) \
152 	do {							\
153 		qdf_nofl_info("RX Rate Info:");			\
154 		\
155 		/* MCS */					\
156 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
157 				"MCS counts (0..9)",		 \
158 				_rx_phy_info->mcs[0],			\
159 				_rx_phy_info->mcs[1],			\
160 				_rx_phy_info->mcs[2],			\
161 				_rx_phy_info->mcs[3],			\
162 				_rx_phy_info->mcs[4],			\
163 				_rx_phy_info->mcs[5],			\
164 				_rx_phy_info->mcs[6],			\
165 				_rx_phy_info->mcs[7],			\
166 				_rx_phy_info->mcs[8],			\
167 				_rx_phy_info->mcs[9]);			\
168 		\
169 		/* SGI */						\
170 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
171 				"SGI counts (0..9)",		 \
172 				_rx_phy_info->sgi[0],			\
173 				_rx_phy_info->sgi[1],			\
174 				_rx_phy_info->sgi[2],			\
175 				_rx_phy_info->sgi[3],			\
176 				_rx_phy_info->sgi[4],			\
177 				_rx_phy_info->sgi[5],			\
178 				_rx_phy_info->sgi[6],			\
179 				_rx_phy_info->sgi[7],			\
180 				_rx_phy_info->sgi[8],			\
181 				_rx_phy_info->sgi[9]);			\
182 		\
183 		/*
184 		 * NSS							       \
185 		 * nss[0] just holds the count of non-stbc frames that were    \
186 		 * sent at 1x1 rates and nsts holds the count of frames sent   \
187 		 * with stbc.						       \
188 		 * It was decided to not include PPDUs sent w/ STBC in nss[0]  \
189 		 * since it would be easier to change the value that needs to  \
190 		 * be printed (from stbc+non-stbc count to only non-stbc count)\
191 		 * if needed in the future. Hence the addition in the host code\
192 		 * at this line.
193 		 */							       \
194 		qdf_nofl_info("NSS  counts: 1x1 %d, 2x2 %d, 3x3 %d, 4x4 %d",\
195 				_rx_phy_info->nss[0] + _rx_phy_info->nsts,\
196 				_rx_phy_info->nss[1],			\
197 				_rx_phy_info->nss[2],			\
198 				_rx_phy_info->nss[3]);		\
199 		\
200 		/* NSTS */					\
201 		qdf_nofl_info("NSTS count: %d", _rx_phy_info->nsts);	\
202 		\
203 		/* BW */					\
204 		if (ARRAY_SIZE(_rx_phy_info->bw) == 3) \
205 			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d",	\
206 				bw_str_arr[0], _rx_phy_info->bw[0],	\
207 				bw_str_arr[1], _rx_phy_info->bw[1],	\
208 				bw_str_arr[2], _rx_phy_info->bw[2]);	\
209 		else if (ARRAY_SIZE(_rx_phy_info->bw) == 4) \
210 			qdf_nofl_info("BW counts: %s %d, %s %d, %s %d, %s %d", \
211 				bw_str_arr[0], _rx_phy_info->bw[0],	\
212 				bw_str_arr[1], _rx_phy_info->bw[1],	\
213 				bw_str_arr[2], _rx_phy_info->bw[2],    \
214 				bw_str_arr[3], _rx_phy_info->bw[3]);	\
215 		\
216 		/* Preamble */					\
217 		qdf_nofl_info("Preamble counts: %d, %d, %d, %d, %d, %d",\
218 				_rx_phy_info->pream[0],		\
219 				_rx_phy_info->pream[1],		\
220 				_rx_phy_info->pream[2],		\
221 				_rx_phy_info->pream[3],		\
222 				_rx_phy_info->pream[4],		\
223 				_rx_phy_info->pream[5]);		\
224 		\
225 		/* STBC rate counts */				\
226 		qdf_nofl_info("%s: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d",\
227 				"STBC rate counts (0..9)",	\
228 				_rx_phy_info->stbc[0],		\
229 				_rx_phy_info->stbc[1],		\
230 				_rx_phy_info->stbc[2],		\
231 				_rx_phy_info->stbc[3],		\
232 				_rx_phy_info->stbc[4],		\
233 				_rx_phy_info->stbc[5],		\
234 				_rx_phy_info->stbc[6],		\
235 				_rx_phy_info->stbc[7],		\
236 				_rx_phy_info->stbc[8],		\
237 				_rx_phy_info->stbc[9]);		\
238 		\
239 		/* LDPC and TxBF counts */			\
240 		qdf_nofl_info("LDPC TXBF Counts: %d, %d",		\
241 				_rx_phy_info->ldpc, _rx_phy_info->txbf);\
242 		/* RSSI Values for last received frames */	\
243 		qdf_nofl_info("RSSI (data, mgmt): %d, %d", _rx_phy_info->data_rssi,\
244 				_rx_phy_info->mgmt_rssi);		\
245 		\
246 		qdf_nofl_info("RSSI Chain 0 (0x%02x 0x%02x 0x%02x 0x%02x)",\
247 				((_rx_phy_info->rssi_chain0 >> 24) & 0xff),\
248 				((_rx_phy_info->rssi_chain0 >> 16) & 0xff),\
249 				((_rx_phy_info->rssi_chain0 >> 8) & 0xff),\
250 				((_rx_phy_info->rssi_chain0 >> 0) & 0xff));\
251 		\
252 		qdf_nofl_info("RSSI Chain 1 (0x%02x 0x%02x 0x%02x 0x%02x)",\
253 				((_rx_phy_info->rssi_chain1 >> 24) & 0xff),\
254 				((_rx_phy_info->rssi_chain1 >> 16) & 0xff),\
255 				((_rx_phy_info->rssi_chain1 >> 8) & 0xff),\
256 				((_rx_phy_info->rssi_chain1 >> 0) & 0xff));\
257 		\
258 		qdf_nofl_info("RSSI Chain 2 (0x%02x 0x%02x 0x%02x 0x%02x)",\
259 				((_rx_phy_info->rssi_chain2 >> 24) & 0xff),\
260 				((_rx_phy_info->rssi_chain2 >> 16) & 0xff),\
261 				((_rx_phy_info->rssi_chain2 >> 8) & 0xff),\
262 				((_rx_phy_info->rssi_chain2 >> 0) & 0xff));\
263 	} while (0)
264 
htt_t2h_stats_rx_rate_stats_print(wlan_dbg_rx_rate_info_t * rx_phy_info,int concise)265 static void htt_t2h_stats_rx_rate_stats_print(wlan_dbg_rx_rate_info_t *
266 					      rx_phy_info, int concise)
267 {
268 	rx_rate_stats_print_cmn(rx_phy_info, concise);
269 }
270 
htt_t2h_stats_rx_rate_stats_print_v2(wlan_dbg_rx_rate_info_v2_t * rx_phy_info,int concise)271 static void htt_t2h_stats_rx_rate_stats_print_v2(wlan_dbg_rx_rate_info_v2_t *
272 					      rx_phy_info, int concise)
273 {
274 	rx_rate_stats_print_cmn(rx_phy_info, concise);
275 }
276 
277 static void
htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats * wlan_pdev_stats,int concise)278 htt_t2h_stats_pdev_stats_print(struct wlan_dbg_stats *wlan_pdev_stats,
279 			       int concise)
280 {
281 	struct wlan_dbg_tx_stats *tx = &wlan_pdev_stats->tx;
282 	struct wlan_dbg_rx_stats *rx = &wlan_pdev_stats->rx;
283 
284 	qdf_nofl_info("WAL Pdev stats:");
285 	qdf_nofl_info("### Tx ###");
286 
287 	/* Num HTT cookies queued to dispatch list */
288 	qdf_nofl_info("comp_queued       :%d", tx->comp_queued);
289 	/* Num HTT cookies dispatched */
290 	qdf_nofl_info("comp_delivered    :%d", tx->comp_delivered);
291 	/* Num MSDU queued to WAL */
292 	qdf_nofl_info("msdu_enqued       :%d", tx->msdu_enqued);
293 	/* Num MPDU queued to WAL */
294 	qdf_nofl_info("mpdu_enqued       :%d", tx->mpdu_enqued);
295 	/* Num MSDUs dropped by WMM limit */
296 	qdf_nofl_info("wmm_drop          :%d", tx->wmm_drop);
297 	/* Num Local frames queued */
298 	qdf_nofl_info("local_enqued      :%d", tx->local_enqued);
299 	/* Num Local frames done */
300 	qdf_nofl_info("local_freed       :%d", tx->local_freed);
301 	/* Num queued to HW */
302 	qdf_nofl_info("hw_queued         :%d", tx->hw_queued);
303 	/* Num PPDU reaped from HW */
304 	qdf_nofl_info("hw_reaped         :%d", tx->hw_reaped);
305 	/* Num underruns */
306 	qdf_nofl_info("mac underrun      :%d", tx->underrun);
307 	/* Num underruns */
308 	qdf_nofl_info("phy underrun      :%d", tx->phy_underrun);
309 	/* Num PPDUs cleaned up in TX abort */
310 	qdf_nofl_info("tx_abort          :%d", tx->tx_abort);
311 	/* Num MPDUs requed by SW */
312 	qdf_nofl_info("mpdus_requed      :%d", tx->mpdus_requed);
313 	/* Excessive retries */
314 #if defined(AR900B)
315 	qdf_nofl_info("excess retries    :%d", tx->tx_xretry);
316 #endif
317 	/* last data rate */
318 	qdf_nofl_info("last rc           :%d", tx->data_rc);
319 	/* scheduler self triggers */
320 	qdf_nofl_info("sched self trig   :%d", tx->self_triggers);
321 	/* SW retry failures */
322 	qdf_nofl_info("ampdu retry failed:%d", tx->sw_retry_failure);
323 	/* illegal phy rate errors */
324 	qdf_nofl_info("illegal rate errs :%d", tx->illgl_rate_phy_err);
325 	/* pdev continuous excessive retries  */
326 	qdf_nofl_info("pdev cont xretry  :%d", tx->pdev_cont_xretry);
327 	/* pdev continuous excessive retries  */
328 	qdf_nofl_info("pdev tx timeout   :%d", tx->pdev_tx_timeout);
329 	/* pdev resets  */
330 	qdf_nofl_info("pdev resets       :%d", tx->pdev_resets);
331 	/* PPDU > txop duration  */
332 	qdf_nofl_info("ppdu txop ovf     :%d", tx->txop_ovf);
333 #if defined(AR900B)
334 	qdf_nofl_info("seq_posted        :%d", tx->seq_posted);
335 	qdf_nofl_info("seq_failed_queueing      :%d", tx->seq_failed_queueing);
336 	qdf_nofl_info("seq_completed     :%d", tx->seq_completed);
337 	qdf_nofl_info("seq_restarted     :%d", tx->seq_restarted);
338 	qdf_nofl_info("mu_seq_posted     :%d", tx->mu_seq_posted);
339 	qdf_nofl_info("mpdus_sw_flush    :%d", tx->mpdus_sw_flush);
340 	qdf_nofl_info("mpdus_hw_filter   :%d", tx->mpdus_hw_filter);
341 	qdf_nofl_info("mpdus_truncated   :%d", tx->mpdus_truncated);
342 	qdf_nofl_info("mpdus_ack_failed  :%d", tx->mpdus_ack_failed);
343 	qdf_nofl_info("mpdus_expired     :%d", tx->mpdus_expired);
344 #endif
345 
346 	qdf_nofl_info("### Rx ###");
347 	/* Cnts any change in ring routing mid-ppdu */
348 	qdf_nofl_info("ppdu_route_change :%d", rx->mid_ppdu_route_change);
349 	/* Total number of statuses processed */
350 	qdf_nofl_info("status_rcvd       :%d", rx->status_rcvd);
351 	/* Extra frags on rings 0-3 */
352 	qdf_nofl_info("r0_frags          :%d", rx->r0_frags);
353 	qdf_nofl_info("r1_frags          :%d", rx->r1_frags);
354 	qdf_nofl_info("r2_frags          :%d", rx->r2_frags);
355 	qdf_nofl_info("r3_frags          :%d", rx->r3_frags);
356 	/* MSDUs / MPDUs delivered to HTT */
357 	qdf_nofl_info("htt_msdus         :%d", rx->htt_msdus);
358 	qdf_nofl_info("htt_mpdus         :%d", rx->htt_mpdus);
359 	/* MSDUs / MPDUs delivered to local stack */
360 	qdf_nofl_info("loc_msdus         :%d", rx->loc_msdus);
361 	qdf_nofl_info("loc_mpdus         :%d", rx->loc_mpdus);
362 	/* AMSDUs that have more MSDUs than the status ring size */
363 	qdf_nofl_info("oversize_amsdu    :%d", rx->oversize_amsdu);
364 	/* Number of PHY errors */
365 	qdf_nofl_info("phy_errs          :%d", rx->phy_errs);
366 	/* Number of PHY errors dropped */
367 	qdf_nofl_info("phy_errs dropped  :%d", rx->phy_err_drop);
368 	/* Number of mpdu errors - FCS, MIC, ENC etc. */
369 	qdf_nofl_info("mpdu_errs         :%d", rx->mpdu_errs);
370 #if defined(AR900B)
371 	qdf_nofl_info("rx_ovfl_errs      :%d", rx->rx_ovfl_errs);
372 #endif
373 
374 }
375 
376 static void
htt_t2h_stats_rx_reorder_stats_print(struct rx_reorder_stats * stats_ptr,int concise)377 htt_t2h_stats_rx_reorder_stats_print(struct rx_reorder_stats *stats_ptr,
378 				     int concise)
379 {
380 	qdf_nofl_info("Rx reorder statistics:");
381 	qdf_nofl_info("  %u non-QoS frames received",
382 		      stats_ptr->deliver_non_qos);
383 	qdf_nofl_info("  %u frames received in-order",
384 		      stats_ptr->deliver_in_order);
385 	qdf_nofl_info("  %u frames flushed due to timeout",
386 		      stats_ptr->deliver_flush_timeout);
387 	qdf_nofl_info("  %u frames flushed due to moving out of window",
388 		      stats_ptr->deliver_flush_oow);
389 	qdf_nofl_info("  %u frames flushed due to receiving DELBA",
390 		      stats_ptr->deliver_flush_delba);
391 	qdf_nofl_info("  %u frames discarded due to FCS error",
392 		      stats_ptr->fcs_error);
393 	qdf_nofl_info("  %u frames discarded due to invalid peer",
394 		      stats_ptr->invalid_peer);
395 	qdf_nofl_info
396 		("  %u frames discarded due to duplication (non aggregation)",
397 		 stats_ptr->dup_non_aggr);
398 	qdf_nofl_info("  %u frames discarded due to duplication in reorder queue",
399 		      stats_ptr->dup_in_reorder);
400 	qdf_nofl_info("  %u frames discarded due to processed before",
401 		      stats_ptr->dup_past);
402 	qdf_nofl_info("  %u times reorder timeout happened",
403 		      stats_ptr->reorder_timeout);
404 	qdf_nofl_info("  %u times incorrect bar received",
405 		      stats_ptr->invalid_bar_ssn);
406 	qdf_nofl_info("  %u times bar ssn reset happened",
407 		      stats_ptr->ssn_reset);
408 	qdf_nofl_info("  %u times flushed due to peer delete",
409 		      stats_ptr->deliver_flush_delpeer);
410 	qdf_nofl_info("  %u times flushed due to offload",
411 		      stats_ptr->deliver_flush_offload);
412 	qdf_nofl_info("  %u times flushed due to ouf of buffer",
413 		      stats_ptr->deliver_flush_oob);
414 	qdf_nofl_info("  %u MPDU's dropped due to PN check fail",
415 		      stats_ptr->pn_fail);
416 	qdf_nofl_info("  %u MPDU's dropped due to lack of memory",
417 		      stats_ptr->store_fail);
418 	qdf_nofl_info("  %u times tid pool alloc succeeded",
419 		      stats_ptr->tid_pool_alloc_succ);
420 	qdf_nofl_info("  %u times MPDU pool alloc succeeded",
421 		      stats_ptr->mpdu_pool_alloc_succ);
422 	qdf_nofl_info("  %u times MSDU pool alloc succeeded",
423 		      stats_ptr->msdu_pool_alloc_succ);
424 	qdf_nofl_info("  %u times tid pool alloc failed",
425 		      stats_ptr->tid_pool_alloc_fail);
426 	qdf_nofl_info("  %u times MPDU pool alloc failed",
427 		      stats_ptr->mpdu_pool_alloc_fail);
428 	qdf_nofl_info("  %u times MSDU pool alloc failed",
429 		      stats_ptr->msdu_pool_alloc_fail);
430 	qdf_nofl_info("  %u times tid pool freed",
431 		      stats_ptr->tid_pool_free);
432 	qdf_nofl_info("  %u times MPDU pool freed",
433 		      stats_ptr->mpdu_pool_free);
434 	qdf_nofl_info("  %u times MSDU pool freed",
435 		      stats_ptr->msdu_pool_free);
436 	qdf_nofl_info("  %u MSDUs undelivered to HTT, queued to Rx MSDU free list",
437 		      stats_ptr->msdu_queued);
438 	qdf_nofl_info("  %u MSDUs released from Rx MSDU list to MAC ring",
439 		      stats_ptr->msdu_recycled);
440 	qdf_nofl_info("  %u MPDUs with invalid peer but A2 found in AST",
441 		      stats_ptr->invalid_peer_a2_in_ast);
442 	qdf_nofl_info("  %u MPDUs with invalid peer but A3 found in AST",
443 		      stats_ptr->invalid_peer_a3_in_ast);
444 	qdf_nofl_info("  %u MPDUs with invalid peer, Broadcast or Mulitcast frame",
445 		      stats_ptr->invalid_peer_bmc_mpdus);
446 	qdf_nofl_info("  %u MSDUs with err attention word",
447 		      stats_ptr->rxdesc_err_att);
448 	qdf_nofl_info("  %u MSDUs with flag of peer_idx_invalid",
449 		      stats_ptr->rxdesc_err_peer_idx_inv);
450 	qdf_nofl_info("  %u MSDUs with  flag of peer_idx_timeout",
451 		      stats_ptr->rxdesc_err_peer_idx_to);
452 	qdf_nofl_info("  %u MSDUs with  flag of overflow",
453 		      stats_ptr->rxdesc_err_ov);
454 	qdf_nofl_info("  %u MSDUs with  flag of msdu_length_err",
455 		      stats_ptr->rxdesc_err_msdu_len);
456 	qdf_nofl_info("  %u MSDUs with  flag of mpdu_length_err",
457 		      stats_ptr->rxdesc_err_mpdu_len);
458 	qdf_nofl_info("  %u MSDUs with  flag of tkip_mic_err",
459 		      stats_ptr->rxdesc_err_tkip_mic);
460 	qdf_nofl_info("  %u MSDUs with  flag of decrypt_err",
461 		      stats_ptr->rxdesc_err_decrypt);
462 	qdf_nofl_info("  %u MSDUs with  flag of fcs_err",
463 		      stats_ptr->rxdesc_err_fcs);
464 	qdf_nofl_info("  %u Unicast frames with invalid peer handler",
465 		      stats_ptr->rxdesc_uc_msdus_inv_peer);
466 	qdf_nofl_info("  %u unicast frame to DUT with invalid peer handler",
467 		      stats_ptr->rxdesc_direct_msdus_inv_peer);
468 	qdf_nofl_info("  %u Broadcast/Multicast frames with invalid peer handler",
469 		      stats_ptr->rxdesc_bmc_msdus_inv_peer);
470 	qdf_nofl_info("  %u MSDUs dropped due to no first MSDU flag",
471 		      stats_ptr->rxdesc_no_1st_msdu);
472 	qdf_nofl_info("  %u MSDUs dropped due to ring overflow",
473 		      stats_ptr->msdu_drop_ring_ov);
474 	qdf_nofl_info("  %u MSDUs dropped due to FC mismatch",
475 		      stats_ptr->msdu_drop_fc_mismatch);
476 	qdf_nofl_info("  %u MSDUs dropped due to mgt frame in Remote ring",
477 		      stats_ptr->msdu_drop_mgmt_remote_ring);
478 	qdf_nofl_info("  %u MSDUs dropped due to misc non error",
479 		      stats_ptr->msdu_drop_misc);
480 	qdf_nofl_info("  %u MSDUs go to offload before reorder",
481 		      stats_ptr->offload_msdu_wal);
482 	qdf_nofl_info("  %u data frame dropped by offload after reorder",
483 		      stats_ptr->offload_msdu_reorder);
484 	qdf_nofl_info("  %u  MPDUs with SN in the past & within BA window",
485 		      stats_ptr->dup_past_within_window);
486 	qdf_nofl_info("  %u  MPDUs with SN in the past & outside BA window",
487 		      stats_ptr->dup_past_outside_window);
488 }
489 
490 static void
htt_t2h_stats_rx_rem_buf_stats_print(struct rx_remote_buffer_mgmt_stats * stats_ptr,int concise)491 htt_t2h_stats_rx_rem_buf_stats_print(
492 	struct rx_remote_buffer_mgmt_stats *stats_ptr, int concise)
493 {
494 	qdf_nofl_info("Rx Remote Buffer Statistics:");
495 	qdf_nofl_info("  %u MSDU's reaped for Rx processing",
496 		      stats_ptr->remote_reaped);
497 	qdf_nofl_info("  %u MSDU's recycled within firmware",
498 		      stats_ptr->remote_recycled);
499 	qdf_nofl_info("  %u MSDU's stored by Data Rx",
500 		      stats_ptr->data_rx_msdus_stored);
501 	qdf_nofl_info("  %u HTT indications from WAL Rx MSDU",
502 		      stats_ptr->wal_rx_ind);
503 	qdf_nofl_info("  %u HTT indications unconsumed from WAL Rx MSDU",
504 		      stats_ptr->wal_rx_ind_unconsumed);
505 	qdf_nofl_info("  %u HTT indications from Data Rx MSDU",
506 		      stats_ptr->data_rx_ind);
507 	qdf_nofl_info("  %u HTT indications unconsumed from Data Rx MSDU",
508 		      stats_ptr->data_rx_ind_unconsumed);
509 	qdf_nofl_info("  %u HTT indications from ATHBUF",
510 		      stats_ptr->athbuf_rx_ind);
511 	qdf_nofl_info("  %u Remote buffers requested for refill",
512 		      stats_ptr->refill_buf_req);
513 	qdf_nofl_info("  %u Remote buffers filled by host",
514 		      stats_ptr->refill_buf_rsp);
515 	qdf_nofl_info("  %u times MAC has no buffers",
516 		      stats_ptr->mac_no_bufs);
517 	qdf_nofl_info("  %u times f/w write & read indices on MAC ring are equal",
518 		      stats_ptr->fw_indices_equal);
519 	qdf_nofl_info("  %u times f/w has no remote buffers to post to MAC",
520 		      stats_ptr->host_no_bufs);
521 }
522 
523 static void
htt_t2h_stats_txbf_info_buf_stats_print(struct wlan_dbg_txbf_data_stats * stats_ptr)524 htt_t2h_stats_txbf_info_buf_stats_print(
525 	struct wlan_dbg_txbf_data_stats *stats_ptr)
526 {
527 	qdf_nofl_info("TXBF data Statistics:");
528 	qdf_nofl_info("tx_txbf_vht (0..9): %u, %u, %u, %u, %u, %u, %u, %u, %u, %d",
529 		      stats_ptr->tx_txbf_vht[0],
530 		      stats_ptr->tx_txbf_vht[1],
531 		      stats_ptr->tx_txbf_vht[2],
532 		      stats_ptr->tx_txbf_vht[3],
533 		      stats_ptr->tx_txbf_vht[4],
534 		      stats_ptr->tx_txbf_vht[5],
535 		      stats_ptr->tx_txbf_vht[6],
536 		      stats_ptr->tx_txbf_vht[7],
537 		      stats_ptr->tx_txbf_vht[8],
538 		      stats_ptr->tx_txbf_vht[9]);
539 	qdf_nofl_info("rx_txbf_vht (0..9): %u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
540 		      stats_ptr->rx_txbf_vht[0],
541 		      stats_ptr->rx_txbf_vht[1],
542 		      stats_ptr->rx_txbf_vht[2],
543 		      stats_ptr->rx_txbf_vht[3],
544 		      stats_ptr->rx_txbf_vht[4],
545 		      stats_ptr->rx_txbf_vht[5],
546 		      stats_ptr->rx_txbf_vht[6],
547 		      stats_ptr->rx_txbf_vht[7],
548 		      stats_ptr->rx_txbf_vht[8],
549 		      stats_ptr->rx_txbf_vht[9]);
550 	qdf_nofl_info("tx_txbf_ht (0..7): %u, %u, %u, %u, %u, %u, %u, %u",
551 		      stats_ptr->tx_txbf_ht[0],
552 		      stats_ptr->tx_txbf_ht[1],
553 		      stats_ptr->tx_txbf_ht[2],
554 		      stats_ptr->tx_txbf_ht[3],
555 		      stats_ptr->tx_txbf_ht[4],
556 		      stats_ptr->tx_txbf_ht[5],
557 		      stats_ptr->tx_txbf_ht[6],
558 		      stats_ptr->tx_txbf_ht[7]);
559 	qdf_nofl_info("tx_txbf_ofdm (0..7): %u, %u, %u, %u, %u, %u, %u, %u",
560 		      stats_ptr->tx_txbf_ofdm[0],
561 		      stats_ptr->tx_txbf_ofdm[1],
562 		      stats_ptr->tx_txbf_ofdm[2],
563 		      stats_ptr->tx_txbf_ofdm[3],
564 		      stats_ptr->tx_txbf_ofdm[4],
565 		      stats_ptr->tx_txbf_ofdm[5],
566 		      stats_ptr->tx_txbf_ofdm[6],
567 		      stats_ptr->tx_txbf_ofdm[7]);
568 	qdf_nofl_info("tx_txbf_cck (0..6): %u, %u, %u, %u, %u, %u, %u",
569 		      stats_ptr->tx_txbf_cck[0],
570 		      stats_ptr->tx_txbf_cck[1],
571 		      stats_ptr->tx_txbf_cck[2],
572 		      stats_ptr->tx_txbf_cck[3],
573 		      stats_ptr->tx_txbf_cck[4],
574 		      stats_ptr->tx_txbf_cck[5],
575 		      stats_ptr->tx_txbf_cck[6]);
576 }
577 
578 static void
htt_t2h_stats_txbf_snd_buf_stats_print(struct wlan_dbg_txbf_snd_stats * stats_ptr)579 htt_t2h_stats_txbf_snd_buf_stats_print(
580 	struct wlan_dbg_txbf_snd_stats *stats_ptr)
581 {
582 	qdf_nofl_info("TXBF snd Buffer Statistics:");
583 	qdf_nofl_info("cbf_20: %u, %u, %u, %u",
584 		      stats_ptr->cbf_20[0],
585 		      stats_ptr->cbf_20[1],
586 		      stats_ptr->cbf_20[2],
587 		      stats_ptr->cbf_20[3]);
588 	qdf_nofl_info("cbf_40: %u, %u, %u, %u",
589 		      stats_ptr->cbf_40[0],
590 		      stats_ptr->cbf_40[1],
591 		      stats_ptr->cbf_40[2],
592 		      stats_ptr->cbf_40[3]);
593 	qdf_nofl_info("cbf_80: %u, %u, %u, %u",
594 		      stats_ptr->cbf_80[0],
595 		      stats_ptr->cbf_80[1],
596 		      stats_ptr->cbf_80[2],
597 		      stats_ptr->cbf_80[3]);
598 	qdf_nofl_info("sounding: %u, %u, %u, %u, %u, %u, %u, %u, %u",
599 		      stats_ptr->sounding[0],
600 		      stats_ptr->sounding[1],
601 		      stats_ptr->sounding[2],
602 		      stats_ptr->sounding[3],
603 		      stats_ptr->sounding[4],
604 		      stats_ptr->sounding[5],
605 		      stats_ptr->sounding[6],
606 		      stats_ptr->sounding[7],
607 		      stats_ptr->sounding[8]);
608 }
609 
610 static void
htt_t2h_stats_tx_selfgen_buf_stats_print(struct wlan_dbg_tx_selfgen_stats * stats_ptr)611 htt_t2h_stats_tx_selfgen_buf_stats_print(
612 	struct wlan_dbg_tx_selfgen_stats *stats_ptr)
613 {
614 	qdf_nofl_info("Tx selfgen Buffer Statistics:");
615 	qdf_nofl_info("  %u su_ndpa",
616 		      stats_ptr->su_ndpa);
617 	qdf_nofl_info("  %u mu_ndp",
618 		      stats_ptr->mu_ndp);
619 	qdf_nofl_info("  %u mu_ndpa",
620 		      stats_ptr->mu_ndpa);
621 	qdf_nofl_info("  %u mu_ndp",
622 		      stats_ptr->mu_ndp);
623 	qdf_nofl_info("  %u mu_brpoll_1",
624 		      stats_ptr->mu_brpoll_1);
625 	qdf_nofl_info("  %u mu_brpoll_2",
626 		      stats_ptr->mu_brpoll_2);
627 	qdf_nofl_info("  %u mu_bar_1",
628 		      stats_ptr->mu_bar_1);
629 	qdf_nofl_info("  %u mu_bar_2",
630 		      stats_ptr->mu_bar_2);
631 	qdf_nofl_info("  %u cts_burst",
632 		      stats_ptr->cts_burst);
633 	qdf_nofl_info("  %u su_ndp_err",
634 		      stats_ptr->su_ndp_err);
635 	qdf_nofl_info("  %u su_ndpa_err",
636 		      stats_ptr->su_ndpa_err);
637 	qdf_nofl_info("  %u mu_ndp_err",
638 		      stats_ptr->mu_ndp_err);
639 	qdf_nofl_info("  %u mu_brp1_err",
640 		      stats_ptr->mu_brp1_err);
641 	qdf_nofl_info("  %u mu_brp2_err",
642 		      stats_ptr->mu_brp2_err);
643 }
644 
645 static void
htt_t2h_stats_wifi2_error_stats_print(struct wlan_dbg_wifi2_error_stats * stats_ptr)646 htt_t2h_stats_wifi2_error_stats_print(
647 	struct wlan_dbg_wifi2_error_stats *stats_ptr)
648 {
649 	int i;
650 
651 	qdf_nofl_info("Scheduler error Statistics:");
652 	qdf_nofl_info("urrn_stats: ");
653 	qdf_nofl_info("urrn_stats: %d, %d, %d",
654 		      stats_ptr->urrn_stats[0],
655 		      stats_ptr->urrn_stats[1],
656 		      stats_ptr->urrn_stats[2]);
657 	qdf_nofl_info("flush_errs (0..%d): ",
658 		      WHAL_DBG_FLUSH_REASON_MAXCNT);
659 	for (i = 0; i < WHAL_DBG_FLUSH_REASON_MAXCNT; i++)
660 		qdf_nofl_info("  %u", stats_ptr->flush_errs[i]);
661 	qdf_nofl_info("\n");
662 	qdf_nofl_info("schd_stall_errs (0..3): ");
663 	qdf_nofl_info("%d, %d, %d, %d",
664 		      stats_ptr->schd_stall_errs[0],
665 		      stats_ptr->schd_stall_errs[1],
666 		      stats_ptr->schd_stall_errs[2],
667 		      stats_ptr->schd_stall_errs[3]);
668 	qdf_nofl_info("schd_cmd_result (0..%d): ",
669 		      WHAL_DBG_CMD_RESULT_MAXCNT);
670 	for (i = 0; i < WHAL_DBG_CMD_RESULT_MAXCNT; i++)
671 		qdf_nofl_info("  %u", stats_ptr->schd_cmd_result[i]);
672 	qdf_nofl_info("\n");
673 	qdf_nofl_info("sifs_status (0..%d): ",
674 		      WHAL_DBG_SIFS_STATUS_MAXCNT);
675 	for (i = 0; i < WHAL_DBG_SIFS_STATUS_MAXCNT; i++)
676 		qdf_nofl_info("  %u", stats_ptr->sifs_status[i]);
677 	qdf_nofl_info("\n");
678 	qdf_nofl_info("phy_errs (0..%d): ",
679 		      WHAL_DBG_PHY_ERR_MAXCNT);
680 	for (i = 0; i < WHAL_DBG_PHY_ERR_MAXCNT; i++)
681 		qdf_nofl_info("  %u", stats_ptr->phy_errs[i]);
682 	qdf_nofl_info("\n");
683 	qdf_nofl_info("  %u rx_rate_inval",
684 		      stats_ptr->rx_rate_inval);
685 }
686 
687 static void
htt_t2h_rx_musu_ndpa_pkts_stats_print(struct rx_txbf_musu_ndpa_pkts_stats * stats_ptr)688 htt_t2h_rx_musu_ndpa_pkts_stats_print(
689 	struct rx_txbf_musu_ndpa_pkts_stats *stats_ptr)
690 {
691 	qdf_nofl_info("Rx TXBF MU/SU Packets and NDPA Statistics:");
692 	qdf_nofl_info("  %u Number of TXBF MU packets received",
693 		      stats_ptr->number_mu_pkts);
694 	qdf_nofl_info("  %u Number of TXBF SU packets received",
695 		      stats_ptr->number_su_pkts);
696 	qdf_nofl_info("  %u Number of TXBF directed NDPA",
697 		      stats_ptr->txbf_directed_ndpa_count);
698 	qdf_nofl_info("  %u Number of TXBF retried NDPA",
699 		      stats_ptr->txbf_ndpa_retry_count);
700 	qdf_nofl_info("  %u Total number of TXBF NDPA",
701 		      stats_ptr->txbf_total_ndpa_count);
702 }
703 
704 #define HTT_TICK_TO_USEC(ticks, microsec_per_tick) (ticks * microsec_per_tick)
htt_rate_flags_to_mhz(uint8_t rate_flags)705 static inline int htt_rate_flags_to_mhz(uint8_t rate_flags)
706 {
707 	if (rate_flags & 0x20)
708 		return 40;      /* WHAL_RC_FLAG_40MHZ */
709 	if (rate_flags & 0x40)
710 		return 80;      /* WHAL_RC_FLAG_80MHZ */
711 	if (rate_flags & 0x80)
712 		return 160;     /* WHAL_RC_FLAG_160MHZ */
713 	return 20;
714 }
715 
716 #define HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW 64
717 
718 static void
htt_t2h_tx_ppdu_bitmaps_pr(uint32_t * queued_ptr,uint32_t * acked_ptr)719 htt_t2h_tx_ppdu_bitmaps_pr(uint32_t *queued_ptr, uint32_t *acked_ptr)
720 {
721 	char queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW + 1];
722 	char acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW + 1];
723 	int i, j, word;
724 
725 	qdf_mem_set(queued_str, HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW, '0');
726 	qdf_mem_set(acked_str, HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW, '-');
727 	i = 0;
728 	for (word = 0; word < 2; word++) {
729 		uint32_t queued = *(queued_ptr + word);
730 		uint32_t acked = *(acked_ptr + word);
731 
732 		for (j = 0; j < 32; j++, i++) {
733 			if (queued & (1 << j)) {
734 				queued_str[i] = '1';
735 				acked_str[i] = (acked & (1 << j)) ? 'y' : 'N';
736 			}
737 		}
738 	}
739 	queued_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0';
740 	acked_str[HTT_FW_STATS_MAX_BLOCK_ACK_WINDOW] = '\0';
741 	qdf_nofl_info("%s\n", queued_str);
742 	qdf_nofl_info("%s\n", acked_str);
743 }
744 
htt_msg_read16(uint16_t * p16)745 static inline uint16_t htt_msg_read16(uint16_t *p16)
746 {
747 #ifdef BIG_ENDIAN_HOST
748 	/*
749 	 * During upload, the bytes within each uint32_t word were
750 	 * swapped by the HIF HW.  This results in the lower and upper bytes
751 	 * of each uint16_t to be in the correct big-endian order with
752 	 * respect to each other, but for each even-index uint16_t to
753 	 * have its position switched with its successor neighbor uint16_t.
754 	 * Undo this uint16_t position swapping.
755 	 */
756 	return (((size_t) p16) & 0x2) ? *(p16 - 1) : *(p16 + 1);
757 #else
758 	return *p16;
759 #endif
760 }
761 
htt_msg_read8(uint8_t * p8)762 static inline uint8_t htt_msg_read8(uint8_t *p8)
763 {
764 #ifdef BIG_ENDIAN_HOST
765 	/*
766 	 * During upload, the bytes within each uint32_t word were
767 	 * swapped by the HIF HW.
768 	 * Undo this byte swapping.
769 	 */
770 	switch (((size_t) p8) & 0x3) {
771 	case 0:
772 		return *(p8 + 3);
773 	case 1:
774 		return *(p8 + 1);
775 	case 2:
776 		return *(p8 - 1);
777 	default /* 3 */:
778 		return *(p8 - 3);
779 	}
780 #else
781 	return *p8;
782 #endif
783 }
784 
htt_make_u8_list_str(uint32_t * aligned_data,char * buffer,int space,int max_elems)785 static void htt_make_u8_list_str(uint32_t *aligned_data,
786 				 char *buffer, int space, int max_elems)
787 {
788 	uint8_t *p8 = (uint8_t *) aligned_data;
789 	char *buf_p = buffer;
790 
791 	while (max_elems-- > 0) {
792 		int bytes;
793 		uint8_t val;
794 
795 		val = htt_msg_read8(p8);
796 		if (val == 0)
797 			/* not enough data to fill the reserved msg buffer*/
798 			break;
799 
800 		bytes = qdf_snprint(buf_p, space, "%d,", val);
801 		space -= bytes;
802 		if (space > 0)
803 			buf_p += bytes;
804 		else /* not enough print buffer space for all the data */
805 			break;
806 		p8++;
807 	}
808 	if (buf_p == buffer)
809 		*buf_p = '\0';        /* nothing was written */
810 	else
811 		*(buf_p - 1) = '\0';  /* erase the final comma */
812 
813 }
814 
htt_make_u16_list_str(uint32_t * aligned_data,char * buffer,int space,int max_elems)815 static void htt_make_u16_list_str(uint32_t *aligned_data,
816 				  char *buffer, int space, int max_elems)
817 {
818 	uint16_t *p16 = (uint16_t *) aligned_data;
819 	char *buf_p = buffer;
820 
821 	while (max_elems-- > 0) {
822 		int bytes;
823 		uint16_t val;
824 
825 		val = htt_msg_read16(p16);
826 		if (val == 0)
827 			/* not enough data to fill the reserved msg buffer */
828 			break;
829 		bytes = qdf_snprint(buf_p, space, "%d,", val);
830 		space -= bytes;
831 		if (space > 0)
832 			buf_p += bytes;
833 		else /* not enough print buffer space for all the data */
834 			break;
835 
836 		p16++;
837 	}
838 	if (buf_p == buffer)
839 		*buf_p = '\0';  /* nothing was written */
840 	else
841 		*(buf_p - 1) = '\0';    /* erase the final comma */
842 }
843 
844 static void
htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr * hdr,struct ol_fw_tx_dbg_ppdu_base * record,int length,int concise)845 htt_t2h_tx_ppdu_log_print(struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr,
846 			  struct ol_fw_tx_dbg_ppdu_base *record,
847 			  int length, int concise)
848 {
849 	int i;
850 	int record_size;
851 	int calculated_record_size;
852 	int num_records;
853 
854 	record_size = sizeof(*record);
855 	calculated_record_size = record_size +
856 				hdr->mpdu_bytes_array_len * sizeof(uint16_t);
857 	if (calculated_record_size < record_size) {
858 		qdf_err("Overflow due to record and hdr->mpdu_bytes_array_len %u",
859 			hdr->mpdu_bytes_array_len);
860 		return;
861 	}
862 	record_size = calculated_record_size;
863 	calculated_record_size += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
864 	if (calculated_record_size < record_size) {
865 		qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
866 			hdr->mpdu_msdus_array_len);
867 		return;
868 	}
869 	record_size = calculated_record_size;
870 	calculated_record_size += hdr->msdu_bytes_array_len * sizeof(uint16_t);
871 	if (calculated_record_size < record_size) {
872 		qdf_err("Overflow due to hdr->msdu_bytes_array_len %u",
873 			hdr->msdu_bytes_array_len);
874 		return;
875 	}
876 	record_size = calculated_record_size;
877 	num_records = (length - sizeof(*hdr)) / record_size;
878 	if (num_records < 0) {
879 		qdf_err("Underflow due to length %d", length);
880 		return;
881 	}
882 	qdf_nofl_info("Tx PPDU log elements: num_records %d", num_records);
883 
884 	for (i = 0; i < num_records; i++) {
885 		uint16_t start_seq_num;
886 		uint16_t start_pn_lsbs;
887 		uint8_t num_mpdus;
888 		uint16_t peer_id;
889 		uint8_t ext_tid;
890 		uint8_t rate_code;
891 		uint8_t rate_flags;
892 		uint8_t tries;
893 		uint8_t complete;
894 		uint32_t time_enqueue_us;
895 		uint32_t time_completion_us;
896 		uint32_t *msg_word = (uint32_t *) record;
897 
898 		/* fields used for both concise and complete printouts */
899 		start_seq_num =
900 			((*(msg_word + OL_FW_TX_DBG_PPDU_START_SEQ_NUM_WORD)) &
901 			 OL_FW_TX_DBG_PPDU_START_SEQ_NUM_M) >>
902 			OL_FW_TX_DBG_PPDU_START_SEQ_NUM_S;
903 		complete =
904 			((*(msg_word + OL_FW_TX_DBG_PPDU_COMPLETE_WORD)) &
905 			 OL_FW_TX_DBG_PPDU_COMPLETE_M) >>
906 			OL_FW_TX_DBG_PPDU_COMPLETE_S;
907 
908 		/* fields used only for complete printouts */
909 		if (!concise) {
910 #define BUF_SIZE 80
911 			char buf[BUF_SIZE];
912 			uint8_t *p8;
913 			uint8_t *calculated_p8;
914 
915 			time_enqueue_us =
916 				HTT_TICK_TO_USEC(record->timestamp_enqueue,
917 						 hdr->microsec_per_tick);
918 			time_completion_us =
919 				HTT_TICK_TO_USEC(record->timestamp_completion,
920 						 hdr->microsec_per_tick);
921 
922 			start_pn_lsbs =
923 				((*(msg_word +
924 				OL_FW_TX_DBG_PPDU_START_PN_LSBS_WORD)) &
925 				OL_FW_TX_DBG_PPDU_START_PN_LSBS_M) >>
926 				OL_FW_TX_DBG_PPDU_START_PN_LSBS_S;
927 			num_mpdus =
928 				((*(msg_word +
929 				OL_FW_TX_DBG_PPDU_NUM_MPDUS_WORD))&
930 				OL_FW_TX_DBG_PPDU_NUM_MPDUS_M) >>
931 				OL_FW_TX_DBG_PPDU_NUM_MPDUS_S;
932 			peer_id =
933 				((*(msg_word +
934 				OL_FW_TX_DBG_PPDU_PEER_ID_WORD)) &
935 				OL_FW_TX_DBG_PPDU_PEER_ID_M) >>
936 				OL_FW_TX_DBG_PPDU_PEER_ID_S;
937 			ext_tid =
938 				((*(msg_word +
939 				OL_FW_TX_DBG_PPDU_EXT_TID_WORD)) &
940 				OL_FW_TX_DBG_PPDU_EXT_TID_M) >>
941 				OL_FW_TX_DBG_PPDU_EXT_TID_S;
942 			rate_code =
943 				((*(msg_word +
944 				OL_FW_TX_DBG_PPDU_RATE_CODE_WORD))&
945 				OL_FW_TX_DBG_PPDU_RATE_CODE_M) >>
946 				OL_FW_TX_DBG_PPDU_RATE_CODE_S;
947 			rate_flags =
948 				((*(msg_word +
949 				OL_FW_TX_DBG_PPDU_RATE_FLAGS_WORD))&
950 				OL_FW_TX_DBG_PPDU_RATE_FLAGS_M) >>
951 				OL_FW_TX_DBG_PPDU_RATE_FLAGS_S;
952 			tries =
953 				((*(msg_word +
954 				OL_FW_TX_DBG_PPDU_TRIES_WORD)) &
955 				OL_FW_TX_DBG_PPDU_TRIES_M) >>
956 				OL_FW_TX_DBG_PPDU_TRIES_S;
957 
958 			qdf_nofl_info(" - PPDU tx to peer %d, TID %d", peer_id,
959 				      ext_tid);
960 			qdf_nofl_info("   start seq num= %u, start PN LSBs= %#04x",
961 				      start_seq_num, start_pn_lsbs);
962 			qdf_nofl_info("   PPDU: %d MPDUs, (?) MSDUs, %d bytes",
963 				      num_mpdus,
964 				      /* num_msdus-not yet computed in target */
965 				      record->num_bytes);
966 			if (complete) {
967 				qdf_nofl_info("   enqueued: %u, completed: %u usec)",
968 					      time_enqueue_us,
969 					      time_completion_us);
970 				qdf_nofl_info("   %d tries, last tx used rate %d ",
971 					      tries, rate_code);
972 				qdf_nofl_info("on %d MHz chan (flags = %#x)",
973 					      htt_rate_flags_to_mhz
974 					      (rate_flags), rate_flags);
975 				qdf_nofl_info("  enqueued and acked MPDU bitmaps:");
976 				htt_t2h_tx_ppdu_bitmaps_pr(msg_word +
977 					OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD,
978 					msg_word +
979 					OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD);
980 			} else {
981 				qdf_nofl_info("  enqueued: %d us, not yet completed",
982 					      time_enqueue_us);
983 			}
984 			/* skip the regular msg fields to reach the tail area */
985 			p8 = (uint8_t *) record;
986 			calculated_p8 = p8 + sizeof(struct ol_fw_tx_dbg_ppdu_base);
987 			if (calculated_p8 < p8) {
988 				qdf_err("Overflow due to record %pK", p8);
989 				continue;
990 			}
991 			p8 = calculated_p8;
992 			if (hdr->mpdu_bytes_array_len) {
993 				htt_make_u16_list_str((uint32_t *) p8, buf,
994 						      BUF_SIZE,
995 						      hdr->
996 						      mpdu_bytes_array_len);
997 				qdf_nofl_info("   MPDU bytes: %s", buf);
998 			}
999 			calculated_p8 += hdr->mpdu_bytes_array_len * sizeof(uint16_t);
1000 			if (calculated_p8 < p8) {
1001 				qdf_err("Overflow due to hdr->mpdu_bytes_array_len %u",
1002 					hdr->mpdu_bytes_array_len);
1003 				continue;
1004 			}
1005 			p8 = calculated_p8;
1006 			if (hdr->mpdu_msdus_array_len) {
1007 				htt_make_u8_list_str((uint32_t *) p8, buf,
1008 						     BUF_SIZE,
1009 						     hdr->mpdu_msdus_array_len);
1010 				qdf_nofl_info("   MPDU MSDUs: %s", buf);
1011 			}
1012 			calculated_p8 += hdr->mpdu_msdus_array_len * sizeof(uint8_t);
1013 			if (calculated_p8 < p8) {
1014 				qdf_err("Overflow due to hdr->mpdu_msdus_array_len %u",
1015 					hdr->mpdu_msdus_array_len);
1016 				continue;
1017 			}
1018 			p8 = calculated_p8;
1019 			if (hdr->msdu_bytes_array_len) {
1020 				htt_make_u16_list_str((uint32_t *) p8, buf,
1021 						      BUF_SIZE,
1022 						      hdr->
1023 						      msdu_bytes_array_len);
1024 				qdf_nofl_info("   MSDU bytes: %s", buf);
1025 			}
1026 		} else {
1027 			/* concise */
1028 			qdf_nofl_info("start seq num = %u ", start_seq_num);
1029 			qdf_nofl_info("enqueued and acked MPDU bitmaps:");
1030 			if (complete) {
1031 				htt_t2h_tx_ppdu_bitmaps_pr(msg_word +
1032 					OL_FW_TX_DBG_PPDU_ENQUEUED_LSBS_WORD,
1033 							   msg_word +
1034 					OL_FW_TX_DBG_PPDU_BLOCK_ACK_LSBS_WORD);
1035 			} else {
1036 				qdf_nofl_info("(not completed)");
1037 			}
1038 		}
1039 		record = (struct ol_fw_tx_dbg_ppdu_base *)
1040 			 (((uint8_t *) record) + record_size);
1041 	}
1042 }
1043 
htt_t2h_stats_tidq_stats_print(struct wlan_dbg_tidq_stats * tidq_stats,int concise)1044 static void htt_t2h_stats_tidq_stats_print(
1045 	struct wlan_dbg_tidq_stats *tidq_stats, int concise)
1046 {
1047 	qdf_nofl_info("TID QUEUE STATS:");
1048 	qdf_nofl_info("tid_txq_stats: %u", tidq_stats->wlan_dbg_tid_txq_status);
1049 	qdf_nofl_info("num_pkts_queued(0..9):");
1050 	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
1051 		      tidq_stats->txq_st.num_pkts_queued[0],
1052 		      tidq_stats->txq_st.num_pkts_queued[1],
1053 		      tidq_stats->txq_st.num_pkts_queued[2],
1054 		      tidq_stats->txq_st.num_pkts_queued[3],
1055 		      tidq_stats->txq_st.num_pkts_queued[4],
1056 		      tidq_stats->txq_st.num_pkts_queued[5],
1057 		      tidq_stats->txq_st.num_pkts_queued[6],
1058 		      tidq_stats->txq_st.num_pkts_queued[7],
1059 		      tidq_stats->txq_st.num_pkts_queued[8],
1060 		      tidq_stats->txq_st.num_pkts_queued[9]);
1061 	qdf_nofl_info("tid_hw_qdepth(0..19):");
1062 	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
1063 		      tidq_stats->txq_st.tid_hw_qdepth[0],
1064 		      tidq_stats->txq_st.tid_hw_qdepth[1],
1065 		      tidq_stats->txq_st.tid_hw_qdepth[2],
1066 		      tidq_stats->txq_st.tid_hw_qdepth[3],
1067 		      tidq_stats->txq_st.tid_hw_qdepth[4],
1068 		      tidq_stats->txq_st.tid_hw_qdepth[5],
1069 		      tidq_stats->txq_st.tid_hw_qdepth[6],
1070 		      tidq_stats->txq_st.tid_hw_qdepth[7],
1071 		      tidq_stats->txq_st.tid_hw_qdepth[8],
1072 		      tidq_stats->txq_st.tid_hw_qdepth[9]);
1073 	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
1074 		      tidq_stats->txq_st.tid_hw_qdepth[10],
1075 		      tidq_stats->txq_st.tid_hw_qdepth[11],
1076 		      tidq_stats->txq_st.tid_hw_qdepth[12],
1077 		      tidq_stats->txq_st.tid_hw_qdepth[13],
1078 		      tidq_stats->txq_st.tid_hw_qdepth[14],
1079 		      tidq_stats->txq_st.tid_hw_qdepth[15],
1080 		      tidq_stats->txq_st.tid_hw_qdepth[16],
1081 		      tidq_stats->txq_st.tid_hw_qdepth[17],
1082 		      tidq_stats->txq_st.tid_hw_qdepth[18],
1083 		      tidq_stats->txq_st.tid_hw_qdepth[19]);
1084 	qdf_nofl_info("tid_sw_qdepth(0..19):");
1085 	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
1086 		      tidq_stats->txq_st.tid_sw_qdepth[0],
1087 		      tidq_stats->txq_st.tid_sw_qdepth[1],
1088 		      tidq_stats->txq_st.tid_sw_qdepth[2],
1089 		      tidq_stats->txq_st.tid_sw_qdepth[3],
1090 		      tidq_stats->txq_st.tid_sw_qdepth[4],
1091 		      tidq_stats->txq_st.tid_sw_qdepth[5],
1092 		      tidq_stats->txq_st.tid_sw_qdepth[6],
1093 		      tidq_stats->txq_st.tid_sw_qdepth[7],
1094 		      tidq_stats->txq_st.tid_sw_qdepth[8],
1095 		      tidq_stats->txq_st.tid_sw_qdepth[9]);
1096 	qdf_nofl_info("%u, %u, %u, %u, %u, %u, %u, %u, %u, %u",
1097 		      tidq_stats->txq_st.tid_sw_qdepth[10],
1098 		      tidq_stats->txq_st.tid_sw_qdepth[11],
1099 		      tidq_stats->txq_st.tid_sw_qdepth[12],
1100 		      tidq_stats->txq_st.tid_sw_qdepth[13],
1101 		      tidq_stats->txq_st.tid_sw_qdepth[14],
1102 		      tidq_stats->txq_st.tid_sw_qdepth[15],
1103 		      tidq_stats->txq_st.tid_sw_qdepth[16],
1104 		      tidq_stats->txq_st.tid_sw_qdepth[17],
1105 		      tidq_stats->txq_st.tid_sw_qdepth[18],
1106 		      tidq_stats->txq_st.tid_sw_qdepth[19]);
1107 }
1108 
htt_t2h_stats_tx_mu_stats_print(struct wlan_dbg_tx_mu_stats * tx_mu_stats,int concise)1109 static void htt_t2h_stats_tx_mu_stats_print(
1110 	struct wlan_dbg_tx_mu_stats *tx_mu_stats, int concise)
1111 {
1112 	qdf_nofl_info("TX MU STATS:");
1113 	qdf_nofl_info("mu_sch_nusers_2: %u", tx_mu_stats->mu_sch_nusers_2);
1114 	qdf_nofl_info("mu_sch_nusers_3: %u", tx_mu_stats->mu_sch_nusers_3);
1115 	qdf_nofl_info("mu_mpdus_queued_usr: %u, %u, %u, %u",
1116 		      tx_mu_stats->mu_mpdus_queued_usr[0],
1117 		      tx_mu_stats->mu_mpdus_queued_usr[1],
1118 		      tx_mu_stats->mu_mpdus_queued_usr[2],
1119 		      tx_mu_stats->mu_mpdus_queued_usr[3]);
1120 	qdf_nofl_info("mu_mpdus_tried_usr: %u, %u, %u, %u",
1121 		      tx_mu_stats->mu_mpdus_tried_usr[0],
1122 		      tx_mu_stats->mu_mpdus_tried_usr[1],
1123 		      tx_mu_stats->mu_mpdus_tried_usr[2],
1124 		      tx_mu_stats->mu_mpdus_tried_usr[3]);
1125 	qdf_nofl_info("mu_mpdus_failed_usr: %u, %u, %u, %u",
1126 		      tx_mu_stats->mu_mpdus_failed_usr[0],
1127 		      tx_mu_stats->mu_mpdus_failed_usr[1],
1128 		      tx_mu_stats->mu_mpdus_failed_usr[2],
1129 		      tx_mu_stats->mu_mpdus_failed_usr[3]);
1130 	qdf_nofl_info("mu_mpdus_requeued_usr: %u, %u, %u, %u",
1131 		      tx_mu_stats->mu_mpdus_requeued_usr[0],
1132 		      tx_mu_stats->mu_mpdus_requeued_usr[1],
1133 		      tx_mu_stats->mu_mpdus_requeued_usr[2],
1134 		      tx_mu_stats->mu_mpdus_requeued_usr[3]);
1135 	qdf_nofl_info("mu_err_no_ba_usr: %u, %u, %u, %u",
1136 		      tx_mu_stats->mu_err_no_ba_usr[0],
1137 		      tx_mu_stats->mu_err_no_ba_usr[1],
1138 		      tx_mu_stats->mu_err_no_ba_usr[2],
1139 		      tx_mu_stats->mu_err_no_ba_usr[3]);
1140 	qdf_nofl_info("mu_mpdu_underrun_usr: %u, %u, %u, %u",
1141 		      tx_mu_stats->mu_mpdu_underrun_usr[0],
1142 		      tx_mu_stats->mu_mpdu_underrun_usr[1],
1143 		      tx_mu_stats->mu_mpdu_underrun_usr[2],
1144 		      tx_mu_stats->mu_mpdu_underrun_usr[3]);
1145 	qdf_nofl_info("mu_ampdu_underrun_usr: %u, %u, %u, %u",
1146 		      tx_mu_stats->mu_ampdu_underrun_usr[0],
1147 		      tx_mu_stats->mu_ampdu_underrun_usr[1],
1148 		      tx_mu_stats->mu_ampdu_underrun_usr[2],
1149 		      tx_mu_stats->mu_ampdu_underrun_usr[3]);
1150 
1151 }
1152 
htt_t2h_stats_sifs_resp_stats_print(struct wlan_dbg_sifs_resp_stats * sifs_stats,int concise)1153 static void htt_t2h_stats_sifs_resp_stats_print(
1154 	struct wlan_dbg_sifs_resp_stats *sifs_stats, int concise)
1155 {
1156 	qdf_nofl_info("SIFS RESP STATS:");
1157 	qdf_nofl_info("num of ps-poll trigger frames: %u",
1158 		      sifs_stats->ps_poll_trigger);
1159 	qdf_nofl_info("num of uapsd trigger frames: %u",
1160 		      sifs_stats->uapsd_trigger);
1161 	qdf_nofl_info("num of data trigger frames: %u, %u",
1162 		      sifs_stats->qb_data_trigger[0],
1163 		      sifs_stats->qb_data_trigger[1]);
1164 	qdf_nofl_info("num of bar trigger frames: %u, %u",
1165 		      sifs_stats->qb_bar_trigger[0],
1166 		      sifs_stats->qb_bar_trigger[1]);
1167 	qdf_nofl_info("num of ppdu transmitted at SIFS interval: %u",
1168 		      sifs_stats->sifs_resp_data);
1169 	qdf_nofl_info("num of ppdu failed to meet SIFS resp timing: %u",
1170 		      sifs_stats->sifs_resp_err);
1171 }
1172 
htt_t2h_stats_print(uint8_t * stats_data,int concise)1173 void htt_t2h_stats_print(uint8_t *stats_data, int concise)
1174 {
1175 	uint32_t *msg_word = (uint32_t *) stats_data;
1176 	enum htt_dbg_stats_type type;
1177 	enum htt_dbg_stats_status status;
1178 	int length;
1179 
1180 	type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word);
1181 	status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word);
1182 	length = HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word);
1183 
1184 	/* check that we've been given a valid stats type */
1185 	if (status == HTT_DBG_STATS_STATUS_SERIES_DONE) {
1186 		return;
1187 	} else if (status == HTT_DBG_STATS_STATUS_INVALID) {
1188 		qdf_debug("Target doesn't support stats type %d", type);
1189 		return;
1190 	} else if (status == HTT_DBG_STATS_STATUS_ERROR) {
1191 		qdf_debug("Target couldn't upload stats type %d (no mem?)",
1192 			  type);
1193 		return;
1194 	}
1195 	/* got valid (though perhaps partial) stats - process them */
1196 	switch (type) {
1197 	case HTT_DBG_STATS_WAL_PDEV_TXRX:
1198 	{
1199 		struct wlan_dbg_stats *wlan_dbg_stats_ptr;
1200 
1201 		wlan_dbg_stats_ptr =
1202 			(struct wlan_dbg_stats *)(msg_word + 1);
1203 		htt_t2h_stats_pdev_stats_print(wlan_dbg_stats_ptr,
1204 					       concise);
1205 		break;
1206 	}
1207 	case HTT_DBG_STATS_RX_REORDER:
1208 	{
1209 		struct rx_reorder_stats *rx_reorder_stats_ptr;
1210 
1211 		rx_reorder_stats_ptr =
1212 			(struct rx_reorder_stats *)(msg_word + 1);
1213 		htt_t2h_stats_rx_reorder_stats_print
1214 			(rx_reorder_stats_ptr, concise);
1215 		break;
1216 	}
1217 
1218 	case HTT_DBG_STATS_RX_RATE_INFO:
1219 	{
1220 		wlan_dbg_rx_rate_info_t *rx_phy_info;
1221 
1222 		rx_phy_info = (wlan_dbg_rx_rate_info_t *) (msg_word + 1);
1223 		htt_t2h_stats_rx_rate_stats_print(rx_phy_info, concise);
1224 		break;
1225 	}
1226 	case HTT_DBG_STATS_RX_RATE_INFO_V2:
1227 	{
1228 		wlan_dbg_rx_rate_info_v2_t *rx_phy_info;
1229 
1230 		rx_phy_info = (wlan_dbg_rx_rate_info_v2_t *) (msg_word + 1);
1231 		htt_t2h_stats_rx_rate_stats_print_v2(rx_phy_info, concise);
1232 		break;
1233 	}
1234 	case HTT_DBG_STATS_TX_PPDU_LOG:
1235 	{
1236 		struct ol_fw_tx_dbg_ppdu_msg_hdr *hdr;
1237 		struct ol_fw_tx_dbg_ppdu_base *record;
1238 
1239 		if (status == HTT_DBG_STATS_STATUS_PARTIAL
1240 		    && length == 0) {
1241 			qdf_debug("HTT_DBG_STATS_TX_PPDU_LOG -- length = 0!");
1242 			break;
1243 		}
1244 		hdr = (struct ol_fw_tx_dbg_ppdu_msg_hdr *)(msg_word + 1);
1245 		record = (struct ol_fw_tx_dbg_ppdu_base *)(hdr + 1);
1246 		htt_t2h_tx_ppdu_log_print(hdr, record, length, concise);
1247 	}
1248 	break;
1249 	case HTT_DBG_STATS_TX_RATE_INFO:
1250 	{
1251 		wlan_dbg_tx_rate_info_t *tx_rate_info;
1252 
1253 		tx_rate_info = (wlan_dbg_tx_rate_info_t *) (msg_word + 1);
1254 		htt_t2h_stats_tx_rate_stats_print(tx_rate_info, concise);
1255 		break;
1256 	}
1257 	case HTT_DBG_STATS_TX_RATE_INFO_V2:
1258 	{
1259 		wlan_dbg_tx_rate_info_v2_t *tx_rate_info;
1260 
1261 		tx_rate_info = (wlan_dbg_tx_rate_info_v2_t *) (msg_word + 1);
1262 		htt_t2h_stats_tx_rate_stats_print_v2(tx_rate_info, concise);
1263 		break;
1264 	}
1265 	case HTT_DBG_STATS_RX_REMOTE_RING_BUFFER_INFO:
1266 	{
1267 		struct rx_remote_buffer_mgmt_stats *rx_rem_buf;
1268 
1269 		rx_rem_buf =
1270 			(struct rx_remote_buffer_mgmt_stats *)(msg_word + 1);
1271 		htt_t2h_stats_rx_rem_buf_stats_print(rx_rem_buf, concise);
1272 		break;
1273 	}
1274 	case HTT_DBG_STATS_TXBF_INFO:
1275 	{
1276 		struct wlan_dbg_txbf_data_stats *txbf_info_buf;
1277 
1278 		txbf_info_buf =
1279 			(struct wlan_dbg_txbf_data_stats *)(msg_word + 1);
1280 		htt_t2h_stats_txbf_info_buf_stats_print(txbf_info_buf);
1281 		break;
1282 	}
1283 	case HTT_DBG_STATS_SND_INFO:
1284 	{
1285 		struct wlan_dbg_txbf_snd_stats *txbf_snd_buf;
1286 
1287 		txbf_snd_buf = (struct wlan_dbg_txbf_snd_stats *)(msg_word + 1);
1288 		htt_t2h_stats_txbf_snd_buf_stats_print(txbf_snd_buf);
1289 		break;
1290 	}
1291 	case HTT_DBG_STATS_TX_SELFGEN_INFO:
1292 	{
1293 		struct wlan_dbg_tx_selfgen_stats  *tx_selfgen_buf;
1294 
1295 		tx_selfgen_buf =
1296 			(struct wlan_dbg_tx_selfgen_stats  *)(msg_word + 1);
1297 		htt_t2h_stats_tx_selfgen_buf_stats_print(tx_selfgen_buf);
1298 		break;
1299 	}
1300 	case HTT_DBG_STATS_ERROR_INFO:
1301 	{
1302 		struct wlan_dbg_wifi2_error_stats  *wifi2_error_buf;
1303 
1304 		wifi2_error_buf =
1305 			(struct wlan_dbg_wifi2_error_stats  *)(msg_word + 1);
1306 		htt_t2h_stats_wifi2_error_stats_print(wifi2_error_buf);
1307 		break;
1308 	}
1309 	case HTT_DBG_STATS_TXBF_MUSU_NDPA_PKT:
1310 	{
1311 		struct rx_txbf_musu_ndpa_pkts_stats *rx_musu_ndpa_stats;
1312 
1313 		rx_musu_ndpa_stats = (struct rx_txbf_musu_ndpa_pkts_stats *)
1314 								(msg_word + 1);
1315 		htt_t2h_rx_musu_ndpa_pkts_stats_print(rx_musu_ndpa_stats);
1316 		break;
1317 	}
1318 	case HTT_DBG_STATS_TIDQ:
1319 	{
1320 		struct wlan_dbg_tidq_stats *tidq_stats;
1321 
1322 		tidq_stats = (struct wlan_dbg_tidq_stats *)(msg_word + 1);
1323 		htt_t2h_stats_tidq_stats_print(tidq_stats, concise);
1324 		break;
1325 	}
1326 	case HTT_DBG_STATS_TX_MU_INFO:
1327 	{
1328 		struct wlan_dbg_tx_mu_stats *tx_mu_stats;
1329 
1330 		tx_mu_stats = (struct wlan_dbg_tx_mu_stats *)(msg_word + 1);
1331 		htt_t2h_stats_tx_mu_stats_print(tx_mu_stats, concise);
1332 		break;
1333 	}
1334 	case HTT_DBG_STATS_SIFS_RESP_INFO:
1335 	{
1336 		struct wlan_dbg_sifs_resp_stats *sifs_stats;
1337 
1338 		sifs_stats = (struct wlan_dbg_sifs_resp_stats *)(msg_word + 1);
1339 		htt_t2h_stats_sifs_resp_stats_print(sifs_stats, concise);
1340 		break;
1341 	}
1342 	default:
1343 		break;
1344 	}
1345 }
1346