1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: i_qdf_trace.h 22 * 23 * Linux-specific definitions for QDF trace 24 * 25 */ 26 27 #if !defined(__I_QDF_TRACE_H) 28 #define __I_QDF_TRACE_H 29 30 /* older kernels have a bug in kallsyms, so ensure module.h is included */ 31 #include <linux/module.h> 32 #include <linux/kallsyms.h> 33 #ifdef CONFIG_QCA_MINIDUMP 34 #include <linux/minidump_tlv.h> 35 #endif 36 37 /* 38 * The CONFIG_QCOM_MINIDUMP feature can only be used 39 * beginning with kernel version msm-4.19 since that is 40 * when msm_minidump_removerefion() was added. 41 */ 42 #if IS_ENABLED(CONFIG_QCOM_MINIDUMP) && \ 43 (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 0)) 44 #if IS_ENABLED(CONFIG_QCOM_VA_MINIDUMP) 45 #define WLAN_QCOM_VA_MINIDUMP 46 #else 47 #define WLAN_QCOM_MINIDUMP 48 #endif 49 50 #include <soc/qcom/minidump.h> 51 #endif 52 53 #if !defined(__printf) 54 #define __printf(a, b) 55 #endif 56 57 /* QDF_TRACE is the macro invoked to add trace messages to code. See the 58 * documentation for qdf_trace_msg() for the parameters etc. for this function. 59 * 60 * NOTE: Code QDF_TRACE() macros into the source code. Do not code directly 61 * to the qdf_trace_msg() function. 62 * 63 * NOTE 2: qdf tracing is totally turned off if WLAN_DEBUG is *not* defined. 64 * This allows us to build 'performance' builds where we can measure performance 65 * without being bogged down by all the tracing in the code 66 */ 67 #if defined(QDF_TRACE_PRINT_ENABLE) 68 #define qdf_trace(log_level, args...) \ 69 do { \ 70 extern int qdf_dbg_mask; \ 71 if (qdf_dbg_mask >= log_level) { \ 72 printk(args); \ 73 printk("\n"); \ 74 } \ 75 } while (0) 76 #endif 77 78 #if defined(WLAN_DEBUG) || defined(DEBUG) || defined(QDF_TRACE_PRINT_ENABLE) 79 #define QDF_TRACE qdf_trace_msg 80 #define QDF_VTRACE qdf_vtrace_msg 81 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump 82 #else 83 #define QDF_TRACE(arg ...) __qdf_trace_dummy(arg) 84 #define QDF_VTRACE(arg ...) __qdf_vtrace_dummy(arg) 85 #define QDF_TRACE_HEX_DUMP(arg ...) __qdf_trace_hexdump_dummy(arg) 86 #endif 87 88 #if defined(WLAN_DEBUG) || defined(DEBUG) || defined(QDF_TRACE_PRINT_ENABLE) 89 #define QDF_MAX_LOGS_PER_SEC 2 90 /** 91 * __QDF_TRACE_RATE_LIMITED() - rate limited version of QDF_TRACE 92 * @params: parameters to pass through to QDF_TRACE 93 * 94 * This API prevents logging a message more than QDF_MAX_LOGS_PER_SEC times per 95 * second. This means any subsequent calls to this API from the same location 96 * within 1/QDF_MAX_LOGS_PER_SEC seconds will be dropped. 97 * 98 * Return: return rate_limted as below: 99 * true if the logging message is bypassed 100 * false if the logging message is printed out 101 */ 102 #define __QDF_TRACE_RATE_LIMITED(params...)\ 103 ({\ 104 static ulong __last_ticks;\ 105 ulong __ticks = jiffies;\ 106 bool rate_limited = true;\ 107 if (time_after(__ticks,\ 108 __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\ 109 QDF_TRACE(params);\ 110 __last_ticks = __ticks;\ 111 rate_limited = false;\ 112 } \ 113 rate_limited;\ 114 }) 115 116 #define __QDF_TRACE_HEX_DUMP_RATE_LIMITED(params...)\ 117 do {\ 118 static ulong __last_ticks;\ 119 ulong __ticks = jiffies;\ 120 if (time_after(__ticks,\ 121 __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\ 122 QDF_TRACE_HEX_DUMP(params);\ 123 __last_ticks = __ticks;\ 124 } \ 125 } while (0) 126 #else 127 #define __QDF_TRACE_RATE_LIMITED(arg ...) ({true; }) 128 #define __QDF_TRACE_HEX_DUMP_RATE_LIMITED(arg ...) 129 #endif 130 131 #define __QDF_TRACE_NO_FL(log_level, module_id, format, args...) \ 132 QDF_TRACE(module_id, log_level, format, ## args) 133 134 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \ 135 QDF_TRACE(module_id, log_level, FL(format), ## args) 136 137 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \ 138 __QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args) 139 140 #define __QDF_TRACE_RL_NO_FL(log_level, module_id, format, args...) \ 141 __QDF_TRACE_RATE_LIMITED(module_id, log_level, format, ## args) 142 143 #define __QDF_TRACE_HEX_DUMP_RL(log_level, module_id, args...) \ 144 __QDF_TRACE_HEX_DUMP_RATE_LIMITED(module_id, log_level, ## args) 145 146 static inline void __qdf_trace_noop(QDF_MODULE_ID module, 147 const char *format, ...) { } 148 static inline bool __qdf_trace_noop_ret(QDF_MODULE_ID module, 149 const char *format, ...) {return true; } 150 static inline void __qdf_trace_dummy(QDF_MODULE_ID module, 151 QDF_TRACE_LEVEL level, 152 const char *format, ...) { } 153 static inline void __qdf_vtrace_dummy(QDF_MODULE_ID module, 154 QDF_TRACE_LEVEL level, 155 const char *str_format, va_list val) { } 156 static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module, 157 QDF_TRACE_LEVEL level, 158 void *data, int buf_len) { } 159 160 161 #ifdef WLAN_LOG_FATAL 162 #define QDF_TRACE_FATAL(params...) \ 163 __QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params) 164 #define QDF_TRACE_FATAL_NO_FL(params...) \ 165 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params) 166 #define QDF_TRACE_FATAL_RL(params...) \ 167 __QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params) 168 #define QDF_TRACE_FATAL_RL_NO_FL(params...) \ 169 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params) 170 #define QDF_VTRACE_FATAL(module_id, fmt, args) \ 171 QDF_VTRACE(module_id, QDF_TRACE_LEVEL_FATAL, fmt, args) 172 #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) \ 173 __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_FATAL, ## params) 174 #else 175 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params) 176 #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params) 177 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop_ret(params) 178 #define QDF_TRACE_FATAL_RL_NO_FL(params...) __qdf_trace_noop_ret(params) 179 #define QDF_VTRACE_FATAL(params...) __qdf_trace_noop(params) 180 #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) __qdf_trace_noop(params) 181 #endif 182 183 #ifdef WLAN_LOG_ERROR 184 #define QDF_TRACE_ERROR(params...) \ 185 __QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params) 186 #define QDF_TRACE_ERROR_NO_FL(params...) \ 187 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params) 188 #define QDF_TRACE_ERROR_RL(params...) \ 189 __QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params) 190 #define QDF_TRACE_ERROR_RL_NO_FL(params...) \ 191 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params) 192 #define QDF_VTRACE_ERROR(module_id, fmt, args) \ 193 QDF_VTRACE(module_id, QDF_TRACE_LEVEL_ERROR, fmt, args) 194 #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) \ 195 __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_ERROR, ## params) 196 #else 197 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params) 198 #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params) 199 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop_ret(params) 200 #define QDF_TRACE_ERROR_RL_NO_FL(params...) __qdf_trace_noop_ret(params) 201 #define QDF_VTRACE_ERROR(params...) __qdf_trace_noop(params) 202 #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) __qdf_trace_noop(params) 203 #endif 204 205 #ifdef WLAN_LOG_WARN 206 #define QDF_TRACE_WARN(params...) \ 207 __QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params) 208 #define QDF_TRACE_WARN_NO_FL(params...) \ 209 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_WARN, ## params) 210 #define QDF_TRACE_WARN_RL(params...) \ 211 __QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params) 212 #define QDF_TRACE_WARN_RL_NO_FL(params...) \ 213 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_WARN, ## params) 214 #define QDF_VTRACE_WARN(module_id, fmt, args) \ 215 QDF_VTRACE(module_id, QDF_TRACE_LEVEL_WARN, fmt, args) 216 #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) \ 217 __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_WARN, ## params) 218 #else 219 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params) 220 #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params) 221 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop_ret(params) 222 #define QDF_TRACE_WARN_RL_NO_FL(params...) __qdf_trace_noop_ret(params) 223 #define QDF_VTRACE_WARN(params...) __qdf_trace_noop(params) 224 #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) __qdf_trace_noop(params) 225 #endif 226 227 #ifdef WLAN_LOG_INFO 228 #define QDF_TRACE_INFO(params...) \ 229 __QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params) 230 #define QDF_TRACE_INFO_NO_FL(params...) \ 231 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_INFO, ## params) 232 #define QDF_TRACE_INFO_RL(params...) \ 233 __QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params) 234 #define QDF_TRACE_INFO_RL_NO_FL(params...) \ 235 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_INFO, ## params) 236 #define QDF_VTRACE_INFO(module_id, fmt, args) \ 237 QDF_VTRACE(module_id, QDF_TRACE_LEVEL_INFO, fmt, args) 238 #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) \ 239 __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_INFO, ## params) 240 #else 241 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params) 242 #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params) 243 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop_ret(params) 244 #define QDF_TRACE_INFO_RL_NO_FL(params...) __qdf_trace_noop_ret(params) 245 #define QDF_VTRACE_INFO(params...) __qdf_trace_noop(params) 246 #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) __qdf_trace_noop(params) 247 #endif 248 249 #ifdef WLAN_LOG_DEBUG 250 #define QDF_TRACE_DEBUG(params...) \ 251 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 252 #define QDF_TRACE_DEBUG_NO_FL(params...) \ 253 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 254 #define QDF_TRACE_DEBUG_RL(params...) \ 255 __QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params) 256 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) \ 257 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 258 #define QDF_VTRACE_DEBUG(module_id, fmt, args) \ 259 QDF_VTRACE(module_id, QDF_TRACE_LEVEL_DEBUG, fmt, args) 260 #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) \ 261 __QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_DEBUG, ## params) 262 #else 263 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params) 264 #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params) 265 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop_ret(params) 266 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) __qdf_trace_noop_ret(params) 267 #define QDF_VTRACE_DEBUG(params...) __qdf_trace_noop(params) 268 #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) __qdf_trace_noop(params) 269 #endif 270 271 #ifdef WLAN_LOG_ENTER 272 #define QDF_TRACE_ENTER(params...) \ 273 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 274 #else 275 #define QDF_TRACE_ENTER(params...) __qdf_trace_noop(params) 276 #endif 277 278 #ifdef WLAN_LOG_EXIT 279 #define QDF_TRACE_EXIT(params...) \ 280 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 281 #else 282 #define QDF_TRACE_EXIT(params...) __qdf_trace_noop(params) 283 #endif 284 285 #define QDF_ENABLE_TRACING 286 #define qdf_scnprintf scnprintf 287 288 #ifdef QDF_ENABLE_TRACING 289 290 #ifdef WLAN_WARN_ON_ASSERT 291 #define QDF_ASSERT(_condition) \ 292 do { \ 293 if (!(_condition)) { \ 294 pr_err("QDF ASSERT in %s Line %d\n", \ 295 __func__, __LINE__); \ 296 WARN_ON(1); \ 297 } \ 298 } while (0) 299 #else 300 #define QDF_ASSERT(_condition) \ 301 do { \ 302 if (!(_condition)) { \ 303 /* no-op */ \ 304 } \ 305 } while (0) 306 #endif /* WLAN_WARN_ON_ASSERT */ 307 /** 308 * qdf_trace_msg()- logging API 309 * @module: Module identifier. A member of the QDF_MODULE_ID enumeration that 310 * identifies the module issuing the trace message. 311 * @level: Trace level. A member of the QDF_TRACE_LEVEL enumeration indicating 312 * the severity of the condition causing the trace message to be issued. 313 * More severe conditions are more likely to be logged. 314 * @str_format: Format string. The message to be logged. This format string 315 * contains printf-like replacement parameters, which follow this 316 * parameter in the variable argument list. 317 * 318 * Users wishing to add tracing information to their code should use 319 * QDF_TRACE. QDF_TRACE() will compile into a call to qdf_trace_msg() when 320 * tracing is enabled. 321 * 322 * Return: nothing 323 * 324 * implemented in qdf_trace.c 325 */ 326 void __printf(3, 4) qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 327 const char *str_format, ...); 328 329 /** 330 * qdf_vtrace_msg() - the va_list version of qdf_trace_msg 331 * @module: the calling module's Id 332 * @level: the logging level to log using 333 * @str_format: the log format string 334 * @val: the va_list containing the values to format according to str_format 335 * 336 * Return: None 337 */ 338 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 339 const char *str_format, va_list val); 340 341 #else 342 343 /* This code will be used for compilation if tracing is to be compiled out */ 344 /* of the code so these functions/macros are 'do nothing' */ 345 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 346 const char *str_format, ...) 347 { 348 } 349 350 #define QDF_ASSERT(_condition) 351 352 #endif 353 354 #ifdef QDF_TRACE_PRINT_ENABLE 355 static inline void qdf_vprint(const char *fmt, va_list args) 356 { 357 QDF_VTRACE_INFO(QDF_MODULE_ID_ANY, fmt, args); 358 } 359 #else /* QDF_TRACE_PRINT_ENABLE */ 360 static inline void qdf_vprint(const char *fmt, va_list args) 361 { 362 QDF_VTRACE_ERROR(QDF_MODULE_ID_QDF, fmt, args); 363 } 364 #endif 365 366 #ifdef PANIC_ON_BUG 367 #ifdef CONFIG_SLUB_DEBUG 368 /** 369 * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled 370 * 371 * Note: Calling BUG() can cause a compiler to assume any following code is 372 * unreachable. Because these BUG's may or may not be enabled by the build 373 * configuration, this can cause developers some pain. Consider: 374 * 375 * bool bit; 376 * 377 * if (ptr) 378 * bit = ptr->returns_bool(); 379 * else 380 * __qdf_bug(); 381 * 382 * // do stuff with @bit 383 * 384 * return bit; 385 * 386 * In this case, @bit is potentially uninitialized when we return! However, the 387 * compiler can correctly assume this case is impossible when PANIC_ON_BUG is 388 * enabled. Because developers typically enable this feature, the "maybe 389 * uninitialized" warning will not be emitted, and the bug remains uncaught 390 * until someone tries to make a build without PANIC_ON_BUG. 391 * 392 * A simple workaround for this, is to put the definition of __qdf_bug in 393 * another compilation unit, which prevents the compiler from assuming 394 * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more 395 * bugs. Otherwise, use the typical inlined approach. 396 * 397 * Return: None 398 */ 399 void __qdf_bug(void); 400 #else /* CONFIG_SLUB_DEBUG */ 401 static inline void __qdf_bug(void) 402 { 403 BUG(); 404 } 405 #endif /* CONFIG_SLUB_DEBUG */ 406 407 /** 408 * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing 409 * @reason_fmt: a format string containing the reason for the panic 410 * @args: zero or more printf compatible logging arguments 411 * 412 * Return: None 413 */ 414 #define QDF_DEBUG_PANIC(reason_fmt, args...) \ 415 QDF_DEBUG_PANIC_FL(__func__, __LINE__, reason_fmt, ## args) 416 417 /** 418 * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing 419 * @func: origin function name to be logged 420 * @line: origin line number to be logged 421 * @fmt: printf compatible format string to be logged 422 * @args: zero or more printf compatible logging arguments 423 * 424 * Return: None 425 */ 426 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 427 do { \ 428 pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \ 429 __qdf_bug(); \ 430 } while (false) 431 432 #define QDF_BUG(_condition) \ 433 do { \ 434 if (!(_condition)) { \ 435 pr_err("QDF BUG in %s Line %d: Failed assertion '" \ 436 #_condition "'\n", __func__, __LINE__); \ 437 __qdf_bug(); \ 438 } \ 439 } while (0) 440 441 #define QDF_BUG_ON_ASSERT(_condition) \ 442 do { \ 443 if (!(_condition)) { \ 444 __qdf_bug(); \ 445 } \ 446 } while (0) 447 448 #else /* PANIC_ON_BUG */ 449 450 #define QDF_DEBUG_PANIC(reason...) \ 451 do { \ 452 /* no-op */ \ 453 } while (false) 454 455 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 456 do { \ 457 /* no-op */ \ 458 } while (false) 459 460 #define QDF_BUG(_condition) \ 461 do { \ 462 if (!(_condition)) { \ 463 /* no-op */ \ 464 } \ 465 } while (0) 466 467 #define QDF_BUG_ON_ASSERT(_condition) \ 468 do { \ 469 if (!(_condition)) { \ 470 /* no-op */ \ 471 } \ 472 } while (0) 473 474 #endif /* PANIC_ON_BUG */ 475 476 #ifdef KSYM_SYMBOL_LEN 477 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN 478 #else 479 #define __QDF_SYMBOL_LEN 1 480 #endif 481 482 #ifdef CONFIG_QCA_MINIDUMP 483 static inline void 484 __qdf_minidump_init(void) 485 { 486 } 487 488 static inline void 489 __qdf_minidump_deinit(void) 490 { 491 } 492 493 static inline void 494 __qdf_minidump_log(void *start_addr, size_t size, const char *name) 495 { 496 if (minidump_fill_segments((const uintptr_t)start_addr, size, 497 QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD, 498 name) < 0) 499 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 500 "%s: failed to log %pK (%s)\n", 501 __func__, start_addr, name); 502 } 503 504 static inline void 505 __qdf_minidump_remove(void *addr, size_t size, const char *name) 506 { 507 minidump_remove_segments((const uintptr_t)addr); 508 } 509 510 #elif defined(WLAN_QCOM_MINIDUMP) 511 #define MAX_WLAN_MINIDUMP_ENTRIES 4 512 513 enum minidump_log_type { 514 MD_HTC_CREDIT = 0, 515 MD_WLAN_LOGS, 516 MD_WMI_TX_CMP, 517 MD_HAL_SOC, 518 }; 519 520 static const char *minidump_table[MAX_WLAN_MINIDUMP_ENTRIES]; 521 522 static int qdf_get_name_idx(const char *name) 523 { 524 int i; 525 static const char * const wlan_str[] = { 526 [MD_HTC_CREDIT] = "htc_credit", 527 [MD_WLAN_LOGS] = "wlan_logs", 528 [MD_WMI_TX_CMP] = "wmi_tx_cmp", 529 [MD_HAL_SOC] = "hal_soc" 530 }; 531 532 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 533 if (strncmp(name, wlan_str[i], strlen(wlan_str[i])) == 0) 534 return i; 535 } 536 537 return -EINVAL; 538 } 539 540 static inline void 541 __qdf_minidump_log(void *start_addr, const size_t size, 542 const char *name) 543 { 544 struct md_region md_entry; 545 int ret, index; 546 547 index = qdf_get_name_idx(name); 548 if (index < 0) { 549 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 550 "%s: invalid entry %s\n", 551 __func__, name); 552 QDF_DEBUG_PANIC("Unknown minidump entry"); 553 return; 554 } 555 snprintf(md_entry.name, sizeof(md_entry.name), name); 556 md_entry.virt_addr = (uintptr_t)start_addr; 557 md_entry.phys_addr = virt_to_phys(start_addr); 558 md_entry.size = size; 559 ret = msm_minidump_add_region(&md_entry); 560 if (ret < 0) { 561 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 562 "%s: failed to log %pK (%s)\n", 563 __func__, start_addr, name); 564 minidump_table[index] = NULL; 565 } else { 566 minidump_table[index] = name; 567 } 568 } 569 570 static inline void 571 __qdf_minidump_remove(void *start_addr, const size_t size, 572 const char *name) 573 { 574 struct md_region md_entry; 575 int index; 576 577 index = qdf_get_name_idx(name); 578 if (index < 0 || !minidump_table[index]) { 579 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 580 "%s: entry was not added", 581 __func__); 582 return; 583 } 584 snprintf(md_entry.name, sizeof(md_entry.name), name); 585 md_entry.virt_addr = (uintptr_t)start_addr; 586 md_entry.phys_addr = virt_to_phys(start_addr); 587 md_entry.size = size; 588 msm_minidump_remove_region(&md_entry); 589 minidump_table[index] = NULL; 590 } 591 592 static inline void 593 __qdf_minidump_init(void) 594 { 595 } 596 597 static inline void 598 __qdf_minidump_deinit(void) 599 { 600 } 601 602 #elif defined(WLAN_QCOM_VA_MINIDUMP) 603 void __qdf_minidump_init(void); 604 605 void __qdf_minidump_deinit(void); 606 607 void __qdf_minidump_log(void *start_addr, size_t size, const char *name); 608 609 void __qdf_minidump_remove(void *addr, size_t size, const char *name); 610 #else 611 static inline 612 void __qdf_minidump_init(void) 613 { 614 } 615 616 static inline 617 void __qdf_minidump_deinit(void) 618 { 619 } 620 621 static inline 622 void __qdf_minidump_log(void *start_addr, size_t size, const char *name) 623 { 624 } 625 626 static inline 627 void __qdf_minidump_remove(void *addr, size_t size, const char *name) 628 { 629 } 630 #endif 631 #endif /* __I_QDF_TRACE_H */ 632