htt_fw_stats.c 37 KB

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