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