xref: /linux/drivers/net/wireless/ath/ath12k/qmi.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/elf.h>
8 
9 #include "qmi.h"
10 #include "core.h"
11 #include "debug.h"
12 #include <linux/of.h>
13 #include <linux/firmware.h>
14 #include <linux/of_address.h>
15 #include <linux/ioport.h>
16 
17 #define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x02
18 #define HOST_CSTATE_BIT			0x04
19 #define PLATFORM_CAP_PCIE_GLOBAL_RESET	0x08
20 #define ATH12K_QMI_MAX_CHUNK_SIZE	2097152
21 
22 static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = {
23 	{
24 		.data_type      = QMI_UNSIGNED_1_BYTE,
25 		.elem_len       = 1,
26 		.elem_size      = sizeof(u8),
27 		.array_type	= NO_ARRAY,
28 		.tlv_type       = 0,
29 		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
30 					   chip_id),
31 	},
32 	{
33 		.data_type      = QMI_UNSIGNED_1_BYTE,
34 		.elem_len       = 1,
35 		.elem_size      = sizeof(u8),
36 		.array_type	= NO_ARRAY,
37 		.tlv_type       = 0,
38 		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
39 					   num_local_links),
40 	},
41 	{
42 		.data_type      = QMI_UNSIGNED_1_BYTE,
43 		.elem_len       = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
44 		.elem_size      = sizeof(u8),
45 		.array_type     = STATIC_ARRAY,
46 		.tlv_type       = 0,
47 		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
48 					   hw_link_id),
49 	},
50 	{
51 		.data_type      = QMI_UNSIGNED_1_BYTE,
52 		.elem_len       = QMI_WLFW_MAX_NUM_MLO_LINKS_PER_CHIP_V01,
53 		.elem_size      = sizeof(u8),
54 		.array_type     = STATIC_ARRAY,
55 		.tlv_type       = 0,
56 		.offset         = offsetof(struct wlfw_host_mlo_chip_info_s_v01,
57 					   valid_mlo_link_id),
58 	},
59 	{
60 		.data_type      = QMI_EOTI,
61 		.array_type	= NO_ARRAY,
62 		.tlv_type       = QMI_COMMON_TLV_TYPE,
63 	},
64 };
65 
66 static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
67 	{
68 		.data_type	= QMI_OPT_FLAG,
69 		.elem_len	= 1,
70 		.elem_size	= sizeof(u8),
71 		.array_type	= NO_ARRAY,
72 		.tlv_type	= 0x10,
73 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
74 					   num_clients_valid),
75 	},
76 	{
77 		.data_type	= QMI_UNSIGNED_4_BYTE,
78 		.elem_len	= 1,
79 		.elem_size	= sizeof(u32),
80 		.array_type	= NO_ARRAY,
81 		.tlv_type	= 0x10,
82 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
83 					   num_clients),
84 	},
85 	{
86 		.data_type	= QMI_OPT_FLAG,
87 		.elem_len	= 1,
88 		.elem_size	= sizeof(u8),
89 		.array_type	= NO_ARRAY,
90 		.tlv_type	= 0x11,
91 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
92 					   wake_msi_valid),
93 	},
94 	{
95 		.data_type	= QMI_UNSIGNED_4_BYTE,
96 		.elem_len	= 1,
97 		.elem_size	= sizeof(u32),
98 		.array_type	= NO_ARRAY,
99 		.tlv_type	= 0x11,
100 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
101 					   wake_msi),
102 	},
103 	{
104 		.data_type	= QMI_OPT_FLAG,
105 		.elem_len	= 1,
106 		.elem_size	= sizeof(u8),
107 		.array_type	= NO_ARRAY,
108 		.tlv_type	= 0x12,
109 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
110 					   gpios_valid),
111 	},
112 	{
113 		.data_type	= QMI_DATA_LEN,
114 		.elem_len	= 1,
115 		.elem_size	= sizeof(u8),
116 		.array_type	= NO_ARRAY,
117 		.tlv_type	= 0x12,
118 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
119 					   gpios_len),
120 	},
121 	{
122 		.data_type	= QMI_UNSIGNED_4_BYTE,
123 		.elem_len	= QMI_WLFW_MAX_NUM_GPIO_V01,
124 		.elem_size	= sizeof(u32),
125 		.array_type	= VAR_LEN_ARRAY,
126 		.tlv_type	= 0x12,
127 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
128 					   gpios),
129 	},
130 	{
131 		.data_type	= QMI_OPT_FLAG,
132 		.elem_len	= 1,
133 		.elem_size	= sizeof(u8),
134 		.array_type	= NO_ARRAY,
135 		.tlv_type	= 0x13,
136 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
137 					   nm_modem_valid),
138 	},
139 	{
140 		.data_type	= QMI_UNSIGNED_1_BYTE,
141 		.elem_len	= 1,
142 		.elem_size	= sizeof(u8),
143 		.array_type	= NO_ARRAY,
144 		.tlv_type	= 0x13,
145 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
146 					   nm_modem),
147 	},
148 	{
149 		.data_type	= QMI_OPT_FLAG,
150 		.elem_len	= 1,
151 		.elem_size	= sizeof(u8),
152 		.array_type	= NO_ARRAY,
153 		.tlv_type	= 0x14,
154 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
155 					   bdf_support_valid),
156 	},
157 	{
158 		.data_type	= QMI_UNSIGNED_1_BYTE,
159 		.elem_len	= 1,
160 		.elem_size	= sizeof(u8),
161 		.array_type	= NO_ARRAY,
162 		.tlv_type	= 0x14,
163 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
164 					   bdf_support),
165 	},
166 	{
167 		.data_type	= QMI_OPT_FLAG,
168 		.elem_len	= 1,
169 		.elem_size	= sizeof(u8),
170 		.array_type	= NO_ARRAY,
171 		.tlv_type	= 0x15,
172 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
173 					   bdf_cache_support_valid),
174 	},
175 	{
176 		.data_type	= QMI_UNSIGNED_1_BYTE,
177 		.elem_len	= 1,
178 		.elem_size	= sizeof(u8),
179 		.array_type	= NO_ARRAY,
180 		.tlv_type	= 0x15,
181 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
182 					   bdf_cache_support),
183 	},
184 	{
185 		.data_type	= QMI_OPT_FLAG,
186 		.elem_len	= 1,
187 		.elem_size	= sizeof(u8),
188 		.array_type	= NO_ARRAY,
189 		.tlv_type	= 0x16,
190 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
191 					   m3_support_valid),
192 	},
193 	{
194 		.data_type	= QMI_UNSIGNED_1_BYTE,
195 		.elem_len	= 1,
196 		.elem_size	= sizeof(u8),
197 		.array_type	= NO_ARRAY,
198 		.tlv_type	= 0x16,
199 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
200 					   m3_support),
201 	},
202 	{
203 		.data_type	= QMI_OPT_FLAG,
204 		.elem_len	= 1,
205 		.elem_size	= sizeof(u8),
206 		.array_type	= NO_ARRAY,
207 		.tlv_type	= 0x17,
208 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
209 					   m3_cache_support_valid),
210 	},
211 	{
212 		.data_type	= QMI_UNSIGNED_1_BYTE,
213 		.elem_len	= 1,
214 		.elem_size	= sizeof(u8),
215 		.array_type	= NO_ARRAY,
216 		.tlv_type	= 0x17,
217 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
218 					   m3_cache_support),
219 	},
220 	{
221 		.data_type	= QMI_OPT_FLAG,
222 		.elem_len	= 1,
223 		.elem_size	= sizeof(u8),
224 		.array_type	= NO_ARRAY,
225 		.tlv_type	= 0x18,
226 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
227 					   cal_filesys_support_valid),
228 	},
229 	{
230 		.data_type	= QMI_UNSIGNED_1_BYTE,
231 		.elem_len	= 1,
232 		.elem_size	= sizeof(u8),
233 		.array_type	= NO_ARRAY,
234 		.tlv_type	= 0x18,
235 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
236 					   cal_filesys_support),
237 	},
238 	{
239 		.data_type	= QMI_OPT_FLAG,
240 		.elem_len	= 1,
241 		.elem_size	= sizeof(u8),
242 		.array_type	= NO_ARRAY,
243 		.tlv_type	= 0x19,
244 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
245 					   cal_cache_support_valid),
246 	},
247 	{
248 		.data_type	= QMI_UNSIGNED_1_BYTE,
249 		.elem_len	= 1,
250 		.elem_size	= sizeof(u8),
251 		.array_type	= NO_ARRAY,
252 		.tlv_type	= 0x19,
253 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
254 					   cal_cache_support),
255 	},
256 	{
257 		.data_type	= QMI_OPT_FLAG,
258 		.elem_len	= 1,
259 		.elem_size	= sizeof(u8),
260 		.array_type	= NO_ARRAY,
261 		.tlv_type	= 0x1A,
262 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
263 					   cal_done_valid),
264 	},
265 	{
266 		.data_type	= QMI_UNSIGNED_1_BYTE,
267 		.elem_len	= 1,
268 		.elem_size	= sizeof(u8),
269 		.array_type	= NO_ARRAY,
270 		.tlv_type	= 0x1A,
271 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
272 					   cal_done),
273 	},
274 	{
275 		.data_type	= QMI_OPT_FLAG,
276 		.elem_len	= 1,
277 		.elem_size	= sizeof(u8),
278 		.array_type	= NO_ARRAY,
279 		.tlv_type	= 0x1B,
280 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
281 					   mem_bucket_valid),
282 	},
283 	{
284 		.data_type	= QMI_UNSIGNED_4_BYTE,
285 		.elem_len	= 1,
286 		.elem_size	= sizeof(u32),
287 		.array_type	= NO_ARRAY,
288 		.tlv_type	= 0x1B,
289 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
290 					   mem_bucket),
291 	},
292 	{
293 		.data_type	= QMI_OPT_FLAG,
294 		.elem_len	= 1,
295 		.elem_size	= sizeof(u8),
296 		.array_type	= NO_ARRAY,
297 		.tlv_type	= 0x1C,
298 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
299 					   mem_cfg_mode_valid),
300 	},
301 	{
302 		.data_type	= QMI_UNSIGNED_1_BYTE,
303 		.elem_len	= 1,
304 		.elem_size	= sizeof(u8),
305 		.array_type	= NO_ARRAY,
306 		.tlv_type	= 0x1C,
307 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
308 					   mem_cfg_mode),
309 	},
310 	{
311 		.data_type	= QMI_OPT_FLAG,
312 		.elem_len	= 1,
313 		.elem_size	= sizeof(u8),
314 		.array_type	= NO_ARRAY,
315 		.tlv_type	= 0x1D,
316 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
317 					   cal_duration_valid),
318 	},
319 	{
320 		.data_type	= QMI_UNSIGNED_2_BYTE,
321 		.elem_len	= 1,
322 		.elem_size	= sizeof(u16),
323 		.array_type	= NO_ARRAY,
324 		.tlv_type	= 0x1D,
325 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
326 					   cal_duraiton),
327 	},
328 	{
329 		.data_type	= QMI_OPT_FLAG,
330 		.elem_len	= 1,
331 		.elem_size	= sizeof(u8),
332 		.array_type	= NO_ARRAY,
333 		.tlv_type	= 0x1E,
334 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
335 					   platform_name_valid),
336 	},
337 	{
338 		.data_type	= QMI_STRING,
339 		.elem_len	= QMI_WLANFW_MAX_PLATFORM_NAME_LEN_V01 + 1,
340 		.elem_size	= sizeof(char),
341 		.array_type	= NO_ARRAY,
342 		.tlv_type	= 0x1E,
343 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
344 					   platform_name),
345 	},
346 	{
347 		.data_type	= QMI_OPT_FLAG,
348 		.elem_len	= 1,
349 		.elem_size	= sizeof(u8),
350 		.array_type	= NO_ARRAY,
351 		.tlv_type	= 0x1F,
352 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
353 					   ddr_range_valid),
354 	},
355 	{
356 		.data_type	= QMI_STRUCT,
357 		.elem_len	= QMI_WLANFW_MAX_HOST_DDR_RANGE_SIZE_V01,
358 		.elem_size	= sizeof(struct qmi_wlanfw_host_ddr_range),
359 		.array_type	= STATIC_ARRAY,
360 		.tlv_type	= 0x1F,
361 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
362 					   ddr_range),
363 	},
364 	{
365 		.data_type	= QMI_OPT_FLAG,
366 		.elem_len	= 1,
367 		.elem_size	= sizeof(u8),
368 		.array_type	= NO_ARRAY,
369 		.tlv_type	= 0x20,
370 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
371 					   host_build_type_valid),
372 	},
373 	{
374 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
375 		.elem_len	= 1,
376 		.elem_size	= sizeof(enum qmi_wlanfw_host_build_type),
377 		.array_type	= NO_ARRAY,
378 		.tlv_type	= 0x20,
379 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
380 					   host_build_type),
381 	},
382 	{
383 		.data_type	= QMI_OPT_FLAG,
384 		.elem_len	= 1,
385 		.elem_size	= sizeof(u8),
386 		.array_type	= NO_ARRAY,
387 		.tlv_type	= 0x21,
388 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
389 					   mlo_capable_valid),
390 	},
391 	{
392 		.data_type	= QMI_UNSIGNED_1_BYTE,
393 		.elem_len	= 1,
394 		.elem_size	= sizeof(u8),
395 		.array_type	= NO_ARRAY,
396 		.tlv_type	= 0x21,
397 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
398 					   mlo_capable),
399 	},
400 	{
401 		.data_type	= QMI_OPT_FLAG,
402 		.elem_len	= 1,
403 		.elem_size	= sizeof(u8),
404 		.array_type	= NO_ARRAY,
405 		.tlv_type	= 0x22,
406 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
407 					   mlo_chip_id_valid),
408 	},
409 	{
410 		.data_type	= QMI_UNSIGNED_2_BYTE,
411 		.elem_len	= 1,
412 		.elem_size	= sizeof(u16),
413 		.array_type	= NO_ARRAY,
414 		.tlv_type	= 0x22,
415 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
416 					   mlo_chip_id),
417 	},
418 	{
419 		.data_type	= QMI_OPT_FLAG,
420 		.elem_len	= 1,
421 		.elem_size	= sizeof(u8),
422 		.array_type	= NO_ARRAY,
423 		.tlv_type	= 0x23,
424 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
425 					   mlo_group_id_valid),
426 	},
427 	{
428 		.data_type	= QMI_UNSIGNED_1_BYTE,
429 		.elem_len	= 1,
430 		.elem_size	= sizeof(u8),
431 		.array_type	= NO_ARRAY,
432 		.tlv_type	= 0x23,
433 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
434 					   mlo_group_id),
435 	},
436 	{
437 		.data_type	= QMI_OPT_FLAG,
438 		.elem_len	= 1,
439 		.elem_size	= sizeof(u8),
440 		.array_type	= NO_ARRAY,
441 		.tlv_type	= 0x24,
442 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
443 					   max_mlo_peer_valid),
444 	},
445 	{
446 		.data_type	= QMI_UNSIGNED_2_BYTE,
447 		.elem_len	= 1,
448 		.elem_size	= sizeof(u16),
449 		.array_type	= NO_ARRAY,
450 		.tlv_type	= 0x24,
451 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
452 					   max_mlo_peer),
453 	},
454 	{
455 		.data_type	= QMI_OPT_FLAG,
456 		.elem_len	= 1,
457 		.elem_size	= sizeof(u8),
458 		.array_type	= NO_ARRAY,
459 		.tlv_type	= 0x25,
460 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
461 					   mlo_num_chips_valid),
462 	},
463 	{
464 		.data_type	= QMI_UNSIGNED_1_BYTE,
465 		.elem_len	= 1,
466 		.elem_size	= sizeof(u8),
467 		.array_type	= NO_ARRAY,
468 		.tlv_type	= 0x25,
469 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
470 					   mlo_num_chips),
471 	},
472 	{
473 		.data_type	= QMI_OPT_FLAG,
474 		.elem_len	= 1,
475 		.elem_size	= sizeof(u8),
476 		.array_type	= NO_ARRAY,
477 		.tlv_type	= 0x26,
478 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
479 					   mlo_chip_info_valid),
480 	},
481 	{
482 		.data_type	= QMI_STRUCT,
483 		.elem_len	= QMI_WLFW_MAX_NUM_MLO_CHIPS_V01,
484 		.elem_size	= sizeof(struct wlfw_host_mlo_chip_info_s_v01),
485 		.array_type	= STATIC_ARRAY,
486 		.tlv_type	= 0x26,
487 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
488 					   mlo_chip_info),
489 		.ei_array	= wlfw_host_mlo_chip_info_s_v01_ei,
490 	},
491 	{
492 		.data_type	= QMI_OPT_FLAG,
493 		.elem_len	= 1,
494 		.elem_size	= sizeof(u8),
495 		.array_type	= NO_ARRAY,
496 		.tlv_type	= 0x27,
497 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
498 					   feature_list_valid),
499 	},
500 	{
501 		.data_type	= QMI_UNSIGNED_8_BYTE,
502 		.elem_len	= 1,
503 		.elem_size	= sizeof(u64),
504 		.array_type	= NO_ARRAY,
505 		.tlv_type	= 0x27,
506 		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
507 					   feature_list),
508 	},
509 	{
510 		.data_type	= QMI_EOTI,
511 		.array_type	= NO_ARRAY,
512 		.tlv_type	= QMI_COMMON_TLV_TYPE,
513 	},
514 };
515 
516 static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
517 	{
518 		.data_type	= QMI_STRUCT,
519 		.elem_len	= 1,
520 		.elem_size	= sizeof(struct qmi_response_type_v01),
521 		.array_type	= NO_ARRAY,
522 		.tlv_type	= 0x02,
523 		.offset		= offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
524 		.ei_array	= qmi_response_type_v01_ei,
525 	},
526 	{
527 		.data_type	= QMI_EOTI,
528 		.array_type	= NO_ARRAY,
529 		.tlv_type	= QMI_COMMON_TLV_TYPE,
530 	},
531 };
532 
533 static const struct qmi_elem_info qmi_wlanfw_phy_cap_req_msg_v01_ei[] = {
534 	{
535 		.data_type	= QMI_EOTI,
536 		.array_type	= NO_ARRAY,
537 		.tlv_type	= QMI_COMMON_TLV_TYPE,
538 	},
539 };
540 
541 static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
542 	{
543 		.data_type	= QMI_STRUCT,
544 		.elem_len	= 1,
545 		.elem_size	= sizeof(struct qmi_response_type_v01),
546 		.array_type	= NO_ARRAY,
547 		.tlv_type	= 0x02,
548 		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01, resp),
549 		.ei_array	= qmi_response_type_v01_ei,
550 	},
551 	{
552 		.data_type	= QMI_OPT_FLAG,
553 		.elem_len	= 1,
554 		.elem_size	= sizeof(u8),
555 		.array_type	= NO_ARRAY,
556 		.tlv_type	= 0x10,
557 		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
558 					   num_phy_valid),
559 	},
560 	{
561 		.data_type	= QMI_UNSIGNED_1_BYTE,
562 		.elem_len	= 1,
563 		.elem_size	= sizeof(u8),
564 		.array_type	= NO_ARRAY,
565 		.tlv_type	= 0x10,
566 		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
567 					   num_phy),
568 	},
569 	{
570 		.data_type	= QMI_OPT_FLAG,
571 		.elem_len	= 1,
572 		.elem_size	= sizeof(u8),
573 		.array_type	= NO_ARRAY,
574 		.tlv_type	= 0x11,
575 		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
576 					   board_id_valid),
577 	},
578 	{
579 		.data_type	= QMI_UNSIGNED_4_BYTE,
580 		.elem_len	= 1,
581 		.elem_size	= sizeof(u32),
582 		.array_type	= NO_ARRAY,
583 		.tlv_type	= 0x11,
584 		.offset		= offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
585 					   board_id),
586 	},
587 	{
588 		.data_type      = QMI_OPT_FLAG,
589 		.elem_len       = 1,
590 		.elem_size      = sizeof(u8),
591 		.array_type     = NO_ARRAY,
592 		.tlv_type       = 0x13,
593 		.offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
594 					   single_chip_mlo_support_valid),
595 	},
596 	{
597 		.data_type      = QMI_UNSIGNED_1_BYTE,
598 		.elem_len       = 1,
599 		.elem_size      = sizeof(u8),
600 		.array_type     = NO_ARRAY,
601 		.tlv_type       = 0x13,
602 		.offset         = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
603 					   single_chip_mlo_support),
604 	},
605 	{
606 		.data_type	= QMI_EOTI,
607 		.array_type	= NO_ARRAY,
608 		.tlv_type	= QMI_COMMON_TLV_TYPE,
609 	},
610 };
611 
612 static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
613 	{
614 		.data_type	= QMI_OPT_FLAG,
615 		.elem_len	= 1,
616 		.elem_size	= sizeof(u8),
617 		.array_type	= NO_ARRAY,
618 		.tlv_type	= 0x10,
619 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
620 					   fw_ready_enable_valid),
621 	},
622 	{
623 		.data_type	= QMI_UNSIGNED_1_BYTE,
624 		.elem_len	= 1,
625 		.elem_size	= sizeof(u8),
626 		.array_type	= NO_ARRAY,
627 		.tlv_type	= 0x10,
628 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
629 					   fw_ready_enable),
630 	},
631 	{
632 		.data_type	= QMI_OPT_FLAG,
633 		.elem_len	= 1,
634 		.elem_size	= sizeof(u8),
635 		.array_type	= NO_ARRAY,
636 		.tlv_type	= 0x11,
637 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
638 					   initiate_cal_download_enable_valid),
639 	},
640 	{
641 		.data_type	= QMI_UNSIGNED_1_BYTE,
642 		.elem_len	= 1,
643 		.elem_size	= sizeof(u8),
644 		.array_type	= NO_ARRAY,
645 		.tlv_type	= 0x11,
646 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
647 					   initiate_cal_download_enable),
648 	},
649 	{
650 		.data_type	= QMI_OPT_FLAG,
651 		.elem_len	= 1,
652 		.elem_size	= sizeof(u8),
653 		.array_type	= NO_ARRAY,
654 		.tlv_type	= 0x12,
655 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
656 					   initiate_cal_update_enable_valid),
657 	},
658 	{
659 		.data_type	= QMI_UNSIGNED_1_BYTE,
660 		.elem_len	= 1,
661 		.elem_size	= sizeof(u8),
662 		.array_type	= NO_ARRAY,
663 		.tlv_type	= 0x12,
664 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
665 					   initiate_cal_update_enable),
666 	},
667 	{
668 		.data_type	= QMI_OPT_FLAG,
669 		.elem_len	= 1,
670 		.elem_size	= sizeof(u8),
671 		.array_type	= NO_ARRAY,
672 		.tlv_type	= 0x13,
673 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
674 					   msa_ready_enable_valid),
675 	},
676 	{
677 		.data_type	= QMI_UNSIGNED_1_BYTE,
678 		.elem_len	= 1,
679 		.elem_size	= sizeof(u8),
680 		.array_type	= NO_ARRAY,
681 		.tlv_type	= 0x13,
682 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
683 					   msa_ready_enable),
684 	},
685 	{
686 		.data_type	= QMI_OPT_FLAG,
687 		.elem_len	= 1,
688 		.elem_size	= sizeof(u8),
689 		.array_type	= NO_ARRAY,
690 		.tlv_type	= 0x14,
691 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
692 					   pin_connect_result_enable_valid),
693 	},
694 	{
695 		.data_type	= QMI_UNSIGNED_1_BYTE,
696 		.elem_len	= 1,
697 		.elem_size	= sizeof(u8),
698 		.array_type	= NO_ARRAY,
699 		.tlv_type	= 0x14,
700 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
701 					   pin_connect_result_enable),
702 	},
703 	{
704 		.data_type	= QMI_OPT_FLAG,
705 		.elem_len	= 1,
706 		.elem_size	= sizeof(u8),
707 		.array_type	= NO_ARRAY,
708 		.tlv_type	= 0x15,
709 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
710 					   client_id_valid),
711 	},
712 	{
713 		.data_type	= QMI_UNSIGNED_4_BYTE,
714 		.elem_len	= 1,
715 		.elem_size	= sizeof(u32),
716 		.array_type	= NO_ARRAY,
717 		.tlv_type	= 0x15,
718 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
719 					   client_id),
720 	},
721 	{
722 		.data_type	= QMI_OPT_FLAG,
723 		.elem_len	= 1,
724 		.elem_size	= sizeof(u8),
725 		.array_type	= NO_ARRAY,
726 		.tlv_type	= 0x16,
727 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
728 					   request_mem_enable_valid),
729 	},
730 	{
731 		.data_type	= QMI_UNSIGNED_1_BYTE,
732 		.elem_len	= 1,
733 		.elem_size	= sizeof(u8),
734 		.array_type	= NO_ARRAY,
735 		.tlv_type	= 0x16,
736 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
737 					   request_mem_enable),
738 	},
739 	{
740 		.data_type	= QMI_OPT_FLAG,
741 		.elem_len	= 1,
742 		.elem_size	= sizeof(u8),
743 		.array_type	= NO_ARRAY,
744 		.tlv_type	= 0x17,
745 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
746 					   fw_mem_ready_enable_valid),
747 	},
748 	{
749 		.data_type	= QMI_UNSIGNED_1_BYTE,
750 		.elem_len	= 1,
751 		.elem_size	= sizeof(u8),
752 		.array_type	= NO_ARRAY,
753 		.tlv_type	= 0x17,
754 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
755 					   fw_mem_ready_enable),
756 	},
757 	{
758 		.data_type	= QMI_OPT_FLAG,
759 		.elem_len	= 1,
760 		.elem_size	= sizeof(u8),
761 		.array_type	= NO_ARRAY,
762 		.tlv_type	= 0x18,
763 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
764 					   fw_init_done_enable_valid),
765 	},
766 	{
767 		.data_type	= QMI_UNSIGNED_1_BYTE,
768 		.elem_len	= 1,
769 		.elem_size	= sizeof(u8),
770 		.array_type	= NO_ARRAY,
771 		.tlv_type	= 0x18,
772 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
773 					   fw_init_done_enable),
774 	},
775 
776 	{
777 		.data_type	= QMI_OPT_FLAG,
778 		.elem_len	= 1,
779 		.elem_size	= sizeof(u8),
780 		.array_type	= NO_ARRAY,
781 		.tlv_type	= 0x19,
782 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
783 					   rejuvenate_enable_valid),
784 	},
785 	{
786 		.data_type	= QMI_UNSIGNED_1_BYTE,
787 		.elem_len	= 1,
788 		.elem_size	= sizeof(u8),
789 		.array_type	= NO_ARRAY,
790 		.tlv_type	= 0x19,
791 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
792 					   rejuvenate_enable),
793 	},
794 	{
795 		.data_type	= QMI_OPT_FLAG,
796 		.elem_len	= 1,
797 		.elem_size	= sizeof(u8),
798 		.array_type	= NO_ARRAY,
799 		.tlv_type	= 0x1A,
800 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
801 					   xo_cal_enable_valid),
802 	},
803 	{
804 		.data_type	= QMI_UNSIGNED_1_BYTE,
805 		.elem_len	= 1,
806 		.elem_size	= sizeof(u8),
807 		.array_type	= NO_ARRAY,
808 		.tlv_type	= 0x1A,
809 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
810 					   xo_cal_enable),
811 	},
812 	{
813 		.data_type	= QMI_OPT_FLAG,
814 		.elem_len	= 1,
815 		.elem_size	= sizeof(u8),
816 		.array_type	= NO_ARRAY,
817 		.tlv_type	= 0x1B,
818 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
819 					   cal_done_enable_valid),
820 	},
821 	{
822 		.data_type	= QMI_UNSIGNED_1_BYTE,
823 		.elem_len	= 1,
824 		.elem_size	= sizeof(u8),
825 		.array_type	= NO_ARRAY,
826 		.tlv_type	= 0x1B,
827 		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
828 					   cal_done_enable),
829 	},
830 	{
831 		.data_type	= QMI_EOTI,
832 		.array_type	= NO_ARRAY,
833 		.tlv_type	= QMI_COMMON_TLV_TYPE,
834 	},
835 };
836 
837 static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
838 	{
839 		.data_type	= QMI_STRUCT,
840 		.elem_len	= 1,
841 		.elem_size	= sizeof(struct qmi_response_type_v01),
842 		.array_type	= NO_ARRAY,
843 		.tlv_type	= 0x02,
844 		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
845 					   resp),
846 		.ei_array	= qmi_response_type_v01_ei,
847 	},
848 	{
849 		.data_type	= QMI_OPT_FLAG,
850 		.elem_len	= 1,
851 		.elem_size	= sizeof(u8),
852 		.array_type	= NO_ARRAY,
853 		.tlv_type	= 0x10,
854 		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
855 					   fw_status_valid),
856 	},
857 	{
858 		.data_type	= QMI_UNSIGNED_8_BYTE,
859 		.elem_len	= 1,
860 		.elem_size	= sizeof(u64),
861 		.array_type	= NO_ARRAY,
862 		.tlv_type	= 0x10,
863 		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
864 					   fw_status),
865 	},
866 	{
867 		.data_type	= QMI_EOTI,
868 		.array_type	= NO_ARRAY,
869 		.tlv_type	= QMI_COMMON_TLV_TYPE,
870 	},
871 };
872 
873 static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
874 	{
875 		.data_type	= QMI_UNSIGNED_8_BYTE,
876 		.elem_len	= 1,
877 		.elem_size	= sizeof(u64),
878 		.array_type	= NO_ARRAY,
879 		.tlv_type	= 0,
880 		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
881 	},
882 	{
883 		.data_type	= QMI_UNSIGNED_4_BYTE,
884 		.elem_len	= 1,
885 		.elem_size	= sizeof(u32),
886 		.array_type	= NO_ARRAY,
887 		.tlv_type	= 0,
888 		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
889 	},
890 	{
891 		.data_type	= QMI_UNSIGNED_1_BYTE,
892 		.elem_len	= 1,
893 		.elem_size	= sizeof(u8),
894 		.array_type	= NO_ARRAY,
895 		.tlv_type	= 0,
896 		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
897 	},
898 	{
899 		.data_type	= QMI_EOTI,
900 		.array_type	= NO_ARRAY,
901 		.tlv_type	= QMI_COMMON_TLV_TYPE,
902 	},
903 };
904 
905 static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
906 	{
907 		.data_type	= QMI_UNSIGNED_4_BYTE,
908 		.elem_len	= 1,
909 		.elem_size	= sizeof(u32),
910 		.array_type	= NO_ARRAY,
911 		.tlv_type	= 0,
912 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01,
913 				  size),
914 	},
915 	{
916 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
917 		.elem_len	= 1,
918 		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
919 		.array_type	= NO_ARRAY,
920 		.tlv_type	= 0,
921 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
922 	},
923 	{
924 		.data_type	= QMI_DATA_LEN,
925 		.elem_len	= 1,
926 		.elem_size	= sizeof(u8),
927 		.array_type	= NO_ARRAY,
928 		.tlv_type	= 0,
929 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
930 	},
931 	{
932 		.data_type	= QMI_STRUCT,
933 		.elem_len	= QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
934 		.elem_size	= sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
935 		.array_type	= VAR_LEN_ARRAY,
936 		.tlv_type	= 0,
937 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
938 		.ei_array	= qmi_wlanfw_mem_cfg_s_v01_ei,
939 	},
940 	{
941 		.data_type	= QMI_EOTI,
942 		.array_type	= NO_ARRAY,
943 		.tlv_type	= QMI_COMMON_TLV_TYPE,
944 	},
945 };
946 
947 static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
948 	{
949 		.data_type	= QMI_DATA_LEN,
950 		.elem_len	= 1,
951 		.elem_size	= sizeof(u8),
952 		.array_type	= NO_ARRAY,
953 		.tlv_type	= 0x01,
954 		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
955 					   mem_seg_len),
956 	},
957 	{
958 		.data_type	= QMI_STRUCT,
959 		.elem_len	= ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
960 		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_s_v01),
961 		.array_type	= VAR_LEN_ARRAY,
962 		.tlv_type	= 0x01,
963 		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
964 					   mem_seg),
965 		.ei_array	= qmi_wlanfw_mem_seg_s_v01_ei,
966 	},
967 	{
968 		.data_type	= QMI_EOTI,
969 		.array_type	= NO_ARRAY,
970 		.tlv_type	= QMI_COMMON_TLV_TYPE,
971 	},
972 };
973 
974 static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
975 	{
976 		.data_type	= QMI_UNSIGNED_8_BYTE,
977 		.elem_len	= 1,
978 		.elem_size	= sizeof(u64),
979 		.array_type	= NO_ARRAY,
980 		.tlv_type	= 0,
981 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
982 	},
983 	{
984 		.data_type	= QMI_UNSIGNED_4_BYTE,
985 		.elem_len	= 1,
986 		.elem_size	= sizeof(u32),
987 		.array_type	= NO_ARRAY,
988 		.tlv_type	= 0,
989 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
990 	},
991 	{
992 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
993 		.elem_len	= 1,
994 		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),
995 		.array_type	= NO_ARRAY,
996 		.tlv_type	= 0,
997 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
998 	},
999 	{
1000 		.data_type	= QMI_UNSIGNED_1_BYTE,
1001 		.elem_len	= 1,
1002 		.elem_size	= sizeof(u8),
1003 		.array_type	= NO_ARRAY,
1004 		.tlv_type	= 0,
1005 		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
1006 	},
1007 	{
1008 		.data_type	= QMI_EOTI,
1009 		.array_type	= NO_ARRAY,
1010 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1011 	},
1012 };
1013 
1014 static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
1015 	{
1016 		.data_type	= QMI_DATA_LEN,
1017 		.elem_len	= 1,
1018 		.elem_size	= sizeof(u8),
1019 		.array_type	= NO_ARRAY,
1020 		.tlv_type	= 0x01,
1021 		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1022 					   mem_seg_len),
1023 	},
1024 	{
1025 		.data_type	= QMI_STRUCT,
1026 		.elem_len	= ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
1027 		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
1028 		.array_type	= VAR_LEN_ARRAY,
1029 		.tlv_type	= 0x01,
1030 		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1031 					   mem_seg),
1032 		.ei_array	= qmi_wlanfw_mem_seg_resp_s_v01_ei,
1033 	},
1034 	{
1035 		.data_type	= QMI_EOTI,
1036 		.array_type	= NO_ARRAY,
1037 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1038 	},
1039 };
1040 
1041 static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
1042 	{
1043 		.data_type	= QMI_STRUCT,
1044 		.elem_len	= 1,
1045 		.elem_size	= sizeof(struct qmi_response_type_v01),
1046 		.array_type	= NO_ARRAY,
1047 		.tlv_type	= 0x02,
1048 		.offset		= offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
1049 					   resp),
1050 		.ei_array	= qmi_response_type_v01_ei,
1051 	},
1052 	{
1053 		.data_type	= QMI_EOTI,
1054 		.array_type	= NO_ARRAY,
1055 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1056 	},
1057 };
1058 
1059 static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
1060 	{
1061 		.data_type	= QMI_EOTI,
1062 		.array_type	= NO_ARRAY,
1063 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1064 	},
1065 };
1066 
1067 static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
1068 	{
1069 		.data_type	= QMI_UNSIGNED_4_BYTE,
1070 		.elem_len	= 1,
1071 		.elem_size	= sizeof(u32),
1072 		.array_type	= NO_ARRAY,
1073 		.tlv_type	= 0,
1074 		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1075 					   chip_id),
1076 	},
1077 	{
1078 		.data_type	= QMI_UNSIGNED_4_BYTE,
1079 		.elem_len	= 1,
1080 		.elem_size	= sizeof(u32),
1081 		.array_type	= NO_ARRAY,
1082 		.tlv_type	= 0,
1083 		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1084 					   chip_family),
1085 	},
1086 	{
1087 		.data_type	= QMI_EOTI,
1088 		.array_type	= NO_ARRAY,
1089 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1090 	},
1091 };
1092 
1093 static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
1094 	{
1095 		.data_type	= QMI_UNSIGNED_4_BYTE,
1096 		.elem_len	= 1,
1097 		.elem_size	= sizeof(u32),
1098 		.array_type	= NO_ARRAY,
1099 		.tlv_type	= 0,
1100 		.offset		= offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
1101 					   board_id),
1102 	},
1103 	{
1104 		.data_type	= QMI_EOTI,
1105 		.array_type	= NO_ARRAY,
1106 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1107 	},
1108 };
1109 
1110 static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
1111 	{
1112 		.data_type	= QMI_UNSIGNED_4_BYTE,
1113 		.elem_len	= 1,
1114 		.elem_size	= sizeof(u32),
1115 		.array_type	= NO_ARRAY,
1116 		.tlv_type	= 0,
1117 		.offset		= offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
1118 	},
1119 	{
1120 		.data_type	= QMI_EOTI,
1121 		.array_type	= NO_ARRAY,
1122 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1123 	},
1124 };
1125 
1126 static const struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
1127 	{
1128 		.data_type	= QMI_UNSIGNED_8_BYTE,
1129 		.elem_len	= 1,
1130 		.elem_size	= sizeof(u64),
1131 		.array_type	= NO_ARRAY,
1132 		.tlv_type	= 0,
1133 		.offset		= offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1134 					   start),
1135 	},
1136 	{
1137 		.data_type	= QMI_UNSIGNED_8_BYTE,
1138 		.elem_len	= 1,
1139 		.elem_size	= sizeof(u64),
1140 		.array_type	= NO_ARRAY,
1141 		.tlv_type	= 0,
1142 		.offset		= offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1143 					   size),
1144 	},
1145 	{
1146 		.data_type	= QMI_EOTI,
1147 		.array_type	= NO_ARRAY,
1148 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1149 	},
1150 };
1151 
1152 static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
1153 	{
1154 		.data_type	= QMI_UNSIGNED_4_BYTE,
1155 		.elem_len	= 1,
1156 		.elem_size	= sizeof(u32),
1157 		.array_type	= NO_ARRAY,
1158 		.tlv_type	= 0,
1159 		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1160 					   fw_version),
1161 	},
1162 	{
1163 		.data_type	= QMI_STRING,
1164 		.elem_len	= ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
1165 		.elem_size	= sizeof(char),
1166 		.array_type	= NO_ARRAY,
1167 		.tlv_type	= 0,
1168 		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1169 					   fw_build_timestamp),
1170 	},
1171 	{
1172 		.data_type	= QMI_EOTI,
1173 		.array_type	= NO_ARRAY,
1174 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1175 	},
1176 };
1177 
1178 static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
1179 	{
1180 		.data_type	= QMI_STRUCT,
1181 		.elem_len	= 1,
1182 		.elem_size	= sizeof(struct qmi_response_type_v01),
1183 		.array_type	= NO_ARRAY,
1184 		.tlv_type	= 0x02,
1185 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
1186 		.ei_array	= qmi_response_type_v01_ei,
1187 	},
1188 	{
1189 		.data_type	= QMI_OPT_FLAG,
1190 		.elem_len	= 1,
1191 		.elem_size	= sizeof(u8),
1192 		.array_type	= NO_ARRAY,
1193 		.tlv_type	= 0x10,
1194 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1195 					   chip_info_valid),
1196 	},
1197 	{
1198 		.data_type	= QMI_STRUCT,
1199 		.elem_len	= 1,
1200 		.elem_size	= sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
1201 		.array_type	= NO_ARRAY,
1202 		.tlv_type	= 0x10,
1203 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1204 					   chip_info),
1205 		.ei_array	= qmi_wlanfw_rf_chip_info_s_v01_ei,
1206 	},
1207 	{
1208 		.data_type	= QMI_OPT_FLAG,
1209 		.elem_len	= 1,
1210 		.elem_size	= sizeof(u8),
1211 		.array_type	= NO_ARRAY,
1212 		.tlv_type	= 0x11,
1213 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1214 					   board_info_valid),
1215 	},
1216 	{
1217 		.data_type	= QMI_STRUCT,
1218 		.elem_len	= 1,
1219 		.elem_size	= sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
1220 		.array_type	= NO_ARRAY,
1221 		.tlv_type	= 0x11,
1222 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1223 					   board_info),
1224 		.ei_array	= qmi_wlanfw_rf_board_info_s_v01_ei,
1225 	},
1226 	{
1227 		.data_type	= QMI_OPT_FLAG,
1228 		.elem_len	= 1,
1229 		.elem_size	= sizeof(u8),
1230 		.array_type	= NO_ARRAY,
1231 		.tlv_type	= 0x12,
1232 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1233 					   soc_info_valid),
1234 	},
1235 	{
1236 		.data_type	= QMI_STRUCT,
1237 		.elem_len	= 1,
1238 		.elem_size	= sizeof(struct qmi_wlanfw_soc_info_s_v01),
1239 		.array_type	= NO_ARRAY,
1240 		.tlv_type	= 0x12,
1241 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1242 					   soc_info),
1243 		.ei_array	= qmi_wlanfw_soc_info_s_v01_ei,
1244 	},
1245 	{
1246 		.data_type	= QMI_OPT_FLAG,
1247 		.elem_len	= 1,
1248 		.elem_size	= sizeof(u8),
1249 		.array_type	= NO_ARRAY,
1250 		.tlv_type	= 0x13,
1251 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1252 					   fw_version_info_valid),
1253 	},
1254 	{
1255 		.data_type	= QMI_STRUCT,
1256 		.elem_len	= 1,
1257 		.elem_size	= sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
1258 		.array_type	= NO_ARRAY,
1259 		.tlv_type	= 0x13,
1260 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1261 					   fw_version_info),
1262 		.ei_array	= qmi_wlanfw_fw_version_info_s_v01_ei,
1263 	},
1264 	{
1265 		.data_type	= QMI_OPT_FLAG,
1266 		.elem_len	= 1,
1267 		.elem_size	= sizeof(u8),
1268 		.array_type	= NO_ARRAY,
1269 		.tlv_type	= 0x14,
1270 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1271 					   fw_build_id_valid),
1272 	},
1273 	{
1274 		.data_type	= QMI_STRING,
1275 		.elem_len	= ATH12K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
1276 		.elem_size	= sizeof(char),
1277 		.array_type	= NO_ARRAY,
1278 		.tlv_type	= 0x14,
1279 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1280 					   fw_build_id),
1281 	},
1282 	{
1283 		.data_type	= QMI_OPT_FLAG,
1284 		.elem_len	= 1,
1285 		.elem_size	= sizeof(u8),
1286 		.array_type	= NO_ARRAY,
1287 		.tlv_type	= 0x15,
1288 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1289 					   num_macs_valid),
1290 	},
1291 	{
1292 		.data_type	= QMI_UNSIGNED_1_BYTE,
1293 		.elem_len	= 1,
1294 		.elem_size	= sizeof(u8),
1295 		.array_type	= NO_ARRAY,
1296 		.tlv_type	= 0x15,
1297 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1298 					   num_macs),
1299 	},
1300 	{
1301 		.data_type	= QMI_OPT_FLAG,
1302 		.elem_len	= 1,
1303 		.elem_size	= sizeof(u8),
1304 		.array_type	= NO_ARRAY,
1305 		.tlv_type	= 0x16,
1306 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1307 					   voltage_mv_valid),
1308 	},
1309 	{
1310 		.data_type	= QMI_UNSIGNED_4_BYTE,
1311 		.elem_len	= 1,
1312 		.elem_size	= sizeof(u32),
1313 		.array_type	= NO_ARRAY,
1314 		.tlv_type	= 0x16,
1315 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1316 					   voltage_mv),
1317 	},
1318 	{
1319 		.data_type	= QMI_OPT_FLAG,
1320 		.elem_len	= 1,
1321 		.elem_size	= sizeof(u8),
1322 		.array_type	= NO_ARRAY,
1323 		.tlv_type	= 0x17,
1324 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1325 					   time_freq_hz_valid),
1326 	},
1327 	{
1328 		.data_type	= QMI_UNSIGNED_4_BYTE,
1329 		.elem_len	= 1,
1330 		.elem_size	= sizeof(u32),
1331 		.array_type	= NO_ARRAY,
1332 		.tlv_type	= 0x17,
1333 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1334 					   time_freq_hz),
1335 	},
1336 	{
1337 		.data_type	= QMI_OPT_FLAG,
1338 		.elem_len	= 1,
1339 		.elem_size	= sizeof(u8),
1340 		.array_type	= NO_ARRAY,
1341 		.tlv_type	= 0x18,
1342 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1343 					   otp_version_valid),
1344 	},
1345 	{
1346 		.data_type	= QMI_UNSIGNED_4_BYTE,
1347 		.elem_len	= 1,
1348 		.elem_size	= sizeof(u32),
1349 		.array_type	= NO_ARRAY,
1350 		.tlv_type	= 0x18,
1351 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1352 					   otp_version),
1353 	},
1354 	{
1355 		.data_type	= QMI_OPT_FLAG,
1356 		.elem_len	= 1,
1357 		.elem_size	= sizeof(u8),
1358 		.array_type	= NO_ARRAY,
1359 		.tlv_type	= 0x19,
1360 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1361 					   eeprom_caldata_read_timeout_valid),
1362 	},
1363 	{
1364 		.data_type	= QMI_UNSIGNED_4_BYTE,
1365 		.elem_len	= 1,
1366 		.elem_size	= sizeof(u32),
1367 		.array_type	= NO_ARRAY,
1368 		.tlv_type	= 0x19,
1369 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1370 					   eeprom_caldata_read_timeout),
1371 	},
1372 	{
1373 		.data_type	= QMI_OPT_FLAG,
1374 		.elem_len	= 1,
1375 		.elem_size	= sizeof(u8),
1376 		.array_type	= NO_ARRAY,
1377 		.tlv_type	= 0x1A,
1378 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1379 					   fw_caps_valid),
1380 	},
1381 	{
1382 		.data_type	= QMI_UNSIGNED_8_BYTE,
1383 		.elem_len	= 1,
1384 		.elem_size	= sizeof(u64),
1385 		.array_type	= NO_ARRAY,
1386 		.tlv_type	= 0x1A,
1387 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, fw_caps),
1388 	},
1389 	{
1390 		.data_type	= QMI_OPT_FLAG,
1391 		.elem_len	= 1,
1392 		.elem_size	= sizeof(u8),
1393 		.array_type	= NO_ARRAY,
1394 		.tlv_type	= 0x1B,
1395 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1396 					   rd_card_chain_cap_valid),
1397 	},
1398 	{
1399 		.data_type	= QMI_UNSIGNED_4_BYTE,
1400 		.elem_len	= 1,
1401 		.elem_size	= sizeof(u32),
1402 		.array_type	= NO_ARRAY,
1403 		.tlv_type	= 0x1B,
1404 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1405 					   rd_card_chain_cap),
1406 	},
1407 	{
1408 		.data_type	= QMI_OPT_FLAG,
1409 		.elem_len	= 1,
1410 		.elem_size	= sizeof(u8),
1411 		.array_type	= NO_ARRAY,
1412 		.tlv_type	= 0x1C,
1413 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1414 					   dev_mem_info_valid),
1415 	},
1416 	{
1417 		.data_type	= QMI_STRUCT,
1418 		.elem_len	= ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01,
1419 		.elem_size	= sizeof(struct qmi_wlanfw_dev_mem_info_s_v01),
1420 		.array_type	= STATIC_ARRAY,
1421 		.tlv_type	= 0x1C,
1422 		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, dev_mem),
1423 		.ei_array	= qmi_wlanfw_dev_mem_info_s_v01_ei,
1424 	},
1425 	{
1426 		.data_type	= QMI_EOTI,
1427 		.array_type	= NO_ARRAY,
1428 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1429 	},
1430 };
1431 
1432 static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
1433 	{
1434 		.data_type	= QMI_UNSIGNED_1_BYTE,
1435 		.elem_len	= 1,
1436 		.elem_size	= sizeof(u8),
1437 		.array_type	= NO_ARRAY,
1438 		.tlv_type	= 0x01,
1439 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1440 					   valid),
1441 	},
1442 	{
1443 		.data_type	= QMI_OPT_FLAG,
1444 		.elem_len	= 1,
1445 		.elem_size	= sizeof(u8),
1446 		.array_type	= NO_ARRAY,
1447 		.tlv_type	= 0x10,
1448 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1449 					   file_id_valid),
1450 	},
1451 	{
1452 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1453 		.elem_len	= 1,
1454 		.elem_size	= sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
1455 		.array_type	= NO_ARRAY,
1456 		.tlv_type	= 0x10,
1457 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1458 					   file_id),
1459 	},
1460 	{
1461 		.data_type	= QMI_OPT_FLAG,
1462 		.elem_len	= 1,
1463 		.elem_size	= sizeof(u8),
1464 		.array_type	= NO_ARRAY,
1465 		.tlv_type	= 0x11,
1466 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1467 					   total_size_valid),
1468 	},
1469 	{
1470 		.data_type	= QMI_UNSIGNED_4_BYTE,
1471 		.elem_len	= 1,
1472 		.elem_size	= sizeof(u32),
1473 		.array_type	= NO_ARRAY,
1474 		.tlv_type	= 0x11,
1475 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1476 					   total_size),
1477 	},
1478 	{
1479 		.data_type	= QMI_OPT_FLAG,
1480 		.elem_len	= 1,
1481 		.elem_size	= sizeof(u8),
1482 		.array_type	= NO_ARRAY,
1483 		.tlv_type	= 0x12,
1484 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1485 					   seg_id_valid),
1486 	},
1487 	{
1488 		.data_type	= QMI_UNSIGNED_4_BYTE,
1489 		.elem_len	= 1,
1490 		.elem_size	= sizeof(u32),
1491 		.array_type	= NO_ARRAY,
1492 		.tlv_type	= 0x12,
1493 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1494 					   seg_id),
1495 	},
1496 	{
1497 		.data_type	= QMI_OPT_FLAG,
1498 		.elem_len	= 1,
1499 		.elem_size	= sizeof(u8),
1500 		.array_type	= NO_ARRAY,
1501 		.tlv_type	= 0x13,
1502 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1503 					   data_valid),
1504 	},
1505 	{
1506 		.data_type	= QMI_DATA_LEN,
1507 		.elem_len	= 1,
1508 		.elem_size	= sizeof(u16),
1509 		.array_type	= NO_ARRAY,
1510 		.tlv_type	= 0x13,
1511 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1512 					   data_len),
1513 	},
1514 	{
1515 		.data_type	= QMI_UNSIGNED_1_BYTE,
1516 		.elem_len	= QMI_WLANFW_MAX_DATA_SIZE_V01,
1517 		.elem_size	= sizeof(u8),
1518 		.array_type	= VAR_LEN_ARRAY,
1519 		.tlv_type	= 0x13,
1520 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1521 					   data),
1522 	},
1523 	{
1524 		.data_type	= QMI_OPT_FLAG,
1525 		.elem_len	= 1,
1526 		.elem_size	= sizeof(u8),
1527 		.array_type	= NO_ARRAY,
1528 		.tlv_type	= 0x14,
1529 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1530 					   end_valid),
1531 	},
1532 	{
1533 		.data_type	= QMI_UNSIGNED_1_BYTE,
1534 		.elem_len	= 1,
1535 		.elem_size	= sizeof(u8),
1536 		.array_type	= NO_ARRAY,
1537 		.tlv_type	= 0x14,
1538 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1539 					   end),
1540 	},
1541 	{
1542 		.data_type	= QMI_OPT_FLAG,
1543 		.elem_len	= 1,
1544 		.elem_size	= sizeof(u8),
1545 		.array_type	= NO_ARRAY,
1546 		.tlv_type	= 0x15,
1547 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1548 					   bdf_type_valid),
1549 	},
1550 	{
1551 		.data_type	= QMI_UNSIGNED_1_BYTE,
1552 		.elem_len	= 1,
1553 		.elem_size	= sizeof(u8),
1554 		.array_type	= NO_ARRAY,
1555 		.tlv_type	= 0x15,
1556 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1557 					   bdf_type),
1558 	},
1559 
1560 	{
1561 		.data_type	= QMI_EOTI,
1562 		.array_type	= NO_ARRAY,
1563 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1564 	},
1565 };
1566 
1567 static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1568 	{
1569 		.data_type	= QMI_STRUCT,
1570 		.elem_len	= 1,
1571 		.elem_size	= sizeof(struct qmi_response_type_v01),
1572 		.array_type	= NO_ARRAY,
1573 		.tlv_type	= 0x02,
1574 		.offset		= offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1575 					   resp),
1576 		.ei_array	= qmi_response_type_v01_ei,
1577 	},
1578 	{
1579 		.data_type	= QMI_EOTI,
1580 		.array_type	= NO_ARRAY,
1581 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1582 	},
1583 };
1584 
1585 static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1586 	{
1587 		.data_type	= QMI_UNSIGNED_8_BYTE,
1588 		.elem_len	= 1,
1589 		.elem_size	= sizeof(u64),
1590 		.array_type	= NO_ARRAY,
1591 		.tlv_type	= 0x01,
1592 		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1593 	},
1594 	{
1595 		.data_type	= QMI_UNSIGNED_4_BYTE,
1596 		.elem_len	= 1,
1597 		.elem_size	= sizeof(u32),
1598 		.array_type	= NO_ARRAY,
1599 		.tlv_type	= 0x02,
1600 		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1601 	},
1602 	{
1603 		.data_type	= QMI_EOTI,
1604 		.array_type	= NO_ARRAY,
1605 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1606 	},
1607 };
1608 
1609 static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1610 	{
1611 		.data_type	= QMI_STRUCT,
1612 		.elem_len	= 1,
1613 		.elem_size	= sizeof(struct qmi_response_type_v01),
1614 		.array_type	= NO_ARRAY,
1615 		.tlv_type	= 0x02,
1616 		.offset		= offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1617 		.ei_array	= qmi_response_type_v01_ei,
1618 	},
1619 	{
1620 		.data_type	= QMI_EOTI,
1621 		.array_type	= NO_ARRAY,
1622 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1623 	},
1624 };
1625 
1626 static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
1627 	{
1628 		.data_type	= QMI_UNSIGNED_4_BYTE,
1629 		.elem_len	= 1,
1630 		.elem_size	= sizeof(u32),
1631 		.array_type	= NO_ARRAY,
1632 		.tlv_type	= 0,
1633 		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1634 					   pipe_num),
1635 	},
1636 	{
1637 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1638 		.elem_len	= 1,
1639 		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1640 		.array_type	= NO_ARRAY,
1641 		.tlv_type	= 0,
1642 		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1643 					   pipe_dir),
1644 	},
1645 	{
1646 		.data_type	= QMI_UNSIGNED_4_BYTE,
1647 		.elem_len	= 1,
1648 		.elem_size	= sizeof(u32),
1649 		.array_type	= NO_ARRAY,
1650 		.tlv_type	= 0,
1651 		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1652 					   nentries),
1653 	},
1654 	{
1655 		.data_type	= QMI_UNSIGNED_4_BYTE,
1656 		.elem_len	= 1,
1657 		.elem_size	= sizeof(u32),
1658 		.array_type	= NO_ARRAY,
1659 		.tlv_type	= 0,
1660 		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1661 					   nbytes_max),
1662 	},
1663 	{
1664 		.data_type	= QMI_UNSIGNED_4_BYTE,
1665 		.elem_len	= 1,
1666 		.elem_size	= sizeof(u32),
1667 		.array_type	= NO_ARRAY,
1668 		.tlv_type	= 0,
1669 		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1670 					   flags),
1671 	},
1672 	{
1673 		.data_type	= QMI_EOTI,
1674 		.array_type	= NO_ARRAY,
1675 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1676 	},
1677 };
1678 
1679 static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
1680 	{
1681 		.data_type	= QMI_UNSIGNED_4_BYTE,
1682 		.elem_len	= 1,
1683 		.elem_size	= sizeof(u32),
1684 		.array_type	= NO_ARRAY,
1685 		.tlv_type	= 0,
1686 		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1687 					   service_id),
1688 	},
1689 	{
1690 		.data_type	= QMI_SIGNED_4_BYTE_ENUM,
1691 		.elem_len	= 1,
1692 		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1693 		.array_type	= NO_ARRAY,
1694 		.tlv_type	= 0,
1695 		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1696 					   pipe_dir),
1697 	},
1698 	{
1699 		.data_type	= QMI_UNSIGNED_4_BYTE,
1700 		.elem_len	= 1,
1701 		.elem_size	= sizeof(u32),
1702 		.array_type	= NO_ARRAY,
1703 		.tlv_type	= 0,
1704 		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1705 					   pipe_num),
1706 	},
1707 	{
1708 		.data_type	= QMI_EOTI,
1709 		.array_type	= NO_ARRAY,
1710 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1711 	},
1712 };
1713 
1714 static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1715 	{
1716 		.data_type	= QMI_UNSIGNED_2_BYTE,
1717 		.elem_len	= 1,
1718 		.elem_size	= sizeof(u16),
1719 		.array_type	= NO_ARRAY,
1720 		.tlv_type	= 0,
1721 		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1722 	},
1723 	{
1724 		.data_type	= QMI_UNSIGNED_2_BYTE,
1725 		.elem_len	= 1,
1726 		.elem_size	= sizeof(u16),
1727 		.array_type	= NO_ARRAY,
1728 		.tlv_type	= 0,
1729 		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1730 					   offset),
1731 	},
1732 	{
1733 		.data_type	= QMI_EOTI,
1734 		.array_type	= QMI_COMMON_TLV_TYPE,
1735 	},
1736 };
1737 
1738 static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
1739 	{
1740 		.data_type	= QMI_UNSIGNED_4_BYTE,
1741 		.elem_len	= 1,
1742 		.elem_size	= sizeof(u32),
1743 		.array_type	= NO_ARRAY,
1744 		.tlv_type	= 0,
1745 		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01,
1746 					   addr),
1747 	},
1748 	{
1749 		.data_type	= QMI_EOTI,
1750 		.array_type	= NO_ARRAY,
1751 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1752 	},
1753 };
1754 
1755 static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1756 	{
1757 		.data_type	= QMI_UNSIGNED_4_BYTE,
1758 		.elem_len	= 1,
1759 		.elem_size	= sizeof(u32),
1760 		.array_type	= NO_ARRAY,
1761 		.tlv_type	= 0x01,
1762 		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1763 					   mode),
1764 	},
1765 	{
1766 		.data_type	= QMI_OPT_FLAG,
1767 		.elem_len	= 1,
1768 		.elem_size	= sizeof(u8),
1769 		.array_type	= NO_ARRAY,
1770 		.tlv_type	= 0x10,
1771 		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1772 					   hw_debug_valid),
1773 	},
1774 	{
1775 		.data_type	= QMI_UNSIGNED_1_BYTE,
1776 		.elem_len	= 1,
1777 		.elem_size	= sizeof(u8),
1778 		.array_type	= NO_ARRAY,
1779 		.tlv_type	= 0x10,
1780 		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1781 					   hw_debug),
1782 	},
1783 	{
1784 		.data_type	= QMI_EOTI,
1785 		.array_type	= NO_ARRAY,
1786 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1787 	},
1788 };
1789 
1790 static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1791 	{
1792 		.data_type	= QMI_STRUCT,
1793 		.elem_len	= 1,
1794 		.elem_size	= sizeof(struct qmi_response_type_v01),
1795 		.array_type	= NO_ARRAY,
1796 		.tlv_type	= 0x02,
1797 		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1798 					   resp),
1799 		.ei_array	= qmi_response_type_v01_ei,
1800 	},
1801 	{
1802 		.data_type	= QMI_EOTI,
1803 		.array_type	= NO_ARRAY,
1804 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1805 	},
1806 };
1807 
1808 static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1809 	{
1810 		.data_type	= QMI_OPT_FLAG,
1811 		.elem_len	= 1,
1812 		.elem_size	= sizeof(u8),
1813 		.array_type	= NO_ARRAY,
1814 		.tlv_type	= 0x10,
1815 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1816 					   host_version_valid),
1817 	},
1818 	{
1819 		.data_type	= QMI_STRING,
1820 		.elem_len	= QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1821 		.elem_size	= sizeof(char),
1822 		.array_type	= NO_ARRAY,
1823 		.tlv_type	= 0x10,
1824 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1825 					   host_version),
1826 	},
1827 	{
1828 		.data_type	= QMI_OPT_FLAG,
1829 		.elem_len	= 1,
1830 		.elem_size	= sizeof(u8),
1831 		.array_type	= NO_ARRAY,
1832 		.tlv_type	= 0x11,
1833 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1834 					   tgt_cfg_valid),
1835 	},
1836 	{
1837 		.data_type	= QMI_DATA_LEN,
1838 		.elem_len	= 1,
1839 		.elem_size	= sizeof(u8),
1840 		.array_type	= NO_ARRAY,
1841 		.tlv_type	= 0x11,
1842 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1843 					   tgt_cfg_len),
1844 	},
1845 	{
1846 		.data_type	= QMI_STRUCT,
1847 		.elem_len	= QMI_WLANFW_MAX_NUM_CE_V01,
1848 		.elem_size	= sizeof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1849 		.array_type	= VAR_LEN_ARRAY,
1850 		.tlv_type	= 0x11,
1851 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1852 					   tgt_cfg),
1853 		.ei_array	= qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1854 	},
1855 	{
1856 		.data_type	= QMI_OPT_FLAG,
1857 		.elem_len	= 1,
1858 		.elem_size	= sizeof(u8),
1859 		.array_type	= NO_ARRAY,
1860 		.tlv_type	= 0x12,
1861 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1862 					   svc_cfg_valid),
1863 	},
1864 	{
1865 		.data_type	= QMI_DATA_LEN,
1866 		.elem_len	= 1,
1867 		.elem_size	= sizeof(u8),
1868 		.array_type	= NO_ARRAY,
1869 		.tlv_type	= 0x12,
1870 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1871 					   svc_cfg_len),
1872 	},
1873 	{
1874 		.data_type	= QMI_STRUCT,
1875 		.elem_len	= QMI_WLANFW_MAX_NUM_SVC_V01,
1876 		.elem_size	= sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1877 		.array_type	= VAR_LEN_ARRAY,
1878 		.tlv_type	= 0x12,
1879 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1880 					   svc_cfg),
1881 		.ei_array	= qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1882 	},
1883 	{
1884 		.data_type	= QMI_OPT_FLAG,
1885 		.elem_len	= 1,
1886 		.elem_size	= sizeof(u8),
1887 		.array_type = NO_ARRAY,
1888 		.tlv_type	= 0x13,
1889 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1890 					   shadow_reg_valid),
1891 	},
1892 	{
1893 		.data_type	= QMI_DATA_LEN,
1894 		.elem_len	= 1,
1895 		.elem_size	= sizeof(u8),
1896 		.array_type = NO_ARRAY,
1897 		.tlv_type	= 0x13,
1898 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1899 					   shadow_reg_len),
1900 	},
1901 	{
1902 		.data_type	= QMI_STRUCT,
1903 		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1904 		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1905 		.array_type = VAR_LEN_ARRAY,
1906 		.tlv_type	= 0x13,
1907 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1908 					   shadow_reg),
1909 		.ei_array	= qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1910 	},
1911 	{
1912 		.data_type	= QMI_OPT_FLAG,
1913 		.elem_len	= 1,
1914 		.elem_size	= sizeof(u8),
1915 		.array_type	= NO_ARRAY,
1916 		.tlv_type	= 0x17,
1917 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1918 					   shadow_reg_v3_valid),
1919 	},
1920 	{
1921 		.data_type	= QMI_DATA_LEN,
1922 		.elem_len	= 1,
1923 		.elem_size	= sizeof(u8),
1924 		.array_type	= NO_ARRAY,
1925 		.tlv_type	= 0x17,
1926 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1927 					   shadow_reg_v3_len),
1928 	},
1929 	{
1930 		.data_type	= QMI_STRUCT,
1931 		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01,
1932 		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01),
1933 		.array_type	= VAR_LEN_ARRAY,
1934 		.tlv_type	= 0x17,
1935 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1936 					   shadow_reg_v3),
1937 		.ei_array	= qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei,
1938 	},
1939 	{
1940 		.data_type	= QMI_EOTI,
1941 		.array_type	= NO_ARRAY,
1942 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1943 	},
1944 };
1945 
1946 static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1947 	{
1948 		.data_type	= QMI_STRUCT,
1949 		.elem_len	= 1,
1950 		.elem_size	= sizeof(struct qmi_response_type_v01),
1951 		.array_type	= NO_ARRAY,
1952 		.tlv_type	= 0x02,
1953 		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1954 		.ei_array	= qmi_response_type_v01_ei,
1955 	},
1956 	{
1957 		.data_type	= QMI_EOTI,
1958 		.array_type	= NO_ARRAY,
1959 		.tlv_type	= QMI_COMMON_TLV_TYPE,
1960 	},
1961 };
1962 
1963 static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1964 	{
1965 		.data_type = QMI_EOTI,
1966 		.array_type = NO_ARRAY,
1967 	},
1968 };
1969 
1970 static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1971 	{
1972 		.data_type = QMI_EOTI,
1973 		.array_type = NO_ARRAY,
1974 	},
1975 };
1976 
1977 static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
1978 	{
1979 		.data_type	= QMI_OPT_FLAG,
1980 		.elem_len	= 1,
1981 		.elem_size	= sizeof(u8),
1982 		.array_type	= NO_ARRAY,
1983 		.tlv_type	= 0x10,
1984 		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1985 					   enable_fwlog_valid),
1986 	},
1987 	{
1988 		.data_type	= QMI_UNSIGNED_1_BYTE,
1989 		.elem_len	= 1,
1990 		.elem_size	= sizeof(u8),
1991 		.array_type	= NO_ARRAY,
1992 		.tlv_type	= 0x10,
1993 		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1994 					   enable_fwlog),
1995 	},
1996 	{
1997 		.data_type	= QMI_EOTI,
1998 		.array_type	= NO_ARRAY,
1999 		.tlv_type	= QMI_COMMON_TLV_TYPE,
2000 	},
2001 };
2002 
2003 static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
2004 	{
2005 		.data_type	= QMI_STRUCT,
2006 		.elem_len	= 1,
2007 		.elem_size	= sizeof(struct qmi_response_type_v01),
2008 		.array_type	= NO_ARRAY,
2009 		.tlv_type	= 0x02,
2010 		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
2011 					   resp),
2012 		.ei_array	= qmi_response_type_v01_ei,
2013 	},
2014 	{
2015 		.data_type	= QMI_EOTI,
2016 		.array_type	= NO_ARRAY,
2017 		.tlv_type	= QMI_COMMON_TLV_TYPE,
2018 	},
2019 };
2020 
ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group * ag)2021 static void ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group *ag)
2022 {
2023 	struct ath12k_base *ab, *partner_ab;
2024 	int i, j, hw_id_base;
2025 
2026 	for (i = 0; i < ag->num_devices; i++) {
2027 		hw_id_base = 0;
2028 		ab = ag->ab[i];
2029 
2030 		for (j = 0; j < ag->num_devices; j++) {
2031 			partner_ab = ag->ab[j];
2032 
2033 			if (partner_ab->wsi_info.index >= ab->wsi_info.index)
2034 				continue;
2035 
2036 			hw_id_base += partner_ab->qmi.num_radios;
2037 		}
2038 
2039 		ab->wsi_info.hw_link_id_base = hw_id_base;
2040 	}
2041 
2042 	ag->hw_link_id_init_done = true;
2043 }
2044 
ath12k_host_cap_parse_mlo(struct ath12k_base * ab,struct qmi_wlanfw_host_cap_req_msg_v01 * req)2045 static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
2046 				     struct qmi_wlanfw_host_cap_req_msg_v01 *req)
2047 {
2048 	struct wlfw_host_mlo_chip_info_s_v01 *info;
2049 	struct ath12k_hw_group *ag = ab->ag;
2050 	struct ath12k_base *partner_ab;
2051 	u8 hw_link_id = 0;
2052 	int i, j, ret;
2053 
2054 	if (!ag->mlo_capable) {
2055 		ath12k_dbg(ab, ATH12K_DBG_QMI,
2056 			   "MLO is disabled hence skip QMI MLO cap");
2057 		return 0;
2058 	}
2059 
2060 	if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) {
2061 		ag->mlo_capable = false;
2062 		ath12k_dbg(ab, ATH12K_DBG_QMI,
2063 			   "skip QMI MLO cap due to invalid num_radio %d\n",
2064 			   ab->qmi.num_radios);
2065 		return 0;
2066 	}
2067 
2068 	if (ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2069 		ath12k_err(ab, "failed to send MLO cap due to invalid device id\n");
2070 		return -EINVAL;
2071 	}
2072 
2073 	req->mlo_capable_valid = 1;
2074 	req->mlo_capable = 1;
2075 	req->mlo_chip_id_valid = 1;
2076 	req->mlo_chip_id = ab->device_id;
2077 	req->mlo_group_id_valid = 1;
2078 	req->mlo_group_id = ag->id;
2079 	req->max_mlo_peer_valid = 1;
2080 	/* Max peer number generally won't change for the same device
2081 	 * but needs to be synced with host driver.
2082 	 */
2083 	req->max_mlo_peer = ab->hw_params->max_mlo_peer;
2084 	req->mlo_num_chips_valid = 1;
2085 	req->mlo_num_chips = ag->num_devices;
2086 
2087 	ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d",
2088 		   req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips);
2089 
2090 	mutex_lock(&ag->mutex);
2091 
2092 	if (!ag->hw_link_id_init_done)
2093 		ath12k_host_cap_hw_link_id_init(ag);
2094 
2095 	for (i = 0; i < ag->num_devices; i++) {
2096 		info = &req->mlo_chip_info[i];
2097 		partner_ab = ag->ab[i];
2098 
2099 		if (partner_ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2100 			ath12k_err(ab, "failed to send MLO cap due to invalid partner device id\n");
2101 			ret = -EINVAL;
2102 			goto device_cleanup;
2103 		}
2104 
2105 		info->chip_id = partner_ab->device_id;
2106 		info->num_local_links = partner_ab->qmi.num_radios;
2107 
2108 		ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n",
2109 			   info->chip_id, info->num_local_links);
2110 
2111 		for (j = 0; j < info->num_local_links; j++) {
2112 			info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j;
2113 			info->valid_mlo_link_id[j] = 1;
2114 
2115 			ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n",
2116 				   info->hw_link_id[j]);
2117 
2118 			hw_link_id++;
2119 		}
2120 	}
2121 
2122 	if (hw_link_id <= 0)
2123 		ag->mlo_capable = false;
2124 
2125 	req->mlo_chip_info_valid = 1;
2126 
2127 	mutex_unlock(&ag->mutex);
2128 
2129 	return 0;
2130 
2131 device_cleanup:
2132 	for (i = i - 1; i >= 0; i--) {
2133 		info = &req->mlo_chip_info[i];
2134 
2135 		memset(info, 0, sizeof(*info));
2136 	}
2137 
2138 	req->mlo_num_chips = 0;
2139 	req->mlo_num_chips_valid = 0;
2140 
2141 	req->max_mlo_peer = 0;
2142 	req->max_mlo_peer_valid = 0;
2143 	req->mlo_group_id = 0;
2144 	req->mlo_group_id_valid = 0;
2145 	req->mlo_chip_id = 0;
2146 	req->mlo_chip_id_valid = 0;
2147 	req->mlo_capable = 0;
2148 	req->mlo_capable_valid = 0;
2149 
2150 	ag->mlo_capable = false;
2151 
2152 	mutex_unlock(&ag->mutex);
2153 
2154 	return ret;
2155 }
2156 
2157 /* clang stack usage explodes if this is inlined */
2158 static noinline_for_stack
ath12k_qmi_host_cap_send(struct ath12k_base * ab)2159 int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
2160 {
2161 	struct qmi_wlanfw_host_cap_req_msg_v01 req = {};
2162 	struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {};
2163 	struct qmi_txn txn;
2164 	int ret = 0;
2165 
2166 	req.num_clients_valid = 1;
2167 	req.num_clients = 1;
2168 	req.mem_cfg_mode = ab->qmi.target_mem_mode;
2169 	req.mem_cfg_mode_valid = 1;
2170 	req.bdf_support_valid = 1;
2171 	req.bdf_support = 1;
2172 
2173 	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_driver) {
2174 		req.m3_support_valid = 1;
2175 		req.m3_support = 1;
2176 		req.m3_cache_support_valid = 1;
2177 		req.m3_cache_support = 1;
2178 	}
2179 
2180 	req.cal_done_valid = 1;
2181 	req.cal_done = ab->qmi.cal_done;
2182 
2183 	if (ab->hw_params->qmi_cnss_feature_bitmap) {
2184 		req.feature_list_valid = 1;
2185 		req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap;
2186 	}
2187 
2188 	/* BRINGUP: here we are piggybacking a lot of stuff using
2189 	 * internal_sleep_clock, should it be split?
2190 	 */
2191 	if (ab->hw_params->internal_sleep_clock) {
2192 		req.nm_modem_valid = 1;
2193 
2194 		/* Notify firmware that this is non-qualcomm platform. */
2195 		req.nm_modem |= HOST_CSTATE_BIT;
2196 
2197 		/* Notify firmware about the sleep clock selection,
2198 		 * nm_modem_bit[1] is used for this purpose. Host driver on
2199 		 * non-qualcomm platforms should select internal sleep
2200 		 * clock.
2201 		 */
2202 		req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
2203 		req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
2204 	}
2205 
2206 	ret = ath12k_host_cap_parse_mlo(ab, &req);
2207 	if (ret < 0)
2208 		goto out;
2209 
2210 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2211 			   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
2212 	if (ret < 0)
2213 		goto out;
2214 
2215 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2216 			       QMI_WLANFW_HOST_CAP_REQ_V01,
2217 			       QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
2218 			       qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
2219 	if (ret < 0) {
2220 		qmi_txn_cancel(&txn);
2221 		ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
2222 		goto out;
2223 	}
2224 
2225 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2226 	if (ret < 0)
2227 		goto out;
2228 
2229 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2230 		ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
2231 			    resp.resp.result, resp.resp.error);
2232 		ret = -EINVAL;
2233 		goto out;
2234 	}
2235 
2236 out:
2237 	return ret;
2238 }
2239 
ath12k_qmi_phy_cap_send(struct ath12k_base * ab)2240 static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
2241 {
2242 	struct qmi_wlanfw_phy_cap_req_msg_v01 req = {};
2243 	struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {};
2244 	struct qmi_txn txn;
2245 	int ret;
2246 
2247 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2248 			   qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp);
2249 	if (ret < 0)
2250 		goto out;
2251 
2252 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2253 			       QMI_WLANFW_PHY_CAP_REQ_V01,
2254 			       QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN,
2255 			       qmi_wlanfw_phy_cap_req_msg_v01_ei, &req);
2256 	if (ret < 0) {
2257 		qmi_txn_cancel(&txn);
2258 		ath12k_warn(ab, "failed to send phy capability request: %d\n", ret);
2259 		goto out;
2260 	}
2261 
2262 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2263 	if (ret < 0)
2264 		goto out;
2265 
2266 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2267 		ret = -EOPNOTSUPP;
2268 		goto out;
2269 	}
2270 
2271 	if (resp.single_chip_mlo_support_valid && resp.single_chip_mlo_support)
2272 		ab->single_chip_mlo_support = true;
2273 
2274 	if (!resp.num_phy_valid) {
2275 		ret = -ENODATA;
2276 		goto out;
2277 	}
2278 
2279 	ab->qmi.num_radios = resp.num_phy;
2280 
2281 	ath12k_dbg(ab, ATH12K_DBG_QMI,
2282 		   "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
2283 		   resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
2284 		   resp.num_phy_valid, resp.num_phy,
2285 		   resp.board_id_valid, resp.board_id);
2286 
2287 	return;
2288 
2289 out:
2290 	/* If PHY capability not advertised then rely on default num link */
2291 	ab->qmi.num_radios = ab->hw_params->def_num_link;
2292 
2293 	ath12k_dbg(ab, ATH12K_DBG_QMI,
2294 		   "no valid response from PHY capability, choose default num_phy %d\n",
2295 		   ab->qmi.num_radios);
2296 }
2297 
ath12k_qmi_fw_ind_register_send(struct ath12k_base * ab)2298 static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
2299 {
2300 	struct qmi_wlanfw_ind_register_req_msg_v01 *req;
2301 	struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
2302 	struct qmi_handle *handle = &ab->qmi.handle;
2303 	struct qmi_txn txn;
2304 	int ret;
2305 
2306 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2307 	if (!req)
2308 		return -ENOMEM;
2309 
2310 	resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2311 	if (!resp) {
2312 		ret = -ENOMEM;
2313 		goto resp_out;
2314 	}
2315 
2316 	req->client_id_valid = 1;
2317 	req->client_id = QMI_WLANFW_CLIENT_ID;
2318 	req->fw_ready_enable_valid = 1;
2319 	req->fw_ready_enable = 1;
2320 	req->request_mem_enable_valid = 1;
2321 	req->request_mem_enable = 1;
2322 	req->fw_mem_ready_enable_valid = 1;
2323 	req->fw_mem_ready_enable = 1;
2324 	req->cal_done_enable_valid = 1;
2325 	req->cal_done_enable = 1;
2326 	req->fw_init_done_enable_valid = 1;
2327 	req->fw_init_done_enable = 1;
2328 
2329 	req->pin_connect_result_enable_valid = 0;
2330 	req->pin_connect_result_enable = 0;
2331 
2332 	ret = qmi_txn_init(handle, &txn,
2333 			   qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
2334 	if (ret < 0)
2335 		goto out;
2336 
2337 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2338 			       QMI_WLANFW_IND_REGISTER_REQ_V01,
2339 			       QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
2340 			       qmi_wlanfw_ind_register_req_msg_v01_ei, req);
2341 	if (ret < 0) {
2342 		qmi_txn_cancel(&txn);
2343 		ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
2344 			    ret);
2345 		goto out;
2346 	}
2347 
2348 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2349 	if (ret < 0) {
2350 		ath12k_warn(ab, "failed to register fw indication %d\n", ret);
2351 		goto out;
2352 	}
2353 
2354 	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2355 		ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
2356 			    resp->resp.result, resp->resp.error);
2357 		ret = -EINVAL;
2358 		goto out;
2359 	}
2360 
2361 out:
2362 	kfree(resp);
2363 resp_out:
2364 	kfree(req);
2365 	return ret;
2366 }
2367 
2368 /* clang stack usage explodes if this is inlined */
2369 static noinline_for_stack
ath12k_qmi_respond_fw_mem_request(struct ath12k_base * ab)2370 int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
2371 {
2372 	struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
2373 	struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {};
2374 	struct qmi_txn txn;
2375 	int ret = 0, i;
2376 	bool delayed;
2377 
2378 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2379 	if (!req)
2380 		return -ENOMEM;
2381 
2382 	/* Some targets by default request a block of big contiguous
2383 	 * DMA memory, it's hard to allocate from kernel. So host returns
2384 	 * failure to firmware and firmware then request multiple blocks of
2385 	 * small chunk size memory.
2386 	 */
2387 	if (!test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags) &&
2388 	    ab->qmi.target_mem_delayed) {
2389 		delayed = true;
2390 		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
2391 			   ab->qmi.mem_seg_count);
2392 	} else {
2393 		delayed = false;
2394 		req->mem_seg_len = ab->qmi.mem_seg_count;
2395 		for (i = 0; i < req->mem_seg_len ; i++) {
2396 			req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
2397 			req->mem_seg[i].size = ab->qmi.target_mem[i].size;
2398 			req->mem_seg[i].type = ab->qmi.target_mem[i].type;
2399 			ath12k_dbg(ab, ATH12K_DBG_QMI,
2400 				   "qmi req mem_seg[%d] %pad %u %u\n", i,
2401 				   &ab->qmi.target_mem[i].paddr,
2402 				   ab->qmi.target_mem[i].size,
2403 				   ab->qmi.target_mem[i].type);
2404 		}
2405 	}
2406 
2407 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2408 			   qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
2409 	if (ret < 0)
2410 		goto out;
2411 
2412 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2413 			       QMI_WLANFW_RESPOND_MEM_REQ_V01,
2414 			       QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
2415 			       qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
2416 	if (ret < 0) {
2417 		qmi_txn_cancel(&txn);
2418 		ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
2419 			    ret);
2420 		goto out;
2421 	}
2422 
2423 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2424 	if (ret < 0) {
2425 		ath12k_warn(ab, "qmi failed memory request, err = %d\n", ret);
2426 		goto out;
2427 	}
2428 
2429 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2430 		/* the error response is expected when
2431 		 * target_mem_delayed is true.
2432 		 */
2433 		if (delayed && resp.resp.error == 0)
2434 			goto out;
2435 
2436 		ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
2437 			    resp.resp.result, resp.resp.error);
2438 		ret = -EINVAL;
2439 		goto out;
2440 	}
2441 out:
2442 	kfree(req);
2443 	return ret;
2444 }
2445 
ath12k_qmi_reset_mlo_mem(struct ath12k_hw_group * ag)2446 void ath12k_qmi_reset_mlo_mem(struct ath12k_hw_group *ag)
2447 {
2448 	struct target_mem_chunk *mlo_chunk;
2449 	int i;
2450 
2451 	lockdep_assert_held(&ag->mutex);
2452 
2453 	if (!ag->mlo_mem.init_done || ag->num_started)
2454 		return;
2455 
2456 	for (i = 0; i < ARRAY_SIZE(ag->mlo_mem.chunk); i++) {
2457 		mlo_chunk = &ag->mlo_mem.chunk[i];
2458 
2459 		if (mlo_chunk->v.addr)
2460 			/* TODO: Mode 0 recovery is the default mode hence resetting the
2461 			 * whole memory region for now. Once Mode 1 support is added, this
2462 			 * needs to be handled properly
2463 			 */
2464 			memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2465 	}
2466 }
2467 
ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk,int idx)2468 static void ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base *ab,
2469 					  struct target_mem_chunk *chunk,
2470 					  int idx)
2471 {
2472 	struct ath12k_hw_group *ag = ab->ag;
2473 	struct target_mem_chunk *mlo_chunk;
2474 	bool fixed_mem;
2475 
2476 	lockdep_assert_held(&ag->mutex);
2477 
2478 	if (!ag->mlo_mem.init_done || ag->num_started)
2479 		return;
2480 
2481 	if (idx >= ARRAY_SIZE(ag->mlo_mem.chunk)) {
2482 		ath12k_warn(ab, "invalid index for MLO memory chunk free: %d\n", idx);
2483 		return;
2484 	}
2485 
2486 	fixed_mem = test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags);
2487 	mlo_chunk = &ag->mlo_mem.chunk[idx];
2488 
2489 	if (fixed_mem && mlo_chunk->v.ioaddr) {
2490 		iounmap(mlo_chunk->v.ioaddr);
2491 		mlo_chunk->v.ioaddr = NULL;
2492 	} else if (mlo_chunk->v.addr) {
2493 		dma_free_coherent(ab->dev,
2494 				  mlo_chunk->size,
2495 				  mlo_chunk->v.addr,
2496 				  mlo_chunk->paddr);
2497 		mlo_chunk->v.addr = NULL;
2498 	}
2499 
2500 	mlo_chunk->paddr = 0;
2501 	mlo_chunk->size = 0;
2502 	if (fixed_mem)
2503 		chunk->v.ioaddr = NULL;
2504 	else
2505 		chunk->v.addr = NULL;
2506 	chunk->paddr = 0;
2507 	chunk->size = 0;
2508 }
2509 
ath12k_qmi_free_target_mem_chunk(struct ath12k_base * ab)2510 static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
2511 {
2512 	struct ath12k_hw_group *ag = ab->ag;
2513 	int i, mlo_idx;
2514 
2515 	for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2516 		if (ab->qmi.target_mem[i].type == MLO_GLOBAL_MEM_REGION_TYPE) {
2517 			ath12k_qmi_free_mlo_mem_chunk(ab,
2518 						      &ab->qmi.target_mem[i],
2519 						      mlo_idx++);
2520 		} else {
2521 			if (test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags) &&
2522 			    ab->qmi.target_mem[i].v.ioaddr) {
2523 				iounmap(ab->qmi.target_mem[i].v.ioaddr);
2524 				ab->qmi.target_mem[i].v.ioaddr = NULL;
2525 			} else {
2526 				if (!ab->qmi.target_mem[i].v.addr)
2527 					continue;
2528 				dma_free_coherent(ab->dev,
2529 						  ab->qmi.target_mem[i].prev_size,
2530 						  ab->qmi.target_mem[i].v.addr,
2531 						  ab->qmi.target_mem[i].paddr);
2532 				ab->qmi.target_mem[i].v.addr = NULL;
2533 			}
2534 		}
2535 	}
2536 
2537 	if (!ag->num_started && ag->mlo_mem.init_done) {
2538 		ag->mlo_mem.init_done = false;
2539 		ag->mlo_mem.mlo_mem_size = 0;
2540 	}
2541 }
2542 
ath12k_qmi_alloc_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk)2543 static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
2544 				  struct target_mem_chunk *chunk)
2545 {
2546 	/* Firmware reloads in recovery/resume.
2547 	 * In such cases, no need to allocate memory for FW again.
2548 	 */
2549 	if (chunk->v.addr) {
2550 		if (chunk->prev_type == chunk->type &&
2551 		    chunk->prev_size == chunk->size)
2552 			goto this_chunk_done;
2553 
2554 		/* cannot reuse the existing chunk */
2555 		dma_free_coherent(ab->dev, chunk->prev_size,
2556 				  chunk->v.addr, chunk->paddr);
2557 		chunk->v.addr = NULL;
2558 	}
2559 
2560 	chunk->v.addr = dma_alloc_coherent(ab->dev,
2561 					   chunk->size,
2562 					   &chunk->paddr,
2563 					   GFP_KERNEL | __GFP_NOWARN);
2564 	if (!chunk->v.addr) {
2565 		if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
2566 			ab->qmi.target_mem_delayed = true;
2567 			ath12k_warn(ab,
2568 				    "qmi dma allocation failed (%d B type %u), will try later with small size\n",
2569 				    chunk->size,
2570 				    chunk->type);
2571 			ath12k_qmi_free_target_mem_chunk(ab);
2572 			return -EAGAIN;
2573 		}
2574 		ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
2575 			    chunk->type, chunk->size);
2576 		return -ENOMEM;
2577 	}
2578 	chunk->prev_type = chunk->type;
2579 	chunk->prev_size = chunk->size;
2580 this_chunk_done:
2581 	return 0;
2582 }
2583 
ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base * ab)2584 static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
2585 {
2586 	struct target_mem_chunk *chunk, *mlo_chunk;
2587 	struct ath12k_hw_group *ag = ab->ag;
2588 	int i, mlo_idx, ret;
2589 	int mlo_size = 0;
2590 
2591 	mutex_lock(&ag->mutex);
2592 
2593 	if (!ag->mlo_mem.init_done) {
2594 		memset(ag->mlo_mem.chunk, 0, sizeof(ag->mlo_mem.chunk));
2595 		ag->mlo_mem.init_done = true;
2596 	}
2597 
2598 	ab->qmi.target_mem_delayed = false;
2599 
2600 	for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2601 		chunk = &ab->qmi.target_mem[i];
2602 
2603 		/* Allocate memory for the region and the functionality supported
2604 		 * on the host. For the non-supported memory region, host does not
2605 		 * allocate memory, assigns NULL and FW will handle this without crashing.
2606 		 */
2607 		switch (chunk->type) {
2608 		case HOST_DDR_REGION_TYPE:
2609 		case M3_DUMP_REGION_TYPE:
2610 		case PAGEABLE_MEM_REGION_TYPE:
2611 		case CALDB_MEM_REGION_TYPE:
2612 			ret = ath12k_qmi_alloc_chunk(ab, chunk);
2613 			if (ret)
2614 				goto err;
2615 			break;
2616 		case MLO_GLOBAL_MEM_REGION_TYPE:
2617 			mlo_size += chunk->size;
2618 			if (ag->mlo_mem.mlo_mem_size &&
2619 			    mlo_size > ag->mlo_mem.mlo_mem_size) {
2620 				ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d",
2621 					   mlo_size, ag->mlo_mem.mlo_mem_size);
2622 				ret = -EINVAL;
2623 				goto err;
2624 			}
2625 
2626 			mlo_chunk = &ag->mlo_mem.chunk[mlo_idx];
2627 			if (mlo_chunk->paddr) {
2628 				if (chunk->size != mlo_chunk->size) {
2629 					ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d",
2630 						   mlo_idx, chunk->size, mlo_chunk->size);
2631 					ret = -EINVAL;
2632 					goto err;
2633 				}
2634 			} else {
2635 				mlo_chunk->size = chunk->size;
2636 				mlo_chunk->type = chunk->type;
2637 				ret = ath12k_qmi_alloc_chunk(ab, mlo_chunk);
2638 				if (ret)
2639 					goto err;
2640 				memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2641 			}
2642 
2643 			chunk->paddr = mlo_chunk->paddr;
2644 			chunk->v.addr = mlo_chunk->v.addr;
2645 			mlo_idx++;
2646 
2647 			break;
2648 		default:
2649 			ath12k_warn(ab, "memory type %u not supported\n",
2650 				    chunk->type);
2651 			chunk->paddr = 0;
2652 			chunk->v.addr = NULL;
2653 			break;
2654 		}
2655 	}
2656 
2657 	if (!ag->mlo_mem.mlo_mem_size) {
2658 		ag->mlo_mem.mlo_mem_size = mlo_size;
2659 	} else if (ag->mlo_mem.mlo_mem_size != mlo_size) {
2660 		ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d",
2661 			   ag->mlo_mem.mlo_mem_size, mlo_size);
2662 		ret = -EINVAL;
2663 		goto err;
2664 	}
2665 
2666 	mutex_unlock(&ag->mutex);
2667 
2668 	return 0;
2669 
2670 err:
2671 	ath12k_qmi_free_target_mem_chunk(ab);
2672 
2673 	mutex_unlock(&ag->mutex);
2674 
2675 	/* The firmware will attempt to request memory in smaller chunks
2676 	 * on the next try. However, the current caller should be notified
2677 	 * that this instance of request parsing was successful.
2678 	 * Therefore, return 0 only.
2679 	 */
2680 	if (ret == -EAGAIN)
2681 		ret = 0;
2682 
2683 	return ret;
2684 }
2685 
ath12k_qmi_assign_target_mem_chunk(struct ath12k_base * ab)2686 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
2687 {
2688 	struct reserved_mem *rmem;
2689 	size_t avail_rmem_size;
2690 	int i, idx, ret;
2691 
2692 	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
2693 		switch (ab->qmi.target_mem[i].type) {
2694 		case HOST_DDR_REGION_TYPE:
2695 			rmem = ath12k_core_get_reserved_mem(ab, 0);
2696 			if (!rmem) {
2697 				ret = -ENODEV;
2698 				goto out;
2699 			}
2700 
2701 			avail_rmem_size = rmem->size;
2702 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2703 				ath12k_dbg(ab, ATH12K_DBG_QMI,
2704 					   "failed to assign mem type %u req size %u avail size %zu\n",
2705 					   ab->qmi.target_mem[i].type,
2706 					   ab->qmi.target_mem[i].size,
2707 					   avail_rmem_size);
2708 				ret = -EINVAL;
2709 				goto out;
2710 			}
2711 
2712 			ab->qmi.target_mem[idx].paddr = rmem->base;
2713 			ab->qmi.target_mem[idx].v.ioaddr =
2714 				ioremap(ab->qmi.target_mem[idx].paddr,
2715 					ab->qmi.target_mem[i].size);
2716 			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2717 				ret = -EIO;
2718 				goto out;
2719 			}
2720 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2721 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2722 			idx++;
2723 			break;
2724 		case BDF_MEM_REGION_TYPE:
2725 			rmem = ath12k_core_get_reserved_mem(ab, 0);
2726 			if (!rmem) {
2727 				ret = -ENODEV;
2728 				goto out;
2729 			}
2730 
2731 			avail_rmem_size = rmem->size - ab->hw_params->bdf_addr_offset;
2732 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2733 				ath12k_dbg(ab, ATH12K_DBG_QMI,
2734 					   "failed to assign mem type %u req size %u avail size %zu\n",
2735 					   ab->qmi.target_mem[i].type,
2736 					   ab->qmi.target_mem[i].size,
2737 					   avail_rmem_size);
2738 				ret = -EINVAL;
2739 				goto out;
2740 			}
2741 			ab->qmi.target_mem[idx].paddr =
2742 				rmem->base + ab->hw_params->bdf_addr_offset;
2743 			ab->qmi.target_mem[idx].v.ioaddr =
2744 				ioremap(ab->qmi.target_mem[idx].paddr,
2745 					ab->qmi.target_mem[i].size);
2746 			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2747 				ret = -EIO;
2748 				goto out;
2749 			}
2750 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2751 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2752 			idx++;
2753 			break;
2754 		case CALDB_MEM_REGION_TYPE:
2755 			/* Cold boot calibration is not enabled in Ath12k. Hence,
2756 			 * assign paddr = 0.
2757 			 * Once cold boot calibration is enabled add support to
2758 			 * assign reserved memory from DT.
2759 			 */
2760 			ab->qmi.target_mem[idx].paddr = 0;
2761 			ab->qmi.target_mem[idx].v.ioaddr = NULL;
2762 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2763 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2764 			idx++;
2765 			break;
2766 		case M3_DUMP_REGION_TYPE:
2767 			rmem = ath12k_core_get_reserved_mem(ab, 1);
2768 			if (!rmem) {
2769 				ret = -EINVAL;
2770 				goto out;
2771 			}
2772 
2773 			avail_rmem_size = rmem->size;
2774 			if (avail_rmem_size < ab->qmi.target_mem[i].size) {
2775 				ath12k_dbg(ab, ATH12K_DBG_QMI,
2776 					   "failed to assign mem type %u req size %u avail size %zu\n",
2777 					   ab->qmi.target_mem[i].type,
2778 					   ab->qmi.target_mem[i].size,
2779 					   avail_rmem_size);
2780 				ret = -EINVAL;
2781 				goto out;
2782 			}
2783 
2784 			ab->qmi.target_mem[idx].paddr = rmem->base;
2785 			ab->qmi.target_mem[idx].v.ioaddr =
2786 				ioremap(ab->qmi.target_mem[idx].paddr,
2787 					ab->qmi.target_mem[i].size);
2788 			if (!ab->qmi.target_mem[idx].v.ioaddr) {
2789 				ret = -EIO;
2790 				goto out;
2791 			}
2792 			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
2793 			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
2794 			idx++;
2795 			break;
2796 		default:
2797 			ath12k_warn(ab, "qmi ignore invalid mem req type %u\n",
2798 				    ab->qmi.target_mem[i].type);
2799 			break;
2800 		}
2801 	}
2802 	ab->qmi.mem_seg_count = idx;
2803 
2804 	return 0;
2805 out:
2806 	ath12k_qmi_free_target_mem_chunk(ab);
2807 	return ret;
2808 }
2809 
2810 /* clang stack usage explodes if this is inlined */
2811 static noinline_for_stack
ath12k_qmi_request_target_cap(struct ath12k_base * ab)2812 int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
2813 {
2814 	struct qmi_wlanfw_cap_req_msg_v01 req = {};
2815 	struct qmi_wlanfw_cap_resp_msg_v01 resp = {};
2816 	struct qmi_txn txn;
2817 	unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
2818 	int ret = 0;
2819 	int r;
2820 	int i;
2821 
2822 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
2823 			   qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
2824 	if (ret < 0)
2825 		goto out;
2826 
2827 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2828 			       QMI_WLANFW_CAP_REQ_V01,
2829 			       QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
2830 			       qmi_wlanfw_cap_req_msg_v01_ei, &req);
2831 	if (ret < 0) {
2832 		qmi_txn_cancel(&txn);
2833 		ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
2834 			    ret);
2835 		goto out;
2836 	}
2837 
2838 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2839 	if (ret < 0) {
2840 		ath12k_warn(ab, "qmi failed target cap request %d\n", ret);
2841 		goto out;
2842 	}
2843 
2844 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2845 		ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
2846 			    resp.resp.result, resp.resp.error);
2847 		ret = -EINVAL;
2848 		goto out;
2849 	}
2850 
2851 	if (resp.chip_info_valid) {
2852 		ab->qmi.target.chip_id = resp.chip_info.chip_id;
2853 		ab->qmi.target.chip_family = resp.chip_info.chip_family;
2854 	}
2855 
2856 	if (resp.board_info_valid)
2857 		ab->qmi.target.board_id = resp.board_info.board_id;
2858 	else
2859 		ab->qmi.target.board_id = board_id;
2860 
2861 	if (resp.soc_info_valid)
2862 		ab->qmi.target.soc_id = resp.soc_info.soc_id;
2863 
2864 	if (resp.fw_version_info_valid) {
2865 		ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
2866 		strscpy(ab->qmi.target.fw_build_timestamp,
2867 			resp.fw_version_info.fw_build_timestamp,
2868 			sizeof(ab->qmi.target.fw_build_timestamp));
2869 	}
2870 
2871 	if (resp.fw_build_id_valid)
2872 		strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
2873 			sizeof(ab->qmi.target.fw_build_id));
2874 
2875 	if (resp.dev_mem_info_valid) {
2876 		for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) {
2877 			ab->qmi.dev_mem[i].start =
2878 				resp.dev_mem[i].start;
2879 			ab->qmi.dev_mem[i].size =
2880 				resp.dev_mem[i].size;
2881 			ath12k_dbg(ab, ATH12K_DBG_QMI,
2882 				   "devmem [%d] start 0x%llx size %llu\n", i,
2883 				   ab->qmi.dev_mem[i].start,
2884 				   ab->qmi.dev_mem[i].size);
2885 		}
2886 	}
2887 
2888 	if (resp.eeprom_caldata_read_timeout_valid) {
2889 		ab->qmi.target.eeprom_caldata = resp.eeprom_caldata_read_timeout;
2890 		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi cal data supported from eeprom\n");
2891 	}
2892 
2893 	ath12k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
2894 		    ab->qmi.target.chip_id, ab->qmi.target.chip_family,
2895 		    ab->qmi.target.board_id, ab->qmi.target.soc_id);
2896 
2897 	ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
2898 		    ab->qmi.target.fw_version,
2899 		    ab->qmi.target.fw_build_timestamp,
2900 		    ab->qmi.target.fw_build_id);
2901 
2902 	r = ath12k_core_check_smbios(ab);
2903 	if (r)
2904 		ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
2905 
2906 	r = ath12k_acpi_start(ab);
2907 	if (r)
2908 		/* ACPI is optional so continue in case of an error */
2909 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", r);
2910 
2911 	r = ath12k_acpi_check_bdf_variant_name(ab);
2912 	if (r)
2913 		ath12k_dbg(ab, ATH12K_DBG_BOOT, "ACPI bdf variant name not set.\n");
2914 
2915 out:
2916 	return ret;
2917 }
2918 
ath12k_qmi_load_file_target_mem(struct ath12k_base * ab,const u8 * data,u32 len,u8 type)2919 static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
2920 					   const u8 *data, u32 len, u8 type)
2921 {
2922 	struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2923 	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
2924 	struct qmi_txn txn;
2925 	const u8 *temp = data;
2926 	int ret = 0;
2927 	u32 remaining = len;
2928 
2929 	req = kzalloc(sizeof(*req), GFP_KERNEL);
2930 	if (!req)
2931 		return -ENOMEM;
2932 
2933 	while (remaining) {
2934 		req->valid = 1;
2935 		req->file_id_valid = 1;
2936 		req->file_id = ab->qmi.target.board_id;
2937 		req->total_size_valid = 1;
2938 		req->total_size = remaining;
2939 		req->seg_id_valid = 1;
2940 		req->data_valid = 1;
2941 		req->bdf_type = type;
2942 		req->bdf_type_valid = 1;
2943 		req->end_valid = 1;
2944 		req->end = 0;
2945 
2946 		if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2947 			req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2948 		} else {
2949 			req->data_len = remaining;
2950 			req->end = 1;
2951 		}
2952 
2953 		if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2954 			req->data_valid = 0;
2955 			req->end = 1;
2956 			req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2957 		} else {
2958 			memcpy(req->data, temp, req->data_len);
2959 		}
2960 
2961 		ret = qmi_txn_init(&ab->qmi.handle, &txn,
2962 				   qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2963 				   &resp);
2964 		if (ret < 0)
2965 			goto out;
2966 
2967 		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
2968 			   type);
2969 
2970 		ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2971 				       QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2972 				       QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2973 				       qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2974 		if (ret < 0) {
2975 			qmi_txn_cancel(&txn);
2976 			goto out;
2977 		}
2978 
2979 		ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2980 		if (ret < 0)
2981 			goto out;
2982 
2983 		if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2984 			ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2985 				    resp.resp.result, resp.resp.error);
2986 			ret = -EINVAL;
2987 			goto out;
2988 		}
2989 
2990 		if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2991 			remaining = 0;
2992 		} else {
2993 			remaining -= req->data_len;
2994 			temp += req->data_len;
2995 			req->seg_id++;
2996 			ath12k_dbg(ab, ATH12K_DBG_QMI,
2997 				   "qmi bdf download request remaining %i\n",
2998 				   remaining);
2999 		}
3000 	}
3001 
3002 out:
3003 	kfree(req);
3004 	return ret;
3005 }
3006 
3007 /* clang stack usage explodes if this is inlined */
3008 static noinline_for_stack
ath12k_qmi_load_bdf_qmi(struct ath12k_base * ab,enum ath12k_qmi_bdf_type type)3009 int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab,
3010 			    enum ath12k_qmi_bdf_type type)
3011 {
3012 	struct device *dev = ab->dev;
3013 	char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE];
3014 	const struct firmware *fw_entry;
3015 	struct ath12k_board_data bd;
3016 	u32 fw_size, file_type;
3017 	int ret = 0;
3018 	const u8 *tmp;
3019 
3020 	memset(&bd, 0, sizeof(bd));
3021 
3022 	switch (type) {
3023 	case ATH12K_QMI_BDF_TYPE_ELF:
3024 		ret = ath12k_core_fetch_bdf(ab, &bd);
3025 		if (ret) {
3026 			ath12k_warn(ab, "qmi failed to load bdf:\n");
3027 			goto out;
3028 		}
3029 
3030 		if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
3031 			type = ATH12K_QMI_BDF_TYPE_ELF;
3032 		else
3033 			type = ATH12K_QMI_BDF_TYPE_BIN;
3034 
3035 		break;
3036 	case ATH12K_QMI_BDF_TYPE_REGDB:
3037 		ret = ath12k_core_fetch_regdb(ab, &bd);
3038 		if (ret) {
3039 			ath12k_warn(ab, "qmi failed to load regdb bin:\n");
3040 			goto out;
3041 		}
3042 		break;
3043 	case ATH12K_QMI_BDF_TYPE_CALIBRATION:
3044 
3045 		if (ab->qmi.target.eeprom_caldata) {
3046 			file_type = ATH12K_QMI_FILE_TYPE_EEPROM;
3047 			tmp = filename;
3048 			fw_size = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
3049 		} else {
3050 			file_type = ATH12K_QMI_FILE_TYPE_CALDATA;
3051 
3052 			/* cal-<bus>-<id>.bin */
3053 			snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
3054 				 ath12k_bus_str(ab->hif.bus), dev_name(dev));
3055 			fw_entry = ath12k_core_firmware_request(ab, filename);
3056 			if (!IS_ERR(fw_entry))
3057 				goto success;
3058 
3059 			fw_entry = ath12k_core_firmware_request(ab,
3060 								ATH12K_DEFAULT_CAL_FILE);
3061 			if (IS_ERR(fw_entry)) {
3062 				ret = PTR_ERR(fw_entry);
3063 				ath12k_warn(ab,
3064 					    "qmi failed to load CAL data file:%s\n",
3065 					    filename);
3066 				goto out;
3067 			}
3068 
3069 success:
3070 			fw_size = min_t(u32, ab->hw_params->fw.board_size,
3071 					fw_entry->size);
3072 			tmp = fw_entry->data;
3073 		}
3074 		ret = ath12k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
3075 		if (ret < 0) {
3076 			ath12k_warn(ab, "qmi failed to load caldata\n");
3077 			goto out_qmi_cal;
3078 		}
3079 
3080 		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
3081 			   file_type);
3082 
3083 out_qmi_cal:
3084 		if (!ab->qmi.target.eeprom_caldata)
3085 			release_firmware(fw_entry);
3086 		return ret;
3087 	default:
3088 		ath12k_warn(ab, "unknown file type for load %d", type);
3089 		goto out;
3090 	}
3091 
3092 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf_type %d\n", type);
3093 
3094 	fw_size = min_t(u32, ab->hw_params->fw.board_size, bd.len);
3095 
3096 	ret = ath12k_qmi_load_file_target_mem(ab, bd.data, fw_size, type);
3097 	if (ret < 0)
3098 		ath12k_warn(ab, "qmi failed to load bdf file\n");
3099 
3100 out:
3101 	ath12k_core_free_bdf(ab, &bd);
3102 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi BDF download sequence completed\n");
3103 
3104 	return ret;
3105 }
3106 
ath12k_qmi_m3_free(struct ath12k_base * ab)3107 static void ath12k_qmi_m3_free(struct ath12k_base *ab)
3108 {
3109 	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3110 
3111 	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_remoteproc)
3112 		return;
3113 
3114 	if (!m3_mem->vaddr)
3115 		return;
3116 
3117 	dma_free_coherent(ab->dev, m3_mem->size,
3118 			  m3_mem->vaddr, m3_mem->paddr);
3119 	m3_mem->vaddr = NULL;
3120 	m3_mem->size = 0;
3121 }
3122 
ath12k_qmi_m3_load(struct ath12k_base * ab)3123 static int ath12k_qmi_m3_load(struct ath12k_base *ab)
3124 {
3125 	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3126 	const struct firmware *fw = NULL;
3127 	const void *m3_data;
3128 	char path[100];
3129 	size_t m3_len;
3130 	int ret;
3131 
3132 	if (ab->fw.m3_data && ab->fw.m3_len > 0) {
3133 		/* firmware-N.bin had a m3 firmware file so use that */
3134 		m3_data = ab->fw.m3_data;
3135 		m3_len = ab->fw.m3_len;
3136 	} else {
3137 		/* No m3 file in firmware-N.bin so try to request old
3138 		 * separate m3.bin.
3139 		 */
3140 		fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
3141 		if (IS_ERR(fw)) {
3142 			ret = PTR_ERR(fw);
3143 			ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
3144 							 path, sizeof(path));
3145 			ath12k_err(ab, "failed to load %s: %d\n", path, ret);
3146 			return ret;
3147 		}
3148 
3149 		m3_data = fw->data;
3150 		m3_len = fw->size;
3151 	}
3152 
3153 	/* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
3154 	if (m3_mem->vaddr) {
3155 		if (m3_mem->size >= m3_len)
3156 			goto skip_m3_alloc;
3157 
3158 		/* Old buffer is too small, free and reallocate */
3159 		ath12k_qmi_m3_free(ab);
3160 	}
3161 
3162 	m3_mem->vaddr = dma_alloc_coherent(ab->dev,
3163 					   m3_len, &m3_mem->paddr,
3164 					   GFP_KERNEL);
3165 	if (!m3_mem->vaddr) {
3166 		ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
3167 			   fw->size);
3168 		ret = -ENOMEM;
3169 		goto out;
3170 	}
3171 
3172 skip_m3_alloc:
3173 	memcpy(m3_mem->vaddr, m3_data, m3_len);
3174 	m3_mem->size = m3_len;
3175 
3176 	ret = 0;
3177 
3178 out:
3179 	release_firmware(fw);
3180 
3181 	return ret;
3182 }
3183 
3184 /* clang stack usage explodes if this is inlined */
3185 static noinline_for_stack
ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base * ab)3186 int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
3187 {
3188 	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3189 	struct qmi_wlanfw_m3_info_req_msg_v01 req = {};
3190 	struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {};
3191 	struct qmi_txn txn;
3192 	int ret = 0;
3193 
3194 	if (ab->hw_params->fw.m3_loader == ath12k_m3_fw_loader_driver) {
3195 		ret = ath12k_qmi_m3_load(ab);
3196 		if (ret) {
3197 			ath12k_err(ab, "failed to load m3 firmware: %d", ret);
3198 			return ret;
3199 		}
3200 		req.addr = m3_mem->paddr;
3201 		req.size = m3_mem->size;
3202 	}
3203 
3204 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3205 			   qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
3206 	if (ret < 0)
3207 		goto out;
3208 
3209 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3210 			       QMI_WLANFW_M3_INFO_REQ_V01,
3211 			       QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
3212 			       qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
3213 	if (ret < 0) {
3214 		qmi_txn_cancel(&txn);
3215 		ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
3216 			    ret);
3217 		goto out;
3218 	}
3219 
3220 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3221 	if (ret < 0) {
3222 		ath12k_warn(ab, "qmi failed M3 information request %d\n", ret);
3223 		goto out;
3224 	}
3225 
3226 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3227 		ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
3228 			    resp.resp.result, resp.resp.error);
3229 		ret = -EINVAL;
3230 		goto out;
3231 	}
3232 out:
3233 	return ret;
3234 }
3235 
ath12k_qmi_wlanfw_mode_send(struct ath12k_base * ab,u32 mode)3236 static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
3237 				       u32 mode)
3238 {
3239 	struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {};
3240 	struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {};
3241 	struct qmi_txn txn;
3242 	int ret = 0;
3243 
3244 	req.mode = mode;
3245 	req.hw_debug_valid = 1;
3246 	req.hw_debug = 0;
3247 
3248 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3249 			   qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
3250 	if (ret < 0)
3251 		goto out;
3252 
3253 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3254 			       QMI_WLANFW_WLAN_MODE_REQ_V01,
3255 			       QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
3256 			       qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
3257 	if (ret < 0) {
3258 		qmi_txn_cancel(&txn);
3259 		ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
3260 			    mode, ret);
3261 		goto out;
3262 	}
3263 
3264 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3265 	if (ret < 0) {
3266 		if (mode == ATH12K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
3267 			ath12k_warn(ab, "WLFW service is dis-connected\n");
3268 			return 0;
3269 		}
3270 		ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
3271 			    mode, ret);
3272 		goto out;
3273 	}
3274 
3275 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3276 		ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
3277 			    mode, resp.resp.result, resp.resp.error);
3278 		ret = -EINVAL;
3279 		goto out;
3280 	}
3281 
3282 out:
3283 	return ret;
3284 }
3285 
ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base * ab)3286 static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
3287 {
3288 	struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
3289 	struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {};
3290 	struct ce_pipe_config *ce_cfg;
3291 	struct service_to_pipe *svc_cfg;
3292 	struct qmi_txn txn;
3293 	int ret = 0, pipe_num;
3294 
3295 	ce_cfg	= (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
3296 	svc_cfg	= (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
3297 
3298 	req = kzalloc(sizeof(*req), GFP_KERNEL);
3299 	if (!req)
3300 		return -ENOMEM;
3301 
3302 	req->host_version_valid = 1;
3303 	strscpy(req->host_version, ATH12K_HOST_VERSION_STRING,
3304 		sizeof(req->host_version));
3305 
3306 	req->tgt_cfg_valid = 1;
3307 	/* This is number of CE configs */
3308 	req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
3309 	for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
3310 		req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
3311 		req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
3312 		req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
3313 		req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
3314 		req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
3315 	}
3316 
3317 	req->svc_cfg_valid = 1;
3318 	/* This is number of Service/CE configs */
3319 	req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
3320 	for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
3321 		req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
3322 		req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
3323 		req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
3324 	}
3325 
3326 	/* set shadow v3 configuration */
3327 	if (ab->hw_params->supports_shadow_regs) {
3328 		req->shadow_reg_v3_valid = 1;
3329 		req->shadow_reg_v3_len = min_t(u32,
3330 					       ab->qmi.ce_cfg.shadow_reg_v3_len,
3331 					       QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01);
3332 		memcpy(&req->shadow_reg_v3, ab->qmi.ce_cfg.shadow_reg_v3,
3333 		       sizeof(u32) * req->shadow_reg_v3_len);
3334 	} else {
3335 		req->shadow_reg_v3_valid = 0;
3336 	}
3337 
3338 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3339 			   qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
3340 	if (ret < 0)
3341 		goto out;
3342 
3343 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3344 			       QMI_WLANFW_WLAN_CFG_REQ_V01,
3345 			       QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
3346 			       qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
3347 	if (ret < 0) {
3348 		qmi_txn_cancel(&txn);
3349 		ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
3350 			    ret);
3351 		goto out;
3352 	}
3353 
3354 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3355 	if (ret < 0) {
3356 		ath12k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
3357 		goto out;
3358 	}
3359 
3360 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3361 		ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
3362 			    resp.resp.result, resp.resp.error);
3363 		ret = -EINVAL;
3364 		goto out;
3365 	}
3366 
3367 out:
3368 	kfree(req);
3369 	return ret;
3370 }
3371 
ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base * ab)3372 static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
3373 {
3374 	struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
3375 	struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
3376 	struct qmi_txn txn;
3377 	int ret;
3378 
3379 	req.enable_fwlog_valid = true;
3380 	req.enable_fwlog = 1;
3381 
3382 	ret = qmi_txn_init(&ab->qmi.handle, &txn,
3383 			   qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
3384 	if (ret < 0)
3385 		goto out;
3386 
3387 	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3388 			       ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01,
3389 			       QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
3390 			       qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
3391 	if (ret < 0) {
3392 		qmi_txn_cancel(&txn);
3393 		ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n",
3394 			    ret);
3395 		goto out;
3396 	}
3397 
3398 	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3399 	if (ret < 0) {
3400 		ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret);
3401 		goto out;
3402 	}
3403 
3404 	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3405 		ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
3406 			    resp.resp.result, resp.resp.error);
3407 		ret = -EINVAL;
3408 		goto out;
3409 	}
3410 
3411 out:
3412 	return ret;
3413 }
3414 
ath12k_qmi_firmware_stop(struct ath12k_base * ab)3415 void ath12k_qmi_firmware_stop(struct ath12k_base *ab)
3416 {
3417 	int ret;
3418 
3419 	clear_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags);
3420 
3421 	ret = ath12k_qmi_wlanfw_mode_send(ab, ATH12K_FIRMWARE_MODE_OFF);
3422 	if (ret < 0) {
3423 		ath12k_warn(ab, "qmi failed to send wlan mode off\n");
3424 		return;
3425 	}
3426 }
3427 
ath12k_qmi_firmware_start(struct ath12k_base * ab,u32 mode)3428 int ath12k_qmi_firmware_start(struct ath12k_base *ab,
3429 			      u32 mode)
3430 {
3431 	int ret;
3432 
3433 	ret = ath12k_qmi_wlanfw_wlan_ini_send(ab);
3434 	if (ret < 0) {
3435 		ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret);
3436 		return ret;
3437 	}
3438 
3439 	ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab);
3440 	if (ret < 0) {
3441 		ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
3442 		return ret;
3443 	}
3444 
3445 	ret = ath12k_qmi_wlanfw_mode_send(ab, mode);
3446 	if (ret < 0) {
3447 		ath12k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
3448 		return ret;
3449 	}
3450 
3451 	return 0;
3452 }
3453 
3454 static int
ath12k_qmi_driver_event_post(struct ath12k_qmi * qmi,enum ath12k_qmi_event_type type,void * data)3455 ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi,
3456 			     enum ath12k_qmi_event_type type,
3457 			     void *data)
3458 {
3459 	struct ath12k_qmi_driver_event *event;
3460 
3461 	event = kzalloc(sizeof(*event), GFP_ATOMIC);
3462 	if (!event)
3463 		return -ENOMEM;
3464 
3465 	event->type = type;
3466 	event->data = data;
3467 
3468 	spin_lock(&qmi->event_lock);
3469 	list_add_tail(&event->list, &qmi->event_list);
3470 	spin_unlock(&qmi->event_lock);
3471 
3472 	queue_work(qmi->event_wq, &qmi->event_work);
3473 
3474 	return 0;
3475 }
3476 
ath12k_qmi_trigger_host_cap(struct ath12k_base * ab)3477 void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab)
3478 {
3479 	struct ath12k_qmi *qmi = &ab->qmi;
3480 
3481 	spin_lock(&qmi->event_lock);
3482 
3483 	if (ath12k_qmi_get_event_block(qmi))
3484 		ath12k_qmi_set_event_block(qmi, false);
3485 
3486 	spin_unlock(&qmi->event_lock);
3487 
3488 	ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n",
3489 		   ab->device_id);
3490 
3491 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL);
3492 }
3493 
ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group * ag)3494 static bool ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group *ag)
3495 {
3496 	struct ath12k_base *ab;
3497 	int i;
3498 
3499 	for (i = 0; i < ag->num_devices; i++) {
3500 		ab = ag->ab[i];
3501 
3502 		if (!(ab && ab->qmi.num_radios != U8_MAX))
3503 			return false;
3504 	}
3505 
3506 	return true;
3507 }
3508 
ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group * ag)3509 static struct ath12k_base *ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group *ag)
3510 {
3511 	struct ath12k_base *ab;
3512 	int i;
3513 
3514 	lockdep_assert_held(&ag->mutex);
3515 
3516 	for (i = 0; i < ag->num_devices; i++) {
3517 		ab = ag->ab[i];
3518 		if (!ab)
3519 			continue;
3520 
3521 		spin_lock(&ab->qmi.event_lock);
3522 
3523 		if (ath12k_qmi_get_event_block(&ab->qmi)) {
3524 			spin_unlock(&ab->qmi.event_lock);
3525 			return ab;
3526 		}
3527 
3528 		spin_unlock(&ab->qmi.event_lock);
3529 	}
3530 
3531 	return NULL;
3532 }
3533 
3534 /* clang stack usage explodes if this is inlined */
3535 static noinline_for_stack
ath12k_qmi_event_server_arrive(struct ath12k_qmi * qmi)3536 int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi)
3537 {
3538 	struct ath12k_base *ab = qmi->ab, *block_ab;
3539 	struct ath12k_hw_group *ag = ab->ag;
3540 	int ret;
3541 
3542 	ath12k_qmi_phy_cap_send(ab);
3543 
3544 	ret = ath12k_qmi_fw_ind_register_send(ab);
3545 	if (ret < 0) {
3546 		ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
3547 		return ret;
3548 	}
3549 
3550 	spin_lock(&qmi->event_lock);
3551 
3552 	ath12k_qmi_set_event_block(qmi, true);
3553 
3554 	spin_unlock(&qmi->event_lock);
3555 
3556 	mutex_lock(&ag->mutex);
3557 
3558 	if (ath12k_qmi_hw_group_host_cap_ready(ag)) {
3559 		ath12k_core_hw_group_set_mlo_capable(ag);
3560 
3561 		block_ab = ath12k_qmi_hw_group_find_blocked(ag);
3562 		if (block_ab)
3563 			ath12k_qmi_trigger_host_cap(block_ab);
3564 	}
3565 
3566 	mutex_unlock(&ag->mutex);
3567 
3568 	return ret;
3569 }
3570 
3571 /* clang stack usage explodes if this is inlined */
3572 static noinline_for_stack
ath12k_qmi_event_mem_request(struct ath12k_qmi * qmi)3573 int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi)
3574 {
3575 	struct ath12k_base *ab = qmi->ab;
3576 	int ret;
3577 
3578 	ret = ath12k_qmi_respond_fw_mem_request(ab);
3579 	if (ret < 0) {
3580 		ath12k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
3581 		return ret;
3582 	}
3583 
3584 	return ret;
3585 }
3586 
3587 /* clang stack usage explodes if this is inlined */
3588 static noinline_for_stack
ath12k_qmi_event_load_bdf(struct ath12k_qmi * qmi)3589 int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
3590 {
3591 	struct ath12k_base *ab = qmi->ab;
3592 	int ret;
3593 
3594 	ret = ath12k_qmi_request_target_cap(ab);
3595 	if (ret < 0) {
3596 		ath12k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
3597 		return ret;
3598 	}
3599 
3600 	ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_REGDB);
3601 	if (ret < 0) {
3602 		ath12k_warn(ab, "qmi failed to load regdb file:%d\n", ret);
3603 		return ret;
3604 	}
3605 
3606 	ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_ELF);
3607 	if (ret < 0) {
3608 		ath12k_warn(ab, "qmi failed to load board data file:%d\n", ret);
3609 		return ret;
3610 	}
3611 
3612 	if (ab->hw_params->download_calib) {
3613 		ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION);
3614 		if (ret < 0)
3615 			ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret);
3616 	}
3617 
3618 	ret = ath12k_qmi_wlanfw_m3_info_send(ab);
3619 	if (ret < 0) {
3620 		ath12k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
3621 		return ret;
3622 	}
3623 
3624 	return ret;
3625 }
3626 
ath12k_qmi_msg_mem_request_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * data)3627 static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
3628 					  struct sockaddr_qrtr *sq,
3629 					  struct qmi_txn *txn,
3630 					  const void *data)
3631 {
3632 	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3633 	struct ath12k_base *ab = qmi->ab;
3634 	const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
3635 	int i, ret;
3636 
3637 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware request memory request\n");
3638 
3639 	if (msg->mem_seg_len == 0 ||
3640 	    msg->mem_seg_len > ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
3641 		ath12k_warn(ab, "Invalid memory segment length: %u\n",
3642 			    msg->mem_seg_len);
3643 
3644 	ab->qmi.mem_seg_count = msg->mem_seg_len;
3645 
3646 	for (i = 0; i < qmi->mem_seg_count ; i++) {
3647 		ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
3648 		ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
3649 		ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n",
3650 			   msg->mem_seg[i].type, msg->mem_seg[i].size);
3651 	}
3652 
3653 	if (test_bit(ATH12K_FLAG_FIXED_MEM_REGION, &ab->dev_flags)) {
3654 		ret = ath12k_qmi_assign_target_mem_chunk(ab);
3655 		if (ret) {
3656 			ath12k_warn(ab, "failed to assign qmi target memory: %d\n",
3657 				    ret);
3658 			return;
3659 		}
3660 	} else {
3661 		ret = ath12k_qmi_alloc_target_mem_chunk(ab);
3662 		if (ret) {
3663 			ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
3664 				    ret);
3665 			return;
3666 		}
3667 	}
3668 
3669 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL);
3670 }
3671 
ath12k_qmi_msg_mem_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3672 static void ath12k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
3673 					struct sockaddr_qrtr *sq,
3674 					struct qmi_txn *txn,
3675 					const void *decoded)
3676 {
3677 	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3678 	struct ath12k_base *ab = qmi->ab;
3679 
3680 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware memory ready indication\n");
3681 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_MEM_READY, NULL);
3682 }
3683 
ath12k_qmi_msg_fw_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3684 static void ath12k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
3685 				       struct sockaddr_qrtr *sq,
3686 				       struct qmi_txn *txn,
3687 				       const void *decoded)
3688 {
3689 	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3690 	struct ath12k_base *ab = qmi->ab;
3691 
3692 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware ready\n");
3693 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_READY, NULL);
3694 }
3695 
3696 static const struct qmi_msg_handler ath12k_qmi_msg_handlers[] = {
3697 	{
3698 		.type = QMI_INDICATION,
3699 		.msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
3700 		.ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
3701 		.decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
3702 		.fn = ath12k_qmi_msg_mem_request_cb,
3703 	},
3704 	{
3705 		.type = QMI_INDICATION,
3706 		.msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
3707 		.ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
3708 		.decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
3709 		.fn = ath12k_qmi_msg_mem_ready_cb,
3710 	},
3711 	{
3712 		.type = QMI_INDICATION,
3713 		.msg_id = QMI_WLFW_FW_READY_IND_V01,
3714 		.ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
3715 		.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
3716 		.fn = ath12k_qmi_msg_fw_ready_cb,
3717 	},
3718 
3719 	/* end of list */
3720 	{},
3721 };
3722 
ath12k_qmi_ops_new_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3723 static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
3724 				     struct qmi_service *service)
3725 {
3726 	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3727 	struct ath12k_base *ab = qmi->ab;
3728 	struct sockaddr_qrtr *sq = &qmi->sq;
3729 	int ret;
3730 
3731 	sq->sq_family = AF_QIPCRTR;
3732 	sq->sq_node = service->node;
3733 	sq->sq_port = service->port;
3734 
3735 	ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
3736 			     sizeof(*sq), 0);
3737 	if (ret) {
3738 		ath12k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
3739 		return ret;
3740 	}
3741 
3742 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw qmi service connected\n");
3743 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_ARRIVE, NULL);
3744 
3745 	return ret;
3746 }
3747 
ath12k_qmi_ops_del_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3748 static void ath12k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
3749 				      struct qmi_service *service)
3750 {
3751 	struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3752 	struct ath12k_base *ab = qmi->ab;
3753 
3754 	ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw del server\n");
3755 	ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_EXIT, NULL);
3756 }
3757 
3758 static const struct qmi_ops ath12k_qmi_ops = {
3759 	.new_server = ath12k_qmi_ops_new_server,
3760 	.del_server = ath12k_qmi_ops_del_server,
3761 };
3762 
ath12k_qmi_event_host_cap(struct ath12k_qmi * qmi)3763 static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi)
3764 {
3765 	struct ath12k_base *ab = qmi->ab;
3766 	int ret;
3767 
3768 	ret = ath12k_qmi_host_cap_send(ab);
3769 	if (ret < 0) {
3770 		ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n",
3771 			    ab->device_id, ret);
3772 		return ret;
3773 	}
3774 
3775 	return ret;
3776 }
3777 
ath12k_qmi_driver_event_work(struct work_struct * work)3778 static void ath12k_qmi_driver_event_work(struct work_struct *work)
3779 {
3780 	struct ath12k_qmi *qmi = container_of(work, struct ath12k_qmi,
3781 					      event_work);
3782 	struct ath12k_qmi_driver_event *event;
3783 	struct ath12k_base *ab = qmi->ab;
3784 	int ret;
3785 
3786 	spin_lock(&qmi->event_lock);
3787 	while (!list_empty(&qmi->event_list)) {
3788 		event = list_first_entry(&qmi->event_list,
3789 					 struct ath12k_qmi_driver_event, list);
3790 		list_del(&event->list);
3791 		spin_unlock(&qmi->event_lock);
3792 
3793 		if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
3794 			goto skip;
3795 
3796 		switch (event->type) {
3797 		case ATH12K_QMI_EVENT_SERVER_ARRIVE:
3798 			ret = ath12k_qmi_event_server_arrive(qmi);
3799 			if (ret < 0)
3800 				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3801 			break;
3802 		case ATH12K_QMI_EVENT_SERVER_EXIT:
3803 			set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
3804 			break;
3805 		case ATH12K_QMI_EVENT_REQUEST_MEM:
3806 			ret = ath12k_qmi_event_mem_request(qmi);
3807 			if (ret < 0)
3808 				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3809 			break;
3810 		case ATH12K_QMI_EVENT_FW_MEM_READY:
3811 			ret = ath12k_qmi_event_load_bdf(qmi);
3812 			if (ret < 0)
3813 				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3814 			break;
3815 		case ATH12K_QMI_EVENT_FW_READY:
3816 			clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3817 			if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) {
3818 				if (ab->is_reset)
3819 					ath12k_hal_dump_srng_stats(ab);
3820 
3821 				set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
3822 				queue_work(ab->workqueue, &ab->restart_work);
3823 				break;
3824 			}
3825 
3826 			clear_bit(ATH12K_FLAG_CRASH_FLUSH,
3827 				  &ab->dev_flags);
3828 			ret = ath12k_core_qmi_firmware_ready(ab);
3829 			if (!ret)
3830 				set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE,
3831 					&ab->dev_flags);
3832 
3833 			break;
3834 		case ATH12K_QMI_EVENT_HOST_CAP:
3835 			ret = ath12k_qmi_event_host_cap(qmi);
3836 			if (ret < 0)
3837 				set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3838 			break;
3839 		default:
3840 			ath12k_warn(ab, "invalid event type: %d", event->type);
3841 			break;
3842 		}
3843 
3844 skip:
3845 		kfree(event);
3846 		spin_lock(&qmi->event_lock);
3847 	}
3848 	spin_unlock(&qmi->event_lock);
3849 }
3850 
ath12k_qmi_init_service(struct ath12k_base * ab)3851 int ath12k_qmi_init_service(struct ath12k_base *ab)
3852 {
3853 	int ret;
3854 
3855 	memset(&ab->qmi.target, 0, sizeof(struct target_info));
3856 	memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
3857 	ab->qmi.ab = ab;
3858 
3859 	ab->qmi.target_mem_mode = ab->target_mem_mode;
3860 	ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
3861 			      &ath12k_qmi_ops, ath12k_qmi_msg_handlers);
3862 	if (ret < 0) {
3863 		ath12k_warn(ab, "failed to initialize qmi handle\n");
3864 		return ret;
3865 	}
3866 
3867 	ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0);
3868 	if (!ab->qmi.event_wq) {
3869 		ath12k_err(ab, "failed to allocate workqueue\n");
3870 		return -EFAULT;
3871 	}
3872 
3873 	INIT_LIST_HEAD(&ab->qmi.event_list);
3874 	spin_lock_init(&ab->qmi.event_lock);
3875 	INIT_WORK(&ab->qmi.event_work, ath12k_qmi_driver_event_work);
3876 
3877 	ret = qmi_add_lookup(&ab->qmi.handle, ATH12K_QMI_WLFW_SERVICE_ID_V01,
3878 			     ATH12K_QMI_WLFW_SERVICE_VERS_V01,
3879 			     ab->qmi.service_ins_id);
3880 	if (ret < 0) {
3881 		ath12k_warn(ab, "failed to add qmi lookup\n");
3882 		destroy_workqueue(ab->qmi.event_wq);
3883 		return ret;
3884 	}
3885 
3886 	return ret;
3887 }
3888 
ath12k_qmi_deinit_service(struct ath12k_base * ab)3889 void ath12k_qmi_deinit_service(struct ath12k_base *ab)
3890 {
3891 	if (!ab->qmi.ab)
3892 		return;
3893 
3894 	qmi_handle_release(&ab->qmi.handle);
3895 	cancel_work_sync(&ab->qmi.event_work);
3896 	destroy_workqueue(ab->qmi.event_wq);
3897 	ath12k_qmi_m3_free(ab);
3898 	ath12k_qmi_free_target_mem_chunk(ab);
3899 	ab->qmi.ab = NULL;
3900 }
3901 
ath12k_qmi_free_resource(struct ath12k_base * ab)3902 void ath12k_qmi_free_resource(struct ath12k_base *ab)
3903 {
3904 	ath12k_qmi_free_target_mem_chunk(ab);
3905 	ath12k_qmi_m3_free(ab);
3906 }
3907