1// SPDX-License-Identifier: BSD-3-Clause-Clear
2/*
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4 */
5
6#include <linux/elf.h>
7
8#include "qmi.h"
9#include "core.h"
10#include "debug.h"
11#include <linux/of.h>
12#include <linux/firmware.h>
13
14#define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x02
15#define HOST_CSTATE_BIT			0x04
16
17static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
18	{
19		.data_type	= QMI_OPT_FLAG,
20		.elem_len	= 1,
21		.elem_size	= sizeof(u8),
22		.array_type	= NO_ARRAY,
23		.tlv_type	= 0x10,
24		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
25					   num_clients_valid),
26	},
27	{
28		.data_type	= QMI_UNSIGNED_4_BYTE,
29		.elem_len	= 1,
30		.elem_size	= sizeof(u32),
31		.array_type	= NO_ARRAY,
32		.tlv_type	= 0x10,
33		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
34					   num_clients),
35	},
36	{
37		.data_type	= QMI_OPT_FLAG,
38		.elem_len	= 1,
39		.elem_size	= sizeof(u8),
40		.array_type	= NO_ARRAY,
41		.tlv_type	= 0x11,
42		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
43					   wake_msi_valid),
44	},
45	{
46		.data_type	= QMI_UNSIGNED_4_BYTE,
47		.elem_len	= 1,
48		.elem_size	= sizeof(u32),
49		.array_type	= NO_ARRAY,
50		.tlv_type	= 0x11,
51		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
52					   wake_msi),
53	},
54	{
55		.data_type	= QMI_OPT_FLAG,
56		.elem_len	= 1,
57		.elem_size	= sizeof(u8),
58		.array_type	= NO_ARRAY,
59		.tlv_type	= 0x12,
60		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
61					   gpios_valid),
62	},
63	{
64		.data_type	= QMI_DATA_LEN,
65		.elem_len	= 1,
66		.elem_size	= sizeof(u8),
67		.array_type	= NO_ARRAY,
68		.tlv_type	= 0x12,
69		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
70					   gpios_len),
71	},
72	{
73		.data_type	= QMI_UNSIGNED_4_BYTE,
74		.elem_len	= QMI_WLFW_MAX_NUM_GPIO_V01,
75		.elem_size	= sizeof(u32),
76		.array_type	= VAR_LEN_ARRAY,
77		.tlv_type	= 0x12,
78		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
79					   gpios),
80	},
81	{
82		.data_type	= QMI_OPT_FLAG,
83		.elem_len	= 1,
84		.elem_size	= sizeof(u8),
85		.array_type	= NO_ARRAY,
86		.tlv_type	= 0x13,
87		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
88					   nm_modem_valid),
89	},
90	{
91		.data_type	= QMI_UNSIGNED_1_BYTE,
92		.elem_len	= 1,
93		.elem_size	= sizeof(u8),
94		.array_type	= NO_ARRAY,
95		.tlv_type	= 0x13,
96		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
97					   nm_modem),
98	},
99	{
100		.data_type	= QMI_OPT_FLAG,
101		.elem_len	= 1,
102		.elem_size	= sizeof(u8),
103		.array_type	= NO_ARRAY,
104		.tlv_type	= 0x14,
105		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
106					   bdf_support_valid),
107	},
108	{
109		.data_type	= QMI_UNSIGNED_1_BYTE,
110		.elem_len	= 1,
111		.elem_size	= sizeof(u8),
112		.array_type	= NO_ARRAY,
113		.tlv_type	= 0x14,
114		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
115					   bdf_support),
116	},
117	{
118		.data_type	= QMI_OPT_FLAG,
119		.elem_len	= 1,
120		.elem_size	= sizeof(u8),
121		.array_type	= NO_ARRAY,
122		.tlv_type	= 0x15,
123		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
124					   bdf_cache_support_valid),
125	},
126	{
127		.data_type	= QMI_UNSIGNED_1_BYTE,
128		.elem_len	= 1,
129		.elem_size	= sizeof(u8),
130		.array_type	= NO_ARRAY,
131		.tlv_type	= 0x15,
132		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
133					   bdf_cache_support),
134	},
135	{
136		.data_type	= QMI_OPT_FLAG,
137		.elem_len	= 1,
138		.elem_size	= sizeof(u8),
139		.array_type	= NO_ARRAY,
140		.tlv_type	= 0x16,
141		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
142					   m3_support_valid),
143	},
144	{
145		.data_type	= QMI_UNSIGNED_1_BYTE,
146		.elem_len	= 1,
147		.elem_size	= sizeof(u8),
148		.array_type	= NO_ARRAY,
149		.tlv_type	= 0x16,
150		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
151					   m3_support),
152	},
153	{
154		.data_type	= QMI_OPT_FLAG,
155		.elem_len	= 1,
156		.elem_size	= sizeof(u8),
157		.array_type	= NO_ARRAY,
158		.tlv_type	= 0x17,
159		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
160					   m3_cache_support_valid),
161	},
162	{
163		.data_type	= QMI_UNSIGNED_1_BYTE,
164		.elem_len	= 1,
165		.elem_size	= sizeof(u8),
166		.array_type	= NO_ARRAY,
167		.tlv_type	= 0x17,
168		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
169					   m3_cache_support),
170	},
171	{
172		.data_type	= QMI_OPT_FLAG,
173		.elem_len	= 1,
174		.elem_size	= sizeof(u8),
175		.array_type	= NO_ARRAY,
176		.tlv_type	= 0x18,
177		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
178					   cal_filesys_support_valid),
179	},
180	{
181		.data_type	= QMI_UNSIGNED_1_BYTE,
182		.elem_len	= 1,
183		.elem_size	= sizeof(u8),
184		.array_type	= NO_ARRAY,
185		.tlv_type	= 0x18,
186		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
187					   cal_filesys_support),
188	},
189	{
190		.data_type	= QMI_OPT_FLAG,
191		.elem_len	= 1,
192		.elem_size	= sizeof(u8),
193		.array_type	= NO_ARRAY,
194		.tlv_type	= 0x19,
195		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
196					   cal_cache_support_valid),
197	},
198	{
199		.data_type	= QMI_UNSIGNED_1_BYTE,
200		.elem_len	= 1,
201		.elem_size	= sizeof(u8),
202		.array_type	= NO_ARRAY,
203		.tlv_type	= 0x19,
204		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
205					   cal_cache_support),
206	},
207	{
208		.data_type	= QMI_OPT_FLAG,
209		.elem_len	= 1,
210		.elem_size	= sizeof(u8),
211		.array_type	= NO_ARRAY,
212		.tlv_type	= 0x1A,
213		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
214					   cal_done_valid),
215	},
216	{
217		.data_type	= QMI_UNSIGNED_1_BYTE,
218		.elem_len	= 1,
219		.elem_size	= sizeof(u8),
220		.array_type	= NO_ARRAY,
221		.tlv_type	= 0x1A,
222		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
223					   cal_done),
224	},
225	{
226		.data_type	= QMI_OPT_FLAG,
227		.elem_len	= 1,
228		.elem_size	= sizeof(u8),
229		.array_type	= NO_ARRAY,
230		.tlv_type	= 0x1B,
231		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
232					   mem_bucket_valid),
233	},
234	{
235		.data_type	= QMI_UNSIGNED_4_BYTE,
236		.elem_len	= 1,
237		.elem_size	= sizeof(u32),
238		.array_type	= NO_ARRAY,
239		.tlv_type	= 0x1B,
240		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
241					   mem_bucket),
242	},
243	{
244		.data_type	= QMI_OPT_FLAG,
245		.elem_len	= 1,
246		.elem_size	= sizeof(u8),
247		.array_type	= NO_ARRAY,
248		.tlv_type	= 0x1C,
249		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
250					   mem_cfg_mode_valid),
251	},
252	{
253		.data_type	= QMI_UNSIGNED_1_BYTE,
254		.elem_len	= 1,
255		.elem_size	= sizeof(u8),
256		.array_type	= NO_ARRAY,
257		.tlv_type	= 0x1C,
258		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
259					   mem_cfg_mode),
260	},
261	{
262		.data_type	= QMI_EOTI,
263		.array_type	= NO_ARRAY,
264		.tlv_type	= QMI_COMMON_TLV_TYPE,
265	},
266};
267
268static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
269	{
270		.data_type	= QMI_STRUCT,
271		.elem_len	= 1,
272		.elem_size	= sizeof(struct qmi_response_type_v01),
273		.array_type	= NO_ARRAY,
274		.tlv_type	= 0x02,
275		.offset		= offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
276		.ei_array	= qmi_response_type_v01_ei,
277	},
278	{
279		.data_type	= QMI_EOTI,
280		.array_type	= NO_ARRAY,
281		.tlv_type	= QMI_COMMON_TLV_TYPE,
282	},
283};
284
285static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
286	{
287		.data_type	= QMI_OPT_FLAG,
288		.elem_len	= 1,
289		.elem_size	= sizeof(u8),
290		.array_type	= NO_ARRAY,
291		.tlv_type	= 0x10,
292		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
293					   fw_ready_enable_valid),
294	},
295	{
296		.data_type	= QMI_UNSIGNED_1_BYTE,
297		.elem_len	= 1,
298		.elem_size	= sizeof(u8),
299		.array_type	= NO_ARRAY,
300		.tlv_type	= 0x10,
301		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
302					   fw_ready_enable),
303	},
304	{
305		.data_type	= QMI_OPT_FLAG,
306		.elem_len	= 1,
307		.elem_size	= sizeof(u8),
308		.array_type	= NO_ARRAY,
309		.tlv_type	= 0x11,
310		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
311					   initiate_cal_download_enable_valid),
312	},
313	{
314		.data_type	= QMI_UNSIGNED_1_BYTE,
315		.elem_len	= 1,
316		.elem_size	= sizeof(u8),
317		.array_type	= NO_ARRAY,
318		.tlv_type	= 0x11,
319		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
320					   initiate_cal_download_enable),
321	},
322	{
323		.data_type	= QMI_OPT_FLAG,
324		.elem_len	= 1,
325		.elem_size	= sizeof(u8),
326		.array_type	= NO_ARRAY,
327		.tlv_type	= 0x12,
328		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
329					   initiate_cal_update_enable_valid),
330	},
331	{
332		.data_type	= QMI_UNSIGNED_1_BYTE,
333		.elem_len	= 1,
334		.elem_size	= sizeof(u8),
335		.array_type	= NO_ARRAY,
336		.tlv_type	= 0x12,
337		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
338					   initiate_cal_update_enable),
339	},
340	{
341		.data_type	= QMI_OPT_FLAG,
342		.elem_len	= 1,
343		.elem_size	= sizeof(u8),
344		.array_type	= NO_ARRAY,
345		.tlv_type	= 0x13,
346		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
347					   msa_ready_enable_valid),
348	},
349	{
350		.data_type	= QMI_UNSIGNED_1_BYTE,
351		.elem_len	= 1,
352		.elem_size	= sizeof(u8),
353		.array_type	= NO_ARRAY,
354		.tlv_type	= 0x13,
355		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
356					   msa_ready_enable),
357	},
358	{
359		.data_type	= QMI_OPT_FLAG,
360		.elem_len	= 1,
361		.elem_size	= sizeof(u8),
362		.array_type	= NO_ARRAY,
363		.tlv_type	= 0x14,
364		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
365					   pin_connect_result_enable_valid),
366	},
367	{
368		.data_type	= QMI_UNSIGNED_1_BYTE,
369		.elem_len	= 1,
370		.elem_size	= sizeof(u8),
371		.array_type	= NO_ARRAY,
372		.tlv_type	= 0x14,
373		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
374					   pin_connect_result_enable),
375	},
376	{
377		.data_type	= QMI_OPT_FLAG,
378		.elem_len	= 1,
379		.elem_size	= sizeof(u8),
380		.array_type	= NO_ARRAY,
381		.tlv_type	= 0x15,
382		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
383					   client_id_valid),
384	},
385	{
386		.data_type	= QMI_UNSIGNED_4_BYTE,
387		.elem_len	= 1,
388		.elem_size	= sizeof(u32),
389		.array_type	= NO_ARRAY,
390		.tlv_type	= 0x15,
391		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
392					   client_id),
393	},
394	{
395		.data_type	= QMI_OPT_FLAG,
396		.elem_len	= 1,
397		.elem_size	= sizeof(u8),
398		.array_type	= NO_ARRAY,
399		.tlv_type	= 0x16,
400		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
401					   request_mem_enable_valid),
402	},
403	{
404		.data_type	= QMI_UNSIGNED_1_BYTE,
405		.elem_len	= 1,
406		.elem_size	= sizeof(u8),
407		.array_type	= NO_ARRAY,
408		.tlv_type	= 0x16,
409		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
410					   request_mem_enable),
411	},
412	{
413		.data_type	= QMI_OPT_FLAG,
414		.elem_len	= 1,
415		.elem_size	= sizeof(u8),
416		.array_type	= NO_ARRAY,
417		.tlv_type	= 0x17,
418		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
419					   fw_mem_ready_enable_valid),
420	},
421	{
422		.data_type	= QMI_UNSIGNED_1_BYTE,
423		.elem_len	= 1,
424		.elem_size	= sizeof(u8),
425		.array_type	= NO_ARRAY,
426		.tlv_type	= 0x17,
427		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
428					   fw_mem_ready_enable),
429	},
430	{
431		.data_type	= QMI_OPT_FLAG,
432		.elem_len	= 1,
433		.elem_size	= sizeof(u8),
434		.array_type	= NO_ARRAY,
435		.tlv_type	= 0x18,
436		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
437					   fw_init_done_enable_valid),
438	},
439	{
440		.data_type	= QMI_UNSIGNED_1_BYTE,
441		.elem_len	= 1,
442		.elem_size	= sizeof(u8),
443		.array_type	= NO_ARRAY,
444		.tlv_type	= 0x18,
445		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
446					   fw_init_done_enable),
447	},
448
449	{
450		.data_type	= QMI_OPT_FLAG,
451		.elem_len	= 1,
452		.elem_size	= sizeof(u8),
453		.array_type	= NO_ARRAY,
454		.tlv_type	= 0x19,
455		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
456					   rejuvenate_enable_valid),
457	},
458	{
459		.data_type	= QMI_UNSIGNED_1_BYTE,
460		.elem_len	= 1,
461		.elem_size	= sizeof(u8),
462		.array_type	= NO_ARRAY,
463		.tlv_type	= 0x19,
464		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
465					   rejuvenate_enable),
466	},
467	{
468		.data_type	= QMI_OPT_FLAG,
469		.elem_len	= 1,
470		.elem_size	= sizeof(u8),
471		.array_type	= NO_ARRAY,
472		.tlv_type	= 0x1A,
473		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
474					   xo_cal_enable_valid),
475	},
476	{
477		.data_type	= QMI_UNSIGNED_1_BYTE,
478		.elem_len	= 1,
479		.elem_size	= sizeof(u8),
480		.array_type	= NO_ARRAY,
481		.tlv_type	= 0x1A,
482		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
483					   xo_cal_enable),
484	},
485	{
486		.data_type	= QMI_OPT_FLAG,
487		.elem_len	= 1,
488		.elem_size	= sizeof(u8),
489		.array_type	= NO_ARRAY,
490		.tlv_type	= 0x1B,
491		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
492					   cal_done_enable_valid),
493	},
494	{
495		.data_type	= QMI_UNSIGNED_1_BYTE,
496		.elem_len	= 1,
497		.elem_size	= sizeof(u8),
498		.array_type	= NO_ARRAY,
499		.tlv_type	= 0x1B,
500		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
501					   cal_done_enable),
502	},
503	{
504		.data_type	= QMI_EOTI,
505		.array_type	= NO_ARRAY,
506		.tlv_type	= QMI_COMMON_TLV_TYPE,
507	},
508};
509
510static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
511	{
512		.data_type	= QMI_STRUCT,
513		.elem_len	= 1,
514		.elem_size	= sizeof(struct qmi_response_type_v01),
515		.array_type	= NO_ARRAY,
516		.tlv_type	= 0x02,
517		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
518					   resp),
519		.ei_array	= qmi_response_type_v01_ei,
520	},
521	{
522		.data_type	= QMI_OPT_FLAG,
523		.elem_len	= 1,
524		.elem_size	= sizeof(u8),
525		.array_type	= NO_ARRAY,
526		.tlv_type	= 0x10,
527		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
528					   fw_status_valid),
529	},
530	{
531		.data_type	= QMI_UNSIGNED_8_BYTE,
532		.elem_len	= 1,
533		.elem_size	= sizeof(u64),
534		.array_type	= NO_ARRAY,
535		.tlv_type	= 0x10,
536		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
537					   fw_status),
538	},
539	{
540		.data_type	= QMI_EOTI,
541		.array_type	= NO_ARRAY,
542		.tlv_type	= QMI_COMMON_TLV_TYPE,
543	},
544};
545
546static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
547	{
548		.data_type	= QMI_UNSIGNED_8_BYTE,
549		.elem_len	= 1,
550		.elem_size	= sizeof(u64),
551		.array_type	= NO_ARRAY,
552		.tlv_type	= 0,
553		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
554	},
555	{
556		.data_type	= QMI_UNSIGNED_4_BYTE,
557		.elem_len	= 1,
558		.elem_size	= sizeof(u32),
559		.array_type	= NO_ARRAY,
560		.tlv_type	= 0,
561		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
562	},
563	{
564		.data_type	= QMI_UNSIGNED_1_BYTE,
565		.elem_len	= 1,
566		.elem_size	= sizeof(u8),
567		.array_type	= NO_ARRAY,
568		.tlv_type	= 0,
569		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
570	},
571	{
572		.data_type	= QMI_EOTI,
573		.array_type	= NO_ARRAY,
574		.tlv_type	= QMI_COMMON_TLV_TYPE,
575	},
576};
577
578static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
579	{
580		.data_type	= QMI_UNSIGNED_4_BYTE,
581		.elem_len	= 1,
582		.elem_size	= sizeof(u32),
583		.array_type	= NO_ARRAY,
584		.tlv_type	= 0,
585		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01,
586				  size),
587	},
588	{
589		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
590		.elem_len	= 1,
591		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
592		.array_type	= NO_ARRAY,
593		.tlv_type	= 0,
594		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
595	},
596	{
597		.data_type	= QMI_DATA_LEN,
598		.elem_len	= 1,
599		.elem_size	= sizeof(u8),
600		.array_type	= NO_ARRAY,
601		.tlv_type	= 0,
602		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
603	},
604	{
605		.data_type	= QMI_STRUCT,
606		.elem_len	= QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
607		.elem_size	= sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
608		.array_type	= VAR_LEN_ARRAY,
609		.tlv_type	= 0,
610		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
611		.ei_array	= qmi_wlanfw_mem_cfg_s_v01_ei,
612	},
613	{
614		.data_type	= QMI_EOTI,
615		.array_type	= NO_ARRAY,
616		.tlv_type	= QMI_COMMON_TLV_TYPE,
617	},
618};
619
620static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
621	{
622		.data_type	= QMI_DATA_LEN,
623		.elem_len	= 1,
624		.elem_size	= sizeof(u8),
625		.array_type	= NO_ARRAY,
626		.tlv_type	= 0x01,
627		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
628					   mem_seg_len),
629	},
630	{
631		.data_type	= QMI_STRUCT,
632		.elem_len	= ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
633		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_s_v01),
634		.array_type	= VAR_LEN_ARRAY,
635		.tlv_type	= 0x01,
636		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
637					   mem_seg),
638		.ei_array	= qmi_wlanfw_mem_seg_s_v01_ei,
639	},
640	{
641		.data_type	= QMI_EOTI,
642		.array_type	= NO_ARRAY,
643		.tlv_type	= QMI_COMMON_TLV_TYPE,
644	},
645};
646
647static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
648	{
649		.data_type	= QMI_UNSIGNED_8_BYTE,
650		.elem_len	= 1,
651		.elem_size	= sizeof(u64),
652		.array_type	= NO_ARRAY,
653		.tlv_type	= 0,
654		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
655	},
656	{
657		.data_type	= QMI_UNSIGNED_4_BYTE,
658		.elem_len	= 1,
659		.elem_size	= sizeof(u32),
660		.array_type	= NO_ARRAY,
661		.tlv_type	= 0,
662		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
663	},
664	{
665		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
666		.elem_len	= 1,
667		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
668		.array_type	= NO_ARRAY,
669		.tlv_type	= 0,
670		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
671	},
672	{
673		.data_type	= QMI_UNSIGNED_1_BYTE,
674		.elem_len	= 1,
675		.elem_size	= sizeof(u8),
676		.array_type	= NO_ARRAY,
677		.tlv_type	= 0,
678		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
679	},
680	{
681		.data_type	= QMI_EOTI,
682		.array_type	= NO_ARRAY,
683		.tlv_type	= QMI_COMMON_TLV_TYPE,
684	},
685};
686
687static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
688	{
689		.data_type	= QMI_DATA_LEN,
690		.elem_len	= 1,
691		.elem_size	= sizeof(u8),
692		.array_type	= NO_ARRAY,
693		.tlv_type	= 0x01,
694		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
695					   mem_seg_len),
696	},
697	{
698		.data_type	= QMI_STRUCT,
699		.elem_len	= ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
700		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
701		.array_type	= VAR_LEN_ARRAY,
702		.tlv_type	= 0x01,
703		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
704					   mem_seg),
705		.ei_array	= qmi_wlanfw_mem_seg_resp_s_v01_ei,
706	},
707	{
708		.data_type	= QMI_EOTI,
709		.array_type	= NO_ARRAY,
710		.tlv_type	= QMI_COMMON_TLV_TYPE,
711	},
712};
713
714static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
715	{
716		.data_type	= QMI_STRUCT,
717		.elem_len	= 1,
718		.elem_size	= sizeof(struct qmi_response_type_v01),
719		.array_type	= NO_ARRAY,
720		.tlv_type	= 0x02,
721		.offset		= offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
722					   resp),
723		.ei_array	= qmi_response_type_v01_ei,
724	},
725	{
726		.data_type	= QMI_EOTI,
727		.array_type	= NO_ARRAY,
728		.tlv_type	= QMI_COMMON_TLV_TYPE,
729	},
730};
731
732static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
733	{
734		.data_type	= QMI_EOTI,
735		.array_type	= NO_ARRAY,
736		.tlv_type	= QMI_COMMON_TLV_TYPE,
737	},
738};
739
740static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
741	{
742		.data_type	= QMI_UNSIGNED_4_BYTE,
743		.elem_len	= 1,
744		.elem_size	= sizeof(u32),
745		.array_type	= NO_ARRAY,
746		.tlv_type	= 0,
747		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
748					   chip_id),
749	},
750	{
751		.data_type	= QMI_UNSIGNED_4_BYTE,
752		.elem_len	= 1,
753		.elem_size	= sizeof(u32),
754		.array_type	= NO_ARRAY,
755		.tlv_type	= 0,
756		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
757					   chip_family),
758	},
759	{
760		.data_type	= QMI_EOTI,
761		.array_type	= NO_ARRAY,
762		.tlv_type	= QMI_COMMON_TLV_TYPE,
763	},
764};
765
766static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
767	{
768		.data_type	= QMI_UNSIGNED_4_BYTE,
769		.elem_len	= 1,
770		.elem_size	= sizeof(u32),
771		.array_type	= NO_ARRAY,
772		.tlv_type	= 0,
773		.offset		= offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
774					   board_id),
775	},
776	{
777		.data_type	= QMI_EOTI,
778		.array_type	= NO_ARRAY,
779		.tlv_type	= QMI_COMMON_TLV_TYPE,
780	},
781};
782
783static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
784	{
785		.data_type	= QMI_UNSIGNED_4_BYTE,
786		.elem_len	= 1,
787		.elem_size	= sizeof(u32),
788		.array_type	= NO_ARRAY,
789		.tlv_type	= 0,
790		.offset		= offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
791	},
792	{
793		.data_type	= QMI_EOTI,
794		.array_type	= NO_ARRAY,
795		.tlv_type	= QMI_COMMON_TLV_TYPE,
796	},
797};
798
799static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
800	{
801		.data_type	= QMI_UNSIGNED_4_BYTE,
802		.elem_len	= 1,
803		.elem_size	= sizeof(u32),
804		.array_type	= NO_ARRAY,
805		.tlv_type	= 0,
806		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
807					   fw_version),
808	},
809	{
810		.data_type	= QMI_STRING,
811		.elem_len	= ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
812		.elem_size	= sizeof(char),
813		.array_type	= NO_ARRAY,
814		.tlv_type	= 0,
815		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
816					   fw_build_timestamp),
817	},
818	{
819		.data_type	= QMI_EOTI,
820		.array_type	= NO_ARRAY,
821		.tlv_type	= QMI_COMMON_TLV_TYPE,
822	},
823};
824
825static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
826	{
827		.data_type	= QMI_STRUCT,
828		.elem_len	= 1,
829		.elem_size	= sizeof(struct qmi_response_type_v01),
830		.array_type	= NO_ARRAY,
831		.tlv_type	= 0x02,
832		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
833		.ei_array	= qmi_response_type_v01_ei,
834	},
835	{
836		.data_type	= QMI_OPT_FLAG,
837		.elem_len	= 1,
838		.elem_size	= sizeof(u8),
839		.array_type	= NO_ARRAY,
840		.tlv_type	= 0x10,
841		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
842					   chip_info_valid),
843	},
844	{
845		.data_type	= QMI_STRUCT,
846		.elem_len	= 1,
847		.elem_size	= sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
848		.array_type	= NO_ARRAY,
849		.tlv_type	= 0x10,
850		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
851					   chip_info),
852		.ei_array	= qmi_wlanfw_rf_chip_info_s_v01_ei,
853	},
854	{
855		.data_type	= QMI_OPT_FLAG,
856		.elem_len	= 1,
857		.elem_size	= sizeof(u8),
858		.array_type	= NO_ARRAY,
859		.tlv_type	= 0x11,
860		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
861					   board_info_valid),
862	},
863	{
864		.data_type	= QMI_STRUCT,
865		.elem_len	= 1,
866		.elem_size	= sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
867		.array_type	= NO_ARRAY,
868		.tlv_type	= 0x11,
869		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
870					   board_info),
871		.ei_array	= qmi_wlanfw_rf_board_info_s_v01_ei,
872	},
873	{
874		.data_type	= QMI_OPT_FLAG,
875		.elem_len	= 1,
876		.elem_size	= sizeof(u8),
877		.array_type	= NO_ARRAY,
878		.tlv_type	= 0x12,
879		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
880					   soc_info_valid),
881	},
882	{
883		.data_type	= QMI_STRUCT,
884		.elem_len	= 1,
885		.elem_size	= sizeof(struct qmi_wlanfw_soc_info_s_v01),
886		.array_type	= NO_ARRAY,
887		.tlv_type	= 0x12,
888		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
889					   soc_info),
890		.ei_array	= qmi_wlanfw_soc_info_s_v01_ei,
891	},
892	{
893		.data_type	= QMI_OPT_FLAG,
894		.elem_len	= 1,
895		.elem_size	= sizeof(u8),
896		.array_type	= NO_ARRAY,
897		.tlv_type	= 0x13,
898		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
899					   fw_version_info_valid),
900	},
901	{
902		.data_type	= QMI_STRUCT,
903		.elem_len	= 1,
904		.elem_size	= sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
905		.array_type	= NO_ARRAY,
906		.tlv_type	= 0x13,
907		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
908					   fw_version_info),
909		.ei_array	= qmi_wlanfw_fw_version_info_s_v01_ei,
910	},
911	{
912		.data_type	= QMI_OPT_FLAG,
913		.elem_len	= 1,
914		.elem_size	= sizeof(u8),
915		.array_type	= NO_ARRAY,
916		.tlv_type	= 0x14,
917		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
918					   fw_build_id_valid),
919	},
920	{
921		.data_type	= QMI_STRING,
922		.elem_len	= ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
923		.elem_size	= sizeof(char),
924		.array_type	= NO_ARRAY,
925		.tlv_type	= 0x14,
926		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
927					   fw_build_id),
928	},
929	{
930		.data_type	= QMI_OPT_FLAG,
931		.elem_len	= 1,
932		.elem_size	= sizeof(u8),
933		.array_type	= NO_ARRAY,
934		.tlv_type	= 0x15,
935		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
936					   num_macs_valid),
937	},
938	{
939		.data_type	= QMI_UNSIGNED_1_BYTE,
940		.elem_len	= 1,
941		.elem_size	= sizeof(u8),
942		.array_type	= NO_ARRAY,
943		.tlv_type	= 0x15,
944		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
945					   num_macs),
946	},
947	{
948		.data_type	= QMI_EOTI,
949		.array_type	= NO_ARRAY,
950		.tlv_type	= QMI_COMMON_TLV_TYPE,
951	},
952};
953
954static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
955	{
956		.data_type	= QMI_UNSIGNED_1_BYTE,
957		.elem_len	= 1,
958		.elem_size	= sizeof(u8),
959		.array_type	= NO_ARRAY,
960		.tlv_type	= 0x01,
961		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
962					   valid),
963	},
964	{
965		.data_type	= QMI_OPT_FLAG,
966		.elem_len	= 1,
967		.elem_size	= sizeof(u8),
968		.array_type	= NO_ARRAY,
969		.tlv_type	= 0x10,
970		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
971					   file_id_valid),
972	},
973	{
974		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
975		.elem_len	= 1,
976		.elem_size	= sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
977		.array_type	= NO_ARRAY,
978		.tlv_type	= 0x10,
979		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
980					   file_id),
981	},
982	{
983		.data_type	= QMI_OPT_FLAG,
984		.elem_len	= 1,
985		.elem_size	= sizeof(u8),
986		.array_type	= NO_ARRAY,
987		.tlv_type	= 0x11,
988		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
989					   total_size_valid),
990	},
991	{
992		.data_type	= QMI_UNSIGNED_4_BYTE,
993		.elem_len	= 1,
994		.elem_size	= sizeof(u32),
995		.array_type	= NO_ARRAY,
996		.tlv_type	= 0x11,
997		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
998					   total_size),
999	},
1000	{
1001		.data_type	= QMI_OPT_FLAG,
1002		.elem_len	= 1,
1003		.elem_size	= sizeof(u8),
1004		.array_type	= NO_ARRAY,
1005		.tlv_type	= 0x12,
1006		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1007					   seg_id_valid),
1008	},
1009	{
1010		.data_type	= QMI_UNSIGNED_4_BYTE,
1011		.elem_len	= 1,
1012		.elem_size	= sizeof(u32),
1013		.array_type	= NO_ARRAY,
1014		.tlv_type	= 0x12,
1015		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1016					   seg_id),
1017	},
1018	{
1019		.data_type	= QMI_OPT_FLAG,
1020		.elem_len	= 1,
1021		.elem_size	= sizeof(u8),
1022		.array_type	= NO_ARRAY,
1023		.tlv_type	= 0x13,
1024		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1025					   data_valid),
1026	},
1027	{
1028		.data_type	= QMI_DATA_LEN,
1029		.elem_len	= 1,
1030		.elem_size	= sizeof(u16),
1031		.array_type	= NO_ARRAY,
1032		.tlv_type	= 0x13,
1033		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1034					   data_len),
1035	},
1036	{
1037		.data_type	= QMI_UNSIGNED_1_BYTE,
1038		.elem_len	= QMI_WLANFW_MAX_DATA_SIZE_V01,
1039		.elem_size	= sizeof(u8),
1040		.array_type	= VAR_LEN_ARRAY,
1041		.tlv_type	= 0x13,
1042		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1043					   data),
1044	},
1045	{
1046		.data_type	= QMI_OPT_FLAG,
1047		.elem_len	= 1,
1048		.elem_size	= sizeof(u8),
1049		.array_type	= NO_ARRAY,
1050		.tlv_type	= 0x14,
1051		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1052					   end_valid),
1053	},
1054	{
1055		.data_type	= QMI_UNSIGNED_1_BYTE,
1056		.elem_len	= 1,
1057		.elem_size	= sizeof(u8),
1058		.array_type	= NO_ARRAY,
1059		.tlv_type	= 0x14,
1060		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1061					   end),
1062	},
1063	{
1064		.data_type	= QMI_OPT_FLAG,
1065		.elem_len	= 1,
1066		.elem_size	= sizeof(u8),
1067		.array_type	= NO_ARRAY,
1068		.tlv_type	= 0x15,
1069		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1070					   bdf_type_valid),
1071	},
1072	{
1073		.data_type	= QMI_UNSIGNED_1_BYTE,
1074		.elem_len	= 1,
1075		.elem_size	= sizeof(u8),
1076		.array_type	= NO_ARRAY,
1077		.tlv_type	= 0x15,
1078		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1079					   bdf_type),
1080	},
1081
1082	{
1083		.data_type	= QMI_EOTI,
1084		.array_type	= NO_ARRAY,
1085		.tlv_type	= QMI_COMMON_TLV_TYPE,
1086	},
1087};
1088
1089static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1090	{
1091		.data_type	= QMI_STRUCT,
1092		.elem_len	= 1,
1093		.elem_size	= sizeof(struct qmi_response_type_v01),
1094		.array_type	= NO_ARRAY,
1095		.tlv_type	= 0x02,
1096		.offset		= offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1097					   resp),
1098		.ei_array	= qmi_response_type_v01_ei,
1099	},
1100	{
1101		.data_type	= QMI_EOTI,
1102		.array_type	= NO_ARRAY,
1103		.tlv_type	= QMI_COMMON_TLV_TYPE,
1104	},
1105};
1106
1107static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1108	{
1109		.data_type	= QMI_UNSIGNED_8_BYTE,
1110		.elem_len	= 1,
1111		.elem_size	= sizeof(u64),
1112		.array_type	= NO_ARRAY,
1113		.tlv_type	= 0x01,
1114		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1115	},
1116	{
1117		.data_type	= QMI_UNSIGNED_4_BYTE,
1118		.elem_len	= 1,
1119		.elem_size	= sizeof(u32),
1120		.array_type	= NO_ARRAY,
1121		.tlv_type	= 0x02,
1122		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1123	},
1124	{
1125		.data_type	= QMI_EOTI,
1126		.array_type	= NO_ARRAY,
1127		.tlv_type	= QMI_COMMON_TLV_TYPE,
1128	},
1129};
1130
1131static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1132	{
1133		.data_type	= QMI_STRUCT,
1134		.elem_len	= 1,
1135		.elem_size	= sizeof(struct qmi_response_type_v01),
1136		.array_type	= NO_ARRAY,
1137		.tlv_type	= 0x02,
1138		.offset		= offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1139		.ei_array	= qmi_response_type_v01_ei,
1140	},
1141	{
1142		.data_type	= QMI_EOTI,
1143		.array_type	= NO_ARRAY,
1144		.tlv_type	= QMI_COMMON_TLV_TYPE,
1145	},
1146};
1147
1148static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
1149	{
1150		.data_type	= QMI_UNSIGNED_4_BYTE,
1151		.elem_len	= 1,
1152		.elem_size	= sizeof(u32),
1153		.array_type	= NO_ARRAY,
1154		.tlv_type	= 0,
1155		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1156					   pipe_num),
1157	},
1158	{
1159		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1160		.elem_len	= 1,
1161		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1162		.array_type	= NO_ARRAY,
1163		.tlv_type	= 0,
1164		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1165					   pipe_dir),
1166	},
1167	{
1168		.data_type	= QMI_UNSIGNED_4_BYTE,
1169		.elem_len	= 1,
1170		.elem_size	= sizeof(u32),
1171		.array_type	= NO_ARRAY,
1172		.tlv_type	= 0,
1173		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1174					   nentries),
1175	},
1176	{
1177		.data_type	= QMI_UNSIGNED_4_BYTE,
1178		.elem_len	= 1,
1179		.elem_size	= sizeof(u32),
1180		.array_type	= NO_ARRAY,
1181		.tlv_type	= 0,
1182		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1183					   nbytes_max),
1184	},
1185	{
1186		.data_type	= QMI_UNSIGNED_4_BYTE,
1187		.elem_len	= 1,
1188		.elem_size	= sizeof(u32),
1189		.array_type	= NO_ARRAY,
1190		.tlv_type	= 0,
1191		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1192					   flags),
1193	},
1194	{
1195		.data_type	= QMI_EOTI,
1196		.array_type	= NO_ARRAY,
1197		.tlv_type	= QMI_COMMON_TLV_TYPE,
1198	},
1199};
1200
1201static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
1202	{
1203		.data_type	= QMI_UNSIGNED_4_BYTE,
1204		.elem_len	= 1,
1205		.elem_size	= sizeof(u32),
1206		.array_type	= NO_ARRAY,
1207		.tlv_type	= 0,
1208		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1209					   service_id),
1210	},
1211	{
1212		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1213		.elem_len	= 1,
1214		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1215		.array_type	= NO_ARRAY,
1216		.tlv_type	= 0,
1217		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1218					   pipe_dir),
1219	},
1220	{
1221		.data_type	= QMI_UNSIGNED_4_BYTE,
1222		.elem_len	= 1,
1223		.elem_size	= sizeof(u32),
1224		.array_type	= NO_ARRAY,
1225		.tlv_type	= 0,
1226		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1227					   pipe_num),
1228	},
1229	{
1230		.data_type	= QMI_EOTI,
1231		.array_type	= NO_ARRAY,
1232		.tlv_type	= QMI_COMMON_TLV_TYPE,
1233	},
1234};
1235
1236static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1237	{
1238		.data_type	= QMI_UNSIGNED_2_BYTE,
1239		.elem_len	= 1,
1240		.elem_size	= sizeof(u16),
1241		.array_type	= NO_ARRAY,
1242		.tlv_type	= 0,
1243		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1244	},
1245	{
1246		.data_type	= QMI_UNSIGNED_2_BYTE,
1247		.elem_len	= 1,
1248		.elem_size	= sizeof(u16),
1249		.array_type	= NO_ARRAY,
1250		.tlv_type	= 0,
1251		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1252					   offset),
1253	},
1254	{
1255		.data_type	= QMI_EOTI,
1256		.array_type	= QMI_COMMON_TLV_TYPE,
1257	},
1258};
1259
1260static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {
1261	{
1262		.data_type	= QMI_UNSIGNED_4_BYTE,
1263		.elem_len	= 1,
1264		.elem_size	= sizeof(u32),
1265		.array_type	= NO_ARRAY,
1266		.tlv_type	= 0,
1267		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,
1268					   addr),
1269	},
1270	{
1271		.data_type	= QMI_EOTI,
1272		.array_type	= NO_ARRAY,
1273		.tlv_type	= QMI_COMMON_TLV_TYPE,
1274	},
1275};
1276
1277static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1278	{
1279		.data_type	= QMI_UNSIGNED_4_BYTE,
1280		.elem_len	= 1,
1281		.elem_size	= sizeof(u32),
1282		.array_type	= NO_ARRAY,
1283		.tlv_type	= 0x01,
1284		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1285					   mode),
1286	},
1287	{
1288		.data_type	= QMI_OPT_FLAG,
1289		.elem_len	= 1,
1290		.elem_size	= sizeof(u8),
1291		.array_type	= NO_ARRAY,
1292		.tlv_type	= 0x10,
1293		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1294					   hw_debug_valid),
1295	},
1296	{
1297		.data_type	= QMI_UNSIGNED_1_BYTE,
1298		.elem_len	= 1,
1299		.elem_size	= sizeof(u8),
1300		.array_type	= NO_ARRAY,
1301		.tlv_type	= 0x10,
1302		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1303					   hw_debug),
1304	},
1305	{
1306		.data_type	= QMI_EOTI,
1307		.array_type	= NO_ARRAY,
1308		.tlv_type	= QMI_COMMON_TLV_TYPE,
1309	},
1310};
1311
1312static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1313	{
1314		.data_type	= QMI_STRUCT,
1315		.elem_len	= 1,
1316		.elem_size	= sizeof(struct qmi_response_type_v01),
1317		.array_type	= NO_ARRAY,
1318		.tlv_type	= 0x02,
1319		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1320					   resp),
1321		.ei_array	= qmi_response_type_v01_ei,
1322	},
1323	{
1324		.data_type	= QMI_EOTI,
1325		.array_type	= NO_ARRAY,
1326		.tlv_type	= QMI_COMMON_TLV_TYPE,
1327	},
1328};
1329
1330static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1331	{
1332		.data_type	= QMI_OPT_FLAG,
1333		.elem_len	= 1,
1334		.elem_size	= sizeof(u8),
1335		.array_type	= NO_ARRAY,
1336		.tlv_type	= 0x10,
1337		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1338					   host_version_valid),
1339	},
1340	{
1341		.data_type	= QMI_STRING,
1342		.elem_len	= QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1343		.elem_size	= sizeof(char),
1344		.array_type	= NO_ARRAY,
1345		.tlv_type	= 0x10,
1346		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1347					   host_version),
1348	},
1349	{
1350		.data_type	= QMI_OPT_FLAG,
1351		.elem_len	= 1,
1352		.elem_size	= sizeof(u8),
1353		.array_type	= NO_ARRAY,
1354		.tlv_type	= 0x11,
1355		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1356					   tgt_cfg_valid),
1357	},
1358	{
1359		.data_type	= QMI_DATA_LEN,
1360		.elem_len	= 1,
1361		.elem_size	= sizeof(u8),
1362		.array_type	= NO_ARRAY,
1363		.tlv_type	= 0x11,
1364		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1365					   tgt_cfg_len),
1366	},
1367	{
1368		.data_type	= QMI_STRUCT,
1369		.elem_len	= QMI_WLANFW_MAX_NUM_CE_V01,
1370		.elem_size	= sizeof(
1371				struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1372		.array_type	= VAR_LEN_ARRAY,
1373		.tlv_type	= 0x11,
1374		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1375					   tgt_cfg),
1376		.ei_array	= qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1377	},
1378	{
1379		.data_type	= QMI_OPT_FLAG,
1380		.elem_len	= 1,
1381		.elem_size	= sizeof(u8),
1382		.array_type	= NO_ARRAY,
1383		.tlv_type	= 0x12,
1384		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1385					   svc_cfg_valid),
1386	},
1387	{
1388		.data_type	= QMI_DATA_LEN,
1389		.elem_len	= 1,
1390		.elem_size	= sizeof(u8),
1391		.array_type	= NO_ARRAY,
1392		.tlv_type	= 0x12,
1393		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1394					   svc_cfg_len),
1395	},
1396	{
1397		.data_type	= QMI_STRUCT,
1398		.elem_len	= QMI_WLANFW_MAX_NUM_SVC_V01,
1399		.elem_size	= sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1400		.array_type	= VAR_LEN_ARRAY,
1401		.tlv_type	= 0x12,
1402		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1403					   svc_cfg),
1404		.ei_array	= qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1405	},
1406	{
1407		.data_type	= QMI_OPT_FLAG,
1408		.elem_len	= 1,
1409		.elem_size	= sizeof(u8),
1410		.array_type	= NO_ARRAY,
1411		.tlv_type	= 0x13,
1412		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1413					   shadow_reg_valid),
1414	},
1415	{
1416		.data_type	= QMI_DATA_LEN,
1417		.elem_len	= 1,
1418		.elem_size	= sizeof(u8),
1419		.array_type	= NO_ARRAY,
1420		.tlv_type	= 0x13,
1421		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1422					   shadow_reg_len),
1423	},
1424	{
1425		.data_type	= QMI_STRUCT,
1426		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1427		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1428		.array_type	= VAR_LEN_ARRAY,
1429		.tlv_type	= 0x13,
1430		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1431					   shadow_reg),
1432		.ei_array	= qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1433	},
1434	{
1435		.data_type	= QMI_OPT_FLAG,
1436		.elem_len	= 1,
1437		.elem_size	= sizeof(u8),
1438		.array_type	= NO_ARRAY,
1439		.tlv_type	= 0x14,
1440		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1441					   shadow_reg_v2_valid),
1442	},
1443	{
1444		.data_type	= QMI_DATA_LEN,
1445		.elem_len	= 1,
1446		.elem_size	= sizeof(u8),
1447		.array_type	= NO_ARRAY,
1448		.tlv_type	= 0x14,
1449		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1450					   shadow_reg_v2_len),
1451	},
1452	{
1453		.data_type	= QMI_STRUCT,
1454		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,
1455		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),
1456		.array_type	= VAR_LEN_ARRAY,
1457		.tlv_type	= 0x14,
1458		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1459					   shadow_reg_v2),
1460		.ei_array	= qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,
1461	},
1462	{
1463		.data_type	= QMI_EOTI,
1464		.array_type	= NO_ARRAY,
1465		.tlv_type	= QMI_COMMON_TLV_TYPE,
1466	},
1467};
1468
1469static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1470	{
1471		.data_type	= QMI_STRUCT,
1472		.elem_len	= 1,
1473		.elem_size	= sizeof(struct qmi_response_type_v01),
1474		.array_type	= NO_ARRAY,
1475		.tlv_type	= 0x02,
1476		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1477		.ei_array	= qmi_response_type_v01_ei,
1478	},
1479	{
1480		.data_type	= QMI_EOTI,
1481		.array_type	= NO_ARRAY,
1482		.tlv_type	= QMI_COMMON_TLV_TYPE,
1483	},
1484};
1485
1486static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1487	{
1488		.data_type = QMI_EOTI,
1489		.array_type = NO_ARRAY,
1490	},
1491};
1492
1493static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1494	{
1495		.data_type = QMI_EOTI,
1496		.array_type = NO_ARRAY,
1497	},
1498};
1499
1500static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {
1501	{
1502		.data_type = QMI_EOTI,
1503		.array_type = NO_ARRAY,
1504	},
1505};
1506
1507static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
1508{
1509	struct qmi_wlanfw_host_cap_req_msg_v01 req;
1510	struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
1511	struct qmi_txn txn = {};
1512	int ret = 0;
1513
1514	memset(&req, 0, sizeof(req));
1515	memset(&resp, 0, sizeof(resp));
1516
1517	req.num_clients_valid = 1;
1518	req.num_clients = 1;
1519	req.mem_cfg_mode = ab->qmi.target_mem_mode;
1520	req.mem_cfg_mode_valid = 1;
1521	req.bdf_support_valid = 1;
1522	req.bdf_support = 1;
1523
1524	if (ab->bus_params.m3_fw_support) {
1525		req.m3_support_valid = 1;
1526		req.m3_support = 1;
1527		req.m3_cache_support_valid = 1;
1528		req.m3_cache_support = 1;
1529	} else {
1530		req.m3_support_valid = 0;
1531		req.m3_support = 0;
1532		req.m3_cache_support_valid = 0;
1533		req.m3_cache_support = 0;
1534	}
1535
1536	req.cal_done_valid = 1;
1537	req.cal_done = ab->qmi.cal_done;
1538
1539	if (ab->hw_params.internal_sleep_clock) {
1540		req.nm_modem_valid = 1;
1541
1542		/* Notify firmware that this is non-qualcomm platform. */
1543		req.nm_modem |= HOST_CSTATE_BIT;
1544
1545		/* Notify firmware about the sleep clock selection,
1546		 * nm_modem_bit[1] is used for this purpose. Host driver on
1547		 * non-qualcomm platforms should select internal sleep
1548		 * clock.
1549		 */
1550		req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
1551	}
1552
1553	ret = qmi_txn_init(&ab->qmi.handle, &txn,
1554			   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
1555	if (ret < 0)
1556		goto out;
1557
1558	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1559			       QMI_WLANFW_HOST_CAP_REQ_V01,
1560			       QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
1561			       qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
1562	if (ret < 0) {
1563		ath11k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
1564		goto out;
1565	}
1566
1567	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1568	if (ret < 0)
1569		goto out;
1570
1571	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1572		ath11k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
1573			    resp.resp.result, resp.resp.error);
1574		ret = -EINVAL;
1575		goto out;
1576	}
1577
1578out:
1579	return ret;
1580}
1581
1582static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)
1583{
1584	struct qmi_wlanfw_ind_register_req_msg_v01 *req;
1585	struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
1586	struct qmi_handle *handle = &ab->qmi.handle;
1587	struct qmi_txn txn;
1588	int ret;
1589
1590	req = kzalloc(sizeof(*req), GFP_KERNEL);
1591	if (!req)
1592		return -ENOMEM;
1593
1594	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1595	if (!resp) {
1596		ret = -ENOMEM;
1597		goto resp_out;
1598	}
1599
1600	req->client_id_valid = 1;
1601	req->client_id = QMI_WLANFW_CLIENT_ID;
1602	req->fw_ready_enable_valid = 1;
1603	req->fw_ready_enable = 1;
1604	req->request_mem_enable_valid = 1;
1605	req->request_mem_enable = 1;
1606	req->fw_mem_ready_enable_valid = 1;
1607	req->fw_mem_ready_enable = 1;
1608	req->cal_done_enable_valid = 1;
1609	req->cal_done_enable = 1;
1610	req->fw_init_done_enable_valid = 1;
1611	req->fw_init_done_enable = 1;
1612
1613	req->pin_connect_result_enable_valid = 0;
1614	req->pin_connect_result_enable = 0;
1615
1616	ret = qmi_txn_init(handle, &txn,
1617			   qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
1618	if (ret < 0)
1619		goto out;
1620
1621	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1622			       QMI_WLANFW_IND_REGISTER_REQ_V01,
1623			       QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
1624			       qmi_wlanfw_ind_register_req_msg_v01_ei, req);
1625	if (ret < 0) {
1626		ath11k_warn(ab, "Failed to send indication register request, err = %d\n",
1627			    ret);
1628		goto out;
1629	}
1630
1631	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1632	if (ret < 0) {
1633		ath11k_warn(ab, "failed to register fw indication %d\n", ret);
1634		goto out;
1635	}
1636
1637	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1638		ath11k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
1639			    resp->resp.result, resp->resp.error);
1640		ret = -EINVAL;
1641		goto out;
1642	}
1643
1644out:
1645	kfree(resp);
1646resp_out:
1647	kfree(req);
1648	return ret;
1649}
1650
1651static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
1652{
1653	struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
1654	struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
1655	struct qmi_txn txn = {};
1656	int ret = 0, i;
1657	bool delayed;
1658
1659	req = kzalloc(sizeof(*req), GFP_KERNEL);
1660	if (!req)
1661		return -ENOMEM;
1662
1663	memset(&resp, 0, sizeof(resp));
1664
1665	/* For QCA6390 by default FW requests a block of ~4M contiguous
1666	 * DMA memory, it's hard to allocate from OS. So host returns
1667	 * failure to FW and FW will then request mulitple blocks of small
1668	 * chunk size memory.
1669	 */
1670	if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) {
1671		delayed = true;
1672		ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n",
1673			   ab->qmi.mem_seg_count);
1674		memset(req, 0, sizeof(*req));
1675	} else {
1676		delayed = false;
1677		req->mem_seg_len = ab->qmi.mem_seg_count;
1678
1679		for (i = 0; i < req->mem_seg_len ; i++) {
1680			req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
1681			req->mem_seg[i].size = ab->qmi.target_mem[i].size;
1682			req->mem_seg[i].type = ab->qmi.target_mem[i].type;
1683		}
1684	}
1685
1686	ret = qmi_txn_init(&ab->qmi.handle, &txn,
1687			   qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
1688	if (ret < 0)
1689		goto out;
1690
1691	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1692			       QMI_WLANFW_RESPOND_MEM_REQ_V01,
1693			       QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
1694			       qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
1695	if (ret < 0) {
1696		ath11k_warn(ab, "qmi failed to respond memory request, err = %d\n",
1697			    ret);
1698		goto out;
1699	}
1700
1701	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1702	if (ret < 0) {
1703		ath11k_warn(ab, "qmi failed memory request, err = %d\n", ret);
1704		goto out;
1705	}
1706
1707	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1708		/* the error response is expected when
1709		 * target_mem_delayed is true.
1710		 */
1711		if (delayed && resp.resp.error == 0)
1712			goto out;
1713
1714		ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
1715			    resp.resp.result, resp.resp.error);
1716		ret = -EINVAL;
1717		goto out;
1718	}
1719out:
1720	kfree(req);
1721	return ret;
1722}
1723
1724static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)
1725{
1726	int i;
1727
1728	if (ab->bus_params.fixed_mem_region)
1729		return;
1730
1731	for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1732		if (!ab->qmi.target_mem[i].vaddr)
1733			continue;
1734
1735		dma_free_coherent(ab->dev,
1736				  ab->qmi.target_mem[i].size,
1737				  ab->qmi.target_mem[i].vaddr,
1738				  ab->qmi.target_mem[i].paddr);
1739		ab->qmi.target_mem[i].vaddr = NULL;
1740	}
1741}
1742
1743static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
1744{
1745	int i;
1746	struct target_mem_chunk *chunk;
1747
1748	ab->qmi.target_mem_delayed = false;
1749
1750	for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1751		chunk = &ab->qmi.target_mem[i];
1752		chunk->vaddr = dma_alloc_coherent(ab->dev,
1753						  chunk->size,
1754						  &chunk->paddr,
1755						  GFP_KERNEL);
1756		if (!chunk->vaddr) {
1757			if (ab->qmi.mem_seg_count <= 2) {
1758				ath11k_dbg(ab, ATH11K_DBG_QMI,
1759					   "qmi dma allocation failed (%d B type %u), will try later with small size\n",
1760					    chunk->size,
1761					    chunk->type);
1762				ath11k_qmi_free_target_mem_chunk(ab);
1763				ab->qmi.target_mem_delayed = true;
1764				return 0;
1765			}
1766			ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n",
1767				   chunk->size,
1768				   chunk->type);
1769			return -EINVAL;
1770		}
1771	}
1772
1773	return 0;
1774}
1775
1776static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
1777{
1778	int i, idx;
1779
1780	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
1781		switch (ab->qmi.target_mem[i].type) {
1782		case BDF_MEM_REGION_TYPE:
1783			ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
1784			ab->qmi.target_mem[idx].vaddr = NULL;
1785			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1786			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1787			idx++;
1788			break;
1789		case CALDB_MEM_REGION_TYPE:
1790			if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {
1791				ath11k_warn(ab, "qmi mem size is low to load caldata\n");
1792				return -EINVAL;
1793			}
1794			/* TODO ath11k does not support cold boot calibration */
1795			ab->qmi.target_mem[idx].paddr = 0;
1796			ab->qmi.target_mem[idx].vaddr = NULL;
1797			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1798			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1799			idx++;
1800			break;
1801		default:
1802			ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
1803				    ab->qmi.target_mem[i].type);
1804			break;
1805		}
1806	}
1807	ab->qmi.mem_seg_count = idx;
1808
1809	return 0;
1810}
1811
1812static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
1813{
1814	struct qmi_wlanfw_cap_req_msg_v01 req;
1815	struct qmi_wlanfw_cap_resp_msg_v01 resp;
1816	struct qmi_txn txn = {};
1817	int ret = 0;
1818
1819	memset(&req, 0, sizeof(req));
1820	memset(&resp, 0, sizeof(resp));
1821
1822	ret = qmi_txn_init(&ab->qmi.handle, &txn,
1823			   qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
1824	if (ret < 0)
1825		goto out;
1826
1827	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1828			       QMI_WLANFW_CAP_REQ_V01,
1829			       QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
1830			       qmi_wlanfw_cap_req_msg_v01_ei, &req);
1831	if (ret < 0) {
1832		ath11k_warn(ab, "qmi failed to send target cap request, err = %d\n",
1833			    ret);
1834		goto out;
1835	}
1836
1837	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1838	if (ret < 0) {
1839		ath11k_warn(ab, "qmi failed target cap request %d\n", ret);
1840		goto out;
1841	}
1842
1843	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1844		ath11k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
1845			    resp.resp.result, resp.resp.error);
1846		ret = -EINVAL;
1847		goto out;
1848	}
1849
1850	if (resp.chip_info_valid) {
1851		ab->qmi.target.chip_id = resp.chip_info.chip_id;
1852		ab->qmi.target.chip_family = resp.chip_info.chip_family;
1853	}
1854
1855	if (resp.board_info_valid)
1856		ab->qmi.target.board_id = resp.board_info.board_id;
1857	else
1858		ab->qmi.target.board_id = 0xFF;
1859
1860	if (resp.soc_info_valid)
1861		ab->qmi.target.soc_id = resp.soc_info.soc_id;
1862
1863	if (resp.fw_version_info_valid) {
1864		ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
1865		strlcpy(ab->qmi.target.fw_build_timestamp,
1866			resp.fw_version_info.fw_build_timestamp,
1867			sizeof(ab->qmi.target.fw_build_timestamp));
1868	}
1869
1870	if (resp.fw_build_id_valid)
1871		strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
1872			sizeof(ab->qmi.target.fw_build_id));
1873
1874	ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
1875		    ab->qmi.target.chip_id, ab->qmi.target.chip_family,
1876		    ab->qmi.target.board_id, ab->qmi.target.soc_id);
1877
1878	ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
1879		    ab->qmi.target.fw_version,
1880		    ab->qmi.target.fw_build_timestamp,
1881		    ab->qmi.target.fw_build_id);
1882
1883out:
1884	return ret;
1885}
1886
1887static int
1888ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
1889				struct qmi_wlanfw_bdf_download_req_msg_v01 *req,
1890				void __iomem *bdf_addr)
1891{
1892	const struct firmware *fw_entry;
1893	struct ath11k_board_data bd;
1894	u32 fw_size;
1895	int ret;
1896
1897	switch (type) {
1898	case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
1899		memset(&bd, 0, sizeof(bd));
1900
1901		ret = ath11k_core_fetch_bdf(ab, &bd);
1902		if (ret) {
1903			ath11k_warn(ab, "qmi failed to load BDF\n");
1904			return ret;
1905		}
1906
1907		fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
1908		memcpy_toio(bdf_addr, bd.data, fw_size);
1909		ath11k_core_free_bdf(ab, &bd);
1910		break;
1911	case ATH11K_QMI_FILE_TYPE_CALDATA:
1912		fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
1913		if (IS_ERR(fw_entry)) {
1914			ret = PTR_ERR(fw_entry);
1915			ath11k_warn(ab, "failed to load %s: %d\n",
1916				    ATH11K_DEFAULT_CAL_FILE, ret);
1917			return ret;
1918		}
1919
1920		fw_size = min_t(u32, ab->hw_params.fw.board_size,
1921				fw_entry->size);
1922
1923		memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET,
1924			    fw_entry->data, fw_size);
1925
1926		release_firmware(fw_entry);
1927		break;
1928	default:
1929		return -EINVAL;
1930	}
1931
1932	req->total_size = fw_size;
1933	return 0;
1934}
1935
1936static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
1937{
1938	struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
1939	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
1940	struct qmi_txn txn = {};
1941	void __iomem *bdf_addr = NULL;
1942	int type, ret;
1943
1944	req = kzalloc(sizeof(*req), GFP_KERNEL);
1945	if (!req)
1946		return -ENOMEM;
1947	memset(&resp, 0, sizeof(resp));
1948
1949	bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
1950	if (!bdf_addr) {
1951		ath11k_warn(ab, "qmi ioremap error for BDF\n");
1952		ret = -EIO;
1953		goto out;
1954	}
1955
1956	for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) {
1957		req->valid = 1;
1958		req->file_id_valid = 1;
1959		req->file_id = ab->qmi.target.board_id;
1960		req->total_size_valid = 1;
1961		req->seg_id_valid = 1;
1962		req->seg_id = type;
1963		req->data_valid = 0;
1964		req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
1965		req->bdf_type = 0;
1966		req->bdf_type_valid = 0;
1967		req->end_valid = 1;
1968		req->end = 1;
1969
1970		ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr);
1971		if (ret < 0)
1972			goto out_qmi_bdf;
1973
1974		ret = qmi_txn_init(&ab->qmi.handle, &txn,
1975				   qmi_wlanfw_bdf_download_resp_msg_v01_ei,
1976				   &resp);
1977		if (ret < 0)
1978			goto out_qmi_bdf;
1979
1980		ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1981				       QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
1982				       QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
1983				       qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
1984		if (ret < 0) {
1985			qmi_txn_cancel(&txn);
1986			goto out_qmi_bdf;
1987		}
1988
1989		ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1990		if (ret < 0)
1991			goto out_qmi_bdf;
1992
1993		if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1994			ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
1995				    resp.resp.result, resp.resp.error);
1996			ret = -EINVAL;
1997			goto out_qmi_bdf;
1998		}
1999	}
2000
2001out_qmi_bdf:
2002	iounmap(bdf_addr);
2003out:
2004	kfree(req);
2005	return ret;
2006}
2007
2008static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
2009{
2010	struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2011	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
2012	struct ath11k_board_data bd;
2013	unsigned int remaining;
2014	struct qmi_txn txn = {};
2015	int ret;
2016	const u8 *temp;
2017	int bdf_type;
2018
2019	req = kzalloc(sizeof(*req), GFP_KERNEL);
2020	if (!req)
2021		return -ENOMEM;
2022	memset(&resp, 0, sizeof(resp));
2023
2024	memset(&bd, 0, sizeof(bd));
2025	ret = ath11k_core_fetch_bdf(ab, &bd);
2026	if (ret) {
2027		ath11k_warn(ab, "qmi failed to load bdf:\n");
2028		goto out;
2029	}
2030
2031	temp = bd.data;
2032	remaining = bd.len;
2033
2034	if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
2035		bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
2036	else
2037		bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
2038
2039	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
2040
2041	while (remaining) {
2042		req->valid = 1;
2043		req->file_id_valid = 1;
2044		req->file_id = ab->qmi.target.board_id;
2045		req->total_size_valid = 1;
2046		req->total_size = bd.len;
2047		req->seg_id_valid = 1;
2048		req->data_valid = 1;
2049		req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
2050		req->bdf_type = bdf_type;
2051		req->bdf_type_valid = 1;
2052		req->end_valid = 1;
2053		req->end = 0;
2054
2055		if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2056			req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2057		} else {
2058			req->data_len = remaining;
2059			req->end = 1;
2060		}
2061
2062		memcpy(req->data, temp, req->data_len);
2063
2064		ret = qmi_txn_init(&ab->qmi.handle, &txn,
2065				   qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2066				   &resp);
2067		if (ret < 0)
2068			goto out_qmi_bdf;
2069
2070		ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2071				       QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2072				       QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2073				       qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2074		if (ret < 0) {
2075			qmi_txn_cancel(&txn);
2076			goto out_qmi_bdf;
2077		}
2078
2079		ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2080		if (ret < 0)
2081			goto out_qmi_bdf;
2082
2083		if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2084			ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2085				    resp.resp.result, resp.resp.error);
2086			ret = resp.resp.result;
2087			goto out_qmi_bdf;
2088		}
2089		remaining -= req->data_len;
2090		temp += req->data_len;
2091		req->seg_id++;
2092	}
2093
2094out_qmi_bdf:
2095	ath11k_core_free_bdf(ab, &bd);
2096
2097out:
2098	kfree(req);
2099	return ret;
2100}
2101
2102static int ath11k_qmi_m3_load(struct ath11k_base *ab)
2103{
2104	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2105	const struct firmware *fw;
2106	char path[100];
2107	int ret;
2108
2109	if (m3_mem->vaddr || m3_mem->size)
2110		return 0;
2111
2112	fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
2113	if (IS_ERR(fw)) {
2114		ret = PTR_ERR(fw);
2115		ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,
2116						 path, sizeof(path));
2117		ath11k_err(ab, "failed to load %s: %d\n", path, ret);
2118		return ret;
2119	}
2120
2121	m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2122					   fw->size, &m3_mem->paddr,
2123					   GFP_KERNEL);
2124	if (!m3_mem->vaddr) {
2125		ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2126			   fw->size);
2127		release_firmware(fw);
2128		return -ENOMEM;
2129	}
2130
2131	memcpy(m3_mem->vaddr, fw->data, fw->size);
2132	m3_mem->size = fw->size;
2133	release_firmware(fw);
2134
2135	return 0;
2136}
2137
2138static void ath11k_qmi_m3_free(struct ath11k_base *ab)
2139{
2140	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2141
2142	if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr)
2143		return;
2144
2145	dma_free_coherent(ab->dev, m3_mem->size,
2146			  m3_mem->vaddr, m3_mem->paddr);
2147	m3_mem->vaddr = NULL;
2148}
2149
2150static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
2151{
2152	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2153	struct qmi_wlanfw_m3_info_req_msg_v01 req;
2154	struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
2155	struct qmi_txn txn = {};
2156	int ret = 0;
2157
2158	memset(&req, 0, sizeof(req));
2159	memset(&resp, 0, sizeof(resp));
2160
2161	if (ab->bus_params.m3_fw_support) {
2162		ret = ath11k_qmi_m3_load(ab);
2163		if (ret) {
2164			ath11k_err(ab, "failed to load m3 firmware: %d", ret);
2165			return ret;
2166		}
2167
2168		req.addr = m3_mem->paddr;
2169		req.size = m3_mem->size;
2170	} else {
2171		req.addr = 0;
2172		req.size = 0;
2173	}
2174
2175	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2176			   qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
2177	if (ret < 0)
2178		goto out;
2179
2180	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2181			       QMI_WLANFW_M3_INFO_REQ_V01,
2182			       QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
2183			       qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
2184	if (ret < 0) {
2185		ath11k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
2186			    ret);
2187		goto out;
2188	}
2189
2190	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2191	if (ret < 0) {
2192		ath11k_warn(ab, "qmi failed M3 information request %d\n", ret);
2193		goto out;
2194	}
2195
2196	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2197		ath11k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
2198			    resp.resp.result, resp.resp.error);
2199		ret = -EINVAL;
2200		goto out;
2201	}
2202out:
2203	return ret;
2204}
2205
2206static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
2207				       u32 mode)
2208{
2209	struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
2210	struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
2211	struct qmi_txn txn = {};
2212	int ret = 0;
2213
2214	memset(&req, 0, sizeof(req));
2215	memset(&resp, 0, sizeof(resp));
2216
2217	req.mode = mode;
2218	req.hw_debug_valid = 1;
2219	req.hw_debug = 0;
2220
2221	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2222			   qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
2223	if (ret < 0)
2224		goto out;
2225
2226	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2227			       QMI_WLANFW_WLAN_MODE_REQ_V01,
2228			       QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
2229			       qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
2230	if (ret < 0) {
2231		ath11k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
2232			    mode, ret);
2233		goto out;
2234	}
2235
2236	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2237	if (ret < 0) {
2238		if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
2239			ath11k_warn(ab, "WLFW service is dis-connected\n");
2240			return 0;
2241		}
2242		ath11k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
2243			    mode, ret);
2244		goto out;
2245	}
2246
2247	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2248		ath11k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
2249			    mode, resp.resp.result, resp.resp.error);
2250		ret = -EINVAL;
2251		goto out;
2252	}
2253
2254out:
2255	return ret;
2256}
2257
2258static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
2259{
2260	struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
2261	struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
2262	struct ce_pipe_config *ce_cfg;
2263	struct service_to_pipe *svc_cfg;
2264	struct qmi_txn txn = {};
2265	int ret = 0, pipe_num;
2266
2267	ce_cfg	= (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
2268	svc_cfg	= (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
2269
2270	req = kzalloc(sizeof(*req), GFP_KERNEL);
2271	if (!req)
2272		return -ENOMEM;
2273
2274	memset(&resp, 0, sizeof(resp));
2275
2276	req->host_version_valid = 1;
2277	strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING,
2278		sizeof(req->host_version));
2279
2280	req->tgt_cfg_valid = 1;
2281	/* This is number of CE configs */
2282	req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
2283	for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
2284		req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
2285		req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
2286		req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
2287		req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
2288		req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
2289	}
2290
2291	req->svc_cfg_valid = 1;
2292	/* This is number of Service/CE configs */
2293	req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
2294	for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
2295		req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
2296		req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
2297		req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
2298	}
2299	req->shadow_reg_valid = 0;
2300
2301	/* set shadow v2 configuration */
2302	if (ab->hw_params.supports_shadow_regs) {
2303		req->shadow_reg_v2_valid = 1;
2304		req->shadow_reg_v2_len = min_t(u32,
2305					       ab->qmi.ce_cfg.shadow_reg_v2_len,
2306					       QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);
2307		memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,
2308		       sizeof(u32) * req->shadow_reg_v2_len);
2309	} else {
2310		req->shadow_reg_v2_valid = 0;
2311	}
2312
2313	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2314			   qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
2315	if (ret < 0)
2316		goto out;
2317
2318	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2319			       QMI_WLANFW_WLAN_CFG_REQ_V01,
2320			       QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
2321			       qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
2322	if (ret < 0) {
2323		ath11k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
2324			    ret);
2325		goto out;
2326	}
2327
2328	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2329	if (ret < 0) {
2330		ath11k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
2331		goto out;
2332	}
2333
2334	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2335		ath11k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
2336			    resp.resp.result, resp.resp.error);
2337		ret = -EINVAL;
2338		goto out;
2339	}
2340
2341out:
2342	kfree(req);
2343	return ret;
2344}
2345
2346void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
2347{
2348	int ret;
2349
2350	ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
2351	if (ret < 0) {
2352		ath11k_warn(ab, "qmi failed to send wlan mode off\n");
2353		return;
2354	}
2355}
2356
2357int ath11k_qmi_firmware_start(struct ath11k_base *ab,
2358			      u32 mode)
2359{
2360	int ret;
2361
2362	ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
2363	if (ret < 0) {
2364		ath11k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
2365		return ret;
2366	}
2367
2368	ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
2369	if (ret < 0) {
2370		ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
2371		return ret;
2372	}
2373
2374	return 0;
2375}
2376
2377static int
2378ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
2379			     enum ath11k_qmi_event_type type,
2380			     void *data)
2381{
2382	struct ath11k_qmi_driver_event *event;
2383
2384	event = kzalloc(sizeof(*event), GFP_ATOMIC);
2385	if (!event)
2386		return -ENOMEM;
2387
2388	event->type = type;
2389	event->data = data;
2390
2391	spin_lock(&qmi->event_lock);
2392	list_add_tail(&event->list, &qmi->event_list);
2393	spin_unlock(&qmi->event_lock);
2394
2395	queue_work(qmi->event_wq, &qmi->event_work);
2396
2397	return 0;
2398}
2399
2400static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
2401{
2402	struct ath11k_base *ab = qmi->ab;
2403	int ret;
2404
2405	ret = ath11k_qmi_fw_ind_register_send(ab);
2406	if (ret < 0) {
2407		ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
2408		return;
2409	}
2410
2411	ret = ath11k_qmi_host_cap_send(ab);
2412	if (ret < 0) {
2413		ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret);
2414		return;
2415	}
2416}
2417
2418static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
2419{
2420	struct ath11k_base *ab = qmi->ab;
2421	int ret;
2422
2423	ret = ath11k_qmi_respond_fw_mem_request(ab);
2424	if (ret < 0) {
2425		ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
2426		return;
2427	}
2428}
2429
2430static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
2431{
2432	struct ath11k_base *ab = qmi->ab;
2433	int ret;
2434
2435	ret = ath11k_qmi_request_target_cap(ab);
2436	if (ret < 0) {
2437		ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
2438		return;
2439	}
2440
2441	if (ab->bus_params.fixed_bdf_addr)
2442		ret = ath11k_qmi_load_bdf_fixed_addr(ab);
2443	else
2444		ret = ath11k_qmi_load_bdf_qmi(ab);
2445	if (ret < 0) {
2446		ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
2447		return;
2448	}
2449
2450	ret = ath11k_qmi_wlanfw_m3_info_send(ab);
2451	if (ret < 0) {
2452		ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
2453		return;
2454	}
2455}
2456
2457static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
2458					  struct sockaddr_qrtr *sq,
2459					  struct qmi_txn *txn,
2460					  const void *data)
2461{
2462	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2463	struct ath11k_base *ab = qmi->ab;
2464	const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
2465	int i, ret;
2466
2467	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware request memory request\n");
2468
2469	if (msg->mem_seg_len == 0 ||
2470	    msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
2471		ath11k_warn(ab, "Invalid memory segment length: %u\n",
2472			    msg->mem_seg_len);
2473
2474	ab->qmi.mem_seg_count = msg->mem_seg_len;
2475
2476	for (i = 0; i < qmi->mem_seg_count ; i++) {
2477		ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
2478		ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
2479		ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi mem seg type %d size %d\n",
2480			   msg->mem_seg[i].type, msg->mem_seg[i].size);
2481	}
2482
2483	if (ab->bus_params.fixed_mem_region) {
2484		ret = ath11k_qmi_assign_target_mem_chunk(ab);
2485		if (ret) {
2486			ath11k_warn(ab, "qmi failed to assign target memory: %d\n",
2487				    ret);
2488			return;
2489		}
2490	} else {
2491		ret = ath11k_qmi_alloc_target_mem_chunk(ab);
2492		if (ret) {
2493			ath11k_warn(ab, "qmi failed to alloc target memory: %d\n",
2494				    ret);
2495			return;
2496		}
2497	}
2498
2499	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);
2500}
2501
2502static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
2503					struct sockaddr_qrtr *sq,
2504					struct qmi_txn *txn,
2505					const void *decoded)
2506{
2507	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2508	struct ath11k_base *ab = qmi->ab;
2509
2510	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware memory ready indication\n");
2511	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);
2512}
2513
2514static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
2515				       struct sockaddr_qrtr *sq,
2516				       struct qmi_txn *txn,
2517				       const void *decoded)
2518{
2519	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2520	struct ath11k_base *ab = qmi->ab;
2521
2522	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
2523	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
2524}
2525
2526static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi,
2527						 struct sockaddr_qrtr *sq,
2528						 struct qmi_txn *txn,
2529						 const void *decoded)
2530{
2531}
2532
2533static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
2534	{
2535		.type = QMI_INDICATION,
2536		.msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
2537		.ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
2538		.decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
2539		.fn = ath11k_qmi_msg_mem_request_cb,
2540	},
2541	{
2542		.type = QMI_INDICATION,
2543		.msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
2544		.ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
2545		.decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
2546		.fn = ath11k_qmi_msg_mem_ready_cb,
2547	},
2548	{
2549		.type = QMI_INDICATION,
2550		.msg_id = QMI_WLFW_FW_READY_IND_V01,
2551		.ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
2552		.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
2553		.fn = ath11k_qmi_msg_fw_ready_cb,
2554	},
2555	{
2556		.type = QMI_INDICATION,
2557		.msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,
2558		.ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,
2559		.decoded_size =
2560			sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
2561		.fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
2562	},
2563};
2564
2565static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
2566				     struct qmi_service *service)
2567{
2568	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2569	struct ath11k_base *ab = qmi->ab;
2570	struct sockaddr_qrtr *sq = &qmi->sq;
2571	int ret;
2572
2573	sq->sq_family = AF_QIPCRTR;
2574	sq->sq_node = service->node;
2575	sq->sq_port = service->port;
2576
2577	ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
2578			     sizeof(*sq), 0);
2579	if (ret) {
2580		ath11k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
2581		return ret;
2582	}
2583
2584	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n");
2585	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);
2586
2587	return 0;
2588}
2589
2590static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
2591				      struct qmi_service *service)
2592{
2593	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2594	struct ath11k_base *ab = qmi->ab;
2595
2596	ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw del server\n");
2597	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);
2598}
2599
2600static const struct qmi_ops ath11k_qmi_ops = {
2601	.new_server = ath11k_qmi_ops_new_server,
2602	.del_server = ath11k_qmi_ops_del_server,
2603};
2604
2605static void ath11k_qmi_driver_event_work(struct work_struct *work)
2606{
2607	struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
2608					      event_work);
2609	struct ath11k_qmi_driver_event *event;
2610	struct ath11k_base *ab = qmi->ab;
2611
2612	spin_lock(&qmi->event_lock);
2613	while (!list_empty(&qmi->event_list)) {
2614		event = list_first_entry(&qmi->event_list,
2615					 struct ath11k_qmi_driver_event, list);
2616		list_del(&event->list);
2617		spin_unlock(&qmi->event_lock);
2618
2619		if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
2620			kfree(event);
2621			return;
2622		}
2623
2624		switch (event->type) {
2625		case ATH11K_QMI_EVENT_SERVER_ARRIVE:
2626			ath11k_qmi_event_server_arrive(qmi);
2627			break;
2628		case ATH11K_QMI_EVENT_SERVER_EXIT:
2629			set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
2630			set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2631			break;
2632		case ATH11K_QMI_EVENT_REQUEST_MEM:
2633			ath11k_qmi_event_mem_request(qmi);
2634			break;
2635		case ATH11K_QMI_EVENT_FW_MEM_READY:
2636			ath11k_qmi_event_load_bdf(qmi);
2637			break;
2638		case ATH11K_QMI_EVENT_FW_READY:
2639			if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
2640				ath11k_hal_dump_srng_stats(ab);
2641				queue_work(ab->workqueue, &ab->restart_work);
2642				break;
2643			}
2644
2645			ath11k_core_qmi_firmware_ready(ab);
2646			ab->qmi.cal_done = 1;
2647			set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
2648
2649			break;
2650		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
2651			break;
2652		default:
2653			ath11k_warn(ab, "invalid event type: %d", event->type);
2654			break;
2655		}
2656		kfree(event);
2657		spin_lock(&qmi->event_lock);
2658	}
2659	spin_unlock(&qmi->event_lock);
2660}
2661
2662int ath11k_qmi_init_service(struct ath11k_base *ab)
2663{
2664	int ret;
2665
2666	memset(&ab->qmi.target, 0, sizeof(struct target_info));
2667	memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
2668	ab->qmi.ab = ab;
2669
2670	ab->qmi.target_mem_mode = ATH11K_QMI_TARGET_MEM_MODE_DEFAULT;
2671	ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
2672			      &ath11k_qmi_ops, ath11k_qmi_msg_handlers);
2673	if (ret < 0) {
2674		ath11k_warn(ab, "failed to initialize qmi handle\n");
2675		return ret;
2676	}
2677
2678	ab->qmi.event_wq = alloc_workqueue("ath11k_qmi_driver_event",
2679					   WQ_UNBOUND, 1);
2680	if (!ab->qmi.event_wq) {
2681		ath11k_err(ab, "failed to allocate workqueue\n");
2682		return -EFAULT;
2683	}
2684
2685	INIT_LIST_HEAD(&ab->qmi.event_list);
2686	spin_lock_init(&ab->qmi.event_lock);
2687	INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);
2688
2689	ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,
2690			     ATH11K_QMI_WLFW_SERVICE_VERS_V01,
2691			     ab->qmi.service_ins_id);
2692	if (ret < 0) {
2693		ath11k_warn(ab, "failed to add qmi lookup\n");
2694		destroy_workqueue(ab->qmi.event_wq);
2695		return ret;
2696	}
2697
2698	return ret;
2699}
2700
2701void ath11k_qmi_deinit_service(struct ath11k_base *ab)
2702{
2703	qmi_handle_release(&ab->qmi.handle);
2704	cancel_work_sync(&ab->qmi.event_work);
2705	destroy_workqueue(ab->qmi.event_wq);
2706	ath11k_qmi_m3_free(ab);
2707	ath11k_qmi_free_target_mem_chunk(ab);
2708}
2709
2710