1 /* 2 * Copyright (c) 2014-2018 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 33 #if !defined(__printf) 34 #define __printf(a, b) 35 #endif 36 37 #ifdef CONFIG_MCL 38 /* QDF_TRACE is the macro invoked to add trace messages to code. See the 39 * documenation for qdf_trace_msg() for the parameters etc. for this function. 40 * 41 * NOTE: Code QDF_TRACE() macros into the source code. Do not code directly 42 * to the qdf_trace_msg() function. 43 * 44 * NOTE 2: qdf tracing is totally turned off if WLAN_DEBUG is *not* defined. 45 * This allows us to build 'performance' builds where we can measure performance 46 * without being bogged down by all the tracing in the code 47 */ 48 #if defined(WLAN_DEBUG) || defined(DEBUG) 49 #define QDF_TRACE qdf_trace_msg 50 #define QDF_VTRACE qdf_vtrace_msg 51 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump 52 #define QDF_MAX_LOGS_PER_SEC 2 53 /** 54 * __QDF_TRACE_RATE_LIMITED() - rate limited version of QDF_TRACE 55 * @params: parameters to pass through to QDF_TRACE 56 * 57 * This API prevents logging a message more than QDF_MAX_LOGS_PER_SEC times per 58 * second. This means any subsequent calls to this API from the same location 59 * within 1/QDF_MAX_LOGS_PER_SEC seconds will be dropped. 60 * 61 * Return: None 62 */ 63 #define __QDF_TRACE_RATE_LIMITED(params...)\ 64 do {\ 65 static ulong __last_ticks;\ 66 ulong __ticks = jiffies;\ 67 if (time_after(__ticks,\ 68 __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\ 69 QDF_TRACE(params);\ 70 __last_ticks = __ticks;\ 71 } \ 72 } while (0) 73 #else 74 #define QDF_TRACE(arg ...) 75 #define QDF_VTRACE(arg ...) 76 #define QDF_TRACE_HEX_DUMP(arg ...) 77 #define __QDF_TRACE_RATE_LIMITED(arg ...) 78 #endif 79 #else /* CONFIG_MCL */ 80 81 #define qdf_trace(log_level, args...) \ 82 do { \ 83 extern int qdf_dbg_mask; \ 84 if (qdf_dbg_mask >= log_level) { \ 85 printk(args); \ 86 printk("\n"); \ 87 } \ 88 } while (0) 89 90 #define QDF_TRACE qdf_trace_msg 91 92 #define QDF_VTRACE qdf_vtrace_msg 93 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump 94 #define __QDF_TRACE_RATE_LIMITED(arg ...) 95 #endif /* CONFIG_MCL */ 96 97 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \ 98 QDF_TRACE(module_id, log_level, FL(format), ## args) 99 100 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \ 101 __QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args) 102 103 static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { } 104 105 #ifdef WLAN_LOG_FATAL 106 #define QDF_TRACE_FATAL(params...) \ 107 __QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params) 108 #define QDF_TRACE_FATAL_RL(params...) \ 109 __QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params) 110 #else 111 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params) 112 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params) 113 #endif 114 115 #ifdef WLAN_LOG_ERROR 116 #define QDF_TRACE_ERROR(params...) \ 117 __QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params) 118 #define QDF_TRACE_ERROR_RL(params...) \ 119 __QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params) 120 #else 121 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params) 122 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params) 123 #endif 124 125 #ifdef WLAN_LOG_WARN 126 #define QDF_TRACE_WARN(params...) \ 127 __QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params) 128 #define QDF_TRACE_WARN_RL(params...) \ 129 __QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params) 130 #else 131 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params) 132 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params) 133 #endif 134 135 #ifdef WLAN_LOG_INFO 136 #define QDF_TRACE_INFO(params...) \ 137 __QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params) 138 #define QDF_TRACE_INFO_RL(params...) \ 139 __QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params) 140 #else 141 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params) 142 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params) 143 #endif 144 145 #ifdef WLAN_LOG_DEBUG 146 #define QDF_TRACE_DEBUG(params...) \ 147 __QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params) 148 #define QDF_TRACE_DEBUG_RL(params...) \ 149 __QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params) 150 #else 151 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params) 152 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params) 153 #endif 154 155 #define QDF_ENABLE_TRACING 156 #define qdf_scnprintf scnprintf 157 158 #ifdef QDF_ENABLE_TRACING 159 160 #ifdef WLAN_WARN_ON_ASSERT 161 #define QDF_ASSERT(_condition) \ 162 do { \ 163 if (!(_condition)) { \ 164 pr_err("QDF ASSERT in %s Line %d\n", \ 165 __func__, __LINE__); \ 166 WARN_ON(1); \ 167 } \ 168 } while (0) 169 #else 170 #define QDF_ASSERT(_condition) \ 171 do { \ 172 if (!(_condition)) { \ 173 /* no-op */ \ 174 } \ 175 } while (0) 176 #endif /* WLAN_WARN_ON_ASSERT */ 177 178 #else 179 180 /* This code will be used for compilation if tracing is to be compiled out */ 181 /* of the code so these functions/macros are 'do nothing' */ 182 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level, 183 char *str_format, ...) 184 { 185 } 186 187 #define QDF_ASSERT(_condition) 188 189 #endif 190 191 #ifdef PANIC_ON_BUG 192 #ifdef CONFIG_SLUB_DEBUG 193 /** 194 * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled 195 * 196 * Note: Calling BUG() can cause a compiler to assume any following code is 197 * unreachable. Because these BUG's may or may not be enabled by the build 198 * configuration, this can cause developers some pain. Consider: 199 * 200 * bool bit; 201 * 202 * if (ptr) 203 * bit = ptr->returns_bool(); 204 * else 205 * __qdf_bug(); 206 * 207 * // do stuff with @bit 208 * 209 * return bit; 210 * 211 * In this case, @bit is potentially uninitialized when we return! However, the 212 * compiler can correctly assume this case is impossible when PANIC_ON_BUG is 213 * enabled. Because developers typically enable this feature, the "maybe 214 * uninitialized" warning will not be emitted, and the bug remains uncaught 215 * until someone tries to make a build without PANIC_ON_BUG. 216 * 217 * A simple workaround for this, is to put the definition of __qdf_bug in 218 * another compilation unit, which prevents the compiler from assuming 219 * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more 220 * bugs. Otherwise, use the typical inlined approach. 221 * 222 * Return: None 223 */ 224 void __qdf_bug(void); 225 #else /* CONFIG_SLUB_DEBUG */ 226 static inline void __qdf_bug(void) 227 { 228 BUG(); 229 } 230 #endif /* CONFIG_SLUB_DEBUG */ 231 232 /** 233 * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing 234 * @reason: An optional reason format string, followed by args 235 * 236 * Return: None 237 */ 238 #define QDF_DEBUG_PANIC(reason...) __QDF_DEBUG_PANIC("" reason) 239 240 #define __QDF_DEBUG_PANIC(ftm, args...) \ 241 do { \ 242 pr_err("WLAN Panic @ %s:%d: " ftm "\n", \ 243 __func__, __LINE__, ##args); \ 244 __qdf_bug(); \ 245 } while (false) 246 247 #define QDF_BUG(_condition) \ 248 do { \ 249 if (!(_condition)) { \ 250 pr_err("QDF BUG in %s Line %d: Failed assertion '" \ 251 #_condition "'\n", __func__, __LINE__); \ 252 __qdf_bug(); \ 253 } \ 254 } while (0) 255 256 #else /* PANIC_ON_BUG */ 257 258 #define QDF_DEBUG_PANIC(reason...) \ 259 do { \ 260 /* no-op */ \ 261 } while (false) 262 263 #define QDF_BUG(_condition) \ 264 do { \ 265 if (!(_condition)) { \ 266 /* no-op */ \ 267 } \ 268 } while (0) 269 270 #endif /* PANIC_ON_BUG */ 271 272 #ifdef KSYM_SYMBOL_LEN 273 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN 274 #else 275 #define __QDF_SYMBOL_LEN 1 276 #endif 277 278 #endif /* __I_QDF_TRACE_H */ 279