1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: qdf_trace 22 * QCA driver framework (QDF) trace APIs 23 * Trace, logging, and debugging definitions and APIs 24 */ 25 26 /* Include Files */ 27 #include "qdf_str.h" 28 #include <qdf_trace.h> 29 #include <qdf_parse.h> 30 #include <qdf_module.h> 31 #include <qdf_util.h> 32 #include <qdf_mem.h> 33 #include <qdf_list.h> 34 35 /* macro to map qdf trace levels into the bitmask */ 36 #define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level))) 37 38 #include <wlan_logging_sock_svc.h> 39 #include <qdf_module.h> 40 static int qdf_pidx = -1; 41 static bool qdf_log_dump_at_kernel_enable = true; 42 qdf_declare_param(qdf_log_dump_at_kernel_enable, bool); 43 44 /* This value of 0 will disable the timer by default. */ 45 static uint32_t qdf_log_flush_timer_period; 46 qdf_declare_param(qdf_log_flush_timer_period, uint); 47 48 #include "qdf_time.h" 49 #include "qdf_mc_timer.h" 50 #include <host_diag_core_log.h> 51 52 #ifdef CONNECTIVITY_DIAG_EVENT 53 #include <wlan_connectivity_logging.h> 54 #include "i_host_diag_core_event.h" 55 #endif 56 57 #ifdef WLAN_CHIPSET_STATS 58 #include "wlan_cp_stats_chipset_stats.h" 59 #endif 60 /* Global qdf print id */ 61 62 /* Preprocessor definitions and constants */ 63 64 enum qdf_timestamp_unit qdf_log_timestamp_type = QDF_LOG_TIMESTAMP_UNIT; 65 66 #define DP_TRACE_META_DATA_STRLEN 50 67 68 #ifdef TRACE_RECORD 69 /* Static and Global variables */ 70 static spinlock_t ltrace_lock; 71 /* global qdf trace data */ 72 static t_qdf_trace_data g_qdf_trace_data; 73 /* 74 * all the call back functions for dumping MTRACE messages from ring buffer 75 * are stored in qdf_trace_cb_table,these callbacks are initialized during init 76 * only so, we will make a copy of these call back functions and maintain in to 77 * qdf_trace_restore_cb_table. Incase if we make modifications to 78 * qdf_trace_cb_table, we can certainly retrieve all the call back functions 79 * back from Restore Table 80 */ 81 static tp_qdf_trace_cb qdf_trace_cb_table[QDF_MODULE_ID_MAX]; 82 static tp_qdf_trace_cb qdf_trace_restore_cb_table[QDF_MODULE_ID_MAX]; 83 84 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY 85 static qdf_trace_record_t *g_qdf_trace_tbl; 86 #else 87 static qdf_trace_record_t g_qdf_trace_tbl[MAX_QDF_TRACE_RECORDS]; 88 #endif 89 90 #endif 91 92 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE 93 static tp_qdf_state_info_cb qdf_state_info_table[QDF_MODULE_ID_MAX]; 94 #endif 95 96 #ifdef CONFIG_DP_TRACE 97 /* Static and Global variables */ 98 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY 99 static struct qdf_dp_trace_record_s *g_qdf_dp_trace_tbl; 100 #else 101 static struct qdf_dp_trace_record_s 102 g_qdf_dp_trace_tbl[MAX_QDF_DP_TRACE_RECORDS]; 103 #endif 104 static spinlock_t l_dp_trace_lock; 105 106 /* 107 * all the options to configure/control DP trace are 108 * defined in this structure 109 */ 110 static struct s_qdf_dp_trace_data g_qdf_dp_trace_data; 111 /* 112 * all the call back functions for dumping DPTRACE messages from ring buffer 113 * are stored in qdf_dp_trace_cb_table, callbacks are initialized during init 114 */ 115 static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1]; 116 #endif 117 118 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI 119 #define QDF_PARAM_STR_LENGTH 40 120 121 enum qdf_num_module_param { 122 MEM_DEBUG_DISABLED, 123 QDF_DBG_MASK, 124 PREALLOC_DISABLED, 125 QDF_LOG_DUMP_AT_KERNEL_ENABLE, 126 QDF_DBG_ARR, 127 QDF_LOG_FLUSH_TIMER_PERIOD, 128 QDF_PARAM_MAX, 129 }; 130 131 static char qdf_module_param[QDF_PARAM_MAX][QDF_PARAM_STR_LENGTH] = { 132 "mem_debug_disabled", 133 "qdf_dbg_mask", 134 "prealloc_disabled", 135 "qdf_log_dump_at_kernel_enable", 136 "qdf_dbg_arr", 137 "qdf_log_flush_timer_period", 138 }; 139 #endif 140 qdf_snprintf(char * str_buffer,unsigned int size,char * str_format,...)141 int qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...) 142 { 143 va_list args; 144 int i; 145 146 va_start(args, str_format); 147 i = vsnprintf(str_buffer, size, str_format, args); 148 va_end(args); 149 150 return i; 151 } 152 qdf_export_symbol(qdf_snprintf); 153 154 #ifdef QDF_ENABLE_TRACING 155 qdf_trace_msg(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,const char * str_format,...)156 void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 157 const char *str_format, ...) 158 { 159 va_list val; 160 161 va_start(val, str_format); 162 qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val); 163 va_end(val); 164 } 165 qdf_export_symbol(qdf_trace_msg); 166 qdf_vtrace_msg(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,const char * str_format,va_list val)167 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 168 const char *str_format, va_list val) 169 { 170 qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val); 171 } 172 qdf_export_symbol(qdf_vtrace_msg); 173 174 #define ROW_SIZE 16 175 /* Buffer size = data bytes(2 hex chars plus space) + NULL */ 176 #define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1) 177 __qdf_trace_hex_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len,bool print_ascii)178 static void __qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 179 void *data, int buf_len, bool print_ascii) 180 { 181 const u8 *ptr = data; 182 int i = 0; 183 184 if (!qdf_print_is_verbose_enabled(qdf_pidx, module, level)) 185 return; 186 187 while (buf_len > 0) { 188 unsigned char linebuf[BUFFER_SIZE] = {0}; 189 int linelen = min(buf_len, ROW_SIZE); 190 191 buf_len -= ROW_SIZE; 192 193 hex_dump_to_buffer(ptr, linelen, ROW_SIZE, 1, 194 linebuf, sizeof(linebuf), print_ascii); 195 196 qdf_trace_msg(module, level, "%.8x: %s", i, linebuf); 197 ptr += ROW_SIZE; 198 i += ROW_SIZE; 199 } 200 } 201 qdf_trace_hex_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len)202 void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 203 void *data, int buf_len) 204 { 205 __qdf_trace_hex_dump(module, level, data, buf_len, false); 206 } 207 208 qdf_export_symbol(qdf_trace_hex_dump); 209 qdf_trace_hex_ascii_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len)210 void qdf_trace_hex_ascii_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 211 void *data, int buf_len) 212 { 213 __qdf_trace_hex_dump(module, level, data, buf_len, true); 214 } 215 216 qdf_export_symbol(qdf_trace_hex_ascii_dump); 217 218 #endif 219 220 #ifdef TRACE_RECORD 221 222 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY allocate_g_qdf_trace_tbl_buffer(void)223 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void) 224 { 225 g_qdf_trace_tbl = qdf_mem_valloc(MAX_QDF_TRACE_RECORDS * 226 sizeof(*g_qdf_trace_tbl)); 227 QDF_BUG(g_qdf_trace_tbl); 228 return g_qdf_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM; 229 } 230 free_g_qdf_trace_tbl_buffer(void)231 static inline void free_g_qdf_trace_tbl_buffer(void) 232 { 233 qdf_mem_vfree(g_qdf_trace_tbl); 234 g_qdf_trace_tbl = NULL; 235 } 236 #else allocate_g_qdf_trace_tbl_buffer(void)237 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void) 238 { 239 return QDF_STATUS_SUCCESS; 240 } 241 free_g_qdf_trace_tbl_buffer(void)242 static inline void free_g_qdf_trace_tbl_buffer(void) 243 { } 244 #endif qdf_trace_enable(uint32_t bitmask_of_module_id,uint8_t enable)245 void qdf_trace_enable(uint32_t bitmask_of_module_id, uint8_t enable) 246 { 247 int i; 248 249 if (bitmask_of_module_id) { 250 for (i = 0; i < QDF_MODULE_ID_MAX; i++) { 251 if (((bitmask_of_module_id >> i) & 1)) { 252 if (enable) { 253 if (NULL != 254 qdf_trace_restore_cb_table[i]) { 255 qdf_trace_cb_table[i] = 256 qdf_trace_restore_cb_table[i]; 257 } 258 } else { 259 qdf_trace_restore_cb_table[i] = 260 qdf_trace_cb_table[i]; 261 qdf_trace_cb_table[i] = NULL; 262 } 263 } 264 } 265 } else { 266 if (enable) { 267 for (i = 0; i < QDF_MODULE_ID_MAX; i++) { 268 if (qdf_trace_restore_cb_table[i]) { 269 qdf_trace_cb_table[i] = 270 qdf_trace_restore_cb_table[i]; 271 } 272 } 273 } else { 274 for (i = 0; i < QDF_MODULE_ID_MAX; i++) { 275 qdf_trace_restore_cb_table[i] = 276 qdf_trace_cb_table[i]; 277 qdf_trace_cb_table[i] = NULL; 278 } 279 } 280 } 281 } 282 qdf_export_symbol(qdf_trace_enable); 283 qdf_trace_init(void)284 void qdf_trace_init(void) 285 { 286 uint8_t i; 287 288 if (allocate_g_qdf_trace_tbl_buffer() != QDF_STATUS_SUCCESS) 289 return; 290 g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR; 291 g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR; 292 g_qdf_trace_data.num = 0; 293 g_qdf_trace_data.enable = true; 294 g_qdf_trace_data.dump_count = DEFAULT_QDF_TRACE_DUMP_COUNT; 295 g_qdf_trace_data.num_since_last_dump = 0; 296 297 for (i = 0; i < QDF_MODULE_ID_MAX; i++) { 298 qdf_trace_cb_table[i] = NULL; 299 qdf_trace_restore_cb_table[i] = NULL; 300 } 301 } 302 qdf_export_symbol(qdf_trace_init); 303 qdf_trace_deinit(void)304 void qdf_trace_deinit(void) 305 { 306 g_qdf_trace_data.enable = false; 307 g_qdf_trace_data.num = 0; 308 g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR; 309 g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR; 310 311 free_g_qdf_trace_tbl_buffer(); 312 } 313 314 qdf_export_symbol(qdf_trace_deinit); 315 qdf_trace(uint8_t module,uint16_t code,uint16_t session,uint32_t data)316 void qdf_trace(uint8_t module, uint16_t code, uint16_t session, uint32_t data) 317 { 318 tp_qdf_trace_record rec = NULL; 319 unsigned long flags; 320 char time[18]; 321 322 if (!g_qdf_trace_data.enable) 323 return; 324 325 /* if module is not registered, don't record for that module */ 326 if (!qdf_trace_cb_table[module]) 327 return; 328 329 qdf_get_time_of_the_day_in_hr_min_sec_usec(time, sizeof(time)); 330 /* Acquire the lock so that only one thread at a time can fill the ring 331 * buffer 332 */ 333 spin_lock_irqsave(<race_lock, flags); 334 335 g_qdf_trace_data.num++; 336 337 if (g_qdf_trace_data.num > MAX_QDF_TRACE_RECORDS) 338 g_qdf_trace_data.num = MAX_QDF_TRACE_RECORDS; 339 340 if (INVALID_QDF_TRACE_ADDR == g_qdf_trace_data.head) { 341 /* first record */ 342 g_qdf_trace_data.head = 0; 343 g_qdf_trace_data.tail = 0; 344 } else { 345 /* queue is not empty */ 346 uint32_t tail = g_qdf_trace_data.tail + 1; 347 348 if (MAX_QDF_TRACE_RECORDS == tail) 349 tail = 0; 350 351 if (g_qdf_trace_data.head == tail) { 352 /* full */ 353 if (MAX_QDF_TRACE_RECORDS == ++g_qdf_trace_data.head) 354 g_qdf_trace_data.head = 0; 355 } 356 g_qdf_trace_data.tail = tail; 357 } 358 359 rec = &g_qdf_trace_tbl[g_qdf_trace_data.tail]; 360 rec->code = code; 361 rec->session = session; 362 rec->data = data; 363 rec->qtime = qdf_get_log_timestamp(); 364 scnprintf(rec->time, sizeof(rec->time), "%s", time); 365 rec->module = module; 366 rec->pid = (in_interrupt() ? 0 : current->pid); 367 g_qdf_trace_data.num_since_last_dump++; 368 spin_unlock_irqrestore(<race_lock, flags); 369 } 370 qdf_export_symbol(qdf_trace); 371 372 #ifdef ENABLE_MTRACE_LOG qdf_mtrace_log(QDF_MODULE_ID src_module,QDF_MODULE_ID dst_module,uint16_t message_id,uint8_t vdev_id)373 void qdf_mtrace_log(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module, 374 uint16_t message_id, uint8_t vdev_id) 375 { 376 uint32_t trace_log, payload; 377 static uint16_t counter; 378 379 trace_log = (src_module << 23) | (dst_module << 15) | message_id; 380 payload = (vdev_id << 16) | counter++; 381 382 QDF_TRACE(src_module, QDF_TRACE_LEVEL_TRACE, "%x %x", 383 trace_log, payload); 384 } 385 386 qdf_export_symbol(qdf_mtrace_log); 387 #endif 388 qdf_mtrace(QDF_MODULE_ID src_module,QDF_MODULE_ID dst_module,uint16_t message_id,uint8_t vdev_id,uint32_t data)389 void qdf_mtrace(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module, 390 uint16_t message_id, uint8_t vdev_id, uint32_t data) 391 { 392 qdf_trace(src_module, message_id, vdev_id, data); 393 qdf_mtrace_log(src_module, dst_module, message_id, vdev_id); 394 } 395 396 qdf_export_symbol(qdf_mtrace); 397 qdf_trace_spin_lock_init(void)398 QDF_STATUS qdf_trace_spin_lock_init(void) 399 { 400 spin_lock_init(<race_lock); 401 402 return QDF_STATUS_SUCCESS; 403 } 404 qdf_export_symbol(qdf_trace_spin_lock_init); 405 qdf_trace_register(QDF_MODULE_ID module_id,tp_qdf_trace_cb qdf_trace_callback)406 void qdf_trace_register(QDF_MODULE_ID module_id, 407 tp_qdf_trace_cb qdf_trace_callback) 408 { 409 qdf_trace_cb_table[module_id] = qdf_trace_callback; 410 } 411 qdf_export_symbol(qdf_trace_register); 412 qdf_trace_dump_all(void * p_mac,uint8_t code,uint8_t session,uint32_t count,uint32_t bitmask_of_module)413 void qdf_trace_dump_all(void *p_mac, uint8_t code, uint8_t session, 414 uint32_t count, uint32_t bitmask_of_module) 415 { 416 qdf_trace_record_t p_record; 417 int32_t i, tail; 418 419 if (!g_qdf_trace_data.enable) { 420 QDF_TRACE(QDF_MODULE_ID_SYS, 421 QDF_TRACE_LEVEL_ERROR, "Tracing Disabled"); 422 return; 423 } 424 425 QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO, 426 "DPT: Total Records: %d, Head: %d, Tail: %d", 427 g_qdf_trace_data.num, g_qdf_trace_data.head, 428 g_qdf_trace_data.tail); 429 430 /* acquire the lock so that only one thread at a time can read 431 * the ring buffer 432 */ 433 spin_lock(<race_lock); 434 435 if (g_qdf_trace_data.head != INVALID_QDF_TRACE_ADDR) { 436 i = g_qdf_trace_data.head; 437 tail = g_qdf_trace_data.tail; 438 439 if (count) { 440 if (count > g_qdf_trace_data.num) 441 count = g_qdf_trace_data.num; 442 if (tail >= (count - 1)) 443 i = tail - count + 1; 444 else if (count != MAX_QDF_TRACE_RECORDS) 445 i = MAX_QDF_TRACE_RECORDS - ((count - 1) - 446 tail); 447 } 448 449 p_record = g_qdf_trace_tbl[i]; 450 /* right now we are not using num_since_last_dump member but 451 * in future we might re-visit and use this member to track 452 * how many latest messages got added while we were dumping 453 * from ring buffer 454 */ 455 g_qdf_trace_data.num_since_last_dump = 0; 456 spin_unlock(<race_lock); 457 for (;; ) { 458 if ((code == 0 || (code == p_record.code)) && 459 (qdf_trace_cb_table[p_record.module])) { 460 if (0 == bitmask_of_module) { 461 qdf_trace_cb_table[p_record. 462 module] (p_mac, 463 &p_record, 464 (uint16_t) 465 i); 466 } else { 467 if (bitmask_of_module & 468 (1 << p_record.module)) { 469 qdf_trace_cb_table[p_record. 470 module] 471 (p_mac, &p_record, 472 (uint16_t) i); 473 } 474 } 475 } 476 477 if (i == tail) 478 break; 479 i += 1; 480 481 spin_lock(<race_lock); 482 if (MAX_QDF_TRACE_RECORDS == i) { 483 i = 0; 484 p_record = g_qdf_trace_tbl[0]; 485 } else { 486 p_record = g_qdf_trace_tbl[i]; 487 } 488 spin_unlock(<race_lock); 489 } 490 } else { 491 spin_unlock(<race_lock); 492 } 493 } 494 qdf_export_symbol(qdf_trace_dump_all); 495 #endif 496 497 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE qdf_register_debugcb_init(void)498 void qdf_register_debugcb_init(void) 499 { 500 uint8_t i; 501 502 for (i = 0; i < QDF_MODULE_ID_MAX; i++) 503 qdf_state_info_table[i] = NULL; 504 } 505 qdf_export_symbol(qdf_register_debugcb_init); 506 qdf_register_debug_callback(QDF_MODULE_ID module_id,tp_qdf_state_info_cb qdf_state_infocb)507 void qdf_register_debug_callback(QDF_MODULE_ID module_id, 508 tp_qdf_state_info_cb qdf_state_infocb) 509 { 510 qdf_state_info_table[module_id] = qdf_state_infocb; 511 } 512 qdf_export_symbol(qdf_register_debug_callback); 513 qdf_state_info_dump_all(char * buf,uint16_t size,uint16_t * driver_dump_size)514 QDF_STATUS qdf_state_info_dump_all(char *buf, uint16_t size, 515 uint16_t *driver_dump_size) 516 { 517 uint8_t module, ret = QDF_STATUS_SUCCESS; 518 uint16_t buf_len = size; 519 char *buf_ptr = buf; 520 521 for (module = 0; module < QDF_MODULE_ID_MAX; module++) { 522 if (qdf_state_info_table[module]) { 523 qdf_state_info_table[module](&buf_ptr, &buf_len); 524 if (!buf_len) { 525 ret = QDF_STATUS_E_NOMEM; 526 break; 527 } 528 } 529 } 530 531 *driver_dump_size = size - buf_len; 532 return ret; 533 } 534 qdf_export_symbol(qdf_state_info_dump_all); 535 #endif 536 537 #ifdef CONFIG_DP_TRACE 538 539 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY allocate_g_qdf_dp_trace_tbl_buffer(void)540 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void) 541 { 542 g_qdf_dp_trace_tbl = qdf_mem_valloc(MAX_QDF_DP_TRACE_RECORDS * 543 sizeof(*g_qdf_dp_trace_tbl)); 544 QDF_BUG(g_qdf_dp_trace_tbl); 545 return g_qdf_dp_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM; 546 } 547 free_g_qdf_dp_trace_tbl_buffer(void)548 static inline void free_g_qdf_dp_trace_tbl_buffer(void) 549 { 550 qdf_mem_vfree(g_qdf_dp_trace_tbl); 551 g_qdf_dp_trace_tbl = NULL; 552 } 553 #else allocate_g_qdf_dp_trace_tbl_buffer(void)554 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void) 555 { 556 return QDF_STATUS_SUCCESS; 557 } 558 free_g_qdf_dp_trace_tbl_buffer(void)559 static inline void free_g_qdf_dp_trace_tbl_buffer(void) 560 { } 561 #endif 562 563 #define QDF_DP_TRACE_PREPEND_STR_SIZE 100 564 /* 565 * one dp trace record can't be greater than 300 bytes. 566 * Max Size will be QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121). 567 * Always make sure to change this QDF_DP_TRACE_MAX_RECORD_SIZE 568 * value accordingly whenever above two mentioned MACRO value changes. 569 */ 570 #define QDF_DP_TRACE_MAX_RECORD_SIZE 300 571 qdf_dp_unused(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)572 static void qdf_dp_unused(struct qdf_dp_trace_record_s *record, 573 uint16_t index, uint8_t pdev_id, uint8_t info) 574 { 575 qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated", 576 __func__); 577 } 578 qdf_dp_trace_init(bool live_mode_config,uint8_t thresh,uint16_t time_limit,uint8_t verbosity,uint32_t proto_bitmap)579 void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh, 580 uint16_t time_limit, uint8_t verbosity, 581 uint32_t proto_bitmap) 582 { 583 uint8_t i; 584 585 if (allocate_g_qdf_dp_trace_tbl_buffer() != QDF_STATUS_SUCCESS) { 586 QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, 587 "Failed!!! DP Trace buffer allocation"); 588 return; 589 } 590 qdf_dp_trace_spin_lock_init(); 591 qdf_dp_trace_clear_buffer(); 592 g_qdf_dp_trace_data.enable = true; 593 g_qdf_dp_trace_data.no_of_record = 1; 594 595 g_qdf_dp_trace_data.live_mode_config = live_mode_config; 596 g_qdf_dp_trace_data.live_mode = live_mode_config; 597 g_qdf_dp_trace_data.high_tput_thresh = thresh; 598 g_qdf_dp_trace_data.thresh_time_limit = time_limit; 599 g_qdf_dp_trace_data.proto_bitmap = proto_bitmap; 600 g_qdf_dp_trace_data.verbosity = verbosity; 601 g_qdf_dp_trace_data.ini_conf_verbosity = verbosity; 602 603 for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++) 604 qdf_dp_trace_cb_table[i] = qdf_dp_display_record; 605 606 qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_TX_PACKET_RECORD] = 607 qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_RX_PACKET_RECORD] = 608 qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_PACKET_RECORD] = 609 qdf_dp_trace_cb_table[QDF_DP_TRACE_RX_PACKET_RECORD] = 610 qdf_dp_trace_cb_table[QDF_DP_TRACE_DROP_PACKET_RECORD] = 611 qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD] = 612 qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD] = 613 qdf_dp_display_data_pkt_record; 614 615 qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD] = 616 qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] = 617 qdf_dp_trace_cb_table[QDF_DP_TRACE_FREE_PACKET_PTR_RECORD] = 618 qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD] = 619 qdf_dp_display_ptr_record; 620 qdf_dp_trace_cb_table[QDF_DP_TRACE_EAPOL_PACKET_RECORD] = 621 qdf_dp_trace_cb_table[QDF_DP_TRACE_DHCP_PACKET_RECORD] = 622 qdf_dp_trace_cb_table[QDF_DP_TRACE_ARP_PACKET_RECORD] = 623 qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMP_PACKET_RECORD] = 624 qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMPv6_PACKET_RECORD] = 625 qdf_dp_display_proto_pkt; 626 qdf_dp_trace_cb_table[QDF_DP_TRACE_MGMT_PACKET_RECORD] = 627 qdf_dp_display_mgmt_pkt; 628 qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_CREDIT_RECORD] = 629 qdf_dp_display_credit_record; 630 qdf_dp_trace_cb_table[QDF_DP_TRACE_EVENT_RECORD] = 631 qdf_dp_display_event_record; 632 633 qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX] = qdf_dp_unused; 634 } 635 qdf_export_symbol(qdf_dp_trace_init); 636 qdf_dp_trace_deinit(void)637 void qdf_dp_trace_deinit(void) 638 { 639 if (!g_qdf_dp_trace_data.enable) 640 return; 641 spin_lock_bh(&l_dp_trace_lock); 642 g_qdf_dp_trace_data.enable = false; 643 g_qdf_dp_trace_data.no_of_record = 0; 644 spin_unlock_bh(&l_dp_trace_lock); 645 646 free_g_qdf_dp_trace_tbl_buffer(); 647 } 648 qdf_dp_trace_set_value(uint32_t proto_bitmap,uint8_t no_of_record,uint8_t verbosity)649 void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_record, 650 uint8_t verbosity) 651 { 652 g_qdf_dp_trace_data.proto_bitmap = proto_bitmap; 653 g_qdf_dp_trace_data.no_of_record = no_of_record; 654 g_qdf_dp_trace_data.verbosity = verbosity; 655 g_qdf_dp_trace_data.dynamic_verbosity_modify = true; 656 } 657 qdf_export_symbol(qdf_dp_trace_set_value); 658 qdf_dp_trace_set_verbosity(uint32_t val)659 void qdf_dp_trace_set_verbosity(uint32_t val) 660 { 661 g_qdf_dp_trace_data.verbosity = val; 662 } 663 qdf_export_symbol(qdf_dp_trace_set_verbosity); 664 665 /** 666 * qdf_dp_get_verbosity() - get verbosity value 667 * 668 * Return: int 669 */ qdf_dp_get_verbosity(void)670 uint8_t qdf_dp_get_verbosity(void) 671 { 672 return g_qdf_dp_trace_data.verbosity; 673 } 674 qdf_export_symbol(qdf_dp_get_verbosity); 675 qdf_dp_set_proto_bitmap(uint32_t val)676 void qdf_dp_set_proto_bitmap(uint32_t val) 677 { 678 g_qdf_dp_trace_data.proto_bitmap = val; 679 } 680 qdf_export_symbol(qdf_dp_set_proto_bitmap); 681 qdf_dp_set_proto_event_bitmap(uint32_t value)682 void qdf_dp_set_proto_event_bitmap(uint32_t value) 683 { 684 g_qdf_dp_trace_data.proto_event_bitmap = value; 685 } 686 687 qdf_export_symbol(qdf_dp_set_proto_event_bitmap); 688 qdf_dp_get_proto_event_bitmap(void)689 static uint32_t qdf_dp_get_proto_event_bitmap(void) 690 { 691 return g_qdf_dp_trace_data.proto_event_bitmap; 692 } 693 qdf_dp_set_no_of_record(uint32_t val)694 void qdf_dp_set_no_of_record(uint32_t val) 695 { 696 g_qdf_dp_trace_data.no_of_record = val; 697 } 698 qdf_export_symbol(qdf_dp_set_no_of_record); 699 qdf_dp_get_no_of_record(void)700 uint8_t qdf_dp_get_no_of_record(void) 701 { 702 return g_qdf_dp_trace_data.no_of_record; 703 } 704 qdf_export_symbol(qdf_dp_get_no_of_record); 705 706 707 /** 708 * qdf_dp_trace_verbosity_check() - check whether verbosity level is enabled 709 * @code: defines the event 710 * 711 * In High verbosity all codes are logged. 712 * For Med/Low and Default case code which has 713 * less value than corresponding verbosity codes 714 * are logged. 715 * 716 * Return: true or false depends on whether tracing enabled 717 */ qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code)718 static bool qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code) 719 { 720 switch (g_qdf_dp_trace_data.verbosity) { 721 case QDF_DP_TRACE_VERBOSITY_HIGH: 722 return true; 723 case QDF_DP_TRACE_VERBOSITY_MEDIUM: 724 if (code <= QDF_DP_TRACE_MED_VERBOSITY) 725 return true; 726 return false; 727 case QDF_DP_TRACE_VERBOSITY_LOW: 728 if (code <= QDF_DP_TRACE_LOW_VERBOSITY) 729 return true; 730 return false; 731 case QDF_DP_TRACE_VERBOSITY_ULTRA_LOW: 732 if (code <= QDF_DP_TRACE_ULTRA_LOW_VERBOSITY) 733 return true; 734 return false; 735 case QDF_DP_TRACE_VERBOSITY_BASE: 736 if (code <= QDF_DP_TRACE_BASE_VERBOSITY) 737 return true; 738 return false; 739 default: 740 return false; 741 } 742 } 743 qdf_dp_get_proto_bitmap(void)744 uint32_t qdf_dp_get_proto_bitmap(void) 745 { 746 if (g_qdf_dp_trace_data.enable) 747 return g_qdf_dp_trace_data.proto_bitmap; 748 else 749 return 0; 750 } 751 qdf_dp_trace_set_track(qdf_nbuf_t nbuf,enum qdf_proto_dir dir)752 void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir) 753 { 754 uint32_t count = 0; 755 756 if (!g_qdf_dp_trace_data.enable) 757 return; 758 759 spin_lock_bh(&l_dp_trace_lock); 760 if (QDF_TX == dir) 761 count = ++g_qdf_dp_trace_data.tx_count; 762 else if (QDF_RX == dir) 763 count = ++g_qdf_dp_trace_data.rx_count; 764 765 if ((g_qdf_dp_trace_data.no_of_record != 0) && 766 (count % g_qdf_dp_trace_data.no_of_record == 0)) { 767 if (QDF_TX == dir) 768 QDF_NBUF_CB_TX_DP_TRACE(nbuf) = 1; 769 else if (QDF_RX == dir) 770 QDF_NBUF_CB_RX_DP_TRACE(nbuf) = 1; 771 } 772 spin_unlock_bh(&l_dp_trace_lock); 773 } 774 qdf_export_symbol(qdf_dp_trace_set_track); 775 776 /* Number of bytes to be grouped together while printing DP-Trace data */ 777 #define QDF_DUMP_DP_GROUP_SIZE 6 778 779 /** 780 * dump_dp_hex_trace() - Display the data in buffer 781 * @prepend_str: string to prepend the hexdump with. 782 * @inbuf: buffer which contains data to be displayed 783 * @inbuf_len: defines the size of the data to be displayed 784 * 785 * Return: None 786 */ 787 static void dump_dp_hex_trace(char * prepend_str,uint8_t * inbuf,uint8_t inbuf_len)788 dump_dp_hex_trace(char *prepend_str, uint8_t *inbuf, uint8_t inbuf_len) 789 { 790 unsigned char outbuf[BUFFER_SIZE]; 791 const uint8_t *inbuf_ptr = inbuf; 792 char *outbuf_ptr = outbuf; 793 int outbytes_written = 0; 794 795 qdf_mem_zero(outbuf, sizeof(outbuf)); 796 do { 797 outbytes_written += scnprintf(outbuf_ptr, 798 BUFFER_SIZE - outbytes_written, 799 "%02x", *inbuf_ptr); 800 outbuf_ptr = outbuf + outbytes_written; 801 802 if ((inbuf_ptr - inbuf) && 803 (inbuf_ptr - inbuf + 1) % QDF_DUMP_DP_GROUP_SIZE == 0) { 804 outbytes_written += scnprintf(outbuf_ptr, 805 BUFFER_SIZE - outbytes_written, 806 " "); 807 outbuf_ptr = outbuf + outbytes_written; 808 } 809 inbuf_ptr++; 810 } while (inbuf_ptr < (inbuf + inbuf_len)); 811 DPTRACE_PRINT("%s %s", prepend_str, outbuf); 812 } 813 814 /** 815 * qdf_dp_code_to_string() - convert dptrace code to string 816 * @code: dptrace code 817 * 818 * Return: string version of code 819 */ 820 static qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code)821 const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code) 822 { 823 switch (code) { 824 case QDF_DP_TRACE_DROP_PACKET_RECORD: 825 return "DROP:"; 826 case QDF_DP_TRACE_EAPOL_PACKET_RECORD: 827 return "EAPOL:"; 828 case QDF_DP_TRACE_DHCP_PACKET_RECORD: 829 return "DHCP:"; 830 case QDF_DP_TRACE_ARP_PACKET_RECORD: 831 return "ARP:"; 832 case QDF_DP_TRACE_ICMP_PACKET_RECORD: 833 return "ICMP:"; 834 case QDF_DP_TRACE_ICMPv6_PACKET_RECORD: 835 return "ICMPv6:"; 836 case QDF_DP_TRACE_MGMT_PACKET_RECORD: 837 return "MGMT:"; 838 case QDF_DP_TRACE_TX_CREDIT_RECORD: 839 return "CREDIT:"; 840 case QDF_DP_TRACE_EVENT_RECORD: 841 return "EVENT:"; 842 case QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD: 843 return "HDD: TX: PTR:"; 844 case QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD: 845 return "LI_DP: TX: PTR:"; 846 case QDF_DP_TRACE_HDD_TX_PACKET_RECORD: 847 return "HDD: TX: DATA:"; 848 case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD: 849 case QDF_DP_TRACE_TX_PACKET_RECORD: 850 return "TX:"; 851 case QDF_DP_TRACE_CE_PACKET_PTR_RECORD: 852 return "CE: TX: PTR:"; 853 case QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD: 854 return "CE: TX: FAST: PTR:"; 855 case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD: 856 return "CE: TX: FAST: ERR:"; 857 case QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD: 858 case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD: 859 return "FREE: TX: PTR:"; 860 case QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD: 861 return "HTT: RX: PTR:"; 862 case QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD: 863 return "HTT: RX: OF: PTR:"; 864 case QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD: 865 return "HDD: RX: PTR:"; 866 case QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD: 867 return "LI_DP: RX: PTR:"; 868 case QDF_DP_TRACE_HDD_RX_PACKET_RECORD: 869 return "HDD: RX: DATA:"; 870 case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD: 871 return "LI_DP_NULL: RX: DATA:"; 872 case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD: 873 case QDF_DP_TRACE_RX_PACKET_RECORD: 874 return "RX:"; 875 case QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD: 876 return "TXRX: TX: Q: PTR:"; 877 case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD: 878 return "TXRX: TX: PTR:"; 879 case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD: 880 return "TXRX: TX: FAST: PTR:"; 881 case QDF_DP_TRACE_HTT_PACKET_PTR_RECORD: 882 return "HTT: TX: PTR:"; 883 case QDF_DP_TRACE_HTC_PACKET_PTR_RECORD: 884 return "HTC: TX: PTR:"; 885 case QDF_DP_TRACE_HIF_PACKET_PTR_RECORD: 886 return "HIF: TX: PTR:"; 887 case QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD: 888 return "TXRX: RX: PTR:"; 889 case QDF_DP_TRACE_HDD_TX_TIMEOUT: 890 return "HDD: STA: TO:"; 891 case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: 892 return "HDD: SAP: TO:"; 893 default: 894 return "Invalid"; 895 } 896 } 897 898 /** 899 * qdf_dp_dir_to_str() - convert direction to string 900 * @dir: direction 901 * 902 * Return: string version of direction 903 */ qdf_dp_dir_to_str(enum qdf_proto_dir dir)904 static const char *qdf_dp_dir_to_str(enum qdf_proto_dir dir) 905 { 906 switch (dir) { 907 case QDF_TX: 908 return " --> "; 909 case QDF_RX: 910 return " <-- "; 911 default: 912 return "invalid"; 913 } 914 } 915 qdf_dp_credit_source_to_str(enum QDF_CREDIT_UPDATE_SOURCE source)916 static const char *qdf_dp_credit_source_to_str( 917 enum QDF_CREDIT_UPDATE_SOURCE source) 918 { 919 switch (source) { 920 case QDF_TX_SCHED: 921 return "TX SCHED"; 922 case QDF_TX_COMP: 923 return "TX COMP"; 924 case QDF_TX_CREDIT_UPDATE: 925 return "CREDIT UP"; 926 case QDF_TX_HTT_MSG: 927 return "HTT TX MSG"; 928 case QDF_HTT_ATTACH: 929 return "HTT ATTACH"; 930 default: 931 return "invalid"; 932 } 933 } 934 qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op)935 static const char *qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op) 936 { 937 switch (op) { 938 case QDF_CREDIT_INC: 939 return "+"; 940 case QDF_CREDIT_DEC: 941 return "-"; 942 case QDF_CREDIT_ABS: 943 return "ABS"; 944 default: 945 return "invalid"; 946 } 947 } 948 949 /** 950 * qdf_dp_type_to_str() - convert packet type to string 951 * @type: type 952 * 953 * Return: string version of packet type 954 */ qdf_dp_type_to_str(enum qdf_proto_type type)955 static const char *qdf_dp_type_to_str(enum qdf_proto_type type) 956 { 957 switch (type) { 958 case QDF_PROTO_TYPE_DHCP: 959 return "DHCP"; 960 case QDF_PROTO_TYPE_EAPOL: 961 return "EAPOL"; 962 case QDF_PROTO_TYPE_ARP: 963 return "ARP"; 964 case QDF_PROTO_TYPE_ICMP: 965 return "ICMP"; 966 case QDF_PROTO_TYPE_ICMPv6: 967 return "ICMPv6"; 968 case QDF_PROTO_TYPE_MGMT: 969 return "MGMT"; 970 case QDF_PROTO_TYPE_EVENT: 971 return "EVENT"; 972 default: 973 return "invalid"; 974 } 975 } 976 977 /** 978 * qdf_dp_subtype_to_str() - convert packet subtype to string 979 * @subtype: subtype 980 * 981 * Return: string version of packet subtype 982 */ qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)983 static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype) 984 { 985 switch (subtype) { 986 case QDF_PROTO_EAPOL_M1: 987 return "M1"; 988 case QDF_PROTO_EAPOL_M2: 989 return "M2"; 990 case QDF_PROTO_EAPOL_M3: 991 return "M3"; 992 case QDF_PROTO_EAPOL_M4: 993 return "M4"; 994 case QDF_PROTO_DHCP_DISCOVER: 995 return "DISC"; 996 case QDF_PROTO_DHCP_REQUEST: 997 return "REQ"; 998 case QDF_PROTO_DHCP_OFFER: 999 return "OFF"; 1000 case QDF_PROTO_DHCP_ACK: 1001 return "ACK"; 1002 case QDF_PROTO_DHCP_NACK: 1003 return "NACK"; 1004 case QDF_PROTO_DHCP_RELEASE: 1005 return "REL"; 1006 case QDF_PROTO_DHCP_INFORM: 1007 return "INFORM"; 1008 case QDF_PROTO_DHCP_DECLINE: 1009 return "DECL"; 1010 case QDF_PROTO_ARP_REQ: 1011 case QDF_PROTO_ICMP_REQ: 1012 case QDF_PROTO_ICMPV6_REQ: 1013 return "REQ"; 1014 case QDF_PROTO_ARP_RES: 1015 case QDF_PROTO_ICMP_RES: 1016 case QDF_PROTO_ICMPV6_RES: 1017 return "RSP"; 1018 case QDF_PROTO_ICMPV6_RS: 1019 return "RS"; 1020 case QDF_PROTO_ICMPV6_RA: 1021 return "RA"; 1022 case QDF_PROTO_ICMPV6_NS: 1023 return "NS"; 1024 case QDF_PROTO_ICMPV6_NA: 1025 return "NA"; 1026 case QDF_PROTO_MGMT_ASSOC: 1027 return "ASSOC"; 1028 case QDF_PROTO_MGMT_DISASSOC: 1029 return "DISASSOC"; 1030 case QDF_PROTO_MGMT_AUTH: 1031 return "AUTH"; 1032 case QDF_PROTO_MGMT_DEAUTH: 1033 return "DEAUTH"; 1034 case QDF_ROAM_SYNCH: 1035 return "ROAM SYNCH"; 1036 case QDF_ROAM_COMPLETE: 1037 return "ROAM COMP"; 1038 case QDF_ROAM_EVENTID: 1039 return "ROAM EVENTID"; 1040 case QDF_PROTO_EAP_REQUEST: 1041 return "EAP REQ"; 1042 case QDF_PROTO_EAP_RESPONSE: 1043 return "EAP RSP"; 1044 case QDF_PROTO_EAP_SUCCESS: 1045 return "EAP SUC"; 1046 case QDF_PROTO_EAP_FAILURE: 1047 return "EAP FAIL"; 1048 case QDF_PROTO_EAP_INITIATE: 1049 return "EAP INIT"; 1050 case QDF_PROTO_EAP_FINISH: 1051 return "EAP FINISH"; 1052 case QDF_PROTO_EAPOL_START: 1053 return "START"; 1054 case QDF_PROTO_EAPOL_LOGOFF: 1055 return "LOGOFF"; 1056 case QDF_PROTO_EAPOL_ASF: 1057 return "ASF"; 1058 case QDF_PROTO_EAP_REQ_ID: 1059 return "EAP REQ ID"; 1060 case QDF_PROTO_EAP_RSP_ID: 1061 return "EAP RSP ID"; 1062 case QDF_PROTO_EAP_M1: 1063 return "EAP M1"; 1064 case QDF_PROTO_EAP_M2: 1065 return "EAP M2"; 1066 case QDF_PROTO_EAP_M3: 1067 return "EAP M3"; 1068 case QDF_PROTO_EAP_M4: 1069 return "EAP M4"; 1070 case QDF_PROTO_EAP_M5: 1071 return "EAP M5"; 1072 case QDF_PROTO_EAP_M6: 1073 return "EAP M6"; 1074 case QDF_PROTO_EAP_M7: 1075 return "EAP M7"; 1076 case QDF_PROTO_EAP_M8: 1077 return "EAP M8"; 1078 case QDF_PROTO_EAP_WSC_START: 1079 return "EAP WSC START"; 1080 case QDF_PROTO_EAP_WSC_DONE: 1081 return "EAP WSC DONE"; 1082 case QDF_PROTO_EAP_WSC_ACK: 1083 return "EAP WSC ACK"; 1084 case QDF_PROTO_EAP_WSC_NACK: 1085 return "EAP WSC NACK"; 1086 case QDF_PROTO_EAP_WSC_FRAG_ACK: 1087 return "EAP WSC FRAG ACK"; 1088 default: 1089 return "invalid"; 1090 } 1091 } 1092 1093 /** 1094 * qdf_dp_enable_check() - check if dptrace, TX/RX tracing is enabled 1095 * @nbuf: nbuf 1096 * @code: dptrace code 1097 * @dir: TX or RX direction 1098 * 1099 * Return: true/false 1100 */ qdf_dp_enable_check(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,enum qdf_proto_dir dir)1101 static bool qdf_dp_enable_check(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, 1102 enum qdf_proto_dir dir) 1103 { 1104 /* Return when Dp trace is not enabled */ 1105 if (!g_qdf_dp_trace_data.enable) 1106 return false; 1107 1108 if (qdf_dp_trace_verbosity_check(code) == false) 1109 return false; 1110 1111 if (nbuf && (dir == QDF_TX && ((QDF_NBUF_CB_TX_DP_TRACE(nbuf) == 0) || 1112 (QDF_NBUF_CB_TX_PACKET_TRACK(nbuf) != 1113 QDF_NBUF_TX_PKT_DATA_TRACK)))) 1114 return false; 1115 1116 if (nbuf && (dir == QDF_RX && (QDF_NBUF_CB_RX_DP_TRACE(nbuf) == 0))) 1117 return false; 1118 1119 /* 1120 * Special packets called with NULL nbuf and this API is expected to 1121 * return true 1122 */ 1123 return true; 1124 } 1125 1126 /** 1127 * qdf_dp_trace_fill_meta_str() - fill up a common meta string 1128 * @prepend_str: pointer to string 1129 * @size: size of prepend_str 1130 * @rec_index: index of record 1131 * @info: info related to the record 1132 * @record: pointer to the record 1133 * 1134 * Return: ret value from scnprintf 1135 */ 1136 static inline qdf_dp_trace_fill_meta_str(char * prepend_str,int size,int rec_index,uint8_t info,struct qdf_dp_trace_record_s * record)1137 int qdf_dp_trace_fill_meta_str(char *prepend_str, int size, 1138 int rec_index, uint8_t info, 1139 struct qdf_dp_trace_record_s *record) 1140 { 1141 char buffer[20]; 1142 int ret = 0; 1143 bool live = info & QDF_DP_TRACE_RECORD_INFO_LIVE ? true : false; 1144 bool throttled = info & QDF_DP_TRACE_RECORD_INFO_THROTTLED ? 1145 true : false; 1146 1147 scnprintf(buffer, sizeof(buffer), "%llu", record->time); 1148 ret = scnprintf(prepend_str, size, 1149 "%s DPT: %04d:%02d%s %s", 1150 throttled ? "*" : "", 1151 rec_index, 1152 record->pdev_id, 1153 live ? "" : buffer, 1154 qdf_dp_code_to_string(record->code)); 1155 1156 return ret; 1157 } 1158 1159 /** 1160 * qdf_dp_fill_record_data() - fill meta data and data into the record 1161 * @rec: pointer to record data 1162 * @data: pointer to data 1163 * @data_size: size of the data 1164 * @meta_data: pointer to metadata 1165 * @metadata_size: size of metadata 1166 * 1167 * Should be called from within a spin_lock for the qdf record. 1168 * Fills up rec->data with |metadata|data| 1169 * 1170 * Return: none 1171 */ qdf_dp_fill_record_data(struct qdf_dp_trace_record_s * rec,uint8_t * data,uint8_t data_size,uint8_t * meta_data,uint8_t metadata_size)1172 static void qdf_dp_fill_record_data 1173 (struct qdf_dp_trace_record_s *rec, 1174 uint8_t *data, uint8_t data_size, 1175 uint8_t *meta_data, uint8_t metadata_size) 1176 { 1177 int32_t available = QDF_DP_TRACE_RECORD_SIZE; 1178 uint8_t *rec_data = rec->data; 1179 uint8_t data_to_copy = 0; 1180 1181 qdf_mem_zero(rec_data, QDF_DP_TRACE_RECORD_SIZE); 1182 1183 /* copy meta data */ 1184 if (meta_data) { 1185 if (metadata_size > available) { 1186 QDF_TRACE_WARN(QDF_MODULE_ID_QDF, 1187 "%s: meta data does not fit into the record", 1188 __func__); 1189 goto end; 1190 } 1191 qdf_mem_copy(rec_data, meta_data, metadata_size); 1192 available = available - metadata_size; 1193 } else { 1194 metadata_size = 0; 1195 } 1196 1197 /* copy data */ 1198 if (data && (data_size > 0) && (available > 0)) { 1199 data_to_copy = data_size; 1200 if (data_size > available) 1201 data_to_copy = available; 1202 qdf_mem_copy(&rec_data[metadata_size], data, data_to_copy); 1203 } 1204 end: 1205 rec->size = data_to_copy; 1206 } 1207 1208 /** 1209 * qdf_dp_add_record() - add dp trace record 1210 * @code: dptrace code 1211 * @pdev_id: pdev_id 1212 * @print: true to print it in kmsg 1213 * @data: data pointer 1214 * @data_size: size of data to be copied 1215 * @meta_data: meta data to be prepended to data 1216 * @metadata_size: sizeof meta data 1217 * @print: whether to print record 1218 * 1219 * Return: none 1220 */ qdf_dp_add_record(enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t data_size,uint8_t * meta_data,uint8_t metadata_size,bool print)1221 static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t pdev_id, 1222 uint8_t *data, uint8_t data_size, 1223 uint8_t *meta_data, uint8_t metadata_size, 1224 bool print) 1225 1226 { 1227 struct qdf_dp_trace_record_s *rec = NULL; 1228 int index; 1229 bool print_this_record = false; 1230 u8 info = 0; 1231 1232 if (code >= QDF_DP_TRACE_MAX) { 1233 QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, 1234 "invalid record code %u, max code %u", 1235 code, QDF_DP_TRACE_MAX); 1236 return; 1237 } 1238 1239 spin_lock_bh(&l_dp_trace_lock); 1240 1241 if (print || g_qdf_dp_trace_data.force_live_mode) { 1242 print_this_record = true; 1243 } else if (g_qdf_dp_trace_data.live_mode == 1) { 1244 print_this_record = true; 1245 g_qdf_dp_trace_data.print_pkt_cnt++; 1246 if (g_qdf_dp_trace_data.print_pkt_cnt > 1247 g_qdf_dp_trace_data.high_tput_thresh) { 1248 g_qdf_dp_trace_data.live_mode = 0; 1249 g_qdf_dp_trace_data.verbosity = 1250 QDF_DP_TRACE_VERBOSITY_ULTRA_LOW; 1251 info |= QDF_DP_TRACE_RECORD_INFO_THROTTLED; 1252 } 1253 } 1254 1255 g_qdf_dp_trace_data.num++; 1256 1257 if (g_qdf_dp_trace_data.num > MAX_QDF_DP_TRACE_RECORDS) 1258 g_qdf_dp_trace_data.num = MAX_QDF_DP_TRACE_RECORDS; 1259 1260 if (INVALID_QDF_DP_TRACE_ADDR == g_qdf_dp_trace_data.head) { 1261 /* first record */ 1262 g_qdf_dp_trace_data.head = 0; 1263 g_qdf_dp_trace_data.tail = 0; 1264 } else { 1265 /* queue is not empty */ 1266 g_qdf_dp_trace_data.tail++; 1267 1268 if (MAX_QDF_DP_TRACE_RECORDS == g_qdf_dp_trace_data.tail) 1269 g_qdf_dp_trace_data.tail = 0; 1270 1271 if (g_qdf_dp_trace_data.head == g_qdf_dp_trace_data.tail) { 1272 /* full */ 1273 if (MAX_QDF_DP_TRACE_RECORDS == 1274 ++g_qdf_dp_trace_data.head) 1275 g_qdf_dp_trace_data.head = 0; 1276 } 1277 } 1278 1279 rec = &g_qdf_dp_trace_tbl[g_qdf_dp_trace_data.tail]; 1280 index = g_qdf_dp_trace_data.tail; 1281 rec->code = code; 1282 rec->pdev_id = pdev_id; 1283 rec->size = 0; 1284 qdf_dp_fill_record_data(rec, data, data_size, 1285 meta_data, metadata_size); 1286 rec->time = qdf_get_log_timestamp(); 1287 rec->pid = (in_interrupt() ? 0 : current->pid); 1288 1289 if (rec->code >= QDF_DP_TRACE_MAX) { 1290 QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, 1291 "invalid record code %u, max code %u", 1292 rec->code, QDF_DP_TRACE_MAX); 1293 return; 1294 } 1295 1296 spin_unlock_bh(&l_dp_trace_lock); 1297 1298 info |= QDF_DP_TRACE_RECORD_INFO_LIVE; 1299 if (print_this_record) 1300 qdf_dp_trace_cb_table[rec->code] (rec, index, 1301 QDF_TRACE_DEFAULT_PDEV_ID, info); 1302 } 1303 1304 /** 1305 * qdf_get_rate_limit_by_type() - Get the rate limit by pkt type 1306 * @type: packet type 1307 * 1308 * Return: Rate limit value for a particular packet type 1309 */ 1310 static inline qdf_get_rate_limit_by_type(uint8_t type)1311 uint8_t qdf_get_rate_limit_by_type(uint8_t type) 1312 { 1313 switch (type) { 1314 case QDF_PROTO_TYPE_DHCP: 1315 return QDF_MAX_DHCP_PKTS_PER_SEC; 1316 case QDF_PROTO_TYPE_EAPOL: 1317 return QDF_MAX_EAPOL_PKTS_PER_SEC; 1318 case QDF_PROTO_TYPE_ARP: 1319 return QDF_MAX_ARP_PKTS_PER_SEC; 1320 case QDF_PROTO_TYPE_DNS: 1321 return QDF_MAX_DNS_PKTS_PER_SEC; 1322 default: 1323 return QDF_MAX_OTHER_PKTS_PER_SEC; 1324 } 1325 } 1326 1327 /** 1328 * qdf_get_pkt_type_string() - Get the string based on pkt type 1329 * @type: packet type 1330 * @subtype: packet subtype 1331 * 1332 * Return: String based on pkt type 1333 */ 1334 static qdf_get_pkt_type_string(uint8_t type,uint8_t subtype)1335 uint8_t *qdf_get_pkt_type_string(uint8_t type, uint8_t subtype) 1336 { 1337 switch (subtype) { 1338 case QDF_PROTO_EAPOL_M1: 1339 return "EAPOL-1"; 1340 case QDF_PROTO_EAPOL_M2: 1341 return "EAPOL-2"; 1342 case QDF_PROTO_EAPOL_M3: 1343 return "EAPOL-3"; 1344 case QDF_PROTO_EAPOL_M4: 1345 return "EAPOL-4"; 1346 case QDF_PROTO_DHCP_DISCOVER: 1347 return "DHCP-D"; 1348 case QDF_PROTO_DHCP_REQUEST: 1349 return "DHCP-R"; 1350 case QDF_PROTO_DHCP_OFFER: 1351 return "DHCP-O"; 1352 case QDF_PROTO_DHCP_ACK: 1353 return "DHCP-A"; 1354 case QDF_PROTO_DHCP_NACK: 1355 return "DHCP-NA"; 1356 case QDF_PROTO_DHCP_RELEASE: 1357 return "DHCP-REL"; 1358 case QDF_PROTO_DHCP_INFORM: 1359 return "DHCP-IN"; 1360 case QDF_PROTO_DHCP_DECLINE: 1361 return "DHCP-DEC"; 1362 case QDF_PROTO_ARP_REQ: 1363 return "ARP-RQ"; 1364 case QDF_PROTO_ARP_RES: 1365 return "ARP-RS"; 1366 case QDF_PROTO_DNS_QUERY: 1367 return "DNS_Q"; 1368 case QDF_PROTO_DNS_RES: 1369 return "DNS_RS"; 1370 case QDF_PROTO_EAP_REQUEST: 1371 return "EAP_REQ"; 1372 case QDF_PROTO_EAP_RESPONSE: 1373 return "EAP-RSP"; 1374 case QDF_PROTO_EAP_SUCCESS: 1375 return "EAP-SUCCESS"; 1376 case QDF_PROTO_EAP_FAILURE: 1377 return "EAP-FAIL"; 1378 case QDF_PROTO_EAP_INITIATE: 1379 return "EAP-INIT"; 1380 case QDF_PROTO_EAP_FINISH: 1381 return "EAP-FINISH"; 1382 case QDF_PROTO_EAPOL_START: 1383 return "EAPOL-START"; 1384 case QDF_PROTO_EAPOL_LOGOFF: 1385 return "EAPOL-LOGOFF"; 1386 case QDF_PROTO_EAPOL_ASF: 1387 return "EAPOL-ASF"; 1388 case QDF_PROTO_EAP_REQ_ID: 1389 return "EAP-REQ-ID"; 1390 case QDF_PROTO_EAP_RSP_ID: 1391 return "EAP-RSP-ID"; 1392 case QDF_PROTO_EAP_M1: 1393 return "EAP-M1"; 1394 case QDF_PROTO_EAP_M2: 1395 return "EAP-M2"; 1396 case QDF_PROTO_EAP_M3: 1397 return "EAP-M3"; 1398 case QDF_PROTO_EAP_M4: 1399 return "EAP-M4"; 1400 case QDF_PROTO_EAP_M5: 1401 return "EAP-M5"; 1402 case QDF_PROTO_EAP_M6: 1403 return "EAP-M6"; 1404 case QDF_PROTO_EAP_M7: 1405 return "EAP-M7"; 1406 case QDF_PROTO_EAP_M8: 1407 return "EAP-M8"; 1408 case QDF_PROTO_EAP_WSC_START: 1409 return "EAP-WSC-START"; 1410 case QDF_PROTO_EAP_WSC_DONE: 1411 return "EAP-WSC-DONE"; 1412 case QDF_PROTO_EAP_WSC_ACK: 1413 return "EAP-WSC-ACK"; 1414 case QDF_PROTO_EAP_WSC_NACK: 1415 return "EAP-WSC-NACK"; 1416 case QDF_PROTO_EAP_WSC_FRAG_ACK: 1417 return "EAP-WSC-FRAG-ACK"; 1418 default: 1419 switch (type) { 1420 case QDF_PROTO_TYPE_EAPOL: 1421 return "EAP"; 1422 case QDF_PROTO_TYPE_DHCP: 1423 return "DHCP"; 1424 case QDF_PROTO_TYPE_ARP: 1425 return "ARP"; 1426 case QDF_PROTO_TYPE_DNS: 1427 return "DNS"; 1428 default: 1429 return "UNKNOWN"; 1430 } 1431 } 1432 } 1433 1434 /** 1435 * qdf_get_pkt_status_string() - Get the string based on pkt status 1436 * @status: packet status 1437 * 1438 * Return: String based on pkt status 1439 */ 1440 static qdf_get_pkt_status_string(uint8_t status)1441 uint8_t *qdf_get_pkt_status_string(uint8_t status) 1442 { 1443 switch (status) { 1444 case QDF_TX_RX_STATUS_INVALID: 1445 return "inv"; 1446 case QDF_TX_RX_STATUS_OK: 1447 return "succ"; 1448 case QDF_TX_RX_STATUS_FW_DISCARD: 1449 return "disc"; 1450 case QDF_TX_RX_STATUS_NO_ACK: 1451 return "nack"; 1452 case QDF_TX_RX_STATUS_DROP: 1453 return "drop"; 1454 default: 1455 return "unknown"; 1456 } 1457 } 1458 qdf_dp_log_proto_pkt_info(uint8_t * sa,uint8_t * da,uint8_t type,uint8_t subtype,uint8_t dir,uint16_t msdu_id,uint8_t status)1459 void qdf_dp_log_proto_pkt_info(uint8_t *sa, uint8_t *da, uint8_t type, 1460 uint8_t subtype, uint8_t dir, uint16_t msdu_id, 1461 uint8_t status) 1462 { 1463 uint8_t pkt_rate_limit; 1464 static ulong last_ticks_tx[QDF_PROTO_SUBTYPE_MAX] = {0}; 1465 static ulong last_ticks_rx[QDF_PROTO_SUBTYPE_MAX] = {0}; 1466 ulong curr_ticks = jiffies; 1467 1468 pkt_rate_limit = qdf_get_rate_limit_by_type(type); 1469 1470 if ((dir == QDF_TX && 1471 !time_after(curr_ticks, 1472 last_ticks_tx[subtype] + HZ / pkt_rate_limit)) || 1473 (dir == QDF_RX && 1474 !time_after(curr_ticks, 1475 last_ticks_rx[subtype] + HZ / pkt_rate_limit))) 1476 return; 1477 1478 if (dir == QDF_TX) 1479 last_ticks_tx[subtype] = curr_ticks; 1480 else 1481 last_ticks_rx[subtype] = curr_ticks; 1482 1483 if (status == QDF_TX_RX_STATUS_INVALID) 1484 qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT, 1485 qdf_get_pkt_type_string(type, subtype), 1486 dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa), 1487 QDF_MAC_ADDR_REF(da)); 1488 else 1489 qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT " msdu_id:%d status: %s", 1490 qdf_get_pkt_type_string(type, subtype), 1491 dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa), 1492 QDF_MAC_ADDR_REF(da), msdu_id, 1493 qdf_get_pkt_status_string(status)); 1494 } 1495 1496 qdf_export_symbol(qdf_dp_log_proto_pkt_info); 1497 1498 /** 1499 * qdf_log_icmpv6_pkt() - log ICMPv6 packet 1500 * @vdev_id: ID of the vdev 1501 * @skb: skb pointer 1502 * @dir: direction 1503 * @pdev_id: ID of the pdev 1504 * 1505 * Return: true/false 1506 */ qdf_log_icmpv6_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)1507 static bool qdf_log_icmpv6_pkt(uint8_t vdev_id, struct sk_buff *skb, 1508 enum qdf_proto_dir dir, uint8_t pdev_id) 1509 { 1510 enum qdf_proto_subtype subtype; 1511 struct qdf_dp_trace_proto_cmn cmn_info; 1512 1513 if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMPv6) && 1514 ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ICMPv6 == 1515 QDF_NBUF_CB_GET_PACKET_TYPE(skb)) || 1516 (dir == QDF_RX && qdf_nbuf_is_icmpv6_pkt(skb) == true))) { 1517 1518 subtype = qdf_nbuf_get_icmpv6_subtype(skb); 1519 1520 QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false; 1521 if (dir == QDF_TX) 1522 QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; 1523 else if (dir == QDF_RX) 1524 QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; 1525 1526 cmn_info.vdev_id = vdev_id; 1527 cmn_info.type = QDF_PROTO_TYPE_ICMPv6; 1528 cmn_info.subtype = subtype; 1529 cmn_info.proto_priv_data = 0; 1530 cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb); 1531 DPTRACE(qdf_dp_trace_proto_pkt( 1532 QDF_DP_TRACE_ICMPv6_PACKET_RECORD, 1533 (skb->data + QDF_NBUF_SRC_MAC_OFFSET), 1534 (skb->data + QDF_NBUF_DEST_MAC_OFFSET), 1535 dir, pdev_id, false, &cmn_info)); 1536 1537 switch (subtype) { 1538 case QDF_PROTO_ICMPV6_REQ: 1539 g_qdf_dp_trace_data.icmpv6_req++; 1540 break; 1541 case QDF_PROTO_ICMPV6_RES: 1542 g_qdf_dp_trace_data.icmpv6_resp++; 1543 break; 1544 case QDF_PROTO_ICMPV6_RS: 1545 g_qdf_dp_trace_data.icmpv6_rs++; 1546 break; 1547 case QDF_PROTO_ICMPV6_RA: 1548 g_qdf_dp_trace_data.icmpv6_ra++; 1549 break; 1550 case QDF_PROTO_ICMPV6_NS: 1551 g_qdf_dp_trace_data.icmpv6_ns++; 1552 break; 1553 case QDF_PROTO_ICMPV6_NA: 1554 g_qdf_dp_trace_data.icmpv6_na++; 1555 break; 1556 default: 1557 break; 1558 } 1559 return true; 1560 } 1561 1562 return false; 1563 } 1564 1565 /** 1566 * qdf_log_icmp_pkt() - log ICMP packet 1567 * @vdev_id: ID of the vdev 1568 * @skb: skb pointer 1569 * @dir: direction 1570 * @pdev_id: ID of the pdev 1571 * 1572 * Return: true/false 1573 */ qdf_log_icmp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)1574 static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb, 1575 enum qdf_proto_dir dir, uint8_t pdev_id) 1576 { 1577 uint8_t *data = NULL; 1578 uint16_t seq_num = 0; 1579 uint16_t icmp_id = 0; 1580 struct qdf_dp_trace_proto_cmn cmn_info; 1581 1582 if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) && 1583 (qdf_nbuf_is_icmp_pkt(skb) == true)) { 1584 1585 QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false; 1586 cmn_info.subtype = qdf_nbuf_get_icmp_subtype(skb); 1587 1588 data = qdf_nbuf_data(skb); 1589 icmp_id = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_ID_OFFSET)); 1590 seq_num = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET)); 1591 1592 cmn_info.proto_priv_data = ((uint32_t)icmp_id) << 16; 1593 cmn_info.proto_priv_data |= (uint32_t)seq_num; 1594 cmn_info.type = QDF_PROTO_TYPE_ICMP; 1595 cmn_info.vdev_id = vdev_id; 1596 cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb); 1597 1598 if (QDF_TX == dir) 1599 QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; 1600 else if (QDF_RX == dir) 1601 QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; 1602 1603 DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD, 1604 skb->data + 1605 QDF_NBUF_SRC_MAC_OFFSET, 1606 skb->data + 1607 QDF_NBUF_DEST_MAC_OFFSET, 1608 dir, pdev_id, 1609 false, &cmn_info)); 1610 1611 if (cmn_info.subtype == QDF_PROTO_ICMP_REQ) 1612 g_qdf_dp_trace_data.icmp_req++; 1613 else 1614 g_qdf_dp_trace_data.icmp_resp++; 1615 1616 return true; 1617 } 1618 return false; 1619 } 1620 1621 #ifdef WLAN_CHIPSET_STATS 1622 static void qdf_log_pkt_cstats(uint8_t * sa,uint8_t * da,enum qdf_proto_type pkt_type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status status,uint8_t vdev_id,enum QDF_OPMODE op_mode)1623 qdf_log_pkt_cstats(uint8_t *sa, uint8_t *da, enum qdf_proto_type pkt_type, 1624 enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, 1625 enum qdf_dp_tx_rx_status status, uint8_t vdev_id, 1626 enum QDF_OPMODE op_mode) 1627 { 1628 wlan_cp_stats_cstats_pkt_log(sa, da, pkt_type, subtype, dir, 1629 status, vdev_id, op_mode); 1630 } 1631 #else 1632 static void qdf_log_pkt_cstats(uint8_t * sa,uint8_t * da,enum qdf_proto_type pkt_type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status status,uint8_t vdev_id,enum QDF_OPMODE op_mode)1633 qdf_log_pkt_cstats(uint8_t *sa, uint8_t *da, enum qdf_proto_type pkt_type, 1634 enum qdf_proto_subtype subtype, enum qdf_proto_dir dir, 1635 enum qdf_dp_tx_rx_status status, uint8_t vdev_id, 1636 enum QDF_OPMODE op_mode) 1637 { 1638 } 1639 #endif 1640 1641 #ifdef CONNECTIVITY_DIAG_EVENT wlan_get_diag_tx_status(enum qdf_dp_tx_rx_status tx_status)1642 enum diag_tx_status wlan_get_diag_tx_status(enum qdf_dp_tx_rx_status tx_status) 1643 { 1644 switch (tx_status) { 1645 case DIAG_TX_RX_STATUS_FW_DISCARD: 1646 case DIAG_TX_RX_STATUS_INVALID: 1647 case DIAG_TX_RX_STATUS_DROP: 1648 case DIAG_TX_RX_STATUS_DOWNLOAD_SUCC: 1649 case DIAG_TX_RX_STATUS_DEFAULT: 1650 default: 1651 return DIAG_TX_STATUS_FAIL; 1652 case DIAG_TX_RX_STATUS_NO_ACK: 1653 return DIAG_TX_STATUS_NO_ACK; 1654 case DIAG_TX_RX_STATUS_OK: 1655 return DIAG_TX_STATUS_ACK; 1656 } 1657 1658 return DIAG_TX_STATUS_FAIL; 1659 } 1660 1661 /** 1662 * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag 1663 * @subtype: EAPoL key subtype 1664 * 1665 * Return: Wlan main tag subtype 1666 */ qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)1667 static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype) 1668 { 1669 switch (subtype) { 1670 case QDF_PROTO_DHCP_DISCOVER: 1671 return WLAN_CONN_DIAG_DHCP_DISC_EVENT; 1672 case QDF_PROTO_DHCP_REQUEST: 1673 return WLAN_CONN_DIAG_DHCP_REQUEST_EVENT; 1674 case QDF_PROTO_DHCP_OFFER: 1675 return WLAN_CONN_DIAG_DHCP_OFFER_EVENT; 1676 case QDF_PROTO_DHCP_ACK: 1677 return WLAN_CONN_DIAG_DHCP_ACK_EVENT; 1678 case QDF_PROTO_DHCP_NACK: 1679 return WLAN_CONN_DIAG_DHCP_NACK_EVENT; 1680 case QDF_PROTO_EAPOL_M1: 1681 return WLAN_CONN_DIAG_EAPOL_M1_EVENT; 1682 case QDF_PROTO_EAPOL_M2: 1683 return WLAN_CONN_DIAG_EAPOL_M2_EVENT; 1684 case QDF_PROTO_EAPOL_M3: 1685 return WLAN_CONN_DIAG_EAPOL_M3_EVENT; 1686 case QDF_PROTO_EAPOL_M4: 1687 return WLAN_CONN_DIAG_EAPOL_M4_EVENT; 1688 case QDF_PROTO_EAP_REQUEST: 1689 return WLAN_CONN_DIAG_EAP_REQ_EVENT; 1690 case QDF_PROTO_EAP_RESPONSE: 1691 return WLAN_CONN_DIAG_EAP_RESP_EVENT; 1692 case QDF_PROTO_EAP_SUCCESS: 1693 return WLAN_CONN_DIAG_EAP_SUCC_EVENT; 1694 case QDF_PROTO_EAP_FAILURE: 1695 return WLAN_CONN_DIAG_EAP_FAIL_EVENT; 1696 case QDF_PROTO_EAPOL_START: 1697 return WLAN_CONN_DIAG_EAP_START_EVENT; 1698 default: 1699 return WLAN_CONN_DIAG_MAX; 1700 } 1701 } 1702 1703 /** 1704 * qdf_get_wlan_eap_code() - Get EAP code 1705 * @data: skb data pointer 1706 * 1707 * Return: EAP code value 1708 */ qdf_get_wlan_eap_code(uint8_t * data)1709 static int qdf_get_wlan_eap_code(uint8_t *data) 1710 { 1711 uint8_t code = *(data + EAP_CODE_OFFSET); 1712 1713 switch (code) { 1714 case QDF_EAP_REQUEST: 1715 return WLAN_CONN_DIAG_EAP_REQ_EVENT; 1716 case QDF_EAP_RESPONSE: 1717 return WLAN_CONN_DIAG_EAP_RESP_EVENT; 1718 case QDF_EAP_SUCCESS: 1719 return WLAN_CONN_DIAG_EAP_SUCC_EVENT; 1720 case QDF_EAP_FAILURE: 1721 return WLAN_CONN_DIAG_EAP_FAIL_EVENT; 1722 default: 1723 return WLAN_CONN_DIAG_MAX; 1724 } 1725 } 1726 1727 /** 1728 * qdf_eapol_get_key_type() - Get EAPOL key type 1729 * @data: skb data pointer 1730 * @subtype: EAPoL key subtype 1731 * 1732 * Return: EAPOL key type 1733 */ 1734 static qdf_eapol_get_key_type(uint8_t * data,enum qdf_proto_subtype subtype)1735 uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype) 1736 { 1737 uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET); 1738 1739 /* If key type is PTK, key type will be set in EAPOL Key info */ 1740 if (key_info & EAPOL_KEY_TYPE_MASK) 1741 return qdf_subtype_to_wlan_main_tag(subtype); 1742 else if (key_info & EAPOL_KEY_ENCRYPTED_MASK) 1743 return WLAN_CONN_DIAG_GTK_M1_EVENT; 1744 else 1745 return WLAN_CONN_DIAG_GTK_M2_EVENT; 1746 } 1747 1748 /** 1749 * qdf_skip_wlan_connectivity_log() - Check if connectivity log need to skip 1750 * @type: Protocol type 1751 * @subtype: Protocol subtype 1752 * @dir: Rx or Tx 1753 * @op_mode: Vdev Operation mode 1754 * 1755 * Return: true or false 1756 */ 1757 static inline qdf_skip_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum QDF_OPMODE op_mode)1758 bool qdf_skip_wlan_connectivity_log(enum qdf_proto_type type, 1759 enum qdf_proto_subtype subtype, 1760 enum qdf_proto_dir dir, 1761 enum QDF_OPMODE op_mode) 1762 { 1763 if (op_mode != QDF_STA_MODE) 1764 return true; 1765 1766 if (dir == QDF_RX && type == QDF_PROTO_TYPE_DHCP && 1767 (subtype == QDF_PROTO_DHCP_DISCOVER || 1768 subtype == QDF_PROTO_DHCP_REQUEST)) 1769 return true; 1770 return false; 1771 } 1772 1773 /** 1774 * qdf_fill_wlan_connectivity_log() - Fill and queue protocol packet to logging 1775 * the logging queue 1776 * @type: Protocol type 1777 * @subtype: Protocol subtype 1778 * @dir: Rx or Tx 1779 * @qdf_tx_status: Tx completion status 1780 * @op_mode: Vdev Operation mode 1781 * @vdev_id: DP vdev ID 1782 * @data: skb data pointer 1783 * @band: band 1784 * 1785 * Return: None 1786 */ 1787 static qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode,uint8_t vdev_id,uint8_t * data,uint8_t band)1788 void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type, 1789 enum qdf_proto_subtype subtype, 1790 enum qdf_proto_dir dir, 1791 enum qdf_dp_tx_rx_status qdf_tx_status, 1792 enum QDF_OPMODE op_mode, 1793 uint8_t vdev_id, uint8_t *data, 1794 uint8_t band) 1795 { 1796 uint8_t pkt_type; 1797 1798 WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info); 1799 1800 if (qdf_skip_wlan_connectivity_log(type, subtype, dir, op_mode)) 1801 return; 1802 1803 qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event)); 1804 1805 wlan_diag_event.diag_cmn.timestamp_us = 1806 qdf_get_time_of_the_day_ms() * 1000; 1807 wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get()); 1808 wlan_diag_event.diag_cmn.vdev_id = vdev_id; 1809 1810 wlan_diag_event.version = DIAG_MGMT_VERSION_V2; 1811 1812 if (type == QDF_PROTO_TYPE_DHCP) { 1813 wlan_diag_event.subtype = 1814 qdf_subtype_to_wlan_main_tag(subtype); 1815 } else if (type == QDF_PROTO_TYPE_EAPOL) { 1816 pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET); 1817 if (pkt_type == EAPOL_PACKET_TYPE_EAP) { 1818 wlan_diag_event.subtype = 1819 qdf_get_wlan_eap_code(data); 1820 wlan_diag_event.eap_type = 1821 *(data + EAP_TYPE_OFFSET); 1822 wlan_diag_event.eap_len = 1823 qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET)); 1824 } else if (pkt_type == EAPOL_PACKET_TYPE_KEY) { 1825 wlan_diag_event.subtype = 1826 qdf_eapol_get_key_type(data, subtype); 1827 } else if (pkt_type == EAPOL_PACKET_TYPE_START) { 1828 wlan_diag_event.subtype = 1829 WLAN_CONN_DIAG_EAP_START_EVENT; 1830 wlan_diag_event.eap_len = 1831 qdf_ntohs(*(uint16_t *)(data + EAPOL_PKT_LEN_OFFSET)); 1832 } else { 1833 return; 1834 } 1835 } else { 1836 return; 1837 } 1838 1839 wlan_diag_event.supported_links = band; 1840 1841 /*Tx completion status needs to be logged*/ 1842 if (dir == QDF_TX) { 1843 wlan_diag_event.is_tx = 1; 1844 wlan_diag_event.tx_status = 1845 wlan_get_diag_tx_status(qdf_tx_status); 1846 } 1847 1848 WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_CONN_DP); 1849 } 1850 1851 #else 1852 static inline qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode,uint8_t vdev_id,uint8_t * data,uint8_t band)1853 void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type, 1854 enum qdf_proto_subtype subtype, 1855 enum qdf_proto_dir dir, 1856 enum qdf_dp_tx_rx_status qdf_tx_status, 1857 enum QDF_OPMODE op_mode, 1858 uint8_t vdev_id, uint8_t *data, 1859 uint8_t band) 1860 { 1861 } 1862 #endif 1863 1864 /** 1865 * qdf_log_eapol_pkt() - log EAPOL packet 1866 * @vdev_id: ID of the vdev 1867 * @skb: skb pointer 1868 * @dir: direction 1869 * @pdev_id: ID of the pdev 1870 * @op_mode: Vdev Operation mode 1871 * 1872 * Return: true/false 1873 */ qdf_log_eapol_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)1874 static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb, 1875 enum qdf_proto_dir dir, uint8_t pdev_id, 1876 enum QDF_OPMODE op_mode) 1877 { 1878 enum qdf_proto_subtype subtype; 1879 uint32_t dp_eap_trace; 1880 uint32_t dp_eap_event; 1881 struct qdf_dp_trace_proto_cmn cmn_info; 1882 1883 dp_eap_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_EAPOL; 1884 dp_eap_event = qdf_dp_get_proto_event_bitmap() & 1885 QDF_NBUF_PKT_TRAC_TYPE_EAPOL; 1886 1887 if (!dp_eap_trace && !dp_eap_event) 1888 return false; 1889 1890 if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_EAPOL == 1891 QDF_NBUF_CB_GET_PACKET_TYPE(skb)) || 1892 (dir == QDF_RX && qdf_nbuf_is_ipv4_eapol_pkt(skb) == true))) 1893 return false; 1894 1895 subtype = qdf_nbuf_get_eapol_subtype(skb); 1896 1897 if (dp_eap_event && dir == QDF_RX) { 1898 qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET, 1899 skb->data + QDF_NBUF_DEST_MAC_OFFSET, 1900 QDF_PROTO_TYPE_EAPOL, subtype, dir, 1901 QDF_TRACE_DEFAULT_MSDU_ID, 1902 QDF_TX_RX_STATUS_INVALID); 1903 qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_EAPOL, subtype, 1904 QDF_RX, 0, op_mode, 1905 vdev_id, skb->data, 1906 qdf_nbuf_rx_get_band(skb)); 1907 qdf_log_pkt_cstats(skb->data + QDF_NBUF_SRC_MAC_OFFSET, 1908 skb->data + QDF_NBUF_DEST_MAC_OFFSET, 1909 QDF_PROTO_TYPE_EAPOL, subtype, dir, 1910 QDF_TX_RX_STATUS_INVALID, vdev_id, op_mode); 1911 } 1912 1913 if (dp_eap_trace) { 1914 QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; 1915 if (QDF_TX == dir) 1916 QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; 1917 else if (QDF_RX == dir) 1918 QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; 1919 1920 cmn_info.vdev_id = vdev_id; 1921 cmn_info.type = QDF_PROTO_TYPE_EAPOL; 1922 cmn_info.subtype = subtype; 1923 cmn_info.proto_priv_data = 0; 1924 cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb); 1925 DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD, 1926 skb->data + 1927 QDF_NBUF_SRC_MAC_OFFSET, 1928 skb->data + 1929 QDF_NBUF_DEST_MAC_OFFSET, 1930 dir, pdev_id, true, &cmn_info)); 1931 1932 switch (subtype) { 1933 case QDF_PROTO_EAPOL_M1: 1934 g_qdf_dp_trace_data.eapol_m1++; 1935 break; 1936 case QDF_PROTO_EAPOL_M2: 1937 g_qdf_dp_trace_data.eapol_m2++; 1938 break; 1939 case QDF_PROTO_EAPOL_M3: 1940 g_qdf_dp_trace_data.eapol_m3++; 1941 break; 1942 case QDF_PROTO_EAPOL_M4: 1943 g_qdf_dp_trace_data.eapol_m4++; 1944 break; 1945 default: 1946 g_qdf_dp_trace_data.eapol_others++; 1947 break; 1948 } 1949 } 1950 1951 return true; 1952 } 1953 1954 /** 1955 * qdf_log_dhcp_pkt() - log DHCP packet 1956 * @vdev_id: ID of the vdev 1957 * @skb: skb pointer 1958 * @dir: direction 1959 * @pdev_id: ID of the pdev 1960 * @op_mode: Vdev Operation mode 1961 * 1962 * Return: true/false 1963 */ qdf_log_dhcp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)1964 static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb, 1965 enum qdf_proto_dir dir, uint8_t pdev_id, 1966 enum QDF_OPMODE op_mode) 1967 { 1968 enum qdf_proto_subtype subtype = QDF_PROTO_INVALID; 1969 uint32_t dp_dhcp_trace; 1970 uint32_t dp_dhcp_event; 1971 struct qdf_dp_trace_proto_cmn cmn_info; 1972 1973 dp_dhcp_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_DHCP; 1974 dp_dhcp_event = qdf_dp_get_proto_event_bitmap() & 1975 QDF_NBUF_PKT_TRAC_TYPE_DHCP; 1976 1977 if (!dp_dhcp_trace && !dp_dhcp_event) 1978 return false; 1979 1980 if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP == 1981 QDF_NBUF_CB_GET_PACKET_TYPE(skb)) || 1982 (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) 1983 return false; 1984 1985 subtype = qdf_nbuf_get_dhcp_subtype(skb); 1986 1987 if (dp_dhcp_event && dir == QDF_RX) { 1988 qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET, 1989 skb->data + QDF_NBUF_DEST_MAC_OFFSET, 1990 QDF_PROTO_TYPE_DHCP, subtype, dir, 1991 QDF_TRACE_DEFAULT_MSDU_ID, 1992 QDF_TX_RX_STATUS_INVALID); 1993 qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_DHCP, subtype, 1994 QDF_RX, 0, op_mode, vdev_id, 0, 1995 qdf_nbuf_rx_get_band(skb)); 1996 qdf_log_pkt_cstats(skb->data + QDF_NBUF_SRC_MAC_OFFSET, 1997 skb->data + QDF_NBUF_DEST_MAC_OFFSET, 1998 QDF_PROTO_TYPE_DHCP, subtype, dir, 1999 QDF_TX_RX_STATUS_INVALID, vdev_id, op_mode); 2000 } 2001 2002 if (dp_dhcp_trace) { 2003 QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; 2004 if (QDF_TX == dir) 2005 QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; 2006 else if (QDF_RX == dir) 2007 QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; 2008 2009 cmn_info.vdev_id = vdev_id; 2010 cmn_info.type = QDF_PROTO_TYPE_DHCP; 2011 cmn_info.subtype = subtype; 2012 cmn_info.proto_priv_data = 0; 2013 cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb); 2014 DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD, 2015 skb->data + 2016 QDF_NBUF_SRC_MAC_OFFSET, 2017 skb->data + 2018 QDF_NBUF_DEST_MAC_OFFSET, 2019 dir, pdev_id, true, &cmn_info)); 2020 2021 switch (subtype) { 2022 case QDF_PROTO_DHCP_DISCOVER: 2023 g_qdf_dp_trace_data.dhcp_disc++; 2024 break; 2025 case QDF_PROTO_DHCP_OFFER: 2026 g_qdf_dp_trace_data.dhcp_off++; 2027 break; 2028 case QDF_PROTO_DHCP_REQUEST: 2029 g_qdf_dp_trace_data.dhcp_req++; 2030 break; 2031 case QDF_PROTO_DHCP_ACK: 2032 g_qdf_dp_trace_data.dhcp_ack++; 2033 break; 2034 case QDF_PROTO_DHCP_NACK: 2035 g_qdf_dp_trace_data.dhcp_nack++; 2036 break; 2037 default: 2038 g_qdf_dp_trace_data.eapol_others++; 2039 break; 2040 } 2041 } 2042 2043 return true; 2044 } 2045 2046 /** 2047 * qdf_log_arp_pkt() - log ARP packet 2048 * @vdev_id: ID of the vdev 2049 * @skb: skb pointer 2050 * @dir: direction 2051 * @pdev_id: ID of the pdev 2052 * 2053 * Return: true/false 2054 */ qdf_log_arp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)2055 static bool qdf_log_arp_pkt(uint8_t vdev_id, struct sk_buff *skb, 2056 enum qdf_proto_dir dir, uint8_t pdev_id) 2057 { 2058 enum qdf_proto_subtype proto_subtype; 2059 struct qdf_dp_trace_proto_cmn cmn_info; 2060 2061 if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ARP) && 2062 ((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ARP == 2063 QDF_NBUF_CB_GET_PACKET_TYPE(skb)) || 2064 (dir == QDF_RX && qdf_nbuf_is_ipv4_arp_pkt(skb) == true))) { 2065 2066 proto_subtype = qdf_nbuf_get_arp_subtype(skb); 2067 QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true; 2068 if (QDF_TX == dir) 2069 QDF_NBUF_CB_TX_DP_TRACE(skb) = 1; 2070 else if (QDF_RX == dir) 2071 QDF_NBUF_CB_RX_DP_TRACE(skb) = 1; 2072 2073 cmn_info.vdev_id = vdev_id; 2074 cmn_info.type = QDF_PROTO_TYPE_ARP; 2075 cmn_info.subtype = proto_subtype; 2076 cmn_info.proto_priv_data = 0; 2077 cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb); 2078 DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD, 2079 skb->data + 2080 QDF_NBUF_SRC_MAC_OFFSET, 2081 skb->data + 2082 QDF_NBUF_DEST_MAC_OFFSET, 2083 dir, pdev_id, true, 2084 &cmn_info)); 2085 2086 if (QDF_PROTO_ARP_REQ == proto_subtype) 2087 g_qdf_dp_trace_data.arp_req++; 2088 else 2089 g_qdf_dp_trace_data.arp_resp++; 2090 2091 return true; 2092 } 2093 return false; 2094 } 2095 2096 qdf_dp_trace_log_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)2097 bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb, 2098 enum qdf_proto_dir dir, uint8_t pdev_id, 2099 enum QDF_OPMODE op_mode) 2100 { 2101 if (!qdf_dp_get_proto_bitmap() && !qdf_dp_get_proto_event_bitmap()) 2102 return false; 2103 if (qdf_log_arp_pkt(vdev_id, skb, dir, pdev_id)) 2104 return true; 2105 if (qdf_log_dhcp_pkt(vdev_id, skb, dir, pdev_id, op_mode)) 2106 return true; 2107 if (qdf_log_eapol_pkt(vdev_id, skb, dir, pdev_id, op_mode)) 2108 return true; 2109 if (qdf_log_icmp_pkt(vdev_id, skb, dir, pdev_id)) 2110 return true; 2111 if (qdf_log_icmpv6_pkt(vdev_id, skb, dir, pdev_id)) 2112 return true; 2113 return false; 2114 } 2115 qdf_export_symbol(qdf_dp_trace_log_pkt); 2116 qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2117 void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record, 2118 uint16_t index, uint8_t pdev_id, uint8_t info) 2119 { 2120 int loc; 2121 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2122 struct qdf_dp_trace_mgmt_buf *buf = 2123 (struct qdf_dp_trace_mgmt_buf *)record->data; 2124 2125 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2126 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2127 index, info, record); 2128 2129 DPTRACE_PRINT("%s [%d] [%s %s]", 2130 prepend_str, 2131 buf->vdev_id, 2132 qdf_dp_type_to_str(buf->type), 2133 qdf_dp_subtype_to_str(buf->subtype)); 2134 } 2135 qdf_export_symbol(qdf_dp_display_mgmt_pkt); 2136 2137 qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code,uint8_t vdev_id,uint8_t pdev_id,enum qdf_proto_type type,enum qdf_proto_subtype subtype)2138 void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 2139 uint8_t pdev_id, enum qdf_proto_type type, 2140 enum qdf_proto_subtype subtype) 2141 { 2142 struct qdf_dp_trace_mgmt_buf buf; 2143 int buf_size = sizeof(struct qdf_dp_trace_mgmt_buf); 2144 2145 if (qdf_dp_enable_check(NULL, code, QDF_NA) == false) 2146 return; 2147 2148 if (buf_size > QDF_DP_TRACE_RECORD_SIZE) 2149 QDF_BUG(0); 2150 2151 buf.type = type; 2152 buf.subtype = subtype; 2153 buf.vdev_id = vdev_id; 2154 qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, 2155 NULL, 0, true); 2156 } 2157 qdf_export_symbol(qdf_dp_trace_mgmt_pkt); 2158 2159 static void qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2160 qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file, 2161 struct qdf_dp_trace_record_s *record, 2162 uint32_t index) 2163 { 2164 int loc; 2165 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2166 struct qdf_dp_trace_credit_record *buf = 2167 (struct qdf_dp_trace_credit_record *)record->data; 2168 2169 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2170 index, 0, record); 2171 if (buf->operation == QDF_OP_NA) 2172 qdf_debugfs_printf(file, "%s [%s] [T: %d G0: %d G1: %d]\n", 2173 prepend_str, 2174 qdf_dp_credit_source_to_str(buf->source), 2175 buf->total_credits, buf->g0_credit, 2176 buf->g1_credit); 2177 else 2178 qdf_debugfs_printf(file, 2179 "%s [%s] [T: %d G0: %d G1: %d] [%s %d]\n", 2180 prepend_str, 2181 qdf_dp_credit_source_to_str(buf->source), 2182 buf->total_credits, buf->g0_credit, 2183 buf->g1_credit, 2184 qdf_dp_operation_to_str(buf->operation), 2185 buf->delta); 2186 } 2187 qdf_dp_display_credit_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2188 void qdf_dp_display_credit_record(struct qdf_dp_trace_record_s *record, 2189 uint16_t index, uint8_t pdev_id, uint8_t info) 2190 { 2191 int loc; 2192 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2193 struct qdf_dp_trace_credit_record *buf = 2194 (struct qdf_dp_trace_credit_record *)record->data; 2195 2196 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2197 index, info, record); 2198 if (buf->operation == QDF_OP_NA) 2199 DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d]", 2200 prepend_str, 2201 qdf_dp_credit_source_to_str(buf->source), 2202 buf->total_credits, buf->g0_credit, 2203 buf->g1_credit); 2204 else 2205 DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d] [%s %d]", 2206 prepend_str, 2207 qdf_dp_credit_source_to_str(buf->source), 2208 buf->total_credits, buf->g0_credit, 2209 buf->g1_credit, 2210 qdf_dp_operation_to_str(buf->operation), 2211 buf->delta); 2212 } 2213 qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source,enum QDF_CREDIT_OPERATION operation,int delta,int total_credits,int g0_credit,int g1_credit)2214 void qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source, 2215 enum QDF_CREDIT_OPERATION operation, 2216 int delta, int total_credits, 2217 int g0_credit, int g1_credit) 2218 { 2219 struct qdf_dp_trace_credit_record buf; 2220 int buf_size = sizeof(struct qdf_dp_trace_credit_record); 2221 enum QDF_DP_TRACE_ID code = QDF_DP_TRACE_TX_CREDIT_RECORD; 2222 2223 if (qdf_dp_enable_check(NULL, code, QDF_NA) == false) 2224 return; 2225 2226 if (!(qdf_dp_get_proto_bitmap() & QDF_HL_CREDIT_TRACKING)) 2227 return; 2228 2229 if (buf_size > QDF_DP_TRACE_RECORD_SIZE) 2230 QDF_BUG(0); 2231 2232 buf.source = source; 2233 buf.operation = operation; 2234 buf.delta = delta; 2235 buf.total_credits = total_credits; 2236 buf.g0_credit = g0_credit; 2237 buf.g1_credit = g1_credit; 2238 2239 qdf_dp_add_record(code, QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)&buf, 2240 buf_size, NULL, 0, false); 2241 } 2242 qdf_export_symbol(qdf_dp_trace_credit_record); 2243 qdf_dp_display_event_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2244 void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record, 2245 uint16_t index, uint8_t pdev_id, uint8_t info) 2246 { 2247 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2248 struct qdf_dp_trace_event_buf *buf = 2249 (struct qdf_dp_trace_event_buf *)record->data; 2250 2251 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2252 qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2253 index, info, record); 2254 2255 DPTRACE_PRINT("%s [%d] [%s %s]", 2256 prepend_str, 2257 buf->vdev_id, 2258 qdf_dp_type_to_str(buf->type), 2259 qdf_dp_subtype_to_str(buf->subtype)); 2260 } 2261 qdf_export_symbol(qdf_dp_display_event_record); 2262 qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code,uint8_t vdev_id,uint8_t pdev_id,enum qdf_proto_type type,enum qdf_proto_subtype subtype)2263 void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id, 2264 uint8_t pdev_id, enum qdf_proto_type type, 2265 enum qdf_proto_subtype subtype) 2266 { 2267 struct qdf_dp_trace_event_buf buf; 2268 int buf_size = sizeof(struct qdf_dp_trace_event_buf); 2269 2270 if (qdf_dp_enable_check(NULL, code, QDF_NA) == false) 2271 return; 2272 2273 if (buf_size > QDF_DP_TRACE_RECORD_SIZE) 2274 QDF_BUG(0); 2275 2276 buf.type = type; 2277 buf.subtype = subtype; 2278 buf.vdev_id = vdev_id; 2279 qdf_dp_add_record(code, pdev_id, 2280 (uint8_t *)&buf, buf_size, NULL, 0, true); 2281 } 2282 qdf_export_symbol(qdf_dp_trace_record_event); 2283 2284 qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2285 void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record, 2286 uint16_t index, uint8_t pdev_id, uint8_t info) 2287 { 2288 int loc; 2289 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2290 struct qdf_dp_trace_proto_buf *buf = 2291 (struct qdf_dp_trace_proto_buf *)record->data; 2292 2293 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2294 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2295 index, info, record); 2296 2297 if (QDF_RX == buf->dir) 2298 DPTRACE_PRINT("%s [%d] [%d] [%s] SA: " 2299 QDF_MAC_ADDR_FMT " %s DA:" 2300 QDF_MAC_ADDR_FMT " proto priv data = %08x", 2301 prepend_str, 2302 buf->cmn_info.vdev_id, 2303 buf->cmn_info.mpdu_seq, 2304 qdf_dp_subtype_to_str(buf->cmn_info.subtype), 2305 QDF_MAC_ADDR_REF(buf->sa.bytes), 2306 qdf_dp_dir_to_str(buf->dir), 2307 QDF_MAC_ADDR_REF(buf->da.bytes), 2308 buf->cmn_info.proto_priv_data); 2309 else 2310 DPTRACE_PRINT("%s [%d] [%s] SA: " 2311 QDF_MAC_ADDR_FMT " %s DA:" 2312 QDF_MAC_ADDR_FMT " proto priv data = %08x", 2313 prepend_str, 2314 buf->cmn_info.vdev_id, 2315 qdf_dp_subtype_to_str(buf->cmn_info.subtype), 2316 QDF_MAC_ADDR_REF(buf->sa.bytes), 2317 qdf_dp_dir_to_str(buf->dir), 2318 QDF_MAC_ADDR_REF(buf->da.bytes), 2319 buf->cmn_info.proto_priv_data); 2320 } 2321 qdf_export_symbol(qdf_dp_display_proto_pkt); 2322 qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code,uint8_t * sa,uint8_t * da,enum qdf_proto_dir dir,uint8_t pdev_id,bool print,struct qdf_dp_trace_proto_cmn * cmn_info)2323 void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, 2324 uint8_t *sa, uint8_t *da, 2325 enum qdf_proto_dir dir, 2326 uint8_t pdev_id, bool print, 2327 struct qdf_dp_trace_proto_cmn *cmn_info) 2328 { 2329 struct qdf_dp_trace_proto_buf buf; 2330 int buf_size = sizeof(struct qdf_dp_trace_proto_buf); 2331 2332 if (qdf_dp_enable_check(NULL, code, dir) == false) 2333 return; 2334 2335 if (buf_size > QDF_DP_TRACE_RECORD_SIZE) 2336 QDF_BUG(0); 2337 2338 memcpy(&buf.sa, sa, QDF_NET_ETH_LEN); 2339 memcpy(&buf.da, da, QDF_NET_ETH_LEN); 2340 memcpy(&buf.cmn_info, cmn_info, sizeof(*cmn_info)); 2341 buf.dir = dir; 2342 qdf_dp_add_record(code, pdev_id, 2343 (uint8_t *)&buf, buf_size, NULL, 0, print); 2344 } 2345 qdf_export_symbol(qdf_dp_trace_proto_pkt); 2346 qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2347 void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record, 2348 uint16_t index, uint8_t pdev_id, uint8_t info) 2349 { 2350 int loc; 2351 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2352 struct qdf_dp_trace_ptr_buf *buf = 2353 (struct qdf_dp_trace_ptr_buf *)record->data; 2354 bool is_free_pkt_ptr_record = false; 2355 2356 if ((record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) || 2357 (record->code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD)) 2358 is_free_pkt_ptr_record = true; 2359 2360 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2361 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2362 index, info, record); 2363 2364 if (loc < sizeof(prepend_str)) 2365 scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc, 2366 "[msdu id %d %s %d]", 2367 buf->msdu_id, 2368 is_free_pkt_ptr_record ? "status" : "vdev_id", 2369 buf->status); 2370 2371 if (info & QDF_DP_TRACE_RECORD_INFO_LIVE) { 2372 /* In live mode donot dump the contents of the cookie */ 2373 DPTRACE_PRINT("%s", prepend_str); 2374 } else { 2375 dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie, 2376 sizeof(buf->cookie)); 2377 } 2378 } 2379 qdf_export_symbol(qdf_dp_display_ptr_record); 2380 2381 static qdf_dp_get_pkt_proto_type(qdf_nbuf_t nbuf)2382 enum qdf_proto_type qdf_dp_get_pkt_proto_type(qdf_nbuf_t nbuf) 2383 { 2384 uint8_t pkt_type; 2385 2386 if (!nbuf) 2387 return QDF_PROTO_TYPE_MAX; 2388 2389 if (qdf_nbuf_data_is_dns_query(nbuf) || 2390 qdf_nbuf_data_is_dns_response(nbuf)) 2391 return QDF_PROTO_TYPE_DNS; 2392 2393 pkt_type = QDF_NBUF_CB_GET_PACKET_TYPE(nbuf); 2394 2395 switch (pkt_type) { 2396 case QDF_NBUF_CB_PACKET_TYPE_EAPOL: 2397 return QDF_PROTO_TYPE_EAPOL; 2398 case QDF_NBUF_CB_PACKET_TYPE_ARP: 2399 return QDF_PROTO_TYPE_ARP; 2400 case QDF_NBUF_CB_PACKET_TYPE_DHCP: 2401 return QDF_PROTO_TYPE_DHCP; 2402 default: 2403 return QDF_PROTO_TYPE_MAX; 2404 } 2405 } 2406 2407 static qdf_dp_get_pkt_subtype(qdf_nbuf_t nbuf,enum qdf_proto_type pkt_type)2408 enum qdf_proto_subtype qdf_dp_get_pkt_subtype(qdf_nbuf_t nbuf, 2409 enum qdf_proto_type pkt_type) 2410 { 2411 switch (pkt_type) { 2412 case QDF_PROTO_TYPE_EAPOL: 2413 return qdf_nbuf_get_eapol_subtype(nbuf); 2414 case QDF_PROTO_TYPE_ARP: 2415 return qdf_nbuf_get_arp_subtype(nbuf); 2416 case QDF_PROTO_TYPE_DHCP: 2417 return qdf_nbuf_get_dhcp_subtype(nbuf); 2418 case QDF_PROTO_TYPE_DNS: 2419 return (qdf_nbuf_data_is_dns_query(nbuf)) ? 2420 QDF_PROTO_DNS_QUERY : QDF_PROTO_DNS_RES; 2421 default: 2422 return QDF_PROTO_INVALID; 2423 } 2424 } 2425 2426 static qdf_dp_proto_log_enable_check(enum qdf_proto_type pkt_type,uint16_t status)2427 bool qdf_dp_proto_log_enable_check(enum qdf_proto_type pkt_type, 2428 uint16_t status) 2429 { 2430 if (pkt_type == QDF_PROTO_TYPE_MAX) 2431 return false; 2432 2433 switch (pkt_type) { 2434 case QDF_PROTO_TYPE_EAPOL: 2435 return qdf_dp_get_proto_event_bitmap() & 2436 QDF_NBUF_PKT_TRAC_TYPE_EAPOL; 2437 case QDF_PROTO_TYPE_DHCP: 2438 return qdf_dp_get_proto_event_bitmap() & 2439 QDF_NBUF_PKT_TRAC_TYPE_DHCP; 2440 case QDF_PROTO_TYPE_ARP: 2441 if (status == QDF_TX_RX_STATUS_OK) 2442 return false; 2443 else 2444 return qdf_dp_get_proto_event_bitmap() & 2445 QDF_NBUF_PKT_TRAC_TYPE_ARP; 2446 case QDF_PROTO_TYPE_DNS: 2447 if (status == QDF_TX_RX_STATUS_OK) 2448 return false; 2449 else 2450 return qdf_dp_get_proto_event_bitmap() & 2451 QDF_NBUF_PKT_TRAC_TYPE_DNS; 2452 default: 2453 return false; 2454 } 2455 } 2456 qdf_dp_track_noack_check(qdf_nbuf_t nbuf,enum qdf_proto_subtype * subtype)2457 void qdf_dp_track_noack_check(qdf_nbuf_t nbuf, enum qdf_proto_subtype *subtype) 2458 { 2459 enum qdf_proto_type pkt_type = qdf_dp_get_pkt_proto_type(nbuf); 2460 uint16_t dp_track = 0; 2461 2462 switch (pkt_type) { 2463 case QDF_PROTO_TYPE_EAPOL: 2464 dp_track = qdf_dp_get_proto_bitmap() & 2465 QDF_NBUF_PKT_TRAC_TYPE_EAPOL; 2466 break; 2467 case QDF_PROTO_TYPE_DHCP: 2468 dp_track = qdf_dp_get_proto_bitmap() & 2469 QDF_NBUF_PKT_TRAC_TYPE_DHCP; 2470 break; 2471 case QDF_PROTO_TYPE_ARP: 2472 dp_track = qdf_dp_get_proto_bitmap() & 2473 QDF_NBUF_PKT_TRAC_TYPE_ARP; 2474 break; 2475 case QDF_PROTO_TYPE_DNS: 2476 dp_track = qdf_dp_get_proto_bitmap() & 2477 QDF_NBUF_PKT_TRAC_TYPE_DNS; 2478 break; 2479 default: 2480 break; 2481 } 2482 2483 if (!dp_track) { 2484 *subtype = QDF_PROTO_INVALID; 2485 return; 2486 } 2487 2488 *subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type); 2489 } 2490 qdf_export_symbol(qdf_dp_track_noack_check); 2491 qdf_dp_get_status_from_a_status(uint8_t status)2492 enum qdf_dp_tx_rx_status qdf_dp_get_status_from_a_status(uint8_t status) 2493 { 2494 if (status == QDF_A_STATUS_ERROR) 2495 return QDF_TX_RX_STATUS_INVALID; 2496 else if (status == QDF_A_STATUS_OK) 2497 return QDF_TX_RX_STATUS_OK; 2498 else 2499 return QDF_TX_RX_STATUS_MAX; 2500 } 2501 qdf_export_symbol(qdf_dp_get_status_from_a_status); 2502 qdf_dp_trace_ptr(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t size,uint16_t msdu_id,uint16_t buf_arg_status,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode)2503 void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, 2504 uint8_t pdev_id, uint8_t *data, uint8_t size, 2505 uint16_t msdu_id, uint16_t buf_arg_status, 2506 enum qdf_dp_tx_rx_status qdf_tx_status, 2507 enum QDF_OPMODE op_mode) 2508 { 2509 struct qdf_dp_trace_ptr_buf buf; 2510 int buf_size = sizeof(struct qdf_dp_trace_ptr_buf); 2511 enum qdf_proto_type pkt_type; 2512 enum qdf_proto_subtype subtype; 2513 2514 pkt_type = qdf_dp_get_pkt_proto_type(nbuf); 2515 if ((code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD || 2516 code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD) && 2517 qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) { 2518 subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type); 2519 qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET, 2520 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET, 2521 pkt_type, subtype, 2522 QDF_TX, msdu_id, qdf_tx_status); 2523 qdf_fill_wlan_connectivity_log(pkt_type, subtype, 2524 QDF_TX, qdf_tx_status, op_mode, 2525 QDF_NBUF_CB_TX_VDEV_CTX(nbuf), 2526 nbuf->data, 2527 qdf_nbuf_tx_get_band(nbuf)); 2528 qdf_log_pkt_cstats(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET, 2529 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET, 2530 pkt_type, subtype, QDF_TX, 2531 qdf_tx_status, QDF_NBUF_CB_TX_VDEV_CTX(nbuf), 2532 op_mode); 2533 } 2534 2535 if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false) 2536 return; 2537 2538 if (buf_size > QDF_DP_TRACE_RECORD_SIZE) 2539 QDF_BUG(0); 2540 2541 qdf_mem_copy(&buf.cookie, data, size); 2542 buf.msdu_id = msdu_id; 2543 buf.status = buf_arg_status; 2544 qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, NULL, 0, 2545 QDF_NBUF_CB_DP_TRACE_PRINT(nbuf)); 2546 } 2547 qdf_export_symbol(qdf_dp_trace_ptr); 2548 qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf,uint8_t pdev_id,enum QDF_DP_TRACE_ID code,uint16_t msdu_id,enum qdf_proto_dir dir)2549 void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id, 2550 enum QDF_DP_TRACE_ID code, uint16_t msdu_id, 2551 enum qdf_proto_dir dir) 2552 { 2553 struct qdf_dp_trace_data_buf buf; 2554 enum qdf_proto_type pkt_type; 2555 2556 pkt_type = qdf_dp_get_pkt_proto_type(nbuf); 2557 if (code == QDF_DP_TRACE_DROP_PACKET_RECORD && 2558 qdf_dp_proto_log_enable_check(pkt_type, QDF_TX_RX_STATUS_DROP)) 2559 qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET, 2560 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET, 2561 pkt_type, 2562 qdf_dp_get_pkt_subtype(nbuf, pkt_type), 2563 QDF_TX, msdu_id, 2564 QDF_TX_RX_STATUS_DROP); 2565 2566 buf.msdu_id = msdu_id; 2567 if (!qdf_dp_enable_check(nbuf, code, dir)) 2568 return; 2569 2570 qdf_dp_add_record(code, pdev_id, 2571 nbuf ? qdf_nbuf_data(nbuf) : NULL, 2572 nbuf ? nbuf->len - nbuf->data_len : 0, 2573 (uint8_t *)&buf, sizeof(struct qdf_dp_trace_data_buf), 2574 (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false); 2575 } 2576 2577 qdf_export_symbol(qdf_dp_trace_data_pkt); 2578 qdf_dp_display_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2579 void qdf_dp_display_record(struct qdf_dp_trace_record_s *record, 2580 uint16_t index, uint8_t pdev_id, uint8_t info) 2581 { 2582 int loc; 2583 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2584 2585 if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID || 2586 pdev_id == record->pdev_id)) 2587 return; 2588 2589 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2590 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2591 index, info, record); 2592 2593 switch (record->code) { 2594 case QDF_DP_TRACE_HDD_TX_TIMEOUT: 2595 DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str); 2596 break; 2597 case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: 2598 DPTRACE_PRINT(" %s: HDD SoftAP TX Timeout", prepend_str); 2599 break; 2600 case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD: 2601 DPTRACE_PRINT(" %s: CE Fast Packet Error", prepend_str); 2602 break; 2603 case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD: 2604 default: 2605 dump_dp_hex_trace(prepend_str, record->data, record->size); 2606 break; 2607 }; 2608 } 2609 qdf_export_symbol(qdf_dp_display_record); 2610 2611 void qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s * record,uint16_t rec_index,uint8_t pdev_id,uint8_t info)2612 qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record, 2613 uint16_t rec_index, uint8_t pdev_id, 2614 uint8_t info) 2615 { 2616 int loc; 2617 char prepend_str[DP_TRACE_META_DATA_STRLEN + 10]; 2618 struct qdf_dp_trace_data_buf *buf = 2619 (struct qdf_dp_trace_data_buf *)record->data; 2620 2621 qdf_mem_zero(prepend_str, sizeof(prepend_str)); 2622 2623 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2624 rec_index, info, record); 2625 if (loc < sizeof(prepend_str)) 2626 loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc, 2627 "[%d]", buf->msdu_id); 2628 dump_dp_hex_trace(prepend_str, 2629 &record->data[sizeof(struct qdf_dp_trace_data_buf)], 2630 record->size); 2631 } 2632 qdf_dp_trace(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t size,enum qdf_proto_dir dir)2633 void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id, 2634 uint8_t *data, uint8_t size, enum qdf_proto_dir dir) 2635 { 2636 2637 if (qdf_dp_enable_check(nbuf, code, dir) == false) 2638 return; 2639 2640 qdf_dp_add_record(code, pdev_id, nbuf ? qdf_nbuf_data(nbuf) : NULL, 2641 size, NULL, 0, 2642 (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false); 2643 } 2644 qdf_export_symbol(qdf_dp_trace); 2645 qdf_dp_trace_spin_lock_init(void)2646 void qdf_dp_trace_spin_lock_init(void) 2647 { 2648 spin_lock_init(&l_dp_trace_lock); 2649 } 2650 qdf_export_symbol(qdf_dp_trace_spin_lock_init); 2651 qdf_dp_trace_disable_live_mode(void)2652 void qdf_dp_trace_disable_live_mode(void) 2653 { 2654 g_qdf_dp_trace_data.force_live_mode = 0; 2655 } 2656 qdf_export_symbol(qdf_dp_trace_disable_live_mode); 2657 qdf_dp_trace_enable_live_mode(void)2658 void qdf_dp_trace_enable_live_mode(void) 2659 { 2660 g_qdf_dp_trace_data.force_live_mode = 1; 2661 } 2662 qdf_export_symbol(qdf_dp_trace_enable_live_mode); 2663 qdf_dp_trace_clear_buffer(void)2664 void qdf_dp_trace_clear_buffer(void) 2665 { 2666 g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR; 2667 g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR; 2668 g_qdf_dp_trace_data.num = 0; 2669 g_qdf_dp_trace_data.dump_counter = 0; 2670 g_qdf_dp_trace_data.num_records_to_dump = MAX_QDF_DP_TRACE_RECORDS; 2671 if (g_qdf_dp_trace_data.enable) 2672 memset(g_qdf_dp_trace_tbl, 0, 2673 MAX_QDF_DP_TRACE_RECORDS * 2674 sizeof(struct qdf_dp_trace_record_s)); 2675 } 2676 qdf_export_symbol(qdf_dp_trace_clear_buffer); 2677 qdf_dp_trace_dump_stats(void)2678 void qdf_dp_trace_dump_stats(void) 2679 { 2680 DPTRACE_PRINT("STATS |DPT: tx %u rx %u icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)", 2681 g_qdf_dp_trace_data.tx_count, 2682 g_qdf_dp_trace_data.rx_count, 2683 g_qdf_dp_trace_data.icmp_req, 2684 g_qdf_dp_trace_data.icmp_resp, 2685 g_qdf_dp_trace_data.arp_req, 2686 g_qdf_dp_trace_data.arp_resp, 2687 g_qdf_dp_trace_data.icmpv6_req, 2688 g_qdf_dp_trace_data.icmpv6_resp, 2689 g_qdf_dp_trace_data.icmpv6_ns, 2690 g_qdf_dp_trace_data.icmpv6_na, 2691 g_qdf_dp_trace_data.icmpv6_rs, 2692 g_qdf_dp_trace_data.icmpv6_ra, 2693 g_qdf_dp_trace_data.dhcp_disc, 2694 g_qdf_dp_trace_data.dhcp_off, 2695 g_qdf_dp_trace_data.dhcp_req, 2696 g_qdf_dp_trace_data.dhcp_ack, 2697 g_qdf_dp_trace_data.dhcp_nack, 2698 g_qdf_dp_trace_data.dhcp_others, 2699 g_qdf_dp_trace_data.eapol_m1, 2700 g_qdf_dp_trace_data.eapol_m2, 2701 g_qdf_dp_trace_data.eapol_m3, 2702 g_qdf_dp_trace_data.eapol_m4, 2703 g_qdf_dp_trace_data.eapol_others); 2704 } 2705 qdf_export_symbol(qdf_dp_trace_dump_stats); 2706 2707 /** 2708 * qdf_dpt_dump_hex_trace_debugfs() - read data in file 2709 * @file: file to read 2710 * @str: string to prepend the hexdump with. 2711 * @buf: buffer which contains data to be written 2712 * @buf_len: defines the size of the data to be written 2713 * 2714 * Return: None 2715 */ qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file,char * str,uint8_t * buf,uint8_t buf_len)2716 static void qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file, 2717 char *str, uint8_t *buf, uint8_t buf_len) 2718 { 2719 unsigned char linebuf[BUFFER_SIZE]; 2720 const u8 *ptr = buf; 2721 int i, linelen, remaining = buf_len; 2722 2723 /* Dump the bytes in the last line */ 2724 for (i = 0; i < buf_len; i += ROW_SIZE) { 2725 linelen = min(remaining, ROW_SIZE); 2726 remaining -= ROW_SIZE; 2727 2728 hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1, 2729 linebuf, sizeof(linebuf), false); 2730 2731 qdf_debugfs_printf(file, "%s %s\n", str, linebuf); 2732 } 2733 } 2734 2735 /** 2736 * qdf_dpt_display_proto_pkt_debugfs() - display proto packet 2737 * @file: file to read 2738 * @record: dptrace record 2739 * @index: index 2740 * 2741 * Return: none 2742 */ qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2743 static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file, 2744 struct qdf_dp_trace_record_s *record, 2745 uint32_t index) 2746 { 2747 int loc; 2748 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2749 struct qdf_dp_trace_proto_buf *buf = 2750 (struct qdf_dp_trace_proto_buf *)record->data; 2751 2752 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2753 index, 0, record); 2754 qdf_debugfs_printf(file, "%s [%d] [%s] SA: " 2755 QDF_MAC_ADDR_FMT " %s DA: " 2756 QDF_MAC_ADDR_FMT, 2757 prepend_str, 2758 buf->cmn_info.vdev_id, 2759 qdf_dp_subtype_to_str(buf->cmn_info.subtype), 2760 QDF_MAC_ADDR_REF(buf->sa.bytes), 2761 qdf_dp_dir_to_str(buf->dir), 2762 QDF_MAC_ADDR_REF(buf->da.bytes)); 2763 qdf_debugfs_printf(file, "\n"); 2764 } 2765 2766 /** 2767 * qdf_dpt_display_mgmt_pkt_debugfs() - display mgmt packet 2768 * @file: file to read 2769 * @record: dptrace record 2770 * @index: index 2771 * 2772 * Return: none 2773 */ qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2774 static void qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file, 2775 struct qdf_dp_trace_record_s *record, 2776 uint32_t index) 2777 { 2778 2779 int loc; 2780 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2781 struct qdf_dp_trace_mgmt_buf *buf = 2782 (struct qdf_dp_trace_mgmt_buf *)record->data; 2783 2784 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2785 index, 0, record); 2786 2787 qdf_debugfs_printf(file, "%s [%d] [%s %s]\n", 2788 prepend_str, 2789 buf->vdev_id, 2790 qdf_dp_type_to_str(buf->type), 2791 qdf_dp_subtype_to_str(buf->subtype)); 2792 } 2793 2794 /** 2795 * qdf_dpt_display_event_record_debugfs() - display event records 2796 * @file: file to read 2797 * @record: dptrace record 2798 * @index: index 2799 * 2800 * Return: none 2801 */ qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2802 static void qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file, 2803 struct qdf_dp_trace_record_s *record, 2804 uint32_t index) 2805 { 2806 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2807 struct qdf_dp_trace_event_buf *buf = 2808 (struct qdf_dp_trace_event_buf *)record->data; 2809 2810 qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2811 index, 0, record); 2812 qdf_debugfs_printf(file, "%s [%d] [%s %s]\n", 2813 prepend_str, 2814 buf->vdev_id, 2815 qdf_dp_type_to_str(buf->type), 2816 qdf_dp_subtype_to_str(buf->subtype)); 2817 } 2818 2819 /** 2820 * qdf_dpt_display_ptr_record_debugfs() - display record ptr 2821 * @file: file to read 2822 * @record: dptrace record 2823 * @index: index 2824 * 2825 * Return: none 2826 */ qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2827 static void qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file, 2828 struct qdf_dp_trace_record_s *record, 2829 uint32_t index) 2830 { 2831 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2832 int loc; 2833 struct qdf_dp_trace_ptr_buf *buf = 2834 (struct qdf_dp_trace_ptr_buf *)record->data; 2835 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2836 index, 0, record); 2837 2838 if (loc < sizeof(prepend_str)) 2839 scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc, 2840 "[msdu id %d %s %d]", 2841 buf->msdu_id, 2842 (record->code == 2843 QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ? 2844 "status" : "vdev_id", 2845 buf->status); 2846 2847 qdf_dpt_dump_hex_trace_debugfs(file, prepend_str, 2848 (uint8_t *)&buf->cookie, 2849 sizeof(buf->cookie)); 2850 } 2851 2852 /** 2853 * qdf_dpt_display_record_debugfs() - display record 2854 * @file: file to read 2855 * @record: dptrace record 2856 * @index: index 2857 * 2858 * Return: none 2859 */ qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2860 static void qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file, 2861 struct qdf_dp_trace_record_s *record, 2862 uint32_t index) 2863 { 2864 int loc; 2865 char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE]; 2866 struct qdf_dp_trace_data_buf *buf = 2867 (struct qdf_dp_trace_data_buf *)record->data; 2868 2869 loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str), 2870 index, 0, record); 2871 if (loc < sizeof(prepend_str)) 2872 loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc, 2873 "[%d]", buf->msdu_id); 2874 qdf_dpt_dump_hex_trace_debugfs(file, prepend_str, 2875 record->data, record->size); 2876 } 2877 qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file,enum qdf_dpt_debugfs_state state)2878 uint32_t qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file, 2879 enum qdf_dpt_debugfs_state state) 2880 { 2881 uint32_t i = 0; 2882 uint32_t tail; 2883 uint32_t count = g_qdf_dp_trace_data.num; 2884 2885 if (!g_qdf_dp_trace_data.enable) { 2886 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, 2887 "%s: Tracing Disabled", __func__); 2888 return QDF_STATUS_E_EMPTY; 2889 } 2890 2891 if (!count) { 2892 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG, 2893 "%s: no packets", __func__); 2894 return QDF_STATUS_E_EMPTY; 2895 } 2896 2897 if (state == QDF_DPT_DEBUGFS_STATE_SHOW_IN_PROGRESS) 2898 return g_qdf_dp_trace_data.curr_pos; 2899 2900 qdf_debugfs_printf(file, 2901 "DPT: config - bitmap 0x%x verb %u #rec %u rec_requested %u live_config %u thresh %u time_limit %u\n", 2902 g_qdf_dp_trace_data.proto_bitmap, 2903 g_qdf_dp_trace_data.verbosity, 2904 g_qdf_dp_trace_data.no_of_record, 2905 g_qdf_dp_trace_data.num_records_to_dump, 2906 g_qdf_dp_trace_data.live_mode_config, 2907 g_qdf_dp_trace_data.high_tput_thresh, 2908 g_qdf_dp_trace_data.thresh_time_limit); 2909 2910 qdf_debugfs_printf(file, 2911 "STATS |DPT: icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)\n", 2912 g_qdf_dp_trace_data.icmp_req, 2913 g_qdf_dp_trace_data.icmp_resp, 2914 g_qdf_dp_trace_data.arp_req, 2915 g_qdf_dp_trace_data.arp_resp, 2916 g_qdf_dp_trace_data.icmpv6_req, 2917 g_qdf_dp_trace_data.icmpv6_resp, 2918 g_qdf_dp_trace_data.icmpv6_ns, 2919 g_qdf_dp_trace_data.icmpv6_na, 2920 g_qdf_dp_trace_data.icmpv6_rs, 2921 g_qdf_dp_trace_data.icmpv6_ra, 2922 g_qdf_dp_trace_data.dhcp_disc, 2923 g_qdf_dp_trace_data.dhcp_off, 2924 g_qdf_dp_trace_data.dhcp_req, 2925 g_qdf_dp_trace_data.dhcp_ack, 2926 g_qdf_dp_trace_data.dhcp_nack, 2927 g_qdf_dp_trace_data.dhcp_others, 2928 g_qdf_dp_trace_data.eapol_m1, 2929 g_qdf_dp_trace_data.eapol_m2, 2930 g_qdf_dp_trace_data.eapol_m3, 2931 g_qdf_dp_trace_data.eapol_m4, 2932 g_qdf_dp_trace_data.eapol_others); 2933 2934 qdf_debugfs_printf(file, 2935 "DPT: Total Records: %d, Head: %d, Tail: %d\n", 2936 g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head, 2937 g_qdf_dp_trace_data.tail); 2938 2939 spin_lock_bh(&l_dp_trace_lock); 2940 if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) { 2941 i = g_qdf_dp_trace_data.head; 2942 tail = g_qdf_dp_trace_data.tail; 2943 2944 if (count > g_qdf_dp_trace_data.num) 2945 count = g_qdf_dp_trace_data.num; 2946 2947 if (tail >= (count - 1)) 2948 i = tail - count + 1; 2949 else if (count != MAX_QDF_DP_TRACE_RECORDS) 2950 i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) - 2951 tail); 2952 g_qdf_dp_trace_data.curr_pos = 0; 2953 g_qdf_dp_trace_data.saved_tail = tail; 2954 } 2955 spin_unlock_bh(&l_dp_trace_lock); 2956 2957 return g_qdf_dp_trace_data.saved_tail; 2958 } 2959 qdf_export_symbol(qdf_dpt_get_curr_pos_debugfs); 2960 qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file,uint32_t curr_pos)2961 QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file, 2962 uint32_t curr_pos) 2963 { 2964 struct qdf_dp_trace_record_s p_record; 2965 uint32_t i = curr_pos; 2966 uint16_t num_records_to_dump = g_qdf_dp_trace_data.num_records_to_dump; 2967 2968 if (!g_qdf_dp_trace_data.enable) { 2969 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, 2970 "%s: Tracing Disabled", __func__); 2971 return QDF_STATUS_E_FAILURE; 2972 } 2973 2974 if (num_records_to_dump > g_qdf_dp_trace_data.num) 2975 num_records_to_dump = g_qdf_dp_trace_data.num; 2976 2977 /* 2978 * Max dp trace record size should always be less than 2979 * QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121). 2980 */ 2981 if (WARN_ON(QDF_DP_TRACE_MAX_RECORD_SIZE < 2982 QDF_DP_TRACE_PREPEND_STR_SIZE + BUFFER_SIZE)) 2983 return QDF_STATUS_E_FAILURE; 2984 2985 spin_lock_bh(&l_dp_trace_lock); 2986 p_record = g_qdf_dp_trace_tbl[i]; 2987 spin_unlock_bh(&l_dp_trace_lock); 2988 2989 for (;; ) { 2990 /* 2991 * Initially we get file as 1 page size, and 2992 * if remaining size in file is less than one record max size, 2993 * then return so that it gets an extra page. 2994 */ 2995 if ((file->size - file->count) < QDF_DP_TRACE_MAX_RECORD_SIZE) { 2996 spin_lock_bh(&l_dp_trace_lock); 2997 g_qdf_dp_trace_data.curr_pos = i; 2998 spin_unlock_bh(&l_dp_trace_lock); 2999 return QDF_STATUS_E_FAILURE; 3000 } 3001 3002 switch (p_record.code) { 3003 case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD: 3004 case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD: 3005 case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD: 3006 qdf_dpt_display_ptr_record_debugfs(file, &p_record, i); 3007 break; 3008 3009 case QDF_DP_TRACE_EAPOL_PACKET_RECORD: 3010 case QDF_DP_TRACE_DHCP_PACKET_RECORD: 3011 case QDF_DP_TRACE_ARP_PACKET_RECORD: 3012 case QDF_DP_TRACE_ICMP_PACKET_RECORD: 3013 case QDF_DP_TRACE_ICMPv6_PACKET_RECORD: 3014 qdf_dpt_display_proto_pkt_debugfs(file, &p_record, i); 3015 break; 3016 3017 case QDF_DP_TRACE_TX_CREDIT_RECORD: 3018 qdf_dpt_display_credit_record_debugfs(file, &p_record, 3019 i); 3020 break; 3021 3022 case QDF_DP_TRACE_MGMT_PACKET_RECORD: 3023 qdf_dpt_display_mgmt_pkt_debugfs(file, &p_record, i); 3024 break; 3025 3026 case QDF_DP_TRACE_EVENT_RECORD: 3027 qdf_dpt_display_event_record_debugfs(file, &p_record, 3028 i); 3029 break; 3030 3031 case QDF_DP_TRACE_HDD_TX_TIMEOUT: 3032 qdf_debugfs_printf( 3033 file, "DPT: %04d: %llu %s\n", 3034 i, p_record.time, 3035 qdf_dp_code_to_string(p_record.code)); 3036 qdf_debugfs_printf(file, "HDD TX Timeout\n"); 3037 break; 3038 3039 case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: 3040 qdf_debugfs_printf( 3041 file, "DPT: %04d: %llu %s\n", 3042 i, p_record.time, 3043 qdf_dp_code_to_string(p_record.code)); 3044 qdf_debugfs_printf(file, "HDD SoftAP TX Timeout\n"); 3045 break; 3046 3047 case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD: 3048 qdf_debugfs_printf( 3049 file, "DPT: %04d: %llu %s\n", 3050 i, p_record.time, 3051 qdf_dp_code_to_string(p_record.code)); 3052 qdf_debugfs_printf(file, "CE Fast Packet Error\n"); 3053 break; 3054 3055 case QDF_DP_TRACE_MAX: 3056 qdf_debugfs_printf(file, 3057 "%s: QDF_DP_TRACE_MAX event should not be generated\n", 3058 __func__); 3059 break; 3060 3061 case QDF_DP_TRACE_HDD_TX_PACKET_RECORD: 3062 case QDF_DP_TRACE_HDD_RX_PACKET_RECORD: 3063 case QDF_DP_TRACE_TX_PACKET_RECORD: 3064 case QDF_DP_TRACE_RX_PACKET_RECORD: 3065 case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD: 3066 case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD: 3067 3068 default: 3069 qdf_dpt_display_record_debugfs(file, &p_record, i); 3070 break; 3071 } 3072 3073 if (++g_qdf_dp_trace_data.dump_counter == num_records_to_dump) 3074 break; 3075 3076 spin_lock_bh(&l_dp_trace_lock); 3077 if (i == 0) 3078 i = MAX_QDF_DP_TRACE_RECORDS; 3079 3080 i -= 1; 3081 p_record = g_qdf_dp_trace_tbl[i]; 3082 spin_unlock_bh(&l_dp_trace_lock); 3083 } 3084 3085 g_qdf_dp_trace_data.dump_counter = 0; 3086 3087 return QDF_STATUS_SUCCESS; 3088 } 3089 qdf_export_symbol(qdf_dpt_dump_stats_debugfs); 3090 qdf_dpt_set_value_debugfs(uint8_t proto_bitmap,uint8_t no_of_record,uint8_t verbosity,uint16_t num_records_to_dump)3091 void qdf_dpt_set_value_debugfs(uint8_t proto_bitmap, uint8_t no_of_record, 3092 uint8_t verbosity, uint16_t num_records_to_dump) 3093 { 3094 if (g_qdf_dp_trace_data.enable) { 3095 g_qdf_dp_trace_data.proto_bitmap = proto_bitmap; 3096 g_qdf_dp_trace_data.no_of_record = no_of_record; 3097 g_qdf_dp_trace_data.verbosity = verbosity; 3098 g_qdf_dp_trace_data.num_records_to_dump = num_records_to_dump; 3099 } 3100 } 3101 qdf_export_symbol(qdf_dpt_set_value_debugfs); 3102 3103 qdf_dp_trace_dump_all(uint32_t count,uint8_t pdev_id)3104 void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id) 3105 { 3106 struct qdf_dp_trace_record_s p_record; 3107 int32_t i, tail; 3108 3109 if (!g_qdf_dp_trace_data.enable) { 3110 DPTRACE_PRINT("Tracing Disabled"); 3111 return; 3112 } 3113 3114 DPTRACE_PRINT( 3115 "DPT: config - bitmap 0x%x verb %u #rec %u live_config %u thresh %u time_limit %u", 3116 g_qdf_dp_trace_data.proto_bitmap, 3117 g_qdf_dp_trace_data.verbosity, 3118 g_qdf_dp_trace_data.no_of_record, 3119 g_qdf_dp_trace_data.live_mode_config, 3120 g_qdf_dp_trace_data.high_tput_thresh, 3121 g_qdf_dp_trace_data.thresh_time_limit); 3122 3123 qdf_dp_trace_dump_stats(); 3124 3125 DPTRACE_PRINT("DPT: Total Records: %d, Head: %d, Tail: %d", 3126 g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head, 3127 g_qdf_dp_trace_data.tail); 3128 3129 /* acquire the lock so that only one thread at a time can read 3130 * the ring buffer 3131 */ 3132 spin_lock_bh(&l_dp_trace_lock); 3133 3134 if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) { 3135 i = g_qdf_dp_trace_data.head; 3136 tail = g_qdf_dp_trace_data.tail; 3137 3138 if (count) { 3139 if (count > g_qdf_dp_trace_data.num) 3140 count = g_qdf_dp_trace_data.num; 3141 if (tail >= (count - 1)) 3142 i = tail - count + 1; 3143 else if (count != MAX_QDF_DP_TRACE_RECORDS) 3144 i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) - 3145 tail); 3146 } 3147 3148 p_record = g_qdf_dp_trace_tbl[i]; 3149 spin_unlock_bh(&l_dp_trace_lock); 3150 for (;; ) { 3151 qdf_dp_trace_cb_table[p_record.code](&p_record, 3152 (uint16_t)i, pdev_id, false); 3153 if (i == tail) 3154 break; 3155 i += 1; 3156 3157 spin_lock_bh(&l_dp_trace_lock); 3158 if (MAX_QDF_DP_TRACE_RECORDS == i) 3159 i = 0; 3160 3161 p_record = g_qdf_dp_trace_tbl[i]; 3162 spin_unlock_bh(&l_dp_trace_lock); 3163 } 3164 } else { 3165 spin_unlock_bh(&l_dp_trace_lock); 3166 } 3167 } 3168 qdf_export_symbol(qdf_dp_trace_dump_all); 3169 qdf_dp_trace_throttle_live_mode(bool high_bw_request)3170 void qdf_dp_trace_throttle_live_mode(bool high_bw_request) 3171 { 3172 static int bw_interval_counter; 3173 3174 if (g_qdf_dp_trace_data.enable == false || 3175 g_qdf_dp_trace_data.live_mode_config == false) 3176 return; 3177 3178 if (high_bw_request) { 3179 g_qdf_dp_trace_data.live_mode = 0; 3180 bw_interval_counter = 0; 3181 return; 3182 } 3183 3184 bw_interval_counter++; 3185 3186 if (0 == (bw_interval_counter % 3187 g_qdf_dp_trace_data.thresh_time_limit)) { 3188 3189 spin_lock_bh(&l_dp_trace_lock); 3190 if (g_qdf_dp_trace_data.print_pkt_cnt <= 3191 g_qdf_dp_trace_data.high_tput_thresh) 3192 g_qdf_dp_trace_data.live_mode = 1; 3193 3194 g_qdf_dp_trace_data.print_pkt_cnt = 0; 3195 spin_unlock_bh(&l_dp_trace_lock); 3196 } 3197 } 3198 qdf_export_symbol(qdf_dp_trace_throttle_live_mode); 3199 qdf_dp_trace_apply_tput_policy(bool is_data_traffic)3200 void qdf_dp_trace_apply_tput_policy(bool is_data_traffic) 3201 { 3202 if (g_qdf_dp_trace_data.dynamic_verbosity_modify) { 3203 goto check_live_mode; 3204 return; 3205 } 3206 3207 if (is_data_traffic) { 3208 g_qdf_dp_trace_data.verbosity = 3209 QDF_DP_TRACE_VERBOSITY_ULTRA_LOW; 3210 } else { 3211 g_qdf_dp_trace_data.verbosity = 3212 g_qdf_dp_trace_data.ini_conf_verbosity; 3213 } 3214 check_live_mode: 3215 qdf_dp_trace_throttle_live_mode(is_data_traffic); 3216 } 3217 #endif 3218 3219 struct qdf_print_ctrl print_ctrl_obj[MAX_PRINT_CONFIG_SUPPORTED]; 3220 3221 struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = { 3222 [QDF_MODULE_ID_TDLS] = {"tdls"}, 3223 [QDF_MODULE_ID_ACS] = {"ACS"}, 3224 [QDF_MODULE_ID_SCAN_SM] = {"scan state machine"}, 3225 [QDF_MODULE_ID_SCANENTRY] = {"scan entry"}, 3226 [QDF_MODULE_ID_WDS] = {"WDS"}, 3227 [QDF_MODULE_ID_ACTION] = {"action"}, 3228 [QDF_MODULE_ID_ROAM] = {"STA roaming"}, 3229 [QDF_MODULE_ID_INACT] = {"inactivity"}, 3230 [QDF_MODULE_ID_DOTH] = {"11h"}, 3231 [QDF_MODULE_ID_IQUE] = {"IQUE"}, 3232 [QDF_MODULE_ID_WME] = {"WME"}, 3233 [QDF_MODULE_ID_ACL] = {"ACL"}, 3234 [QDF_MODULE_ID_WPA] = {"WPA/RSN"}, 3235 [QDF_MODULE_ID_RADKEYS] = {"dump 802.1x keys"}, 3236 [QDF_MODULE_ID_RADDUMP] = {"dump radius packet"}, 3237 [QDF_MODULE_ID_RADIUS] = {"802.1x radius client"}, 3238 [QDF_MODULE_ID_DOT1XSM] = {"802.1x state machine"}, 3239 [QDF_MODULE_ID_DOT1X] = {"802.1x authenticator"}, 3240 [QDF_MODULE_ID_POWER] = {"power save"}, 3241 [QDF_MODULE_ID_STATE] = {"state"}, 3242 [QDF_MODULE_ID_OUTPUT] = {"output"}, 3243 [QDF_MODULE_ID_SCAN] = {"scan"}, 3244 [QDF_MODULE_ID_AUTH] = {"authentication"}, 3245 [QDF_MODULE_ID_ASSOC] = {"association"}, 3246 [QDF_MODULE_ID_NODE] = {"node"}, 3247 [QDF_MODULE_ID_ELEMID] = {"element ID"}, 3248 [QDF_MODULE_ID_XRATE] = {"rate"}, 3249 [QDF_MODULE_ID_INPUT] = {"input"}, 3250 [QDF_MODULE_ID_CRYPTO] = {"crypto"}, 3251 [QDF_MODULE_ID_DUMPPKTS] = {"dump packet"}, 3252 [QDF_MODULE_ID_DEBUG] = {"debug"}, 3253 [QDF_MODULE_ID_MLME] = {"mlme"}, 3254 [QDF_MODULE_ID_RRM] = {"rrm"}, 3255 [QDF_MODULE_ID_WNM] = {"wnm"}, 3256 [QDF_MODULE_ID_P2P_PROT] = {"p2p_prot"}, 3257 [QDF_MODULE_ID_PROXYARP] = {"proxyarp"}, 3258 [QDF_MODULE_ID_L2TIF] = {"l2tif"}, 3259 [QDF_MODULE_ID_WIFIPOS] = {"wifipos"}, 3260 [QDF_MODULE_ID_WRAP] = {"wrap"}, 3261 [QDF_MODULE_ID_DFS] = {"dfs"}, 3262 [QDF_MODULE_ID_ATF] = {"atf"}, 3263 [QDF_MODULE_ID_SPLITMAC] = {"splitmac"}, 3264 [QDF_MODULE_ID_IOCTL] = {"ioctl"}, 3265 [QDF_MODULE_ID_NAC] = {"nac"}, 3266 [QDF_MODULE_ID_MESH] = {"mesh"}, 3267 [QDF_MODULE_ID_MBO] = {"mbo"}, 3268 [QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = {"extchanswitch"}, 3269 [QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = {"extchanscan"}, 3270 [QDF_MODULE_ID_TLSHIM] = {"tlshim"}, 3271 [QDF_MODULE_ID_WMI] = {"WMI"}, 3272 [QDF_MODULE_ID_HTT] = {"HTT"}, 3273 [QDF_MODULE_ID_HDD] = {"HDD"}, 3274 [QDF_MODULE_ID_SME] = {"SME"}, 3275 [QDF_MODULE_ID_PE] = {"PE"}, 3276 [QDF_MODULE_ID_WMA] = {"WMA"}, 3277 [QDF_MODULE_ID_SYS] = {"SYS"}, 3278 [QDF_MODULE_ID_QDF] = {"QDF"}, 3279 [QDF_MODULE_ID_SAP] = {"SAP"}, 3280 [QDF_MODULE_ID_HDD_SOFTAP] = {"HDD_SAP"}, 3281 [QDF_MODULE_ID_HDD_DATA] = {"DATA"}, 3282 [QDF_MODULE_ID_HDD_SAP_DATA] = {"SAP_DATA"}, 3283 [QDF_MODULE_ID_HIF] = {"HIF"}, 3284 [QDF_MODULE_ID_HTC] = {"HTC"}, 3285 [QDF_MODULE_ID_TXRX] = {"TXRX"}, 3286 [QDF_MODULE_ID_QDF_DEVICE] = {"QDF_DEV"}, 3287 [QDF_MODULE_ID_CFG] = {"CFG"}, 3288 [QDF_MODULE_ID_BMI] = {"BMI"}, 3289 [QDF_MODULE_ID_EPPING] = {"EPPING"}, 3290 [QDF_MODULE_ID_QVIT] = {"QVIT"}, 3291 [QDF_MODULE_ID_DP] = {"DP"}, 3292 [QDF_MODULE_ID_HAL] = {"HAL"}, 3293 [QDF_MODULE_ID_SOC] = {"SOC"}, 3294 [QDF_MODULE_ID_OS_IF] = {"OSIF"}, 3295 [QDF_MODULE_ID_TARGET_IF] = {"TIF"}, 3296 [QDF_MODULE_ID_SCHEDULER] = {"SCH"}, 3297 [QDF_MODULE_ID_MGMT_TXRX] = {"MGMT_TXRX"}, 3298 [QDF_MODULE_ID_PMO] = {"PMO"}, 3299 [QDF_MODULE_ID_POLICY_MGR] = {"POLICY_MGR"}, 3300 [QDF_MODULE_ID_SA_API] = {"SA_API"}, 3301 [QDF_MODULE_ID_NAN] = {"NAN"}, 3302 [QDF_MODULE_ID_SPECTRAL] = {"SPECTRAL"}, 3303 [QDF_MODULE_ID_P2P] = {"P2P"}, 3304 [QDF_MODULE_ID_OFFCHAN_TXRX] = {"OFFCHAN"}, 3305 [QDF_MODULE_ID_REGULATORY] = {"REGULATORY"}, 3306 [QDF_MODULE_ID_OBJ_MGR] = {"OBJMGR"}, 3307 [QDF_MODULE_ID_SERIALIZATION] = {"SER"}, 3308 [QDF_MODULE_ID_NSS] = {"NSS"}, 3309 [QDF_MODULE_ID_ROAM_DEBUG] = {"roam debug"}, 3310 [QDF_MODULE_ID_DIRECT_BUF_RX] = {"DIRECT_BUF_RX"}, 3311 [QDF_MODULE_ID_DISA] = {"disa"}, 3312 [QDF_MODULE_ID_GREEN_AP] = {"GREEN_AP"}, 3313 [QDF_MODULE_ID_FD] = {"FILS discovery"}, 3314 [QDF_MODULE_ID_FTM] = {"FTM"}, 3315 [QDF_MODULE_ID_OCB] = {"OCB"}, 3316 [QDF_MODULE_ID_CONFIG] = {"CONFIG"}, 3317 [QDF_MODULE_ID_IPA] = {"IPA"}, 3318 [QDF_MODULE_ID_CP_STATS] = {"CP_STATS"}, 3319 [QDF_MODULE_ID_DCS] = {"DCS"}, 3320 [QDF_MODULE_ID_ACTION_OUI] = {"action_oui"}, 3321 [QDF_MODULE_ID_TARGET] = {"TARGET"}, 3322 [QDF_MODULE_ID_MBSSIE] = {"MBSSIE"}, 3323 [QDF_MODULE_ID_FWOL] = {"fwol"}, 3324 [QDF_MODULE_ID_SM_ENGINE] = {"SM_ENG"}, 3325 [QDF_MODULE_ID_CMN_MLME] = {"CMN_MLME"}, 3326 [QDF_MODULE_ID_BSSCOLOR] = {"BSSCOLOR"}, 3327 [QDF_MODULE_ID_CFR] = {"CFR"}, 3328 [QDF_MODULE_ID_DP_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"}, 3329 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"}, 3330 [QDF_MODULE_ID_DENYLIST_MGR] = {"dlm"}, 3331 [QDF_MODULE_ID_QLD] = {"QLD"}, 3332 [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = {"Dynamic Mode Change"}, 3333 [QDF_MODULE_ID_COEX] = {"COEX"}, 3334 [QDF_MODULE_ID_MON_FILTER] = {"Monitor Filter"}, 3335 [QDF_MODULE_ID_PKT_CAPTURE] = {"pkt_capture"}, 3336 [QDF_MODULE_ID_RPTR] = {"RPTR"}, 3337 [QDF_MODULE_ID_6GHZ] = {"6GHZ"}, 3338 [QDF_MODULE_ID_IOT_SIM] = {"IOT_SIM"}, 3339 [QDF_MODULE_ID_MSCS] = {"MSCS"}, 3340 [QDF_MODULE_ID_GPIO] = {"GPIO_CFG"}, 3341 [QDF_MODULE_ID_IFMGR] = {"IF_MGR"}, 3342 [QDF_MODULE_ID_DIAG] = {"DIAG"}, 3343 [QDF_MODULE_ID_DP_INIT] = {"DP_INIT"}, 3344 [QDF_MODULE_ID_DP_TX] = {"DP_TX"}, 3345 [QDF_MODULE_ID_DP_RX] = {"DP_RX"}, 3346 [QDF_MODULE_ID_DP_STATS] = {"DP_STATS"}, 3347 [QDF_MODULE_ID_DP_HTT] = {"DP_HTT"}, 3348 [QDF_MODULE_ID_DP_PEER] = {"DP_PEER"}, 3349 [QDF_MODULE_ID_DP_RX_ERROR] = {"DP_RX_ERROR"}, 3350 [QDF_MODULE_ID_DP_HTT_TX_STATS] = {"DP_HTT_TX_STATS"}, 3351 [QDF_MODULE_ID_DP_RX_MON_STATUS] = {"DP_RX_MON_STATUS"}, 3352 [QDF_MODULE_ID_DP_RX_MON_DEST] = {"DP_RX_MON_DEST"}, 3353 [QDF_MODULE_ID_DP_REO] = {"DP_REO"}, 3354 [QDF_MODULE_ID_DP_TX_COMP] = {"DP_TX_COMP"}, 3355 [QDF_MODULE_ID_DP_VDEV] = {"DP_VDEV"}, 3356 [QDF_MODULE_ID_DP_CDP] = {"DP_CDP"}, 3357 [QDF_MODULE_ID_TSO] = {"TSO"}, 3358 [QDF_MODULE_ID_ME] = {"ME"}, 3359 [QDF_MODULE_ID_QWRAP] = {"QWRAP"}, 3360 [QDF_MODULE_ID_DBDC_REP] = {"DBDC_REP"}, 3361 [QDF_MODULE_ID_EXT_AP] = {"EXT_AP"}, 3362 [QDF_MODULE_ID_MLO] = {"MLO_MGR"}, 3363 [QDF_MODULE_ID_MGMT_RX_REO] = {"MGMT_RX_REO"}, 3364 [QDF_MODULE_ID_MLOIE] = {"MLOIE"}, 3365 [QDF_MODULE_ID_MBSS] = {"MBSS"}, 3366 [QDF_MODULE_ID_MON] = {"MONITOR"}, 3367 [QDF_MODULE_ID_AFC] = {"AFC"}, 3368 [QDF_MODULE_ID_TWT] = {"TWT"}, 3369 [QDF_MODULE_ID_SON] = {"SON"}, 3370 [QDF_MODULE_ID_WLAN_PRE_CAC] = {"PRE_CAC"}, 3371 [QDF_MODULE_ID_T2LM] = {"T2LM"}, 3372 [QDF_MODULE_ID_DP_SAWF] = {"DP_SAWF"}, 3373 [QDF_MODULE_ID_SCS] = {"SCS"}, 3374 [QDF_MODULE_ID_DP_UMAC_RESET] = {"UMAC_HW_RESET"}, 3375 [QDF_MODULE_ID_COAP] = {"COAP"}, 3376 [QDF_MODULE_ID_FTM_TIME_SYNC] = {"Time Sync"}, 3377 [QDF_MODULE_ID_WIFI_RADAR] = {"WIFI RADAR"}, 3378 [QDF_MODULE_ID_CDP] = {"CDP"}, 3379 [QDF_MODULE_ID_QMI] = {"QMI"}, 3380 [QDF_MODULE_ID_SOUNDING] = {"SOUNDING"}, 3381 [QDF_MODULE_ID_SAWF] = {"SAWF"}, 3382 [QDF_MODULE_ID_EPCS] = {"EPCS"}, 3383 [QDF_MODULE_ID_LL_SAP] = {"LL_SAP"}, 3384 [QDF_MODULE_ID_COHOSTED_BSS] = {"COHOSTED_BSS"}, 3385 [QDF_MODULE_ID_TELEMETRY_AGENT] = {"TELEMETRY_AGENT"}, 3386 [QDF_MODULE_ID_RF_PATH_SWITCH] = {"Dynamic RF Path Switch"}, 3387 [QDF_MODULE_ID_ANY] = {"ANY"}, 3388 }; 3389 qdf_export_symbol(g_qdf_category_name); 3390 qdf_trace_display(void)3391 void qdf_trace_display(void) 3392 { 3393 QDF_MODULE_ID module_id; 3394 3395 pr_err(" 1)FATAL 2)ERROR 3)WARN 4)INFO 5)INFO_H 6)INFO_M 7)INFO_L 8)DEBUG\n"); 3396 for (module_id = 0; module_id < QDF_MODULE_ID_MAX; ++module_id) { 3397 pr_err("%2d)%s %s %s %s %s %s %s %s %s\n", 3398 (int)module_id, 3399 g_qdf_category_name[module_id].category_name_str, 3400 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3401 QDF_TRACE_LEVEL_FATAL) ? "X" : " ", 3402 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3403 QDF_TRACE_LEVEL_ERROR) ? "X" : " ", 3404 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3405 QDF_TRACE_LEVEL_WARN) ? "X" : " ", 3406 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3407 QDF_TRACE_LEVEL_INFO) ? "X" : " ", 3408 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3409 QDF_TRACE_LEVEL_INFO_HIGH) ? "X" : " ", 3410 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3411 QDF_TRACE_LEVEL_INFO_MED) ? "X" : " ", 3412 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3413 QDF_TRACE_LEVEL_INFO_LOW) ? "X" : " ", 3414 qdf_print_is_verbose_enabled(qdf_pidx, module_id, 3415 QDF_TRACE_LEVEL_DEBUG) ? "X" : " "); 3416 } 3417 } 3418 qdf_export_symbol(qdf_trace_display); 3419 3420 #ifdef WLAN_MAX_LOGS_PER_SEC 3421 static qdf_time_t __log_window_end; 3422 static qdf_atomic_t __log_window_count; 3423 uint32_t qdf_rl_print_count = WLAN_MAX_LOGS_PER_SEC; 3424 uint32_t qdf_rl_print_time = 1; 3425 uint32_t qdf_rl_print_suppressed; 3426 qdf_detected_excessive_logging(void)3427 bool qdf_detected_excessive_logging(void) 3428 { 3429 qdf_time_t now = qdf_system_ticks(); 3430 bool excessive_prints = false; 3431 3432 /* 3433 * If 'now' is more recent than the end of the window, reset. 3434 * 3435 * Note: This is not thread safe, and can result in more than one reset. 3436 * For our purposes, this is fine. 3437 */ 3438 if (!qdf_atomic_read(&__log_window_count)) { 3439 __log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time); 3440 } else if (qdf_system_time_after(now, __log_window_end)) { 3441 __log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time); 3442 qdf_atomic_set(&__log_window_count, 0); 3443 } 3444 3445 if (qdf_atomic_inc_return(&__log_window_count) > qdf_rl_print_count) 3446 excessive_prints = true; 3447 3448 return excessive_prints; 3449 } 3450 qdf_rl_print_count_set(uint32_t rl_print_count)3451 void qdf_rl_print_count_set(uint32_t rl_print_count) 3452 { 3453 qdf_rl_print_count = rl_print_count; 3454 } 3455 3456 qdf_export_symbol(qdf_rl_print_count_set); 3457 qdf_rl_print_time_set(uint32_t rl_print_time)3458 void qdf_rl_print_time_set(uint32_t rl_print_time) 3459 { 3460 qdf_rl_print_time = rl_print_time; 3461 } 3462 3463 qdf_export_symbol(qdf_rl_print_time_set); 3464 qdf_rl_print_suppressed_log(void)3465 void qdf_rl_print_suppressed_log(void) 3466 { 3467 if (qdf_rl_print_suppressed) { 3468 pr_err("QDF Ratelimiting: %d prints suppressed", 3469 qdf_rl_print_suppressed); 3470 qdf_rl_print_suppressed = 0; 3471 } 3472 } 3473 qdf_rl_print_suppressed_inc(void)3474 void qdf_rl_print_suppressed_inc(void) 3475 { 3476 qdf_rl_print_suppressed++; 3477 } 3478 #else 3479 #define qdf_rl_print_suppressed_log() 3480 #define qdf_rl_print_suppressed_inc() 3481 #endif /* WLAN_MAX_LOGS_PER_SEC */ 3482 3483 #ifdef QDF_TRACE_PRINT_ENABLE print_to_console(char * str_buffer)3484 static inline void print_to_console(char *str_buffer) 3485 { 3486 if (qdf_in_interrupt() && qdf_detected_excessive_logging()) { 3487 qdf_rl_print_suppressed_inc(); 3488 return; 3489 } 3490 qdf_rl_print_suppressed_log(); 3491 pr_err("%s\n", str_buffer); 3492 } 3493 #else 3494 3495 #define print_to_console(str) 3496 #endif 3497 3498 #ifdef MULTI_IF_NAME qdf_trace_wlan_modname(void)3499 static const char *qdf_trace_wlan_modname(void) 3500 { 3501 return MULTI_IF_NAME; 3502 } 3503 #else qdf_trace_wlan_modname(void)3504 static const char *qdf_trace_wlan_modname(void) 3505 { 3506 return "wlan"; 3507 } 3508 #endif 3509 qdf_trace_msg_cmn(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose,const char * str_format,va_list val)3510 void qdf_trace_msg_cmn(unsigned int idx, 3511 QDF_MODULE_ID category, 3512 QDF_TRACE_LEVEL verbose, 3513 const char *str_format, va_list val) 3514 { 3515 char str_buffer[QDF_TRACE_BUFFER_SIZE]; 3516 int n; 3517 3518 /* Check if index passed is valid */ 3519 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 3520 pr_info("%s: Invalid index - %d\n", __func__, idx); 3521 return; 3522 } 3523 3524 /* Check if print control object is in use */ 3525 if (!print_ctrl_obj[idx].in_use) { 3526 pr_info("%s: Invalid print control object\n", __func__); 3527 return; 3528 } 3529 3530 /* Check if category passed is valid */ 3531 if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) { 3532 vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val); 3533 pr_info("%s: Invalid category: %d, log: %s\n", 3534 __func__, category, str_buffer); 3535 return; 3536 } 3537 3538 /* Check if verbose mask is valid */ 3539 if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) { 3540 vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val); 3541 pr_info("%s: Invalid verbose level %d, log: %s\n", 3542 __func__, verbose, str_buffer); 3543 return; 3544 } 3545 3546 /* 3547 * Print the trace message when the desired verbose level is set in 3548 * the desired category for the print control object 3549 */ 3550 if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask & 3551 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) { 3552 static const char * const VERBOSE_STR[] = { 3553 [QDF_TRACE_LEVEL_NONE] = "", 3554 [QDF_TRACE_LEVEL_FATAL] = "F", 3555 [QDF_TRACE_LEVEL_ERROR] = "E", 3556 [QDF_TRACE_LEVEL_WARN] = "W", 3557 [QDF_TRACE_LEVEL_INFO] = "I", 3558 [QDF_TRACE_LEVEL_INFO_HIGH] = "IH", 3559 [QDF_TRACE_LEVEL_INFO_MED] = "IM", 3560 [QDF_TRACE_LEVEL_INFO_LOW] = "IL", 3561 [QDF_TRACE_LEVEL_DEBUG] = "D", 3562 [QDF_TRACE_LEVEL_TRACE] = "T", 3563 [QDF_TRACE_LEVEL_ALL] = "" }; 3564 3565 /* print the prefix string into the string buffer... */ 3566 n = scnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, 3567 "%s: [%d:%s:%s] ", qdf_trace_wlan_modname(), 3568 in_interrupt() ? 0 : current->pid, 3569 VERBOSE_STR[verbose], 3570 g_qdf_category_name[category].category_name_str); 3571 3572 /* print the formatted log message after the prefix string */ 3573 vscnprintf(str_buffer + n, QDF_TRACE_BUFFER_SIZE - n, 3574 str_format, val); 3575 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE) 3576 wlan_log_to_user(verbose, (char *)str_buffer, 3577 strlen(str_buffer)); 3578 if (qdf_unlikely(qdf_log_dump_at_kernel_enable)) 3579 print_to_console(str_buffer); 3580 #else 3581 pr_err("%s\n", str_buffer); 3582 #endif 3583 } 3584 } 3585 qdf_export_symbol(qdf_trace_msg_cmn); 3586 qdf_print_setup(void)3587 QDF_STATUS qdf_print_setup(void) 3588 { 3589 int i; 3590 3591 /* Loop through all print ctrl objects */ 3592 for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) { 3593 if (qdf_print_ctrl_cleanup(i)) 3594 return QDF_STATUS_E_FAILURE; 3595 } 3596 return QDF_STATUS_SUCCESS; 3597 } 3598 qdf_export_symbol(qdf_print_setup); 3599 qdf_print_ctrl_cleanup(unsigned int idx)3600 QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx) 3601 { 3602 int i = 0; 3603 3604 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 3605 pr_info("%s: Invalid index - %d\n", __func__, idx); 3606 return QDF_STATUS_E_FAILURE; 3607 } 3608 3609 /* Clean up the print control object corresponding to that index 3610 * If success, callee to change print control index to -1 3611 */ 3612 3613 for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { 3614 print_ctrl_obj[idx].cat_info[i].category_verbose_mask = 3615 QDF_TRACE_LEVEL_NONE; 3616 } 3617 print_ctrl_obj[idx].custom_print = NULL; 3618 print_ctrl_obj[idx].custom_ctxt = NULL; 3619 qdf_print_clean_node_flag(idx); 3620 print_ctrl_obj[idx].in_use = false; 3621 3622 return QDF_STATUS_SUCCESS; 3623 } 3624 qdf_export_symbol(qdf_print_ctrl_cleanup); 3625 qdf_print_ctrl_register(const struct category_info * cinfo,void * custom_print_handler,void * custom_ctx,const char * pctrl_name)3626 int qdf_print_ctrl_register(const struct category_info *cinfo, 3627 void *custom_print_handler, 3628 void *custom_ctx, 3629 const char *pctrl_name) 3630 { 3631 int idx = -1; 3632 int i = 0; 3633 3634 for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) { 3635 if (!print_ctrl_obj[i].in_use) { 3636 idx = i; 3637 break; 3638 } 3639 } 3640 3641 /* Callee to handle idx -1 appropriately */ 3642 if (idx == -1) { 3643 pr_info("%s: Allocation failed! No print control object free\n", 3644 __func__); 3645 return idx; 3646 } 3647 3648 print_ctrl_obj[idx].in_use = true; 3649 3650 /* 3651 * In case callee does not pass category info, 3652 * custom print handler, custom context and print control name, 3653 * we do not set any value here. Clean up for the print control 3654 * getting allocated would have taken care of initializing 3655 * default values. 3656 * 3657 * We need to only set in_use to 1 in such a case 3658 */ 3659 3660 if (pctrl_name) { 3661 qdf_str_lcopy(print_ctrl_obj[idx].name, pctrl_name, 3662 sizeof(print_ctrl_obj[idx].name)); 3663 } 3664 3665 if (custom_print_handler) 3666 print_ctrl_obj[idx].custom_print = custom_print_handler; 3667 3668 if (custom_ctx) 3669 print_ctrl_obj[idx].custom_ctxt = custom_ctx; 3670 3671 if (cinfo) { 3672 for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { 3673 if (cinfo[i].category_verbose_mask == 3674 QDF_TRACE_LEVEL_ALL) { 3675 print_ctrl_obj[idx].cat_info[i] 3676 .category_verbose_mask = 0xFFFF; 3677 } else if ((cinfo[i].category_verbose_mask == 3678 QDF_TRACE_LEVEL_NONE) || 3679 (cinfo[i].category_verbose_mask == 3680 QDF_TRACE_LEVEL_TO_MODULE_BITMASK( 3681 QDF_TRACE_LEVEL_NONE))) { 3682 print_ctrl_obj[idx].cat_info[i] 3683 .category_verbose_mask = 0; 3684 } else { 3685 print_ctrl_obj[idx].cat_info[i] 3686 .category_verbose_mask = 3687 cinfo[i].category_verbose_mask; 3688 } 3689 } 3690 } 3691 3692 return idx; 3693 } 3694 qdf_export_symbol(qdf_print_ctrl_register); 3695 3696 #ifdef QDF_TRACE_PRINT_ENABLE qdf_shared_print_ctrl_cleanup(void)3697 void qdf_shared_print_ctrl_cleanup(void) 3698 { 3699 qdf_print_ctrl_cleanup(qdf_pidx); 3700 } 3701 qdf_export_symbol(qdf_shared_print_ctrl_cleanup); 3702 3703 /* 3704 * Set this to invalid value to differentiate with user-provided 3705 * value. 3706 */ 3707 int qdf_dbg_mask = QDF_TRACE_LEVEL_MAX; 3708 qdf_export_symbol(qdf_dbg_mask); 3709 qdf_declare_param(qdf_dbg_mask, int); 3710 3711 /* 3712 * QDF can be passed parameters which indicate the 3713 * debug level for each module. 3714 * an array of string values are passed, each string hold the following form 3715 * 3716 * <module name string>=<integer debug level value> 3717 * 3718 * The array qdf_dbg_arr will hold these module-string=value strings 3719 * The variable qdf_dbg_arr_cnt will have the count of how many such 3720 * string values were passed. 3721 */ 3722 static char *qdf_dbg_arr[QDF_MODULE_ID_MAX]; 3723 static int qdf_dbg_arr_cnt; 3724 qdf_declare_param_array(qdf_dbg_arr, charp, &qdf_dbg_arr_cnt); 3725 set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level)3726 static uint16_t set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level) 3727 { 3728 uint16_t category_verbose_mask = 0; 3729 QDF_TRACE_LEVEL level; 3730 3731 for (level = QDF_TRACE_LEVEL_FATAL; level <= max_level; level++) { 3732 category_verbose_mask |= 3733 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level); 3734 } 3735 return category_verbose_mask; 3736 } 3737 find_qdf_module_from_string(char * str)3738 static QDF_MODULE_ID find_qdf_module_from_string(char *str) 3739 { 3740 QDF_MODULE_ID mod_id; 3741 3742 for (mod_id = 0; mod_id < QDF_MODULE_ID_MAX; mod_id++) { 3743 if (strcasecmp(str, 3744 g_qdf_category_name[mod_id].category_name_str) 3745 == 0) { 3746 break; 3747 } 3748 } 3749 return mod_id; 3750 } 3751 process_qdf_dbg_arr_param(struct category_info * cinfo,int array_index)3752 static void process_qdf_dbg_arr_param(struct category_info *cinfo, 3753 int array_index) 3754 { 3755 char *mod_val_str, *mod_str, *val_str; 3756 unsigned long dbg_level; 3757 QDF_MODULE_ID mod_id; 3758 3759 mod_val_str = qdf_dbg_arr[array_index]; 3760 mod_str = strsep(&mod_val_str, "="); 3761 val_str = mod_val_str; 3762 if (!val_str) { 3763 pr_info("qdf_dbg_arr: %s not in the <mod>=<val> form\n", 3764 mod_str); 3765 return; 3766 } 3767 3768 mod_id = find_qdf_module_from_string(mod_str); 3769 if (mod_id >= QDF_MODULE_ID_MAX) { 3770 pr_info("ERROR!!Module name %s not in the list of modules\n", 3771 mod_str); 3772 return; 3773 } 3774 3775 if (kstrtol(val_str, 10, &dbg_level) < 0) { 3776 pr_info("ERROR!!Invalid debug level for module: %s\n", 3777 mod_str); 3778 return; 3779 } 3780 3781 if (dbg_level >= QDF_TRACE_LEVEL_MAX) { 3782 pr_info("ERROR!!Debug level for %s too high", mod_str); 3783 pr_info("max: %d given %lu\n", QDF_TRACE_LEVEL_MAX, 3784 dbg_level); 3785 return; 3786 } 3787 3788 pr_info("User passed setting module %s(%d) to level %lu\n", 3789 mod_str, 3790 mod_id, 3791 dbg_level); 3792 cinfo[mod_id].category_verbose_mask = 3793 set_cumulative_verbose_mask((QDF_TRACE_LEVEL)dbg_level); 3794 } 3795 set_default_trace_levels(struct category_info * cinfo)3796 static void set_default_trace_levels(struct category_info *cinfo) 3797 { 3798 int i; 3799 static QDF_TRACE_LEVEL module_trace_default_level[QDF_MODULE_ID_MAX] = { 3800 [QDF_MODULE_ID_TDLS] = QDF_TRACE_LEVEL_NONE, 3801 [QDF_MODULE_ID_ACS] = QDF_TRACE_LEVEL_NONE, 3802 [QDF_MODULE_ID_SCAN_SM] = QDF_TRACE_LEVEL_NONE, 3803 [QDF_MODULE_ID_SCANENTRY] = QDF_TRACE_LEVEL_NONE, 3804 [QDF_MODULE_ID_WDS] = QDF_TRACE_LEVEL_NONE, 3805 [QDF_MODULE_ID_ACTION] = QDF_TRACE_LEVEL_NONE, 3806 [QDF_MODULE_ID_ROAM] = QDF_TRACE_LEVEL_NONE, 3807 [QDF_MODULE_ID_INACT] = QDF_TRACE_LEVEL_NONE, 3808 [QDF_MODULE_ID_DOTH] = QDF_TRACE_LEVEL_NONE, 3809 [QDF_MODULE_ID_IQUE] = QDF_TRACE_LEVEL_NONE, 3810 [QDF_MODULE_ID_WME] = QDF_TRACE_LEVEL_NONE, 3811 [QDF_MODULE_ID_ACL] = QDF_TRACE_LEVEL_NONE, 3812 [QDF_MODULE_ID_WPA] = QDF_TRACE_LEVEL_NONE, 3813 [QDF_MODULE_ID_RADKEYS] = QDF_TRACE_LEVEL_NONE, 3814 [QDF_MODULE_ID_RADDUMP] = QDF_TRACE_LEVEL_NONE, 3815 [QDF_MODULE_ID_RADIUS] = QDF_TRACE_LEVEL_NONE, 3816 [QDF_MODULE_ID_DOT1XSM] = QDF_TRACE_LEVEL_NONE, 3817 [QDF_MODULE_ID_DOT1X] = QDF_TRACE_LEVEL_NONE, 3818 [QDF_MODULE_ID_POWER] = QDF_TRACE_LEVEL_NONE, 3819 [QDF_MODULE_ID_STATE] = QDF_TRACE_LEVEL_NONE, 3820 [QDF_MODULE_ID_OUTPUT] = QDF_TRACE_LEVEL_NONE, 3821 [QDF_MODULE_ID_SCAN] = QDF_TRACE_LEVEL_ERROR, 3822 [QDF_MODULE_ID_AUTH] = QDF_TRACE_LEVEL_NONE, 3823 [QDF_MODULE_ID_ASSOC] = QDF_TRACE_LEVEL_NONE, 3824 [QDF_MODULE_ID_NODE] = QDF_TRACE_LEVEL_NONE, 3825 [QDF_MODULE_ID_ELEMID] = QDF_TRACE_LEVEL_NONE, 3826 [QDF_MODULE_ID_XRATE] = QDF_TRACE_LEVEL_NONE, 3827 [QDF_MODULE_ID_INPUT] = QDF_TRACE_LEVEL_NONE, 3828 [QDF_MODULE_ID_CRYPTO] = QDF_TRACE_LEVEL_NONE, 3829 [QDF_MODULE_ID_DUMPPKTS] = QDF_TRACE_LEVEL_NONE, 3830 [QDF_MODULE_ID_DEBUG] = QDF_TRACE_LEVEL_NONE, 3831 [QDF_MODULE_ID_MLME] = QDF_TRACE_LEVEL_ERROR, 3832 [QDF_MODULE_ID_RRM] = QDF_TRACE_LEVEL_NONE, 3833 [QDF_MODULE_ID_WNM] = QDF_TRACE_LEVEL_NONE, 3834 [QDF_MODULE_ID_P2P_PROT] = QDF_TRACE_LEVEL_NONE, 3835 [QDF_MODULE_ID_PROXYARP] = QDF_TRACE_LEVEL_NONE, 3836 [QDF_MODULE_ID_L2TIF] = QDF_TRACE_LEVEL_NONE, 3837 [QDF_MODULE_ID_WIFIPOS] = QDF_TRACE_LEVEL_NONE, 3838 [QDF_MODULE_ID_WRAP] = QDF_TRACE_LEVEL_NONE, 3839 [QDF_MODULE_ID_DFS] = QDF_TRACE_LEVEL_NONE, 3840 [QDF_MODULE_ID_ATF] = QDF_TRACE_LEVEL_ERROR, 3841 [QDF_MODULE_ID_SPLITMAC] = QDF_TRACE_LEVEL_NONE, 3842 [QDF_MODULE_ID_IOCTL] = QDF_TRACE_LEVEL_NONE, 3843 [QDF_MODULE_ID_NAC] = QDF_TRACE_LEVEL_NONE, 3844 [QDF_MODULE_ID_MESH] = QDF_TRACE_LEVEL_NONE, 3845 [QDF_MODULE_ID_MBO] = QDF_TRACE_LEVEL_NONE, 3846 [QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = QDF_TRACE_LEVEL_NONE, 3847 [QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = QDF_TRACE_LEVEL_NONE, 3848 [QDF_MODULE_ID_TLSHIM] = QDF_TRACE_LEVEL_NONE, 3849 [QDF_MODULE_ID_WMI] = QDF_TRACE_LEVEL_ERROR, 3850 [QDF_MODULE_ID_HTT] = QDF_TRACE_LEVEL_NONE, 3851 [QDF_MODULE_ID_HDD] = QDF_TRACE_LEVEL_NONE, 3852 [QDF_MODULE_ID_SME] = QDF_TRACE_LEVEL_NONE, 3853 [QDF_MODULE_ID_PE] = QDF_TRACE_LEVEL_NONE, 3854 [QDF_MODULE_ID_WMA] = QDF_TRACE_LEVEL_NONE, 3855 [QDF_MODULE_ID_SYS] = QDF_TRACE_LEVEL_NONE, 3856 [QDF_MODULE_ID_QDF] = QDF_TRACE_LEVEL_ERROR, 3857 [QDF_MODULE_ID_SAP] = QDF_TRACE_LEVEL_NONE, 3858 [QDF_MODULE_ID_HDD_SOFTAP] = QDF_TRACE_LEVEL_NONE, 3859 [QDF_MODULE_ID_HDD_DATA] = QDF_TRACE_LEVEL_NONE, 3860 [QDF_MODULE_ID_HDD_SAP_DATA] = QDF_TRACE_LEVEL_NONE, 3861 [QDF_MODULE_ID_HIF] = QDF_TRACE_LEVEL_ERROR, 3862 [QDF_MODULE_ID_HTC] = QDF_TRACE_LEVEL_NONE, 3863 [QDF_MODULE_ID_TXRX] = QDF_TRACE_LEVEL_NONE, 3864 [QDF_MODULE_ID_QDF_DEVICE] = QDF_TRACE_LEVEL_NONE, 3865 [QDF_MODULE_ID_CFG] = QDF_TRACE_LEVEL_NONE, 3866 [QDF_MODULE_ID_BMI] = QDF_TRACE_LEVEL_NONE, 3867 [QDF_MODULE_ID_EPPING] = QDF_TRACE_LEVEL_NONE, 3868 [QDF_MODULE_ID_QVIT] = QDF_TRACE_LEVEL_NONE, 3869 [QDF_MODULE_ID_DP] = QDF_TRACE_LEVEL_FATAL, 3870 [QDF_MODULE_ID_HAL] = QDF_TRACE_LEVEL_NONE, 3871 [QDF_MODULE_ID_SOC] = QDF_TRACE_LEVEL_NONE, 3872 [QDF_MODULE_ID_OS_IF] = QDF_TRACE_LEVEL_NONE, 3873 [QDF_MODULE_ID_TARGET_IF] = QDF_TRACE_LEVEL_INFO, 3874 [QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_FATAL, 3875 [QDF_MODULE_ID_MGMT_TXRX] = QDF_TRACE_LEVEL_NONE, 3876 [QDF_MODULE_ID_SERIALIZATION] = QDF_TRACE_LEVEL_ERROR, 3877 [QDF_MODULE_ID_PMO] = QDF_TRACE_LEVEL_NONE, 3878 [QDF_MODULE_ID_P2P] = QDF_TRACE_LEVEL_NONE, 3879 [QDF_MODULE_ID_POLICY_MGR] = QDF_TRACE_LEVEL_NONE, 3880 [QDF_MODULE_ID_CONFIG] = QDF_TRACE_LEVEL_ERROR, 3881 [QDF_MODULE_ID_REGULATORY] = QDF_TRACE_LEVEL_NONE, 3882 [QDF_MODULE_ID_SA_API] = QDF_TRACE_LEVEL_NONE, 3883 [QDF_MODULE_ID_NAN] = QDF_TRACE_LEVEL_NONE, 3884 [QDF_MODULE_ID_OFFCHAN_TXRX] = QDF_TRACE_LEVEL_NONE, 3885 [QDF_MODULE_ID_SON] = QDF_TRACE_LEVEL_NONE, 3886 [QDF_MODULE_ID_SPECTRAL] = QDF_TRACE_LEVEL_ERROR, 3887 [QDF_MODULE_ID_OBJ_MGR] = QDF_TRACE_LEVEL_FATAL, 3888 [QDF_MODULE_ID_NSS] = QDF_TRACE_LEVEL_ERROR, 3889 [QDF_MODULE_ID_ROAM_DEBUG] = QDF_TRACE_LEVEL_ERROR, 3890 [QDF_MODULE_ID_CDP] = QDF_TRACE_LEVEL_NONE, 3891 [QDF_MODULE_ID_DIRECT_BUF_RX] = QDF_TRACE_LEVEL_ERROR, 3892 [QDF_MODULE_ID_DISA] = QDF_TRACE_LEVEL_NONE, 3893 [QDF_MODULE_ID_GREEN_AP] = QDF_TRACE_LEVEL_ERROR, 3894 [QDF_MODULE_ID_FTM] = QDF_TRACE_LEVEL_ERROR, 3895 [QDF_MODULE_ID_FD] = QDF_TRACE_LEVEL_ERROR, 3896 [QDF_MODULE_ID_OCB] = QDF_TRACE_LEVEL_ERROR, 3897 [QDF_MODULE_ID_IPA] = QDF_TRACE_LEVEL_NONE, 3898 [QDF_MODULE_ID_ACTION_OUI] = QDF_TRACE_LEVEL_NONE, 3899 [QDF_MODULE_ID_CP_STATS] = QDF_TRACE_LEVEL_ERROR, 3900 [QDF_MODULE_ID_DCS] = QDF_TRACE_LEVEL_ERROR, 3901 [QDF_MODULE_ID_MBSSIE] = QDF_TRACE_LEVEL_INFO, 3902 [QDF_MODULE_ID_FWOL] = QDF_TRACE_LEVEL_NONE, 3903 [QDF_MODULE_ID_SM_ENGINE] = QDF_TRACE_LEVEL_ERROR, 3904 [QDF_MODULE_ID_CMN_MLME] = QDF_TRACE_LEVEL_INFO, 3905 [QDF_MODULE_ID_BSSCOLOR] = QDF_TRACE_LEVEL_ERROR, 3906 [QDF_MODULE_ID_CFR] = QDF_TRACE_LEVEL_ERROR, 3907 [QDF_MODULE_ID_DP_TX_CAPTURE] = QDF_TRACE_LEVEL_FATAL, 3908 [QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE, 3909 [QDF_MODULE_ID_DENYLIST_MGR] = QDF_TRACE_LEVEL_NONE, 3910 [QDF_MODULE_ID_QLD] = QDF_TRACE_LEVEL_ERROR, 3911 [QDF_MODULE_ID_DYNAMIC_MODE_CHG] = QDF_TRACE_LEVEL_INFO, 3912 [QDF_MODULE_ID_COEX] = QDF_TRACE_LEVEL_ERROR, 3913 [QDF_MODULE_ID_MON_FILTER] = QDF_TRACE_LEVEL_INFO, 3914 [QDF_MODULE_ID_PKT_CAPTURE] = QDF_TRACE_LEVEL_NONE, 3915 [QDF_MODULE_ID_RPTR] = QDF_TRACE_LEVEL_INFO, 3916 [QDF_MODULE_ID_6GHZ] = QDF_TRACE_LEVEL_ERROR, 3917 [QDF_MODULE_ID_IOT_SIM] = QDF_TRACE_LEVEL_ERROR, 3918 [QDF_MODULE_ID_MSCS] = QDF_TRACE_LEVEL_INFO, 3919 [QDF_MODULE_ID_GPIO] = QDF_TRACE_LEVEL_NONE, 3920 [QDF_MODULE_ID_IFMGR] = QDF_TRACE_LEVEL_ERROR, 3921 [QDF_MODULE_ID_DIAG] = QDF_TRACE_LEVEL_ERROR, 3922 [QDF_MODULE_ID_DP_INIT] = QDF_TRACE_LEVEL_FATAL, 3923 [QDF_MODULE_ID_DP_TX] = QDF_TRACE_LEVEL_FATAL, 3924 [QDF_MODULE_ID_DP_RX] = QDF_TRACE_LEVEL_FATAL, 3925 [QDF_MODULE_ID_DP_STATS] = QDF_TRACE_LEVEL_FATAL, 3926 [QDF_MODULE_ID_DP_HTT] = QDF_TRACE_LEVEL_FATAL, 3927 [QDF_MODULE_ID_DP_PEER] = QDF_TRACE_LEVEL_FATAL, 3928 [QDF_MODULE_ID_DP_RX_ERROR] = QDF_TRACE_LEVEL_FATAL, 3929 [QDF_MODULE_ID_DP_HTT_TX_STATS] = QDF_TRACE_LEVEL_FATAL, 3930 [QDF_MODULE_ID_DP_RX_MON_STATUS] = QDF_TRACE_LEVEL_FATAL, 3931 [QDF_MODULE_ID_DP_RX_MON_DEST] = QDF_TRACE_LEVEL_FATAL, 3932 [QDF_MODULE_ID_DP_REO] = QDF_TRACE_LEVEL_FATAL, 3933 [QDF_MODULE_ID_DP_TX_COMP] = QDF_TRACE_LEVEL_FATAL, 3934 [QDF_MODULE_ID_DP_VDEV] = QDF_TRACE_LEVEL_FATAL, 3935 [QDF_MODULE_ID_DP_CDP] = QDF_TRACE_LEVEL_FATAL, 3936 [QDF_MODULE_ID_TSO] = QDF_TRACE_LEVEL_FATAL, 3937 [QDF_MODULE_ID_ME] = QDF_TRACE_LEVEL_INFO, 3938 [QDF_MODULE_ID_QWRAP] = QDF_TRACE_LEVEL_FATAL, 3939 [QDF_MODULE_ID_DBDC_REP] = QDF_TRACE_LEVEL_FATAL, 3940 [QDF_MODULE_ID_EXT_AP] = QDF_TRACE_LEVEL_NONE, 3941 [QDF_MODULE_ID_MLO] = QDF_TRACE_LEVEL_INFO, 3942 [QDF_MODULE_ID_MLOIE] = QDF_TRACE_LEVEL_INFO, 3943 [QDF_MODULE_ID_MBSS] = QDF_TRACE_LEVEL_ERROR, 3944 [QDF_MODULE_ID_MON] = QDF_TRACE_LEVEL_ERROR, 3945 [QDF_MODULE_ID_MGMT_RX_REO] = QDF_TRACE_LEVEL_WARN, 3946 [QDF_MODULE_ID_TWT] = QDF_TRACE_LEVEL_ERROR, 3947 [QDF_MODULE_ID_WLAN_PRE_CAC] = QDF_TRACE_LEVEL_ERROR, 3948 [QDF_MODULE_ID_T2LM] = QDF_TRACE_LEVEL_ERROR, 3949 [QDF_MODULE_ID_DP_SAWF] = QDF_TRACE_LEVEL_ERROR, 3950 [QDF_MODULE_ID_SCS] = QDF_TRACE_LEVEL_ERROR, 3951 [QDF_MODULE_ID_DP_UMAC_RESET] = QDF_TRACE_LEVEL_ERROR, 3952 [QDF_MODULE_ID_COAP] = QDF_TRACE_LEVEL_ERROR, 3953 [QDF_MODULE_ID_FTM_TIME_SYNC] = QDF_TRACE_LEVEL_NONE, 3954 [QDF_MODULE_ID_AFC] = QDF_TRACE_LEVEL_NONE, 3955 [QDF_MODULE_ID_WIFI_RADAR] = QDF_TRACE_LEVEL_NONE, 3956 [QDF_MODULE_ID_TARGET] = QDF_TRACE_LEVEL_NONE, 3957 [QDF_MODULE_ID_QMI] = QDF_TRACE_LEVEL_ERROR, 3958 [QDF_MODULE_ID_SOUNDING] = QDF_TRACE_LEVEL_ERROR, 3959 [QDF_MODULE_ID_SAWF] = QDF_TRACE_LEVEL_INFO, 3960 [QDF_MODULE_ID_EPCS] = QDF_TRACE_LEVEL_INFO, 3961 [QDF_MODULE_ID_LL_SAP] = QDF_TRACE_LEVEL_NONE, 3962 [QDF_MODULE_ID_COHOSTED_BSS] = QDF_TRACE_LEVEL_INFO, 3963 [QDF_MODULE_ID_TELEMETRY_AGENT] = QDF_TRACE_LEVEL_ERROR, 3964 [QDF_MODULE_ID_RF_PATH_SWITCH] = QDF_TRACE_LEVEL_INFO, 3965 [QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO, 3966 }; 3967 3968 for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { 3969 cinfo[i].category_verbose_mask = set_cumulative_verbose_mask( 3970 module_trace_default_level[i]); 3971 } 3972 } 3973 qdf_shared_print_ctrl_init(void)3974 void qdf_shared_print_ctrl_init(void) 3975 { 3976 int i; 3977 struct category_info cinfo[MAX_SUPPORTED_CATEGORY]; 3978 3979 set_default_trace_levels(cinfo); 3980 3981 /* 3982 * User specified across-module single debug level 3983 */ 3984 if ((qdf_dbg_mask >= 0) && (qdf_dbg_mask < QDF_TRACE_LEVEL_MAX)) { 3985 pr_info("User specified module debug level of %d\n", 3986 qdf_dbg_mask); 3987 for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) { 3988 cinfo[i].category_verbose_mask = 3989 set_cumulative_verbose_mask(qdf_dbg_mask); 3990 } 3991 } else if (qdf_dbg_mask != QDF_TRACE_LEVEL_MAX) { 3992 pr_info("qdf_dbg_mask value is invalid\n"); 3993 pr_info("Using the default module debug levels instead\n"); 3994 } 3995 3996 /* 3997 * Module ID-Level specified as array during module load 3998 */ 3999 for (i = 0; i < qdf_dbg_arr_cnt; i++) { 4000 process_qdf_dbg_arr_param(cinfo, i); 4001 } 4002 qdf_pidx = qdf_print_ctrl_register(cinfo, NULL, NULL, 4003 "LOG_SHARED_OBJ"); 4004 } 4005 qdf_export_symbol(qdf_shared_print_ctrl_init); 4006 #endif 4007 4008 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI qdf_module_param_handler(void * context,const char * str_param,const char * str)4009 QDF_STATUS qdf_module_param_handler(void *context, const char *str_param, 4010 const char *str) 4011 { 4012 QDF_STATUS status = QDF_STATUS_E_FAILURE; 4013 uint16_t param = 0; 4014 uint32_t flush_tmr_prd; 4015 bool dump_flag; 4016 4017 while (param < QDF_PARAM_MAX) { 4018 if (qdf_str_eq(qdf_module_param[param], str_param)) { 4019 switch (param) { 4020 case MEM_DEBUG_DISABLED: 4021 status = qdf_mem_debug_disabled_config_set(str); 4022 break; 4023 case QDF_DBG_MASK: 4024 status = qdf_int32_parse(str, &qdf_dbg_mask); 4025 break; 4026 case PREALLOC_DISABLED: 4027 status = qdf_prealloc_disabled_config_set(str); 4028 break; 4029 case QDF_LOG_DUMP_AT_KERNEL_ENABLE: 4030 status = qdf_bool_parse(str, &dump_flag); 4031 qdf_log_dump_at_kernel_enable = dump_flag; 4032 break; 4033 case QDF_DBG_ARR: 4034 qdf_dbg_arr[0] = (char *)str; 4035 status = QDF_STATUS_SUCCESS; 4036 break; 4037 case QDF_LOG_FLUSH_TIMER_PERIOD: 4038 status = qdf_uint32_parse(str, &flush_tmr_prd); 4039 qdf_log_flush_timer_period = flush_tmr_prd; 4040 break; 4041 default: 4042 break; 4043 } 4044 return status; 4045 } 4046 param++; 4047 } 4048 4049 return QDF_STATUS_SUCCESS; 4050 } 4051 qdf_initialize_module_param_from_ini(void)4052 void qdf_initialize_module_param_from_ini(void) 4053 { 4054 QDF_STATUS status; 4055 char *path = QDF_WIFI_MODULE_PARAMS_FILE; 4056 4057 status = qdf_ini_parse(path, NULL, qdf_module_param_handler, NULL); 4058 if (QDF_IS_STATUS_ERROR(status)) { 4059 QDF_TRACE_ERROR(QDF_MODULE_ID_QDF, 4060 "Failed to parse *.ini file @ %s; status:%d", 4061 path, status); 4062 return; 4063 } 4064 } 4065 #endif 4066 qdf_print_set_category_verbose(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose,bool is_set)4067 QDF_STATUS qdf_print_set_category_verbose(unsigned int idx, 4068 QDF_MODULE_ID category, 4069 QDF_TRACE_LEVEL verbose, 4070 bool is_set) 4071 { 4072 /* Check if index passed is valid */ 4073 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 4074 pr_err("%s: Invalid index - %d\n", __func__, idx); 4075 return QDF_STATUS_E_FAILURE; 4076 } 4077 4078 /* Check if print control object is in use */ 4079 if (!print_ctrl_obj[idx].in_use) { 4080 pr_err("%s: Invalid print control object\n", __func__); 4081 return QDF_STATUS_E_FAILURE; 4082 } 4083 4084 /* Check if category passed is valid */ 4085 if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) { 4086 pr_err("%s: Invalid category: %d\n", __func__, category); 4087 return QDF_STATUS_E_FAILURE; 4088 } 4089 4090 /* Check if verbose mask is valid */ 4091 if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) { 4092 pr_err("%s: Invalid verbose level %d\n", __func__, verbose); 4093 return QDF_STATUS_E_FAILURE; 4094 } 4095 4096 if (verbose == QDF_TRACE_LEVEL_ALL) { 4097 print_ctrl_obj[idx].cat_info[category].category_verbose_mask = 4098 0xFFFF; 4099 return QDF_STATUS_SUCCESS; 4100 } 4101 4102 if (verbose == QDF_TRACE_LEVEL_NONE) { 4103 print_ctrl_obj[idx].cat_info[category].category_verbose_mask = 4104 QDF_TRACE_LEVEL_NONE; 4105 return QDF_STATUS_SUCCESS; 4106 } 4107 4108 if (!is_set) { 4109 if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask 4110 & QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) { 4111 print_ctrl_obj[idx].cat_info[category] 4112 .category_verbose_mask &= 4113 ~QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose); 4114 } 4115 } else { 4116 print_ctrl_obj[idx].cat_info[category].category_verbose_mask |= 4117 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose); 4118 } 4119 4120 pr_debug("%s: Print control object %d, Category %d, Verbose level %d\n", 4121 __func__, 4122 idx, 4123 category, 4124 print_ctrl_obj[idx].cat_info[category].category_verbose_mask); 4125 4126 return QDF_STATUS_SUCCESS; 4127 } 4128 qdf_export_symbol(qdf_print_set_category_verbose); 4129 qdf_log_dump_at_kernel_level(bool enable)4130 void qdf_log_dump_at_kernel_level(bool enable) 4131 { 4132 if (qdf_log_dump_at_kernel_enable == enable) { 4133 QDF_TRACE_INFO(QDF_MODULE_ID_QDF, 4134 "qdf_log_dump_at_kernel_enable is already %d\n", 4135 enable); 4136 } 4137 qdf_log_dump_at_kernel_enable = enable; 4138 } 4139 4140 qdf_export_symbol(qdf_log_dump_at_kernel_level); 4141 qdf_print_get_category_verbose(unsigned int idx,QDF_MODULE_ID category)4142 QDF_TRACE_LEVEL qdf_print_get_category_verbose(unsigned int idx, 4143 QDF_MODULE_ID category) 4144 { 4145 /* Check if index passed is valid */ 4146 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 4147 pr_info("%s: Invalid index - %d\n", __func__, idx); 4148 return false; 4149 } 4150 4151 /* Check if print control object is in use */ 4152 if (!print_ctrl_obj[idx].in_use) { 4153 pr_info("%s: Invalid print control object\n", __func__); 4154 return false; 4155 } 4156 4157 /* Check if category passed is valid */ 4158 if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) { 4159 pr_info("%s: Invalid category: %d\n", __func__, category); 4160 return false; 4161 } 4162 4163 return print_ctrl_obj[idx].cat_info[category].category_verbose_mask; 4164 } 4165 4166 qdf_export_symbol(qdf_print_get_category_verbose); 4167 qdf_print_is_category_enabled(unsigned int idx,QDF_MODULE_ID category)4168 bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category) 4169 { 4170 QDF_TRACE_LEVEL verbose_mask; 4171 4172 verbose_mask = qdf_print_get_category_verbose(idx, category); 4173 4174 if (verbose_mask == QDF_TRACE_LEVEL_NONE) 4175 return false; 4176 else 4177 return true; 4178 } 4179 4180 qdf_export_symbol(qdf_print_is_category_enabled); 4181 qdf_print_is_verbose_enabled(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose)4182 bool qdf_print_is_verbose_enabled(unsigned int idx, QDF_MODULE_ID category, 4183 QDF_TRACE_LEVEL verbose) 4184 { 4185 bool verbose_enabled = false; 4186 4187 /* Check if index passed is valid */ 4188 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 4189 pr_info("%s: Invalid index - %d\n", __func__, idx); 4190 return verbose_enabled; 4191 } 4192 4193 /* Check if print control object is in use */ 4194 if (!print_ctrl_obj[idx].in_use) { 4195 pr_info("%s: Invalid print control object\n", __func__); 4196 return verbose_enabled; 4197 } 4198 4199 /* Check if category passed is valid */ 4200 if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) { 4201 pr_info("%s: Invalid category: %d\n", __func__, category); 4202 return verbose_enabled; 4203 } 4204 4205 if ((verbose == QDF_TRACE_LEVEL_NONE) || 4206 (verbose >= QDF_TRACE_LEVEL_MAX)) { 4207 verbose_enabled = false; 4208 } else if (verbose == QDF_TRACE_LEVEL_ALL) { 4209 if (print_ctrl_obj[idx].cat_info[category] 4210 .category_verbose_mask == 0xFFFF) 4211 verbose_enabled = true; 4212 } else { 4213 verbose_enabled = 4214 (print_ctrl_obj[idx].cat_info[category].category_verbose_mask & 4215 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) ? true : false; 4216 } 4217 4218 return verbose_enabled; 4219 } 4220 qdf_export_symbol(qdf_print_is_verbose_enabled); 4221 4222 #ifdef DBG_LVL_MAC_FILTERING 4223 qdf_print_set_node_flag(unsigned int idx,uint8_t enable)4224 QDF_STATUS qdf_print_set_node_flag(unsigned int idx, uint8_t enable) 4225 { 4226 /* Check if index passed is valid */ 4227 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 4228 pr_info("%s: Invalid index - %d\n", __func__, idx); 4229 return QDF_STATUS_E_FAILURE; 4230 } 4231 4232 /* Check if print control object is in use */ 4233 if (!print_ctrl_obj[idx].in_use) { 4234 pr_info("%s: Invalid print control object\n", __func__); 4235 return QDF_STATUS_E_FAILURE; 4236 } 4237 4238 if (enable > 1) { 4239 pr_info("%s: Incorrect input: Use 1 or 0 to enable or disable\n", 4240 __func__); 4241 return QDF_STATUS_E_FAILURE; 4242 } 4243 4244 print_ctrl_obj[idx].dbglvlmac_on = enable; 4245 pr_info("%s: DbgLVLmac feature %s\n", 4246 __func__, 4247 ((enable) ? "enabled" : "disabled")); 4248 4249 return QDF_STATUS_SUCCESS; 4250 } 4251 qdf_export_symbol(qdf_print_set_node_flag); 4252 qdf_print_get_node_flag(unsigned int idx)4253 bool qdf_print_get_node_flag(unsigned int idx) 4254 { 4255 bool node_flag = false; 4256 4257 /* Check if index passed is valid */ 4258 if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) { 4259 pr_info("%s: Invalid index - %d\n", __func__, idx); 4260 return node_flag; 4261 } 4262 4263 /* Check if print control object is in use */ 4264 if (!print_ctrl_obj[idx].in_use) { 4265 pr_info("%s: Invalid print control object\n", __func__); 4266 return node_flag; 4267 } 4268 4269 if (print_ctrl_obj[idx].dbglvlmac_on) 4270 node_flag = true; 4271 4272 return node_flag; 4273 } 4274 qdf_export_symbol(qdf_print_get_node_flag); 4275 qdf_print_clean_node_flag(unsigned int idx)4276 void qdf_print_clean_node_flag(unsigned int idx) 4277 { 4278 /* Disable dbglvlmac_on during cleanup */ 4279 print_ctrl_obj[idx].dbglvlmac_on = 0; 4280 } 4281 4282 #else 4283 qdf_print_clean_node_flag(unsigned int idx)4284 void qdf_print_clean_node_flag(unsigned int idx) 4285 { 4286 /* No operation in case of no support for DBG_LVL_MAC_FILTERING */ 4287 return; 4288 } 4289 #endif 4290 QDF_PRINT_INFO(unsigned int idx,QDF_MODULE_ID module,QDF_TRACE_LEVEL level,char * str_format,...)4291 void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module, 4292 QDF_TRACE_LEVEL level, 4293 char *str_format, ...) 4294 { 4295 va_list args; 4296 4297 /* Generic wrapper API will compile qdf_vprint in order to 4298 * log the message. Once QDF converged debug framework is in 4299 * place, this will be changed to adapt to the framework, compiling 4300 * call to converged tracing API 4301 */ 4302 va_start(args, str_format); 4303 qdf_vprint(str_format, args); 4304 va_end(args); 4305 } 4306 qdf_export_symbol(QDF_PRINT_INFO); 4307 4308 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE qdf_logging_init(void)4309 void qdf_logging_init(void) 4310 { 4311 wlan_logging_sock_init_svc(); 4312 nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY); 4313 wlan_logging_notifier_init(qdf_log_dump_at_kernel_enable); 4314 wlan_logging_set_flush_timer(qdf_log_flush_timer_period); 4315 } 4316 qdf_logging_exit(void)4317 void qdf_logging_exit(void) 4318 { 4319 wlan_logging_notifier_deinit(qdf_log_dump_at_kernel_enable); 4320 nl_srv_exit(); 4321 wlan_logging_sock_deinit_svc(); 4322 } 4323 qdf_logging_set_flush_timer(uint32_t milliseconds)4324 int qdf_logging_set_flush_timer(uint32_t milliseconds) 4325 { 4326 if (wlan_logging_set_flush_timer(milliseconds) == 0) 4327 return QDF_STATUS_SUCCESS; 4328 else 4329 return QDF_STATUS_E_FAILURE; 4330 } 4331 qdf_logging_flush_logs(void)4332 void qdf_logging_flush_logs(void) 4333 { 4334 wlan_flush_host_logs_for_fatal(); 4335 } 4336 4337 #else qdf_logging_init(void)4338 void qdf_logging_init(void) 4339 { 4340 nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY); 4341 } 4342 qdf_logging_exit(void)4343 void qdf_logging_exit(void) 4344 { 4345 nl_srv_exit(); 4346 } 4347 qdf_logging_set_flush_timer(uint32_t milliseconds)4348 int qdf_logging_set_flush_timer(uint32_t milliseconds) 4349 { 4350 return QDF_STATUS_E_FAILURE; 4351 } 4352 qdf_logging_flush_logs(void)4353 void qdf_logging_flush_logs(void) 4354 { 4355 } 4356 #endif 4357 4358 qdf_export_symbol(qdf_logging_set_flush_timer); 4359 qdf_export_symbol(qdf_logging_flush_logs); 4360 4361 #ifdef CONFIG_KALLSYMS qdf_sprint_symbol(char * buffer,void * addr)4362 inline int qdf_sprint_symbol(char *buffer, void *addr) 4363 { 4364 return sprint_symbol(buffer, (unsigned long)addr); 4365 } 4366 #else qdf_sprint_symbol(char * buffer,void * addr)4367 int qdf_sprint_symbol(char *buffer, void *addr) 4368 { 4369 if (!buffer) 4370 return 0; 4371 4372 buffer[0] = '\0'; 4373 return 1; 4374 } 4375 #endif 4376 qdf_export_symbol(qdf_sprint_symbol); 4377 qdf_set_pidx(int pidx)4378 void qdf_set_pidx(int pidx) 4379 { 4380 qdf_pidx = pidx; 4381 } 4382 qdf_export_symbol(qdf_set_pidx); 4383 qdf_get_pidx(void)4384 int qdf_get_pidx(void) 4385 { 4386 return qdf_pidx; 4387 } 4388 qdf_export_symbol(qdf_get_pidx); 4389 4390 #ifdef PANIC_ON_BUG 4391 #ifdef CONFIG_SLUB_DEBUG __qdf_bug(void)4392 void __qdf_bug(void) 4393 { 4394 BUG(); 4395 } 4396 qdf_export_symbol(__qdf_bug); 4397 #endif /* CONFIG_SLUB_DEBUG */ 4398 #endif /* PANIC_ON_BUG */ 4399 4400 #ifdef WLAN_QCOM_VA_MINIDUMP 4401 static bool qdf_va_md_initialized; 4402 static qdf_list_t qdf_va_md_list; 4403 static qdf_spinlock_t qdf_va_md_list_lock; 4404 #define QDF_MINIDUMP_LIST_SIZE 128 4405 4406 struct qdf_va_md_entry { 4407 qdf_list_node_t node; 4408 struct va_md_entry data; 4409 }; 4410 qdf_va_md_notif_handler(struct notifier_block * this,unsigned long event,void * ptr)4411 static int qdf_va_md_notif_handler(struct notifier_block *this, 4412 unsigned long event, void *ptr) 4413 { 4414 struct qdf_va_md_entry *entry; 4415 struct qdf_va_md_entry *next; 4416 4417 qdf_spin_lock_irqsave(&qdf_va_md_list_lock); 4418 qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) { 4419 qcom_va_md_add_region(&entry->data); 4420 } 4421 4422 qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock); 4423 return NOTIFY_OK; 4424 } 4425 4426 static struct notifier_block qdf_va_md_notif_blk = { 4427 .notifier_call = qdf_va_md_notif_handler, 4428 .priority = INT_MAX, 4429 }; 4430 __qdf_minidump_init(void)4431 void __qdf_minidump_init(void) 4432 { 4433 int ret; 4434 4435 if (qdf_va_md_initialized) 4436 return; 4437 4438 qdf_spinlock_create(&qdf_va_md_list_lock); 4439 qdf_list_create(&qdf_va_md_list, QDF_MINIDUMP_LIST_SIZE); 4440 ret = qcom_va_md_register(qdf_trace_wlan_modname(), 4441 &qdf_va_md_notif_blk); 4442 qdf_va_md_initialized = !ret; 4443 } 4444 4445 qdf_export_symbol(__qdf_minidump_init); 4446 __qdf_minidump_deinit(void)4447 void __qdf_minidump_deinit(void) 4448 { 4449 struct qdf_va_md_entry *entry; 4450 struct qdf_va_md_entry *next; 4451 4452 if (!qdf_va_md_initialized) 4453 return; 4454 4455 qdf_va_md_initialized = false; 4456 qcom_va_md_unregister(qdf_trace_wlan_modname(), 4457 &qdf_va_md_notif_blk); 4458 qdf_spin_lock_irqsave(&qdf_va_md_list_lock); 4459 qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) { 4460 qdf_list_remove_node(&qdf_va_md_list, &entry->node); 4461 qdf_mem_free(entry); 4462 } 4463 4464 qdf_list_destroy(&qdf_va_md_list); 4465 qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock); 4466 qdf_spinlock_destroy(&qdf_va_md_list_lock); 4467 } 4468 4469 qdf_export_symbol(__qdf_minidump_deinit); 4470 __qdf_minidump_log(void * start_addr,size_t size,const char * name)4471 void __qdf_minidump_log(void *start_addr, size_t size, const char *name) 4472 { 4473 struct qdf_va_md_entry *entry; 4474 QDF_STATUS status; 4475 4476 if (!qdf_va_md_initialized) 4477 return; 4478 4479 entry = qdf_mem_malloc(sizeof(*entry)); 4480 if (!entry) { 4481 qdf_err("malloc failed for %s: %pK, %zu", 4482 name, start_addr, size); 4483 return; 4484 } 4485 4486 qdf_str_lcopy(entry->data.owner, name, sizeof(entry->data.owner)); 4487 entry->data.vaddr = (unsigned long)start_addr; 4488 entry->data.size = size; 4489 4490 qdf_spin_lock_irqsave(&qdf_va_md_list_lock); 4491 status = qdf_list_insert_front(&qdf_va_md_list, &entry->node); 4492 qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock); 4493 if (QDF_IS_STATUS_ERROR(status)) { 4494 qdf_err("Failed to insert qdf va md entry, status %d", status); 4495 qdf_mem_free(entry); 4496 } 4497 } 4498 4499 qdf_export_symbol(__qdf_minidump_log); 4500 __qdf_minidump_remove(void * addr,size_t size,const char * name)4501 void __qdf_minidump_remove(void *addr, size_t size, const char *name) 4502 { 4503 struct qdf_va_md_entry *entry; 4504 struct qdf_va_md_entry *next; 4505 4506 if (!qdf_va_md_initialized) 4507 return; 4508 4509 qdf_spin_lock_irqsave(&qdf_va_md_list_lock); 4510 qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) { 4511 if (entry->data.vaddr == (unsigned long)addr && 4512 entry->data.size == size && 4513 !qdf_str_cmp(entry->data.owner, name)) { 4514 qdf_list_remove_node(&qdf_va_md_list, &entry->node); 4515 qdf_mem_free(entry); 4516 break; 4517 } 4518 } 4519 4520 qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock); 4521 } 4522 4523 qdf_export_symbol(__qdf_minidump_remove); 4524 #endif 4525