xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h (revision 4865edfd190c086bbe2c69aae12a8226f877b91e)
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 #endif /* CONFIG_MCL */
95 
96 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \
97 	QDF_TRACE(module_id, log_level, FL(format), ## args)
98 
99 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \
100 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args)
101 
102 static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { }
103 
104 #ifdef WLAN_LOG_FATAL
105 #define QDF_TRACE_FATAL(params...) \
106 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_FATAL, ## params)
107 #define QDF_TRACE_FATAL_RL(params...) \
108 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_FATAL, ## params)
109 #else
110 #define QDF_TRACE_FATAL(params...) __qdf_trace_noop(params)
111 #define QDF_TRACE_FATAL_RL(params...) __qdf_trace_noop(params)
112 #endif
113 
114 #ifdef WLAN_LOG_ERROR
115 #define QDF_TRACE_ERROR(params...) \
116 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params)
117 #define QDF_TRACE_ERROR_RL(params...) \
118 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params)
119 #else
120 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params)
121 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params)
122 #endif
123 
124 #ifdef WLAN_LOG_WARN
125 #define QDF_TRACE_WARN(params...) \
126 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params)
127 #define QDF_TRACE_WARN_RL(params...) \
128 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params)
129 #else
130 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params)
131 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params)
132 #endif
133 
134 #ifdef WLAN_LOG_INFO
135 #define QDF_TRACE_INFO(params...) \
136 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)
137 #define QDF_TRACE_INFO_RL(params...) \
138 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params)
139 #else
140 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params)
141 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params)
142 #endif
143 
144 #ifdef WLAN_LOG_DEBUG
145 #define QDF_TRACE_DEBUG(params...) \
146 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
147 #define QDF_TRACE_DEBUG_RL(params...) \
148 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
149 #else
150 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params)
151 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params)
152 #endif
153 
154 #define QDF_ENABLE_TRACING
155 #define qdf_scnprintf scnprintf
156 
157 #ifdef QDF_ENABLE_TRACING
158 
159 #ifdef WLAN_WARN_ON_ASSERT
160 #define QDF_ASSERT(_condition) \
161 	do { \
162 		if (!(_condition)) { \
163 			pr_err("QDF ASSERT in %s Line %d\n", \
164 			       __func__, __LINE__); \
165 			WARN_ON(1); \
166 		} \
167 	} while (0)
168 #else
169 #define QDF_ASSERT(_condition) \
170 	do { \
171 		if (!(_condition)) { \
172 			/* no-op */ \
173 		} \
174 	} while (0)
175 #endif /* WLAN_WARN_ON_ASSERT */
176 
177 #else
178 
179 /* This code will be used for compilation if tracing is to be compiled out */
180 /* of the code so these functions/macros are 'do nothing' */
181 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
182 		   char *str_format, ...)
183 {
184 }
185 
186 #define QDF_ASSERT(_condition)
187 
188 #endif
189 
190 #ifdef PANIC_ON_BUG
191 #ifdef CONFIG_SLUB_DEBUG
192 /**
193  * QDF_DEBUG_PANIC() - Causes a panic if PANIC_ON_BUG option is enabled
194  *
195  * Note: Calling panic can cause a compiler to assume any following code is
196  * unreachable. Because these panics may or may not be enabled by the build
197  * configuration, this can cause developers some pain. Consider:
198  *
199  *	bool bit;
200  *
201  *	if (ptr)
202  *		bit = ptr->returns_bool();
203  *	else
204  *		panic();
205  *
206  *	// do stuff with @bit
207  *
208  *	return bit;
209  *
210  * In this case, @bit is potentially uninitialized when we return! However, the
211  * compiler can correctly assume this case is impossible when PANIC_ON_BUG is
212  * enabled. Because developers typically enable this feature, the "maybe
213  * uninitialized" warning will not be emitted, and the bug remains uncaught
214  * until someone tries to make a build without PANIC_ON_BUG.
215  *
216  * A simple workaround for this, is to put the definition of QDF_DEBUG_PANIC in
217  * another compilation unit, which prevents the compiler from assuming
218  * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more
219  * bugs. Otherwise, use the typical inlined approach.
220  *
221  * Return: None
222  */
223 void QDF_DEBUG_PANIC(void);
224 #else
225 static inline void QDF_DEBUG_PANIC(void)
226 {
227 	BUG();
228 }
229 #endif /* CONFIG_SLUB_DEBUG */
230 
231 #define QDF_BUG(_condition) \
232 	do { \
233 		if (!(_condition)) { \
234 			pr_err("QDF BUG in %s Line %d: Failed assertion '" \
235 			       #_condition "'\n", __func__, __LINE__); \
236 			QDF_DEBUG_PANIC(); \
237 		} \
238 	} while (0)
239 
240 #else
241 
242 static inline void QDF_DEBUG_PANIC(void) { }
243 
244 #define QDF_BUG(_condition) \
245 	do { \
246 		if (!(_condition)) { \
247 			/* no-op */ \
248 		} \
249 	} while (0)
250 #endif /* PANIC_ON_BUG */
251 
252 #ifdef KSYM_SYMBOL_LEN
253 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN
254 #else
255 #define __QDF_SYMBOL_LEN 1
256 #endif
257 
258 #endif /* __I_QDF_TRACE_H */
259