xref: /wlan-driver/qca-wifi-host-cmn/wmi/src/wmi_unified.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /*
21*5113495bSYour Name  * Host WMI unified implementation
22*5113495bSYour Name  */
23*5113495bSYour Name #include "htc_api.h"
24*5113495bSYour Name #include "htc_api.h"
25*5113495bSYour Name #include "wmi_unified_priv.h"
26*5113495bSYour Name #include "wmi_unified_api.h"
27*5113495bSYour Name #include "qdf_module.h"
28*5113495bSYour Name #include "qdf_platform.h"
29*5113495bSYour Name #include "qdf_ssr_driver_dump.h"
30*5113495bSYour Name #ifdef WMI_EXT_DBG
31*5113495bSYour Name #include "qdf_list.h"
32*5113495bSYour Name #include "qdf_atomic.h"
33*5113495bSYour Name #endif
34*5113495bSYour Name 
35*5113495bSYour Name #ifndef WMI_NON_TLV_SUPPORT
36*5113495bSYour Name #include "wmi_tlv_helper.h"
37*5113495bSYour Name #endif
38*5113495bSYour Name 
39*5113495bSYour Name #include <linux/debugfs.h>
40*5113495bSYour Name #include <target_if.h>
41*5113495bSYour Name #include <qdf_debugfs.h>
42*5113495bSYour Name #include "wmi_filtered_logging.h"
43*5113495bSYour Name #include <wmi_hang_event.h>
44*5113495bSYour Name 
45*5113495bSYour Name #ifdef DP_UMAC_HW_RESET_SUPPORT
46*5113495bSYour Name #include <cdp_txrx_ctrl.h>
47*5113495bSYour Name #endif
48*5113495bSYour Name 
49*5113495bSYour Name /* This check for CONFIG_WIN temporary added due to redeclaration compilation
50*5113495bSYour Name error in MCL. Error is caused due to inclusion of wmi.h in wmi_unified_api.h
51*5113495bSYour Name which gets included here through ol_if_athvar.h. Eventually it is expected that
52*5113495bSYour Name wmi.h will be removed from wmi_unified_api.h after cleanup, which will need
53*5113495bSYour Name WMI_CMD_HDR to be defined here. */
54*5113495bSYour Name /* Copied from wmi.h */
55*5113495bSYour Name #undef MS
56*5113495bSYour Name #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
57*5113495bSYour Name #undef SM
58*5113495bSYour Name #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
59*5113495bSYour Name #undef WO
60*5113495bSYour Name #define WO(_f)      ((_f##_OFFSET) >> 2)
61*5113495bSYour Name 
62*5113495bSYour Name #undef GET_FIELD
63*5113495bSYour Name #define GET_FIELD(_addr, _f) MS(*((uint32_t *)(_addr) + WO(_f)), _f)
64*5113495bSYour Name #undef SET_FIELD
65*5113495bSYour Name #define SET_FIELD(_addr, _f, _val)  \
66*5113495bSYour Name 	    (*((uint32_t *)(_addr) + WO(_f)) = \
67*5113495bSYour Name 		(*((uint32_t *)(_addr) + WO(_f)) & ~_f##_MASK) | SM(_val, _f))
68*5113495bSYour Name 
69*5113495bSYour Name #define WMI_GET_FIELD(_msg_buf, _msg_type, _f) \
70*5113495bSYour Name 	    GET_FIELD(_msg_buf, _msg_type ## _ ## _f)
71*5113495bSYour Name 
72*5113495bSYour Name #define WMI_SET_FIELD(_msg_buf, _msg_type, _f, _val) \
73*5113495bSYour Name 	    SET_FIELD(_msg_buf, _msg_type ## _ ## _f, _val)
74*5113495bSYour Name 
75*5113495bSYour Name #define WMI_EP_APASS           0x0
76*5113495bSYour Name #define WMI_EP_LPASS           0x1
77*5113495bSYour Name #define WMI_EP_SENSOR          0x2
78*5113495bSYour Name 
79*5113495bSYour Name #define WMI_INFOS_DBG_FILE_PERM (QDF_FILE_USR_READ | \
80*5113495bSYour Name 				 QDF_FILE_USR_WRITE | \
81*5113495bSYour Name 				 QDF_FILE_GRP_READ | \
82*5113495bSYour Name 				 QDF_FILE_OTH_READ)
83*5113495bSYour Name 
84*5113495bSYour Name /*
85*5113495bSYour Name  *  * Control Path
86*5113495bSYour Name  *   */
87*5113495bSYour Name typedef PREPACK struct {
88*5113495bSYour Name 	uint32_t	commandId:24,
89*5113495bSYour Name 			reserved:2, /* used for WMI endpoint ID */
90*5113495bSYour Name 			plt_priv:6; /* platform private */
91*5113495bSYour Name } POSTPACK WMI_CMD_HDR;        /* used for commands and events */
92*5113495bSYour Name 
93*5113495bSYour Name #define WMI_CMD_HDR_COMMANDID_LSB           0
94*5113495bSYour Name #define WMI_CMD_HDR_COMMANDID_MASK          0x00ffffff
95*5113495bSYour Name #define WMI_CMD_HDR_COMMANDID_OFFSET        0x00000000
96*5113495bSYour Name #define WMI_CMD_HDR_WMI_ENDPOINTID_MASK        0x03000000
97*5113495bSYour Name #define WMI_CMD_HDR_WMI_ENDPOINTID_OFFSET      24
98*5113495bSYour Name #define WMI_CMD_HDR_PLT_PRIV_LSB               24
99*5113495bSYour Name #define WMI_CMD_HDR_PLT_PRIV_MASK              0xff000000
100*5113495bSYour Name #define WMI_CMD_HDR_PLT_PRIV_OFFSET            0x00000000
101*5113495bSYour Name /* end of copy wmi.h */
102*5113495bSYour Name 
103*5113495bSYour Name #define WMI_MIN_HEAD_ROOM 64
104*5113495bSYour Name 
105*5113495bSYour Name /* WBUFF pool sizes for WMI */
106*5113495bSYour Name /* Allocation of size 256 bytes */
107*5113495bSYour Name #define WMI_WBUFF_POOL_0_SIZE 128
108*5113495bSYour Name /* Allocation of size 512 bytes */
109*5113495bSYour Name #define WMI_WBUFF_POOL_1_SIZE 16
110*5113495bSYour Name /* Allocation of size 1024 bytes */
111*5113495bSYour Name #define WMI_WBUFF_POOL_2_SIZE 8
112*5113495bSYour Name /* Allocation of size 2048 bytes */
113*5113495bSYour Name #define WMI_WBUFF_POOL_3_SIZE 8
114*5113495bSYour Name 
115*5113495bSYour Name /* wbuff pool buffer lengths in bytes for WMI*/
116*5113495bSYour Name #define WMI_WBUFF_LEN_POOL0 256
117*5113495bSYour Name #define WMI_WBUFF_LEN_POOL1 512
118*5113495bSYour Name #define WMI_WBUFF_LEN_POOL2 1024
119*5113495bSYour Name #define WMI_WBUFF_LEN_POOL3 2048
120*5113495bSYour Name 
121*5113495bSYour Name #define RX_DIAG_EVENT_WORK_PROCESS_MAX_COUNT 500
122*5113495bSYour Name 
123*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
124*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
125*5113495bSYour Name /* TODO Cleanup this backported function */
wmi_bp_seq_printf(qdf_debugfs_file_t m,const char * f,...)126*5113495bSYour Name static int wmi_bp_seq_printf(qdf_debugfs_file_t m, const char *f, ...)
127*5113495bSYour Name {
128*5113495bSYour Name 	va_list args;
129*5113495bSYour Name 
130*5113495bSYour Name 	va_start(args, f);
131*5113495bSYour Name 	seq_vprintf(m, f, args);
132*5113495bSYour Name 	va_end(args);
133*5113495bSYour Name 
134*5113495bSYour Name 	return 0;
135*5113495bSYour Name }
136*5113495bSYour Name #else
137*5113495bSYour Name #define wmi_bp_seq_printf(m, fmt, ...) seq_printf((m), fmt, ##__VA_ARGS__)
138*5113495bSYour Name #endif
139*5113495bSYour Name 
140*5113495bSYour Name #ifndef MAX_WMI_INSTANCES
141*5113495bSYour Name #define CUSTOM_MGMT_CMD_DATA_SIZE 4
142*5113495bSYour Name #endif
143*5113495bSYour Name 
144*5113495bSYour Name #ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
145*5113495bSYour Name /* WMI commands */
146*5113495bSYour Name uint32_t g_wmi_command_buf_idx = 0;
147*5113495bSYour Name struct wmi_command_debug wmi_command_log_buffer[WMI_CMD_DEBUG_MAX_ENTRY];
148*5113495bSYour Name 
149*5113495bSYour Name /* WMI commands TX completed */
150*5113495bSYour Name uint32_t g_wmi_command_tx_cmp_buf_idx = 0;
151*5113495bSYour Name struct wmi_command_cmp_debug
152*5113495bSYour Name 	wmi_command_tx_cmp_log_buffer[WMI_CMD_CMPL_DEBUG_MAX_ENTRY];
153*5113495bSYour Name 
154*5113495bSYour Name /* WMI events when processed */
155*5113495bSYour Name uint32_t g_wmi_event_buf_idx = 0;
156*5113495bSYour Name struct wmi_event_debug wmi_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
157*5113495bSYour Name 
158*5113495bSYour Name /* WMI events when queued */
159*5113495bSYour Name uint32_t g_wmi_rx_event_buf_idx = 0;
160*5113495bSYour Name struct wmi_event_debug wmi_rx_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
161*5113495bSYour Name #endif
162*5113495bSYour Name 
wmi_minidump_detach(struct wmi_unified * wmi_handle)163*5113495bSYour Name static void wmi_minidump_detach(struct wmi_unified *wmi_handle)
164*5113495bSYour Name {
165*5113495bSYour Name 	struct wmi_log_buf_t *info =
166*5113495bSYour Name 		&wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
167*5113495bSYour Name 	uint32_t buf_size = info->size * sizeof(struct wmi_command_cmp_debug);
168*5113495bSYour Name 
169*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_debug_log_info");
170*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_rx_event_idx");
171*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_rx_event");
172*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_event_log_idx");
173*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_event_log");
174*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_command_log_idx");
175*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_command_log");
176*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_tx_cmp_idx");
177*5113495bSYour Name 	qdf_ssr_driver_dump_unregister_region("wmi_tx_cmp");
178*5113495bSYour Name 	qdf_minidump_remove(info->buf, buf_size, "wmi_tx_cmp");
179*5113495bSYour Name }
180*5113495bSYour Name 
wmi_minidump_attach(struct wmi_unified * wmi_handle)181*5113495bSYour Name static void wmi_minidump_attach(struct wmi_unified *wmi_handle)
182*5113495bSYour Name {
183*5113495bSYour Name 	struct wmi_log_buf_t *info =
184*5113495bSYour Name 		&wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
185*5113495bSYour Name 	uint32_t buf_size = info->size * sizeof(struct wmi_command_cmp_debug);
186*5113495bSYour Name 
187*5113495bSYour Name 	qdf_minidump_log(info->buf, buf_size, "wmi_tx_cmp");
188*5113495bSYour Name 
189*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_tx_cmp", info->buf, buf_size);
190*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_tx_cmp_idx",
191*5113495bSYour Name 					    info->p_buf_tail_idx,
192*5113495bSYour Name 					    sizeof(*info->p_buf_tail_idx));
193*5113495bSYour Name 
194*5113495bSYour Name 	info = &wmi_handle->log_info.wmi_command_log_buf_info;
195*5113495bSYour Name 	buf_size = info->size * sizeof(struct wmi_command_debug);
196*5113495bSYour Name 
197*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_command_log", info->buf,
198*5113495bSYour Name 					    buf_size);
199*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_command_log_idx",
200*5113495bSYour Name 					    info->p_buf_tail_idx,
201*5113495bSYour Name 					    sizeof(*info->p_buf_tail_idx));
202*5113495bSYour Name 
203*5113495bSYour Name 	info = &wmi_handle->log_info.wmi_event_log_buf_info;
204*5113495bSYour Name 	buf_size = info->size * sizeof(struct wmi_event_debug);
205*5113495bSYour Name 
206*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_event_log", info->buf,
207*5113495bSYour Name 					    buf_size);
208*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_event_log_idx",
209*5113495bSYour Name 					    info->p_buf_tail_idx,
210*5113495bSYour Name 					    sizeof(*info->p_buf_tail_idx));
211*5113495bSYour Name 
212*5113495bSYour Name 	info = &wmi_handle->log_info.wmi_rx_event_log_buf_info;
213*5113495bSYour Name 	buf_size = info->size * sizeof(struct wmi_event_debug);
214*5113495bSYour Name 
215*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_rx_event", info->buf,
216*5113495bSYour Name 					    buf_size);
217*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_rx_event_idx",
218*5113495bSYour Name 					    info->p_buf_tail_idx,
219*5113495bSYour Name 					    sizeof(*info->p_buf_tail_idx));
220*5113495bSYour Name 
221*5113495bSYour Name 	qdf_ssr_driver_dump_register_region("wmi_debug_log_info",
222*5113495bSYour Name 					    &wmi_handle->log_info,
223*5113495bSYour Name 					    sizeof(wmi_handle->log_info));
224*5113495bSYour Name }
225*5113495bSYour Name 
226*5113495bSYour Name #define WMI_COMMAND_RECORD(h, a, b) {					\
227*5113495bSYour Name 	if (wmi_cmd_log_max_entry <=					\
228*5113495bSYour Name 		*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx))	\
229*5113495bSYour Name 		*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx) = 0;\
230*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.wmi_command_log_buf_info.buf)\
231*5113495bSYour Name 		[*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)]\
232*5113495bSYour Name 						.command = a;		\
233*5113495bSYour Name 	qdf_mem_copy(((struct wmi_command_debug *)h->log_info.		\
234*5113495bSYour Name 				wmi_command_log_buf_info.buf)		\
235*5113495bSYour Name 		[*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)].data,\
236*5113495bSYour Name 			b, wmi_record_max_length);			\
237*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.wmi_command_log_buf_info.buf)\
238*5113495bSYour Name 		[*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)].\
239*5113495bSYour Name 		time = qdf_get_log_timestamp();			\
240*5113495bSYour Name 	(*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx))++;	\
241*5113495bSYour Name 	h->log_info.wmi_command_log_buf_info.length++;			\
242*5113495bSYour Name }
243*5113495bSYour Name 
244*5113495bSYour Name #define WMI_COMMAND_TX_CMP_RECORD(h, a, b, da, pa) {			\
245*5113495bSYour Name 	if (wmi_cmd_cmpl_log_max_entry <=				\
246*5113495bSYour Name 		*(h->log_info.wmi_command_tx_cmp_log_buf_info.p_buf_tail_idx))\
247*5113495bSYour Name 		*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
248*5113495bSYour Name 				p_buf_tail_idx) = 0;			\
249*5113495bSYour Name 	((struct wmi_command_cmp_debug *)h->log_info.			\
250*5113495bSYour Name 		wmi_command_tx_cmp_log_buf_info.buf)			\
251*5113495bSYour Name 		[*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
252*5113495bSYour Name 				p_buf_tail_idx)].			\
253*5113495bSYour Name 							command	= a;	\
254*5113495bSYour Name 	qdf_mem_copy(((struct wmi_command_cmp_debug *)h->log_info.	\
255*5113495bSYour Name 				wmi_command_tx_cmp_log_buf_info.buf)	\
256*5113495bSYour Name 		[*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
257*5113495bSYour Name 			p_buf_tail_idx)].				\
258*5113495bSYour Name 		data, b, wmi_record_max_length);			\
259*5113495bSYour Name 	((struct wmi_command_cmp_debug *)h->log_info.			\
260*5113495bSYour Name 		wmi_command_tx_cmp_log_buf_info.buf)			\
261*5113495bSYour Name 		[*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
262*5113495bSYour Name 				p_buf_tail_idx)].			\
263*5113495bSYour Name 		time = qdf_get_log_timestamp();				\
264*5113495bSYour Name 	((struct wmi_command_cmp_debug *)h->log_info.			\
265*5113495bSYour Name 		wmi_command_tx_cmp_log_buf_info.buf)			\
266*5113495bSYour Name 		[*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
267*5113495bSYour Name 				p_buf_tail_idx)].			\
268*5113495bSYour Name 		dma_addr = da;						\
269*5113495bSYour Name 	((struct wmi_command_cmp_debug *)h->log_info.			\
270*5113495bSYour Name 		wmi_command_tx_cmp_log_buf_info.buf)			\
271*5113495bSYour Name 		[*(h->log_info.wmi_command_tx_cmp_log_buf_info.		\
272*5113495bSYour Name 				p_buf_tail_idx)].			\
273*5113495bSYour Name 		phy_addr = pa;						\
274*5113495bSYour Name 	(*(h->log_info.wmi_command_tx_cmp_log_buf_info.p_buf_tail_idx))++;\
275*5113495bSYour Name 	h->log_info.wmi_command_tx_cmp_log_buf_info.length++;		\
276*5113495bSYour Name }
277*5113495bSYour Name 
278*5113495bSYour Name #define WMI_EVENT_RECORD(h, a, b) {					\
279*5113495bSYour Name 	if (wmi_event_log_max_entry <=					\
280*5113495bSYour Name 		*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx))	\
281*5113495bSYour Name 		*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx) = 0;\
282*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_event_log_buf_info.buf)\
283*5113495bSYour Name 		[*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)].	\
284*5113495bSYour Name 		event = a;						\
285*5113495bSYour Name 	qdf_mem_copy(((struct wmi_event_debug *)h->log_info.		\
286*5113495bSYour Name 				wmi_event_log_buf_info.buf)		\
287*5113495bSYour Name 		[*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)].data, b,\
288*5113495bSYour Name 		wmi_record_max_length);					\
289*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_event_log_buf_info.buf)\
290*5113495bSYour Name 		[*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)].time =\
291*5113495bSYour Name 		qdf_get_log_timestamp();				\
292*5113495bSYour Name 	(*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx))++;	\
293*5113495bSYour Name 	h->log_info.wmi_event_log_buf_info.length++;			\
294*5113495bSYour Name }
295*5113495bSYour Name 
296*5113495bSYour Name #define WMI_RX_EVENT_RECORD(h, a, b) {					\
297*5113495bSYour Name 	if (wmi_event_log_max_entry <=					\
298*5113495bSYour Name 		*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx))\
299*5113495bSYour Name 		*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx) = 0;\
300*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_rx_event_log_buf_info.buf)\
301*5113495bSYour Name 		[*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
302*5113495bSYour Name 		event = a;						\
303*5113495bSYour Name 	qdf_mem_copy(((struct wmi_event_debug *)h->log_info.		\
304*5113495bSYour Name 				wmi_rx_event_log_buf_info.buf)		\
305*5113495bSYour Name 		[*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
306*5113495bSYour Name 			data, b, wmi_record_max_length);		\
307*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_rx_event_log_buf_info.buf)\
308*5113495bSYour Name 		[*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
309*5113495bSYour Name 		time =	qdf_get_log_timestamp();			\
310*5113495bSYour Name 	(*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx))++;	\
311*5113495bSYour Name 	h->log_info.wmi_rx_event_log_buf_info.length++;			\
312*5113495bSYour Name }
313*5113495bSYour Name 
314*5113495bSYour Name #ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
315*5113495bSYour Name uint32_t g_wmi_mgmt_command_buf_idx = 0;
316*5113495bSYour Name struct
317*5113495bSYour Name wmi_command_debug wmi_mgmt_command_log_buffer[WMI_MGMT_TX_DEBUG_MAX_ENTRY];
318*5113495bSYour Name 
319*5113495bSYour Name /* wmi_mgmt commands TX completed */
320*5113495bSYour Name uint32_t g_wmi_mgmt_command_tx_cmp_buf_idx = 0;
321*5113495bSYour Name struct wmi_command_debug
322*5113495bSYour Name wmi_mgmt_command_tx_cmp_log_buffer[WMI_MGMT_TX_CMPL_DEBUG_MAX_ENTRY];
323*5113495bSYour Name 
324*5113495bSYour Name /* wmi_mgmt events when received */
325*5113495bSYour Name uint32_t g_wmi_mgmt_rx_event_buf_idx = 0;
326*5113495bSYour Name struct wmi_event_debug
327*5113495bSYour Name wmi_mgmt_rx_event_log_buffer[WMI_MGMT_RX_DEBUG_MAX_ENTRY];
328*5113495bSYour Name 
329*5113495bSYour Name /* wmi_diag events when received */
330*5113495bSYour Name uint32_t g_wmi_diag_rx_event_buf_idx = 0;
331*5113495bSYour Name struct wmi_event_debug
332*5113495bSYour Name wmi_diag_rx_event_log_buffer[WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY];
333*5113495bSYour Name #endif
334*5113495bSYour Name 
335*5113495bSYour Name #define WMI_MGMT_COMMAND_RECORD(h, a, b) {                              \
336*5113495bSYour Name 	if (wmi_mgmt_tx_log_max_entry <=                                   \
337*5113495bSYour Name 		*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)) \
338*5113495bSYour Name 		*(h->log_info.wmi_mgmt_command_log_buf_info.		\
339*5113495bSYour Name 				p_buf_tail_idx) = 0;			\
340*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.                       \
341*5113495bSYour Name 		 wmi_mgmt_command_log_buf_info.buf)                     \
342*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
343*5113495bSYour Name 			command = a;                                    \
344*5113495bSYour Name 	qdf_mem_copy(((struct wmi_command_debug *)h->log_info.          \
345*5113495bSYour Name 				wmi_mgmt_command_log_buf_info.buf)      \
346*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
347*5113495bSYour Name 		data, b,                                                \
348*5113495bSYour Name 		wmi_record_max_length);                                	\
349*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.                       \
350*5113495bSYour Name 		 wmi_mgmt_command_log_buf_info.buf)                     \
351*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
352*5113495bSYour Name 			time =        qdf_get_log_timestamp();          \
353*5113495bSYour Name 	(*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx))++;\
354*5113495bSYour Name 	h->log_info.wmi_mgmt_command_log_buf_info.length++;             \
355*5113495bSYour Name }
356*5113495bSYour Name 
357*5113495bSYour Name #define WMI_MGMT_COMMAND_TX_CMP_RECORD(h, a, b) {			\
358*5113495bSYour Name 	if (wmi_mgmt_tx_cmpl_log_max_entry <=				\
359*5113495bSYour Name 		*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.	\
360*5113495bSYour Name 			p_buf_tail_idx))				\
361*5113495bSYour Name 		*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.	\
362*5113495bSYour Name 			p_buf_tail_idx) = 0;				\
363*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.			\
364*5113495bSYour Name 			wmi_mgmt_command_tx_cmp_log_buf_info.buf)	\
365*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.	\
366*5113495bSYour Name 				p_buf_tail_idx)].command = a;		\
367*5113495bSYour Name 	qdf_mem_copy(((struct wmi_command_debug *)h->log_info.		\
368*5113495bSYour Name 				wmi_mgmt_command_tx_cmp_log_buf_info.buf)\
369*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.	\
370*5113495bSYour Name 			p_buf_tail_idx)].data, b,			\
371*5113495bSYour Name 			wmi_record_max_length);				\
372*5113495bSYour Name 	((struct wmi_command_debug *)h->log_info.			\
373*5113495bSYour Name 			wmi_mgmt_command_tx_cmp_log_buf_info.buf)	\
374*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.	\
375*5113495bSYour Name 				p_buf_tail_idx)].time =			\
376*5113495bSYour Name 		qdf_get_log_timestamp();				\
377*5113495bSYour Name 	(*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.		\
378*5113495bSYour Name 			p_buf_tail_idx))++;				\
379*5113495bSYour Name 	h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.length++;	\
380*5113495bSYour Name }
381*5113495bSYour Name 
382*5113495bSYour Name #define WMI_MGMT_RX_EVENT_RECORD(h, a, b) do {				\
383*5113495bSYour Name 	if (wmi_mgmt_rx_log_max_entry <=				\
384*5113495bSYour Name 		*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx))\
385*5113495bSYour Name 		*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx) = 0;\
386*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_mgmt_event_log_buf_info.buf)\
387*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)]\
388*5113495bSYour Name 					.event = a;			\
389*5113495bSYour Name 	qdf_mem_copy(((struct wmi_event_debug *)h->log_info.		\
390*5113495bSYour Name 				wmi_mgmt_event_log_buf_info.buf)	\
391*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)].\
392*5113495bSYour Name 			data, b, wmi_record_max_length);		\
393*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_mgmt_event_log_buf_info.buf)\
394*5113495bSYour Name 		[*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)].\
395*5113495bSYour Name 			time = qdf_get_log_timestamp();			\
396*5113495bSYour Name 	(*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx))++;	\
397*5113495bSYour Name 	h->log_info.wmi_mgmt_event_log_buf_info.length++;		\
398*5113495bSYour Name } while (0);
399*5113495bSYour Name 
400*5113495bSYour Name #define WMI_DIAG_RX_EVENT_RECORD(h, a, b) do {                             \
401*5113495bSYour Name 	if (wmi_diag_log_max_entry <=                                   \
402*5113495bSYour Name 		*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))\
403*5113495bSYour Name 		*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx) = 0;\
404*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
405*5113495bSYour Name 		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)]\
406*5113495bSYour Name 					.event = a;                     \
407*5113495bSYour Name 	qdf_mem_copy(((struct wmi_event_debug *)h->log_info.            \
408*5113495bSYour Name 				wmi_diag_event_log_buf_info.buf)        \
409*5113495bSYour Name 		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
410*5113495bSYour Name 			data, b, wmi_record_max_length);                \
411*5113495bSYour Name 	((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
412*5113495bSYour Name 		[*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
413*5113495bSYour Name 			time = qdf_get_log_timestamp();                 \
414*5113495bSYour Name 	(*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))++;  \
415*5113495bSYour Name 	h->log_info.wmi_diag_event_log_buf_info.length++;               \
416*5113495bSYour Name } while (0);
417*5113495bSYour Name 
418*5113495bSYour Name /* These are defined to made it as module param, which can be configured */
419*5113495bSYour Name /* WMI Commands */
420*5113495bSYour Name uint32_t wmi_cmd_log_max_entry = WMI_CMD_DEBUG_MAX_ENTRY;
421*5113495bSYour Name uint32_t wmi_cmd_cmpl_log_max_entry = WMI_CMD_CMPL_DEBUG_MAX_ENTRY;
422*5113495bSYour Name /* WMI Events */
423*5113495bSYour Name uint32_t wmi_event_log_max_entry = WMI_EVENT_DEBUG_MAX_ENTRY;
424*5113495bSYour Name /* WMI MGMT Tx */
425*5113495bSYour Name uint32_t wmi_mgmt_tx_log_max_entry = WMI_MGMT_TX_DEBUG_MAX_ENTRY;
426*5113495bSYour Name uint32_t wmi_mgmt_tx_cmpl_log_max_entry = WMI_MGMT_TX_CMPL_DEBUG_MAX_ENTRY;
427*5113495bSYour Name /* WMI MGMT Rx */
428*5113495bSYour Name uint32_t wmi_mgmt_rx_log_max_entry = WMI_MGMT_RX_DEBUG_MAX_ENTRY;
429*5113495bSYour Name /* WMI Diag Event */
430*5113495bSYour Name uint32_t wmi_diag_log_max_entry = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
431*5113495bSYour Name /* WMI capture size */
432*5113495bSYour Name uint32_t wmi_record_max_length = WMI_DEBUG_ENTRY_MAX_LENGTH;
433*5113495bSYour Name uint32_t wmi_display_size = 100;
434*5113495bSYour Name 
435*5113495bSYour Name /**
436*5113495bSYour Name  * wmi_log_init() - Initialize WMI event logging
437*5113495bSYour Name  * @wmi_handle: WMI handle.
438*5113495bSYour Name  *
439*5113495bSYour Name  * Return: Initialization status
440*5113495bSYour Name  */
441*5113495bSYour Name #ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
wmi_log_init(struct wmi_unified * wmi_handle)442*5113495bSYour Name static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
443*5113495bSYour Name {
444*5113495bSYour Name 	struct wmi_log_buf_t *cmd_log_buf =
445*5113495bSYour Name 			&wmi_handle->log_info.wmi_command_log_buf_info;
446*5113495bSYour Name 	struct wmi_log_buf_t *cmd_tx_cmpl_log_buf =
447*5113495bSYour Name 			&wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
448*5113495bSYour Name 
449*5113495bSYour Name 	struct wmi_log_buf_t *event_log_buf =
450*5113495bSYour Name 			&wmi_handle->log_info.wmi_event_log_buf_info;
451*5113495bSYour Name 	struct wmi_log_buf_t *rx_event_log_buf =
452*5113495bSYour Name 			&wmi_handle->log_info.wmi_rx_event_log_buf_info;
453*5113495bSYour Name 
454*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_cmd_log_buf =
455*5113495bSYour Name 			&wmi_handle->log_info.wmi_mgmt_command_log_buf_info;
456*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_cmd_tx_cmp_log_buf =
457*5113495bSYour Name 		&wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
458*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_event_log_buf =
459*5113495bSYour Name 			&wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
460*5113495bSYour Name 	struct wmi_log_buf_t *diag_event_log_buf =
461*5113495bSYour Name 			&wmi_handle->log_info.wmi_diag_event_log_buf_info;
462*5113495bSYour Name 
463*5113495bSYour Name 	/* WMI commands */
464*5113495bSYour Name 	cmd_log_buf->length = 0;
465*5113495bSYour Name 	cmd_log_buf->buf_tail_idx = 0;
466*5113495bSYour Name 	cmd_log_buf->buf = wmi_command_log_buffer;
467*5113495bSYour Name 	cmd_log_buf->p_buf_tail_idx = &g_wmi_command_buf_idx;
468*5113495bSYour Name 	cmd_log_buf->size = WMI_CMD_DEBUG_MAX_ENTRY;
469*5113495bSYour Name 
470*5113495bSYour Name 	/* WMI commands TX completed */
471*5113495bSYour Name 	cmd_tx_cmpl_log_buf->length = 0;
472*5113495bSYour Name 	cmd_tx_cmpl_log_buf->buf_tail_idx = 0;
473*5113495bSYour Name 	cmd_tx_cmpl_log_buf->buf = wmi_command_tx_cmp_log_buffer;
474*5113495bSYour Name 	cmd_tx_cmpl_log_buf->p_buf_tail_idx = &g_wmi_command_tx_cmp_buf_idx;
475*5113495bSYour Name 	cmd_tx_cmpl_log_buf->size = WMI_CMD_CMPL_DEBUG_MAX_ENTRY;
476*5113495bSYour Name 
477*5113495bSYour Name 	/* WMI events when processed */
478*5113495bSYour Name 	event_log_buf->length = 0;
479*5113495bSYour Name 	event_log_buf->buf_tail_idx = 0;
480*5113495bSYour Name 	event_log_buf->buf = wmi_event_log_buffer;
481*5113495bSYour Name 	event_log_buf->p_buf_tail_idx = &g_wmi_event_buf_idx;
482*5113495bSYour Name 	event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
483*5113495bSYour Name 
484*5113495bSYour Name 	/* WMI events when queued */
485*5113495bSYour Name 	rx_event_log_buf->length = 0;
486*5113495bSYour Name 	rx_event_log_buf->buf_tail_idx = 0;
487*5113495bSYour Name 	rx_event_log_buf->buf = wmi_rx_event_log_buffer;
488*5113495bSYour Name 	rx_event_log_buf->p_buf_tail_idx = &g_wmi_rx_event_buf_idx;
489*5113495bSYour Name 	rx_event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
490*5113495bSYour Name 
491*5113495bSYour Name 	/* WMI Management commands */
492*5113495bSYour Name 	mgmt_cmd_log_buf->length = 0;
493*5113495bSYour Name 	mgmt_cmd_log_buf->buf_tail_idx = 0;
494*5113495bSYour Name 	mgmt_cmd_log_buf->buf = wmi_mgmt_command_log_buffer;
495*5113495bSYour Name 	mgmt_cmd_log_buf->p_buf_tail_idx = &g_wmi_mgmt_command_buf_idx;
496*5113495bSYour Name 	mgmt_cmd_log_buf->size = WMI_MGMT_TX_DEBUG_MAX_ENTRY;
497*5113495bSYour Name 
498*5113495bSYour Name 	/* WMI Management commands Tx completed*/
499*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->length = 0;
500*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->buf_tail_idx = 0;
501*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->buf = wmi_mgmt_command_tx_cmp_log_buffer;
502*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx =
503*5113495bSYour Name 		&g_wmi_mgmt_command_tx_cmp_buf_idx;
504*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->size = WMI_MGMT_TX_CMPL_DEBUG_MAX_ENTRY;
505*5113495bSYour Name 
506*5113495bSYour Name 	/* WMI Management events when received */
507*5113495bSYour Name 	mgmt_event_log_buf->length = 0;
508*5113495bSYour Name 	mgmt_event_log_buf->buf_tail_idx = 0;
509*5113495bSYour Name 	mgmt_event_log_buf->buf = wmi_mgmt_rx_event_log_buffer;
510*5113495bSYour Name 	mgmt_event_log_buf->p_buf_tail_idx = &g_wmi_mgmt_rx_event_buf_idx;
511*5113495bSYour Name 	mgmt_event_log_buf->size = WMI_MGMT_RX_DEBUG_MAX_ENTRY;
512*5113495bSYour Name 
513*5113495bSYour Name 	/* WMI diag events when received */
514*5113495bSYour Name 	diag_event_log_buf->length = 0;
515*5113495bSYour Name 	diag_event_log_buf->buf_tail_idx = 0;
516*5113495bSYour Name 	diag_event_log_buf->buf = wmi_diag_rx_event_log_buffer;
517*5113495bSYour Name 	diag_event_log_buf->p_buf_tail_idx = &g_wmi_diag_rx_event_buf_idx;
518*5113495bSYour Name 	diag_event_log_buf->size = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
519*5113495bSYour Name 
520*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
521*5113495bSYour Name 	wmi_handle->log_info.wmi_logging_enable = 1;
522*5113495bSYour Name 
523*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
524*5113495bSYour Name }
525*5113495bSYour Name #else
wmi_log_init(struct wmi_unified * wmi_handle)526*5113495bSYour Name static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
527*5113495bSYour Name {
528*5113495bSYour Name 	struct wmi_log_buf_t *cmd_log_buf =
529*5113495bSYour Name 			&wmi_handle->log_info.wmi_command_log_buf_info;
530*5113495bSYour Name 	struct wmi_log_buf_t *cmd_tx_cmpl_log_buf =
531*5113495bSYour Name 			&wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
532*5113495bSYour Name 
533*5113495bSYour Name 	struct wmi_log_buf_t *event_log_buf =
534*5113495bSYour Name 			&wmi_handle->log_info.wmi_event_log_buf_info;
535*5113495bSYour Name 	struct wmi_log_buf_t *rx_event_log_buf =
536*5113495bSYour Name 			&wmi_handle->log_info.wmi_rx_event_log_buf_info;
537*5113495bSYour Name 
538*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_cmd_log_buf =
539*5113495bSYour Name 			&wmi_handle->log_info.wmi_mgmt_command_log_buf_info;
540*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_cmd_tx_cmp_log_buf =
541*5113495bSYour Name 		&wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
542*5113495bSYour Name 	struct wmi_log_buf_t *mgmt_event_log_buf =
543*5113495bSYour Name 			&wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
544*5113495bSYour Name 	struct wmi_log_buf_t *diag_event_log_buf =
545*5113495bSYour Name 			&wmi_handle->log_info.wmi_diag_event_log_buf_info;
546*5113495bSYour Name 
547*5113495bSYour Name 	wmi_handle->log_info.wmi_logging_enable = 0;
548*5113495bSYour Name 
549*5113495bSYour Name 	/* WMI commands */
550*5113495bSYour Name 	cmd_log_buf->length = 0;
551*5113495bSYour Name 	cmd_log_buf->buf_tail_idx = 0;
552*5113495bSYour Name 	cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc(
553*5113495bSYour Name 		wmi_cmd_log_max_entry * sizeof(struct wmi_command_debug));
554*5113495bSYour Name 	cmd_log_buf->size = wmi_cmd_log_max_entry;
555*5113495bSYour Name 
556*5113495bSYour Name 	if (!cmd_log_buf->buf)
557*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
558*5113495bSYour Name 
559*5113495bSYour Name 	cmd_log_buf->p_buf_tail_idx = &cmd_log_buf->buf_tail_idx;
560*5113495bSYour Name 
561*5113495bSYour Name 	/* WMI commands TX completed */
562*5113495bSYour Name 	cmd_tx_cmpl_log_buf->length = 0;
563*5113495bSYour Name 	cmd_tx_cmpl_log_buf->buf_tail_idx = 0;
564*5113495bSYour Name 	cmd_tx_cmpl_log_buf->buf = (struct wmi_command_cmp_debug *) qdf_mem_malloc(
565*5113495bSYour Name 		wmi_cmd_cmpl_log_max_entry * sizeof(struct wmi_command_cmp_debug));
566*5113495bSYour Name 	cmd_tx_cmpl_log_buf->size = wmi_cmd_cmpl_log_max_entry;
567*5113495bSYour Name 
568*5113495bSYour Name 	if (!cmd_tx_cmpl_log_buf->buf)
569*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
570*5113495bSYour Name 
571*5113495bSYour Name 	cmd_tx_cmpl_log_buf->p_buf_tail_idx =
572*5113495bSYour Name 		&cmd_tx_cmpl_log_buf->buf_tail_idx;
573*5113495bSYour Name 
574*5113495bSYour Name 	/* WMI events when processed */
575*5113495bSYour Name 	event_log_buf->length = 0;
576*5113495bSYour Name 	event_log_buf->buf_tail_idx = 0;
577*5113495bSYour Name 	event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
578*5113495bSYour Name 		wmi_event_log_max_entry * sizeof(struct wmi_event_debug));
579*5113495bSYour Name 	event_log_buf->size = wmi_event_log_max_entry;
580*5113495bSYour Name 
581*5113495bSYour Name 	if (!event_log_buf->buf)
582*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
583*5113495bSYour Name 
584*5113495bSYour Name 	event_log_buf->p_buf_tail_idx = &event_log_buf->buf_tail_idx;
585*5113495bSYour Name 
586*5113495bSYour Name 	/* WMI events when queued */
587*5113495bSYour Name 	rx_event_log_buf->length = 0;
588*5113495bSYour Name 	rx_event_log_buf->buf_tail_idx = 0;
589*5113495bSYour Name 	rx_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
590*5113495bSYour Name 		wmi_event_log_max_entry * sizeof(struct wmi_event_debug));
591*5113495bSYour Name 	rx_event_log_buf->size = wmi_event_log_max_entry;
592*5113495bSYour Name 
593*5113495bSYour Name 	if (!rx_event_log_buf->buf)
594*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
595*5113495bSYour Name 
596*5113495bSYour Name 	rx_event_log_buf->p_buf_tail_idx = &rx_event_log_buf->buf_tail_idx;
597*5113495bSYour Name 
598*5113495bSYour Name 	/* WMI Management commands */
599*5113495bSYour Name 	mgmt_cmd_log_buf->length = 0;
600*5113495bSYour Name 	mgmt_cmd_log_buf->buf_tail_idx = 0;
601*5113495bSYour Name 	mgmt_cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc(
602*5113495bSYour Name 		wmi_mgmt_tx_log_max_entry * sizeof(struct wmi_command_debug));
603*5113495bSYour Name 	mgmt_cmd_log_buf->size = wmi_mgmt_tx_log_max_entry;
604*5113495bSYour Name 
605*5113495bSYour Name 	if (!mgmt_cmd_log_buf->buf)
606*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
607*5113495bSYour Name 
608*5113495bSYour Name 	mgmt_cmd_log_buf->p_buf_tail_idx = &mgmt_cmd_log_buf->buf_tail_idx;
609*5113495bSYour Name 
610*5113495bSYour Name 	/* WMI Management commands Tx completed*/
611*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->length = 0;
612*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->buf_tail_idx = 0;
613*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->buf = (struct wmi_command_debug *)
614*5113495bSYour Name 		qdf_mem_malloc(
615*5113495bSYour Name 		wmi_mgmt_tx_cmpl_log_max_entry *
616*5113495bSYour Name 		sizeof(struct wmi_command_debug));
617*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->size = wmi_mgmt_tx_cmpl_log_max_entry;
618*5113495bSYour Name 
619*5113495bSYour Name 	if (!mgmt_cmd_tx_cmp_log_buf->buf)
620*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
621*5113495bSYour Name 
622*5113495bSYour Name 	mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx =
623*5113495bSYour Name 		&mgmt_cmd_tx_cmp_log_buf->buf_tail_idx;
624*5113495bSYour Name 
625*5113495bSYour Name 	/* WMI Management events when received */
626*5113495bSYour Name 	mgmt_event_log_buf->length = 0;
627*5113495bSYour Name 	mgmt_event_log_buf->buf_tail_idx = 0;
628*5113495bSYour Name 
629*5113495bSYour Name 	mgmt_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
630*5113495bSYour Name 		wmi_mgmt_rx_log_max_entry *
631*5113495bSYour Name 		sizeof(struct wmi_event_debug));
632*5113495bSYour Name 	mgmt_event_log_buf->size = wmi_mgmt_rx_log_max_entry;
633*5113495bSYour Name 
634*5113495bSYour Name 	if (!mgmt_event_log_buf->buf)
635*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
636*5113495bSYour Name 
637*5113495bSYour Name 	mgmt_event_log_buf->p_buf_tail_idx = &mgmt_event_log_buf->buf_tail_idx;
638*5113495bSYour Name 
639*5113495bSYour Name 	/* WMI diag events when received */
640*5113495bSYour Name 	diag_event_log_buf->length = 0;
641*5113495bSYour Name 	diag_event_log_buf->buf_tail_idx = 0;
642*5113495bSYour Name 
643*5113495bSYour Name 	diag_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
644*5113495bSYour Name 		wmi_diag_log_max_entry *
645*5113495bSYour Name 		sizeof(struct wmi_event_debug));
646*5113495bSYour Name 	diag_event_log_buf->size = wmi_diag_log_max_entry;
647*5113495bSYour Name 
648*5113495bSYour Name 	if (!diag_event_log_buf->buf)
649*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
650*5113495bSYour Name 
651*5113495bSYour Name 	diag_event_log_buf->p_buf_tail_idx = &diag_event_log_buf->buf_tail_idx;
652*5113495bSYour Name 
653*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
654*5113495bSYour Name 	wmi_handle->log_info.wmi_logging_enable = 1;
655*5113495bSYour Name 
656*5113495bSYour Name 	wmi_filtered_logging_init(wmi_handle);
657*5113495bSYour Name 
658*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
659*5113495bSYour Name }
660*5113495bSYour Name #endif
661*5113495bSYour Name 
662*5113495bSYour Name /**
663*5113495bSYour Name  * wmi_log_buffer_free() - Free all dynamic allocated buffer memory for
664*5113495bSYour Name  * event logging
665*5113495bSYour Name  * @wmi_handle: WMI handle.
666*5113495bSYour Name  *
667*5113495bSYour Name  * Return: None
668*5113495bSYour Name  */
669*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
wmi_log_buffer_free(struct wmi_unified * wmi_handle)670*5113495bSYour Name static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
671*5113495bSYour Name {
672*5113495bSYour Name 	wmi_filtered_logging_free(wmi_handle);
673*5113495bSYour Name 
674*5113495bSYour Name 	if (wmi_handle->log_info.wmi_command_log_buf_info.buf)
675*5113495bSYour Name 		qdf_mem_free(wmi_handle->log_info.wmi_command_log_buf_info.buf);
676*5113495bSYour Name 	if (wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info.buf)
677*5113495bSYour Name 		qdf_mem_free(
678*5113495bSYour Name 		wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info.buf);
679*5113495bSYour Name 	if (wmi_handle->log_info.wmi_event_log_buf_info.buf)
680*5113495bSYour Name 		qdf_mem_free(wmi_handle->log_info.wmi_event_log_buf_info.buf);
681*5113495bSYour Name 	if (wmi_handle->log_info.wmi_rx_event_log_buf_info.buf)
682*5113495bSYour Name 		qdf_mem_free(
683*5113495bSYour Name 			wmi_handle->log_info.wmi_rx_event_log_buf_info.buf);
684*5113495bSYour Name 	if (wmi_handle->log_info.wmi_mgmt_command_log_buf_info.buf)
685*5113495bSYour Name 		qdf_mem_free(
686*5113495bSYour Name 			wmi_handle->log_info.wmi_mgmt_command_log_buf_info.buf);
687*5113495bSYour Name 	if (wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.buf)
688*5113495bSYour Name 		qdf_mem_free(
689*5113495bSYour Name 		wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.buf);
690*5113495bSYour Name 	if (wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf)
691*5113495bSYour Name 		qdf_mem_free(
692*5113495bSYour Name 			wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf);
693*5113495bSYour Name 	if (wmi_handle->log_info.wmi_diag_event_log_buf_info.buf)
694*5113495bSYour Name 		qdf_mem_free(
695*5113495bSYour Name 			wmi_handle->log_info.wmi_diag_event_log_buf_info.buf);
696*5113495bSYour Name 	wmi_handle->log_info.wmi_logging_enable = 0;
697*5113495bSYour Name 
698*5113495bSYour Name 	qdf_spinlock_destroy(&wmi_handle->log_info.wmi_record_lock);
699*5113495bSYour Name }
700*5113495bSYour Name #else
wmi_log_buffer_free(struct wmi_unified * wmi_handle)701*5113495bSYour Name static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
702*5113495bSYour Name {
703*5113495bSYour Name 	/* Do Nothing */
704*5113495bSYour Name }
705*5113495bSYour Name #endif
706*5113495bSYour Name 
707*5113495bSYour Name /**
708*5113495bSYour Name  * wmi_print_cmd_log_buffer() - an output agnostic wmi command log printer
709*5113495bSYour Name  * @log_buffer: the command log buffer metadata of the buffer to print
710*5113495bSYour Name  * @count: the maximum number of entries to print
711*5113495bSYour Name  * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper
712*5113495bSYour Name  * @print_priv: any data required by the print method, e.g. a file handle
713*5113495bSYour Name  *
714*5113495bSYour Name  * Return: None
715*5113495bSYour Name  */
716*5113495bSYour Name static void
wmi_print_cmd_log_buffer(struct wmi_log_buf_t * log_buffer,uint32_t count,qdf_abstract_print * print,void * print_priv)717*5113495bSYour Name wmi_print_cmd_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count,
718*5113495bSYour Name 			 qdf_abstract_print *print, void *print_priv)
719*5113495bSYour Name {
720*5113495bSYour Name 	static const int data_len =
721*5113495bSYour Name 		WMI_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t);
722*5113495bSYour Name 	char str[128];
723*5113495bSYour Name 	uint32_t idx;
724*5113495bSYour Name 
725*5113495bSYour Name 	if (count > log_buffer->size)
726*5113495bSYour Name 		count = log_buffer->size;
727*5113495bSYour Name 	if (count > log_buffer->length)
728*5113495bSYour Name 		count = log_buffer->length;
729*5113495bSYour Name 
730*5113495bSYour Name 	/* subtract count from index, and wrap if necessary */
731*5113495bSYour Name 	idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count;
732*5113495bSYour Name 	idx %= log_buffer->size;
733*5113495bSYour Name 
734*5113495bSYour Name 	print(print_priv, "Time (seconds)      Cmd Id              Payload");
735*5113495bSYour Name 	while (count) {
736*5113495bSYour Name 		struct wmi_command_debug *cmd_log = (struct wmi_command_debug *)
737*5113495bSYour Name 			&((struct wmi_command_debug *)log_buffer->buf)[idx];
738*5113495bSYour Name 		uint64_t secs, usecs;
739*5113495bSYour Name 		int len = 0;
740*5113495bSYour Name 		int i;
741*5113495bSYour Name 
742*5113495bSYour Name 		qdf_log_timestamp_to_secs(cmd_log->time, &secs, &usecs);
743*5113495bSYour Name 		len += scnprintf(str + len, sizeof(str) - len,
744*5113495bSYour Name 				 "% 8lld.%06lld    %6u (0x%06x)    ",
745*5113495bSYour Name 				 secs, usecs,
746*5113495bSYour Name 				 cmd_log->command, cmd_log->command);
747*5113495bSYour Name 		for (i = 0; i < data_len; ++i) {
748*5113495bSYour Name 			len += scnprintf(str + len, sizeof(str) - len,
749*5113495bSYour Name 					 "0x%08x ", cmd_log->data[i]);
750*5113495bSYour Name 		}
751*5113495bSYour Name 
752*5113495bSYour Name 		print(print_priv, str);
753*5113495bSYour Name 
754*5113495bSYour Name 		--count;
755*5113495bSYour Name 		++idx;
756*5113495bSYour Name 		if (idx >= log_buffer->size)
757*5113495bSYour Name 			idx = 0;
758*5113495bSYour Name 	}
759*5113495bSYour Name }
760*5113495bSYour Name 
761*5113495bSYour Name /**
762*5113495bSYour Name  * wmi_dump_last_cmd_rec_info() - last wmi command tx completion time print
763*5113495bSYour Name  * @wmi_handle: wmi handle
764*5113495bSYour Name  *
765*5113495bSYour Name  * Return: None
766*5113495bSYour Name  */
767*5113495bSYour Name static void
wmi_dump_last_cmd_rec_info(wmi_unified_t wmi_handle)768*5113495bSYour Name wmi_dump_last_cmd_rec_info(wmi_unified_t wmi_handle) {
769*5113495bSYour Name 	uint32_t idx, idx_tx_cmp, cmd_tmp_log, cmd_tmp_tx_cmp;
770*5113495bSYour Name 	uint64_t secs, secs_tx_cmp, usecs, usecs_tx_cmp;
771*5113495bSYour Name 	struct wmi_command_debug *cmd_log;
772*5113495bSYour Name 	struct wmi_command_debug *cmd_log_tx_cmp;
773*5113495bSYour Name 	struct wmi_log_buf_t *log_buf =
774*5113495bSYour Name 		&wmi_handle->log_info.wmi_command_log_buf_info;
775*5113495bSYour Name 	struct wmi_log_buf_t *log_buf_tx_cmp =
776*5113495bSYour Name 		&wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
777*5113495bSYour Name 
778*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
779*5113495bSYour Name 
780*5113495bSYour Name 	(*log_buf->p_buf_tail_idx == 0) ? (idx = log_buf->size) :
781*5113495bSYour Name 		(idx = *log_buf->p_buf_tail_idx - 1);
782*5113495bSYour Name 	idx %= log_buf->size;
783*5113495bSYour Name 
784*5113495bSYour Name 	(*log_buf_tx_cmp->p_buf_tail_idx == 0) ? (idx_tx_cmp =
785*5113495bSYour Name 		log_buf_tx_cmp->size) : (idx_tx_cmp =
786*5113495bSYour Name 		*log_buf_tx_cmp->p_buf_tail_idx - 1);
787*5113495bSYour Name 	idx_tx_cmp %= log_buf_tx_cmp->size;
788*5113495bSYour Name 	cmd_log = &((struct wmi_command_debug *)log_buf->buf)[idx];
789*5113495bSYour Name 	cmd_log_tx_cmp = &((struct wmi_command_debug *)log_buf_tx_cmp->buf)
790*5113495bSYour Name 		[idx_tx_cmp];
791*5113495bSYour Name 	cmd_tmp_log = cmd_log->command;
792*5113495bSYour Name 	cmd_tmp_tx_cmp = cmd_log_tx_cmp->command;
793*5113495bSYour Name 	qdf_log_timestamp_to_secs(cmd_log->time, &secs, &usecs);
794*5113495bSYour Name 	qdf_log_timestamp_to_secs(cmd_log_tx_cmp->time, &secs_tx_cmp,
795*5113495bSYour Name 				  &usecs_tx_cmp);
796*5113495bSYour Name 
797*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
798*5113495bSYour Name 
799*5113495bSYour Name 	wmi_nofl_err("Last wmi command Time (s) = % 8lld.%06lld ",
800*5113495bSYour Name 		     secs, usecs);
801*5113495bSYour Name 	wmi_nofl_err("Last wmi Cmd_Id = (0x%06x) ", cmd_tmp_log);
802*5113495bSYour Name 	wmi_nofl_err("Last wmi command tx completion Time (s) = % 8lld.%06lld",
803*5113495bSYour Name 		     secs_tx_cmp, usecs_tx_cmp);
804*5113495bSYour Name 	wmi_nofl_err("Last wmi command tx completion Cmd_Id = (0x%06x) ",
805*5113495bSYour Name 		     cmd_tmp_tx_cmp);
806*5113495bSYour Name }
807*5113495bSYour Name 
808*5113495bSYour Name /**
809*5113495bSYour Name  * wmi_print_cmd_cmp_log_buffer() - wmi command completion log printer
810*5113495bSYour Name  * @log_buffer: the command completion log buffer metadata of the buffer to print
811*5113495bSYour Name  * @count: the maximum number of entries to print
812*5113495bSYour Name  * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper
813*5113495bSYour Name  * @print_priv: any data required by the print method, e.g. a file handle
814*5113495bSYour Name  *
815*5113495bSYour Name  * Return: None
816*5113495bSYour Name  */
817*5113495bSYour Name static void
wmi_print_cmd_cmp_log_buffer(struct wmi_log_buf_t * log_buffer,uint32_t count,qdf_abstract_print * print,void * print_priv)818*5113495bSYour Name wmi_print_cmd_cmp_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count,
819*5113495bSYour Name 			 qdf_abstract_print *print, void *print_priv)
820*5113495bSYour Name {
821*5113495bSYour Name 	static const int data_len =
822*5113495bSYour Name 		WMI_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t);
823*5113495bSYour Name 	char str[128];
824*5113495bSYour Name 	uint32_t idx;
825*5113495bSYour Name 
826*5113495bSYour Name 	if (count > log_buffer->size)
827*5113495bSYour Name 		count = log_buffer->size;
828*5113495bSYour Name 	if (count > log_buffer->length)
829*5113495bSYour Name 		count = log_buffer->length;
830*5113495bSYour Name 
831*5113495bSYour Name 	/* subtract count from index, and wrap if necessary */
832*5113495bSYour Name 	idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count;
833*5113495bSYour Name 	idx %= log_buffer->size;
834*5113495bSYour Name 
835*5113495bSYour Name 	print(print_priv, "Time (seconds)      Cmd Id              Payload");
836*5113495bSYour Name 	while (count) {
837*5113495bSYour Name 		struct wmi_command_cmp_debug *cmd_log = (struct wmi_command_cmp_debug *)
838*5113495bSYour Name 			&((struct wmi_command_cmp_debug *)log_buffer->buf)[idx];
839*5113495bSYour Name 		uint64_t secs, usecs;
840*5113495bSYour Name 		int len = 0;
841*5113495bSYour Name 		int i;
842*5113495bSYour Name 
843*5113495bSYour Name 		qdf_log_timestamp_to_secs(cmd_log->time, &secs, &usecs);
844*5113495bSYour Name 		len += scnprintf(str + len, sizeof(str) - len,
845*5113495bSYour Name 				 "% 8lld.%06lld    %6u (0x%06x)    ",
846*5113495bSYour Name 				 secs, usecs,
847*5113495bSYour Name 				 cmd_log->command, cmd_log->command);
848*5113495bSYour Name 		for (i = 0; i < data_len; ++i) {
849*5113495bSYour Name 			len += scnprintf(str + len, sizeof(str) - len,
850*5113495bSYour Name 					 "0x%08x ", cmd_log->data[i]);
851*5113495bSYour Name 		}
852*5113495bSYour Name 
853*5113495bSYour Name 		print(print_priv, str);
854*5113495bSYour Name 
855*5113495bSYour Name 		--count;
856*5113495bSYour Name 		++idx;
857*5113495bSYour Name 		if (idx >= log_buffer->size)
858*5113495bSYour Name 			idx = 0;
859*5113495bSYour Name 	}
860*5113495bSYour Name }
861*5113495bSYour Name 
862*5113495bSYour Name /**
863*5113495bSYour Name  * wmi_print_event_log_buffer() - an output agnostic wmi event log printer
864*5113495bSYour Name  * @log_buffer: the event log buffer metadata of the buffer to print
865*5113495bSYour Name  * @count: the maximum number of entries to print
866*5113495bSYour Name  * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper
867*5113495bSYour Name  * @print_priv: any data required by the print method, e.g. a file handle
868*5113495bSYour Name  *
869*5113495bSYour Name  * Return: None
870*5113495bSYour Name  */
871*5113495bSYour Name static void
wmi_print_event_log_buffer(struct wmi_log_buf_t * log_buffer,uint32_t count,qdf_abstract_print * print,void * print_priv)872*5113495bSYour Name wmi_print_event_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count,
873*5113495bSYour Name 			   qdf_abstract_print *print, void *print_priv)
874*5113495bSYour Name {
875*5113495bSYour Name 	static const int data_len =
876*5113495bSYour Name 		WMI_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t);
877*5113495bSYour Name 	char str[128];
878*5113495bSYour Name 	uint32_t idx;
879*5113495bSYour Name 
880*5113495bSYour Name 	if (count > log_buffer->size)
881*5113495bSYour Name 		count = log_buffer->size;
882*5113495bSYour Name 	if (count > log_buffer->length)
883*5113495bSYour Name 		count = log_buffer->length;
884*5113495bSYour Name 
885*5113495bSYour Name 	/* subtract count from index, and wrap if necessary */
886*5113495bSYour Name 	idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count;
887*5113495bSYour Name 	idx %= log_buffer->size;
888*5113495bSYour Name 
889*5113495bSYour Name 	print(print_priv, "Time (seconds)      Event Id             Payload");
890*5113495bSYour Name 	while (count) {
891*5113495bSYour Name 		struct wmi_event_debug *event_log = (struct wmi_event_debug *)
892*5113495bSYour Name 			&((struct wmi_event_debug *)log_buffer->buf)[idx];
893*5113495bSYour Name 		uint64_t secs, usecs;
894*5113495bSYour Name 		int len = 0;
895*5113495bSYour Name 		int i;
896*5113495bSYour Name 
897*5113495bSYour Name 		qdf_log_timestamp_to_secs(event_log->time, &secs, &usecs);
898*5113495bSYour Name 		len += scnprintf(str + len, sizeof(str) - len,
899*5113495bSYour Name 				 "% 8lld.%06lld    %6u (0x%06x)    ",
900*5113495bSYour Name 				 secs, usecs,
901*5113495bSYour Name 				 event_log->event, event_log->event);
902*5113495bSYour Name 		for (i = 0; i < data_len; ++i) {
903*5113495bSYour Name 			len += scnprintf(str + len, sizeof(str) - len,
904*5113495bSYour Name 					 "0x%08x ", event_log->data[i]);
905*5113495bSYour Name 		}
906*5113495bSYour Name 
907*5113495bSYour Name 		print(print_priv, str);
908*5113495bSYour Name 
909*5113495bSYour Name 		--count;
910*5113495bSYour Name 		++idx;
911*5113495bSYour Name 		if (idx >= log_buffer->size)
912*5113495bSYour Name 			idx = 0;
913*5113495bSYour Name 	}
914*5113495bSYour Name }
915*5113495bSYour Name 
916*5113495bSYour Name inline void
wmi_print_cmd_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)917*5113495bSYour Name wmi_print_cmd_log(wmi_unified_t wmi, uint32_t count,
918*5113495bSYour Name 		  qdf_abstract_print *print, void *print_priv)
919*5113495bSYour Name {
920*5113495bSYour Name 	wmi_print_cmd_log_buffer(
921*5113495bSYour Name 		&wmi->log_info.wmi_command_log_buf_info,
922*5113495bSYour Name 		count, print, print_priv);
923*5113495bSYour Name }
924*5113495bSYour Name 
925*5113495bSYour Name inline void
wmi_print_cmd_tx_cmp_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)926*5113495bSYour Name wmi_print_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count,
927*5113495bSYour Name 			 qdf_abstract_print *print, void *print_priv)
928*5113495bSYour Name {
929*5113495bSYour Name 	wmi_print_cmd_cmp_log_buffer(
930*5113495bSYour Name 		&wmi->log_info.wmi_command_tx_cmp_log_buf_info,
931*5113495bSYour Name 		count, print, print_priv);
932*5113495bSYour Name }
933*5113495bSYour Name 
934*5113495bSYour Name inline void
wmi_print_mgmt_cmd_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)935*5113495bSYour Name wmi_print_mgmt_cmd_log(wmi_unified_t wmi, uint32_t count,
936*5113495bSYour Name 		       qdf_abstract_print *print, void *print_priv)
937*5113495bSYour Name {
938*5113495bSYour Name 	wmi_print_cmd_log_buffer(
939*5113495bSYour Name 		&wmi->log_info.wmi_mgmt_command_log_buf_info,
940*5113495bSYour Name 		count, print, print_priv);
941*5113495bSYour Name }
942*5113495bSYour Name 
943*5113495bSYour Name inline void
wmi_print_mgmt_cmd_tx_cmp_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)944*5113495bSYour Name wmi_print_mgmt_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count,
945*5113495bSYour Name 			      qdf_abstract_print *print, void *print_priv)
946*5113495bSYour Name {
947*5113495bSYour Name 	wmi_print_cmd_log_buffer(
948*5113495bSYour Name 		&wmi->log_info.wmi_mgmt_command_tx_cmp_log_buf_info,
949*5113495bSYour Name 		count, print, print_priv);
950*5113495bSYour Name }
951*5113495bSYour Name 
952*5113495bSYour Name inline void
wmi_print_event_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)953*5113495bSYour Name wmi_print_event_log(wmi_unified_t wmi, uint32_t count,
954*5113495bSYour Name 		    qdf_abstract_print *print, void *print_priv)
955*5113495bSYour Name {
956*5113495bSYour Name 	wmi_print_event_log_buffer(
957*5113495bSYour Name 		&wmi->log_info.wmi_event_log_buf_info,
958*5113495bSYour Name 		count, print, print_priv);
959*5113495bSYour Name }
960*5113495bSYour Name 
961*5113495bSYour Name inline void
wmi_print_rx_event_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)962*5113495bSYour Name wmi_print_rx_event_log(wmi_unified_t wmi, uint32_t count,
963*5113495bSYour Name 		       qdf_abstract_print *print, void *print_priv)
964*5113495bSYour Name {
965*5113495bSYour Name 	wmi_print_event_log_buffer(
966*5113495bSYour Name 		&wmi->log_info.wmi_rx_event_log_buf_info,
967*5113495bSYour Name 		count, print, print_priv);
968*5113495bSYour Name }
969*5113495bSYour Name 
970*5113495bSYour Name inline void
wmi_print_mgmt_event_log(wmi_unified_t wmi,uint32_t count,qdf_abstract_print * print,void * print_priv)971*5113495bSYour Name wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count,
972*5113495bSYour Name 			 qdf_abstract_print *print, void *print_priv)
973*5113495bSYour Name {
974*5113495bSYour Name 	wmi_print_event_log_buffer(
975*5113495bSYour Name 		&wmi->log_info.wmi_mgmt_event_log_buf_info,
976*5113495bSYour Name 		count, print, print_priv);
977*5113495bSYour Name }
978*5113495bSYour Name 
979*5113495bSYour Name 
980*5113495bSYour Name /* debugfs routines*/
981*5113495bSYour Name 
982*5113495bSYour Name /*
983*5113495bSYour Name  * debug_wmi_##func_base##_show() - debugfs functions to display content of
984*5113495bSYour Name  * command and event buffers. Macro uses max buffer length to display
985*5113495bSYour Name  * buffer when it is wraparound.
986*5113495bSYour Name  *
987*5113495bSYour Name  * @m: debugfs handler to access wmi_handle
988*5113495bSYour Name  * @v: Variable arguments (not used)
989*5113495bSYour Name  *
990*5113495bSYour Name  * Return: Length of characters printed
991*5113495bSYour Name  */
992*5113495bSYour Name #define GENERATE_COMMAND_DEBUG_SHOW_FUNCS(func_base, wmi_ring_size, wmi_record_type)\
993*5113495bSYour Name 	static int debug_wmi_##func_base##_show(struct seq_file *m,	\
994*5113495bSYour Name 						void *v)		\
995*5113495bSYour Name 	{								\
996*5113495bSYour Name 		wmi_unified_t wmi_handle = (wmi_unified_t) m->private;	\
997*5113495bSYour Name 		struct wmi_log_buf_t *wmi_log =				\
998*5113495bSYour Name 			&wmi_handle->log_info.wmi_##func_base##_buf_info;\
999*5113495bSYour Name 		int pos, nread, outlen;					\
1000*5113495bSYour Name 		int i;							\
1001*5113495bSYour Name 		uint64_t secs, usecs;					\
1002*5113495bSYour Name 									\
1003*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
1004*5113495bSYour Name 		if (!wmi_log->length) {					\
1005*5113495bSYour Name 			qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
1006*5113495bSYour Name 			return wmi_bp_seq_printf(m,			\
1007*5113495bSYour Name 			"no elements to read from ring buffer!\n");	\
1008*5113495bSYour Name 		}							\
1009*5113495bSYour Name 									\
1010*5113495bSYour Name 		if (wmi_log->length <= wmi_ring_size)			\
1011*5113495bSYour Name 			nread = wmi_log->length;			\
1012*5113495bSYour Name 		else							\
1013*5113495bSYour Name 			nread = wmi_ring_size;				\
1014*5113495bSYour Name 									\
1015*5113495bSYour Name 		if (*(wmi_log->p_buf_tail_idx) == 0)			\
1016*5113495bSYour Name 			/* tail can be 0 after wrap-around */		\
1017*5113495bSYour Name 			pos = wmi_ring_size - 1;			\
1018*5113495bSYour Name 		else							\
1019*5113495bSYour Name 			pos = *(wmi_log->p_buf_tail_idx) - 1;		\
1020*5113495bSYour Name 									\
1021*5113495bSYour Name 		outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
1022*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
1023*5113495bSYour Name 		while (nread--) {					\
1024*5113495bSYour Name 			struct wmi_record_type *wmi_record;		\
1025*5113495bSYour Name 									\
1026*5113495bSYour Name 			wmi_record = (struct wmi_record_type *)	\
1027*5113495bSYour Name 			&(((struct wmi_record_type *)wmi_log->buf)[pos]);\
1028*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "CMD ID = %x\n",	\
1029*5113495bSYour Name 				(wmi_record->command));			\
1030*5113495bSYour Name 			qdf_log_timestamp_to_secs(wmi_record->time, &secs,\
1031*5113495bSYour Name 				&usecs);				\
1032*5113495bSYour Name 			outlen +=					\
1033*5113495bSYour Name 			wmi_bp_seq_printf(m, "CMD TIME = [%llu.%06llu]\n",\
1034*5113495bSYour Name 				secs, usecs);				\
1035*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "CMD = ");	\
1036*5113495bSYour Name 			for (i = 0; i < (wmi_record_max_length/		\
1037*5113495bSYour Name 					sizeof(uint32_t)); i++)		\
1038*5113495bSYour Name 				outlen += wmi_bp_seq_printf(m, "%x ",	\
1039*5113495bSYour Name 					wmi_record->data[i]);		\
1040*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "\n");		\
1041*5113495bSYour Name 									\
1042*5113495bSYour Name 			if (pos == 0)					\
1043*5113495bSYour Name 				pos = wmi_ring_size - 1;		\
1044*5113495bSYour Name 			else						\
1045*5113495bSYour Name 				pos--;					\
1046*5113495bSYour Name 		}							\
1047*5113495bSYour Name 		return outlen;						\
1048*5113495bSYour Name 	}								\
1049*5113495bSYour Name 
1050*5113495bSYour Name #define GENERATE_EVENT_DEBUG_SHOW_FUNCS(func_base, wmi_ring_size)	\
1051*5113495bSYour Name 	static int debug_wmi_##func_base##_show(struct seq_file *m,	\
1052*5113495bSYour Name 						void *v)		\
1053*5113495bSYour Name 	{								\
1054*5113495bSYour Name 		wmi_unified_t wmi_handle = (wmi_unified_t) m->private;	\
1055*5113495bSYour Name 		struct wmi_log_buf_t *wmi_log =				\
1056*5113495bSYour Name 			&wmi_handle->log_info.wmi_##func_base##_buf_info;\
1057*5113495bSYour Name 		int pos, nread, outlen;					\
1058*5113495bSYour Name 		int i;							\
1059*5113495bSYour Name 		uint64_t secs, usecs;					\
1060*5113495bSYour Name 									\
1061*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
1062*5113495bSYour Name 		if (!wmi_log->length) {					\
1063*5113495bSYour Name 			qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
1064*5113495bSYour Name 			return wmi_bp_seq_printf(m,			\
1065*5113495bSYour Name 			"no elements to read from ring buffer!\n");	\
1066*5113495bSYour Name 		}							\
1067*5113495bSYour Name 									\
1068*5113495bSYour Name 		if (wmi_log->length <= wmi_ring_size)			\
1069*5113495bSYour Name 			nread = wmi_log->length;			\
1070*5113495bSYour Name 		else							\
1071*5113495bSYour Name 			nread = wmi_ring_size;				\
1072*5113495bSYour Name 									\
1073*5113495bSYour Name 		if (*(wmi_log->p_buf_tail_idx) == 0)			\
1074*5113495bSYour Name 			/* tail can be 0 after wrap-around */		\
1075*5113495bSYour Name 			pos = wmi_ring_size - 1;			\
1076*5113495bSYour Name 		else							\
1077*5113495bSYour Name 			pos = *(wmi_log->p_buf_tail_idx) - 1;		\
1078*5113495bSYour Name 									\
1079*5113495bSYour Name 		outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
1080*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
1081*5113495bSYour Name 		while (nread--) {					\
1082*5113495bSYour Name 			struct wmi_event_debug *wmi_record;		\
1083*5113495bSYour Name 									\
1084*5113495bSYour Name 			wmi_record = (struct wmi_event_debug *)		\
1085*5113495bSYour Name 			&(((struct wmi_event_debug *)wmi_log->buf)[pos]);\
1086*5113495bSYour Name 			qdf_log_timestamp_to_secs(wmi_record->time, &secs,\
1087*5113495bSYour Name 				&usecs);				\
1088*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "Event ID = %x\n",\
1089*5113495bSYour Name 				(wmi_record->event));			\
1090*5113495bSYour Name 			outlen +=					\
1091*5113495bSYour Name 			wmi_bp_seq_printf(m, "Event TIME = [%llu.%06llu]\n",\
1092*5113495bSYour Name 				secs, usecs);				\
1093*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "CMD = ");	\
1094*5113495bSYour Name 			for (i = 0; i < (wmi_record_max_length/		\
1095*5113495bSYour Name 					sizeof(uint32_t)); i++)		\
1096*5113495bSYour Name 				outlen += wmi_bp_seq_printf(m, "%x ",	\
1097*5113495bSYour Name 					wmi_record->data[i]);		\
1098*5113495bSYour Name 			outlen += wmi_bp_seq_printf(m, "\n");		\
1099*5113495bSYour Name 									\
1100*5113495bSYour Name 			if (pos == 0)					\
1101*5113495bSYour Name 				pos = wmi_ring_size - 1;		\
1102*5113495bSYour Name 			else						\
1103*5113495bSYour Name 				pos--;					\
1104*5113495bSYour Name 		}							\
1105*5113495bSYour Name 		return outlen;						\
1106*5113495bSYour Name 	}
1107*5113495bSYour Name 
1108*5113495bSYour Name GENERATE_COMMAND_DEBUG_SHOW_FUNCS(command_log, wmi_display_size,
1109*5113495bSYour Name 				  wmi_command_debug);
1110*5113495bSYour Name GENERATE_COMMAND_DEBUG_SHOW_FUNCS(command_tx_cmp_log, wmi_display_size,
1111*5113495bSYour Name 				  wmi_command_cmp_debug);
1112*5113495bSYour Name GENERATE_EVENT_DEBUG_SHOW_FUNCS(event_log, wmi_display_size);
1113*5113495bSYour Name GENERATE_EVENT_DEBUG_SHOW_FUNCS(rx_event_log, wmi_display_size);
1114*5113495bSYour Name GENERATE_COMMAND_DEBUG_SHOW_FUNCS(mgmt_command_log, wmi_display_size,
1115*5113495bSYour Name 				  wmi_command_debug);
1116*5113495bSYour Name GENERATE_COMMAND_DEBUG_SHOW_FUNCS(mgmt_command_tx_cmp_log,
1117*5113495bSYour Name 					wmi_display_size,
1118*5113495bSYour Name 					wmi_command_debug);
1119*5113495bSYour Name GENERATE_EVENT_DEBUG_SHOW_FUNCS(mgmt_event_log, wmi_display_size);
1120*5113495bSYour Name 
1121*5113495bSYour Name /**
1122*5113495bSYour Name  * debug_wmi_enable_show() - debugfs functions to display enable state of
1123*5113495bSYour Name  * wmi logging feature.
1124*5113495bSYour Name  *
1125*5113495bSYour Name  * @m: debugfs handler to access wmi_handle
1126*5113495bSYour Name  * @v: Variable arguments (not used)
1127*5113495bSYour Name  *
1128*5113495bSYour Name  * Return: always 1
1129*5113495bSYour Name  */
debug_wmi_enable_show(struct seq_file * m,void * v)1130*5113495bSYour Name static int debug_wmi_enable_show(struct seq_file *m, void *v)
1131*5113495bSYour Name {
1132*5113495bSYour Name 	wmi_unified_t wmi_handle = (wmi_unified_t) m->private;
1133*5113495bSYour Name 
1134*5113495bSYour Name 	return wmi_bp_seq_printf(m, "%d\n",
1135*5113495bSYour Name 			wmi_handle->log_info.wmi_logging_enable);
1136*5113495bSYour Name }
1137*5113495bSYour Name 
1138*5113495bSYour Name /**
1139*5113495bSYour Name  * debug_wmi_log_size_show() - debugfs functions to display configured size of
1140*5113495bSYour Name  * wmi logging command/event buffer and management command/event buffer.
1141*5113495bSYour Name  *
1142*5113495bSYour Name  * @m: debugfs handler to access wmi_handle
1143*5113495bSYour Name  * @v: Variable arguments (not used)
1144*5113495bSYour Name  *
1145*5113495bSYour Name  * Return: Length of characters printed
1146*5113495bSYour Name  */
debug_wmi_log_size_show(struct seq_file * m,void * v)1147*5113495bSYour Name static int debug_wmi_log_size_show(struct seq_file *m, void *v)
1148*5113495bSYour Name {
1149*5113495bSYour Name 
1150*5113495bSYour Name 	wmi_bp_seq_printf(m, "WMI command/cmpl log max size:%d/%d\n",
1151*5113495bSYour Name 			  wmi_cmd_log_max_entry, wmi_cmd_cmpl_log_max_entry);
1152*5113495bSYour Name 	wmi_bp_seq_printf(m, "WMI management Tx/cmpl log max size:%d/%d\n",
1153*5113495bSYour Name 			  wmi_mgmt_tx_log_max_entry,
1154*5113495bSYour Name 			  wmi_mgmt_tx_cmpl_log_max_entry);
1155*5113495bSYour Name 	wmi_bp_seq_printf(m, "WMI event log max size:%d\n",
1156*5113495bSYour Name 			  wmi_event_log_max_entry);
1157*5113495bSYour Name 	wmi_bp_seq_printf(m, "WMI management Rx log max size:%d\n",
1158*5113495bSYour Name 			  wmi_mgmt_rx_log_max_entry);
1159*5113495bSYour Name 	return wmi_bp_seq_printf(m,
1160*5113495bSYour Name 				 "WMI diag log max size:%d\n",
1161*5113495bSYour Name 				 wmi_diag_log_max_entry);
1162*5113495bSYour Name }
1163*5113495bSYour Name 
1164*5113495bSYour Name /*
1165*5113495bSYour Name  * debug_wmi_##func_base##_write() - debugfs functions to clear
1166*5113495bSYour Name  * wmi logging command/event buffer and management command/event buffer.
1167*5113495bSYour Name  *
1168*5113495bSYour Name  * @file: file handler to access wmi_handle
1169*5113495bSYour Name  * @buf: received data buffer
1170*5113495bSYour Name  * @count: length of received buffer
1171*5113495bSYour Name  * @ppos: Not used
1172*5113495bSYour Name  *
1173*5113495bSYour Name  * Return: count
1174*5113495bSYour Name  */
1175*5113495bSYour Name #define GENERATE_DEBUG_WRITE_FUNCS(func_base, wmi_ring_size, wmi_record_type)\
1176*5113495bSYour Name 	static ssize_t debug_wmi_##func_base##_write(struct file *file,	\
1177*5113495bSYour Name 				const char __user *buf,			\
1178*5113495bSYour Name 				size_t count, loff_t *ppos)		\
1179*5113495bSYour Name 	{								\
1180*5113495bSYour Name 		int k, ret;						\
1181*5113495bSYour Name 		wmi_unified_t wmi_handle =				\
1182*5113495bSYour Name 			((struct seq_file *)file->private_data)->private;\
1183*5113495bSYour Name 		struct wmi_log_buf_t *wmi_log = &wmi_handle->log_info.	\
1184*5113495bSYour Name 				wmi_##func_base##_buf_info;		\
1185*5113495bSYour Name 		char locbuf[50] = {0x00};				\
1186*5113495bSYour Name 									\
1187*5113495bSYour Name 		if ((!buf) || (count > 50))				\
1188*5113495bSYour Name 			return -EFAULT;					\
1189*5113495bSYour Name 									\
1190*5113495bSYour Name 		if (copy_from_user(locbuf, buf, count))			\
1191*5113495bSYour Name 			return -EFAULT;					\
1192*5113495bSYour Name 									\
1193*5113495bSYour Name 		ret = sscanf(locbuf, "%d", &k);				\
1194*5113495bSYour Name 		if ((ret != 1) || (k != 0)) {                           \
1195*5113495bSYour Name 			wmi_err("Wrong input, echo 0 to clear the wmi buffer");\
1196*5113495bSYour Name 			return -EINVAL;					\
1197*5113495bSYour Name 		}							\
1198*5113495bSYour Name 									\
1199*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
1200*5113495bSYour Name 		qdf_mem_zero(wmi_log->buf, wmi_ring_size *		\
1201*5113495bSYour Name 				sizeof(struct wmi_record_type));	\
1202*5113495bSYour Name 		wmi_log->length = 0;					\
1203*5113495bSYour Name 		*(wmi_log->p_buf_tail_idx) = 0;				\
1204*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
1205*5113495bSYour Name 									\
1206*5113495bSYour Name 		return count;						\
1207*5113495bSYour Name 	}
1208*5113495bSYour Name 
1209*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(command_log, wmi_cmd_log_max_entry,
1210*5113495bSYour Name 			   wmi_command_debug);
1211*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(command_tx_cmp_log, wmi_cmd_cmpl_log_max_entry,
1212*5113495bSYour Name 			   wmi_command_cmp_debug);
1213*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(event_log, wmi_event_log_max_entry,
1214*5113495bSYour Name 			   wmi_event_debug);
1215*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(rx_event_log, wmi_event_log_max_entry,
1216*5113495bSYour Name 			   wmi_event_debug);
1217*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(mgmt_command_log, wmi_mgmt_tx_log_max_entry,
1218*5113495bSYour Name 			   wmi_command_debug);
1219*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(mgmt_command_tx_cmp_log,
1220*5113495bSYour Name 			   wmi_mgmt_tx_cmpl_log_max_entry, wmi_command_debug);
1221*5113495bSYour Name GENERATE_DEBUG_WRITE_FUNCS(mgmt_event_log, wmi_mgmt_rx_log_max_entry,
1222*5113495bSYour Name 			   wmi_event_debug);
1223*5113495bSYour Name 
1224*5113495bSYour Name /**
1225*5113495bSYour Name  * debug_wmi_enable_write() - debugfs functions to enable/disable
1226*5113495bSYour Name  * wmi logging feature.
1227*5113495bSYour Name  *
1228*5113495bSYour Name  * @file: file handler to access wmi_handle
1229*5113495bSYour Name  * @buf: received data buffer
1230*5113495bSYour Name  * @count: length of received buffer
1231*5113495bSYour Name  * @ppos: Not used
1232*5113495bSYour Name  *
1233*5113495bSYour Name  * Return: count
1234*5113495bSYour Name  */
debug_wmi_enable_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)1235*5113495bSYour Name static ssize_t debug_wmi_enable_write(struct file *file, const char __user *buf,
1236*5113495bSYour Name 					size_t count, loff_t *ppos)
1237*5113495bSYour Name {
1238*5113495bSYour Name 	wmi_unified_t wmi_handle =
1239*5113495bSYour Name 		((struct seq_file *)file->private_data)->private;
1240*5113495bSYour Name 	int k, ret;
1241*5113495bSYour Name 	char locbuf[50] = {0x00};
1242*5113495bSYour Name 
1243*5113495bSYour Name 	if ((!buf) || (count > 50))
1244*5113495bSYour Name 		return -EFAULT;
1245*5113495bSYour Name 
1246*5113495bSYour Name 	if (copy_from_user(locbuf, buf, count))
1247*5113495bSYour Name 		return -EFAULT;
1248*5113495bSYour Name 
1249*5113495bSYour Name 	ret = sscanf(locbuf, "%d", &k);
1250*5113495bSYour Name 	if ((ret != 1) || ((k != 0) && (k != 1)))
1251*5113495bSYour Name 		return -EINVAL;
1252*5113495bSYour Name 
1253*5113495bSYour Name 	wmi_handle->log_info.wmi_logging_enable = k;
1254*5113495bSYour Name 	return count;
1255*5113495bSYour Name }
1256*5113495bSYour Name 
1257*5113495bSYour Name /**
1258*5113495bSYour Name  * debug_wmi_log_size_write() - reserved.
1259*5113495bSYour Name  *
1260*5113495bSYour Name  * @file: file handler to access wmi_handle
1261*5113495bSYour Name  * @buf: received data buffer
1262*5113495bSYour Name  * @count: length of received buffer
1263*5113495bSYour Name  * @ppos: Not used
1264*5113495bSYour Name  *
1265*5113495bSYour Name  * Return: count
1266*5113495bSYour Name  */
debug_wmi_log_size_write(struct file * file,const char __user * buf,size_t count,loff_t * ppos)1267*5113495bSYour Name static ssize_t debug_wmi_log_size_write(struct file *file,
1268*5113495bSYour Name 		const char __user *buf, size_t count, loff_t *ppos)
1269*5113495bSYour Name {
1270*5113495bSYour Name 	return -EINVAL;
1271*5113495bSYour Name }
1272*5113495bSYour Name 
1273*5113495bSYour Name /* Structure to maintain debug information */
1274*5113495bSYour Name struct wmi_debugfs_info {
1275*5113495bSYour Name 	const char *name;
1276*5113495bSYour Name 	const struct file_operations *ops;
1277*5113495bSYour Name };
1278*5113495bSYour Name 
1279*5113495bSYour Name #define DEBUG_FOO(func_base) { .name = #func_base,			\
1280*5113495bSYour Name 	.ops = &debug_##func_base##_ops }
1281*5113495bSYour Name 
1282*5113495bSYour Name /*
1283*5113495bSYour Name  * debug_##func_base##_open() - Open debugfs entry for respective command
1284*5113495bSYour Name  * and event buffer.
1285*5113495bSYour Name  *
1286*5113495bSYour Name  * @inode: node for debug dir entry
1287*5113495bSYour Name  * @file: file handler
1288*5113495bSYour Name  *
1289*5113495bSYour Name  * Return: open status
1290*5113495bSYour Name  */
1291*5113495bSYour Name #define GENERATE_DEBUG_STRUCTS(func_base)				\
1292*5113495bSYour Name 	static int debug_##func_base##_open(struct inode *inode,	\
1293*5113495bSYour Name 						struct file *file)	\
1294*5113495bSYour Name 	{								\
1295*5113495bSYour Name 		return single_open(file, debug_##func_base##_show,	\
1296*5113495bSYour Name 				inode->i_private);			\
1297*5113495bSYour Name 	}								\
1298*5113495bSYour Name 									\
1299*5113495bSYour Name 									\
1300*5113495bSYour Name 	static struct file_operations debug_##func_base##_ops = {	\
1301*5113495bSYour Name 		.open		= debug_##func_base##_open,		\
1302*5113495bSYour Name 		.read		= seq_read,				\
1303*5113495bSYour Name 		.llseek		= seq_lseek,				\
1304*5113495bSYour Name 		.write		= debug_##func_base##_write,		\
1305*5113495bSYour Name 		.release	= single_release,			\
1306*5113495bSYour Name 	};
1307*5113495bSYour Name 
1308*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_command_log);
1309*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_command_tx_cmp_log);
1310*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_event_log);
1311*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_rx_event_log);
1312*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_mgmt_command_log);
1313*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_mgmt_command_tx_cmp_log);
1314*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_mgmt_event_log);
1315*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_enable);
1316*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_log_size);
1317*5113495bSYour Name #ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
1318*5113495bSYour Name GENERATE_DEBUG_STRUCTS(filtered_wmi_cmds);
1319*5113495bSYour Name GENERATE_DEBUG_STRUCTS(filtered_wmi_evts);
1320*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_filtered_command_log);
1321*5113495bSYour Name GENERATE_DEBUG_STRUCTS(wmi_filtered_event_log);
1322*5113495bSYour Name #endif
1323*5113495bSYour Name 
1324*5113495bSYour Name struct wmi_debugfs_info wmi_debugfs_infos[NUM_DEBUG_INFOS] = {
1325*5113495bSYour Name 	DEBUG_FOO(wmi_command_log),
1326*5113495bSYour Name 	DEBUG_FOO(wmi_command_tx_cmp_log),
1327*5113495bSYour Name 	DEBUG_FOO(wmi_event_log),
1328*5113495bSYour Name 	DEBUG_FOO(wmi_rx_event_log),
1329*5113495bSYour Name 	DEBUG_FOO(wmi_mgmt_command_log),
1330*5113495bSYour Name 	DEBUG_FOO(wmi_mgmt_command_tx_cmp_log),
1331*5113495bSYour Name 	DEBUG_FOO(wmi_mgmt_event_log),
1332*5113495bSYour Name 	DEBUG_FOO(wmi_enable),
1333*5113495bSYour Name 	DEBUG_FOO(wmi_log_size),
1334*5113495bSYour Name #ifdef WMI_INTERFACE_FILTERED_EVENT_LOGGING
1335*5113495bSYour Name 	DEBUG_FOO(filtered_wmi_cmds),
1336*5113495bSYour Name 	DEBUG_FOO(filtered_wmi_evts),
1337*5113495bSYour Name 	DEBUG_FOO(wmi_filtered_command_log),
1338*5113495bSYour Name 	DEBUG_FOO(wmi_filtered_event_log),
1339*5113495bSYour Name #endif
1340*5113495bSYour Name };
1341*5113495bSYour Name 
1342*5113495bSYour Name /**
1343*5113495bSYour Name  * wmi_debugfs_create() - Create debug_fs entry for wmi logging.
1344*5113495bSYour Name  *
1345*5113495bSYour Name  * @wmi_handle: wmi handle
1346*5113495bSYour Name  * @par_entry: debug directory entry
1347*5113495bSYour Name  *
1348*5113495bSYour Name  * Return: none
1349*5113495bSYour Name  */
wmi_debugfs_create(wmi_unified_t wmi_handle,struct dentry * par_entry)1350*5113495bSYour Name static void wmi_debugfs_create(wmi_unified_t wmi_handle,
1351*5113495bSYour Name 			       struct dentry *par_entry)
1352*5113495bSYour Name {
1353*5113495bSYour Name 	int i;
1354*5113495bSYour Name 
1355*5113495bSYour Name 	if (!par_entry)
1356*5113495bSYour Name 		goto out;
1357*5113495bSYour Name 
1358*5113495bSYour Name 	for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
1359*5113495bSYour Name 		wmi_handle->debugfs_de[i] = qdf_debugfs_create_entry(
1360*5113495bSYour Name 						wmi_debugfs_infos[i].name,
1361*5113495bSYour Name 						WMI_INFOS_DBG_FILE_PERM,
1362*5113495bSYour Name 						par_entry,
1363*5113495bSYour Name 						wmi_handle,
1364*5113495bSYour Name 						wmi_debugfs_infos[i].ops);
1365*5113495bSYour Name 
1366*5113495bSYour Name 		if (!wmi_handle->debugfs_de[i]) {
1367*5113495bSYour Name 			wmi_err("debug Entry creation failed!");
1368*5113495bSYour Name 			goto out;
1369*5113495bSYour Name 		}
1370*5113495bSYour Name 	}
1371*5113495bSYour Name 
1372*5113495bSYour Name 	return;
1373*5113495bSYour Name 
1374*5113495bSYour Name out:
1375*5113495bSYour Name 	wmi_err("debug Entry creation failed!");
1376*5113495bSYour Name 	wmi_log_buffer_free(wmi_handle);
1377*5113495bSYour Name 	return;
1378*5113495bSYour Name }
1379*5113495bSYour Name 
1380*5113495bSYour Name /**
1381*5113495bSYour Name  * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
1382*5113495bSYour Name  * @wmi_handle: wmi handle
1383*5113495bSYour Name  *
1384*5113495bSYour Name  * Return: none
1385*5113495bSYour Name  */
wmi_debugfs_remove(wmi_unified_t wmi_handle)1386*5113495bSYour Name static void wmi_debugfs_remove(wmi_unified_t wmi_handle)
1387*5113495bSYour Name {
1388*5113495bSYour Name 	int i;
1389*5113495bSYour Name 	struct dentry *dentry = wmi_handle->log_info.wmi_log_debugfs_dir;
1390*5113495bSYour Name 
1391*5113495bSYour Name 	if (dentry) {
1392*5113495bSYour Name 		for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
1393*5113495bSYour Name 			if (wmi_handle->debugfs_de[i])
1394*5113495bSYour Name 				wmi_handle->debugfs_de[i] = NULL;
1395*5113495bSYour Name 		}
1396*5113495bSYour Name 	}
1397*5113495bSYour Name 
1398*5113495bSYour Name 	if (dentry)
1399*5113495bSYour Name 		qdf_debugfs_remove_dir_recursive(dentry);
1400*5113495bSYour Name }
1401*5113495bSYour Name 
1402*5113495bSYour Name /**
1403*5113495bSYour Name  * wmi_debugfs_init() - debugfs functions to create debugfs directory and to
1404*5113495bSYour Name  *                      create debugfs entries.
1405*5113495bSYour Name  * @wmi_handle: wmi handler
1406*5113495bSYour Name  * @pdev_idx: pdev id
1407*5113495bSYour Name  *
1408*5113495bSYour Name  * Return: init status
1409*5113495bSYour Name  */
wmi_debugfs_init(wmi_unified_t wmi_handle,uint32_t pdev_idx)1410*5113495bSYour Name static QDF_STATUS wmi_debugfs_init(wmi_unified_t wmi_handle, uint32_t pdev_idx)
1411*5113495bSYour Name {
1412*5113495bSYour Name 	char buf[32];
1413*5113495bSYour Name 
1414*5113495bSYour Name 	snprintf(buf, sizeof(buf), "WMI_SOC%u_PDEV%u",
1415*5113495bSYour Name 		 wmi_handle->soc->soc_idx, pdev_idx);
1416*5113495bSYour Name 
1417*5113495bSYour Name 	wmi_handle->log_info.wmi_log_debugfs_dir =
1418*5113495bSYour Name 		qdf_debugfs_create_dir(buf, NULL);
1419*5113495bSYour Name 
1420*5113495bSYour Name 	if (!wmi_handle->log_info.wmi_log_debugfs_dir) {
1421*5113495bSYour Name 		wmi_err("error while creating debugfs dir for %s", buf);
1422*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1423*5113495bSYour Name 	}
1424*5113495bSYour Name 	wmi_debugfs_create(wmi_handle,
1425*5113495bSYour Name 			   wmi_handle->log_info.wmi_log_debugfs_dir);
1426*5113495bSYour Name 
1427*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1428*5113495bSYour Name }
1429*5113495bSYour Name 
wmi_mgmt_cmd_record(wmi_unified_t wmi_handle,uint32_t cmd,void * header,uint32_t vdev_id,uint32_t chanfreq)1430*5113495bSYour Name void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
1431*5113495bSYour Name 			void *header, uint32_t vdev_id, uint32_t chanfreq)
1432*5113495bSYour Name {
1433*5113495bSYour Name 
1434*5113495bSYour Name 	uint32_t data[CUSTOM_MGMT_CMD_DATA_SIZE];
1435*5113495bSYour Name 
1436*5113495bSYour Name 	data[0] = ((struct wmi_command_header *)header)->type;
1437*5113495bSYour Name 	data[1] = ((struct wmi_command_header *)header)->sub_type;
1438*5113495bSYour Name 	data[2] = vdev_id;
1439*5113495bSYour Name 	data[3] = chanfreq;
1440*5113495bSYour Name 
1441*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
1442*5113495bSYour Name 
1443*5113495bSYour Name 	WMI_MGMT_COMMAND_RECORD(wmi_handle, cmd, (uint8_t *)data);
1444*5113495bSYour Name 	wmi_specific_cmd_record(wmi_handle, cmd, (uint8_t *)data);
1445*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
1446*5113495bSYour Name }
1447*5113495bSYour Name #else
wmi_debugfs_remove(wmi_unified_t wmi_handle)1448*5113495bSYour Name static void wmi_debugfs_remove(wmi_unified_t wmi_handle) { }
wmi_mgmt_cmd_record(wmi_unified_t wmi_handle,uint32_t cmd,void * header,uint32_t vdev_id,uint32_t chanfreq)1449*5113495bSYour Name void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
1450*5113495bSYour Name 			void *header, uint32_t vdev_id, uint32_t chanfreq) { }
wmi_log_buffer_free(struct wmi_unified * wmi_handle)1451*5113495bSYour Name static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle) { }
wmi_minidump_detach(struct wmi_unified * wmi_handle)1452*5113495bSYour Name static void wmi_minidump_detach(struct wmi_unified *wmi_handle) { }
wmi_minidump_attach(struct wmi_unified * wmi_handle)1453*5113495bSYour Name static void wmi_minidump_attach(struct wmi_unified *wmi_handle) { }
wmi_dump_last_cmd_rec_info(wmi_unified_t wmi_handle)1454*5113495bSYour Name static void wmi_dump_last_cmd_rec_info(wmi_unified_t wmi_handle) { }
1455*5113495bSYour Name #endif /*WMI_INTERFACE_EVENT_LOGGING */
1456*5113495bSYour Name qdf_export_symbol(wmi_mgmt_cmd_record);
1457*5113495bSYour Name 
1458*5113495bSYour Name #ifdef WMI_EXT_DBG
1459*5113495bSYour Name 
1460*5113495bSYour Name /**
1461*5113495bSYour Name  * wmi_ext_dbg_msg_enqueue() - enqueue wmi message
1462*5113495bSYour Name  * @wmi_handle: wmi handler
1463*5113495bSYour Name  * @msg: WMI message
1464*5113495bSYour Name  *
1465*5113495bSYour Name  * Return: size of wmi message queue after enqueue
1466*5113495bSYour Name  */
wmi_ext_dbg_msg_enqueue(struct wmi_unified * wmi_handle,struct wmi_ext_dbg_msg * msg)1467*5113495bSYour Name static uint32_t wmi_ext_dbg_msg_enqueue(struct wmi_unified *wmi_handle,
1468*5113495bSYour Name 					struct wmi_ext_dbg_msg *msg)
1469*5113495bSYour Name {
1470*5113495bSYour Name 	uint32_t list_size;
1471*5113495bSYour Name 
1472*5113495bSYour Name 	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1473*5113495bSYour Name 	qdf_list_insert_back_size(&wmi_handle->wmi_ext_dbg_msg_queue,
1474*5113495bSYour Name 				  &msg->node, &list_size);
1475*5113495bSYour Name 	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1476*5113495bSYour Name 
1477*5113495bSYour Name 	return list_size;
1478*5113495bSYour Name }
1479*5113495bSYour Name 
1480*5113495bSYour Name /**
1481*5113495bSYour Name  * wmi_ext_dbg_msg_dequeue() - dequeue wmi message
1482*5113495bSYour Name  * @wmi_handle: wmi handler
1483*5113495bSYour Name  *
1484*5113495bSYour Name  * Return: wmi msg on success else NULL
1485*5113495bSYour Name  */
wmi_ext_dbg_msg_dequeue(struct wmi_unified * wmi_handle)1486*5113495bSYour Name static struct wmi_ext_dbg_msg *wmi_ext_dbg_msg_dequeue(struct wmi_unified
1487*5113495bSYour Name 						       *wmi_handle)
1488*5113495bSYour Name {
1489*5113495bSYour Name 	qdf_list_node_t *list_node = NULL;
1490*5113495bSYour Name 
1491*5113495bSYour Name 	qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1492*5113495bSYour Name 	qdf_list_remove_front(&wmi_handle->wmi_ext_dbg_msg_queue, &list_node);
1493*5113495bSYour Name 	qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1494*5113495bSYour Name 
1495*5113495bSYour Name 	if (!list_node)
1496*5113495bSYour Name 		return NULL;
1497*5113495bSYour Name 
1498*5113495bSYour Name 	return qdf_container_of(list_node, struct wmi_ext_dbg_msg, node);
1499*5113495bSYour Name }
1500*5113495bSYour Name 
1501*5113495bSYour Name /**
1502*5113495bSYour Name  * wmi_ext_dbg_msg_record() - record wmi messages
1503*5113495bSYour Name  * @wmi_handle: wmi handler
1504*5113495bSYour Name  * @buf: wmi message buffer
1505*5113495bSYour Name  * @len: wmi message length
1506*5113495bSYour Name  * @type: wmi message type
1507*5113495bSYour Name  *
1508*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on successful recording else failure.
1509*5113495bSYour Name  */
wmi_ext_dbg_msg_record(struct wmi_unified * wmi_handle,uint8_t * buf,uint32_t len,enum WMI_MSG_TYPE type)1510*5113495bSYour Name static QDF_STATUS wmi_ext_dbg_msg_record(struct wmi_unified *wmi_handle,
1511*5113495bSYour Name 					 uint8_t *buf, uint32_t len,
1512*5113495bSYour Name 					 enum WMI_MSG_TYPE type)
1513*5113495bSYour Name {
1514*5113495bSYour Name 	struct wmi_ext_dbg_msg *msg;
1515*5113495bSYour Name 	uint32_t list_size;
1516*5113495bSYour Name 
1517*5113495bSYour Name 	msg = wmi_ext_dbg_msg_get(len);
1518*5113495bSYour Name 	if (!msg)
1519*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
1520*5113495bSYour Name 
1521*5113495bSYour Name 	msg->len = len;
1522*5113495bSYour Name 	msg->type = type;
1523*5113495bSYour Name 	qdf_mem_copy(msg->buf, buf, len);
1524*5113495bSYour Name 	msg->ts = qdf_get_log_timestamp();
1525*5113495bSYour Name 	list_size = wmi_ext_dbg_msg_enqueue(wmi_handle, msg);
1526*5113495bSYour Name 
1527*5113495bSYour Name 	if (list_size >= wmi_handle->wmi_ext_dbg_msg_queue_size) {
1528*5113495bSYour Name 		msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
1529*5113495bSYour Name 		wmi_ext_dbg_msg_put(msg);
1530*5113495bSYour Name 	}
1531*5113495bSYour Name 
1532*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1533*5113495bSYour Name }
1534*5113495bSYour Name 
1535*5113495bSYour Name /**
1536*5113495bSYour Name  * wmi_ext_dbg_msg_cmd_record() - record wmi command messages
1537*5113495bSYour Name  * @wmi_handle: wmi handler
1538*5113495bSYour Name  * @buf: wmi command buffer
1539*5113495bSYour Name  * @len: wmi command message length
1540*5113495bSYour Name  *
1541*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on successful recording else failure.
1542*5113495bSYour Name  */
wmi_ext_dbg_msg_cmd_record(struct wmi_unified * wmi_handle,uint8_t * buf,uint32_t len)1543*5113495bSYour Name static QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified *wmi_handle,
1544*5113495bSYour Name 					     uint8_t *buf, uint32_t len)
1545*5113495bSYour Name {
1546*5113495bSYour Name 	return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
1547*5113495bSYour Name 				      WMI_MSG_TYPE_CMD);
1548*5113495bSYour Name }
1549*5113495bSYour Name 
1550*5113495bSYour Name /**
1551*5113495bSYour Name  * wmi_ext_dbg_msg_event_record() - record wmi event messages
1552*5113495bSYour Name  * @wmi_handle: wmi handler
1553*5113495bSYour Name  * @buf: wmi event buffer
1554*5113495bSYour Name  * @len: wmi event message length
1555*5113495bSYour Name  *
1556*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on successful recording else failure.
1557*5113495bSYour Name  */
wmi_ext_dbg_msg_event_record(struct wmi_unified * wmi_handle,uint8_t * buf,uint32_t len)1558*5113495bSYour Name static QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified *wmi_handle,
1559*5113495bSYour Name 					       uint8_t *buf, uint32_t len)
1560*5113495bSYour Name {
1561*5113495bSYour Name 	uint32_t id;
1562*5113495bSYour Name 
1563*5113495bSYour Name 	id = WMI_GET_FIELD(buf, WMI_CMD_HDR, COMMANDID);
1564*5113495bSYour Name 	if (id != wmi_handle->wmi_events[wmi_diag_event_id])
1565*5113495bSYour Name 		return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
1566*5113495bSYour Name 					      WMI_MSG_TYPE_EVENT);
1567*5113495bSYour Name 
1568*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1569*5113495bSYour Name }
1570*5113495bSYour Name 
1571*5113495bSYour Name /**
1572*5113495bSYour Name  * wmi_ext_dbg_msg_queue_init() - create debugfs queue and associated lock
1573*5113495bSYour Name  * @wmi_handle: wmi handler
1574*5113495bSYour Name  *
1575*5113495bSYour Name  * Return: none
1576*5113495bSYour Name  */
wmi_ext_dbg_msg_queue_init(struct wmi_unified * wmi_handle)1577*5113495bSYour Name static void wmi_ext_dbg_msg_queue_init(struct wmi_unified *wmi_handle)
1578*5113495bSYour Name {
1579*5113495bSYour Name 	qdf_list_create(&wmi_handle->wmi_ext_dbg_msg_queue,
1580*5113495bSYour Name 			wmi_handle->wmi_ext_dbg_msg_queue_size);
1581*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1582*5113495bSYour Name }
1583*5113495bSYour Name 
1584*5113495bSYour Name /**
1585*5113495bSYour Name  * wmi_ext_dbg_msg_queue_deinit() - destroy debugfs queue and associated lock
1586*5113495bSYour Name  * @wmi_handle: wmi handler
1587*5113495bSYour Name  *
1588*5113495bSYour Name  * Return: none
1589*5113495bSYour Name  */
wmi_ext_dbg_msg_queue_deinit(struct wmi_unified * wmi_handle)1590*5113495bSYour Name static void wmi_ext_dbg_msg_queue_deinit(struct wmi_unified *wmi_handle)
1591*5113495bSYour Name {
1592*5113495bSYour Name 	qdf_list_destroy(&wmi_handle->wmi_ext_dbg_msg_queue);
1593*5113495bSYour Name 	qdf_spinlock_destroy(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1594*5113495bSYour Name }
1595*5113495bSYour Name 
1596*5113495bSYour Name /**
1597*5113495bSYour Name  * wmi_ext_dbg_msg_show() - debugfs function to display whole content of
1598*5113495bSYour Name  * wmi command/event messages including headers.
1599*5113495bSYour Name  * @file: qdf debugfs file handler
1600*5113495bSYour Name  * @arg: pointer to wmi handler
1601*5113495bSYour Name  *
1602*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if all the messages are shown successfully,
1603*5113495bSYour Name  * else QDF_STATUS_E_AGAIN if more data to show.
1604*5113495bSYour Name  */
wmi_ext_dbg_msg_show(qdf_debugfs_file_t file,void * arg)1605*5113495bSYour Name static QDF_STATUS wmi_ext_dbg_msg_show(qdf_debugfs_file_t file, void *arg)
1606*5113495bSYour Name {
1607*5113495bSYour Name 	struct wmi_unified *wmi_handle = (struct wmi_unified *)arg;
1608*5113495bSYour Name 	struct wmi_ext_dbg_msg *msg;
1609*5113495bSYour Name 	uint64_t secs, usecs;
1610*5113495bSYour Name 
1611*5113495bSYour Name 	msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
1612*5113495bSYour Name 	if (!msg)
1613*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1614*5113495bSYour Name 
1615*5113495bSYour Name 	qdf_debugfs_printf(file, "%s: 0x%x\n",
1616*5113495bSYour Name 			   msg->type == WMI_MSG_TYPE_CMD ? "COMMAND" :
1617*5113495bSYour Name 			   "EVENT", WMI_GET_FIELD(msg->buf, WMI_CMD_HDR,
1618*5113495bSYour Name 						  COMMANDID));
1619*5113495bSYour Name 	qdf_log_timestamp_to_secs(msg->ts, &secs, &usecs);
1620*5113495bSYour Name 	qdf_debugfs_printf(file, "Time: %llu.%llu\n", secs, usecs);
1621*5113495bSYour Name 	qdf_debugfs_printf(file, "Length:%d\n", msg->len);
1622*5113495bSYour Name 	qdf_debugfs_hexdump(file, msg->buf, msg->len,
1623*5113495bSYour Name 			    WMI_EXT_DBG_DUMP_ROW_SIZE,
1624*5113495bSYour Name 			    WMI_EXT_DBG_DUMP_GROUP_SIZE);
1625*5113495bSYour Name 	qdf_debugfs_printf(file, "\n");
1626*5113495bSYour Name 
1627*5113495bSYour Name 	if (qdf_debugfs_overflow(file)) {
1628*5113495bSYour Name 		qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1629*5113495bSYour Name 		qdf_list_insert_front(&wmi_handle->wmi_ext_dbg_msg_queue,
1630*5113495bSYour Name 				      &msg->node);
1631*5113495bSYour Name 		qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
1632*5113495bSYour Name 
1633*5113495bSYour Name 	} else {
1634*5113495bSYour Name 		wmi_ext_dbg_msg_put(msg);
1635*5113495bSYour Name 	}
1636*5113495bSYour Name 
1637*5113495bSYour Name 	return QDF_STATUS_E_AGAIN;
1638*5113495bSYour Name }
1639*5113495bSYour Name 
1640*5113495bSYour Name /**
1641*5113495bSYour Name  * wmi_ext_dbg_msg_write() - debugfs write not supported
1642*5113495bSYour Name  * @priv: private data
1643*5113495bSYour Name  * @buf: received data buffer
1644*5113495bSYour Name  * @len: length of received buffer
1645*5113495bSYour Name  *
1646*5113495bSYour Name  * Return: QDF_STATUS_E_NOSUPPORT.
1647*5113495bSYour Name  */
wmi_ext_dbg_msg_write(void * priv,const char * buf,qdf_size_t len)1648*5113495bSYour Name static QDF_STATUS wmi_ext_dbg_msg_write(void *priv, const char *buf,
1649*5113495bSYour Name 					qdf_size_t len)
1650*5113495bSYour Name {
1651*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
1652*5113495bSYour Name }
1653*5113495bSYour Name 
1654*5113495bSYour Name static struct qdf_debugfs_fops wmi_ext_dbgfs_ops[WMI_MAX_RADIOS];
1655*5113495bSYour Name 
1656*5113495bSYour Name /**
1657*5113495bSYour Name  * wmi_ext_dbgfs_init() - init debugfs items for extended wmi dump.
1658*5113495bSYour Name  * @wmi_handle: wmi handler
1659*5113495bSYour Name  * @pdev_idx: pdev index
1660*5113495bSYour Name  *
1661*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if debugfs is initialized else
1662*5113495bSYour Name  * QDF_STATUS_E_FAILURE
1663*5113495bSYour Name  */
wmi_ext_dbgfs_init(struct wmi_unified * wmi_handle,uint32_t pdev_idx)1664*5113495bSYour Name static QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle,
1665*5113495bSYour Name 				     uint32_t pdev_idx)
1666*5113495bSYour Name {
1667*5113495bSYour Name 	qdf_dentry_t dentry;
1668*5113495bSYour Name 	char buf[32];
1669*5113495bSYour Name 
1670*5113495bSYour Name 	/* To maintain backward compatibility, naming convention for PDEV 0
1671*5113495bSYour Name 	 * dentry is kept same as before. For more than 1 PDEV, dentry
1672*5113495bSYour Name 	 * names will be appended with PDEVx.
1673*5113495bSYour Name 	*/
1674*5113495bSYour Name 	if (wmi_handle->soc->soc_idx == 0 && pdev_idx == 0) {
1675*5113495bSYour Name 		dentry  = qdf_debugfs_create_dir(WMI_EXT_DBG_DIR, NULL);
1676*5113495bSYour Name 	} else {
1677*5113495bSYour Name 		snprintf(buf, sizeof(buf), "WMI_EXT_DBG_SOC%u_PDEV%u",
1678*5113495bSYour Name 			 wmi_handle->soc->soc_idx, pdev_idx);
1679*5113495bSYour Name 		dentry  = qdf_debugfs_create_dir(buf, NULL);
1680*5113495bSYour Name 	}
1681*5113495bSYour Name 
1682*5113495bSYour Name 	if (!dentry) {
1683*5113495bSYour Name 		wmi_err("error while creating extended wmi debugfs dir");
1684*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1685*5113495bSYour Name 	}
1686*5113495bSYour Name 
1687*5113495bSYour Name 	wmi_ext_dbgfs_ops[pdev_idx].show = wmi_ext_dbg_msg_show;
1688*5113495bSYour Name 	wmi_ext_dbgfs_ops[pdev_idx].write = wmi_ext_dbg_msg_write;
1689*5113495bSYour Name 	wmi_ext_dbgfs_ops[pdev_idx].priv = wmi_handle;
1690*5113495bSYour Name 	if (!qdf_debugfs_create_file(WMI_EXT_DBG_FILE, WMI_EXT_DBG_FILE_PERM,
1691*5113495bSYour Name 				     dentry, &wmi_ext_dbgfs_ops[pdev_idx])) {
1692*5113495bSYour Name 		qdf_debugfs_remove_dir(dentry);
1693*5113495bSYour Name 		wmi_err("Error while creating extended wmi debugfs file");
1694*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
1695*5113495bSYour Name 	}
1696*5113495bSYour Name 
1697*5113495bSYour Name 	wmi_handle->wmi_ext_dbg_dentry = dentry;
1698*5113495bSYour Name 	wmi_handle->wmi_ext_dbg_msg_queue_size = WMI_EXT_DBG_QUEUE_SIZE;
1699*5113495bSYour Name 	wmi_ext_dbg_msg_queue_init(wmi_handle);
1700*5113495bSYour Name 
1701*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1702*5113495bSYour Name }
1703*5113495bSYour Name 
1704*5113495bSYour Name /**
1705*5113495bSYour Name  * wmi_ext_dbgfs_deinit() - cleanup/deinit debugfs items of extended wmi dump.
1706*5113495bSYour Name  * @wmi_handle: wmi handler
1707*5113495bSYour Name  *
1708*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS if cleanup is successful
1709*5113495bSYour Name  */
wmi_ext_dbgfs_deinit(struct wmi_unified * wmi_handle)1710*5113495bSYour Name static QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
1711*5113495bSYour Name {
1712*5113495bSYour Name 	struct wmi_ext_dbg_msg *msg;
1713*5113495bSYour Name 
1714*5113495bSYour Name 	while ((msg = wmi_ext_dbg_msg_dequeue(wmi_handle)))
1715*5113495bSYour Name 		wmi_ext_dbg_msg_put(msg);
1716*5113495bSYour Name 
1717*5113495bSYour Name 	wmi_ext_dbg_msg_queue_deinit(wmi_handle);
1718*5113495bSYour Name 	qdf_debugfs_remove_dir_recursive(wmi_handle->wmi_ext_dbg_dentry);
1719*5113495bSYour Name 
1720*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1721*5113495bSYour Name }
1722*5113495bSYour Name 
1723*5113495bSYour Name #else
1724*5113495bSYour Name 
wmi_ext_dbg_msg_cmd_record(struct wmi_unified * wmi_handle,uint8_t * buf,uint32_t len)1725*5113495bSYour Name static inline QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified
1726*5113495bSYour Name 						    *wmi_handle,
1727*5113495bSYour Name 						    uint8_t *buf, uint32_t len)
1728*5113495bSYour Name {
1729*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1730*5113495bSYour Name }
1731*5113495bSYour Name 
wmi_ext_dbg_msg_event_record(struct wmi_unified * wmi_handle,uint8_t * buf,uint32_t len)1732*5113495bSYour Name static inline QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified
1733*5113495bSYour Name 						      *wmi_handle,
1734*5113495bSYour Name 						      uint8_t *buf, uint32_t len)
1735*5113495bSYour Name {
1736*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1737*5113495bSYour Name }
1738*5113495bSYour Name 
wmi_ext_dbgfs_init(struct wmi_unified * wmi_handle,uint32_t pdev_idx)1739*5113495bSYour Name static inline QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle,
1740*5113495bSYour Name 					    uint32_t pdev_idx)
1741*5113495bSYour Name {
1742*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1743*5113495bSYour Name }
1744*5113495bSYour Name 
wmi_ext_dbgfs_deinit(struct wmi_unified * wmi_handle)1745*5113495bSYour Name static inline QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
1746*5113495bSYour Name {
1747*5113495bSYour Name 		return QDF_STATUS_SUCCESS;
1748*5113495bSYour Name }
1749*5113495bSYour Name 
1750*5113495bSYour Name #endif /*WMI_EXT_DBG */
1751*5113495bSYour Name 
1752*5113495bSYour Name int wmi_get_host_credits(wmi_unified_t wmi_handle);
1753*5113495bSYour Name /* WMI buffer APIs */
1754*5113495bSYour Name 
1755*5113495bSYour Name #ifdef NBUF_MEMORY_DEBUG
1756*5113495bSYour Name wmi_buf_t
wmi_buf_alloc_debug(wmi_unified_t wmi_handle,uint32_t len,const char * func_name,uint32_t line_num)1757*5113495bSYour Name wmi_buf_alloc_debug(wmi_unified_t wmi_handle, uint32_t len,
1758*5113495bSYour Name 		    const char *func_name,
1759*5113495bSYour Name 		    uint32_t line_num)
1760*5113495bSYour Name {
1761*5113495bSYour Name 	wmi_buf_t wmi_buf;
1762*5113495bSYour Name 
1763*5113495bSYour Name 	if (roundup(len, 4) > wmi_handle->max_msg_len) {
1764*5113495bSYour Name 		wmi_err("Invalid length %u (via %s:%u) max size: %u",
1765*5113495bSYour Name 			len, func_name, line_num,
1766*5113495bSYour Name 			wmi_handle->max_msg_len);
1767*5113495bSYour Name 		QDF_ASSERT(0);
1768*5113495bSYour Name 		return NULL;
1769*5113495bSYour Name 	}
1770*5113495bSYour Name 
1771*5113495bSYour Name 	wmi_buf = wbuff_buff_get(wmi_handle->wbuff_handle, WBUFF_MAX_POOL_ID,
1772*5113495bSYour Name 				 len, func_name, line_num);
1773*5113495bSYour Name 	if (!wmi_buf)
1774*5113495bSYour Name 		wmi_buf = qdf_nbuf_alloc_debug(NULL,
1775*5113495bSYour Name 					       roundup(len + WMI_MIN_HEAD_ROOM,
1776*5113495bSYour Name 						       4),
1777*5113495bSYour Name 					       WMI_MIN_HEAD_ROOM, 4, false,
1778*5113495bSYour Name 					       func_name, line_num);
1779*5113495bSYour Name 	if (!wmi_buf)
1780*5113495bSYour Name 		return NULL;
1781*5113495bSYour Name 
1782*5113495bSYour Name 	/* Clear the wmi buffer */
1783*5113495bSYour Name 	OS_MEMZERO(qdf_nbuf_data(wmi_buf), len);
1784*5113495bSYour Name 
1785*5113495bSYour Name 	/*
1786*5113495bSYour Name 	 * Set the length of the buffer to match the allocation size.
1787*5113495bSYour Name 	 */
1788*5113495bSYour Name 	qdf_nbuf_set_pktlen(wmi_buf, len);
1789*5113495bSYour Name 
1790*5113495bSYour Name 	return wmi_buf;
1791*5113495bSYour Name }
1792*5113495bSYour Name qdf_export_symbol(wmi_buf_alloc_debug);
1793*5113495bSYour Name 
wmi_buf_free(wmi_buf_t net_buf)1794*5113495bSYour Name void wmi_buf_free(wmi_buf_t net_buf)
1795*5113495bSYour Name {
1796*5113495bSYour Name 	net_buf = wbuff_buff_put(net_buf);
1797*5113495bSYour Name 	if (net_buf)
1798*5113495bSYour Name 		qdf_nbuf_free(net_buf);
1799*5113495bSYour Name }
1800*5113495bSYour Name qdf_export_symbol(wmi_buf_free);
1801*5113495bSYour Name #else
wmi_buf_alloc_fl(wmi_unified_t wmi_handle,uint32_t len,const char * func,uint32_t line)1802*5113495bSYour Name wmi_buf_t wmi_buf_alloc_fl(wmi_unified_t wmi_handle, uint32_t len,
1803*5113495bSYour Name 			   const char *func, uint32_t line)
1804*5113495bSYour Name {
1805*5113495bSYour Name 	wmi_buf_t wmi_buf;
1806*5113495bSYour Name 
1807*5113495bSYour Name 	if (roundup(len, 4) > wmi_handle->max_msg_len) {
1808*5113495bSYour Name 		QDF_DEBUG_PANIC("Invalid length %u (via %s:%u) max size: %u",
1809*5113495bSYour Name 				len, func, line, wmi_handle->max_msg_len);
1810*5113495bSYour Name 		return NULL;
1811*5113495bSYour Name 	}
1812*5113495bSYour Name 
1813*5113495bSYour Name 	wmi_buf = wbuff_buff_get(wmi_handle->wbuff_handle, WBUFF_MAX_POOL_ID,
1814*5113495bSYour Name 				 len, __func__, __LINE__);
1815*5113495bSYour Name 	if (!wmi_buf)
1816*5113495bSYour Name 		wmi_buf = qdf_nbuf_alloc_fl(NULL, roundup(len +
1817*5113495bSYour Name 				WMI_MIN_HEAD_ROOM, 4), WMI_MIN_HEAD_ROOM, 4,
1818*5113495bSYour Name 				false, func, line);
1819*5113495bSYour Name 
1820*5113495bSYour Name 	if (!wmi_buf) {
1821*5113495bSYour Name 		wmi_nofl_err("%s:%d, failed to alloc len:%d", func, line, len);
1822*5113495bSYour Name 		return NULL;
1823*5113495bSYour Name 	}
1824*5113495bSYour Name 
1825*5113495bSYour Name 	/* Clear the wmi buffer */
1826*5113495bSYour Name 	OS_MEMZERO(qdf_nbuf_data(wmi_buf), len);
1827*5113495bSYour Name 
1828*5113495bSYour Name 	/*
1829*5113495bSYour Name 	 * Set the length of the buffer to match the allocation size.
1830*5113495bSYour Name 	 */
1831*5113495bSYour Name 	qdf_nbuf_set_pktlen(wmi_buf, len);
1832*5113495bSYour Name 
1833*5113495bSYour Name 	return wmi_buf;
1834*5113495bSYour Name }
1835*5113495bSYour Name qdf_export_symbol(wmi_buf_alloc_fl);
1836*5113495bSYour Name 
wmi_buf_free(wmi_buf_t net_buf)1837*5113495bSYour Name void wmi_buf_free(wmi_buf_t net_buf)
1838*5113495bSYour Name {
1839*5113495bSYour Name 	net_buf = wbuff_buff_put(net_buf);
1840*5113495bSYour Name 	if (net_buf)
1841*5113495bSYour Name 		qdf_nbuf_free(net_buf);
1842*5113495bSYour Name }
1843*5113495bSYour Name qdf_export_symbol(wmi_buf_free);
1844*5113495bSYour Name #endif
1845*5113495bSYour Name 
wmi_get_max_msg_len(wmi_unified_t wmi_handle)1846*5113495bSYour Name uint16_t wmi_get_max_msg_len(wmi_unified_t wmi_handle)
1847*5113495bSYour Name {
1848*5113495bSYour Name 	return wmi_handle->max_msg_len - WMI_MIN_HEAD_ROOM;
1849*5113495bSYour Name }
1850*5113495bSYour Name qdf_export_symbol(wmi_get_max_msg_len);
1851*5113495bSYour Name 
1852*5113495bSYour Name #ifndef WMI_CMD_STRINGS
wmi_id_to_name(uint32_t wmi_command)1853*5113495bSYour Name static uint8_t *wmi_id_to_name(uint32_t wmi_command)
1854*5113495bSYour Name {
1855*5113495bSYour Name 	return "Invalid WMI cmd";
1856*5113495bSYour Name }
1857*5113495bSYour Name #endif
1858*5113495bSYour Name 
wmi_log_cmd_id(uint32_t cmd_id,uint32_t tag)1859*5113495bSYour Name static inline void wmi_log_cmd_id(uint32_t cmd_id, uint32_t tag)
1860*5113495bSYour Name {
1861*5113495bSYour Name 	wmi_nofl_debug("Send cmd %s(0x%x) tag:%d",
1862*5113495bSYour Name 		       wmi_id_to_name(cmd_id), cmd_id, tag);
1863*5113495bSYour Name }
1864*5113495bSYour Name 
1865*5113495bSYour Name /**
1866*5113495bSYour Name  * wmi_is_pm_resume_cmd() - check if a cmd is part of the resume sequence
1867*5113495bSYour Name  * @cmd_id: command to check
1868*5113495bSYour Name  *
1869*5113495bSYour Name  * Return: true if the command is part of the resume sequence.
1870*5113495bSYour Name  */
1871*5113495bSYour Name #ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
wmi_is_pm_resume_cmd(uint32_t cmd_id)1872*5113495bSYour Name static bool wmi_is_pm_resume_cmd(uint32_t cmd_id)
1873*5113495bSYour Name {
1874*5113495bSYour Name 	switch (cmd_id) {
1875*5113495bSYour Name 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
1876*5113495bSYour Name 	case WMI_PDEV_RESUME_CMDID:
1877*5113495bSYour Name 		return true;
1878*5113495bSYour Name 
1879*5113495bSYour Name 	default:
1880*5113495bSYour Name 		return false;
1881*5113495bSYour Name 	}
1882*5113495bSYour Name }
1883*5113495bSYour Name 
1884*5113495bSYour Name #else
wmi_is_pm_resume_cmd(uint32_t cmd_id)1885*5113495bSYour Name static bool wmi_is_pm_resume_cmd(uint32_t cmd_id)
1886*5113495bSYour Name {
1887*5113495bSYour Name 	return false;
1888*5113495bSYour Name }
1889*5113495bSYour Name 
1890*5113495bSYour Name #endif
1891*5113495bSYour Name 
1892*5113495bSYour Name #ifdef FEATURE_WLAN_D0WOW
wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf,uint32_t cmd_id)1893*5113495bSYour Name static bool wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf, uint32_t cmd_id)
1894*5113495bSYour Name {
1895*5113495bSYour Name 	wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1896*5113495bSYour Name 
1897*5113495bSYour Name 	if (cmd_id == WMI_D0_WOW_ENABLE_DISABLE_CMDID) {
1898*5113495bSYour Name 		cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *)
1899*5113495bSYour Name 			wmi_buf_data(buf);
1900*5113495bSYour Name 		if (!cmd->enable)
1901*5113495bSYour Name 			return true;
1902*5113495bSYour Name 		else
1903*5113495bSYour Name 			return false;
1904*5113495bSYour Name 	}
1905*5113495bSYour Name 
1906*5113495bSYour Name 	return false;
1907*5113495bSYour Name }
1908*5113495bSYour Name #else
wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf,uint32_t cmd_id)1909*5113495bSYour Name static bool wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf, uint32_t cmd_id)
1910*5113495bSYour Name {
1911*5113495bSYour Name 	return false;
1912*5113495bSYour Name }
1913*5113495bSYour Name 
1914*5113495bSYour Name #endif
1915*5113495bSYour Name 
1916*5113495bSYour Name #ifdef WMI_INTERFACE_SEQUENCE_CHECK
wmi_interface_sequence_reset(struct wmi_unified * wmi_handle)1917*5113495bSYour Name static inline void wmi_interface_sequence_reset(struct wmi_unified *wmi_handle)
1918*5113495bSYour Name {
1919*5113495bSYour Name 	wmi_handle->wmi_sequence = 0;
1920*5113495bSYour Name 	wmi_handle->wmi_exp_sequence = 0;
1921*5113495bSYour Name 	wmi_handle->wmi_sequence_stop = false;
1922*5113495bSYour Name }
1923*5113495bSYour Name 
wmi_interface_sequence_init(struct wmi_unified * wmi_handle)1924*5113495bSYour Name static inline void wmi_interface_sequence_init(struct wmi_unified *wmi_handle)
1925*5113495bSYour Name {
1926*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->wmi_seq_lock);
1927*5113495bSYour Name 	wmi_interface_sequence_reset(wmi_handle);
1928*5113495bSYour Name }
1929*5113495bSYour Name 
wmi_interface_sequence_deinit(struct wmi_unified * wmi_handle)1930*5113495bSYour Name static inline void wmi_interface_sequence_deinit(struct wmi_unified *wmi_handle)
1931*5113495bSYour Name {
1932*5113495bSYour Name 	qdf_spinlock_destroy(&wmi_handle->wmi_seq_lock);
1933*5113495bSYour Name }
1934*5113495bSYour Name 
wmi_interface_sequence_stop(struct wmi_unified * wmi_handle)1935*5113495bSYour Name void wmi_interface_sequence_stop(struct wmi_unified *wmi_handle)
1936*5113495bSYour Name {
1937*5113495bSYour Name 	wmi_handle->wmi_sequence_stop = true;
1938*5113495bSYour Name }
1939*5113495bSYour Name 
wmi_htc_send_pkt(struct wmi_unified * wmi_handle,HTC_PACKET * pkt,const char * func,uint32_t line)1940*5113495bSYour Name static inline QDF_STATUS wmi_htc_send_pkt(struct wmi_unified *wmi_handle,
1941*5113495bSYour Name 					  HTC_PACKET *pkt,
1942*5113495bSYour Name 					  const char *func, uint32_t line)
1943*5113495bSYour Name {
1944*5113495bSYour Name 	wmi_buf_t buf = GET_HTC_PACKET_NET_BUF_CONTEXT(pkt);
1945*5113495bSYour Name 	QDF_STATUS status;
1946*5113495bSYour Name 
1947*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->wmi_seq_lock);
1948*5113495bSYour Name 	status = htc_send_pkt(wmi_handle->htc_handle, pkt);
1949*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
1950*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->wmi_seq_lock);
1951*5113495bSYour Name 		qdf_atomic_dec(&wmi_handle->pending_cmds);
1952*5113495bSYour Name 		wmi_nofl_err("%s:%d, htc_send_pkt failed, status:%d",
1953*5113495bSYour Name 			     func, line, status);
1954*5113495bSYour Name 		qdf_mem_free(pkt);
1955*5113495bSYour Name 		return status;
1956*5113495bSYour Name 	}
1957*5113495bSYour Name 	/* Record the sequence number in the SKB */
1958*5113495bSYour Name 	qdf_nbuf_set_mark(buf, wmi_handle->wmi_sequence);
1959*5113495bSYour Name 	/* Increment the sequence number */
1960*5113495bSYour Name 	wmi_handle->wmi_sequence = (wmi_handle->wmi_sequence + 1)
1961*5113495bSYour Name 				   & (wmi_handle->wmi_max_cmds - 1);
1962*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->wmi_seq_lock);
1963*5113495bSYour Name 
1964*5113495bSYour Name 	return status;
1965*5113495bSYour Name }
1966*5113495bSYour Name 
wmi_interface_sequence_check(struct wmi_unified * wmi_handle,wmi_buf_t buf)1967*5113495bSYour Name static inline void wmi_interface_sequence_check(struct wmi_unified *wmi_handle,
1968*5113495bSYour Name 						wmi_buf_t buf)
1969*5113495bSYour Name {
1970*5113495bSYour Name 	/* Skip sequence check when wmi sequence stop is set */
1971*5113495bSYour Name 	if (wmi_handle->wmi_sequence_stop)
1972*5113495bSYour Name 		return;
1973*5113495bSYour Name 
1974*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->wmi_seq_lock);
1975*5113495bSYour Name 	/* Match the completion sequence and expected sequence number */
1976*5113495bSYour Name 	if (qdf_nbuf_get_mark(buf) != wmi_handle->wmi_exp_sequence) {
1977*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->wmi_seq_lock);
1978*5113495bSYour Name 		wmi_nofl_err("WMI Tx Completion Sequence number mismatch");
1979*5113495bSYour Name 		wmi_nofl_err("Expected %d Received %d",
1980*5113495bSYour Name 			     wmi_handle->wmi_exp_sequence,
1981*5113495bSYour Name 			     qdf_nbuf_get_mark(buf));
1982*5113495bSYour Name 		/* Trigger Recovery */
1983*5113495bSYour Name 		qdf_trigger_self_recovery(wmi_handle->soc,
1984*5113495bSYour Name 					  QDF_WMI_BUF_SEQUENCE_MISMATCH);
1985*5113495bSYour Name 	} else {
1986*5113495bSYour Name 		/* Increment the expected sequence number */
1987*5113495bSYour Name 		wmi_handle->wmi_exp_sequence =
1988*5113495bSYour Name 				(wmi_handle->wmi_exp_sequence + 1)
1989*5113495bSYour Name 				& (wmi_handle->wmi_max_cmds - 1);
1990*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->wmi_seq_lock);
1991*5113495bSYour Name 	}
1992*5113495bSYour Name }
1993*5113495bSYour Name #else
wmi_interface_sequence_reset(struct wmi_unified * wmi_handle)1994*5113495bSYour Name static inline void wmi_interface_sequence_reset(struct wmi_unified *wmi_handle)
1995*5113495bSYour Name {
1996*5113495bSYour Name }
1997*5113495bSYour Name 
wmi_interface_sequence_init(struct wmi_unified * wmi_handle)1998*5113495bSYour Name static inline void wmi_interface_sequence_init(struct wmi_unified *wmi_handle)
1999*5113495bSYour Name {
2000*5113495bSYour Name }
2001*5113495bSYour Name 
wmi_interface_sequence_deinit(struct wmi_unified * wmi_handle)2002*5113495bSYour Name static inline void wmi_interface_sequence_deinit(struct wmi_unified *wmi_handle)
2003*5113495bSYour Name {
2004*5113495bSYour Name }
2005*5113495bSYour Name 
wmi_interface_sequence_stop(struct wmi_unified * wmi_handle)2006*5113495bSYour Name void wmi_interface_sequence_stop(struct wmi_unified *wmi_handle)
2007*5113495bSYour Name {
2008*5113495bSYour Name }
2009*5113495bSYour Name 
wmi_htc_send_pkt(struct wmi_unified * wmi_handle,HTC_PACKET * pkt,const char * func,uint32_t line)2010*5113495bSYour Name static inline QDF_STATUS wmi_htc_send_pkt(struct wmi_unified *wmi_handle,
2011*5113495bSYour Name 					  HTC_PACKET *pkt,
2012*5113495bSYour Name 					  const char *func, uint32_t line)
2013*5113495bSYour Name {
2014*5113495bSYour Name 	QDF_STATUS status;
2015*5113495bSYour Name 
2016*5113495bSYour Name 	status = htc_send_pkt(wmi_handle->htc_handle, pkt);
2017*5113495bSYour Name 	if (QDF_STATUS_SUCCESS != status) {
2018*5113495bSYour Name 		qdf_atomic_dec(&wmi_handle->pending_cmds);
2019*5113495bSYour Name 		wmi_nofl_err("%s:%d, htc_send_pkt failed, status:%d",
2020*5113495bSYour Name 			     func, line, status);
2021*5113495bSYour Name 		qdf_mem_free(pkt);
2022*5113495bSYour Name 		return status;
2023*5113495bSYour Name 	}
2024*5113495bSYour Name 
2025*5113495bSYour Name 	return status;
2026*5113495bSYour Name }
2027*5113495bSYour Name 
wmi_interface_sequence_check(struct wmi_unified * wmi_handle,wmi_buf_t buf)2028*5113495bSYour Name static inline void wmi_interface_sequence_check(struct wmi_unified *wmi_handle,
2029*5113495bSYour Name 						wmi_buf_t buf)
2030*5113495bSYour Name {
2031*5113495bSYour Name }
2032*5113495bSYour Name #endif
2033*5113495bSYour Name 
wmi_unified_debug_dump(wmi_unified_t wmi_handle)2034*5113495bSYour Name static inline void wmi_unified_debug_dump(wmi_unified_t wmi_handle)
2035*5113495bSYour Name {
2036*5113495bSYour Name 	wmi_nofl_err("Endpoint ID = %d, Tx Queue Depth = %d, soc_id = %u, target type = %s",
2037*5113495bSYour Name 		     wmi_handle->wmi_endpoint_id,
2038*5113495bSYour Name 		     htc_get_tx_queue_depth(wmi_handle->htc_handle,
2039*5113495bSYour Name 					    wmi_handle->wmi_endpoint_id),
2040*5113495bSYour Name 		     wmi_handle->soc->soc_idx,
2041*5113495bSYour Name 		     (wmi_handle->target_type ==
2042*5113495bSYour Name 		      WMI_TLV_TARGET ? "WMI_TLV_TARGET" :
2043*5113495bSYour Name 						"WMI_NON_TLV_TARGET"));
2044*5113495bSYour Name }
2045*5113495bSYour Name 
2046*5113495bSYour Name #ifdef SYSTEM_PM_CHECK
2047*5113495bSYour Name /**
2048*5113495bSYour Name  * wmi_set_system_pm_pkt_tag() - API to set tag for system pm packets
2049*5113495bSYour Name  * @htc_tag: HTC tag
2050*5113495bSYour Name  * @buf: wmi cmd buffer
2051*5113495bSYour Name  * @cmd_id: cmd id
2052*5113495bSYour Name  *
2053*5113495bSYour Name  * Return: None
2054*5113495bSYour Name  */
wmi_set_system_pm_pkt_tag(uint16_t * htc_tag,wmi_buf_t buf,uint32_t cmd_id)2055*5113495bSYour Name static void wmi_set_system_pm_pkt_tag(uint16_t *htc_tag, wmi_buf_t buf,
2056*5113495bSYour Name 				      uint32_t cmd_id)
2057*5113495bSYour Name {
2058*5113495bSYour Name 	switch (cmd_id) {
2059*5113495bSYour Name 	case WMI_WOW_ENABLE_CMDID:
2060*5113495bSYour Name 	case WMI_PDEV_SUSPEND_CMDID:
2061*5113495bSYour Name 		*htc_tag = HTC_TX_PACKET_SYSTEM_SUSPEND;
2062*5113495bSYour Name 		break;
2063*5113495bSYour Name 	case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
2064*5113495bSYour Name 	case WMI_PDEV_RESUME_CMDID:
2065*5113495bSYour Name 		*htc_tag = HTC_TX_PACKET_SYSTEM_RESUME;
2066*5113495bSYour Name 		break;
2067*5113495bSYour Name 	case WMI_D0_WOW_ENABLE_DISABLE_CMDID:
2068*5113495bSYour Name 		if (wmi_is_legacy_d0wow_disable_cmd(buf, cmd_id))
2069*5113495bSYour Name 			*htc_tag = HTC_TX_PACKET_SYSTEM_RESUME;
2070*5113495bSYour Name 		else
2071*5113495bSYour Name 			*htc_tag = HTC_TX_PACKET_SYSTEM_SUSPEND;
2072*5113495bSYour Name 		break;
2073*5113495bSYour Name 	default:
2074*5113495bSYour Name 		break;
2075*5113495bSYour Name 	}
2076*5113495bSYour Name }
2077*5113495bSYour Name #else
wmi_set_system_pm_pkt_tag(uint16_t * htc_tag,wmi_buf_t buf,uint32_t cmd_id)2078*5113495bSYour Name static inline void wmi_set_system_pm_pkt_tag(uint16_t *htc_tag, wmi_buf_t buf,
2079*5113495bSYour Name 					     uint32_t cmd_id)
2080*5113495bSYour Name {
2081*5113495bSYour Name }
2082*5113495bSYour Name #endif
2083*5113495bSYour Name 
2084*5113495bSYour Name #ifdef DP_UMAC_HW_RESET_SUPPORT
2085*5113495bSYour Name /**
2086*5113495bSYour Name  * wmi_unified_is_max_pending_commands_reached() - API to check if WMI max
2087*5113495bSYour Name  * pending commands are reached.
2088*5113495bSYour Name  * @wmi_handle: Pointer to WMI handle
2089*5113495bSYour Name  *
2090*5113495bSYour Name  * Return: If umac reset is in progress and max wmi pending commands are reached
2091*5113495bSYour Name  * then return false. The reason is FW will not reap the WMI commands from CE
2092*5113495bSYour Name  * ring when umac reset is in progress. Hence, all the pending WMI command to
2093*5113495bSYour Name  * host SW ring.
2094*5113495bSYour Name  */
2095*5113495bSYour Name static inline bool
wmi_unified_is_max_pending_commands_reached(wmi_unified_t wmi_handle)2096*5113495bSYour Name wmi_unified_is_max_pending_commands_reached(wmi_unified_t wmi_handle)
2097*5113495bSYour Name {
2098*5113495bSYour Name 	ol_txrx_soc_handle soc_txrx_handle;
2099*5113495bSYour Name 
2100*5113495bSYour Name 	soc_txrx_handle = (ol_txrx_soc_handle)wlan_psoc_get_dp_handle(
2101*5113495bSYour Name 			wmi_handle->soc->wmi_psoc);
2102*5113495bSYour Name 	if (!soc_txrx_handle) {
2103*5113495bSYour Name 		wmi_err("psoc handle is NULL");
2104*5113495bSYour Name 		return false;
2105*5113495bSYour Name 	}
2106*5113495bSYour Name 
2107*5113495bSYour Name 	return ((qdf_atomic_read(&wmi_handle->pending_cmds) >=
2108*5113495bSYour Name 			wmi_handle->wmi_max_cmds) &&
2109*5113495bSYour Name 		!cdp_umac_reset_is_inprogress(soc_txrx_handle));
2110*5113495bSYour Name }
2111*5113495bSYour Name #else
2112*5113495bSYour Name static inline bool
wmi_unified_is_max_pending_commands_reached(wmi_unified_t wmi_handle)2113*5113495bSYour Name wmi_unified_is_max_pending_commands_reached(wmi_unified_t wmi_handle)
2114*5113495bSYour Name {
2115*5113495bSYour Name 	return (qdf_atomic_read(&wmi_handle->pending_cmds) >=
2116*5113495bSYour Name 			wmi_handle->wmi_max_cmds);
2117*5113495bSYour Name }
2118*5113495bSYour Name #endif
2119*5113495bSYour Name 
wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle,wmi_buf_t buf,uint32_t len,uint32_t cmd_id,const char * func,uint32_t line)2120*5113495bSYour Name QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf,
2121*5113495bSYour Name 				   uint32_t len, uint32_t cmd_id,
2122*5113495bSYour Name 				   const char *func, uint32_t line)
2123*5113495bSYour Name {
2124*5113495bSYour Name 	HTC_PACKET *pkt;
2125*5113495bSYour Name 	uint16_t htc_tag = 0;
2126*5113495bSYour Name 	bool rtpm_inprogress;
2127*5113495bSYour Name 
2128*5113495bSYour Name 	rtpm_inprogress = wmi_get_runtime_pm_inprogress(wmi_handle);
2129*5113495bSYour Name 	if (rtpm_inprogress) {
2130*5113495bSYour Name 		htc_tag = wmi_handle->ops->wmi_set_htc_tx_tag(wmi_handle, buf,
2131*5113495bSYour Name 							      cmd_id);
2132*5113495bSYour Name 	} else if (qdf_atomic_read(&wmi_handle->is_target_suspended) &&
2133*5113495bSYour Name 		   !wmi_is_pm_resume_cmd(cmd_id) &&
2134*5113495bSYour Name 		   !wmi_is_legacy_d0wow_disable_cmd(buf, cmd_id)) {
2135*5113495bSYour Name 			wmi_nofl_err("Target is suspended (via %s:%u)",
2136*5113495bSYour Name 					func, line);
2137*5113495bSYour Name 		return QDF_STATUS_E_BUSY;
2138*5113495bSYour Name 	}
2139*5113495bSYour Name 
2140*5113495bSYour Name 	if (wmi_handle->wmi_stopinprogress) {
2141*5113495bSYour Name 		wmi_nofl_err("%s:%d, WMI stop in progress, wmi_handle:%pK",
2142*5113495bSYour Name 			     func, line, wmi_handle);
2143*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2144*5113495bSYour Name 	}
2145*5113495bSYour Name 
2146*5113495bSYour Name 	if (wmi_has_wow_enable_ack_failed(wmi_handle)) {
2147*5113495bSYour Name 		wmi_nofl_err("wow enable ack already failed(via %s:%u)",
2148*5113495bSYour Name 			     func, line);
2149*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2150*5113495bSYour Name 	}
2151*5113495bSYour Name 
2152*5113495bSYour Name #ifndef WMI_NON_TLV_SUPPORT
2153*5113495bSYour Name 	/* Do sanity check on the TLV parameter structure */
2154*5113495bSYour Name 	if (wmi_handle->target_type == WMI_TLV_TARGET) {
2155*5113495bSYour Name 		void *buf_ptr = (void *)qdf_nbuf_data(buf);
2156*5113495bSYour Name 
2157*5113495bSYour Name 		if (wmi_handle->ops->wmi_check_command_params(NULL, buf_ptr, len, cmd_id)
2158*5113495bSYour Name 			!= 0) {
2159*5113495bSYour Name 			wmi_nofl_err("%s:%d, Invalid WMI Param Buffer for Cmd:%d",
2160*5113495bSYour Name 				     func, line, cmd_id);
2161*5113495bSYour Name 			return QDF_STATUS_E_INVAL;
2162*5113495bSYour Name 		}
2163*5113495bSYour Name 	}
2164*5113495bSYour Name #endif
2165*5113495bSYour Name 
2166*5113495bSYour Name 	if (qdf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR)) == NULL) {
2167*5113495bSYour Name 		wmi_nofl_err("%s:%d, Failed to send cmd %x, no memory",
2168*5113495bSYour Name 			     func, line, cmd_id);
2169*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2170*5113495bSYour Name 	}
2171*5113495bSYour Name 
2172*5113495bSYour Name 	qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
2173*5113495bSYour Name 	WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
2174*5113495bSYour Name 
2175*5113495bSYour Name 	qdf_atomic_inc(&wmi_handle->pending_cmds);
2176*5113495bSYour Name 	if (wmi_unified_is_max_pending_commands_reached(wmi_handle)) {
2177*5113495bSYour Name 		wmi_dump_last_cmd_rec_info(wmi_handle);
2178*5113495bSYour Name 		wmi_nofl_err("hostcredits = %d",
2179*5113495bSYour Name 			     wmi_get_host_credits(wmi_handle));
2180*5113495bSYour Name 		htc_dump_counter_info(wmi_handle->htc_handle);
2181*5113495bSYour Name 		qdf_atomic_dec(&wmi_handle->pending_cmds);
2182*5113495bSYour Name 		wmi_nofl_err("%s:%d, MAX %d WMI Pending cmds reached",
2183*5113495bSYour Name 			     func, line, wmi_handle->wmi_max_cmds);
2184*5113495bSYour Name 		wmi_unified_debug_dump(wmi_handle);
2185*5113495bSYour Name 		htc_ce_tasklet_debug_dump(wmi_handle->htc_handle);
2186*5113495bSYour Name 		qdf_trigger_self_recovery(wmi_handle->soc->wmi_psoc,
2187*5113495bSYour Name 					  QDF_WMI_EXCEED_MAX_PENDING_CMDS);
2188*5113495bSYour Name 		return QDF_STATUS_E_BUSY;
2189*5113495bSYour Name 	}
2190*5113495bSYour Name 
2191*5113495bSYour Name 	pkt = qdf_mem_malloc_fl(sizeof(*pkt), func, line);
2192*5113495bSYour Name 	if (!pkt) {
2193*5113495bSYour Name 		qdf_atomic_dec(&wmi_handle->pending_cmds);
2194*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2195*5113495bSYour Name 	}
2196*5113495bSYour Name 
2197*5113495bSYour Name 	if (!rtpm_inprogress)
2198*5113495bSYour Name 		wmi_set_system_pm_pkt_tag(&htc_tag, buf, cmd_id);
2199*5113495bSYour Name 
2200*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(pkt,
2201*5113495bSYour Name 			       NULL,
2202*5113495bSYour Name 			       qdf_nbuf_data(buf), len + sizeof(WMI_CMD_HDR),
2203*5113495bSYour Name 			       wmi_handle->wmi_endpoint_id, htc_tag);
2204*5113495bSYour Name 
2205*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(pkt, buf);
2206*5113495bSYour Name 	wmi_log_cmd_id(cmd_id, htc_tag);
2207*5113495bSYour Name 	wmi_ext_dbg_msg_cmd_record(wmi_handle,
2208*5113495bSYour Name 				   qdf_nbuf_data(buf), qdf_nbuf_len(buf));
2209*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
2210*5113495bSYour Name 	if (wmi_handle->log_info.wmi_logging_enable) {
2211*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
2212*5113495bSYour Name 		/*
2213*5113495bSYour Name 		 * Record 16 bytes of WMI cmd data -
2214*5113495bSYour Name 		 * exclude TLV and WMI headers
2215*5113495bSYour Name 		 *
2216*5113495bSYour Name 		 * WMI mgmt command already recorded in wmi_mgmt_cmd_record
2217*5113495bSYour Name 		 */
2218*5113495bSYour Name 		if (wmi_handle->ops->is_management_record(cmd_id) == false) {
2219*5113495bSYour Name 			uint8_t *tmpbuf = (uint8_t *)qdf_nbuf_data(buf) +
2220*5113495bSYour Name 				wmi_handle->soc->buf_offset_command;
2221*5113495bSYour Name 
2222*5113495bSYour Name 			WMI_COMMAND_RECORD(wmi_handle, cmd_id, tmpbuf);
2223*5113495bSYour Name 			wmi_specific_cmd_record(wmi_handle, cmd_id, tmpbuf);
2224*5113495bSYour Name 		}
2225*5113495bSYour Name 
2226*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
2227*5113495bSYour Name 	}
2228*5113495bSYour Name #endif
2229*5113495bSYour Name 	return wmi_htc_send_pkt(wmi_handle, pkt, func, line);
2230*5113495bSYour Name }
2231*5113495bSYour Name qdf_export_symbol(wmi_unified_cmd_send_fl);
2232*5113495bSYour Name 
2233*5113495bSYour Name /**
2234*5113495bSYour Name  * wmi_unified_get_event_handler_ix() - gives event handler's index
2235*5113495bSYour Name  * @wmi_handle: handle to wmi
2236*5113495bSYour Name  * @event_id: wmi  event id
2237*5113495bSYour Name  *
2238*5113495bSYour Name  * Return: event handler's index
2239*5113495bSYour Name  */
wmi_unified_get_event_handler_ix(wmi_unified_t wmi_handle,uint32_t event_id)2240*5113495bSYour Name static int wmi_unified_get_event_handler_ix(wmi_unified_t wmi_handle,
2241*5113495bSYour Name 					    uint32_t event_id)
2242*5113495bSYour Name {
2243*5113495bSYour Name 	uint32_t idx = 0;
2244*5113495bSYour Name 	int32_t invalid_idx = -1;
2245*5113495bSYour Name 	struct wmi_soc *soc = wmi_handle->soc;
2246*5113495bSYour Name 
2247*5113495bSYour Name 	for (idx = 0; (idx < soc->max_event_idx &&
2248*5113495bSYour Name 		       idx < WMI_UNIFIED_MAX_EVENT); ++idx) {
2249*5113495bSYour Name 		if (wmi_handle->event_id[idx] == event_id &&
2250*5113495bSYour Name 		    wmi_handle->event_handler[idx]) {
2251*5113495bSYour Name 			return idx;
2252*5113495bSYour Name 		}
2253*5113495bSYour Name 	}
2254*5113495bSYour Name 
2255*5113495bSYour Name 	return invalid_idx;
2256*5113495bSYour Name }
2257*5113495bSYour Name 
2258*5113495bSYour Name /**
2259*5113495bSYour Name  * wmi_register_event_handler_with_ctx() - register event handler with
2260*5113495bSYour Name  * exec ctx and buffer type
2261*5113495bSYour Name  * @wmi_handle: handle to wmi
2262*5113495bSYour Name  * @event_id: wmi event id
2263*5113495bSYour Name  * @handler_func: wmi event handler function
2264*5113495bSYour Name  * @rx_ctx: rx execution context for wmi rx events
2265*5113495bSYour Name  * @rx_buf_type: rx execution context for wmi rx events
2266*5113495bSYour Name  *
2267*5113495bSYour Name  * Return: QDF_STATUS_SUCCESS on successful register event else failure.
2268*5113495bSYour Name  */
2269*5113495bSYour Name static QDF_STATUS
wmi_register_event_handler_with_ctx(wmi_unified_t wmi_handle,uint32_t event_id,wmi_unified_event_handler handler_func,enum wmi_rx_exec_ctx rx_ctx,enum wmi_rx_buff_type rx_buf_type)2270*5113495bSYour Name wmi_register_event_handler_with_ctx(wmi_unified_t wmi_handle,
2271*5113495bSYour Name 				    uint32_t event_id,
2272*5113495bSYour Name 				    wmi_unified_event_handler handler_func,
2273*5113495bSYour Name 				    enum wmi_rx_exec_ctx rx_ctx,
2274*5113495bSYour Name 				    enum wmi_rx_buff_type rx_buf_type)
2275*5113495bSYour Name {
2276*5113495bSYour Name 	uint32_t idx = 0;
2277*5113495bSYour Name 	uint32_t evt_id;
2278*5113495bSYour Name 	struct wmi_soc *soc;
2279*5113495bSYour Name 
2280*5113495bSYour Name 	if (!wmi_handle) {
2281*5113495bSYour Name 		wmi_err("WMI handle is NULL");
2282*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2283*5113495bSYour Name 	}
2284*5113495bSYour Name 
2285*5113495bSYour Name 	soc = wmi_handle->soc;
2286*5113495bSYour Name 
2287*5113495bSYour Name 	if (event_id >= wmi_events_max) {
2288*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
2289*5113495bSYour Name 			  "%s: Event id %d is unavailable",
2290*5113495bSYour Name 					__func__, event_id);
2291*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2292*5113495bSYour Name 	}
2293*5113495bSYour Name 
2294*5113495bSYour Name 	if (wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
2295*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
2296*5113495bSYour Name 			  "%s: Event id %d is not supported",
2297*5113495bSYour Name 			  __func__, event_id);
2298*5113495bSYour Name 		return QDF_STATUS_E_NOSUPPORT;
2299*5113495bSYour Name 	}
2300*5113495bSYour Name 	evt_id = wmi_handle->wmi_events[event_id];
2301*5113495bSYour Name 
2302*5113495bSYour Name 	if (wmi_unified_get_event_handler_ix(wmi_handle, evt_id) != -1) {
2303*5113495bSYour Name 		wmi_info("event handler already registered 0x%x", evt_id);
2304*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2305*5113495bSYour Name 	}
2306*5113495bSYour Name 	if (soc->max_event_idx == WMI_UNIFIED_MAX_EVENT) {
2307*5113495bSYour Name 		wmi_err("no more event handlers 0x%x",
2308*5113495bSYour Name 			 evt_id);
2309*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2310*5113495bSYour Name 	}
2311*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
2312*5113495bSYour Name 		  "Registered event handler for event 0x%8x", evt_id);
2313*5113495bSYour Name 	idx = soc->max_event_idx;
2314*5113495bSYour Name 	wmi_handle->event_handler[idx] = handler_func;
2315*5113495bSYour Name 	wmi_handle->event_id[idx] = evt_id;
2316*5113495bSYour Name 
2317*5113495bSYour Name 	qdf_spin_lock_bh(&soc->ctx_lock);
2318*5113495bSYour Name 	wmi_handle->ctx[idx].exec_ctx = rx_ctx;
2319*5113495bSYour Name 	wmi_handle->ctx[idx].buff_type = rx_buf_type;
2320*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->ctx_lock);
2321*5113495bSYour Name 	soc->max_event_idx++;
2322*5113495bSYour Name 
2323*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2324*5113495bSYour Name }
2325*5113495bSYour Name 
2326*5113495bSYour Name QDF_STATUS
wmi_unified_register_event(wmi_unified_t wmi_handle,uint32_t event_id,wmi_unified_event_handler handler_func)2327*5113495bSYour Name wmi_unified_register_event(wmi_unified_t wmi_handle,
2328*5113495bSYour Name 			   uint32_t event_id,
2329*5113495bSYour Name 			   wmi_unified_event_handler handler_func)
2330*5113495bSYour Name {
2331*5113495bSYour Name 	return wmi_register_event_handler_with_ctx(wmi_handle, event_id,
2332*5113495bSYour Name 						   handler_func,
2333*5113495bSYour Name 						   WMI_RX_UMAC_CTX,
2334*5113495bSYour Name 						   WMI_RX_PROCESSED_BUFF);
2335*5113495bSYour Name }
2336*5113495bSYour Name 
2337*5113495bSYour Name QDF_STATUS
wmi_unified_register_event_handler(wmi_unified_t wmi_handle,wmi_conv_event_id event_id,wmi_unified_event_handler handler_func,uint8_t rx_ctx)2338*5113495bSYour Name wmi_unified_register_event_handler(wmi_unified_t wmi_handle,
2339*5113495bSYour Name 				   wmi_conv_event_id event_id,
2340*5113495bSYour Name 				   wmi_unified_event_handler handler_func,
2341*5113495bSYour Name 				   uint8_t rx_ctx)
2342*5113495bSYour Name {
2343*5113495bSYour Name 	return wmi_register_event_handler_with_ctx(wmi_handle, event_id,
2344*5113495bSYour Name 						   handler_func, rx_ctx,
2345*5113495bSYour Name 						   WMI_RX_PROCESSED_BUFF);
2346*5113495bSYour Name }
2347*5113495bSYour Name 
2348*5113495bSYour Name qdf_export_symbol(wmi_unified_register_event_handler);
2349*5113495bSYour Name 
2350*5113495bSYour Name QDF_STATUS
wmi_unified_register_raw_event_handler(wmi_unified_t wmi_handle,wmi_conv_event_id event_id,wmi_unified_event_handler handler_func,enum wmi_rx_exec_ctx rx_ctx)2351*5113495bSYour Name wmi_unified_register_raw_event_handler(wmi_unified_t wmi_handle,
2352*5113495bSYour Name 				       wmi_conv_event_id event_id,
2353*5113495bSYour Name 				       wmi_unified_event_handler handler_func,
2354*5113495bSYour Name 				       enum wmi_rx_exec_ctx rx_ctx)
2355*5113495bSYour Name {
2356*5113495bSYour Name 	return wmi_register_event_handler_with_ctx(wmi_handle, event_id,
2357*5113495bSYour Name 						   handler_func, rx_ctx,
2358*5113495bSYour Name 						   WMI_RX_RAW_BUFF);
2359*5113495bSYour Name }
2360*5113495bSYour Name 
2361*5113495bSYour Name qdf_export_symbol(wmi_unified_register_raw_event_handler);
2362*5113495bSYour Name 
wmi_unified_unregister_event(wmi_unified_t wmi_handle,uint32_t event_id)2363*5113495bSYour Name QDF_STATUS wmi_unified_unregister_event(wmi_unified_t wmi_handle,
2364*5113495bSYour Name 					uint32_t event_id)
2365*5113495bSYour Name {
2366*5113495bSYour Name 	uint32_t idx = 0;
2367*5113495bSYour Name 	uint32_t evt_id;
2368*5113495bSYour Name 	struct wmi_soc *soc;
2369*5113495bSYour Name 
2370*5113495bSYour Name 	if (!wmi_handle) {
2371*5113495bSYour Name 		wmi_err("WMI handle is NULL");
2372*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2373*5113495bSYour Name 	}
2374*5113495bSYour Name 
2375*5113495bSYour Name 	soc = wmi_handle->soc;
2376*5113495bSYour Name 	if (event_id >= wmi_events_max ||
2377*5113495bSYour Name 		wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
2378*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
2379*5113495bSYour Name 			  "%s: Event id %d is unavailable",
2380*5113495bSYour Name 					__func__, event_id);
2381*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2382*5113495bSYour Name 	}
2383*5113495bSYour Name 	evt_id = wmi_handle->wmi_events[event_id];
2384*5113495bSYour Name 
2385*5113495bSYour Name 	idx = wmi_unified_get_event_handler_ix(wmi_handle, evt_id);
2386*5113495bSYour Name 	if (idx == -1) {
2387*5113495bSYour Name 		wmi_warn("event handler is not registered: evt id 0x%x",
2388*5113495bSYour Name 			 evt_id);
2389*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2390*5113495bSYour Name 	}
2391*5113495bSYour Name 	wmi_handle->event_handler[idx] = NULL;
2392*5113495bSYour Name 	wmi_handle->event_id[idx] = 0;
2393*5113495bSYour Name 	--soc->max_event_idx;
2394*5113495bSYour Name 	wmi_handle->event_handler[idx] =
2395*5113495bSYour Name 		wmi_handle->event_handler[soc->max_event_idx];
2396*5113495bSYour Name 	wmi_handle->event_id[idx] =
2397*5113495bSYour Name 		wmi_handle->event_id[soc->max_event_idx];
2398*5113495bSYour Name 
2399*5113495bSYour Name 	qdf_spin_lock_bh(&soc->ctx_lock);
2400*5113495bSYour Name 
2401*5113495bSYour Name 	wmi_handle->ctx[idx].exec_ctx =
2402*5113495bSYour Name 		wmi_handle->ctx[soc->max_event_idx].exec_ctx;
2403*5113495bSYour Name 	wmi_handle->ctx[idx].buff_type =
2404*5113495bSYour Name 		wmi_handle->ctx[soc->max_event_idx].buff_type;
2405*5113495bSYour Name 
2406*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->ctx_lock);
2407*5113495bSYour Name 
2408*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2409*5113495bSYour Name }
2410*5113495bSYour Name 
wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle,wmi_conv_event_id event_id)2411*5113495bSYour Name QDF_STATUS wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle,
2412*5113495bSYour Name 						wmi_conv_event_id event_id)
2413*5113495bSYour Name {
2414*5113495bSYour Name 	uint32_t idx = 0;
2415*5113495bSYour Name 	uint32_t evt_id;
2416*5113495bSYour Name 	struct wmi_soc *soc;
2417*5113495bSYour Name 
2418*5113495bSYour Name 	if (!wmi_handle) {
2419*5113495bSYour Name 		wmi_err("WMI handle is NULL");
2420*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2421*5113495bSYour Name 	}
2422*5113495bSYour Name 
2423*5113495bSYour Name 	soc = wmi_handle->soc;
2424*5113495bSYour Name 
2425*5113495bSYour Name 	if (event_id >= wmi_events_max) {
2426*5113495bSYour Name 		wmi_err("Event id %d is unavailable", event_id);
2427*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2428*5113495bSYour Name 	}
2429*5113495bSYour Name 
2430*5113495bSYour Name 	if (wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
2431*5113495bSYour Name 		wmi_debug("Event id %d is not supported", event_id);
2432*5113495bSYour Name 		return QDF_STATUS_E_NOSUPPORT;
2433*5113495bSYour Name 	}
2434*5113495bSYour Name 
2435*5113495bSYour Name 	evt_id = wmi_handle->wmi_events[event_id];
2436*5113495bSYour Name 
2437*5113495bSYour Name 	idx = wmi_unified_get_event_handler_ix(wmi_handle, evt_id);
2438*5113495bSYour Name 	if (idx == -1) {
2439*5113495bSYour Name 		wmi_err("event handler is not registered: evt id 0x%x",
2440*5113495bSYour Name 			 evt_id);
2441*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2442*5113495bSYour Name 	}
2443*5113495bSYour Name 	wmi_handle->event_handler[idx] = NULL;
2444*5113495bSYour Name 	wmi_handle->event_id[idx] = 0;
2445*5113495bSYour Name 	--soc->max_event_idx;
2446*5113495bSYour Name 	wmi_handle->event_handler[idx] =
2447*5113495bSYour Name 		wmi_handle->event_handler[soc->max_event_idx];
2448*5113495bSYour Name 	wmi_handle->event_id[idx] =
2449*5113495bSYour Name 		wmi_handle->event_id[soc->max_event_idx];
2450*5113495bSYour Name 
2451*5113495bSYour Name 	qdf_spin_lock_bh(&soc->ctx_lock);
2452*5113495bSYour Name 
2453*5113495bSYour Name 	wmi_handle->ctx[idx].exec_ctx =
2454*5113495bSYour Name 		wmi_handle->ctx[soc->max_event_idx].exec_ctx;
2455*5113495bSYour Name 	wmi_handle->ctx[idx].buff_type =
2456*5113495bSYour Name 		wmi_handle->ctx[soc->max_event_idx].buff_type;
2457*5113495bSYour Name 
2458*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->ctx_lock);
2459*5113495bSYour Name 
2460*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2461*5113495bSYour Name }
2462*5113495bSYour Name qdf_export_symbol(wmi_unified_unregister_event_handler);
2463*5113495bSYour Name 
2464*5113495bSYour Name static void
wmi_process_rx_diag_event_worker_thread_ctx(struct wmi_unified * wmi_handle,void * evt_buf)2465*5113495bSYour Name wmi_process_rx_diag_event_worker_thread_ctx(struct wmi_unified *wmi_handle,
2466*5113495bSYour Name 					    void *evt_buf)
2467*5113495bSYour Name {
2468*5113495bSYour Name 	uint32_t num_diag_events_pending;
2469*5113495bSYour Name 
2470*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->diag_eventq_lock);
2471*5113495bSYour Name 	if (RX_DIAG_WQ_MAX_SIZE > 0) {
2472*5113495bSYour Name 		num_diag_events_pending = qdf_nbuf_queue_len(
2473*5113495bSYour Name 						&wmi_handle->diag_event_queue);
2474*5113495bSYour Name 
2475*5113495bSYour Name 		if (num_diag_events_pending >= RX_DIAG_WQ_MAX_SIZE) {
2476*5113495bSYour Name 			qdf_spin_unlock_bh(&wmi_handle->diag_eventq_lock);
2477*5113495bSYour Name 			wmi_handle->wmi_rx_diag_events_dropped++;
2478*5113495bSYour Name 			wmi_debug_rl("Rx diag events dropped count: %d",
2479*5113495bSYour Name 				     wmi_handle->wmi_rx_diag_events_dropped);
2480*5113495bSYour Name 			qdf_nbuf_free(evt_buf);
2481*5113495bSYour Name 			return;
2482*5113495bSYour Name 		}
2483*5113495bSYour Name 	}
2484*5113495bSYour Name 
2485*5113495bSYour Name 	qdf_nbuf_queue_add(&wmi_handle->diag_event_queue, evt_buf);
2486*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->diag_eventq_lock);
2487*5113495bSYour Name 	qdf_queue_work(0, wmi_handle->wmi_rx_diag_work_queue,
2488*5113495bSYour Name 		       &wmi_handle->rx_diag_event_work);
2489*5113495bSYour Name }
2490*5113495bSYour Name 
wmi_process_fw_event_worker_thread_ctx(struct wmi_unified * wmi_handle,void * evt_buf)2491*5113495bSYour Name void wmi_process_fw_event_worker_thread_ctx(struct wmi_unified *wmi_handle,
2492*5113495bSYour Name 					    void *evt_buf)
2493*5113495bSYour Name {
2494*5113495bSYour Name 
2495*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->eventq_lock);
2496*5113495bSYour Name 	qdf_nbuf_queue_add(&wmi_handle->event_queue, evt_buf);
2497*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->eventq_lock);
2498*5113495bSYour Name 	qdf_queue_work(0, wmi_handle->wmi_rx_work_queue,
2499*5113495bSYour Name 			&wmi_handle->rx_event_work);
2500*5113495bSYour Name 
2501*5113495bSYour Name 	return;
2502*5113495bSYour Name }
2503*5113495bSYour Name 
2504*5113495bSYour Name qdf_export_symbol(wmi_process_fw_event_worker_thread_ctx);
2505*5113495bSYour Name 
wmi_critical_events_in_flight(struct wmi_unified * wmi)2506*5113495bSYour Name uint32_t wmi_critical_events_in_flight(struct wmi_unified *wmi)
2507*5113495bSYour Name {
2508*5113495bSYour Name 	return qdf_atomic_read(&wmi->critical_events_in_flight);
2509*5113495bSYour Name }
2510*5113495bSYour Name 
2511*5113495bSYour Name static bool
wmi_is_event_critical(struct wmi_unified * wmi_handle,uint32_t event_id)2512*5113495bSYour Name wmi_is_event_critical(struct wmi_unified *wmi_handle, uint32_t event_id)
2513*5113495bSYour Name {
2514*5113495bSYour Name 	if (wmi_handle->wmi_events[wmi_roam_synch_event_id] == event_id)
2515*5113495bSYour Name 		return true;
2516*5113495bSYour Name 
2517*5113495bSYour Name 	return false;
2518*5113495bSYour Name }
2519*5113495bSYour Name 
wmi_discard_fw_event(struct scheduler_msg * msg)2520*5113495bSYour Name static QDF_STATUS wmi_discard_fw_event(struct scheduler_msg *msg)
2521*5113495bSYour Name {
2522*5113495bSYour Name 	struct wmi_process_fw_event_params *event_param;
2523*5113495bSYour Name 
2524*5113495bSYour Name 	if (!msg->bodyptr)
2525*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2526*5113495bSYour Name 
2527*5113495bSYour Name 	event_param = (struct wmi_process_fw_event_params *)msg->bodyptr;
2528*5113495bSYour Name 	qdf_nbuf_free(event_param->evt_buf);
2529*5113495bSYour Name 	qdf_mem_free(msg->bodyptr);
2530*5113495bSYour Name 	msg->bodyptr = NULL;
2531*5113495bSYour Name 	msg->bodyval = 0;
2532*5113495bSYour Name 	msg->type = 0;
2533*5113495bSYour Name 
2534*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2535*5113495bSYour Name }
2536*5113495bSYour Name 
wmi_process_fw_event_handler(struct scheduler_msg * msg)2537*5113495bSYour Name static QDF_STATUS wmi_process_fw_event_handler(struct scheduler_msg *msg)
2538*5113495bSYour Name {
2539*5113495bSYour Name 	struct wmi_process_fw_event_params *params =
2540*5113495bSYour Name 		(struct wmi_process_fw_event_params *)msg->bodyptr;
2541*5113495bSYour Name 	struct wmi_unified *wmi_handle;
2542*5113495bSYour Name 	uint32_t event_id;
2543*5113495bSYour Name 
2544*5113495bSYour Name 	wmi_handle = (struct wmi_unified *)params->wmi_handle;
2545*5113495bSYour Name 	event_id = WMI_GET_FIELD(qdf_nbuf_data(params->evt_buf),
2546*5113495bSYour Name 				 WMI_CMD_HDR, COMMANDID);
2547*5113495bSYour Name 	wmi_process_fw_event(wmi_handle, params->evt_buf);
2548*5113495bSYour Name 
2549*5113495bSYour Name 	if (wmi_is_event_critical(wmi_handle, event_id))
2550*5113495bSYour Name 		qdf_atomic_dec(&wmi_handle->critical_events_in_flight);
2551*5113495bSYour Name 
2552*5113495bSYour Name 	qdf_mem_free(msg->bodyptr);
2553*5113495bSYour Name 
2554*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2555*5113495bSYour Name }
2556*5113495bSYour Name 
2557*5113495bSYour Name /**
2558*5113495bSYour Name  * wmi_process_fw_event_sched_thread_ctx() - common event handler to serialize
2559*5113495bSYour Name  *                                  event processing through scheduler thread
2560*5113495bSYour Name  * @wmi: wmi context
2561*5113495bSYour Name  * @ev: event buffer
2562*5113495bSYour Name  *
2563*5113495bSYour Name  * Return: 0 on success, errno on failure
2564*5113495bSYour Name  */
2565*5113495bSYour Name static QDF_STATUS
wmi_process_fw_event_sched_thread_ctx(struct wmi_unified * wmi,void * ev)2566*5113495bSYour Name wmi_process_fw_event_sched_thread_ctx(struct wmi_unified *wmi,
2567*5113495bSYour Name 				      void *ev)
2568*5113495bSYour Name {
2569*5113495bSYour Name 	struct wmi_process_fw_event_params *params_buf;
2570*5113495bSYour Name 	struct scheduler_msg msg = { 0 };
2571*5113495bSYour Name 	uint32_t event_id;
2572*5113495bSYour Name 
2573*5113495bSYour Name 	params_buf = qdf_mem_malloc(sizeof(struct wmi_process_fw_event_params));
2574*5113495bSYour Name 	if (!params_buf) {
2575*5113495bSYour Name 		wmi_err("malloc failed");
2576*5113495bSYour Name 		qdf_nbuf_free(ev);
2577*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2578*5113495bSYour Name 	}
2579*5113495bSYour Name 
2580*5113495bSYour Name 	params_buf->wmi_handle = wmi;
2581*5113495bSYour Name 	params_buf->evt_buf = ev;
2582*5113495bSYour Name 
2583*5113495bSYour Name 	event_id = WMI_GET_FIELD(qdf_nbuf_data(params_buf->evt_buf),
2584*5113495bSYour Name 				 WMI_CMD_HDR, COMMANDID);
2585*5113495bSYour Name 	if (wmi_is_event_critical(wmi, event_id))
2586*5113495bSYour Name 		qdf_atomic_inc(&wmi->critical_events_in_flight);
2587*5113495bSYour Name 
2588*5113495bSYour Name 	msg.bodyptr = params_buf;
2589*5113495bSYour Name 	msg.bodyval = 0;
2590*5113495bSYour Name 	msg.callback = wmi_process_fw_event_handler;
2591*5113495bSYour Name 	msg.flush_callback = wmi_discard_fw_event;
2592*5113495bSYour Name 
2593*5113495bSYour Name 	if (QDF_STATUS_SUCCESS !=
2594*5113495bSYour Name 		scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
2595*5113495bSYour Name 				       QDF_MODULE_ID_TARGET_IF,
2596*5113495bSYour Name 				       QDF_MODULE_ID_TARGET_IF, &msg)) {
2597*5113495bSYour Name 		qdf_nbuf_free(ev);
2598*5113495bSYour Name 		qdf_mem_free(params_buf);
2599*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
2600*5113495bSYour Name 	}
2601*5113495bSYour Name 
2602*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2603*5113495bSYour Name }
2604*5113495bSYour Name 
2605*5113495bSYour Name /**
2606*5113495bSYour Name  * wmi_get_pdev_ep: Get wmi handle based on endpoint
2607*5113495bSYour Name  * @soc: handle to wmi soc
2608*5113495bSYour Name  * @ep: endpoint id
2609*5113495bSYour Name  *
2610*5113495bSYour Name  * Return: none
2611*5113495bSYour Name  */
wmi_get_pdev_ep(struct wmi_soc * soc,HTC_ENDPOINT_ID ep)2612*5113495bSYour Name static struct wmi_unified *wmi_get_pdev_ep(struct wmi_soc *soc,
2613*5113495bSYour Name 						HTC_ENDPOINT_ID ep)
2614*5113495bSYour Name {
2615*5113495bSYour Name 	uint32_t i;
2616*5113495bSYour Name 
2617*5113495bSYour Name 	for (i = 0; i < WMI_MAX_RADIOS; i++)
2618*5113495bSYour Name 		if (soc->wmi_endpoint_id[i] == ep)
2619*5113495bSYour Name 			break;
2620*5113495bSYour Name 
2621*5113495bSYour Name 	if (i == WMI_MAX_RADIOS)
2622*5113495bSYour Name 		return NULL;
2623*5113495bSYour Name 
2624*5113495bSYour Name 	return soc->wmi_pdev[i];
2625*5113495bSYour Name }
2626*5113495bSYour Name 
2627*5113495bSYour Name /**
2628*5113495bSYour Name  * wmi_mtrace_rx() - Wrappper function for qdf_mtrace api
2629*5113495bSYour Name  * @message_id: 32-Bit Wmi message ID
2630*5113495bSYour Name  * @vdev_id: Vdev ID
2631*5113495bSYour Name  * @data: Actual message contents
2632*5113495bSYour Name  *
2633*5113495bSYour Name  * This function converts the 32-bit WMI message ID in 15-bit message ID
2634*5113495bSYour Name  * format for qdf_mtrace as in qdf_mtrace message there are only 15
2635*5113495bSYour Name  * bits reserved for message ID.
2636*5113495bSYour Name  * out of these 15-bits, 8-bits (From LSB) specifies the WMI_GRP_ID
2637*5113495bSYour Name  * and remaining 7-bits specifies the actual WMI command. With this
2638*5113495bSYour Name  * notation there can be maximum 256 groups and each group can have
2639*5113495bSYour Name  * max 128 commands can be supported.
2640*5113495bSYour Name  *
2641*5113495bSYour Name  * Return: None
2642*5113495bSYour Name  */
wmi_mtrace_rx(uint32_t message_id,uint16_t vdev_id,uint32_t data)2643*5113495bSYour Name static void wmi_mtrace_rx(uint32_t message_id, uint16_t vdev_id, uint32_t data)
2644*5113495bSYour Name {
2645*5113495bSYour Name 	uint16_t mtrace_message_id;
2646*5113495bSYour Name 
2647*5113495bSYour Name 	mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) |
2648*5113495bSYour Name 		(QDF_WMI_MTRACE_GRP_ID(message_id) <<
2649*5113495bSYour Name 						QDF_WMI_MTRACE_CMD_NUM_BITS);
2650*5113495bSYour Name 	qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_WMA,
2651*5113495bSYour Name 		   mtrace_message_id, vdev_id, data);
2652*5113495bSYour Name }
2653*5113495bSYour Name 
2654*5113495bSYour Name #ifdef WLAN_FEATURE_CE_RX_BUFFER_REUSE
wmi_rx_nbuf_free(qdf_nbuf_t nbuf)2655*5113495bSYour Name static void wmi_rx_nbuf_free(qdf_nbuf_t nbuf)
2656*5113495bSYour Name {
2657*5113495bSYour Name 	nbuf = wbuff_buff_put(nbuf);
2658*5113495bSYour Name 	if (nbuf)
2659*5113495bSYour Name 		qdf_nbuf_free(nbuf);
2660*5113495bSYour Name }
2661*5113495bSYour Name #else
wmi_rx_nbuf_free(qdf_nbuf_t nbuf)2662*5113495bSYour Name static inline void wmi_rx_nbuf_free(qdf_nbuf_t nbuf)
2663*5113495bSYour Name {
2664*5113495bSYour Name 	return qdf_nbuf_free(nbuf);
2665*5113495bSYour Name }
2666*5113495bSYour Name #endif
2667*5113495bSYour Name 
2668*5113495bSYour Name /**
2669*5113495bSYour Name  * wmi_process_control_rx() - process fw events callbacks
2670*5113495bSYour Name  * @wmi_handle: handle to wmi_unified
2671*5113495bSYour Name  * @evt_buf: handle to wmi_buf_t
2672*5113495bSYour Name  *
2673*5113495bSYour Name  * Return: none
2674*5113495bSYour Name  */
wmi_process_control_rx(struct wmi_unified * wmi_handle,wmi_buf_t evt_buf)2675*5113495bSYour Name static void wmi_process_control_rx(struct wmi_unified *wmi_handle,
2676*5113495bSYour Name 				   wmi_buf_t evt_buf)
2677*5113495bSYour Name {
2678*5113495bSYour Name 	struct wmi_soc *soc = wmi_handle->soc;
2679*5113495bSYour Name 	uint32_t id;
2680*5113495bSYour Name 	uint32_t idx;
2681*5113495bSYour Name 	enum wmi_rx_exec_ctx exec_ctx;
2682*5113495bSYour Name 
2683*5113495bSYour Name 	id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
2684*5113495bSYour Name 	idx = wmi_unified_get_event_handler_ix(wmi_handle, id);
2685*5113495bSYour Name 	if (qdf_unlikely(idx == A_ERROR)) {
2686*5113495bSYour Name 		wmi_debug("no handler registered for event id 0x%x", id);
2687*5113495bSYour Name 		wmi_rx_nbuf_free(evt_buf);
2688*5113495bSYour Name 		return;
2689*5113495bSYour Name 	}
2690*5113495bSYour Name 	wmi_mtrace_rx(id, 0xFF, idx);
2691*5113495bSYour Name 	qdf_spin_lock_bh(&soc->ctx_lock);
2692*5113495bSYour Name 	exec_ctx = wmi_handle->ctx[idx].exec_ctx;
2693*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->ctx_lock);
2694*5113495bSYour Name 
2695*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
2696*5113495bSYour Name 	if (wmi_handle->log_info.wmi_logging_enable) {
2697*5113495bSYour Name 		uint8_t *data;
2698*5113495bSYour Name 		data = qdf_nbuf_data(evt_buf);
2699*5113495bSYour Name 
2700*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
2701*5113495bSYour Name 		/* Exclude 4 bytes of TLV header */
2702*5113495bSYour Name 		if (wmi_handle->ops->is_diag_event(id)) {
2703*5113495bSYour Name 			WMI_DIAG_RX_EVENT_RECORD(wmi_handle, id,
2704*5113495bSYour Name 				((uint8_t *) data +
2705*5113495bSYour Name 				wmi_handle->soc->buf_offset_event));
2706*5113495bSYour Name 		} else if (wmi_handle->ops->is_management_record(id)) {
2707*5113495bSYour Name 			WMI_MGMT_RX_EVENT_RECORD(wmi_handle, id,
2708*5113495bSYour Name 				((uint8_t *) data +
2709*5113495bSYour Name 				wmi_handle->soc->buf_offset_event));
2710*5113495bSYour Name 		} else {
2711*5113495bSYour Name 			WMI_RX_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
2712*5113495bSYour Name 				wmi_handle->soc->buf_offset_event));
2713*5113495bSYour Name 		}
2714*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
2715*5113495bSYour Name 	}
2716*5113495bSYour Name #endif
2717*5113495bSYour Name 
2718*5113495bSYour Name 	if (exec_ctx == WMI_RX_WORK_CTX) {
2719*5113495bSYour Name 		wmi_process_fw_event_worker_thread_ctx(wmi_handle, evt_buf);
2720*5113495bSYour Name 	} else if (exec_ctx == WMI_RX_TASKLET_CTX) {
2721*5113495bSYour Name 		wmi_process_fw_event(wmi_handle, evt_buf);
2722*5113495bSYour Name 	} else if (exec_ctx == WMI_RX_SERIALIZER_CTX) {
2723*5113495bSYour Name 		wmi_process_fw_event_sched_thread_ctx(wmi_handle, evt_buf);
2724*5113495bSYour Name 	} else if (exec_ctx == WMI_RX_DIAG_WORK_CTX) {
2725*5113495bSYour Name 		wmi_process_rx_diag_event_worker_thread_ctx(wmi_handle,
2726*5113495bSYour Name 							    evt_buf);
2727*5113495bSYour Name 	} else {
2728*5113495bSYour Name 		wmi_err("Invalid event context %d", exec_ctx);
2729*5113495bSYour Name 		wmi_rx_nbuf_free(evt_buf);
2730*5113495bSYour Name 	}
2731*5113495bSYour Name 
2732*5113495bSYour Name }
2733*5113495bSYour Name 
2734*5113495bSYour Name /**
2735*5113495bSYour Name  * wmi_control_rx() - process fw events callbacks
2736*5113495bSYour Name  * @ctx: handle to wmi
2737*5113495bSYour Name  * @htc_packet: pointer to htc packet
2738*5113495bSYour Name  *
2739*5113495bSYour Name  * Return: none
2740*5113495bSYour Name  */
wmi_control_rx(void * ctx,HTC_PACKET * htc_packet)2741*5113495bSYour Name static void wmi_control_rx(void *ctx, HTC_PACKET *htc_packet)
2742*5113495bSYour Name {
2743*5113495bSYour Name 	struct wmi_soc *soc = (struct wmi_soc *)ctx;
2744*5113495bSYour Name 	struct wmi_unified *wmi_handle;
2745*5113495bSYour Name 	wmi_buf_t evt_buf;
2746*5113495bSYour Name 
2747*5113495bSYour Name 	evt_buf = (wmi_buf_t)htc_packet->pPktContext;
2748*5113495bSYour Name 
2749*5113495bSYour Name 	wmi_handle = wmi_get_pdev_ep(soc, htc_packet->Endpoint);
2750*5113495bSYour Name 	if (!wmi_handle) {
2751*5113495bSYour Name 		wmi_err("unable to get wmi_handle to Endpoint %d",
2752*5113495bSYour Name 			htc_packet->Endpoint);
2753*5113495bSYour Name 		wmi_rx_nbuf_free(evt_buf);
2754*5113495bSYour Name 		return;
2755*5113495bSYour Name 	}
2756*5113495bSYour Name 
2757*5113495bSYour Name 	wmi_process_control_rx(wmi_handle, evt_buf);
2758*5113495bSYour Name }
2759*5113495bSYour Name 
2760*5113495bSYour Name #if defined(WLAN_FEATURE_WMI_DIAG_OVER_CE7) || \
2761*5113495bSYour Name 	defined(WLAN_DIAG_AND_DBR_OVER_SEPARATE_CE)
2762*5113495bSYour Name /**
2763*5113495bSYour Name  * wmi_control_diag_rx() - process diag fw events callbacks
2764*5113495bSYour Name  * @ctx: handle to wmi
2765*5113495bSYour Name  * @htc_packet: pointer to htc packet
2766*5113495bSYour Name  *
2767*5113495bSYour Name  * Return: none
2768*5113495bSYour Name  */
wmi_control_diag_rx(void * ctx,HTC_PACKET * htc_packet)2769*5113495bSYour Name static void wmi_control_diag_rx(void *ctx, HTC_PACKET *htc_packet)
2770*5113495bSYour Name {
2771*5113495bSYour Name 	struct wmi_soc *soc = (struct wmi_soc *)ctx;
2772*5113495bSYour Name 	struct wmi_unified *wmi_handle;
2773*5113495bSYour Name 	wmi_buf_t evt_buf;
2774*5113495bSYour Name 
2775*5113495bSYour Name 	evt_buf = (wmi_buf_t)htc_packet->pPktContext;
2776*5113495bSYour Name 
2777*5113495bSYour Name 	wmi_handle = soc->wmi_pdev[0];
2778*5113495bSYour Name 
2779*5113495bSYour Name 	if (!wmi_handle) {
2780*5113495bSYour Name 		wmi_err("unable to get wmi_handle for diag event end point id:%d", htc_packet->Endpoint);
2781*5113495bSYour Name 		wmi_rx_nbuf_free(evt_buf);
2782*5113495bSYour Name 		return;
2783*5113495bSYour Name 	}
2784*5113495bSYour Name 
2785*5113495bSYour Name 	wmi_process_control_rx(wmi_handle, evt_buf);
2786*5113495bSYour Name }
2787*5113495bSYour Name #endif
2788*5113495bSYour Name 
2789*5113495bSYour Name #if defined(WLAN_DIAG_AND_DBR_OVER_SEPARATE_CE)
2790*5113495bSYour Name /**
2791*5113495bSYour Name  * wmi_control_dbr_rx() - process dbr fw events callbacks
2792*5113495bSYour Name  * @ctx: handle to wmi
2793*5113495bSYour Name  * @htc_packet: pointer to htc packet
2794*5113495bSYour Name  *
2795*5113495bSYour Name  * Return: none
2796*5113495bSYour Name  */
wmi_control_dbr_rx(void * ctx,HTC_PACKET * htc_packet)2797*5113495bSYour Name static void wmi_control_dbr_rx(void *ctx, HTC_PACKET *htc_packet)
2798*5113495bSYour Name {
2799*5113495bSYour Name 	struct wmi_soc *soc = (struct wmi_soc *)ctx;
2800*5113495bSYour Name 	struct wmi_unified *wmi_handle;
2801*5113495bSYour Name 	wmi_buf_t evt_buf;
2802*5113495bSYour Name 
2803*5113495bSYour Name 	evt_buf = (wmi_buf_t)htc_packet->pPktContext;
2804*5113495bSYour Name 	wmi_handle = soc->wmi_pdev[0];
2805*5113495bSYour Name 
2806*5113495bSYour Name 	if (!wmi_handle) {
2807*5113495bSYour Name 		wmi_err("unable to get wmi_handle for dbr event endpoint id:%d",
2808*5113495bSYour Name 			htc_packet->Endpoint);
2809*5113495bSYour Name 		wmi_rx_nbuf_free(evt_buf);
2810*5113495bSYour Name 		return;
2811*5113495bSYour Name 	}
2812*5113495bSYour Name 
2813*5113495bSYour Name 	wmi_process_control_rx(wmi_handle, evt_buf);
2814*5113495bSYour Name }
2815*5113495bSYour Name #endif
2816*5113495bSYour Name 
2817*5113495bSYour Name #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
wmi_unified_cmd_send_over_qmi(struct wmi_unified * wmi_handle,wmi_buf_t buf,uint32_t buflen,uint32_t cmd_id)2818*5113495bSYour Name QDF_STATUS wmi_unified_cmd_send_over_qmi(struct wmi_unified *wmi_handle,
2819*5113495bSYour Name 					 wmi_buf_t buf, uint32_t buflen,
2820*5113495bSYour Name 					 uint32_t cmd_id)
2821*5113495bSYour Name {
2822*5113495bSYour Name 	QDF_STATUS status;
2823*5113495bSYour Name 	int32_t ret;
2824*5113495bSYour Name 
2825*5113495bSYour Name 	if (!qdf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR))) {
2826*5113495bSYour Name 		wmi_err("Failed to send cmd %x, no memory", cmd_id);
2827*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2828*5113495bSYour Name 	}
2829*5113495bSYour Name 
2830*5113495bSYour Name 	qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
2831*5113495bSYour Name 	WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
2832*5113495bSYour Name 	wmi_debug("Sending WMI_CMD_ID: 0x%x over qmi", cmd_id);
2833*5113495bSYour Name 	status = qdf_wmi_send_recv_qmi(qdf_nbuf_data(buf),
2834*5113495bSYour Name 				       buflen + sizeof(WMI_CMD_HDR),
2835*5113495bSYour Name 				       wmi_handle,
2836*5113495bSYour Name 				       wmi_process_qmi_fw_event);
2837*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
2838*5113495bSYour Name 		qdf_nbuf_pull_head(buf, sizeof(WMI_CMD_HDR));
2839*5113495bSYour Name 		wmi_warn("WMI send on QMI failed. Retrying WMI on HTC");
2840*5113495bSYour Name 	} else {
2841*5113495bSYour Name 		ret = qdf_atomic_inc_return(&wmi_handle->num_stats_over_qmi);
2842*5113495bSYour Name 		wmi_debug("num stats over qmi: %d", ret);
2843*5113495bSYour Name 		wmi_buf_free(buf);
2844*5113495bSYour Name 	}
2845*5113495bSYour Name 
2846*5113495bSYour Name 	return status;
2847*5113495bSYour Name }
2848*5113495bSYour Name 
__wmi_process_qmi_fw_event(void * wmi_cb_ctx,void * buf,int len)2849*5113495bSYour Name static int __wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
2850*5113495bSYour Name {
2851*5113495bSYour Name 	struct wmi_unified *wmi_handle = wmi_cb_ctx;
2852*5113495bSYour Name 	wmi_buf_t evt_buf;
2853*5113495bSYour Name 	uint32_t evt_id;
2854*5113495bSYour Name 
2855*5113495bSYour Name 	if (!wmi_handle || !buf || !len) {
2856*5113495bSYour Name 		wmi_err_rl("%s is invalid", !wmi_handle ?
2857*5113495bSYour Name 				"wmi_buf" : !buf ? "buf" : "length");
2858*5113495bSYour Name 		return -EINVAL;
2859*5113495bSYour Name 	}
2860*5113495bSYour Name 
2861*5113495bSYour Name 	evt_buf = wmi_buf_alloc(wmi_handle, len);
2862*5113495bSYour Name 	if (!evt_buf)
2863*5113495bSYour Name 		return -ENOMEM;
2864*5113495bSYour Name 
2865*5113495bSYour Name 	qdf_mem_copy(qdf_nbuf_data(evt_buf), buf, len);
2866*5113495bSYour Name 	evt_id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
2867*5113495bSYour Name 	wmi_debug("Received WMI_EVT_ID: 0x%x over qmi", evt_id);
2868*5113495bSYour Name 	wmi_process_control_rx(wmi_handle, evt_buf);
2869*5113495bSYour Name 
2870*5113495bSYour Name 	return 0;
2871*5113495bSYour Name }
2872*5113495bSYour Name 
wmi_process_qmi_fw_event(void * wmi_cb_ctx,void * buf,int len)2873*5113495bSYour Name int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
2874*5113495bSYour Name {
2875*5113495bSYour Name 	struct qdf_op_sync *op_sync;
2876*5113495bSYour Name 	int ret;
2877*5113495bSYour Name 
2878*5113495bSYour Name 	if (qdf_op_protect(&op_sync))
2879*5113495bSYour Name 		return -EINVAL;
2880*5113495bSYour Name 	ret = __wmi_process_qmi_fw_event(wmi_cb_ctx, buf, len);
2881*5113495bSYour Name 	qdf_op_unprotect(op_sync);
2882*5113495bSYour Name 
2883*5113495bSYour Name 	return ret;
2884*5113495bSYour Name }
2885*5113495bSYour Name #endif
2886*5113495bSYour Name 
wmi_process_fw_event(struct wmi_unified * wmi_handle,wmi_buf_t evt_buf)2887*5113495bSYour Name void wmi_process_fw_event(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf)
2888*5113495bSYour Name {
2889*5113495bSYour Name 	__wmi_control_rx(wmi_handle, evt_buf);
2890*5113495bSYour Name }
2891*5113495bSYour Name 
__wmi_control_rx(struct wmi_unified * wmi_handle,wmi_buf_t evt_buf)2892*5113495bSYour Name void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf)
2893*5113495bSYour Name {
2894*5113495bSYour Name 	uint32_t id;
2895*5113495bSYour Name 	uint8_t *data;
2896*5113495bSYour Name 	uint32_t len;
2897*5113495bSYour Name 	void *wmi_cmd_struct_ptr = NULL;
2898*5113495bSYour Name #ifndef WMI_NON_TLV_SUPPORT
2899*5113495bSYour Name 	int tlv_ok_status = 0;
2900*5113495bSYour Name #endif
2901*5113495bSYour Name 	uint32_t idx = 0;
2902*5113495bSYour Name 	struct wmi_raw_event_buffer ev_buf;
2903*5113495bSYour Name 	enum wmi_rx_buff_type ev_buff_type;
2904*5113495bSYour Name 
2905*5113495bSYour Name 	id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
2906*5113495bSYour Name 
2907*5113495bSYour Name 	wmi_ext_dbg_msg_event_record(wmi_handle, qdf_nbuf_data(evt_buf),
2908*5113495bSYour Name 				     qdf_nbuf_len(evt_buf));
2909*5113495bSYour Name 
2910*5113495bSYour Name 	if (qdf_nbuf_pull_head(evt_buf, sizeof(WMI_CMD_HDR)) == NULL)
2911*5113495bSYour Name 		goto end;
2912*5113495bSYour Name 
2913*5113495bSYour Name 	data = qdf_nbuf_data(evt_buf);
2914*5113495bSYour Name 	len = qdf_nbuf_len(evt_buf);
2915*5113495bSYour Name 
2916*5113495bSYour Name #ifndef WMI_NON_TLV_SUPPORT
2917*5113495bSYour Name 	if (wmi_handle->target_type == WMI_TLV_TARGET) {
2918*5113495bSYour Name 		/* Validate and pad(if necessary) the TLVs */
2919*5113495bSYour Name 		tlv_ok_status =
2920*5113495bSYour Name 			wmi_handle->ops->wmi_check_and_pad_event(wmi_handle->scn_handle,
2921*5113495bSYour Name 							data, len, id,
2922*5113495bSYour Name 							&wmi_cmd_struct_ptr);
2923*5113495bSYour Name 		if (tlv_ok_status != 0) {
2924*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
2925*5113495bSYour Name 				  "%s: Error: id=0x%x, wmitlv check status=%d",
2926*5113495bSYour Name 				  __func__, id, tlv_ok_status);
2927*5113495bSYour Name 			goto end;
2928*5113495bSYour Name 		}
2929*5113495bSYour Name 	}
2930*5113495bSYour Name #endif
2931*5113495bSYour Name 
2932*5113495bSYour Name 	idx = wmi_unified_get_event_handler_ix(wmi_handle, id);
2933*5113495bSYour Name 	if (idx == A_ERROR) {
2934*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
2935*5113495bSYour Name 		   "%s : event handler is not registered: event id 0x%x",
2936*5113495bSYour Name 			__func__, id);
2937*5113495bSYour Name 		goto end;
2938*5113495bSYour Name 	}
2939*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
2940*5113495bSYour Name 	if (wmi_handle->log_info.wmi_logging_enable) {
2941*5113495bSYour Name 		qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
2942*5113495bSYour Name 		/* Exclude 4 bytes of TLV header */
2943*5113495bSYour Name 		if (wmi_handle->ops->is_diag_event(id)) {
2944*5113495bSYour Name 			/*
2945*5113495bSYour Name 			 * skip diag event logging in WMI event buffer
2946*5113495bSYour Name 			 * as its already logged in WMI RX event buffer
2947*5113495bSYour Name 			 */
2948*5113495bSYour Name 		} else if (wmi_handle->ops->is_management_record(id)) {
2949*5113495bSYour Name 			/*
2950*5113495bSYour Name 			 * skip wmi mgmt event logging in WMI event buffer
2951*5113495bSYour Name 			 * as its already logged in WMI RX event buffer
2952*5113495bSYour Name 			 */
2953*5113495bSYour Name 		} else {
2954*5113495bSYour Name 			uint8_t *tmpbuf = (uint8_t *)data +
2955*5113495bSYour Name 					wmi_handle->soc->buf_offset_event;
2956*5113495bSYour Name 
2957*5113495bSYour Name 			WMI_EVENT_RECORD(wmi_handle, id, tmpbuf);
2958*5113495bSYour Name 			wmi_specific_evt_record(wmi_handle, id, tmpbuf);
2959*5113495bSYour Name 		}
2960*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
2961*5113495bSYour Name 	}
2962*5113495bSYour Name #endif
2963*5113495bSYour Name 	/* Call the WMI registered event handler */
2964*5113495bSYour Name 	if (wmi_handle->target_type == WMI_TLV_TARGET) {
2965*5113495bSYour Name 		ev_buff_type = wmi_handle->ctx[idx].buff_type;
2966*5113495bSYour Name 		if (ev_buff_type == WMI_RX_PROCESSED_BUFF) {
2967*5113495bSYour Name 			if (qdf_likely(wmi_handle->event_handler[idx]))
2968*5113495bSYour Name 				wmi_handle->event_handler[idx] (wmi_handle->scn_handle,
2969*5113495bSYour Name 								wmi_cmd_struct_ptr, len);
2970*5113495bSYour Name 		} else if (ev_buff_type == WMI_RX_RAW_BUFF) {
2971*5113495bSYour Name 			ev_buf.evt_raw_buf = data;
2972*5113495bSYour Name 			ev_buf.evt_processed_buf = wmi_cmd_struct_ptr;
2973*5113495bSYour Name 			wmi_handle->event_handler[idx] (wmi_handle->scn_handle,
2974*5113495bSYour Name 							(void *)&ev_buf, len);
2975*5113495bSYour Name 		}
2976*5113495bSYour Name 	}
2977*5113495bSYour Name 	else
2978*5113495bSYour Name 		wmi_handle->event_handler[idx] (wmi_handle->scn_handle,
2979*5113495bSYour Name 			data, len);
2980*5113495bSYour Name 
2981*5113495bSYour Name end:
2982*5113495bSYour Name 	/* Free event buffer and allocated event tlv */
2983*5113495bSYour Name #ifndef WMI_NON_TLV_SUPPORT
2984*5113495bSYour Name 	if (wmi_handle->target_type == WMI_TLV_TARGET)
2985*5113495bSYour Name 		wmi_handle->ops->wmi_free_allocated_event(id, &wmi_cmd_struct_ptr);
2986*5113495bSYour Name #endif
2987*5113495bSYour Name 
2988*5113495bSYour Name 	wmi_rx_nbuf_free(evt_buf);
2989*5113495bSYour Name 
2990*5113495bSYour Name }
2991*5113495bSYour Name 
2992*5113495bSYour Name #define WMI_WQ_WD_TIMEOUT (30 * 1000) /* 30s */
2993*5113495bSYour Name 
wmi_workqueue_watchdog_warn(uint32_t msg_type_id)2994*5113495bSYour Name static inline void wmi_workqueue_watchdog_warn(uint32_t msg_type_id)
2995*5113495bSYour Name {
2996*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2997*5113495bSYour Name 		  "%s: WLAN_BUG_RCA: Message type %x has exceeded its allotted time of %ds",
2998*5113495bSYour Name 		  __func__, msg_type_id, WMI_WQ_WD_TIMEOUT / 1000);
2999*5113495bSYour Name }
3000*5113495bSYour Name 
3001*5113495bSYour Name #ifdef CONFIG_SLUB_DEBUG_ON
wmi_workqueue_watchdog_bite(void * arg)3002*5113495bSYour Name static void wmi_workqueue_watchdog_bite(void *arg)
3003*5113495bSYour Name {
3004*5113495bSYour Name 	struct wmi_wq_dbg_info *info = arg;
3005*5113495bSYour Name 
3006*5113495bSYour Name 	wmi_workqueue_watchdog_warn(info->wd_msg_type_id);
3007*5113495bSYour Name 	qdf_print_thread_trace(info->task);
3008*5113495bSYour Name 
3009*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
3010*5113495bSYour Name 		  "%s: Going down for WMI WQ Watchdog Bite!", __func__);
3011*5113495bSYour Name 	QDF_BUG(0);
3012*5113495bSYour Name }
3013*5113495bSYour Name #else
wmi_workqueue_watchdog_bite(void * arg)3014*5113495bSYour Name static inline void wmi_workqueue_watchdog_bite(void *arg)
3015*5113495bSYour Name {
3016*5113495bSYour Name 	struct wmi_wq_dbg_info *info = arg;
3017*5113495bSYour Name 
3018*5113495bSYour Name 	wmi_workqueue_watchdog_warn(info->wd_msg_type_id);
3019*5113495bSYour Name 
3020*5113495bSYour Name 	qdf_print_thread_trace(info->task);
3021*5113495bSYour Name }
3022*5113495bSYour Name #endif
3023*5113495bSYour Name 
3024*5113495bSYour Name /**
3025*5113495bSYour Name  * wmi_rx_event_work() - process rx event in rx work queue context
3026*5113495bSYour Name  * @arg: opaque pointer to wmi handle
3027*5113495bSYour Name  *
3028*5113495bSYour Name  * This function process any fw event to serialize it through rx worker thread.
3029*5113495bSYour Name  *
3030*5113495bSYour Name  * Return: none
3031*5113495bSYour Name  */
wmi_rx_event_work(void * arg)3032*5113495bSYour Name static void wmi_rx_event_work(void *arg)
3033*5113495bSYour Name {
3034*5113495bSYour Name 	wmi_buf_t buf;
3035*5113495bSYour Name 	struct wmi_unified *wmi = arg;
3036*5113495bSYour Name 	qdf_timer_t wd_timer;
3037*5113495bSYour Name 	struct wmi_wq_dbg_info info;
3038*5113495bSYour Name 
3039*5113495bSYour Name 	/* initialize WMI workqueue watchdog timer */
3040*5113495bSYour Name 	qdf_timer_init(NULL, &wd_timer, &wmi_workqueue_watchdog_bite,
3041*5113495bSYour Name 			&info, QDF_TIMER_TYPE_SW);
3042*5113495bSYour Name 	qdf_spin_lock_bh(&wmi->eventq_lock);
3043*5113495bSYour Name 	buf = qdf_nbuf_queue_remove(&wmi->event_queue);
3044*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi->eventq_lock);
3045*5113495bSYour Name 	while (buf) {
3046*5113495bSYour Name 		qdf_timer_start(&wd_timer, WMI_WQ_WD_TIMEOUT);
3047*5113495bSYour Name 		info.wd_msg_type_id =
3048*5113495bSYour Name 		   WMI_GET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID);
3049*5113495bSYour Name 		info.wmi_wq = wmi->wmi_rx_work_queue;
3050*5113495bSYour Name 		info.task = qdf_get_current_task();
3051*5113495bSYour Name 		__wmi_control_rx(wmi, buf);
3052*5113495bSYour Name 		qdf_timer_stop(&wd_timer);
3053*5113495bSYour Name 		qdf_spin_lock_bh(&wmi->eventq_lock);
3054*5113495bSYour Name 		buf = qdf_nbuf_queue_remove(&wmi->event_queue);
3055*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi->eventq_lock);
3056*5113495bSYour Name 	}
3057*5113495bSYour Name 	qdf_timer_free(&wd_timer);
3058*5113495bSYour Name }
3059*5113495bSYour Name 
3060*5113495bSYour Name /**
3061*5113495bSYour Name  * wmi_rx_diag_event_work() - process rx diag event in work queue context
3062*5113495bSYour Name  * @arg: opaque pointer to wmi handle
3063*5113495bSYour Name  *
3064*5113495bSYour Name  * This function process fw diag event to serialize it through rx worker thread.
3065*5113495bSYour Name  *
3066*5113495bSYour Name  * Return: none
3067*5113495bSYour Name  */
wmi_rx_diag_event_work(void * arg)3068*5113495bSYour Name static void wmi_rx_diag_event_work(void *arg)
3069*5113495bSYour Name {
3070*5113495bSYour Name 	wmi_buf_t buf;
3071*5113495bSYour Name 	struct wmi_unified *wmi = arg;
3072*5113495bSYour Name 	qdf_timer_t wd_timer;
3073*5113495bSYour Name 	struct wmi_wq_dbg_info info;
3074*5113495bSYour Name 	uint32_t diag_event_process_count = 0;
3075*5113495bSYour Name 
3076*5113495bSYour Name 	if (!wmi) {
3077*5113495bSYour Name 		wmi_err("Invalid WMI handle");
3078*5113495bSYour Name 		return;
3079*5113495bSYour Name 	}
3080*5113495bSYour Name 
3081*5113495bSYour Name 	/* initialize WMI workqueue watchdog timer */
3082*5113495bSYour Name 	qdf_timer_init(NULL, &wd_timer, &wmi_workqueue_watchdog_bite,
3083*5113495bSYour Name 		       &info, QDF_TIMER_TYPE_SW);
3084*5113495bSYour Name 	qdf_spin_lock_bh(&wmi->diag_eventq_lock);
3085*5113495bSYour Name 	buf = qdf_nbuf_queue_remove(&wmi->diag_event_queue);
3086*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi->diag_eventq_lock);
3087*5113495bSYour Name 	while (buf) {
3088*5113495bSYour Name 		qdf_timer_start(&wd_timer, WMI_WQ_WD_TIMEOUT);
3089*5113495bSYour Name 		info.wd_msg_type_id =
3090*5113495bSYour Name 		   WMI_GET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID);
3091*5113495bSYour Name 		info.wmi_wq = NULL;
3092*5113495bSYour Name 		info.task = qdf_get_current_task();
3093*5113495bSYour Name 		__wmi_control_rx(wmi, buf);
3094*5113495bSYour Name 		qdf_timer_stop(&wd_timer);
3095*5113495bSYour Name 
3096*5113495bSYour Name 		if (diag_event_process_count++ >
3097*5113495bSYour Name 		    RX_DIAG_EVENT_WORK_PROCESS_MAX_COUNT) {
3098*5113495bSYour Name 			qdf_queue_work(0, wmi->wmi_rx_diag_work_queue,
3099*5113495bSYour Name 				       &wmi->rx_diag_event_work);
3100*5113495bSYour Name 			break;
3101*5113495bSYour Name 		}
3102*5113495bSYour Name 
3103*5113495bSYour Name 		qdf_spin_lock_bh(&wmi->diag_eventq_lock);
3104*5113495bSYour Name 		buf = qdf_nbuf_queue_remove(&wmi->diag_event_queue);
3105*5113495bSYour Name 		qdf_spin_unlock_bh(&wmi->diag_eventq_lock);
3106*5113495bSYour Name 	}
3107*5113495bSYour Name 	qdf_timer_free(&wd_timer);
3108*5113495bSYour Name }
3109*5113495bSYour Name 
3110*5113495bSYour Name #ifdef FEATURE_RUNTIME_PM
3111*5113495bSYour Name /**
3112*5113495bSYour Name  * wmi_runtime_pm_init() - initialize runtime pm wmi variables
3113*5113495bSYour Name  * @wmi_handle: wmi context
3114*5113495bSYour Name  */
wmi_runtime_pm_init(struct wmi_unified * wmi_handle)3115*5113495bSYour Name static void wmi_runtime_pm_init(struct wmi_unified *wmi_handle)
3116*5113495bSYour Name {
3117*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->runtime_pm_inprogress);
3118*5113495bSYour Name }
3119*5113495bSYour Name 
wmi_set_runtime_pm_inprogress(wmi_unified_t wmi_handle,A_BOOL val)3120*5113495bSYour Name void wmi_set_runtime_pm_inprogress(wmi_unified_t wmi_handle, A_BOOL val)
3121*5113495bSYour Name {
3122*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->runtime_pm_inprogress, val);
3123*5113495bSYour Name }
3124*5113495bSYour Name 
wmi_get_runtime_pm_inprogress(wmi_unified_t wmi_handle)3125*5113495bSYour Name bool wmi_get_runtime_pm_inprogress(wmi_unified_t wmi_handle)
3126*5113495bSYour Name {
3127*5113495bSYour Name 	return qdf_atomic_read(&wmi_handle->runtime_pm_inprogress);
3128*5113495bSYour Name }
3129*5113495bSYour Name #else
wmi_runtime_pm_init(struct wmi_unified * wmi_handle)3130*5113495bSYour Name static void wmi_runtime_pm_init(struct wmi_unified *wmi_handle)
3131*5113495bSYour Name {
3132*5113495bSYour Name }
3133*5113495bSYour Name #endif
3134*5113495bSYour Name 
wmi_set_wow_enable_ack_failed(wmi_unified_t wmi_handle)3135*5113495bSYour Name void wmi_set_wow_enable_ack_failed(wmi_unified_t wmi_handle)
3136*5113495bSYour Name {
3137*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->is_wow_enable_ack_failed, 1);
3138*5113495bSYour Name }
3139*5113495bSYour Name 
wmi_clear_wow_enable_ack_failed(wmi_unified_t wmi_handle)3140*5113495bSYour Name void wmi_clear_wow_enable_ack_failed(wmi_unified_t wmi_handle)
3141*5113495bSYour Name {
3142*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->is_wow_enable_ack_failed, 0);
3143*5113495bSYour Name }
3144*5113495bSYour Name 
wmi_has_wow_enable_ack_failed(wmi_unified_t wmi_handle)3145*5113495bSYour Name bool wmi_has_wow_enable_ack_failed(wmi_unified_t wmi_handle)
3146*5113495bSYour Name {
3147*5113495bSYour Name 	return qdf_atomic_read(&wmi_handle->is_wow_enable_ack_failed);
3148*5113495bSYour Name }
3149*5113495bSYour Name 
wmi_unified_get_soc_handle(struct wmi_unified * wmi_handle)3150*5113495bSYour Name void *wmi_unified_get_soc_handle(struct wmi_unified *wmi_handle)
3151*5113495bSYour Name {
3152*5113495bSYour Name 	return wmi_handle->soc;
3153*5113495bSYour Name }
3154*5113495bSYour Name 
3155*5113495bSYour Name /**
3156*5113495bSYour Name  * wmi_interface_logging_init: Interface looging init
3157*5113495bSYour Name  * @wmi_handle: Pointer to wmi handle object
3158*5113495bSYour Name  * @pdev_idx: pdev index
3159*5113495bSYour Name  *
3160*5113495bSYour Name  * Return: None
3161*5113495bSYour Name  */
3162*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
wmi_interface_logging_init(struct wmi_unified * wmi_handle,uint32_t pdev_idx)3163*5113495bSYour Name static inline void wmi_interface_logging_init(struct wmi_unified *wmi_handle,
3164*5113495bSYour Name 					      uint32_t pdev_idx)
3165*5113495bSYour Name {
3166*5113495bSYour Name 	if (QDF_STATUS_SUCCESS == wmi_log_init(wmi_handle)) {
3167*5113495bSYour Name 		qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
3168*5113495bSYour Name 		wmi_debugfs_init(wmi_handle, pdev_idx);
3169*5113495bSYour Name 	}
3170*5113495bSYour Name }
3171*5113495bSYour Name #else
wmi_interface_logging_init(struct wmi_unified * wmi_handle,uint32_t pdev_idx)3172*5113495bSYour Name static inline void wmi_interface_logging_init(struct wmi_unified *wmi_handle,
3173*5113495bSYour Name 					      uint32_t pdev_idx)
3174*5113495bSYour Name {
3175*5113495bSYour Name }
3176*5113495bSYour Name #endif
3177*5113495bSYour Name 
wmi_initialize_worker_context(struct wmi_unified * wmi_handle)3178*5113495bSYour Name static QDF_STATUS wmi_initialize_worker_context(struct wmi_unified *wmi_handle)
3179*5113495bSYour Name {
3180*5113495bSYour Name 	wmi_handle->wmi_rx_work_queue =
3181*5113495bSYour Name 		qdf_alloc_unbound_workqueue("wmi_rx_event_work_queue");
3182*5113495bSYour Name 	if (!wmi_handle->wmi_rx_work_queue) {
3183*5113495bSYour Name 		wmi_err("failed to create wmi_rx_event_work_queue");
3184*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
3185*5113495bSYour Name 	}
3186*5113495bSYour Name 
3187*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->eventq_lock);
3188*5113495bSYour Name 	qdf_nbuf_queue_init(&wmi_handle->event_queue);
3189*5113495bSYour Name 	qdf_create_work(0, &wmi_handle->rx_event_work,
3190*5113495bSYour Name 			wmi_rx_event_work, wmi_handle);
3191*5113495bSYour Name 
3192*5113495bSYour Name 	wmi_handle->wmi_rx_diag_work_queue =
3193*5113495bSYour Name 		qdf_alloc_unbound_workqueue("wmi_rx_diag_event_work_queue");
3194*5113495bSYour Name 	if (!wmi_handle->wmi_rx_diag_work_queue) {
3195*5113495bSYour Name 		wmi_err("failed to create wmi_rx_diag_event_work_queue");
3196*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES;
3197*5113495bSYour Name 	}
3198*5113495bSYour Name 	qdf_spinlock_create(&wmi_handle->diag_eventq_lock);
3199*5113495bSYour Name 	qdf_nbuf_queue_init(&wmi_handle->diag_event_queue);
3200*5113495bSYour Name 	qdf_create_work(0, &wmi_handle->rx_diag_event_work,
3201*5113495bSYour Name 			wmi_rx_diag_event_work, wmi_handle);
3202*5113495bSYour Name 	wmi_handle->wmi_rx_diag_events_dropped = 0;
3203*5113495bSYour Name 
3204*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3205*5113495bSYour Name }
3206*5113495bSYour Name 
wmi_unified_get_pdev_handle(struct wmi_soc * soc,uint32_t pdev_idx)3207*5113495bSYour Name void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx)
3208*5113495bSYour Name {
3209*5113495bSYour Name 	struct wmi_unified *wmi_handle;
3210*5113495bSYour Name 	QDF_STATUS status;
3211*5113495bSYour Name 
3212*5113495bSYour Name 	if (pdev_idx >= WMI_MAX_RADIOS)
3213*5113495bSYour Name 		return NULL;
3214*5113495bSYour Name 
3215*5113495bSYour Name 	if (!soc->wmi_pdev[pdev_idx]) {
3216*5113495bSYour Name 		wmi_handle =
3217*5113495bSYour Name 			(struct wmi_unified *) qdf_mem_malloc(
3218*5113495bSYour Name 					sizeof(struct wmi_unified));
3219*5113495bSYour Name 		if (!wmi_handle)
3220*5113495bSYour Name 			return NULL;
3221*5113495bSYour Name 
3222*5113495bSYour Name 		status = wmi_initialize_worker_context(wmi_handle);
3223*5113495bSYour Name 		if (QDF_IS_STATUS_ERROR(status))
3224*5113495bSYour Name 			goto error;
3225*5113495bSYour Name 
3226*5113495bSYour Name 		wmi_handle->scn_handle = soc->scn_handle;
3227*5113495bSYour Name 		wmi_handle->event_id = soc->event_id;
3228*5113495bSYour Name 		wmi_handle->event_handler = soc->event_handler;
3229*5113495bSYour Name 		wmi_handle->ctx = soc->ctx;
3230*5113495bSYour Name 		wmi_handle->ops = soc->ops;
3231*5113495bSYour Name 		wmi_handle->wmi_events = soc->wmi_events;
3232*5113495bSYour Name 		wmi_handle->services = soc->services;
3233*5113495bSYour Name 		wmi_handle->soc = soc;
3234*5113495bSYour Name 		wmi_handle->cmd_pdev_id_map = soc->cmd_pdev_id_map;
3235*5113495bSYour Name 		wmi_handle->evt_pdev_id_map = soc->evt_pdev_id_map;
3236*5113495bSYour Name 		wmi_handle->cmd_phy_id_map = soc->cmd_phy_id_map;
3237*5113495bSYour Name 		wmi_handle->evt_phy_id_map = soc->evt_phy_id_map;
3238*5113495bSYour Name 		wmi_interface_logging_init(wmi_handle, pdev_idx);
3239*5113495bSYour Name 		qdf_atomic_init(&wmi_handle->is_target_suspended);
3240*5113495bSYour Name 		qdf_atomic_init(&wmi_handle->is_wow_enable_ack_failed);
3241*5113495bSYour Name 		wmi_handle->target_type = soc->target_type;
3242*5113495bSYour Name 		wmi_handle->wmi_max_cmds = soc->wmi_max_cmds;
3243*5113495bSYour Name 
3244*5113495bSYour Name 		wmi_interface_sequence_init(wmi_handle);
3245*5113495bSYour Name 		if (wmi_ext_dbgfs_init(wmi_handle, pdev_idx) !=
3246*5113495bSYour Name 		    QDF_STATUS_SUCCESS)
3247*5113495bSYour Name 			wmi_err("Failed to initialize wmi extended debugfs");
3248*5113495bSYour Name 
3249*5113495bSYour Name 		soc->wmi_pdev[pdev_idx] = wmi_handle;
3250*5113495bSYour Name 	} else
3251*5113495bSYour Name 		wmi_handle = soc->wmi_pdev[pdev_idx];
3252*5113495bSYour Name 
3253*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->pending_cmds);
3254*5113495bSYour Name 	wmi_handle->wmi_stopinprogress = 0;
3255*5113495bSYour Name 	wmi_handle->wmi_endpoint_id = soc->wmi_endpoint_id[pdev_idx];
3256*5113495bSYour Name 	wmi_handle->htc_handle = soc->htc_handle;
3257*5113495bSYour Name 	wmi_handle->max_msg_len = soc->max_msg_len[pdev_idx];
3258*5113495bSYour Name 	wmi_handle->tag_crash_inject = false;
3259*5113495bSYour Name 	wmi_interface_sequence_reset(wmi_handle);
3260*5113495bSYour Name 
3261*5113495bSYour Name 	return wmi_handle;
3262*5113495bSYour Name 
3263*5113495bSYour Name error:
3264*5113495bSYour Name 	qdf_mem_free(wmi_handle);
3265*5113495bSYour Name 
3266*5113495bSYour Name 	return NULL;
3267*5113495bSYour Name }
3268*5113495bSYour Name qdf_export_symbol(wmi_unified_get_pdev_handle);
3269*5113495bSYour Name 
3270*5113495bSYour Name static void (*wmi_attach_register[WMI_MAX_TARGET_TYPE])(wmi_unified_t);
3271*5113495bSYour Name 
wmi_unified_register_module(enum wmi_target_type target_type,void (* wmi_attach)(wmi_unified_t wmi_handle))3272*5113495bSYour Name void wmi_unified_register_module(enum wmi_target_type target_type,
3273*5113495bSYour Name 			void (*wmi_attach)(wmi_unified_t wmi_handle))
3274*5113495bSYour Name {
3275*5113495bSYour Name 	if (target_type < WMI_MAX_TARGET_TYPE)
3276*5113495bSYour Name 		wmi_attach_register[target_type] = wmi_attach;
3277*5113495bSYour Name 
3278*5113495bSYour Name 	return;
3279*5113495bSYour Name }
3280*5113495bSYour Name qdf_export_symbol(wmi_unified_register_module);
3281*5113495bSYour Name 
3282*5113495bSYour Name /**
3283*5113495bSYour Name  * wmi_wbuff_register() - register wmi with wbuff
3284*5113495bSYour Name  * @wmi_handle: handle to wmi
3285*5113495bSYour Name  *
3286*5113495bSYour Name  * Return: void
3287*5113495bSYour Name  */
wmi_wbuff_register(struct wmi_unified * wmi_handle)3288*5113495bSYour Name static void wmi_wbuff_register(struct wmi_unified *wmi_handle)
3289*5113495bSYour Name {
3290*5113495bSYour Name 	struct wbuff_alloc_request wbuff_alloc[4];
3291*5113495bSYour Name 	uint8_t reserve = WMI_MIN_HEAD_ROOM;
3292*5113495bSYour Name 
3293*5113495bSYour Name 	wbuff_alloc[0].pool_id = 0;
3294*5113495bSYour Name 	wbuff_alloc[0].pool_size = WMI_WBUFF_POOL_0_SIZE;
3295*5113495bSYour Name 	wbuff_alloc[0].buffer_size = roundup(WMI_WBUFF_LEN_POOL0 + reserve, 4);
3296*5113495bSYour Name 
3297*5113495bSYour Name 	wbuff_alloc[1].pool_id = 1;
3298*5113495bSYour Name 	wbuff_alloc[1].pool_size = WMI_WBUFF_POOL_1_SIZE;
3299*5113495bSYour Name 	wbuff_alloc[1].buffer_size = roundup(WMI_WBUFF_LEN_POOL1 + reserve, 4);
3300*5113495bSYour Name 
3301*5113495bSYour Name 	wbuff_alloc[2].pool_id = 2;
3302*5113495bSYour Name 	wbuff_alloc[2].pool_size = WMI_WBUFF_POOL_2_SIZE;
3303*5113495bSYour Name 	wbuff_alloc[2].buffer_size = roundup(WMI_WBUFF_LEN_POOL2 + reserve, 4);
3304*5113495bSYour Name 
3305*5113495bSYour Name 	wbuff_alloc[3].pool_id = 3;
3306*5113495bSYour Name 	wbuff_alloc[3].pool_size = WMI_WBUFF_POOL_3_SIZE;
3307*5113495bSYour Name 	wbuff_alloc[3].buffer_size = roundup(WMI_WBUFF_LEN_POOL3 + reserve, 4);
3308*5113495bSYour Name 
3309*5113495bSYour Name 	wmi_handle->wbuff_handle =
3310*5113495bSYour Name 		wbuff_module_register(wbuff_alloc, QDF_ARRAY_SIZE(wbuff_alloc),
3311*5113495bSYour Name 				      reserve, 4, WBUFF_MODULE_WMI_TX);
3312*5113495bSYour Name }
3313*5113495bSYour Name 
3314*5113495bSYour Name /**
3315*5113495bSYour Name  * wmi_wbuff_deregister() - deregister wmi with wbuff
3316*5113495bSYour Name  * @wmi_handle: handle to wmi
3317*5113495bSYour Name  *
3318*5113495bSYour Name  * Return: void
3319*5113495bSYour Name  */
wmi_wbuff_deregister(struct wmi_unified * wmi_handle)3320*5113495bSYour Name static inline void wmi_wbuff_deregister(struct wmi_unified *wmi_handle)
3321*5113495bSYour Name {
3322*5113495bSYour Name 	wbuff_module_deregister(wmi_handle->wbuff_handle);
3323*5113495bSYour Name 	wmi_handle->wbuff_handle = NULL;
3324*5113495bSYour Name }
3325*5113495bSYour Name 
wmi_unified_attach(void * scn_handle,struct wmi_unified_attach_params * param)3326*5113495bSYour Name void *wmi_unified_attach(void *scn_handle,
3327*5113495bSYour Name 			 struct wmi_unified_attach_params *param)
3328*5113495bSYour Name {
3329*5113495bSYour Name 	struct wmi_unified *wmi_handle;
3330*5113495bSYour Name 	struct wmi_soc *soc;
3331*5113495bSYour Name 	QDF_STATUS status;
3332*5113495bSYour Name 
3333*5113495bSYour Name 	soc = (struct wmi_soc *) qdf_mem_malloc(sizeof(struct wmi_soc));
3334*5113495bSYour Name 	if (!soc)
3335*5113495bSYour Name 		return NULL;
3336*5113495bSYour Name 
3337*5113495bSYour Name 	wmi_handle =
3338*5113495bSYour Name 		(struct wmi_unified *) qdf_mem_malloc(
3339*5113495bSYour Name 			sizeof(struct wmi_unified));
3340*5113495bSYour Name 	if (!wmi_handle) {
3341*5113495bSYour Name 		qdf_mem_free(soc);
3342*5113495bSYour Name 		return NULL;
3343*5113495bSYour Name 	}
3344*5113495bSYour Name 
3345*5113495bSYour Name 	status = wmi_initialize_worker_context(wmi_handle);
3346*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status))
3347*5113495bSYour Name 		goto error;
3348*5113495bSYour Name 
3349*5113495bSYour Name 	wmi_handle->soc = soc;
3350*5113495bSYour Name 	wmi_handle->soc->soc_idx = param->soc_id;
3351*5113495bSYour Name 	wmi_handle->soc->is_async_ep = param->is_async_ep;
3352*5113495bSYour Name 	wmi_handle->event_id = soc->event_id;
3353*5113495bSYour Name 	wmi_handle->event_handler = soc->event_handler;
3354*5113495bSYour Name 	wmi_handle->ctx = soc->ctx;
3355*5113495bSYour Name 	wmi_handle->wmi_events = soc->wmi_events;
3356*5113495bSYour Name 	wmi_handle->services = soc->services;
3357*5113495bSYour Name 	wmi_handle->scn_handle = scn_handle;
3358*5113495bSYour Name 	wmi_handle->cmd_pdev_id_map = soc->cmd_pdev_id_map;
3359*5113495bSYour Name 	wmi_handle->evt_pdev_id_map = soc->evt_pdev_id_map;
3360*5113495bSYour Name 	wmi_handle->cmd_phy_id_map = soc->cmd_phy_id_map;
3361*5113495bSYour Name 	wmi_handle->evt_phy_id_map = soc->evt_phy_id_map;
3362*5113495bSYour Name 	soc->scn_handle = scn_handle;
3363*5113495bSYour Name 	wmi_handle->target_type = param->target_type;
3364*5113495bSYour Name 	soc->target_type = param->target_type;
3365*5113495bSYour Name 
3366*5113495bSYour Name 	if (param->target_type >= WMI_MAX_TARGET_TYPE)
3367*5113495bSYour Name 		goto error;
3368*5113495bSYour Name 
3369*5113495bSYour Name 	if (wmi_attach_register[param->target_type]) {
3370*5113495bSYour Name 		wmi_attach_register[param->target_type](wmi_handle);
3371*5113495bSYour Name 	} else {
3372*5113495bSYour Name 		wmi_err("wmi attach is not registered");
3373*5113495bSYour Name 		goto error;
3374*5113495bSYour Name 	}
3375*5113495bSYour Name 
3376*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->pending_cmds);
3377*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->is_target_suspended);
3378*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->is_target_suspend_acked);
3379*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->num_stats_over_qmi);
3380*5113495bSYour Name 	qdf_atomic_init(&wmi_handle->is_wow_enable_ack_failed);
3381*5113495bSYour Name 	wmi_runtime_pm_init(wmi_handle);
3382*5113495bSYour Name 	wmi_interface_logging_init(wmi_handle, WMI_HOST_PDEV_ID_0);
3383*5113495bSYour Name 
3384*5113495bSYour Name 	wmi_interface_sequence_init(wmi_handle);
3385*5113495bSYour Name 	/* Assign target cookie capability */
3386*5113495bSYour Name 	wmi_handle->use_cookie = param->use_cookie;
3387*5113495bSYour Name 	wmi_handle->osdev = param->osdev;
3388*5113495bSYour Name 	wmi_handle->wmi_stopinprogress = 0;
3389*5113495bSYour Name 	wmi_handle->wmi_max_cmds = param->max_commands;
3390*5113495bSYour Name 	soc->wmi_max_cmds = param->max_commands;
3391*5113495bSYour Name 	/* Increase the ref count once refcount infra is present */
3392*5113495bSYour Name 	soc->wmi_psoc = param->psoc;
3393*5113495bSYour Name 	qdf_spinlock_create(&soc->ctx_lock);
3394*5113495bSYour Name 	soc->ops = wmi_handle->ops;
3395*5113495bSYour Name 	soc->wmi_pdev[0] = wmi_handle;
3396*5113495bSYour Name 	if (wmi_ext_dbgfs_init(wmi_handle, 0) != QDF_STATUS_SUCCESS)
3397*5113495bSYour Name 		wmi_err("Failed to initialize wmi extended debugfs");
3398*5113495bSYour Name 
3399*5113495bSYour Name 	wmi_wbuff_register(wmi_handle);
3400*5113495bSYour Name 
3401*5113495bSYour Name 	wmi_hang_event_notifier_register(wmi_handle);
3402*5113495bSYour Name 
3403*5113495bSYour Name 	wmi_minidump_attach(wmi_handle);
3404*5113495bSYour Name 
3405*5113495bSYour Name 	return wmi_handle;
3406*5113495bSYour Name 
3407*5113495bSYour Name error:
3408*5113495bSYour Name 	qdf_mem_free(soc);
3409*5113495bSYour Name 	qdf_mem_free(wmi_handle);
3410*5113495bSYour Name 
3411*5113495bSYour Name 	return NULL;
3412*5113495bSYour Name }
3413*5113495bSYour Name 
wmi_unified_detach(struct wmi_unified * wmi_handle)3414*5113495bSYour Name void wmi_unified_detach(struct wmi_unified *wmi_handle)
3415*5113495bSYour Name {
3416*5113495bSYour Name 	wmi_buf_t buf;
3417*5113495bSYour Name 	struct wmi_soc *soc;
3418*5113495bSYour Name 	uint8_t i;
3419*5113495bSYour Name 
3420*5113495bSYour Name 	wmi_minidump_detach(wmi_handle);
3421*5113495bSYour Name 
3422*5113495bSYour Name 	wmi_hang_event_notifier_unregister();
3423*5113495bSYour Name 
3424*5113495bSYour Name 	wmi_wbuff_deregister(wmi_handle);
3425*5113495bSYour Name 
3426*5113495bSYour Name 	soc = wmi_handle->soc;
3427*5113495bSYour Name 	for (i = 0; i < WMI_MAX_RADIOS; i++) {
3428*5113495bSYour Name 		if (soc->wmi_pdev[i]) {
3429*5113495bSYour Name 			qdf_flush_workqueue(0,
3430*5113495bSYour Name 				soc->wmi_pdev[i]->wmi_rx_work_queue);
3431*5113495bSYour Name 			qdf_destroy_workqueue(0,
3432*5113495bSYour Name 				soc->wmi_pdev[i]->wmi_rx_work_queue);
3433*5113495bSYour Name 			wmi_debugfs_remove(soc->wmi_pdev[i]);
3434*5113495bSYour Name 			buf = qdf_nbuf_queue_remove(
3435*5113495bSYour Name 					&soc->wmi_pdev[i]->event_queue);
3436*5113495bSYour Name 			while (buf) {
3437*5113495bSYour Name 				qdf_nbuf_free(buf);
3438*5113495bSYour Name 				buf = qdf_nbuf_queue_remove(
3439*5113495bSYour Name 						&soc->wmi_pdev[i]->event_queue);
3440*5113495bSYour Name 			}
3441*5113495bSYour Name 
3442*5113495bSYour Name 			qdf_flush_workqueue(0,
3443*5113495bSYour Name 				soc->wmi_pdev[i]->wmi_rx_diag_work_queue);
3444*5113495bSYour Name 			qdf_destroy_workqueue(0,
3445*5113495bSYour Name 				soc->wmi_pdev[i]->wmi_rx_diag_work_queue);
3446*5113495bSYour Name 			buf = qdf_nbuf_queue_remove(
3447*5113495bSYour Name 					&soc->wmi_pdev[i]->diag_event_queue);
3448*5113495bSYour Name 			while (buf) {
3449*5113495bSYour Name 				qdf_nbuf_free(buf);
3450*5113495bSYour Name 				buf = qdf_nbuf_queue_remove(
3451*5113495bSYour Name 					&soc->wmi_pdev[i]->diag_event_queue);
3452*5113495bSYour Name 			}
3453*5113495bSYour Name 
3454*5113495bSYour Name 			wmi_log_buffer_free(soc->wmi_pdev[i]);
3455*5113495bSYour Name 
3456*5113495bSYour Name 			/* Free events logs list */
3457*5113495bSYour Name 			if (soc->wmi_pdev[i]->events_logs_list)
3458*5113495bSYour Name 				qdf_mem_free(
3459*5113495bSYour Name 					soc->wmi_pdev[i]->events_logs_list);
3460*5113495bSYour Name 
3461*5113495bSYour Name 			qdf_spinlock_destroy(&soc->wmi_pdev[i]->eventq_lock);
3462*5113495bSYour Name 			qdf_spinlock_destroy(
3463*5113495bSYour Name 					&soc->wmi_pdev[i]->diag_eventq_lock);
3464*5113495bSYour Name 
3465*5113495bSYour Name 			wmi_interface_sequence_deinit(soc->wmi_pdev[i]);
3466*5113495bSYour Name 			wmi_ext_dbgfs_deinit(soc->wmi_pdev[i]);
3467*5113495bSYour Name 			wmi_clear_wow_enable_ack_failed(soc->wmi_pdev[i]);
3468*5113495bSYour Name 
3469*5113495bSYour Name 			qdf_mem_free(soc->wmi_pdev[i]);
3470*5113495bSYour Name 		}
3471*5113495bSYour Name 	}
3472*5113495bSYour Name 	qdf_spinlock_destroy(&soc->ctx_lock);
3473*5113495bSYour Name 
3474*5113495bSYour Name 	if (soc->wmi_service_bitmap) {
3475*5113495bSYour Name 		qdf_mem_free(soc->wmi_service_bitmap);
3476*5113495bSYour Name 		soc->wmi_service_bitmap = NULL;
3477*5113495bSYour Name 	}
3478*5113495bSYour Name 
3479*5113495bSYour Name 	if (soc->wmi_ext_service_bitmap) {
3480*5113495bSYour Name 		qdf_mem_free(soc->wmi_ext_service_bitmap);
3481*5113495bSYour Name 		soc->wmi_ext_service_bitmap = NULL;
3482*5113495bSYour Name 	}
3483*5113495bSYour Name 
3484*5113495bSYour Name 	if (soc->wmi_ext2_service_bitmap) {
3485*5113495bSYour Name 		qdf_mem_free(soc->wmi_ext2_service_bitmap);
3486*5113495bSYour Name 		soc->wmi_ext2_service_bitmap = NULL;
3487*5113495bSYour Name 	}
3488*5113495bSYour Name 
3489*5113495bSYour Name 	/* Decrease the ref count once refcount infra is present */
3490*5113495bSYour Name 	soc->wmi_psoc = NULL;
3491*5113495bSYour Name 	qdf_mem_free(soc);
3492*5113495bSYour Name }
3493*5113495bSYour Name 
3494*5113495bSYour Name void
wmi_unified_remove_work(struct wmi_unified * wmi_handle)3495*5113495bSYour Name wmi_unified_remove_work(struct wmi_unified *wmi_handle)
3496*5113495bSYour Name {
3497*5113495bSYour Name 	wmi_buf_t buf;
3498*5113495bSYour Name 
3499*5113495bSYour Name 	qdf_flush_workqueue(0, wmi_handle->wmi_rx_work_queue);
3500*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->eventq_lock);
3501*5113495bSYour Name 	buf = qdf_nbuf_queue_remove(&wmi_handle->event_queue);
3502*5113495bSYour Name 	while (buf) {
3503*5113495bSYour Name 		qdf_nbuf_free(buf);
3504*5113495bSYour Name 		buf = qdf_nbuf_queue_remove(&wmi_handle->event_queue);
3505*5113495bSYour Name 	}
3506*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->eventq_lock);
3507*5113495bSYour Name 
3508*5113495bSYour Name 	/* Remove diag events work */
3509*5113495bSYour Name 	qdf_flush_workqueue(0, wmi_handle->wmi_rx_diag_work_queue);
3510*5113495bSYour Name 	qdf_spin_lock_bh(&wmi_handle->diag_eventq_lock);
3511*5113495bSYour Name 	buf = qdf_nbuf_queue_remove(&wmi_handle->diag_event_queue);
3512*5113495bSYour Name 	while (buf) {
3513*5113495bSYour Name 		qdf_nbuf_free(buf);
3514*5113495bSYour Name 		buf = qdf_nbuf_queue_remove(&wmi_handle->diag_event_queue);
3515*5113495bSYour Name 	}
3516*5113495bSYour Name 	qdf_spin_unlock_bh(&wmi_handle->diag_eventq_lock);
3517*5113495bSYour Name }
3518*5113495bSYour Name 
3519*5113495bSYour Name /**
3520*5113495bSYour Name  * wmi_htc_tx_complete() - Process htc tx completion
3521*5113495bSYour Name  *
3522*5113495bSYour Name  * @ctx: handle to wmi
3523*5113495bSYour Name  * @htc_pkt: pointer to htc packet
3524*5113495bSYour Name  *
3525*5113495bSYour Name  * Return: none.
3526*5113495bSYour Name  */
wmi_htc_tx_complete(void * ctx,HTC_PACKET * htc_pkt)3527*5113495bSYour Name static void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt)
3528*5113495bSYour Name {
3529*5113495bSYour Name 	struct wmi_soc *soc = (struct wmi_soc *) ctx;
3530*5113495bSYour Name 	wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
3531*5113495bSYour Name 	u_int8_t *buf_ptr;
3532*5113495bSYour Name 	u_int32_t len;
3533*5113495bSYour Name 	struct wmi_unified *wmi_handle;
3534*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
3535*5113495bSYour Name 	struct wmi_debug_log_info *log_info;
3536*5113495bSYour Name 	uint32_t cmd_id;
3537*5113495bSYour Name 	uint8_t *offset_ptr;
3538*5113495bSYour Name 	qdf_dma_addr_t dma_addr;
3539*5113495bSYour Name 	uint64_t phy_addr;
3540*5113495bSYour Name #endif
3541*5113495bSYour Name 
3542*5113495bSYour Name 	ASSERT(wmi_cmd_buf);
3543*5113495bSYour Name 	wmi_handle = wmi_get_pdev_ep(soc, htc_pkt->Endpoint);
3544*5113495bSYour Name 	if (!wmi_handle) {
3545*5113495bSYour Name 		wmi_err("Unable to get wmi handle");
3546*5113495bSYour Name 		QDF_ASSERT(0);
3547*5113495bSYour Name 		return;
3548*5113495bSYour Name 	}
3549*5113495bSYour Name 	buf_ptr = (u_int8_t *)wmi_buf_data(wmi_cmd_buf);
3550*5113495bSYour Name #ifdef WMI_INTERFACE_EVENT_LOGGING
3551*5113495bSYour Name 	log_info = &wmi_handle->log_info;
3552*5113495bSYour Name 
3553*5113495bSYour Name 	if (wmi_handle && log_info->wmi_logging_enable) {
3554*5113495bSYour Name 		cmd_id = WMI_GET_FIELD(qdf_nbuf_data(wmi_cmd_buf),
3555*5113495bSYour Name 				WMI_CMD_HDR, COMMANDID);
3556*5113495bSYour Name 
3557*5113495bSYour Name 		dma_addr = QDF_NBUF_CB_PADDR(wmi_cmd_buf);
3558*5113495bSYour Name 		phy_addr = qdf_mem_virt_to_phys(qdf_nbuf_data(wmi_cmd_buf));
3559*5113495bSYour Name 
3560*5113495bSYour Name 		qdf_spin_lock_bh(&log_info->wmi_record_lock);
3561*5113495bSYour Name 		/* Record 16 bytes of WMI cmd tx complete data
3562*5113495bSYour Name 		 * - exclude TLV and WMI headers
3563*5113495bSYour Name 		 */
3564*5113495bSYour Name 		offset_ptr = buf_ptr + wmi_handle->soc->buf_offset_command;
3565*5113495bSYour Name 		if (wmi_handle->ops->is_management_record(cmd_id)) {
3566*5113495bSYour Name 			WMI_MGMT_COMMAND_TX_CMP_RECORD(wmi_handle, cmd_id,
3567*5113495bSYour Name 						       offset_ptr);
3568*5113495bSYour Name 		} else {
3569*5113495bSYour Name 			if (wmi_handle->ops->is_force_fw_hang_cmd(cmd_id)) {
3570*5113495bSYour Name 				wmi_info("Tx completion received for WMI_FORCE_FW_HANG_CMDID, current_time:%ld",
3571*5113495bSYour Name 					 qdf_mc_timer_get_system_time());
3572*5113495bSYour Name 			}
3573*5113495bSYour Name 
3574*5113495bSYour Name 			WMI_COMMAND_TX_CMP_RECORD(wmi_handle, cmd_id,
3575*5113495bSYour Name 						  offset_ptr, dma_addr,
3576*5113495bSYour Name 						  phy_addr);
3577*5113495bSYour Name 		}
3578*5113495bSYour Name 
3579*5113495bSYour Name 		qdf_spin_unlock_bh(&log_info->wmi_record_lock);
3580*5113495bSYour Name 	}
3581*5113495bSYour Name #endif
3582*5113495bSYour Name 
3583*5113495bSYour Name 	wmi_interface_sequence_check(wmi_handle, wmi_cmd_buf);
3584*5113495bSYour Name 
3585*5113495bSYour Name 	len = qdf_nbuf_len(wmi_cmd_buf);
3586*5113495bSYour Name 	qdf_mem_zero(buf_ptr, len);
3587*5113495bSYour Name 	wmi_buf_free(wmi_cmd_buf);
3588*5113495bSYour Name 	qdf_mem_free(htc_pkt);
3589*5113495bSYour Name 	qdf_atomic_dec(&wmi_handle->pending_cmds);
3590*5113495bSYour Name }
3591*5113495bSYour Name 
3592*5113495bSYour Name #ifdef FEATURE_RUNTIME_PM
3593*5113495bSYour Name /**
3594*5113495bSYour Name  * wmi_htc_log_pkt() - Print information of WMI command from HTC packet
3595*5113495bSYour Name  *
3596*5113495bSYour Name  * @ctx: handle of WMI context
3597*5113495bSYour Name  * @htc_pkt: handle of HTC packet
3598*5113495bSYour Name  *
3599*5113495bSYour Name  * Return: none
3600*5113495bSYour Name  */
wmi_htc_log_pkt(void * ctx,HTC_PACKET * htc_pkt)3601*5113495bSYour Name static void wmi_htc_log_pkt(void *ctx, HTC_PACKET *htc_pkt)
3602*5113495bSYour Name {
3603*5113495bSYour Name 	wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
3604*5113495bSYour Name 	uint32_t cmd_id;
3605*5113495bSYour Name 
3606*5113495bSYour Name 	ASSERT(wmi_cmd_buf);
3607*5113495bSYour Name 	cmd_id = WMI_GET_FIELD(qdf_nbuf_data(wmi_cmd_buf), WMI_CMD_HDR,
3608*5113495bSYour Name 			       COMMANDID);
3609*5113495bSYour Name 
3610*5113495bSYour Name 	wmi_debug("WMI command from HTC packet: %s, ID: %d",
3611*5113495bSYour Name 		 wmi_id_to_name(cmd_id), cmd_id);
3612*5113495bSYour Name }
3613*5113495bSYour Name #else
wmi_htc_log_pkt(void * ctx,HTC_PACKET * htc_pkt)3614*5113495bSYour Name static void wmi_htc_log_pkt(void *ctx, HTC_PACKET *htc_pkt)
3615*5113495bSYour Name {
3616*5113495bSYour Name }
3617*5113495bSYour Name #endif
3618*5113495bSYour Name 
3619*5113495bSYour Name /**
3620*5113495bSYour Name  * wmi_connect_pdev_htc_service() -  WMI API to get connect to HTC service
3621*5113495bSYour Name  * @soc: handle to WMI SoC
3622*5113495bSYour Name  * @pdev_idx: Pdev index
3623*5113495bSYour Name  *
3624*5113495bSYour Name  * Return: QDF_STATUS
3625*5113495bSYour Name  */
wmi_connect_pdev_htc_service(struct wmi_soc * soc,uint32_t pdev_idx)3626*5113495bSYour Name static QDF_STATUS wmi_connect_pdev_htc_service(struct wmi_soc *soc,
3627*5113495bSYour Name 					       uint32_t pdev_idx)
3628*5113495bSYour Name {
3629*5113495bSYour Name 	QDF_STATUS status;
3630*5113495bSYour Name 	struct htc_service_connect_resp response;
3631*5113495bSYour Name 	struct htc_service_connect_req connect;
3632*5113495bSYour Name 
3633*5113495bSYour Name 	OS_MEMZERO(&connect, sizeof(connect));
3634*5113495bSYour Name 	OS_MEMZERO(&response, sizeof(response));
3635*5113495bSYour Name 
3636*5113495bSYour Name 	/* meta data is unused for now */
3637*5113495bSYour Name 	connect.pMetaData = NULL;
3638*5113495bSYour Name 	connect.MetaDataLength = 0;
3639*5113495bSYour Name 	/* these fields are the same for all service endpoints */
3640*5113495bSYour Name 	connect.EpCallbacks.pContext = soc;
3641*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple =
3642*5113495bSYour Name 		NULL /* Control path completion ar6000_tx_complete */;
3643*5113495bSYour Name 	connect.EpCallbacks.EpRecv = wmi_control_rx /* Control path rx */;
3644*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL /* ar6000_rx_refill */;
3645*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = NULL /* ar6000_tx_queue_full */;
3646*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete =
3647*5113495bSYour Name 		wmi_htc_tx_complete /* ar6000_tx_queue_full */;
3648*5113495bSYour Name 	connect.EpCallbacks.ep_log_pkt = wmi_htc_log_pkt;
3649*5113495bSYour Name 
3650*5113495bSYour Name 	/* connect to control service */
3651*5113495bSYour Name 	connect.service_id = soc->svc_ids[pdev_idx];
3652*5113495bSYour Name 	status = htc_connect_service(soc->htc_handle, &connect, &response);
3653*5113495bSYour Name 
3654*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3655*5113495bSYour Name 		wmi_err("Failed to connect to WMI CONTROL service status:%d",
3656*5113495bSYour Name 			 status);
3657*5113495bSYour Name 		return status;
3658*5113495bSYour Name 	}
3659*5113495bSYour Name 
3660*5113495bSYour Name 	if (soc->is_async_ep)
3661*5113495bSYour Name 		htc_set_async_ep(soc->htc_handle, response.Endpoint, true);
3662*5113495bSYour Name 
3663*5113495bSYour Name 	soc->wmi_endpoint_id[pdev_idx] = response.Endpoint;
3664*5113495bSYour Name 	soc->max_msg_len[pdev_idx] = response.MaxMsgLength;
3665*5113495bSYour Name 
3666*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3667*5113495bSYour Name }
3668*5113495bSYour Name 
3669*5113495bSYour Name QDF_STATUS
wmi_unified_connect_htc_service(struct wmi_unified * wmi_handle,HTC_HANDLE htc_handle)3670*5113495bSYour Name wmi_unified_connect_htc_service(struct wmi_unified *wmi_handle,
3671*5113495bSYour Name 				HTC_HANDLE htc_handle)
3672*5113495bSYour Name {
3673*5113495bSYour Name 	uint32_t i;
3674*5113495bSYour Name 	uint8_t wmi_ep_count;
3675*5113495bSYour Name 
3676*5113495bSYour Name 	wmi_handle->soc->htc_handle = htc_handle;
3677*5113495bSYour Name 
3678*5113495bSYour Name 	wmi_ep_count = htc_get_wmi_endpoint_count(htc_handle);
3679*5113495bSYour Name 	if (wmi_ep_count > WMI_MAX_RADIOS)
3680*5113495bSYour Name 		return QDF_STATUS_E_FAULT;
3681*5113495bSYour Name 
3682*5113495bSYour Name 	for (i = 0; i < wmi_ep_count; i++)
3683*5113495bSYour Name 		wmi_connect_pdev_htc_service(wmi_handle->soc, i);
3684*5113495bSYour Name 
3685*5113495bSYour Name 	wmi_handle->htc_handle = htc_handle;
3686*5113495bSYour Name 	wmi_handle->wmi_endpoint_id = wmi_handle->soc->wmi_endpoint_id[0];
3687*5113495bSYour Name 	wmi_handle->max_msg_len = wmi_handle->soc->max_msg_len[0];
3688*5113495bSYour Name 
3689*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3690*5113495bSYour Name }
3691*5113495bSYour Name 
3692*5113495bSYour Name #if defined(WLAN_FEATURE_WMI_DIAG_OVER_CE7) || \
3693*5113495bSYour Name 	defined(WLAN_DIAG_AND_DBR_OVER_SEPARATE_CE)
wmi_diag_connect_pdev_htc_service(struct wmi_unified * wmi_handle,HTC_HANDLE htc_handle)3694*5113495bSYour Name QDF_STATUS wmi_diag_connect_pdev_htc_service(struct wmi_unified *wmi_handle,
3695*5113495bSYour Name 					     HTC_HANDLE htc_handle)
3696*5113495bSYour Name {
3697*5113495bSYour Name 	QDF_STATUS status;
3698*5113495bSYour Name 	struct htc_service_connect_resp response = {0};
3699*5113495bSYour Name 	struct htc_service_connect_req connect = {0};
3700*5113495bSYour Name 
3701*5113495bSYour Name 	/* meta data is unused for now */
3702*5113495bSYour Name 	connect.pMetaData = NULL;
3703*5113495bSYour Name 	connect.MetaDataLength = 0;
3704*5113495bSYour Name 	connect.EpCallbacks.pContext = wmi_handle->soc;
3705*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
3706*5113495bSYour Name 	connect.EpCallbacks.EpRecv = wmi_control_diag_rx /* wmi diag rx */;
3707*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL;
3708*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = NULL;
3709*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete = NULL;
3710*5113495bSYour Name 	connect.EpCallbacks.ep_log_pkt = wmi_htc_log_pkt;
3711*5113495bSYour Name 
3712*5113495bSYour Name 	/* connect to wmi diag service */
3713*5113495bSYour Name 	connect.service_id = WMI_CONTROL_DIAG_SVC;
3714*5113495bSYour Name 	status = htc_connect_service(htc_handle, &connect, &response);
3715*5113495bSYour Name 
3716*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3717*5113495bSYour Name 		wmi_err("Failed to connect to WMI DIAG service status:%d",
3718*5113495bSYour Name 			status);
3719*5113495bSYour Name 		return status;
3720*5113495bSYour Name 	}
3721*5113495bSYour Name 
3722*5113495bSYour Name 	if (wmi_handle->soc->is_async_ep)
3723*5113495bSYour Name 		htc_set_async_ep(htc_handle, response.Endpoint, true);
3724*5113495bSYour Name 
3725*5113495bSYour Name 	wmi_handle->soc->wmi_diag_endpoint_id = response.Endpoint;
3726*5113495bSYour Name 
3727*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3728*5113495bSYour Name }
3729*5113495bSYour Name #endif
3730*5113495bSYour Name 
3731*5113495bSYour Name #if defined(WLAN_DIAG_AND_DBR_OVER_SEPARATE_CE)
wmi_dbr_connect_pdev_htc_service(struct wmi_unified * wmi_handle,HTC_HANDLE htc_handle)3732*5113495bSYour Name QDF_STATUS wmi_dbr_connect_pdev_htc_service(struct wmi_unified *wmi_handle,
3733*5113495bSYour Name 					    HTC_HANDLE htc_handle)
3734*5113495bSYour Name {
3735*5113495bSYour Name 	QDF_STATUS status;
3736*5113495bSYour Name 	struct htc_service_connect_resp response = {0};
3737*5113495bSYour Name 	struct htc_service_connect_req connect = {0};
3738*5113495bSYour Name 
3739*5113495bSYour Name 	/* meta data is unused for now */
3740*5113495bSYour Name 	connect.pMetaData = NULL;
3741*5113495bSYour Name 	connect.MetaDataLength = 0;
3742*5113495bSYour Name 	connect.EpCallbacks.pContext = wmi_handle->soc;
3743*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
3744*5113495bSYour Name 	connect.EpCallbacks.EpRecv = wmi_control_dbr_rx /* wmi dbr rx */;
3745*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL;
3746*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = NULL;
3747*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete = NULL;
3748*5113495bSYour Name 	connect.EpCallbacks.ep_log_pkt = wmi_htc_log_pkt;
3749*5113495bSYour Name 
3750*5113495bSYour Name 	/* connect to wmi dbr service */
3751*5113495bSYour Name 	connect.service_id = WMI_CONTROL_DBR_SVC;
3752*5113495bSYour Name 	status = htc_connect_service(htc_handle, &connect, &response);
3753*5113495bSYour Name 
3754*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3755*5113495bSYour Name 		wmi_err("Failed to connect to WMI DBR service status:%d",
3756*5113495bSYour Name 			status);
3757*5113495bSYour Name 		return status;
3758*5113495bSYour Name 	}
3759*5113495bSYour Name 
3760*5113495bSYour Name 	if (wmi_handle->soc->is_async_ep)
3761*5113495bSYour Name 		htc_set_async_ep(htc_handle, response.Endpoint, true);
3762*5113495bSYour Name 
3763*5113495bSYour Name 	wmi_handle->soc->wmi_dbr_endpoint_id = response.Endpoint;
3764*5113495bSYour Name 
3765*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
3766*5113495bSYour Name }
3767*5113495bSYour Name #endif
3768*5113495bSYour Name 
wmi_get_host_credits(wmi_unified_t wmi_handle)3769*5113495bSYour Name int wmi_get_host_credits(wmi_unified_t wmi_handle)
3770*5113495bSYour Name {
3771*5113495bSYour Name 	int host_credits = 0;
3772*5113495bSYour Name 
3773*5113495bSYour Name 	htc_get_control_endpoint_tx_host_credits(wmi_handle->htc_handle,
3774*5113495bSYour Name 						 &host_credits);
3775*5113495bSYour Name 	return host_credits;
3776*5113495bSYour Name }
3777*5113495bSYour Name 
wmi_get_pending_cmds(wmi_unified_t wmi_handle)3778*5113495bSYour Name int wmi_get_pending_cmds(wmi_unified_t wmi_handle)
3779*5113495bSYour Name {
3780*5113495bSYour Name 	return qdf_atomic_read(&wmi_handle->pending_cmds);
3781*5113495bSYour Name }
3782*5113495bSYour Name 
wmi_set_target_suspend(wmi_unified_t wmi_handle,A_BOOL val)3783*5113495bSYour Name void wmi_set_target_suspend(wmi_unified_t wmi_handle, A_BOOL val)
3784*5113495bSYour Name {
3785*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->is_target_suspended, val);
3786*5113495bSYour Name }
3787*5113495bSYour Name 
wmi_set_target_suspend_acked(wmi_unified_t wmi_handle,A_BOOL val)3788*5113495bSYour Name void wmi_set_target_suspend_acked(wmi_unified_t wmi_handle, A_BOOL val)
3789*5113495bSYour Name {
3790*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->is_target_suspend_acked, val);
3791*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->num_stats_over_qmi, 0);
3792*5113495bSYour Name }
3793*5113495bSYour Name 
wmi_is_target_suspended(struct wmi_unified * wmi_handle)3794*5113495bSYour Name bool wmi_is_target_suspended(struct wmi_unified *wmi_handle)
3795*5113495bSYour Name {
3796*5113495bSYour Name 	return qdf_atomic_read(&wmi_handle->is_target_suspended);
3797*5113495bSYour Name }
3798*5113495bSYour Name qdf_export_symbol(wmi_is_target_suspended);
3799*5113495bSYour Name 
wmi_is_target_suspend_acked(struct wmi_unified * wmi_handle)3800*5113495bSYour Name bool wmi_is_target_suspend_acked(struct wmi_unified *wmi_handle)
3801*5113495bSYour Name {
3802*5113495bSYour Name 	return qdf_atomic_read(&wmi_handle->is_target_suspend_acked);
3803*5113495bSYour Name }
3804*5113495bSYour Name qdf_export_symbol(wmi_is_target_suspend_acked);
3805*5113495bSYour Name 
3806*5113495bSYour Name #ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
wmi_set_qmi_stats(wmi_unified_t wmi_handle,bool val)3807*5113495bSYour Name void wmi_set_qmi_stats(wmi_unified_t wmi_handle, bool val)
3808*5113495bSYour Name {
3809*5113495bSYour Name 	wmi_handle->is_qmi_stats_enabled = val;
3810*5113495bSYour Name }
3811*5113495bSYour Name 
wmi_is_qmi_stats_enabled(struct wmi_unified * wmi_handle)3812*5113495bSYour Name bool wmi_is_qmi_stats_enabled(struct wmi_unified *wmi_handle)
3813*5113495bSYour Name {
3814*5113495bSYour Name 	return wmi_handle->is_qmi_stats_enabled;
3815*5113495bSYour Name }
3816*5113495bSYour Name #endif
3817*5113495bSYour Name 
wmi_tag_crash_inject(wmi_unified_t wmi_handle,A_BOOL flag)3818*5113495bSYour Name void wmi_tag_crash_inject(wmi_unified_t wmi_handle, A_BOOL flag)
3819*5113495bSYour Name {
3820*5113495bSYour Name 	wmi_handle->tag_crash_inject = flag;
3821*5113495bSYour Name }
3822*5113495bSYour Name 
wmi_set_is_wow_bus_suspended(wmi_unified_t wmi_handle,A_BOOL val)3823*5113495bSYour Name void wmi_set_is_wow_bus_suspended(wmi_unified_t wmi_handle, A_BOOL val)
3824*5113495bSYour Name {
3825*5113495bSYour Name 	qdf_atomic_set(&wmi_handle->is_wow_bus_suspended, val);
3826*5113495bSYour Name }
3827*5113495bSYour Name 
wmi_set_tgt_assert(wmi_unified_t wmi_handle,bool val)3828*5113495bSYour Name void wmi_set_tgt_assert(wmi_unified_t wmi_handle, bool val)
3829*5113495bSYour Name {
3830*5113495bSYour Name 	wmi_handle->tgt_force_assert_enable = val;
3831*5113495bSYour Name }
3832*5113495bSYour Name 
3833*5113495bSYour Name int
wmi_stop(wmi_unified_t wmi_handle)3834*5113495bSYour Name wmi_stop(wmi_unified_t wmi_handle)
3835*5113495bSYour Name {
3836*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
3837*5113495bSYour Name 		  "WMI Stop");
3838*5113495bSYour Name 	wmi_handle->wmi_stopinprogress = 1;
3839*5113495bSYour Name 	return 0;
3840*5113495bSYour Name }
3841*5113495bSYour Name 
3842*5113495bSYour Name int
wmi_start(wmi_unified_t wmi_handle)3843*5113495bSYour Name wmi_start(wmi_unified_t wmi_handle)
3844*5113495bSYour Name {
3845*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
3846*5113495bSYour Name 		  "WMI Start");
3847*5113495bSYour Name 	wmi_handle->wmi_stopinprogress = 0;
3848*5113495bSYour Name 	return 0;
3849*5113495bSYour Name }
3850*5113495bSYour Name 
3851*5113495bSYour Name bool
wmi_is_blocked(wmi_unified_t wmi_handle)3852*5113495bSYour Name wmi_is_blocked(wmi_unified_t wmi_handle)
3853*5113495bSYour Name {
3854*5113495bSYour Name 	return (!(!wmi_handle->wmi_stopinprogress));
3855*5113495bSYour Name }
3856*5113495bSYour Name 
3857*5113495bSYour Name void
wmi_flush_endpoint(wmi_unified_t wmi_handle)3858*5113495bSYour Name wmi_flush_endpoint(wmi_unified_t wmi_handle)
3859*5113495bSYour Name {
3860*5113495bSYour Name 	htc_flush_endpoint(wmi_handle->htc_handle,
3861*5113495bSYour Name 		wmi_handle->wmi_endpoint_id, 0);
3862*5113495bSYour Name }
3863*5113495bSYour Name qdf_export_symbol(wmi_flush_endpoint);
3864*5113495bSYour Name 
wmi_get_endpoint(wmi_unified_t wmi_handle)3865*5113495bSYour Name HTC_ENDPOINT_ID wmi_get_endpoint(wmi_unified_t wmi_handle)
3866*5113495bSYour Name {
3867*5113495bSYour Name 	return wmi_handle->wmi_endpoint_id;
3868*5113495bSYour Name }
3869*5113495bSYour Name 
wmi_pdev_id_conversion_enable(wmi_unified_t wmi_handle,uint32_t * pdev_id_map,uint8_t size)3870*5113495bSYour Name void wmi_pdev_id_conversion_enable(wmi_unified_t wmi_handle,
3871*5113495bSYour Name 				   uint32_t *pdev_id_map,
3872*5113495bSYour Name 				   uint8_t size)
3873*5113495bSYour Name {
3874*5113495bSYour Name 	if (wmi_handle->target_type == WMI_TLV_TARGET)
3875*5113495bSYour Name 		wmi_handle->ops->wmi_pdev_id_conversion_enable(wmi_handle,
3876*5113495bSYour Name 							       pdev_id_map,
3877*5113495bSYour Name 							       size);
3878*5113495bSYour Name }
3879*5113495bSYour Name 
__wmi_validate_handle(wmi_unified_t wmi_handle,const char * func)3880*5113495bSYour Name int __wmi_validate_handle(wmi_unified_t wmi_handle, const char *func)
3881*5113495bSYour Name {
3882*5113495bSYour Name         if (!wmi_handle) {
3883*5113495bSYour Name                 wmi_err("Invalid WMI handle (via %s)", func);
3884*5113495bSYour Name                 return -EINVAL;
3885*5113495bSYour Name         }
3886*5113495bSYour Name 
3887*5113495bSYour Name         return 0;
3888*5113495bSYour Name }
3889