1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #include <linux/vmalloc.h> 8 #include "core.h" 9 #include "debug.h" 10 #include "debugfs_htt_stats.h" 11 #include "dp_tx.h" 12 #include "dp_rx.h" 13 14 static u32 15 print_array_to_buf(u8 *buf, u32 offset, const char *header, 16 const __le32 *array, u32 array_len, const char *footer) 17 { 18 int index = 0; 19 u8 i; 20 21 if (header) { 22 index += scnprintf(buf + offset, 23 ATH12K_HTT_STATS_BUF_SIZE - offset, 24 "%s = ", header); 25 } 26 for (i = 0; i < array_len; i++) { 27 index += scnprintf(buf + offset + index, 28 (ATH12K_HTT_STATS_BUF_SIZE - offset) - index, 29 " %u:%u,", i, le32_to_cpu(array[i])); 30 } 31 /* To overwrite the last trailing comma */ 32 index--; 33 *(buf + offset + index) = '\0'; 34 35 if (footer) { 36 index += scnprintf(buf + offset + index, 37 (ATH12K_HTT_STATS_BUF_SIZE - offset) - index, 38 "%s", footer); 39 } 40 return index; 41 } 42 43 static void 44 htt_print_tx_pdev_stats_cmn_tlv(const void *tag_buf, u16 tag_len, 45 struct debug_htt_stats_req *stats_req) 46 { 47 const struct ath12k_htt_tx_pdev_stats_cmn_tlv *htt_stats_buf = tag_buf; 48 u8 *buf = stats_req->buf; 49 u32 len = stats_req->buf_len; 50 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 51 u32 mac_id_word; 52 53 if (tag_len < sizeof(*htt_stats_buf)) 54 return; 55 56 mac_id_word = le32_to_cpu(htt_stats_buf->mac_id__word); 57 58 len += scnprintf(buf + len, buf_len - len, "HTT_TX_PDEV_STATS_CMN_TLV:\n"); 59 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 60 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 61 len += scnprintf(buf + len, buf_len - len, "comp_delivered = %u\n", 62 le32_to_cpu(htt_stats_buf->comp_delivered)); 63 len += scnprintf(buf + len, buf_len - len, "self_triggers = %u\n", 64 le32_to_cpu(htt_stats_buf->self_triggers)); 65 len += scnprintf(buf + len, buf_len - len, "hw_queued = %u\n", 66 le32_to_cpu(htt_stats_buf->hw_queued)); 67 len += scnprintf(buf + len, buf_len - len, "hw_reaped = %u\n", 68 le32_to_cpu(htt_stats_buf->hw_reaped)); 69 len += scnprintf(buf + len, buf_len - len, "underrun = %u\n", 70 le32_to_cpu(htt_stats_buf->underrun)); 71 len += scnprintf(buf + len, buf_len - len, "hw_paused = %u\n", 72 le32_to_cpu(htt_stats_buf->hw_paused)); 73 len += scnprintf(buf + len, buf_len - len, "hw_flush = %u\n", 74 le32_to_cpu(htt_stats_buf->hw_flush)); 75 len += scnprintf(buf + len, buf_len - len, "hw_filt = %u\n", 76 le32_to_cpu(htt_stats_buf->hw_filt)); 77 len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n", 78 le32_to_cpu(htt_stats_buf->tx_abort)); 79 len += scnprintf(buf + len, buf_len - len, "ppdu_ok = %u\n", 80 le32_to_cpu(htt_stats_buf->ppdu_ok)); 81 len += scnprintf(buf + len, buf_len - len, "mpdu_requeued = %u\n", 82 le32_to_cpu(htt_stats_buf->mpdu_requed)); 83 len += scnprintf(buf + len, buf_len - len, "tx_xretry = %u\n", 84 le32_to_cpu(htt_stats_buf->tx_xretry)); 85 len += scnprintf(buf + len, buf_len - len, "data_rc = %u\n", 86 le32_to_cpu(htt_stats_buf->data_rc)); 87 len += scnprintf(buf + len, buf_len - len, "mpdu_dropped_xretry = %u\n", 88 le32_to_cpu(htt_stats_buf->mpdu_dropped_xretry)); 89 len += scnprintf(buf + len, buf_len - len, "illegal_rate_phy_err = %u\n", 90 le32_to_cpu(htt_stats_buf->illgl_rate_phy_err)); 91 len += scnprintf(buf + len, buf_len - len, "cont_xretry = %u\n", 92 le32_to_cpu(htt_stats_buf->cont_xretry)); 93 len += scnprintf(buf + len, buf_len - len, "tx_timeout = %u\n", 94 le32_to_cpu(htt_stats_buf->tx_timeout)); 95 len += scnprintf(buf + len, buf_len - len, "tx_time_dur_data = %u\n", 96 le32_to_cpu(htt_stats_buf->tx_time_dur_data)); 97 len += scnprintf(buf + len, buf_len - len, "pdev_resets = %u\n", 98 le32_to_cpu(htt_stats_buf->pdev_resets)); 99 len += scnprintf(buf + len, buf_len - len, "phy_underrun = %u\n", 100 le32_to_cpu(htt_stats_buf->phy_underrun)); 101 len += scnprintf(buf + len, buf_len - len, "txop_ovf = %u\n", 102 le32_to_cpu(htt_stats_buf->txop_ovf)); 103 len += scnprintf(buf + len, buf_len - len, "seq_posted = %u\n", 104 le32_to_cpu(htt_stats_buf->seq_posted)); 105 len += scnprintf(buf + len, buf_len - len, "seq_failed_queueing = %u\n", 106 le32_to_cpu(htt_stats_buf->seq_failed_queueing)); 107 len += scnprintf(buf + len, buf_len - len, "seq_completed = %u\n", 108 le32_to_cpu(htt_stats_buf->seq_completed)); 109 len += scnprintf(buf + len, buf_len - len, "seq_restarted = %u\n", 110 le32_to_cpu(htt_stats_buf->seq_restarted)); 111 len += scnprintf(buf + len, buf_len - len, "seq_txop_repost_stop = %u\n", 112 le32_to_cpu(htt_stats_buf->seq_txop_repost_stop)); 113 len += scnprintf(buf + len, buf_len - len, "next_seq_cancel = %u\n", 114 le32_to_cpu(htt_stats_buf->next_seq_cancel)); 115 len += scnprintf(buf + len, buf_len - len, "dl_mu_mimo_seq_posted = %u\n", 116 le32_to_cpu(htt_stats_buf->mu_seq_posted)); 117 len += scnprintf(buf + len, buf_len - len, "dl_mu_ofdma_seq_posted = %u\n", 118 le32_to_cpu(htt_stats_buf->mu_ofdma_seq_posted)); 119 len += scnprintf(buf + len, buf_len - len, "ul_mu_mimo_seq_posted = %u\n", 120 le32_to_cpu(htt_stats_buf->ul_mumimo_seq_posted)); 121 len += scnprintf(buf + len, buf_len - len, "ul_mu_ofdma_seq_posted = %u\n", 122 le32_to_cpu(htt_stats_buf->ul_ofdma_seq_posted)); 123 len += scnprintf(buf + len, buf_len - len, "mu_mimo_peer_blacklisted = %u\n", 124 le32_to_cpu(htt_stats_buf->num_mu_peer_blacklisted)); 125 len += scnprintf(buf + len, buf_len - len, "seq_qdepth_repost_stop = %u\n", 126 le32_to_cpu(htt_stats_buf->seq_qdepth_repost_stop)); 127 len += scnprintf(buf + len, buf_len - len, "seq_min_msdu_repost_stop = %u\n", 128 le32_to_cpu(htt_stats_buf->seq_min_msdu_repost_stop)); 129 len += scnprintf(buf + len, buf_len - len, "mu_seq_min_msdu_repost_stop = %u\n", 130 le32_to_cpu(htt_stats_buf->mu_seq_min_msdu_repost_stop)); 131 len += scnprintf(buf + len, buf_len - len, "seq_switch_hw_paused = %u\n", 132 le32_to_cpu(htt_stats_buf->seq_switch_hw_paused)); 133 len += scnprintf(buf + len, buf_len - len, "next_seq_posted_dsr = %u\n", 134 le32_to_cpu(htt_stats_buf->next_seq_posted_dsr)); 135 len += scnprintf(buf + len, buf_len - len, "seq_posted_isr = %u\n", 136 le32_to_cpu(htt_stats_buf->seq_posted_isr)); 137 len += scnprintf(buf + len, buf_len - len, "seq_ctrl_cached = %u\n", 138 le32_to_cpu(htt_stats_buf->seq_ctrl_cached)); 139 len += scnprintf(buf + len, buf_len - len, "mpdu_count_tqm = %u\n", 140 le32_to_cpu(htt_stats_buf->mpdu_count_tqm)); 141 len += scnprintf(buf + len, buf_len - len, "msdu_count_tqm = %u\n", 142 le32_to_cpu(htt_stats_buf->msdu_count_tqm)); 143 len += scnprintf(buf + len, buf_len - len, "mpdu_removed_tqm = %u\n", 144 le32_to_cpu(htt_stats_buf->mpdu_removed_tqm)); 145 len += scnprintf(buf + len, buf_len - len, "msdu_removed_tqm = %u\n", 146 le32_to_cpu(htt_stats_buf->msdu_removed_tqm)); 147 len += scnprintf(buf + len, buf_len - len, "remove_mpdus_max_retries = %u\n", 148 le32_to_cpu(htt_stats_buf->remove_mpdus_max_retries)); 149 len += scnprintf(buf + len, buf_len - len, "mpdus_sw_flush = %u\n", 150 le32_to_cpu(htt_stats_buf->mpdus_sw_flush)); 151 len += scnprintf(buf + len, buf_len - len, "mpdus_hw_filter = %u\n", 152 le32_to_cpu(htt_stats_buf->mpdus_hw_filter)); 153 len += scnprintf(buf + len, buf_len - len, "mpdus_truncated = %u\n", 154 le32_to_cpu(htt_stats_buf->mpdus_truncated)); 155 len += scnprintf(buf + len, buf_len - len, "mpdus_ack_failed = %u\n", 156 le32_to_cpu(htt_stats_buf->mpdus_ack_failed)); 157 len += scnprintf(buf + len, buf_len - len, "mpdus_expired = %u\n", 158 le32_to_cpu(htt_stats_buf->mpdus_expired)); 159 len += scnprintf(buf + len, buf_len - len, "mpdus_seq_hw_retry = %u\n", 160 le32_to_cpu(htt_stats_buf->mpdus_seq_hw_retry)); 161 len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", 162 le32_to_cpu(htt_stats_buf->ack_tlv_proc)); 163 len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt_valid = %u\n", 164 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt_valid)); 165 len += scnprintf(buf + len, buf_len - len, "coex_abort_mpdu_cnt = %u\n", 166 le32_to_cpu(htt_stats_buf->coex_abort_mpdu_cnt)); 167 len += scnprintf(buf + len, buf_len - len, "num_total_ppdus_tried_ota = %u\n", 168 le32_to_cpu(htt_stats_buf->num_total_ppdus_tried_ota)); 169 len += scnprintf(buf + len, buf_len - len, "num_data_ppdus_tried_ota = %u\n", 170 le32_to_cpu(htt_stats_buf->num_data_ppdus_tried_ota)); 171 len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_enqued = %u\n", 172 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_enqued)); 173 len += scnprintf(buf + len, buf_len - len, "local_ctrl_mgmt_freed = %u\n", 174 le32_to_cpu(htt_stats_buf->local_ctrl_mgmt_freed)); 175 len += scnprintf(buf + len, buf_len - len, "local_data_enqued = %u\n", 176 le32_to_cpu(htt_stats_buf->local_data_enqued)); 177 len += scnprintf(buf + len, buf_len - len, "local_data_freed = %u\n", 178 le32_to_cpu(htt_stats_buf->local_data_freed)); 179 len += scnprintf(buf + len, buf_len - len, "mpdu_tried = %u\n", 180 le32_to_cpu(htt_stats_buf->mpdu_tried)); 181 len += scnprintf(buf + len, buf_len - len, "isr_wait_seq_posted = %u\n", 182 le32_to_cpu(htt_stats_buf->isr_wait_seq_posted)); 183 len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_low = %u\n", 184 le32_to_cpu(htt_stats_buf->tx_active_dur_us_low)); 185 len += scnprintf(buf + len, buf_len - len, "tx_active_dur_us_high = %u\n", 186 le32_to_cpu(htt_stats_buf->tx_active_dur_us_high)); 187 len += scnprintf(buf + len, buf_len - len, "fes_offsets_err_cnt = %u\n\n", 188 le32_to_cpu(htt_stats_buf->fes_offsets_err_cnt)); 189 190 stats_req->buf_len = len; 191 } 192 193 static void 194 htt_print_tx_pdev_stats_urrn_tlv(const void *tag_buf, 195 u16 tag_len, 196 struct debug_htt_stats_req *stats_req) 197 { 198 const struct ath12k_htt_tx_pdev_stats_urrn_tlv *htt_stats_buf = tag_buf; 199 u8 *buf = stats_req->buf; 200 u32 len = stats_req->buf_len; 201 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 202 u16 num_elems = min_t(u16, (tag_len >> 2), 203 HTT_TX_PDEV_MAX_URRN_STATS); 204 205 len += scnprintf(buf + len, buf_len - len, 206 "HTT_TX_PDEV_STATS_URRN_TLV:\n"); 207 208 len += print_array_to_buf(buf, len, "urrn_stats", htt_stats_buf->urrn_stats, 209 num_elems, "\n\n"); 210 211 stats_req->buf_len = len; 212 } 213 214 static void 215 htt_print_tx_pdev_stats_flush_tlv(const void *tag_buf, 216 u16 tag_len, 217 struct debug_htt_stats_req *stats_req) 218 { 219 const struct ath12k_htt_tx_pdev_stats_flush_tlv *htt_stats_buf = tag_buf; 220 u8 *buf = stats_req->buf; 221 u32 len = stats_req->buf_len; 222 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 223 u16 num_elems = min_t(u16, (tag_len >> 2), 224 ATH12K_HTT_TX_PDEV_MAX_FLUSH_REASON_STATS); 225 226 len += scnprintf(buf + len, buf_len - len, 227 "HTT_TX_PDEV_STATS_FLUSH_TLV:\n"); 228 229 len += print_array_to_buf(buf, len, "flush_errs", htt_stats_buf->flush_errs, 230 num_elems, "\n\n"); 231 232 stats_req->buf_len = len; 233 } 234 235 static void 236 htt_print_tx_pdev_stats_sifs_tlv(const void *tag_buf, 237 u16 tag_len, 238 struct debug_htt_stats_req *stats_req) 239 { 240 const struct ath12k_htt_tx_pdev_stats_sifs_tlv *htt_stats_buf = tag_buf; 241 u8 *buf = stats_req->buf; 242 u32 len = stats_req->buf_len; 243 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 244 u16 num_elems = min_t(u16, (tag_len >> 2), 245 ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_STATS); 246 247 len += scnprintf(buf + len, buf_len - len, 248 "HTT_TX_PDEV_STATS_SIFS_TLV:\n"); 249 250 len += print_array_to_buf(buf, len, "sifs_status", htt_stats_buf->sifs_status, 251 num_elems, "\n\n"); 252 253 stats_req->buf_len = len; 254 } 255 256 static void 257 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(const void *tag_buf, u16 tag_len, 258 struct debug_htt_stats_req *stats_req) 259 { 260 const struct ath12k_htt_tx_pdev_mu_ppdu_dist_stats_tlv *htt_stats_buf = tag_buf; 261 char *mode; 262 u8 j, hw_mode, i, str_buf_len; 263 u8 *buf = stats_req->buf; 264 u32 len = stats_req->buf_len; 265 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 266 u32 stats_value; 267 u8 max_ppdu = ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST; 268 u8 max_sched = ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS; 269 char str_buf[ATH12K_HTT_MAX_STRING_LEN]; 270 271 if (tag_len < sizeof(*htt_stats_buf)) 272 return; 273 274 hw_mode = le32_to_cpu(htt_stats_buf->hw_mode); 275 276 switch (hw_mode) { 277 case ATH12K_HTT_STATS_HWMODE_AC: 278 len += scnprintf(buf + len, buf_len - len, 279 "HTT_TX_PDEV_AC_MU_PPDU_DISTRIBUTION_STATS:\n"); 280 mode = "ac"; 281 break; 282 case ATH12K_HTT_STATS_HWMODE_AX: 283 len += scnprintf(buf + len, buf_len - len, 284 "HTT_TX_PDEV_AX_MU_PPDU_DISTRIBUTION_STATS:\n"); 285 mode = "ax"; 286 break; 287 case ATH12K_HTT_STATS_HWMODE_BE: 288 len += scnprintf(buf + len, buf_len - len, 289 "HTT_TX_PDEV_BE_MU_PPDU_DISTRIBUTION_STATS:\n"); 290 mode = "be"; 291 break; 292 default: 293 return; 294 } 295 296 for (i = 0; i < ATH12K_HTT_STATS_NUM_NR_BINS ; i++) { 297 len += scnprintf(buf + len, buf_len - len, 298 "%s_mu_mimo_num_seq_posted_nr%u = %u\n", mode, 299 ((i + 1) * 4), htt_stats_buf->num_seq_posted[i]); 300 str_buf_len = 0; 301 memset(str_buf, 0x0, sizeof(str_buf)); 302 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) { 303 stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_posted_per_burst 304 [i * max_ppdu + j]); 305 str_buf_len += scnprintf(&str_buf[str_buf_len], 306 ATH12K_HTT_MAX_STRING_LEN - str_buf_len, 307 " %u:%u,", j, stats_value); 308 } 309 /* To overwrite the last trailing comma */ 310 str_buf[str_buf_len - 1] = '\0'; 311 len += scnprintf(buf + len, buf_len - len, 312 "%s_mu_mimo_num_ppdu_posted_per_burst_nr%u = %s\n", 313 mode, ((i + 1) * 4), str_buf); 314 str_buf_len = 0; 315 memset(str_buf, 0x0, sizeof(str_buf)); 316 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_MU_PPDU_PER_BURST ; j++) { 317 stats_value = le32_to_cpu(htt_stats_buf->num_ppdu_cmpl_per_burst 318 [i * max_ppdu + j]); 319 str_buf_len += scnprintf(&str_buf[str_buf_len], 320 ATH12K_HTT_MAX_STRING_LEN - str_buf_len, 321 " %u:%u,", j, stats_value); 322 } 323 /* To overwrite the last trailing comma */ 324 str_buf[str_buf_len - 1] = '\0'; 325 len += scnprintf(buf + len, buf_len - len, 326 "%s_mu_mimo_num_ppdu_completed_per_burst_nr%u = %s\n", 327 mode, ((i + 1) * 4), str_buf); 328 str_buf_len = 0; 329 memset(str_buf, 0x0, sizeof(str_buf)); 330 for (j = 0; j < ATH12K_HTT_STATS_MAX_NUM_SCHED_STATUS ; j++) { 331 stats_value = le32_to_cpu(htt_stats_buf->num_seq_term_status 332 [i * max_sched + j]); 333 str_buf_len += scnprintf(&str_buf[str_buf_len], 334 ATH12K_HTT_MAX_STRING_LEN - str_buf_len, 335 " %u:%u,", j, stats_value); 336 } 337 /* To overwrite the last trailing comma */ 338 str_buf[str_buf_len - 1] = '\0'; 339 len += scnprintf(buf + len, buf_len - len, 340 "%s_mu_mimo_num_seq_term_status_nr%u = %s\n\n", 341 mode, ((i + 1) * 4), str_buf); 342 } 343 344 stats_req->buf_len = len; 345 } 346 347 static void 348 htt_print_tx_pdev_stats_sifs_hist_tlv(const void *tag_buf, 349 u16 tag_len, 350 struct debug_htt_stats_req *stats_req) 351 { 352 const struct ath12k_htt_tx_pdev_stats_sifs_hist_tlv *htt_stats_buf = tag_buf; 353 u8 *buf = stats_req->buf; 354 u32 len = stats_req->buf_len; 355 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 356 u16 num_elems = min_t(u16, (tag_len >> 2), 357 ATH12K_HTT_TX_PDEV_MAX_SIFS_BURST_HIST_STATS); 358 359 len += scnprintf(buf + len, buf_len - len, 360 "HTT_TX_PDEV_STATS_SIFS_HIST_TLV:\n"); 361 362 len += print_array_to_buf(buf, len, "sifs_hist_status", 363 htt_stats_buf->sifs_hist_status, num_elems, "\n\n"); 364 365 stats_req->buf_len = len; 366 } 367 368 static void 369 htt_print_pdev_ctrl_path_tx_stats_tlv(const void *tag_buf, u16 tag_len, 370 struct debug_htt_stats_req *stats_req) 371 { 372 const struct ath12k_htt_pdev_ctrl_path_tx_stats_tlv *htt_stats_buf = tag_buf; 373 u8 *buf = stats_req->buf; 374 u32 len = stats_req->buf_len; 375 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 376 377 if (len < sizeof(*htt_stats_buf)) 378 return; 379 380 len += scnprintf(buf + len, buf_len - len, 381 "HTT_TX_PDEV_STATS_CTRL_PATH_TX_STATS:\n"); 382 len += print_array_to_buf(buf, len, "fw_tx_mgmt_subtype", 383 htt_stats_buf->fw_tx_mgmt_subtype, 384 ATH12K_HTT_STATS_SUBTYPE_MAX, "\n\n"); 385 386 stats_req->buf_len = len; 387 } 388 389 static void 390 ath12k_htt_print_stats_tx_sched_cmn_tlv(const void *tag_buf, 391 u16 tag_len, 392 struct debug_htt_stats_req *stats_req) 393 { 394 const struct ath12k_htt_stats_tx_sched_cmn_tlv *htt_stats_buf = tag_buf; 395 u8 *buf = stats_req->buf; 396 u32 len = stats_req->buf_len; 397 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 398 u32 mac_id_word; 399 400 if (tag_len < sizeof(*htt_stats_buf)) 401 return; 402 403 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word); 404 405 len += scnprintf(buf + len, buf_len - len, "HTT_STATS_TX_SCHED_CMN_TLV:\n"); 406 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 407 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 408 len += scnprintf(buf + len, buf_len - len, "current_timestamp = %u\n\n", 409 le32_to_cpu(htt_stats_buf->current_timestamp)); 410 411 stats_req->buf_len = len; 412 } 413 414 static void 415 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(const void *tag_buf, 416 u16 tag_len, 417 struct debug_htt_stats_req *stats_req) 418 { 419 const struct ath12k_htt_tx_pdev_stats_sched_per_txq_tlv *htt_stats_buf = tag_buf; 420 u8 *buf = stats_req->buf; 421 u32 len = stats_req->buf_len; 422 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 423 u32 mac_id_word; 424 425 if (tag_len < sizeof(*htt_stats_buf)) 426 return; 427 428 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word); 429 430 len += scnprintf(buf + len, buf_len - len, 431 "HTT_TX_PDEV_STATS_SCHED_PER_TXQ_TLV:\n"); 432 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 433 u32_get_bits(mac_id_word, 434 ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_MAC_ID)); 435 len += scnprintf(buf + len, buf_len - len, "txq_id = %u\n", 436 u32_get_bits(mac_id_word, 437 ATH12K_HTT_TX_PDEV_STATS_SCHED_PER_TXQ_ID)); 438 len += scnprintf(buf + len, buf_len - len, "sched_policy = %u\n", 439 le32_to_cpu(htt_stats_buf->sched_policy)); 440 len += scnprintf(buf + len, buf_len - len, 441 "last_sched_cmd_posted_timestamp = %u\n", 442 le32_to_cpu(htt_stats_buf->last_sched_cmd_posted_timestamp)); 443 len += scnprintf(buf + len, buf_len - len, 444 "last_sched_cmd_compl_timestamp = %u\n", 445 le32_to_cpu(htt_stats_buf->last_sched_cmd_compl_timestamp)); 446 len += scnprintf(buf + len, buf_len - len, "sched_2_tac_lwm_count = %u\n", 447 le32_to_cpu(htt_stats_buf->sched_2_tac_lwm_count)); 448 len += scnprintf(buf + len, buf_len - len, "sched_2_tac_ring_full = %u\n", 449 le32_to_cpu(htt_stats_buf->sched_2_tac_ring_full)); 450 len += scnprintf(buf + len, buf_len - len, "sched_cmd_post_failure = %u\n", 451 le32_to_cpu(htt_stats_buf->sched_cmd_post_failure)); 452 len += scnprintf(buf + len, buf_len - len, "num_active_tids = %u\n", 453 le32_to_cpu(htt_stats_buf->num_active_tids)); 454 len += scnprintf(buf + len, buf_len - len, "num_ps_schedules = %u\n", 455 le32_to_cpu(htt_stats_buf->num_ps_schedules)); 456 len += scnprintf(buf + len, buf_len - len, "sched_cmds_pending = %u\n", 457 le32_to_cpu(htt_stats_buf->sched_cmds_pending)); 458 len += scnprintf(buf + len, buf_len - len, "num_tid_register = %u\n", 459 le32_to_cpu(htt_stats_buf->num_tid_register)); 460 len += scnprintf(buf + len, buf_len - len, "num_tid_unregister = %u\n", 461 le32_to_cpu(htt_stats_buf->num_tid_unregister)); 462 len += scnprintf(buf + len, buf_len - len, "num_qstats_queried = %u\n", 463 le32_to_cpu(htt_stats_buf->num_qstats_queried)); 464 len += scnprintf(buf + len, buf_len - len, "qstats_update_pending = %u\n", 465 le32_to_cpu(htt_stats_buf->qstats_update_pending)); 466 len += scnprintf(buf + len, buf_len - len, "last_qstats_query_timestamp = %u\n", 467 le32_to_cpu(htt_stats_buf->last_qstats_query_timestamp)); 468 len += scnprintf(buf + len, buf_len - len, "num_tqm_cmdq_full = %u\n", 469 le32_to_cpu(htt_stats_buf->num_tqm_cmdq_full)); 470 len += scnprintf(buf + len, buf_len - len, "num_de_sched_algo_trigger = %u\n", 471 le32_to_cpu(htt_stats_buf->num_de_sched_algo_trigger)); 472 len += scnprintf(buf + len, buf_len - len, "num_rt_sched_algo_trigger = %u\n", 473 le32_to_cpu(htt_stats_buf->num_rt_sched_algo_trigger)); 474 len += scnprintf(buf + len, buf_len - len, "num_tqm_sched_algo_trigger = %u\n", 475 le32_to_cpu(htt_stats_buf->num_tqm_sched_algo_trigger)); 476 len += scnprintf(buf + len, buf_len - len, "notify_sched = %u\n", 477 le32_to_cpu(htt_stats_buf->notify_sched)); 478 len += scnprintf(buf + len, buf_len - len, "dur_based_sendn_term = %u\n", 479 le32_to_cpu(htt_stats_buf->dur_based_sendn_term)); 480 len += scnprintf(buf + len, buf_len - len, "su_notify2_sched = %u\n", 481 le32_to_cpu(htt_stats_buf->su_notify2_sched)); 482 len += scnprintf(buf + len, buf_len - len, "su_optimal_queued_msdus_sched = %u\n", 483 le32_to_cpu(htt_stats_buf->su_optimal_queued_msdus_sched)); 484 len += scnprintf(buf + len, buf_len - len, "su_delay_timeout_sched = %u\n", 485 le32_to_cpu(htt_stats_buf->su_delay_timeout_sched)); 486 len += scnprintf(buf + len, buf_len - len, "su_min_txtime_sched_delay = %u\n", 487 le32_to_cpu(htt_stats_buf->su_min_txtime_sched_delay)); 488 len += scnprintf(buf + len, buf_len - len, "su_no_delay = %u\n", 489 le32_to_cpu(htt_stats_buf->su_no_delay)); 490 len += scnprintf(buf + len, buf_len - len, "num_supercycles = %u\n", 491 le32_to_cpu(htt_stats_buf->num_supercycles)); 492 len += scnprintf(buf + len, buf_len - len, "num_subcycles_with_sort = %u\n", 493 le32_to_cpu(htt_stats_buf->num_subcycles_with_sort)); 494 len += scnprintf(buf + len, buf_len - len, "num_subcycles_no_sort = %u\n\n", 495 le32_to_cpu(htt_stats_buf->num_subcycles_no_sort)); 496 497 stats_req->buf_len = len; 498 } 499 500 static void 501 ath12k_htt_print_sched_txq_cmd_posted_tlv(const void *tag_buf, 502 u16 tag_len, 503 struct debug_htt_stats_req *stats_req) 504 { 505 const struct ath12k_htt_sched_txq_cmd_posted_tlv *htt_stats_buf = tag_buf; 506 u8 *buf = stats_req->buf; 507 u32 len = stats_req->buf_len; 508 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 509 u16 num_elements = tag_len >> 2; 510 511 len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_POSTED_TLV:\n"); 512 len += print_array_to_buf(buf, len, "sched_cmd_posted", 513 htt_stats_buf->sched_cmd_posted, num_elements, "\n\n"); 514 515 stats_req->buf_len = len; 516 } 517 518 static void 519 ath12k_htt_print_sched_txq_cmd_reaped_tlv(const void *tag_buf, 520 u16 tag_len, 521 struct debug_htt_stats_req *stats_req) 522 { 523 const struct ath12k_htt_sched_txq_cmd_reaped_tlv *htt_stats_buf = tag_buf; 524 u8 *buf = stats_req->buf; 525 u32 len = stats_req->buf_len; 526 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 527 u16 num_elements = tag_len >> 2; 528 529 len += scnprintf(buf + len, buf_len - len, "HTT_SCHED_TXQ_CMD_REAPED_TLV:\n"); 530 len += print_array_to_buf(buf, len, "sched_cmd_reaped", 531 htt_stats_buf->sched_cmd_reaped, num_elements, "\n\n"); 532 533 stats_req->buf_len = len; 534 } 535 536 static void 537 ath12k_htt_print_sched_txq_sched_order_su_tlv(const void *tag_buf, 538 u16 tag_len, 539 struct debug_htt_stats_req *stats_req) 540 { 541 const struct ath12k_htt_sched_txq_sched_order_su_tlv *htt_stats_buf = tag_buf; 542 u8 *buf = stats_req->buf; 543 u32 len = stats_req->buf_len; 544 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 545 u32 sched_order_su_num_entries = min_t(u32, (tag_len >> 2), 546 ATH12K_HTT_TX_PDEV_NUM_SCHED_ORDER_LOG); 547 548 len += scnprintf(buf + len, buf_len - len, 549 "HTT_SCHED_TXQ_SCHED_ORDER_SU_TLV:\n"); 550 len += print_array_to_buf(buf, len, "sched_order_su", 551 htt_stats_buf->sched_order_su, 552 sched_order_su_num_entries, "\n\n"); 553 554 stats_req->buf_len = len; 555 } 556 557 static void 558 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(const void *tag_buf, 559 u16 tag_len, 560 struct debug_htt_stats_req *stats_req) 561 { 562 const struct ath12k_htt_sched_txq_sched_ineligibility_tlv *htt_stats_buf = 563 tag_buf; 564 u8 *buf = stats_req->buf; 565 u32 len = stats_req->buf_len; 566 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 567 u32 sched_ineligibility_num_entries = tag_len >> 2; 568 569 len += scnprintf(buf + len, buf_len - len, 570 "HTT_SCHED_TXQ_SCHED_INELIGIBILITY:\n"); 571 len += print_array_to_buf(buf, len, "sched_ineligibility", 572 htt_stats_buf->sched_ineligibility, 573 sched_ineligibility_num_entries, "\n\n"); 574 575 stats_req->buf_len = len; 576 } 577 578 static void 579 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(const void *tag_buf, 580 u16 tag_len, 581 struct debug_htt_stats_req *stats_req) 582 { 583 const struct ath12k_htt_sched_txq_supercycle_triggers_tlv *htt_stats_buf = 584 tag_buf; 585 u8 *buf = stats_req->buf; 586 u32 len = stats_req->buf_len; 587 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 588 u16 num_elems = min_t(u16, (tag_len >> 2), 589 ATH12K_HTT_SCHED_SUPERCYCLE_TRIGGER_MAX); 590 591 len += scnprintf(buf + len, buf_len - len, 592 "HTT_SCHED_TXQ_SUPERCYCLE_TRIGGER:\n"); 593 len += print_array_to_buf(buf, len, "supercycle_triggers", 594 htt_stats_buf->supercycle_triggers, num_elems, "\n\n"); 595 596 stats_req->buf_len = len; 597 } 598 599 static void 600 ath12k_htt_print_hw_stats_pdev_errs_tlv(const void *tag_buf, u16 tag_len, 601 struct debug_htt_stats_req *stats_req) 602 { 603 const struct ath12k_htt_hw_stats_pdev_errs_tlv *htt_buf = tag_buf; 604 u8 *buf = stats_req->buf; 605 u32 len = stats_req->buf_len; 606 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 607 u32 mac_id_word; 608 609 if (tag_len < sizeof(*htt_buf)) 610 return; 611 612 mac_id_word = le32_to_cpu(htt_buf->mac_id__word); 613 614 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_PDEV_ERRS_TLV:\n"); 615 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 616 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 617 len += scnprintf(buf + len, buf_len - len, "tx_abort = %u\n", 618 le32_to_cpu(htt_buf->tx_abort)); 619 len += scnprintf(buf + len, buf_len - len, "tx_abort_fail_count = %u\n", 620 le32_to_cpu(htt_buf->tx_abort_fail_count)); 621 len += scnprintf(buf + len, buf_len - len, "rx_abort = %u\n", 622 le32_to_cpu(htt_buf->rx_abort)); 623 len += scnprintf(buf + len, buf_len - len, "rx_abort_fail_count = %u\n", 624 le32_to_cpu(htt_buf->rx_abort_fail_count)); 625 len += scnprintf(buf + len, buf_len - len, "rx_flush_cnt = %u\n", 626 le32_to_cpu(htt_buf->rx_flush_cnt)); 627 len += scnprintf(buf + len, buf_len - len, "warm_reset = %u\n", 628 le32_to_cpu(htt_buf->warm_reset)); 629 len += scnprintf(buf + len, buf_len - len, "cold_reset = %u\n", 630 le32_to_cpu(htt_buf->cold_reset)); 631 len += scnprintf(buf + len, buf_len - len, "mac_cold_reset_restore_cal = %u\n", 632 le32_to_cpu(htt_buf->mac_cold_reset_restore_cal)); 633 len += scnprintf(buf + len, buf_len - len, "mac_cold_reset = %u\n", 634 le32_to_cpu(htt_buf->mac_cold_reset)); 635 len += scnprintf(buf + len, buf_len - len, "mac_warm_reset = %u\n", 636 le32_to_cpu(htt_buf->mac_warm_reset)); 637 len += scnprintf(buf + len, buf_len - len, "mac_only_reset = %u\n", 638 le32_to_cpu(htt_buf->mac_only_reset)); 639 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset = %u\n", 640 le32_to_cpu(htt_buf->phy_warm_reset)); 641 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_ucode_trig = %u\n", 642 le32_to_cpu(htt_buf->phy_warm_reset_ucode_trig)); 643 len += scnprintf(buf + len, buf_len - len, "mac_warm_reset_restore_cal = %u\n", 644 le32_to_cpu(htt_buf->mac_warm_reset_restore_cal)); 645 len += scnprintf(buf + len, buf_len - len, "mac_sfm_reset = %u\n", 646 le32_to_cpu(htt_buf->mac_sfm_reset)); 647 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_m3_ssr = %u\n", 648 le32_to_cpu(htt_buf->phy_warm_reset_m3_ssr)); 649 len += scnprintf(buf + len, buf_len - len, "fw_rx_rings_reset = %u\n", 650 le32_to_cpu(htt_buf->fw_rx_rings_reset)); 651 len += scnprintf(buf + len, buf_len - len, "tx_flush = %u\n", 652 le32_to_cpu(htt_buf->tx_flush)); 653 len += scnprintf(buf + len, buf_len - len, "tx_glb_reset = %u\n", 654 le32_to_cpu(htt_buf->tx_glb_reset)); 655 len += scnprintf(buf + len, buf_len - len, "tx_txq_reset = %u\n", 656 le32_to_cpu(htt_buf->tx_txq_reset)); 657 len += scnprintf(buf + len, buf_len - len, "rx_timeout_reset = %u\n\n", 658 le32_to_cpu(htt_buf->rx_timeout_reset)); 659 660 len += scnprintf(buf + len, buf_len - len, "PDEV_PHY_WARM_RESET_REASONS:\n"); 661 len += scnprintf(buf + len, buf_len - len, "phy_warm_reset_reason_phy_m3 = %u\n", 662 le32_to_cpu(htt_buf->phy_warm_reset_reason_phy_m3)); 663 len += scnprintf(buf + len, buf_len - len, 664 "phy_warm_reset_reason_tx_hw_stuck = %u\n", 665 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hw_stuck)); 666 len += scnprintf(buf + len, buf_len - len, 667 "phy_warm_reset_reason_num_cca_rx_frame_stuck = %u\n", 668 le32_to_cpu(htt_buf->phy_warm_reset_reason_num_rx_frame_stuck)); 669 len += scnprintf(buf + len, buf_len - len, 670 "phy_warm_reset_reason_wal_rx_recovery_rst_rx_busy = %u\n", 671 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_rx_busy)); 672 len += scnprintf(buf + len, buf_len - len, 673 "phy_warm_reset_reason_wal_rx_recovery_rst_mac_hang = %u\n", 674 le32_to_cpu(htt_buf->phy_warm_reset_reason_wal_rx_rec_mac_hng)); 675 len += scnprintf(buf + len, buf_len - len, 676 "phy_warm_reset_reason_mac_reset_converted_phy_reset = %u\n", 677 le32_to_cpu(htt_buf->phy_warm_reset_reason_mac_conv_phy_reset)); 678 len += scnprintf(buf + len, buf_len - len, 679 "phy_warm_reset_reason_tx_lifetime_expiry_cca_stuck = %u\n", 680 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_exp_cca_stuck)); 681 len += scnprintf(buf + len, buf_len - len, 682 "phy_warm_reset_reason_tx_consecutive_flush9_war = %u\n", 683 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_consec_flsh_war)); 684 len += scnprintf(buf + len, buf_len - len, 685 "phy_warm_reset_reason_tx_hwsch_reset_war = %u\n", 686 le32_to_cpu(htt_buf->phy_warm_reset_reason_tx_hwsch_reset_war)); 687 len += scnprintf(buf + len, buf_len - len, 688 "phy_warm_reset_reason_hwsch_wdog_or_cca_wdog_war = %u\n\n", 689 le32_to_cpu(htt_buf->phy_warm_reset_reason_hwsch_cca_wdog_war)); 690 691 len += scnprintf(buf + len, buf_len - len, "WAL_RX_RECOVERY_STATS:\n"); 692 len += scnprintf(buf + len, buf_len - len, 693 "wal_rx_recovery_rst_mac_hang_count = %u\n", 694 le32_to_cpu(htt_buf->wal_rx_recovery_rst_mac_hang_cnt)); 695 len += scnprintf(buf + len, buf_len - len, 696 "wal_rx_recovery_rst_known_sig_count = %u\n", 697 le32_to_cpu(htt_buf->wal_rx_recovery_rst_known_sig_cnt)); 698 len += scnprintf(buf + len, buf_len - len, 699 "wal_rx_recovery_rst_no_rx_count = %u\n", 700 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_cnt)); 701 len += scnprintf(buf + len, buf_len - len, 702 "wal_rx_recovery_rst_no_rx_consecutive_count = %u\n", 703 le32_to_cpu(htt_buf->wal_rx_recovery_rst_no_rx_consec_cnt)); 704 len += scnprintf(buf + len, buf_len - len, 705 "wal_rx_recovery_rst_rx_busy_count = %u\n", 706 le32_to_cpu(htt_buf->wal_rx_recovery_rst_rx_busy_cnt)); 707 len += scnprintf(buf + len, buf_len - len, 708 "wal_rx_recovery_rst_phy_mac_hang_count = %u\n\n", 709 le32_to_cpu(htt_buf->wal_rx_recovery_rst_phy_mac_hang_cnt)); 710 711 len += scnprintf(buf + len, buf_len - len, "HTT_RX_DEST_DRAIN_STATS:\n"); 712 len += scnprintf(buf + len, buf_len - len, 713 "rx_dest_drain_rx_descs_leak_prevention_done = %u\n", 714 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_leak_prevented)); 715 len += scnprintf(buf + len, buf_len - len, 716 "rx_dest_drain_rx_descs_saved_cnt = %u\n", 717 le32_to_cpu(htt_buf->rx_dest_drain_rx_descs_saved_cnt)); 718 len += scnprintf(buf + len, buf_len - len, 719 "rx_dest_drain_rxdma2reo_leak_detected = %u\n", 720 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2reo_leak_detected)); 721 len += scnprintf(buf + len, buf_len - len, 722 "rx_dest_drain_rxdma2fw_leak_detected = %u\n", 723 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2fw_leak_detected)); 724 len += scnprintf(buf + len, buf_len - len, 725 "rx_dest_drain_rxdma2wbm_leak_detected = %u\n", 726 le32_to_cpu(htt_buf->rx_dest_drain_rxdma2wbm_leak_detected)); 727 len += scnprintf(buf + len, buf_len - len, 728 "rx_dest_drain_rxdma1_2sw_leak_detected = %u\n", 729 le32_to_cpu(htt_buf->rx_dest_drain_rxdma1_2sw_leak_detected)); 730 len += scnprintf(buf + len, buf_len - len, 731 "rx_dest_drain_rx_drain_ok_mac_idle = %u\n", 732 le32_to_cpu(htt_buf->rx_dest_drain_rx_drain_ok_mac_idle)); 733 len += scnprintf(buf + len, buf_len - len, 734 "rx_dest_drain_ok_mac_not_idle = %u\n", 735 le32_to_cpu(htt_buf->rx_dest_drain_ok_mac_not_idle)); 736 len += scnprintf(buf + len, buf_len - len, 737 "rx_dest_drain_prerequisite_invld = %u\n", 738 le32_to_cpu(htt_buf->rx_dest_drain_prerequisite_invld)); 739 len += scnprintf(buf + len, buf_len - len, 740 "rx_dest_drain_skip_for_non_lmac_reset = %u\n", 741 le32_to_cpu(htt_buf->rx_dest_drain_skip_non_lmac_reset)); 742 len += scnprintf(buf + len, buf_len - len, 743 "rx_dest_drain_hw_fifo_not_empty_post_drain_wait = %u\n\n", 744 le32_to_cpu(htt_buf->rx_dest_drain_hw_fifo_notempty_post_wait)); 745 746 stats_req->buf_len = len; 747 } 748 749 static void 750 ath12k_htt_print_hw_stats_intr_misc_tlv(const void *tag_buf, u16 tag_len, 751 struct debug_htt_stats_req *stats_req) 752 { 753 const struct ath12k_htt_hw_stats_intr_misc_tlv *htt_stats_buf = tag_buf; 754 u8 *buf = stats_req->buf; 755 u32 len = stats_req->buf_len; 756 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 757 758 if (tag_len < sizeof(*htt_stats_buf)) 759 return; 760 761 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_INTR_MISC_TLV:\n"); 762 len += scnprintf(buf + len, buf_len - len, "hw_intr_name = %s\n", 763 htt_stats_buf->hw_intr_name); 764 len += scnprintf(buf + len, buf_len - len, "mask = %u\n", 765 le32_to_cpu(htt_stats_buf->mask)); 766 len += scnprintf(buf + len, buf_len - len, "count = %u\n\n", 767 le32_to_cpu(htt_stats_buf->count)); 768 769 stats_req->buf_len = len; 770 } 771 772 static void 773 ath12k_htt_print_hw_stats_whal_tx_tlv(const void *tag_buf, u16 tag_len, 774 struct debug_htt_stats_req *stats_req) 775 { 776 const struct ath12k_htt_hw_stats_whal_tx_tlv *htt_stats_buf = tag_buf; 777 u8 *buf = stats_req->buf; 778 u32 len = stats_req->buf_len; 779 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 780 u32 mac_id_word; 781 782 if (tag_len < sizeof(*htt_stats_buf)) 783 return; 784 785 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word); 786 787 len += scnprintf(buf + len, buf_len - len, "HTT_HW_STATS_WHAL_TX_TLV:\n"); 788 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 789 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 790 len += scnprintf(buf + len, buf_len - len, "last_unpause_ppdu_id = %u\n", 791 le32_to_cpu(htt_stats_buf->last_unpause_ppdu_id)); 792 len += scnprintf(buf + len, buf_len - len, "hwsch_unpause_wait_tqm_write = %u\n", 793 le32_to_cpu(htt_stats_buf->hwsch_unpause_wait_tqm_write)); 794 len += scnprintf(buf + len, buf_len - len, "hwsch_dummy_tlv_skipped = %u\n", 795 le32_to_cpu(htt_stats_buf->hwsch_dummy_tlv_skipped)); 796 len += scnprintf(buf + len, buf_len - len, 797 "hwsch_misaligned_offset_received = %u\n", 798 le32_to_cpu(htt_stats_buf->hwsch_misaligned_offset_received)); 799 len += scnprintf(buf + len, buf_len - len, "hwsch_reset_count = %u\n", 800 le32_to_cpu(htt_stats_buf->hwsch_reset_count)); 801 len += scnprintf(buf + len, buf_len - len, "hwsch_dev_reset_war = %u\n", 802 le32_to_cpu(htt_stats_buf->hwsch_dev_reset_war)); 803 len += scnprintf(buf + len, buf_len - len, "hwsch_delayed_pause = %u\n", 804 le32_to_cpu(htt_stats_buf->hwsch_delayed_pause)); 805 len += scnprintf(buf + len, buf_len - len, "hwsch_long_delayed_pause = %u\n", 806 le32_to_cpu(htt_stats_buf->hwsch_long_delayed_pause)); 807 len += scnprintf(buf + len, buf_len - len, "sch_rx_ppdu_no_response = %u\n", 808 le32_to_cpu(htt_stats_buf->sch_rx_ppdu_no_response)); 809 len += scnprintf(buf + len, buf_len - len, "sch_selfgen_response = %u\n", 810 le32_to_cpu(htt_stats_buf->sch_selfgen_response)); 811 len += scnprintf(buf + len, buf_len - len, "sch_rx_sifs_resp_trigger= %u\n\n", 812 le32_to_cpu(htt_stats_buf->sch_rx_sifs_resp_trigger)); 813 814 stats_req->buf_len = len; 815 } 816 817 static void 818 ath12k_htt_print_hw_war_tlv(const void *tag_buf, u16 tag_len, 819 struct debug_htt_stats_req *stats_req) 820 { 821 const struct ath12k_htt_hw_war_stats_tlv *htt_stats_buf = tag_buf; 822 u8 *buf = stats_req->buf; 823 u32 len = stats_req->buf_len; 824 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 825 u16 fixed_len, array_len; 826 u8 i, array_words; 827 u32 mac_id; 828 829 if (tag_len < sizeof(*htt_stats_buf)) 830 return; 831 832 mac_id = __le32_to_cpu(htt_stats_buf->mac_id__word); 833 fixed_len = sizeof(*htt_stats_buf); 834 array_len = tag_len - fixed_len; 835 array_words = array_len >> 2; 836 837 len += scnprintf(buf + len, buf_len - len, "HTT_HW_WAR_STATS_TLV:\n"); 838 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 839 u32_get_bits(mac_id, ATH12K_HTT_STATS_MAC_ID)); 840 841 for (i = 0; i < array_words; i++) { 842 len += scnprintf(buf + len, buf_len - len, "hw_war %u = %u\n\n", 843 i, le32_to_cpu(htt_stats_buf->hw_wars[i])); 844 } 845 846 stats_req->buf_len = len; 847 } 848 849 static void 850 ath12k_htt_print_tx_tqm_cmn_stats_tlv(const void *tag_buf, u16 tag_len, 851 struct debug_htt_stats_req *stats_req) 852 { 853 const struct ath12k_htt_tx_tqm_cmn_stats_tlv *htt_stats_buf = tag_buf; 854 u8 *buf = stats_req->buf; 855 u32 len = stats_req->buf_len; 856 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 857 u32 mac_id_word; 858 859 if (tag_len < sizeof(*htt_stats_buf)) 860 return; 861 862 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word); 863 864 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_CMN_STATS_TLV:\n"); 865 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 866 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 867 len += scnprintf(buf + len, buf_len - len, "max_cmdq_id = %u\n", 868 le32_to_cpu(htt_stats_buf->max_cmdq_id)); 869 len += scnprintf(buf + len, buf_len - len, "list_mpdu_cnt_hist_intvl = %u\n", 870 le32_to_cpu(htt_stats_buf->list_mpdu_cnt_hist_intvl)); 871 len += scnprintf(buf + len, buf_len - len, "add_msdu = %u\n", 872 le32_to_cpu(htt_stats_buf->add_msdu)); 873 len += scnprintf(buf + len, buf_len - len, "q_empty = %u\n", 874 le32_to_cpu(htt_stats_buf->q_empty)); 875 len += scnprintf(buf + len, buf_len - len, "q_not_empty = %u\n", 876 le32_to_cpu(htt_stats_buf->q_not_empty)); 877 len += scnprintf(buf + len, buf_len - len, "drop_notification = %u\n", 878 le32_to_cpu(htt_stats_buf->drop_notification)); 879 len += scnprintf(buf + len, buf_len - len, "desc_threshold = %u\n", 880 le32_to_cpu(htt_stats_buf->desc_threshold)); 881 len += scnprintf(buf + len, buf_len - len, "hwsch_tqm_invalid_status = %u\n", 882 le32_to_cpu(htt_stats_buf->hwsch_tqm_invalid_status)); 883 len += scnprintf(buf + len, buf_len - len, "missed_tqm_gen_mpdus = %u\n", 884 le32_to_cpu(htt_stats_buf->missed_tqm_gen_mpdus)); 885 len += scnprintf(buf + len, buf_len - len, 886 "total_msduq_timestamp_updates = %u\n", 887 le32_to_cpu(htt_stats_buf->msduq_timestamp_updates)); 888 len += scnprintf(buf + len, buf_len - len, 889 "total_msduq_timestamp_updates_by_get_mpdu_head_info_cmd = %u\n", 890 le32_to_cpu(htt_stats_buf->msduq_updates_mpdu_head_info_cmd)); 891 len += scnprintf(buf + len, buf_len - len, 892 "total_msduq_timestamp_updates_by_emp_to_nonemp_status = %u\n", 893 le32_to_cpu(htt_stats_buf->msduq_updates_emp_to_nonemp_status)); 894 len += scnprintf(buf + len, buf_len - len, 895 "total_get_mpdu_head_info_cmds_by_sched_algo_la_query = %u\n", 896 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_query)); 897 len += scnprintf(buf + len, buf_len - len, 898 "total_get_mpdu_head_info_cmds_by_tac = %u\n", 899 le32_to_cpu(htt_stats_buf->get_mpdu_head_info_cmds_by_tac)); 900 len += scnprintf(buf + len, buf_len - len, 901 "total_gen_mpdu_cmds_by_sched_algo_la_query = %u\n", 902 le32_to_cpu(htt_stats_buf->gen_mpdu_cmds_by_query)); 903 len += scnprintf(buf + len, buf_len - len, "active_tqm_tids = %u\n", 904 le32_to_cpu(htt_stats_buf->tqm_active_tids)); 905 len += scnprintf(buf + len, buf_len - len, "inactive_tqm_tids = %u\n", 906 le32_to_cpu(htt_stats_buf->tqm_inactive_tids)); 907 len += scnprintf(buf + len, buf_len - len, "tqm_active_msduq_flows = %u\n", 908 le32_to_cpu(htt_stats_buf->tqm_active_msduq_flows)); 909 len += scnprintf(buf + len, buf_len - len, "hi_prio_q_not_empty = %u\n\n", 910 le32_to_cpu(htt_stats_buf->high_prio_q_not_empty)); 911 912 stats_req->buf_len = len; 913 } 914 915 static void 916 ath12k_htt_print_tx_tqm_error_stats_tlv(const void *tag_buf, u16 tag_len, 917 struct debug_htt_stats_req *stats_req) 918 { 919 const struct ath12k_htt_tx_tqm_error_stats_tlv *htt_stats_buf = tag_buf; 920 u8 *buf = stats_req->buf; 921 u32 len = stats_req->buf_len; 922 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 923 924 if (tag_len < sizeof(*htt_stats_buf)) 925 return; 926 927 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_ERROR_STATS_TLV:\n"); 928 len += scnprintf(buf + len, buf_len - len, "q_empty_failure = %u\n", 929 le32_to_cpu(htt_stats_buf->q_empty_failure)); 930 len += scnprintf(buf + len, buf_len - len, "q_not_empty_failure = %u\n", 931 le32_to_cpu(htt_stats_buf->q_not_empty_failure)); 932 len += scnprintf(buf + len, buf_len - len, "add_msdu_failure = %u\n\n", 933 le32_to_cpu(htt_stats_buf->add_msdu_failure)); 934 935 len += scnprintf(buf + len, buf_len - len, "TQM_ERROR_RESET_STATS:\n"); 936 len += scnprintf(buf + len, buf_len - len, "tqm_cache_ctl_err = %u\n", 937 le32_to_cpu(htt_stats_buf->tqm_cache_ctl_err)); 938 len += scnprintf(buf + len, buf_len - len, "tqm_soft_reset = %u\n", 939 le32_to_cpu(htt_stats_buf->tqm_soft_reset)); 940 len += scnprintf(buf + len, buf_len - len, 941 "tqm_reset_total_num_in_use_link_descs = %u\n", 942 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_link_descs)); 943 len += scnprintf(buf + len, buf_len - len, 944 "tqm_reset_worst_case_num_lost_link_descs = %u\n", 945 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_link_descs)); 946 len += scnprintf(buf + len, buf_len - len, 947 "tqm_reset_worst_case_num_lost_host_tx_bufs_count = %u\n", 948 le32_to_cpu(htt_stats_buf->tqm_reset_num_lost_host_tx_buf_cnt)); 949 len += scnprintf(buf + len, buf_len - len, 950 "tqm_reset_num_in_use_link_descs_internal_tqm = %u\n", 951 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_internal_tqm)); 952 len += scnprintf(buf + len, buf_len - len, 953 "tqm_reset_num_in_use_link_descs_wbm_idle_link_ring = %u\n", 954 le32_to_cpu(htt_stats_buf->tqm_reset_num_in_use_idle_link_rng)); 955 len += scnprintf(buf + len, buf_len - len, 956 "tqm_reset_time_to_tqm_hang_delta_ms = %u\n", 957 le32_to_cpu(htt_stats_buf->tqm_reset_time_to_tqm_hang_delta_ms)); 958 len += scnprintf(buf + len, buf_len - len, "tqm_reset_recovery_time_ms = %u\n", 959 le32_to_cpu(htt_stats_buf->tqm_reset_recovery_time_ms)); 960 len += scnprintf(buf + len, buf_len - len, "tqm_reset_num_peers_hdl = %u\n", 961 le32_to_cpu(htt_stats_buf->tqm_reset_num_peers_hdl)); 962 len += scnprintf(buf + len, buf_len - len, 963 "tqm_reset_cumm_dirty_hw_mpduq_proc_cnt = %u\n", 964 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_mpduq_cnt)); 965 len += scnprintf(buf + len, buf_len - len, 966 "tqm_reset_cumm_dirty_hw_msduq_proc = %u\n", 967 le32_to_cpu(htt_stats_buf->tqm_reset_cumm_dirty_hw_msduq_proc)); 968 len += scnprintf(buf + len, buf_len - len, 969 "tqm_reset_flush_cache_cmd_su_cnt = %u\n", 970 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_su_cnt)); 971 len += scnprintf(buf + len, buf_len - len, 972 "tqm_reset_flush_cache_cmd_other_cnt = %u\n", 973 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_other_cnt)); 974 len += scnprintf(buf + len, buf_len - len, 975 "tqm_reset_flush_cache_cmd_trig_type = %u\n", 976 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_type)); 977 len += scnprintf(buf + len, buf_len - len, 978 "tqm_reset_flush_cache_cmd_trig_cfg = %u\n", 979 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cache_cmd_trig_cfg)); 980 len += scnprintf(buf + len, buf_len - len, 981 "tqm_reset_flush_cache_cmd_skip_cmd_status_null = %u\n\n", 982 le32_to_cpu(htt_stats_buf->tqm_reset_flush_cmd_skp_status_null)); 983 984 stats_req->buf_len = len; 985 } 986 987 static void 988 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(const void *tag_buf, u16 tag_len, 989 struct debug_htt_stats_req *stats_req) 990 { 991 const struct ath12k_htt_tx_tqm_gen_mpdu_stats_tlv *htt_stats_buf = tag_buf; 992 u8 *buf = stats_req->buf; 993 u32 len = stats_req->buf_len; 994 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 995 u16 num_elements = tag_len >> 2; 996 997 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_GEN_MPDU_STATS_TLV:\n"); 998 len += print_array_to_buf(buf, len, "gen_mpdu_end_reason", 999 htt_stats_buf->gen_mpdu_end_reason, num_elements, 1000 "\n\n"); 1001 1002 stats_req->buf_len = len; 1003 } 1004 1005 static void 1006 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(const void *tag_buf, u16 tag_len, 1007 struct debug_htt_stats_req *stats_req) 1008 { 1009 const struct ath12k_htt_tx_tqm_list_mpdu_stats_tlv *htt_stats_buf = tag_buf; 1010 u8 *buf = stats_req->buf; 1011 u32 len = stats_req->buf_len; 1012 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1013 u16 num_elems = min_t(u16, (tag_len >> 2), 1014 ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_END_REASON); 1015 1016 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_STATS_TLV:\n"); 1017 len += print_array_to_buf(buf, len, "list_mpdu_end_reason", 1018 htt_stats_buf->list_mpdu_end_reason, num_elems, "\n\n"); 1019 1020 stats_req->buf_len = len; 1021 } 1022 1023 static void 1024 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(const void *tag_buf, u16 tag_len, 1025 struct debug_htt_stats_req *stats_req) 1026 { 1027 const struct ath12k_htt_tx_tqm_list_mpdu_cnt_tlv *htt_stats_buf = tag_buf; 1028 u8 *buf = stats_req->buf; 1029 u32 len = stats_req->buf_len; 1030 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1031 u16 num_elems = min_t(u16, (tag_len >> 2), 1032 ATH12K_HTT_TX_TQM_MAX_LIST_MPDU_CNT_HISTOGRAM_BINS); 1033 1034 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_LIST_MPDU_CNT_TLV_V:\n"); 1035 len += print_array_to_buf(buf, len, "list_mpdu_cnt_hist", 1036 htt_stats_buf->list_mpdu_cnt_hist, num_elems, "\n\n"); 1037 1038 stats_req->buf_len = len; 1039 } 1040 1041 static void 1042 ath12k_htt_print_tx_tqm_pdev_stats_tlv(const void *tag_buf, u16 tag_len, 1043 struct debug_htt_stats_req *stats_req) 1044 { 1045 const struct ath12k_htt_tx_tqm_pdev_stats_tlv *htt_stats_buf = tag_buf; 1046 u8 *buf = stats_req->buf; 1047 u32 len = stats_req->buf_len; 1048 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1049 1050 if (tag_len < sizeof(*htt_stats_buf)) 1051 return; 1052 1053 len += scnprintf(buf + len, buf_len - len, "HTT_TX_TQM_PDEV_STATS_TLV_V:\n"); 1054 len += scnprintf(buf + len, buf_len - len, "msdu_count = %u\n", 1055 le32_to_cpu(htt_stats_buf->msdu_count)); 1056 len += scnprintf(buf + len, buf_len - len, "mpdu_count = %u\n", 1057 le32_to_cpu(htt_stats_buf->mpdu_count)); 1058 len += scnprintf(buf + len, buf_len - len, "remove_msdu = %u\n", 1059 le32_to_cpu(htt_stats_buf->remove_msdu)); 1060 len += scnprintf(buf + len, buf_len - len, "remove_mpdu = %u\n", 1061 le32_to_cpu(htt_stats_buf->remove_mpdu)); 1062 len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl = %u\n", 1063 le32_to_cpu(htt_stats_buf->remove_msdu_ttl)); 1064 len += scnprintf(buf + len, buf_len - len, "send_bar = %u\n", 1065 le32_to_cpu(htt_stats_buf->send_bar)); 1066 len += scnprintf(buf + len, buf_len - len, "bar_sync = %u\n", 1067 le32_to_cpu(htt_stats_buf->bar_sync)); 1068 len += scnprintf(buf + len, buf_len - len, "notify_mpdu = %u\n", 1069 le32_to_cpu(htt_stats_buf->notify_mpdu)); 1070 len += scnprintf(buf + len, buf_len - len, "sync_cmd = %u\n", 1071 le32_to_cpu(htt_stats_buf->sync_cmd)); 1072 len += scnprintf(buf + len, buf_len - len, "write_cmd = %u\n", 1073 le32_to_cpu(htt_stats_buf->write_cmd)); 1074 len += scnprintf(buf + len, buf_len - len, "hwsch_trigger = %u\n", 1075 le32_to_cpu(htt_stats_buf->hwsch_trigger)); 1076 len += scnprintf(buf + len, buf_len - len, "ack_tlv_proc = %u\n", 1077 le32_to_cpu(htt_stats_buf->ack_tlv_proc)); 1078 len += scnprintf(buf + len, buf_len - len, "gen_mpdu_cmd = %u\n", 1079 le32_to_cpu(htt_stats_buf->gen_mpdu_cmd)); 1080 len += scnprintf(buf + len, buf_len - len, "gen_list_cmd = %u\n", 1081 le32_to_cpu(htt_stats_buf->gen_list_cmd)); 1082 len += scnprintf(buf + len, buf_len - len, "remove_mpdu_cmd = %u\n", 1083 le32_to_cpu(htt_stats_buf->remove_mpdu_cmd)); 1084 len += scnprintf(buf + len, buf_len - len, "remove_mpdu_tried_cmd = %u\n", 1085 le32_to_cpu(htt_stats_buf->remove_mpdu_tried_cmd)); 1086 len += scnprintf(buf + len, buf_len - len, "mpdu_queue_stats_cmd = %u\n", 1087 le32_to_cpu(htt_stats_buf->mpdu_queue_stats_cmd)); 1088 len += scnprintf(buf + len, buf_len - len, "mpdu_head_info_cmd = %u\n", 1089 le32_to_cpu(htt_stats_buf->mpdu_head_info_cmd)); 1090 len += scnprintf(buf + len, buf_len - len, "msdu_flow_stats_cmd = %u\n", 1091 le32_to_cpu(htt_stats_buf->msdu_flow_stats_cmd)); 1092 len += scnprintf(buf + len, buf_len - len, "remove_msdu_cmd = %u\n", 1093 le32_to_cpu(htt_stats_buf->remove_msdu_cmd)); 1094 len += scnprintf(buf + len, buf_len - len, "remove_msdu_ttl_cmd = %u\n", 1095 le32_to_cpu(htt_stats_buf->remove_msdu_ttl_cmd)); 1096 len += scnprintf(buf + len, buf_len - len, "flush_cache_cmd = %u\n", 1097 le32_to_cpu(htt_stats_buf->flush_cache_cmd)); 1098 len += scnprintf(buf + len, buf_len - len, "update_mpduq_cmd = %u\n", 1099 le32_to_cpu(htt_stats_buf->update_mpduq_cmd)); 1100 len += scnprintf(buf + len, buf_len - len, "enqueue = %u\n", 1101 le32_to_cpu(htt_stats_buf->enqueue)); 1102 len += scnprintf(buf + len, buf_len - len, "enqueue_notify = %u\n", 1103 le32_to_cpu(htt_stats_buf->enqueue_notify)); 1104 len += scnprintf(buf + len, buf_len - len, "notify_mpdu_at_head = %u\n", 1105 le32_to_cpu(htt_stats_buf->notify_mpdu_at_head)); 1106 len += scnprintf(buf + len, buf_len - len, "notify_mpdu_state_valid = %u\n", 1107 le32_to_cpu(htt_stats_buf->notify_mpdu_state_valid)); 1108 len += scnprintf(buf + len, buf_len - len, "sched_udp_notify1 = %u\n", 1109 le32_to_cpu(htt_stats_buf->sched_udp_notify1)); 1110 len += scnprintf(buf + len, buf_len - len, "sched_udp_notify2 = %u\n", 1111 le32_to_cpu(htt_stats_buf->sched_udp_notify2)); 1112 len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify1 = %u\n", 1113 le32_to_cpu(htt_stats_buf->sched_nonudp_notify1)); 1114 len += scnprintf(buf + len, buf_len - len, "sched_nonudp_notify2 = %u\n\n", 1115 le32_to_cpu(htt_stats_buf->sched_nonudp_notify2)); 1116 1117 stats_req->buf_len = len; 1118 } 1119 1120 static void 1121 ath12k_htt_print_tx_de_cmn_stats_tlv(const void *tag_buf, u16 tag_len, 1122 struct debug_htt_stats_req *stats_req) 1123 { 1124 const struct ath12k_htt_tx_de_cmn_stats_tlv *htt_stats_buf = tag_buf; 1125 u8 *buf = stats_req->buf; 1126 u32 len = stats_req->buf_len; 1127 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1128 u32 mac_id_word; 1129 1130 if (tag_len < sizeof(*htt_stats_buf)) 1131 return; 1132 1133 mac_id_word = __le32_to_cpu(htt_stats_buf->mac_id__word); 1134 1135 len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CMN_STATS_TLV:\n"); 1136 len += scnprintf(buf + len, buf_len - len, "mac_id = %u\n", 1137 u32_get_bits(mac_id_word, ATH12K_HTT_STATS_MAC_ID)); 1138 len += scnprintf(buf + len, buf_len - len, "tcl2fw_entry_count = %u\n", 1139 le32_to_cpu(htt_stats_buf->tcl2fw_entry_count)); 1140 len += scnprintf(buf + len, buf_len - len, "not_to_fw = %u\n", 1141 le32_to_cpu(htt_stats_buf->not_to_fw)); 1142 len += scnprintf(buf + len, buf_len - len, "invalid_pdev_vdev_peer = %u\n", 1143 le32_to_cpu(htt_stats_buf->invalid_pdev_vdev_peer)); 1144 len += scnprintf(buf + len, buf_len - len, "tcl_res_invalid_addrx = %u\n", 1145 le32_to_cpu(htt_stats_buf->tcl_res_invalid_addrx)); 1146 len += scnprintf(buf + len, buf_len - len, "wbm2fw_entry_count = %u\n", 1147 le32_to_cpu(htt_stats_buf->wbm2fw_entry_count)); 1148 len += scnprintf(buf + len, buf_len - len, "invalid_pdev = %u\n", 1149 le32_to_cpu(htt_stats_buf->invalid_pdev)); 1150 len += scnprintf(buf + len, buf_len - len, "tcl_res_addrx_timeout = %u\n", 1151 le32_to_cpu(htt_stats_buf->tcl_res_addrx_timeout)); 1152 len += scnprintf(buf + len, buf_len - len, "invalid_vdev = %u\n", 1153 le32_to_cpu(htt_stats_buf->invalid_vdev)); 1154 len += scnprintf(buf + len, buf_len - len, "invalid_tcl_exp_frame_desc = %u\n", 1155 le32_to_cpu(htt_stats_buf->invalid_tcl_exp_frame_desc)); 1156 len += scnprintf(buf + len, buf_len - len, "vdev_id_mismatch_count = %u\n\n", 1157 le32_to_cpu(htt_stats_buf->vdev_id_mismatch_cnt)); 1158 1159 stats_req->buf_len = len; 1160 } 1161 1162 static void 1163 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(const void *tag_buf, u16 tag_len, 1164 struct debug_htt_stats_req *stats_req) 1165 { 1166 const struct ath12k_htt_tx_de_eapol_packets_stats_tlv *htt_stats_buf = tag_buf; 1167 u8 *buf = stats_req->buf; 1168 u32 len = stats_req->buf_len; 1169 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1170 1171 if (tag_len < sizeof(*htt_stats_buf)) 1172 return; 1173 1174 len += scnprintf(buf + len, buf_len - len, 1175 "HTT_TX_DE_EAPOL_PACKETS_STATS_TLV:\n"); 1176 len += scnprintf(buf + len, buf_len - len, "m1_packets = %u\n", 1177 le32_to_cpu(htt_stats_buf->m1_packets)); 1178 len += scnprintf(buf + len, buf_len - len, "m2_packets = %u\n", 1179 le32_to_cpu(htt_stats_buf->m2_packets)); 1180 len += scnprintf(buf + len, buf_len - len, "m3_packets = %u\n", 1181 le32_to_cpu(htt_stats_buf->m3_packets)); 1182 len += scnprintf(buf + len, buf_len - len, "m4_packets = %u\n", 1183 le32_to_cpu(htt_stats_buf->m4_packets)); 1184 len += scnprintf(buf + len, buf_len - len, "g1_packets = %u\n", 1185 le32_to_cpu(htt_stats_buf->g1_packets)); 1186 len += scnprintf(buf + len, buf_len - len, "g2_packets = %u\n", 1187 le32_to_cpu(htt_stats_buf->g2_packets)); 1188 len += scnprintf(buf + len, buf_len - len, "rc4_packets = %u\n", 1189 le32_to_cpu(htt_stats_buf->rc4_packets)); 1190 len += scnprintf(buf + len, buf_len - len, "eap_packets = %u\n", 1191 le32_to_cpu(htt_stats_buf->eap_packets)); 1192 len += scnprintf(buf + len, buf_len - len, "eapol_start_packets = %u\n", 1193 le32_to_cpu(htt_stats_buf->eapol_start_packets)); 1194 len += scnprintf(buf + len, buf_len - len, "eapol_logoff_packets = %u\n", 1195 le32_to_cpu(htt_stats_buf->eapol_logoff_packets)); 1196 len += scnprintf(buf + len, buf_len - len, "eapol_encap_asf_packets = %u\n\n", 1197 le32_to_cpu(htt_stats_buf->eapol_encap_asf_packets)); 1198 1199 stats_req->buf_len = len; 1200 } 1201 1202 static void 1203 ath12k_htt_print_tx_de_classify_stats_tlv(const void *tag_buf, u16 tag_len, 1204 struct debug_htt_stats_req *stats_req) 1205 { 1206 const struct ath12k_htt_tx_de_classify_stats_tlv *htt_stats_buf = tag_buf; 1207 u8 *buf = stats_req->buf; 1208 u32 len = stats_req->buf_len; 1209 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1210 1211 if (tag_len < sizeof(*htt_stats_buf)) 1212 return; 1213 1214 len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_CLASSIFY_STATS_TLV:\n"); 1215 len += scnprintf(buf + len, buf_len - len, "arp_packets = %u\n", 1216 le32_to_cpu(htt_stats_buf->arp_packets)); 1217 len += scnprintf(buf + len, buf_len - len, "igmp_packets = %u\n", 1218 le32_to_cpu(htt_stats_buf->igmp_packets)); 1219 len += scnprintf(buf + len, buf_len - len, "dhcp_packets = %u\n", 1220 le32_to_cpu(htt_stats_buf->dhcp_packets)); 1221 len += scnprintf(buf + len, buf_len - len, "host_inspected = %u\n", 1222 le32_to_cpu(htt_stats_buf->host_inspected)); 1223 len += scnprintf(buf + len, buf_len - len, "htt_included = %u\n", 1224 le32_to_cpu(htt_stats_buf->htt_included)); 1225 len += scnprintf(buf + len, buf_len - len, "htt_valid_mcs = %u\n", 1226 le32_to_cpu(htt_stats_buf->htt_valid_mcs)); 1227 len += scnprintf(buf + len, buf_len - len, "htt_valid_nss = %u\n", 1228 le32_to_cpu(htt_stats_buf->htt_valid_nss)); 1229 len += scnprintf(buf + len, buf_len - len, "htt_valid_preamble_type = %u\n", 1230 le32_to_cpu(htt_stats_buf->htt_valid_preamble_type)); 1231 len += scnprintf(buf + len, buf_len - len, "htt_valid_chainmask = %u\n", 1232 le32_to_cpu(htt_stats_buf->htt_valid_chainmask)); 1233 len += scnprintf(buf + len, buf_len - len, "htt_valid_guard_interval = %u\n", 1234 le32_to_cpu(htt_stats_buf->htt_valid_guard_interval)); 1235 len += scnprintf(buf + len, buf_len - len, "htt_valid_retries = %u\n", 1236 le32_to_cpu(htt_stats_buf->htt_valid_retries)); 1237 len += scnprintf(buf + len, buf_len - len, "htt_valid_bw_info = %u\n", 1238 le32_to_cpu(htt_stats_buf->htt_valid_bw_info)); 1239 len += scnprintf(buf + len, buf_len - len, "htt_valid_power = %u\n", 1240 le32_to_cpu(htt_stats_buf->htt_valid_power)); 1241 len += scnprintf(buf + len, buf_len - len, "htt_valid_key_flags = 0x%x\n", 1242 le32_to_cpu(htt_stats_buf->htt_valid_key_flags)); 1243 len += scnprintf(buf + len, buf_len - len, "htt_valid_no_encryption = %u\n", 1244 le32_to_cpu(htt_stats_buf->htt_valid_no_encryption)); 1245 len += scnprintf(buf + len, buf_len - len, "fse_entry_count = %u\n", 1246 le32_to_cpu(htt_stats_buf->fse_entry_count)); 1247 len += scnprintf(buf + len, buf_len - len, "fse_priority_be = %u\n", 1248 le32_to_cpu(htt_stats_buf->fse_priority_be)); 1249 len += scnprintf(buf + len, buf_len - len, "fse_priority_high = %u\n", 1250 le32_to_cpu(htt_stats_buf->fse_priority_high)); 1251 len += scnprintf(buf + len, buf_len - len, "fse_priority_low = %u\n", 1252 le32_to_cpu(htt_stats_buf->fse_priority_low)); 1253 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_be = %u\n", 1254 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_be)); 1255 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_over_sub = %u\n", 1256 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_over_sub)); 1257 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_bursty = %u\n", 1258 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_bursty)); 1259 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_interactive = %u\n", 1260 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_interactive)); 1261 len += scnprintf(buf + len, buf_len - len, "fse_traffic_ptrn_periodic = %u\n", 1262 le32_to_cpu(htt_stats_buf->fse_traffic_ptrn_periodic)); 1263 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_alloc = %u\n", 1264 le32_to_cpu(htt_stats_buf->fse_hwqueue_alloc)); 1265 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_created = %u\n", 1266 le32_to_cpu(htt_stats_buf->fse_hwqueue_created)); 1267 len += scnprintf(buf + len, buf_len - len, "fse_hwqueue_send_to_host = %u\n", 1268 le32_to_cpu(htt_stats_buf->fse_hwqueue_send_to_host)); 1269 len += scnprintf(buf + len, buf_len - len, "mcast_entry = %u\n", 1270 le32_to_cpu(htt_stats_buf->mcast_entry)); 1271 len += scnprintf(buf + len, buf_len - len, "bcast_entry = %u\n", 1272 le32_to_cpu(htt_stats_buf->bcast_entry)); 1273 len += scnprintf(buf + len, buf_len - len, "htt_update_peer_cache = %u\n", 1274 le32_to_cpu(htt_stats_buf->htt_update_peer_cache)); 1275 len += scnprintf(buf + len, buf_len - len, "htt_learning_frame = %u\n", 1276 le32_to_cpu(htt_stats_buf->htt_learning_frame)); 1277 len += scnprintf(buf + len, buf_len - len, "fse_invalid_peer = %u\n", 1278 le32_to_cpu(htt_stats_buf->fse_invalid_peer)); 1279 len += scnprintf(buf + len, buf_len - len, "mec_notify = %u\n\n", 1280 le32_to_cpu(htt_stats_buf->mec_notify)); 1281 1282 stats_req->buf_len = len; 1283 } 1284 1285 static void 1286 ath12k_htt_print_tx_de_classify_failed_stats_tlv(const void *tag_buf, u16 tag_len, 1287 struct debug_htt_stats_req *stats_req) 1288 { 1289 const struct ath12k_htt_tx_de_classify_failed_stats_tlv *htt_stats_buf = tag_buf; 1290 u8 *buf = stats_req->buf; 1291 u32 len = stats_req->buf_len; 1292 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1293 1294 if (tag_len < sizeof(*htt_stats_buf)) 1295 return; 1296 1297 len += scnprintf(buf + len, buf_len - len, 1298 "HTT_TX_DE_CLASSIFY_FAILED_STATS_TLV:\n"); 1299 len += scnprintf(buf + len, buf_len - len, "ap_bss_peer_not_found = %u\n", 1300 le32_to_cpu(htt_stats_buf->ap_bss_peer_not_found)); 1301 len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_no_peer = %u\n", 1302 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_no_peer)); 1303 len += scnprintf(buf + len, buf_len - len, "sta_delete_in_progress = %u\n", 1304 le32_to_cpu(htt_stats_buf->sta_delete_in_progress)); 1305 len += scnprintf(buf + len, buf_len - len, "ibss_no_bss_peer = %u\n", 1306 le32_to_cpu(htt_stats_buf->ibss_no_bss_peer)); 1307 len += scnprintf(buf + len, buf_len - len, "invalid_vdev_type = %u\n", 1308 le32_to_cpu(htt_stats_buf->invalid_vdev_type)); 1309 len += scnprintf(buf + len, buf_len - len, "invalid_ast_peer_entry = %u\n", 1310 le32_to_cpu(htt_stats_buf->invalid_ast_peer_entry)); 1311 len += scnprintf(buf + len, buf_len - len, "peer_entry_invalid = %u\n", 1312 le32_to_cpu(htt_stats_buf->peer_entry_invalid)); 1313 len += scnprintf(buf + len, buf_len - len, "ethertype_not_ip = %u\n", 1314 le32_to_cpu(htt_stats_buf->ethertype_not_ip)); 1315 len += scnprintf(buf + len, buf_len - len, "eapol_lookup_failed = %u\n", 1316 le32_to_cpu(htt_stats_buf->eapol_lookup_failed)); 1317 len += scnprintf(buf + len, buf_len - len, "qpeer_not_allow_data = %u\n", 1318 le32_to_cpu(htt_stats_buf->qpeer_not_allow_data)); 1319 len += scnprintf(buf + len, buf_len - len, "fse_tid_override = %u\n", 1320 le32_to_cpu(htt_stats_buf->fse_tid_override)); 1321 len += scnprintf(buf + len, buf_len - len, "ipv6_jumbogram_zero_length = %u\n", 1322 le32_to_cpu(htt_stats_buf->ipv6_jumbogram_zero_length)); 1323 len += scnprintf(buf + len, buf_len - len, "qos_to_non_qos_in_prog = %u\n", 1324 le32_to_cpu(htt_stats_buf->qos_to_non_qos_in_prog)); 1325 len += scnprintf(buf + len, buf_len - len, "ap_bcast_mcast_eapol = %u\n", 1326 le32_to_cpu(htt_stats_buf->ap_bcast_mcast_eapol)); 1327 len += scnprintf(buf + len, buf_len - len, "unicast_on_ap_bss_peer = %u\n", 1328 le32_to_cpu(htt_stats_buf->unicast_on_ap_bss_peer)); 1329 len += scnprintf(buf + len, buf_len - len, "ap_vdev_invalid = %u\n", 1330 le32_to_cpu(htt_stats_buf->ap_vdev_invalid)); 1331 len += scnprintf(buf + len, buf_len - len, "incomplete_llc = %u\n", 1332 le32_to_cpu(htt_stats_buf->incomplete_llc)); 1333 len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m3 = %u\n", 1334 le32_to_cpu(htt_stats_buf->eapol_duplicate_m3)); 1335 len += scnprintf(buf + len, buf_len - len, "eapol_duplicate_m4 = %u\n\n", 1336 le32_to_cpu(htt_stats_buf->eapol_duplicate_m4)); 1337 1338 stats_req->buf_len = len; 1339 } 1340 1341 static void 1342 ath12k_htt_print_tx_de_classify_status_stats_tlv(const void *tag_buf, u16 tag_len, 1343 struct debug_htt_stats_req *stats_req) 1344 { 1345 const struct ath12k_htt_tx_de_classify_status_stats_tlv *htt_stats_buf = tag_buf; 1346 u8 *buf = stats_req->buf; 1347 u32 len = stats_req->buf_len; 1348 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1349 1350 if (tag_len < sizeof(*htt_stats_buf)) 1351 return; 1352 1353 len += scnprintf(buf + len, buf_len - len, 1354 "HTT_TX_DE_CLASSIFY_STATUS_STATS_TLV:\n"); 1355 len += scnprintf(buf + len, buf_len - len, "eok = %u\n", 1356 le32_to_cpu(htt_stats_buf->eok)); 1357 len += scnprintf(buf + len, buf_len - len, "classify_done = %u\n", 1358 le32_to_cpu(htt_stats_buf->classify_done)); 1359 len += scnprintf(buf + len, buf_len - len, "lookup_failed = %u\n", 1360 le32_to_cpu(htt_stats_buf->lookup_failed)); 1361 len += scnprintf(buf + len, buf_len - len, "send_host_dhcp = %u\n", 1362 le32_to_cpu(htt_stats_buf->send_host_dhcp)); 1363 len += scnprintf(buf + len, buf_len - len, "send_host_mcast = %u\n", 1364 le32_to_cpu(htt_stats_buf->send_host_mcast)); 1365 len += scnprintf(buf + len, buf_len - len, "send_host_unknown_dest = %u\n", 1366 le32_to_cpu(htt_stats_buf->send_host_unknown_dest)); 1367 len += scnprintf(buf + len, buf_len - len, "send_host = %u\n", 1368 le32_to_cpu(htt_stats_buf->send_host)); 1369 len += scnprintf(buf + len, buf_len - len, "status_invalid = %u\n\n", 1370 le32_to_cpu(htt_stats_buf->status_invalid)); 1371 1372 stats_req->buf_len = len; 1373 } 1374 1375 static void 1376 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(const void *tag_buf, u16 tag_len, 1377 struct debug_htt_stats_req *stats_req) 1378 { 1379 const struct ath12k_htt_tx_de_enqueue_packets_stats_tlv *htt_stats_buf = tag_buf; 1380 u8 *buf = stats_req->buf; 1381 u32 len = stats_req->buf_len; 1382 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1383 1384 if (tag_len < sizeof(*htt_stats_buf)) 1385 return; 1386 1387 len += scnprintf(buf + len, buf_len - len, 1388 "HTT_TX_DE_ENQUEUE_PACKETS_STATS_TLV:\n"); 1389 len += scnprintf(buf + len, buf_len - len, "enqueued_pkts = %u\n", 1390 le32_to_cpu(htt_stats_buf->enqueued_pkts)); 1391 len += scnprintf(buf + len, buf_len - len, "to_tqm = %u\n", 1392 le32_to_cpu(htt_stats_buf->to_tqm)); 1393 len += scnprintf(buf + len, buf_len - len, "to_tqm_bypass = %u\n\n", 1394 le32_to_cpu(htt_stats_buf->to_tqm_bypass)); 1395 1396 stats_req->buf_len = len; 1397 } 1398 1399 static void 1400 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(const void *tag_buf, u16 tag_len, 1401 struct debug_htt_stats_req *stats_req) 1402 { 1403 const struct ath12k_htt_tx_de_enqueue_discard_stats_tlv *htt_stats_buf = tag_buf; 1404 u8 *buf = stats_req->buf; 1405 u32 len = stats_req->buf_len; 1406 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1407 1408 if (tag_len < sizeof(*htt_stats_buf)) 1409 return; 1410 1411 len += scnprintf(buf + len, buf_len - len, 1412 "HTT_TX_DE_ENQUEUE_DISCARD_STATS_TLV:\n"); 1413 len += scnprintf(buf + len, buf_len - len, "discarded_pkts = %u\n", 1414 le32_to_cpu(htt_stats_buf->discarded_pkts)); 1415 len += scnprintf(buf + len, buf_len - len, "local_frames = %u\n", 1416 le32_to_cpu(htt_stats_buf->local_frames)); 1417 len += scnprintf(buf + len, buf_len - len, "is_ext_msdu = %u\n\n", 1418 le32_to_cpu(htt_stats_buf->is_ext_msdu)); 1419 1420 stats_req->buf_len = len; 1421 } 1422 1423 static void 1424 ath12k_htt_print_tx_de_compl_stats_tlv(const void *tag_buf, u16 tag_len, 1425 struct debug_htt_stats_req *stats_req) 1426 { 1427 const struct ath12k_htt_tx_de_compl_stats_tlv *htt_stats_buf = tag_buf; 1428 u8 *buf = stats_req->buf; 1429 u32 len = stats_req->buf_len; 1430 u32 buf_len = ATH12K_HTT_STATS_BUF_SIZE; 1431 1432 if (tag_len < sizeof(*htt_stats_buf)) 1433 return; 1434 1435 len += scnprintf(buf + len, buf_len - len, "HTT_TX_DE_COMPL_STATS_TLV:\n"); 1436 len += scnprintf(buf + len, buf_len - len, "tcl_dummy_frame = %u\n", 1437 le32_to_cpu(htt_stats_buf->tcl_dummy_frame)); 1438 len += scnprintf(buf + len, buf_len - len, "tqm_dummy_frame = %u\n", 1439 le32_to_cpu(htt_stats_buf->tqm_dummy_frame)); 1440 len += scnprintf(buf + len, buf_len - len, "tqm_notify_frame = %u\n", 1441 le32_to_cpu(htt_stats_buf->tqm_notify_frame)); 1442 len += scnprintf(buf + len, buf_len - len, "fw2wbm_enq = %u\n", 1443 le32_to_cpu(htt_stats_buf->fw2wbm_enq)); 1444 len += scnprintf(buf + len, buf_len - len, "tqm_bypass_frame = %u\n\n", 1445 le32_to_cpu(htt_stats_buf->tqm_bypass_frame)); 1446 1447 stats_req->buf_len = len; 1448 } 1449 1450 static int ath12k_dbg_htt_ext_stats_parse(struct ath12k_base *ab, 1451 u16 tag, u16 len, const void *tag_buf, 1452 void *user_data) 1453 { 1454 struct debug_htt_stats_req *stats_req = user_data; 1455 1456 switch (tag) { 1457 case HTT_STATS_TX_PDEV_CMN_TAG: 1458 htt_print_tx_pdev_stats_cmn_tlv(tag_buf, len, stats_req); 1459 break; 1460 case HTT_STATS_TX_PDEV_UNDERRUN_TAG: 1461 htt_print_tx_pdev_stats_urrn_tlv(tag_buf, len, stats_req); 1462 break; 1463 case HTT_STATS_TX_PDEV_SIFS_TAG: 1464 htt_print_tx_pdev_stats_sifs_tlv(tag_buf, len, stats_req); 1465 break; 1466 case HTT_STATS_TX_PDEV_FLUSH_TAG: 1467 htt_print_tx_pdev_stats_flush_tlv(tag_buf, len, stats_req); 1468 break; 1469 case HTT_STATS_TX_PDEV_SIFS_HIST_TAG: 1470 htt_print_tx_pdev_stats_sifs_hist_tlv(tag_buf, len, stats_req); 1471 break; 1472 case HTT_STATS_PDEV_CTRL_PATH_TX_STATS_TAG: 1473 htt_print_pdev_ctrl_path_tx_stats_tlv(tag_buf, len, stats_req); 1474 break; 1475 case HTT_STATS_MU_PPDU_DIST_TAG: 1476 htt_print_tx_pdev_mu_ppdu_dist_stats_tlv(tag_buf, len, stats_req); 1477 break; 1478 case HTT_STATS_TX_SCHED_CMN_TAG: 1479 ath12k_htt_print_stats_tx_sched_cmn_tlv(tag_buf, len, stats_req); 1480 break; 1481 case HTT_STATS_TX_PDEV_SCHEDULER_TXQ_STATS_TAG: 1482 ath12k_htt_print_tx_pdev_stats_sched_per_txq_tlv(tag_buf, len, stats_req); 1483 break; 1484 case HTT_STATS_SCHED_TXQ_CMD_POSTED_TAG: 1485 ath12k_htt_print_sched_txq_cmd_posted_tlv(tag_buf, len, stats_req); 1486 break; 1487 case HTT_STATS_SCHED_TXQ_CMD_REAPED_TAG: 1488 ath12k_htt_print_sched_txq_cmd_reaped_tlv(tag_buf, len, stats_req); 1489 break; 1490 case HTT_STATS_SCHED_TXQ_SCHED_ORDER_SU_TAG: 1491 ath12k_htt_print_sched_txq_sched_order_su_tlv(tag_buf, len, stats_req); 1492 break; 1493 case HTT_STATS_SCHED_TXQ_SCHED_INELIGIBILITY_TAG: 1494 ath12k_htt_print_sched_txq_sched_ineligibility_tlv(tag_buf, len, 1495 stats_req); 1496 break; 1497 case HTT_STATS_SCHED_TXQ_SUPERCYCLE_TRIGGER_TAG: 1498 ath12k_htt_print_sched_txq_supercycle_trigger_tlv(tag_buf, len, 1499 stats_req); 1500 break; 1501 case HTT_STATS_HW_PDEV_ERRS_TAG: 1502 ath12k_htt_print_hw_stats_pdev_errs_tlv(tag_buf, len, stats_req); 1503 break; 1504 case HTT_STATS_HW_INTR_MISC_TAG: 1505 ath12k_htt_print_hw_stats_intr_misc_tlv(tag_buf, len, stats_req); 1506 break; 1507 case HTT_STATS_WHAL_TX_TAG: 1508 ath12k_htt_print_hw_stats_whal_tx_tlv(tag_buf, len, stats_req); 1509 break; 1510 case HTT_STATS_HW_WAR_TAG: 1511 ath12k_htt_print_hw_war_tlv(tag_buf, len, stats_req); 1512 break; 1513 case HTT_STATS_TX_TQM_CMN_TAG: 1514 ath12k_htt_print_tx_tqm_cmn_stats_tlv(tag_buf, len, stats_req); 1515 break; 1516 case HTT_STATS_TX_TQM_ERROR_STATS_TAG: 1517 ath12k_htt_print_tx_tqm_error_stats_tlv(tag_buf, len, stats_req); 1518 break; 1519 case HTT_STATS_TX_TQM_GEN_MPDU_TAG: 1520 ath12k_htt_print_tx_tqm_gen_mpdu_stats_tlv(tag_buf, len, stats_req); 1521 break; 1522 case HTT_STATS_TX_TQM_LIST_MPDU_TAG: 1523 ath12k_htt_print_tx_tqm_list_mpdu_stats_tlv(tag_buf, len, stats_req); 1524 break; 1525 case HTT_STATS_TX_TQM_LIST_MPDU_CNT_TAG: 1526 ath12k_htt_print_tx_tqm_list_mpdu_cnt_tlv(tag_buf, len, stats_req); 1527 break; 1528 case HTT_STATS_TX_TQM_PDEV_TAG: 1529 ath12k_htt_print_tx_tqm_pdev_stats_tlv(tag_buf, len, stats_req); 1530 break; 1531 case HTT_STATS_TX_DE_CMN_TAG: 1532 ath12k_htt_print_tx_de_cmn_stats_tlv(tag_buf, len, stats_req); 1533 break; 1534 case HTT_STATS_TX_DE_EAPOL_PACKETS_TAG: 1535 ath12k_htt_print_tx_de_eapol_packets_stats_tlv(tag_buf, len, stats_req); 1536 break; 1537 case HTT_STATS_TX_DE_CLASSIFY_STATS_TAG: 1538 ath12k_htt_print_tx_de_classify_stats_tlv(tag_buf, len, stats_req); 1539 break; 1540 case HTT_STATS_TX_DE_CLASSIFY_FAILED_TAG: 1541 ath12k_htt_print_tx_de_classify_failed_stats_tlv(tag_buf, len, stats_req); 1542 break; 1543 case HTT_STATS_TX_DE_CLASSIFY_STATUS_TAG: 1544 ath12k_htt_print_tx_de_classify_status_stats_tlv(tag_buf, len, stats_req); 1545 break; 1546 case HTT_STATS_TX_DE_ENQUEUE_PACKETS_TAG: 1547 ath12k_htt_print_tx_de_enqueue_packets_stats_tlv(tag_buf, len, stats_req); 1548 break; 1549 case HTT_STATS_TX_DE_ENQUEUE_DISCARD_TAG: 1550 ath12k_htt_print_tx_de_enqueue_discard_stats_tlv(tag_buf, len, stats_req); 1551 break; 1552 case HTT_STATS_TX_DE_COMPL_STATS_TAG: 1553 ath12k_htt_print_tx_de_compl_stats_tlv(tag_buf, len, stats_req); 1554 break; 1555 default: 1556 break; 1557 } 1558 1559 return 0; 1560 } 1561 1562 void ath12k_debugfs_htt_ext_stats_handler(struct ath12k_base *ab, 1563 struct sk_buff *skb) 1564 { 1565 struct ath12k_htt_extd_stats_msg *msg; 1566 struct debug_htt_stats_req *stats_req; 1567 struct ath12k *ar; 1568 u32 len, pdev_id, stats_info; 1569 u64 cookie; 1570 int ret; 1571 bool send_completion = false; 1572 1573 msg = (struct ath12k_htt_extd_stats_msg *)skb->data; 1574 cookie = le64_to_cpu(msg->cookie); 1575 1576 if (u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_MSB) != 1577 ATH12K_HTT_STATS_MAGIC_VALUE) { 1578 ath12k_warn(ab, "received invalid htt ext stats event\n"); 1579 return; 1580 } 1581 1582 pdev_id = u64_get_bits(cookie, ATH12K_HTT_STATS_COOKIE_LSB); 1583 rcu_read_lock(); 1584 ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id); 1585 if (!ar) { 1586 ath12k_warn(ab, "failed to get ar for pdev_id %d\n", pdev_id); 1587 goto exit; 1588 } 1589 1590 stats_req = ar->debug.htt_stats.stats_req; 1591 if (!stats_req) 1592 goto exit; 1593 1594 spin_lock_bh(&ar->data_lock); 1595 1596 stats_info = le32_to_cpu(msg->info1); 1597 stats_req->done = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_DONE); 1598 if (stats_req->done) 1599 send_completion = true; 1600 1601 spin_unlock_bh(&ar->data_lock); 1602 1603 len = u32_get_bits(stats_info, ATH12K_HTT_T2H_EXT_STATS_INFO1_LENGTH); 1604 if (len > skb->len) { 1605 ath12k_warn(ab, "invalid length %d for HTT stats", len); 1606 goto exit; 1607 } 1608 1609 ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len, 1610 ath12k_dbg_htt_ext_stats_parse, 1611 stats_req); 1612 if (ret) 1613 ath12k_warn(ab, "Failed to parse tlv %d\n", ret); 1614 1615 if (send_completion) 1616 complete(&stats_req->htt_stats_rcvd); 1617 exit: 1618 rcu_read_unlock(); 1619 } 1620 1621 static ssize_t ath12k_read_htt_stats_type(struct file *file, 1622 char __user *user_buf, 1623 size_t count, loff_t *ppos) 1624 { 1625 struct ath12k *ar = file->private_data; 1626 enum ath12k_dbg_htt_ext_stats_type type; 1627 char buf[32]; 1628 size_t len; 1629 1630 mutex_lock(&ar->conf_mutex); 1631 type = ar->debug.htt_stats.type; 1632 mutex_unlock(&ar->conf_mutex); 1633 1634 len = scnprintf(buf, sizeof(buf), "%u\n", type); 1635 1636 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1637 } 1638 1639 static ssize_t ath12k_write_htt_stats_type(struct file *file, 1640 const char __user *user_buf, 1641 size_t count, loff_t *ppos) 1642 { 1643 struct ath12k *ar = file->private_data; 1644 enum ath12k_dbg_htt_ext_stats_type type; 1645 unsigned int cfg_param[4] = {0}; 1646 const int size = 32; 1647 int num_args; 1648 1649 char *buf __free(kfree) = kzalloc(size, GFP_KERNEL); 1650 if (!buf) 1651 return -ENOMEM; 1652 1653 if (copy_from_user(buf, user_buf, count)) 1654 return -EFAULT; 1655 1656 num_args = sscanf(buf, "%u %u %u %u %u\n", &type, &cfg_param[0], 1657 &cfg_param[1], &cfg_param[2], &cfg_param[3]); 1658 if (!num_args || num_args > 5) 1659 return -EINVAL; 1660 1661 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET || 1662 type >= ATH12K_DBG_HTT_NUM_EXT_STATS) 1663 return -EINVAL; 1664 1665 mutex_lock(&ar->conf_mutex); 1666 1667 ar->debug.htt_stats.type = type; 1668 ar->debug.htt_stats.cfg_param[0] = cfg_param[0]; 1669 ar->debug.htt_stats.cfg_param[1] = cfg_param[1]; 1670 ar->debug.htt_stats.cfg_param[2] = cfg_param[2]; 1671 ar->debug.htt_stats.cfg_param[3] = cfg_param[3]; 1672 1673 mutex_unlock(&ar->conf_mutex); 1674 1675 return count; 1676 } 1677 1678 static const struct file_operations fops_htt_stats_type = { 1679 .read = ath12k_read_htt_stats_type, 1680 .write = ath12k_write_htt_stats_type, 1681 .open = simple_open, 1682 .owner = THIS_MODULE, 1683 .llseek = default_llseek, 1684 }; 1685 1686 static int ath12k_debugfs_htt_stats_req(struct ath12k *ar) 1687 { 1688 struct debug_htt_stats_req *stats_req = ar->debug.htt_stats.stats_req; 1689 enum ath12k_dbg_htt_ext_stats_type type = stats_req->type; 1690 u64 cookie; 1691 int ret, pdev_id; 1692 struct htt_ext_stats_cfg_params cfg_params = { 0 }; 1693 1694 lockdep_assert_held(&ar->conf_mutex); 1695 1696 init_completion(&stats_req->htt_stats_rcvd); 1697 1698 pdev_id = ath12k_mac_get_target_pdev_id(ar); 1699 stats_req->done = false; 1700 stats_req->pdev_id = pdev_id; 1701 1702 cookie = u64_encode_bits(ATH12K_HTT_STATS_MAGIC_VALUE, 1703 ATH12K_HTT_STATS_COOKIE_MSB); 1704 cookie |= u64_encode_bits(pdev_id, ATH12K_HTT_STATS_COOKIE_LSB); 1705 1706 if (stats_req->override_cfg_param) { 1707 cfg_params.cfg0 = stats_req->cfg_param[0]; 1708 cfg_params.cfg1 = stats_req->cfg_param[1]; 1709 cfg_params.cfg2 = stats_req->cfg_param[2]; 1710 cfg_params.cfg3 = stats_req->cfg_param[3]; 1711 } 1712 1713 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie); 1714 if (ret) { 1715 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret); 1716 return ret; 1717 } 1718 if (!wait_for_completion_timeout(&stats_req->htt_stats_rcvd, 3 * HZ)) { 1719 spin_lock_bh(&ar->data_lock); 1720 if (!stats_req->done) { 1721 stats_req->done = true; 1722 spin_unlock_bh(&ar->data_lock); 1723 ath12k_warn(ar->ab, "stats request timed out\n"); 1724 return -ETIMEDOUT; 1725 } 1726 spin_unlock_bh(&ar->data_lock); 1727 } 1728 1729 return 0; 1730 } 1731 1732 static int ath12k_open_htt_stats(struct inode *inode, 1733 struct file *file) 1734 { 1735 struct ath12k *ar = inode->i_private; 1736 struct debug_htt_stats_req *stats_req; 1737 enum ath12k_dbg_htt_ext_stats_type type = ar->debug.htt_stats.type; 1738 struct ath12k_hw *ah = ath12k_ar_to_ah(ar); 1739 int ret; 1740 1741 if (type == ATH12K_DBG_HTT_EXT_STATS_RESET) 1742 return -EPERM; 1743 1744 mutex_lock(&ar->conf_mutex); 1745 1746 if (ah->state != ATH12K_HW_STATE_ON) { 1747 ret = -ENETDOWN; 1748 goto err_unlock; 1749 } 1750 1751 if (ar->debug.htt_stats.stats_req) { 1752 ret = -EAGAIN; 1753 goto err_unlock; 1754 } 1755 1756 stats_req = kzalloc(sizeof(*stats_req) + ATH12K_HTT_STATS_BUF_SIZE, GFP_KERNEL); 1757 if (!stats_req) { 1758 ret = -ENOMEM; 1759 goto err_unlock; 1760 } 1761 1762 ar->debug.htt_stats.stats_req = stats_req; 1763 stats_req->type = type; 1764 stats_req->cfg_param[0] = ar->debug.htt_stats.cfg_param[0]; 1765 stats_req->cfg_param[1] = ar->debug.htt_stats.cfg_param[1]; 1766 stats_req->cfg_param[2] = ar->debug.htt_stats.cfg_param[2]; 1767 stats_req->cfg_param[3] = ar->debug.htt_stats.cfg_param[3]; 1768 stats_req->override_cfg_param = !!stats_req->cfg_param[0] || 1769 !!stats_req->cfg_param[1] || 1770 !!stats_req->cfg_param[2] || 1771 !!stats_req->cfg_param[3]; 1772 1773 ret = ath12k_debugfs_htt_stats_req(ar); 1774 if (ret < 0) 1775 goto out; 1776 1777 file->private_data = stats_req; 1778 1779 mutex_unlock(&ar->conf_mutex); 1780 1781 return 0; 1782 out: 1783 kfree(stats_req); 1784 ar->debug.htt_stats.stats_req = NULL; 1785 err_unlock: 1786 mutex_unlock(&ar->conf_mutex); 1787 1788 return ret; 1789 } 1790 1791 static int ath12k_release_htt_stats(struct inode *inode, 1792 struct file *file) 1793 { 1794 struct ath12k *ar = inode->i_private; 1795 1796 mutex_lock(&ar->conf_mutex); 1797 kfree(file->private_data); 1798 ar->debug.htt_stats.stats_req = NULL; 1799 mutex_unlock(&ar->conf_mutex); 1800 1801 return 0; 1802 } 1803 1804 static ssize_t ath12k_read_htt_stats(struct file *file, 1805 char __user *user_buf, 1806 size_t count, loff_t *ppos) 1807 { 1808 struct debug_htt_stats_req *stats_req = file->private_data; 1809 char *buf; 1810 u32 length; 1811 1812 buf = stats_req->buf; 1813 length = min_t(u32, stats_req->buf_len, ATH12K_HTT_STATS_BUF_SIZE); 1814 return simple_read_from_buffer(user_buf, count, ppos, buf, length); 1815 } 1816 1817 static const struct file_operations fops_dump_htt_stats = { 1818 .open = ath12k_open_htt_stats, 1819 .release = ath12k_release_htt_stats, 1820 .read = ath12k_read_htt_stats, 1821 .owner = THIS_MODULE, 1822 .llseek = default_llseek, 1823 }; 1824 1825 static ssize_t ath12k_write_htt_stats_reset(struct file *file, 1826 const char __user *user_buf, 1827 size_t count, loff_t *ppos) 1828 { 1829 struct ath12k *ar = file->private_data; 1830 enum ath12k_dbg_htt_ext_stats_type type; 1831 struct htt_ext_stats_cfg_params cfg_params = { 0 }; 1832 u8 param_pos; 1833 int ret; 1834 1835 ret = kstrtou32_from_user(user_buf, count, 0, &type); 1836 if (ret) 1837 return ret; 1838 1839 if (type >= ATH12K_DBG_HTT_NUM_EXT_STATS || 1840 type == ATH12K_DBG_HTT_EXT_STATS_RESET) 1841 return -E2BIG; 1842 1843 mutex_lock(&ar->conf_mutex); 1844 cfg_params.cfg0 = HTT_STAT_DEFAULT_RESET_START_OFFSET; 1845 param_pos = (type >> 5) + 1; 1846 1847 switch (param_pos) { 1848 case ATH12K_HTT_STATS_RESET_PARAM_CFG_32_BYTES: 1849 cfg_params.cfg1 = 1 << (cfg_params.cfg0 + type); 1850 break; 1851 case ATH12K_HTT_STATS_RESET_PARAM_CFG_64_BYTES: 1852 cfg_params.cfg2 = ATH12K_HTT_STATS_RESET_BITMAP32_BIT(cfg_params.cfg0 + 1853 type); 1854 break; 1855 case ATH12K_HTT_STATS_RESET_PARAM_CFG_128_BYTES: 1856 cfg_params.cfg3 = ATH12K_HTT_STATS_RESET_BITMAP64_BIT(cfg_params.cfg0 + 1857 type); 1858 break; 1859 default: 1860 break; 1861 } 1862 1863 ret = ath12k_dp_tx_htt_h2t_ext_stats_req(ar, 1864 ATH12K_DBG_HTT_EXT_STATS_RESET, 1865 &cfg_params, 1866 0ULL); 1867 if (ret) { 1868 ath12k_warn(ar->ab, "failed to send htt stats request: %d\n", ret); 1869 mutex_unlock(&ar->conf_mutex); 1870 return ret; 1871 } 1872 1873 ar->debug.htt_stats.reset = type; 1874 mutex_unlock(&ar->conf_mutex); 1875 1876 return count; 1877 } 1878 1879 static const struct file_operations fops_htt_stats_reset = { 1880 .write = ath12k_write_htt_stats_reset, 1881 .open = simple_open, 1882 .owner = THIS_MODULE, 1883 .llseek = default_llseek, 1884 }; 1885 1886 void ath12k_debugfs_htt_stats_register(struct ath12k *ar) 1887 { 1888 debugfs_create_file("htt_stats_type", 0600, ar->debug.debugfs_pdev, 1889 ar, &fops_htt_stats_type); 1890 debugfs_create_file("htt_stats", 0400, ar->debug.debugfs_pdev, 1891 ar, &fops_dump_htt_stats); 1892 debugfs_create_file("htt_stats_reset", 0200, ar->debug.debugfs_pdev, 1893 ar, &fops_htt_stats_reset); 1894 } 1895