xref: /wlan-dirver/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c (revision 1f55ed1a9f5050d8da228aa8dd3fff7c0242aa71)
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:  qdf_trace
21  *  QCA driver framework (QDF) trace APIs
22  *  Trace, logging, and debugging definitions and APIs
23  */
24 
25 /* Include Files */
26 #include "qdf_str.h"
27 #include <qdf_trace.h>
28 #include <qdf_module.h>
29 
30 /* macro to map qdf trace levels into the bitmask */
31 #define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
32 
33 #include <wlan_logging_sock_svc.h>
34 #include <qdf_module.h>
35 static int qdf_pidx = -1;
36 static bool qdf_log_dump_at_kernel_enable = true;
37 qdf_declare_param(qdf_log_dump_at_kernel_enable, bool);
38 
39 /* This value of 0 will disable the timer by default. */
40 static uint32_t qdf_log_flush_timer_period;
41 qdf_declare_param(qdf_log_flush_timer_period, uint);
42 
43 #include "qdf_time.h"
44 #include "qdf_mc_timer.h"
45 
46 /* Global qdf print id */
47 
48 /* Preprocessor definitions and constants */
49 
50 enum qdf_timestamp_unit qdf_log_timestamp_type = QDF_LOG_TIMESTAMP_UNIT;
51 
52 /**
53  * typedef struct module_trace_info - Trace level for a module, as a bitmask.
54  * The bits in this mask are ordered by QDF_TRACE_LEVEL.  For example,
55  * each bit represents one of the bits in QDF_TRACE_LEVEL that may be turned
56  * on to have traces at that level logged, i.e. if QDF_TRACE_LEVEL_ERROR is
57  * == 2, then if bit 2 (low order) is turned ON, then ERROR traces will be
58  * printed to the trace log. Note that all bits turned OFF means no traces
59  * @module_trace_level: trace level
60  * @module_name_str: 3 character string name for the module
61  */
62 typedef struct {
63 	uint16_t module_trace_level;
64 	unsigned char module_name_str[4];
65 } module_trace_info;
66 
67 #define DP_TRACE_META_DATA_STRLEN 50
68 
69 /* Array of static data that contains all of the per module trace
70  * information.  This includes the trace level for the module and
71  * the 3 character 'name' of the module for marking the trace logs
72  */
73 module_trace_info g_qdf_trace_info[QDF_MODULE_ID_MAX] = {
74 	[QDF_MODULE_ID_TLSHIM] = {QDF_DEFAULT_TRACE_LEVEL, "DP"},
75 	[QDF_MODULE_ID_WMI] = {QDF_DEFAULT_TRACE_LEVEL, "WMI"},
76 	[QDF_MODULE_ID_HDD] = {QDF_DEFAULT_TRACE_LEVEL, "HDD"},
77 	[QDF_MODULE_ID_SME] = {QDF_DEFAULT_TRACE_LEVEL, "SME"},
78 	[QDF_MODULE_ID_PE] = {QDF_DEFAULT_TRACE_LEVEL, "PE "},
79 	[QDF_MODULE_ID_WMA] = {QDF_DEFAULT_TRACE_LEVEL, "WMA"},
80 	[QDF_MODULE_ID_SYS] = {QDF_DEFAULT_TRACE_LEVEL, "SYS"},
81 	[QDF_MODULE_ID_QDF] = {QDF_DEFAULT_TRACE_LEVEL, "QDF"},
82 	[QDF_MODULE_ID_SAP] = {QDF_DEFAULT_TRACE_LEVEL, "SAP"},
83 	[QDF_MODULE_ID_HDD_SOFTAP] = {QDF_DEFAULT_TRACE_LEVEL, "HSP"},
84 	[QDF_MODULE_ID_HDD_DATA] = {QDF_DEFAULT_TRACE_LEVEL, "HDP"},
85 	[QDF_MODULE_ID_HDD_SAP_DATA] = {QDF_DEFAULT_TRACE_LEVEL, "SDP"},
86 	[QDF_MODULE_ID_BMI] = {QDF_DEFAULT_TRACE_LEVEL, "BMI"},
87 	[QDF_MODULE_ID_HIF] = {QDF_DEFAULT_TRACE_LEVEL, "HIF"},
88 	[QDF_MODULE_ID_TXRX] = {QDF_DEFAULT_TRACE_LEVEL, "TRX"},
89 	[QDF_MODULE_ID_HTT] = {QDF_DEFAULT_TRACE_LEVEL, "HTT"},
90 	[QDF_MODULE_ID_SERIALIZATION] = {QDF_DEFAULT_TRACE_LEVEL, "SER"},
91 	[QDF_MODULE_ID_REGULATORY] = {QDF_DEFAULT_TRACE_LEVEL, "REG"},
92 };
93 
94 #ifdef TRACE_RECORD
95 /* Static and Global variables */
96 static spinlock_t ltrace_lock;
97 /* global qdf trace data */
98 static t_qdf_trace_data g_qdf_trace_data;
99 /*
100  * all the call back functions for dumping MTRACE messages from ring buffer
101  * are stored in qdf_trace_cb_table,these callbacks are initialized during init
102  * only so, we will make a copy of these call back functions and maintain in to
103  * qdf_trace_restore_cb_table. Incase if we make modifications to
104  * qdf_trace_cb_table, we can certainly retrieve all the call back functions
105  * back from Restore Table
106  */
107 static tp_qdf_trace_cb qdf_trace_cb_table[QDF_MODULE_ID_MAX];
108 static tp_qdf_trace_cb qdf_trace_restore_cb_table[QDF_MODULE_ID_MAX];
109 
110 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
111 static qdf_trace_record_t *g_qdf_trace_tbl;
112 #else
113 static qdf_trace_record_t g_qdf_trace_tbl[MAX_QDF_TRACE_RECORDS];
114 #endif
115 
116 #endif
117 
118 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
119 static tp_qdf_state_info_cb qdf_state_info_table[QDF_MODULE_ID_MAX];
120 #endif
121 
122 #ifdef CONFIG_DP_TRACE
123 /* Static and Global variables */
124 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
125 static struct qdf_dp_trace_record_s *g_qdf_dp_trace_tbl;
126 #else
127 static struct qdf_dp_trace_record_s
128 			g_qdf_dp_trace_tbl[MAX_QDF_DP_TRACE_RECORDS];
129 #endif
130 static spinlock_t l_dp_trace_lock;
131 
132 /*
133  * all the options to configure/control DP trace are
134  * defined in this structure
135  */
136 static struct s_qdf_dp_trace_data g_qdf_dp_trace_data;
137 /*
138  * all the call back functions for dumping DPTRACE messages from ring buffer
139  * are stored in qdf_dp_trace_cb_table, callbacks are initialized during init
140  */
141 static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1];
142 #endif
143 
144 /**
145  * qdf_trace_set_level() - Set the trace level for a particular module
146  * @module: Module id
147  * @level : trace level
148  *
149  * Trace level is a member of the QDF_TRACE_LEVEL enumeration indicating
150  * the severity of the condition causing the trace message to be issued.
151  * More severe conditions are more likely to be logged.
152  *
153  * This is an external API that allows trace levels to be set for each module.
154  *
155  * Return:  None
156  */
157 void qdf_trace_set_level(QDF_MODULE_ID module, QDF_TRACE_LEVEL level)
158 {
159 	/* make sure the caller is passing in a valid LEVEL */
160 	if (level >= QDF_TRACE_LEVEL_MAX) {
161 		pr_err("%s: Invalid trace level %d passed in!\n", __func__,
162 		       level);
163 		return;
164 	}
165 
166 	/* Treat 'none' differently.  NONE means we have to run off all
167 	 * the bits in the bit mask so none of the traces appear. Anything
168 	 * other than 'none' means we need to turn ON a bit in the bitmask
169 	 */
170 	if (QDF_TRACE_LEVEL_NONE == level)
171 		g_qdf_trace_info[module].module_trace_level =
172 			QDF_TRACE_LEVEL_NONE;
173 	else
174 		/* set the desired bit in the bit mask for the module trace
175 		 * level
176 		 */
177 		g_qdf_trace_info[module].module_trace_level |=
178 			QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level);
179 }
180 qdf_export_symbol(qdf_trace_set_level);
181 
182 /**
183  * qdf_trace_set_module_trace_level() - Set module trace level
184  * @module: Module id
185  * @level: Trace level for a module, as a bitmask as per 'module_trace_info'
186  *
187  * Sets the module trace level where the trace level is given as a bit mask
188  *
189  * Return: None
190  */
191 void qdf_trace_set_module_trace_level(QDF_MODULE_ID module, uint32_t level)
192 {
193 	if (module < 0 || module >= QDF_MODULE_ID_MAX) {
194 		pr_err("%s: Invalid module id %d passed\n", __func__, module);
195 		return;
196 	}
197 	g_qdf_trace_info[module].module_trace_level = level;
198 }
199 qdf_export_symbol(qdf_trace_set_module_trace_level);
200 
201 /**
202  * qdf_trace_set_value() - Set module trace value
203  * @module: Module id
204  * @level: Trace level for a module, as a bitmask as per 'module_trace_info'
205  * @on: set/clear the desired bit in the bit mask
206  *
207  * Return: None
208  */
209 void qdf_trace_set_value(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
210 			 uint8_t on)
211 {
212 	/* make sure the caller is passing in a valid LEVEL */
213 	if (level < 0 || level >= QDF_TRACE_LEVEL_MAX) {
214 		pr_err("%s: Invalid trace level %d passed in!\n", __func__,
215 		       level);
216 		return;
217 	}
218 
219 	/* make sure the caller is passing in a valid module */
220 	if (module < 0 || module >= QDF_MODULE_ID_MAX) {
221 		pr_err("%s: Invalid module id %d passed in!\n", __func__,
222 		       module);
223 		return;
224 	}
225 
226 	/* Treat 'none' differently.  NONE means we have to turn off all
227 	 * the bits in the bit mask so none of the traces appear
228 	 */
229 	if (QDF_TRACE_LEVEL_NONE == level) {
230 		g_qdf_trace_info[module].module_trace_level =
231 			QDF_TRACE_LEVEL_NONE;
232 	}
233 	/* Treat 'All' differently.  All means we have to turn on all
234 	 * the bits in the bit mask so all of the traces appear
235 	 */
236 	else if (QDF_TRACE_LEVEL_ALL == level) {
237 		g_qdf_trace_info[module].module_trace_level = 0xFFFF;
238 	} else {
239 		if (on)
240 			/* set the desired bit in the bit mask for the module
241 			 * trace level
242 			 */
243 			g_qdf_trace_info[module].module_trace_level |=
244 				QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level);
245 		else
246 			/* clear the desired bit in the bit mask for the module
247 			 * trace level
248 			 */
249 			g_qdf_trace_info[module].module_trace_level &=
250 				~(QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level));
251 	}
252 }
253 qdf_export_symbol(qdf_trace_set_value);
254 
255 /**
256  * qdf_trace_get_level() - get the trace level
257  * @module: module Id
258  * @level: trace level
259  *
260  * This is an external API that returns a bool value to signify if a
261  * particular trace level is set for the specified module.
262  * A member of the QDF_TRACE_LEVEL enumeration indicating the severity
263  * of the condition causing the trace message to be issued.
264  *
265  * Note that individual trace levels are the only valid values
266  * for this API.  QDF_TRACE_LEVEL_NONE and QDF_TRACE_LEVEL_ALL
267  * are not valid input and will return false
268  *
269  * Return:
270  * false - the specified trace level for the specified module is OFF
271  * true - the specified trace level for the specified module is ON
272  */
273 bool qdf_trace_get_level(QDF_MODULE_ID module, QDF_TRACE_LEVEL level)
274 {
275 	bool trace_on = false;
276 
277 	if ((QDF_TRACE_LEVEL_NONE == level) ||
278 	    (QDF_TRACE_LEVEL_ALL == level) || (level >= QDF_TRACE_LEVEL_MAX)) {
279 		trace_on = false;
280 	} else {
281 		trace_on = (level & g_qdf_trace_info[module].module_trace_level)
282 			  ? true : false;
283 	}
284 
285 	return trace_on;
286 }
287 qdf_export_symbol(qdf_trace_get_level);
288 
289 /**
290  * qdf_snprintf() - wrapper function to snprintf
291  * @str_buffer: string Buffer
292  * @size: defines the size of the data record
293  * @str_format: Format string in which the message to be logged. This format
294  * string contains printf-like replacement parameters, which follow
295  * this parameter in the variable argument list.
296  *
297  * Return: None
298  */
299 void qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...)
300 {
301 	snprintf(str_buffer, size, str_format);
302 }
303 qdf_export_symbol(qdf_snprintf);
304 
305 #ifdef QDF_ENABLE_TRACING
306 
307 /**
308  * qdf_trace_msg() - externally called trace function
309  * @module: Module identifier a member of the QDF_MODULE_ID
310  * enumeration that identifies the module issuing the trace message.
311  * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration
312  * indicating the severity of the condition causing the trace message
313  * to be issued. More severe conditions are more likely to be logged.
314  * @str_format: Format string in which the message to be logged. This format
315  * string contains printf-like replacement parameters, which follow
316  * this parameter in the variable argument list.
317  *
318  * Checks the level of severity and accordingly prints the trace messages
319  *
320  * Return: None
321  */
322 void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
323 		   char *str_format, ...)
324 {
325 	va_list val;
326 
327 	va_start(val, str_format);
328 	qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
329 	va_end(val);
330 }
331 qdf_export_symbol(qdf_trace_msg);
332 
333 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
334 		    char *str_format, va_list val)
335 {
336 	qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
337 }
338 qdf_export_symbol(qdf_vtrace_msg);
339 
340 #define ROW_SIZE 16
341 /* Buffer size = data bytes(2 hex chars plus space) + NULL */
342 #define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1)
343 
344 /**
345  * qdf_trace_hex_dump() - externally called hex dump function
346  * @module: Module identifier a member of the QDF_MODULE_ID enumeration that
347  * identifies the module issuing the trace message.
348  * @level: Trace level a member of the QDF_TRACE_LEVEL enumeration indicating
349  * the severity of the condition causing the trace message to be
350  * issued. More severe conditions are more likely to be logged.
351  * @data: The base address of the buffer to be logged.
352  * @buf_len: The size of the buffer to be logged.
353  *
354  * Checks the level of severity and accordingly prints the trace messages
355  *
356  * Return:  None
357  */
358 void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
359 			void *data, int buf_len)
360 {
361 	const u8 *ptr = data;
362 	int i = 0;
363 
364 	if (!qdf_print_is_verbose_enabled(qdf_pidx, module, level))
365 		return;
366 
367 	while (buf_len > 0) {
368 		unsigned char linebuf[BUFFER_SIZE] = {0};
369 		int linelen = min(buf_len, ROW_SIZE);
370 
371 		buf_len -= ROW_SIZE;
372 
373 		hex_dump_to_buffer(ptr, linelen, ROW_SIZE, 1,
374 				linebuf, sizeof(linebuf), false);
375 
376 		qdf_trace_msg(module, level, "%.8x: %s", i, linebuf);
377 		ptr += ROW_SIZE;
378 		i += ROW_SIZE;
379 	}
380 }
381 qdf_export_symbol(qdf_trace_hex_dump);
382 
383 #endif
384 
385 #ifdef TRACE_RECORD
386 
387 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
388 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
389 {
390 	g_qdf_trace_tbl = vzalloc(MAX_QDF_TRACE_RECORDS *
391 				  sizeof(*g_qdf_trace_tbl));
392 	QDF_BUG(g_qdf_trace_tbl);
393 	return g_qdf_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
394 }
395 
396 static inline void free_g_qdf_trace_tbl_buffer(void)
397 {
398 	vfree(g_qdf_trace_tbl);
399 	g_qdf_trace_tbl = NULL;
400 }
401 #else
402 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
403 {
404 	return QDF_STATUS_SUCCESS;
405 }
406 
407 static inline void free_g_qdf_trace_tbl_buffer(void)
408 { }
409 #endif
410 /**
411  * qdf_trace_enable() - Enable MTRACE for specific modules
412  * @bitmask_of_module_id: Bitmask according to enum of the modules.
413  *  32[dec] = 0010 0000 [bin] <enum of HDD is 5>
414  *  64[dec] = 0100 0000 [bin] <enum of SME is 6>
415  *  128[dec] = 1000 0000 [bin] <enum of PE is 7>
416  * @enable: can be true or false true implies enabling MTRACE false implies
417  *		disabling MTRACE.
418  *
419  * Enable MTRACE for specific modules whose bits are set in bitmask and enable
420  * is true. if enable is false it disables MTRACE for that module. set the
421  * bitmask according to enum value of the modules.
422  * This functions will be called when you issue ioctl as mentioned following
423  * [iwpriv wlan0 setdumplog <value> <enable>].
424  * <value> - Decimal number, i.e. 64 decimal value shows only SME module,
425  * 128 decimal value shows only PE module, 192 decimal value shows PE and SME.
426  *
427  * Return: None
428  */
429 void qdf_trace_enable(uint32_t bitmask_of_module_id, uint8_t enable)
430 {
431 	int i;
432 
433 	if (bitmask_of_module_id) {
434 		for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
435 			if (((bitmask_of_module_id >> i) & 1)) {
436 				if (enable) {
437 					if (NULL !=
438 					    qdf_trace_restore_cb_table[i]) {
439 						qdf_trace_cb_table[i] =
440 						qdf_trace_restore_cb_table[i];
441 					}
442 				} else {
443 					qdf_trace_restore_cb_table[i] =
444 						qdf_trace_cb_table[i];
445 					qdf_trace_cb_table[i] = NULL;
446 				}
447 			}
448 		}
449 	} else {
450 		if (enable) {
451 			for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
452 				if (NULL != qdf_trace_restore_cb_table[i]) {
453 					qdf_trace_cb_table[i] =
454 						qdf_trace_restore_cb_table[i];
455 				}
456 			}
457 		} else {
458 			for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
459 				qdf_trace_restore_cb_table[i] =
460 					qdf_trace_cb_table[i];
461 				qdf_trace_cb_table[i] = NULL;
462 			}
463 		}
464 	}
465 }
466 qdf_export_symbol(qdf_trace_enable);
467 
468 /**
469  * qdf_trace_init() - initializes qdf trace structures and variables
470  *
471  * Called immediately after cds_preopen, so that we can start recording HDD
472  * events ASAP.
473  *
474  * Return: None
475  */
476 void qdf_trace_init(void)
477 {
478 	uint8_t i;
479 
480 	if (allocate_g_qdf_trace_tbl_buffer() != QDF_STATUS_SUCCESS)
481 		return;
482 	g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
483 	g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
484 	g_qdf_trace_data.num = 0;
485 	g_qdf_trace_data.enable = true;
486 	g_qdf_trace_data.dump_count = DEFAULT_QDF_TRACE_DUMP_COUNT;
487 	g_qdf_trace_data.num_since_last_dump = 0;
488 
489 	for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
490 		qdf_trace_cb_table[i] = NULL;
491 		qdf_trace_restore_cb_table[i] = NULL;
492 	}
493 }
494 qdf_export_symbol(qdf_trace_init);
495 
496 /**
497  * qdf_trace_deinit() - frees memory allocated dynamically
498  *
499  * Called from cds_deinit, so that we can free the memory and resets
500  * the variables
501  *
502  * Return: None
503  */
504 void qdf_trace_deinit(void)
505 {
506 	g_qdf_trace_data.enable = false;
507 	g_qdf_trace_data.num = 0;
508 	g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
509 	g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
510 
511 	free_g_qdf_trace_tbl_buffer();
512 }
513 
514 qdf_export_symbol(qdf_trace_deinit);
515 
516 /**
517  * qdf_trace() - puts the messages in to ring-buffer
518  * @module: Enum of module, basically module id.
519  * @code: Code to be recorded
520  * @session: Session ID of the log
521  * @data: Actual message contents
522  *
523  * This function will be called from each module who wants record the messages
524  * in circular queue. Before calling this functions make sure you have
525  * registered your module with qdf through qdf_trace_register function.
526  *
527  * Return: None
528  */
529 void qdf_trace(uint8_t module, uint8_t code, uint16_t session, uint32_t data)
530 {
531 	tp_qdf_trace_record rec = NULL;
532 	unsigned long flags;
533 	char time[18];
534 
535 	if (!g_qdf_trace_data.enable)
536 		return;
537 
538 	/* if module is not registered, don't record for that module */
539 	if (NULL == qdf_trace_cb_table[module])
540 		return;
541 
542 	qdf_get_time_of_the_day_in_hr_min_sec_usec(time, sizeof(time));
543 	/* Aquire the lock so that only one thread at a time can fill the ring
544 	 * buffer
545 	 */
546 	spin_lock_irqsave(&ltrace_lock, flags);
547 
548 	g_qdf_trace_data.num++;
549 
550 	if (g_qdf_trace_data.num > MAX_QDF_TRACE_RECORDS)
551 		g_qdf_trace_data.num = MAX_QDF_TRACE_RECORDS;
552 
553 	if (INVALID_QDF_TRACE_ADDR == g_qdf_trace_data.head) {
554 		/* first record */
555 		g_qdf_trace_data.head = 0;
556 		g_qdf_trace_data.tail = 0;
557 	} else {
558 		/* queue is not empty */
559 		uint32_t tail = g_qdf_trace_data.tail + 1;
560 
561 		if (MAX_QDF_TRACE_RECORDS == tail)
562 			tail = 0;
563 
564 		if (g_qdf_trace_data.head == tail) {
565 			/* full */
566 			if (MAX_QDF_TRACE_RECORDS == ++g_qdf_trace_data.head)
567 				g_qdf_trace_data.head = 0;
568 		}
569 		g_qdf_trace_data.tail = tail;
570 	}
571 
572 	rec = &g_qdf_trace_tbl[g_qdf_trace_data.tail];
573 	rec->code = code;
574 	rec->session = session;
575 	rec->data = data;
576 	rec->qtime = qdf_get_log_timestamp();
577 	scnprintf(rec->time, sizeof(rec->time), "%s", time);
578 	rec->module = module;
579 	rec->pid = (in_interrupt() ? 0 : current->pid);
580 	g_qdf_trace_data.num_since_last_dump++;
581 	spin_unlock_irqrestore(&ltrace_lock, flags);
582 }
583 qdf_export_symbol(qdf_trace);
584 
585 #ifdef ENABLE_MTRACE_LOG
586 void qdf_mtrace_log(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
587 		    uint16_t message_id, uint8_t vdev_id)
588 {
589 	uint32_t trace_log, payload;
590 	static uint16_t counter;
591 
592 	trace_log = (src_module << 23) | (dst_module << 15) | message_id;
593 	payload = (vdev_id << 16) | counter++;
594 
595 	QDF_TRACE(src_module, QDF_TRACE_LEVEL_TRACE, "%x %x",
596 		  trace_log, payload);
597 }
598 
599 qdf_export_symbol(qdf_mtrace_log);
600 #endif
601 
602 void qdf_mtrace(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
603 		uint16_t message_id, uint8_t vdev_id, uint32_t data)
604 {
605 	qdf_trace(src_module, message_id, vdev_id, data);
606 	qdf_mtrace_log(src_module, dst_module, message_id, vdev_id);
607 }
608 
609 qdf_export_symbol(qdf_mtrace);
610 
611 /**
612  * qdf_trace_spin_lock_init() - initializes the lock variable before use
613  *
614  * This function will be called from cds_alloc_global_context, we will have lock
615  * available to use ASAP
616  *
617  * Return: None
618  */
619 QDF_STATUS qdf_trace_spin_lock_init(void)
620 {
621 	spin_lock_init(&ltrace_lock);
622 
623 	return QDF_STATUS_SUCCESS;
624 }
625 qdf_export_symbol(qdf_trace_spin_lock_init);
626 
627 /**
628  * qdf_trace_register() - registers the call back functions
629  * @module_iD: enum value of module
630  * @qdf_trace_callback: call back functions to display the messages in
631  * particular format.
632  *
633  * Registers the call back functions to display the messages in particular
634  * format mentioned in these call back functions. This functions should be
635  * called by interested module in their init part as we will be ready to
636  * register as soon as modules are up.
637  *
638  * Return: None
639  */
640 void qdf_trace_register(QDF_MODULE_ID module_id,
641 			tp_qdf_trace_cb qdf_trace_callback)
642 {
643 	qdf_trace_cb_table[module_id] = qdf_trace_callback;
644 }
645 qdf_export_symbol(qdf_trace_register);
646 
647 /**
648  * qdf_trace_dump_all() - Dump data from ring buffer via call back functions
649  * registered with QDF
650  * @p_mac: Context of particular module
651  * @code: Reason code
652  * @session: Session id of log
653  * @count: Number of lines to dump starting from tail to head
654  *
655  * This function will be called up on issueing ioctl call as mentioned following
656  * [iwpriv wlan0 dumplog 0 0 <n> <bitmask_of_module>]
657  *
658  * <n> - number lines to dump starting from tail to head.
659  *
660  * <bitmask_of_module> - if anybody wants to know how many messages were
661  * recorded for particular module/s mentioned by setbit in bitmask from last
662  * <n> messages. It is optional, if you don't provide then it will dump
663  * everything from buffer.
664  *
665  * Return: None
666  */
667 void qdf_trace_dump_all(void *p_mac, uint8_t code, uint8_t session,
668 	uint32_t count, uint32_t bitmask_of_module)
669 {
670 	qdf_trace_record_t p_record;
671 	int32_t i, tail;
672 
673 	if (!g_qdf_trace_data.enable) {
674 		QDF_TRACE(QDF_MODULE_ID_SYS,
675 			  QDF_TRACE_LEVEL_ERROR, "Tracing Disabled");
676 		return;
677 	}
678 
679 	QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO,
680 		  "DPT: Total Records: %d, Head: %d, Tail: %d",
681 		  g_qdf_trace_data.num, g_qdf_trace_data.head,
682 		  g_qdf_trace_data.tail);
683 
684 	/* aquire the lock so that only one thread at a time can read
685 	 * the ring buffer
686 	 */
687 	spin_lock(&ltrace_lock);
688 
689 	if (g_qdf_trace_data.head != INVALID_QDF_TRACE_ADDR) {
690 		i = g_qdf_trace_data.head;
691 		tail = g_qdf_trace_data.tail;
692 
693 		if (count) {
694 			if (count > g_qdf_trace_data.num)
695 				count = g_qdf_trace_data.num;
696 			if (tail >= (count - 1))
697 				i = tail - count + 1;
698 			else if (count != MAX_QDF_TRACE_RECORDS)
699 				i = MAX_QDF_TRACE_RECORDS - ((count - 1) -
700 							     tail);
701 		}
702 
703 		p_record = g_qdf_trace_tbl[i];
704 		/* right now we are not using num_since_last_dump member but
705 		 * in future we might re-visit and use this member to track
706 		 * how many latest messages got added while we were dumping
707 		 * from ring buffer
708 		 */
709 		g_qdf_trace_data.num_since_last_dump = 0;
710 		spin_unlock(&ltrace_lock);
711 		for (;; ) {
712 			if ((code == 0 || (code == p_record.code)) &&
713 			    (qdf_trace_cb_table[p_record.module] != NULL)) {
714 				if (0 == bitmask_of_module) {
715 					qdf_trace_cb_table[p_record.
716 							   module] (p_mac,
717 								    &p_record,
718 								    (uint16_t)
719 								    i);
720 				} else {
721 					if (bitmask_of_module &
722 					    (1 << p_record.module)) {
723 						qdf_trace_cb_table[p_record.
724 								   module]
725 							(p_mac, &p_record,
726 							(uint16_t) i);
727 					}
728 				}
729 			}
730 
731 			if (i == tail)
732 				break;
733 			i += 1;
734 
735 			spin_lock(&ltrace_lock);
736 			if (MAX_QDF_TRACE_RECORDS == i) {
737 				i = 0;
738 				p_record = g_qdf_trace_tbl[0];
739 			} else {
740 				p_record = g_qdf_trace_tbl[i];
741 			}
742 			spin_unlock(&ltrace_lock);
743 		}
744 	} else {
745 		spin_unlock(&ltrace_lock);
746 	}
747 }
748 qdf_export_symbol(qdf_trace_dump_all);
749 #endif
750 
751 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
752 /**
753  * qdf_register_debugcb_init() - initializes debug callbacks
754  * to NULL
755  *
756  * Return: None
757  */
758 void qdf_register_debugcb_init(void)
759 {
760 	uint8_t i;
761 
762 	for (i = 0; i < QDF_MODULE_ID_MAX; i++)
763 		qdf_state_info_table[i] = NULL;
764 }
765 qdf_export_symbol(qdf_register_debugcb_init);
766 
767 /**
768  * qdf_register_debug_callback() - stores callback handlers to print
769  * state information
770  * @module_id: module id of layer
771  * @qdf_state_infocb: callback to be registered
772  *
773  * This function is used to store callback handlers to print
774  * state information
775  *
776  * Return: None
777  */
778 void qdf_register_debug_callback(QDF_MODULE_ID module_id,
779 					tp_qdf_state_info_cb qdf_state_infocb)
780 {
781 	qdf_state_info_table[module_id] = qdf_state_infocb;
782 }
783 qdf_export_symbol(qdf_register_debug_callback);
784 
785 /**
786  * qdf_state_info_dump_all() - it invokes callback of layer which registered
787  * its callback to print its state information.
788  * @buf:  buffer pointer to be passed
789  * @size:  size of buffer to be filled
790  * @driver_dump_size: actual size of buffer used
791  *
792  * Return: QDF_STATUS_SUCCESS on success
793  */
794 QDF_STATUS qdf_state_info_dump_all(char *buf, uint16_t size,
795 			uint16_t *driver_dump_size)
796 {
797 	uint8_t module, ret = QDF_STATUS_SUCCESS;
798 	uint16_t buf_len = size;
799 	char *buf_ptr = buf;
800 
801 	for (module = 0; module < QDF_MODULE_ID_MAX; module++) {
802 		if (NULL != qdf_state_info_table[module]) {
803 			qdf_state_info_table[module](&buf_ptr, &buf_len);
804 			if (!buf_len) {
805 				ret = QDF_STATUS_E_NOMEM;
806 				break;
807 			}
808 		}
809 	}
810 
811 	*driver_dump_size = size - buf_len;
812 	return ret;
813 }
814 qdf_export_symbol(qdf_state_info_dump_all);
815 #endif
816 
817 #ifdef CONFIG_DP_TRACE
818 
819 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
820 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
821 {
822 	g_qdf_dp_trace_tbl = vzalloc(MAX_QDF_DP_TRACE_RECORDS *
823 				     sizeof(*g_qdf_dp_trace_tbl));
824 	QDF_BUG(g_qdf_dp_trace_tbl);
825 	return g_qdf_dp_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
826 }
827 
828 static inline void free_g_qdf_dp_trace_tbl_buffer(void)
829 {
830 	vfree(g_qdf_dp_trace_tbl);
831 	g_qdf_dp_trace_tbl = NULL;
832 }
833 #else
834 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
835 {
836 	return QDF_STATUS_SUCCESS;
837 }
838 
839 static inline void free_g_qdf_dp_trace_tbl_buffer(void)
840 { }
841 #endif
842 
843 #define QDF_DP_TRACE_PREPEND_STR_SIZE 100
844 /*
845  * one dp trace record can't be greater than 300 bytes.
846  * Max Size will be QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
847  * Always make sure to change this QDF_DP_TRACE_MAX_RECORD_SIZE
848  * value accordingly whenever above two mentioned MACRO value changes.
849  */
850 #define QDF_DP_TRACE_MAX_RECORD_SIZE 300
851 
852 static void qdf_dp_unused(struct qdf_dp_trace_record_s *record,
853 			  uint16_t index, uint8_t pdev_id, uint8_t info)
854 {
855 	qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated",
856 		  __func__);
857 }
858 
859 /**
860  * qdf_dp_trace_init() - enables the DP trace
861  * @live_mode_config: live mode configuration
862  * @thresh: high throughput threshold for disabling live mode
863  * @thresh_time_limit: max time to wait before deciding if thresh is crossed
864  * @verbosity: dptrace verbosity level
865  * @proto_bitmap: bitmap to enable/disable specific protocols
866  *
867  * Called during driver load to init dptrace
868  *
869  * A brief note on the 'thresh' param -
870  * Total # of packets received in a bandwidth timer interval beyond which
871  * DP Trace logging for data packets (including ICMP) will be disabled.
872  * In memory logging will still continue for these packets. Other packets for
873  * which proto.bitmap is set will continue to be recorded in logs and in memory.
874 
875  * Return: None
876  */
877 void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
878 				uint16_t time_limit, uint8_t verbosity,
879 				uint8_t proto_bitmap)
880 {
881 	uint8_t i;
882 
883 	if (allocate_g_qdf_dp_trace_tbl_buffer() != QDF_STATUS_SUCCESS) {
884 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
885 				"Failed!!! DP Trace buffer allocation");
886 		return;
887 	}
888 	qdf_dp_trace_spin_lock_init();
889 	qdf_dp_trace_clear_buffer();
890 	g_qdf_dp_trace_data.enable = true;
891 	g_qdf_dp_trace_data.no_of_record = 1;
892 
893 	g_qdf_dp_trace_data.live_mode_config = live_mode_config;
894 	g_qdf_dp_trace_data.live_mode = live_mode_config;
895 	g_qdf_dp_trace_data.high_tput_thresh = thresh;
896 	g_qdf_dp_trace_data.thresh_time_limit = time_limit;
897 	g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
898 	g_qdf_dp_trace_data.verbosity = verbosity;
899 	g_qdf_dp_trace_data.ini_conf_verbosity = verbosity;
900 
901 	for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++)
902 		qdf_dp_trace_cb_table[i] = qdf_dp_display_record;
903 
904 	qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_TX_PACKET_RECORD] =
905 		qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_RX_PACKET_RECORD] =
906 		qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_PACKET_RECORD] =
907 		qdf_dp_trace_cb_table[QDF_DP_TRACE_RX_PACKET_RECORD] =
908 		qdf_dp_trace_cb_table[QDF_DP_TRACE_DROP_PACKET_RECORD] =
909 		qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD] =
910 		qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD] =
911 		qdf_dp_display_data_pkt_record;
912 
913 	qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD] =
914 	qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] =
915 	qdf_dp_trace_cb_table[QDF_DP_TRACE_FREE_PACKET_PTR_RECORD] =
916 	qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD] =
917 						qdf_dp_display_ptr_record;
918 	qdf_dp_trace_cb_table[QDF_DP_TRACE_EAPOL_PACKET_RECORD] =
919 	qdf_dp_trace_cb_table[QDF_DP_TRACE_DHCP_PACKET_RECORD] =
920 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ARP_PACKET_RECORD] =
921 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMP_PACKET_RECORD] =
922 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMPv6_PACKET_RECORD] =
923 						qdf_dp_display_proto_pkt;
924 	qdf_dp_trace_cb_table[QDF_DP_TRACE_MGMT_PACKET_RECORD] =
925 					qdf_dp_display_mgmt_pkt;
926 	qdf_dp_trace_cb_table[QDF_DP_TRACE_EVENT_RECORD] =
927 					qdf_dp_display_event_record;
928 
929 	qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX] = qdf_dp_unused;
930 }
931 qdf_export_symbol(qdf_dp_trace_init);
932 
933 void qdf_dp_trace_deinit(void)
934 {
935 	if (!g_qdf_dp_trace_data.enable)
936 		return;
937 	spin_lock_bh(&l_dp_trace_lock);
938 	g_qdf_dp_trace_data.enable = false;
939 	g_qdf_dp_trace_data.no_of_record = 0;
940 	spin_unlock_bh(&l_dp_trace_lock);
941 
942 	free_g_qdf_dp_trace_tbl_buffer();
943 }
944 /**
945  * qdf_dp_trace_set_value() - Configure the value to control DP trace
946  * @proto_bitmap: defines the protocol to be tracked
947  * @no_of_records: defines the nth packet which is traced
948  * @verbosity: defines the verbosity level
949  *
950  * Return: None
951  */
952 void qdf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_record,
953 			    uint8_t verbosity)
954 {
955 	g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
956 	g_qdf_dp_trace_data.no_of_record = no_of_record;
957 	g_qdf_dp_trace_data.verbosity    = verbosity;
958 	g_qdf_dp_trace_data.dynamic_verbosity_modify = true;
959 }
960 qdf_export_symbol(qdf_dp_trace_set_value);
961 
962 /**
963  * qdf_dp_trace_set_verbosity() - set verbosity value
964  *
965  * @val: Value to set
966  *
967  * Return: Null
968  */
969 void qdf_dp_trace_set_verbosity(uint32_t val)
970 {
971 	g_qdf_dp_trace_data.verbosity = val;
972 }
973 qdf_export_symbol(qdf_dp_trace_set_verbosity);
974 
975 /**
976  * qdf_dp_get_verbosity) - get verbosity value
977  *
978  * Return: int
979  */
980 uint8_t qdf_dp_get_verbosity(void)
981 {
982 	return g_qdf_dp_trace_data.verbosity;
983 }
984 qdf_export_symbol(qdf_dp_get_verbosity);
985 
986 /**
987  * qdf_dp_set_proto_bitmap() - set dp trace proto bitmap
988  *
989  * @val         : unsigned bitmap to set
990  *
991  * Return: proto bitmap
992  */
993 void qdf_dp_set_proto_bitmap(uint32_t val)
994 {
995 	g_qdf_dp_trace_data.proto_bitmap = val;
996 }
997 qdf_export_symbol(qdf_dp_set_proto_bitmap);
998 
999 /**
1000  * qdf_dp_set_no_of_record() - set dp trace no_of_record
1001  *
1002  * @val         : unsigned no_of_record to set
1003  *
1004  * Return: null
1005  */
1006 void qdf_dp_set_no_of_record(uint32_t val)
1007 {
1008 	g_qdf_dp_trace_data.no_of_record = val;
1009 }
1010 qdf_export_symbol(qdf_dp_set_no_of_record);
1011 
1012 /**
1013  * qdf_dp_get_no_of_record() - get dp trace no_of_record
1014  *
1015  * Return: number of records
1016  */
1017 uint8_t qdf_dp_get_no_of_record(void)
1018 {
1019 	return g_qdf_dp_trace_data.no_of_record;
1020 }
1021 qdf_export_symbol(qdf_dp_get_no_of_record);
1022 
1023 
1024 /**
1025  * qdf_dp_trace_verbosity_check() - check whether verbosity level is enabled
1026  * @code: defines the event
1027  *
1028  * In High verbosity all codes are logged.
1029  * For Med/Low and Default case code which has
1030  * less value than corresponding verbosity codes
1031  * are logged.
1032  *
1033  * Return: true or false depends on whether tracing enabled
1034  */
1035 static bool qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code)
1036 {
1037 	switch (g_qdf_dp_trace_data.verbosity) {
1038 	case QDF_DP_TRACE_VERBOSITY_HIGH:
1039 		return true;
1040 	case QDF_DP_TRACE_VERBOSITY_MEDIUM:
1041 		if (code <= QDF_DP_TRACE_MED_VERBOSITY)
1042 			return true;
1043 		return false;
1044 	case QDF_DP_TRACE_VERBOSITY_LOW:
1045 		if (code <= QDF_DP_TRACE_LOW_VERBOSITY)
1046 			return true;
1047 		return false;
1048 	case QDF_DP_TRACE_VERBOSITY_ULTRA_LOW:
1049 		if (code <= QDF_DP_TRACE_ULTRA_LOW_VERBOSITY)
1050 			return true;
1051 		return false;
1052 	case QDF_DP_TRACE_VERBOSITY_BASE:
1053 		if (code <= QDF_DP_TRACE_BASE_VERBOSITY)
1054 			return true;
1055 		return false;
1056 	default:
1057 		return false;
1058 	}
1059 }
1060 
1061 /**
1062  * qdf_dp_get_proto_bitmap() - get dp trace proto bitmap
1063  *
1064  * Return: proto bitmap
1065  */
1066 uint8_t qdf_dp_get_proto_bitmap(void)
1067 {
1068 	if (g_qdf_dp_trace_data.enable)
1069 		return g_qdf_dp_trace_data.proto_bitmap;
1070 	else
1071 		return 0;
1072 }
1073 
1074 /**
1075  * qdf_dp_trace_set_track() - Marks whether the packet needs to be traced
1076  * @nbuf: defines the netbuf
1077  * @dir: direction
1078  *
1079  * Return: None
1080  */
1081 void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir)
1082 {
1083 	uint32_t count = 0;
1084 
1085 	if (!g_qdf_dp_trace_data.enable)
1086 		return;
1087 
1088 	spin_lock_bh(&l_dp_trace_lock);
1089 	if (QDF_TX == dir)
1090 		count = ++g_qdf_dp_trace_data.tx_count;
1091 	else if (QDF_RX == dir)
1092 		count = ++g_qdf_dp_trace_data.rx_count;
1093 
1094 	if ((g_qdf_dp_trace_data.no_of_record != 0) &&
1095 		(count % g_qdf_dp_trace_data.no_of_record == 0)) {
1096 		if (QDF_TX == dir)
1097 			QDF_NBUF_CB_TX_DP_TRACE(nbuf) = 1;
1098 		else if (QDF_RX == dir)
1099 			QDF_NBUF_CB_RX_DP_TRACE(nbuf) = 1;
1100 	}
1101 	spin_unlock_bh(&l_dp_trace_lock);
1102 }
1103 qdf_export_symbol(qdf_dp_trace_set_track);
1104 
1105 /* Number of bytes to be grouped together while printing DP-Trace data */
1106 #define QDF_DUMP_DP_GROUP_SIZE 6
1107 
1108 /**
1109  * dump_dp_hex_trace() - Display the data in buffer
1110  * @prepend_str:     string to prepend the hexdump with.
1111  * @inbuf:     buffer which contains data to be displayed
1112  * @inbuf_len: defines the size of the data to be displayed
1113  *
1114  * Return: None
1115  */
1116 static void
1117 dump_dp_hex_trace(char *prepend_str, uint8_t *inbuf, uint8_t inbuf_len)
1118 {
1119 	unsigned char outbuf[BUFFER_SIZE];
1120 	const uint8_t *inbuf_ptr = inbuf;
1121 	char *outbuf_ptr = outbuf;
1122 	int outbytes_written = 0;
1123 
1124 	qdf_mem_set(outbuf, 0, sizeof(outbuf));
1125 	do {
1126 		outbytes_written += scnprintf(outbuf_ptr,
1127 					BUFFER_SIZE - outbytes_written,
1128 					"%02x", *inbuf_ptr);
1129 		outbuf_ptr = outbuf + outbytes_written;
1130 
1131 		if ((inbuf_ptr - inbuf) &&
1132 		    (inbuf_ptr - inbuf + 1) % QDF_DUMP_DP_GROUP_SIZE == 0) {
1133 			outbytes_written += scnprintf(outbuf_ptr,
1134 						BUFFER_SIZE - outbytes_written,
1135 						" ");
1136 			outbuf_ptr = outbuf + outbytes_written;
1137 		}
1138 		inbuf_ptr++;
1139 	} while (inbuf_ptr < (inbuf + inbuf_len));
1140 	DPTRACE_PRINT("%s %s", prepend_str, outbuf);
1141 }
1142 
1143 /**
1144  * qdf_dp_code_to_string() - convert dptrace code to string
1145  * @code: dptrace code
1146  *
1147  * Return: string version of code
1148  */
1149 static
1150 const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code)
1151 {
1152 	switch (code) {
1153 	case QDF_DP_TRACE_DROP_PACKET_RECORD:
1154 		return "DROP:";
1155 	case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
1156 		return "EAPOL:";
1157 	case QDF_DP_TRACE_DHCP_PACKET_RECORD:
1158 		return "DHCP:";
1159 	case QDF_DP_TRACE_ARP_PACKET_RECORD:
1160 		return "ARP:";
1161 	case QDF_DP_TRACE_ICMP_PACKET_RECORD:
1162 		return "ICMP:";
1163 	case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
1164 		return "ICMPv6:";
1165 	case QDF_DP_TRACE_MGMT_PACKET_RECORD:
1166 		return "MGMT:";
1167 	case QDF_DP_TRACE_EVENT_RECORD:
1168 		return "EVENT:";
1169 	case QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD:
1170 		return "HDD: TX: PTR:";
1171 	case QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD:
1172 		return "LI_DP: TX: PTR:";
1173 	case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
1174 		return "HDD: TX: DATA:";
1175 	case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
1176 	case QDF_DP_TRACE_TX_PACKET_RECORD:
1177 		return "TX:";
1178 	case QDF_DP_TRACE_CE_PACKET_PTR_RECORD:
1179 		return "CE: TX: PTR:";
1180 	case QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD:
1181 		return "CE: TX: FAST: PTR:";
1182 	case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
1183 		return "CE: TX: FAST: ERR:";
1184 	case QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD:
1185 	case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
1186 		return "FREE: TX: PTR:";
1187 	case QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD:
1188 		return "HTT: RX: PTR:";
1189 	case QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD:
1190 		return "HTT: RX: OF: PTR:";
1191 	case QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD:
1192 		return "HDD: RX: PTR:";
1193 	case QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD:
1194 		return "LI_DP: RX: PTR:";
1195 	case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
1196 		return "HDD: RX: DATA:";
1197 	case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
1198 		return "LI_DP_NULL: RX: DATA:";
1199 	case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
1200 	case QDF_DP_TRACE_RX_PACKET_RECORD:
1201 		return "RX:";
1202 	case QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD:
1203 		return "TXRX: TX: Q: PTR:";
1204 	case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
1205 		return "TXRX: TX: PTR:";
1206 	case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
1207 		return "TXRX: TX: FAST: PTR:";
1208 	case QDF_DP_TRACE_HTT_PACKET_PTR_RECORD:
1209 		return "HTT: TX: PTR:";
1210 	case QDF_DP_TRACE_HTC_PACKET_PTR_RECORD:
1211 		return "HTC: TX: PTR:";
1212 	case QDF_DP_TRACE_HIF_PACKET_PTR_RECORD:
1213 		return "HIF: TX: PTR:";
1214 	case QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD:
1215 		return "TXRX: RX: PTR:";
1216 	case QDF_DP_TRACE_HDD_TX_TIMEOUT:
1217 		return "HDD: STA: TO:";
1218 	case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
1219 		return "HDD: SAP: TO:";
1220 	default:
1221 		return "Invalid";
1222 	}
1223 }
1224 
1225 /**
1226  * qdf_dp_dir_to_str() - convert direction to string
1227  * @dir: direction
1228  *
1229  * Return: string version of direction
1230  */
1231 static const char *qdf_dp_dir_to_str(enum qdf_proto_dir dir)
1232 {
1233 	switch (dir) {
1234 	case QDF_TX:
1235 		return " --> ";
1236 	case QDF_RX:
1237 		return " <-- ";
1238 	default:
1239 		return "invalid";
1240 	}
1241 }
1242 
1243 /**
1244  * qdf_dp_type_to_str() - convert packet type to string
1245  * @type: type
1246  *
1247  * Return: string version of packet type
1248  */
1249 static const char *qdf_dp_type_to_str(enum qdf_proto_type type)
1250 {
1251 	switch (type) {
1252 	case QDF_PROTO_TYPE_DHCP:
1253 		return "DHCP";
1254 	case QDF_PROTO_TYPE_EAPOL:
1255 		return "EAPOL";
1256 	case QDF_PROTO_TYPE_ARP:
1257 		return "ARP";
1258 	case QDF_PROTO_TYPE_ICMP:
1259 		return "ICMP";
1260 	case QDF_PROTO_TYPE_ICMPv6:
1261 		return "ICMPv6";
1262 	case QDF_PROTO_TYPE_MGMT:
1263 		return "MGMT";
1264 	case QDF_PROTO_TYPE_EVENT:
1265 		return "EVENT";
1266 	default:
1267 		return "invalid";
1268 	}
1269 }
1270 
1271 /**
1272  * qdf_dp_subtype_to_str() - convert packet subtype to string
1273  * @type: type
1274  *
1275  * Return: string version of packet subtype
1276  */
1277 static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)
1278 {
1279 	switch (subtype) {
1280 	case QDF_PROTO_EAPOL_M1:
1281 		return "M1";
1282 	case QDF_PROTO_EAPOL_M2:
1283 		return "M2";
1284 	case QDF_PROTO_EAPOL_M3:
1285 		return "M3";
1286 	case QDF_PROTO_EAPOL_M4:
1287 		return "M4";
1288 	case QDF_PROTO_DHCP_DISCOVER:
1289 		return "DISC";
1290 	case QDF_PROTO_DHCP_REQUEST:
1291 		return "REQ";
1292 	case QDF_PROTO_DHCP_OFFER:
1293 		return "OFF";
1294 	case QDF_PROTO_DHCP_ACK:
1295 		return "ACK";
1296 	case QDF_PROTO_DHCP_NACK:
1297 		return "NACK";
1298 	case QDF_PROTO_DHCP_RELEASE:
1299 		return "REL";
1300 	case QDF_PROTO_DHCP_INFORM:
1301 		return "INFORM";
1302 	case QDF_PROTO_DHCP_DECLINE:
1303 		return "DECL";
1304 	case QDF_PROTO_ARP_REQ:
1305 	case QDF_PROTO_ICMP_REQ:
1306 	case QDF_PROTO_ICMPV6_REQ:
1307 		return "REQ";
1308 	case QDF_PROTO_ARP_RES:
1309 	case QDF_PROTO_ICMP_RES:
1310 	case QDF_PROTO_ICMPV6_RES:
1311 		return "RSP";
1312 	case QDF_PROTO_ICMPV6_RS:
1313 		return "RS";
1314 	case QDF_PROTO_ICMPV6_RA:
1315 		return "RA";
1316 	case QDF_PROTO_ICMPV6_NS:
1317 		return "NS";
1318 	case QDF_PROTO_ICMPV6_NA:
1319 		return "NA";
1320 	case QDF_PROTO_MGMT_ASSOC:
1321 		return "ASSOC";
1322 	case QDF_PROTO_MGMT_DISASSOC:
1323 		return "DISASSOC";
1324 	case QDF_PROTO_MGMT_AUTH:
1325 		return "AUTH";
1326 	case QDF_PROTO_MGMT_DEAUTH:
1327 		return "DEAUTH";
1328 	case QDF_ROAM_SYNCH:
1329 		return "ROAM SYNCH";
1330 	case QDF_ROAM_COMPLETE:
1331 		return "ROAM COMP";
1332 	case QDF_ROAM_EVENTID:
1333 		return "ROAM EVENTID";
1334 	default:
1335 		return "invalid";
1336 	}
1337 }
1338 
1339 /**
1340  * qdf_dp_enable_check() - check if dptrace, TX/RX tracing is enabled
1341  * @nbuf: nbuf
1342  * @code: dptrace code
1343  * @dir: TX or RX direction
1344  *
1345  * Return: true/false
1346  */
1347 static bool qdf_dp_enable_check(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
1348 				enum qdf_proto_dir dir)
1349 {
1350 	/* Return when Dp trace is not enabled */
1351 	if (!g_qdf_dp_trace_data.enable)
1352 		return false;
1353 
1354 	if (qdf_dp_trace_verbosity_check(code) == false)
1355 		return false;
1356 
1357 	if (nbuf && (dir == QDF_TX && ((QDF_NBUF_CB_TX_DP_TRACE(nbuf) == 0) ||
1358 				       (QDF_NBUF_CB_TX_PACKET_TRACK(nbuf) !=
1359 					QDF_NBUF_TX_PKT_DATA_TRACK))))
1360 		return false;
1361 
1362 	if (nbuf && (dir == QDF_RX && (QDF_NBUF_CB_RX_DP_TRACE(nbuf) == 0)))
1363 		return false;
1364 
1365 	/*
1366 	 * Special packets called with NULL nbuf and this API is expected to
1367 	 * return true
1368 	 */
1369 	return true;
1370 }
1371 
1372 /**
1373  * qdf_dp_trace_fill_meta_str() - fill up a common meta string
1374  * @prepend_str: pointer to string
1375  * @size: size of prepend_str
1376  * @rec_index: index of record
1377  * @info: info related to the record
1378  * @record: pointer to the record
1379  *
1380  * Return: ret value from scnprintf
1381  */
1382 static inline
1383 int qdf_dp_trace_fill_meta_str(char *prepend_str, int size,
1384 			       int rec_index, uint8_t info,
1385 			       struct qdf_dp_trace_record_s *record)
1386 {
1387 	char buffer[20];
1388 	int ret = 0;
1389 	bool live = info & QDF_DP_TRACE_RECORD_INFO_LIVE ? true : false;
1390 	bool throttled = info & QDF_DP_TRACE_RECORD_INFO_THROTTLED ?
1391 								true : false;
1392 
1393 	scnprintf(buffer, sizeof(buffer), "%llu", record->time);
1394 	ret = scnprintf(prepend_str, size,
1395 			"%s DPT: %04d:%02d%s %s",
1396 			throttled ? "*" : "",
1397 			rec_index,
1398 			record->pdev_id,
1399 			live ? "" : buffer,
1400 			qdf_dp_code_to_string(record->code));
1401 
1402 	return ret;
1403 }
1404 
1405 /**
1406  * qdf_dp_fill_record_data() - fill meta data and data into the record
1407  * @rec: pointer to record data
1408  * @data: pointer to data
1409  * @data_size: size of the data
1410  * @meta_data: pointer to metadata
1411  * @metadata_size: size of metadata
1412  *
1413  * Should be called from within a spin_lock for the qdf record.
1414  * Fills up rec->data with |metadata|data|
1415  *
1416  * Return: none
1417  */
1418 static void qdf_dp_fill_record_data
1419 	(struct qdf_dp_trace_record_s *rec,
1420 	uint8_t *data, uint8_t data_size,
1421 	uint8_t *meta_data, uint8_t metadata_size)
1422 {
1423 	int32_t available = QDF_DP_TRACE_RECORD_SIZE;
1424 	uint8_t *rec_data = rec->data;
1425 	uint8_t data_to_copy = 0;
1426 
1427 	qdf_mem_set(rec_data, QDF_DP_TRACE_RECORD_SIZE, 0);
1428 
1429 	/* copy meta data */
1430 	if (meta_data) {
1431 		if (metadata_size > available) {
1432 			QDF_TRACE_WARN(QDF_MODULE_ID_QDF,
1433 				       "%s: meta data does not fit into the record",
1434 				       __func__);
1435 			goto end;
1436 		}
1437 		qdf_mem_copy(rec_data, meta_data, metadata_size);
1438 		available = available - metadata_size;
1439 	} else {
1440 		metadata_size = 0;
1441 	}
1442 
1443 	/* copy data */
1444 	if (data && (data_size > 0) && (available > 0)) {
1445 		data_to_copy = data_size;
1446 		if (data_size > available)
1447 			data_to_copy = available;
1448 		qdf_mem_copy(&rec_data[metadata_size], data, data_to_copy);
1449 	}
1450 end:
1451 	rec->size = data_to_copy;
1452 }
1453 
1454 /**
1455  * qdf_dp_add_record() - add dp trace record
1456  * @code: dptrace code
1457  * @pdev_id: pdev_id
1458  * @print: true to print it in kmsg
1459  * @data: data pointer
1460  * @data_size: size of data to be copied
1461  * @meta_data: meta data to be prepended to data
1462  * @metadata_size: sizeof meta data
1463  * @print: whether to print record
1464  *
1465  * Return: none
1466  */
1467 static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
1468 			      uint8_t *data, uint8_t data_size,
1469 			      uint8_t *meta_data, uint8_t metadata_size,
1470 			      bool print)
1471 
1472 {
1473 	struct qdf_dp_trace_record_s *rec = NULL;
1474 	int index;
1475 	bool print_this_record = false;
1476 	u8 info = 0;
1477 
1478 	if (code >= QDF_DP_TRACE_MAX) {
1479 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
1480 				"invalid record code %u, max code %u",
1481 				code, QDF_DP_TRACE_MAX);
1482 		return;
1483 	}
1484 
1485 	spin_lock_bh(&l_dp_trace_lock);
1486 
1487 	if (print || g_qdf_dp_trace_data.force_live_mode) {
1488 		print_this_record = true;
1489 	} else if (g_qdf_dp_trace_data.live_mode == 1) {
1490 		print_this_record = true;
1491 		g_qdf_dp_trace_data.print_pkt_cnt++;
1492 		if (g_qdf_dp_trace_data.print_pkt_cnt >
1493 				g_qdf_dp_trace_data.high_tput_thresh) {
1494 			g_qdf_dp_trace_data.live_mode = 0;
1495 			g_qdf_dp_trace_data.verbosity =
1496 					QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
1497 			info |= QDF_DP_TRACE_RECORD_INFO_THROTTLED;
1498 		}
1499 	}
1500 
1501 	g_qdf_dp_trace_data.num++;
1502 
1503 	if (g_qdf_dp_trace_data.num > MAX_QDF_DP_TRACE_RECORDS)
1504 		g_qdf_dp_trace_data.num = MAX_QDF_DP_TRACE_RECORDS;
1505 
1506 	if (INVALID_QDF_DP_TRACE_ADDR == g_qdf_dp_trace_data.head) {
1507 		/* first record */
1508 		g_qdf_dp_trace_data.head = 0;
1509 		g_qdf_dp_trace_data.tail = 0;
1510 	} else {
1511 		/* queue is not empty */
1512 		g_qdf_dp_trace_data.tail++;
1513 
1514 		if (MAX_QDF_DP_TRACE_RECORDS == g_qdf_dp_trace_data.tail)
1515 			g_qdf_dp_trace_data.tail = 0;
1516 
1517 		if (g_qdf_dp_trace_data.head == g_qdf_dp_trace_data.tail) {
1518 			/* full */
1519 			if (MAX_QDF_DP_TRACE_RECORDS ==
1520 				++g_qdf_dp_trace_data.head)
1521 				g_qdf_dp_trace_data.head = 0;
1522 		}
1523 	}
1524 
1525 	rec = &g_qdf_dp_trace_tbl[g_qdf_dp_trace_data.tail];
1526 	index = g_qdf_dp_trace_data.tail;
1527 	rec->code = code;
1528 	rec->pdev_id = pdev_id;
1529 	rec->size = 0;
1530 	qdf_dp_fill_record_data(rec, data, data_size,
1531 				meta_data, metadata_size);
1532 	rec->time = qdf_get_log_timestamp();
1533 	rec->pid = (in_interrupt() ? 0 : current->pid);
1534 
1535 	if (rec->code >= QDF_DP_TRACE_MAX) {
1536 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
1537 				"invalid record code %u, max code %u",
1538 				rec->code, QDF_DP_TRACE_MAX);
1539 		return;
1540 	}
1541 
1542 	spin_unlock_bh(&l_dp_trace_lock);
1543 
1544 	info |= QDF_DP_TRACE_RECORD_INFO_LIVE;
1545 	if (print_this_record)
1546 		qdf_dp_trace_cb_table[rec->code] (rec, index,
1547 					QDF_TRACE_DEFAULT_PDEV_ID, info);
1548 }
1549 
1550 
1551 /**
1552  * qdf_log_icmpv6_pkt() - log ICMPv6 packet
1553  * @vdev_id: ID of the vdev
1554  * @skb: skb pointer
1555  * @dir: direction
1556  * @pdev_id: ID of the pdev
1557  *
1558  * Return: true/false
1559  */
1560 static bool qdf_log_icmpv6_pkt(uint8_t vdev_id, struct sk_buff *skb,
1561 			       enum qdf_proto_dir dir, uint8_t pdev_id)
1562 {
1563 	enum qdf_proto_subtype subtype;
1564 
1565 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMPv6) &&
1566 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ICMPv6 ==
1567 			QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1568 		 (dir == QDF_RX && qdf_nbuf_is_icmpv6_pkt(skb) == true))) {
1569 
1570 		subtype = qdf_nbuf_get_icmpv6_subtype(skb);
1571 
1572 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
1573 		if (dir == QDF_TX)
1574 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1575 		else if (dir == QDF_RX)
1576 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1577 
1578 		DPTRACE(qdf_dp_trace_proto_pkt(
1579 			QDF_DP_TRACE_ICMPv6_PACKET_RECORD,
1580 			vdev_id, (skb->data + QDF_NBUF_SRC_MAC_OFFSET),
1581 			(skb->data + QDF_NBUF_DEST_MAC_OFFSET),
1582 			QDF_PROTO_TYPE_ICMPv6, subtype, dir, pdev_id, false));
1583 
1584 		switch (subtype) {
1585 		case QDF_PROTO_ICMPV6_REQ:
1586 			g_qdf_dp_trace_data.icmpv6_req++;
1587 			break;
1588 		case QDF_PROTO_ICMPV6_RES:
1589 			g_qdf_dp_trace_data.icmpv6_resp++;
1590 			break;
1591 		case QDF_PROTO_ICMPV6_RS:
1592 			g_qdf_dp_trace_data.icmpv6_rs++;
1593 			break;
1594 		case QDF_PROTO_ICMPV6_RA:
1595 			g_qdf_dp_trace_data.icmpv6_ra++;
1596 			break;
1597 		case QDF_PROTO_ICMPV6_NS:
1598 			g_qdf_dp_trace_data.icmpv6_ns++;
1599 			break;
1600 		case QDF_PROTO_ICMPV6_NA:
1601 			g_qdf_dp_trace_data.icmpv6_na++;
1602 			break;
1603 		default:
1604 			break;
1605 		}
1606 		return true;
1607 	}
1608 
1609 	return false;
1610 }
1611 
1612 /**
1613  * qdf_log_icmp_pkt() - log ICMP packet
1614  * @vdev_id: ID of the vdev
1615  * @skb: skb pointer
1616  * @dir: direction
1617  * @pdev_id: ID of the pdev
1618  *
1619  * Return: true/false
1620  */
1621 static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb,
1622 			     enum qdf_proto_dir dir, uint8_t pdev_id)
1623 {
1624 	enum qdf_proto_subtype proto_subtype;
1625 
1626 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) &&
1627 	    (qdf_nbuf_is_icmp_pkt(skb) == true)) {
1628 
1629 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
1630 		proto_subtype = qdf_nbuf_get_icmp_subtype(skb);
1631 
1632 		if (QDF_TX == dir)
1633 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1634 		else if (QDF_RX == dir)
1635 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1636 
1637 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD,
1638 					       vdev_id,
1639 					       skb->data +
1640 					       QDF_NBUF_SRC_MAC_OFFSET,
1641 					       skb->data +
1642 					       QDF_NBUF_DEST_MAC_OFFSET,
1643 					       QDF_PROTO_TYPE_ICMP,
1644 					       proto_subtype, dir, pdev_id,
1645 					       false));
1646 
1647 		if (proto_subtype == QDF_PROTO_ICMP_REQ)
1648 			g_qdf_dp_trace_data.icmp_req++;
1649 		else
1650 			g_qdf_dp_trace_data.icmp_resp++;
1651 
1652 		return true;
1653 	}
1654 	return false;
1655 }
1656 
1657 /**
1658  * qdf_log_eapol_pkt() - log EAPOL packet
1659  * @vdev_id: ID of the vdev
1660  * @skb: skb pointer
1661  * @dir: direction
1662  * @pdev_id: ID of the pdev
1663  *
1664  * Return: true/false
1665  */
1666 static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb,
1667 			      enum qdf_proto_dir dir, uint8_t pdev_id)
1668 {
1669 	enum qdf_proto_subtype subtype;
1670 
1671 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_EAPOL) &&
1672 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
1673 			QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1674 		 (dir == QDF_RX && qdf_nbuf_is_ipv4_eapol_pkt(skb) == true))) {
1675 
1676 		subtype = qdf_nbuf_get_eapol_subtype(skb);
1677 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
1678 		if (QDF_TX == dir)
1679 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1680 		else if (QDF_RX == dir)
1681 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1682 
1683 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD,
1684 					       vdev_id,
1685 					       skb->data +
1686 					       QDF_NBUF_SRC_MAC_OFFSET,
1687 					       skb->data +
1688 					       QDF_NBUF_DEST_MAC_OFFSET,
1689 					       QDF_PROTO_TYPE_EAPOL, subtype,
1690 					       dir, pdev_id, true));
1691 
1692 		switch (subtype) {
1693 		case QDF_PROTO_EAPOL_M1:
1694 			g_qdf_dp_trace_data.eapol_m1++;
1695 			break;
1696 		case QDF_PROTO_EAPOL_M2:
1697 			g_qdf_dp_trace_data.eapol_m2++;
1698 			break;
1699 		case QDF_PROTO_EAPOL_M3:
1700 			g_qdf_dp_trace_data.eapol_m3++;
1701 			break;
1702 		case QDF_PROTO_EAPOL_M4:
1703 			g_qdf_dp_trace_data.eapol_m4++;
1704 			break;
1705 		default:
1706 			g_qdf_dp_trace_data.eapol_others++;
1707 			break;
1708 		}
1709 		return true;
1710 	}
1711 	return false;
1712 }
1713 
1714 /**
1715  * qdf_log_dhcp_pkt() - log DHCP packet
1716  * @vdev_id: ID of the vdev
1717  * @skb: skb pointer
1718  * @dir: direction
1719  * @pdev_id: ID of the pdev
1720  *
1721  * Return: true/false
1722  */
1723 static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb,
1724 			     enum qdf_proto_dir dir, uint8_t pdev_id)
1725 {
1726 	enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
1727 
1728 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_DHCP) &&
1729 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP ==
1730 				QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1731 		 (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true))) {
1732 
1733 		subtype = qdf_nbuf_get_dhcp_subtype(skb);
1734 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
1735 		if (QDF_TX == dir)
1736 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1737 		else if (QDF_RX == dir)
1738 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1739 
1740 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD,
1741 					       vdev_id,
1742 					       skb->data +
1743 					       QDF_NBUF_SRC_MAC_OFFSET,
1744 					       skb->data +
1745 					       QDF_NBUF_DEST_MAC_OFFSET,
1746 					       QDF_PROTO_TYPE_DHCP, subtype,
1747 					       dir, pdev_id, true));
1748 
1749 		switch (subtype) {
1750 		case QDF_PROTO_DHCP_DISCOVER:
1751 			g_qdf_dp_trace_data.dhcp_disc++;
1752 			break;
1753 		case QDF_PROTO_DHCP_OFFER:
1754 			g_qdf_dp_trace_data.dhcp_off++;
1755 			break;
1756 		case QDF_PROTO_DHCP_REQUEST:
1757 			g_qdf_dp_trace_data.dhcp_req++;
1758 			break;
1759 		case QDF_PROTO_DHCP_ACK:
1760 			g_qdf_dp_trace_data.dhcp_ack++;
1761 			break;
1762 		case QDF_PROTO_DHCP_NACK:
1763 			g_qdf_dp_trace_data.dhcp_nack++;
1764 			break;
1765 		default:
1766 			g_qdf_dp_trace_data.eapol_others++;
1767 			break;
1768 		}
1769 
1770 		return true;
1771 	}
1772 	return false;
1773 }
1774 
1775 /**
1776  * qdf_log_arp_pkt() - log ARP packet
1777  * @vdev_id: ID of the vdev
1778  * @skb: skb pointer
1779  * @dir: direction
1780  * @pdev_id: ID of the pdev
1781  *
1782  * Return: true/false
1783  */
1784 static bool qdf_log_arp_pkt(uint8_t vdev_id, struct sk_buff *skb,
1785 			    enum qdf_proto_dir dir, uint8_t pdev_id)
1786 {
1787 	enum qdf_proto_subtype proto_subtype;
1788 
1789 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ARP) &&
1790 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ARP ==
1791 			QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1792 		 (dir == QDF_RX && qdf_nbuf_is_ipv4_arp_pkt(skb) == true))) {
1793 
1794 		proto_subtype = qdf_nbuf_get_arp_subtype(skb);
1795 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
1796 		if (QDF_TX == dir)
1797 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1798 		else if (QDF_RX == dir)
1799 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1800 
1801 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD,
1802 					       vdev_id,
1803 					       skb->data +
1804 					       QDF_NBUF_SRC_MAC_OFFSET,
1805 					       skb->data +
1806 					       QDF_NBUF_DEST_MAC_OFFSET,
1807 					       QDF_PROTO_TYPE_ARP,
1808 					       proto_subtype, dir, pdev_id,
1809 					       true));
1810 
1811 		if (QDF_PROTO_ARP_REQ == proto_subtype)
1812 			g_qdf_dp_trace_data.arp_req++;
1813 		else
1814 			g_qdf_dp_trace_data.arp_resp++;
1815 
1816 		return true;
1817 	}
1818 	return false;
1819 }
1820 
1821 
1822 bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb,
1823 			  enum qdf_proto_dir dir, uint8_t pdev_id)
1824 {
1825 	if (!qdf_dp_get_proto_bitmap())
1826 		return false;
1827 	if (qdf_log_arp_pkt(vdev_id, skb, dir, pdev_id))
1828 		return true;
1829 	if (qdf_log_dhcp_pkt(vdev_id, skb, dir, pdev_id))
1830 		return true;
1831 	if (qdf_log_eapol_pkt(vdev_id, skb, dir, pdev_id))
1832 		return true;
1833 	if (qdf_log_icmp_pkt(vdev_id, skb, dir, pdev_id))
1834 		return true;
1835 	if (qdf_log_icmpv6_pkt(vdev_id, skb, dir, pdev_id))
1836 		return true;
1837 	return false;
1838 }
1839 qdf_export_symbol(qdf_dp_trace_log_pkt);
1840 
1841 void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record,
1842 			      uint16_t index, uint8_t pdev_id, uint8_t info)
1843 {
1844 	int loc;
1845 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
1846 	struct qdf_dp_trace_mgmt_buf *buf =
1847 		(struct qdf_dp_trace_mgmt_buf *)record->data;
1848 
1849 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
1850 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
1851 					 index, info, record);
1852 
1853 	DPTRACE_PRINT("%s [%d] [%s %s]",
1854 		      prepend_str,
1855 		      buf->vdev_id,
1856 		      qdf_dp_type_to_str(buf->type),
1857 		      qdf_dp_subtype_to_str(buf->subtype));
1858 }
1859 qdf_export_symbol(qdf_dp_display_mgmt_pkt);
1860 
1861 
1862 void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
1863 		uint8_t pdev_id, enum qdf_proto_type type,
1864 		enum qdf_proto_subtype subtype)
1865 {
1866 	struct qdf_dp_trace_mgmt_buf buf;
1867 	int buf_size = sizeof(struct qdf_dp_trace_mgmt_buf);
1868 
1869 	if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
1870 		return;
1871 
1872 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
1873 		QDF_BUG(0);
1874 
1875 	buf.type = type;
1876 	buf.subtype = subtype;
1877 	buf.vdev_id = vdev_id;
1878 	qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size,
1879 			  NULL, 0, true);
1880 }
1881 qdf_export_symbol(qdf_dp_trace_mgmt_pkt);
1882 
1883 void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record,
1884 			      uint16_t index, uint8_t pdev_id, uint8_t info)
1885 {
1886 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
1887 	struct qdf_dp_trace_event_buf *buf =
1888 		(struct qdf_dp_trace_event_buf *)record->data;
1889 
1890 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
1891 	qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
1892 				   index, info, record);
1893 
1894 	DPTRACE_PRINT("%s [%d] [%s %s]",
1895 		      prepend_str,
1896 		      buf->vdev_id,
1897 		      qdf_dp_type_to_str(buf->type),
1898 		      qdf_dp_subtype_to_str(buf->subtype));
1899 }
1900 qdf_export_symbol(qdf_dp_display_event_record);
1901 
1902 /**
1903  * qdf_dp_trace_record_event() - record events
1904  * @code: dptrace code
1905  * @vdev_id: vdev id
1906  * @pdev_id: pdev_id
1907  * @type: proto type
1908  * @subtype: proto subtype
1909  *
1910  * Return: none
1911  */
1912 void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
1913 		uint8_t pdev_id, enum qdf_proto_type type,
1914 		enum qdf_proto_subtype subtype)
1915 {
1916 	struct qdf_dp_trace_event_buf buf;
1917 	int buf_size = sizeof(struct qdf_dp_trace_event_buf);
1918 
1919 	if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
1920 		return;
1921 
1922 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
1923 		QDF_BUG(0);
1924 
1925 	buf.type = type;
1926 	buf.subtype = subtype;
1927 	buf.vdev_id = vdev_id;
1928 	qdf_dp_add_record(code, pdev_id,
1929 			  (uint8_t *)&buf, buf_size, NULL, 0, true);
1930 }
1931 qdf_export_symbol(qdf_dp_trace_record_event);
1932 
1933 
1934 void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record,
1935 			      uint16_t index, uint8_t pdev_id, uint8_t info)
1936 {
1937 	int loc;
1938 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
1939 	struct qdf_dp_trace_proto_buf *buf =
1940 		(struct qdf_dp_trace_proto_buf *)record->data;
1941 
1942 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
1943 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
1944 					 index, info, record);
1945 	DPTRACE_PRINT("%s [%d] [%s] SA: "
1946 		      QDF_MAC_ADDR_STR " %s DA: "
1947 		      QDF_MAC_ADDR_STR,
1948 		      prepend_str,
1949 		      buf->vdev_id,
1950 		      qdf_dp_subtype_to_str(buf->subtype),
1951 		      QDF_MAC_ADDR_ARRAY(buf->sa.bytes),
1952 		      qdf_dp_dir_to_str(buf->dir),
1953 		      QDF_MAC_ADDR_ARRAY(buf->da.bytes));
1954 }
1955 qdf_export_symbol(qdf_dp_display_proto_pkt);
1956 
1957 void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
1958 		uint8_t *sa, uint8_t *da, enum qdf_proto_type type,
1959 		enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
1960 		uint8_t pdev_id, bool print)
1961 {
1962 	struct qdf_dp_trace_proto_buf buf;
1963 	int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
1964 
1965 	if (qdf_dp_enable_check(NULL, code, dir) == false)
1966 		return;
1967 
1968 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
1969 		QDF_BUG(0);
1970 
1971 	memcpy(&buf.sa, sa, QDF_NET_ETH_LEN);
1972 	memcpy(&buf.da, da, QDF_NET_ETH_LEN);
1973 	buf.dir = dir;
1974 	buf.type = type;
1975 	buf.subtype = subtype;
1976 	buf.vdev_id = vdev_id;
1977 	qdf_dp_add_record(code, pdev_id,
1978 			  (uint8_t *)&buf, buf_size, NULL, 0, print);
1979 }
1980 qdf_export_symbol(qdf_dp_trace_proto_pkt);
1981 
1982 void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record,
1983 				uint16_t index, uint8_t pdev_id, uint8_t info)
1984 {
1985 	int loc;
1986 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
1987 	struct qdf_dp_trace_ptr_buf *buf =
1988 		(struct qdf_dp_trace_ptr_buf *)record->data;
1989 	bool is_free_pkt_ptr_record = false;
1990 
1991 	if ((record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ||
1992 	    (record->code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD))
1993 		is_free_pkt_ptr_record = true;
1994 
1995 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
1996 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
1997 					 index, info, record);
1998 
1999 	if (loc < sizeof(prepend_str))
2000 		scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2001 			  "[msdu id %d %s %d]",
2002 			  buf->msdu_id,
2003 			  is_free_pkt_ptr_record ? "status" : "vdev_id",
2004 			  buf->status);
2005 
2006 	if (info & QDF_DP_TRACE_RECORD_INFO_LIVE) {
2007 		/* In live mode donot dump the contents of the cookie */
2008 		DPTRACE_PRINT("%s", prepend_str);
2009 	} else {
2010 		dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie,
2011 			sizeof(buf->cookie));
2012 	}
2013 }
2014 qdf_export_symbol(qdf_dp_display_ptr_record);
2015 
2016 /**
2017  * qdf_dp_trace_ptr() - record dptrace
2018  * @code: dptrace code
2019  * @pdev_id: pdev_id
2020  * @data: data
2021  * @size: size of data
2022  * @msdu_id: msdu_id
2023  * @status: return status
2024  *
2025  * Return: none
2026  */
2027 void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
2028 		uint8_t pdev_id, uint8_t *data, uint8_t size,
2029 		uint16_t msdu_id, uint16_t status)
2030 {
2031 	struct qdf_dp_trace_ptr_buf buf;
2032 	int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
2033 
2034 	if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false)
2035 		return;
2036 
2037 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2038 		QDF_BUG(0);
2039 
2040 	qdf_mem_copy(&buf.cookie, data, size);
2041 	buf.msdu_id = msdu_id;
2042 	buf.status = status;
2043 	qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, NULL, 0,
2044 			  QDF_NBUF_CB_DP_TRACE_PRINT(nbuf));
2045 }
2046 qdf_export_symbol(qdf_dp_trace_ptr);
2047 
2048 void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id,
2049 			   enum QDF_DP_TRACE_ID code, uint16_t msdu_id,
2050 			   enum qdf_proto_dir dir)
2051 {
2052 	struct qdf_dp_trace_data_buf buf;
2053 
2054 	buf.msdu_id = msdu_id;
2055 	if (!qdf_dp_enable_check(nbuf, code, dir))
2056 		return;
2057 
2058 	qdf_dp_add_record(code, pdev_id,
2059 			  nbuf ? qdf_nbuf_data(nbuf) : NULL,
2060 			  nbuf ? nbuf->len - nbuf->data_len : 0,
2061 			  (uint8_t *)&buf, sizeof(struct qdf_dp_trace_data_buf),
2062 			  (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
2063 }
2064 
2065 qdf_export_symbol(qdf_dp_trace_data_pkt);
2066 
2067 void qdf_dp_display_record(struct qdf_dp_trace_record_s *record,
2068 			   uint16_t index, uint8_t pdev_id, uint8_t info)
2069 {
2070 	int loc;
2071 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2072 
2073 	if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID ||
2074 		pdev_id == record->pdev_id))
2075 		return;
2076 
2077 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
2078 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2079 					 index, info, record);
2080 
2081 	switch (record->code) {
2082 	case  QDF_DP_TRACE_HDD_TX_TIMEOUT:
2083 		DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str);
2084 		break;
2085 	case  QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
2086 		DPTRACE_PRINT(" %s: HDD SoftAP TX Timeout", prepend_str);
2087 		break;
2088 	case  QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
2089 		DPTRACE_PRINT(" %s: CE Fast Packet Error", prepend_str);
2090 		break;
2091 	case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
2092 	default:
2093 		dump_dp_hex_trace(prepend_str, record->data, record->size);
2094 		break;
2095 	};
2096 }
2097 qdf_export_symbol(qdf_dp_display_record);
2098 
2099 void
2100 qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record,
2101 			       uint16_t rec_index, uint8_t pdev_id,
2102 			       uint8_t info)
2103 {
2104 	int loc;
2105 	char prepend_str[DP_TRACE_META_DATA_STRLEN + 10];
2106 	struct qdf_dp_trace_data_buf *buf =
2107 		(struct qdf_dp_trace_data_buf *)record->data;
2108 
2109 	qdf_mem_set(prepend_str, 0, sizeof(prepend_str));
2110 
2111 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2112 					 rec_index, info, record);
2113 	if (loc < sizeof(prepend_str))
2114 		loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2115 				"[%d]", buf->msdu_id);
2116 	dump_dp_hex_trace(prepend_str,
2117 			  &record->data[sizeof(struct qdf_dp_trace_data_buf)],
2118 			  record->size);
2119 }
2120 
2121 /**
2122  * qdf_dp_trace() - Stores the data in buffer
2123  * @nbuf  : defines the netbuf
2124  * @code : defines the event
2125  * @pdev_id: pdev_id
2126  * @data : defines the data to be stored
2127  * @size : defines the size of the data record
2128  *
2129  * Return: None
2130  */
2131 void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
2132 	uint8_t *data, uint8_t size, enum qdf_proto_dir dir)
2133 {
2134 
2135 	if (qdf_dp_enable_check(nbuf, code, dir) == false)
2136 		return;
2137 
2138 	qdf_dp_add_record(code, pdev_id, nbuf ? qdf_nbuf_data(nbuf) : NULL,
2139 			  size, NULL, 0,
2140 			  (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
2141 }
2142 qdf_export_symbol(qdf_dp_trace);
2143 
2144 /**
2145  * qdf_dp_trace_spin_lock_init() - initializes the lock variable before use
2146  * This function will be called from cds_alloc_global_context, we will have lock
2147  * available to use ASAP
2148  *
2149  * Return: None
2150  */
2151 void qdf_dp_trace_spin_lock_init(void)
2152 {
2153 	spin_lock_init(&l_dp_trace_lock);
2154 }
2155 qdf_export_symbol(qdf_dp_trace_spin_lock_init);
2156 
2157 /**
2158  * qdf_dp_trace_disable_live_mode - disable live mode for dptrace
2159  *
2160  * Return: none
2161  */
2162 void qdf_dp_trace_disable_live_mode(void)
2163 {
2164 	g_qdf_dp_trace_data.force_live_mode = 0;
2165 }
2166 qdf_export_symbol(qdf_dp_trace_disable_live_mode);
2167 
2168 /**
2169  * qdf_dp_trace_enable_live_mode() - enable live mode for dptrace
2170  *
2171  * Return: none
2172  */
2173 void qdf_dp_trace_enable_live_mode(void)
2174 {
2175 	g_qdf_dp_trace_data.force_live_mode = 1;
2176 }
2177 qdf_export_symbol(qdf_dp_trace_enable_live_mode);
2178 
2179 /**
2180  * qdf_dp_trace_clear_buffer() - clear dp trace buffer
2181  *
2182  * Return: none
2183  */
2184 void qdf_dp_trace_clear_buffer(void)
2185 {
2186 	g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR;
2187 	g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR;
2188 	g_qdf_dp_trace_data.num = 0;
2189 	g_qdf_dp_trace_data.dump_counter = 0;
2190 	g_qdf_dp_trace_data.num_records_to_dump = MAX_QDF_DP_TRACE_RECORDS;
2191 	if (g_qdf_dp_trace_data.enable)
2192 		memset(g_qdf_dp_trace_tbl, 0,
2193 		       MAX_QDF_DP_TRACE_RECORDS *
2194 		       sizeof(struct qdf_dp_trace_record_s));
2195 }
2196 qdf_export_symbol(qdf_dp_trace_clear_buffer);
2197 
2198 void qdf_dp_trace_dump_stats(void)
2199 {
2200 		DPTRACE_PRINT("STATS |DPT: tx %u rx %u icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)",
2201 			      g_qdf_dp_trace_data.tx_count,
2202 			      g_qdf_dp_trace_data.rx_count,
2203 			      g_qdf_dp_trace_data.icmp_req,
2204 			      g_qdf_dp_trace_data.icmp_resp,
2205 			      g_qdf_dp_trace_data.arp_req,
2206 			      g_qdf_dp_trace_data.arp_resp,
2207 			      g_qdf_dp_trace_data.icmpv6_req,
2208 			      g_qdf_dp_trace_data.icmpv6_resp,
2209 			      g_qdf_dp_trace_data.icmpv6_ns,
2210 			      g_qdf_dp_trace_data.icmpv6_na,
2211 			      g_qdf_dp_trace_data.icmpv6_rs,
2212 			      g_qdf_dp_trace_data.icmpv6_ra,
2213 			      g_qdf_dp_trace_data.dhcp_disc,
2214 			      g_qdf_dp_trace_data.dhcp_off,
2215 			      g_qdf_dp_trace_data.dhcp_req,
2216 			      g_qdf_dp_trace_data.dhcp_ack,
2217 			      g_qdf_dp_trace_data.dhcp_nack,
2218 			      g_qdf_dp_trace_data.dhcp_others,
2219 			      g_qdf_dp_trace_data.eapol_m1,
2220 			      g_qdf_dp_trace_data.eapol_m2,
2221 			      g_qdf_dp_trace_data.eapol_m3,
2222 			      g_qdf_dp_trace_data.eapol_m4,
2223 			      g_qdf_dp_trace_data.eapol_others);
2224 }
2225 qdf_export_symbol(qdf_dp_trace_dump_stats);
2226 
2227 /**
2228  * qdf_dpt_dump_hex_trace_debugfs() - read data in file
2229  * @file: file to read
2230  * @str: string to prepend the hexdump with.
2231  * @buf: buffer which contains data to be written
2232  * @buf_len: defines the size of the data to be written
2233  *
2234  * Return: None
2235  */
2236 static void qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file,
2237 				char *str, uint8_t *buf, uint8_t buf_len)
2238 {
2239 	unsigned char linebuf[BUFFER_SIZE];
2240 	const u8 *ptr = buf;
2241 	int i, linelen, remaining = buf_len;
2242 
2243 	/* Dump the bytes in the last line */
2244 	for (i = 0; i < buf_len; i += ROW_SIZE) {
2245 		linelen = min(remaining, ROW_SIZE);
2246 		remaining -= ROW_SIZE;
2247 
2248 		hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1,
2249 				linebuf, sizeof(linebuf), false);
2250 
2251 		qdf_debugfs_printf(file, "%s %s\n", str, linebuf);
2252 	}
2253 }
2254 
2255 /**
2256  * qdf_dpt_display_proto_pkt_debugfs() - display proto packet
2257  * @file: file to read
2258  * @record: dptrace record
2259  * @index: index
2260  *
2261  * Return: none
2262  */
2263 static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file,
2264 				struct qdf_dp_trace_record_s *record,
2265 				uint32_t index)
2266 {
2267 	int loc;
2268 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2269 	struct qdf_dp_trace_proto_buf *buf =
2270 		(struct qdf_dp_trace_proto_buf *)record->data;
2271 
2272 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2273 					 index, 0, record);
2274 	qdf_debugfs_printf(file, "%s [%d] [%s] SA: "
2275 			   QDF_MAC_ADDR_STR " %s DA: "
2276 			   QDF_MAC_ADDR_STR,
2277 			   prepend_str,
2278 			   buf->vdev_id,
2279 			   qdf_dp_subtype_to_str(buf->subtype),
2280 			   QDF_MAC_ADDR_ARRAY(buf->sa.bytes),
2281 			   qdf_dp_dir_to_str(buf->dir),
2282 			   QDF_MAC_ADDR_ARRAY(buf->da.bytes));
2283 	qdf_debugfs_printf(file, "\n");
2284 }
2285 
2286 /**
2287  * qdf_dpt_display_mgmt_pkt_debugfs() - display mgmt packet
2288  * @file: file to read
2289  * @record: dptrace record
2290  * @index: index
2291  *
2292  * Return: none
2293  */
2294 static void qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file,
2295 				struct qdf_dp_trace_record_s *record,
2296 				uint32_t index)
2297 {
2298 
2299 	int loc;
2300 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2301 	struct qdf_dp_trace_mgmt_buf *buf =
2302 		(struct qdf_dp_trace_mgmt_buf *)record->data;
2303 
2304 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2305 					 index, 0, record);
2306 
2307 	qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
2308 			   prepend_str,
2309 			   buf->vdev_id,
2310 			   qdf_dp_type_to_str(buf->type),
2311 			   qdf_dp_subtype_to_str(buf->subtype));
2312 }
2313 
2314 /**
2315  * qdf_dpt_display_event_record_debugfs() - display event records
2316  * @file: file to read
2317  * @record: dptrace record
2318  * @index: index
2319  *
2320  * Return: none
2321  */
2322 static void qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file,
2323 				struct qdf_dp_trace_record_s *record,
2324 				uint32_t index)
2325 {
2326 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2327 	struct qdf_dp_trace_event_buf *buf =
2328 		(struct qdf_dp_trace_event_buf *)record->data;
2329 
2330 	qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2331 				   index, 0, record);
2332 	qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
2333 			   prepend_str,
2334 			   buf->vdev_id,
2335 			   qdf_dp_type_to_str(buf->type),
2336 			   qdf_dp_subtype_to_str(buf->subtype));
2337 }
2338 
2339 /**
2340  * qdf_dpt_display_ptr_record_debugfs() - display record ptr
2341  * @file: file to read
2342  * @record: dptrace record
2343  * @index: index
2344  *
2345  * Return: none
2346  */
2347 static void qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file,
2348 				struct qdf_dp_trace_record_s *record,
2349 				uint32_t index)
2350 {
2351 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2352 	int loc;
2353 	struct qdf_dp_trace_ptr_buf *buf =
2354 		(struct qdf_dp_trace_ptr_buf *)record->data;
2355 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2356 					 index, 0, record);
2357 
2358 	if (loc < sizeof(prepend_str))
2359 		scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2360 			  "[msdu id %d %s %d]",
2361 			  buf->msdu_id,
2362 			  (record->code ==
2363 				QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ?
2364 			  "status" : "vdev_id",
2365 			  buf->status);
2366 
2367 	qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
2368 				       (uint8_t *)&buf->cookie,
2369 				       sizeof(buf->cookie));
2370 }
2371 
2372 /**
2373  * qdf_dpt_display_ptr_record_debugfs() - display record
2374  * @file: file to read
2375  * @record: dptrace record
2376  * @index: index
2377  *
2378  * Return: none
2379  */
2380 static void qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file,
2381 				struct qdf_dp_trace_record_s *record,
2382 				uint32_t index)
2383 {
2384 	int loc;
2385 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2386 	struct qdf_dp_trace_data_buf *buf =
2387 		(struct qdf_dp_trace_data_buf *)record->data;
2388 
2389 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2390 					 index, 0, record);
2391 	if (loc < sizeof(prepend_str))
2392 		loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2393 				"[%d]", buf->msdu_id);
2394 	qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
2395 				       record->data, record->size);
2396 }
2397 
2398 uint32_t qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file,
2399 				      enum qdf_dpt_debugfs_state state)
2400 {
2401 	uint32_t i = 0;
2402 	uint32_t tail;
2403 	uint32_t count = g_qdf_dp_trace_data.num;
2404 
2405 	if (!g_qdf_dp_trace_data.enable) {
2406 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
2407 		  "%s: Tracing Disabled", __func__);
2408 		return QDF_STATUS_E_EMPTY;
2409 	}
2410 
2411 	if (!count) {
2412 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
2413 		  "%s: no packets", __func__);
2414 		return QDF_STATUS_E_EMPTY;
2415 	}
2416 
2417 	if (state == QDF_DPT_DEBUGFS_STATE_SHOW_IN_PROGRESS)
2418 		return g_qdf_dp_trace_data.curr_pos;
2419 
2420 	qdf_debugfs_printf(file,
2421 		"DPT: config - bitmap 0x%x verb %u #rec %u rec_requested %u live_config %u thresh %u time_limit %u\n",
2422 		g_qdf_dp_trace_data.proto_bitmap,
2423 		g_qdf_dp_trace_data.verbosity,
2424 		g_qdf_dp_trace_data.no_of_record,
2425 		g_qdf_dp_trace_data.num_records_to_dump,
2426 		g_qdf_dp_trace_data.live_mode_config,
2427 		g_qdf_dp_trace_data.high_tput_thresh,
2428 		g_qdf_dp_trace_data.thresh_time_limit);
2429 
2430 	qdf_debugfs_printf(file,
2431 		"STATS |DPT: icmp(%u %u) arp(%u %u) icmpv6(%u %u %u %u %u %u) dhcp(%u %u %u %u %u %u) eapol(%u %u %u %u %u)\n",
2432 		g_qdf_dp_trace_data.icmp_req,
2433 		g_qdf_dp_trace_data.icmp_resp,
2434 		g_qdf_dp_trace_data.arp_req,
2435 		g_qdf_dp_trace_data.arp_resp,
2436 		g_qdf_dp_trace_data.icmpv6_req,
2437 		g_qdf_dp_trace_data.icmpv6_resp,
2438 		g_qdf_dp_trace_data.icmpv6_ns,
2439 		g_qdf_dp_trace_data.icmpv6_na,
2440 		g_qdf_dp_trace_data.icmpv6_rs,
2441 		g_qdf_dp_trace_data.icmpv6_ra,
2442 		g_qdf_dp_trace_data.dhcp_disc,
2443 		g_qdf_dp_trace_data.dhcp_off,
2444 		g_qdf_dp_trace_data.dhcp_req,
2445 		g_qdf_dp_trace_data.dhcp_ack,
2446 		g_qdf_dp_trace_data.dhcp_nack,
2447 		g_qdf_dp_trace_data.dhcp_others,
2448 		g_qdf_dp_trace_data.eapol_m1,
2449 		g_qdf_dp_trace_data.eapol_m2,
2450 		g_qdf_dp_trace_data.eapol_m3,
2451 		g_qdf_dp_trace_data.eapol_m4,
2452 		g_qdf_dp_trace_data.eapol_others);
2453 
2454 	qdf_debugfs_printf(file,
2455 		"DPT: Total Records: %d, Head: %d, Tail: %d\n",
2456 		g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
2457 		g_qdf_dp_trace_data.tail);
2458 
2459 	spin_lock_bh(&l_dp_trace_lock);
2460 	if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
2461 		i = g_qdf_dp_trace_data.head;
2462 		tail = g_qdf_dp_trace_data.tail;
2463 
2464 		if (count > g_qdf_dp_trace_data.num)
2465 			count = g_qdf_dp_trace_data.num;
2466 
2467 		if (tail >= (count - 1))
2468 			i = tail - count + 1;
2469 		else if (count != MAX_QDF_DP_TRACE_RECORDS)
2470 			i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
2471 						     tail);
2472 		g_qdf_dp_trace_data.curr_pos = 0;
2473 		g_qdf_dp_trace_data.saved_tail = tail;
2474 	}
2475 	spin_unlock_bh(&l_dp_trace_lock);
2476 
2477 	return g_qdf_dp_trace_data.saved_tail;
2478 }
2479 qdf_export_symbol(qdf_dpt_get_curr_pos_debugfs);
2480 
2481 QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file,
2482 				      uint32_t curr_pos)
2483 {
2484 	struct qdf_dp_trace_record_s p_record;
2485 	uint32_t i = curr_pos;
2486 	uint16_t num_records_to_dump = g_qdf_dp_trace_data.num_records_to_dump;
2487 
2488 	if (!g_qdf_dp_trace_data.enable) {
2489 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2490 			  "%s: Tracing Disabled", __func__);
2491 		return QDF_STATUS_E_FAILURE;
2492 	}
2493 
2494 	if (num_records_to_dump > g_qdf_dp_trace_data.num)
2495 		num_records_to_dump = g_qdf_dp_trace_data.num;
2496 
2497 	/*
2498 	 * Max dp trace record size should always be less than
2499 	 * QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
2500 	 */
2501 	if (WARN_ON(QDF_DP_TRACE_MAX_RECORD_SIZE <
2502 				QDF_DP_TRACE_PREPEND_STR_SIZE + BUFFER_SIZE))
2503 		return QDF_STATUS_E_FAILURE;
2504 
2505 	spin_lock_bh(&l_dp_trace_lock);
2506 	p_record = g_qdf_dp_trace_tbl[i];
2507 	spin_unlock_bh(&l_dp_trace_lock);
2508 
2509 	for (;; ) {
2510 		/*
2511 		 * Initially we get file as 1 page size, and
2512 		 * if remaining size in file is less than one record max size,
2513 		 * then return so that it gets an extra page.
2514 		 */
2515 		if ((file->size - file->count) < QDF_DP_TRACE_MAX_RECORD_SIZE) {
2516 			spin_lock_bh(&l_dp_trace_lock);
2517 			g_qdf_dp_trace_data.curr_pos = i;
2518 			spin_unlock_bh(&l_dp_trace_lock);
2519 			return QDF_STATUS_E_FAILURE;
2520 		}
2521 
2522 		switch (p_record.code) {
2523 		case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
2524 		case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
2525 		case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
2526 			qdf_dpt_display_ptr_record_debugfs(file, &p_record, i);
2527 			break;
2528 
2529 		case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
2530 		case QDF_DP_TRACE_DHCP_PACKET_RECORD:
2531 		case QDF_DP_TRACE_ARP_PACKET_RECORD:
2532 		case QDF_DP_TRACE_ICMP_PACKET_RECORD:
2533 		case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
2534 			qdf_dpt_display_proto_pkt_debugfs(file, &p_record, i);
2535 			break;
2536 
2537 		case QDF_DP_TRACE_MGMT_PACKET_RECORD:
2538 			qdf_dpt_display_mgmt_pkt_debugfs(file, &p_record, i);
2539 			break;
2540 
2541 		case QDF_DP_TRACE_EVENT_RECORD:
2542 			qdf_dpt_display_event_record_debugfs(file, &p_record,
2543 							     i);
2544 			break;
2545 
2546 		case QDF_DP_TRACE_HDD_TX_TIMEOUT:
2547 			qdf_debugfs_printf(file, "DPT: %04d: %s %s\n",
2548 				i, p_record.time,
2549 				qdf_dp_code_to_string(p_record.code));
2550 			qdf_debugfs_printf(file, "%s: HDD TX Timeout\n");
2551 			break;
2552 
2553 		case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
2554 			qdf_debugfs_printf(file, "%04d: %s %s\n",
2555 				i, p_record.time,
2556 				qdf_dp_code_to_string(p_record.code));
2557 			qdf_debugfs_printf(file,
2558 					   "%s: HDD  SoftAP TX Timeout\n");
2559 			break;
2560 
2561 		case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
2562 			qdf_debugfs_printf(file, "DPT: %04d: %s %s\n",
2563 				i, p_record.time,
2564 				qdf_dp_code_to_string(p_record.code));
2565 			qdf_debugfs_printf(file,
2566 					   "%s: CE Fast Packet Error\n");
2567 			break;
2568 
2569 		case QDF_DP_TRACE_MAX:
2570 			qdf_debugfs_printf(file,
2571 				"%s: QDF_DP_TRACE_MAX event should not be generated\n",
2572 				__func__);
2573 			break;
2574 
2575 		case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
2576 		case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
2577 		case QDF_DP_TRACE_TX_PACKET_RECORD:
2578 		case QDF_DP_TRACE_RX_PACKET_RECORD:
2579 		case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
2580 		case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
2581 
2582 		default:
2583 			qdf_dpt_display_record_debugfs(file, &p_record, i);
2584 			break;
2585 		}
2586 
2587 		if (++g_qdf_dp_trace_data.dump_counter == num_records_to_dump)
2588 			break;
2589 
2590 		spin_lock_bh(&l_dp_trace_lock);
2591 		if (i == 0)
2592 			i = MAX_QDF_DP_TRACE_RECORDS;
2593 
2594 		i -= 1;
2595 		p_record = g_qdf_dp_trace_tbl[i];
2596 		spin_unlock_bh(&l_dp_trace_lock);
2597 	}
2598 
2599 	g_qdf_dp_trace_data.dump_counter = 0;
2600 
2601 	return QDF_STATUS_SUCCESS;
2602 }
2603 qdf_export_symbol(qdf_dpt_dump_stats_debugfs);
2604 
2605 /**
2606  * qdf_dpt_set_value_debugfs() - Configure the value to control DP trace
2607  * @proto_bitmap: defines the protocol to be tracked
2608  * @no_of_records: defines the nth packet which is traced
2609  * @verbosity: defines the verbosity level
2610  *
2611  * Return: None
2612  */
2613 void qdf_dpt_set_value_debugfs(uint8_t proto_bitmap, uint8_t no_of_record,
2614 			    uint8_t verbosity, uint16_t num_records_to_dump)
2615 {
2616 	if (g_qdf_dp_trace_data.enable) {
2617 		g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
2618 		g_qdf_dp_trace_data.no_of_record = no_of_record;
2619 		g_qdf_dp_trace_data.verbosity    = verbosity;
2620 		g_qdf_dp_trace_data.num_records_to_dump = num_records_to_dump;
2621 	}
2622 }
2623 qdf_export_symbol(qdf_dpt_set_value_debugfs);
2624 
2625 
2626 /**
2627  * qdf_dp_trace_dump_all() - Dump data from ring buffer via call back functions
2628  * registered with QDF
2629  * @count: Number of lines to dump starting from tail to head
2630  * @pdev_id: pdev_id
2631  *
2632  * Return: None
2633  */
2634 void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
2635 {
2636 	struct qdf_dp_trace_record_s p_record;
2637 	int32_t i, tail;
2638 
2639 	if (!g_qdf_dp_trace_data.enable) {
2640 		DPTRACE_PRINT("Tracing Disabled");
2641 		return;
2642 	}
2643 
2644 	DPTRACE_PRINT(
2645 		"DPT: config - bitmap 0x%x verb %u #rec %u live_config %u thresh %u time_limit %u",
2646 		g_qdf_dp_trace_data.proto_bitmap,
2647 		g_qdf_dp_trace_data.verbosity,
2648 		g_qdf_dp_trace_data.no_of_record,
2649 		g_qdf_dp_trace_data.live_mode_config,
2650 		g_qdf_dp_trace_data.high_tput_thresh,
2651 		g_qdf_dp_trace_data.thresh_time_limit);
2652 
2653 	qdf_dp_trace_dump_stats();
2654 
2655 	DPTRACE_PRINT("DPT: Total Records: %d, Head: %d, Tail: %d",
2656 		      g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
2657 		      g_qdf_dp_trace_data.tail);
2658 
2659 	/* aquire the lock so that only one thread at a time can read
2660 	 * the ring buffer
2661 	 */
2662 	spin_lock_bh(&l_dp_trace_lock);
2663 
2664 	if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
2665 		i = g_qdf_dp_trace_data.head;
2666 		tail = g_qdf_dp_trace_data.tail;
2667 
2668 		if (count) {
2669 			if (count > g_qdf_dp_trace_data.num)
2670 				count = g_qdf_dp_trace_data.num;
2671 			if (tail >= (count - 1))
2672 				i = tail - count + 1;
2673 			else if (count != MAX_QDF_DP_TRACE_RECORDS)
2674 				i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
2675 							     tail);
2676 		}
2677 
2678 		p_record = g_qdf_dp_trace_tbl[i];
2679 		spin_unlock_bh(&l_dp_trace_lock);
2680 		for (;; ) {
2681 			qdf_dp_trace_cb_table[p_record.code](&p_record,
2682 							(uint16_t)i, pdev_id, false);
2683 			if (i == tail)
2684 				break;
2685 			i += 1;
2686 
2687 			spin_lock_bh(&l_dp_trace_lock);
2688 			if (MAX_QDF_DP_TRACE_RECORDS == i)
2689 				i = 0;
2690 
2691 			p_record = g_qdf_dp_trace_tbl[i];
2692 			spin_unlock_bh(&l_dp_trace_lock);
2693 		}
2694 	} else {
2695 		spin_unlock_bh(&l_dp_trace_lock);
2696 	}
2697 }
2698 qdf_export_symbol(qdf_dp_trace_dump_all);
2699 
2700 /**
2701  * qdf_dp_trace_throttle_live_mode() - Throttle DP Trace live mode
2702  * @high_bw_request: whether this is a high BW req or not
2703  *
2704  * The function tries to prevent excessive logging into the live buffer by
2705  * having an upper limit on number of packets that can be logged per second.
2706  *
2707  * The intention is to allow occasional pings and data packets and really low
2708  * throughput levels while suppressing bursts and higher throughput levels so
2709  * that we donot hog the live buffer.
2710  *
2711  * If the number of packets printed in a particular second exceeds the thresh,
2712  * disable printing in the next second.
2713  *
2714  * Return: None
2715  */
2716 void qdf_dp_trace_throttle_live_mode(bool high_bw_request)
2717 {
2718 	static int bw_interval_counter;
2719 
2720 	if (g_qdf_dp_trace_data.enable == false ||
2721 		g_qdf_dp_trace_data.live_mode_config == false)
2722 		return;
2723 
2724 	if (high_bw_request) {
2725 		g_qdf_dp_trace_data.live_mode = 0;
2726 		bw_interval_counter = 0;
2727 		return;
2728 	}
2729 
2730 	bw_interval_counter++;
2731 
2732 	if (0 == (bw_interval_counter %
2733 			g_qdf_dp_trace_data.thresh_time_limit)) {
2734 
2735 		spin_lock_bh(&l_dp_trace_lock);
2736 			if (g_qdf_dp_trace_data.print_pkt_cnt <=
2737 				g_qdf_dp_trace_data.high_tput_thresh)
2738 				g_qdf_dp_trace_data.live_mode = 1;
2739 
2740 		g_qdf_dp_trace_data.print_pkt_cnt = 0;
2741 		spin_unlock_bh(&l_dp_trace_lock);
2742 	}
2743 }
2744 qdf_export_symbol(qdf_dp_trace_throttle_live_mode);
2745 
2746 void qdf_dp_trace_apply_tput_policy(bool is_data_traffic)
2747 {
2748 	if (g_qdf_dp_trace_data.dynamic_verbosity_modify) {
2749 		goto check_live_mode;
2750 		return;
2751 	}
2752 
2753 	if (is_data_traffic) {
2754 		g_qdf_dp_trace_data.verbosity =
2755 					QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
2756 	} else {
2757 		g_qdf_dp_trace_data.verbosity =
2758 					g_qdf_dp_trace_data.ini_conf_verbosity;
2759 	}
2760 check_live_mode:
2761 	qdf_dp_trace_throttle_live_mode(is_data_traffic);
2762 }
2763 #endif
2764 
2765 struct qdf_print_ctrl print_ctrl_obj[MAX_PRINT_CONFIG_SUPPORTED];
2766 
2767 struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = {
2768 	[QDF_MODULE_ID_TDLS] = {"tdls"},
2769 	[QDF_MODULE_ID_ACS] = {"ACS"},
2770 	[QDF_MODULE_ID_SCAN_SM] = {"scan state machine"},
2771 	[QDF_MODULE_ID_SCANENTRY] = {"scan entry"},
2772 	[QDF_MODULE_ID_WDS] = {"WDS"},
2773 	[QDF_MODULE_ID_ACTION] = {"action"},
2774 	[QDF_MODULE_ID_ROAM] = {"STA roaming"},
2775 	[QDF_MODULE_ID_INACT] = {"inactivity"},
2776 	[QDF_MODULE_ID_DOTH] = {"11h"},
2777 	[QDF_MODULE_ID_IQUE] = {"IQUE"},
2778 	[QDF_MODULE_ID_WME] = {"WME"},
2779 	[QDF_MODULE_ID_ACL] = {"ACL"},
2780 	[QDF_MODULE_ID_WPA] = {"WPA/RSN"},
2781 	[QDF_MODULE_ID_RADKEYS] = {"dump 802.1x keys"},
2782 	[QDF_MODULE_ID_RADDUMP] = {"dump radius packet"},
2783 	[QDF_MODULE_ID_RADIUS] = {"802.1x radius client"},
2784 	[QDF_MODULE_ID_DOT1XSM] = {"802.1x state machine"},
2785 	[QDF_MODULE_ID_DOT1X] = {"802.1x authenticator"},
2786 	[QDF_MODULE_ID_POWER] = {"power save"},
2787 	[QDF_MODULE_ID_STATE] = {"state"},
2788 	[QDF_MODULE_ID_OUTPUT] = {"output"},
2789 	[QDF_MODULE_ID_SCAN] = {"scan"},
2790 	[QDF_MODULE_ID_AUTH] = {"authentication"},
2791 	[QDF_MODULE_ID_ASSOC] = {"association"},
2792 	[QDF_MODULE_ID_NODE] = {"node"},
2793 	[QDF_MODULE_ID_ELEMID] = {"element ID"},
2794 	[QDF_MODULE_ID_XRATE] = {"rate"},
2795 	[QDF_MODULE_ID_INPUT] = {"input"},
2796 	[QDF_MODULE_ID_CRYPTO] = {"crypto"},
2797 	[QDF_MODULE_ID_DUMPPKTS] = {"dump packet"},
2798 	[QDF_MODULE_ID_DEBUG] = {"debug"},
2799 	[QDF_MODULE_ID_MLME] = {"mlme"},
2800 	[QDF_MODULE_ID_RRM] = {"rrm"},
2801 	[QDF_MODULE_ID_WNM] = {"wnm"},
2802 	[QDF_MODULE_ID_P2P_PROT] = {"p2p_prot"},
2803 	[QDF_MODULE_ID_PROXYARP] = {"proxyarp"},
2804 	[QDF_MODULE_ID_L2TIF] = {"l2tif"},
2805 	[QDF_MODULE_ID_WIFIPOS] = {"wifipos"},
2806 	[QDF_MODULE_ID_WRAP] = {"wrap"},
2807 	[QDF_MODULE_ID_DFS] = {"dfs"},
2808 	[QDF_MODULE_ID_ATF] = {"atf"},
2809 	[QDF_MODULE_ID_SPLITMAC] = {"splitmac"},
2810 	[QDF_MODULE_ID_IOCTL] = {"ioctl"},
2811 	[QDF_MODULE_ID_NAC] = {"nac"},
2812 	[QDF_MODULE_ID_MESH] = {"mesh"},
2813 	[QDF_MODULE_ID_MBO] = {"mbo"},
2814 	[QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = {"extchanswitch"},
2815 	[QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = {"extchanscan"},
2816 	[QDF_MODULE_ID_TLSHIM] = {"tlshim"},
2817 	[QDF_MODULE_ID_WMI] = {"WMI"},
2818 	[QDF_MODULE_ID_HTT] = {"HTT"},
2819 	[QDF_MODULE_ID_HDD] = {"HDD"},
2820 	[QDF_MODULE_ID_SME] = {"SME"},
2821 	[QDF_MODULE_ID_PE] = {"PE"},
2822 	[QDF_MODULE_ID_WMA] = {"WMA"},
2823 	[QDF_MODULE_ID_SYS] = {"SYS"},
2824 	[QDF_MODULE_ID_QDF] = {"QDF"},
2825 	[QDF_MODULE_ID_SAP] = {"SAP"},
2826 	[QDF_MODULE_ID_HDD_SOFTAP] = {"HDD_SAP"},
2827 	[QDF_MODULE_ID_HDD_DATA] = {"DATA"},
2828 	[QDF_MODULE_ID_HDD_SAP_DATA] = {"SAP_DATA"},
2829 	[QDF_MODULE_ID_HIF] = {"HIF"},
2830 	[QDF_MODULE_ID_HTC] = {"HTC"},
2831 	[QDF_MODULE_ID_TXRX] = {"TXRX"},
2832 	[QDF_MODULE_ID_QDF_DEVICE] = {"QDF_DEV"},
2833 	[QDF_MODULE_ID_CFG] = {"CFG"},
2834 	[QDF_MODULE_ID_BMI] = {"BMI"},
2835 	[QDF_MODULE_ID_EPPING] = {"EPPING"},
2836 	[QDF_MODULE_ID_QVIT] = {"QVIT"},
2837 	[QDF_MODULE_ID_DP] = {"DP"},
2838 	[QDF_MODULE_ID_HAL] = {"HAL"},
2839 	[QDF_MODULE_ID_SOC] = {"SOC"},
2840 	[QDF_MODULE_ID_OS_IF] = {"OSIF"},
2841 	[QDF_MODULE_ID_TARGET_IF] = {"TIF"},
2842 	[QDF_MODULE_ID_SCHEDULER] = {"SCH"},
2843 	[QDF_MODULE_ID_MGMT_TXRX] = {"MGMT_TXRX"},
2844 	[QDF_MODULE_ID_PMO] = {"PMO"},
2845 	[QDF_MODULE_ID_POLICY_MGR] = {"POLICY_MGR"},
2846 	[QDF_MODULE_ID_SA_API] = {"SA_API"},
2847 	[QDF_MODULE_ID_NAN] = {"NAN"},
2848 	[QDF_MODULE_ID_SPECTRAL] = {"SPECTRAL"},
2849 	[QDF_MODULE_ID_P2P] = {"P2P"},
2850 	[QDF_MODULE_ID_OFFCHAN_TXRX] = {"OFFCHAN"},
2851 	[QDF_MODULE_ID_REGULATORY] = {"REGULATORY"},
2852 	[QDF_MODULE_ID_OBJ_MGR] = {"OBJMGR"},
2853 	[QDF_MODULE_ID_SERIALIZATION] = {"SER"},
2854 	[QDF_MODULE_ID_NSS] = {"NSS"},
2855 	[QDF_MODULE_ID_ROAM_DEBUG] = {"roam debug"},
2856 	[QDF_MODULE_ID_DIRECT_BUF_RX] = {"DIRECT_BUF_RX"},
2857 	[QDF_MODULE_ID_DISA] = {"disa"},
2858 	[QDF_MODULE_ID_GREEN_AP] = {"GREEN_AP"},
2859 	[QDF_MODULE_ID_EXTAP] = {"EXTAP"},
2860 	[QDF_MODULE_ID_FD] = {"FILS discovery"},
2861 	[QDF_MODULE_ID_FTM] = {"FTM"},
2862 	[QDF_MODULE_ID_OCB] = {"OCB"},
2863 	[QDF_MODULE_ID_CONFIG] = {"CONFIG"},
2864 	[QDF_MODULE_ID_IPA] = {"IPA"},
2865 	[QDF_MODULE_ID_CP_STATS] = {"CP_STATS"},
2866 	[QDF_MODULE_ID_ACTION_OUI] = {"action_oui"},
2867 	[QDF_MODULE_ID_TARGET] = {"TARGET"},
2868 	[QDF_MODULE_ID_MBSSIE] = {"MBSSIE"},
2869 	[QDF_MODULE_ID_FWOL] = {"fwol"},
2870 	[QDF_MODULE_ID_SM_ENGINE] = {"SM_ENGINE"},
2871 	[QDF_MODULE_ID_CMN_MLME] = {"CMN_MLME"},
2872 	[QDF_MODULE_ID_BSSCOLOR] = {"BSSCOLOR"},
2873 	[QDF_MODULE_ID_ANY] = {"ANY"},
2874 };
2875 qdf_export_symbol(g_qdf_category_name);
2876 
2877 /**
2878  * qdf_trace_display() - Display trace
2879  *
2880  * Return:  None
2881  */
2882 void qdf_trace_display(void)
2883 {
2884 	QDF_MODULE_ID module_id;
2885 
2886 	pr_err("     1)FATAL  2)ERROR  3)WARN  4)INFO  5)INFO_H  6)INFO_M  7)INFO_L 8)DEBUG\n");
2887 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; ++module_id) {
2888 		pr_err("%2d)%s    %s        %s       %s       %s        %s         %s         %s        %s\n",
2889 		       (int)module_id,
2890 		       g_qdf_category_name[module_id].category_name_str,
2891 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2892 			       QDF_TRACE_LEVEL_FATAL) ? "X" : " ",
2893 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2894 			       QDF_TRACE_LEVEL_ERROR) ? "X" : " ",
2895 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2896 			       QDF_TRACE_LEVEL_WARN) ? "X" : " ",
2897 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2898 			       QDF_TRACE_LEVEL_INFO) ? "X" : " ",
2899 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2900 			       QDF_TRACE_LEVEL_INFO_HIGH) ? "X" : " ",
2901 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2902 			       QDF_TRACE_LEVEL_INFO_MED) ? "X" : " ",
2903 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2904 			       QDF_TRACE_LEVEL_INFO_LOW) ? "X" : " ",
2905 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
2906 			       QDF_TRACE_LEVEL_DEBUG) ? "X" : " ");
2907 	}
2908 }
2909 qdf_export_symbol(qdf_trace_display);
2910 
2911 #ifdef CONFIG_MCL
2912 #define print_to_console(str)
2913 #else
2914 static inline void print_to_console(char *str_buffer)
2915 {
2916 	pr_err("%s\n", str_buffer);
2917 }
2918 #endif
2919 
2920 #ifdef MULTI_IF_NAME
2921 static const char *qdf_trace_wlan_modname(void)
2922 {
2923 	return MULTI_IF_NAME;
2924 }
2925 #else
2926 static const char *qdf_trace_wlan_modname(void)
2927 {
2928 	return "wlan";
2929 }
2930 #endif
2931 
2932 void qdf_trace_msg_cmn(unsigned int idx,
2933 			QDF_MODULE_ID category,
2934 			QDF_TRACE_LEVEL verbose,
2935 			const char *str_format, va_list val)
2936 {
2937 	char str_buffer[QDF_TRACE_BUFFER_SIZE];
2938 	int n;
2939 
2940 	/* Check if index passed is valid */
2941 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
2942 		pr_info("%s: Invalid index - %d\n", __func__, idx);
2943 		return;
2944 	}
2945 
2946 	/* Check if print control object is in use */
2947 	if (!print_ctrl_obj[idx].in_use) {
2948 		pr_info("%s: Invalid print control object\n", __func__);
2949 		return;
2950 	}
2951 
2952 	/* Check if category passed is valid */
2953 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
2954 		pr_info("%s: Invalid category: %d\n", __func__, category);
2955 		return;
2956 	}
2957 
2958 	/* Check if verbose mask is valid */
2959 	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
2960 		pr_info("%s: Invalid verbose level %d\n", __func__, verbose);
2961 		return;
2962 	}
2963 
2964 	/*
2965 	 * Print the trace message when the desired verbose level is set in
2966 	 * the desired category for the print control object
2967 	 */
2968 	if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
2969 	    QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
2970 		static const char * const VERBOSE_STR[] = {
2971 			[QDF_TRACE_LEVEL_NONE] = "",
2972 			[QDF_TRACE_LEVEL_FATAL] = "F",
2973 			[QDF_TRACE_LEVEL_ERROR] = "E",
2974 			[QDF_TRACE_LEVEL_WARN] = "W",
2975 			[QDF_TRACE_LEVEL_INFO] = "I",
2976 			[QDF_TRACE_LEVEL_INFO_HIGH] = "IH",
2977 			[QDF_TRACE_LEVEL_INFO_MED] = "IM",
2978 			[QDF_TRACE_LEVEL_INFO_LOW] = "IL",
2979 			[QDF_TRACE_LEVEL_DEBUG] = "D",
2980 			[QDF_TRACE_LEVEL_TRACE] = "T",
2981 			[QDF_TRACE_LEVEL_ALL] = "" };
2982 
2983 		/* print the prefix string into the string buffer... */
2984 		n = scnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE,
2985 			     "%s: [%d:%s:%s] ", qdf_trace_wlan_modname(),
2986 			     in_interrupt() ? 0 : current->pid,
2987 			     VERBOSE_STR[verbose],
2988 			     g_qdf_category_name[category].category_name_str);
2989 
2990 		/* print the formatted log message after the prefix string */
2991 		vscnprintf(str_buffer + n, QDF_TRACE_BUFFER_SIZE - n,
2992 			   str_format, val);
2993 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
2994 		wlan_log_to_user(verbose, (char *)str_buffer,
2995 				 strlen(str_buffer));
2996 		if (qdf_likely(qdf_log_dump_at_kernel_enable))
2997 			print_to_console(str_buffer);
2998 #else
2999 		pr_err("%s\n", str_buffer);
3000 #endif
3001 	}
3002 }
3003 qdf_export_symbol(qdf_trace_msg_cmn);
3004 
3005 QDF_STATUS qdf_print_setup(void)
3006 {
3007 	int i;
3008 
3009 	/* Loop through all print ctrl objects */
3010 	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
3011 		if (qdf_print_ctrl_cleanup(i))
3012 			return QDF_STATUS_E_FAILURE;
3013 	}
3014 	return QDF_STATUS_SUCCESS;
3015 }
3016 qdf_export_symbol(qdf_print_setup);
3017 
3018 QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx)
3019 {
3020 	int i = 0;
3021 
3022 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3023 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3024 		return QDF_STATUS_E_FAILURE;
3025 	}
3026 
3027 	/* Clean up the print control object corresponding to that index
3028 	 * If success, callee to change print control index to -1
3029 	 */
3030 
3031 	for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3032 		print_ctrl_obj[idx].cat_info[i].category_verbose_mask =
3033 							QDF_TRACE_LEVEL_NONE;
3034 	}
3035 	print_ctrl_obj[idx].custom_print = NULL;
3036 	print_ctrl_obj[idx].custom_ctxt = NULL;
3037 	qdf_print_clean_node_flag(idx);
3038 	print_ctrl_obj[idx].in_use = false;
3039 
3040 	return QDF_STATUS_SUCCESS;
3041 }
3042 qdf_export_symbol(qdf_print_ctrl_cleanup);
3043 
3044 int qdf_print_ctrl_register(const struct category_info *cinfo,
3045 			    void *custom_print_handler,
3046 			    void *custom_ctx,
3047 			    const char *pctrl_name)
3048 {
3049 	int idx = -1;
3050 	int i = 0;
3051 
3052 	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
3053 		if (!print_ctrl_obj[i].in_use) {
3054 			idx = i;
3055 			break;
3056 		}
3057 	}
3058 
3059 	/* Callee to handle idx -1 appropriately */
3060 	if (idx == -1) {
3061 		pr_info("%s: Allocation failed! No print control object free\n",
3062 			__func__);
3063 		return idx;
3064 	}
3065 
3066 	print_ctrl_obj[idx].in_use = true;
3067 
3068 	/*
3069 	 * In case callee does not pass category info,
3070 	 * custom print handler, custom context and print control name,
3071 	 * we do not set any value here. Clean up for the print control
3072 	 * getting allocated would have taken care of initializing
3073 	 * default values.
3074 	 *
3075 	 * We need to only set in_use to 1 in such a case
3076 	 */
3077 
3078 	if (pctrl_name) {
3079 		qdf_str_lcopy(print_ctrl_obj[idx].name, pctrl_name,
3080 			      sizeof(print_ctrl_obj[idx].name));
3081 	}
3082 
3083 	if (custom_print_handler)
3084 		print_ctrl_obj[idx].custom_print = custom_print_handler;
3085 
3086 	if (custom_ctx)
3087 		print_ctrl_obj[idx].custom_ctxt = custom_ctx;
3088 
3089 	if (cinfo) {
3090 		for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3091 			if (cinfo[i].category_verbose_mask ==
3092 			    QDF_TRACE_LEVEL_ALL) {
3093 				print_ctrl_obj[idx].cat_info[i]
3094 				.category_verbose_mask = 0xFFFF;
3095 			} else if ((cinfo[i].category_verbose_mask ==
3096 				   QDF_TRACE_LEVEL_NONE) ||
3097 				   (cinfo[i].category_verbose_mask ==
3098 				   QDF_TRACE_LEVEL_TO_MODULE_BITMASK(
3099 				   QDF_TRACE_LEVEL_NONE))) {
3100 				print_ctrl_obj[idx].cat_info[i]
3101 				.category_verbose_mask = 0;
3102 			} else {
3103 				print_ctrl_obj[idx].cat_info[i]
3104 				.category_verbose_mask =
3105 				cinfo[i].category_verbose_mask;
3106 			}
3107 		}
3108 	}
3109 
3110 	pr_info("%s: Allocated print control object %d\n",
3111 		__func__, idx);
3112 	return idx;
3113 }
3114 qdf_export_symbol(qdf_print_ctrl_register);
3115 
3116 #ifndef CONFIG_MCL
3117 void qdf_shared_print_ctrl_cleanup(void)
3118 {
3119 	qdf_print_ctrl_cleanup(qdf_pidx);
3120 }
3121 qdf_export_symbol(qdf_shared_print_ctrl_cleanup);
3122 
3123 /*
3124  * Set this to invalid value to differentiate with user-provided
3125  * value.
3126  */
3127 int qdf_dbg_mask = 0;
3128 qdf_export_symbol(qdf_dbg_mask);
3129 qdf_declare_param(qdf_dbg_mask, int);
3130 
3131 /*
3132  * QDF can be passed parameters which indicate the
3133  * debug level for each module.
3134  * an array of string values are passed, each string hold the following form
3135  *
3136  * <module name string>=<integer debug level value>
3137  *
3138  * The array qdf_dbg_arr will hold these module-string=value strings
3139  * The variable qdf_dbg_arr_cnt will have the count of how many such
3140  * string values were passed.
3141  */
3142 static char *qdf_dbg_arr[QDF_MODULE_ID_MAX];
3143 static int qdf_dbg_arr_cnt;
3144 qdf_declare_param_array(qdf_dbg_arr, charp, &qdf_dbg_arr_cnt);
3145 
3146 static uint16_t set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level)
3147 {
3148 	uint16_t category_verbose_mask = 0;
3149 	QDF_TRACE_LEVEL level;
3150 
3151 	for (level = QDF_TRACE_LEVEL_FATAL; level <= max_level; level++) {
3152 		category_verbose_mask |=
3153 			QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level);
3154 	}
3155 	return category_verbose_mask;
3156 }
3157 
3158 static QDF_MODULE_ID find_qdf_module_from_string(char *str)
3159 {
3160 	QDF_MODULE_ID mod_id;
3161 
3162 	for (mod_id = 0; mod_id < QDF_MODULE_ID_MAX; mod_id++) {
3163 		if (strcasecmp(str,
3164 				g_qdf_category_name[mod_id].category_name_str)
3165 				== 0) {
3166 			break;
3167 		}
3168 	}
3169 	return mod_id;
3170 }
3171 
3172 static void process_qdf_dbg_arr_param(struct category_info *cinfo,
3173 					int array_index)
3174 {
3175 	char *mod_val_str, *mod_str, *val_str;
3176 	unsigned long dbg_level;
3177 	QDF_MODULE_ID mod_id;
3178 
3179 	mod_val_str = qdf_dbg_arr[array_index];
3180 	mod_str = strsep(&mod_val_str, "=");
3181 	val_str = mod_val_str;
3182 	if (val_str == NULL) {
3183 		pr_info("qdf_dbg_arr: %s not in the <mod>=<val> form\n",
3184 				mod_str);
3185 		return;
3186 	}
3187 
3188 	mod_id = find_qdf_module_from_string(mod_str);
3189 	if (mod_id >= QDF_MODULE_ID_MAX) {
3190 		pr_info("ERROR!!Module name %s not in the list of modules\n",
3191 				mod_str);
3192 		return;
3193 	}
3194 
3195 	if (kstrtol(val_str, 10, &dbg_level) < 0) {
3196 		pr_info("ERROR!!Invalid debug level for module: %s\n",
3197 				mod_str);
3198 		return;
3199 	}
3200 
3201 	if (dbg_level >= QDF_TRACE_LEVEL_MAX) {
3202 		pr_info("ERROR!!Debug level for %s too high", mod_str);
3203 		pr_info("max: %d given %lu\n", QDF_TRACE_LEVEL_MAX,
3204 				dbg_level);
3205 		return;
3206 	}
3207 
3208 	pr_info("User passed setting module %s(%d) to level %lu\n",
3209 			mod_str,
3210 			mod_id,
3211 			dbg_level);
3212 	cinfo[mod_id].category_verbose_mask =
3213 		set_cumulative_verbose_mask((QDF_TRACE_LEVEL)dbg_level);
3214 }
3215 
3216 static void set_default_trace_levels(struct category_info *cinfo)
3217 {
3218 	int i;
3219 	static QDF_TRACE_LEVEL module_trace_default_level[QDF_MODULE_ID_MAX] = {
3220 		[QDF_MODULE_ID_TDLS] = QDF_TRACE_LEVEL_NONE,
3221 		[QDF_MODULE_ID_ACS] = QDF_TRACE_LEVEL_NONE,
3222 		[QDF_MODULE_ID_SCAN_SM] = QDF_TRACE_LEVEL_NONE,
3223 		[QDF_MODULE_ID_SCANENTRY] = QDF_TRACE_LEVEL_NONE,
3224 		[QDF_MODULE_ID_WDS] = QDF_TRACE_LEVEL_NONE,
3225 		[QDF_MODULE_ID_ACTION] = QDF_TRACE_LEVEL_NONE,
3226 		[QDF_MODULE_ID_ROAM] = QDF_TRACE_LEVEL_NONE,
3227 		[QDF_MODULE_ID_INACT] = QDF_TRACE_LEVEL_NONE,
3228 		[QDF_MODULE_ID_DOTH] = QDF_TRACE_LEVEL_NONE,
3229 		[QDF_MODULE_ID_IQUE] = QDF_TRACE_LEVEL_NONE,
3230 		[QDF_MODULE_ID_WME] = QDF_TRACE_LEVEL_NONE,
3231 		[QDF_MODULE_ID_ACL] = QDF_TRACE_LEVEL_NONE,
3232 		[QDF_MODULE_ID_WPA] = QDF_TRACE_LEVEL_NONE,
3233 		[QDF_MODULE_ID_RADKEYS] = QDF_TRACE_LEVEL_NONE,
3234 		[QDF_MODULE_ID_RADDUMP] = QDF_TRACE_LEVEL_NONE,
3235 		[QDF_MODULE_ID_RADIUS] = QDF_TRACE_LEVEL_NONE,
3236 		[QDF_MODULE_ID_DOT1XSM] = QDF_TRACE_LEVEL_NONE,
3237 		[QDF_MODULE_ID_DOT1X] = QDF_TRACE_LEVEL_NONE,
3238 		[QDF_MODULE_ID_POWER] = QDF_TRACE_LEVEL_NONE,
3239 		[QDF_MODULE_ID_STATE] = QDF_TRACE_LEVEL_NONE,
3240 		[QDF_MODULE_ID_OUTPUT] = QDF_TRACE_LEVEL_NONE,
3241 		[QDF_MODULE_ID_SCAN] = QDF_TRACE_LEVEL_ERROR,
3242 		[QDF_MODULE_ID_AUTH] = QDF_TRACE_LEVEL_NONE,
3243 		[QDF_MODULE_ID_ASSOC] = QDF_TRACE_LEVEL_NONE,
3244 		[QDF_MODULE_ID_NODE] = QDF_TRACE_LEVEL_NONE,
3245 		[QDF_MODULE_ID_ELEMID] = QDF_TRACE_LEVEL_NONE,
3246 		[QDF_MODULE_ID_XRATE] = QDF_TRACE_LEVEL_NONE,
3247 		[QDF_MODULE_ID_INPUT] = QDF_TRACE_LEVEL_NONE,
3248 		[QDF_MODULE_ID_CRYPTO] = QDF_TRACE_LEVEL_NONE,
3249 		[QDF_MODULE_ID_DUMPPKTS] = QDF_TRACE_LEVEL_NONE,
3250 		[QDF_MODULE_ID_DEBUG] = QDF_TRACE_LEVEL_NONE,
3251 		[QDF_MODULE_ID_MLME] = QDF_TRACE_LEVEL_NONE,
3252 		[QDF_MODULE_ID_RRM] = QDF_TRACE_LEVEL_NONE,
3253 		[QDF_MODULE_ID_WNM] = QDF_TRACE_LEVEL_NONE,
3254 		[QDF_MODULE_ID_P2P_PROT] = QDF_TRACE_LEVEL_NONE,
3255 		[QDF_MODULE_ID_PROXYARP] = QDF_TRACE_LEVEL_NONE,
3256 		[QDF_MODULE_ID_L2TIF] = QDF_TRACE_LEVEL_NONE,
3257 		[QDF_MODULE_ID_WIFIPOS] = QDF_TRACE_LEVEL_NONE,
3258 		[QDF_MODULE_ID_WRAP] = QDF_TRACE_LEVEL_NONE,
3259 		[QDF_MODULE_ID_DFS] = QDF_TRACE_LEVEL_NONE,
3260 		[QDF_MODULE_ID_ATF] = QDF_TRACE_LEVEL_ERROR,
3261 		[QDF_MODULE_ID_SPLITMAC] = QDF_TRACE_LEVEL_NONE,
3262 		[QDF_MODULE_ID_IOCTL] = QDF_TRACE_LEVEL_NONE,
3263 		[QDF_MODULE_ID_NAC] = QDF_TRACE_LEVEL_NONE,
3264 		[QDF_MODULE_ID_MESH] = QDF_TRACE_LEVEL_NONE,
3265 		[QDF_MODULE_ID_MBO] = QDF_TRACE_LEVEL_NONE,
3266 		[QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = QDF_TRACE_LEVEL_NONE,
3267 		[QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = QDF_TRACE_LEVEL_NONE,
3268 		[QDF_MODULE_ID_TLSHIM] = QDF_TRACE_LEVEL_NONE,
3269 		[QDF_MODULE_ID_WMI] = QDF_TRACE_LEVEL_NONE,
3270 		[QDF_MODULE_ID_HTT] = QDF_TRACE_LEVEL_NONE,
3271 		[QDF_MODULE_ID_HDD] = QDF_TRACE_LEVEL_NONE,
3272 		[QDF_MODULE_ID_SME] = QDF_TRACE_LEVEL_NONE,
3273 		[QDF_MODULE_ID_PE] = QDF_TRACE_LEVEL_NONE,
3274 		[QDF_MODULE_ID_WMA] = QDF_TRACE_LEVEL_NONE,
3275 		[QDF_MODULE_ID_SYS] = QDF_TRACE_LEVEL_NONE,
3276 		[QDF_MODULE_ID_QDF] = QDF_TRACE_LEVEL_ERROR,
3277 		[QDF_MODULE_ID_SAP] = QDF_TRACE_LEVEL_NONE,
3278 		[QDF_MODULE_ID_HDD_SOFTAP] = QDF_TRACE_LEVEL_NONE,
3279 		[QDF_MODULE_ID_HDD_DATA] = QDF_TRACE_LEVEL_NONE,
3280 		[QDF_MODULE_ID_HDD_SAP_DATA] = QDF_TRACE_LEVEL_NONE,
3281 		[QDF_MODULE_ID_HIF] = QDF_TRACE_LEVEL_ERROR,
3282 		[QDF_MODULE_ID_HTC] = QDF_TRACE_LEVEL_NONE,
3283 		[QDF_MODULE_ID_TXRX] = QDF_TRACE_LEVEL_NONE,
3284 		[QDF_MODULE_ID_QDF_DEVICE] = QDF_TRACE_LEVEL_NONE,
3285 		[QDF_MODULE_ID_CFG] = QDF_TRACE_LEVEL_NONE,
3286 		[QDF_MODULE_ID_BMI] = QDF_TRACE_LEVEL_NONE,
3287 		[QDF_MODULE_ID_EPPING] = QDF_TRACE_LEVEL_NONE,
3288 		[QDF_MODULE_ID_QVIT] = QDF_TRACE_LEVEL_NONE,
3289 		[QDF_MODULE_ID_DP] = QDF_TRACE_LEVEL_FATAL,
3290 		[QDF_MODULE_ID_HAL] = QDF_TRACE_LEVEL_NONE,
3291 		[QDF_MODULE_ID_SOC] = QDF_TRACE_LEVEL_NONE,
3292 		[QDF_MODULE_ID_OS_IF] = QDF_TRACE_LEVEL_NONE,
3293 		[QDF_MODULE_ID_TARGET_IF] = QDF_TRACE_LEVEL_INFO,
3294 		[QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_NONE,
3295 		[QDF_MODULE_ID_MGMT_TXRX] = QDF_TRACE_LEVEL_NONE,
3296 		[QDF_MODULE_ID_SERIALIZATION] = QDF_TRACE_LEVEL_NONE,
3297 		[QDF_MODULE_ID_PMO] = QDF_TRACE_LEVEL_NONE,
3298 		[QDF_MODULE_ID_P2P] = QDF_TRACE_LEVEL_NONE,
3299 		[QDF_MODULE_ID_POLICY_MGR] = QDF_TRACE_LEVEL_NONE,
3300 		[QDF_MODULE_ID_CONFIG] = QDF_TRACE_LEVEL_ERROR,
3301 		[QDF_MODULE_ID_REGULATORY] = QDF_TRACE_LEVEL_NONE,
3302 		[QDF_MODULE_ID_SA_API] = QDF_TRACE_LEVEL_NONE,
3303 		[QDF_MODULE_ID_NAN] = QDF_TRACE_LEVEL_NONE,
3304 		[QDF_MODULE_ID_OFFCHAN_TXRX] = QDF_TRACE_LEVEL_NONE,
3305 		[QDF_MODULE_ID_SON] = QDF_TRACE_LEVEL_NONE,
3306 		[QDF_MODULE_ID_SPECTRAL] = QDF_TRACE_LEVEL_NONE,
3307 		[QDF_MODULE_ID_OBJ_MGR] = QDF_TRACE_LEVEL_FATAL,
3308 		[QDF_MODULE_ID_NSS] = QDF_TRACE_LEVEL_ERROR,
3309 		[QDF_MODULE_ID_ROAM_DEBUG] = QDF_TRACE_LEVEL_ERROR,
3310 		[QDF_MODULE_ID_CDP] = QDF_TRACE_LEVEL_NONE,
3311 		[QDF_MODULE_ID_DIRECT_BUF_RX] = QDF_TRACE_LEVEL_ERROR,
3312 		[QDF_MODULE_ID_DISA] = QDF_TRACE_LEVEL_NONE,
3313 		[QDF_MODULE_ID_GREEN_AP] = QDF_TRACE_LEVEL_ERROR,
3314 		[QDF_MODULE_ID_FTM] = QDF_TRACE_LEVEL_ERROR,
3315 		[QDF_MODULE_ID_EXTAP] = QDF_TRACE_LEVEL_NONE,
3316 		[QDF_MODULE_ID_FD] = QDF_TRACE_LEVEL_ERROR,
3317 		[QDF_MODULE_ID_OCB] = QDF_TRACE_LEVEL_ERROR,
3318 		[QDF_MODULE_ID_IPA] = QDF_TRACE_LEVEL_NONE,
3319 		[QDF_MODULE_ID_ACTION_OUI] = QDF_TRACE_LEVEL_NONE,
3320 		[QDF_MODULE_ID_CP_STATS] = QDF_TRACE_LEVEL_ERROR,
3321 		[QDF_MODULE_ID_MBSSIE] = QDF_TRACE_LEVEL_INFO,
3322 		[QDF_MODULE_ID_FWOL] = QDF_TRACE_LEVEL_NONE,
3323 		[QDF_MODULE_ID_SM_ENGINE] = QDF_TRACE_LEVEL_DEBUG,
3324 		[QDF_MODULE_ID_CMN_MLME] = QDF_TRACE_LEVEL_INFO,
3325 		[QDF_MODULE_ID_BSSCOLOR] = QDF_TRACE_LEVEL_ERROR,
3326 		[QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO,
3327 	};
3328 
3329 	for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3330 		cinfo[i].category_verbose_mask = set_cumulative_verbose_mask(
3331 				module_trace_default_level[i]);
3332 	}
3333 }
3334 
3335 void qdf_shared_print_ctrl_init(void)
3336 {
3337 	int i;
3338 	struct category_info cinfo[MAX_SUPPORTED_CATEGORY];
3339 
3340 	set_default_trace_levels(cinfo);
3341 
3342 	/*
3343 	 * User specified across-module single debug level
3344 	 */
3345 	if ((qdf_dbg_mask > 0) && (qdf_dbg_mask <= QDF_TRACE_LEVEL_MAX)) {
3346 		pr_info("User specified module debug level of %d\n",
3347 			qdf_dbg_mask);
3348 		for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3349 			cinfo[i].category_verbose_mask =
3350 			set_cumulative_verbose_mask(qdf_dbg_mask);
3351 		}
3352 	} else {
3353 		pr_info("qdf_dbg_mask value is invalid\n");
3354 		pr_info("Using the default module debug levels instead\n");
3355 	}
3356 
3357 	/*
3358 	 * Module ID-Level specified as array during module load
3359 	 */
3360 	for (i = 0; i < qdf_dbg_arr_cnt; i++) {
3361 		process_qdf_dbg_arr_param(cinfo, i);
3362 	}
3363 	qdf_pidx = qdf_print_ctrl_register(cinfo, NULL, NULL,
3364 			"LOG_SHARED_OBJ");
3365 }
3366 qdf_export_symbol(qdf_shared_print_ctrl_init);
3367 #endif
3368 
3369 QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
3370 						QDF_MODULE_ID category,
3371 						QDF_TRACE_LEVEL verbose,
3372 						bool is_set)
3373 {
3374 	/* Check if index passed is valid */
3375 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3376 		pr_err("%s: Invalid index - %d\n", __func__, idx);
3377 		return QDF_STATUS_E_FAILURE;
3378 	}
3379 
3380 	/* Check if print control object is in use */
3381 	if (!print_ctrl_obj[idx].in_use) {
3382 		pr_err("%s: Invalid print control object\n", __func__);
3383 		return QDF_STATUS_E_FAILURE;
3384 	}
3385 
3386 	/* Check if category passed is valid */
3387 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
3388 		pr_err("%s: Invalid category: %d\n", __func__, category);
3389 		return QDF_STATUS_E_FAILURE;
3390 	}
3391 
3392 	/* Check if verbose mask is valid */
3393 	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
3394 		pr_err("%s: Invalid verbose level %d\n", __func__, verbose);
3395 		return QDF_STATUS_E_FAILURE;
3396 	}
3397 
3398 	if (verbose == QDF_TRACE_LEVEL_ALL) {
3399 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
3400 				0xFFFF;
3401 		return QDF_STATUS_SUCCESS;
3402 	}
3403 
3404 	if (verbose == QDF_TRACE_LEVEL_NONE) {
3405 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
3406 				QDF_TRACE_LEVEL_NONE;
3407 		return QDF_STATUS_SUCCESS;
3408 	}
3409 
3410 	if (!is_set) {
3411 		if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask
3412 		    & QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
3413 			print_ctrl_obj[idx].cat_info[category]
3414 				.category_verbose_mask &=
3415 				~QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
3416 		}
3417 	} else {
3418 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask |=
3419 				QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
3420 	}
3421 
3422 	pr_debug("%s: Print control object %d, Category %d, Verbose level %d\n",
3423 		__func__,
3424 		idx,
3425 		category,
3426 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask);
3427 
3428 	return QDF_STATUS_SUCCESS;
3429 }
3430 qdf_export_symbol(qdf_print_set_category_verbose);
3431 
3432 void qdf_log_dump_at_kernel_level(bool enable)
3433 {
3434 	if (qdf_log_dump_at_kernel_enable == enable) {
3435 		QDF_TRACE_INFO(QDF_MODULE_ID_QDF,
3436 			       "qdf_log_dump_at_kernel_enable is already %d\n",
3437 			       enable);
3438 	}
3439 	qdf_log_dump_at_kernel_enable = enable;
3440 }
3441 
3442 qdf_export_symbol(qdf_log_dump_at_kernel_level);
3443 
3444 bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
3445 {
3446 	QDF_TRACE_LEVEL verbose_mask;
3447 
3448 	/* Check if index passed is valid */
3449 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3450 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3451 		return false;
3452 	}
3453 
3454 	/* Check if print control object is in use */
3455 	if (!print_ctrl_obj[idx].in_use) {
3456 		pr_info("%s: Invalid print control object\n", __func__);
3457 		return false;
3458 	}
3459 
3460 	/* Check if category passed is valid */
3461 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
3462 		pr_info("%s: Invalid category: %d\n", __func__, category);
3463 		return false;
3464 	}
3465 
3466 	verbose_mask =
3467 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask;
3468 
3469 	if (verbose_mask == QDF_TRACE_LEVEL_NONE)
3470 		return false;
3471 	else
3472 		return true;
3473 }
3474 qdf_export_symbol(qdf_print_is_category_enabled);
3475 
3476 bool qdf_print_is_verbose_enabled(unsigned int idx, QDF_MODULE_ID category,
3477 				  QDF_TRACE_LEVEL verbose)
3478 {
3479 	bool verbose_enabled = false;
3480 
3481 	/* Check if index passed is valid */
3482 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3483 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3484 		return verbose_enabled;
3485 	}
3486 
3487 	/* Check if print control object is in use */
3488 	if (!print_ctrl_obj[idx].in_use) {
3489 		pr_info("%s: Invalid print control object\n", __func__);
3490 		return verbose_enabled;
3491 	}
3492 
3493 	/* Check if category passed is valid */
3494 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
3495 		pr_info("%s: Invalid category: %d\n", __func__, category);
3496 		return verbose_enabled;
3497 	}
3498 
3499 	if ((verbose == QDF_TRACE_LEVEL_NONE) ||
3500 	    (verbose >= QDF_TRACE_LEVEL_MAX)) {
3501 		verbose_enabled = false;
3502 	} else if (verbose == QDF_TRACE_LEVEL_ALL) {
3503 		if (print_ctrl_obj[idx].cat_info[category]
3504 					.category_verbose_mask == 0xFFFF)
3505 			verbose_enabled = true;
3506 	} else {
3507 		verbose_enabled =
3508 		(print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
3509 		 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) ? true : false;
3510 	}
3511 
3512 	return verbose_enabled;
3513 }
3514 qdf_export_symbol(qdf_print_is_verbose_enabled);
3515 
3516 #ifdef DBG_LVL_MAC_FILTERING
3517 
3518 QDF_STATUS qdf_print_set_node_flag(unsigned int idx, uint8_t enable)
3519 {
3520 	/* Check if index passed is valid */
3521 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3522 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3523 		return QDF_STATUS_E_FAILURE;
3524 	}
3525 
3526 	/* Check if print control object is in use */
3527 	if (!print_ctrl_obj[idx].in_use) {
3528 		pr_info("%s: Invalid print control object\n", __func__);
3529 		return QDF_STATUS_E_FAILURE;
3530 	}
3531 
3532 	if (enable > 1) {
3533 		pr_info("%s: Incorrect input: Use 1 or 0 to enable or disable\n",
3534 			__func__);
3535 		return QDF_STATUS_E_FAILURE;
3536 	}
3537 
3538 	print_ctrl_obj[idx].dbglvlmac_on = enable;
3539 	pr_info("%s: DbgLVLmac feature %s\n",
3540 		__func__,
3541 		((enable) ? "enabled" : "disabled"));
3542 
3543 	return QDF_STATUS_SUCCESS;
3544 }
3545 qdf_export_symbol(qdf_print_set_node_flag);
3546 
3547 bool qdf_print_get_node_flag(unsigned int idx)
3548 {
3549 	bool node_flag = false;
3550 
3551 	/* Check if index passed is valid */
3552 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3553 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3554 		return node_flag;
3555 	}
3556 
3557 	/* Check if print control object is in use */
3558 	if (!print_ctrl_obj[idx].in_use) {
3559 		pr_info("%s: Invalid print control object\n", __func__);
3560 		return node_flag;
3561 	}
3562 
3563 	if (print_ctrl_obj[idx].dbglvlmac_on)
3564 		node_flag = true;
3565 
3566 	return node_flag;
3567 }
3568 qdf_export_symbol(qdf_print_get_node_flag);
3569 
3570 void qdf_print_clean_node_flag(unsigned int idx)
3571 {
3572 	/* Disable dbglvlmac_on during cleanup */
3573 	print_ctrl_obj[idx].dbglvlmac_on = 0;
3574 }
3575 
3576 #else
3577 
3578 void qdf_print_clean_node_flag(unsigned int idx)
3579 {
3580 	/* No operation in case of no support for DBG_LVL_MAC_FILTERING */
3581 	return;
3582 }
3583 #endif
3584 
3585 void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
3586 		    QDF_TRACE_LEVEL level,
3587 		    char *str_format, ...)
3588 {
3589 	va_list args;
3590 
3591 	/* Generic wrapper API will compile qdf_vprint in order to
3592 	 * log the message. Once QDF converged debug framework is in
3593 	 * place, this will be changed to adapt to the framework, compiling
3594 	 * call to converged tracing API
3595 	 */
3596 	va_start(args, str_format);
3597 	qdf_vprint(str_format, args);
3598 	va_end(args);
3599 }
3600 qdf_export_symbol(QDF_PRINT_INFO);
3601 
3602 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
3603 void qdf_logging_init(void)
3604 {
3605 	wlan_logging_sock_init_svc();
3606 	nl_srv_init(NULL);
3607 	wlan_logging_set_flush_timer(qdf_log_flush_timer_period);
3608 }
3609 
3610 void qdf_logging_exit(void)
3611 {
3612 	nl_srv_exit();
3613 	wlan_logging_sock_deinit_svc();
3614 }
3615 
3616 int qdf_logging_set_flush_timer(uint32_t milliseconds)
3617 {
3618 	if (wlan_logging_set_flush_timer(milliseconds) == 0)
3619 		return QDF_STATUS_SUCCESS;
3620 	else
3621 		return QDF_STATUS_E_FAILURE;
3622 }
3623 
3624 void qdf_logging_flush_logs(void)
3625 {
3626 	wlan_flush_host_logs_for_fatal();
3627 }
3628 
3629 #else
3630 void qdf_logging_init(void)
3631 {
3632 	nl_srv_init(NULL);
3633 }
3634 
3635 void qdf_logging_exit(void)
3636 {
3637 	nl_srv_exit();
3638 }
3639 
3640 int qdf_logging_set_flush_timer(uint32_t milliseconds)
3641 {
3642 	return QDF_STATUS_E_FAILURE;
3643 }
3644 
3645 void qdf_logging_flush_logs(void)
3646 {
3647 }
3648 #endif
3649 
3650 qdf_export_symbol(qdf_logging_set_flush_timer);
3651 qdf_export_symbol(qdf_logging_flush_logs);
3652 
3653 #ifdef CONFIG_KALLSYMS
3654 inline int qdf_sprint_symbol(char *buffer, void *addr)
3655 {
3656 	return sprint_symbol(buffer, (unsigned long)addr);
3657 }
3658 #else
3659 int qdf_sprint_symbol(char *buffer, void *addr)
3660 {
3661 	if (!buffer)
3662 		return 0;
3663 
3664 	buffer[0] = '\0';
3665 	return 1;
3666 }
3667 #endif
3668 qdf_export_symbol(qdf_sprint_symbol);
3669 
3670 void qdf_set_pidx(int pidx)
3671 {
3672 	qdf_pidx = pidx;
3673 }
3674 qdf_export_symbol(qdf_set_pidx);
3675 
3676 int qdf_get_pidx(void)
3677 {
3678 	return qdf_pidx;
3679 }
3680 qdf_export_symbol(qdf_get_pidx);
3681 
3682 #ifdef PANIC_ON_BUG
3683 #ifdef CONFIG_SLUB_DEBUG
3684 void __qdf_bug(void)
3685 {
3686 	BUG();
3687 }
3688 qdf_export_symbol(__qdf_bug);
3689 #endif /* CONFIG_SLUB_DEBUG */
3690 #endif /* PANIC_ON_BUG */
3691 
3692