xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h (revision 1b9674e21e24478fba4530f5ae7396b9555e9c6a)
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 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 #else
119 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params)
120 #define QDF_TRACE_FATAL_NO_FL(params...) __qdf_trace_noop(params)
121 #define QDF_TRACE_FATAL_RL(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 #else
132 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params)
133 #define QDF_TRACE_ERROR_NO_FL(params...) __qdf_trace_noop(params)
134 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params)
135 #endif
136 
137 #ifdef WLAN_LOG_WARN
138 #define QDF_TRACE_WARN(params...) \
139 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params)
140 #define QDF_TRACE_WARN_NO_FL(params...) \
141 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_WARN, ## params)
142 #define QDF_TRACE_WARN_RL(params...) \
143 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params)
144 #else
145 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params)
146 #define QDF_TRACE_WARN_NO_FL(params...) __qdf_trace_noop(params)
147 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params)
148 #endif
149 
150 #ifdef WLAN_LOG_INFO
151 #define QDF_TRACE_INFO(params...) \
152 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)
153 #define QDF_TRACE_INFO_NO_FL(params...) \
154 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_INFO, ## params)
155 #define QDF_TRACE_INFO_RL(params...) \
156 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params)
157 #else
158 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params)
159 #define QDF_TRACE_INFO_NO_FL(params...) __qdf_trace_noop(params)
160 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params)
161 #endif
162 
163 #ifdef WLAN_LOG_DEBUG
164 #define QDF_TRACE_DEBUG(params...) \
165 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
166 #define QDF_TRACE_DEBUG_NO_FL(params...) \
167 	__QDF_TRACE_NO_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
168 #define QDF_TRACE_DEBUG_RL(params...) \
169 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
170 #else
171 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params)
172 #define QDF_TRACE_DEBUG_NO_FL(params...) __qdf_trace_noop(params)
173 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params)
174 #endif
175 
176 #ifdef WLAN_LOG_ENTER
177 #define QDF_TRACE_ENTER(params...) \
178 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
179 #else
180 #define QDF_TRACE_ENTER(params...) __qdf_trace_noop(params)
181 #endif
182 
183 #ifdef WLAN_LOG_EXIT
184 #define QDF_TRACE_EXIT(params...) \
185 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
186 #else
187 #define QDF_TRACE_EXIT(params...) __qdf_trace_noop(params)
188 #endif
189 
190 #define QDF_ENABLE_TRACING
191 #define qdf_scnprintf scnprintf
192 
193 #ifdef QDF_ENABLE_TRACING
194 
195 #ifdef WLAN_WARN_ON_ASSERT
196 #define QDF_ASSERT(_condition) \
197 	do { \
198 		if (!(_condition)) { \
199 			pr_err("QDF ASSERT in %s Line %d\n", \
200 			       __func__, __LINE__); \
201 			WARN_ON(1); \
202 		} \
203 	} while (0)
204 #else
205 #define QDF_ASSERT(_condition) \
206 	do { \
207 		if (!(_condition)) { \
208 			/* no-op */ \
209 		} \
210 	} while (0)
211 #endif /* WLAN_WARN_ON_ASSERT */
212 
213 #else
214 
215 /* This code will be used for compilation if tracing is to be compiled out */
216 /* of the code so these functions/macros are 'do nothing' */
217 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
218 		   char *str_format, ...)
219 {
220 }
221 
222 #define QDF_ASSERT(_condition)
223 
224 #endif
225 
226 #ifdef PANIC_ON_BUG
227 #ifdef CONFIG_SLUB_DEBUG
228 /**
229  * __qdf_bug() - Calls BUG() when the PANIC_ON_BUG compilation option is enabled
230  *
231  * Note: Calling BUG() can cause a compiler to assume any following code is
232  * unreachable. Because these BUG's may or may not be enabled by the build
233  * configuration, this can cause developers some pain. Consider:
234  *
235  *	bool bit;
236  *
237  *	if (ptr)
238  *		bit = ptr->returns_bool();
239  *	else
240  *		__qdf_bug();
241  *
242  *	// do stuff with @bit
243  *
244  *	return bit;
245  *
246  * In this case, @bit is potentially uninitialized when we return! However, the
247  * compiler can correctly assume this case is impossible when PANIC_ON_BUG is
248  * enabled. Because developers typically enable this feature, the "maybe
249  * uninitialized" warning will not be emitted, and the bug remains uncaught
250  * until someone tries to make a build without PANIC_ON_BUG.
251  *
252  * A simple workaround for this, is to put the definition of __qdf_bug in
253  * another compilation unit, which prevents the compiler from assuming
254  * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more
255  * bugs. Otherwise, use the typical inlined approach.
256  *
257  * Return: None
258  */
259 void __qdf_bug(void);
260 #else /* CONFIG_SLUB_DEBUG */
261 static inline void __qdf_bug(void)
262 {
263 	BUG();
264 }
265 #endif /* CONFIG_SLUB_DEBUG */
266 
267 /**
268  * QDF_DEBUG_PANIC() - In debug builds, panic, otherwise do nothing
269  * @reason: An optional reason format string, followed by args
270  *
271  * Return: None
272  */
273 #define QDF_DEBUG_PANIC(reason...) \
274 	QDF_DEBUG_PANIC_FL(__func__, __LINE__, "" reason)
275 
276 /**
277  * QDF_DEBUG_PANIC_FL() - In debug builds, panic, otherwise do nothing
278  * @func: origin function name to be logged
279  * @line: origin line number to be logged
280  * @fmt: printf compatible format string to be logged
281  * @args: zero or more printf compatible logging arguments
282  *
283  * Return: None
284  */
285 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
286 	do { \
287 		pr_err("WLAN Panic @ %s:%d: " fmt "\n", func, line, ##args); \
288 		__qdf_bug(); \
289 	} while (false)
290 
291 #define QDF_BUG(_condition) \
292 	do { \
293 		if (!(_condition)) { \
294 			pr_err("QDF BUG in %s Line %d: Failed assertion '" \
295 			       #_condition "'\n", __func__, __LINE__); \
296 			__qdf_bug(); \
297 		} \
298 	} while (0)
299 
300 #else /* PANIC_ON_BUG */
301 
302 #define QDF_DEBUG_PANIC(reason...) \
303 	do { \
304 		/* no-op */ \
305 	} while (false)
306 
307 #define QDF_DEBUG_PANIC_FL(func, line, fmt, args...) \
308 	do { \
309 		/* no-op */ \
310 	} while (false)
311 
312 #define QDF_BUG(_condition) \
313 	do { \
314 		if (!(_condition)) { \
315 			/* no-op */ \
316 		} \
317 	} while (0)
318 
319 #endif /* PANIC_ON_BUG */
320 
321 #ifdef KSYM_SYMBOL_LEN
322 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN
323 #else
324 #define __QDF_SYMBOL_LEN 1
325 #endif
326 
327 #endif /* __I_QDF_TRACE_H */
328