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