xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h (revision 861af9fad3d20cded5a90c420dd1ed901be32691)
1 /*
2  * Copyright (c) 2014-2020 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 ...) __qdf_trace_dummy(arg)
67 #define QDF_VTRACE(arg ...) __qdf_vtrace_dummy(arg)
68 #define QDF_TRACE_HEX_DUMP(arg ...) __qdf_trace_hexdump_dummy(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 
94 #define __QDF_TRACE_HEX_DUMP_RATE_LIMITED(params...)\
95 	do {\
96 		static ulong __last_ticks;\
97 		ulong __ticks = jiffies;\
98 		if (time_after(__ticks,\
99 			       __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\
100 			QDF_TRACE_HEX_DUMP(params);\
101 			__last_ticks = __ticks;\
102 		} \
103 	} while (0)
104 #else
105 #define __QDF_TRACE_RATE_LIMITED(arg ...)
106 #define __QDF_TRACE_HEX_DUMP_RATE_LIMITED(arg ...)
107 #endif
108 
109 #define __QDF_TRACE_NO_FL(log_level, module_id, format, args...) \
110 	QDF_TRACE(module_id, log_level, format, ## args)
111 
112 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \
113 	QDF_TRACE(module_id, log_level, FL(format), ## args)
114 
115 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \
116 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args)
117 
118 #define __QDF_TRACE_RL_NO_FL(log_level, module_id, format, args...) \
119 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, format, ## args)
120 
121 #define __QDF_TRACE_HEX_DUMP_RL(log_level, module_id, args...) \
122 	__QDF_TRACE_HEX_DUMP_RATE_LIMITED(module_id, log_level, ## args)
123 
124 static inline void __qdf_trace_noop(QDF_MODULE_ID module,
125 				    const char *format, ...) { }
126 static inline void __qdf_trace_dummy(QDF_MODULE_ID module,
127 				     QDF_TRACE_LEVEL level,
128 				     const char *format, ...) { }
129 static inline void __qdf_vtrace_dummy(QDF_MODULE_ID module,
130 				      QDF_TRACE_LEVEL level,
131 				      const char *str_format, va_list val) { }
132 static inline void __qdf_trace_hexdump_dummy(QDF_MODULE_ID module,
133 					     QDF_TRACE_LEVEL level,
134 					     void *data, int buf_len) { }
135 
136 
137 #ifdef WLAN_LOG_FATAL
138 #define QDF_TRACE_FATAL(params...) \
139 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params)
140 #define QDF_TRACE_FATAL_NO_FL(params...) \
141 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params)
142 #define QDF_TRACE_FATAL_RL(params...) \
143 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params)
144 #define QDF_TRACE_FATAL_RL_NO_FL(params...) \
145 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params)
146 #define QDF_VTRACE_FATAL(module_id, fmt, args) \
147 	QDF_VTRACE(module_id, QDF_TRACE_LEVEL_FATAL, fmt, args)
148 #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) \
149 	__QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_FATAL, ## params)
150 #else
151 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params)
152 #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params)
153 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params)
154 #define QDF_TRACE_FATAL_RL_NO_FL(params...) __qdf_trace_noop(params)
155 #define QDF_VTRACE_FATAL(params...) __qdf_trace_noop(params)
156 #define QDF_TRACE_HEX_DUMP_FATAL_RL(params...) __qdf_trace_noop(params)
157 #endif
158 
159 #ifdef WLAN_LOG_ERROR
160 #define QDF_TRACE_ERROR(params...) \
161 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params)
162 #define QDF_TRACE_ERROR_NO_FL(params...) \
163 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params)
164 #define QDF_TRACE_ERROR_RL(params...) \
165 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params)
166 #define QDF_TRACE_ERROR_RL_NO_FL(params...) \
167 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params)
168 #define QDF_VTRACE_ERROR(module_id, fmt, args) \
169 	QDF_VTRACE(module_id, QDF_TRACE_LEVEL_ERROR, fmt, args)
170 #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) \
171 	__QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_ERROR, ## params)
172 #else
173 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params)
174 #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params)
175 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params)
176 #define QDF_TRACE_ERROR_RL_NO_FL(params...) __qdf_trace_noop(params)
177 #define QDF_VTRACE_ERROR(params...) __qdf_trace_noop(params)
178 #define QDF_TRACE_HEX_DUMP_ERROR_RL(params...) __qdf_trace_noop(params)
179 #endif
180 
181 #ifdef WLAN_LOG_WARN
182 #define QDF_TRACE_WARN(params...) \
183 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params)
184 #define QDF_TRACE_WARN_NO_FL(params...) \
185 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_WARN, ## params)
186 #define QDF_TRACE_WARN_RL(params...) \
187 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params)
188 #define QDF_TRACE_WARN_RL_NO_FL(params...) \
189 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_WARN, ## params)
190 #define QDF_VTRACE_WARN(module_id, fmt, args) \
191 	QDF_VTRACE(module_id, QDF_TRACE_LEVEL_WARN, fmt, args)
192 #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) \
193 	__QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_WARN, ## params)
194 #else
195 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params)
196 #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params)
197 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params)
198 #define QDF_TRACE_WARN_RL_NO_FL(params...) __qdf_trace_noop(params)
199 #define QDF_VTRACE_WARN(params...) __qdf_trace_noop(params)
200 #define QDF_TRACE_HEX_DUMP_WARN_RL(params...) __qdf_trace_noop(params)
201 #endif
202 
203 #ifdef WLAN_LOG_INFO
204 #define QDF_TRACE_INFO(params...) \
205 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)
206 #define QDF_TRACE_INFO_NO_FL(params...) \
207 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_INFO, ## params)
208 #define QDF_TRACE_INFO_RL(params...) \
209 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params)
210 #define QDF_TRACE_INFO_RL_NO_FL(params...) \
211 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_INFO, ## params)
212 #define QDF_VTRACE_INFO(module_id, fmt, args) \
213 	QDF_VTRACE(module_id, QDF_TRACE_LEVEL_INFO, fmt, args)
214 #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) \
215 	__QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_INFO, ## params)
216 #else
217 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params)
218 #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params)
219 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params)
220 #define QDF_TRACE_INFO_RL_NO_FL(params...) __qdf_trace_noop(params)
221 #define QDF_VTRACE_INFO(params...) __qdf_trace_noop(params)
222 #define QDF_TRACE_HEX_DUMP_INFO_RL(params...) __qdf_trace_noop(params)
223 #endif
224 
225 #ifdef WLAN_LOG_DEBUG
226 #define QDF_TRACE_DEBUG(params...) \
227 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
228 #define QDF_TRACE_DEBUG_NO_FL(params...) \
229 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
230 #define QDF_TRACE_DEBUG_RL(params...) \
231 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
232 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) \
233 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
234 #define QDF_VTRACE_DEBUG(module_id, fmt, args) \
235 	QDF_VTRACE(module_id, QDF_TRACE_LEVEL_DEBUG, fmt, args)
236 #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) \
237 	__QDF_TRACE_HEX_DUMP_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
238 #else
239 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params)
240 #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params)
241 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params)
242 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) __qdf_trace_noop(params)
243 #define QDF_VTRACE_DEBUG(params...) __qdf_trace_noop(params)
244 #define QDF_TRACE_HEX_DUMP_DEBUG_RL(params...) __qdf_trace_noop(params)
245 #endif
246 
247 #ifdef WLAN_LOG_ENTER
248 #define QDF_TRACE_ENTER(params...) \
249 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
250 #else
251 #define QDF_TRACE_ENTER(params...) __qdf_trace_noop(params)
252 #endif
253 
254 #ifdef WLAN_LOG_EXIT
255 #define QDF_TRACE_EXIT(params...) \
256 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
257 #else
258 #define QDF_TRACE_EXIT(params...) __qdf_trace_noop(params)
259 #endif
260 
261 #define QDF_ENABLE_TRACING
262 #define qdf_scnprintf scnprintf
263 
264 #ifdef QDF_ENABLE_TRACING
265 
266 #ifdef WLAN_WARN_ON_ASSERT
267 #define QDF_ASSERT(_condition) \
268 	do { \
269 		if (!(_condition)) { \
270 			pr_err("QDF ASSERT in %s Line %d\n", \
271 			       __func__, __LINE__); \
272 			WARN_ON(1); \
273 		} \
274 	} while (0)
275 #else
276 #define QDF_ASSERT(_condition) \
277 	do { \
278 		if (!(_condition)) { \
279 			/* no-op */ \
280 		} \
281 	} while (0)
282 #endif /* WLAN_WARN_ON_ASSERT */
283 /**
284  * qdf_trace_msg()- logging API
285  * @module: Module identifier. A member of the QDF_MODULE_ID enumeration that
286  *	    identifies the module issuing the trace message.
287  * @level: Trace level. A member of the QDF_TRACE_LEVEL enumeration indicating
288  *	   the severity of the condition causing the trace message to be issued.
289  *	   More severe conditions are more likely to be logged.
290  * @str_format: Format string. The message to be logged. This format string
291  *	       contains printf-like replacement parameters, which follow this
292  *	       parameter in the variable argument list.
293  *
294  * Users wishing to add tracing information to their code should use
295  * QDF_TRACE.  QDF_TRACE() will compile into a call to qdf_trace_msg() when
296  * tracing is enabled.
297  *
298  * Return: nothing
299  *
300  * implemented in qdf_trace.c
301  */
302 void __printf(3, 4) qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
303 				  const char *str_format, ...);
304 
305 /**
306  * qdf_vtrace_msg() - the va_list version of qdf_trace_msg
307  * @module: the calling module's Id
308  * @level: the logging level to log using
309  * @str_format: the log format string
310  * @val: the va_list containing the values to format according to str_format
311  *
312  * Return: None
313  */
314 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
315 		    const char *str_format, va_list val);
316 
317 #else
318 
319 /* This code will be used for compilation if tracing is to be compiled out */
320 /* of the code so these functions/macros are 'do nothing' */
321 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
322 				 const char *str_format, ...)
323 {
324 }
325 
326 #define QDF_ASSERT(_condition)
327 
328 #endif
329 
330 #ifdef QDF_TRACE_PRINT_ENABLE
331 static inline void qdf_vprint(const char *fmt, va_list args)
332 {
333 	QDF_VTRACE_INFO(QDF_MODULE_ID_ANY, fmt, args);
334 }
335 #else /* QDF_TRACE_PRINT_ENABLE */
336 static inline void qdf_vprint(const char *fmt, va_list args)
337 {
338 	QDF_VTRACE_ERROR(QDF_MODULE_ID_QDF, fmt, args);
339 }
340 #endif
341 
342 #ifdef PANIC_ON_BUG
343 #ifdef CONFIG_SLUB_DEBUG
344 /**
345  * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled
346  *
347  * Note: Calling BUG() can cause a compiler to assume any following code is
348  * unreachable. Because these BUG's may or may not be enabled by the build
349  * configuration, this can cause developers some pain. Consider:
350  *
351  *	bool bit;
352  *
353  *	if (ptr)
354  *		bit = ptr->returns_bool();
355  *	else
356  *		__qdf_bug();
357  *
358  *	// do stuff with @bit
359  *
360  *	return bit;
361  *
362  * In this case, @bit is potentially uninitialized when we return! However, the
363  * compiler can correctly assume this case is impossible when PANIC_ON_BUG is
364  * enabled. Because developers typically enable this feature, the "maybe
365  * uninitialized" warning will not be emitted, and the bug remains uncaught
366  * until someone tries to make a build without PANIC_ON_BUG.
367  *
368  * A simple workaround for this, is to put the definition of __qdf_bug in
369  * another compilation unit, which prevents the compiler from assuming
370  * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more
371  * bugs. Otherwise, use the typical inlined approach.
372  *
373  * Return: None
374  */
375 void __qdf_bug(void);
376 #else /* CONFIG_SLUB_DEBUG */
377 static inline void __qdf_bug(void)
378 {
379 	BUG();
380 }
381 #endif /* CONFIG_SLUB_DEBUG */
382 
383 /**
384  * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing
385  * @reason_fmt: a format string containing the reason for the panic
386  * @args: zero or more printf compatible logging arguments
387  *
388  * Return: None
389  */
390 #define QDF_DEBUG_PANIC(reason_fmt, args...) \
391 	QDF_DEBUG_PANIC_FL(__func__, __LINE__, reason_fmt, ## args)
392 
393 /**
394  * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing
395  * @func: origin function name to be logged
396  * @line: origin line number to be logged
397  * @fmt: printf compatible format string to be logged
398  * @args: zero or more printf compatible logging arguments
399  *
400  * Return: None
401  */
402 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
403 	do { \
404 		pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \
405 		__qdf_bug(); \
406 	} while (false)
407 
408 #define QDF_BUG(_condition) \
409 	do { \
410 		if (!(_condition)) { \
411 			pr_err("QDF BUG in %s Line %d: Failed assertion '" \
412 			       #_condition "'\n", __func__, __LINE__); \
413 			__qdf_bug(); \
414 		} \
415 	} while (0)
416 
417 #else /* PANIC_ON_BUG */
418 
419 #define QDF_DEBUG_PANIC(reason...) \
420 	do { \
421 		/* no-op */ \
422 	} while (false)
423 
424 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
425 	do { \
426 		/* no-op */ \
427 	} while (false)
428 
429 #define QDF_BUG(_condition) \
430 	do { \
431 		if (!(_condition)) { \
432 			/* no-op */ \
433 		} \
434 	} while (0)
435 
436 #endif /* PANIC_ON_BUG */
437 
438 #ifdef KSYM_SYMBOL_LEN
439 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN
440 #else
441 #define __QDF_SYMBOL_LEN 1
442 #endif
443 
444 #ifdef CONFIG_QCA_MINIDUMP
445 static inline void
446 __qdf_minidump_log(void *start_addr, size_t size, const char *name)
447 {
448 	if (minidump_fill_segments((const uintptr_t)start_addr, size,
449 				   QCA_WDT_LOG_DUMP_TYPE_WLAN_MOD,
450 				   name) < 0)
451 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO,
452 			"%s: failed to log %pK (%s)\n",
453 			__func__, start_addr, name);
454 }
455 
456 static inline void
457 __qdf_minidump_remove(void *addr)
458 {
459 	minidump_remove_segments((const uintptr_t)addr);
460 }
461 #else
462 static inline void
463 __qdf_minidump_log(void *start_addr, size_t size, const char *name) {}
464 static inline void
465 __qdf_minidump_remove(void *addr) {}
466 #endif
467 #endif /* __I_QDF_TRACE_H */
468