1 /* 2 * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /** 20 * DOC: i_qdf_trace.h 21 * 22 * Linux-specific definitions for QDF trace 23 * 24 */ 25 26 #if !defined(__I_QDF_TRACE_H) 27 #define __I_QDF_TRACE_H 28 29 /* older kernels have a bug in kallsyms, so ensure module.h is included */ 30 #include <linux/module.h> 31 #include <linux/kallsyms.h> 32 #ifdef CONFIG_QCA_MINIDUMP 33 #include <linux/minidump_tlv.h> 34 #endif 35 36 #if !defined(__printf) 37 #define __printf(a, b) 38 #endif 39 40 /* QDF_TRACE is the macro invoked to add trace messages to code. See the 41 * documenation for qdf_trace_msg() for the parameters etc. for this function. 42 * 43 * NOTE: Code QDF_TRACE() macros into the source code. Do not code directly 44 * to the qdf_trace_msg() function. 45 * 46 * NOTE 2: qdf tracing is totally turned off if WLAN_DEBUG is *not* defined. 47 * This allows us to build 'performance' builds where we can measure performance 48 * without being bogged down by all the tracing in the code 49 */ 50 #if defined(QDF_TRACE_PRINT_ENABLE) 51 #define qdf_trace(log_level, args...) \ 52 do { \ 53 extern int qdf_dbg_mask; \ 54 if (qdf_dbg_mask >= log_level) { \ 55 printk(args); \ 56 printk("\n"); \ 57 } \ 58 } while (0) 59 #endif 60 61 #if defined(WLAN_DEBUG) || defined(DEBUG) || defined(QDF_TRACE_PRINT_ENABLE) 62 #define QDF_TRACE qdf_trace_msg 63 #define QDF_VTRACE qdf_vtrace_msg 64 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump 65 #else 66 #define QDF_TRACE(arg ...) 67 #define QDF_VTRACE(arg ...) 68 #define QDF_TRACE_HEX_DUMP(arg ...) 69 #endif 70 71 #if defined(WLAN_DEBUG) || defined(DEBUG) || defined(QDF_TRACE_PRINT_ENABLE) 72 #define QDF_MAX_LOGS_PER_SEC 2 73 /** 74 * __QDF_TRACE_RATE_LIMITED() - rate limited version of QDF_TRACE 75 * @params: parameters to pass through to QDF_TRACE 76 * 77 * This API prevents logging a message more than QDF_MAX_LOGS_PER_SEC times per 78 * second. This means any subsequent calls to this API from the same location 79 * within 1/QDF_MAX_LOGS_PER_SEC seconds will be dropped. 80 * 81 * Return: None 82 */ 83 #define __QDF_TRACE_RATE_LIMITED(params...)\ 84 do {\ 85 static ulong __last_ticks;\ 86 ulong __ticks = jiffies;\ 87 if (time_after(__ticks,\ 88 __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\ 89 QDF_TRACE(params);\ 90 __last_ticks = __ticks;\ 91 } \ 92 } while (0) 93 #else 94 #define __QDF_TRACE_RATE_LIMITED(arg ...) 95 #endif 96 97 #define __QDF_TRACE_NO_FL(log_level, module_id, format, args...) \ 98 QDF_TRACE(module_id, log_level, format, ## args) 99 100 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \ 101 QDF_TRACE(module_id, log_level, FL(format), ## args) 102 103 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \ 104 __QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args) 105 106 #define __QDF_TRACE_RL_NO_FL(log_level, module_id, format, args...) \ 107 __QDF_TRACE_RATE_LIMITED(module_id, log_level, format, ## args) 108 109 static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { } 110 111 #ifdef WLAN_LOG_FATAL 112 #define QDF_TRACE_FATAL(params...) \ 113 __QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params) 114 #define QDF_TRACE_FATAL_NO_FL(params...) \ 115 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params) 116 #define QDF_TRACE_FATAL_RL(params...) \ 117 __QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params) 118 #define QDF_TRACE_FATAL_RL_NO_FL(params...) \ 119 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params) 120 #else 121 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params) 122 #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params) 123 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params) 124 #define QDF_TRACE_FATAL_RL_NO_FL(params...) __qdf_trace_noop(params) 125 #endif 126 127 #ifdef WLAN_LOG_ERROR 128 #define QDF_TRACE_ERROR(params...) \ 129 __QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params) 130 #define QDF_TRACE_ERROR_NO_FL(params...) \ 131 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params) 132 #define QDF_TRACE_ERROR_RL(params...) \ 133 __QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params) 134 #define QDF_TRACE_ERROR_RL_NO_FL(params...) \ 135 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params) 136 #else 137 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params) 138 #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params) 139 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params) 140 #define QDF_TRACE_ERROR_RL_NO_FL(params...) __qdf_trace_noop(params) 141 #endif 142 143 #ifdef WLAN_LOG_WARN 144 #define QDF_TRACE_WARN(params...) \ 145 __QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params) 146 #define QDF_TRACE_WARN_NO_FL(params...) \ 147 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_WARN, ## params) 148 #define QDF_TRACE_WARN_RL(params...) \ 149 __QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params) 150 #define QDF_TRACE_WARN_RL_NO_FL(params...) \ 151 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_WARN, ## params) 152 #else 153 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params) 154 #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params) 155 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params) 156 #define QDF_TRACE_WARN_RL_NO_FL(params...) __qdf_trace_noop(params) 157 #endif 158 159 #ifdef WLAN_LOG_INFO 160 #define QDF_TRACE_INFO(params...) \ 161 __QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params) 162 #define QDF_TRACE_INFO_NO_FL(params...) \ 163 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_INFO, ## params) 164 #define QDF_TRACE_INFO_RL(params...) \ 165 __QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params) 166 #define QDF_TRACE_INFO_RL_NO_FL(params...) \ 167 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_INFO, ## params) 168 #else 169 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params) 170 #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params) 171 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params) 172 #define QDF_TRACE_INFO_RL_NO_FL(params...) __qdf_trace_noop(params) 173 #endif 174 175 #ifdef WLAN_LOG_DEBUG 176 #define QDF_TRACE_DEBUG(params...) \ 177 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 178 #define QDF_TRACE_DEBUG_NO_FL(params...) \ 179 __QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 180 #define QDF_TRACE_DEBUG_RL(params...) \ 181 __QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params) 182 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) \ 183 __QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 184 #else 185 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params) 186 #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params) 187 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params) 188 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) __qdf_trace_noop(params) 189 #endif 190 191 #ifdef WLAN_LOG_ENTER 192 #define QDF_TRACE_ENTER(params...) \ 193 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 194 #else 195 #define QDF_TRACE_ENTER(params...) __qdf_trace_noop(params) 196 #endif 197 198 #ifdef WLAN_LOG_EXIT 199 #define QDF_TRACE_EXIT(params...) \ 200 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 201 #else 202 #define QDF_TRACE_EXIT(params...) __qdf_trace_noop(params) 203 #endif 204 205 #define QDF_ENABLE_TRACING 206 #define qdf_scnprintf scnprintf 207 208 #ifdef QDF_ENABLE_TRACING 209 210 #ifdef WLAN_WARN_ON_ASSERT 211 #define QDF_ASSERT(_condition) \ 212 do { \ 213 if (!(_condition)) { \ 214 pr_err("QDF ASSERT in %s Line %d\n", \ 215 __func__, __LINE__); \ 216 WARN_ON(1); \ 217 } \ 218 } while (0) 219 #else 220 #define QDF_ASSERT(_condition) \ 221 do { \ 222 if (!(_condition)) { \ 223 /* no-op */ \ 224 } \ 225 } while (0) 226 #endif /* WLAN_WARN_ON_ASSERT */ 227 228 #else 229 230 /* This code will be used for compilation if tracing is to be compiled out */ 231 /* of the code so these functions/macros are 'do nothing' */ 232 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 233 const char *str_format, ...) 234 { 235 } 236 237 #define QDF_ASSERT(_condition) 238 239 #endif 240 241 #ifdef PANIC_ON_BUG 242 #ifdef CONFIG_SLUB_DEBUG 243 /** 244 * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled 245 * 246 * Note: Calling BUG() can cause a compiler to assume any following code is 247 * unreachable. Because these BUG's may or may not be enabled by the build 248 * configuration, this can cause developers some pain. Consider: 249 * 250 * bool bit; 251 * 252 * if (ptr) 253 * bit = ptr->returns_bool(); 254 * else 255 * __qdf_bug(); 256 * 257 * // do stuff with @bit 258 * 259 * return bit; 260 * 261 * In this case, @bit is potentially uninitialized when we return! However, the 262 * compiler can correctly assume this case is impossible when PANIC_ON_BUG is 263 * enabled. Because developers typically enable this feature, the "maybe 264 * uninitialized" warning will not be emitted, and the bug remains uncaught 265 * until someone tries to make a build without PANIC_ON_BUG. 266 * 267 * A simple workaround for this, is to put the definition of __qdf_bug in 268 * another compilation unit, which prevents the compiler from assuming 269 * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more 270 * bugs. Otherwise, use the typical inlined approach. 271 * 272 * Return: None 273 */ 274 void __qdf_bug(void); 275 #else /* CONFIG_SLUB_DEBUG */ 276 static inline void __qdf_bug(void) 277 { 278 BUG(); 279 } 280 #endif /* CONFIG_SLUB_DEBUG */ 281 282 /** 283 * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing 284 * @reason_fmt: a format string containing the reason for the panic 285 * @args: zero or more printf compatible logging arguments 286 * 287 * Return: None 288 */ 289 #define QDF_DEBUG_PANIC(reason_fmt, args...) \ 290 QDF_DEBUG_PANIC_FL(__func__, __LINE__, reason_fmt, ## args) 291 292 /** 293 * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing 294 * @func: origin function name to be logged 295 * @line: origin line number to be logged 296 * @fmt: printf compatible format string to be logged 297 * @args: zero or more printf compatible logging arguments 298 * 299 * Return: None 300 */ 301 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 302 do { \ 303 pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \ 304 __qdf_bug(); \ 305 } while (false) 306 307 #define QDF_BUG(_condition) \ 308 do { \ 309 if (!(_condition)) { \ 310 pr_err("QDF BUG in %s Line %d: Failed assertion '" \ 311 #_condition "'\n", __func__, __LINE__); \ 312 __qdf_bug(); \ 313 } \ 314 } while (0) 315 316 #else /* PANIC_ON_BUG */ 317 318 #define QDF_DEBUG_PANIC(reason...) \ 319 do { \ 320 /* no-op */ \ 321 } while (false) 322 323 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \ 324 do { \ 325 /* no-op */ \ 326 } while (false) 327 328 #define QDF_BUG(_condition) \ 329 do { \ 330 if (!(_condition)) { \ 331 /* no-op */ \ 332 } \ 333 } while (0) 334 335 #endif /* PANIC_ON_BUG */ 336 337 #ifdef KSYM_SYMBOL_LEN 338 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN 339 #else 340 #define __QDF_SYMBOL_LEN 1 341 #endif 342 343 #ifdef CONFIG_QCA_MINIDUMP 344 static inline void 345 __qdf_minidump_log(void *start_addr, size_t size, const char *name) 346 { 347 if (fill_minidump_segments((uintptr_t)start_addr, size, 348 QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD, (char *)name) < 0) 349 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO, 350 "%s: failed to log %pK (%s)\n", 351 __func__, start_addr, name); 352 } 353 #else 354 static inline void 355 __qdf_minidump_log(void *start_addr, size_t size, const char *name) {} 356 #endif 357 #endif /* __I_QDF_TRACE_H */ 358