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