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

source code of linux/drivers/net/wireless/ath/ath12k/qmi.c