1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2022-2023 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 /** 309 * qdf_trace_msg()- logging API 310 * @module: Module identifier. A member of the QDF_MODULE_ID enumeration that 311 * identifies the module issuing the trace message. 312 * @level: Trace level. A member of the QDF_TRACE_LEVEL enumeration indicating 313 * the severity of the condition causing the trace message to be issued. 314 * More severe conditions are more likely to be logged. 315 * @str_format: Format string. The message to be logged. This format string 316 * contains printf-like replacement parameters, which follow this 317 * parameter in the variable argument list. 318 * 319 * Users wishing to add tracing information to their code should use 320 * QDF_TRACE. QDF_TRACE() will compile into a call to qdf_trace_msg() when 321 * tracing is enabled. 322 * 323 * Return: nothing 324 */ 325 void __printf(3, 4) qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 326 const char *str_format, ...); 327 328 /** 329 * qdf_vtrace_msg() - the va_list version of qdf_trace_msg 330 * @module: the calling module's Id 331 * @level: the logging level to log using 332 * @str_format: the log format string 333 * @val: the va_list containing the values to format according to str_format 334 * 335 * Return: None 336 */ 337 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 338 const char *str_format, va_list val); 339 340 #else 341 342 /* This code will be used for compilation if tracing is to be compiled out */ 343 /* of the code so these functions/macros are 'do nothing' */ 344 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 345 const char *str_format, ...) 346 { 347 } 348 349 #define QDF_ASSERT(_condition) 350 351 #endif 352 353 #ifdef QDF_TRACE_PRINT_ENABLE 354 static inline void qdf_vprint(const char *fmt, va_list args) 355 { 356 QDF_VTRACE_INFO(QDF_MODULE_ID_ANY, fmt, args); 357 } 358 #else /* QDF_TRACE_PRINT_ENABLE */ 359 static inline void qdf_vprint(const char *fmt, va_list args) 360 { 361 QDF_VTRACE_ERROR(QDF_MODULE_ID_QDF, fmt, args); 362 } 363 #endif 364 365 #ifdef PANIC_ON_BUG 366 #ifdef CONFIG_SLUB_DEBUG 367 /** 368 * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled 369 * 370 * Note: Calling BUG() can cause a compiler to assume any following code is 371 * unreachable. Because these BUG's may or may not be enabled by the build 372 * configuration, this can cause developers some pain. Consider: 373 * 374 * bool bit; 375 * 376 * if (ptr) 377 * bit = ptr->returns_bool(); 378 * else 379 * __qdf_bug(); 380 * 381 * // do stuff with @bit 382 * 383 * return bit; 384 * 385 * In this case, @bit is potentially uninitialized when we return! However, the 386 * compiler can correctly assume this case is impossible when PANIC_ON_BUG is 387 * enabled. Because developers typically enable this feature, the "maybe 388 * uninitialized" warning will not be emitted, and the bug remains uncaught 389 * until someone tries to make a build without PANIC_ON_BUG. 390 * 391 * A simple workaround for this, is to put the definition of __qdf_bug in 392 * another compilation unit, which prevents the compiler from assuming 393 * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more 394 * bugs. Otherwise, use the typical inlined approach. 395 * 396 * Return: None 397 */ 398 void __qdf_bug(void); 399 #else /* CONFIG_SLUB_DEBUG */ 400 static inline void __qdf_bug(void) 401 { 402 BUG(); 403 } 404 #endif /* CONFIG_SLUB_DEBUG */ 405 406 /** 407 * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing 408 * @reason_fmt: a format string containing the reason for the panic 409 * @args: zero or more printf compatible logging arguments 410 * 411 * Return: None 412 */ 413 #define QDF_DEBUG_PANIC(reason_fmt, args...) \ 414 QDF_DEBUG_PANIC_FL(__func__, __LINE__, reason_fmt, ## args) 415 416 /** 417 * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing 418 * @func: origin function name to be logged 419 * @line: origin line number to be logged 420 * @fmt: printf compatible format string to be logged 421 * @args: zero or more printf compatible logging arguments 422 * 423 * Return: None 424 */ 425 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 426 do { \ 427 pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \ 428 __qdf_bug(); \ 429 } while (false) 430 431 #define QDF_BUG(_condition) \ 432 do { \ 433 if (!(_condition)) { \ 434 pr_err("QDF BUG in %s Line %d: Failed assertion '" \ 435 #_condition "'\n", __func__, __LINE__); \ 436 __qdf_bug(); \ 437 } \ 438 } while (0) 439 440 #define QDF_BUG_ON_ASSERT(_condition) \ 441 do { \ 442 if (!(_condition)) { \ 443 __qdf_bug(); \ 444 } \ 445 } while (0) 446 447 #else /* PANIC_ON_BUG */ 448 449 #define QDF_DEBUG_PANIC(reason...) \ 450 do { \ 451 /* no-op */ \ 452 } while (false) 453 454 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 455 do { \ 456 /* no-op */ \ 457 } while (false) 458 459 #define QDF_BUG(_condition) \ 460 do { \ 461 if (!(_condition)) { \ 462 /* no-op */ \ 463 } \ 464 } while (0) 465 466 #define QDF_BUG_ON_ASSERT(_condition) \ 467 do { \ 468 if (!(_condition)) { \ 469 /* no-op */ \ 470 } \ 471 } while (0) 472 473 #endif /* PANIC_ON_BUG */ 474 475 #ifdef KSYM_SYMBOL_LEN 476 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN 477 #else 478 #define __QDF_SYMBOL_LEN 1 479 #endif 480 481 #ifdef CONFIG_QCA_MINIDUMP 482 static inline void 483 __qdf_minidump_init(void) 484 { 485 } 486 487 static inline void 488 __qdf_minidump_deinit(void) 489 { 490 } 491 492 static inline void 493 __qdf_minidump_log(void *start_addr, size_t size, const char *name) 494 { 495 if (minidump_fill_segments((const uintptr_t)start_addr, size, 496 QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD, 497 name) < 0) 498 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 499 "%s: failed to log %pK (%s)\n", 500 __func__, start_addr, name); 501 } 502 503 static inline void 504 __qdf_minidump_remove(void *addr, size_t size, const char *name) 505 { 506 minidump_remove_segments((const uintptr_t)addr); 507 } 508 509 #elif defined(WLAN_QCOM_MINIDUMP) 510 #define MAX_WLAN_MINIDUMP_ENTRIES 4 511 512 enum minidump_log_type { 513 MD_HTC_CREDIT = 0, 514 MD_WLAN_LOGS, 515 MD_WMI_TX_CMP, 516 MD_HAL_SOC, 517 }; 518 519 static const char *minidump_table[MAX_WLAN_MINIDUMP_ENTRIES]; 520 521 static int qdf_get_name_idx(const char *name) 522 { 523 int i; 524 static const char * const wlan_str[] = { 525 [MD_HTC_CREDIT] = "htc_credit", 526 [MD_WLAN_LOGS] = "wlan_logs", 527 [MD_WMI_TX_CMP] = "wmi_tx_cmp", 528 [MD_HAL_SOC] = "hal_soc" 529 }; 530 531 for (i = 0; i < ARRAY_SIZE(wlan_str); i++) { 532 if (strncmp(name, wlan_str[i], strlen(wlan_str[i])) == 0) 533 return i; 534 } 535 536 return -EINVAL; 537 } 538 539 static inline void 540 __qdf_minidump_log(void *start_addr, const size_t size, 541 const char *name) 542 { 543 struct md_region md_entry; 544 int ret, index; 545 546 index = qdf_get_name_idx(name); 547 if (index < 0) { 548 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 549 "%s: invalid entry %s\n", 550 __func__, name); 551 QDF_DEBUG_PANIC("Unknown minidump entry"); 552 return; 553 } 554 snprintf(md_entry.name, sizeof(md_entry.name), name); 555 md_entry.virt_addr = (uintptr_t)start_addr; 556 md_entry.phys_addr = virt_to_phys(start_addr); 557 md_entry.size = size; 558 ret = msm_minidump_add_region(&md_entry); 559 if (ret < 0) { 560 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 561 "%s: failed to log %pK (%s)\n", 562 __func__, start_addr, name); 563 minidump_table[index] = NULL; 564 } else { 565 minidump_table[index] = name; 566 } 567 } 568 569 static inline void 570 __qdf_minidump_remove(void *start_addr, const size_t size, 571 const char *name) 572 { 573 struct md_region md_entry; 574 int index; 575 576 index = qdf_get_name_idx(name); 577 if (index < 0 || !minidump_table[index]) { 578 QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_QDF, 579 "%s: entry was not added", 580 __func__); 581 return; 582 } 583 snprintf(md_entry.name, sizeof(md_entry.name), name); 584 md_entry.virt_addr = (uintptr_t)start_addr; 585 md_entry.phys_addr = virt_to_phys(start_addr); 586 md_entry.size = size; 587 msm_minidump_remove_region(&md_entry); 588 minidump_table[index] = NULL; 589 } 590 591 static inline void 592 __qdf_minidump_init(void) 593 { 594 } 595 596 static inline void 597 __qdf_minidump_deinit(void) 598 { 599 } 600 601 #elif defined(WLAN_QCOM_VA_MINIDUMP) 602 void __qdf_minidump_init(void); 603 604 void __qdf_minidump_deinit(void); 605 606 void __qdf_minidump_log(void *start_addr, size_t size, const char *name); 607 608 void __qdf_minidump_remove(void *addr, size_t size, const char *name); 609 #else 610 static inline 611 void __qdf_minidump_init(void) 612 { 613 } 614 615 static inline 616 void __qdf_minidump_deinit(void) 617 { 618 } 619 620 static inline 621 void __qdf_minidump_log(void *start_addr, size_t size, const char *name) 622 { 623 } 624 625 static inline 626 void __qdf_minidump_remove(void *addr, size_t size, const char *name) 627 { 628 } 629 #endif 630 #endif /* __I_QDF_TRACE_H */ 631