1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2025 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
20 static 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
64 static 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
514 static 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
531 static 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
539 static 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_OPT_FLAG,
587 .elem_len = 1,
588 .elem_size = sizeof(u8),
589 .array_type = NO_ARRAY,
590 .tlv_type = 0x13,
591 .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
592 single_chip_mlo_support_valid),
593 },
594 {
595 .data_type = QMI_UNSIGNED_1_BYTE,
596 .elem_len = 1,
597 .elem_size = sizeof(u8),
598 .array_type = NO_ARRAY,
599 .tlv_type = 0x13,
600 .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
601 single_chip_mlo_support),
602 },
603 {
604 .data_type = QMI_EOTI,
605 .array_type = NO_ARRAY,
606 .tlv_type = QMI_COMMON_TLV_TYPE,
607 },
608 };
609
610 static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
611 {
612 .data_type = QMI_OPT_FLAG,
613 .elem_len = 1,
614 .elem_size = sizeof(u8),
615 .array_type = NO_ARRAY,
616 .tlv_type = 0x10,
617 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
618 fw_ready_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 = 0x10,
626 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
627 fw_ready_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 = 0x11,
635 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
636 initiate_cal_download_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 = 0x11,
644 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
645 initiate_cal_download_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 = 0x12,
653 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
654 initiate_cal_update_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 = 0x12,
662 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
663 initiate_cal_update_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 = 0x13,
671 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
672 msa_ready_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 = 0x13,
680 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
681 msa_ready_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 = 0x14,
689 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
690 pin_connect_result_enable_valid),
691 },
692 {
693 .data_type = QMI_UNSIGNED_1_BYTE,
694 .elem_len = 1,
695 .elem_size = sizeof(u8),
696 .array_type = NO_ARRAY,
697 .tlv_type = 0x14,
698 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
699 pin_connect_result_enable),
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 = 0x15,
707 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
708 client_id_valid),
709 },
710 {
711 .data_type = QMI_UNSIGNED_4_BYTE,
712 .elem_len = 1,
713 .elem_size = sizeof(u32),
714 .array_type = NO_ARRAY,
715 .tlv_type = 0x15,
716 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
717 client_id),
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 = 0x16,
725 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
726 request_mem_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 = 0x16,
734 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
735 request_mem_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 = 0x17,
743 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
744 fw_mem_ready_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 = 0x17,
752 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
753 fw_mem_ready_enable),
754 },
755 {
756 .data_type = QMI_OPT_FLAG,
757 .elem_len = 1,
758 .elem_size = sizeof(u8),
759 .array_type = NO_ARRAY,
760 .tlv_type = 0x18,
761 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
762 fw_init_done_enable_valid),
763 },
764 {
765 .data_type = QMI_UNSIGNED_1_BYTE,
766 .elem_len = 1,
767 .elem_size = sizeof(u8),
768 .array_type = NO_ARRAY,
769 .tlv_type = 0x18,
770 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
771 fw_init_done_enable),
772 },
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 = 0x19,
780 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
781 rejuvenate_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 = 0x19,
789 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
790 rejuvenate_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 = 0x1A,
798 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
799 xo_cal_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 = 0x1A,
807 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
808 xo_cal_enable),
809 },
810 {
811 .data_type = QMI_OPT_FLAG,
812 .elem_len = 1,
813 .elem_size = sizeof(u8),
814 .array_type = NO_ARRAY,
815 .tlv_type = 0x1B,
816 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
817 cal_done_enable_valid),
818 },
819 {
820 .data_type = QMI_UNSIGNED_1_BYTE,
821 .elem_len = 1,
822 .elem_size = sizeof(u8),
823 .array_type = NO_ARRAY,
824 .tlv_type = 0x1B,
825 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
826 cal_done_enable),
827 },
828 {
829 .data_type = QMI_EOTI,
830 .array_type = NO_ARRAY,
831 .tlv_type = QMI_COMMON_TLV_TYPE,
832 },
833 };
834
835 static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
836 {
837 .data_type = QMI_STRUCT,
838 .elem_len = 1,
839 .elem_size = sizeof(struct qmi_response_type_v01),
840 .array_type = NO_ARRAY,
841 .tlv_type = 0x02,
842 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
843 resp),
844 .ei_array = qmi_response_type_v01_ei,
845 },
846 {
847 .data_type = QMI_OPT_FLAG,
848 .elem_len = 1,
849 .elem_size = sizeof(u8),
850 .array_type = NO_ARRAY,
851 .tlv_type = 0x10,
852 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
853 fw_status_valid),
854 },
855 {
856 .data_type = QMI_UNSIGNED_8_BYTE,
857 .elem_len = 1,
858 .elem_size = sizeof(u64),
859 .array_type = NO_ARRAY,
860 .tlv_type = 0x10,
861 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
862 fw_status),
863 },
864 {
865 .data_type = QMI_EOTI,
866 .array_type = NO_ARRAY,
867 .tlv_type = QMI_COMMON_TLV_TYPE,
868 },
869 };
870
871 static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
872 {
873 .data_type = QMI_UNSIGNED_8_BYTE,
874 .elem_len = 1,
875 .elem_size = sizeof(u64),
876 .array_type = NO_ARRAY,
877 .tlv_type = 0,
878 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
879 },
880 {
881 .data_type = QMI_UNSIGNED_4_BYTE,
882 .elem_len = 1,
883 .elem_size = sizeof(u32),
884 .array_type = NO_ARRAY,
885 .tlv_type = 0,
886 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
887 },
888 {
889 .data_type = QMI_UNSIGNED_1_BYTE,
890 .elem_len = 1,
891 .elem_size = sizeof(u8),
892 .array_type = NO_ARRAY,
893 .tlv_type = 0,
894 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
895 },
896 {
897 .data_type = QMI_EOTI,
898 .array_type = NO_ARRAY,
899 .tlv_type = QMI_COMMON_TLV_TYPE,
900 },
901 };
902
903 static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
904 {
905 .data_type = QMI_UNSIGNED_4_BYTE,
906 .elem_len = 1,
907 .elem_size = sizeof(u32),
908 .array_type = NO_ARRAY,
909 .tlv_type = 0,
910 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01,
911 size),
912 },
913 {
914 .data_type = QMI_SIGNED_4_BYTE_ENUM,
915 .elem_len = 1,
916 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
917 .array_type = NO_ARRAY,
918 .tlv_type = 0,
919 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
920 },
921 {
922 .data_type = QMI_DATA_LEN,
923 .elem_len = 1,
924 .elem_size = sizeof(u8),
925 .array_type = NO_ARRAY,
926 .tlv_type = 0,
927 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
928 },
929 {
930 .data_type = QMI_STRUCT,
931 .elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
932 .elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
933 .array_type = VAR_LEN_ARRAY,
934 .tlv_type = 0,
935 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
936 .ei_array = qmi_wlanfw_mem_cfg_s_v01_ei,
937 },
938 {
939 .data_type = QMI_EOTI,
940 .array_type = NO_ARRAY,
941 .tlv_type = QMI_COMMON_TLV_TYPE,
942 },
943 };
944
945 static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
946 {
947 .data_type = QMI_DATA_LEN,
948 .elem_len = 1,
949 .elem_size = sizeof(u8),
950 .array_type = NO_ARRAY,
951 .tlv_type = 0x01,
952 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
953 mem_seg_len),
954 },
955 {
956 .data_type = QMI_STRUCT,
957 .elem_len = ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
958 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01),
959 .array_type = VAR_LEN_ARRAY,
960 .tlv_type = 0x01,
961 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
962 mem_seg),
963 .ei_array = qmi_wlanfw_mem_seg_s_v01_ei,
964 },
965 {
966 .data_type = QMI_EOTI,
967 .array_type = NO_ARRAY,
968 .tlv_type = QMI_COMMON_TLV_TYPE,
969 },
970 };
971
972 static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
973 {
974 .data_type = QMI_UNSIGNED_8_BYTE,
975 .elem_len = 1,
976 .elem_size = sizeof(u64),
977 .array_type = NO_ARRAY,
978 .tlv_type = 0,
979 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
980 },
981 {
982 .data_type = QMI_UNSIGNED_4_BYTE,
983 .elem_len = 1,
984 .elem_size = sizeof(u32),
985 .array_type = NO_ARRAY,
986 .tlv_type = 0,
987 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
988 },
989 {
990 .data_type = QMI_SIGNED_4_BYTE_ENUM,
991 .elem_len = 1,
992 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
993 .array_type = NO_ARRAY,
994 .tlv_type = 0,
995 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
996 },
997 {
998 .data_type = QMI_UNSIGNED_1_BYTE,
999 .elem_len = 1,
1000 .elem_size = sizeof(u8),
1001 .array_type = NO_ARRAY,
1002 .tlv_type = 0,
1003 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
1004 },
1005 {
1006 .data_type = QMI_EOTI,
1007 .array_type = NO_ARRAY,
1008 .tlv_type = QMI_COMMON_TLV_TYPE,
1009 },
1010 };
1011
1012 static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
1013 {
1014 .data_type = QMI_DATA_LEN,
1015 .elem_len = 1,
1016 .elem_size = sizeof(u8),
1017 .array_type = NO_ARRAY,
1018 .tlv_type = 0x01,
1019 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1020 mem_seg_len),
1021 },
1022 {
1023 .data_type = QMI_STRUCT,
1024 .elem_len = ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
1025 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
1026 .array_type = VAR_LEN_ARRAY,
1027 .tlv_type = 0x01,
1028 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
1029 mem_seg),
1030 .ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei,
1031 },
1032 {
1033 .data_type = QMI_EOTI,
1034 .array_type = NO_ARRAY,
1035 .tlv_type = QMI_COMMON_TLV_TYPE,
1036 },
1037 };
1038
1039 static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
1040 {
1041 .data_type = QMI_STRUCT,
1042 .elem_len = 1,
1043 .elem_size = sizeof(struct qmi_response_type_v01),
1044 .array_type = NO_ARRAY,
1045 .tlv_type = 0x02,
1046 .offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
1047 resp),
1048 .ei_array = qmi_response_type_v01_ei,
1049 },
1050 {
1051 .data_type = QMI_EOTI,
1052 .array_type = NO_ARRAY,
1053 .tlv_type = QMI_COMMON_TLV_TYPE,
1054 },
1055 };
1056
1057 static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
1058 {
1059 .data_type = QMI_EOTI,
1060 .array_type = NO_ARRAY,
1061 .tlv_type = QMI_COMMON_TLV_TYPE,
1062 },
1063 };
1064
1065 static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
1066 {
1067 .data_type = QMI_UNSIGNED_4_BYTE,
1068 .elem_len = 1,
1069 .elem_size = sizeof(u32),
1070 .array_type = NO_ARRAY,
1071 .tlv_type = 0,
1072 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1073 chip_id),
1074 },
1075 {
1076 .data_type = QMI_UNSIGNED_4_BYTE,
1077 .elem_len = 1,
1078 .elem_size = sizeof(u32),
1079 .array_type = NO_ARRAY,
1080 .tlv_type = 0,
1081 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
1082 chip_family),
1083 },
1084 {
1085 .data_type = QMI_EOTI,
1086 .array_type = NO_ARRAY,
1087 .tlv_type = QMI_COMMON_TLV_TYPE,
1088 },
1089 };
1090
1091 static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
1092 {
1093 .data_type = QMI_UNSIGNED_4_BYTE,
1094 .elem_len = 1,
1095 .elem_size = sizeof(u32),
1096 .array_type = NO_ARRAY,
1097 .tlv_type = 0,
1098 .offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
1099 board_id),
1100 },
1101 {
1102 .data_type = QMI_EOTI,
1103 .array_type = NO_ARRAY,
1104 .tlv_type = QMI_COMMON_TLV_TYPE,
1105 },
1106 };
1107
1108 static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
1109 {
1110 .data_type = QMI_UNSIGNED_4_BYTE,
1111 .elem_len = 1,
1112 .elem_size = sizeof(u32),
1113 .array_type = NO_ARRAY,
1114 .tlv_type = 0,
1115 .offset = offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
1116 },
1117 {
1118 .data_type = QMI_EOTI,
1119 .array_type = NO_ARRAY,
1120 .tlv_type = QMI_COMMON_TLV_TYPE,
1121 },
1122 };
1123
1124 static const struct qmi_elem_info qmi_wlanfw_dev_mem_info_s_v01_ei[] = {
1125 {
1126 .data_type = QMI_UNSIGNED_8_BYTE,
1127 .elem_len = 1,
1128 .elem_size = sizeof(u64),
1129 .array_type = NO_ARRAY,
1130 .tlv_type = 0,
1131 .offset = offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1132 start),
1133 },
1134 {
1135 .data_type = QMI_UNSIGNED_8_BYTE,
1136 .elem_len = 1,
1137 .elem_size = sizeof(u64),
1138 .array_type = NO_ARRAY,
1139 .tlv_type = 0,
1140 .offset = offsetof(struct qmi_wlanfw_dev_mem_info_s_v01,
1141 size),
1142 },
1143 {
1144 .data_type = QMI_EOTI,
1145 .array_type = NO_ARRAY,
1146 .tlv_type = QMI_COMMON_TLV_TYPE,
1147 },
1148 };
1149
1150 static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
1151 {
1152 .data_type = QMI_UNSIGNED_4_BYTE,
1153 .elem_len = 1,
1154 .elem_size = sizeof(u32),
1155 .array_type = NO_ARRAY,
1156 .tlv_type = 0,
1157 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1158 fw_version),
1159 },
1160 {
1161 .data_type = QMI_STRING,
1162 .elem_len = ATH12K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
1163 .elem_size = sizeof(char),
1164 .array_type = NO_ARRAY,
1165 .tlv_type = 0,
1166 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
1167 fw_build_timestamp),
1168 },
1169 {
1170 .data_type = QMI_EOTI,
1171 .array_type = NO_ARRAY,
1172 .tlv_type = QMI_COMMON_TLV_TYPE,
1173 },
1174 };
1175
1176 static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
1177 {
1178 .data_type = QMI_STRUCT,
1179 .elem_len = 1,
1180 .elem_size = sizeof(struct qmi_response_type_v01),
1181 .array_type = NO_ARRAY,
1182 .tlv_type = 0x02,
1183 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
1184 .ei_array = qmi_response_type_v01_ei,
1185 },
1186 {
1187 .data_type = QMI_OPT_FLAG,
1188 .elem_len = 1,
1189 .elem_size = sizeof(u8),
1190 .array_type = NO_ARRAY,
1191 .tlv_type = 0x10,
1192 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1193 chip_info_valid),
1194 },
1195 {
1196 .data_type = QMI_STRUCT,
1197 .elem_len = 1,
1198 .elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
1199 .array_type = NO_ARRAY,
1200 .tlv_type = 0x10,
1201 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1202 chip_info),
1203 .ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei,
1204 },
1205 {
1206 .data_type = QMI_OPT_FLAG,
1207 .elem_len = 1,
1208 .elem_size = sizeof(u8),
1209 .array_type = NO_ARRAY,
1210 .tlv_type = 0x11,
1211 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1212 board_info_valid),
1213 },
1214 {
1215 .data_type = QMI_STRUCT,
1216 .elem_len = 1,
1217 .elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
1218 .array_type = NO_ARRAY,
1219 .tlv_type = 0x11,
1220 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1221 board_info),
1222 .ei_array = qmi_wlanfw_rf_board_info_s_v01_ei,
1223 },
1224 {
1225 .data_type = QMI_OPT_FLAG,
1226 .elem_len = 1,
1227 .elem_size = sizeof(u8),
1228 .array_type = NO_ARRAY,
1229 .tlv_type = 0x12,
1230 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1231 soc_info_valid),
1232 },
1233 {
1234 .data_type = QMI_STRUCT,
1235 .elem_len = 1,
1236 .elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01),
1237 .array_type = NO_ARRAY,
1238 .tlv_type = 0x12,
1239 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1240 soc_info),
1241 .ei_array = qmi_wlanfw_soc_info_s_v01_ei,
1242 },
1243 {
1244 .data_type = QMI_OPT_FLAG,
1245 .elem_len = 1,
1246 .elem_size = sizeof(u8),
1247 .array_type = NO_ARRAY,
1248 .tlv_type = 0x13,
1249 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1250 fw_version_info_valid),
1251 },
1252 {
1253 .data_type = QMI_STRUCT,
1254 .elem_len = 1,
1255 .elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
1256 .array_type = NO_ARRAY,
1257 .tlv_type = 0x13,
1258 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1259 fw_version_info),
1260 .ei_array = qmi_wlanfw_fw_version_info_s_v01_ei,
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 = 0x14,
1268 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1269 fw_build_id_valid),
1270 },
1271 {
1272 .data_type = QMI_STRING,
1273 .elem_len = ATH12K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
1274 .elem_size = sizeof(char),
1275 .array_type = NO_ARRAY,
1276 .tlv_type = 0x14,
1277 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1278 fw_build_id),
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 = 0x15,
1286 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1287 num_macs_valid),
1288 },
1289 {
1290 .data_type = QMI_UNSIGNED_1_BYTE,
1291 .elem_len = 1,
1292 .elem_size = sizeof(u8),
1293 .array_type = NO_ARRAY,
1294 .tlv_type = 0x15,
1295 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1296 num_macs),
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 = 0x16,
1304 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1305 voltage_mv_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 = 0x16,
1313 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1314 voltage_mv),
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 = 0x17,
1322 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1323 time_freq_hz_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 = 0x17,
1331 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1332 time_freq_hz),
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 = 0x18,
1340 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1341 otp_version_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 = 0x18,
1349 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1350 otp_version),
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 = 0x19,
1358 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1359 eeprom_caldata_read_timeout_valid),
1360 },
1361 {
1362 .data_type = QMI_UNSIGNED_4_BYTE,
1363 .elem_len = 1,
1364 .elem_size = sizeof(u32),
1365 .array_type = NO_ARRAY,
1366 .tlv_type = 0x19,
1367 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1368 eeprom_caldata_read_timeout),
1369 },
1370 {
1371 .data_type = QMI_OPT_FLAG,
1372 .elem_len = 1,
1373 .elem_size = sizeof(u8),
1374 .array_type = NO_ARRAY,
1375 .tlv_type = 0x1A,
1376 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1377 fw_caps_valid),
1378 },
1379 {
1380 .data_type = QMI_UNSIGNED_8_BYTE,
1381 .elem_len = 1,
1382 .elem_size = sizeof(u64),
1383 .array_type = NO_ARRAY,
1384 .tlv_type = 0x1A,
1385 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, fw_caps),
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 = 0x1B,
1393 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1394 rd_card_chain_cap_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 = 0x1B,
1402 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1403 rd_card_chain_cap),
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 = 0x1C,
1411 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1412 dev_mem_info_valid),
1413 },
1414 {
1415 .data_type = QMI_STRUCT,
1416 .elem_len = ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01,
1417 .elem_size = sizeof(struct qmi_wlanfw_dev_mem_info_s_v01),
1418 .array_type = STATIC_ARRAY,
1419 .tlv_type = 0x1C,
1420 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, dev_mem),
1421 .ei_array = qmi_wlanfw_dev_mem_info_s_v01_ei,
1422 },
1423 {
1424 .data_type = QMI_EOTI,
1425 .array_type = NO_ARRAY,
1426 .tlv_type = QMI_COMMON_TLV_TYPE,
1427 },
1428 };
1429
1430 static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
1431 {
1432 .data_type = QMI_UNSIGNED_1_BYTE,
1433 .elem_len = 1,
1434 .elem_size = sizeof(u8),
1435 .array_type = NO_ARRAY,
1436 .tlv_type = 0x01,
1437 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1438 valid),
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 = 0x10,
1446 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1447 file_id_valid),
1448 },
1449 {
1450 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1451 .elem_len = 1,
1452 .elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
1453 .array_type = NO_ARRAY,
1454 .tlv_type = 0x10,
1455 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1456 file_id),
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 = 0x11,
1464 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1465 total_size_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 = 0x11,
1473 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1474 total_size),
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 = 0x12,
1482 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1483 seg_id_valid),
1484 },
1485 {
1486 .data_type = QMI_UNSIGNED_4_BYTE,
1487 .elem_len = 1,
1488 .elem_size = sizeof(u32),
1489 .array_type = NO_ARRAY,
1490 .tlv_type = 0x12,
1491 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1492 seg_id),
1493 },
1494 {
1495 .data_type = QMI_OPT_FLAG,
1496 .elem_len = 1,
1497 .elem_size = sizeof(u8),
1498 .array_type = NO_ARRAY,
1499 .tlv_type = 0x13,
1500 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1501 data_valid),
1502 },
1503 {
1504 .data_type = QMI_DATA_LEN,
1505 .elem_len = 1,
1506 .elem_size = sizeof(u16),
1507 .array_type = NO_ARRAY,
1508 .tlv_type = 0x13,
1509 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1510 data_len),
1511 },
1512 {
1513 .data_type = QMI_UNSIGNED_1_BYTE,
1514 .elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01,
1515 .elem_size = sizeof(u8),
1516 .array_type = VAR_LEN_ARRAY,
1517 .tlv_type = 0x13,
1518 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1519 data),
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 = 0x14,
1527 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1528 end_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 = 0x14,
1536 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1537 end),
1538 },
1539 {
1540 .data_type = QMI_OPT_FLAG,
1541 .elem_len = 1,
1542 .elem_size = sizeof(u8),
1543 .array_type = NO_ARRAY,
1544 .tlv_type = 0x15,
1545 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1546 bdf_type_valid),
1547 },
1548 {
1549 .data_type = QMI_UNSIGNED_1_BYTE,
1550 .elem_len = 1,
1551 .elem_size = sizeof(u8),
1552 .array_type = NO_ARRAY,
1553 .tlv_type = 0x15,
1554 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1555 bdf_type),
1556 },
1557
1558 {
1559 .data_type = QMI_EOTI,
1560 .array_type = NO_ARRAY,
1561 .tlv_type = QMI_COMMON_TLV_TYPE,
1562 },
1563 };
1564
1565 static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1566 {
1567 .data_type = QMI_STRUCT,
1568 .elem_len = 1,
1569 .elem_size = sizeof(struct qmi_response_type_v01),
1570 .array_type = NO_ARRAY,
1571 .tlv_type = 0x02,
1572 .offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1573 resp),
1574 .ei_array = qmi_response_type_v01_ei,
1575 },
1576 {
1577 .data_type = QMI_EOTI,
1578 .array_type = NO_ARRAY,
1579 .tlv_type = QMI_COMMON_TLV_TYPE,
1580 },
1581 };
1582
1583 static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1584 {
1585 .data_type = QMI_UNSIGNED_8_BYTE,
1586 .elem_len = 1,
1587 .elem_size = sizeof(u64),
1588 .array_type = NO_ARRAY,
1589 .tlv_type = 0x01,
1590 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1591 },
1592 {
1593 .data_type = QMI_UNSIGNED_4_BYTE,
1594 .elem_len = 1,
1595 .elem_size = sizeof(u32),
1596 .array_type = NO_ARRAY,
1597 .tlv_type = 0x02,
1598 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1599 },
1600 {
1601 .data_type = QMI_EOTI,
1602 .array_type = NO_ARRAY,
1603 .tlv_type = QMI_COMMON_TLV_TYPE,
1604 },
1605 };
1606
1607 static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1608 {
1609 .data_type = QMI_STRUCT,
1610 .elem_len = 1,
1611 .elem_size = sizeof(struct qmi_response_type_v01),
1612 .array_type = NO_ARRAY,
1613 .tlv_type = 0x02,
1614 .offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1615 .ei_array = qmi_response_type_v01_ei,
1616 },
1617 {
1618 .data_type = QMI_EOTI,
1619 .array_type = NO_ARRAY,
1620 .tlv_type = QMI_COMMON_TLV_TYPE,
1621 },
1622 };
1623
1624 static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
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 pipe_num),
1633 },
1634 {
1635 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1636 .elem_len = 1,
1637 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1638 .array_type = NO_ARRAY,
1639 .tlv_type = 0,
1640 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1641 pipe_dir),
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 nentries),
1651 },
1652 {
1653 .data_type = QMI_UNSIGNED_4_BYTE,
1654 .elem_len = 1,
1655 .elem_size = sizeof(u32),
1656 .array_type = NO_ARRAY,
1657 .tlv_type = 0,
1658 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1659 nbytes_max),
1660 },
1661 {
1662 .data_type = QMI_UNSIGNED_4_BYTE,
1663 .elem_len = 1,
1664 .elem_size = sizeof(u32),
1665 .array_type = NO_ARRAY,
1666 .tlv_type = 0,
1667 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1668 flags),
1669 },
1670 {
1671 .data_type = QMI_EOTI,
1672 .array_type = NO_ARRAY,
1673 .tlv_type = QMI_COMMON_TLV_TYPE,
1674 },
1675 };
1676
1677 static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
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 service_id),
1686 },
1687 {
1688 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1689 .elem_len = 1,
1690 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1691 .array_type = NO_ARRAY,
1692 .tlv_type = 0,
1693 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1694 pipe_dir),
1695 },
1696 {
1697 .data_type = QMI_UNSIGNED_4_BYTE,
1698 .elem_len = 1,
1699 .elem_size = sizeof(u32),
1700 .array_type = NO_ARRAY,
1701 .tlv_type = 0,
1702 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1703 pipe_num),
1704 },
1705 {
1706 .data_type = QMI_EOTI,
1707 .array_type = NO_ARRAY,
1708 .tlv_type = QMI_COMMON_TLV_TYPE,
1709 },
1710 };
1711
1712 static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1713 {
1714 .data_type = QMI_UNSIGNED_2_BYTE,
1715 .elem_len = 1,
1716 .elem_size = sizeof(u16),
1717 .array_type = NO_ARRAY,
1718 .tlv_type = 0,
1719 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1720 },
1721 {
1722 .data_type = QMI_UNSIGNED_2_BYTE,
1723 .elem_len = 1,
1724 .elem_size = sizeof(u16),
1725 .array_type = NO_ARRAY,
1726 .tlv_type = 0,
1727 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1728 offset),
1729 },
1730 {
1731 .data_type = QMI_EOTI,
1732 .array_type = QMI_COMMON_TLV_TYPE,
1733 },
1734 };
1735
1736 static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei[] = {
1737 {
1738 .data_type = QMI_UNSIGNED_4_BYTE,
1739 .elem_len = 1,
1740 .elem_size = sizeof(u32),
1741 .array_type = NO_ARRAY,
1742 .tlv_type = 0,
1743 .offset = offsetof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01,
1744 addr),
1745 },
1746 {
1747 .data_type = QMI_EOTI,
1748 .array_type = NO_ARRAY,
1749 .tlv_type = QMI_COMMON_TLV_TYPE,
1750 },
1751 };
1752
1753 static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1754 {
1755 .data_type = QMI_UNSIGNED_4_BYTE,
1756 .elem_len = 1,
1757 .elem_size = sizeof(u32),
1758 .array_type = NO_ARRAY,
1759 .tlv_type = 0x01,
1760 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1761 mode),
1762 },
1763 {
1764 .data_type = QMI_OPT_FLAG,
1765 .elem_len = 1,
1766 .elem_size = sizeof(u8),
1767 .array_type = NO_ARRAY,
1768 .tlv_type = 0x10,
1769 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1770 hw_debug_valid),
1771 },
1772 {
1773 .data_type = QMI_UNSIGNED_1_BYTE,
1774 .elem_len = 1,
1775 .elem_size = sizeof(u8),
1776 .array_type = NO_ARRAY,
1777 .tlv_type = 0x10,
1778 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1779 hw_debug),
1780 },
1781 {
1782 .data_type = QMI_EOTI,
1783 .array_type = NO_ARRAY,
1784 .tlv_type = QMI_COMMON_TLV_TYPE,
1785 },
1786 };
1787
1788 static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1789 {
1790 .data_type = QMI_STRUCT,
1791 .elem_len = 1,
1792 .elem_size = sizeof(struct qmi_response_type_v01),
1793 .array_type = NO_ARRAY,
1794 .tlv_type = 0x02,
1795 .offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1796 resp),
1797 .ei_array = qmi_response_type_v01_ei,
1798 },
1799 {
1800 .data_type = QMI_EOTI,
1801 .array_type = NO_ARRAY,
1802 .tlv_type = QMI_COMMON_TLV_TYPE,
1803 },
1804 };
1805
1806 static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1807 {
1808 .data_type = QMI_OPT_FLAG,
1809 .elem_len = 1,
1810 .elem_size = sizeof(u8),
1811 .array_type = NO_ARRAY,
1812 .tlv_type = 0x10,
1813 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1814 host_version_valid),
1815 },
1816 {
1817 .data_type = QMI_STRING,
1818 .elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1819 .elem_size = sizeof(char),
1820 .array_type = NO_ARRAY,
1821 .tlv_type = 0x10,
1822 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1823 host_version),
1824 },
1825 {
1826 .data_type = QMI_OPT_FLAG,
1827 .elem_len = 1,
1828 .elem_size = sizeof(u8),
1829 .array_type = NO_ARRAY,
1830 .tlv_type = 0x11,
1831 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1832 tgt_cfg_valid),
1833 },
1834 {
1835 .data_type = QMI_DATA_LEN,
1836 .elem_len = 1,
1837 .elem_size = sizeof(u8),
1838 .array_type = NO_ARRAY,
1839 .tlv_type = 0x11,
1840 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1841 tgt_cfg_len),
1842 },
1843 {
1844 .data_type = QMI_STRUCT,
1845 .elem_len = QMI_WLANFW_MAX_NUM_CE_V01,
1846 .elem_size = sizeof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1847 .array_type = VAR_LEN_ARRAY,
1848 .tlv_type = 0x11,
1849 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1850 tgt_cfg),
1851 .ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1852 },
1853 {
1854 .data_type = QMI_OPT_FLAG,
1855 .elem_len = 1,
1856 .elem_size = sizeof(u8),
1857 .array_type = NO_ARRAY,
1858 .tlv_type = 0x12,
1859 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1860 svc_cfg_valid),
1861 },
1862 {
1863 .data_type = QMI_DATA_LEN,
1864 .elem_len = 1,
1865 .elem_size = sizeof(u8),
1866 .array_type = NO_ARRAY,
1867 .tlv_type = 0x12,
1868 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1869 svc_cfg_len),
1870 },
1871 {
1872 .data_type = QMI_STRUCT,
1873 .elem_len = QMI_WLANFW_MAX_NUM_SVC_V01,
1874 .elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1875 .array_type = VAR_LEN_ARRAY,
1876 .tlv_type = 0x12,
1877 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1878 svc_cfg),
1879 .ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1880 },
1881 {
1882 .data_type = QMI_OPT_FLAG,
1883 .elem_len = 1,
1884 .elem_size = sizeof(u8),
1885 .array_type = NO_ARRAY,
1886 .tlv_type = 0x13,
1887 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1888 shadow_reg_valid),
1889 },
1890 {
1891 .data_type = QMI_DATA_LEN,
1892 .elem_len = 1,
1893 .elem_size = sizeof(u8),
1894 .array_type = NO_ARRAY,
1895 .tlv_type = 0x13,
1896 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1897 shadow_reg_len),
1898 },
1899 {
1900 .data_type = QMI_STRUCT,
1901 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1902 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1903 .array_type = VAR_LEN_ARRAY,
1904 .tlv_type = 0x13,
1905 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1906 shadow_reg),
1907 .ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1908 },
1909 {
1910 .data_type = QMI_OPT_FLAG,
1911 .elem_len = 1,
1912 .elem_size = sizeof(u8),
1913 .array_type = NO_ARRAY,
1914 .tlv_type = 0x17,
1915 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1916 shadow_reg_v3_valid),
1917 },
1918 {
1919 .data_type = QMI_DATA_LEN,
1920 .elem_len = 1,
1921 .elem_size = sizeof(u8),
1922 .array_type = NO_ARRAY,
1923 .tlv_type = 0x17,
1924 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1925 shadow_reg_v3_len),
1926 },
1927 {
1928 .data_type = QMI_STRUCT,
1929 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01,
1930 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v3_cfg_s_v01),
1931 .array_type = VAR_LEN_ARRAY,
1932 .tlv_type = 0x17,
1933 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1934 shadow_reg_v3),
1935 .ei_array = qmi_wlanfw_shadow_reg_v3_cfg_s_v01_ei,
1936 },
1937 {
1938 .data_type = QMI_EOTI,
1939 .array_type = NO_ARRAY,
1940 .tlv_type = QMI_COMMON_TLV_TYPE,
1941 },
1942 };
1943
1944 static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1945 {
1946 .data_type = QMI_STRUCT,
1947 .elem_len = 1,
1948 .elem_size = sizeof(struct qmi_response_type_v01),
1949 .array_type = NO_ARRAY,
1950 .tlv_type = 0x02,
1951 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1952 .ei_array = qmi_response_type_v01_ei,
1953 },
1954 {
1955 .data_type = QMI_EOTI,
1956 .array_type = NO_ARRAY,
1957 .tlv_type = QMI_COMMON_TLV_TYPE,
1958 },
1959 };
1960
1961 static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1962 {
1963 .data_type = QMI_EOTI,
1964 .array_type = NO_ARRAY,
1965 },
1966 };
1967
1968 static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1969 {
1970 .data_type = QMI_EOTI,
1971 .array_type = NO_ARRAY,
1972 },
1973 };
1974
1975 static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
1976 {
1977 .data_type = QMI_OPT_FLAG,
1978 .elem_len = 1,
1979 .elem_size = sizeof(u8),
1980 .array_type = NO_ARRAY,
1981 .tlv_type = 0x10,
1982 .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1983 enable_fwlog_valid),
1984 },
1985 {
1986 .data_type = QMI_UNSIGNED_1_BYTE,
1987 .elem_len = 1,
1988 .elem_size = sizeof(u8),
1989 .array_type = NO_ARRAY,
1990 .tlv_type = 0x10,
1991 .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1992 enable_fwlog),
1993 },
1994 {
1995 .data_type = QMI_EOTI,
1996 .array_type = NO_ARRAY,
1997 .tlv_type = QMI_COMMON_TLV_TYPE,
1998 },
1999 };
2000
2001 static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
2002 {
2003 .data_type = QMI_STRUCT,
2004 .elem_len = 1,
2005 .elem_size = sizeof(struct qmi_response_type_v01),
2006 .array_type = NO_ARRAY,
2007 .tlv_type = 0x02,
2008 .offset = offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
2009 resp),
2010 .ei_array = qmi_response_type_v01_ei,
2011 },
2012 {
2013 .data_type = QMI_EOTI,
2014 .array_type = NO_ARRAY,
2015 .tlv_type = QMI_COMMON_TLV_TYPE,
2016 },
2017 };
2018
ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group * ag)2019 static void ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group *ag)
2020 {
2021 struct ath12k_base *ab, *partner_ab;
2022 int i, j, hw_id_base;
2023
2024 for (i = 0; i < ag->num_devices; i++) {
2025 hw_id_base = 0;
2026 ab = ag->ab[i];
2027
2028 for (j = 0; j < ag->num_devices; j++) {
2029 partner_ab = ag->ab[j];
2030
2031 if (partner_ab->wsi_info.index >= ab->wsi_info.index)
2032 continue;
2033
2034 hw_id_base += partner_ab->qmi.num_radios;
2035 }
2036
2037 ab->wsi_info.hw_link_id_base = hw_id_base;
2038 }
2039
2040 ag->hw_link_id_init_done = true;
2041 }
2042
ath12k_host_cap_parse_mlo(struct ath12k_base * ab,struct qmi_wlanfw_host_cap_req_msg_v01 * req)2043 static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab,
2044 struct qmi_wlanfw_host_cap_req_msg_v01 *req)
2045 {
2046 struct wlfw_host_mlo_chip_info_s_v01 *info;
2047 struct ath12k_hw_group *ag = ab->ag;
2048 struct ath12k_base *partner_ab;
2049 u8 hw_link_id = 0;
2050 int i, j, ret;
2051
2052 if (!ag->mlo_capable) {
2053 ath12k_dbg(ab, ATH12K_DBG_QMI,
2054 "MLO is disabled hence skip QMI MLO cap");
2055 return 0;
2056 }
2057
2058 if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) {
2059 ag->mlo_capable = false;
2060 ath12k_dbg(ab, ATH12K_DBG_QMI,
2061 "skip QMI MLO cap due to invalid num_radio %d\n",
2062 ab->qmi.num_radios);
2063 return 0;
2064 }
2065
2066 if (ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2067 ath12k_err(ab, "failed to send MLO cap due to invalid device id\n");
2068 return -EINVAL;
2069 }
2070
2071 req->mlo_capable_valid = 1;
2072 req->mlo_capable = 1;
2073 req->mlo_chip_id_valid = 1;
2074 req->mlo_chip_id = ab->device_id;
2075 req->mlo_group_id_valid = 1;
2076 req->mlo_group_id = ag->id;
2077 req->max_mlo_peer_valid = 1;
2078 /* Max peer number generally won't change for the same device
2079 * but needs to be synced with host driver.
2080 */
2081 req->max_mlo_peer = ab->hw_params->max_mlo_peer;
2082 req->mlo_num_chips_valid = 1;
2083 req->mlo_num_chips = ag->num_devices;
2084
2085 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d",
2086 req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips);
2087
2088 mutex_lock(&ag->mutex);
2089
2090 if (!ag->hw_link_id_init_done)
2091 ath12k_host_cap_hw_link_id_init(ag);
2092
2093 for (i = 0; i < ag->num_devices; i++) {
2094 info = &req->mlo_chip_info[i];
2095 partner_ab = ag->ab[i];
2096
2097 if (partner_ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2098 ath12k_err(ab, "failed to send MLO cap due to invalid partner device id\n");
2099 ret = -EINVAL;
2100 goto device_cleanup;
2101 }
2102
2103 info->chip_id = partner_ab->device_id;
2104 info->num_local_links = partner_ab->qmi.num_radios;
2105
2106 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n",
2107 info->chip_id, info->num_local_links);
2108
2109 for (j = 0; j < info->num_local_links; j++) {
2110 info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j;
2111 info->valid_mlo_link_id[j] = 1;
2112
2113 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n",
2114 info->hw_link_id[j]);
2115
2116 hw_link_id++;
2117 }
2118 }
2119
2120 if (hw_link_id <= 0)
2121 ag->mlo_capable = false;
2122
2123 req->mlo_chip_info_valid = 1;
2124
2125 mutex_unlock(&ag->mutex);
2126
2127 return 0;
2128
2129 device_cleanup:
2130 for (i = i - 1; i >= 0; i--) {
2131 info = &req->mlo_chip_info[i];
2132
2133 memset(info, 0, sizeof(*info));
2134 }
2135
2136 req->mlo_num_chips = 0;
2137 req->mlo_num_chips_valid = 0;
2138
2139 req->max_mlo_peer = 0;
2140 req->max_mlo_peer_valid = 0;
2141 req->mlo_group_id = 0;
2142 req->mlo_group_id_valid = 0;
2143 req->mlo_chip_id = 0;
2144 req->mlo_chip_id_valid = 0;
2145 req->mlo_capable = 0;
2146 req->mlo_capable_valid = 0;
2147
2148 ag->mlo_capable = false;
2149
2150 mutex_unlock(&ag->mutex);
2151
2152 return ret;
2153 }
2154
2155 /* clang stack usage explodes if this is inlined */
2156 static noinline_for_stack
ath12k_qmi_host_cap_send(struct ath12k_base * ab)2157 int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
2158 {
2159 struct qmi_wlanfw_host_cap_req_msg_v01 req = {};
2160 struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {};
2161 struct qmi_txn txn;
2162 int ret = 0;
2163
2164 req.num_clients_valid = 1;
2165 req.num_clients = 1;
2166 req.mem_cfg_mode = ab->qmi.target_mem_mode;
2167 req.mem_cfg_mode_valid = 1;
2168 req.bdf_support_valid = 1;
2169 req.bdf_support = 1;
2170
2171 req.m3_support_valid = 1;
2172 req.m3_support = 1;
2173 req.m3_cache_support_valid = 1;
2174 req.m3_cache_support = 1;
2175
2176 req.cal_done_valid = 1;
2177 req.cal_done = ab->qmi.cal_done;
2178
2179 if (ab->hw_params->qmi_cnss_feature_bitmap) {
2180 req.feature_list_valid = 1;
2181 req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap;
2182 }
2183
2184 /* BRINGUP: here we are piggybacking a lot of stuff using
2185 * internal_sleep_clock, should it be split?
2186 */
2187 if (ab->hw_params->internal_sleep_clock) {
2188 req.nm_modem_valid = 1;
2189
2190 /* Notify firmware that this is non-qualcomm platform. */
2191 req.nm_modem |= HOST_CSTATE_BIT;
2192
2193 /* Notify firmware about the sleep clock selection,
2194 * nm_modem_bit[1] is used for this purpose. Host driver on
2195 * non-qualcomm platforms should select internal sleep
2196 * clock.
2197 */
2198 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
2199 req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
2200 }
2201
2202 ret = ath12k_host_cap_parse_mlo(ab, &req);
2203 if (ret < 0)
2204 goto out;
2205
2206 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2207 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
2208 if (ret < 0)
2209 goto out;
2210
2211 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2212 QMI_WLANFW_HOST_CAP_REQ_V01,
2213 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
2214 qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
2215 if (ret < 0) {
2216 qmi_txn_cancel(&txn);
2217 ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
2218 goto out;
2219 }
2220
2221 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2222 if (ret < 0)
2223 goto out;
2224
2225 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2226 ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
2227 resp.resp.result, resp.resp.error);
2228 ret = -EINVAL;
2229 goto out;
2230 }
2231
2232 out:
2233 return ret;
2234 }
2235
ath12k_qmi_phy_cap_send(struct ath12k_base * ab)2236 static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
2237 {
2238 struct qmi_wlanfw_phy_cap_req_msg_v01 req = {};
2239 struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {};
2240 struct qmi_txn txn;
2241 int ret;
2242
2243 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2244 qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp);
2245 if (ret < 0)
2246 goto out;
2247
2248 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2249 QMI_WLANFW_PHY_CAP_REQ_V01,
2250 QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN,
2251 qmi_wlanfw_phy_cap_req_msg_v01_ei, &req);
2252 if (ret < 0) {
2253 qmi_txn_cancel(&txn);
2254 ath12k_warn(ab, "failed to send phy capability request: %d\n", ret);
2255 goto out;
2256 }
2257
2258 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2259 if (ret < 0)
2260 goto out;
2261
2262 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2263 ret = -EOPNOTSUPP;
2264 goto out;
2265 }
2266
2267 if (!resp.num_phy_valid) {
2268 ret = -ENODATA;
2269 goto out;
2270 }
2271
2272 ab->qmi.num_radios = resp.num_phy;
2273
2274 ath12k_dbg(ab, ATH12K_DBG_QMI,
2275 "phy capability resp valid %d num_phy %d valid %d board_id %d\n",
2276 resp.num_phy_valid, resp.num_phy,
2277 resp.board_id_valid, resp.board_id);
2278
2279 return;
2280
2281 out:
2282 /* If PHY capability not advertised then rely on default num link */
2283 ab->qmi.num_radios = ab->hw_params->def_num_link;
2284
2285 ath12k_dbg(ab, ATH12K_DBG_QMI,
2286 "no valid response from PHY capability, choose default num_phy %d\n",
2287 ab->qmi.num_radios);
2288 }
2289
ath12k_qmi_fw_ind_register_send(struct ath12k_base * ab)2290 static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
2291 {
2292 struct qmi_wlanfw_ind_register_req_msg_v01 *req;
2293 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
2294 struct qmi_handle *handle = &ab->qmi.handle;
2295 struct qmi_txn txn;
2296 int ret;
2297
2298 req = kzalloc(sizeof(*req), GFP_KERNEL);
2299 if (!req)
2300 return -ENOMEM;
2301
2302 resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2303 if (!resp) {
2304 ret = -ENOMEM;
2305 goto resp_out;
2306 }
2307
2308 req->client_id_valid = 1;
2309 req->client_id = QMI_WLANFW_CLIENT_ID;
2310 req->fw_ready_enable_valid = 1;
2311 req->fw_ready_enable = 1;
2312 req->request_mem_enable_valid = 1;
2313 req->request_mem_enable = 1;
2314 req->fw_mem_ready_enable_valid = 1;
2315 req->fw_mem_ready_enable = 1;
2316 req->cal_done_enable_valid = 1;
2317 req->cal_done_enable = 1;
2318 req->fw_init_done_enable_valid = 1;
2319 req->fw_init_done_enable = 1;
2320
2321 req->pin_connect_result_enable_valid = 0;
2322 req->pin_connect_result_enable = 0;
2323
2324 ret = qmi_txn_init(handle, &txn,
2325 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
2326 if (ret < 0)
2327 goto out;
2328
2329 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2330 QMI_WLANFW_IND_REGISTER_REQ_V01,
2331 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
2332 qmi_wlanfw_ind_register_req_msg_v01_ei, req);
2333 if (ret < 0) {
2334 qmi_txn_cancel(&txn);
2335 ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
2336 ret);
2337 goto out;
2338 }
2339
2340 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2341 if (ret < 0) {
2342 ath12k_warn(ab, "failed to register fw indication %d\n", ret);
2343 goto out;
2344 }
2345
2346 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2347 ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
2348 resp->resp.result, resp->resp.error);
2349 ret = -EINVAL;
2350 goto out;
2351 }
2352
2353 out:
2354 kfree(resp);
2355 resp_out:
2356 kfree(req);
2357 return ret;
2358 }
2359
2360 /* clang stack usage explodes if this is inlined */
2361 static noinline_for_stack
ath12k_qmi_respond_fw_mem_request(struct ath12k_base * ab)2362 int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
2363 {
2364 struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
2365 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {};
2366 struct qmi_txn txn;
2367 int ret = 0, i;
2368 bool delayed;
2369
2370 req = kzalloc(sizeof(*req), GFP_KERNEL);
2371 if (!req)
2372 return -ENOMEM;
2373
2374 /* Some targets by default request a block of big contiguous
2375 * DMA memory, it's hard to allocate from kernel. So host returns
2376 * failure to firmware and firmware then request multiple blocks of
2377 * small chunk size memory.
2378 */
2379 if (ab->qmi.target_mem_delayed) {
2380 delayed = true;
2381 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
2382 ab->qmi.mem_seg_count);
2383 } else {
2384 delayed = false;
2385 req->mem_seg_len = ab->qmi.mem_seg_count;
2386 for (i = 0; i < req->mem_seg_len ; i++) {
2387 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
2388 req->mem_seg[i].size = ab->qmi.target_mem[i].size;
2389 req->mem_seg[i].type = ab->qmi.target_mem[i].type;
2390 ath12k_dbg(ab, ATH12K_DBG_QMI,
2391 "qmi req mem_seg[%d] %pad %u %u\n", i,
2392 &ab->qmi.target_mem[i].paddr,
2393 ab->qmi.target_mem[i].size,
2394 ab->qmi.target_mem[i].type);
2395 }
2396 }
2397
2398 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2399 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
2400 if (ret < 0)
2401 goto out;
2402
2403 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2404 QMI_WLANFW_RESPOND_MEM_REQ_V01,
2405 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
2406 qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
2407 if (ret < 0) {
2408 qmi_txn_cancel(&txn);
2409 ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
2410 ret);
2411 goto out;
2412 }
2413
2414 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2415 if (ret < 0) {
2416 ath12k_warn(ab, "qmi failed memory request, err = %d\n", ret);
2417 goto out;
2418 }
2419
2420 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2421 /* the error response is expected when
2422 * target_mem_delayed is true.
2423 */
2424 if (delayed && resp.resp.error == 0)
2425 goto out;
2426
2427 ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
2428 resp.resp.result, resp.resp.error);
2429 ret = -EINVAL;
2430 goto out;
2431 }
2432 out:
2433 kfree(req);
2434 return ret;
2435 }
2436
ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk,int idx)2437 static void ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base *ab,
2438 struct target_mem_chunk *chunk,
2439 int idx)
2440 {
2441 struct ath12k_hw_group *ag = ab->ag;
2442 struct target_mem_chunk *mlo_chunk;
2443
2444 lockdep_assert_held(&ag->mutex);
2445
2446 if (!ag->mlo_mem.init_done || ag->num_started)
2447 return;
2448
2449 if (idx >= ARRAY_SIZE(ag->mlo_mem.chunk)) {
2450 ath12k_warn(ab, "invalid index for MLO memory chunk free: %d\n", idx);
2451 return;
2452 }
2453
2454 mlo_chunk = &ag->mlo_mem.chunk[idx];
2455 if (mlo_chunk->v.addr) {
2456 dma_free_coherent(ab->dev,
2457 mlo_chunk->size,
2458 mlo_chunk->v.addr,
2459 mlo_chunk->paddr);
2460 mlo_chunk->v.addr = NULL;
2461 }
2462
2463 mlo_chunk->paddr = 0;
2464 mlo_chunk->size = 0;
2465 chunk->v.addr = NULL;
2466 chunk->paddr = 0;
2467 chunk->size = 0;
2468 }
2469
ath12k_qmi_free_target_mem_chunk(struct ath12k_base * ab)2470 static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
2471 {
2472 struct ath12k_hw_group *ag = ab->ag;
2473 int i, mlo_idx;
2474
2475 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2476 if (!ab->qmi.target_mem[i].v.addr)
2477 continue;
2478
2479 if (ab->qmi.target_mem[i].type == MLO_GLOBAL_MEM_REGION_TYPE) {
2480 ath12k_qmi_free_mlo_mem_chunk(ab,
2481 &ab->qmi.target_mem[i],
2482 mlo_idx++);
2483 } else {
2484 dma_free_coherent(ab->dev,
2485 ab->qmi.target_mem[i].prev_size,
2486 ab->qmi.target_mem[i].v.addr,
2487 ab->qmi.target_mem[i].paddr);
2488 ab->qmi.target_mem[i].v.addr = NULL;
2489 }
2490 }
2491
2492 if (!ag->num_started && ag->mlo_mem.init_done) {
2493 ag->mlo_mem.init_done = false;
2494 ag->mlo_mem.mlo_mem_size = 0;
2495 }
2496 }
2497
ath12k_qmi_alloc_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk)2498 static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
2499 struct target_mem_chunk *chunk)
2500 {
2501 /* Firmware reloads in recovery/resume.
2502 * In such cases, no need to allocate memory for FW again.
2503 */
2504 if (chunk->v.addr) {
2505 if (chunk->prev_type == chunk->type &&
2506 chunk->prev_size == chunk->size)
2507 goto this_chunk_done;
2508
2509 /* cannot reuse the existing chunk */
2510 dma_free_coherent(ab->dev, chunk->prev_size,
2511 chunk->v.addr, chunk->paddr);
2512 chunk->v.addr = NULL;
2513 }
2514
2515 chunk->v.addr = dma_alloc_coherent(ab->dev,
2516 chunk->size,
2517 &chunk->paddr,
2518 GFP_KERNEL | __GFP_NOWARN);
2519 if (!chunk->v.addr) {
2520 if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
2521 ab->qmi.target_mem_delayed = true;
2522 ath12k_warn(ab,
2523 "qmi dma allocation failed (%d B type %u), will try later with small size\n",
2524 chunk->size,
2525 chunk->type);
2526 ath12k_qmi_free_target_mem_chunk(ab);
2527 return -EAGAIN;
2528 }
2529 ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
2530 chunk->type, chunk->size);
2531 return -ENOMEM;
2532 }
2533 chunk->prev_type = chunk->type;
2534 chunk->prev_size = chunk->size;
2535 this_chunk_done:
2536 return 0;
2537 }
2538
ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base * ab)2539 static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
2540 {
2541 struct target_mem_chunk *chunk, *mlo_chunk;
2542 struct ath12k_hw_group *ag = ab->ag;
2543 int i, mlo_idx, ret;
2544 int mlo_size = 0;
2545
2546 mutex_lock(&ag->mutex);
2547
2548 if (!ag->mlo_mem.init_done) {
2549 memset(ag->mlo_mem.chunk, 0, sizeof(ag->mlo_mem.chunk));
2550 ag->mlo_mem.init_done = true;
2551 }
2552
2553 ab->qmi.target_mem_delayed = false;
2554
2555 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2556 chunk = &ab->qmi.target_mem[i];
2557
2558 /* Allocate memory for the region and the functionality supported
2559 * on the host. For the non-supported memory region, host does not
2560 * allocate memory, assigns NULL and FW will handle this without crashing.
2561 */
2562 switch (chunk->type) {
2563 case HOST_DDR_REGION_TYPE:
2564 case M3_DUMP_REGION_TYPE:
2565 case PAGEABLE_MEM_REGION_TYPE:
2566 case CALDB_MEM_REGION_TYPE:
2567 ret = ath12k_qmi_alloc_chunk(ab, chunk);
2568 if (ret)
2569 goto err;
2570 break;
2571 case MLO_GLOBAL_MEM_REGION_TYPE:
2572 mlo_size += chunk->size;
2573 if (ag->mlo_mem.mlo_mem_size &&
2574 mlo_size > ag->mlo_mem.mlo_mem_size) {
2575 ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d",
2576 mlo_size, ag->mlo_mem.mlo_mem_size);
2577 ret = -EINVAL;
2578 goto err;
2579 }
2580
2581 mlo_chunk = &ag->mlo_mem.chunk[mlo_idx];
2582 if (mlo_chunk->paddr) {
2583 if (chunk->size != mlo_chunk->size) {
2584 ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d",
2585 mlo_idx, chunk->size, mlo_chunk->size);
2586 ret = -EINVAL;
2587 goto err;
2588 }
2589 } else {
2590 mlo_chunk->size = chunk->size;
2591 mlo_chunk->type = chunk->type;
2592 ret = ath12k_qmi_alloc_chunk(ab, mlo_chunk);
2593 if (ret)
2594 goto err;
2595 memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2596 }
2597
2598 chunk->paddr = mlo_chunk->paddr;
2599 chunk->v.addr = mlo_chunk->v.addr;
2600 mlo_idx++;
2601
2602 break;
2603 default:
2604 ath12k_warn(ab, "memory type %u not supported\n",
2605 chunk->type);
2606 chunk->paddr = 0;
2607 chunk->v.addr = NULL;
2608 break;
2609 }
2610 }
2611
2612 if (!ag->mlo_mem.mlo_mem_size) {
2613 ag->mlo_mem.mlo_mem_size = mlo_size;
2614 } else if (ag->mlo_mem.mlo_mem_size != mlo_size) {
2615 ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d",
2616 ag->mlo_mem.mlo_mem_size, mlo_size);
2617 ret = -EINVAL;
2618 goto err;
2619 }
2620
2621 mutex_unlock(&ag->mutex);
2622
2623 return 0;
2624
2625 err:
2626 ath12k_qmi_free_target_mem_chunk(ab);
2627
2628 mutex_unlock(&ag->mutex);
2629
2630 /* The firmware will attempt to request memory in smaller chunks
2631 * on the next try. However, the current caller should be notified
2632 * that this instance of request parsing was successful.
2633 * Therefore, return 0 only.
2634 */
2635 if (ret == -EAGAIN)
2636 ret = 0;
2637
2638 return ret;
2639 }
2640
2641 /* clang stack usage explodes if this is inlined */
2642 static noinline_for_stack
ath12k_qmi_request_target_cap(struct ath12k_base * ab)2643 int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
2644 {
2645 struct qmi_wlanfw_cap_req_msg_v01 req = {};
2646 struct qmi_wlanfw_cap_resp_msg_v01 resp = {};
2647 struct qmi_txn txn;
2648 unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
2649 int ret = 0;
2650 int r;
2651 int i;
2652
2653 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2654 qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
2655 if (ret < 0)
2656 goto out;
2657
2658 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2659 QMI_WLANFW_CAP_REQ_V01,
2660 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
2661 qmi_wlanfw_cap_req_msg_v01_ei, &req);
2662 if (ret < 0) {
2663 qmi_txn_cancel(&txn);
2664 ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
2665 ret);
2666 goto out;
2667 }
2668
2669 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2670 if (ret < 0) {
2671 ath12k_warn(ab, "qmi failed target cap request %d\n", ret);
2672 goto out;
2673 }
2674
2675 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2676 ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
2677 resp.resp.result, resp.resp.error);
2678 ret = -EINVAL;
2679 goto out;
2680 }
2681
2682 if (resp.chip_info_valid) {
2683 ab->qmi.target.chip_id = resp.chip_info.chip_id;
2684 ab->qmi.target.chip_family = resp.chip_info.chip_family;
2685 }
2686
2687 if (resp.board_info_valid)
2688 ab->qmi.target.board_id = resp.board_info.board_id;
2689 else
2690 ab->qmi.target.board_id = board_id;
2691
2692 if (resp.soc_info_valid)
2693 ab->qmi.target.soc_id = resp.soc_info.soc_id;
2694
2695 if (resp.fw_version_info_valid) {
2696 ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
2697 strscpy(ab->qmi.target.fw_build_timestamp,
2698 resp.fw_version_info.fw_build_timestamp,
2699 sizeof(ab->qmi.target.fw_build_timestamp));
2700 }
2701
2702 if (resp.fw_build_id_valid)
2703 strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
2704 sizeof(ab->qmi.target.fw_build_id));
2705
2706 if (resp.dev_mem_info_valid) {
2707 for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) {
2708 ab->qmi.dev_mem[i].start =
2709 resp.dev_mem[i].start;
2710 ab->qmi.dev_mem[i].size =
2711 resp.dev_mem[i].size;
2712 ath12k_dbg(ab, ATH12K_DBG_QMI,
2713 "devmem [%d] start 0x%llx size %llu\n", i,
2714 ab->qmi.dev_mem[i].start,
2715 ab->qmi.dev_mem[i].size);
2716 }
2717 }
2718
2719 if (resp.eeprom_caldata_read_timeout_valid) {
2720 ab->qmi.target.eeprom_caldata = resp.eeprom_caldata_read_timeout;
2721 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi cal data supported from eeprom\n");
2722 }
2723
2724 ath12k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
2725 ab->qmi.target.chip_id, ab->qmi.target.chip_family,
2726 ab->qmi.target.board_id, ab->qmi.target.soc_id);
2727
2728 ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
2729 ab->qmi.target.fw_version,
2730 ab->qmi.target.fw_build_timestamp,
2731 ab->qmi.target.fw_build_id);
2732
2733 r = ath12k_core_check_smbios(ab);
2734 if (r)
2735 ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
2736
2737 r = ath12k_acpi_start(ab);
2738 if (r)
2739 /* ACPI is optional so continue in case of an error */
2740 ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", r);
2741
2742 r = ath12k_acpi_check_bdf_variant_name(ab);
2743 if (r)
2744 ath12k_dbg(ab, ATH12K_DBG_BOOT, "ACPI bdf variant name not set.\n");
2745
2746 out:
2747 return ret;
2748 }
2749
ath12k_qmi_load_file_target_mem(struct ath12k_base * ab,const u8 * data,u32 len,u8 type)2750 static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
2751 const u8 *data, u32 len, u8 type)
2752 {
2753 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2754 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
2755 struct qmi_txn txn;
2756 const u8 *temp = data;
2757 int ret = 0;
2758 u32 remaining = len;
2759
2760 req = kzalloc(sizeof(*req), GFP_KERNEL);
2761 if (!req)
2762 return -ENOMEM;
2763
2764 while (remaining) {
2765 req->valid = 1;
2766 req->file_id_valid = 1;
2767 req->file_id = ab->qmi.target.board_id;
2768 req->total_size_valid = 1;
2769 req->total_size = remaining;
2770 req->seg_id_valid = 1;
2771 req->data_valid = 1;
2772 req->bdf_type = type;
2773 req->bdf_type_valid = 1;
2774 req->end_valid = 1;
2775 req->end = 0;
2776
2777 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2778 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2779 } else {
2780 req->data_len = remaining;
2781 req->end = 1;
2782 }
2783
2784 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2785 req->data_valid = 0;
2786 req->end = 1;
2787 req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2788 } else {
2789 memcpy(req->data, temp, req->data_len);
2790 }
2791
2792 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2793 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2794 &resp);
2795 if (ret < 0)
2796 goto out;
2797
2798 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
2799 type);
2800
2801 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2802 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2803 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2804 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2805 if (ret < 0) {
2806 qmi_txn_cancel(&txn);
2807 goto out;
2808 }
2809
2810 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2811 if (ret < 0)
2812 goto out;
2813
2814 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2815 ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2816 resp.resp.result, resp.resp.error);
2817 ret = -EINVAL;
2818 goto out;
2819 }
2820
2821 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2822 remaining = 0;
2823 } else {
2824 remaining -= req->data_len;
2825 temp += req->data_len;
2826 req->seg_id++;
2827 ath12k_dbg(ab, ATH12K_DBG_QMI,
2828 "qmi bdf download request remaining %i\n",
2829 remaining);
2830 }
2831 }
2832
2833 out:
2834 kfree(req);
2835 return ret;
2836 }
2837
2838 /* clang stack usage explodes if this is inlined */
2839 static noinline_for_stack
ath12k_qmi_load_bdf_qmi(struct ath12k_base * ab,enum ath12k_qmi_bdf_type type)2840 int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab,
2841 enum ath12k_qmi_bdf_type type)
2842 {
2843 struct device *dev = ab->dev;
2844 char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE];
2845 const struct firmware *fw_entry;
2846 struct ath12k_board_data bd;
2847 u32 fw_size, file_type;
2848 int ret = 0;
2849 const u8 *tmp;
2850
2851 memset(&bd, 0, sizeof(bd));
2852
2853 switch (type) {
2854 case ATH12K_QMI_BDF_TYPE_ELF:
2855 ret = ath12k_core_fetch_bdf(ab, &bd);
2856 if (ret) {
2857 ath12k_warn(ab, "qmi failed to load bdf:\n");
2858 goto out;
2859 }
2860
2861 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
2862 type = ATH12K_QMI_BDF_TYPE_ELF;
2863 else
2864 type = ATH12K_QMI_BDF_TYPE_BIN;
2865
2866 break;
2867 case ATH12K_QMI_BDF_TYPE_REGDB:
2868 ret = ath12k_core_fetch_regdb(ab, &bd);
2869 if (ret) {
2870 ath12k_warn(ab, "qmi failed to load regdb bin:\n");
2871 goto out;
2872 }
2873 break;
2874 case ATH12K_QMI_BDF_TYPE_CALIBRATION:
2875
2876 if (ab->qmi.target.eeprom_caldata) {
2877 file_type = ATH12K_QMI_FILE_TYPE_EEPROM;
2878 tmp = filename;
2879 fw_size = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2880 } else {
2881 file_type = ATH12K_QMI_FILE_TYPE_CALDATA;
2882
2883 /* cal-<bus>-<id>.bin */
2884 snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
2885 ath12k_bus_str(ab->hif.bus), dev_name(dev));
2886 fw_entry = ath12k_core_firmware_request(ab, filename);
2887 if (!IS_ERR(fw_entry))
2888 goto success;
2889
2890 fw_entry = ath12k_core_firmware_request(ab,
2891 ATH12K_DEFAULT_CAL_FILE);
2892 if (IS_ERR(fw_entry)) {
2893 ret = PTR_ERR(fw_entry);
2894 ath12k_warn(ab,
2895 "qmi failed to load CAL data file:%s\n",
2896 filename);
2897 goto out;
2898 }
2899
2900 success:
2901 fw_size = min_t(u32, ab->hw_params->fw.board_size,
2902 fw_entry->size);
2903 tmp = fw_entry->data;
2904 }
2905 ret = ath12k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
2906 if (ret < 0) {
2907 ath12k_warn(ab, "qmi failed to load caldata\n");
2908 goto out_qmi_cal;
2909 }
2910
2911 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
2912 file_type);
2913
2914 out_qmi_cal:
2915 if (!ab->qmi.target.eeprom_caldata)
2916 release_firmware(fw_entry);
2917 return ret;
2918 default:
2919 ath12k_warn(ab, "unknown file type for load %d", type);
2920 goto out;
2921 }
2922
2923 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf_type %d\n", type);
2924
2925 fw_size = min_t(u32, ab->hw_params->fw.board_size, bd.len);
2926
2927 ret = ath12k_qmi_load_file_target_mem(ab, bd.data, fw_size, type);
2928 if (ret < 0)
2929 ath12k_warn(ab, "qmi failed to load bdf file\n");
2930
2931 out:
2932 ath12k_core_free_bdf(ab, &bd);
2933 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi BDF download sequence completed\n");
2934
2935 return ret;
2936 }
2937
ath12k_qmi_m3_free(struct ath12k_base * ab)2938 static void ath12k_qmi_m3_free(struct ath12k_base *ab)
2939 {
2940 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2941
2942 if (!m3_mem->vaddr)
2943 return;
2944
2945 dma_free_coherent(ab->dev, m3_mem->size,
2946 m3_mem->vaddr, m3_mem->paddr);
2947 m3_mem->vaddr = NULL;
2948 m3_mem->size = 0;
2949 }
2950
ath12k_qmi_m3_load(struct ath12k_base * ab)2951 static int ath12k_qmi_m3_load(struct ath12k_base *ab)
2952 {
2953 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2954 const struct firmware *fw = NULL;
2955 const void *m3_data;
2956 char path[100];
2957 size_t m3_len;
2958 int ret;
2959
2960 if (ab->fw.m3_data && ab->fw.m3_len > 0) {
2961 /* firmware-N.bin had a m3 firmware file so use that */
2962 m3_data = ab->fw.m3_data;
2963 m3_len = ab->fw.m3_len;
2964 } else {
2965 /* No m3 file in firmware-N.bin so try to request old
2966 * separate m3.bin.
2967 */
2968 fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
2969 if (IS_ERR(fw)) {
2970 ret = PTR_ERR(fw);
2971 ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
2972 path, sizeof(path));
2973 ath12k_err(ab, "failed to load %s: %d\n", path, ret);
2974 return ret;
2975 }
2976
2977 m3_data = fw->data;
2978 m3_len = fw->size;
2979 }
2980
2981 /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
2982 if (m3_mem->vaddr) {
2983 if (m3_mem->size >= m3_len)
2984 goto skip_m3_alloc;
2985
2986 /* Old buffer is too small, free and reallocate */
2987 ath12k_qmi_m3_free(ab);
2988 }
2989
2990 m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2991 m3_len, &m3_mem->paddr,
2992 GFP_KERNEL);
2993 if (!m3_mem->vaddr) {
2994 ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2995 fw->size);
2996 ret = -ENOMEM;
2997 goto out;
2998 }
2999
3000 skip_m3_alloc:
3001 memcpy(m3_mem->vaddr, m3_data, m3_len);
3002 m3_mem->size = m3_len;
3003
3004 ret = 0;
3005
3006 out:
3007 release_firmware(fw);
3008
3009 return ret;
3010 }
3011
3012 /* clang stack usage explodes if this is inlined */
3013 static noinline_for_stack
ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base * ab)3014 int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
3015 {
3016 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3017 struct qmi_wlanfw_m3_info_req_msg_v01 req = {};
3018 struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {};
3019 struct qmi_txn txn;
3020 int ret = 0;
3021
3022 ret = ath12k_qmi_m3_load(ab);
3023 if (ret) {
3024 ath12k_err(ab, "failed to load m3 firmware: %d", ret);
3025 return ret;
3026 }
3027
3028 req.addr = m3_mem->paddr;
3029 req.size = m3_mem->size;
3030
3031 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3032 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
3033 if (ret < 0)
3034 goto out;
3035
3036 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3037 QMI_WLANFW_M3_INFO_REQ_V01,
3038 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
3039 qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
3040 if (ret < 0) {
3041 qmi_txn_cancel(&txn);
3042 ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
3043 ret);
3044 goto out;
3045 }
3046
3047 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3048 if (ret < 0) {
3049 ath12k_warn(ab, "qmi failed M3 information request %d\n", ret);
3050 goto out;
3051 }
3052
3053 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3054 ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
3055 resp.resp.result, resp.resp.error);
3056 ret = -EINVAL;
3057 goto out;
3058 }
3059 out:
3060 return ret;
3061 }
3062
ath12k_qmi_wlanfw_mode_send(struct ath12k_base * ab,u32 mode)3063 static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
3064 u32 mode)
3065 {
3066 struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {};
3067 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {};
3068 struct qmi_txn txn;
3069 int ret = 0;
3070
3071 req.mode = mode;
3072 req.hw_debug_valid = 1;
3073 req.hw_debug = 0;
3074
3075 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3076 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
3077 if (ret < 0)
3078 goto out;
3079
3080 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3081 QMI_WLANFW_WLAN_MODE_REQ_V01,
3082 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
3083 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
3084 if (ret < 0) {
3085 qmi_txn_cancel(&txn);
3086 ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
3087 mode, ret);
3088 goto out;
3089 }
3090
3091 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3092 if (ret < 0) {
3093 if (mode == ATH12K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
3094 ath12k_warn(ab, "WLFW service is dis-connected\n");
3095 return 0;
3096 }
3097 ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
3098 mode, ret);
3099 goto out;
3100 }
3101
3102 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3103 ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
3104 mode, resp.resp.result, resp.resp.error);
3105 ret = -EINVAL;
3106 goto out;
3107 }
3108
3109 out:
3110 return ret;
3111 }
3112
ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base * ab)3113 static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
3114 {
3115 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
3116 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {};
3117 struct ce_pipe_config *ce_cfg;
3118 struct service_to_pipe *svc_cfg;
3119 struct qmi_txn txn;
3120 int ret = 0, pipe_num;
3121
3122 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
3123 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
3124
3125 req = kzalloc(sizeof(*req), GFP_KERNEL);
3126 if (!req)
3127 return -ENOMEM;
3128
3129 req->host_version_valid = 1;
3130 strscpy(req->host_version, ATH12K_HOST_VERSION_STRING,
3131 sizeof(req->host_version));
3132
3133 req->tgt_cfg_valid = 1;
3134 /* This is number of CE configs */
3135 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
3136 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
3137 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
3138 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
3139 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
3140 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
3141 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
3142 }
3143
3144 req->svc_cfg_valid = 1;
3145 /* This is number of Service/CE configs */
3146 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
3147 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
3148 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
3149 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
3150 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
3151 }
3152
3153 /* set shadow v3 configuration */
3154 if (ab->hw_params->supports_shadow_regs) {
3155 req->shadow_reg_v3_valid = 1;
3156 req->shadow_reg_v3_len = min_t(u32,
3157 ab->qmi.ce_cfg.shadow_reg_v3_len,
3158 QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01);
3159 memcpy(&req->shadow_reg_v3, ab->qmi.ce_cfg.shadow_reg_v3,
3160 sizeof(u32) * req->shadow_reg_v3_len);
3161 } else {
3162 req->shadow_reg_v3_valid = 0;
3163 }
3164
3165 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3166 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
3167 if (ret < 0)
3168 goto out;
3169
3170 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3171 QMI_WLANFW_WLAN_CFG_REQ_V01,
3172 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
3173 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
3174 if (ret < 0) {
3175 qmi_txn_cancel(&txn);
3176 ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
3177 ret);
3178 goto out;
3179 }
3180
3181 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3182 if (ret < 0) {
3183 ath12k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
3184 goto out;
3185 }
3186
3187 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3188 ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
3189 resp.resp.result, resp.resp.error);
3190 ret = -EINVAL;
3191 goto out;
3192 }
3193
3194 out:
3195 kfree(req);
3196 return ret;
3197 }
3198
ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base * ab)3199 static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
3200 {
3201 struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
3202 struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
3203 struct qmi_txn txn;
3204 int ret;
3205
3206 req.enable_fwlog_valid = true;
3207 req.enable_fwlog = 1;
3208
3209 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3210 qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
3211 if (ret < 0)
3212 goto out;
3213
3214 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3215 ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01,
3216 QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
3217 qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
3218 if (ret < 0) {
3219 qmi_txn_cancel(&txn);
3220 ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n",
3221 ret);
3222 goto out;
3223 }
3224
3225 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3226 if (ret < 0) {
3227 ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret);
3228 goto out;
3229 }
3230
3231 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3232 ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
3233 resp.resp.result, resp.resp.error);
3234 ret = -EINVAL;
3235 goto out;
3236 }
3237
3238 out:
3239 return ret;
3240 }
3241
ath12k_qmi_firmware_stop(struct ath12k_base * ab)3242 void ath12k_qmi_firmware_stop(struct ath12k_base *ab)
3243 {
3244 int ret;
3245
3246 clear_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags);
3247
3248 ret = ath12k_qmi_wlanfw_mode_send(ab, ATH12K_FIRMWARE_MODE_OFF);
3249 if (ret < 0) {
3250 ath12k_warn(ab, "qmi failed to send wlan mode off\n");
3251 return;
3252 }
3253 }
3254
ath12k_qmi_firmware_start(struct ath12k_base * ab,u32 mode)3255 int ath12k_qmi_firmware_start(struct ath12k_base *ab,
3256 u32 mode)
3257 {
3258 int ret;
3259
3260 ret = ath12k_qmi_wlanfw_wlan_ini_send(ab);
3261 if (ret < 0) {
3262 ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret);
3263 return ret;
3264 }
3265
3266 ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab);
3267 if (ret < 0) {
3268 ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
3269 return ret;
3270 }
3271
3272 ret = ath12k_qmi_wlanfw_mode_send(ab, mode);
3273 if (ret < 0) {
3274 ath12k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
3275 return ret;
3276 }
3277
3278 return 0;
3279 }
3280
3281 static int
ath12k_qmi_driver_event_post(struct ath12k_qmi * qmi,enum ath12k_qmi_event_type type,void * data)3282 ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi,
3283 enum ath12k_qmi_event_type type,
3284 void *data)
3285 {
3286 struct ath12k_qmi_driver_event *event;
3287
3288 event = kzalloc(sizeof(*event), GFP_ATOMIC);
3289 if (!event)
3290 return -ENOMEM;
3291
3292 event->type = type;
3293 event->data = data;
3294
3295 spin_lock(&qmi->event_lock);
3296 list_add_tail(&event->list, &qmi->event_list);
3297 spin_unlock(&qmi->event_lock);
3298
3299 queue_work(qmi->event_wq, &qmi->event_work);
3300
3301 return 0;
3302 }
3303
ath12k_qmi_trigger_host_cap(struct ath12k_base * ab)3304 void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab)
3305 {
3306 struct ath12k_qmi *qmi = &ab->qmi;
3307
3308 spin_lock(&qmi->event_lock);
3309
3310 if (ath12k_qmi_get_event_block(qmi))
3311 ath12k_qmi_set_event_block(qmi, false);
3312
3313 spin_unlock(&qmi->event_lock);
3314
3315 ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n",
3316 ab->device_id);
3317
3318 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL);
3319 }
3320
ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group * ag)3321 static bool ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group *ag)
3322 {
3323 struct ath12k_base *ab;
3324 int i;
3325
3326 for (i = 0; i < ag->num_devices; i++) {
3327 ab = ag->ab[i];
3328
3329 if (!(ab && ab->qmi.num_radios != U8_MAX))
3330 return false;
3331 }
3332
3333 return true;
3334 }
3335
ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group * ag)3336 static struct ath12k_base *ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group *ag)
3337 {
3338 struct ath12k_base *ab;
3339 int i;
3340
3341 lockdep_assert_held(&ag->mutex);
3342
3343 for (i = 0; i < ag->num_devices; i++) {
3344 ab = ag->ab[i];
3345 if (!ab)
3346 continue;
3347
3348 spin_lock(&ab->qmi.event_lock);
3349
3350 if (ath12k_qmi_get_event_block(&ab->qmi)) {
3351 spin_unlock(&ab->qmi.event_lock);
3352 return ab;
3353 }
3354
3355 spin_unlock(&ab->qmi.event_lock);
3356 }
3357
3358 return NULL;
3359 }
3360
3361 /* clang stack usage explodes if this is inlined */
3362 static noinline_for_stack
ath12k_qmi_event_server_arrive(struct ath12k_qmi * qmi)3363 int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi)
3364 {
3365 struct ath12k_base *ab = qmi->ab, *block_ab;
3366 struct ath12k_hw_group *ag = ab->ag;
3367 int ret;
3368
3369 ath12k_qmi_phy_cap_send(ab);
3370
3371 ret = ath12k_qmi_fw_ind_register_send(ab);
3372 if (ret < 0) {
3373 ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
3374 return ret;
3375 }
3376
3377 spin_lock(&qmi->event_lock);
3378
3379 ath12k_qmi_set_event_block(qmi, true);
3380
3381 spin_unlock(&qmi->event_lock);
3382
3383 mutex_lock(&ag->mutex);
3384
3385 if (ath12k_qmi_hw_group_host_cap_ready(ag)) {
3386 ath12k_core_hw_group_set_mlo_capable(ag);
3387
3388 block_ab = ath12k_qmi_hw_group_find_blocked(ag);
3389 if (block_ab)
3390 ath12k_qmi_trigger_host_cap(block_ab);
3391 }
3392
3393 mutex_unlock(&ag->mutex);
3394
3395 return ret;
3396 }
3397
3398 /* clang stack usage explodes if this is inlined */
3399 static noinline_for_stack
ath12k_qmi_event_mem_request(struct ath12k_qmi * qmi)3400 int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi)
3401 {
3402 struct ath12k_base *ab = qmi->ab;
3403 int ret;
3404
3405 ret = ath12k_qmi_respond_fw_mem_request(ab);
3406 if (ret < 0) {
3407 ath12k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
3408 return ret;
3409 }
3410
3411 return ret;
3412 }
3413
3414 /* clang stack usage explodes if this is inlined */
3415 static noinline_for_stack
ath12k_qmi_event_load_bdf(struct ath12k_qmi * qmi)3416 int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
3417 {
3418 struct ath12k_base *ab = qmi->ab;
3419 int ret;
3420
3421 ret = ath12k_qmi_request_target_cap(ab);
3422 if (ret < 0) {
3423 ath12k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
3424 return ret;
3425 }
3426
3427 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_REGDB);
3428 if (ret < 0) {
3429 ath12k_warn(ab, "qmi failed to load regdb file:%d\n", ret);
3430 return ret;
3431 }
3432
3433 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_ELF);
3434 if (ret < 0) {
3435 ath12k_warn(ab, "qmi failed to load board data file:%d\n", ret);
3436 return ret;
3437 }
3438
3439 if (ab->hw_params->download_calib) {
3440 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION);
3441 if (ret < 0)
3442 ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret);
3443 }
3444
3445 ret = ath12k_qmi_wlanfw_m3_info_send(ab);
3446 if (ret < 0) {
3447 ath12k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
3448 return ret;
3449 }
3450
3451 return ret;
3452 }
3453
ath12k_qmi_msg_mem_request_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * data)3454 static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
3455 struct sockaddr_qrtr *sq,
3456 struct qmi_txn *txn,
3457 const void *data)
3458 {
3459 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3460 struct ath12k_base *ab = qmi->ab;
3461 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
3462 int i, ret;
3463
3464 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware request memory request\n");
3465
3466 if (msg->mem_seg_len == 0 ||
3467 msg->mem_seg_len > ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
3468 ath12k_warn(ab, "Invalid memory segment length: %u\n",
3469 msg->mem_seg_len);
3470
3471 ab->qmi.mem_seg_count = msg->mem_seg_len;
3472
3473 for (i = 0; i < qmi->mem_seg_count ; i++) {
3474 ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
3475 ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
3476 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n",
3477 msg->mem_seg[i].type, msg->mem_seg[i].size);
3478 }
3479
3480 ret = ath12k_qmi_alloc_target_mem_chunk(ab);
3481 if (ret) {
3482 ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
3483 ret);
3484 return;
3485 }
3486
3487 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL);
3488 }
3489
ath12k_qmi_msg_mem_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3490 static void ath12k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
3491 struct sockaddr_qrtr *sq,
3492 struct qmi_txn *txn,
3493 const void *decoded)
3494 {
3495 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3496 struct ath12k_base *ab = qmi->ab;
3497
3498 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware memory ready indication\n");
3499 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_MEM_READY, NULL);
3500 }
3501
ath12k_qmi_msg_fw_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3502 static void ath12k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
3503 struct sockaddr_qrtr *sq,
3504 struct qmi_txn *txn,
3505 const void *decoded)
3506 {
3507 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3508 struct ath12k_base *ab = qmi->ab;
3509
3510 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware ready\n");
3511 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_READY, NULL);
3512 }
3513
3514 static const struct qmi_msg_handler ath12k_qmi_msg_handlers[] = {
3515 {
3516 .type = QMI_INDICATION,
3517 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
3518 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
3519 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
3520 .fn = ath12k_qmi_msg_mem_request_cb,
3521 },
3522 {
3523 .type = QMI_INDICATION,
3524 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
3525 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
3526 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
3527 .fn = ath12k_qmi_msg_mem_ready_cb,
3528 },
3529 {
3530 .type = QMI_INDICATION,
3531 .msg_id = QMI_WLFW_FW_READY_IND_V01,
3532 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
3533 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
3534 .fn = ath12k_qmi_msg_fw_ready_cb,
3535 },
3536
3537 /* end of list */
3538 {},
3539 };
3540
ath12k_qmi_ops_new_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3541 static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
3542 struct qmi_service *service)
3543 {
3544 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3545 struct ath12k_base *ab = qmi->ab;
3546 struct sockaddr_qrtr *sq = &qmi->sq;
3547 int ret;
3548
3549 sq->sq_family = AF_QIPCRTR;
3550 sq->sq_node = service->node;
3551 sq->sq_port = service->port;
3552
3553 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
3554 sizeof(*sq), 0);
3555 if (ret) {
3556 ath12k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
3557 return ret;
3558 }
3559
3560 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw qmi service connected\n");
3561 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_ARRIVE, NULL);
3562
3563 return ret;
3564 }
3565
ath12k_qmi_ops_del_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3566 static void ath12k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
3567 struct qmi_service *service)
3568 {
3569 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3570 struct ath12k_base *ab = qmi->ab;
3571
3572 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw del server\n");
3573 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_EXIT, NULL);
3574 }
3575
3576 static const struct qmi_ops ath12k_qmi_ops = {
3577 .new_server = ath12k_qmi_ops_new_server,
3578 .del_server = ath12k_qmi_ops_del_server,
3579 };
3580
ath12k_qmi_event_host_cap(struct ath12k_qmi * qmi)3581 static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi)
3582 {
3583 struct ath12k_base *ab = qmi->ab;
3584 int ret;
3585
3586 ret = ath12k_qmi_host_cap_send(ab);
3587 if (ret < 0) {
3588 ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n",
3589 ab->device_id, ret);
3590 return ret;
3591 }
3592
3593 return ret;
3594 }
3595
ath12k_qmi_driver_event_work(struct work_struct * work)3596 static void ath12k_qmi_driver_event_work(struct work_struct *work)
3597 {
3598 struct ath12k_qmi *qmi = container_of(work, struct ath12k_qmi,
3599 event_work);
3600 struct ath12k_qmi_driver_event *event;
3601 struct ath12k_base *ab = qmi->ab;
3602 int ret;
3603
3604 spin_lock(&qmi->event_lock);
3605 while (!list_empty(&qmi->event_list)) {
3606 event = list_first_entry(&qmi->event_list,
3607 struct ath12k_qmi_driver_event, list);
3608 list_del(&event->list);
3609 spin_unlock(&qmi->event_lock);
3610
3611 if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
3612 goto skip;
3613
3614 switch (event->type) {
3615 case ATH12K_QMI_EVENT_SERVER_ARRIVE:
3616 ret = ath12k_qmi_event_server_arrive(qmi);
3617 if (ret < 0)
3618 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3619 break;
3620 case ATH12K_QMI_EVENT_SERVER_EXIT:
3621 set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
3622 break;
3623 case ATH12K_QMI_EVENT_REQUEST_MEM:
3624 ret = ath12k_qmi_event_mem_request(qmi);
3625 if (ret < 0)
3626 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3627 break;
3628 case ATH12K_QMI_EVENT_FW_MEM_READY:
3629 ret = ath12k_qmi_event_load_bdf(qmi);
3630 if (ret < 0)
3631 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3632 break;
3633 case ATH12K_QMI_EVENT_FW_READY:
3634 clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3635 if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) {
3636 if (ab->is_reset)
3637 ath12k_hal_dump_srng_stats(ab);
3638
3639 set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
3640 queue_work(ab->workqueue, &ab->restart_work);
3641 break;
3642 }
3643
3644 clear_bit(ATH12K_FLAG_CRASH_FLUSH,
3645 &ab->dev_flags);
3646 ret = ath12k_core_qmi_firmware_ready(ab);
3647 if (!ret)
3648 set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE,
3649 &ab->dev_flags);
3650
3651 break;
3652 case ATH12K_QMI_EVENT_HOST_CAP:
3653 ret = ath12k_qmi_event_host_cap(qmi);
3654 if (ret < 0)
3655 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3656 break;
3657 default:
3658 ath12k_warn(ab, "invalid event type: %d", event->type);
3659 break;
3660 }
3661
3662 skip:
3663 kfree(event);
3664 spin_lock(&qmi->event_lock);
3665 }
3666 spin_unlock(&qmi->event_lock);
3667 }
3668
ath12k_qmi_init_service(struct ath12k_base * ab)3669 int ath12k_qmi_init_service(struct ath12k_base *ab)
3670 {
3671 int ret;
3672
3673 memset(&ab->qmi.target, 0, sizeof(struct target_info));
3674 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
3675 ab->qmi.ab = ab;
3676
3677 ab->qmi.target_mem_mode = ATH12K_QMI_TARGET_MEM_MODE_DEFAULT;
3678 ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
3679 &ath12k_qmi_ops, ath12k_qmi_msg_handlers);
3680 if (ret < 0) {
3681 ath12k_warn(ab, "failed to initialize qmi handle\n");
3682 return ret;
3683 }
3684
3685 ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0);
3686 if (!ab->qmi.event_wq) {
3687 ath12k_err(ab, "failed to allocate workqueue\n");
3688 return -EFAULT;
3689 }
3690
3691 INIT_LIST_HEAD(&ab->qmi.event_list);
3692 spin_lock_init(&ab->qmi.event_lock);
3693 INIT_WORK(&ab->qmi.event_work, ath12k_qmi_driver_event_work);
3694
3695 ret = qmi_add_lookup(&ab->qmi.handle, ATH12K_QMI_WLFW_SERVICE_ID_V01,
3696 ATH12K_QMI_WLFW_SERVICE_VERS_V01,
3697 ab->qmi.service_ins_id);
3698 if (ret < 0) {
3699 ath12k_warn(ab, "failed to add qmi lookup\n");
3700 destroy_workqueue(ab->qmi.event_wq);
3701 return ret;
3702 }
3703
3704 return ret;
3705 }
3706
ath12k_qmi_deinit_service(struct ath12k_base * ab)3707 void ath12k_qmi_deinit_service(struct ath12k_base *ab)
3708 {
3709 if (!ab->qmi.ab)
3710 return;
3711
3712 qmi_handle_release(&ab->qmi.handle);
3713 cancel_work_sync(&ab->qmi.event_work);
3714 destroy_workqueue(ab->qmi.event_wq);
3715 ath12k_qmi_m3_free(ab);
3716 ath12k_qmi_free_target_mem_chunk(ab);
3717 ab->qmi.ab = NULL;
3718 }
3719
ath12k_qmi_free_resource(struct ath12k_base * ab)3720 void ath12k_qmi_free_resource(struct ath12k_base *ab)
3721 {
3722 ath12k_qmi_free_target_mem_chunk(ab);
3723 ath12k_qmi_m3_free(ab);
3724 }
3725