xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h (revision 302a1d9701784af5f4797b1a9fe07ae820b51907)
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 #else
53 #define QDF_TRACE(arg ...)
54 #define QDF_VTRACE(arg ...)
55 #define QDF_TRACE_HEX_DUMP(arg ...)
56 #endif
57 #else /* CONFIG_MCL */
58 
59 #define qdf_trace(log_level, args...) \
60 		do {	\
61 			extern int qdf_dbg_mask; \
62 			if (qdf_dbg_mask >= log_level) { \
63 				printk(args); \
64 				printk("\n"); \
65 			} \
66 		} while (0)
67 
68 #define QDF_TRACE qdf_trace_msg
69 
70 #define QDF_VTRACE qdf_vtrace_msg
71 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump
72 #endif /* CONFIG_MCL */
73 
74 #if defined(WLAN_DEBUG) || defined(DEBUG)
75 #define QDF_MAX_LOGS_PER_SEC 2
76 /**
77  * __QDF_TRACE_RATE_LIMITED() - rate limited version of QDF_TRACE
78  * @params: parameters to pass through to QDF_TRACE
79  *
80  * This API prevents logging a message more than QDF_MAX_LOGS_PER_SEC times per
81  * second. This means any subsequent calls to this API from the same location
82  * within 1/QDF_MAX_LOGS_PER_SEC seconds will be dropped.
83  *
84  * Return: None
85  */
86 #define __QDF_TRACE_RATE_LIMITED(params...)\
87 	do {\
88 		static ulong __last_ticks;\
89 		ulong __ticks = jiffies;\
90 		if (time_after(__ticks,\
91 			       __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\
92 			QDF_TRACE(params);\
93 			__last_ticks = __ticks;\
94 		} \
95 	} while (0)
96 #else
97 #define __QDF_TRACE_RATE_LIMITED(arg ...)
98 #endif
99 
100 #define __QDF_TRACE_NO_FL(log_level, module_id, format, args...) \
101 	QDF_TRACE(module_id, log_level, format, ## args)
102 
103 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \
104 	QDF_TRACE(module_id, log_level, FL(format), ## args)
105 
106 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \
107 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args)
108 
109 #define __QDF_TRACE_RL_NO_FL(log_level, module_id, format, args...) \
110 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, format, ## args)
111 
112 static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { }
113 
114 #ifdef WLAN_LOG_FATAL
115 #define QDF_TRACE_FATAL(params...) \
116 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params)
117 #define QDF_TRACE_FATAL_NO_FL(params...) \
118 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params)
119 #define QDF_TRACE_FATAL_RL(params...) \
120 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params)
121 #define QDF_TRACE_FATAL_RL_NO_FL(params...) \
122 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_FATAL, ## params)
123 #else
124 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params)
125 #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params)
126 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params)
127 #define QDF_TRACE_FATAL_RL_NO_FL(params...) __qdf_trace_noop(params)
128 #endif
129 
130 #ifdef WLAN_LOG_ERROR
131 #define QDF_TRACE_ERROR(params...) \
132 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params)
133 #define QDF_TRACE_ERROR_NO_FL(params...) \
134 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params)
135 #define QDF_TRACE_ERROR_RL(params...) \
136 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params)
137 #define QDF_TRACE_ERROR_RL_NO_FL(params...) \
138 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_ERROR, ## params)
139 #else
140 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params)
141 #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params)
142 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params)
143 #define QDF_TRACE_ERROR_RL_NO_FL(params...) __qdf_trace_noop(params)
144 #endif
145 
146 #ifdef WLAN_LOG_WARN
147 #define QDF_TRACE_WARN(params...) \
148 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params)
149 #define QDF_TRACE_WARN_NO_FL(params...) \
150 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_WARN, ## params)
151 #define QDF_TRACE_WARN_RL(params...) \
152 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params)
153 #define QDF_TRACE_WARN_RL_NO_FL(params...) \
154 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_WARN, ## params)
155 #else
156 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params)
157 #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params)
158 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params)
159 #define QDF_TRACE_WARN_RL_NO_FL(params...) __qdf_trace_noop(params)
160 #endif
161 
162 #ifdef WLAN_LOG_INFO
163 #define QDF_TRACE_INFO(params...) \
164 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)
165 #define QDF_TRACE_INFO_NO_FL(params...) \
166 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_INFO, ## params)
167 #define QDF_TRACE_INFO_RL(params...) \
168 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params)
169 #define QDF_TRACE_INFO_RL_NO_FL(params...) \
170 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_INFO, ## params)
171 #else
172 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params)
173 #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params)
174 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params)
175 #define QDF_TRACE_INFO_RL_NO_FL(params...) __qdf_trace_noop(params)
176 #endif
177 
178 #ifdef WLAN_LOG_DEBUG
179 #define QDF_TRACE_DEBUG(params...) \
180 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
181 #define QDF_TRACE_DEBUG_NO_FL(params...) \
182 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
183 #define QDF_TRACE_DEBUG_RL(params...) \
184 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
185 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) \
186 	__QDF_TRACE_RL_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
187 #else
188 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params)
189 #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params)
190 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params)
191 #define QDF_TRACE_DEBUG_RL_NO_FL(params...) __qdf_trace_noop(params)
192 #endif
193 
194 #ifdef WLAN_LOG_ENTER
195 #define QDF_TRACE_ENTER(params...) \
196 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
197 #else
198 #define QDF_TRACE_ENTER(params...) __qdf_trace_noop(params)
199 #endif
200 
201 #ifdef WLAN_LOG_EXIT
202 #define QDF_TRACE_EXIT(params...) \
203 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
204 #else
205 #define QDF_TRACE_EXIT(params...) __qdf_trace_noop(params)
206 #endif
207 
208 #define QDF_ENABLE_TRACING
209 #define qdf_scnprintf scnprintf
210 
211 #ifdef QDF_ENABLE_TRACING
212 
213 #ifdef WLAN_WARN_ON_ASSERT
214 #define QDF_ASSERT(_condition) \
215 	do { \
216 		if (!(_condition)) { \
217 			pr_err("QDF ASSERT in %s Line %d\n", \
218 			       __func__, __LINE__); \
219 			WARN_ON(1); \
220 		} \
221 	} while (0)
222 #else
223 #define QDF_ASSERT(_condition) \
224 	do { \
225 		if (!(_condition)) { \
226 			/* no-op */ \
227 		} \
228 	} while (0)
229 #endif /* WLAN_WARN_ON_ASSERT */
230 
231 #else
232 
233 /* This code will be used for compilation if tracing is to be compiled out */
234 /* of the code so these functions/macros are 'do nothing' */
235 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
236 		   char *str_format, ...)
237 {
238 }
239 
240 #define QDF_ASSERT(_condition)
241 
242 #endif
243 
244 #ifdef PANIC_ON_BUG
245 #ifdef CONFIG_SLUB_DEBUG
246 /**
247  * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled
248  *
249  * Note: Calling BUG() can cause a compiler to assume any following code is
250  * unreachable. Because these BUG's may or may not be enabled by the build
251  * configuration, this can cause developers some pain. Consider:
252  *
253  *	bool bit;
254  *
255  *	if (ptr)
256  *		bit = ptr->returns_bool();
257  *	else
258  *		__qdf_bug();
259  *
260  *	// do stuff with @bit
261  *
262  *	return bit;
263  *
264  * In this case, @bit is potentially uninitialized when we return! However, the
265  * compiler can correctly assume this case is impossible when PANIC_ON_BUG is
266  * enabled. Because developers typically enable this feature, the "maybe
267  * uninitialized" warning will not be emitted, and the bug remains uncaught
268  * until someone tries to make a build without PANIC_ON_BUG.
269  *
270  * A simple workaround for this, is to put the definition of __qdf_bug in
271  * another compilation unit, which prevents the compiler from assuming
272  * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more
273  * bugs. Otherwise, use the typical inlined approach.
274  *
275  * Return: None
276  */
277 void __qdf_bug(void);
278 #else /* CONFIG_SLUB_DEBUG */
279 static inline void __qdf_bug(void)
280 {
281 	BUG();
282 }
283 #endif /* CONFIG_SLUB_DEBUG */
284 
285 /**
286  * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing
287  * @reason: An optional reason format string, followed by args
288  *
289  * Return: None
290  */
291 #define QDF_DEBUG_PANIC(reason...) \
292 	QDF_DEBUG_PANIC_FL(__func__, __LINE__, "" reason)
293 
294 /**
295  * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing
296  * @func: origin function name to be logged
297  * @line: origin line number to be logged
298  * @fmt: printf compatible format string to be logged
299  * @args: zero or more printf compatible logging arguments
300  *
301  * Return: None
302  */
303 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
304 	do { \
305 		pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \
306 		__qdf_bug(); \
307 	} while (false)
308 
309 #define QDF_BUG(_condition) \
310 	do { \
311 		if (!(_condition)) { \
312 			pr_err("QDF BUG in %s Line %d: Failed assertion '" \
313 			       #_condition "'\n", __func__, __LINE__); \
314 			__qdf_bug(); \
315 		} \
316 	} while (0)
317 
318 #else /* PANIC_ON_BUG */
319 
320 #define QDF_DEBUG_PANIC(reason...) \
321 	do { \
322 		/* no-op */ \
323 	} while (false)
324 
325 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
326 	do { \
327 		/* no-op */ \
328 	} while (false)
329 
330 #define QDF_BUG(_condition) \
331 	do { \
332 		if (!(_condition)) { \
333 			/* no-op */ \
334 		} \
335 	} while (0)
336 
337 #endif /* PANIC_ON_BUG */
338 
339 #ifdef KSYM_SYMBOL_LEN
340 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN
341 #else
342 #define __QDF_SYMBOL_LEN 1
343 #endif
344 
345 #endif /* __I_QDF_TRACE_H */
346