xref: /wlan-driver/qca-wifi-host-cmn/qdf/linux/src/qdf_trace.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1 /*
2  * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  *  DOC:  qdf_trace
22  *  QCA driver framework (QDF) trace APIs
23  *  Trace, logging, and debugging definitions and APIs
24  */
25 
26 /* Include Files */
27 #include "qdf_str.h"
28 #include <qdf_trace.h>
29 #include <qdf_parse.h>
30 #include <qdf_module.h>
31 #include <qdf_util.h>
32 #include <qdf_mem.h>
33 #include <qdf_list.h>
34 
35 /* macro to map qdf trace levels into the bitmask */
36 #define QDF_TRACE_LEVEL_TO_MODULE_BITMASK(_level) ((1 << (_level)))
37 
38 #include <wlan_logging_sock_svc.h>
39 #include <qdf_module.h>
40 static int qdf_pidx = -1;
41 static bool qdf_log_dump_at_kernel_enable = true;
42 qdf_declare_param(qdf_log_dump_at_kernel_enable, bool);
43 
44 /* This value of 0 will disable the timer by default. */
45 static uint32_t qdf_log_flush_timer_period;
46 qdf_declare_param(qdf_log_flush_timer_period, uint);
47 
48 #include "qdf_time.h"
49 #include "qdf_mc_timer.h"
50 #include <host_diag_core_log.h>
51 
52 #ifdef CONNECTIVITY_DIAG_EVENT
53 #include <wlan_connectivity_logging.h>
54 #include "i_host_diag_core_event.h"
55 #endif
56 
57 #ifdef WLAN_CHIPSET_STATS
58 #include "wlan_cp_stats_chipset_stats.h"
59 #endif
60 /* Global qdf print id */
61 
62 /* Preprocessor definitions and constants */
63 
64 enum qdf_timestamp_unit qdf_log_timestamp_type = QDF_LOG_TIMESTAMP_UNIT;
65 
66 #define DP_TRACE_META_DATA_STRLEN 50
67 
68 #ifdef TRACE_RECORD
69 /* Static and Global variables */
70 static spinlock_t ltrace_lock;
71 /* global qdf trace data */
72 static t_qdf_trace_data g_qdf_trace_data;
73 /*
74  * all the call back functions for dumping MTRACE messages from ring buffer
75  * are stored in qdf_trace_cb_table,these callbacks are initialized during init
76  * only so, we will make a copy of these call back functions and maintain in to
77  * qdf_trace_restore_cb_table. Incase if we make modifications to
78  * qdf_trace_cb_table, we can certainly retrieve all the call back functions
79  * back from Restore Table
80  */
81 static tp_qdf_trace_cb qdf_trace_cb_table[QDF_MODULE_ID_MAX];
82 static tp_qdf_trace_cb qdf_trace_restore_cb_table[QDF_MODULE_ID_MAX];
83 
84 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
85 static qdf_trace_record_t *g_qdf_trace_tbl;
86 #else
87 static qdf_trace_record_t g_qdf_trace_tbl[MAX_QDF_TRACE_RECORDS];
88 #endif
89 
90 #endif
91 
92 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
93 static tp_qdf_state_info_cb qdf_state_info_table[QDF_MODULE_ID_MAX];
94 #endif
95 
96 #ifdef CONFIG_DP_TRACE
97 /* Static and Global variables */
98 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
99 static struct qdf_dp_trace_record_s *g_qdf_dp_trace_tbl;
100 #else
101 static struct qdf_dp_trace_record_s
102 			g_qdf_dp_trace_tbl[MAX_QDF_DP_TRACE_RECORDS];
103 #endif
104 static spinlock_t l_dp_trace_lock;
105 
106 /*
107  * all the options to configure/control DP trace are
108  * defined in this structure
109  */
110 static struct s_qdf_dp_trace_data g_qdf_dp_trace_data;
111 /*
112  * all the call back functions for dumping DPTRACE messages from ring buffer
113  * are stored in qdf_dp_trace_cb_table, callbacks are initialized during init
114  */
115 static tp_qdf_dp_trace_cb qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX + 1];
116 #endif
117 
118 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
119 #define QDF_PARAM_STR_LENGTH 40
120 
121 enum qdf_num_module_param {
122 	MEM_DEBUG_DISABLED,
123 	QDF_DBG_MASK,
124 	PREALLOC_DISABLED,
125 	QDF_LOG_DUMP_AT_KERNEL_ENABLE,
126 	QDF_DBG_ARR,
127 	QDF_LOG_FLUSH_TIMER_PERIOD,
128 	QDF_PARAM_MAX,
129 };
130 
131 static char qdf_module_param[QDF_PARAM_MAX][QDF_PARAM_STR_LENGTH] = {
132 	"mem_debug_disabled",
133 	"qdf_dbg_mask",
134 	"prealloc_disabled",
135 	"qdf_log_dump_at_kernel_enable",
136 	"qdf_dbg_arr",
137 	"qdf_log_flush_timer_period",
138 };
139 #endif
140 
qdf_snprintf(char * str_buffer,unsigned int size,char * str_format,...)141 int qdf_snprintf(char *str_buffer, unsigned int size, char *str_format, ...)
142 {
143 	va_list args;
144 	int i;
145 
146 	va_start(args, str_format);
147 	i = vsnprintf(str_buffer, size, str_format, args);
148 	va_end(args);
149 
150 	return i;
151 }
152 qdf_export_symbol(qdf_snprintf);
153 
154 #ifdef QDF_ENABLE_TRACING
155 
qdf_trace_msg(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,const char * str_format,...)156 void qdf_trace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
157 		   const char *str_format, ...)
158 {
159 	va_list val;
160 
161 	va_start(val, str_format);
162 	qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
163 	va_end(val);
164 }
165 qdf_export_symbol(qdf_trace_msg);
166 
qdf_vtrace_msg(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,const char * str_format,va_list val)167 void qdf_vtrace_msg(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
168 		    const char *str_format, va_list val)
169 {
170 	qdf_trace_msg_cmn(qdf_pidx, module, level, str_format, val);
171 }
172 qdf_export_symbol(qdf_vtrace_msg);
173 
174 #define ROW_SIZE 16
175 /* Buffer size = data bytes(2 hex chars plus space) + NULL */
176 #define BUFFER_SIZE ((QDF_DP_TRACE_RECORD_SIZE * 3) + 1)
177 
__qdf_trace_hex_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len,bool print_ascii)178 static void __qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
179 				 void *data, int buf_len, bool print_ascii)
180 {
181 	const u8 *ptr = data;
182 	int i = 0;
183 
184 	if (!qdf_print_is_verbose_enabled(qdf_pidx, module, level))
185 		return;
186 
187 	while (buf_len > 0) {
188 		unsigned char linebuf[BUFFER_SIZE] = {0};
189 		int linelen = min(buf_len, ROW_SIZE);
190 
191 		buf_len -= ROW_SIZE;
192 
193 		hex_dump_to_buffer(ptr, linelen, ROW_SIZE, 1,
194 				   linebuf, sizeof(linebuf), print_ascii);
195 
196 		qdf_trace_msg(module, level, "%.8x: %s", i, linebuf);
197 		ptr += ROW_SIZE;
198 		i += ROW_SIZE;
199 	}
200 }
201 
qdf_trace_hex_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len)202 void qdf_trace_hex_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
203 			void *data, int buf_len)
204 {
205 	__qdf_trace_hex_dump(module, level, data, buf_len, false);
206 }
207 
208 qdf_export_symbol(qdf_trace_hex_dump);
209 
qdf_trace_hex_ascii_dump(QDF_MODULE_ID module,QDF_TRACE_LEVEL level,void * data,int buf_len)210 void qdf_trace_hex_ascii_dump(QDF_MODULE_ID module, QDF_TRACE_LEVEL level,
211 			      void *data, int buf_len)
212 {
213 	__qdf_trace_hex_dump(module, level, data, buf_len, true);
214 }
215 
216 qdf_export_symbol(qdf_trace_hex_ascii_dump);
217 
218 #endif
219 
220 #ifdef TRACE_RECORD
221 
222 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
allocate_g_qdf_trace_tbl_buffer(void)223 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
224 {
225 	g_qdf_trace_tbl = qdf_mem_valloc(MAX_QDF_TRACE_RECORDS *
226 					 sizeof(*g_qdf_trace_tbl));
227 	QDF_BUG(g_qdf_trace_tbl);
228 	return g_qdf_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
229 }
230 
free_g_qdf_trace_tbl_buffer(void)231 static inline void free_g_qdf_trace_tbl_buffer(void)
232 {
233 	qdf_mem_vfree(g_qdf_trace_tbl);
234 	g_qdf_trace_tbl = NULL;
235 }
236 #else
allocate_g_qdf_trace_tbl_buffer(void)237 static inline QDF_STATUS allocate_g_qdf_trace_tbl_buffer(void)
238 {
239 	return QDF_STATUS_SUCCESS;
240 }
241 
free_g_qdf_trace_tbl_buffer(void)242 static inline void free_g_qdf_trace_tbl_buffer(void)
243 { }
244 #endif
qdf_trace_enable(uint32_t bitmask_of_module_id,uint8_t enable)245 void qdf_trace_enable(uint32_t bitmask_of_module_id, uint8_t enable)
246 {
247 	int i;
248 
249 	if (bitmask_of_module_id) {
250 		for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
251 			if (((bitmask_of_module_id >> i) & 1)) {
252 				if (enable) {
253 					if (NULL !=
254 					    qdf_trace_restore_cb_table[i]) {
255 						qdf_trace_cb_table[i] =
256 						qdf_trace_restore_cb_table[i];
257 					}
258 				} else {
259 					qdf_trace_restore_cb_table[i] =
260 						qdf_trace_cb_table[i];
261 					qdf_trace_cb_table[i] = NULL;
262 				}
263 			}
264 		}
265 	} else {
266 		if (enable) {
267 			for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
268 				if (qdf_trace_restore_cb_table[i]) {
269 					qdf_trace_cb_table[i] =
270 						qdf_trace_restore_cb_table[i];
271 				}
272 			}
273 		} else {
274 			for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
275 				qdf_trace_restore_cb_table[i] =
276 					qdf_trace_cb_table[i];
277 				qdf_trace_cb_table[i] = NULL;
278 			}
279 		}
280 	}
281 }
282 qdf_export_symbol(qdf_trace_enable);
283 
qdf_trace_init(void)284 void qdf_trace_init(void)
285 {
286 	uint8_t i;
287 
288 	if (allocate_g_qdf_trace_tbl_buffer() != QDF_STATUS_SUCCESS)
289 		return;
290 	g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
291 	g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
292 	g_qdf_trace_data.num = 0;
293 	g_qdf_trace_data.enable = true;
294 	g_qdf_trace_data.dump_count = DEFAULT_QDF_TRACE_DUMP_COUNT;
295 	g_qdf_trace_data.num_since_last_dump = 0;
296 
297 	for (i = 0; i < QDF_MODULE_ID_MAX; i++) {
298 		qdf_trace_cb_table[i] = NULL;
299 		qdf_trace_restore_cb_table[i] = NULL;
300 	}
301 }
302 qdf_export_symbol(qdf_trace_init);
303 
qdf_trace_deinit(void)304 void qdf_trace_deinit(void)
305 {
306 	g_qdf_trace_data.enable = false;
307 	g_qdf_trace_data.num = 0;
308 	g_qdf_trace_data.head = INVALID_QDF_TRACE_ADDR;
309 	g_qdf_trace_data.tail = INVALID_QDF_TRACE_ADDR;
310 
311 	free_g_qdf_trace_tbl_buffer();
312 }
313 
314 qdf_export_symbol(qdf_trace_deinit);
315 
qdf_trace(uint8_t module,uint16_t code,uint16_t session,uint32_t data)316 void qdf_trace(uint8_t module, uint16_t code, uint16_t session, uint32_t data)
317 {
318 	tp_qdf_trace_record rec = NULL;
319 	unsigned long flags;
320 	char time[18];
321 
322 	if (!g_qdf_trace_data.enable)
323 		return;
324 
325 	/* if module is not registered, don't record for that module */
326 	if (!qdf_trace_cb_table[module])
327 		return;
328 
329 	qdf_get_time_of_the_day_in_hr_min_sec_usec(time, sizeof(time));
330 	/* Acquire the lock so that only one thread at a time can fill the ring
331 	 * buffer
332 	 */
333 	spin_lock_irqsave(&ltrace_lock, flags);
334 
335 	g_qdf_trace_data.num++;
336 
337 	if (g_qdf_trace_data.num > MAX_QDF_TRACE_RECORDS)
338 		g_qdf_trace_data.num = MAX_QDF_TRACE_RECORDS;
339 
340 	if (INVALID_QDF_TRACE_ADDR == g_qdf_trace_data.head) {
341 		/* first record */
342 		g_qdf_trace_data.head = 0;
343 		g_qdf_trace_data.tail = 0;
344 	} else {
345 		/* queue is not empty */
346 		uint32_t tail = g_qdf_trace_data.tail + 1;
347 
348 		if (MAX_QDF_TRACE_RECORDS == tail)
349 			tail = 0;
350 
351 		if (g_qdf_trace_data.head == tail) {
352 			/* full */
353 			if (MAX_QDF_TRACE_RECORDS == ++g_qdf_trace_data.head)
354 				g_qdf_trace_data.head = 0;
355 		}
356 		g_qdf_trace_data.tail = tail;
357 	}
358 
359 	rec = &g_qdf_trace_tbl[g_qdf_trace_data.tail];
360 	rec->code = code;
361 	rec->session = session;
362 	rec->data = data;
363 	rec->qtime = qdf_get_log_timestamp();
364 	scnprintf(rec->time, sizeof(rec->time), "%s", time);
365 	rec->module = module;
366 	rec->pid = (in_interrupt() ? 0 : current->pid);
367 	g_qdf_trace_data.num_since_last_dump++;
368 	spin_unlock_irqrestore(&ltrace_lock, flags);
369 }
370 qdf_export_symbol(qdf_trace);
371 
372 #ifdef ENABLE_MTRACE_LOG
qdf_mtrace_log(QDF_MODULE_ID src_module,QDF_MODULE_ID dst_module,uint16_t message_id,uint8_t vdev_id)373 void qdf_mtrace_log(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
374 		    uint16_t message_id, uint8_t vdev_id)
375 {
376 	uint32_t trace_log, payload;
377 	static uint16_t counter;
378 
379 	trace_log = (src_module << 23) | (dst_module << 15) | message_id;
380 	payload = (vdev_id << 16) | counter++;
381 
382 	QDF_TRACE(src_module, QDF_TRACE_LEVEL_TRACE, "%x %x",
383 		  trace_log, payload);
384 }
385 
386 qdf_export_symbol(qdf_mtrace_log);
387 #endif
388 
qdf_mtrace(QDF_MODULE_ID src_module,QDF_MODULE_ID dst_module,uint16_t message_id,uint8_t vdev_id,uint32_t data)389 void qdf_mtrace(QDF_MODULE_ID src_module, QDF_MODULE_ID dst_module,
390 		uint16_t message_id, uint8_t vdev_id, uint32_t data)
391 {
392 	qdf_trace(src_module, message_id, vdev_id, data);
393 	qdf_mtrace_log(src_module, dst_module, message_id, vdev_id);
394 }
395 
396 qdf_export_symbol(qdf_mtrace);
397 
qdf_trace_spin_lock_init(void)398 QDF_STATUS qdf_trace_spin_lock_init(void)
399 {
400 	spin_lock_init(&ltrace_lock);
401 
402 	return QDF_STATUS_SUCCESS;
403 }
404 qdf_export_symbol(qdf_trace_spin_lock_init);
405 
qdf_trace_register(QDF_MODULE_ID module_id,tp_qdf_trace_cb qdf_trace_callback)406 void qdf_trace_register(QDF_MODULE_ID module_id,
407 			tp_qdf_trace_cb qdf_trace_callback)
408 {
409 	qdf_trace_cb_table[module_id] = qdf_trace_callback;
410 }
411 qdf_export_symbol(qdf_trace_register);
412 
qdf_trace_dump_all(void * p_mac,uint8_t code,uint8_t session,uint32_t count,uint32_t bitmask_of_module)413 void qdf_trace_dump_all(void *p_mac, uint8_t code, uint8_t session,
414 	uint32_t count, uint32_t bitmask_of_module)
415 {
416 	qdf_trace_record_t p_record;
417 	int32_t i, tail;
418 
419 	if (!g_qdf_trace_data.enable) {
420 		QDF_TRACE(QDF_MODULE_ID_SYS,
421 			  QDF_TRACE_LEVEL_ERROR, "Tracing Disabled");
422 		return;
423 	}
424 
425 	QDF_TRACE(QDF_MODULE_ID_SYS, QDF_TRACE_LEVEL_INFO,
426 		  "DPT: Total Records: %d, Head: %d, Tail: %d",
427 		  g_qdf_trace_data.num, g_qdf_trace_data.head,
428 		  g_qdf_trace_data.tail);
429 
430 	/* acquire the lock so that only one thread at a time can read
431 	 * the ring buffer
432 	 */
433 	spin_lock(&ltrace_lock);
434 
435 	if (g_qdf_trace_data.head != INVALID_QDF_TRACE_ADDR) {
436 		i = g_qdf_trace_data.head;
437 		tail = g_qdf_trace_data.tail;
438 
439 		if (count) {
440 			if (count > g_qdf_trace_data.num)
441 				count = g_qdf_trace_data.num;
442 			if (tail >= (count - 1))
443 				i = tail - count + 1;
444 			else if (count != MAX_QDF_TRACE_RECORDS)
445 				i = MAX_QDF_TRACE_RECORDS - ((count - 1) -
446 							     tail);
447 		}
448 
449 		p_record = g_qdf_trace_tbl[i];
450 		/* right now we are not using num_since_last_dump member but
451 		 * in future we might re-visit and use this member to track
452 		 * how many latest messages got added while we were dumping
453 		 * from ring buffer
454 		 */
455 		g_qdf_trace_data.num_since_last_dump = 0;
456 		spin_unlock(&ltrace_lock);
457 		for (;; ) {
458 			if ((code == 0 || (code == p_record.code)) &&
459 			    (qdf_trace_cb_table[p_record.module])) {
460 				if (0 == bitmask_of_module) {
461 					qdf_trace_cb_table[p_record.
462 							   module] (p_mac,
463 								    &p_record,
464 								    (uint16_t)
465 								    i);
466 				} else {
467 					if (bitmask_of_module &
468 					    (1 << p_record.module)) {
469 						qdf_trace_cb_table[p_record.
470 								   module]
471 							(p_mac, &p_record,
472 							(uint16_t) i);
473 					}
474 				}
475 			}
476 
477 			if (i == tail)
478 				break;
479 			i += 1;
480 
481 			spin_lock(&ltrace_lock);
482 			if (MAX_QDF_TRACE_RECORDS == i) {
483 				i = 0;
484 				p_record = g_qdf_trace_tbl[0];
485 			} else {
486 				p_record = g_qdf_trace_tbl[i];
487 			}
488 			spin_unlock(&ltrace_lock);
489 		}
490 	} else {
491 		spin_unlock(&ltrace_lock);
492 	}
493 }
494 qdf_export_symbol(qdf_trace_dump_all);
495 #endif
496 
497 #ifdef WLAN_FEATURE_MEMDUMP_ENABLE
qdf_register_debugcb_init(void)498 void qdf_register_debugcb_init(void)
499 {
500 	uint8_t i;
501 
502 	for (i = 0; i < QDF_MODULE_ID_MAX; i++)
503 		qdf_state_info_table[i] = NULL;
504 }
505 qdf_export_symbol(qdf_register_debugcb_init);
506 
qdf_register_debug_callback(QDF_MODULE_ID module_id,tp_qdf_state_info_cb qdf_state_infocb)507 void qdf_register_debug_callback(QDF_MODULE_ID module_id,
508 					tp_qdf_state_info_cb qdf_state_infocb)
509 {
510 	qdf_state_info_table[module_id] = qdf_state_infocb;
511 }
512 qdf_export_symbol(qdf_register_debug_callback);
513 
qdf_state_info_dump_all(char * buf,uint16_t size,uint16_t * driver_dump_size)514 QDF_STATUS qdf_state_info_dump_all(char *buf, uint16_t size,
515 				   uint16_t *driver_dump_size)
516 {
517 	uint8_t module, ret = QDF_STATUS_SUCCESS;
518 	uint16_t buf_len = size;
519 	char *buf_ptr = buf;
520 
521 	for (module = 0; module < QDF_MODULE_ID_MAX; module++) {
522 		if (qdf_state_info_table[module]) {
523 			qdf_state_info_table[module](&buf_ptr, &buf_len);
524 			if (!buf_len) {
525 				ret = QDF_STATUS_E_NOMEM;
526 				break;
527 			}
528 		}
529 	}
530 
531 	*driver_dump_size = size - buf_len;
532 	return ret;
533 }
534 qdf_export_symbol(qdf_state_info_dump_all);
535 #endif
536 
537 #ifdef CONFIG_DP_TRACE
538 
539 #ifdef WLAN_LOGGING_BUFFERS_DYNAMICALLY
allocate_g_qdf_dp_trace_tbl_buffer(void)540 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
541 {
542 	g_qdf_dp_trace_tbl = qdf_mem_valloc(MAX_QDF_DP_TRACE_RECORDS *
543 					    sizeof(*g_qdf_dp_trace_tbl));
544 	QDF_BUG(g_qdf_dp_trace_tbl);
545 	return g_qdf_dp_trace_tbl ? QDF_STATUS_SUCCESS : QDF_STATUS_E_NOMEM;
546 }
547 
free_g_qdf_dp_trace_tbl_buffer(void)548 static inline void free_g_qdf_dp_trace_tbl_buffer(void)
549 {
550 	qdf_mem_vfree(g_qdf_dp_trace_tbl);
551 	g_qdf_dp_trace_tbl = NULL;
552 }
553 #else
allocate_g_qdf_dp_trace_tbl_buffer(void)554 static inline QDF_STATUS allocate_g_qdf_dp_trace_tbl_buffer(void)
555 {
556 	return QDF_STATUS_SUCCESS;
557 }
558 
free_g_qdf_dp_trace_tbl_buffer(void)559 static inline void free_g_qdf_dp_trace_tbl_buffer(void)
560 { }
561 #endif
562 
563 #define QDF_DP_TRACE_PREPEND_STR_SIZE 100
564 /*
565  * one dp trace record can't be greater than 300 bytes.
566  * Max Size will be QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
567  * Always make sure to change this QDF_DP_TRACE_MAX_RECORD_SIZE
568  * value accordingly whenever above two mentioned MACRO value changes.
569  */
570 #define QDF_DP_TRACE_MAX_RECORD_SIZE 300
571 
qdf_dp_unused(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)572 static void qdf_dp_unused(struct qdf_dp_trace_record_s *record,
573 			  uint16_t index, uint8_t pdev_id, uint8_t info)
574 {
575 	qdf_print("%s: QDF_DP_TRACE_MAX event should not be generated",
576 		  __func__);
577 }
578 
qdf_dp_trace_init(bool live_mode_config,uint8_t thresh,uint16_t time_limit,uint8_t verbosity,uint32_t proto_bitmap)579 void qdf_dp_trace_init(bool live_mode_config, uint8_t thresh,
580 				uint16_t time_limit, uint8_t verbosity,
581 				uint32_t proto_bitmap)
582 {
583 	uint8_t i;
584 
585 	if (allocate_g_qdf_dp_trace_tbl_buffer() != QDF_STATUS_SUCCESS) {
586 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
587 				"Failed!!! DP Trace buffer allocation");
588 		return;
589 	}
590 	qdf_dp_trace_spin_lock_init();
591 	qdf_dp_trace_clear_buffer();
592 	g_qdf_dp_trace_data.enable = true;
593 	g_qdf_dp_trace_data.no_of_record = 1;
594 
595 	g_qdf_dp_trace_data.live_mode_config = live_mode_config;
596 	g_qdf_dp_trace_data.live_mode = live_mode_config;
597 	g_qdf_dp_trace_data.high_tput_thresh = thresh;
598 	g_qdf_dp_trace_data.thresh_time_limit = time_limit;
599 	g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
600 	g_qdf_dp_trace_data.verbosity = verbosity;
601 	g_qdf_dp_trace_data.ini_conf_verbosity = verbosity;
602 
603 	for (i = 0; i < ARRAY_SIZE(qdf_dp_trace_cb_table); i++)
604 		qdf_dp_trace_cb_table[i] = qdf_dp_display_record;
605 
606 	qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_TX_PACKET_RECORD] =
607 		qdf_dp_trace_cb_table[QDF_DP_TRACE_HDD_RX_PACKET_RECORD] =
608 		qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_PACKET_RECORD] =
609 		qdf_dp_trace_cb_table[QDF_DP_TRACE_RX_PACKET_RECORD] =
610 		qdf_dp_trace_cb_table[QDF_DP_TRACE_DROP_PACKET_RECORD] =
611 		qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD] =
612 		qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD] =
613 		qdf_dp_display_data_pkt_record;
614 
615 	qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD] =
616 	qdf_dp_trace_cb_table[QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] =
617 	qdf_dp_trace_cb_table[QDF_DP_TRACE_FREE_PACKET_PTR_RECORD] =
618 	qdf_dp_trace_cb_table[QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD] =
619 						qdf_dp_display_ptr_record;
620 	qdf_dp_trace_cb_table[QDF_DP_TRACE_EAPOL_PACKET_RECORD] =
621 	qdf_dp_trace_cb_table[QDF_DP_TRACE_DHCP_PACKET_RECORD] =
622 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ARP_PACKET_RECORD] =
623 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMP_PACKET_RECORD] =
624 	qdf_dp_trace_cb_table[QDF_DP_TRACE_ICMPv6_PACKET_RECORD] =
625 						qdf_dp_display_proto_pkt;
626 	qdf_dp_trace_cb_table[QDF_DP_TRACE_MGMT_PACKET_RECORD] =
627 					qdf_dp_display_mgmt_pkt;
628 	qdf_dp_trace_cb_table[QDF_DP_TRACE_TX_CREDIT_RECORD] =
629 					qdf_dp_display_credit_record;
630 	qdf_dp_trace_cb_table[QDF_DP_TRACE_EVENT_RECORD] =
631 					qdf_dp_display_event_record;
632 
633 	qdf_dp_trace_cb_table[QDF_DP_TRACE_MAX] = qdf_dp_unused;
634 }
635 qdf_export_symbol(qdf_dp_trace_init);
636 
qdf_dp_trace_deinit(void)637 void qdf_dp_trace_deinit(void)
638 {
639 	if (!g_qdf_dp_trace_data.enable)
640 		return;
641 	spin_lock_bh(&l_dp_trace_lock);
642 	g_qdf_dp_trace_data.enable = false;
643 	g_qdf_dp_trace_data.no_of_record = 0;
644 	spin_unlock_bh(&l_dp_trace_lock);
645 
646 	free_g_qdf_dp_trace_tbl_buffer();
647 }
648 
qdf_dp_trace_set_value(uint32_t proto_bitmap,uint8_t no_of_record,uint8_t verbosity)649 void qdf_dp_trace_set_value(uint32_t proto_bitmap, uint8_t no_of_record,
650 			    uint8_t verbosity)
651 {
652 	g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
653 	g_qdf_dp_trace_data.no_of_record = no_of_record;
654 	g_qdf_dp_trace_data.verbosity    = verbosity;
655 	g_qdf_dp_trace_data.dynamic_verbosity_modify = true;
656 }
657 qdf_export_symbol(qdf_dp_trace_set_value);
658 
qdf_dp_trace_set_verbosity(uint32_t val)659 void qdf_dp_trace_set_verbosity(uint32_t val)
660 {
661 	g_qdf_dp_trace_data.verbosity = val;
662 }
663 qdf_export_symbol(qdf_dp_trace_set_verbosity);
664 
665 /**
666  * qdf_dp_get_verbosity() - get verbosity value
667  *
668  * Return: int
669  */
qdf_dp_get_verbosity(void)670 uint8_t qdf_dp_get_verbosity(void)
671 {
672 	return g_qdf_dp_trace_data.verbosity;
673 }
674 qdf_export_symbol(qdf_dp_get_verbosity);
675 
qdf_dp_set_proto_bitmap(uint32_t val)676 void qdf_dp_set_proto_bitmap(uint32_t val)
677 {
678 	g_qdf_dp_trace_data.proto_bitmap = val;
679 }
680 qdf_export_symbol(qdf_dp_set_proto_bitmap);
681 
qdf_dp_set_proto_event_bitmap(uint32_t value)682 void qdf_dp_set_proto_event_bitmap(uint32_t value)
683 {
684 	g_qdf_dp_trace_data.proto_event_bitmap = value;
685 }
686 
687 qdf_export_symbol(qdf_dp_set_proto_event_bitmap);
688 
qdf_dp_get_proto_event_bitmap(void)689 static uint32_t qdf_dp_get_proto_event_bitmap(void)
690 {
691 	return g_qdf_dp_trace_data.proto_event_bitmap;
692 }
693 
qdf_dp_set_no_of_record(uint32_t val)694 void qdf_dp_set_no_of_record(uint32_t val)
695 {
696 	g_qdf_dp_trace_data.no_of_record = val;
697 }
698 qdf_export_symbol(qdf_dp_set_no_of_record);
699 
qdf_dp_get_no_of_record(void)700 uint8_t qdf_dp_get_no_of_record(void)
701 {
702 	return g_qdf_dp_trace_data.no_of_record;
703 }
704 qdf_export_symbol(qdf_dp_get_no_of_record);
705 
706 
707 /**
708  * qdf_dp_trace_verbosity_check() - check whether verbosity level is enabled
709  * @code: defines the event
710  *
711  * In High verbosity all codes are logged.
712  * For Med/Low and Default case code which has
713  * less value than corresponding verbosity codes
714  * are logged.
715  *
716  * Return: true or false depends on whether tracing enabled
717  */
qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code)718 static bool qdf_dp_trace_verbosity_check(enum QDF_DP_TRACE_ID code)
719 {
720 	switch (g_qdf_dp_trace_data.verbosity) {
721 	case QDF_DP_TRACE_VERBOSITY_HIGH:
722 		return true;
723 	case QDF_DP_TRACE_VERBOSITY_MEDIUM:
724 		if (code <= QDF_DP_TRACE_MED_VERBOSITY)
725 			return true;
726 		return false;
727 	case QDF_DP_TRACE_VERBOSITY_LOW:
728 		if (code <= QDF_DP_TRACE_LOW_VERBOSITY)
729 			return true;
730 		return false;
731 	case QDF_DP_TRACE_VERBOSITY_ULTRA_LOW:
732 		if (code <= QDF_DP_TRACE_ULTRA_LOW_VERBOSITY)
733 			return true;
734 		return false;
735 	case QDF_DP_TRACE_VERBOSITY_BASE:
736 		if (code <= QDF_DP_TRACE_BASE_VERBOSITY)
737 			return true;
738 		return false;
739 	default:
740 		return false;
741 	}
742 }
743 
qdf_dp_get_proto_bitmap(void)744 uint32_t qdf_dp_get_proto_bitmap(void)
745 {
746 	if (g_qdf_dp_trace_data.enable)
747 		return g_qdf_dp_trace_data.proto_bitmap;
748 	else
749 		return 0;
750 }
751 
qdf_dp_trace_set_track(qdf_nbuf_t nbuf,enum qdf_proto_dir dir)752 void qdf_dp_trace_set_track(qdf_nbuf_t nbuf, enum qdf_proto_dir dir)
753 {
754 	uint32_t count = 0;
755 
756 	if (!g_qdf_dp_trace_data.enable)
757 		return;
758 
759 	spin_lock_bh(&l_dp_trace_lock);
760 	if (QDF_TX == dir)
761 		count = ++g_qdf_dp_trace_data.tx_count;
762 	else if (QDF_RX == dir)
763 		count = ++g_qdf_dp_trace_data.rx_count;
764 
765 	if ((g_qdf_dp_trace_data.no_of_record != 0) &&
766 		(count % g_qdf_dp_trace_data.no_of_record == 0)) {
767 		if (QDF_TX == dir)
768 			QDF_NBUF_CB_TX_DP_TRACE(nbuf) = 1;
769 		else if (QDF_RX == dir)
770 			QDF_NBUF_CB_RX_DP_TRACE(nbuf) = 1;
771 	}
772 	spin_unlock_bh(&l_dp_trace_lock);
773 }
774 qdf_export_symbol(qdf_dp_trace_set_track);
775 
776 /* Number of bytes to be grouped together while printing DP-Trace data */
777 #define QDF_DUMP_DP_GROUP_SIZE 6
778 
779 /**
780  * dump_dp_hex_trace() - Display the data in buffer
781  * @prepend_str:     string to prepend the hexdump with.
782  * @inbuf:     buffer which contains data to be displayed
783  * @inbuf_len: defines the size of the data to be displayed
784  *
785  * Return: None
786  */
787 static void
dump_dp_hex_trace(char * prepend_str,uint8_t * inbuf,uint8_t inbuf_len)788 dump_dp_hex_trace(char *prepend_str, uint8_t *inbuf, uint8_t inbuf_len)
789 {
790 	unsigned char outbuf[BUFFER_SIZE];
791 	const uint8_t *inbuf_ptr = inbuf;
792 	char *outbuf_ptr = outbuf;
793 	int outbytes_written = 0;
794 
795 	qdf_mem_zero(outbuf, sizeof(outbuf));
796 	do {
797 		outbytes_written += scnprintf(outbuf_ptr,
798 					BUFFER_SIZE - outbytes_written,
799 					"%02x", *inbuf_ptr);
800 		outbuf_ptr = outbuf + outbytes_written;
801 
802 		if ((inbuf_ptr - inbuf) &&
803 		    (inbuf_ptr - inbuf + 1) % QDF_DUMP_DP_GROUP_SIZE == 0) {
804 			outbytes_written += scnprintf(outbuf_ptr,
805 						BUFFER_SIZE - outbytes_written,
806 						" ");
807 			outbuf_ptr = outbuf + outbytes_written;
808 		}
809 		inbuf_ptr++;
810 	} while (inbuf_ptr < (inbuf + inbuf_len));
811 	DPTRACE_PRINT("%s %s", prepend_str, outbuf);
812 }
813 
814 /**
815  * qdf_dp_code_to_string() - convert dptrace code to string
816  * @code: dptrace code
817  *
818  * Return: string version of code
819  */
820 static
qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code)821 const char *qdf_dp_code_to_string(enum QDF_DP_TRACE_ID code)
822 {
823 	switch (code) {
824 	case QDF_DP_TRACE_DROP_PACKET_RECORD:
825 		return "DROP:";
826 	case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
827 		return "EAPOL:";
828 	case QDF_DP_TRACE_DHCP_PACKET_RECORD:
829 		return "DHCP:";
830 	case QDF_DP_TRACE_ARP_PACKET_RECORD:
831 		return "ARP:";
832 	case QDF_DP_TRACE_ICMP_PACKET_RECORD:
833 		return "ICMP:";
834 	case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
835 		return "ICMPv6:";
836 	case QDF_DP_TRACE_MGMT_PACKET_RECORD:
837 		return "MGMT:";
838 	case QDF_DP_TRACE_TX_CREDIT_RECORD:
839 		return "CREDIT:";
840 	case QDF_DP_TRACE_EVENT_RECORD:
841 		return "EVENT:";
842 	case QDF_DP_TRACE_HDD_TX_PACKET_PTR_RECORD:
843 		return "HDD: TX: PTR:";
844 	case QDF_DP_TRACE_LI_DP_TX_PACKET_PTR_RECORD:
845 		return "LI_DP: TX: PTR:";
846 	case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
847 		return "HDD: TX: DATA:";
848 	case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
849 	case QDF_DP_TRACE_TX_PACKET_RECORD:
850 		return "TX:";
851 	case QDF_DP_TRACE_CE_PACKET_PTR_RECORD:
852 		return "CE: TX: PTR:";
853 	case QDF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD:
854 		return "CE: TX: FAST: PTR:";
855 	case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
856 		return "CE: TX: FAST: ERR:";
857 	case QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD:
858 	case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
859 		return "FREE: TX: PTR:";
860 	case QDF_DP_TRACE_RX_HTT_PACKET_PTR_RECORD:
861 		return "HTT: RX: PTR:";
862 	case QDF_DP_TRACE_RX_OFFLOAD_HTT_PACKET_PTR_RECORD:
863 		return "HTT: RX: OF: PTR:";
864 	case QDF_DP_TRACE_RX_HDD_PACKET_PTR_RECORD:
865 		return "HDD: RX: PTR:";
866 	case QDF_DP_TRACE_RX_LI_DP_PACKET_PTR_RECORD:
867 		return "LI_DP: RX: PTR:";
868 	case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
869 		return "HDD: RX: DATA:";
870 	case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
871 		return "LI_DP_NULL: RX: DATA:";
872 	case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
873 	case QDF_DP_TRACE_RX_PACKET_RECORD:
874 		return "RX:";
875 	case QDF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD:
876 		return "TXRX: TX: Q: PTR:";
877 	case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
878 		return "TXRX: TX: PTR:";
879 	case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
880 		return "TXRX: TX: FAST: PTR:";
881 	case QDF_DP_TRACE_HTT_PACKET_PTR_RECORD:
882 		return "HTT: TX: PTR:";
883 	case QDF_DP_TRACE_HTC_PACKET_PTR_RECORD:
884 		return "HTC: TX: PTR:";
885 	case QDF_DP_TRACE_HIF_PACKET_PTR_RECORD:
886 		return "HIF: TX: PTR:";
887 	case QDF_DP_TRACE_RX_TXRX_PACKET_PTR_RECORD:
888 		return "TXRX: RX: PTR:";
889 	case QDF_DP_TRACE_HDD_TX_TIMEOUT:
890 		return "HDD: STA: TO:";
891 	case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
892 		return "HDD: SAP: TO:";
893 	default:
894 		return "Invalid";
895 	}
896 }
897 
898 /**
899  * qdf_dp_dir_to_str() - convert direction to string
900  * @dir: direction
901  *
902  * Return: string version of direction
903  */
qdf_dp_dir_to_str(enum qdf_proto_dir dir)904 static const char *qdf_dp_dir_to_str(enum qdf_proto_dir dir)
905 {
906 	switch (dir) {
907 	case QDF_TX:
908 		return " --> ";
909 	case QDF_RX:
910 		return " <-- ";
911 	default:
912 		return "invalid";
913 	}
914 }
915 
qdf_dp_credit_source_to_str(enum QDF_CREDIT_UPDATE_SOURCE source)916 static const char *qdf_dp_credit_source_to_str(
917 		enum QDF_CREDIT_UPDATE_SOURCE source)
918 {
919 	switch (source) {
920 	case QDF_TX_SCHED:
921 		return "TX SCHED";
922 	case QDF_TX_COMP:
923 		return "TX COMP";
924 	case QDF_TX_CREDIT_UPDATE:
925 		return "CREDIT UP";
926 	case QDF_TX_HTT_MSG:
927 		return "HTT TX MSG";
928 	case QDF_HTT_ATTACH:
929 		return "HTT ATTACH";
930 	default:
931 		return "invalid";
932 	}
933 }
934 
qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op)935 static const char *qdf_dp_operation_to_str(enum QDF_CREDIT_OPERATION op)
936 {
937 	switch (op) {
938 	case QDF_CREDIT_INC:
939 		return "+";
940 	case QDF_CREDIT_DEC:
941 		return "-";
942 	case QDF_CREDIT_ABS:
943 		return "ABS";
944 	default:
945 		return "invalid";
946 	}
947 }
948 
949 /**
950  * qdf_dp_type_to_str() - convert packet type to string
951  * @type: type
952  *
953  * Return: string version of packet type
954  */
qdf_dp_type_to_str(enum qdf_proto_type type)955 static const char *qdf_dp_type_to_str(enum qdf_proto_type type)
956 {
957 	switch (type) {
958 	case QDF_PROTO_TYPE_DHCP:
959 		return "DHCP";
960 	case QDF_PROTO_TYPE_EAPOL:
961 		return "EAPOL";
962 	case QDF_PROTO_TYPE_ARP:
963 		return "ARP";
964 	case QDF_PROTO_TYPE_ICMP:
965 		return "ICMP";
966 	case QDF_PROTO_TYPE_ICMPv6:
967 		return "ICMPv6";
968 	case QDF_PROTO_TYPE_MGMT:
969 		return "MGMT";
970 	case QDF_PROTO_TYPE_EVENT:
971 		return "EVENT";
972 	default:
973 		return "invalid";
974 	}
975 }
976 
977 /**
978  * qdf_dp_subtype_to_str() - convert packet subtype to string
979  * @subtype: subtype
980  *
981  * Return: string version of packet subtype
982  */
qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)983 static const char *qdf_dp_subtype_to_str(enum qdf_proto_subtype subtype)
984 {
985 	switch (subtype) {
986 	case QDF_PROTO_EAPOL_M1:
987 		return "M1";
988 	case QDF_PROTO_EAPOL_M2:
989 		return "M2";
990 	case QDF_PROTO_EAPOL_M3:
991 		return "M3";
992 	case QDF_PROTO_EAPOL_M4:
993 		return "M4";
994 	case QDF_PROTO_DHCP_DISCOVER:
995 		return "DISC";
996 	case QDF_PROTO_DHCP_REQUEST:
997 		return "REQ";
998 	case QDF_PROTO_DHCP_OFFER:
999 		return "OFF";
1000 	case QDF_PROTO_DHCP_ACK:
1001 		return "ACK";
1002 	case QDF_PROTO_DHCP_NACK:
1003 		return "NACK";
1004 	case QDF_PROTO_DHCP_RELEASE:
1005 		return "REL";
1006 	case QDF_PROTO_DHCP_INFORM:
1007 		return "INFORM";
1008 	case QDF_PROTO_DHCP_DECLINE:
1009 		return "DECL";
1010 	case QDF_PROTO_ARP_REQ:
1011 	case QDF_PROTO_ICMP_REQ:
1012 	case QDF_PROTO_ICMPV6_REQ:
1013 		return "REQ";
1014 	case QDF_PROTO_ARP_RES:
1015 	case QDF_PROTO_ICMP_RES:
1016 	case QDF_PROTO_ICMPV6_RES:
1017 		return "RSP";
1018 	case QDF_PROTO_ICMPV6_RS:
1019 		return "RS";
1020 	case QDF_PROTO_ICMPV6_RA:
1021 		return "RA";
1022 	case QDF_PROTO_ICMPV6_NS:
1023 		return "NS";
1024 	case QDF_PROTO_ICMPV6_NA:
1025 		return "NA";
1026 	case QDF_PROTO_MGMT_ASSOC:
1027 		return "ASSOC";
1028 	case QDF_PROTO_MGMT_DISASSOC:
1029 		return "DISASSOC";
1030 	case QDF_PROTO_MGMT_AUTH:
1031 		return "AUTH";
1032 	case QDF_PROTO_MGMT_DEAUTH:
1033 		return "DEAUTH";
1034 	case QDF_ROAM_SYNCH:
1035 		return "ROAM SYNCH";
1036 	case QDF_ROAM_COMPLETE:
1037 		return "ROAM COMP";
1038 	case QDF_ROAM_EVENTID:
1039 		return "ROAM EVENTID";
1040 	case QDF_PROTO_EAP_REQUEST:
1041 		return "EAP REQ";
1042 	case QDF_PROTO_EAP_RESPONSE:
1043 		return "EAP RSP";
1044 	case QDF_PROTO_EAP_SUCCESS:
1045 		return "EAP SUC";
1046 	case QDF_PROTO_EAP_FAILURE:
1047 		return "EAP FAIL";
1048 	case QDF_PROTO_EAP_INITIATE:
1049 		return "EAP INIT";
1050 	case QDF_PROTO_EAP_FINISH:
1051 		return "EAP FINISH";
1052 	case QDF_PROTO_EAPOL_START:
1053 		return "START";
1054 	case QDF_PROTO_EAPOL_LOGOFF:
1055 		return "LOGOFF";
1056 	case QDF_PROTO_EAPOL_ASF:
1057 		return "ASF";
1058 	case QDF_PROTO_EAP_REQ_ID:
1059 		return "EAP REQ ID";
1060 	case QDF_PROTO_EAP_RSP_ID:
1061 		return "EAP RSP ID";
1062 	case QDF_PROTO_EAP_M1:
1063 		return "EAP M1";
1064 	case QDF_PROTO_EAP_M2:
1065 		return "EAP M2";
1066 	case QDF_PROTO_EAP_M3:
1067 		return "EAP M3";
1068 	case QDF_PROTO_EAP_M4:
1069 		return "EAP M4";
1070 	case QDF_PROTO_EAP_M5:
1071 		return "EAP M5";
1072 	case QDF_PROTO_EAP_M6:
1073 		return "EAP M6";
1074 	case QDF_PROTO_EAP_M7:
1075 		return "EAP M7";
1076 	case QDF_PROTO_EAP_M8:
1077 		return "EAP M8";
1078 	case QDF_PROTO_EAP_WSC_START:
1079 		return "EAP WSC START";
1080 	case QDF_PROTO_EAP_WSC_DONE:
1081 		return "EAP WSC DONE";
1082 	case QDF_PROTO_EAP_WSC_ACK:
1083 		return "EAP WSC ACK";
1084 	case QDF_PROTO_EAP_WSC_NACK:
1085 		return "EAP WSC NACK";
1086 	case QDF_PROTO_EAP_WSC_FRAG_ACK:
1087 		return "EAP WSC FRAG ACK";
1088 	default:
1089 		return "invalid";
1090 	}
1091 }
1092 
1093 /**
1094  * qdf_dp_enable_check() - check if dptrace, TX/RX tracing is enabled
1095  * @nbuf: nbuf
1096  * @code: dptrace code
1097  * @dir: TX or RX direction
1098  *
1099  * Return: true/false
1100  */
qdf_dp_enable_check(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,enum qdf_proto_dir dir)1101 static bool qdf_dp_enable_check(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
1102 				enum qdf_proto_dir dir)
1103 {
1104 	/* Return when Dp trace is not enabled */
1105 	if (!g_qdf_dp_trace_data.enable)
1106 		return false;
1107 
1108 	if (qdf_dp_trace_verbosity_check(code) == false)
1109 		return false;
1110 
1111 	if (nbuf && (dir == QDF_TX && ((QDF_NBUF_CB_TX_DP_TRACE(nbuf) == 0) ||
1112 				       (QDF_NBUF_CB_TX_PACKET_TRACK(nbuf) !=
1113 					QDF_NBUF_TX_PKT_DATA_TRACK))))
1114 		return false;
1115 
1116 	if (nbuf && (dir == QDF_RX && (QDF_NBUF_CB_RX_DP_TRACE(nbuf) == 0)))
1117 		return false;
1118 
1119 	/*
1120 	 * Special packets called with NULL nbuf and this API is expected to
1121 	 * return true
1122 	 */
1123 	return true;
1124 }
1125 
1126 /**
1127  * qdf_dp_trace_fill_meta_str() - fill up a common meta string
1128  * @prepend_str: pointer to string
1129  * @size: size of prepend_str
1130  * @rec_index: index of record
1131  * @info: info related to the record
1132  * @record: pointer to the record
1133  *
1134  * Return: ret value from scnprintf
1135  */
1136 static inline
qdf_dp_trace_fill_meta_str(char * prepend_str,int size,int rec_index,uint8_t info,struct qdf_dp_trace_record_s * record)1137 int qdf_dp_trace_fill_meta_str(char *prepend_str, int size,
1138 			       int rec_index, uint8_t info,
1139 			       struct qdf_dp_trace_record_s *record)
1140 {
1141 	char buffer[20];
1142 	int ret = 0;
1143 	bool live = info & QDF_DP_TRACE_RECORD_INFO_LIVE ? true : false;
1144 	bool throttled = info & QDF_DP_TRACE_RECORD_INFO_THROTTLED ?
1145 								true : false;
1146 
1147 	scnprintf(buffer, sizeof(buffer), "%llu", record->time);
1148 	ret = scnprintf(prepend_str, size,
1149 			"%s DPT: %04d:%02d%s %s",
1150 			throttled ? "*" : "",
1151 			rec_index,
1152 			record->pdev_id,
1153 			live ? "" : buffer,
1154 			qdf_dp_code_to_string(record->code));
1155 
1156 	return ret;
1157 }
1158 
1159 /**
1160  * qdf_dp_fill_record_data() - fill meta data and data into the record
1161  * @rec: pointer to record data
1162  * @data: pointer to data
1163  * @data_size: size of the data
1164  * @meta_data: pointer to metadata
1165  * @metadata_size: size of metadata
1166  *
1167  * Should be called from within a spin_lock for the qdf record.
1168  * Fills up rec->data with |metadata|data|
1169  *
1170  * Return: none
1171  */
qdf_dp_fill_record_data(struct qdf_dp_trace_record_s * rec,uint8_t * data,uint8_t data_size,uint8_t * meta_data,uint8_t metadata_size)1172 static void qdf_dp_fill_record_data
1173 	(struct qdf_dp_trace_record_s *rec,
1174 	uint8_t *data, uint8_t data_size,
1175 	uint8_t *meta_data, uint8_t metadata_size)
1176 {
1177 	int32_t available = QDF_DP_TRACE_RECORD_SIZE;
1178 	uint8_t *rec_data = rec->data;
1179 	uint8_t data_to_copy = 0;
1180 
1181 	qdf_mem_zero(rec_data, QDF_DP_TRACE_RECORD_SIZE);
1182 
1183 	/* copy meta data */
1184 	if (meta_data) {
1185 		if (metadata_size > available) {
1186 			QDF_TRACE_WARN(QDF_MODULE_ID_QDF,
1187 				       "%s: meta data does not fit into the record",
1188 				       __func__);
1189 			goto end;
1190 		}
1191 		qdf_mem_copy(rec_data, meta_data, metadata_size);
1192 		available = available - metadata_size;
1193 	} else {
1194 		metadata_size = 0;
1195 	}
1196 
1197 	/* copy data */
1198 	if (data && (data_size > 0) && (available > 0)) {
1199 		data_to_copy = data_size;
1200 		if (data_size > available)
1201 			data_to_copy = available;
1202 		qdf_mem_copy(&rec_data[metadata_size], data, data_to_copy);
1203 	}
1204 end:
1205 	rec->size = data_to_copy;
1206 }
1207 
1208 /**
1209  * qdf_dp_add_record() - add dp trace record
1210  * @code: dptrace code
1211  * @pdev_id: pdev_id
1212  * @print: true to print it in kmsg
1213  * @data: data pointer
1214  * @data_size: size of data to be copied
1215  * @meta_data: meta data to be prepended to data
1216  * @metadata_size: sizeof meta data
1217  * @print: whether to print record
1218  *
1219  * Return: none
1220  */
qdf_dp_add_record(enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t data_size,uint8_t * meta_data,uint8_t metadata_size,bool print)1221 static void qdf_dp_add_record(enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
1222 			      uint8_t *data, uint8_t data_size,
1223 			      uint8_t *meta_data, uint8_t metadata_size,
1224 			      bool print)
1225 
1226 {
1227 	struct qdf_dp_trace_record_s *rec = NULL;
1228 	int index;
1229 	bool print_this_record = false;
1230 	u8 info = 0;
1231 
1232 	if (code >= QDF_DP_TRACE_MAX) {
1233 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
1234 				"invalid record code %u, max code %u",
1235 				code, QDF_DP_TRACE_MAX);
1236 		return;
1237 	}
1238 
1239 	spin_lock_bh(&l_dp_trace_lock);
1240 
1241 	if (print || g_qdf_dp_trace_data.force_live_mode) {
1242 		print_this_record = true;
1243 	} else if (g_qdf_dp_trace_data.live_mode == 1) {
1244 		print_this_record = true;
1245 		g_qdf_dp_trace_data.print_pkt_cnt++;
1246 		if (g_qdf_dp_trace_data.print_pkt_cnt >
1247 				g_qdf_dp_trace_data.high_tput_thresh) {
1248 			g_qdf_dp_trace_data.live_mode = 0;
1249 			g_qdf_dp_trace_data.verbosity =
1250 					QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
1251 			info |= QDF_DP_TRACE_RECORD_INFO_THROTTLED;
1252 		}
1253 	}
1254 
1255 	g_qdf_dp_trace_data.num++;
1256 
1257 	if (g_qdf_dp_trace_data.num > MAX_QDF_DP_TRACE_RECORDS)
1258 		g_qdf_dp_trace_data.num = MAX_QDF_DP_TRACE_RECORDS;
1259 
1260 	if (INVALID_QDF_DP_TRACE_ADDR == g_qdf_dp_trace_data.head) {
1261 		/* first record */
1262 		g_qdf_dp_trace_data.head = 0;
1263 		g_qdf_dp_trace_data.tail = 0;
1264 	} else {
1265 		/* queue is not empty */
1266 		g_qdf_dp_trace_data.tail++;
1267 
1268 		if (MAX_QDF_DP_TRACE_RECORDS == g_qdf_dp_trace_data.tail)
1269 			g_qdf_dp_trace_data.tail = 0;
1270 
1271 		if (g_qdf_dp_trace_data.head == g_qdf_dp_trace_data.tail) {
1272 			/* full */
1273 			if (MAX_QDF_DP_TRACE_RECORDS ==
1274 				++g_qdf_dp_trace_data.head)
1275 				g_qdf_dp_trace_data.head = 0;
1276 		}
1277 	}
1278 
1279 	rec = &g_qdf_dp_trace_tbl[g_qdf_dp_trace_data.tail];
1280 	index = g_qdf_dp_trace_data.tail;
1281 	rec->code = code;
1282 	rec->pdev_id = pdev_id;
1283 	rec->size = 0;
1284 	qdf_dp_fill_record_data(rec, data, data_size,
1285 				meta_data, metadata_size);
1286 	rec->time = qdf_get_log_timestamp();
1287 	rec->pid = (in_interrupt() ? 0 : current->pid);
1288 
1289 	if (rec->code >= QDF_DP_TRACE_MAX) {
1290 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
1291 				"invalid record code %u, max code %u",
1292 				rec->code, QDF_DP_TRACE_MAX);
1293 		return;
1294 	}
1295 
1296 	spin_unlock_bh(&l_dp_trace_lock);
1297 
1298 	info |= QDF_DP_TRACE_RECORD_INFO_LIVE;
1299 	if (print_this_record)
1300 		qdf_dp_trace_cb_table[rec->code] (rec, index,
1301 					QDF_TRACE_DEFAULT_PDEV_ID, info);
1302 }
1303 
1304 /**
1305  * qdf_get_rate_limit_by_type() - Get the rate limit by pkt type
1306  * @type: packet type
1307  *
1308  * Return: Rate limit value for a particular packet type
1309  */
1310 static inline
qdf_get_rate_limit_by_type(uint8_t type)1311 uint8_t qdf_get_rate_limit_by_type(uint8_t type)
1312 {
1313 	switch (type) {
1314 	case QDF_PROTO_TYPE_DHCP:
1315 		return QDF_MAX_DHCP_PKTS_PER_SEC;
1316 	case QDF_PROTO_TYPE_EAPOL:
1317 		return QDF_MAX_EAPOL_PKTS_PER_SEC;
1318 	case QDF_PROTO_TYPE_ARP:
1319 		return QDF_MAX_ARP_PKTS_PER_SEC;
1320 	case QDF_PROTO_TYPE_DNS:
1321 		return QDF_MAX_DNS_PKTS_PER_SEC;
1322 	default:
1323 		return QDF_MAX_OTHER_PKTS_PER_SEC;
1324 	}
1325 }
1326 
1327 /**
1328  * qdf_get_pkt_type_string() - Get the string based on pkt type
1329  * @type: packet type
1330  * @subtype: packet subtype
1331  *
1332  * Return: String based on pkt type
1333  */
1334 static
qdf_get_pkt_type_string(uint8_t type,uint8_t subtype)1335 uint8_t *qdf_get_pkt_type_string(uint8_t type, uint8_t subtype)
1336 {
1337 	switch (subtype) {
1338 	case QDF_PROTO_EAPOL_M1:
1339 		return "EAPOL-1";
1340 	case QDF_PROTO_EAPOL_M2:
1341 		return "EAPOL-2";
1342 	case QDF_PROTO_EAPOL_M3:
1343 		return "EAPOL-3";
1344 	case QDF_PROTO_EAPOL_M4:
1345 		return "EAPOL-4";
1346 	case QDF_PROTO_DHCP_DISCOVER:
1347 		return "DHCP-D";
1348 	case QDF_PROTO_DHCP_REQUEST:
1349 		return "DHCP-R";
1350 	case QDF_PROTO_DHCP_OFFER:
1351 		return "DHCP-O";
1352 	case QDF_PROTO_DHCP_ACK:
1353 		return "DHCP-A";
1354 	case QDF_PROTO_DHCP_NACK:
1355 		return "DHCP-NA";
1356 	case QDF_PROTO_DHCP_RELEASE:
1357 		return "DHCP-REL";
1358 	case QDF_PROTO_DHCP_INFORM:
1359 		return "DHCP-IN";
1360 	case QDF_PROTO_DHCP_DECLINE:
1361 		return "DHCP-DEC";
1362 	case QDF_PROTO_ARP_REQ:
1363 		return "ARP-RQ";
1364 	case QDF_PROTO_ARP_RES:
1365 		return "ARP-RS";
1366 	case QDF_PROTO_DNS_QUERY:
1367 		return "DNS_Q";
1368 	case QDF_PROTO_DNS_RES:
1369 		return "DNS_RS";
1370 	case QDF_PROTO_EAP_REQUEST:
1371 		return "EAP_REQ";
1372 	case QDF_PROTO_EAP_RESPONSE:
1373 		return "EAP-RSP";
1374 	case QDF_PROTO_EAP_SUCCESS:
1375 		return "EAP-SUCCESS";
1376 	case QDF_PROTO_EAP_FAILURE:
1377 		return "EAP-FAIL";
1378 	case QDF_PROTO_EAP_INITIATE:
1379 		return "EAP-INIT";
1380 	case QDF_PROTO_EAP_FINISH:
1381 		return "EAP-FINISH";
1382 	case QDF_PROTO_EAPOL_START:
1383 		return "EAPOL-START";
1384 	case QDF_PROTO_EAPOL_LOGOFF:
1385 		return "EAPOL-LOGOFF";
1386 	case QDF_PROTO_EAPOL_ASF:
1387 		return "EAPOL-ASF";
1388 	case QDF_PROTO_EAP_REQ_ID:
1389 		return "EAP-REQ-ID";
1390 	case QDF_PROTO_EAP_RSP_ID:
1391 		return "EAP-RSP-ID";
1392 	case QDF_PROTO_EAP_M1:
1393 		return "EAP-M1";
1394 	case QDF_PROTO_EAP_M2:
1395 		return "EAP-M2";
1396 	case QDF_PROTO_EAP_M3:
1397 		return "EAP-M3";
1398 	case QDF_PROTO_EAP_M4:
1399 		return "EAP-M4";
1400 	case QDF_PROTO_EAP_M5:
1401 		return "EAP-M5";
1402 	case QDF_PROTO_EAP_M6:
1403 		return "EAP-M6";
1404 	case QDF_PROTO_EAP_M7:
1405 		return "EAP-M7";
1406 	case QDF_PROTO_EAP_M8:
1407 		return "EAP-M8";
1408 	case QDF_PROTO_EAP_WSC_START:
1409 		return "EAP-WSC-START";
1410 	case QDF_PROTO_EAP_WSC_DONE:
1411 		return "EAP-WSC-DONE";
1412 	case QDF_PROTO_EAP_WSC_ACK:
1413 		return "EAP-WSC-ACK";
1414 	case QDF_PROTO_EAP_WSC_NACK:
1415 		return "EAP-WSC-NACK";
1416 	case QDF_PROTO_EAP_WSC_FRAG_ACK:
1417 		return "EAP-WSC-FRAG-ACK";
1418 	default:
1419 		switch (type) {
1420 		case QDF_PROTO_TYPE_EAPOL:
1421 			return "EAP";
1422 		case QDF_PROTO_TYPE_DHCP:
1423 			return "DHCP";
1424 		case QDF_PROTO_TYPE_ARP:
1425 			return "ARP";
1426 		case QDF_PROTO_TYPE_DNS:
1427 			return "DNS";
1428 		default:
1429 			return "UNKNOWN";
1430 		}
1431 	}
1432 }
1433 
1434 /**
1435  * qdf_get_pkt_status_string() - Get the string based on pkt status
1436  * @status: packet status
1437  *
1438  * Return: String based on pkt status
1439  */
1440 static
qdf_get_pkt_status_string(uint8_t status)1441 uint8_t *qdf_get_pkt_status_string(uint8_t status)
1442 {
1443 	switch (status) {
1444 	case QDF_TX_RX_STATUS_INVALID:
1445 		return "inv";
1446 	case QDF_TX_RX_STATUS_OK:
1447 		return "succ";
1448 	case QDF_TX_RX_STATUS_FW_DISCARD:
1449 		return "disc";
1450 	case QDF_TX_RX_STATUS_NO_ACK:
1451 		return "nack";
1452 	case QDF_TX_RX_STATUS_DROP:
1453 		return "drop";
1454 	default:
1455 		return "unknown";
1456 	}
1457 }
1458 
qdf_dp_log_proto_pkt_info(uint8_t * sa,uint8_t * da,uint8_t type,uint8_t subtype,uint8_t dir,uint16_t msdu_id,uint8_t status)1459 void qdf_dp_log_proto_pkt_info(uint8_t *sa, uint8_t *da, uint8_t type,
1460 			       uint8_t subtype, uint8_t dir, uint16_t msdu_id,
1461 			       uint8_t status)
1462 {
1463 	uint8_t pkt_rate_limit;
1464 	static ulong last_ticks_tx[QDF_PROTO_SUBTYPE_MAX] = {0};
1465 	static ulong last_ticks_rx[QDF_PROTO_SUBTYPE_MAX] = {0};
1466 	ulong curr_ticks = jiffies;
1467 
1468 	pkt_rate_limit = qdf_get_rate_limit_by_type(type);
1469 
1470 	if ((dir == QDF_TX &&
1471 	     !time_after(curr_ticks,
1472 			 last_ticks_tx[subtype] + HZ / pkt_rate_limit)) ||
1473 	    (dir == QDF_RX &&
1474 	     !time_after(curr_ticks,
1475 			 last_ticks_rx[subtype] + HZ / pkt_rate_limit)))
1476 		return;
1477 
1478 	if (dir == QDF_TX)
1479 		last_ticks_tx[subtype] = curr_ticks;
1480 	else
1481 		last_ticks_rx[subtype] = curr_ticks;
1482 
1483 	if (status == QDF_TX_RX_STATUS_INVALID)
1484 		qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT,
1485 			      qdf_get_pkt_type_string(type, subtype),
1486 			      dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa),
1487 			      QDF_MAC_ADDR_REF(da));
1488 	else
1489 		qdf_nofl_info("%s %s: SA:" QDF_MAC_ADDR_FMT " DA:" QDF_MAC_ADDR_FMT " msdu_id:%d status: %s",
1490 			      qdf_get_pkt_type_string(type, subtype),
1491 			      dir ? "RX" : "TX", QDF_MAC_ADDR_REF(sa),
1492 			      QDF_MAC_ADDR_REF(da), msdu_id,
1493 			      qdf_get_pkt_status_string(status));
1494 }
1495 
1496 qdf_export_symbol(qdf_dp_log_proto_pkt_info);
1497 
1498 /**
1499  * qdf_log_icmpv6_pkt() - log ICMPv6 packet
1500  * @vdev_id: ID of the vdev
1501  * @skb: skb pointer
1502  * @dir: direction
1503  * @pdev_id: ID of the pdev
1504  *
1505  * Return: true/false
1506  */
qdf_log_icmpv6_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)1507 static bool qdf_log_icmpv6_pkt(uint8_t vdev_id, struct sk_buff *skb,
1508 			       enum qdf_proto_dir dir, uint8_t pdev_id)
1509 {
1510 	enum qdf_proto_subtype subtype;
1511 	struct qdf_dp_trace_proto_cmn cmn_info;
1512 
1513 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMPv6) &&
1514 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ICMPv6 ==
1515 			QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1516 		 (dir == QDF_RX && qdf_nbuf_is_icmpv6_pkt(skb) == true))) {
1517 
1518 		subtype = qdf_nbuf_get_icmpv6_subtype(skb);
1519 
1520 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
1521 		if (dir == QDF_TX)
1522 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1523 		else if (dir == QDF_RX)
1524 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1525 
1526 		cmn_info.vdev_id = vdev_id;
1527 		cmn_info.type = QDF_PROTO_TYPE_ICMPv6;
1528 		cmn_info.subtype = subtype;
1529 		cmn_info.proto_priv_data = 0;
1530 		cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb);
1531 		DPTRACE(qdf_dp_trace_proto_pkt(
1532 			QDF_DP_TRACE_ICMPv6_PACKET_RECORD,
1533 			(skb->data + QDF_NBUF_SRC_MAC_OFFSET),
1534 			(skb->data + QDF_NBUF_DEST_MAC_OFFSET),
1535 			dir, pdev_id, false, &cmn_info));
1536 
1537 		switch (subtype) {
1538 		case QDF_PROTO_ICMPV6_REQ:
1539 			g_qdf_dp_trace_data.icmpv6_req++;
1540 			break;
1541 		case QDF_PROTO_ICMPV6_RES:
1542 			g_qdf_dp_trace_data.icmpv6_resp++;
1543 			break;
1544 		case QDF_PROTO_ICMPV6_RS:
1545 			g_qdf_dp_trace_data.icmpv6_rs++;
1546 			break;
1547 		case QDF_PROTO_ICMPV6_RA:
1548 			g_qdf_dp_trace_data.icmpv6_ra++;
1549 			break;
1550 		case QDF_PROTO_ICMPV6_NS:
1551 			g_qdf_dp_trace_data.icmpv6_ns++;
1552 			break;
1553 		case QDF_PROTO_ICMPV6_NA:
1554 			g_qdf_dp_trace_data.icmpv6_na++;
1555 			break;
1556 		default:
1557 			break;
1558 		}
1559 		return true;
1560 	}
1561 
1562 	return false;
1563 }
1564 
1565 /**
1566  * qdf_log_icmp_pkt() - log ICMP packet
1567  * @vdev_id: ID of the vdev
1568  * @skb: skb pointer
1569  * @dir: direction
1570  * @pdev_id: ID of the pdev
1571  *
1572  * Return: true/false
1573  */
qdf_log_icmp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)1574 static bool qdf_log_icmp_pkt(uint8_t vdev_id, struct sk_buff *skb,
1575 			     enum qdf_proto_dir dir, uint8_t pdev_id)
1576 {
1577 	uint8_t *data = NULL;
1578 	uint16_t seq_num = 0;
1579 	uint16_t icmp_id = 0;
1580 	struct qdf_dp_trace_proto_cmn cmn_info;
1581 
1582 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ICMP) &&
1583 	    (qdf_nbuf_is_icmp_pkt(skb) == true)) {
1584 
1585 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = false;
1586 		cmn_info.subtype = qdf_nbuf_get_icmp_subtype(skb);
1587 
1588 		data = qdf_nbuf_data(skb);
1589 		icmp_id = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_ID_OFFSET));
1590 		seq_num = qdf_cpu_to_be16(*(uint16_t *)(data + ICMP_SEQ_NUM_OFFSET));
1591 
1592 		cmn_info.proto_priv_data = ((uint32_t)icmp_id) << 16;
1593 		cmn_info.proto_priv_data |= (uint32_t)seq_num;
1594 		cmn_info.type = QDF_PROTO_TYPE_ICMP;
1595 		cmn_info.vdev_id = vdev_id;
1596 		cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb);
1597 
1598 		if (QDF_TX == dir)
1599 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1600 		else if (QDF_RX == dir)
1601 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1602 
1603 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ICMP_PACKET_RECORD,
1604 					       skb->data +
1605 					       QDF_NBUF_SRC_MAC_OFFSET,
1606 					       skb->data +
1607 					       QDF_NBUF_DEST_MAC_OFFSET,
1608 					       dir, pdev_id,
1609 					       false, &cmn_info));
1610 
1611 		if (cmn_info.subtype == QDF_PROTO_ICMP_REQ)
1612 			g_qdf_dp_trace_data.icmp_req++;
1613 		else
1614 			g_qdf_dp_trace_data.icmp_resp++;
1615 
1616 		return true;
1617 	}
1618 	return false;
1619 }
1620 
1621 #ifdef WLAN_CHIPSET_STATS
1622 static void
qdf_log_pkt_cstats(uint8_t * sa,uint8_t * da,enum qdf_proto_type pkt_type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status status,uint8_t vdev_id,enum QDF_OPMODE op_mode)1623 qdf_log_pkt_cstats(uint8_t *sa, uint8_t *da, enum qdf_proto_type pkt_type,
1624 		   enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
1625 		   enum qdf_dp_tx_rx_status status, uint8_t vdev_id,
1626 		   enum QDF_OPMODE op_mode)
1627 {
1628 	wlan_cp_stats_cstats_pkt_log(sa, da, pkt_type, subtype, dir,
1629 				     status, vdev_id, op_mode);
1630 }
1631 #else
1632 static void
qdf_log_pkt_cstats(uint8_t * sa,uint8_t * da,enum qdf_proto_type pkt_type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status status,uint8_t vdev_id,enum QDF_OPMODE op_mode)1633 qdf_log_pkt_cstats(uint8_t *sa, uint8_t *da, enum qdf_proto_type pkt_type,
1634 		   enum qdf_proto_subtype subtype, enum qdf_proto_dir dir,
1635 		   enum qdf_dp_tx_rx_status status, uint8_t vdev_id,
1636 		   enum QDF_OPMODE op_mode)
1637 {
1638 }
1639 #endif
1640 
1641 #ifdef CONNECTIVITY_DIAG_EVENT
wlan_get_diag_tx_status(enum qdf_dp_tx_rx_status tx_status)1642 enum diag_tx_status wlan_get_diag_tx_status(enum qdf_dp_tx_rx_status tx_status)
1643 {
1644 	switch (tx_status) {
1645 	case DIAG_TX_RX_STATUS_FW_DISCARD:
1646 	case DIAG_TX_RX_STATUS_INVALID:
1647 	case DIAG_TX_RX_STATUS_DROP:
1648 	case DIAG_TX_RX_STATUS_DOWNLOAD_SUCC:
1649 	case DIAG_TX_RX_STATUS_DEFAULT:
1650 	default:
1651 		return DIAG_TX_STATUS_FAIL;
1652 	case DIAG_TX_RX_STATUS_NO_ACK:
1653 		return DIAG_TX_STATUS_NO_ACK;
1654 	case DIAG_TX_RX_STATUS_OK:
1655 		return DIAG_TX_STATUS_ACK;
1656 	}
1657 
1658 	return DIAG_TX_STATUS_FAIL;
1659 }
1660 
1661 /**
1662  * qdf_subtype_to_wlan_main_tag() - Convert qdf subtype to wlan main tag
1663  * @subtype: EAPoL key subtype
1664  *
1665  * Return: Wlan main tag subtype
1666  */
qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)1667 static int qdf_subtype_to_wlan_main_tag(enum qdf_proto_subtype subtype)
1668 {
1669 	switch (subtype) {
1670 	case QDF_PROTO_DHCP_DISCOVER:
1671 		return WLAN_CONN_DIAG_DHCP_DISC_EVENT;
1672 	case QDF_PROTO_DHCP_REQUEST:
1673 		return WLAN_CONN_DIAG_DHCP_REQUEST_EVENT;
1674 	case QDF_PROTO_DHCP_OFFER:
1675 		return WLAN_CONN_DIAG_DHCP_OFFER_EVENT;
1676 	case QDF_PROTO_DHCP_ACK:
1677 		return WLAN_CONN_DIAG_DHCP_ACK_EVENT;
1678 	case QDF_PROTO_DHCP_NACK:
1679 		return WLAN_CONN_DIAG_DHCP_NACK_EVENT;
1680 	case QDF_PROTO_EAPOL_M1:
1681 		return WLAN_CONN_DIAG_EAPOL_M1_EVENT;
1682 	case QDF_PROTO_EAPOL_M2:
1683 		return WLAN_CONN_DIAG_EAPOL_M2_EVENT;
1684 	case QDF_PROTO_EAPOL_M3:
1685 		return WLAN_CONN_DIAG_EAPOL_M3_EVENT;
1686 	case QDF_PROTO_EAPOL_M4:
1687 		return WLAN_CONN_DIAG_EAPOL_M4_EVENT;
1688 	case QDF_PROTO_EAP_REQUEST:
1689 		return WLAN_CONN_DIAG_EAP_REQ_EVENT;
1690 	case QDF_PROTO_EAP_RESPONSE:
1691 		return WLAN_CONN_DIAG_EAP_RESP_EVENT;
1692 	case QDF_PROTO_EAP_SUCCESS:
1693 		return WLAN_CONN_DIAG_EAP_SUCC_EVENT;
1694 	case QDF_PROTO_EAP_FAILURE:
1695 		return WLAN_CONN_DIAG_EAP_FAIL_EVENT;
1696 	case QDF_PROTO_EAPOL_START:
1697 		return WLAN_CONN_DIAG_EAP_START_EVENT;
1698 	default:
1699 		return WLAN_CONN_DIAG_MAX;
1700 	}
1701 }
1702 
1703 /**
1704  * qdf_get_wlan_eap_code() - Get EAP code
1705  * @data: skb data pointer
1706  *
1707  * Return: EAP code value
1708  */
qdf_get_wlan_eap_code(uint8_t * data)1709 static int qdf_get_wlan_eap_code(uint8_t *data)
1710 {
1711 	uint8_t code = *(data + EAP_CODE_OFFSET);
1712 
1713 	switch (code) {
1714 	case QDF_EAP_REQUEST:
1715 		return WLAN_CONN_DIAG_EAP_REQ_EVENT;
1716 	case QDF_EAP_RESPONSE:
1717 		return WLAN_CONN_DIAG_EAP_RESP_EVENT;
1718 	case QDF_EAP_SUCCESS:
1719 		return WLAN_CONN_DIAG_EAP_SUCC_EVENT;
1720 	case QDF_EAP_FAILURE:
1721 		return WLAN_CONN_DIAG_EAP_FAIL_EVENT;
1722 	default:
1723 		return WLAN_CONN_DIAG_MAX;
1724 	}
1725 }
1726 
1727 /**
1728  * qdf_eapol_get_key_type() - Get EAPOL key type
1729  * @data: skb data pointer
1730  * @subtype: EAPoL key subtype
1731  *
1732  * Return: EAPOL key type
1733  */
1734 static
qdf_eapol_get_key_type(uint8_t * data,enum qdf_proto_subtype subtype)1735 uint8_t qdf_eapol_get_key_type(uint8_t *data, enum qdf_proto_subtype subtype)
1736 {
1737 	uint16_t key_info = *(uint16_t *)(data + EAPOL_KEY_INFO_OFFSET);
1738 
1739 	/* If key type is PTK, key type will be set in EAPOL Key info */
1740 	if (key_info & EAPOL_KEY_TYPE_MASK)
1741 		return qdf_subtype_to_wlan_main_tag(subtype);
1742 	else if (key_info & EAPOL_KEY_ENCRYPTED_MASK)
1743 		return WLAN_CONN_DIAG_GTK_M1_EVENT;
1744 	else
1745 		return WLAN_CONN_DIAG_GTK_M2_EVENT;
1746 }
1747 
1748 /**
1749  * qdf_skip_wlan_connectivity_log() - Check if connectivity log need to skip
1750  * @type: Protocol type
1751  * @subtype: Protocol subtype
1752  * @dir: Rx or Tx
1753  * @op_mode: Vdev Operation mode
1754  *
1755  * Return: true or false
1756  */
1757 static inline
qdf_skip_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum QDF_OPMODE op_mode)1758 bool qdf_skip_wlan_connectivity_log(enum qdf_proto_type type,
1759 				    enum qdf_proto_subtype subtype,
1760 				    enum qdf_proto_dir dir,
1761 				    enum QDF_OPMODE op_mode)
1762 {
1763 	if (op_mode != QDF_STA_MODE)
1764 		return true;
1765 
1766 	if (dir == QDF_RX && type == QDF_PROTO_TYPE_DHCP &&
1767 	    (subtype == QDF_PROTO_DHCP_DISCOVER ||
1768 	     subtype == QDF_PROTO_DHCP_REQUEST))
1769 		return true;
1770 	return false;
1771 }
1772 
1773 /**
1774  * qdf_fill_wlan_connectivity_log() - Fill and queue protocol packet to logging
1775  * the logging queue
1776  * @type: Protocol type
1777  * @subtype: Protocol subtype
1778  * @dir: Rx or Tx
1779  * @qdf_tx_status: Tx completion status
1780  * @op_mode: Vdev Operation mode
1781  * @vdev_id: DP vdev ID
1782  * @data: skb data pointer
1783  * @band: band
1784  *
1785  * Return: None
1786  */
1787 static
qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode,uint8_t vdev_id,uint8_t * data,uint8_t band)1788 void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
1789 				    enum qdf_proto_subtype subtype,
1790 				    enum qdf_proto_dir dir,
1791 				    enum qdf_dp_tx_rx_status qdf_tx_status,
1792 				    enum QDF_OPMODE op_mode,
1793 				    uint8_t vdev_id, uint8_t *data,
1794 				    uint8_t band)
1795 {
1796 	uint8_t pkt_type;
1797 
1798 	WLAN_HOST_DIAG_EVENT_DEF(wlan_diag_event, struct wlan_diag_packet_info);
1799 
1800 	if (qdf_skip_wlan_connectivity_log(type, subtype, dir, op_mode))
1801 		return;
1802 
1803 	qdf_mem_zero(&wlan_diag_event, sizeof(wlan_diag_event));
1804 
1805 	wlan_diag_event.diag_cmn.timestamp_us =
1806 					qdf_get_time_of_the_day_ms() * 1000;
1807 	wlan_diag_event.diag_cmn.ktime_us = qdf_ktime_to_us(qdf_ktime_get());
1808 	wlan_diag_event.diag_cmn.vdev_id = vdev_id;
1809 
1810 	wlan_diag_event.version = DIAG_MGMT_VERSION_V2;
1811 
1812 	if (type == QDF_PROTO_TYPE_DHCP) {
1813 		wlan_diag_event.subtype =
1814 					qdf_subtype_to_wlan_main_tag(subtype);
1815 	} else if (type == QDF_PROTO_TYPE_EAPOL) {
1816 		pkt_type = *(data + EAPOL_PACKET_TYPE_OFFSET);
1817 		if (pkt_type == EAPOL_PACKET_TYPE_EAP) {
1818 			wlan_diag_event.subtype =
1819 						qdf_get_wlan_eap_code(data);
1820 			wlan_diag_event.eap_type =
1821 						*(data + EAP_TYPE_OFFSET);
1822 			wlan_diag_event.eap_len =
1823 			   qdf_ntohs(*(uint16_t *)(data + EAP_LENGTH_OFFSET));
1824 		} else if (pkt_type == EAPOL_PACKET_TYPE_KEY) {
1825 			wlan_diag_event.subtype =
1826 					qdf_eapol_get_key_type(data, subtype);
1827 		} else if (pkt_type == EAPOL_PACKET_TYPE_START) {
1828 			wlan_diag_event.subtype =
1829 					WLAN_CONN_DIAG_EAP_START_EVENT;
1830 			wlan_diag_event.eap_len =
1831 			    qdf_ntohs(*(uint16_t *)(data + EAPOL_PKT_LEN_OFFSET));
1832 		} else {
1833 			return;
1834 		}
1835 	} else {
1836 		return;
1837 	}
1838 
1839 	wlan_diag_event.supported_links = band;
1840 
1841 	/*Tx completion status needs to be logged*/
1842 	if (dir == QDF_TX) {
1843 		wlan_diag_event.is_tx = 1;
1844 		wlan_diag_event.tx_status =
1845 					wlan_get_diag_tx_status(qdf_tx_status);
1846 	}
1847 
1848 	WLAN_HOST_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_CONN_DP);
1849 }
1850 
1851 #else
1852 static inline
qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,enum qdf_proto_subtype subtype,enum qdf_proto_dir dir,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode,uint8_t vdev_id,uint8_t * data,uint8_t band)1853 void qdf_fill_wlan_connectivity_log(enum qdf_proto_type type,
1854 				    enum qdf_proto_subtype subtype,
1855 				    enum qdf_proto_dir dir,
1856 				    enum qdf_dp_tx_rx_status qdf_tx_status,
1857 				    enum QDF_OPMODE op_mode,
1858 				    uint8_t vdev_id, uint8_t *data,
1859 				    uint8_t band)
1860 {
1861 }
1862 #endif
1863 
1864 /**
1865  * qdf_log_eapol_pkt() - log EAPOL packet
1866  * @vdev_id: ID of the vdev
1867  * @skb: skb pointer
1868  * @dir: direction
1869  * @pdev_id: ID of the pdev
1870  * @op_mode: Vdev Operation mode
1871  *
1872  * Return: true/false
1873  */
qdf_log_eapol_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)1874 static bool qdf_log_eapol_pkt(uint8_t vdev_id, struct sk_buff *skb,
1875 			      enum qdf_proto_dir dir, uint8_t pdev_id,
1876 				  enum QDF_OPMODE op_mode)
1877 {
1878 	enum qdf_proto_subtype subtype;
1879 	uint32_t dp_eap_trace;
1880 	uint32_t dp_eap_event;
1881 	struct qdf_dp_trace_proto_cmn cmn_info;
1882 
1883 	dp_eap_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
1884 	dp_eap_event = qdf_dp_get_proto_event_bitmap() &
1885 				QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
1886 
1887 	if (!dp_eap_trace && !dp_eap_event)
1888 		return false;
1889 
1890 	if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_EAPOL ==
1891 	       QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1892 	      (dir == QDF_RX && qdf_nbuf_is_ipv4_eapol_pkt(skb) == true)))
1893 		return false;
1894 
1895 	subtype = qdf_nbuf_get_eapol_subtype(skb);
1896 
1897 	if (dp_eap_event && dir == QDF_RX) {
1898 		qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
1899 					  skb->data + QDF_NBUF_DEST_MAC_OFFSET,
1900 					  QDF_PROTO_TYPE_EAPOL, subtype, dir,
1901 					  QDF_TRACE_DEFAULT_MSDU_ID,
1902 					  QDF_TX_RX_STATUS_INVALID);
1903 		qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_EAPOL, subtype,
1904 					       QDF_RX, 0, op_mode,
1905 					       vdev_id, skb->data,
1906 					       qdf_nbuf_rx_get_band(skb));
1907 		qdf_log_pkt_cstats(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
1908 				   skb->data + QDF_NBUF_DEST_MAC_OFFSET,
1909 				   QDF_PROTO_TYPE_EAPOL, subtype, dir,
1910 				   QDF_TX_RX_STATUS_INVALID, vdev_id, op_mode);
1911 	}
1912 
1913 	if (dp_eap_trace) {
1914 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
1915 		if (QDF_TX == dir)
1916 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
1917 		else if (QDF_RX == dir)
1918 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
1919 
1920 		cmn_info.vdev_id = vdev_id;
1921 		cmn_info.type = QDF_PROTO_TYPE_EAPOL;
1922 		cmn_info.subtype = subtype;
1923 		cmn_info.proto_priv_data = 0;
1924 		cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb);
1925 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_EAPOL_PACKET_RECORD,
1926 					       skb->data +
1927 					       QDF_NBUF_SRC_MAC_OFFSET,
1928 					       skb->data +
1929 					       QDF_NBUF_DEST_MAC_OFFSET,
1930 					       dir, pdev_id, true, &cmn_info));
1931 
1932 		switch (subtype) {
1933 		case QDF_PROTO_EAPOL_M1:
1934 			g_qdf_dp_trace_data.eapol_m1++;
1935 			break;
1936 		case QDF_PROTO_EAPOL_M2:
1937 			g_qdf_dp_trace_data.eapol_m2++;
1938 			break;
1939 		case QDF_PROTO_EAPOL_M3:
1940 			g_qdf_dp_trace_data.eapol_m3++;
1941 			break;
1942 		case QDF_PROTO_EAPOL_M4:
1943 			g_qdf_dp_trace_data.eapol_m4++;
1944 			break;
1945 		default:
1946 			g_qdf_dp_trace_data.eapol_others++;
1947 			break;
1948 		}
1949 	}
1950 
1951 	return true;
1952 }
1953 
1954 /**
1955  * qdf_log_dhcp_pkt() - log DHCP packet
1956  * @vdev_id: ID of the vdev
1957  * @skb: skb pointer
1958  * @dir: direction
1959  * @pdev_id: ID of the pdev
1960  * @op_mode: Vdev Operation mode
1961  *
1962  * Return: true/false
1963  */
qdf_log_dhcp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)1964 static bool qdf_log_dhcp_pkt(uint8_t vdev_id, struct sk_buff *skb,
1965 			     enum qdf_proto_dir dir, uint8_t pdev_id,
1966 			     enum QDF_OPMODE op_mode)
1967 {
1968 	enum qdf_proto_subtype subtype = QDF_PROTO_INVALID;
1969 	uint32_t dp_dhcp_trace;
1970 	uint32_t dp_dhcp_event;
1971 	struct qdf_dp_trace_proto_cmn cmn_info;
1972 
1973 	dp_dhcp_trace = qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_DHCP;
1974 	dp_dhcp_event = qdf_dp_get_proto_event_bitmap() &
1975 				QDF_NBUF_PKT_TRAC_TYPE_DHCP;
1976 
1977 	if (!dp_dhcp_trace && !dp_dhcp_event)
1978 		return false;
1979 
1980 	if (!((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_DHCP ==
1981 	       QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
1982 	      (dir == QDF_RX && qdf_nbuf_is_ipv4_dhcp_pkt(skb) == true)))
1983 		return false;
1984 
1985 	subtype = qdf_nbuf_get_dhcp_subtype(skb);
1986 
1987 	if (dp_dhcp_event && dir == QDF_RX) {
1988 		qdf_dp_log_proto_pkt_info(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
1989 					  skb->data + QDF_NBUF_DEST_MAC_OFFSET,
1990 					  QDF_PROTO_TYPE_DHCP, subtype, dir,
1991 					  QDF_TRACE_DEFAULT_MSDU_ID,
1992 					  QDF_TX_RX_STATUS_INVALID);
1993 		qdf_fill_wlan_connectivity_log(QDF_PROTO_TYPE_DHCP, subtype,
1994 					       QDF_RX, 0, op_mode, vdev_id, 0,
1995 					       qdf_nbuf_rx_get_band(skb));
1996 		qdf_log_pkt_cstats(skb->data + QDF_NBUF_SRC_MAC_OFFSET,
1997 				   skb->data + QDF_NBUF_DEST_MAC_OFFSET,
1998 				   QDF_PROTO_TYPE_DHCP, subtype, dir,
1999 				   QDF_TX_RX_STATUS_INVALID, vdev_id, op_mode);
2000 	}
2001 
2002 	if (dp_dhcp_trace) {
2003 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
2004 		if (QDF_TX == dir)
2005 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
2006 		else if (QDF_RX == dir)
2007 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
2008 
2009 		cmn_info.vdev_id = vdev_id;
2010 		cmn_info.type = QDF_PROTO_TYPE_DHCP;
2011 		cmn_info.subtype = subtype;
2012 		cmn_info.proto_priv_data = 0;
2013 		cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb);
2014 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_DHCP_PACKET_RECORD,
2015 					       skb->data +
2016 					       QDF_NBUF_SRC_MAC_OFFSET,
2017 					       skb->data +
2018 					       QDF_NBUF_DEST_MAC_OFFSET,
2019 					       dir, pdev_id, true, &cmn_info));
2020 
2021 		switch (subtype) {
2022 		case QDF_PROTO_DHCP_DISCOVER:
2023 			g_qdf_dp_trace_data.dhcp_disc++;
2024 			break;
2025 		case QDF_PROTO_DHCP_OFFER:
2026 			g_qdf_dp_trace_data.dhcp_off++;
2027 			break;
2028 		case QDF_PROTO_DHCP_REQUEST:
2029 			g_qdf_dp_trace_data.dhcp_req++;
2030 			break;
2031 		case QDF_PROTO_DHCP_ACK:
2032 			g_qdf_dp_trace_data.dhcp_ack++;
2033 			break;
2034 		case QDF_PROTO_DHCP_NACK:
2035 			g_qdf_dp_trace_data.dhcp_nack++;
2036 			break;
2037 		default:
2038 			g_qdf_dp_trace_data.eapol_others++;
2039 			break;
2040 		}
2041 	}
2042 
2043 	return true;
2044 }
2045 
2046 /**
2047  * qdf_log_arp_pkt() - log ARP packet
2048  * @vdev_id: ID of the vdev
2049  * @skb: skb pointer
2050  * @dir: direction
2051  * @pdev_id: ID of the pdev
2052  *
2053  * Return: true/false
2054  */
qdf_log_arp_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id)2055 static bool qdf_log_arp_pkt(uint8_t vdev_id, struct sk_buff *skb,
2056 			    enum qdf_proto_dir dir, uint8_t pdev_id)
2057 {
2058 	enum qdf_proto_subtype proto_subtype;
2059 	struct qdf_dp_trace_proto_cmn cmn_info;
2060 
2061 	if ((qdf_dp_get_proto_bitmap() & QDF_NBUF_PKT_TRAC_TYPE_ARP) &&
2062 		((dir == QDF_TX && QDF_NBUF_CB_PACKET_TYPE_ARP ==
2063 			QDF_NBUF_CB_GET_PACKET_TYPE(skb)) ||
2064 		 (dir == QDF_RX && qdf_nbuf_is_ipv4_arp_pkt(skb) == true))) {
2065 
2066 		proto_subtype = qdf_nbuf_get_arp_subtype(skb);
2067 		QDF_NBUF_CB_DP_TRACE_PRINT(skb) = true;
2068 		if (QDF_TX == dir)
2069 			QDF_NBUF_CB_TX_DP_TRACE(skb) = 1;
2070 		else if (QDF_RX == dir)
2071 			QDF_NBUF_CB_RX_DP_TRACE(skb) = 1;
2072 
2073 		cmn_info.vdev_id = vdev_id;
2074 		cmn_info.type = QDF_PROTO_TYPE_ARP;
2075 		cmn_info.subtype = proto_subtype;
2076 		cmn_info.proto_priv_data = 0;
2077 		cmn_info.mpdu_seq = qdf_nbuf_get_mpdu_seq_num(skb);
2078 		DPTRACE(qdf_dp_trace_proto_pkt(QDF_DP_TRACE_ARP_PACKET_RECORD,
2079 					       skb->data +
2080 					       QDF_NBUF_SRC_MAC_OFFSET,
2081 					       skb->data +
2082 					       QDF_NBUF_DEST_MAC_OFFSET,
2083 					       dir, pdev_id, true,
2084 					       &cmn_info));
2085 
2086 		if (QDF_PROTO_ARP_REQ == proto_subtype)
2087 			g_qdf_dp_trace_data.arp_req++;
2088 		else
2089 			g_qdf_dp_trace_data.arp_resp++;
2090 
2091 		return true;
2092 	}
2093 	return false;
2094 }
2095 
2096 
qdf_dp_trace_log_pkt(uint8_t vdev_id,struct sk_buff * skb,enum qdf_proto_dir dir,uint8_t pdev_id,enum QDF_OPMODE op_mode)2097 bool qdf_dp_trace_log_pkt(uint8_t vdev_id, struct sk_buff *skb,
2098 			  enum qdf_proto_dir dir, uint8_t pdev_id,
2099 			  enum QDF_OPMODE op_mode)
2100 {
2101 	if (!qdf_dp_get_proto_bitmap() && !qdf_dp_get_proto_event_bitmap())
2102 		return false;
2103 	if (qdf_log_arp_pkt(vdev_id, skb, dir, pdev_id))
2104 		return true;
2105 	if (qdf_log_dhcp_pkt(vdev_id, skb, dir, pdev_id, op_mode))
2106 		return true;
2107 	if (qdf_log_eapol_pkt(vdev_id, skb, dir, pdev_id, op_mode))
2108 		return true;
2109 	if (qdf_log_icmp_pkt(vdev_id, skb, dir, pdev_id))
2110 		return true;
2111 	if (qdf_log_icmpv6_pkt(vdev_id, skb, dir, pdev_id))
2112 		return true;
2113 	return false;
2114 }
2115 qdf_export_symbol(qdf_dp_trace_log_pkt);
2116 
qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2117 void qdf_dp_display_mgmt_pkt(struct qdf_dp_trace_record_s *record,
2118 			      uint16_t index, uint8_t pdev_id, uint8_t info)
2119 {
2120 	int loc;
2121 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2122 	struct qdf_dp_trace_mgmt_buf *buf =
2123 		(struct qdf_dp_trace_mgmt_buf *)record->data;
2124 
2125 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2126 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2127 					 index, info, record);
2128 
2129 	DPTRACE_PRINT("%s [%d] [%s %s]",
2130 		      prepend_str,
2131 		      buf->vdev_id,
2132 		      qdf_dp_type_to_str(buf->type),
2133 		      qdf_dp_subtype_to_str(buf->subtype));
2134 }
2135 qdf_export_symbol(qdf_dp_display_mgmt_pkt);
2136 
2137 
qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code,uint8_t vdev_id,uint8_t pdev_id,enum qdf_proto_type type,enum qdf_proto_subtype subtype)2138 void qdf_dp_trace_mgmt_pkt(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
2139 		uint8_t pdev_id, enum qdf_proto_type type,
2140 		enum qdf_proto_subtype subtype)
2141 {
2142 	struct qdf_dp_trace_mgmt_buf buf;
2143 	int buf_size = sizeof(struct qdf_dp_trace_mgmt_buf);
2144 
2145 	if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
2146 		return;
2147 
2148 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2149 		QDF_BUG(0);
2150 
2151 	buf.type = type;
2152 	buf.subtype = subtype;
2153 	buf.vdev_id = vdev_id;
2154 	qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size,
2155 			  NULL, 0, true);
2156 }
2157 qdf_export_symbol(qdf_dp_trace_mgmt_pkt);
2158 
2159 static void
qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2160 qdf_dpt_display_credit_record_debugfs(qdf_debugfs_file_t file,
2161 				      struct qdf_dp_trace_record_s *record,
2162 				      uint32_t index)
2163 {
2164 	int loc;
2165 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2166 	struct qdf_dp_trace_credit_record *buf =
2167 		(struct qdf_dp_trace_credit_record *)record->data;
2168 
2169 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2170 					 index, 0, record);
2171 	if (buf->operation == QDF_OP_NA)
2172 		qdf_debugfs_printf(file, "%s [%s] [T: %d G0: %d G1: %d]\n",
2173 				   prepend_str,
2174 				   qdf_dp_credit_source_to_str(buf->source),
2175 				   buf->total_credits, buf->g0_credit,
2176 				   buf->g1_credit);
2177 	else
2178 		qdf_debugfs_printf(file,
2179 				   "%s [%s] [T: %d G0: %d G1: %d] [%s %d]\n",
2180 				   prepend_str,
2181 				   qdf_dp_credit_source_to_str(buf->source),
2182 				   buf->total_credits, buf->g0_credit,
2183 				   buf->g1_credit,
2184 				   qdf_dp_operation_to_str(buf->operation),
2185 				   buf->delta);
2186 }
2187 
qdf_dp_display_credit_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2188 void qdf_dp_display_credit_record(struct qdf_dp_trace_record_s *record,
2189 				  uint16_t index, uint8_t pdev_id, uint8_t info)
2190 {
2191 	int loc;
2192 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2193 	struct qdf_dp_trace_credit_record *buf =
2194 		(struct qdf_dp_trace_credit_record *)record->data;
2195 
2196 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2197 					 index, info, record);
2198 	if (buf->operation == QDF_OP_NA)
2199 		DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d]",
2200 			      prepend_str,
2201 			      qdf_dp_credit_source_to_str(buf->source),
2202 			      buf->total_credits, buf->g0_credit,
2203 			      buf->g1_credit);
2204 	else
2205 		DPTRACE_PRINT("%s [%s] [T: %d G0: %d G1: %d] [%s %d]",
2206 			      prepend_str,
2207 			      qdf_dp_credit_source_to_str(buf->source),
2208 			      buf->total_credits, buf->g0_credit,
2209 			      buf->g1_credit,
2210 			      qdf_dp_operation_to_str(buf->operation),
2211 			      buf->delta);
2212 }
2213 
qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source,enum QDF_CREDIT_OPERATION operation,int delta,int total_credits,int g0_credit,int g1_credit)2214 void qdf_dp_trace_credit_record(enum QDF_CREDIT_UPDATE_SOURCE source,
2215 				enum QDF_CREDIT_OPERATION operation,
2216 				int delta, int total_credits,
2217 				int g0_credit, int g1_credit)
2218 {
2219 	struct qdf_dp_trace_credit_record buf;
2220 	int buf_size = sizeof(struct qdf_dp_trace_credit_record);
2221 	enum QDF_DP_TRACE_ID code = QDF_DP_TRACE_TX_CREDIT_RECORD;
2222 
2223 	if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
2224 		return;
2225 
2226 	if (!(qdf_dp_get_proto_bitmap() & QDF_HL_CREDIT_TRACKING))
2227 		return;
2228 
2229 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2230 		QDF_BUG(0);
2231 
2232 	buf.source = source;
2233 	buf.operation = operation;
2234 	buf.delta = delta;
2235 	buf.total_credits = total_credits;
2236 	buf.g0_credit = g0_credit;
2237 	buf.g1_credit = g1_credit;
2238 
2239 	qdf_dp_add_record(code, QDF_TRACE_DEFAULT_PDEV_ID, (uint8_t *)&buf,
2240 			  buf_size, NULL, 0, false);
2241 }
2242 qdf_export_symbol(qdf_dp_trace_credit_record);
2243 
qdf_dp_display_event_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2244 void qdf_dp_display_event_record(struct qdf_dp_trace_record_s *record,
2245 			      uint16_t index, uint8_t pdev_id, uint8_t info)
2246 {
2247 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2248 	struct qdf_dp_trace_event_buf *buf =
2249 		(struct qdf_dp_trace_event_buf *)record->data;
2250 
2251 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2252 	qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2253 				   index, info, record);
2254 
2255 	DPTRACE_PRINT("%s [%d] [%s %s]",
2256 		      prepend_str,
2257 		      buf->vdev_id,
2258 		      qdf_dp_type_to_str(buf->type),
2259 		      qdf_dp_subtype_to_str(buf->subtype));
2260 }
2261 qdf_export_symbol(qdf_dp_display_event_record);
2262 
qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code,uint8_t vdev_id,uint8_t pdev_id,enum qdf_proto_type type,enum qdf_proto_subtype subtype)2263 void qdf_dp_trace_record_event(enum QDF_DP_TRACE_ID code, uint8_t vdev_id,
2264 			       uint8_t pdev_id, enum qdf_proto_type type,
2265 			       enum qdf_proto_subtype subtype)
2266 {
2267 	struct qdf_dp_trace_event_buf buf;
2268 	int buf_size = sizeof(struct qdf_dp_trace_event_buf);
2269 
2270 	if (qdf_dp_enable_check(NULL, code, QDF_NA) == false)
2271 		return;
2272 
2273 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2274 		QDF_BUG(0);
2275 
2276 	buf.type = type;
2277 	buf.subtype = subtype;
2278 	buf.vdev_id = vdev_id;
2279 	qdf_dp_add_record(code, pdev_id,
2280 			  (uint8_t *)&buf, buf_size, NULL, 0, true);
2281 }
2282 qdf_export_symbol(qdf_dp_trace_record_event);
2283 
2284 
qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2285 void qdf_dp_display_proto_pkt(struct qdf_dp_trace_record_s *record,
2286 			      uint16_t index, uint8_t pdev_id, uint8_t info)
2287 {
2288 	int loc;
2289 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2290 	struct qdf_dp_trace_proto_buf *buf =
2291 		(struct qdf_dp_trace_proto_buf *)record->data;
2292 
2293 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2294 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2295 					 index, info, record);
2296 
2297 	if (QDF_RX == buf->dir)
2298 		DPTRACE_PRINT("%s [%d] [%d] [%s] SA: "
2299 			      QDF_MAC_ADDR_FMT " %s DA:"
2300 			      QDF_MAC_ADDR_FMT " proto priv data = %08x",
2301 			      prepend_str,
2302 			      buf->cmn_info.vdev_id,
2303 			      buf->cmn_info.mpdu_seq,
2304 			      qdf_dp_subtype_to_str(buf->cmn_info.subtype),
2305 			      QDF_MAC_ADDR_REF(buf->sa.bytes),
2306 			      qdf_dp_dir_to_str(buf->dir),
2307 			      QDF_MAC_ADDR_REF(buf->da.bytes),
2308 			      buf->cmn_info.proto_priv_data);
2309 	else
2310 		DPTRACE_PRINT("%s [%d] [%s] SA: "
2311 			      QDF_MAC_ADDR_FMT " %s DA:"
2312 			      QDF_MAC_ADDR_FMT " proto priv data = %08x",
2313 			      prepend_str,
2314 			      buf->cmn_info.vdev_id,
2315 			      qdf_dp_subtype_to_str(buf->cmn_info.subtype),
2316 			      QDF_MAC_ADDR_REF(buf->sa.bytes),
2317 			      qdf_dp_dir_to_str(buf->dir),
2318 			      QDF_MAC_ADDR_REF(buf->da.bytes),
2319 			      buf->cmn_info.proto_priv_data);
2320 }
2321 qdf_export_symbol(qdf_dp_display_proto_pkt);
2322 
qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code,uint8_t * sa,uint8_t * da,enum qdf_proto_dir dir,uint8_t pdev_id,bool print,struct qdf_dp_trace_proto_cmn * cmn_info)2323 void qdf_dp_trace_proto_pkt(enum QDF_DP_TRACE_ID code,
2324 			    uint8_t *sa, uint8_t *da,
2325 			    enum qdf_proto_dir dir,
2326 			    uint8_t pdev_id, bool print,
2327 			    struct qdf_dp_trace_proto_cmn *cmn_info)
2328 {
2329 	struct qdf_dp_trace_proto_buf buf;
2330 	int buf_size = sizeof(struct qdf_dp_trace_proto_buf);
2331 
2332 	if (qdf_dp_enable_check(NULL, code, dir) == false)
2333 		return;
2334 
2335 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2336 		QDF_BUG(0);
2337 
2338 	memcpy(&buf.sa, sa, QDF_NET_ETH_LEN);
2339 	memcpy(&buf.da, da, QDF_NET_ETH_LEN);
2340 	memcpy(&buf.cmn_info, cmn_info, sizeof(*cmn_info));
2341 	buf.dir = dir;
2342 	qdf_dp_add_record(code, pdev_id,
2343 			  (uint8_t *)&buf, buf_size, NULL, 0, print);
2344 }
2345 qdf_export_symbol(qdf_dp_trace_proto_pkt);
2346 
qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2347 void qdf_dp_display_ptr_record(struct qdf_dp_trace_record_s *record,
2348 				uint16_t index, uint8_t pdev_id, uint8_t info)
2349 {
2350 	int loc;
2351 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2352 	struct qdf_dp_trace_ptr_buf *buf =
2353 		(struct qdf_dp_trace_ptr_buf *)record->data;
2354 	bool is_free_pkt_ptr_record = false;
2355 
2356 	if ((record->code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ||
2357 	    (record->code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD))
2358 		is_free_pkt_ptr_record = true;
2359 
2360 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2361 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2362 					 index, info, record);
2363 
2364 	if (loc < sizeof(prepend_str))
2365 		scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2366 			  "[msdu id %d %s %d]",
2367 			  buf->msdu_id,
2368 			  is_free_pkt_ptr_record ? "status" : "vdev_id",
2369 			  buf->status);
2370 
2371 	if (info & QDF_DP_TRACE_RECORD_INFO_LIVE) {
2372 		/* In live mode donot dump the contents of the cookie */
2373 		DPTRACE_PRINT("%s", prepend_str);
2374 	} else {
2375 		dump_dp_hex_trace(prepend_str, (uint8_t *)&buf->cookie,
2376 			sizeof(buf->cookie));
2377 	}
2378 }
2379 qdf_export_symbol(qdf_dp_display_ptr_record);
2380 
2381 static
qdf_dp_get_pkt_proto_type(qdf_nbuf_t nbuf)2382 enum qdf_proto_type qdf_dp_get_pkt_proto_type(qdf_nbuf_t nbuf)
2383 {
2384 	uint8_t pkt_type;
2385 
2386 	if (!nbuf)
2387 		return QDF_PROTO_TYPE_MAX;
2388 
2389 	if (qdf_nbuf_data_is_dns_query(nbuf) ||
2390 	    qdf_nbuf_data_is_dns_response(nbuf))
2391 		return QDF_PROTO_TYPE_DNS;
2392 
2393 	pkt_type = QDF_NBUF_CB_GET_PACKET_TYPE(nbuf);
2394 
2395 	switch (pkt_type) {
2396 	case QDF_NBUF_CB_PACKET_TYPE_EAPOL:
2397 		return QDF_PROTO_TYPE_EAPOL;
2398 	case QDF_NBUF_CB_PACKET_TYPE_ARP:
2399 		return QDF_PROTO_TYPE_ARP;
2400 	case QDF_NBUF_CB_PACKET_TYPE_DHCP:
2401 		return QDF_PROTO_TYPE_DHCP;
2402 	default:
2403 		return QDF_PROTO_TYPE_MAX;
2404 	}
2405 }
2406 
2407 static
qdf_dp_get_pkt_subtype(qdf_nbuf_t nbuf,enum qdf_proto_type pkt_type)2408 enum qdf_proto_subtype qdf_dp_get_pkt_subtype(qdf_nbuf_t nbuf,
2409 					      enum qdf_proto_type pkt_type)
2410 {
2411 	switch (pkt_type) {
2412 	case QDF_PROTO_TYPE_EAPOL:
2413 		return qdf_nbuf_get_eapol_subtype(nbuf);
2414 	case QDF_PROTO_TYPE_ARP:
2415 		return qdf_nbuf_get_arp_subtype(nbuf);
2416 	case QDF_PROTO_TYPE_DHCP:
2417 		return qdf_nbuf_get_dhcp_subtype(nbuf);
2418 	case QDF_PROTO_TYPE_DNS:
2419 		return (qdf_nbuf_data_is_dns_query(nbuf)) ?
2420 				QDF_PROTO_DNS_QUERY : QDF_PROTO_DNS_RES;
2421 	default:
2422 		return QDF_PROTO_INVALID;
2423 	}
2424 }
2425 
2426 static
qdf_dp_proto_log_enable_check(enum qdf_proto_type pkt_type,uint16_t status)2427 bool qdf_dp_proto_log_enable_check(enum qdf_proto_type pkt_type,
2428 				   uint16_t status)
2429 {
2430 	if (pkt_type == QDF_PROTO_TYPE_MAX)
2431 		return false;
2432 
2433 	switch (pkt_type) {
2434 	case QDF_PROTO_TYPE_EAPOL:
2435 		return qdf_dp_get_proto_event_bitmap() &
2436 				QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
2437 	case QDF_PROTO_TYPE_DHCP:
2438 		return qdf_dp_get_proto_event_bitmap() &
2439 				QDF_NBUF_PKT_TRAC_TYPE_DHCP;
2440 	case QDF_PROTO_TYPE_ARP:
2441 		if (status == QDF_TX_RX_STATUS_OK)
2442 			return false;
2443 		else
2444 			return qdf_dp_get_proto_event_bitmap() &
2445 					QDF_NBUF_PKT_TRAC_TYPE_ARP;
2446 	case QDF_PROTO_TYPE_DNS:
2447 		if (status == QDF_TX_RX_STATUS_OK)
2448 			return false;
2449 		else
2450 			return qdf_dp_get_proto_event_bitmap() &
2451 					QDF_NBUF_PKT_TRAC_TYPE_DNS;
2452 	default:
2453 		return false;
2454 	}
2455 }
2456 
qdf_dp_track_noack_check(qdf_nbuf_t nbuf,enum qdf_proto_subtype * subtype)2457 void qdf_dp_track_noack_check(qdf_nbuf_t nbuf, enum qdf_proto_subtype *subtype)
2458 {
2459 	enum qdf_proto_type pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
2460 	uint16_t dp_track = 0;
2461 
2462 	switch (pkt_type) {
2463 	case QDF_PROTO_TYPE_EAPOL:
2464 		dp_track = qdf_dp_get_proto_bitmap() &
2465 				QDF_NBUF_PKT_TRAC_TYPE_EAPOL;
2466 		break;
2467 	case QDF_PROTO_TYPE_DHCP:
2468 		dp_track = qdf_dp_get_proto_bitmap() &
2469 				QDF_NBUF_PKT_TRAC_TYPE_DHCP;
2470 		break;
2471 	case QDF_PROTO_TYPE_ARP:
2472 		dp_track = qdf_dp_get_proto_bitmap() &
2473 					QDF_NBUF_PKT_TRAC_TYPE_ARP;
2474 		break;
2475 	case QDF_PROTO_TYPE_DNS:
2476 		dp_track = qdf_dp_get_proto_bitmap() &
2477 					QDF_NBUF_PKT_TRAC_TYPE_DNS;
2478 		break;
2479 	default:
2480 		break;
2481 	}
2482 
2483 	if (!dp_track) {
2484 		*subtype = QDF_PROTO_INVALID;
2485 		return;
2486 	}
2487 
2488 	*subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type);
2489 }
2490 qdf_export_symbol(qdf_dp_track_noack_check);
2491 
qdf_dp_get_status_from_a_status(uint8_t status)2492 enum qdf_dp_tx_rx_status qdf_dp_get_status_from_a_status(uint8_t status)
2493 {
2494 	if (status == QDF_A_STATUS_ERROR)
2495 		return QDF_TX_RX_STATUS_INVALID;
2496 	else if (status == QDF_A_STATUS_OK)
2497 		return QDF_TX_RX_STATUS_OK;
2498 	else
2499 		return QDF_TX_RX_STATUS_MAX;
2500 }
2501 qdf_export_symbol(qdf_dp_get_status_from_a_status);
2502 
qdf_dp_trace_ptr(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t size,uint16_t msdu_id,uint16_t buf_arg_status,enum qdf_dp_tx_rx_status qdf_tx_status,enum QDF_OPMODE op_mode)2503 void qdf_dp_trace_ptr(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code,
2504 		uint8_t pdev_id, uint8_t *data, uint8_t size,
2505 		uint16_t msdu_id, uint16_t buf_arg_status,
2506 		enum qdf_dp_tx_rx_status qdf_tx_status,
2507 		enum QDF_OPMODE op_mode)
2508 {
2509 	struct qdf_dp_trace_ptr_buf buf;
2510 	int buf_size = sizeof(struct qdf_dp_trace_ptr_buf);
2511 	enum qdf_proto_type pkt_type;
2512 	enum qdf_proto_subtype subtype;
2513 
2514 	pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
2515 	if ((code == QDF_DP_TRACE_FREE_PACKET_PTR_RECORD ||
2516 	     code == QDF_DP_TRACE_LI_DP_FREE_PACKET_PTR_RECORD) &&
2517 	    qdf_dp_proto_log_enable_check(pkt_type, qdf_tx_status)) {
2518 		subtype = qdf_dp_get_pkt_subtype(nbuf, pkt_type);
2519 		qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
2520 					 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
2521 					 pkt_type, subtype,
2522 					 QDF_TX, msdu_id, qdf_tx_status);
2523 		qdf_fill_wlan_connectivity_log(pkt_type, subtype,
2524 					       QDF_TX, qdf_tx_status, op_mode,
2525 					       QDF_NBUF_CB_TX_VDEV_CTX(nbuf),
2526 					       nbuf->data,
2527 					       qdf_nbuf_tx_get_band(nbuf));
2528 		qdf_log_pkt_cstats(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
2529 				   nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
2530 				   pkt_type, subtype, QDF_TX,
2531 				   qdf_tx_status, QDF_NBUF_CB_TX_VDEV_CTX(nbuf),
2532 				   op_mode);
2533 	}
2534 
2535 	if (qdf_dp_enable_check(nbuf, code, QDF_TX) == false)
2536 		return;
2537 
2538 	if (buf_size > QDF_DP_TRACE_RECORD_SIZE)
2539 		QDF_BUG(0);
2540 
2541 	qdf_mem_copy(&buf.cookie, data, size);
2542 	buf.msdu_id = msdu_id;
2543 	buf.status = buf_arg_status;
2544 	qdf_dp_add_record(code, pdev_id, (uint8_t *)&buf, buf_size, NULL, 0,
2545 			  QDF_NBUF_CB_DP_TRACE_PRINT(nbuf));
2546 }
2547 qdf_export_symbol(qdf_dp_trace_ptr);
2548 
qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf,uint8_t pdev_id,enum QDF_DP_TRACE_ID code,uint16_t msdu_id,enum qdf_proto_dir dir)2549 void qdf_dp_trace_data_pkt(qdf_nbuf_t nbuf, uint8_t pdev_id,
2550 			   enum QDF_DP_TRACE_ID code, uint16_t msdu_id,
2551 			   enum qdf_proto_dir dir)
2552 {
2553 	struct qdf_dp_trace_data_buf buf;
2554 	enum qdf_proto_type pkt_type;
2555 
2556 	pkt_type = qdf_dp_get_pkt_proto_type(nbuf);
2557 	if (code == QDF_DP_TRACE_DROP_PACKET_RECORD &&
2558 	    qdf_dp_proto_log_enable_check(pkt_type, QDF_TX_RX_STATUS_DROP))
2559 		qdf_dp_log_proto_pkt_info(nbuf->data + QDF_NBUF_SRC_MAC_OFFSET,
2560 					 nbuf->data + QDF_NBUF_DEST_MAC_OFFSET,
2561 					 pkt_type,
2562 					 qdf_dp_get_pkt_subtype(nbuf, pkt_type),
2563 					 QDF_TX, msdu_id,
2564 					 QDF_TX_RX_STATUS_DROP);
2565 
2566 	buf.msdu_id = msdu_id;
2567 	if (!qdf_dp_enable_check(nbuf, code, dir))
2568 		return;
2569 
2570 	qdf_dp_add_record(code, pdev_id,
2571 			  nbuf ? qdf_nbuf_data(nbuf) : NULL,
2572 			  nbuf ? nbuf->len - nbuf->data_len : 0,
2573 			  (uint8_t *)&buf, sizeof(struct qdf_dp_trace_data_buf),
2574 			  (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
2575 }
2576 
2577 qdf_export_symbol(qdf_dp_trace_data_pkt);
2578 
qdf_dp_display_record(struct qdf_dp_trace_record_s * record,uint16_t index,uint8_t pdev_id,uint8_t info)2579 void qdf_dp_display_record(struct qdf_dp_trace_record_s *record,
2580 			   uint16_t index, uint8_t pdev_id, uint8_t info)
2581 {
2582 	int loc;
2583 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2584 
2585 	if (!(pdev_id == QDF_TRACE_DEFAULT_PDEV_ID ||
2586 		pdev_id == record->pdev_id))
2587 		return;
2588 
2589 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2590 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2591 					 index, info, record);
2592 
2593 	switch (record->code) {
2594 	case  QDF_DP_TRACE_HDD_TX_TIMEOUT:
2595 		DPTRACE_PRINT(" %s: HDD TX Timeout", prepend_str);
2596 		break;
2597 	case  QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
2598 		DPTRACE_PRINT(" %s: HDD SoftAP TX Timeout", prepend_str);
2599 		break;
2600 	case  QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
2601 		DPTRACE_PRINT(" %s: CE Fast Packet Error", prepend_str);
2602 		break;
2603 	case QDF_DP_TRACE_LI_DP_NULL_RX_PACKET_RECORD:
2604 	default:
2605 		dump_dp_hex_trace(prepend_str, record->data, record->size);
2606 		break;
2607 	};
2608 }
2609 qdf_export_symbol(qdf_dp_display_record);
2610 
2611 void
qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s * record,uint16_t rec_index,uint8_t pdev_id,uint8_t info)2612 qdf_dp_display_data_pkt_record(struct qdf_dp_trace_record_s *record,
2613 			       uint16_t rec_index, uint8_t pdev_id,
2614 			       uint8_t info)
2615 {
2616 	int loc;
2617 	char prepend_str[DP_TRACE_META_DATA_STRLEN + 10];
2618 	struct qdf_dp_trace_data_buf *buf =
2619 		(struct qdf_dp_trace_data_buf *)record->data;
2620 
2621 	qdf_mem_zero(prepend_str, sizeof(prepend_str));
2622 
2623 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2624 					 rec_index, info, record);
2625 	if (loc < sizeof(prepend_str))
2626 		loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2627 				"[%d]", buf->msdu_id);
2628 	dump_dp_hex_trace(prepend_str,
2629 			  &record->data[sizeof(struct qdf_dp_trace_data_buf)],
2630 			  record->size);
2631 }
2632 
qdf_dp_trace(qdf_nbuf_t nbuf,enum QDF_DP_TRACE_ID code,uint8_t pdev_id,uint8_t * data,uint8_t size,enum qdf_proto_dir dir)2633 void qdf_dp_trace(qdf_nbuf_t nbuf, enum QDF_DP_TRACE_ID code, uint8_t pdev_id,
2634 	uint8_t *data, uint8_t size, enum qdf_proto_dir dir)
2635 {
2636 
2637 	if (qdf_dp_enable_check(nbuf, code, dir) == false)
2638 		return;
2639 
2640 	qdf_dp_add_record(code, pdev_id, nbuf ? qdf_nbuf_data(nbuf) : NULL,
2641 			  size, NULL, 0,
2642 			  (nbuf) ? QDF_NBUF_CB_DP_TRACE_PRINT(nbuf) : false);
2643 }
2644 qdf_export_symbol(qdf_dp_trace);
2645 
qdf_dp_trace_spin_lock_init(void)2646 void qdf_dp_trace_spin_lock_init(void)
2647 {
2648 	spin_lock_init(&l_dp_trace_lock);
2649 }
2650 qdf_export_symbol(qdf_dp_trace_spin_lock_init);
2651 
qdf_dp_trace_disable_live_mode(void)2652 void qdf_dp_trace_disable_live_mode(void)
2653 {
2654 	g_qdf_dp_trace_data.force_live_mode = 0;
2655 }
2656 qdf_export_symbol(qdf_dp_trace_disable_live_mode);
2657 
qdf_dp_trace_enable_live_mode(void)2658 void qdf_dp_trace_enable_live_mode(void)
2659 {
2660 	g_qdf_dp_trace_data.force_live_mode = 1;
2661 }
2662 qdf_export_symbol(qdf_dp_trace_enable_live_mode);
2663 
qdf_dp_trace_clear_buffer(void)2664 void qdf_dp_trace_clear_buffer(void)
2665 {
2666 	g_qdf_dp_trace_data.head = INVALID_QDF_DP_TRACE_ADDR;
2667 	g_qdf_dp_trace_data.tail = INVALID_QDF_DP_TRACE_ADDR;
2668 	g_qdf_dp_trace_data.num = 0;
2669 	g_qdf_dp_trace_data.dump_counter = 0;
2670 	g_qdf_dp_trace_data.num_records_to_dump = MAX_QDF_DP_TRACE_RECORDS;
2671 	if (g_qdf_dp_trace_data.enable)
2672 		memset(g_qdf_dp_trace_tbl, 0,
2673 		       MAX_QDF_DP_TRACE_RECORDS *
2674 		       sizeof(struct qdf_dp_trace_record_s));
2675 }
2676 qdf_export_symbol(qdf_dp_trace_clear_buffer);
2677 
qdf_dp_trace_dump_stats(void)2678 void qdf_dp_trace_dump_stats(void)
2679 {
2680 		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)",
2681 			      g_qdf_dp_trace_data.tx_count,
2682 			      g_qdf_dp_trace_data.rx_count,
2683 			      g_qdf_dp_trace_data.icmp_req,
2684 			      g_qdf_dp_trace_data.icmp_resp,
2685 			      g_qdf_dp_trace_data.arp_req,
2686 			      g_qdf_dp_trace_data.arp_resp,
2687 			      g_qdf_dp_trace_data.icmpv6_req,
2688 			      g_qdf_dp_trace_data.icmpv6_resp,
2689 			      g_qdf_dp_trace_data.icmpv6_ns,
2690 			      g_qdf_dp_trace_data.icmpv6_na,
2691 			      g_qdf_dp_trace_data.icmpv6_rs,
2692 			      g_qdf_dp_trace_data.icmpv6_ra,
2693 			      g_qdf_dp_trace_data.dhcp_disc,
2694 			      g_qdf_dp_trace_data.dhcp_off,
2695 			      g_qdf_dp_trace_data.dhcp_req,
2696 			      g_qdf_dp_trace_data.dhcp_ack,
2697 			      g_qdf_dp_trace_data.dhcp_nack,
2698 			      g_qdf_dp_trace_data.dhcp_others,
2699 			      g_qdf_dp_trace_data.eapol_m1,
2700 			      g_qdf_dp_trace_data.eapol_m2,
2701 			      g_qdf_dp_trace_data.eapol_m3,
2702 			      g_qdf_dp_trace_data.eapol_m4,
2703 			      g_qdf_dp_trace_data.eapol_others);
2704 }
2705 qdf_export_symbol(qdf_dp_trace_dump_stats);
2706 
2707 /**
2708  * qdf_dpt_dump_hex_trace_debugfs() - read data in file
2709  * @file: file to read
2710  * @str: string to prepend the hexdump with.
2711  * @buf: buffer which contains data to be written
2712  * @buf_len: defines the size of the data to be written
2713  *
2714  * Return: None
2715  */
qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file,char * str,uint8_t * buf,uint8_t buf_len)2716 static void qdf_dpt_dump_hex_trace_debugfs(qdf_debugfs_file_t file,
2717 				char *str, uint8_t *buf, uint8_t buf_len)
2718 {
2719 	unsigned char linebuf[BUFFER_SIZE];
2720 	const u8 *ptr = buf;
2721 	int i, linelen, remaining = buf_len;
2722 
2723 	/* Dump the bytes in the last line */
2724 	for (i = 0; i < buf_len; i += ROW_SIZE) {
2725 		linelen = min(remaining, ROW_SIZE);
2726 		remaining -= ROW_SIZE;
2727 
2728 		hex_dump_to_buffer(ptr + i, linelen, ROW_SIZE, 1,
2729 				linebuf, sizeof(linebuf), false);
2730 
2731 		qdf_debugfs_printf(file, "%s %s\n", str, linebuf);
2732 	}
2733 }
2734 
2735 /**
2736  * qdf_dpt_display_proto_pkt_debugfs() - display proto packet
2737  * @file: file to read
2738  * @record: dptrace record
2739  * @index: index
2740  *
2741  * Return: none
2742  */
qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2743 static void qdf_dpt_display_proto_pkt_debugfs(qdf_debugfs_file_t file,
2744 				struct qdf_dp_trace_record_s *record,
2745 				uint32_t index)
2746 {
2747 	int loc;
2748 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2749 	struct qdf_dp_trace_proto_buf *buf =
2750 		(struct qdf_dp_trace_proto_buf *)record->data;
2751 
2752 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2753 					 index, 0, record);
2754 	qdf_debugfs_printf(file, "%s [%d] [%s] SA: "
2755 			   QDF_MAC_ADDR_FMT " %s DA: "
2756 			   QDF_MAC_ADDR_FMT,
2757 			   prepend_str,
2758 			   buf->cmn_info.vdev_id,
2759 			   qdf_dp_subtype_to_str(buf->cmn_info.subtype),
2760 			   QDF_MAC_ADDR_REF(buf->sa.bytes),
2761 			   qdf_dp_dir_to_str(buf->dir),
2762 			   QDF_MAC_ADDR_REF(buf->da.bytes));
2763 	qdf_debugfs_printf(file, "\n");
2764 }
2765 
2766 /**
2767  * qdf_dpt_display_mgmt_pkt_debugfs() - display mgmt packet
2768  * @file: file to read
2769  * @record: dptrace record
2770  * @index: index
2771  *
2772  * Return: none
2773  */
qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2774 static void qdf_dpt_display_mgmt_pkt_debugfs(qdf_debugfs_file_t file,
2775 				struct qdf_dp_trace_record_s *record,
2776 				uint32_t index)
2777 {
2778 
2779 	int loc;
2780 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2781 	struct qdf_dp_trace_mgmt_buf *buf =
2782 		(struct qdf_dp_trace_mgmt_buf *)record->data;
2783 
2784 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2785 					 index, 0, record);
2786 
2787 	qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
2788 			   prepend_str,
2789 			   buf->vdev_id,
2790 			   qdf_dp_type_to_str(buf->type),
2791 			   qdf_dp_subtype_to_str(buf->subtype));
2792 }
2793 
2794 /**
2795  * qdf_dpt_display_event_record_debugfs() - display event records
2796  * @file: file to read
2797  * @record: dptrace record
2798  * @index: index
2799  *
2800  * Return: none
2801  */
qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2802 static void qdf_dpt_display_event_record_debugfs(qdf_debugfs_file_t file,
2803 				struct qdf_dp_trace_record_s *record,
2804 				uint32_t index)
2805 {
2806 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2807 	struct qdf_dp_trace_event_buf *buf =
2808 		(struct qdf_dp_trace_event_buf *)record->data;
2809 
2810 	qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2811 				   index, 0, record);
2812 	qdf_debugfs_printf(file, "%s [%d] [%s %s]\n",
2813 			   prepend_str,
2814 			   buf->vdev_id,
2815 			   qdf_dp_type_to_str(buf->type),
2816 			   qdf_dp_subtype_to_str(buf->subtype));
2817 }
2818 
2819 /**
2820  * qdf_dpt_display_ptr_record_debugfs() - display record ptr
2821  * @file: file to read
2822  * @record: dptrace record
2823  * @index: index
2824  *
2825  * Return: none
2826  */
qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2827 static void qdf_dpt_display_ptr_record_debugfs(qdf_debugfs_file_t file,
2828 				struct qdf_dp_trace_record_s *record,
2829 				uint32_t index)
2830 {
2831 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2832 	int loc;
2833 	struct qdf_dp_trace_ptr_buf *buf =
2834 		(struct qdf_dp_trace_ptr_buf *)record->data;
2835 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2836 					 index, 0, record);
2837 
2838 	if (loc < sizeof(prepend_str))
2839 		scnprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2840 			  "[msdu id %d %s %d]",
2841 			  buf->msdu_id,
2842 			  (record->code ==
2843 				QDF_DP_TRACE_FREE_PACKET_PTR_RECORD) ?
2844 			  "status" : "vdev_id",
2845 			  buf->status);
2846 
2847 	qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
2848 				       (uint8_t *)&buf->cookie,
2849 				       sizeof(buf->cookie));
2850 }
2851 
2852 /**
2853  * qdf_dpt_display_record_debugfs() - display record
2854  * @file: file to read
2855  * @record: dptrace record
2856  * @index: index
2857  *
2858  * Return: none
2859  */
qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file,struct qdf_dp_trace_record_s * record,uint32_t index)2860 static void qdf_dpt_display_record_debugfs(qdf_debugfs_file_t file,
2861 				struct qdf_dp_trace_record_s *record,
2862 				uint32_t index)
2863 {
2864 	int loc;
2865 	char prepend_str[QDF_DP_TRACE_PREPEND_STR_SIZE];
2866 	struct qdf_dp_trace_data_buf *buf =
2867 		(struct qdf_dp_trace_data_buf *)record->data;
2868 
2869 	loc = qdf_dp_trace_fill_meta_str(prepend_str, sizeof(prepend_str),
2870 					 index, 0, record);
2871 	if (loc < sizeof(prepend_str))
2872 		loc += snprintf(&prepend_str[loc], sizeof(prepend_str) - loc,
2873 				"[%d]", buf->msdu_id);
2874 	qdf_dpt_dump_hex_trace_debugfs(file, prepend_str,
2875 				       record->data, record->size);
2876 }
2877 
qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file,enum qdf_dpt_debugfs_state state)2878 uint32_t qdf_dpt_get_curr_pos_debugfs(qdf_debugfs_file_t file,
2879 				      enum qdf_dpt_debugfs_state state)
2880 {
2881 	uint32_t i = 0;
2882 	uint32_t tail;
2883 	uint32_t count = g_qdf_dp_trace_data.num;
2884 
2885 	if (!g_qdf_dp_trace_data.enable) {
2886 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
2887 		  "%s: Tracing Disabled", __func__);
2888 		return QDF_STATUS_E_EMPTY;
2889 	}
2890 
2891 	if (!count) {
2892 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_DEBUG,
2893 		  "%s: no packets", __func__);
2894 		return QDF_STATUS_E_EMPTY;
2895 	}
2896 
2897 	if (state == QDF_DPT_DEBUGFS_STATE_SHOW_IN_PROGRESS)
2898 		return g_qdf_dp_trace_data.curr_pos;
2899 
2900 	qdf_debugfs_printf(file,
2901 		"DPT: config - bitmap 0x%x verb %u #rec %u rec_requested %u live_config %u thresh %u time_limit %u\n",
2902 		g_qdf_dp_trace_data.proto_bitmap,
2903 		g_qdf_dp_trace_data.verbosity,
2904 		g_qdf_dp_trace_data.no_of_record,
2905 		g_qdf_dp_trace_data.num_records_to_dump,
2906 		g_qdf_dp_trace_data.live_mode_config,
2907 		g_qdf_dp_trace_data.high_tput_thresh,
2908 		g_qdf_dp_trace_data.thresh_time_limit);
2909 
2910 	qdf_debugfs_printf(file,
2911 		"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",
2912 		g_qdf_dp_trace_data.icmp_req,
2913 		g_qdf_dp_trace_data.icmp_resp,
2914 		g_qdf_dp_trace_data.arp_req,
2915 		g_qdf_dp_trace_data.arp_resp,
2916 		g_qdf_dp_trace_data.icmpv6_req,
2917 		g_qdf_dp_trace_data.icmpv6_resp,
2918 		g_qdf_dp_trace_data.icmpv6_ns,
2919 		g_qdf_dp_trace_data.icmpv6_na,
2920 		g_qdf_dp_trace_data.icmpv6_rs,
2921 		g_qdf_dp_trace_data.icmpv6_ra,
2922 		g_qdf_dp_trace_data.dhcp_disc,
2923 		g_qdf_dp_trace_data.dhcp_off,
2924 		g_qdf_dp_trace_data.dhcp_req,
2925 		g_qdf_dp_trace_data.dhcp_ack,
2926 		g_qdf_dp_trace_data.dhcp_nack,
2927 		g_qdf_dp_trace_data.dhcp_others,
2928 		g_qdf_dp_trace_data.eapol_m1,
2929 		g_qdf_dp_trace_data.eapol_m2,
2930 		g_qdf_dp_trace_data.eapol_m3,
2931 		g_qdf_dp_trace_data.eapol_m4,
2932 		g_qdf_dp_trace_data.eapol_others);
2933 
2934 	qdf_debugfs_printf(file,
2935 		"DPT: Total Records: %d, Head: %d, Tail: %d\n",
2936 		g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
2937 		g_qdf_dp_trace_data.tail);
2938 
2939 	spin_lock_bh(&l_dp_trace_lock);
2940 	if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
2941 		i = g_qdf_dp_trace_data.head;
2942 		tail = g_qdf_dp_trace_data.tail;
2943 
2944 		if (count > g_qdf_dp_trace_data.num)
2945 			count = g_qdf_dp_trace_data.num;
2946 
2947 		if (tail >= (count - 1))
2948 			i = tail - count + 1;
2949 		else if (count != MAX_QDF_DP_TRACE_RECORDS)
2950 			i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
2951 						     tail);
2952 		g_qdf_dp_trace_data.curr_pos = 0;
2953 		g_qdf_dp_trace_data.saved_tail = tail;
2954 	}
2955 	spin_unlock_bh(&l_dp_trace_lock);
2956 
2957 	return g_qdf_dp_trace_data.saved_tail;
2958 }
2959 qdf_export_symbol(qdf_dpt_get_curr_pos_debugfs);
2960 
qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file,uint32_t curr_pos)2961 QDF_STATUS qdf_dpt_dump_stats_debugfs(qdf_debugfs_file_t file,
2962 				      uint32_t curr_pos)
2963 {
2964 	struct qdf_dp_trace_record_s p_record;
2965 	uint32_t i = curr_pos;
2966 	uint16_t num_records_to_dump = g_qdf_dp_trace_data.num_records_to_dump;
2967 
2968 	if (!g_qdf_dp_trace_data.enable) {
2969 		QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2970 			  "%s: Tracing Disabled", __func__);
2971 		return QDF_STATUS_E_FAILURE;
2972 	}
2973 
2974 	if (num_records_to_dump > g_qdf_dp_trace_data.num)
2975 		num_records_to_dump = g_qdf_dp_trace_data.num;
2976 
2977 	/*
2978 	 * Max dp trace record size should always be less than
2979 	 * QDF_DP_TRACE_PREPEND_STR_SIZE(100) + BUFFER_SIZE(121).
2980 	 */
2981 	if (WARN_ON(QDF_DP_TRACE_MAX_RECORD_SIZE <
2982 				QDF_DP_TRACE_PREPEND_STR_SIZE + BUFFER_SIZE))
2983 		return QDF_STATUS_E_FAILURE;
2984 
2985 	spin_lock_bh(&l_dp_trace_lock);
2986 	p_record = g_qdf_dp_trace_tbl[i];
2987 	spin_unlock_bh(&l_dp_trace_lock);
2988 
2989 	for (;; ) {
2990 		/*
2991 		 * Initially we get file as 1 page size, and
2992 		 * if remaining size in file is less than one record max size,
2993 		 * then return so that it gets an extra page.
2994 		 */
2995 		if ((file->size - file->count) < QDF_DP_TRACE_MAX_RECORD_SIZE) {
2996 			spin_lock_bh(&l_dp_trace_lock);
2997 			g_qdf_dp_trace_data.curr_pos = i;
2998 			spin_unlock_bh(&l_dp_trace_lock);
2999 			return QDF_STATUS_E_FAILURE;
3000 		}
3001 
3002 		switch (p_record.code) {
3003 		case QDF_DP_TRACE_TXRX_PACKET_PTR_RECORD:
3004 		case QDF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD:
3005 		case QDF_DP_TRACE_FREE_PACKET_PTR_RECORD:
3006 			qdf_dpt_display_ptr_record_debugfs(file, &p_record, i);
3007 			break;
3008 
3009 		case QDF_DP_TRACE_EAPOL_PACKET_RECORD:
3010 		case QDF_DP_TRACE_DHCP_PACKET_RECORD:
3011 		case QDF_DP_TRACE_ARP_PACKET_RECORD:
3012 		case QDF_DP_TRACE_ICMP_PACKET_RECORD:
3013 		case QDF_DP_TRACE_ICMPv6_PACKET_RECORD:
3014 			qdf_dpt_display_proto_pkt_debugfs(file, &p_record, i);
3015 			break;
3016 
3017 		case QDF_DP_TRACE_TX_CREDIT_RECORD:
3018 			qdf_dpt_display_credit_record_debugfs(file, &p_record,
3019 							      i);
3020 			break;
3021 
3022 		case QDF_DP_TRACE_MGMT_PACKET_RECORD:
3023 			qdf_dpt_display_mgmt_pkt_debugfs(file, &p_record, i);
3024 			break;
3025 
3026 		case QDF_DP_TRACE_EVENT_RECORD:
3027 			qdf_dpt_display_event_record_debugfs(file, &p_record,
3028 							     i);
3029 			break;
3030 
3031 		case QDF_DP_TRACE_HDD_TX_TIMEOUT:
3032 			qdf_debugfs_printf(
3033 					file, "DPT: %04d: %llu %s\n",
3034 					i, p_record.time,
3035 					qdf_dp_code_to_string(p_record.code));
3036 			qdf_debugfs_printf(file, "HDD TX Timeout\n");
3037 			break;
3038 
3039 		case QDF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT:
3040 			qdf_debugfs_printf(
3041 					file, "DPT: %04d: %llu %s\n",
3042 					i, p_record.time,
3043 					qdf_dp_code_to_string(p_record.code));
3044 			qdf_debugfs_printf(file, "HDD SoftAP TX Timeout\n");
3045 			break;
3046 
3047 		case QDF_DP_TRACE_CE_FAST_PACKET_ERR_RECORD:
3048 			qdf_debugfs_printf(
3049 					file, "DPT: %04d: %llu %s\n",
3050 					i, p_record.time,
3051 					qdf_dp_code_to_string(p_record.code));
3052 			qdf_debugfs_printf(file, "CE Fast Packet Error\n");
3053 			break;
3054 
3055 		case QDF_DP_TRACE_MAX:
3056 			qdf_debugfs_printf(file,
3057 				"%s: QDF_DP_TRACE_MAX event should not be generated\n",
3058 				__func__);
3059 			break;
3060 
3061 		case QDF_DP_TRACE_HDD_TX_PACKET_RECORD:
3062 		case QDF_DP_TRACE_HDD_RX_PACKET_RECORD:
3063 		case QDF_DP_TRACE_TX_PACKET_RECORD:
3064 		case QDF_DP_TRACE_RX_PACKET_RECORD:
3065 		case QDF_DP_TRACE_LI_DP_TX_PACKET_RECORD:
3066 		case QDF_DP_TRACE_LI_DP_RX_PACKET_RECORD:
3067 
3068 		default:
3069 			qdf_dpt_display_record_debugfs(file, &p_record, i);
3070 			break;
3071 		}
3072 
3073 		if (++g_qdf_dp_trace_data.dump_counter == num_records_to_dump)
3074 			break;
3075 
3076 		spin_lock_bh(&l_dp_trace_lock);
3077 		if (i == 0)
3078 			i = MAX_QDF_DP_TRACE_RECORDS;
3079 
3080 		i -= 1;
3081 		p_record = g_qdf_dp_trace_tbl[i];
3082 		spin_unlock_bh(&l_dp_trace_lock);
3083 	}
3084 
3085 	g_qdf_dp_trace_data.dump_counter = 0;
3086 
3087 	return QDF_STATUS_SUCCESS;
3088 }
3089 qdf_export_symbol(qdf_dpt_dump_stats_debugfs);
3090 
qdf_dpt_set_value_debugfs(uint8_t proto_bitmap,uint8_t no_of_record,uint8_t verbosity,uint16_t num_records_to_dump)3091 void qdf_dpt_set_value_debugfs(uint8_t proto_bitmap, uint8_t no_of_record,
3092 			    uint8_t verbosity, uint16_t num_records_to_dump)
3093 {
3094 	if (g_qdf_dp_trace_data.enable) {
3095 		g_qdf_dp_trace_data.proto_bitmap = proto_bitmap;
3096 		g_qdf_dp_trace_data.no_of_record = no_of_record;
3097 		g_qdf_dp_trace_data.verbosity    = verbosity;
3098 		g_qdf_dp_trace_data.num_records_to_dump = num_records_to_dump;
3099 	}
3100 }
3101 qdf_export_symbol(qdf_dpt_set_value_debugfs);
3102 
3103 
qdf_dp_trace_dump_all(uint32_t count,uint8_t pdev_id)3104 void qdf_dp_trace_dump_all(uint32_t count, uint8_t pdev_id)
3105 {
3106 	struct qdf_dp_trace_record_s p_record;
3107 	int32_t i, tail;
3108 
3109 	if (!g_qdf_dp_trace_data.enable) {
3110 		DPTRACE_PRINT("Tracing Disabled");
3111 		return;
3112 	}
3113 
3114 	DPTRACE_PRINT(
3115 		"DPT: config - bitmap 0x%x verb %u #rec %u live_config %u thresh %u time_limit %u",
3116 		g_qdf_dp_trace_data.proto_bitmap,
3117 		g_qdf_dp_trace_data.verbosity,
3118 		g_qdf_dp_trace_data.no_of_record,
3119 		g_qdf_dp_trace_data.live_mode_config,
3120 		g_qdf_dp_trace_data.high_tput_thresh,
3121 		g_qdf_dp_trace_data.thresh_time_limit);
3122 
3123 	qdf_dp_trace_dump_stats();
3124 
3125 	DPTRACE_PRINT("DPT: Total Records: %d, Head: %d, Tail: %d",
3126 		      g_qdf_dp_trace_data.num, g_qdf_dp_trace_data.head,
3127 		      g_qdf_dp_trace_data.tail);
3128 
3129 	/* acquire the lock so that only one thread at a time can read
3130 	 * the ring buffer
3131 	 */
3132 	spin_lock_bh(&l_dp_trace_lock);
3133 
3134 	if (g_qdf_dp_trace_data.head != INVALID_QDF_DP_TRACE_ADDR) {
3135 		i = g_qdf_dp_trace_data.head;
3136 		tail = g_qdf_dp_trace_data.tail;
3137 
3138 		if (count) {
3139 			if (count > g_qdf_dp_trace_data.num)
3140 				count = g_qdf_dp_trace_data.num;
3141 			if (tail >= (count - 1))
3142 				i = tail - count + 1;
3143 			else if (count != MAX_QDF_DP_TRACE_RECORDS)
3144 				i = MAX_QDF_DP_TRACE_RECORDS - ((count - 1) -
3145 							     tail);
3146 		}
3147 
3148 		p_record = g_qdf_dp_trace_tbl[i];
3149 		spin_unlock_bh(&l_dp_trace_lock);
3150 		for (;; ) {
3151 			qdf_dp_trace_cb_table[p_record.code](&p_record,
3152 							(uint16_t)i, pdev_id, false);
3153 			if (i == tail)
3154 				break;
3155 			i += 1;
3156 
3157 			spin_lock_bh(&l_dp_trace_lock);
3158 			if (MAX_QDF_DP_TRACE_RECORDS == i)
3159 				i = 0;
3160 
3161 			p_record = g_qdf_dp_trace_tbl[i];
3162 			spin_unlock_bh(&l_dp_trace_lock);
3163 		}
3164 	} else {
3165 		spin_unlock_bh(&l_dp_trace_lock);
3166 	}
3167 }
3168 qdf_export_symbol(qdf_dp_trace_dump_all);
3169 
qdf_dp_trace_throttle_live_mode(bool high_bw_request)3170 void qdf_dp_trace_throttle_live_mode(bool high_bw_request)
3171 {
3172 	static int bw_interval_counter;
3173 
3174 	if (g_qdf_dp_trace_data.enable == false ||
3175 		g_qdf_dp_trace_data.live_mode_config == false)
3176 		return;
3177 
3178 	if (high_bw_request) {
3179 		g_qdf_dp_trace_data.live_mode = 0;
3180 		bw_interval_counter = 0;
3181 		return;
3182 	}
3183 
3184 	bw_interval_counter++;
3185 
3186 	if (0 == (bw_interval_counter %
3187 			g_qdf_dp_trace_data.thresh_time_limit)) {
3188 
3189 		spin_lock_bh(&l_dp_trace_lock);
3190 			if (g_qdf_dp_trace_data.print_pkt_cnt <=
3191 				g_qdf_dp_trace_data.high_tput_thresh)
3192 				g_qdf_dp_trace_data.live_mode = 1;
3193 
3194 		g_qdf_dp_trace_data.print_pkt_cnt = 0;
3195 		spin_unlock_bh(&l_dp_trace_lock);
3196 	}
3197 }
3198 qdf_export_symbol(qdf_dp_trace_throttle_live_mode);
3199 
qdf_dp_trace_apply_tput_policy(bool is_data_traffic)3200 void qdf_dp_trace_apply_tput_policy(bool is_data_traffic)
3201 {
3202 	if (g_qdf_dp_trace_data.dynamic_verbosity_modify) {
3203 		goto check_live_mode;
3204 		return;
3205 	}
3206 
3207 	if (is_data_traffic) {
3208 		g_qdf_dp_trace_data.verbosity =
3209 					QDF_DP_TRACE_VERBOSITY_ULTRA_LOW;
3210 	} else {
3211 		g_qdf_dp_trace_data.verbosity =
3212 					g_qdf_dp_trace_data.ini_conf_verbosity;
3213 	}
3214 check_live_mode:
3215 	qdf_dp_trace_throttle_live_mode(is_data_traffic);
3216 }
3217 #endif
3218 
3219 struct qdf_print_ctrl print_ctrl_obj[MAX_PRINT_CONFIG_SUPPORTED];
3220 
3221 struct category_name_info g_qdf_category_name[MAX_SUPPORTED_CATEGORY] = {
3222 	[QDF_MODULE_ID_TDLS] = {"tdls"},
3223 	[QDF_MODULE_ID_ACS] = {"ACS"},
3224 	[QDF_MODULE_ID_SCAN_SM] = {"scan state machine"},
3225 	[QDF_MODULE_ID_SCANENTRY] = {"scan entry"},
3226 	[QDF_MODULE_ID_WDS] = {"WDS"},
3227 	[QDF_MODULE_ID_ACTION] = {"action"},
3228 	[QDF_MODULE_ID_ROAM] = {"STA roaming"},
3229 	[QDF_MODULE_ID_INACT] = {"inactivity"},
3230 	[QDF_MODULE_ID_DOTH] = {"11h"},
3231 	[QDF_MODULE_ID_IQUE] = {"IQUE"},
3232 	[QDF_MODULE_ID_WME] = {"WME"},
3233 	[QDF_MODULE_ID_ACL] = {"ACL"},
3234 	[QDF_MODULE_ID_WPA] = {"WPA/RSN"},
3235 	[QDF_MODULE_ID_RADKEYS] = {"dump 802.1x keys"},
3236 	[QDF_MODULE_ID_RADDUMP] = {"dump radius packet"},
3237 	[QDF_MODULE_ID_RADIUS] = {"802.1x radius client"},
3238 	[QDF_MODULE_ID_DOT1XSM] = {"802.1x state machine"},
3239 	[QDF_MODULE_ID_DOT1X] = {"802.1x authenticator"},
3240 	[QDF_MODULE_ID_POWER] = {"power save"},
3241 	[QDF_MODULE_ID_STATE] = {"state"},
3242 	[QDF_MODULE_ID_OUTPUT] = {"output"},
3243 	[QDF_MODULE_ID_SCAN] = {"scan"},
3244 	[QDF_MODULE_ID_AUTH] = {"authentication"},
3245 	[QDF_MODULE_ID_ASSOC] = {"association"},
3246 	[QDF_MODULE_ID_NODE] = {"node"},
3247 	[QDF_MODULE_ID_ELEMID] = {"element ID"},
3248 	[QDF_MODULE_ID_XRATE] = {"rate"},
3249 	[QDF_MODULE_ID_INPUT] = {"input"},
3250 	[QDF_MODULE_ID_CRYPTO] = {"crypto"},
3251 	[QDF_MODULE_ID_DUMPPKTS] = {"dump packet"},
3252 	[QDF_MODULE_ID_DEBUG] = {"debug"},
3253 	[QDF_MODULE_ID_MLME] = {"mlme"},
3254 	[QDF_MODULE_ID_RRM] = {"rrm"},
3255 	[QDF_MODULE_ID_WNM] = {"wnm"},
3256 	[QDF_MODULE_ID_P2P_PROT] = {"p2p_prot"},
3257 	[QDF_MODULE_ID_PROXYARP] = {"proxyarp"},
3258 	[QDF_MODULE_ID_L2TIF] = {"l2tif"},
3259 	[QDF_MODULE_ID_WIFIPOS] = {"wifipos"},
3260 	[QDF_MODULE_ID_WRAP] = {"wrap"},
3261 	[QDF_MODULE_ID_DFS] = {"dfs"},
3262 	[QDF_MODULE_ID_ATF] = {"atf"},
3263 	[QDF_MODULE_ID_SPLITMAC] = {"splitmac"},
3264 	[QDF_MODULE_ID_IOCTL] = {"ioctl"},
3265 	[QDF_MODULE_ID_NAC] = {"nac"},
3266 	[QDF_MODULE_ID_MESH] = {"mesh"},
3267 	[QDF_MODULE_ID_MBO] = {"mbo"},
3268 	[QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = {"extchanswitch"},
3269 	[QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = {"extchanscan"},
3270 	[QDF_MODULE_ID_TLSHIM] = {"tlshim"},
3271 	[QDF_MODULE_ID_WMI] = {"WMI"},
3272 	[QDF_MODULE_ID_HTT] = {"HTT"},
3273 	[QDF_MODULE_ID_HDD] = {"HDD"},
3274 	[QDF_MODULE_ID_SME] = {"SME"},
3275 	[QDF_MODULE_ID_PE] = {"PE"},
3276 	[QDF_MODULE_ID_WMA] = {"WMA"},
3277 	[QDF_MODULE_ID_SYS] = {"SYS"},
3278 	[QDF_MODULE_ID_QDF] = {"QDF"},
3279 	[QDF_MODULE_ID_SAP] = {"SAP"},
3280 	[QDF_MODULE_ID_HDD_SOFTAP] = {"HDD_SAP"},
3281 	[QDF_MODULE_ID_HDD_DATA] = {"DATA"},
3282 	[QDF_MODULE_ID_HDD_SAP_DATA] = {"SAP_DATA"},
3283 	[QDF_MODULE_ID_HIF] = {"HIF"},
3284 	[QDF_MODULE_ID_HTC] = {"HTC"},
3285 	[QDF_MODULE_ID_TXRX] = {"TXRX"},
3286 	[QDF_MODULE_ID_QDF_DEVICE] = {"QDF_DEV"},
3287 	[QDF_MODULE_ID_CFG] = {"CFG"},
3288 	[QDF_MODULE_ID_BMI] = {"BMI"},
3289 	[QDF_MODULE_ID_EPPING] = {"EPPING"},
3290 	[QDF_MODULE_ID_QVIT] = {"QVIT"},
3291 	[QDF_MODULE_ID_DP] = {"DP"},
3292 	[QDF_MODULE_ID_HAL] = {"HAL"},
3293 	[QDF_MODULE_ID_SOC] = {"SOC"},
3294 	[QDF_MODULE_ID_OS_IF] = {"OSIF"},
3295 	[QDF_MODULE_ID_TARGET_IF] = {"TIF"},
3296 	[QDF_MODULE_ID_SCHEDULER] = {"SCH"},
3297 	[QDF_MODULE_ID_MGMT_TXRX] = {"MGMT_TXRX"},
3298 	[QDF_MODULE_ID_PMO] = {"PMO"},
3299 	[QDF_MODULE_ID_POLICY_MGR] = {"POLICY_MGR"},
3300 	[QDF_MODULE_ID_SA_API] = {"SA_API"},
3301 	[QDF_MODULE_ID_NAN] = {"NAN"},
3302 	[QDF_MODULE_ID_SPECTRAL] = {"SPECTRAL"},
3303 	[QDF_MODULE_ID_P2P] = {"P2P"},
3304 	[QDF_MODULE_ID_OFFCHAN_TXRX] = {"OFFCHAN"},
3305 	[QDF_MODULE_ID_REGULATORY] = {"REGULATORY"},
3306 	[QDF_MODULE_ID_OBJ_MGR] = {"OBJMGR"},
3307 	[QDF_MODULE_ID_SERIALIZATION] = {"SER"},
3308 	[QDF_MODULE_ID_NSS] = {"NSS"},
3309 	[QDF_MODULE_ID_ROAM_DEBUG] = {"roam debug"},
3310 	[QDF_MODULE_ID_DIRECT_BUF_RX] = {"DIRECT_BUF_RX"},
3311 	[QDF_MODULE_ID_DISA] = {"disa"},
3312 	[QDF_MODULE_ID_GREEN_AP] = {"GREEN_AP"},
3313 	[QDF_MODULE_ID_FD] = {"FILS discovery"},
3314 	[QDF_MODULE_ID_FTM] = {"FTM"},
3315 	[QDF_MODULE_ID_OCB] = {"OCB"},
3316 	[QDF_MODULE_ID_CONFIG] = {"CONFIG"},
3317 	[QDF_MODULE_ID_IPA] = {"IPA"},
3318 	[QDF_MODULE_ID_CP_STATS] = {"CP_STATS"},
3319 	[QDF_MODULE_ID_DCS] = {"DCS"},
3320 	[QDF_MODULE_ID_ACTION_OUI] = {"action_oui"},
3321 	[QDF_MODULE_ID_TARGET] = {"TARGET"},
3322 	[QDF_MODULE_ID_MBSSIE] = {"MBSSIE"},
3323 	[QDF_MODULE_ID_FWOL] = {"fwol"},
3324 	[QDF_MODULE_ID_SM_ENGINE] = {"SM_ENG"},
3325 	[QDF_MODULE_ID_CMN_MLME] = {"CMN_MLME"},
3326 	[QDF_MODULE_ID_BSSCOLOR] = {"BSSCOLOR"},
3327 	[QDF_MODULE_ID_CFR] = {"CFR"},
3328 	[QDF_MODULE_ID_DP_TX_CAPTURE] = {"TX_CAPTURE_ENHANCE"},
3329 	[QDF_MODULE_ID_INTEROP_ISSUES_AP] = {"INTEROP_ISSUES_AP"},
3330 	[QDF_MODULE_ID_DENYLIST_MGR] = {"dlm"},
3331 	[QDF_MODULE_ID_QLD] = {"QLD"},
3332 	[QDF_MODULE_ID_DYNAMIC_MODE_CHG] = {"Dynamic Mode Change"},
3333 	[QDF_MODULE_ID_COEX] = {"COEX"},
3334 	[QDF_MODULE_ID_MON_FILTER] = {"Monitor Filter"},
3335 	[QDF_MODULE_ID_PKT_CAPTURE] = {"pkt_capture"},
3336 	[QDF_MODULE_ID_RPTR] = {"RPTR"},
3337 	[QDF_MODULE_ID_6GHZ] = {"6GHZ"},
3338 	[QDF_MODULE_ID_IOT_SIM] = {"IOT_SIM"},
3339 	[QDF_MODULE_ID_MSCS] = {"MSCS"},
3340 	[QDF_MODULE_ID_GPIO] = {"GPIO_CFG"},
3341 	[QDF_MODULE_ID_IFMGR] = {"IF_MGR"},
3342 	[QDF_MODULE_ID_DIAG] = {"DIAG"},
3343 	[QDF_MODULE_ID_DP_INIT] = {"DP_INIT"},
3344 	[QDF_MODULE_ID_DP_TX] = {"DP_TX"},
3345 	[QDF_MODULE_ID_DP_RX] = {"DP_RX"},
3346 	[QDF_MODULE_ID_DP_STATS] = {"DP_STATS"},
3347 	[QDF_MODULE_ID_DP_HTT] = {"DP_HTT"},
3348 	[QDF_MODULE_ID_DP_PEER] = {"DP_PEER"},
3349 	[QDF_MODULE_ID_DP_RX_ERROR] = {"DP_RX_ERROR"},
3350 	[QDF_MODULE_ID_DP_HTT_TX_STATS] = {"DP_HTT_TX_STATS"},
3351 	[QDF_MODULE_ID_DP_RX_MON_STATUS] = {"DP_RX_MON_STATUS"},
3352 	[QDF_MODULE_ID_DP_RX_MON_DEST] = {"DP_RX_MON_DEST"},
3353 	[QDF_MODULE_ID_DP_REO] = {"DP_REO"},
3354 	[QDF_MODULE_ID_DP_TX_COMP] = {"DP_TX_COMP"},
3355 	[QDF_MODULE_ID_DP_VDEV] = {"DP_VDEV"},
3356 	[QDF_MODULE_ID_DP_CDP] = {"DP_CDP"},
3357 	[QDF_MODULE_ID_TSO] = {"TSO"},
3358 	[QDF_MODULE_ID_ME] = {"ME"},
3359 	[QDF_MODULE_ID_QWRAP] = {"QWRAP"},
3360 	[QDF_MODULE_ID_DBDC_REP] = {"DBDC_REP"},
3361 	[QDF_MODULE_ID_EXT_AP] = {"EXT_AP"},
3362 	[QDF_MODULE_ID_MLO] = {"MLO_MGR"},
3363 	[QDF_MODULE_ID_MGMT_RX_REO] = {"MGMT_RX_REO"},
3364 	[QDF_MODULE_ID_MLOIE] = {"MLOIE"},
3365 	[QDF_MODULE_ID_MBSS] = {"MBSS"},
3366 	[QDF_MODULE_ID_MON] = {"MONITOR"},
3367 	[QDF_MODULE_ID_AFC] = {"AFC"},
3368 	[QDF_MODULE_ID_TWT] = {"TWT"},
3369 	[QDF_MODULE_ID_SON] = {"SON"},
3370 	[QDF_MODULE_ID_WLAN_PRE_CAC] = {"PRE_CAC"},
3371 	[QDF_MODULE_ID_T2LM] = {"T2LM"},
3372 	[QDF_MODULE_ID_DP_SAWF] = {"DP_SAWF"},
3373 	[QDF_MODULE_ID_SCS] = {"SCS"},
3374 	[QDF_MODULE_ID_DP_UMAC_RESET] = {"UMAC_HW_RESET"},
3375 	[QDF_MODULE_ID_COAP] = {"COAP"},
3376 	[QDF_MODULE_ID_FTM_TIME_SYNC] = {"Time Sync"},
3377 	[QDF_MODULE_ID_WIFI_RADAR] = {"WIFI RADAR"},
3378 	[QDF_MODULE_ID_CDP] =  {"CDP"},
3379 	[QDF_MODULE_ID_QMI] = {"QMI"},
3380 	[QDF_MODULE_ID_SOUNDING] = {"SOUNDING"},
3381 	[QDF_MODULE_ID_SAWF] = {"SAWF"},
3382 	[QDF_MODULE_ID_EPCS] = {"EPCS"},
3383 	[QDF_MODULE_ID_LL_SAP] = {"LL_SAP"},
3384 	[QDF_MODULE_ID_COHOSTED_BSS] = {"COHOSTED_BSS"},
3385 	[QDF_MODULE_ID_TELEMETRY_AGENT] = {"TELEMETRY_AGENT"},
3386 	[QDF_MODULE_ID_RF_PATH_SWITCH] = {"Dynamic RF Path Switch"},
3387 	[QDF_MODULE_ID_ANY] = {"ANY"},
3388 };
3389 qdf_export_symbol(g_qdf_category_name);
3390 
qdf_trace_display(void)3391 void qdf_trace_display(void)
3392 {
3393 	QDF_MODULE_ID module_id;
3394 
3395 	pr_err("     1)FATAL  2)ERROR  3)WARN  4)INFO  5)INFO_H  6)INFO_M  7)INFO_L 8)DEBUG\n");
3396 	for (module_id = 0; module_id < QDF_MODULE_ID_MAX; ++module_id) {
3397 		pr_err("%2d)%s    %s        %s       %s       %s        %s         %s         %s        %s\n",
3398 		       (int)module_id,
3399 		       g_qdf_category_name[module_id].category_name_str,
3400 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3401 			       QDF_TRACE_LEVEL_FATAL) ? "X" : " ",
3402 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3403 			       QDF_TRACE_LEVEL_ERROR) ? "X" : " ",
3404 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3405 			       QDF_TRACE_LEVEL_WARN) ? "X" : " ",
3406 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3407 			       QDF_TRACE_LEVEL_INFO) ? "X" : " ",
3408 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3409 			       QDF_TRACE_LEVEL_INFO_HIGH) ? "X" : " ",
3410 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3411 			       QDF_TRACE_LEVEL_INFO_MED) ? "X" : " ",
3412 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3413 			       QDF_TRACE_LEVEL_INFO_LOW) ? "X" : " ",
3414 		       qdf_print_is_verbose_enabled(qdf_pidx, module_id,
3415 			       QDF_TRACE_LEVEL_DEBUG) ? "X" : " ");
3416 	}
3417 }
3418 qdf_export_symbol(qdf_trace_display);
3419 
3420 #ifdef WLAN_MAX_LOGS_PER_SEC
3421 static qdf_time_t __log_window_end;
3422 static qdf_atomic_t __log_window_count;
3423 uint32_t qdf_rl_print_count = WLAN_MAX_LOGS_PER_SEC;
3424 uint32_t qdf_rl_print_time = 1;
3425 uint32_t qdf_rl_print_suppressed;
3426 
qdf_detected_excessive_logging(void)3427 bool qdf_detected_excessive_logging(void)
3428 {
3429 	qdf_time_t now = qdf_system_ticks();
3430 	bool excessive_prints = false;
3431 
3432 	/*
3433 	 * If 'now' is more recent than the end of the window, reset.
3434 	 *
3435 	 * Note: This is not thread safe, and can result in more than one reset.
3436 	 * For our purposes, this is fine.
3437 	 */
3438 	if (!qdf_atomic_read(&__log_window_count)) {
3439 		__log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time);
3440 	} else if (qdf_system_time_after(now, __log_window_end)) {
3441 		__log_window_end = now + (qdf_system_ticks_per_sec * qdf_rl_print_time);
3442 		qdf_atomic_set(&__log_window_count, 0);
3443 	}
3444 
3445 	if (qdf_atomic_inc_return(&__log_window_count) > qdf_rl_print_count)
3446 		excessive_prints = true;
3447 
3448 	return excessive_prints;
3449 }
3450 
qdf_rl_print_count_set(uint32_t rl_print_count)3451 void qdf_rl_print_count_set(uint32_t rl_print_count)
3452 {
3453 	qdf_rl_print_count = rl_print_count;
3454 }
3455 
3456 qdf_export_symbol(qdf_rl_print_count_set);
3457 
qdf_rl_print_time_set(uint32_t rl_print_time)3458 void qdf_rl_print_time_set(uint32_t rl_print_time)
3459 {
3460 	qdf_rl_print_time = rl_print_time;
3461 }
3462 
3463 qdf_export_symbol(qdf_rl_print_time_set);
3464 
qdf_rl_print_suppressed_log(void)3465 void qdf_rl_print_suppressed_log(void)
3466 {
3467 	if (qdf_rl_print_suppressed) {
3468 		pr_err("QDF Ratelimiting: %d prints suppressed",
3469 		       qdf_rl_print_suppressed);
3470 		qdf_rl_print_suppressed = 0;
3471 	}
3472 }
3473 
qdf_rl_print_suppressed_inc(void)3474 void qdf_rl_print_suppressed_inc(void)
3475 {
3476 	qdf_rl_print_suppressed++;
3477 }
3478 #else
3479 #define qdf_rl_print_suppressed_log()
3480 #define qdf_rl_print_suppressed_inc()
3481 #endif /* WLAN_MAX_LOGS_PER_SEC */
3482 
3483 #ifdef QDF_TRACE_PRINT_ENABLE
print_to_console(char * str_buffer)3484 static inline void print_to_console(char *str_buffer)
3485 {
3486 	if (qdf_in_interrupt() && qdf_detected_excessive_logging()) {
3487 		qdf_rl_print_suppressed_inc();
3488 		return;
3489 	}
3490 	qdf_rl_print_suppressed_log();
3491 	pr_err("%s\n", str_buffer);
3492 }
3493 #else
3494 
3495 #define print_to_console(str)
3496 #endif
3497 
3498 #ifdef MULTI_IF_NAME
qdf_trace_wlan_modname(void)3499 static const char *qdf_trace_wlan_modname(void)
3500 {
3501 	return MULTI_IF_NAME;
3502 }
3503 #else
qdf_trace_wlan_modname(void)3504 static const char *qdf_trace_wlan_modname(void)
3505 {
3506 	return "wlan";
3507 }
3508 #endif
3509 
qdf_trace_msg_cmn(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose,const char * str_format,va_list val)3510 void qdf_trace_msg_cmn(unsigned int idx,
3511 			QDF_MODULE_ID category,
3512 			QDF_TRACE_LEVEL verbose,
3513 			const char *str_format, va_list val)
3514 {
3515 	char str_buffer[QDF_TRACE_BUFFER_SIZE];
3516 	int n;
3517 
3518 	/* Check if index passed is valid */
3519 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3520 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3521 		return;
3522 	}
3523 
3524 	/* Check if print control object is in use */
3525 	if (!print_ctrl_obj[idx].in_use) {
3526 		pr_info("%s: Invalid print control object\n", __func__);
3527 		return;
3528 	}
3529 
3530 	/* Check if category passed is valid */
3531 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
3532 		vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val);
3533 		pr_info("%s: Invalid category: %d, log: %s\n",
3534 			__func__, category, str_buffer);
3535 		return;
3536 	}
3537 
3538 	/* Check if verbose mask is valid */
3539 	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
3540 		vscnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE, str_format, val);
3541 		pr_info("%s: Invalid verbose level %d, log: %s\n",
3542 			__func__, verbose, str_buffer);
3543 		return;
3544 	}
3545 
3546 	/*
3547 	 * Print the trace message when the desired verbose level is set in
3548 	 * the desired category for the print control object
3549 	 */
3550 	if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
3551 	    QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
3552 		static const char * const VERBOSE_STR[] = {
3553 			[QDF_TRACE_LEVEL_NONE] = "",
3554 			[QDF_TRACE_LEVEL_FATAL] = "F",
3555 			[QDF_TRACE_LEVEL_ERROR] = "E",
3556 			[QDF_TRACE_LEVEL_WARN] = "W",
3557 			[QDF_TRACE_LEVEL_INFO] = "I",
3558 			[QDF_TRACE_LEVEL_INFO_HIGH] = "IH",
3559 			[QDF_TRACE_LEVEL_INFO_MED] = "IM",
3560 			[QDF_TRACE_LEVEL_INFO_LOW] = "IL",
3561 			[QDF_TRACE_LEVEL_DEBUG] = "D",
3562 			[QDF_TRACE_LEVEL_TRACE] = "T",
3563 			[QDF_TRACE_LEVEL_ALL] = "" };
3564 
3565 		/* print the prefix string into the string buffer... */
3566 		n = scnprintf(str_buffer, QDF_TRACE_BUFFER_SIZE,
3567 			     "%s: [%d:%s:%s] ", qdf_trace_wlan_modname(),
3568 			     in_interrupt() ? 0 : current->pid,
3569 			     VERBOSE_STR[verbose],
3570 			     g_qdf_category_name[category].category_name_str);
3571 
3572 		/* print the formatted log message after the prefix string */
3573 		vscnprintf(str_buffer + n, QDF_TRACE_BUFFER_SIZE - n,
3574 			   str_format, val);
3575 #if defined(WLAN_LOGGING_SOCK_SVC_ENABLE)
3576 		wlan_log_to_user(verbose, (char *)str_buffer,
3577 				 strlen(str_buffer));
3578 		if (qdf_unlikely(qdf_log_dump_at_kernel_enable))
3579 			print_to_console(str_buffer);
3580 #else
3581 		pr_err("%s\n", str_buffer);
3582 #endif
3583 	}
3584 }
3585 qdf_export_symbol(qdf_trace_msg_cmn);
3586 
qdf_print_setup(void)3587 QDF_STATUS qdf_print_setup(void)
3588 {
3589 	int i;
3590 
3591 	/* Loop through all print ctrl objects */
3592 	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
3593 		if (qdf_print_ctrl_cleanup(i))
3594 			return QDF_STATUS_E_FAILURE;
3595 	}
3596 	return QDF_STATUS_SUCCESS;
3597 }
3598 qdf_export_symbol(qdf_print_setup);
3599 
qdf_print_ctrl_cleanup(unsigned int idx)3600 QDF_STATUS qdf_print_ctrl_cleanup(unsigned int idx)
3601 {
3602 	int i = 0;
3603 
3604 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
3605 		pr_info("%s: Invalid index - %d\n", __func__, idx);
3606 		return QDF_STATUS_E_FAILURE;
3607 	}
3608 
3609 	/* Clean up the print control object corresponding to that index
3610 	 * If success, callee to change print control index to -1
3611 	 */
3612 
3613 	for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3614 		print_ctrl_obj[idx].cat_info[i].category_verbose_mask =
3615 							QDF_TRACE_LEVEL_NONE;
3616 	}
3617 	print_ctrl_obj[idx].custom_print = NULL;
3618 	print_ctrl_obj[idx].custom_ctxt = NULL;
3619 	qdf_print_clean_node_flag(idx);
3620 	print_ctrl_obj[idx].in_use = false;
3621 
3622 	return QDF_STATUS_SUCCESS;
3623 }
3624 qdf_export_symbol(qdf_print_ctrl_cleanup);
3625 
qdf_print_ctrl_register(const struct category_info * cinfo,void * custom_print_handler,void * custom_ctx,const char * pctrl_name)3626 int qdf_print_ctrl_register(const struct category_info *cinfo,
3627 			    void *custom_print_handler,
3628 			    void *custom_ctx,
3629 			    const char *pctrl_name)
3630 {
3631 	int idx = -1;
3632 	int i = 0;
3633 
3634 	for (i = 0; i < MAX_PRINT_CONFIG_SUPPORTED; i++) {
3635 		if (!print_ctrl_obj[i].in_use) {
3636 			idx = i;
3637 			break;
3638 		}
3639 	}
3640 
3641 	/* Callee to handle idx -1 appropriately */
3642 	if (idx == -1) {
3643 		pr_info("%s: Allocation failed! No print control object free\n",
3644 			__func__);
3645 		return idx;
3646 	}
3647 
3648 	print_ctrl_obj[idx].in_use = true;
3649 
3650 	/*
3651 	 * In case callee does not pass category info,
3652 	 * custom print handler, custom context and print control name,
3653 	 * we do not set any value here. Clean up for the print control
3654 	 * getting allocated would have taken care of initializing
3655 	 * default values.
3656 	 *
3657 	 * We need to only set in_use to 1 in such a case
3658 	 */
3659 
3660 	if (pctrl_name) {
3661 		qdf_str_lcopy(print_ctrl_obj[idx].name, pctrl_name,
3662 			      sizeof(print_ctrl_obj[idx].name));
3663 	}
3664 
3665 	if (custom_print_handler)
3666 		print_ctrl_obj[idx].custom_print = custom_print_handler;
3667 
3668 	if (custom_ctx)
3669 		print_ctrl_obj[idx].custom_ctxt = custom_ctx;
3670 
3671 	if (cinfo) {
3672 		for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3673 			if (cinfo[i].category_verbose_mask ==
3674 			    QDF_TRACE_LEVEL_ALL) {
3675 				print_ctrl_obj[idx].cat_info[i]
3676 				.category_verbose_mask = 0xFFFF;
3677 			} else if ((cinfo[i].category_verbose_mask ==
3678 				   QDF_TRACE_LEVEL_NONE) ||
3679 				   (cinfo[i].category_verbose_mask ==
3680 				   QDF_TRACE_LEVEL_TO_MODULE_BITMASK(
3681 				   QDF_TRACE_LEVEL_NONE))) {
3682 				print_ctrl_obj[idx].cat_info[i]
3683 				.category_verbose_mask = 0;
3684 			} else {
3685 				print_ctrl_obj[idx].cat_info[i]
3686 				.category_verbose_mask =
3687 				cinfo[i].category_verbose_mask;
3688 			}
3689 		}
3690 	}
3691 
3692 	return idx;
3693 }
3694 qdf_export_symbol(qdf_print_ctrl_register);
3695 
3696 #ifdef QDF_TRACE_PRINT_ENABLE
qdf_shared_print_ctrl_cleanup(void)3697 void qdf_shared_print_ctrl_cleanup(void)
3698 {
3699 	qdf_print_ctrl_cleanup(qdf_pidx);
3700 }
3701 qdf_export_symbol(qdf_shared_print_ctrl_cleanup);
3702 
3703 /*
3704  * Set this to invalid value to differentiate with user-provided
3705  * value.
3706  */
3707 int qdf_dbg_mask = QDF_TRACE_LEVEL_MAX;
3708 qdf_export_symbol(qdf_dbg_mask);
3709 qdf_declare_param(qdf_dbg_mask, int);
3710 
3711 /*
3712  * QDF can be passed parameters which indicate the
3713  * debug level for each module.
3714  * an array of string values are passed, each string hold the following form
3715  *
3716  * <module name string>=<integer debug level value>
3717  *
3718  * The array qdf_dbg_arr will hold these module-string=value strings
3719  * The variable qdf_dbg_arr_cnt will have the count of how many such
3720  * string values were passed.
3721  */
3722 static char *qdf_dbg_arr[QDF_MODULE_ID_MAX];
3723 static int qdf_dbg_arr_cnt;
3724 qdf_declare_param_array(qdf_dbg_arr, charp, &qdf_dbg_arr_cnt);
3725 
set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level)3726 static uint16_t set_cumulative_verbose_mask(QDF_TRACE_LEVEL max_level)
3727 {
3728 	uint16_t category_verbose_mask = 0;
3729 	QDF_TRACE_LEVEL level;
3730 
3731 	for (level = QDF_TRACE_LEVEL_FATAL; level <= max_level; level++) {
3732 		category_verbose_mask |=
3733 			QDF_TRACE_LEVEL_TO_MODULE_BITMASK(level);
3734 	}
3735 	return category_verbose_mask;
3736 }
3737 
find_qdf_module_from_string(char * str)3738 static QDF_MODULE_ID find_qdf_module_from_string(char *str)
3739 {
3740 	QDF_MODULE_ID mod_id;
3741 
3742 	for (mod_id = 0; mod_id < QDF_MODULE_ID_MAX; mod_id++) {
3743 		if (strcasecmp(str,
3744 				g_qdf_category_name[mod_id].category_name_str)
3745 				== 0) {
3746 			break;
3747 		}
3748 	}
3749 	return mod_id;
3750 }
3751 
process_qdf_dbg_arr_param(struct category_info * cinfo,int array_index)3752 static void process_qdf_dbg_arr_param(struct category_info *cinfo,
3753 					int array_index)
3754 {
3755 	char *mod_val_str, *mod_str, *val_str;
3756 	unsigned long dbg_level;
3757 	QDF_MODULE_ID mod_id;
3758 
3759 	mod_val_str = qdf_dbg_arr[array_index];
3760 	mod_str = strsep(&mod_val_str, "=");
3761 	val_str = mod_val_str;
3762 	if (!val_str) {
3763 		pr_info("qdf_dbg_arr: %s not in the <mod>=<val> form\n",
3764 				mod_str);
3765 		return;
3766 	}
3767 
3768 	mod_id = find_qdf_module_from_string(mod_str);
3769 	if (mod_id >= QDF_MODULE_ID_MAX) {
3770 		pr_info("ERROR!!Module name %s not in the list of modules\n",
3771 				mod_str);
3772 		return;
3773 	}
3774 
3775 	if (kstrtol(val_str, 10, &dbg_level) < 0) {
3776 		pr_info("ERROR!!Invalid debug level for module: %s\n",
3777 				mod_str);
3778 		return;
3779 	}
3780 
3781 	if (dbg_level >= QDF_TRACE_LEVEL_MAX) {
3782 		pr_info("ERROR!!Debug level for %s too high", mod_str);
3783 		pr_info("max: %d given %lu\n", QDF_TRACE_LEVEL_MAX,
3784 				dbg_level);
3785 		return;
3786 	}
3787 
3788 	pr_info("User passed setting module %s(%d) to level %lu\n",
3789 			mod_str,
3790 			mod_id,
3791 			dbg_level);
3792 	cinfo[mod_id].category_verbose_mask =
3793 		set_cumulative_verbose_mask((QDF_TRACE_LEVEL)dbg_level);
3794 }
3795 
set_default_trace_levels(struct category_info * cinfo)3796 static void set_default_trace_levels(struct category_info *cinfo)
3797 {
3798 	int i;
3799 	static QDF_TRACE_LEVEL module_trace_default_level[QDF_MODULE_ID_MAX] = {
3800 		[QDF_MODULE_ID_TDLS] = QDF_TRACE_LEVEL_NONE,
3801 		[QDF_MODULE_ID_ACS] = QDF_TRACE_LEVEL_NONE,
3802 		[QDF_MODULE_ID_SCAN_SM] = QDF_TRACE_LEVEL_NONE,
3803 		[QDF_MODULE_ID_SCANENTRY] = QDF_TRACE_LEVEL_NONE,
3804 		[QDF_MODULE_ID_WDS] = QDF_TRACE_LEVEL_NONE,
3805 		[QDF_MODULE_ID_ACTION] = QDF_TRACE_LEVEL_NONE,
3806 		[QDF_MODULE_ID_ROAM] = QDF_TRACE_LEVEL_NONE,
3807 		[QDF_MODULE_ID_INACT] = QDF_TRACE_LEVEL_NONE,
3808 		[QDF_MODULE_ID_DOTH] = QDF_TRACE_LEVEL_NONE,
3809 		[QDF_MODULE_ID_IQUE] = QDF_TRACE_LEVEL_NONE,
3810 		[QDF_MODULE_ID_WME] = QDF_TRACE_LEVEL_NONE,
3811 		[QDF_MODULE_ID_ACL] = QDF_TRACE_LEVEL_NONE,
3812 		[QDF_MODULE_ID_WPA] = QDF_TRACE_LEVEL_NONE,
3813 		[QDF_MODULE_ID_RADKEYS] = QDF_TRACE_LEVEL_NONE,
3814 		[QDF_MODULE_ID_RADDUMP] = QDF_TRACE_LEVEL_NONE,
3815 		[QDF_MODULE_ID_RADIUS] = QDF_TRACE_LEVEL_NONE,
3816 		[QDF_MODULE_ID_DOT1XSM] = QDF_TRACE_LEVEL_NONE,
3817 		[QDF_MODULE_ID_DOT1X] = QDF_TRACE_LEVEL_NONE,
3818 		[QDF_MODULE_ID_POWER] = QDF_TRACE_LEVEL_NONE,
3819 		[QDF_MODULE_ID_STATE] = QDF_TRACE_LEVEL_NONE,
3820 		[QDF_MODULE_ID_OUTPUT] = QDF_TRACE_LEVEL_NONE,
3821 		[QDF_MODULE_ID_SCAN] = QDF_TRACE_LEVEL_ERROR,
3822 		[QDF_MODULE_ID_AUTH] = QDF_TRACE_LEVEL_NONE,
3823 		[QDF_MODULE_ID_ASSOC] = QDF_TRACE_LEVEL_NONE,
3824 		[QDF_MODULE_ID_NODE] = QDF_TRACE_LEVEL_NONE,
3825 		[QDF_MODULE_ID_ELEMID] = QDF_TRACE_LEVEL_NONE,
3826 		[QDF_MODULE_ID_XRATE] = QDF_TRACE_LEVEL_NONE,
3827 		[QDF_MODULE_ID_INPUT] = QDF_TRACE_LEVEL_NONE,
3828 		[QDF_MODULE_ID_CRYPTO] = QDF_TRACE_LEVEL_NONE,
3829 		[QDF_MODULE_ID_DUMPPKTS] = QDF_TRACE_LEVEL_NONE,
3830 		[QDF_MODULE_ID_DEBUG] = QDF_TRACE_LEVEL_NONE,
3831 		[QDF_MODULE_ID_MLME] = QDF_TRACE_LEVEL_ERROR,
3832 		[QDF_MODULE_ID_RRM] = QDF_TRACE_LEVEL_NONE,
3833 		[QDF_MODULE_ID_WNM] = QDF_TRACE_LEVEL_NONE,
3834 		[QDF_MODULE_ID_P2P_PROT] = QDF_TRACE_LEVEL_NONE,
3835 		[QDF_MODULE_ID_PROXYARP] = QDF_TRACE_LEVEL_NONE,
3836 		[QDF_MODULE_ID_L2TIF] = QDF_TRACE_LEVEL_NONE,
3837 		[QDF_MODULE_ID_WIFIPOS] = QDF_TRACE_LEVEL_NONE,
3838 		[QDF_MODULE_ID_WRAP] = QDF_TRACE_LEVEL_NONE,
3839 		[QDF_MODULE_ID_DFS] = QDF_TRACE_LEVEL_NONE,
3840 		[QDF_MODULE_ID_ATF] = QDF_TRACE_LEVEL_ERROR,
3841 		[QDF_MODULE_ID_SPLITMAC] = QDF_TRACE_LEVEL_NONE,
3842 		[QDF_MODULE_ID_IOCTL] = QDF_TRACE_LEVEL_NONE,
3843 		[QDF_MODULE_ID_NAC] = QDF_TRACE_LEVEL_NONE,
3844 		[QDF_MODULE_ID_MESH] = QDF_TRACE_LEVEL_NONE,
3845 		[QDF_MODULE_ID_MBO] = QDF_TRACE_LEVEL_NONE,
3846 		[QDF_MODULE_ID_EXTIOCTL_CHANSWITCH] = QDF_TRACE_LEVEL_NONE,
3847 		[QDF_MODULE_ID_EXTIOCTL_CHANSSCAN] = QDF_TRACE_LEVEL_NONE,
3848 		[QDF_MODULE_ID_TLSHIM] = QDF_TRACE_LEVEL_NONE,
3849 		[QDF_MODULE_ID_WMI] = QDF_TRACE_LEVEL_ERROR,
3850 		[QDF_MODULE_ID_HTT] = QDF_TRACE_LEVEL_NONE,
3851 		[QDF_MODULE_ID_HDD] = QDF_TRACE_LEVEL_NONE,
3852 		[QDF_MODULE_ID_SME] = QDF_TRACE_LEVEL_NONE,
3853 		[QDF_MODULE_ID_PE] = QDF_TRACE_LEVEL_NONE,
3854 		[QDF_MODULE_ID_WMA] = QDF_TRACE_LEVEL_NONE,
3855 		[QDF_MODULE_ID_SYS] = QDF_TRACE_LEVEL_NONE,
3856 		[QDF_MODULE_ID_QDF] = QDF_TRACE_LEVEL_ERROR,
3857 		[QDF_MODULE_ID_SAP] = QDF_TRACE_LEVEL_NONE,
3858 		[QDF_MODULE_ID_HDD_SOFTAP] = QDF_TRACE_LEVEL_NONE,
3859 		[QDF_MODULE_ID_HDD_DATA] = QDF_TRACE_LEVEL_NONE,
3860 		[QDF_MODULE_ID_HDD_SAP_DATA] = QDF_TRACE_LEVEL_NONE,
3861 		[QDF_MODULE_ID_HIF] = QDF_TRACE_LEVEL_ERROR,
3862 		[QDF_MODULE_ID_HTC] = QDF_TRACE_LEVEL_NONE,
3863 		[QDF_MODULE_ID_TXRX] = QDF_TRACE_LEVEL_NONE,
3864 		[QDF_MODULE_ID_QDF_DEVICE] = QDF_TRACE_LEVEL_NONE,
3865 		[QDF_MODULE_ID_CFG] = QDF_TRACE_LEVEL_NONE,
3866 		[QDF_MODULE_ID_BMI] = QDF_TRACE_LEVEL_NONE,
3867 		[QDF_MODULE_ID_EPPING] = QDF_TRACE_LEVEL_NONE,
3868 		[QDF_MODULE_ID_QVIT] = QDF_TRACE_LEVEL_NONE,
3869 		[QDF_MODULE_ID_DP] = QDF_TRACE_LEVEL_FATAL,
3870 		[QDF_MODULE_ID_HAL] = QDF_TRACE_LEVEL_NONE,
3871 		[QDF_MODULE_ID_SOC] = QDF_TRACE_LEVEL_NONE,
3872 		[QDF_MODULE_ID_OS_IF] = QDF_TRACE_LEVEL_NONE,
3873 		[QDF_MODULE_ID_TARGET_IF] = QDF_TRACE_LEVEL_INFO,
3874 		[QDF_MODULE_ID_SCHEDULER] = QDF_TRACE_LEVEL_FATAL,
3875 		[QDF_MODULE_ID_MGMT_TXRX] = QDF_TRACE_LEVEL_NONE,
3876 		[QDF_MODULE_ID_SERIALIZATION] = QDF_TRACE_LEVEL_ERROR,
3877 		[QDF_MODULE_ID_PMO] = QDF_TRACE_LEVEL_NONE,
3878 		[QDF_MODULE_ID_P2P] = QDF_TRACE_LEVEL_NONE,
3879 		[QDF_MODULE_ID_POLICY_MGR] = QDF_TRACE_LEVEL_NONE,
3880 		[QDF_MODULE_ID_CONFIG] = QDF_TRACE_LEVEL_ERROR,
3881 		[QDF_MODULE_ID_REGULATORY] = QDF_TRACE_LEVEL_NONE,
3882 		[QDF_MODULE_ID_SA_API] = QDF_TRACE_LEVEL_NONE,
3883 		[QDF_MODULE_ID_NAN] = QDF_TRACE_LEVEL_NONE,
3884 		[QDF_MODULE_ID_OFFCHAN_TXRX] = QDF_TRACE_LEVEL_NONE,
3885 		[QDF_MODULE_ID_SON] = QDF_TRACE_LEVEL_NONE,
3886 		[QDF_MODULE_ID_SPECTRAL] = QDF_TRACE_LEVEL_ERROR,
3887 		[QDF_MODULE_ID_OBJ_MGR] = QDF_TRACE_LEVEL_FATAL,
3888 		[QDF_MODULE_ID_NSS] = QDF_TRACE_LEVEL_ERROR,
3889 		[QDF_MODULE_ID_ROAM_DEBUG] = QDF_TRACE_LEVEL_ERROR,
3890 		[QDF_MODULE_ID_CDP] = QDF_TRACE_LEVEL_NONE,
3891 		[QDF_MODULE_ID_DIRECT_BUF_RX] = QDF_TRACE_LEVEL_ERROR,
3892 		[QDF_MODULE_ID_DISA] = QDF_TRACE_LEVEL_NONE,
3893 		[QDF_MODULE_ID_GREEN_AP] = QDF_TRACE_LEVEL_ERROR,
3894 		[QDF_MODULE_ID_FTM] = QDF_TRACE_LEVEL_ERROR,
3895 		[QDF_MODULE_ID_FD] = QDF_TRACE_LEVEL_ERROR,
3896 		[QDF_MODULE_ID_OCB] = QDF_TRACE_LEVEL_ERROR,
3897 		[QDF_MODULE_ID_IPA] = QDF_TRACE_LEVEL_NONE,
3898 		[QDF_MODULE_ID_ACTION_OUI] = QDF_TRACE_LEVEL_NONE,
3899 		[QDF_MODULE_ID_CP_STATS] = QDF_TRACE_LEVEL_ERROR,
3900 		[QDF_MODULE_ID_DCS] = QDF_TRACE_LEVEL_ERROR,
3901 		[QDF_MODULE_ID_MBSSIE] = QDF_TRACE_LEVEL_INFO,
3902 		[QDF_MODULE_ID_FWOL] = QDF_TRACE_LEVEL_NONE,
3903 		[QDF_MODULE_ID_SM_ENGINE] = QDF_TRACE_LEVEL_ERROR,
3904 		[QDF_MODULE_ID_CMN_MLME] = QDF_TRACE_LEVEL_INFO,
3905 		[QDF_MODULE_ID_BSSCOLOR] = QDF_TRACE_LEVEL_ERROR,
3906 		[QDF_MODULE_ID_CFR] = QDF_TRACE_LEVEL_ERROR,
3907 		[QDF_MODULE_ID_DP_TX_CAPTURE] = QDF_TRACE_LEVEL_FATAL,
3908 		[QDF_MODULE_ID_INTEROP_ISSUES_AP] = QDF_TRACE_LEVEL_NONE,
3909 		[QDF_MODULE_ID_DENYLIST_MGR] = QDF_TRACE_LEVEL_NONE,
3910 		[QDF_MODULE_ID_QLD] = QDF_TRACE_LEVEL_ERROR,
3911 		[QDF_MODULE_ID_DYNAMIC_MODE_CHG] = QDF_TRACE_LEVEL_INFO,
3912 		[QDF_MODULE_ID_COEX] = QDF_TRACE_LEVEL_ERROR,
3913 		[QDF_MODULE_ID_MON_FILTER] = QDF_TRACE_LEVEL_INFO,
3914 		[QDF_MODULE_ID_PKT_CAPTURE] = QDF_TRACE_LEVEL_NONE,
3915 		[QDF_MODULE_ID_RPTR] = QDF_TRACE_LEVEL_INFO,
3916 		[QDF_MODULE_ID_6GHZ] = QDF_TRACE_LEVEL_ERROR,
3917 		[QDF_MODULE_ID_IOT_SIM] = QDF_TRACE_LEVEL_ERROR,
3918 		[QDF_MODULE_ID_MSCS] = QDF_TRACE_LEVEL_INFO,
3919 		[QDF_MODULE_ID_GPIO] = QDF_TRACE_LEVEL_NONE,
3920 		[QDF_MODULE_ID_IFMGR] = QDF_TRACE_LEVEL_ERROR,
3921 		[QDF_MODULE_ID_DIAG] = QDF_TRACE_LEVEL_ERROR,
3922 		[QDF_MODULE_ID_DP_INIT] = QDF_TRACE_LEVEL_FATAL,
3923 		[QDF_MODULE_ID_DP_TX] = QDF_TRACE_LEVEL_FATAL,
3924 		[QDF_MODULE_ID_DP_RX] = QDF_TRACE_LEVEL_FATAL,
3925 		[QDF_MODULE_ID_DP_STATS] = QDF_TRACE_LEVEL_FATAL,
3926 		[QDF_MODULE_ID_DP_HTT] = QDF_TRACE_LEVEL_FATAL,
3927 		[QDF_MODULE_ID_DP_PEER] = QDF_TRACE_LEVEL_FATAL,
3928 		[QDF_MODULE_ID_DP_RX_ERROR] = QDF_TRACE_LEVEL_FATAL,
3929 		[QDF_MODULE_ID_DP_HTT_TX_STATS] = QDF_TRACE_LEVEL_FATAL,
3930 		[QDF_MODULE_ID_DP_RX_MON_STATUS] = QDF_TRACE_LEVEL_FATAL,
3931 		[QDF_MODULE_ID_DP_RX_MON_DEST] = QDF_TRACE_LEVEL_FATAL,
3932 		[QDF_MODULE_ID_DP_REO] = QDF_TRACE_LEVEL_FATAL,
3933 		[QDF_MODULE_ID_DP_TX_COMP] = QDF_TRACE_LEVEL_FATAL,
3934 		[QDF_MODULE_ID_DP_VDEV] = QDF_TRACE_LEVEL_FATAL,
3935 		[QDF_MODULE_ID_DP_CDP] = QDF_TRACE_LEVEL_FATAL,
3936 		[QDF_MODULE_ID_TSO] = QDF_TRACE_LEVEL_FATAL,
3937 		[QDF_MODULE_ID_ME] = QDF_TRACE_LEVEL_INFO,
3938 		[QDF_MODULE_ID_QWRAP] = QDF_TRACE_LEVEL_FATAL,
3939 		[QDF_MODULE_ID_DBDC_REP] = QDF_TRACE_LEVEL_FATAL,
3940 		[QDF_MODULE_ID_EXT_AP] = QDF_TRACE_LEVEL_NONE,
3941 		[QDF_MODULE_ID_MLO] = QDF_TRACE_LEVEL_INFO,
3942 		[QDF_MODULE_ID_MLOIE] = QDF_TRACE_LEVEL_INFO,
3943 		[QDF_MODULE_ID_MBSS] = QDF_TRACE_LEVEL_ERROR,
3944 		[QDF_MODULE_ID_MON] = QDF_TRACE_LEVEL_ERROR,
3945 		[QDF_MODULE_ID_MGMT_RX_REO] = QDF_TRACE_LEVEL_WARN,
3946 		[QDF_MODULE_ID_TWT] = QDF_TRACE_LEVEL_ERROR,
3947 		[QDF_MODULE_ID_WLAN_PRE_CAC] = QDF_TRACE_LEVEL_ERROR,
3948 		[QDF_MODULE_ID_T2LM] = QDF_TRACE_LEVEL_ERROR,
3949 		[QDF_MODULE_ID_DP_SAWF] = QDF_TRACE_LEVEL_ERROR,
3950 		[QDF_MODULE_ID_SCS] = QDF_TRACE_LEVEL_ERROR,
3951 		[QDF_MODULE_ID_DP_UMAC_RESET] = QDF_TRACE_LEVEL_ERROR,
3952 		[QDF_MODULE_ID_COAP] = QDF_TRACE_LEVEL_ERROR,
3953 		[QDF_MODULE_ID_FTM_TIME_SYNC] = QDF_TRACE_LEVEL_NONE,
3954 		[QDF_MODULE_ID_AFC] = QDF_TRACE_LEVEL_NONE,
3955 		[QDF_MODULE_ID_WIFI_RADAR] = QDF_TRACE_LEVEL_NONE,
3956 		[QDF_MODULE_ID_TARGET] = QDF_TRACE_LEVEL_NONE,
3957 		[QDF_MODULE_ID_QMI] = QDF_TRACE_LEVEL_ERROR,
3958 		[QDF_MODULE_ID_SOUNDING] = QDF_TRACE_LEVEL_ERROR,
3959 		[QDF_MODULE_ID_SAWF] = QDF_TRACE_LEVEL_INFO,
3960 		[QDF_MODULE_ID_EPCS] = QDF_TRACE_LEVEL_INFO,
3961 		[QDF_MODULE_ID_LL_SAP] = QDF_TRACE_LEVEL_NONE,
3962 		[QDF_MODULE_ID_COHOSTED_BSS] = QDF_TRACE_LEVEL_INFO,
3963 		[QDF_MODULE_ID_TELEMETRY_AGENT] = QDF_TRACE_LEVEL_ERROR,
3964 		[QDF_MODULE_ID_RF_PATH_SWITCH] = QDF_TRACE_LEVEL_INFO,
3965 		[QDF_MODULE_ID_ANY] = QDF_TRACE_LEVEL_INFO,
3966 	};
3967 
3968 	for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3969 		cinfo[i].category_verbose_mask = set_cumulative_verbose_mask(
3970 				module_trace_default_level[i]);
3971 	}
3972 }
3973 
qdf_shared_print_ctrl_init(void)3974 void qdf_shared_print_ctrl_init(void)
3975 {
3976 	int i;
3977 	struct category_info cinfo[MAX_SUPPORTED_CATEGORY];
3978 
3979 	set_default_trace_levels(cinfo);
3980 
3981 	/*
3982 	 * User specified across-module single debug level
3983 	 */
3984 	if ((qdf_dbg_mask >= 0) && (qdf_dbg_mask < QDF_TRACE_LEVEL_MAX)) {
3985 		pr_info("User specified module debug level of %d\n",
3986 			qdf_dbg_mask);
3987 		for (i = 0; i < MAX_SUPPORTED_CATEGORY; i++) {
3988 			cinfo[i].category_verbose_mask =
3989 			set_cumulative_verbose_mask(qdf_dbg_mask);
3990 		}
3991 	} else if (qdf_dbg_mask != QDF_TRACE_LEVEL_MAX) {
3992 		pr_info("qdf_dbg_mask value is invalid\n");
3993 		pr_info("Using the default module debug levels instead\n");
3994 	}
3995 
3996 	/*
3997 	 * Module ID-Level specified as array during module load
3998 	 */
3999 	for (i = 0; i < qdf_dbg_arr_cnt; i++) {
4000 		process_qdf_dbg_arr_param(cinfo, i);
4001 	}
4002 	qdf_pidx = qdf_print_ctrl_register(cinfo, NULL, NULL,
4003 			"LOG_SHARED_OBJ");
4004 }
4005 qdf_export_symbol(qdf_shared_print_ctrl_init);
4006 #endif
4007 
4008 #ifdef QCA_WIFI_MODULE_PARAMS_FROM_INI
qdf_module_param_handler(void * context,const char * str_param,const char * str)4009 QDF_STATUS qdf_module_param_handler(void *context, const char *str_param,
4010 				    const char *str)
4011 {
4012 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
4013 	uint16_t param = 0;
4014 	uint32_t flush_tmr_prd;
4015 	bool dump_flag;
4016 
4017 	while (param < QDF_PARAM_MAX) {
4018 		if (qdf_str_eq(qdf_module_param[param], str_param)) {
4019 			switch (param) {
4020 			case MEM_DEBUG_DISABLED:
4021 				status = qdf_mem_debug_disabled_config_set(str);
4022 				break;
4023 			case QDF_DBG_MASK:
4024 				status = qdf_int32_parse(str, &qdf_dbg_mask);
4025 				break;
4026 			case PREALLOC_DISABLED:
4027 				status = qdf_prealloc_disabled_config_set(str);
4028 				break;
4029 			case QDF_LOG_DUMP_AT_KERNEL_ENABLE:
4030 				status = qdf_bool_parse(str, &dump_flag);
4031 				qdf_log_dump_at_kernel_enable = dump_flag;
4032 				break;
4033 			case QDF_DBG_ARR:
4034 				qdf_dbg_arr[0] = (char *)str;
4035 				status = QDF_STATUS_SUCCESS;
4036 				break;
4037 			case QDF_LOG_FLUSH_TIMER_PERIOD:
4038 				status = qdf_uint32_parse(str, &flush_tmr_prd);
4039 				qdf_log_flush_timer_period = flush_tmr_prd;
4040 				break;
4041 			default:
4042 				break;
4043 			}
4044 			return status;
4045 		}
4046 		param++;
4047 	}
4048 
4049 	return QDF_STATUS_SUCCESS;
4050 }
4051 
qdf_initialize_module_param_from_ini(void)4052 void qdf_initialize_module_param_from_ini(void)
4053 {
4054 	QDF_STATUS status;
4055 	char *path = QDF_WIFI_MODULE_PARAMS_FILE;
4056 
4057 	status = qdf_ini_parse(path, NULL, qdf_module_param_handler, NULL);
4058 	if (QDF_IS_STATUS_ERROR(status)) {
4059 		QDF_TRACE_ERROR(QDF_MODULE_ID_QDF,
4060 				"Failed to parse *.ini file @ %s; status:%d",
4061 				path, status);
4062 		return;
4063 	}
4064 }
4065 #endif
4066 
qdf_print_set_category_verbose(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose,bool is_set)4067 QDF_STATUS qdf_print_set_category_verbose(unsigned int idx,
4068 						QDF_MODULE_ID category,
4069 						QDF_TRACE_LEVEL verbose,
4070 						bool is_set)
4071 {
4072 	/* Check if index passed is valid */
4073 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
4074 		pr_err("%s: Invalid index - %d\n", __func__, idx);
4075 		return QDF_STATUS_E_FAILURE;
4076 	}
4077 
4078 	/* Check if print control object is in use */
4079 	if (!print_ctrl_obj[idx].in_use) {
4080 		pr_err("%s: Invalid print control object\n", __func__);
4081 		return QDF_STATUS_E_FAILURE;
4082 	}
4083 
4084 	/* Check if category passed is valid */
4085 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
4086 		pr_err("%s: Invalid category: %d\n", __func__, category);
4087 		return QDF_STATUS_E_FAILURE;
4088 	}
4089 
4090 	/* Check if verbose mask is valid */
4091 	if (verbose < 0 || verbose >= QDF_TRACE_LEVEL_MAX) {
4092 		pr_err("%s: Invalid verbose level %d\n", __func__, verbose);
4093 		return QDF_STATUS_E_FAILURE;
4094 	}
4095 
4096 	if (verbose == QDF_TRACE_LEVEL_ALL) {
4097 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
4098 				0xFFFF;
4099 		return QDF_STATUS_SUCCESS;
4100 	}
4101 
4102 	if (verbose == QDF_TRACE_LEVEL_NONE) {
4103 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask =
4104 				QDF_TRACE_LEVEL_NONE;
4105 		return QDF_STATUS_SUCCESS;
4106 	}
4107 
4108 	if (!is_set) {
4109 		if (print_ctrl_obj[idx].cat_info[category].category_verbose_mask
4110 		    & QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) {
4111 			print_ctrl_obj[idx].cat_info[category]
4112 				.category_verbose_mask &=
4113 				~QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
4114 		}
4115 	} else {
4116 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask |=
4117 				QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose);
4118 	}
4119 
4120 	pr_debug("%s: Print control object %d, Category %d, Verbose level %d\n",
4121 		__func__,
4122 		idx,
4123 		category,
4124 		print_ctrl_obj[idx].cat_info[category].category_verbose_mask);
4125 
4126 	return QDF_STATUS_SUCCESS;
4127 }
4128 qdf_export_symbol(qdf_print_set_category_verbose);
4129 
qdf_log_dump_at_kernel_level(bool enable)4130 void qdf_log_dump_at_kernel_level(bool enable)
4131 {
4132 	if (qdf_log_dump_at_kernel_enable == enable) {
4133 		QDF_TRACE_INFO(QDF_MODULE_ID_QDF,
4134 			       "qdf_log_dump_at_kernel_enable is already %d\n",
4135 			       enable);
4136 	}
4137 	qdf_log_dump_at_kernel_enable = enable;
4138 }
4139 
4140 qdf_export_symbol(qdf_log_dump_at_kernel_level);
4141 
qdf_print_get_category_verbose(unsigned int idx,QDF_MODULE_ID category)4142 QDF_TRACE_LEVEL qdf_print_get_category_verbose(unsigned int idx,
4143 					       QDF_MODULE_ID category)
4144 {
4145 	/* Check if index passed is valid */
4146 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
4147 		pr_info("%s: Invalid index - %d\n", __func__, idx);
4148 		return false;
4149 	}
4150 
4151 	/* Check if print control object is in use */
4152 	if (!print_ctrl_obj[idx].in_use) {
4153 		pr_info("%s: Invalid print control object\n", __func__);
4154 		return false;
4155 	}
4156 
4157 	/* Check if category passed is valid */
4158 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
4159 		pr_info("%s: Invalid category: %d\n", __func__, category);
4160 		return false;
4161 	}
4162 
4163 	return print_ctrl_obj[idx].cat_info[category].category_verbose_mask;
4164 }
4165 
4166 qdf_export_symbol(qdf_print_get_category_verbose);
4167 
qdf_print_is_category_enabled(unsigned int idx,QDF_MODULE_ID category)4168 bool qdf_print_is_category_enabled(unsigned int idx, QDF_MODULE_ID category)
4169 {
4170 	QDF_TRACE_LEVEL verbose_mask;
4171 
4172 	verbose_mask = qdf_print_get_category_verbose(idx, category);
4173 
4174 	if (verbose_mask == QDF_TRACE_LEVEL_NONE)
4175 		return false;
4176 	else
4177 		return true;
4178 }
4179 
4180 qdf_export_symbol(qdf_print_is_category_enabled);
4181 
qdf_print_is_verbose_enabled(unsigned int idx,QDF_MODULE_ID category,QDF_TRACE_LEVEL verbose)4182 bool qdf_print_is_verbose_enabled(unsigned int idx, QDF_MODULE_ID category,
4183 				  QDF_TRACE_LEVEL verbose)
4184 {
4185 	bool verbose_enabled = false;
4186 
4187 	/* Check if index passed is valid */
4188 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
4189 		pr_info("%s: Invalid index - %d\n", __func__, idx);
4190 		return verbose_enabled;
4191 	}
4192 
4193 	/* Check if print control object is in use */
4194 	if (!print_ctrl_obj[idx].in_use) {
4195 		pr_info("%s: Invalid print control object\n", __func__);
4196 		return verbose_enabled;
4197 	}
4198 
4199 	/* Check if category passed is valid */
4200 	if (category < 0 || category >= MAX_SUPPORTED_CATEGORY) {
4201 		pr_info("%s: Invalid category: %d\n", __func__, category);
4202 		return verbose_enabled;
4203 	}
4204 
4205 	if ((verbose == QDF_TRACE_LEVEL_NONE) ||
4206 	    (verbose >= QDF_TRACE_LEVEL_MAX)) {
4207 		verbose_enabled = false;
4208 	} else if (verbose == QDF_TRACE_LEVEL_ALL) {
4209 		if (print_ctrl_obj[idx].cat_info[category]
4210 					.category_verbose_mask == 0xFFFF)
4211 			verbose_enabled = true;
4212 	} else {
4213 		verbose_enabled =
4214 		(print_ctrl_obj[idx].cat_info[category].category_verbose_mask &
4215 		 QDF_TRACE_LEVEL_TO_MODULE_BITMASK(verbose)) ? true : false;
4216 	}
4217 
4218 	return verbose_enabled;
4219 }
4220 qdf_export_symbol(qdf_print_is_verbose_enabled);
4221 
4222 #ifdef DBG_LVL_MAC_FILTERING
4223 
qdf_print_set_node_flag(unsigned int idx,uint8_t enable)4224 QDF_STATUS qdf_print_set_node_flag(unsigned int idx, uint8_t enable)
4225 {
4226 	/* Check if index passed is valid */
4227 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
4228 		pr_info("%s: Invalid index - %d\n", __func__, idx);
4229 		return QDF_STATUS_E_FAILURE;
4230 	}
4231 
4232 	/* Check if print control object is in use */
4233 	if (!print_ctrl_obj[idx].in_use) {
4234 		pr_info("%s: Invalid print control object\n", __func__);
4235 		return QDF_STATUS_E_FAILURE;
4236 	}
4237 
4238 	if (enable > 1) {
4239 		pr_info("%s: Incorrect input: Use 1 or 0 to enable or disable\n",
4240 			__func__);
4241 		return QDF_STATUS_E_FAILURE;
4242 	}
4243 
4244 	print_ctrl_obj[idx].dbglvlmac_on = enable;
4245 	pr_info("%s: DbgLVLmac feature %s\n",
4246 		__func__,
4247 		((enable) ? "enabled" : "disabled"));
4248 
4249 	return QDF_STATUS_SUCCESS;
4250 }
4251 qdf_export_symbol(qdf_print_set_node_flag);
4252 
qdf_print_get_node_flag(unsigned int idx)4253 bool qdf_print_get_node_flag(unsigned int idx)
4254 {
4255 	bool node_flag = false;
4256 
4257 	/* Check if index passed is valid */
4258 	if (idx < 0 || idx >= MAX_PRINT_CONFIG_SUPPORTED) {
4259 		pr_info("%s: Invalid index - %d\n", __func__, idx);
4260 		return node_flag;
4261 	}
4262 
4263 	/* Check if print control object is in use */
4264 	if (!print_ctrl_obj[idx].in_use) {
4265 		pr_info("%s: Invalid print control object\n", __func__);
4266 		return node_flag;
4267 	}
4268 
4269 	if (print_ctrl_obj[idx].dbglvlmac_on)
4270 		node_flag = true;
4271 
4272 	return node_flag;
4273 }
4274 qdf_export_symbol(qdf_print_get_node_flag);
4275 
qdf_print_clean_node_flag(unsigned int idx)4276 void qdf_print_clean_node_flag(unsigned int idx)
4277 {
4278 	/* Disable dbglvlmac_on during cleanup */
4279 	print_ctrl_obj[idx].dbglvlmac_on = 0;
4280 }
4281 
4282 #else
4283 
qdf_print_clean_node_flag(unsigned int idx)4284 void qdf_print_clean_node_flag(unsigned int idx)
4285 {
4286 	/* No operation in case of no support for DBG_LVL_MAC_FILTERING */
4287 	return;
4288 }
4289 #endif
4290 
QDF_PRINT_INFO(unsigned int idx,QDF_MODULE_ID module,QDF_TRACE_LEVEL level,char * str_format,...)4291 void QDF_PRINT_INFO(unsigned int idx, QDF_MODULE_ID module,
4292 		    QDF_TRACE_LEVEL level,
4293 		    char *str_format, ...)
4294 {
4295 	va_list args;
4296 
4297 	/* Generic wrapper API will compile qdf_vprint in order to
4298 	 * log the message. Once QDF converged debug framework is in
4299 	 * place, this will be changed to adapt to the framework, compiling
4300 	 * call to converged tracing API
4301 	 */
4302 	va_start(args, str_format);
4303 	qdf_vprint(str_format, args);
4304 	va_end(args);
4305 }
4306 qdf_export_symbol(QDF_PRINT_INFO);
4307 
4308 #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
qdf_logging_init(void)4309 void qdf_logging_init(void)
4310 {
4311 	wlan_logging_sock_init_svc();
4312 	nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY);
4313 	wlan_logging_notifier_init(qdf_log_dump_at_kernel_enable);
4314 	wlan_logging_set_flush_timer(qdf_log_flush_timer_period);
4315 }
4316 
qdf_logging_exit(void)4317 void qdf_logging_exit(void)
4318 {
4319 	wlan_logging_notifier_deinit(qdf_log_dump_at_kernel_enable);
4320 	nl_srv_exit();
4321 	wlan_logging_sock_deinit_svc();
4322 }
4323 
qdf_logging_set_flush_timer(uint32_t milliseconds)4324 int qdf_logging_set_flush_timer(uint32_t milliseconds)
4325 {
4326 	if (wlan_logging_set_flush_timer(milliseconds) == 0)
4327 		return QDF_STATUS_SUCCESS;
4328 	else
4329 		return QDF_STATUS_E_FAILURE;
4330 }
4331 
qdf_logging_flush_logs(void)4332 void qdf_logging_flush_logs(void)
4333 {
4334 	wlan_flush_host_logs_for_fatal();
4335 }
4336 
4337 #else
qdf_logging_init(void)4338 void qdf_logging_init(void)
4339 {
4340 	nl_srv_init(NULL, WLAN_NLINK_PROTO_FAMILY);
4341 }
4342 
qdf_logging_exit(void)4343 void qdf_logging_exit(void)
4344 {
4345 	nl_srv_exit();
4346 }
4347 
qdf_logging_set_flush_timer(uint32_t milliseconds)4348 int qdf_logging_set_flush_timer(uint32_t milliseconds)
4349 {
4350 	return QDF_STATUS_E_FAILURE;
4351 }
4352 
qdf_logging_flush_logs(void)4353 void qdf_logging_flush_logs(void)
4354 {
4355 }
4356 #endif
4357 
4358 qdf_export_symbol(qdf_logging_set_flush_timer);
4359 qdf_export_symbol(qdf_logging_flush_logs);
4360 
4361 #ifdef CONFIG_KALLSYMS
qdf_sprint_symbol(char * buffer,void * addr)4362 inline int qdf_sprint_symbol(char *buffer, void *addr)
4363 {
4364 	return sprint_symbol(buffer, (unsigned long)addr);
4365 }
4366 #else
qdf_sprint_symbol(char * buffer,void * addr)4367 int qdf_sprint_symbol(char *buffer, void *addr)
4368 {
4369 	if (!buffer)
4370 		return 0;
4371 
4372 	buffer[0] = '\0';
4373 	return 1;
4374 }
4375 #endif
4376 qdf_export_symbol(qdf_sprint_symbol);
4377 
qdf_set_pidx(int pidx)4378 void qdf_set_pidx(int pidx)
4379 {
4380 	qdf_pidx = pidx;
4381 }
4382 qdf_export_symbol(qdf_set_pidx);
4383 
qdf_get_pidx(void)4384 int qdf_get_pidx(void)
4385 {
4386 	return qdf_pidx;
4387 }
4388 qdf_export_symbol(qdf_get_pidx);
4389 
4390 #ifdef PANIC_ON_BUG
4391 #ifdef CONFIG_SLUB_DEBUG
__qdf_bug(void)4392 void __qdf_bug(void)
4393 {
4394 	BUG();
4395 }
4396 qdf_export_symbol(__qdf_bug);
4397 #endif /* CONFIG_SLUB_DEBUG */
4398 #endif /* PANIC_ON_BUG */
4399 
4400 #ifdef WLAN_QCOM_VA_MINIDUMP
4401 static bool qdf_va_md_initialized;
4402 static qdf_list_t qdf_va_md_list;
4403 static qdf_spinlock_t qdf_va_md_list_lock;
4404 #define QDF_MINIDUMP_LIST_SIZE 128
4405 
4406 struct qdf_va_md_entry {
4407 	qdf_list_node_t node;
4408 	struct va_md_entry data;
4409 };
4410 
qdf_va_md_notif_handler(struct notifier_block * this,unsigned long event,void * ptr)4411 static int qdf_va_md_notif_handler(struct notifier_block *this,
4412 				   unsigned long event, void *ptr)
4413 {
4414 	struct qdf_va_md_entry *entry;
4415 	struct qdf_va_md_entry *next;
4416 
4417 	qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
4418 	qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
4419 		qcom_va_md_add_region(&entry->data);
4420 	}
4421 
4422 	qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
4423 	return NOTIFY_OK;
4424 }
4425 
4426 static struct notifier_block qdf_va_md_notif_blk = {
4427 	.notifier_call = qdf_va_md_notif_handler,
4428 	.priority = INT_MAX,
4429 };
4430 
__qdf_minidump_init(void)4431 void __qdf_minidump_init(void)
4432 {
4433 	int ret;
4434 
4435 	if (qdf_va_md_initialized)
4436 		return;
4437 
4438 	qdf_spinlock_create(&qdf_va_md_list_lock);
4439 	qdf_list_create(&qdf_va_md_list, QDF_MINIDUMP_LIST_SIZE);
4440 	ret = qcom_va_md_register(qdf_trace_wlan_modname(),
4441 				  &qdf_va_md_notif_blk);
4442 	qdf_va_md_initialized = !ret;
4443 }
4444 
4445 qdf_export_symbol(__qdf_minidump_init);
4446 
__qdf_minidump_deinit(void)4447 void __qdf_minidump_deinit(void)
4448 {
4449 	struct qdf_va_md_entry *entry;
4450 	struct qdf_va_md_entry *next;
4451 
4452 	if (!qdf_va_md_initialized)
4453 		return;
4454 
4455 	qdf_va_md_initialized = false;
4456 	qcom_va_md_unregister(qdf_trace_wlan_modname(),
4457 			      &qdf_va_md_notif_blk);
4458 	qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
4459 	qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
4460 		qdf_list_remove_node(&qdf_va_md_list, &entry->node);
4461 		qdf_mem_free(entry);
4462 	}
4463 
4464 	qdf_list_destroy(&qdf_va_md_list);
4465 	qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
4466 	qdf_spinlock_destroy(&qdf_va_md_list_lock);
4467 }
4468 
4469 qdf_export_symbol(__qdf_minidump_deinit);
4470 
__qdf_minidump_log(void * start_addr,size_t size,const char * name)4471 void __qdf_minidump_log(void *start_addr, size_t size, const char *name)
4472 {
4473 	struct qdf_va_md_entry *entry;
4474 	QDF_STATUS status;
4475 
4476 	if (!qdf_va_md_initialized)
4477 		return;
4478 
4479 	entry = qdf_mem_malloc(sizeof(*entry));
4480 	if (!entry) {
4481 		qdf_err("malloc failed for %s: %pK, %zu",
4482 			name, start_addr, size);
4483 		return;
4484 	}
4485 
4486 	qdf_str_lcopy(entry->data.owner, name, sizeof(entry->data.owner));
4487 	entry->data.vaddr = (unsigned long)start_addr;
4488 	entry->data.size = size;
4489 
4490 	qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
4491 	status = qdf_list_insert_front(&qdf_va_md_list, &entry->node);
4492 	qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
4493 	if (QDF_IS_STATUS_ERROR(status)) {
4494 		qdf_err("Failed to insert qdf va md entry, status %d", status);
4495 		qdf_mem_free(entry);
4496 	}
4497 }
4498 
4499 qdf_export_symbol(__qdf_minidump_log);
4500 
__qdf_minidump_remove(void * addr,size_t size,const char * name)4501 void __qdf_minidump_remove(void *addr, size_t size, const char *name)
4502 {
4503 	struct qdf_va_md_entry *entry;
4504 	struct qdf_va_md_entry *next;
4505 
4506 	if (!qdf_va_md_initialized)
4507 		return;
4508 
4509 	qdf_spin_lock_irqsave(&qdf_va_md_list_lock);
4510 	qdf_list_for_each_del(&qdf_va_md_list, entry, next, node) {
4511 		if (entry->data.vaddr == (unsigned long)addr &&
4512 		    entry->data.size == size &&
4513 		    !qdf_str_cmp(entry->data.owner, name)) {
4514 			qdf_list_remove_node(&qdf_va_md_list, &entry->node);
4515 			qdf_mem_free(entry);
4516 			break;
4517 		}
4518 	}
4519 
4520 	qdf_spin_unlock_irqrestore(&qdf_va_md_list_lock);
4521 }
4522 
4523 qdf_export_symbol(__qdf_minidump_remove);
4524 #endif
4525