blob: 558e23478fb35787d594b673e32cab661fa82d18 [file] [log] [blame]
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001/*
Surya Prakash Raajenb9760762020-01-02 20:02:52 +05302 * Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003 *
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08004 * Permission to use, copy, modify, and/or distribute this software for
5 * any purpose with or without fee is hereby granted, provided that the
6 * above copyright notice and this permission notice appear in all
7 * copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16 * PERFORMANCE OF THIS SOFTWARE.
17 */
18
19/*
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080020 * Host WMI unified implementation
21 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080022#include "htc_api.h"
23#include "htc_api.h"
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080024#include "wmi_unified_priv.h"
Amar Singhaldbff0cc2018-06-26 16:45:54 -070025#include "wmi_unified_api.h"
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +053026#include "qdf_module.h"
Jingxiang Ge23c56582019-04-08 20:13:42 +080027#include "qdf_platform.h"
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +053028#ifdef WMI_EXT_DBG
29#include "qdf_list.h"
Karthik Kantamnenicc5c7892019-12-26 12:36:00 +053030#include "qdf_atomic.h"
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +053031#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -080032
Kiran Venkatappa1f27ef32016-11-11 16:49:40 +053033#ifndef WMI_NON_TLV_SUPPORT
34#include "wmi_tlv_helper.h"
35#endif
36
Govind Singh08bd3dc2016-05-12 12:45:51 +053037#include <linux/debugfs.h>
Sandeep Puligilla9304a972019-06-27 20:46:59 -070038#include <target_if.h>
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +053039
Himanshu Agarwal810141a2016-07-19 15:41:51 +053040/* This check for CONFIG_WIN temporary added due to redeclaration compilation
41error in MCL. Error is caused due to inclusion of wmi.h in wmi_unified_api.h
42which gets included here through ol_if_athvar.h. Eventually it is expected that
43wmi.h will be removed from wmi_unified_api.h after cleanup, which will need
44WMI_CMD_HDR to be defined here. */
Himanshu Agarwal810141a2016-07-19 15:41:51 +053045/* Copied from wmi.h */
46#undef MS
47#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
48#undef SM
49#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
50#undef WO
51#define WO(_f) ((_f##_OFFSET) >> 2)
52
53#undef GET_FIELD
Vivek2b109822018-03-22 23:27:21 +053054#define GET_FIELD(_addr, _f) MS(*((uint32_t *)(_addr) + WO(_f)), _f)
Himanshu Agarwal810141a2016-07-19 15:41:51 +053055#undef SET_FIELD
56#define SET_FIELD(_addr, _f, _val) \
Vivek2b109822018-03-22 23:27:21 +053057 (*((uint32_t *)(_addr) + WO(_f)) = \
58 (*((uint32_t *)(_addr) + WO(_f)) & ~_f##_MASK) | SM(_val, _f))
Himanshu Agarwal810141a2016-07-19 15:41:51 +053059
60#define WMI_GET_FIELD(_msg_buf, _msg_type, _f) \
61 GET_FIELD(_msg_buf, _msg_type ## _ ## _f)
62
63#define WMI_SET_FIELD(_msg_buf, _msg_type, _f, _val) \
64 SET_FIELD(_msg_buf, _msg_type ## _ ## _f, _val)
65
66#define WMI_EP_APASS 0x0
67#define WMI_EP_LPASS 0x1
68#define WMI_EP_SENSOR 0x2
69
70/*
71 * * Control Path
72 * */
73typedef PREPACK struct {
Vivek2b109822018-03-22 23:27:21 +053074 uint32_t commandId:24,
Himanshu Agarwal810141a2016-07-19 15:41:51 +053075 reserved:2, /* used for WMI endpoint ID */
76 plt_priv:6; /* platform private */
77} POSTPACK WMI_CMD_HDR; /* used for commands and events */
78
79#define WMI_CMD_HDR_COMMANDID_LSB 0
80#define WMI_CMD_HDR_COMMANDID_MASK 0x00ffffff
81#define WMI_CMD_HDR_COMMANDID_OFFSET 0x00000000
82#define WMI_CMD_HDR_WMI_ENDPOINTID_MASK 0x03000000
83#define WMI_CMD_HDR_WMI_ENDPOINTID_OFFSET 24
84#define WMI_CMD_HDR_PLT_PRIV_LSB 24
85#define WMI_CMD_HDR_PLT_PRIV_MASK 0xff000000
86#define WMI_CMD_HDR_PLT_PRIV_OFFSET 0x00000000
87/* end of copy wmi.h */
Himanshu Agarwal810141a2016-07-19 15:41:51 +053088
Rachit Kankanec50c2282018-02-19 11:28:10 +053089#define WMI_MIN_HEAD_ROOM 64
90
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +053091/* WBUFF pool sizes for WMI */
92/* Allocation of size 256 bytes */
93#define WMI_WBUFF_POOL_0_SIZE 128
94/* Allocation of size 512 bytes */
95#define WMI_WBUFF_POOL_1_SIZE 16
96/* Allocation of size 1024 bytes */
97#define WMI_WBUFF_POOL_2_SIZE 8
98/* Allocation of size 2048 bytes */
99#define WMI_WBUFF_POOL_3_SIZE 8
100
Rachit Kankanec50c2282018-02-19 11:28:10 +0530101#ifdef WMI_INTERFACE_EVENT_LOGGING
Manikandan Mohan83304852016-06-08 16:29:39 -0700102#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0))
103/* TODO Cleanup this backported function */
Pratik Gandhi2c07e442017-05-03 20:15:50 +0530104static int wmi_bp_seq_printf(struct seq_file *m, const char *f, ...)
Manikandan Mohan83304852016-06-08 16:29:39 -0700105{
106 va_list args;
107
108 va_start(args, f);
Pratik Gandhi2c07e442017-05-03 20:15:50 +0530109 seq_vprintf(m, f, args);
Manikandan Mohan83304852016-06-08 16:29:39 -0700110 va_end(args);
111
Pratik Gandhi2c07e442017-05-03 20:15:50 +0530112 return 0;
Manikandan Mohan83304852016-06-08 16:29:39 -0700113}
Pratik Gandhi2c07e442017-05-03 20:15:50 +0530114#else
115#define wmi_bp_seq_printf(m, fmt, ...) seq_printf((m), fmt, ##__VA_ARGS__)
Manikandan Mohan83304852016-06-08 16:29:39 -0700116#endif
117
Govind Singh08bd3dc2016-05-12 12:45:51 +0530118#ifndef MAX_WMI_INSTANCES
Pratik Gandhi381fd122016-09-16 01:32:51 +0530119#define CUSTOM_MGMT_CMD_DATA_SIZE 4
Govind Singh08bd3dc2016-05-12 12:45:51 +0530120#endif
121
Surya Prakash Raajen9d48cd92019-05-10 12:48:39 +0530122#ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800123/* WMI commands */
124uint32_t g_wmi_command_buf_idx = 0;
125struct wmi_command_debug wmi_command_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
126
127/* WMI commands TX completed */
128uint32_t g_wmi_command_tx_cmp_buf_idx = 0;
129struct wmi_command_debug
130 wmi_command_tx_cmp_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
131
132/* WMI events when processed */
133uint32_t g_wmi_event_buf_idx = 0;
134struct wmi_event_debug wmi_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
135
136/* WMI events when queued */
137uint32_t g_wmi_rx_event_buf_idx = 0;
138struct wmi_event_debug wmi_rx_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY];
Pratik Gandhi381fd122016-09-16 01:32:51 +0530139#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800140
Govind Singh08bd3dc2016-05-12 12:45:51 +0530141#define WMI_COMMAND_RECORD(h, a, b) { \
142 if (wmi_log_max_entry <= \
143 *(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)) \
144 *(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx) = 0;\
145 ((struct wmi_command_debug *)h->log_info.wmi_command_log_buf_info.buf)\
146 [*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)]\
147 .command = a; \
148 qdf_mem_copy(((struct wmi_command_debug *)h->log_info. \
149 wmi_command_log_buf_info.buf) \
150 [*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)].data,\
151 b, wmi_record_max_length); \
152 ((struct wmi_command_debug *)h->log_info.wmi_command_log_buf_info.buf)\
153 [*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx)].\
154 time = qdf_get_log_timestamp(); \
155 (*(h->log_info.wmi_command_log_buf_info.p_buf_tail_idx))++; \
156 h->log_info.wmi_command_log_buf_info.length++; \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800157}
158
Govind Singh08bd3dc2016-05-12 12:45:51 +0530159#define WMI_COMMAND_TX_CMP_RECORD(h, a, b) { \
160 if (wmi_log_max_entry <= \
161 *(h->log_info.wmi_command_tx_cmp_log_buf_info.p_buf_tail_idx))\
Pratik Gandhi381fd122016-09-16 01:32:51 +0530162 *(h->log_info.wmi_command_tx_cmp_log_buf_info. \
163 p_buf_tail_idx) = 0; \
Govind Singh08bd3dc2016-05-12 12:45:51 +0530164 ((struct wmi_command_debug *)h->log_info. \
165 wmi_command_tx_cmp_log_buf_info.buf) \
166 [*(h->log_info.wmi_command_tx_cmp_log_buf_info. \
167 p_buf_tail_idx)]. \
168 command = a; \
169 qdf_mem_copy(((struct wmi_command_debug *)h->log_info. \
170 wmi_command_tx_cmp_log_buf_info.buf) \
171 [*(h->log_info.wmi_command_tx_cmp_log_buf_info. \
172 p_buf_tail_idx)]. \
173 data, b, wmi_record_max_length); \
174 ((struct wmi_command_debug *)h->log_info. \
175 wmi_command_tx_cmp_log_buf_info.buf) \
176 [*(h->log_info.wmi_command_tx_cmp_log_buf_info. \
177 p_buf_tail_idx)]. \
178 time = qdf_get_log_timestamp(); \
179 (*(h->log_info.wmi_command_tx_cmp_log_buf_info.p_buf_tail_idx))++;\
180 h->log_info.wmi_command_tx_cmp_log_buf_info.length++; \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800181}
182
Govind Singh08bd3dc2016-05-12 12:45:51 +0530183#define WMI_EVENT_RECORD(h, a, b) { \
184 if (wmi_log_max_entry <= \
185 *(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)) \
186 *(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx) = 0;\
187 ((struct wmi_event_debug *)h->log_info.wmi_event_log_buf_info.buf)\
188 [*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)]. \
189 event = a; \
190 qdf_mem_copy(((struct wmi_event_debug *)h->log_info. \
191 wmi_event_log_buf_info.buf) \
192 [*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)].data, b,\
193 wmi_record_max_length); \
194 ((struct wmi_event_debug *)h->log_info.wmi_event_log_buf_info.buf)\
195 [*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx)].time =\
Govind Singh236fc202016-03-09 14:32:57 +0530196 qdf_get_log_timestamp(); \
Govind Singh08bd3dc2016-05-12 12:45:51 +0530197 (*(h->log_info.wmi_event_log_buf_info.p_buf_tail_idx))++; \
198 h->log_info.wmi_event_log_buf_info.length++; \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800199}
200
Govind Singh08bd3dc2016-05-12 12:45:51 +0530201#define WMI_RX_EVENT_RECORD(h, a, b) { \
202 if (wmi_log_max_entry <= \
203 *(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx))\
204 *(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx) = 0;\
205 ((struct wmi_event_debug *)h->log_info.wmi_rx_event_log_buf_info.buf)\
206 [*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
207 event = a; \
208 qdf_mem_copy(((struct wmi_event_debug *)h->log_info. \
209 wmi_rx_event_log_buf_info.buf) \
210 [*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
211 data, b, wmi_record_max_length); \
212 ((struct wmi_event_debug *)h->log_info.wmi_rx_event_log_buf_info.buf)\
213 [*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx)].\
214 time = qdf_get_log_timestamp(); \
215 (*(h->log_info.wmi_rx_event_log_buf_info.p_buf_tail_idx))++; \
216 h->log_info.wmi_rx_event_log_buf_info.length++; \
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800217}
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800218
Surya Prakash Raajen9d48cd92019-05-10 12:48:39 +0530219#ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800220uint32_t g_wmi_mgmt_command_buf_idx = 0;
221struct
222wmi_command_debug wmi_mgmt_command_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
223
224/* wmi_mgmt commands TX completed */
225uint32_t g_wmi_mgmt_command_tx_cmp_buf_idx = 0;
226struct wmi_command_debug
227wmi_mgmt_command_tx_cmp_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
228
Rajeev Kumar80473702018-09-19 13:02:23 -0700229/* wmi_mgmt events when received */
230uint32_t g_wmi_mgmt_rx_event_buf_idx = 0;
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800231struct wmi_event_debug
Rajeev Kumar80473702018-09-19 13:02:23 -0700232wmi_mgmt_rx_event_log_buffer[WMI_MGMT_EVENT_DEBUG_MAX_ENTRY];
233
234/* wmi_diag events when received */
235uint32_t g_wmi_diag_rx_event_buf_idx = 0;
236struct wmi_event_debug
237wmi_diag_rx_event_log_buffer[WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY];
Pratik Gandhi381fd122016-09-16 01:32:51 +0530238#endif
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800239
Pratik Gandhi381fd122016-09-16 01:32:51 +0530240#define WMI_MGMT_COMMAND_RECORD(h, a, b) { \
241 if (wmi_mgmt_log_max_entry <= \
242 *(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)) \
243 *(h->log_info.wmi_mgmt_command_log_buf_info. \
244 p_buf_tail_idx) = 0; \
245 ((struct wmi_command_debug *)h->log_info. \
246 wmi_mgmt_command_log_buf_info.buf) \
247 [*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
248 command = a; \
249 qdf_mem_copy(((struct wmi_command_debug *)h->log_info. \
250 wmi_mgmt_command_log_buf_info.buf) \
251 [*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
252 data, b, \
253 wmi_record_max_length); \
254 ((struct wmi_command_debug *)h->log_info. \
255 wmi_mgmt_command_log_buf_info.buf) \
256 [*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx)].\
257 time = qdf_get_log_timestamp(); \
258 (*(h->log_info.wmi_mgmt_command_log_buf_info.p_buf_tail_idx))++;\
259 h->log_info.wmi_mgmt_command_log_buf_info.length++; \
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800260}
261
Govind Singh08bd3dc2016-05-12 12:45:51 +0530262#define WMI_MGMT_COMMAND_TX_CMP_RECORD(h, a, b) { \
263 if (wmi_mgmt_log_max_entry <= \
264 *(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
265 p_buf_tail_idx)) \
266 *(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
267 p_buf_tail_idx) = 0; \
268 ((struct wmi_command_debug *)h->log_info. \
269 wmi_mgmt_command_tx_cmp_log_buf_info.buf) \
270 [*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
271 p_buf_tail_idx)].command = a; \
272 qdf_mem_copy(((struct wmi_command_debug *)h->log_info. \
273 wmi_mgmt_command_tx_cmp_log_buf_info.buf)\
274 [*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
275 p_buf_tail_idx)].data, b, \
276 wmi_record_max_length); \
277 ((struct wmi_command_debug *)h->log_info. \
278 wmi_mgmt_command_tx_cmp_log_buf_info.buf) \
279 [*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
280 p_buf_tail_idx)].time = \
281 qdf_get_log_timestamp(); \
282 (*(h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info. \
283 p_buf_tail_idx))++; \
284 h->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.length++; \
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -0800285}
286
Rajeev Kumar80473702018-09-19 13:02:23 -0700287#define WMI_MGMT_RX_EVENT_RECORD(h, a, b) do { \
Govind Singh08bd3dc2016-05-12 12:45:51 +0530288 if (wmi_mgmt_log_max_entry <= \
289 *(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx))\
290 *(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx) = 0;\
291 ((struct wmi_event_debug *)h->log_info.wmi_mgmt_event_log_buf_info.buf)\
292 [*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)]\
293 .event = a; \
294 qdf_mem_copy(((struct wmi_event_debug *)h->log_info. \
295 wmi_mgmt_event_log_buf_info.buf) \
296 [*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)].\
297 data, b, wmi_record_max_length); \
298 ((struct wmi_event_debug *)h->log_info.wmi_mgmt_event_log_buf_info.buf)\
299 [*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx)].\
300 time = qdf_get_log_timestamp(); \
301 (*(h->log_info.wmi_mgmt_event_log_buf_info.p_buf_tail_idx))++; \
302 h->log_info.wmi_mgmt_event_log_buf_info.length++; \
Rajeev Kumar80473702018-09-19 13:02:23 -0700303} while (0);
304
305#define WMI_DIAG_RX_EVENT_RECORD(h, a, b) do { \
Surya Prakash Raajenc59f7dc2019-07-12 11:53:03 +0530306 if (wmi_diag_log_max_entry <= \
Rajeev Kumar80473702018-09-19 13:02:23 -0700307 *(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))\
308 *(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx) = 0;\
309 ((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
310 [*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)]\
311 .event = a; \
312 qdf_mem_copy(((struct wmi_event_debug *)h->log_info. \
313 wmi_diag_event_log_buf_info.buf) \
314 [*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
315 data, b, wmi_record_max_length); \
316 ((struct wmi_event_debug *)h->log_info.wmi_diag_event_log_buf_info.buf)\
317 [*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx)].\
318 time = qdf_get_log_timestamp(); \
319 (*(h->log_info.wmi_diag_event_log_buf_info.p_buf_tail_idx))++; \
320 h->log_info.wmi_diag_event_log_buf_info.length++; \
321} while (0);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -0800322
Govind Singh08bd3dc2016-05-12 12:45:51 +0530323/* These are defined to made it as module param, which can be configured */
324uint32_t wmi_log_max_entry = WMI_EVENT_DEBUG_MAX_ENTRY;
325uint32_t wmi_mgmt_log_max_entry = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
Rajeev Kumar80473702018-09-19 13:02:23 -0700326uint32_t wmi_diag_log_max_entry = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530327uint32_t wmi_record_max_length = WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH;
328uint32_t wmi_display_size = 100;
329
Karthik Kantamnenicc5c7892019-12-26 12:36:00 +0530330#ifdef WMI_EXT_DBG
331
332/**
333 * wmi_ext_dbg_msg_enqueue() - enqueue wmi message
334 *
335 * @wmi_handle: wmi handler
336 *
337 * Return: size of wmi message queue after enqueue
338 */
339static uint32_t wmi_ext_dbg_msg_enqueue(struct wmi_unified *wmi_handle,
340 struct wmi_ext_dbg_msg *msg)
341{
342 uint32_t list_size;
343
344 qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
345 qdf_list_insert_back_size(&wmi_handle->wmi_ext_dbg_msg_queue,
346 &msg->node, &list_size);
347 qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
348
349 return list_size;
350}
351
352/**
353 * wmi_ext_dbg_msg_dequeue() - dequeue wmi message
354 *
355 * @wmi_handle: wmi handler
356 *
357 * Return: wmi msg on success else NULL
358 */
359static struct wmi_ext_dbg_msg *wmi_ext_dbg_msg_dequeue(struct wmi_unified
360 *wmi_handle)
361{
362 qdf_list_node_t *list_node = NULL;
363
364 qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
365 qdf_list_remove_front(&wmi_handle->wmi_ext_dbg_msg_queue, &list_node);
366 qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
367
368 if (!list_node)
369 return NULL;
370
371 return qdf_container_of(list_node, struct wmi_ext_dbg_msg, node);
372}
373
374/**
375 * wmi_ext_dbg_msg_record() - record wmi messages
376 *
377 * @wmi_handle: wmi handler
378 * @buf: wmi message buffer
379 * @len: wmi message length
380 * @type: wmi message type
381 *
382 * Return: QDF_STATUS_SUCCESS on successful recording else failure.
383 */
384static QDF_STATUS wmi_ext_dbg_msg_record(struct wmi_unified *wmi_handle,
385 uint8_t *buf, uint32_t len,
386 enum WMI_MSG_TYPE type)
387{
388 struct wmi_ext_dbg_msg *msg;
389 uint32_t list_size;
390
391 msg = wmi_ext_dbg_msg_get(len);
392 if (!msg)
393 return QDF_STATUS_E_NOMEM;
394
395 msg->len = len;
396 msg->type = type;
397 qdf_mem_copy(msg->buf, buf, len);
398 msg->ts = qdf_get_log_timestamp();
399 list_size = wmi_ext_dbg_msg_enqueue(wmi_handle, msg);
400
401 if (list_size >= wmi_handle->wmi_ext_dbg_msg_queue_size) {
402 msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
403 wmi_ext_dbg_msg_put(msg);
404 }
405
406 return QDF_STATUS_SUCCESS;
407}
408
409/**
410 * wmi_ext_dbg_msg_cmd_record() - record wmi command messages
411 *
412 * @wmi_handle: wmi handler
413 * @buf: wmi command buffer
414 * @len: wmi command message length
415 *
416 * Return: QDF_STATUS_SUCCESS on successful recording else failure.
417 */
418static QDF_STATUS wmi_ext_dbg_msg_cmd_record(struct wmi_unified *wmi_handle,
419 uint8_t *buf, uint32_t len)
420{
421 return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
422 WMI_MSG_TYPE_CMD);
423}
424
425/**
426 * wmi_ext_dbg_msg_event_record() - record wmi event messages
427 *
428 * @wmi_handle: wmi handler
429 * @buf: wmi event buffer
430 * @len: wmi event message length
431 *
432 * Return: QDF_STATUS_SUCCESS on successful recording else failure.
433 */
434static QDF_STATUS wmi_ext_dbg_msg_event_record(struct wmi_unified *wmi_handle,
435 uint8_t *buf, uint32_t len)
436{
437 uint32_t id;
438
439 id = WMI_GET_FIELD(buf, WMI_CMD_HDR, COMMANDID);
440 if (id != wmi_handle->wmi_events[wmi_diag_event_id])
441 return wmi_ext_dbg_msg_record(wmi_handle, buf, len,
442 WMI_MSG_TYPE_EVENT);
443
444 return QDF_STATUS_SUCCESS;
445}
446
447/**
448 * wmi_ext_dbg_msg_queue_init() - create debugfs queue and associated lock
449 *
450 * @wmi_handle: wmi handler
451 *
452 * Return: none
453 */
454static void wmi_ext_dbg_msg_queue_init(struct wmi_unified *wmi_handle)
455{
456 qdf_list_create(&wmi_handle->wmi_ext_dbg_msg_queue,
457 wmi_handle->wmi_ext_dbg_msg_queue_size);
458 qdf_spinlock_create(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
459}
460
461/**
462 * wmi_ext_dbg_msg_queue_deinit() - destroy debugfs queue and associated lock
463 *
464 * @wmi_handle: wmi handler
465 *
466 * Return: none
467 */
468static void wmi_ext_dbg_msg_queue_deinit(struct wmi_unified *wmi_handle)
469{
470 qdf_list_destroy(&wmi_handle->wmi_ext_dbg_msg_queue);
471 qdf_spinlock_destroy(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
472}
473
474/**
475 * wmi_ext_dbg_msg_show() - debugfs function to display whole content of
476 * wmi command/event messages including headers.
477 *
478 * @file: qdf debugfs file handler
479 * @arg: pointer to wmi handler
480 *
481 * Return: QDF_STATUS_SUCCESS if all the messages are shown successfully,
482 * else QDF_STATUS_E_AGAIN if more data to show.
483 */
484static QDF_STATUS wmi_ext_dbg_msg_show(qdf_debugfs_file_t file, void *arg)
485{
486 struct wmi_unified *wmi_handle = (struct wmi_unified *)arg;
487 struct wmi_ext_dbg_msg *msg;
488 uint64_t secs, usecs;
489
490 msg = wmi_ext_dbg_msg_dequeue(wmi_handle);
491 if (!msg)
492 return QDF_STATUS_SUCCESS;
493
494 qdf_debugfs_printf(file, "%s: 0x%x\n",
495 msg->type == WMI_MSG_TYPE_CMD ? "COMMAND" :
496 "EVENT", WMI_GET_FIELD(msg->buf, WMI_CMD_HDR,
497 COMMANDID));
498 qdf_log_timestamp_to_secs(msg->ts, &secs, &usecs);
499 qdf_debugfs_printf(file, "Time: %llu.%llu\n", secs, usecs);
500 qdf_debugfs_printf(file, "Length:%d\n", msg->len);
501 qdf_debugfs_hexdump(file, msg->buf, msg->len,
502 WMI_EXT_DBG_DUMP_ROW_SIZE,
503 WMI_EXT_DBG_DUMP_GROUP_SIZE);
504 qdf_debugfs_printf(file, "\n");
505
506 if (qdf_debugfs_overflow(file)) {
507 qdf_spinlock_acquire(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
508 qdf_list_insert_front(&wmi_handle->wmi_ext_dbg_msg_queue,
509 &msg->node);
510 qdf_spinlock_release(&wmi_handle->wmi_ext_dbg_msg_queue_lock);
511
512 } else {
513 wmi_ext_dbg_msg_put(msg);
514 }
515
516 return QDF_STATUS_E_AGAIN;
517}
518
519/**
520 * wmi_ext_dbg_msg_write() - debugfs write not supported
521 *
522 * @priv: private data
523 * @buf: received data buffer
524 * @len: length of received buffer
525 *
526 * Return: QDF_STATUS_E_NOSUPPORT.
527 */
528static QDF_STATUS wmi_ext_dbg_msg_write(void *priv, const char *buf,
529 qdf_size_t len)
530{
531 return QDF_STATUS_E_NOSUPPORT;
532}
533
534static struct qdf_debugfs_fops wmi_ext_dbgfs_ops = {
535 .show = wmi_ext_dbg_msg_show,
536 .write = wmi_ext_dbg_msg_write,
537 .priv = NULL,
538};
539
540/**
541 * wmi_ext_debugfs_init() - init debugfs items for extended wmi dump.
542 *
543 * @wmi_handle: wmi handler
544 *
545 * Return: QDF_STATUS_SUCCESS if debugfs is initialized else
546 * QDF_STATUS_E_FAILURE
547 */
548static QDF_STATUS wmi_ext_dbgfs_init(struct wmi_unified *wmi_handle)
549{
550 qdf_dentry_t dentry;
551
552 dentry = qdf_debugfs_create_dir(WMI_EXT_DBG_DIR, NULL);
553 if (!dentry) {
554 WMI_LOGE("error while creating extended wmi debugfs dir");
555 return QDF_STATUS_E_FAILURE;
556 }
557
558 wmi_ext_dbgfs_ops.priv = wmi_handle;
559 if (!qdf_debugfs_create_file(WMI_EXT_DBG_FILE, WMI_EXT_DBG_FILE_PERM,
560 dentry, &wmi_ext_dbgfs_ops)) {
561 qdf_debugfs_remove_dir(dentry);
562 WMI_LOGE("error while creating extended wmi debugfs file");
563 return QDF_STATUS_E_FAILURE;
564 }
565
566 wmi_handle->wmi_ext_dbg_dentry = dentry;
567 wmi_handle->wmi_ext_dbg_msg_queue_size = WMI_EXT_DBG_QUEUE_SIZE;
568 wmi_ext_dbg_msg_queue_init(wmi_handle);
569
570 return QDF_STATUS_SUCCESS;
571}
572
573/**
574 * wmi_ext_debugfs_deinit() - cleanup/deinit debugfs items of extended wmi dump.
575 *
576 * @wmi_handle: wmi handler
577 *
578 * Return: QDF_STATUS_SUCCESS if cleanup is successful
579 */
580static QDF_STATUS wmi_ext_dbgfs_deinit(struct wmi_unified *wmi_handle)
581{
582 struct wmi_ext_dbg_msg *msg;
583
584 while ((msg = wmi_ext_dbg_msg_dequeue(wmi_handle)))
585 wmi_ext_dbg_msg_put(msg);
586
587 wmi_ext_dbg_msg_queue_deinit(wmi_handle);
588 qdf_debugfs_remove_dir_recursive(wmi_handle->wmi_ext_dbg_dentry);
589
590 return QDF_STATUS_SUCCESS;
591}
592
593#endif /*WMI_EXT_DBG */
594
Govind Singh08bd3dc2016-05-12 12:45:51 +0530595/**
596 * wmi_log_init() - Initialize WMI event logging
597 * @wmi_handle: WMI handle.
598 *
599 * Return: Initialization status
600 */
Surya Prakash Raajen9d48cd92019-05-10 12:48:39 +0530601#ifndef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
Govind Singh08bd3dc2016-05-12 12:45:51 +0530602static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
603{
604 struct wmi_log_buf_t *cmd_log_buf =
605 &wmi_handle->log_info.wmi_command_log_buf_info;
606 struct wmi_log_buf_t *cmd_tx_cmpl_log_buf =
607 &wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
608
609 struct wmi_log_buf_t *event_log_buf =
610 &wmi_handle->log_info.wmi_event_log_buf_info;
611 struct wmi_log_buf_t *rx_event_log_buf =
612 &wmi_handle->log_info.wmi_rx_event_log_buf_info;
613
614 struct wmi_log_buf_t *mgmt_cmd_log_buf =
615 &wmi_handle->log_info.wmi_mgmt_command_log_buf_info;
616 struct wmi_log_buf_t *mgmt_cmd_tx_cmp_log_buf =
617 &wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
618 struct wmi_log_buf_t *mgmt_event_log_buf =
619 &wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
Rajeev Kumar80473702018-09-19 13:02:23 -0700620 struct wmi_log_buf_t *diag_event_log_buf =
621 &wmi_handle->log_info.wmi_diag_event_log_buf_info;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530622
623 /* WMI commands */
624 cmd_log_buf->length = 0;
625 cmd_log_buf->buf_tail_idx = 0;
626 cmd_log_buf->buf = wmi_command_log_buffer;
627 cmd_log_buf->p_buf_tail_idx = &g_wmi_command_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700628 cmd_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530629
630 /* WMI commands TX completed */
631 cmd_tx_cmpl_log_buf->length = 0;
632 cmd_tx_cmpl_log_buf->buf_tail_idx = 0;
633 cmd_tx_cmpl_log_buf->buf = wmi_command_tx_cmp_log_buffer;
634 cmd_tx_cmpl_log_buf->p_buf_tail_idx = &g_wmi_command_tx_cmp_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700635 cmd_tx_cmpl_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530636
637 /* WMI events when processed */
638 event_log_buf->length = 0;
639 event_log_buf->buf_tail_idx = 0;
640 event_log_buf->buf = wmi_event_log_buffer;
641 event_log_buf->p_buf_tail_idx = &g_wmi_event_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700642 event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530643
644 /* WMI events when queued */
645 rx_event_log_buf->length = 0;
646 rx_event_log_buf->buf_tail_idx = 0;
647 rx_event_log_buf->buf = wmi_rx_event_log_buffer;
648 rx_event_log_buf->p_buf_tail_idx = &g_wmi_rx_event_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700649 rx_event_log_buf->size = WMI_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530650
651 /* WMI Management commands */
652 mgmt_cmd_log_buf->length = 0;
653 mgmt_cmd_log_buf->buf_tail_idx = 0;
654 mgmt_cmd_log_buf->buf = wmi_mgmt_command_log_buffer;
655 mgmt_cmd_log_buf->p_buf_tail_idx = &g_wmi_mgmt_command_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700656 mgmt_cmd_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530657
658 /* WMI Management commands Tx completed*/
659 mgmt_cmd_tx_cmp_log_buf->length = 0;
660 mgmt_cmd_tx_cmp_log_buf->buf_tail_idx = 0;
661 mgmt_cmd_tx_cmp_log_buf->buf = wmi_mgmt_command_tx_cmp_log_buffer;
662 mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx =
663 &g_wmi_mgmt_command_tx_cmp_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700664 mgmt_cmd_tx_cmp_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530665
Rajeev Kumar80473702018-09-19 13:02:23 -0700666 /* WMI Management events when received */
Govind Singh08bd3dc2016-05-12 12:45:51 +0530667 mgmt_event_log_buf->length = 0;
668 mgmt_event_log_buf->buf_tail_idx = 0;
Rajeev Kumar80473702018-09-19 13:02:23 -0700669 mgmt_event_log_buf->buf = wmi_mgmt_rx_event_log_buffer;
670 mgmt_event_log_buf->p_buf_tail_idx = &g_wmi_mgmt_rx_event_buf_idx;
Dustin Brown536064a2017-04-03 17:00:07 -0700671 mgmt_event_log_buf->size = WMI_MGMT_EVENT_DEBUG_MAX_ENTRY;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530672
Rajeev Kumar80473702018-09-19 13:02:23 -0700673 /* WMI diag events when received */
674 diag_event_log_buf->length = 0;
675 diag_event_log_buf->buf_tail_idx = 0;
676 diag_event_log_buf->buf = wmi_diag_rx_event_log_buffer;
677 diag_event_log_buf->p_buf_tail_idx = &g_wmi_diag_rx_event_buf_idx;
678 diag_event_log_buf->size = WMI_DIAG_RX_EVENT_DEBUG_MAX_ENTRY;
679
Govind Singh08bd3dc2016-05-12 12:45:51 +0530680 qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
681 wmi_handle->log_info.wmi_logging_enable = 1;
682
683 return QDF_STATUS_SUCCESS;
684}
685#else
686static QDF_STATUS wmi_log_init(struct wmi_unified *wmi_handle)
687{
688 struct wmi_log_buf_t *cmd_log_buf =
689 &wmi_handle->log_info.wmi_command_log_buf_info;
690 struct wmi_log_buf_t *cmd_tx_cmpl_log_buf =
691 &wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info;
692
693 struct wmi_log_buf_t *event_log_buf =
694 &wmi_handle->log_info.wmi_event_log_buf_info;
695 struct wmi_log_buf_t *rx_event_log_buf =
696 &wmi_handle->log_info.wmi_rx_event_log_buf_info;
697
698 struct wmi_log_buf_t *mgmt_cmd_log_buf =
699 &wmi_handle->log_info.wmi_mgmt_command_log_buf_info;
700 struct wmi_log_buf_t *mgmt_cmd_tx_cmp_log_buf =
701 &wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info;
702 struct wmi_log_buf_t *mgmt_event_log_buf =
703 &wmi_handle->log_info.wmi_mgmt_event_log_buf_info;
Rajeev Kumar80473702018-09-19 13:02:23 -0700704 struct wmi_log_buf_t *diag_event_log_buf =
705 &wmi_handle->log_info.wmi_diag_event_log_buf_info;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530706
707 wmi_handle->log_info.wmi_logging_enable = 0;
708
709 /* WMI commands */
710 cmd_log_buf->length = 0;
711 cmd_log_buf->buf_tail_idx = 0;
712 cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc(
713 wmi_log_max_entry * sizeof(struct wmi_command_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700714 cmd_log_buf->size = wmi_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530715
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530716 if (!cmd_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530717 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530718
Govind Singh08bd3dc2016-05-12 12:45:51 +0530719 cmd_log_buf->p_buf_tail_idx = &cmd_log_buf->buf_tail_idx;
720
721 /* WMI commands TX completed */
722 cmd_tx_cmpl_log_buf->length = 0;
723 cmd_tx_cmpl_log_buf->buf_tail_idx = 0;
724 cmd_tx_cmpl_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc(
725 wmi_log_max_entry * sizeof(struct wmi_command_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700726 cmd_tx_cmpl_log_buf->size = wmi_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530727
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530728 if (!cmd_tx_cmpl_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530729 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530730
Govind Singh08bd3dc2016-05-12 12:45:51 +0530731 cmd_tx_cmpl_log_buf->p_buf_tail_idx =
732 &cmd_tx_cmpl_log_buf->buf_tail_idx;
733
734 /* WMI events when processed */
735 event_log_buf->length = 0;
736 event_log_buf->buf_tail_idx = 0;
737 event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
738 wmi_log_max_entry * sizeof(struct wmi_event_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700739 event_log_buf->size = wmi_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530740
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530741 if (!event_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530742 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530743
Govind Singh08bd3dc2016-05-12 12:45:51 +0530744 event_log_buf->p_buf_tail_idx = &event_log_buf->buf_tail_idx;
745
746 /* WMI events when queued */
747 rx_event_log_buf->length = 0;
748 rx_event_log_buf->buf_tail_idx = 0;
749 rx_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
750 wmi_log_max_entry * sizeof(struct wmi_event_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700751 rx_event_log_buf->size = wmi_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530752
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530753 if (!rx_event_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530754 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530755
Govind Singh08bd3dc2016-05-12 12:45:51 +0530756 rx_event_log_buf->p_buf_tail_idx = &rx_event_log_buf->buf_tail_idx;
757
758 /* WMI Management commands */
759 mgmt_cmd_log_buf->length = 0;
760 mgmt_cmd_log_buf->buf_tail_idx = 0;
761 mgmt_cmd_log_buf->buf = (struct wmi_command_debug *) qdf_mem_malloc(
Dustin Brown536064a2017-04-03 17:00:07 -0700762 wmi_mgmt_log_max_entry * sizeof(struct wmi_command_debug));
763 mgmt_cmd_log_buf->size = wmi_mgmt_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530764
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530765 if (!mgmt_cmd_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530766 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530767
Govind Singh08bd3dc2016-05-12 12:45:51 +0530768 mgmt_cmd_log_buf->p_buf_tail_idx = &mgmt_cmd_log_buf->buf_tail_idx;
769
770 /* WMI Management commands Tx completed*/
771 mgmt_cmd_tx_cmp_log_buf->length = 0;
772 mgmt_cmd_tx_cmp_log_buf->buf_tail_idx = 0;
773 mgmt_cmd_tx_cmp_log_buf->buf = (struct wmi_command_debug *)
774 qdf_mem_malloc(
775 wmi_mgmt_log_max_entry *
776 sizeof(struct wmi_command_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700777 mgmt_cmd_tx_cmp_log_buf->size = wmi_mgmt_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530778
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530779 if (!mgmt_cmd_tx_cmp_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530780 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530781
Govind Singh08bd3dc2016-05-12 12:45:51 +0530782 mgmt_cmd_tx_cmp_log_buf->p_buf_tail_idx =
783 &mgmt_cmd_tx_cmp_log_buf->buf_tail_idx;
784
Rajeev Kumar80473702018-09-19 13:02:23 -0700785 /* WMI Management events when received */
Govind Singh08bd3dc2016-05-12 12:45:51 +0530786 mgmt_event_log_buf->length = 0;
787 mgmt_event_log_buf->buf_tail_idx = 0;
788
789 mgmt_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
790 wmi_mgmt_log_max_entry *
791 sizeof(struct wmi_event_debug));
Dustin Brown536064a2017-04-03 17:00:07 -0700792 mgmt_event_log_buf->size = wmi_mgmt_log_max_entry;
Govind Singh08bd3dc2016-05-12 12:45:51 +0530793
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530794 if (!mgmt_event_log_buf->buf)
Govind Singh08bd3dc2016-05-12 12:45:51 +0530795 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530796
Govind Singh08bd3dc2016-05-12 12:45:51 +0530797 mgmt_event_log_buf->p_buf_tail_idx = &mgmt_event_log_buf->buf_tail_idx;
798
Rajeev Kumar80473702018-09-19 13:02:23 -0700799 /* WMI diag events when received */
800 diag_event_log_buf->length = 0;
801 diag_event_log_buf->buf_tail_idx = 0;
802
803 diag_event_log_buf->buf = (struct wmi_event_debug *) qdf_mem_malloc(
804 wmi_diag_log_max_entry *
805 sizeof(struct wmi_event_debug));
806 diag_event_log_buf->size = wmi_diag_log_max_entry;
807
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530808 if (!diag_event_log_buf->buf)
Rajeev Kumar80473702018-09-19 13:02:23 -0700809 return QDF_STATUS_E_NOMEM;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +0530810
Rajeev Kumar80473702018-09-19 13:02:23 -0700811 diag_event_log_buf->p_buf_tail_idx = &diag_event_log_buf->buf_tail_idx;
812
Govind Singh08bd3dc2016-05-12 12:45:51 +0530813 qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
814 wmi_handle->log_info.wmi_logging_enable = 1;
815
816 return QDF_STATUS_SUCCESS;
817}
818#endif
819
820/**
821 * wmi_log_buffer_free() - Free all dynamic allocated buffer memory for
822 * event logging
823 * @wmi_handle: WMI handle.
824 *
825 * Return: None
826 */
Surya Prakash Raajen9d48cd92019-05-10 12:48:39 +0530827#ifdef WMI_INTERFACE_EVENT_LOGGING_DYNAMIC_ALLOC
Govind Singh08bd3dc2016-05-12 12:45:51 +0530828static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
829{
830 if (wmi_handle->log_info.wmi_command_log_buf_info.buf)
831 qdf_mem_free(wmi_handle->log_info.wmi_command_log_buf_info.buf);
832 if (wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info.buf)
833 qdf_mem_free(
834 wmi_handle->log_info.wmi_command_tx_cmp_log_buf_info.buf);
835 if (wmi_handle->log_info.wmi_event_log_buf_info.buf)
836 qdf_mem_free(wmi_handle->log_info.wmi_event_log_buf_info.buf);
837 if (wmi_handle->log_info.wmi_rx_event_log_buf_info.buf)
838 qdf_mem_free(
839 wmi_handle->log_info.wmi_rx_event_log_buf_info.buf);
840 if (wmi_handle->log_info.wmi_mgmt_command_log_buf_info.buf)
841 qdf_mem_free(
842 wmi_handle->log_info.wmi_mgmt_command_log_buf_info.buf);
843 if (wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.buf)
844 qdf_mem_free(
845 wmi_handle->log_info.wmi_mgmt_command_tx_cmp_log_buf_info.buf);
846 if (wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf)
847 qdf_mem_free(
848 wmi_handle->log_info.wmi_mgmt_event_log_buf_info.buf);
Rajeev Kumar80473702018-09-19 13:02:23 -0700849 if (wmi_handle->log_info.wmi_diag_event_log_buf_info.buf)
850 qdf_mem_free(
851 wmi_handle->log_info.wmi_diag_event_log_buf_info.buf);
Govind Singh08bd3dc2016-05-12 12:45:51 +0530852 wmi_handle->log_info.wmi_logging_enable = 0;
853 qdf_spinlock_destroy(&wmi_handle->log_info.wmi_record_lock);
854}
855#else
856static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle)
857{
858 /* Do Nothing */
859}
860#endif
861
Dustin Brown536064a2017-04-03 17:00:07 -0700862/**
863 * wmi_print_cmd_log_buffer() - an output agnostic wmi command log printer
864 * @log_buffer: the command log buffer metadata of the buffer to print
865 * @count: the maximum number of entries to print
866 * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper
867 * @print_priv: any data required by the print method, e.g. a file handle
868 *
869 * Return: None
870 */
871static void
872wmi_print_cmd_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count,
873 qdf_abstract_print *print, void *print_priv)
874{
875 static const int data_len =
876 WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t);
877 char str[128];
878 uint32_t idx;
879
880 if (count > log_buffer->size)
881 count = log_buffer->size;
882 if (count > log_buffer->length)
883 count = log_buffer->length;
884
885 /* subtract count from index, and wrap if necessary */
886 idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count;
887 idx %= log_buffer->size;
888
889 print(print_priv, "Time (seconds) Cmd Id Payload");
890 while (count) {
891 struct wmi_command_debug *cmd_log = (struct wmi_command_debug *)
892 &((struct wmi_command_debug *)log_buffer->buf)[idx];
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700893 uint64_t secs, usecs;
Dustin Brown536064a2017-04-03 17:00:07 -0700894 int len = 0;
895 int i;
896
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700897 qdf_log_timestamp_to_secs(cmd_log->time, &secs, &usecs);
Dustin Brown536064a2017-04-03 17:00:07 -0700898 len += scnprintf(str + len, sizeof(str) - len,
899 "% 8lld.%06lld %6u (0x%06x) ",
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700900 secs, usecs,
Dustin Brown536064a2017-04-03 17:00:07 -0700901 cmd_log->command, cmd_log->command);
902 for (i = 0; i < data_len; ++i) {
903 len += scnprintf(str + len, sizeof(str) - len,
904 "0x%08x ", cmd_log->data[i]);
905 }
906
907 print(print_priv, str);
908
909 --count;
910 ++idx;
911 if (idx >= log_buffer->size)
912 idx = 0;
913 }
914}
915
916/**
917 * wmi_print_event_log_buffer() - an output agnostic wmi event log printer
918 * @log_buffer: the event log buffer metadata of the buffer to print
919 * @count: the maximum number of entries to print
920 * @print: an abstract print method, e.g. a qdf_print() or seq_printf() wrapper
921 * @print_priv: any data required by the print method, e.g. a file handle
922 *
923 * Return: None
924 */
925static void
926wmi_print_event_log_buffer(struct wmi_log_buf_t *log_buffer, uint32_t count,
927 qdf_abstract_print *print, void *print_priv)
928{
929 static const int data_len =
930 WMI_EVENT_DEBUG_ENTRY_MAX_LENGTH / sizeof(uint32_t);
931 char str[128];
932 uint32_t idx;
933
934 if (count > log_buffer->size)
935 count = log_buffer->size;
936 if (count > log_buffer->length)
937 count = log_buffer->length;
938
939 /* subtract count from index, and wrap if necessary */
940 idx = log_buffer->size + *log_buffer->p_buf_tail_idx - count;
941 idx %= log_buffer->size;
942
943 print(print_priv, "Time (seconds) Event Id Payload");
944 while (count) {
945 struct wmi_event_debug *event_log = (struct wmi_event_debug *)
946 &((struct wmi_event_debug *)log_buffer->buf)[idx];
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700947 uint64_t secs, usecs;
Dustin Brown536064a2017-04-03 17:00:07 -0700948 int len = 0;
949 int i;
950
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700951 qdf_log_timestamp_to_secs(event_log->time, &secs, &usecs);
Dustin Brown536064a2017-04-03 17:00:07 -0700952 len += scnprintf(str + len, sizeof(str) - len,
953 "% 8lld.%06lld %6u (0x%06x) ",
Dustin Brown6cb0fa12017-04-10 13:26:56 -0700954 secs, usecs,
Dustin Brown536064a2017-04-03 17:00:07 -0700955 event_log->event, event_log->event);
956 for (i = 0; i < data_len; ++i) {
957 len += scnprintf(str + len, sizeof(str) - len,
958 "0x%08x ", event_log->data[i]);
959 }
960
961 print(print_priv, str);
962
963 --count;
964 ++idx;
965 if (idx >= log_buffer->size)
966 idx = 0;
967 }
968}
969
970inline void
971wmi_print_cmd_log(wmi_unified_t wmi, uint32_t count,
972 qdf_abstract_print *print, void *print_priv)
973{
974 wmi_print_cmd_log_buffer(
975 &wmi->log_info.wmi_command_log_buf_info,
976 count, print, print_priv);
977}
978
979inline void
980wmi_print_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count,
981 qdf_abstract_print *print, void *print_priv)
982{
983 wmi_print_cmd_log_buffer(
984 &wmi->log_info.wmi_command_tx_cmp_log_buf_info,
985 count, print, print_priv);
986}
987
988inline void
989wmi_print_mgmt_cmd_log(wmi_unified_t wmi, uint32_t count,
990 qdf_abstract_print *print, void *print_priv)
991{
992 wmi_print_cmd_log_buffer(
993 &wmi->log_info.wmi_mgmt_command_log_buf_info,
994 count, print, print_priv);
995}
996
997inline void
998wmi_print_mgmt_cmd_tx_cmp_log(wmi_unified_t wmi, uint32_t count,
999 qdf_abstract_print *print, void *print_priv)
1000{
1001 wmi_print_cmd_log_buffer(
1002 &wmi->log_info.wmi_mgmt_command_tx_cmp_log_buf_info,
1003 count, print, print_priv);
1004}
1005
1006inline void
1007wmi_print_event_log(wmi_unified_t wmi, uint32_t count,
1008 qdf_abstract_print *print, void *print_priv)
1009{
1010 wmi_print_event_log_buffer(
1011 &wmi->log_info.wmi_event_log_buf_info,
1012 count, print, print_priv);
1013}
1014
1015inline void
1016wmi_print_rx_event_log(wmi_unified_t wmi, uint32_t count,
1017 qdf_abstract_print *print, void *print_priv)
1018{
1019 wmi_print_event_log_buffer(
1020 &wmi->log_info.wmi_rx_event_log_buf_info,
1021 count, print, print_priv);
1022}
1023
1024inline void
1025wmi_print_mgmt_event_log(wmi_unified_t wmi, uint32_t count,
1026 qdf_abstract_print *print, void *print_priv)
1027{
1028 wmi_print_event_log_buffer(
1029 &wmi->log_info.wmi_mgmt_event_log_buf_info,
1030 count, print, print_priv);
1031}
1032
Govind Singh08bd3dc2016-05-12 12:45:51 +05301033
1034/* debugfs routines*/
1035
1036/**
1037 * debug_wmi_##func_base##_show() - debugfs functions to display content of
1038 * command and event buffers. Macro uses max buffer length to display
1039 * buffer when it is wraparound.
1040 *
1041 * @m: debugfs handler to access wmi_handle
1042 * @v: Variable arguments (not used)
1043 *
1044 * Return: Length of characters printed
1045 */
1046#define GENERATE_COMMAND_DEBUG_SHOW_FUNCS(func_base, wmi_ring_size) \
1047 static int debug_wmi_##func_base##_show(struct seq_file *m, \
1048 void *v) \
1049 { \
1050 wmi_unified_t wmi_handle = (wmi_unified_t) m->private; \
1051 struct wmi_log_buf_t *wmi_log = \
1052 &wmi_handle->log_info.wmi_##func_base##_buf_info;\
1053 int pos, nread, outlen; \
1054 int i; \
nobelj53193342017-12-11 23:18:27 -08001055 uint64_t secs, usecs; \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301056 \
Uraj Sasan485478a2019-05-21 19:24:06 +05301057 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
Pratik Gandhi381fd122016-09-16 01:32:51 +05301058 if (!wmi_log->length) { \
Uraj Sasan485478a2019-05-21 19:24:06 +05301059 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301060 return wmi_bp_seq_printf(m, \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301061 "no elements to read from ring buffer!\n"); \
Pratik Gandhi381fd122016-09-16 01:32:51 +05301062 } \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301063 \
1064 if (wmi_log->length <= wmi_ring_size) \
1065 nread = wmi_log->length; \
1066 else \
1067 nread = wmi_ring_size; \
1068 \
1069 if (*(wmi_log->p_buf_tail_idx) == 0) \
1070 /* tail can be 0 after wrap-around */ \
1071 pos = wmi_ring_size - 1; \
1072 else \
1073 pos = *(wmi_log->p_buf_tail_idx) - 1; \
1074 \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301075 outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
Uraj Sasan485478a2019-05-21 19:24:06 +05301076 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301077 while (nread--) { \
1078 struct wmi_command_debug *wmi_record; \
1079 \
1080 wmi_record = (struct wmi_command_debug *) \
1081 &(((struct wmi_command_debug *)wmi_log->buf)[pos]);\
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301082 outlen += wmi_bp_seq_printf(m, "CMD ID = %x\n", \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301083 (wmi_record->command)); \
nobelj53193342017-12-11 23:18:27 -08001084 qdf_log_timestamp_to_secs(wmi_record->time, &secs,\
1085 &usecs); \
1086 outlen += \
1087 wmi_bp_seq_printf(m, "CMD TIME = [%llu.%06llu]\n",\
1088 secs, usecs); \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301089 outlen += wmi_bp_seq_printf(m, "CMD = "); \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301090 for (i = 0; i < (wmi_record_max_length/ \
1091 sizeof(uint32_t)); i++) \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301092 outlen += wmi_bp_seq_printf(m, "%x ", \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301093 wmi_record->data[i]); \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301094 outlen += wmi_bp_seq_printf(m, "\n"); \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301095 \
1096 if (pos == 0) \
1097 pos = wmi_ring_size - 1; \
1098 else \
1099 pos--; \
1100 } \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301101 return outlen; \
1102 } \
1103
1104#define GENERATE_EVENT_DEBUG_SHOW_FUNCS(func_base, wmi_ring_size) \
1105 static int debug_wmi_##func_base##_show(struct seq_file *m, \
1106 void *v) \
1107 { \
1108 wmi_unified_t wmi_handle = (wmi_unified_t) m->private; \
1109 struct wmi_log_buf_t *wmi_log = \
1110 &wmi_handle->log_info.wmi_##func_base##_buf_info;\
1111 int pos, nread, outlen; \
1112 int i; \
nobelj53193342017-12-11 23:18:27 -08001113 uint64_t secs, usecs; \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301114 \
Uraj Sasan485478a2019-05-21 19:24:06 +05301115 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
Pratik Gandhi381fd122016-09-16 01:32:51 +05301116 if (!wmi_log->length) { \
Uraj Sasan485478a2019-05-21 19:24:06 +05301117 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301118 return wmi_bp_seq_printf(m, \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301119 "no elements to read from ring buffer!\n"); \
Pratik Gandhi381fd122016-09-16 01:32:51 +05301120 } \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301121 \
1122 if (wmi_log->length <= wmi_ring_size) \
1123 nread = wmi_log->length; \
1124 else \
1125 nread = wmi_ring_size; \
1126 \
1127 if (*(wmi_log->p_buf_tail_idx) == 0) \
1128 /* tail can be 0 after wrap-around */ \
1129 pos = wmi_ring_size - 1; \
1130 else \
1131 pos = *(wmi_log->p_buf_tail_idx) - 1; \
1132 \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301133 outlen = wmi_bp_seq_printf(m, "Length = %d\n", wmi_log->length);\
Uraj Sasan485478a2019-05-21 19:24:06 +05301134 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301135 while (nread--) { \
1136 struct wmi_event_debug *wmi_record; \
1137 \
1138 wmi_record = (struct wmi_event_debug *) \
1139 &(((struct wmi_event_debug *)wmi_log->buf)[pos]);\
nobelj53193342017-12-11 23:18:27 -08001140 qdf_log_timestamp_to_secs(wmi_record->time, &secs,\
1141 &usecs); \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301142 outlen += wmi_bp_seq_printf(m, "Event ID = %x\n",\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301143 (wmi_record->event)); \
nobelj53193342017-12-11 23:18:27 -08001144 outlen += \
1145 wmi_bp_seq_printf(m, "Event TIME = [%llu.%06llu]\n",\
1146 secs, usecs); \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301147 outlen += wmi_bp_seq_printf(m, "CMD = "); \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301148 for (i = 0; i < (wmi_record_max_length/ \
1149 sizeof(uint32_t)); i++) \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301150 outlen += wmi_bp_seq_printf(m, "%x ", \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301151 wmi_record->data[i]); \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301152 outlen += wmi_bp_seq_printf(m, "\n"); \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301153 \
1154 if (pos == 0) \
1155 pos = wmi_ring_size - 1; \
1156 else \
1157 pos--; \
1158 } \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301159 return outlen; \
1160 }
1161
1162GENERATE_COMMAND_DEBUG_SHOW_FUNCS(command_log, wmi_display_size);
1163GENERATE_COMMAND_DEBUG_SHOW_FUNCS(command_tx_cmp_log, wmi_display_size);
1164GENERATE_EVENT_DEBUG_SHOW_FUNCS(event_log, wmi_display_size);
1165GENERATE_EVENT_DEBUG_SHOW_FUNCS(rx_event_log, wmi_display_size);
1166GENERATE_COMMAND_DEBUG_SHOW_FUNCS(mgmt_command_log, wmi_display_size);
1167GENERATE_COMMAND_DEBUG_SHOW_FUNCS(mgmt_command_tx_cmp_log,
1168 wmi_display_size);
1169GENERATE_EVENT_DEBUG_SHOW_FUNCS(mgmt_event_log, wmi_display_size);
1170
1171/**
1172 * debug_wmi_enable_show() - debugfs functions to display enable state of
1173 * wmi logging feature.
1174 *
1175 * @m: debugfs handler to access wmi_handle
1176 * @v: Variable arguments (not used)
1177 *
1178 * Return: always 1
1179 */
1180static int debug_wmi_enable_show(struct seq_file *m, void *v)
1181{
1182 wmi_unified_t wmi_handle = (wmi_unified_t) m->private;
1183
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301184 return wmi_bp_seq_printf(m, "%d\n",
1185 wmi_handle->log_info.wmi_logging_enable);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301186}
1187
1188/**
1189 * debug_wmi_log_size_show() - debugfs functions to display configured size of
1190 * wmi logging command/event buffer and management command/event buffer.
1191 *
1192 * @m: debugfs handler to access wmi_handle
1193 * @v: Variable arguments (not used)
1194 *
1195 * Return: Length of characters printed
1196 */
1197static int debug_wmi_log_size_show(struct seq_file *m, void *v)
1198{
1199
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301200 wmi_bp_seq_printf(m, "WMI command/event log max size:%d\n",
1201 wmi_log_max_entry);
1202 return wmi_bp_seq_printf(m,
1203 "WMI management command/events log max size:%d\n",
1204 wmi_mgmt_log_max_entry);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301205}
1206
1207/**
1208 * debug_wmi_##func_base##_write() - debugfs functions to clear
1209 * wmi logging command/event buffer and management command/event buffer.
1210 *
1211 * @file: file handler to access wmi_handle
1212 * @buf: received data buffer
1213 * @count: length of received buffer
1214 * @ppos: Not used
1215 *
1216 * Return: count
1217 */
1218#define GENERATE_DEBUG_WRITE_FUNCS(func_base, wmi_ring_size, wmi_record_type)\
1219 static ssize_t debug_wmi_##func_base##_write(struct file *file, \
1220 const char __user *buf, \
1221 size_t count, loff_t *ppos) \
1222 { \
1223 int k, ret; \
Pratik Gandhi6d2e13b2017-01-16 12:50:27 +05301224 wmi_unified_t wmi_handle = \
1225 ((struct seq_file *)file->private_data)->private;\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301226 struct wmi_log_buf_t *wmi_log = &wmi_handle->log_info. \
1227 wmi_##func_base##_buf_info; \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301228 char locbuf[50]; \
Govind Singh08bd3dc2016-05-12 12:45:51 +05301229 \
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301230 if ((!buf) || (count > 50)) \
1231 return -EFAULT; \
1232 \
1233 if (copy_from_user(locbuf, buf, count)) \
1234 return -EFAULT; \
1235 \
1236 ret = sscanf(locbuf, "%d", &k); \
1237 if ((ret != 1) || (k != 0)) { \
Sathish Kumar4c46c872018-09-20 16:07:20 +05301238 WMI_LOGE("Wrong input, echo 0 to clear the wmi buffer");\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301239 return -EINVAL; \
1240 } \
1241 \
Uraj Sasan485478a2019-05-21 19:24:06 +05301242 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301243 qdf_mem_zero(wmi_log->buf, wmi_ring_size * \
1244 sizeof(struct wmi_record_type)); \
1245 wmi_log->length = 0; \
1246 *(wmi_log->p_buf_tail_idx) = 0; \
Uraj Sasan485478a2019-05-21 19:24:06 +05301247 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);\
Govind Singh08bd3dc2016-05-12 12:45:51 +05301248 \
1249 return count; \
1250 }
1251
1252GENERATE_DEBUG_WRITE_FUNCS(command_log, wmi_log_max_entry,
1253 wmi_command_debug);
1254GENERATE_DEBUG_WRITE_FUNCS(command_tx_cmp_log, wmi_log_max_entry,
1255 wmi_command_debug);
1256GENERATE_DEBUG_WRITE_FUNCS(event_log, wmi_log_max_entry,
1257 wmi_event_debug);
1258GENERATE_DEBUG_WRITE_FUNCS(rx_event_log, wmi_log_max_entry,
1259 wmi_event_debug);
1260GENERATE_DEBUG_WRITE_FUNCS(mgmt_command_log, wmi_mgmt_log_max_entry,
1261 wmi_command_debug);
1262GENERATE_DEBUG_WRITE_FUNCS(mgmt_command_tx_cmp_log,
1263 wmi_mgmt_log_max_entry, wmi_command_debug);
1264GENERATE_DEBUG_WRITE_FUNCS(mgmt_event_log, wmi_mgmt_log_max_entry,
1265 wmi_event_debug);
1266
1267/**
1268 * debug_wmi_enable_write() - debugfs functions to enable/disable
1269 * wmi logging feature.
1270 *
1271 * @file: file handler to access wmi_handle
1272 * @buf: received data buffer
1273 * @count: length of received buffer
1274 * @ppos: Not used
1275 *
1276 * Return: count
1277 */
1278static ssize_t debug_wmi_enable_write(struct file *file, const char __user *buf,
1279 size_t count, loff_t *ppos)
1280{
Pratik Gandhi6d2e13b2017-01-16 12:50:27 +05301281 wmi_unified_t wmi_handle =
1282 ((struct seq_file *)file->private_data)->private;
Govind Singh08bd3dc2016-05-12 12:45:51 +05301283 int k, ret;
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301284 char locbuf[50];
Govind Singh08bd3dc2016-05-12 12:45:51 +05301285
Pratik Gandhi2c07e442017-05-03 20:15:50 +05301286 if ((!buf) || (count > 50))
1287 return -EFAULT;
1288
1289 if (copy_from_user(locbuf, buf, count))
1290 return -EFAULT;
1291
1292 ret = sscanf(locbuf, "%d", &k);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301293 if ((ret != 1) || ((k != 0) && (k != 1)))
1294 return -EINVAL;
1295
1296 wmi_handle->log_info.wmi_logging_enable = k;
1297 return count;
1298}
1299
1300/**
1301 * debug_wmi_log_size_write() - reserved.
1302 *
1303 * @file: file handler to access wmi_handle
1304 * @buf: received data buffer
1305 * @count: length of received buffer
1306 * @ppos: Not used
1307 *
1308 * Return: count
1309 */
1310static ssize_t debug_wmi_log_size_write(struct file *file,
1311 const char __user *buf, size_t count, loff_t *ppos)
1312{
1313 return -EINVAL;
1314}
1315
1316/* Structure to maintain debug information */
1317struct wmi_debugfs_info {
1318 const char *name;
Govind Singh08bd3dc2016-05-12 12:45:51 +05301319 const struct file_operations *ops;
1320};
1321
1322#define DEBUG_FOO(func_base) { .name = #func_base, \
1323 .ops = &debug_##func_base##_ops }
1324
1325/**
1326 * debug_##func_base##_open() - Open debugfs entry for respective command
1327 * and event buffer.
1328 *
1329 * @inode: node for debug dir entry
1330 * @file: file handler
1331 *
1332 * Return: open status
1333 */
1334#define GENERATE_DEBUG_STRUCTS(func_base) \
1335 static int debug_##func_base##_open(struct inode *inode, \
1336 struct file *file) \
1337 { \
1338 return single_open(file, debug_##func_base##_show, \
1339 inode->i_private); \
1340 } \
1341 \
1342 \
1343 static struct file_operations debug_##func_base##_ops = { \
1344 .open = debug_##func_base##_open, \
1345 .read = seq_read, \
1346 .llseek = seq_lseek, \
1347 .write = debug_##func_base##_write, \
1348 .release = single_release, \
1349 };
1350
1351GENERATE_DEBUG_STRUCTS(wmi_command_log);
1352GENERATE_DEBUG_STRUCTS(wmi_command_tx_cmp_log);
1353GENERATE_DEBUG_STRUCTS(wmi_event_log);
1354GENERATE_DEBUG_STRUCTS(wmi_rx_event_log);
1355GENERATE_DEBUG_STRUCTS(wmi_mgmt_command_log);
1356GENERATE_DEBUG_STRUCTS(wmi_mgmt_command_tx_cmp_log);
1357GENERATE_DEBUG_STRUCTS(wmi_mgmt_event_log);
1358GENERATE_DEBUG_STRUCTS(wmi_enable);
1359GENERATE_DEBUG_STRUCTS(wmi_log_size);
1360
c_priysb214c242018-06-12 16:53:51 +05301361struct wmi_debugfs_info wmi_debugfs_infos[NUM_DEBUG_INFOS] = {
Govind Singh08bd3dc2016-05-12 12:45:51 +05301362 DEBUG_FOO(wmi_command_log),
1363 DEBUG_FOO(wmi_command_tx_cmp_log),
1364 DEBUG_FOO(wmi_event_log),
1365 DEBUG_FOO(wmi_rx_event_log),
1366 DEBUG_FOO(wmi_mgmt_command_log),
1367 DEBUG_FOO(wmi_mgmt_command_tx_cmp_log),
1368 DEBUG_FOO(wmi_mgmt_event_log),
1369 DEBUG_FOO(wmi_enable),
1370 DEBUG_FOO(wmi_log_size),
1371};
1372
Govind Singh08bd3dc2016-05-12 12:45:51 +05301373
1374/**
1375 * wmi_debugfs_create() - Create debug_fs entry for wmi logging.
1376 *
1377 * @wmi_handle: wmi handle
1378 * @par_entry: debug directory entry
1379 * @id: Index to debug info data array
1380 *
1381 * Return: none
1382 */
1383static void wmi_debugfs_create(wmi_unified_t wmi_handle,
c_priysb214c242018-06-12 16:53:51 +05301384 struct dentry *par_entry)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301385{
1386 int i;
1387
c_priysb214c242018-06-12 16:53:51 +05301388 if (!par_entry)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301389 goto out;
1390
1391 for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
c_priysb214c242018-06-12 16:53:51 +05301392 wmi_handle->debugfs_de[i] = debugfs_create_file(
Govind Singh08bd3dc2016-05-12 12:45:51 +05301393 wmi_debugfs_infos[i].name, 0644, par_entry,
1394 wmi_handle, wmi_debugfs_infos[i].ops);
1395
c_priysb214c242018-06-12 16:53:51 +05301396 if (!wmi_handle->debugfs_de[i]) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05301397 WMI_LOGE("debug Entry creation failed!");
Govind Singh08bd3dc2016-05-12 12:45:51 +05301398 goto out;
1399 }
1400 }
1401
1402 return;
1403
1404out:
Sathish Kumar4c46c872018-09-20 16:07:20 +05301405 WMI_LOGE("debug Entry creation failed!");
Govind Singh08bd3dc2016-05-12 12:45:51 +05301406 wmi_log_buffer_free(wmi_handle);
1407 return;
1408}
1409
1410/**
1411 * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
Govind Singh08bd3dc2016-05-12 12:45:51 +05301412 * @wmi_handle: wmi handle
1413 * @dentry: debugfs directory entry
1414 * @id: Index to debug info data array
1415 *
1416 * Return: none
1417 */
Govind Singh8f788f42016-06-10 10:33:19 +05301418static void wmi_debugfs_remove(wmi_unified_t wmi_handle)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301419{
1420 int i;
Govind Singh8f788f42016-06-10 10:33:19 +05301421 struct dentry *dentry = wmi_handle->log_info.wmi_log_debugfs_dir;
Govind Singh08bd3dc2016-05-12 12:45:51 +05301422
c_priysb214c242018-06-12 16:53:51 +05301423 if (dentry) {
Govind Singh08bd3dc2016-05-12 12:45:51 +05301424 for (i = 0; i < NUM_DEBUG_INFOS; ++i) {
c_priysb214c242018-06-12 16:53:51 +05301425 if (wmi_handle->debugfs_de[i])
1426 wmi_handle->debugfs_de[i] = NULL;
Govind Singh08bd3dc2016-05-12 12:45:51 +05301427 }
1428 }
1429
1430 if (dentry)
1431 debugfs_remove_recursive(dentry);
1432}
1433
1434/**
1435 * wmi_debugfs_init() - debugfs functions to create debugfs directory and to
1436 * create debugfs enteries.
1437 *
1438 * @h: wmi handler
1439 *
1440 * Return: init status
1441 */
c_priysb214c242018-06-12 16:53:51 +05301442static QDF_STATUS wmi_debugfs_init(wmi_unified_t wmi_handle, uint32_t pdev_idx)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301443{
c_priysb214c242018-06-12 16:53:51 +05301444 char buf[32];
Govind Singh08bd3dc2016-05-12 12:45:51 +05301445
c_priysb214c242018-06-12 16:53:51 +05301446 snprintf(buf, sizeof(buf), "WMI_SOC%u_PDEV%u",
1447 wmi_handle->soc->soc_idx, pdev_idx);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301448
c_priysb214c242018-06-12 16:53:51 +05301449 wmi_handle->log_info.wmi_log_debugfs_dir =
1450 debugfs_create_dir(buf, NULL);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301451
c_priysb214c242018-06-12 16:53:51 +05301452 if (!wmi_handle->log_info.wmi_log_debugfs_dir) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05301453 WMI_LOGE("error while creating debugfs dir for %s", buf);
c_priysb214c242018-06-12 16:53:51 +05301454 return QDF_STATUS_E_FAILURE;
Rakesh Pillai1d3e9302017-12-26 19:02:35 +05301455 }
c_priysb214c242018-06-12 16:53:51 +05301456 wmi_debugfs_create(wmi_handle,
1457 wmi_handle->log_info.wmi_log_debugfs_dir);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301458
1459 return QDF_STATUS_SUCCESS;
1460}
Sandeep Puligillaac71f152016-06-13 15:42:55 -07001461
1462/**
1463 * wmi_mgmt_cmd_record() - Wrapper function for mgmt command logging macro
1464 *
1465 * @wmi_handle: wmi handle
1466 * @cmd: mgmt command
Sandeep Puligilla489c7192016-07-19 13:20:57 -07001467 * @header: pointer to 802.11 header
Sandeep Puligillaac71f152016-06-13 15:42:55 -07001468 * @vdev_id: vdev id
1469 * @chanfreq: channel frequency
1470 *
1471 * Return: none
1472 */
Himanshu Agarwal810141a2016-07-19 15:41:51 +05301473void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
Sandeep Puligilla489c7192016-07-19 13:20:57 -07001474 void *header, uint32_t vdev_id, uint32_t chanfreq)
Sandeep Puligillaac71f152016-06-13 15:42:55 -07001475{
Pratik Gandhi381fd122016-09-16 01:32:51 +05301476
1477 uint32_t data[CUSTOM_MGMT_CMD_DATA_SIZE];
1478
1479 data[0] = ((struct wmi_command_header *)header)->type;
1480 data[1] = ((struct wmi_command_header *)header)->sub_type;
1481 data[2] = vdev_id;
1482 data[3] = chanfreq;
1483
Sandeep Puligillaac71f152016-06-13 15:42:55 -07001484 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
1485
Rakesh Pillai6b0c64f2017-12-27 14:08:59 +05301486 WMI_MGMT_COMMAND_RECORD(wmi_handle, cmd, (uint8_t *)data);
Sandeep Puligillaac71f152016-06-13 15:42:55 -07001487
1488 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
1489}
Rajeev Kumar177f6212016-05-25 16:07:23 -07001490#else
1491/**
1492 * wmi_debugfs_remove() - Remove debugfs entry for wmi logging.
1493 * @wmi_handle: wmi handle
1494 * @dentry: debugfs directory entry
1495 * @id: Index to debug info data array
1496 *
1497 * Return: none
1498 */
Govind Singh8f788f42016-06-10 10:33:19 +05301499static void wmi_debugfs_remove(wmi_unified_t wmi_handle) { }
Himanshu Agarwal810141a2016-07-19 15:41:51 +05301500void wmi_mgmt_cmd_record(wmi_unified_t wmi_handle, uint32_t cmd,
Sandeep Puligilla489c7192016-07-19 13:20:57 -07001501 void *header, uint32_t vdev_id, uint32_t chanfreq) { }
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05301502static inline void wmi_log_buffer_free(struct wmi_unified *wmi_handle) { }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001503#endif /*WMI_INTERFACE_EVENT_LOGGING */
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301504qdf_export_symbol(wmi_mgmt_cmd_record);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001505
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001506int wmi_get_host_credits(wmi_unified_t wmi_handle);
1507/* WMI buffer APIs */
1508
Shiva Krishna Pittalab1554312018-04-02 17:23:42 +05301509#ifdef NBUF_MEMORY_DEBUG
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001510wmi_buf_t
Arif Hussain61847a92018-08-09 16:11:14 -07001511wmi_buf_alloc_debug(wmi_unified_t wmi_handle, uint32_t len,
1512 const char *func_name,
Debasis Das78495ce2018-04-04 17:17:55 +05301513 uint32_t line_num)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001514{
1515 wmi_buf_t wmi_buf;
1516
1517 if (roundup(len + WMI_MIN_HEAD_ROOM, 4) > wmi_handle->max_msg_len) {
Govind Singh236fc202016-03-09 14:32:57 +05301518 QDF_ASSERT(0);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001519 return NULL;
1520 }
1521
Arif Hussain61847a92018-08-09 16:11:14 -07001522 wmi_buf = wbuff_buff_get(wmi_handle->wbuff_handle, len, func_name,
Rakshith Suresh Patkar5c881ec2018-10-05 15:21:37 +05301523 line_num);
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05301524 if (!wmi_buf)
1525 wmi_buf = qdf_nbuf_alloc_debug(NULL,
1526 roundup(len + WMI_MIN_HEAD_ROOM,
1527 4),
1528 WMI_MIN_HEAD_ROOM, 4, false,
Arif Hussain61847a92018-08-09 16:11:14 -07001529 func_name, line_num);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001530 if (!wmi_buf)
1531 return NULL;
1532
1533 /* Clear the wmi buffer */
Govind Singh236fc202016-03-09 14:32:57 +05301534 OS_MEMZERO(qdf_nbuf_data(wmi_buf), len);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001535
1536 /*
1537 * Set the length of the buffer to match the allocation size.
1538 */
Govind Singh236fc202016-03-09 14:32:57 +05301539 qdf_nbuf_set_pktlen(wmi_buf, len);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001540
1541 return wmi_buf;
1542}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301543qdf_export_symbol(wmi_buf_alloc_debug);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001544
1545void wmi_buf_free(wmi_buf_t net_buf)
1546{
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05301547 net_buf = wbuff_buff_put(net_buf);
1548 if (net_buf)
1549 qdf_nbuf_free(net_buf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001550}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301551qdf_export_symbol(wmi_buf_free);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001552#else
Arif Hussain58189eb2018-07-19 14:15:36 -07001553wmi_buf_t wmi_buf_alloc_fl(wmi_unified_t wmi_handle, uint32_t len,
1554 const char *func, uint32_t line)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001555{
1556 wmi_buf_t wmi_buf;
1557
1558 if (roundup(len + WMI_MIN_HEAD_ROOM, 4) > wmi_handle->max_msg_len) {
Dustin Brownd33659b2019-02-22 10:58:48 -08001559 QDF_DEBUG_PANIC("Invalid length %u (via %s:%u)",
1560 len, func, line);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001561 return NULL;
1562 }
1563
Arif Hussain61847a92018-08-09 16:11:14 -07001564 wmi_buf = wbuff_buff_get(wmi_handle->wbuff_handle, len, __func__,
Rakshith Suresh Patkar5c881ec2018-10-05 15:21:37 +05301565 __LINE__);
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05301566 if (!wmi_buf)
1567 wmi_buf = qdf_nbuf_alloc_fl(NULL, roundup(len +
1568 WMI_MIN_HEAD_ROOM, 4), WMI_MIN_HEAD_ROOM, 4,
1569 false, func, line);
1570
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05301571 if (!wmi_buf) {
1572 wmi_nofl_err("%s:%d, failed to alloc len:%d", func, line, len);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001573 return NULL;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05301574 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001575
1576 /* Clear the wmi buffer */
Govind Singh236fc202016-03-09 14:32:57 +05301577 OS_MEMZERO(qdf_nbuf_data(wmi_buf), len);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001578
1579 /*
1580 * Set the length of the buffer to match the allocation size.
1581 */
Govind Singh236fc202016-03-09 14:32:57 +05301582 qdf_nbuf_set_pktlen(wmi_buf, len);
Dustin Brownd33659b2019-02-22 10:58:48 -08001583
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001584 return wmi_buf;
1585}
Arif Hussain58189eb2018-07-19 14:15:36 -07001586qdf_export_symbol(wmi_buf_alloc_fl);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001587
1588void wmi_buf_free(wmi_buf_t net_buf)
1589{
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05301590 net_buf = wbuff_buff_put(net_buf);
1591 if (net_buf)
1592 qdf_nbuf_free(net_buf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001593}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301594qdf_export_symbol(wmi_buf_free);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001595#endif
1596
1597/**
1598 * wmi_get_max_msg_len() - get maximum WMI message length
1599 * @wmi_handle: WMI handle.
1600 *
1601 * This function returns the maximum WMI message length
1602 *
1603 * Return: maximum WMI message length
1604 */
1605uint16_t wmi_get_max_msg_len(wmi_unified_t wmi_handle)
1606{
1607 return wmi_handle->max_msg_len - WMI_MIN_HEAD_ROOM;
1608}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301609qdf_export_symbol(wmi_get_max_msg_len);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001610
Ashish Kumar Dhanotiya9563db82017-03-16 18:03:32 +05301611#ifndef WMI_CMD_STRINGS
Himanshu Agarwal810141a2016-07-19 15:41:51 +05301612static uint8_t *wmi_id_to_name(uint32_t wmi_command)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301613{
1614 return "Invalid WMI cmd";
1615}
Govind Singha5e18c42016-04-15 13:58:27 +05301616#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001617
Govind Singh3dda60e2017-03-21 13:02:00 +05301618static inline void wmi_log_cmd_id(uint32_t cmd_id, uint32_t tag)
1619{
1620 WMI_LOGD("Send WMI command:%s command_id:%d htc_tag:%d\n",
1621 wmi_id_to_name(cmd_id), cmd_id, tag);
1622}
1623
Govind Singhd88ae7f2016-03-06 19:55:02 +05301624/**
Govind Singha5e18c42016-04-15 13:58:27 +05301625 * wmi_is_pm_resume_cmd() - check if a cmd is part of the resume sequence
1626 * @cmd_id: command to check
1627 *
1628 * Return: true if the command is part of the resume sequence.
1629 */
Bala Venkatesh63b4f6a2019-07-17 11:43:08 +05301630#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
Himanshu Agarwal810141a2016-07-19 15:41:51 +05301631static bool wmi_is_pm_resume_cmd(uint32_t cmd_id)
Govind Singha5e18c42016-04-15 13:58:27 +05301632{
1633 switch (cmd_id) {
1634 case WMI_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID:
1635 case WMI_PDEV_RESUME_CMDID:
1636 return true;
1637
1638 default:
1639 return false;
1640 }
1641}
lifeng12ed1892019-05-30 14:12:42 +08001642
Bala Venkatesh63b4f6a2019-07-17 11:43:08 +05301643#else
1644static bool wmi_is_pm_resume_cmd(uint32_t cmd_id)
1645{
1646 return false;
1647}
1648
1649#endif
1650
1651#ifdef FEATURE_WLAN_D0WOW
lifeng12ed1892019-05-30 14:12:42 +08001652static bool wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf, uint32_t cmd_id)
1653{
1654 wmi_d0_wow_enable_disable_cmd_fixed_param *cmd;
1655
1656 if (cmd_id == WMI_D0_WOW_ENABLE_DISABLE_CMDID) {
1657 cmd = (wmi_d0_wow_enable_disable_cmd_fixed_param *)
1658 wmi_buf_data(buf);
1659 if (!cmd->enable)
1660 return true;
1661 else
1662 return false;
1663 }
1664
1665 return false;
1666}
Govind Singha5e18c42016-04-15 13:58:27 +05301667#else
lifeng12ed1892019-05-30 14:12:42 +08001668static bool wmi_is_legacy_d0wow_disable_cmd(wmi_buf_t buf, uint32_t cmd_id)
1669{
1670 return false;
1671}
Bala Venkatesh63b4f6a2019-07-17 11:43:08 +05301672
Govind Singha5e18c42016-04-15 13:58:27 +05301673#endif
1674
Surya Prakash27fba322019-01-31 14:16:27 +05301675static inline void wmi_unified_debug_dump(wmi_unified_t wmi_handle)
1676{
1677 wmi_nofl_err("Endpoint ID = %d, Tx Queue Depth = %d, soc_id = %u, target type = %s",
1678 wmi_handle->wmi_endpoint_id,
1679 htc_get_tx_queue_depth(wmi_handle->htc_handle,
1680 wmi_handle->wmi_endpoint_id),
1681 wmi_handle->soc->soc_idx,
1682 (wmi_handle->target_type ==
1683 WMI_TLV_TARGET ? "WMI_TLV_TARGET" :
1684 "WMI_NON_TLV_TARGET"));
1685}
1686
Manikandan Mohan9b1b93c2019-08-23 08:47:21 -07001687#ifdef WLAN_FEATURE_WMI_SEND_RECV_QMI
1688QDF_STATUS wmi_unified_cmd_send_over_qmi(struct wmi_unified *wmi_handle,
1689 wmi_buf_t buf, uint32_t buflen,
1690 uint32_t cmd_id)
1691{
1692 QDF_STATUS status;
Alan Chenb2bc5592019-10-03 16:22:59 -07001693 int32_t ret;
Manikandan Mohan9b1b93c2019-08-23 08:47:21 -07001694
1695 if (!qdf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR))) {
1696 wmi_err("Failed to send cmd %x, no memory", cmd_id);
1697 return QDF_STATUS_E_NOMEM;
1698 }
1699
1700 qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
1701 WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
1702 wmi_debug("Sending WMI_CMD_ID: %d over qmi", cmd_id);
1703 status = qdf_wmi_send_recv_qmi(qdf_nbuf_data(buf),
1704 buflen + sizeof(WMI_CMD_HDR),
1705 wmi_handle,
1706 wmi_process_qmi_fw_event);
1707 if (QDF_IS_STATUS_ERROR(status)) {
1708 qdf_nbuf_pull_head(buf, sizeof(WMI_CMD_HDR));
1709 wmi_warn("WMI send on QMI failed. Retrying WMI on HTC");
1710 } else {
Alan Chenb2bc5592019-10-03 16:22:59 -07001711 ret = qdf_atomic_inc_return(&wmi_handle->num_stats_over_qmi);
1712 wmi_debug("num stats over qmi: %d", ret);
Manikandan Mohan9b1b93c2019-08-23 08:47:21 -07001713 wmi_buf_free(buf);
1714 }
1715
1716 return status;
1717}
1718
1719static int __wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
1720{
1721 struct wmi_unified *wmi_handle = wmi_cb_ctx;
1722 wmi_buf_t evt_buf;
1723 uint32_t evt_id;
1724
1725 if (!wmi_handle || !buf)
1726 return -EINVAL;
1727
1728 evt_buf = wmi_buf_alloc(wmi_handle, len);
1729 if (!evt_buf)
1730 return -ENOMEM;
1731
1732 qdf_mem_copy(qdf_nbuf_data(evt_buf), buf, len);
1733 evt_id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
1734 wmi_debug("Received WMI_EVT_ID: %d over qmi", evt_id);
1735 wmi_process_fw_event(wmi_handle, evt_buf);
1736
1737 return 0;
1738}
1739
1740int wmi_process_qmi_fw_event(void *wmi_cb_ctx, void *buf, int len)
1741{
1742 struct qdf_op_sync *op_sync;
1743 int ret;
1744
1745 if (qdf_op_protect(&op_sync))
1746 return -EINVAL;
1747 ret = __wmi_process_qmi_fw_event(wmi_cb_ctx, buf, len);
1748 qdf_op_unprotect(op_sync);
1749
1750 return ret;
1751}
1752#endif
1753
Arif Hussainffcaef42018-07-19 15:05:16 -07001754QDF_STATUS wmi_unified_cmd_send_fl(wmi_unified_t wmi_handle, wmi_buf_t buf,
1755 uint32_t len, uint32_t cmd_id,
1756 const char *func, uint32_t line)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001757{
1758 HTC_PACKET *pkt;
Rakesh Pillai13146452017-06-22 12:52:31 +05301759 QDF_STATUS status;
Govind Singh3f302ec2016-03-09 12:03:29 +05301760 uint16_t htc_tag = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001761
Houston Hoffmanc5141b02015-11-18 02:36:30 -08001762 if (wmi_get_runtime_pm_inprogress(wmi_handle)) {
Dustin Brownd33659b2019-02-22 10:58:48 -08001763 htc_tag = wmi_handle->ops->wmi_set_htc_tx_tag(wmi_handle, buf,
1764 cmd_id);
Govind Singh236fc202016-03-09 14:32:57 +05301765 } else if (qdf_atomic_read(&wmi_handle->is_target_suspended) &&
lifeng12ed1892019-05-30 14:12:42 +08001766 !wmi_is_pm_resume_cmd(cmd_id) &&
1767 !wmi_is_legacy_d0wow_disable_cmd(buf, cmd_id)) {
hangtian032a78d2019-03-08 14:24:00 +08001768 wmi_nofl_err("Target is suspended (via %s:%u)",
Rajeev Kumar6b276f62019-04-25 14:50:05 -07001769 func, line);
Govind Singh3f14f6f2016-04-01 16:48:57 +05301770 return QDF_STATUS_E_BUSY;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001771 }
Dustin Brownd33659b2019-02-22 10:58:48 -08001772
Govind Singha5e18c42016-04-15 13:58:27 +05301773 if (wmi_handle->wmi_stopinprogress) {
Manoj Ekbote9c0ec6c2019-10-29 23:05:09 -07001774 wmi_nofl_err("%s:%d, WMI stop in progress, wmi_handle:%pK",
1775 func, line, wmi_handle);
Houston Hoffmane007aed2016-09-27 23:29:49 -07001776 return QDF_STATUS_E_INVAL;
Govind Singha5e18c42016-04-15 13:58:27 +05301777 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001778
Govind Singha5e18c42016-04-15 13:58:27 +05301779#ifndef WMI_NON_TLV_SUPPORT
Kiran Venkatappa068d22d2016-08-09 22:52:35 +05301780 /* Do sanity check on the TLV parameter structure */
Govind Singha5e18c42016-04-15 13:58:27 +05301781 if (wmi_handle->target_type == WMI_TLV_TARGET) {
Govind Singh236fc202016-03-09 14:32:57 +05301782 void *buf_ptr = (void *)qdf_nbuf_data(buf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001783
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05301784 if (wmi_handle->ops->wmi_check_command_params(NULL, buf_ptr, len, cmd_id)
Govind Singh08bd3dc2016-05-12 12:45:51 +05301785 != 0) {
Arif Hussainffcaef42018-07-19 15:05:16 -07001786 wmi_nofl_err("%s:%d, Invalid WMI Param Buffer for Cmd:%d",
1787 func, line, cmd_id);
Govind Singh3f14f6f2016-04-01 16:48:57 +05301788 return QDF_STATUS_E_INVAL;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001789 }
1790 }
Govind Singha5e18c42016-04-15 13:58:27 +05301791#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001792
Govind Singh236fc202016-03-09 14:32:57 +05301793 if (qdf_nbuf_push_head(buf, sizeof(WMI_CMD_HDR)) == NULL) {
Arif Hussainffcaef42018-07-19 15:05:16 -07001794 wmi_nofl_err("%s:%d, Failed to send cmd %x, no memory",
1795 func, line, cmd_id);
Govind Singh3f14f6f2016-04-01 16:48:57 +05301796 return QDF_STATUS_E_NOMEM;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001797 }
1798
Vignesh Viswanathanc352d602018-06-15 12:42:45 +05301799 qdf_mem_zero(qdf_nbuf_data(buf), sizeof(WMI_CMD_HDR));
Govind Singh236fc202016-03-09 14:32:57 +05301800 WMI_SET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID, cmd_id);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001801
Govind Singh236fc202016-03-09 14:32:57 +05301802 qdf_atomic_inc(&wmi_handle->pending_cmds);
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05301803 if (qdf_atomic_read(&wmi_handle->pending_cmds) >=
1804 wmi_handle->wmi_max_cmds) {
Arif Hussainffcaef42018-07-19 15:05:16 -07001805 wmi_nofl_err("hostcredits = %d",
1806 wmi_get_host_credits(wmi_handle));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001807 htc_dump_counter_info(wmi_handle->htc_handle);
Govind Singh236fc202016-03-09 14:32:57 +05301808 qdf_atomic_dec(&wmi_handle->pending_cmds);
Arif Hussainffcaef42018-07-19 15:05:16 -07001809 wmi_nofl_err("%s:%d, MAX %d WMI Pending cmds reached",
1810 func, line, wmi_handle->wmi_max_cmds);
Surya Prakash27fba322019-01-31 14:16:27 +05301811 wmi_unified_debug_dump(wmi_handle);
Surya Prakash Raajenb9760762020-01-02 20:02:52 +05301812 htc_ce_tasklet_debug_dump(wmi_handle->htc_handle);
Jingxiang Ge4218f022019-04-10 14:49:57 +08001813 qdf_trigger_self_recovery(QDF_WMI_EXCEED_MAX_PENDING_CMDS);
Govind Singh3f14f6f2016-04-01 16:48:57 +05301814 return QDF_STATUS_E_BUSY;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001815 }
1816
Arif Hussainffcaef42018-07-19 15:05:16 -07001817 pkt = qdf_mem_malloc_fl(sizeof(*pkt), func, line);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001818 if (!pkt) {
Govind Singh236fc202016-03-09 14:32:57 +05301819 qdf_atomic_dec(&wmi_handle->pending_cmds);
Govind Singh3f14f6f2016-04-01 16:48:57 +05301820 return QDF_STATUS_E_NOMEM;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001821 }
1822
1823 SET_HTC_PACKET_INFO_TX(pkt,
1824 NULL,
Govind Singh236fc202016-03-09 14:32:57 +05301825 qdf_nbuf_data(buf), len + sizeof(WMI_CMD_HDR),
Houston Hoffmanc5141b02015-11-18 02:36:30 -08001826 wmi_handle->wmi_endpoint_id, htc_tag);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001827
1828 SET_HTC_PACKET_NET_BUF_CONTEXT(pkt, buf);
Govind Singh3dda60e2017-03-21 13:02:00 +05301829 wmi_log_cmd_id(cmd_id, htc_tag);
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +05301830 wmi_ext_dbg_msg_cmd_record(wmi_handle,
1831 qdf_nbuf_data(buf), qdf_nbuf_len(buf));
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001832#ifdef WMI_INTERFACE_EVENT_LOGGING
Govind Singh08bd3dc2016-05-12 12:45:51 +05301833 if (wmi_handle->log_info.wmi_logging_enable) {
1834 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
jiad99bc15a2018-01-22 15:37:03 +08001835 /*
1836 * Record 16 bytes of WMI cmd data -
1837 * exclude TLV and WMI headers
1838 *
1839 * WMI mgmt command already recorded in wmi_mgmt_cmd_record
1840 */
1841 if (wmi_handle->ops->is_management_record(cmd_id) == false) {
Govind Singh08bd3dc2016-05-12 12:45:51 +05301842 WMI_COMMAND_RECORD(wmi_handle, cmd_id,
Rakesh Pillai6b0c64f2017-12-27 14:08:59 +05301843 qdf_nbuf_data(buf) +
Pratik Gandhi5526a552018-10-10 12:12:32 +05301844 wmi_handle->soc->buf_offset_command);
Govind Singh08bd3dc2016-05-12 12:45:51 +05301845 }
Govind Singh08bd3dc2016-05-12 12:45:51 +05301846 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
1847 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001848#endif
1849
1850 status = htc_send_pkt(wmi_handle->htc_handle, pkt);
1851
Rakesh Pillai13146452017-06-22 12:52:31 +05301852 if (QDF_STATUS_SUCCESS != status) {
Govind Singh236fc202016-03-09 14:32:57 +05301853 qdf_atomic_dec(&wmi_handle->pending_cmds);
Arif Hussainffcaef42018-07-19 15:05:16 -07001854 wmi_nofl_err("%s:%d, htc_send_pkt failed, status:%d",
1855 func, line, status);
Houston Hoffmanebc2bbc2016-10-13 15:30:52 -07001856 qdf_mem_free(pkt);
Rakesh Pillai13146452017-06-22 12:52:31 +05301857 return status;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001858 }
1859
Govind Singh236fc202016-03-09 14:32:57 +05301860 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001861}
Arif Hussainffcaef42018-07-19 15:05:16 -07001862qdf_export_symbol(wmi_unified_cmd_send_fl);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001863
Govind Singhd88ae7f2016-03-06 19:55:02 +05301864/**
1865 * wmi_unified_get_event_handler_ix() - gives event handler's index
1866 * @wmi_handle: handle to wmi
1867 * @event_id: wmi event id
1868 *
1869 * Return: event handler's index
1870 */
Jeff Johnson589ca092016-10-07 13:03:02 -07001871static int wmi_unified_get_event_handler_ix(wmi_unified_t wmi_handle,
1872 uint32_t event_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001873{
1874 uint32_t idx = 0;
Govind Singhd88ae7f2016-03-06 19:55:02 +05301875 int32_t invalid_idx = -1;
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301876 struct wmi_soc *soc = wmi_handle->soc;
Govind Singha5e18c42016-04-15 13:58:27 +05301877
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301878 for (idx = 0; (idx < soc->max_event_idx &&
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001879 idx < WMI_UNIFIED_MAX_EVENT); ++idx) {
1880 if (wmi_handle->event_id[idx] == event_id &&
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07001881 wmi_handle->event_handler[idx]) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001882 return idx;
1883 }
1884 }
Govind Singhd88ae7f2016-03-06 19:55:02 +05301885
1886 return invalid_idx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001887}
1888
Govind Singhd88ae7f2016-03-06 19:55:02 +05301889/**
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301890 * wmi_unified_register_event() - register wmi event handler
1891 * @wmi_handle: handle to wmi
1892 * @event_id: wmi event id
1893 * @handler_func: wmi event handler function
1894 *
1895 * Return: 0 on success
1896 */
1897int wmi_unified_register_event(wmi_unified_t wmi_handle,
1898 uint32_t event_id,
1899 wmi_unified_event_handler handler_func)
1900{
1901 uint32_t idx = 0;
1902 uint32_t evt_id;
Akshay Kosigi46050aa2018-12-15 12:07:43 +05301903 struct wmi_soc *soc;
1904
1905 if (!wmi_handle) {
1906 WMI_LOGE("WMI handle is NULL");
1907 return QDF_STATUS_E_FAILURE;
1908 }
1909
1910 soc = wmi_handle->soc;
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301911
1912 if (event_id >= wmi_events_max ||
1913 wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301914 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
1915 "%s: Event id %d is unavailable",
1916 __func__, event_id);
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301917 return QDF_STATUS_E_FAILURE;
1918 }
1919 evt_id = wmi_handle->wmi_events[event_id];
1920 if (wmi_unified_get_event_handler_ix(wmi_handle, evt_id) != -1) {
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301921 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
1922 "%s : event handler already registered 0x%x",
1923 __func__, evt_id);
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301924 return QDF_STATUS_E_FAILURE;
1925 }
1926 if (soc->max_event_idx == WMI_UNIFIED_MAX_EVENT) {
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301927 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
1928 "%s : no more event handlers 0x%x",
1929 __func__, evt_id);
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301930 return QDF_STATUS_E_FAILURE;
1931 }
1932 idx = soc->max_event_idx;
1933 wmi_handle->event_handler[idx] = handler_func;
1934 wmi_handle->event_id[idx] = evt_id;
1935 qdf_spin_lock_bh(&soc->ctx_lock);
1936 wmi_handle->ctx[idx] = WMI_RX_UMAC_CTX;
1937 qdf_spin_unlock_bh(&soc->ctx_lock);
1938 soc->max_event_idx++;
1939
1940 return 0;
1941}
1942
1943/**
Govind Singhd88ae7f2016-03-06 19:55:02 +05301944 * wmi_unified_register_event_handler() - register wmi event handler
1945 * @wmi_handle: handle to wmi
1946 * @event_id: wmi event id
1947 * @handler_func: wmi event handler function
Govind Singh3f302ec2016-03-09 12:03:29 +05301948 * @rx_ctx: rx execution context for wmi rx events
Govind Singhd88ae7f2016-03-06 19:55:02 +05301949 *
Soumya Bhat8b71edb2017-03-22 14:41:01 +05301950 * This API is to support legacy requirements. Will be deprecated in future.
Govind Singhd88ae7f2016-03-06 19:55:02 +05301951 * Return: 0 on success
1952 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001953int wmi_unified_register_event_handler(wmi_unified_t wmi_handle,
Mukul Sharma396cef72017-11-03 19:26:54 +05301954 wmi_conv_event_id event_id,
Govind Singh3f302ec2016-03-09 12:03:29 +05301955 wmi_unified_event_handler handler_func,
1956 uint8_t rx_ctx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001957{
1958 uint32_t idx = 0;
Govind Singha5e18c42016-04-15 13:58:27 +05301959 uint32_t evt_id;
Akshay Kosigi46050aa2018-12-15 12:07:43 +05301960 struct wmi_soc *soc;
1961
1962 if (!wmi_handle) {
1963 WMI_LOGE("WMI handle is NULL");
1964 return QDF_STATUS_E_FAILURE;
1965 }
1966
1967 soc = wmi_handle->soc;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001968
Govind Singha5e18c42016-04-15 13:58:27 +05301969 if (event_id >= wmi_events_max ||
1970 wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301971 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
1972 "%s: Event id %d is unavailable",
1973 __func__, event_id);
Govind Singha5e18c42016-04-15 13:58:27 +05301974 return QDF_STATUS_E_FAILURE;
1975 }
1976 evt_id = wmi_handle->wmi_events[event_id];
Mukul Sharma396cef72017-11-03 19:26:54 +05301977
Govind Singha5e18c42016-04-15 13:58:27 +05301978 if (wmi_unified_get_event_handler_ix(wmi_handle, evt_id) != -1) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05301979 WMI_LOGE("event handler already registered 0x%x",
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301980 evt_id);
Govind Singh236fc202016-03-09 14:32:57 +05301981 return QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001982 }
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301983 if (soc->max_event_idx == WMI_UNIFIED_MAX_EVENT) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05301984 WMI_LOGE("no more event handlers 0x%x",
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301985 evt_id);
Govind Singh236fc202016-03-09 14:32:57 +05301986 return QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001987 }
Adil Saeed Musthafa0ec675d2017-07-05 14:43:51 -07001988 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_DEBUG,
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05301989 "Registered event handler for event 0x%8x", evt_id);
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301990 idx = soc->max_event_idx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001991 wmi_handle->event_handler[idx] = handler_func;
Govind Singha5e18c42016-04-15 13:58:27 +05301992 wmi_handle->event_id[idx] = evt_id;
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301993 qdf_spin_lock_bh(&soc->ctx_lock);
Govind Singh3f302ec2016-03-09 12:03:29 +05301994 wmi_handle->ctx[idx] = rx_ctx;
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05301995 qdf_spin_unlock_bh(&soc->ctx_lock);
1996 soc->max_event_idx++;
Govind Singhd88ae7f2016-03-06 19:55:02 +05301997
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08001998 return 0;
1999}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302000qdf_export_symbol(wmi_unified_register_event_handler);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002001
Govind Singhd88ae7f2016-03-06 19:55:02 +05302002/**
Soumya Bhat169eff12017-03-27 12:26:56 +05302003 * wmi_unified_unregister_event() - unregister wmi event handler
2004 * @wmi_handle: handle to wmi
2005 * @event_id: wmi event id
2006 *
2007 * Return: 0 on success
2008 */
2009int wmi_unified_unregister_event(wmi_unified_t wmi_handle,
2010 uint32_t event_id)
2011{
2012 uint32_t idx = 0;
2013 uint32_t evt_id;
2014 struct wmi_soc *soc = wmi_handle->soc;
2015
2016 if (event_id >= wmi_events_max ||
2017 wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302018 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
2019 "%s: Event id %d is unavailable",
2020 __func__, event_id);
Soumya Bhat169eff12017-03-27 12:26:56 +05302021 return QDF_STATUS_E_FAILURE;
2022 }
2023 evt_id = wmi_handle->wmi_events[event_id];
2024
2025 idx = wmi_unified_get_event_handler_ix(wmi_handle, evt_id);
2026 if (idx == -1) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05302027 WMI_LOGE("event handler is not registered: evt id 0x%x",
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302028 evt_id);
Soumya Bhat169eff12017-03-27 12:26:56 +05302029 return QDF_STATUS_E_FAILURE;
2030 }
2031 wmi_handle->event_handler[idx] = NULL;
2032 wmi_handle->event_id[idx] = 0;
2033 --soc->max_event_idx;
2034 wmi_handle->event_handler[idx] =
2035 wmi_handle->event_handler[soc->max_event_idx];
2036 wmi_handle->event_id[idx] =
2037 wmi_handle->event_id[soc->max_event_idx];
2038
2039 return 0;
2040}
2041
2042/**
Govind Singhd88ae7f2016-03-06 19:55:02 +05302043 * wmi_unified_unregister_event_handler() - unregister wmi event handler
2044 * @wmi_handle: handle to wmi
2045 * @event_id: wmi event id
2046 *
2047 * Return: 0 on success
2048 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002049int wmi_unified_unregister_event_handler(wmi_unified_t wmi_handle,
Mukul Sharma396cef72017-11-03 19:26:54 +05302050 wmi_conv_event_id event_id)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002051{
2052 uint32_t idx = 0;
Govind Singha5e18c42016-04-15 13:58:27 +05302053 uint32_t evt_id;
Akshay Kosigi46050aa2018-12-15 12:07:43 +05302054 struct wmi_soc *soc;
2055
2056 if (!wmi_handle) {
2057 WMI_LOGE("WMI handle is NULL");
2058 return QDF_STATUS_E_FAILURE;
2059 }
2060
2061 soc = wmi_handle->soc;
Govind Singhd88ae7f2016-03-06 19:55:02 +05302062
Govind Singha5e18c42016-04-15 13:58:27 +05302063 if (event_id >= wmi_events_max ||
2064 wmi_handle->wmi_events[event_id] == WMI_EVENT_ID_INVALID) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05302065 WMI_LOGE("Event id %d is unavailable",
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302066 event_id);
Govind Singha5e18c42016-04-15 13:58:27 +05302067 return QDF_STATUS_E_FAILURE;
2068 }
2069 evt_id = wmi_handle->wmi_events[event_id];
Govind Singha5e18c42016-04-15 13:58:27 +05302070
2071 idx = wmi_unified_get_event_handler_ix(wmi_handle, evt_id);
Govind Singhd88ae7f2016-03-06 19:55:02 +05302072 if (idx == -1) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05302073 WMI_LOGE("event handler is not registered: evt id 0x%x",
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302074 evt_id);
Govind Singh236fc202016-03-09 14:32:57 +05302075 return QDF_STATUS_E_FAILURE;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002076 }
2077 wmi_handle->event_handler[idx] = NULL;
2078 wmi_handle->event_id[idx] = 0;
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302079 --soc->max_event_idx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002080 wmi_handle->event_handler[idx] =
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302081 wmi_handle->event_handler[soc->max_event_idx];
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002082 wmi_handle->event_id[idx] =
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302083 wmi_handle->event_id[soc->max_event_idx];
Govind Singhd88ae7f2016-03-06 19:55:02 +05302084
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002085 return 0;
2086}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302087qdf_export_symbol(wmi_unified_unregister_event_handler);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002088
Amar Singhaldbff0cc2018-06-26 16:45:54 -07002089void wmi_process_fw_event_worker_thread_ctx(struct wmi_unified *wmi_handle,
Harprit Chhabada71c98462018-12-26 14:10:39 -08002090 void *evt_buf)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002091{
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002092
Govind Singh236fc202016-03-09 14:32:57 +05302093 qdf_spin_lock_bh(&wmi_handle->eventq_lock);
2094 qdf_nbuf_queue_add(&wmi_handle->event_queue, evt_buf);
2095 qdf_spin_unlock_bh(&wmi_handle->eventq_lock);
Rajeev Kumarbc623432017-03-29 17:14:14 -07002096 qdf_queue_work(0, wmi_handle->wmi_rx_work_queue,
2097 &wmi_handle->rx_event_work);
2098
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002099 return;
2100}
2101
Amar Singhaldbff0cc2018-06-26 16:45:54 -07002102qdf_export_symbol(wmi_process_fw_event_worker_thread_ctx);
2103
Sandeep Puligilla9304a972019-06-27 20:46:59 -07002104uint32_t wmi_critical_events_in_flight(struct wmi_unified *wmi)
2105{
2106 return qdf_atomic_read(&wmi->critical_events_in_flight);
2107}
2108
2109static bool
2110wmi_is_event_critical(struct wmi_unified *wmi_handle, uint32_t event_id)
2111{
2112 if (wmi_handle->wmi_events[wmi_roam_synch_event_id] == event_id)
2113 return true;
2114
2115 return false;
2116}
2117
2118static void wmi_discard_fw_event(struct scheduler_msg *msg)
2119{
2120 struct wmi_process_fw_event_params *event_param;
2121
2122 if (!msg->bodyptr)
2123 return;
2124
2125 event_param = (struct wmi_process_fw_event_params *)msg->bodyptr;
2126 qdf_nbuf_free(event_param->evt_buf);
2127 qdf_mem_free(msg->bodyptr);
2128 msg->bodyptr = NULL;
2129 msg->bodyval = 0;
2130 msg->type = 0;
2131}
2132
2133static int wmi_process_fw_event_handler(struct scheduler_msg *msg)
2134{
2135 struct wmi_process_fw_event_params *params =
2136 (struct wmi_process_fw_event_params *)msg->bodyptr;
2137 struct wmi_unified *wmi_handle;
2138 uint32_t event_id;
2139
2140 wmi_handle = (struct wmi_unified *)params->wmi_handle;
2141 event_id = WMI_GET_FIELD(qdf_nbuf_data(params->evt_buf),
2142 WMI_CMD_HDR, COMMANDID);
2143 wmi_process_fw_event(wmi_handle, params->evt_buf);
2144
2145 if (wmi_is_event_critical(wmi_handle, event_id))
2146 qdf_atomic_dec(&wmi_handle->critical_events_in_flight);
2147
2148 qdf_mem_free(msg->bodyptr);
2149
2150 return 0;
2151}
2152
2153/**
2154 * wmi_process_fw_event_sched_thread_ctx() - common event handler to serialize
2155 * event processing through scheduler thread
2156 * @ctx: wmi context
2157 * @ev: event buffer
2158 * @rx_ctx: rx execution context
2159 *
2160 * Return: 0 on success, errno on failure
2161 */
2162static QDF_STATUS
2163wmi_process_fw_event_sched_thread_ctx(struct wmi_unified *wmi,
2164 void *ev)
2165{
2166 struct wmi_process_fw_event_params *params_buf;
2167 struct scheduler_msg msg = { 0 };
2168 uint32_t event_id;
2169 struct target_psoc_info *tgt_hdl;
2170 bool is_wmi_ready = false;
2171 struct wlan_objmgr_psoc *psoc;
2172
2173 psoc = target_if_get_psoc_from_scn_hdl(wmi->scn_handle);
2174 if (!psoc) {
2175 target_if_err("psoc is null");
2176 qdf_nbuf_free(ev);
2177 return QDF_STATUS_E_INVAL;
2178 }
2179
2180 tgt_hdl = wlan_psoc_get_tgt_if_handle(psoc);
2181 if (!tgt_hdl) {
2182 wmi_err("target_psoc_info is null");
2183 qdf_nbuf_free(ev);
2184 return QDF_STATUS_E_INVAL;
2185 }
2186
2187 is_wmi_ready = target_psoc_get_wmi_ready(tgt_hdl);
2188 if (!is_wmi_ready) {
2189 wmi_debug("fw event recvd before ready event processed");
2190 wmi_debug("therefore use worker thread");
2191 wmi_process_fw_event_worker_thread_ctx(wmi, ev);
2192 return QDF_STATUS_E_INVAL;
2193 }
2194
2195 params_buf = qdf_mem_malloc(sizeof(struct wmi_process_fw_event_params));
2196 if (!params_buf) {
2197 wmi_err("malloc failed");
2198 qdf_nbuf_free(ev);
2199 return QDF_STATUS_E_NOMEM;
2200 }
2201
2202 params_buf->wmi_handle = wmi;
2203 params_buf->evt_buf = ev;
2204
2205 event_id = WMI_GET_FIELD(qdf_nbuf_data(params_buf->evt_buf),
2206 WMI_CMD_HDR, COMMANDID);
2207 if (wmi_is_event_critical(wmi, event_id))
2208 qdf_atomic_inc(&wmi->critical_events_in_flight);
2209
2210 msg.bodyptr = params_buf;
2211 msg.bodyval = 0;
2212 msg.callback = wmi_process_fw_event_handler;
2213 msg.flush_callback = wmi_discard_fw_event;
2214
2215 if (QDF_STATUS_SUCCESS !=
2216 scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
2217 QDF_MODULE_ID_TARGET_IF,
2218 QDF_MODULE_ID_TARGET_IF, &msg)) {
2219 qdf_nbuf_free(ev);
2220 qdf_mem_free(params_buf);
2221 return QDF_STATUS_E_FAULT;
2222 }
2223
2224 return QDF_STATUS_SUCCESS;
2225}
2226
Govind Singhd88ae7f2016-03-06 19:55:02 +05302227/**
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302228 * wmi_get_pdev_ep: Get wmi handle based on endpoint
2229 * @soc: handle to wmi soc
2230 * @ep: endpoint id
2231 *
2232 * Return: none
2233 */
2234static struct wmi_unified *wmi_get_pdev_ep(struct wmi_soc *soc,
2235 HTC_ENDPOINT_ID ep)
2236{
2237 uint32_t i;
2238
2239 for (i = 0; i < WMI_MAX_RADIOS; i++)
2240 if (soc->wmi_endpoint_id[i] == ep)
2241 break;
2242
2243 if (i == WMI_MAX_RADIOS)
2244 return NULL;
2245
2246 return soc->wmi_pdev[i];
2247}
2248
2249/**
gaurank kathpalia8a339e82018-08-03 12:00:12 +05302250 * wmi_mtrace_rx() - Wrappper function for qdf_mtrace api
2251 * @message_id: 32-Bit Wmi message ID
2252 * @vdev_id: Vdev ID
2253 * @data: Actual message contents
2254 *
2255 * This function converts the 32-bit WMI message ID in 15-bit message ID
2256 * format for qdf_mtrace as in qdf_mtrace message there are only 15
2257 * bits reserved for message ID.
2258 * out of these 15-bits, 8-bits (From LSB) specifies the WMI_GRP_ID
2259 * and remaining 7-bits specifies the actual WMI command. With this
2260 * notation there can be maximum 256 groups and each group can have
2261 * max 128 commands can be supported.
2262 *
2263 * Return: None
2264 */
2265static void wmi_mtrace_rx(uint32_t message_id, uint16_t vdev_id, uint32_t data)
2266{
2267 uint16_t mtrace_message_id;
2268
2269 mtrace_message_id = QDF_WMI_MTRACE_CMD_ID(message_id) |
2270 (QDF_WMI_MTRACE_GRP_ID(message_id) <<
2271 QDF_WMI_MTRACE_CMD_NUM_BITS);
2272 qdf_mtrace(QDF_MODULE_ID_WMI, QDF_MODULE_ID_WMA,
2273 mtrace_message_id, vdev_id, data);
2274}
2275
2276/**
Govind Singh3f302ec2016-03-09 12:03:29 +05302277 * wmi_control_rx() - process fw events callbacks
Govind Singhd88ae7f2016-03-06 19:55:02 +05302278 * @ctx: handle to wmi
2279 * @htc_packet: pointer to htc packet
2280 *
Govind Singhd88ae7f2016-03-06 19:55:02 +05302281 * Return: none
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002282 */
Jeff Johnson589ca092016-10-07 13:03:02 -07002283static void wmi_control_rx(void *ctx, HTC_PACKET *htc_packet)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002284{
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302285 struct wmi_soc *soc = (struct wmi_soc *) ctx;
2286 struct wmi_unified *wmi_handle;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002287 wmi_buf_t evt_buf;
2288 uint32_t id;
Govind Singh3f302ec2016-03-09 12:03:29 +05302289 uint32_t idx = 0;
2290 enum wmi_rx_exec_ctx exec_ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002291
2292 evt_buf = (wmi_buf_t) htc_packet->pPktContext;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302293
2294 wmi_handle = wmi_get_pdev_ep(soc, htc_packet->Endpoint);
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07002295 if (!wmi_handle) {
Sathish Kumar4c46c872018-09-20 16:07:20 +05302296 WMI_LOGE
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302297 ("unable to get wmi_handle to Endpoint %d\n",
2298 htc_packet->Endpoint);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302299 qdf_nbuf_free(evt_buf);
2300 return;
2301 }
2302
Govind Singh236fc202016-03-09 14:32:57 +05302303 id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
Govind Singh3f302ec2016-03-09 12:03:29 +05302304 idx = wmi_unified_get_event_handler_ix(wmi_handle, id);
Govind Singh236fc202016-03-09 14:32:57 +05302305 if (qdf_unlikely(idx == A_ERROR)) {
Dustin Brownf88a90f2018-10-30 10:00:37 -07002306 wmi_debug("no handler registered for event id 0x%x", id);
Govind Singh236fc202016-03-09 14:32:57 +05302307 qdf_nbuf_free(evt_buf);
Govind Singh3f302ec2016-03-09 12:03:29 +05302308 return;
2309 }
gaurank kathpalia8a339e82018-08-03 12:00:12 +05302310 wmi_mtrace_rx(id, 0xFF, idx);
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302311 qdf_spin_lock_bh(&soc->ctx_lock);
Govind Singh3f302ec2016-03-09 12:03:29 +05302312 exec_ctx = wmi_handle->ctx[idx];
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302313 qdf_spin_unlock_bh(&soc->ctx_lock);
Govind Singh3f302ec2016-03-09 12:03:29 +05302314
Houston Hoffman353f06c2017-10-11 14:50:30 -07002315#ifdef WMI_INTERFACE_EVENT_LOGGING
2316 if (wmi_handle->log_info.wmi_logging_enable) {
2317 uint8_t *data;
2318 data = qdf_nbuf_data(evt_buf);
2319
2320 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
2321 /* Exclude 4 bytes of TLV header */
Rajeev Kumar80473702018-09-19 13:02:23 -07002322 if (wmi_handle->ops->is_diag_event(id)) {
2323 WMI_DIAG_RX_EVENT_RECORD(wmi_handle, id,
2324 ((uint8_t *) data +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302325 wmi_handle->soc->buf_offset_event));
Rajeev Kumar80473702018-09-19 13:02:23 -07002326 } else if (wmi_handle->ops->is_management_record(id)) {
2327 WMI_MGMT_RX_EVENT_RECORD(wmi_handle, id,
2328 ((uint8_t *) data +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302329 wmi_handle->soc->buf_offset_event));
Rajeev Kumar80473702018-09-19 13:02:23 -07002330 } else {
2331 WMI_RX_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302332 wmi_handle->soc->buf_offset_event));
Rajeev Kumar80473702018-09-19 13:02:23 -07002333 }
Houston Hoffman353f06c2017-10-11 14:50:30 -07002334 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
2335 }
2336#endif
2337
Govind Singh3f302ec2016-03-09 12:03:29 +05302338 if (exec_ctx == WMI_RX_WORK_CTX) {
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002339 wmi_process_fw_event_worker_thread_ctx
Harprit Chhabada71c98462018-12-26 14:10:39 -08002340 (wmi_handle, evt_buf);
Sandeep Puligilla9304a972019-06-27 20:46:59 -07002341 } else if (exec_ctx == WMI_RX_TASKLET_CTX) {
2342 wmi_process_fw_event(wmi_handle, evt_buf);
2343 } else if (exec_ctx == WMI_RX_SERIALIZER_CTX) {
2344 wmi_process_fw_event_sched_thread_ctx(wmi_handle, evt_buf);
Govind Singh3f302ec2016-03-09 12:03:29 +05302345 } else {
Sathish Kumar4c46c872018-09-20 16:07:20 +05302346 WMI_LOGE("Invalid event context %d", exec_ctx);
Govind Singh236fc202016-03-09 14:32:57 +05302347 qdf_nbuf_free(evt_buf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002348 }
Govind Singh3f302ec2016-03-09 12:03:29 +05302349
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002350}
2351
Govind Singhd88ae7f2016-03-06 19:55:02 +05302352/**
2353 * wmi_process_fw_event() - process any fw event
2354 * @wmi_handle: wmi handle
2355 * @evt_buf: fw event buffer
2356 *
Govind Singh3f302ec2016-03-09 12:03:29 +05302357 * This function process fw event in caller context
Govind Singhd88ae7f2016-03-06 19:55:02 +05302358 *
2359 * Return: none
2360 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002361void wmi_process_fw_event(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf)
2362{
2363 __wmi_control_rx(wmi_handle, evt_buf);
2364}
2365
Govind Singhd88ae7f2016-03-06 19:55:02 +05302366/**
2367 * __wmi_control_rx() - process serialize wmi event callback
2368 * @wmi_handle: wmi handle
2369 * @evt_buf: fw event buffer
2370 *
2371 * Return: none
2372 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002373void __wmi_control_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf)
2374{
2375 uint32_t id;
2376 uint8_t *data;
2377 uint32_t len;
2378 void *wmi_cmd_struct_ptr = NULL;
Govind Singha5e18c42016-04-15 13:58:27 +05302379#ifndef WMI_NON_TLV_SUPPORT
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002380 int tlv_ok_status = 0;
Govind Singha5e18c42016-04-15 13:58:27 +05302381#endif
Govind Singh3f302ec2016-03-09 12:03:29 +05302382 uint32_t idx = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002383
Govind Singh236fc202016-03-09 14:32:57 +05302384 id = WMI_GET_FIELD(qdf_nbuf_data(evt_buf), WMI_CMD_HDR, COMMANDID);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002385
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +05302386 wmi_ext_dbg_msg_event_record(wmi_handle, qdf_nbuf_data(evt_buf),
2387 qdf_nbuf_len(evt_buf));
2388
Govind Singh236fc202016-03-09 14:32:57 +05302389 if (qdf_nbuf_pull_head(evt_buf, sizeof(WMI_CMD_HDR)) == NULL)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002390 goto end;
2391
Govind Singh236fc202016-03-09 14:32:57 +05302392 data = qdf_nbuf_data(evt_buf);
2393 len = qdf_nbuf_len(evt_buf);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002394
Govind Singha5e18c42016-04-15 13:58:27 +05302395#ifndef WMI_NON_TLV_SUPPORT
2396 if (wmi_handle->target_type == WMI_TLV_TARGET) {
2397 /* Validate and pad(if necessary) the TLVs */
2398 tlv_ok_status =
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302399 wmi_handle->ops->wmi_check_and_pad_event(wmi_handle->scn_handle,
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002400 data, len, id,
2401 &wmi_cmd_struct_ptr);
Govind Singha5e18c42016-04-15 13:58:27 +05302402 if (tlv_ok_status != 0) {
2403 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302404 "%s: Error: id=0x%x, wmitlv check status=%d",
2405 __func__, id, tlv_ok_status);
Govind Singha5e18c42016-04-15 13:58:27 +05302406 goto end;
2407 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002408 }
Govind Singha5e18c42016-04-15 13:58:27 +05302409#endif
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002410
Govind Singh3f302ec2016-03-09 12:03:29 +05302411 idx = wmi_unified_get_event_handler_ix(wmi_handle, id);
2412 if (idx == A_ERROR) {
Govind Singh236fc202016-03-09 14:32:57 +05302413 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_ERROR,
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05302414 "%s : event handler is not registered: event id 0x%x",
Govind Singh3f302ec2016-03-09 12:03:29 +05302415 __func__, id);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002416 goto end;
2417 }
Govind Singh3f302ec2016-03-09 12:03:29 +05302418#ifdef WMI_INTERFACE_EVENT_LOGGING
Govind Singh08bd3dc2016-05-12 12:45:51 +05302419 if (wmi_handle->log_info.wmi_logging_enable) {
2420 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
2421 /* Exclude 4 bytes of TLV header */
Rajeev Kumar80473702018-09-19 13:02:23 -07002422 if (wmi_handle->ops->is_diag_event(id)) {
2423 /*
2424 * skip diag event logging in WMI event buffer
2425 * as its already logged in WMI RX event buffer
2426 */
2427 } else if (wmi_handle->ops->is_management_record(id)) {
2428 /*
2429 * skip wmi mgmt event logging in WMI event buffer
2430 * as its already logged in WMI RX event buffer
2431 */
Govind Singh08bd3dc2016-05-12 12:45:51 +05302432 } else {
Rajeev Kumar80473702018-09-19 13:02:23 -07002433 WMI_EVENT_RECORD(wmi_handle, id, ((uint8_t *) data +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302434 wmi_handle->soc->buf_offset_event));
Govind Singh08bd3dc2016-05-12 12:45:51 +05302435 }
2436 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002437 }
Govind Singh3f302ec2016-03-09 12:03:29 +05302438#endif
2439 /* Call the WMI registered event handler */
Govind Singha5e18c42016-04-15 13:58:27 +05302440 if (wmi_handle->target_type == WMI_TLV_TARGET)
2441 wmi_handle->event_handler[idx] (wmi_handle->scn_handle,
2442 wmi_cmd_struct_ptr, len);
2443 else
2444 wmi_handle->event_handler[idx] (wmi_handle->scn_handle,
2445 data, len);
Govind Singh3f302ec2016-03-09 12:03:29 +05302446
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002447end:
Govind Singh3f302ec2016-03-09 12:03:29 +05302448 /* Free event buffer and allocated event tlv */
Govind Singha5e18c42016-04-15 13:58:27 +05302449#ifndef WMI_NON_TLV_SUPPORT
2450 if (wmi_handle->target_type == WMI_TLV_TARGET)
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302451 wmi_handle->ops->wmi_free_allocated_event(id, &wmi_cmd_struct_ptr);
Govind Singha5e18c42016-04-15 13:58:27 +05302452#endif
Kiran Venkatappa068d22d2016-08-09 22:52:35 +05302453
Govind Singh236fc202016-03-09 14:32:57 +05302454 qdf_nbuf_free(evt_buf);
Govind Singh3f302ec2016-03-09 12:03:29 +05302455
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002456}
2457
Arunk Khandavalli82a39a12017-12-06 15:47:10 +05302458#define WMI_WQ_WD_TIMEOUT (30 * 1000) /* 30s */
Govind Singhe265e332017-09-07 18:23:39 +05302459
Surabhi Vishnoie7c14012017-11-29 15:07:10 +05302460static inline void wmi_workqueue_watchdog_warn(uint32_t msg_type_id)
Govind Singhe265e332017-09-07 18:23:39 +05302461{
2462 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
Kabilan Kannan7eab01c2018-03-08 14:34:28 -08002463 "%s: WLAN_BUG_RCA: Message type %x has exceeded its alloted time of %ds",
Govind Singhe265e332017-09-07 18:23:39 +05302464 __func__, msg_type_id, WMI_WQ_WD_TIMEOUT / 1000);
2465}
2466
2467#ifdef CONFIG_SLUB_DEBUG_ON
2468static void wmi_workqueue_watchdog_bite(void *arg)
2469{
Govind Singh11c7f8b2017-11-21 10:53:40 +05302470 struct wmi_wq_dbg_info *info = arg;
2471
2472 wmi_workqueue_watchdog_warn(info->wd_msg_type_id);
2473 qdf_print_thread_trace(info->task);
2474
Govind Singhe265e332017-09-07 18:23:39 +05302475 QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR,
2476 "%s: Going down for WMI WQ Watchdog Bite!", __func__);
2477 QDF_BUG(0);
2478}
2479#else
2480static inline void wmi_workqueue_watchdog_bite(void *arg)
2481{
Govind Singh11c7f8b2017-11-21 10:53:40 +05302482 struct wmi_wq_dbg_info *info = arg;
2483
2484 wmi_workqueue_watchdog_warn(info->wd_msg_type_id);
Govind Singhe265e332017-09-07 18:23:39 +05302485}
2486#endif
2487
Govind Singhd88ae7f2016-03-06 19:55:02 +05302488/**
2489 * wmi_rx_event_work() - process rx event in rx work queue context
Rajeev Kumarbc623432017-03-29 17:14:14 -07002490 * @arg: opaque pointer to wmi handle
Govind Singhd88ae7f2016-03-06 19:55:02 +05302491 *
2492 * This function process any fw event to serialize it through rx worker thread.
2493 *
2494 * Return: none
2495 */
Rajeev Kumarbc623432017-03-29 17:14:14 -07002496static void wmi_rx_event_work(void *arg)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002497{
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002498 wmi_buf_t buf;
Rajeev Kumarbc623432017-03-29 17:14:14 -07002499 struct wmi_unified *wmi = arg;
Govind Singhe265e332017-09-07 18:23:39 +05302500 qdf_timer_t wd_timer;
Govind Singh11c7f8b2017-11-21 10:53:40 +05302501 struct wmi_wq_dbg_info info;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002502
Govind Singhe265e332017-09-07 18:23:39 +05302503 /* initialize WMI workqueue watchdog timer */
2504 qdf_timer_init(NULL, &wd_timer, &wmi_workqueue_watchdog_bite,
Govind Singh11c7f8b2017-11-21 10:53:40 +05302505 &info, QDF_TIMER_TYPE_SW);
Govind Singh236fc202016-03-09 14:32:57 +05302506 qdf_spin_lock_bh(&wmi->eventq_lock);
2507 buf = qdf_nbuf_queue_remove(&wmi->event_queue);
2508 qdf_spin_unlock_bh(&wmi->eventq_lock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002509 while (buf) {
Govind Singhe265e332017-09-07 18:23:39 +05302510 qdf_timer_start(&wd_timer, WMI_WQ_WD_TIMEOUT);
Govind Singh11c7f8b2017-11-21 10:53:40 +05302511 info.wd_msg_type_id =
Govind Singhe265e332017-09-07 18:23:39 +05302512 WMI_GET_FIELD(qdf_nbuf_data(buf), WMI_CMD_HDR, COMMANDID);
Govind Singh11c7f8b2017-11-21 10:53:40 +05302513 info.wmi_wq = wmi->wmi_rx_work_queue;
2514 info.task = qdf_get_current_task();
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002515 __wmi_control_rx(wmi, buf);
Govind Singhe265e332017-09-07 18:23:39 +05302516 qdf_timer_stop(&wd_timer);
Govind Singh236fc202016-03-09 14:32:57 +05302517 qdf_spin_lock_bh(&wmi->eventq_lock);
2518 buf = qdf_nbuf_queue_remove(&wmi->event_queue);
2519 qdf_spin_unlock_bh(&wmi->eventq_lock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002520 }
Govind Singhe265e332017-09-07 18:23:39 +05302521 qdf_timer_free(&wd_timer);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002522}
2523
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002524#ifdef FEATURE_RUNTIME_PM
2525/**
2526 * wmi_runtime_pm_init() - initialize runtime pm wmi variables
2527 * @wmi_handle: wmi context
2528 */
Govind Singh3f302ec2016-03-09 12:03:29 +05302529static void wmi_runtime_pm_init(struct wmi_unified *wmi_handle)
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002530{
Govind Singh236fc202016-03-09 14:32:57 +05302531 qdf_atomic_init(&wmi_handle->runtime_pm_inprogress);
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002532}
Govind Singh3f302ec2016-03-09 12:03:29 +05302533
2534/**
2535 * wmi_set_runtime_pm_inprogress() - set runtime pm progress flag
2536 * @wmi_handle: wmi context
2537 * @val: runtime pm progress flag
2538 */
2539void wmi_set_runtime_pm_inprogress(wmi_unified_t wmi_handle, A_BOOL val)
2540{
Govind Singh236fc202016-03-09 14:32:57 +05302541 qdf_atomic_set(&wmi_handle->runtime_pm_inprogress, val);
Govind Singh3f302ec2016-03-09 12:03:29 +05302542}
2543
2544/**
2545 * wmi_get_runtime_pm_inprogress() - get runtime pm progress flag
2546 * @wmi_handle: wmi context
2547 */
2548inline bool wmi_get_runtime_pm_inprogress(wmi_unified_t wmi_handle)
2549{
Govind Singh236fc202016-03-09 14:32:57 +05302550 return qdf_atomic_read(&wmi_handle->runtime_pm_inprogress);
Govind Singh3f302ec2016-03-09 12:03:29 +05302551}
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002552#else
Govind Singh3f302ec2016-03-09 12:03:29 +05302553static void wmi_runtime_pm_init(struct wmi_unified *wmi_handle)
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002554{
2555}
2556#endif
2557
Govind Singhd88ae7f2016-03-06 19:55:02 +05302558/**
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302559 * wmi_unified_get_soc_handle: Get WMI SoC handle
2560 * @param wmi_handle: WMI context got from wmi_attach
2561 *
2562 * return: Pointer to Soc handle
2563 */
2564void *wmi_unified_get_soc_handle(struct wmi_unified *wmi_handle)
2565{
2566 return wmi_handle->soc;
2567}
2568
2569/**
2570 * wmi_interface_logging_init: Interface looging init
2571 * @param wmi_handle: Pointer to wmi handle object
2572 *
2573 * return: None
2574 */
2575#ifdef WMI_INTERFACE_EVENT_LOGGING
c_priysb214c242018-06-12 16:53:51 +05302576static inline void wmi_interface_logging_init(struct wmi_unified *wmi_handle,
2577 uint32_t pdev_idx)
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302578{
2579 if (QDF_STATUS_SUCCESS == wmi_log_init(wmi_handle)) {
2580 qdf_spinlock_create(&wmi_handle->log_info.wmi_record_lock);
c_priysb214c242018-06-12 16:53:51 +05302581 wmi_debugfs_init(wmi_handle, pdev_idx);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302582 }
2583}
2584#else
c_priysb214c242018-06-12 16:53:51 +05302585static inline void wmi_interface_logging_init(struct wmi_unified *wmi_handle,
2586 uint32_t pdev_idx)
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302587{
2588}
2589#endif
2590
2591/**
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302592 * wmi_unified_get_pdev_handle: Get WMI SoC handle
2593 * @param wmi_soc: Pointer to wmi soc object
2594 * @param pdev_idx: pdev index
2595 *
2596 * return: Pointer to wmi handle or NULL on failure
2597 */
2598void *wmi_unified_get_pdev_handle(struct wmi_soc *soc, uint32_t pdev_idx)
2599{
2600 struct wmi_unified *wmi_handle;
2601
2602 if (pdev_idx >= WMI_MAX_RADIOS)
2603 return NULL;
2604
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07002605 if (!soc->wmi_pdev[pdev_idx]) {
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302606 wmi_handle =
2607 (struct wmi_unified *) qdf_mem_malloc(
2608 sizeof(struct wmi_unified));
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05302609 if (!wmi_handle)
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302610 return NULL;
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05302611
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302612 wmi_handle->scn_handle = soc->scn_handle;
2613 wmi_handle->event_id = soc->event_id;
2614 wmi_handle->event_handler = soc->event_handler;
2615 wmi_handle->ctx = soc->ctx;
2616 wmi_handle->ops = soc->ops;
2617 qdf_spinlock_create(&wmi_handle->eventq_lock);
2618 qdf_nbuf_queue_init(&wmi_handle->event_queue);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302619
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302620 qdf_create_work(0, &wmi_handle->rx_event_work,
2621 wmi_rx_event_work, wmi_handle);
2622 wmi_handle->wmi_rx_work_queue =
Shashikala Prabhubfd50432018-11-20 17:53:05 +05302623 qdf_alloc_unbound_workqueue("wmi_rx_event_work_queue");
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07002624 if (!wmi_handle->wmi_rx_work_queue) {
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302625 WMI_LOGE("failed to create wmi_rx_event_work_queue");
2626 goto error;
2627 }
2628 wmi_handle->wmi_events = soc->wmi_events;
Surya Prakash Raajen80638512019-02-21 19:24:35 +05302629 wmi_handle->services = soc->services;
c_priysb214c242018-06-12 16:53:51 +05302630 wmi_handle->soc = soc;
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07002631 wmi_handle->cmd_pdev_id_map = soc->cmd_pdev_id_map;
2632 wmi_handle->evt_pdev_id_map = soc->evt_pdev_id_map;
Shaakir Mohamed68a9a922020-01-10 12:02:15 -08002633 wmi_handle->cmd_phy_id_map = soc->cmd_phy_id_map;
2634 wmi_handle->evt_phy_id_map = soc->evt_phy_id_map;
c_priysb214c242018-06-12 16:53:51 +05302635 wmi_interface_logging_init(wmi_handle, pdev_idx);
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302636 qdf_atomic_init(&wmi_handle->pending_cmds);
2637 qdf_atomic_init(&wmi_handle->is_target_suspended);
2638 wmi_handle->target_type = soc->target_type;
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302639 wmi_handle->wmi_max_cmds = soc->wmi_max_cmds;
Rajeev Kumarbc623432017-03-29 17:14:14 -07002640
Kiran Venkatappaf13e82a2017-06-15 17:27:38 +05302641 soc->wmi_pdev[pdev_idx] = wmi_handle;
2642 } else
2643 wmi_handle = soc->wmi_pdev[pdev_idx];
2644
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302645 wmi_handle->wmi_stopinprogress = 0;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302646 wmi_handle->wmi_endpoint_id = soc->wmi_endpoint_id[pdev_idx];
2647 wmi_handle->htc_handle = soc->htc_handle;
2648 wmi_handle->max_msg_len = soc->max_msg_len[pdev_idx];
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302649
2650 return wmi_handle;
Rajeev Kumarbc623432017-03-29 17:14:14 -07002651
2652error:
2653 qdf_mem_free(wmi_handle);
2654
2655 return NULL;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302656}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302657qdf_export_symbol(wmi_unified_get_pdev_handle);
2658
2659static void (*wmi_attach_register[WMI_MAX_TARGET_TYPE])(wmi_unified_t);
2660
2661void wmi_unified_register_module(enum wmi_target_type target_type,
2662 void (*wmi_attach)(wmi_unified_t wmi_handle))
2663{
2664 if (target_type < WMI_MAX_TARGET_TYPE)
2665 wmi_attach_register[target_type] = wmi_attach;
2666
2667 return;
2668}
2669qdf_export_symbol(wmi_unified_register_module);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302670
2671/**
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05302672 * wmi_wbuff_register() - register wmi with wbuff
2673 * @wmi_handle: handle to wmi
2674 *
2675 * @Return: void
2676 */
2677static void wmi_wbuff_register(struct wmi_unified *wmi_handle)
2678{
2679 struct wbuff_alloc_request wbuff_alloc[4];
2680
2681 wbuff_alloc[0].slot = WBUFF_POOL_0;
2682 wbuff_alloc[0].size = WMI_WBUFF_POOL_0_SIZE;
2683 wbuff_alloc[1].slot = WBUFF_POOL_1;
2684 wbuff_alloc[1].size = WMI_WBUFF_POOL_1_SIZE;
2685 wbuff_alloc[2].slot = WBUFF_POOL_2;
2686 wbuff_alloc[2].size = WMI_WBUFF_POOL_2_SIZE;
2687 wbuff_alloc[3].slot = WBUFF_POOL_3;
2688 wbuff_alloc[3].size = WMI_WBUFF_POOL_3_SIZE;
2689
2690 wmi_handle->wbuff_handle = wbuff_module_register(wbuff_alloc, 4,
2691 WMI_MIN_HEAD_ROOM, 4);
2692}
2693
2694/**
2695 * wmi_wbuff_deregister() - deregister wmi with wbuff
2696 * @wmi_handle: handle to wmi
2697 *
2698 * @Return: void
2699 */
2700static inline void wmi_wbuff_deregister(struct wmi_unified *wmi_handle)
2701{
2702 wbuff_module_deregister(wmi_handle->wbuff_handle);
2703 wmi_handle->wbuff_handle = NULL;
2704}
2705
2706/**
Govind Singhd88ae7f2016-03-06 19:55:02 +05302707 * wmi_unified_attach() - attach for unified WMI
Govind Singh01dd33e2016-02-04 18:42:30 +05302708 * @scn_handle: handle to SCN
2709 * @osdev: OS device context
2710 * @target_type: TLV or not-TLV based target
2711 * @use_cookie: cookie based allocation enabled/disabled
2712 * @ops: umac rx callbacks
Mukul Sharma45223f32017-01-30 19:55:40 +05302713 * @psoc: objmgr psoc
Govind Singhd88ae7f2016-03-06 19:55:02 +05302714 *
2715 * @Return: wmi handle.
2716 */
Govind Singh01dd33e2016-02-04 18:42:30 +05302717void *wmi_unified_attach(void *scn_handle,
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302718 struct wmi_unified_attach_params *param)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002719{
2720 struct wmi_unified *wmi_handle;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302721 struct wmi_soc *soc;
Govind Singha5e18c42016-04-15 13:58:27 +05302722
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302723 soc = (struct wmi_soc *) qdf_mem_malloc(sizeof(struct wmi_soc));
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05302724 if (!soc)
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302725 return NULL;
Mukul Sharma396cef72017-11-03 19:26:54 +05302726
Govind Singha5e18c42016-04-15 13:58:27 +05302727 wmi_handle =
2728 (struct wmi_unified *) qdf_mem_malloc(
2729 sizeof(struct wmi_unified));
Madhvapathi Sriram610c0c82019-01-07 09:33:56 +05302730 if (!wmi_handle) {
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302731 qdf_mem_free(soc);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002732 return NULL;
2733 }
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302734 wmi_handle->soc = soc;
c_priysb214c242018-06-12 16:53:51 +05302735 wmi_handle->soc->soc_idx = param->soc_id;
phadimane5a330a2018-11-13 12:04:07 +05302736 wmi_handle->soc->is_async_ep = param->is_async_ep;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302737 wmi_handle->event_id = soc->event_id;
2738 wmi_handle->event_handler = soc->event_handler;
2739 wmi_handle->ctx = soc->ctx;
Soumya Bhat8b71edb2017-03-22 14:41:01 +05302740 wmi_handle->wmi_events = soc->wmi_events;
Surya Prakash Raajen80638512019-02-21 19:24:35 +05302741 wmi_handle->services = soc->services;
Govind Singha5e18c42016-04-15 13:58:27 +05302742 wmi_handle->scn_handle = scn_handle;
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07002743 wmi_handle->cmd_pdev_id_map = soc->cmd_pdev_id_map;
2744 wmi_handle->evt_pdev_id_map = soc->evt_pdev_id_map;
Shaakir Mohamed68a9a922020-01-10 12:02:15 -08002745 wmi_handle->cmd_phy_id_map = soc->cmd_phy_id_map;
2746 wmi_handle->evt_phy_id_map = soc->evt_phy_id_map;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302747 soc->scn_handle = scn_handle;
Govind Singh236fc202016-03-09 14:32:57 +05302748 qdf_atomic_init(&wmi_handle->pending_cmds);
2749 qdf_atomic_init(&wmi_handle->is_target_suspended);
Alan Chenb2bc5592019-10-03 16:22:59 -07002750 qdf_atomic_init(&wmi_handle->num_stats_over_qmi);
Houston Hoffmanc5141b02015-11-18 02:36:30 -08002751 wmi_runtime_pm_init(wmi_handle);
Govind Singh236fc202016-03-09 14:32:57 +05302752 qdf_spinlock_create(&wmi_handle->eventq_lock);
2753 qdf_nbuf_queue_init(&wmi_handle->event_queue);
Rajeev Kumarbc623432017-03-29 17:14:14 -07002754 qdf_create_work(0, &wmi_handle->rx_event_work,
2755 wmi_rx_event_work, wmi_handle);
2756 wmi_handle->wmi_rx_work_queue =
Shashikala Prabhubfd50432018-11-20 17:53:05 +05302757 qdf_alloc_unbound_workqueue("wmi_rx_event_work_queue");
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07002758 if (!wmi_handle->wmi_rx_work_queue) {
Rajeev Kumarbc623432017-03-29 17:14:14 -07002759 WMI_LOGE("failed to create wmi_rx_event_work_queue");
2760 goto error;
2761 }
c_priysb214c242018-06-12 16:53:51 +05302762 wmi_interface_logging_init(wmi_handle, WMI_HOST_PDEV_ID_0);
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302763 wmi_handle->target_type = param->target_type;
2764 soc->target_type = param->target_type;
Abhiram Jogadenu9c5c6132018-05-14 17:13:28 +05302765
2766 if (param->target_type >= WMI_MAX_TARGET_TYPE)
2767 goto error;
2768
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302769 if (wmi_attach_register[param->target_type]) {
2770 wmi_attach_register[param->target_type](wmi_handle);
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05302771 } else {
2772 WMI_LOGE("wmi attach is not registered");
2773 goto error;
2774 }
Govind Singh01dd33e2016-02-04 18:42:30 +05302775 /* Assign target cookie capablity */
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302776 wmi_handle->use_cookie = param->use_cookie;
2777 wmi_handle->osdev = param->osdev;
Govind Singha5e18c42016-04-15 13:58:27 +05302778 wmi_handle->wmi_stopinprogress = 0;
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302779 wmi_handle->wmi_max_cmds = param->max_commands;
2780 soc->wmi_max_cmds = param->max_commands;
Mukul Sharma45223f32017-01-30 19:55:40 +05302781 /* Increase the ref count once refcount infra is present */
Chaithanya Garrepalli830d5852017-12-01 14:55:26 +05302782 soc->wmi_psoc = param->psoc;
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302783 qdf_spinlock_create(&soc->ctx_lock);
Govind Singhd88ae7f2016-03-06 19:55:02 +05302784
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302785 soc->ops = wmi_handle->ops;
2786 soc->wmi_pdev[0] = wmi_handle;
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +05302787 if (wmi_ext_dbgfs_init(wmi_handle) != QDF_STATUS_SUCCESS)
Sathish Kumar4c46c872018-09-20 16:07:20 +05302788 WMI_LOGE("failed to initialize wmi extended debugfs");
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302789
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05302790 wmi_wbuff_register(wmi_handle);
2791
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002792 return wmi_handle;
Rajeev Kumarbc623432017-03-29 17:14:14 -07002793
2794error:
2795 qdf_mem_free(soc);
2796 qdf_mem_free(wmi_handle);
2797
2798 return NULL;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002799}
2800
Govind Singhd88ae7f2016-03-06 19:55:02 +05302801/**
2802 * wmi_unified_detach() - detach for unified WMI
2803 *
2804 * @wmi_handle : handle to wmi.
2805 *
2806 * @Return: none.
2807 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002808void wmi_unified_detach(struct wmi_unified *wmi_handle)
2809{
2810 wmi_buf_t buf;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302811 struct wmi_soc *soc;
2812 uint8_t i;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002813
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05302814 wmi_wbuff_deregister(wmi_handle);
2815
Venkat Karthik Kantamnenif902e522018-05-21 19:13:02 +05302816 wmi_ext_dbgfs_deinit(wmi_handle);
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05302817
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302818 soc = wmi_handle->soc;
2819 for (i = 0; i < WMI_MAX_RADIOS; i++) {
2820 if (soc->wmi_pdev[i]) {
Rajeev Kumarbc623432017-03-29 17:14:14 -07002821 qdf_flush_workqueue(0,
2822 soc->wmi_pdev[i]->wmi_rx_work_queue);
2823 qdf_destroy_workqueue(0,
2824 soc->wmi_pdev[i]->wmi_rx_work_queue);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302825 wmi_debugfs_remove(soc->wmi_pdev[i]);
2826 buf = qdf_nbuf_queue_remove(
2827 &soc->wmi_pdev[i]->event_queue);
2828 while (buf) {
2829 qdf_nbuf_free(buf);
2830 buf = qdf_nbuf_queue_remove(
2831 &soc->wmi_pdev[i]->event_queue);
2832 }
Rajeev Kumar177f6212016-05-25 16:07:23 -07002833
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302834 wmi_log_buffer_free(soc->wmi_pdev[i]);
Wu Gaoa5e5c642017-06-23 16:39:17 +08002835
2836 /* Free events logs list */
2837 if (soc->wmi_pdev[i]->events_logs_list)
2838 qdf_mem_free(
2839 soc->wmi_pdev[i]->events_logs_list);
2840
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302841 qdf_spinlock_destroy(&soc->wmi_pdev[i]->eventq_lock);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302842 qdf_mem_free(soc->wmi_pdev[i]);
2843 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002844 }
Kiran Venkatappaef66f6d2017-03-20 20:38:44 +05302845 qdf_spinlock_destroy(&soc->ctx_lock);
Kiran Venkatappa482bc5e2017-09-01 17:02:34 +05302846
2847 if (soc->wmi_service_bitmap) {
2848 qdf_mem_free(soc->wmi_service_bitmap);
2849 soc->wmi_service_bitmap = NULL;
2850 }
2851
2852 if (soc->wmi_ext_service_bitmap) {
2853 qdf_mem_free(soc->wmi_ext_service_bitmap);
2854 soc->wmi_ext_service_bitmap = NULL;
2855 }
2856
Mukul Sharma45223f32017-01-30 19:55:40 +05302857 /* Decrease the ref count once refcount infra is present */
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302858 soc->wmi_psoc = NULL;
2859 qdf_mem_free(soc);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002860}
2861
Xun Luo9a863a42015-11-10 08:24:45 -08002862/**
2863 * wmi_unified_remove_work() - detach for WMI work
2864 * @wmi_handle: handle to WMI
2865 *
2866 * A function that does not fully detach WMI, but just remove work
2867 * queue items associated with it. This is used to make sure that
2868 * before any other processing code that may destroy related contexts
2869 * (HTC, etc), work queue processing on WMI has already been stopped.
2870 *
2871 * Return: None
2872 */
2873void
2874wmi_unified_remove_work(struct wmi_unified *wmi_handle)
2875{
2876 wmi_buf_t buf;
2877
Rajeev Kumarbc623432017-03-29 17:14:14 -07002878 qdf_flush_workqueue(0, wmi_handle->wmi_rx_work_queue);
Govind Singh236fc202016-03-09 14:32:57 +05302879 qdf_spin_lock_bh(&wmi_handle->eventq_lock);
2880 buf = qdf_nbuf_queue_remove(&wmi_handle->event_queue);
Xun Luo9a863a42015-11-10 08:24:45 -08002881 while (buf) {
Govind Singh236fc202016-03-09 14:32:57 +05302882 qdf_nbuf_free(buf);
2883 buf = qdf_nbuf_queue_remove(&wmi_handle->event_queue);
Xun Luo9a863a42015-11-10 08:24:45 -08002884 }
Govind Singh236fc202016-03-09 14:32:57 +05302885 qdf_spin_unlock_bh(&wmi_handle->eventq_lock);
Xun Luo9a863a42015-11-10 08:24:45 -08002886}
2887
Govind Singha5e18c42016-04-15 13:58:27 +05302888/**
2889 * wmi_htc_tx_complete() - Process htc tx completion
2890 *
2891 * @ctx: handle to wmi
2892 * @htc_packet: pointer to htc packet
2893 *
2894 * @Return: none.
2895 */
Jeff Johnson589ca092016-10-07 13:03:02 -07002896static void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002897{
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302898 struct wmi_soc *soc = (struct wmi_soc *) ctx;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002899 wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
Govind Singh0f785152016-09-02 15:24:25 +05302900 u_int8_t *buf_ptr;
2901 u_int32_t len;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302902 struct wmi_unified *wmi_handle;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002903#ifdef WMI_INTERFACE_EVENT_LOGGING
2904 uint32_t cmd_id;
2905#endif
2906
2907 ASSERT(wmi_cmd_buf);
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302908 wmi_handle = wmi_get_pdev_ep(soc, htc_pkt->Endpoint);
Jeff Johnsonab5b78d2019-03-18 09:37:23 -07002909 if (!wmi_handle) {
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302910 WMI_LOGE("%s: Unable to get wmi handle\n", __func__);
2911 QDF_ASSERT(0);
2912 return;
2913 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002914#ifdef WMI_INTERFACE_EVENT_LOGGING
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302915 if (wmi_handle && wmi_handle->log_info.wmi_logging_enable) {
Govind Singh08bd3dc2016-05-12 12:45:51 +05302916 cmd_id = WMI_GET_FIELD(qdf_nbuf_data(wmi_cmd_buf),
2917 WMI_CMD_HDR, COMMANDID);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002918
Govind Singh08bd3dc2016-05-12 12:45:51 +05302919 qdf_spin_lock_bh(&wmi_handle->log_info.wmi_record_lock);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002920 /* Record 16 bytes of WMI cmd tx complete data
Govind Singh08bd3dc2016-05-12 12:45:51 +05302921 - exclude TLV and WMI headers */
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302922 if (wmi_handle->ops->is_management_record(cmd_id)) {
Govind Singh08bd3dc2016-05-12 12:45:51 +05302923 WMI_MGMT_COMMAND_TX_CMP_RECORD(wmi_handle, cmd_id,
Rakesh Pillai6b0c64f2017-12-27 14:08:59 +05302924 qdf_nbuf_data(wmi_cmd_buf) +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302925 wmi_handle->soc->buf_offset_command);
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -08002926 } else {
Govind Singh08bd3dc2016-05-12 12:45:51 +05302927 WMI_COMMAND_TX_CMP_RECORD(wmi_handle, cmd_id,
Rakesh Pillai6b0c64f2017-12-27 14:08:59 +05302928 qdf_nbuf_data(wmi_cmd_buf) +
Pratik Gandhi5526a552018-10-10 12:12:32 +05302929 wmi_handle->soc->buf_offset_command);
Manjunathappa Prakash3044c6e2015-12-04 00:08:58 -08002930 }
2931
Govind Singh08bd3dc2016-05-12 12:45:51 +05302932 qdf_spin_unlock_bh(&wmi_handle->log_info.wmi_record_lock);
2933 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002934#endif
Govind Singh0f785152016-09-02 15:24:25 +05302935 buf_ptr = (u_int8_t *) wmi_buf_data(wmi_cmd_buf);
2936 len = qdf_nbuf_len(wmi_cmd_buf);
2937 qdf_mem_zero(buf_ptr, len);
Rakshith Suresh Patkar1f184542018-09-12 16:51:30 +05302938 wmi_buf_free(wmi_cmd_buf);
Govind Singh236fc202016-03-09 14:32:57 +05302939 qdf_mem_free(htc_pkt);
2940 qdf_atomic_dec(&wmi_handle->pending_cmds);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002941}
2942
Yue Ma4986b252019-07-23 15:57:48 -07002943#ifdef FEATURE_RUNTIME_PM
2944/**
2945 * wmi_htc_log_pkt() - Print information of WMI command from HTC packet
2946 *
2947 * @ctx: handle of WMI context
2948 * @htc_pkt: handle of HTC packet
2949 *
2950 * @Return: none
2951 */
2952static void wmi_htc_log_pkt(void *ctx, HTC_PACKET *htc_pkt)
2953{
2954 wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
2955 uint32_t cmd_id;
2956
2957 ASSERT(wmi_cmd_buf);
2958 cmd_id = WMI_GET_FIELD(qdf_nbuf_data(wmi_cmd_buf), WMI_CMD_HDR,
2959 COMMANDID);
2960
Yue Maa7203102019-08-30 14:19:11 -07002961 WMI_LOGD("WMI command from HTC packet: %s, ID: %d\n",
Yue Ma4986b252019-07-23 15:57:48 -07002962 wmi_id_to_name(cmd_id), cmd_id);
2963}
2964#else
2965static void wmi_htc_log_pkt(void *ctx, HTC_PACKET *htc_pkt)
2966{
2967}
2968#endif
2969
Govind Singhd88ae7f2016-03-06 19:55:02 +05302970/**
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302971 * wmi_connect_pdev_htc_service() - WMI API to get connect to HTC service
Govind Singhd88ae7f2016-03-06 19:55:02 +05302972 *
2973 * @wmi_handle: handle to WMI.
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302974 * @pdev_idx: Pdev index
Govind Singhd88ae7f2016-03-06 19:55:02 +05302975 *
Dustin Brown3fe77af2019-02-25 11:58:59 -08002976 * @Return: QDF_STATUS
Govind Singhd88ae7f2016-03-06 19:55:02 +05302977 */
Dustin Brown3fe77af2019-02-25 11:58:59 -08002978static QDF_STATUS wmi_connect_pdev_htc_service(struct wmi_soc *soc,
2979 uint32_t pdev_idx)
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002980{
Dustin Brown3fe77af2019-02-25 11:58:59 -08002981 QDF_STATUS status;
Manikandan Mohane3e209e2017-04-13 20:19:26 -07002982 struct htc_service_connect_resp response;
2983 struct htc_service_connect_req connect;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002984
2985 OS_MEMZERO(&connect, sizeof(connect));
2986 OS_MEMZERO(&response, sizeof(response));
2987
2988 /* meta data is unused for now */
2989 connect.pMetaData = NULL;
2990 connect.MetaDataLength = 0;
2991 /* these fields are the same for all service endpoints */
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05302992 connect.EpCallbacks.pContext = soc;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08002993 connect.EpCallbacks.EpTxCompleteMultiple =
2994 NULL /* Control path completion ar6000_tx_complete */;
2995 connect.EpCallbacks.EpRecv = wmi_control_rx /* Control path rx */;
2996 connect.EpCallbacks.EpRecvRefill = NULL /* ar6000_rx_refill */;
2997 connect.EpCallbacks.EpSendFull = NULL /* ar6000_tx_queue_full */;
2998 connect.EpCallbacks.EpTxComplete =
2999 wmi_htc_tx_complete /* ar6000_tx_queue_full */;
Yue Ma4986b252019-07-23 15:57:48 -07003000 connect.EpCallbacks.ep_log_pkt = wmi_htc_log_pkt;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003001
3002 /* connect to control service */
Pratik Gandhi78461502018-02-05 17:22:41 +05303003 connect.service_id = soc->svc_ids[pdev_idx];
Dustin Brown3fe77af2019-02-25 11:58:59 -08003004 status = htc_connect_service(soc->htc_handle, &connect, &response);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003005
Dustin Brown3fe77af2019-02-25 11:58:59 -08003006 if (QDF_IS_STATUS_ERROR(status)) {
3007 WMI_LOGE("Failed to connect to WMI CONTROL service status:%d\n",
3008 status);
Govind Singhd88ae7f2016-03-06 19:55:02 +05303009 return status;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003010 }
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003011
phadimane5a330a2018-11-13 12:04:07 +05303012 if (soc->is_async_ep)
3013 htc_set_async_ep(soc->htc_handle, response.Endpoint, true);
phadiman1a2f48a2018-10-10 15:53:03 +05303014
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05303015 soc->wmi_endpoint_id[pdev_idx] = response.Endpoint;
3016 soc->max_msg_len[pdev_idx] = response.MaxMsgLength;
3017
Dustin Brown3fe77af2019-02-25 11:58:59 -08003018 return QDF_STATUS_SUCCESS;
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05303019}
3020
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05303021QDF_STATUS
3022wmi_unified_connect_htc_service(struct wmi_unified *wmi_handle,
Himanshu Batra032d3522019-07-10 12:36:06 +05303023 HTC_HANDLE htc_handle)
Kiran Venkatappab5c5b532017-02-10 16:57:59 +05303024{
3025 uint32_t i;
3026 uint8_t wmi_ep_count;
3027
3028 wmi_handle->soc->htc_handle = htc_handle;
3029
3030 wmi_ep_count = htc_get_wmi_endpoint_count(htc_handle);
3031 if (wmi_ep_count > WMI_MAX_RADIOS)
3032 return QDF_STATUS_E_FAULT;
3033
3034 for (i = 0; i < wmi_ep_count; i++)
3035 wmi_connect_pdev_htc_service(wmi_handle->soc, i);
3036
3037 wmi_handle->htc_handle = htc_handle;
3038 wmi_handle->wmi_endpoint_id = wmi_handle->soc->wmi_endpoint_id[0];
3039 wmi_handle->max_msg_len = wmi_handle->soc->max_msg_len[0];
3040
3041 return QDF_STATUS_SUCCESS;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003042}
3043
Govind Singhd88ae7f2016-03-06 19:55:02 +05303044/**
3045 * wmi_get_host_credits() - WMI API to get updated host_credits
3046 *
3047 * @wmi_handle: handle to WMI.
3048 *
3049 * @Return: updated host_credits.
3050 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003051int wmi_get_host_credits(wmi_unified_t wmi_handle)
3052{
Govind Singha5e18c42016-04-15 13:58:27 +05303053 int host_credits = 0;
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003054
3055 htc_get_control_endpoint_tx_host_credits(wmi_handle->htc_handle,
3056 &host_credits);
3057 return host_credits;
3058}
3059
Govind Singhd88ae7f2016-03-06 19:55:02 +05303060/**
Govind Singha5e18c42016-04-15 13:58:27 +05303061 * wmi_get_pending_cmds() - WMI API to get WMI Pending Commands in the HTC
3062 * queue
Govind Singhd88ae7f2016-03-06 19:55:02 +05303063 *
3064 * @wmi_handle: handle to WMI.
3065 *
3066 * @Return: Pending Commands in the HTC queue.
3067 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003068int wmi_get_pending_cmds(wmi_unified_t wmi_handle)
3069{
Govind Singh236fc202016-03-09 14:32:57 +05303070 return qdf_atomic_read(&wmi_handle->pending_cmds);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003071}
3072
Govind Singhd88ae7f2016-03-06 19:55:02 +05303073/**
3074 * wmi_set_target_suspend() - WMI API to set target suspend state
3075 *
3076 * @wmi_handle: handle to WMI.
3077 * @val: suspend state boolean.
3078 *
3079 * @Return: none.
3080 */
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003081void wmi_set_target_suspend(wmi_unified_t wmi_handle, A_BOOL val)
3082{
Govind Singh236fc202016-03-09 14:32:57 +05303083 qdf_atomic_set(&wmi_handle->is_target_suspended, val);
Prakash Dhavalid5c9f1c2015-11-08 19:04:44 -08003084}
3085
Sarada Prasanna Garnayak6249b432017-01-05 19:30:07 +05303086/**
Ajit Pal Singheb5bf8c2019-03-28 19:23:40 +05303087 * wmi_is_target_suspended() - WMI API to check target suspend state
3088 * @wmi_handle: handle to WMI.
3089 *
3090 * WMI API to check target suspend state
3091 *
3092 * Return: true if target is suspended, else false.
3093 */
3094bool wmi_is_target_suspended(struct wmi_unified *wmi_handle)
3095{
3096 return qdf_atomic_read(&wmi_handle->is_target_suspended);
3097}
3098
3099/**
Sarada Prasanna Garnayak6249b432017-01-05 19:30:07 +05303100 * WMI API to set crash injection state
3101 * @param wmi_handle: handle to WMI.
3102 * @param val: crash injection state boolean.
3103 */
3104void wmi_tag_crash_inject(wmi_unified_t wmi_handle, A_BOOL flag)
3105{
3106 wmi_handle->tag_crash_inject = flag;
3107}
3108
3109/**
3110 * WMI API to set bus suspend state
3111 * @param wmi_handle: handle to WMI.
3112 * @param val: suspend state boolean.
3113 */
3114void wmi_set_is_wow_bus_suspended(wmi_unified_t wmi_handle, A_BOOL val)
3115{
3116 qdf_atomic_set(&wmi_handle->is_wow_bus_suspended, val);
3117}
3118
Ravi Kumar Bokka0090e222016-11-09 18:07:56 +05303119void wmi_set_tgt_assert(wmi_unified_t wmi_handle, bool val)
3120{
3121 wmi_handle->tgt_force_assert_enable = val;
3122}
3123
Kabilan Kannan2c0da262018-02-21 13:41:00 -08003124/**
3125 * wmi_stop() - generic function to block unified WMI command
3126 * @wmi_handle: handle to WMI.
3127 *
3128 * @Return: success always.
3129 */
3130int
3131wmi_stop(wmi_unified_t wmi_handle)
3132{
3133 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
Aditya Sathishca0ebcd2018-07-02 17:31:55 +05303134 "WMI Stop");
Kabilan Kannan2c0da262018-02-21 13:41:00 -08003135 wmi_handle->wmi_stopinprogress = 1;
3136 return 0;
3137}
3138
Govind Singha5e18c42016-04-15 13:58:27 +05303139/**
Manoj Ekbote9c0ec6c2019-10-29 23:05:09 -07003140 * wmi_start() - generic function to allow unified WMI command
3141 * @wmi_handle: handle to WMI.
3142 *
3143 * @Return: success always.
3144 */
3145int
3146wmi_start(wmi_unified_t wmi_handle)
3147{
3148 QDF_TRACE(QDF_MODULE_ID_WMI, QDF_TRACE_LEVEL_INFO,
3149 "WMI Start");
3150 wmi_handle->wmi_stopinprogress = 0;
3151 return 0;
3152}
3153
3154/**
Govind Singha5e18c42016-04-15 13:58:27 +05303155 * API to flush all the previous packets associated with the wmi endpoint
3156 *
3157 * @param wmi_handle : handle to WMI.
3158 */
3159void
3160wmi_flush_endpoint(wmi_unified_t wmi_handle)
3161{
3162 htc_flush_endpoint(wmi_handle->htc_handle,
3163 wmi_handle->wmi_endpoint_id, 0);
3164}
Pratik Gandhi6c8fdba2018-01-30 19:05:41 +05303165qdf_export_symbol(wmi_flush_endpoint);
Govind Singha5e18c42016-04-15 13:58:27 +05303166
3167/**
Shaakir Mohamed68a9a922020-01-10 12:02:15 -08003168 * wmi_pdev_id_conversion_enable() - API to enable pdev_id/phy_id conversion
3169 * in WMI. By default pdev_id conversion is not done in WMI.
Kiran Venkatappa8dfac072017-05-10 16:24:51 +05303170 * This API can be used enable conversion in WMI.
3171 * @param wmi_handle : handle to WMI
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07003172 * @param pdev_map : pointer to pdev_map
3173 * @size : size of pdev_id_map
Kiran Venkatappa8dfac072017-05-10 16:24:51 +05303174 * Return none
3175 */
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07003176void wmi_pdev_id_conversion_enable(wmi_unified_t wmi_handle,
Shaakir Mohamed68a9a922020-01-10 12:02:15 -08003177 uint32_t *pdev_id_map,
3178 uint8_t size)
Kiran Venkatappa8dfac072017-05-10 16:24:51 +05303179{
3180 if (wmi_handle->target_type == WMI_TLV_TARGET)
Shaakir Mohamedaf7c6e02019-08-09 14:22:46 -07003181 wmi_handle->ops->wmi_pdev_id_conversion_enable(wmi_handle,
3182 pdev_id_map,
3183 size);
Kiran Venkatappa8dfac072017-05-10 16:24:51 +05303184}