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