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