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