xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/i_qdf_trace.h (revision 6ecd284e5a94a1c96e26d571dd47419ac305990d)
1 /*
2  * Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
3  *
4  * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5  *
6  *
7  * Permission to use, copy, modify, and/or distribute this software for
8  * any purpose with or without fee is hereby granted, provided that the
9  * above copyright notice and this permission notice appear in all
10  * copies.
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19  * PERFORMANCE OF THIS SOFTWARE.
20  */
21 
22 /*
23  * This file was originally distributed by Qualcomm Atheros, Inc.
24  * under proprietary terms before Copyright ownership was assigned
25  * to the Linux Foundation.
26  */
27 
28 /**
29  * DOC: i_qdf_trace.h
30  *
31  * Linux-specific definitions for QDF trace
32  *
33  */
34 
35 #if !defined(__I_QDF_TRACE_H)
36 #define __I_QDF_TRACE_H
37 
38 /* older kernels have a bug in kallsyms, so ensure module.h is included */
39 #include <linux/module.h>
40 #include <linux/kallsyms.h>
41 
42 #if !defined(__printf)
43 #define __printf(a, b)
44 #endif
45 
46 #ifdef CONFIG_MCL
47 /* QDF_TRACE is the macro invoked to add trace messages to code.  See the
48  * documenation for qdf_trace_msg() for the parameters etc. for this function.
49  *
50  * NOTE:  Code QDF_TRACE() macros into the source code.  Do not code directly
51  * to the qdf_trace_msg() function.
52  *
53  * NOTE 2:  qdf tracing is totally turned off if WLAN_DEBUG is *not* defined.
54  * This allows us to build 'performance' builds where we can measure performance
55  * without being bogged down by all the tracing in the code
56  */
57 #if defined(WLAN_DEBUG) || defined(DEBUG)
58 #define QDF_TRACE qdf_trace_msg
59 #define QDF_VTRACE qdf_vtrace_msg
60 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump
61 #define QDF_MAX_LOGS_PER_SEC 2
62 /**
63  * __QDF_TRACE_RATE_LIMITED() - rate limited version of QDF_TRACE
64  * @params: parameters to pass through to QDF_TRACE
65  *
66  * This API prevents logging a message more than QDF_MAX_LOGS_PER_SEC times per
67  * second. This means any subsequent calls to this API from the same location
68  * within 1/QDF_MAX_LOGS_PER_SEC seconds will be dropped.
69  *
70  * Return: None
71  */
72 #define __QDF_TRACE_RATE_LIMITED(params...)\
73 	do {\
74 		static ulong __last_ticks;\
75 		ulong __ticks = jiffies;\
76 		if (time_after(__ticks,\
77 			       __last_ticks + HZ / QDF_MAX_LOGS_PER_SEC)) {\
78 			QDF_TRACE(params);\
79 			__last_ticks = __ticks;\
80 		} \
81 	} while (0)
82 #else
83 #define QDF_TRACE(arg ...)
84 #define QDF_VTRACE(arg ...)
85 #define QDF_TRACE_HEX_DUMP(arg ...)
86 #define __QDF_TRACE_RATE_LIMITED(arg ...)
87 #endif
88 #else /* CONFIG_MCL */
89 
90 #define qdf_trace(log_level, args...) \
91 		do {	\
92 			extern int qdf_dbg_mask; \
93 			if (qdf_dbg_mask >= log_level) { \
94 				printk(args); \
95 				printk("\n"); \
96 			} \
97 		} while (0)
98 
99 #define QDF_TRACE qdf_trace_msg
100 
101 #define QDF_VTRACE qdf_vtrace_msg
102 #define QDF_TRACE_HEX_DUMP qdf_trace_hex_dump
103 #endif /* CONFIG_MCL */
104 
105 #define __QDF_TRACE_FL(log_level, module_id, format, args...) \
106 	QDF_TRACE(module_id, log_level, FL(format), ## args)
107 
108 #define __QDF_TRACE_RL(log_level, module_id, format, args...) \
109 	__QDF_TRACE_RATE_LIMITED(module_id, log_level, FL(format), ## args)
110 
111 static inline void __qdf_trace_noop(QDF_MODULE_ID module, char *format, ...) { }
112 
113 #ifdef WLAN_LOG_FATAL
114 #define QDF_TRACE_FATAL(params...) \
115 	__QDF_TRACE_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_RL(params...) __qdf_trace_noop(params)
121 #endif
122 
123 #ifdef WLAN_LOG_ERROR
124 #define QDF_TRACE_ERROR(params...) \
125 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_ERROR, ## params)
126 #define QDF_TRACE_ERROR_RL(params...) \
127 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_ERROR, ## params)
128 #else
129 #define QDF_TRACE_ERROR(params...) __qdf_trace_noop(params)
130 #define QDF_TRACE_ERROR_RL(params...) __qdf_trace_noop(params)
131 #endif
132 
133 #ifdef WLAN_LOG_WARN
134 #define QDF_TRACE_WARN(params...) \
135 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_WARN, ## params)
136 #define QDF_TRACE_WARN_RL(params...) \
137 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_WARN, ## params)
138 #else
139 #define QDF_TRACE_WARN(params...) __qdf_trace_noop(params)
140 #define QDF_TRACE_WARN_RL(params...) __qdf_trace_noop(params)
141 #endif
142 
143 #ifdef WLAN_LOG_INFO
144 #define QDF_TRACE_INFO(params...) \
145 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_INFO, ## params)
146 #define QDF_TRACE_INFO_RL(params...) \
147 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_INFO, ## params)
148 #else
149 #define QDF_TRACE_INFO(params...) __qdf_trace_noop(params)
150 #define QDF_TRACE_INFO_RL(params...) __qdf_trace_noop(params)
151 #endif
152 
153 #ifdef WLAN_LOG_DEBUG
154 #define QDF_TRACE_DEBUG(params...) \
155 	__QDF_TRACE_FL(QDF_TRACE_LEVEL_DEBUG, ## params)
156 #define QDF_TRACE_DEBUG_RL(params...) \
157 	__QDF_TRACE_RL(QDF_TRACE_LEVEL_DEBUG, ## params)
158 #else
159 #define QDF_TRACE_DEBUG(params...) __qdf_trace_noop(params)
160 #define QDF_TRACE_DEBUG_RL(params...) __qdf_trace_noop(params)
161 #endif
162 
163 #define QDF_ENABLE_TRACING
164 #define qdf_scnprintf scnprintf
165 
166 #ifdef QDF_ENABLE_TRACING
167 
168 #ifdef WLAN_WARN_ON_ASSERT
169 #define QDF_ASSERT(_condition) \
170 	do { \
171 		if (!(_condition)) { \
172 			pr_err("QDF ASSERT in %s Line %d\n", \
173 			       __func__, __LINE__); \
174 			WARN_ON(1); \
175 		} \
176 	} while (0)
177 #else
178 #define QDF_ASSERT(_condition) \
179 	do { \
180 		if (!(_condition)) { \
181 			/* no-op */ \
182 		} \
183 	} while (0)
184 #endif /* WLAN_WARN_ON_ASSERT */
185 
186 #else
187 
188 /* This code will be used for compilation if tracing is to be compiled out */
189 /* of the code so these functions/macros are 'do nothing' */
190 static inline void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
191 		   char *str_format, ...)
192 {
193 }
194 
195 #define QDF_ASSERT(_condition)
196 
197 #endif
198 
199 #ifdef PANIC_ON_BUG
200 #ifdef CONFIG_SLUB_DEBUG
201 /**
202  * QDF_DEBUG_PANIC() - Causes a panic if PANIC_ON_BUG option is enabled
203  *
204  * Note: Calling panic can cause a compiler to assume any following code is
205  * unreachable. Because these panics may or may not be enabled by the build
206  * configuration, this can cause developers some pain. Consider:
207  *
208  *	bool bit;
209  *
210  *	if (ptr)
211  *		bit = ptr->returns_bool();
212  *	else
213  *		panic();
214  *
215  *	// do stuff with @bit
216  *
217  *	return bit;
218  *
219  * In this case, @bit is potentially uninitialized when we return! However, the
220  * compiler can correctly assume this case is impossible when PANIC_ON_BUG is
221  * enabled. Because developers typically enable this feature, the "maybe
222  * uninitialized" warning will not be emitted, and the bug remains uncaught
223  * until someone tries to make a build without PANIC_ON_BUG.
224  *
225  * A simple workaround for this, is to put the definition of QDF_DEBUG_PANIC in
226  * another compilation unit, which prevents the compiler from assuming
227  * subsequent code is unreachable. For CONFIG_SLUB_DEBUG, do this to catch more
228  * bugs. Otherwise, use the typical inlined approach.
229  *
230  * Return: None
231  */
232 void QDF_DEBUG_PANIC(void);
233 #else
234 static inline void QDF_DEBUG_PANIC(void)
235 {
236 	BUG();
237 }
238 #endif /* CONFIG_SLUB_DEBUG */
239 
240 #define QDF_BUG(_condition) \
241 	do { \
242 		if (!(_condition)) { \
243 			pr_err("QDF BUG in %s Line %d: Failed assertion '" \
244 			       #_condition "'\n", __func__, __LINE__); \
245 			QDF_DEBUG_PANIC(); \
246 		} \
247 	} while (0)
248 
249 #else
250 
251 static inline void QDF_DEBUG_PANIC(void) { }
252 
253 #define QDF_BUG(_condition) \
254 	do { \
255 		if (!(_condition)) { \
256 			/* no-op */ \
257 		} \
258 	} while (0)
259 #endif /* PANIC_ON_BUG */
260 
261 #ifdef KSYM_SYMBOL_LEN
262 #define __QDF_SYMBOL_LEN KSYM_SYMBOL_LEN
263 #else
264 #define __QDF_SYMBOL_LEN 1
265 #endif
266 
267 #endif /* __I_QDF_TRACE_H */
268