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