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