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