1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
5 */
6
7 #include <linux/elf.h>
8
9 #include "qmi.h"
10 #include "core.h"
11 #include "debug.h"
12 #include <linux/of.h>
13 #include <linux/firmware.h>
14
15 #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
16 #define HOST_CSTATE_BIT 0x04
17 #define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08
18 #define ATH12K_QMI_MAX_CHUNK_SIZE 2097152
19
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 ab->single_chip_mlo_supp = false;
2060
2061 ath12k_dbg(ab, ATH12K_DBG_QMI,
2062 "skip QMI MLO cap due to invalid num_radio %d\n",
2063 ab->qmi.num_radios);
2064 return 0;
2065 }
2066
2067 if (ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2068 ath12k_err(ab, "failed to send MLO cap due to invalid device id\n");
2069 return -EINVAL;
2070 }
2071
2072 req->mlo_capable_valid = 1;
2073 req->mlo_capable = 1;
2074 req->mlo_chip_id_valid = 1;
2075 req->mlo_chip_id = ab->device_id;
2076 req->mlo_group_id_valid = 1;
2077 req->mlo_group_id = ag->id;
2078 req->max_mlo_peer_valid = 1;
2079 /* Max peer number generally won't change for the same device
2080 * but needs to be synced with host driver.
2081 */
2082 req->max_mlo_peer = ab->hw_params->max_mlo_peer;
2083 req->mlo_num_chips_valid = 1;
2084 req->mlo_num_chips = ag->num_devices;
2085
2086 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d",
2087 req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips);
2088
2089 mutex_lock(&ag->mutex);
2090
2091 if (!ag->hw_link_id_init_done)
2092 ath12k_host_cap_hw_link_id_init(ag);
2093
2094 for (i = 0; i < ag->num_devices; i++) {
2095 info = &req->mlo_chip_info[i];
2096 partner_ab = ag->ab[i];
2097
2098 if (partner_ab->device_id == ATH12K_INVALID_DEVICE_ID) {
2099 ath12k_err(ab, "failed to send MLO cap due to invalid partner device id\n");
2100 ret = -EINVAL;
2101 goto device_cleanup;
2102 }
2103
2104 info->chip_id = partner_ab->device_id;
2105 info->num_local_links = partner_ab->qmi.num_radios;
2106
2107 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n",
2108 info->chip_id, info->num_local_links);
2109
2110 for (j = 0; j < info->num_local_links; j++) {
2111 info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j;
2112 info->valid_mlo_link_id[j] = 1;
2113
2114 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n",
2115 info->hw_link_id[j]);
2116
2117 hw_link_id++;
2118 }
2119 }
2120
2121 if (hw_link_id <= 0)
2122 ag->mlo_capable = false;
2123
2124 req->mlo_chip_info_valid = 1;
2125
2126 mutex_unlock(&ag->mutex);
2127
2128 return 0;
2129
2130 device_cleanup:
2131 for (i = i - 1; i >= 0; i--) {
2132 info = &req->mlo_chip_info[i];
2133
2134 memset(info, 0, sizeof(*info));
2135 }
2136
2137 req->mlo_num_chips = 0;
2138 req->mlo_num_chips_valid = 0;
2139
2140 req->max_mlo_peer = 0;
2141 req->max_mlo_peer_valid = 0;
2142 req->mlo_group_id = 0;
2143 req->mlo_group_id_valid = 0;
2144 req->mlo_chip_id = 0;
2145 req->mlo_chip_id_valid = 0;
2146 req->mlo_capable = 0;
2147 req->mlo_capable_valid = 0;
2148
2149 ag->mlo_capable = false;
2150
2151 mutex_unlock(&ag->mutex);
2152
2153 return ret;
2154 }
2155
2156 /* clang stack usage explodes if this is inlined */
2157 static noinline_for_stack
ath12k_qmi_host_cap_send(struct ath12k_base * ab)2158 int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
2159 {
2160 struct qmi_wlanfw_host_cap_req_msg_v01 req = {};
2161 struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {};
2162 struct qmi_txn txn;
2163 int ret = 0;
2164
2165 req.num_clients_valid = 1;
2166 req.num_clients = 1;
2167 req.mem_cfg_mode = ab->qmi.target_mem_mode;
2168 req.mem_cfg_mode_valid = 1;
2169 req.bdf_support_valid = 1;
2170 req.bdf_support = 1;
2171
2172 req.m3_support_valid = 1;
2173 req.m3_support = 1;
2174 req.m3_cache_support_valid = 1;
2175 req.m3_cache_support = 1;
2176
2177 req.cal_done_valid = 1;
2178 req.cal_done = ab->qmi.cal_done;
2179
2180 if (ab->hw_params->qmi_cnss_feature_bitmap) {
2181 req.feature_list_valid = 1;
2182 req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap;
2183 }
2184
2185 /* BRINGUP: here we are piggybacking a lot of stuff using
2186 * internal_sleep_clock, should it be split?
2187 */
2188 if (ab->hw_params->internal_sleep_clock) {
2189 req.nm_modem_valid = 1;
2190
2191 /* Notify firmware that this is non-qualcomm platform. */
2192 req.nm_modem |= HOST_CSTATE_BIT;
2193
2194 /* Notify firmware about the sleep clock selection,
2195 * nm_modem_bit[1] is used for this purpose. Host driver on
2196 * non-qualcomm platforms should select internal sleep
2197 * clock.
2198 */
2199 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
2200 req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;
2201 }
2202
2203 ret = ath12k_host_cap_parse_mlo(ab, &req);
2204 if (ret < 0)
2205 goto out;
2206
2207 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2208 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
2209 if (ret < 0)
2210 goto out;
2211
2212 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2213 QMI_WLANFW_HOST_CAP_REQ_V01,
2214 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
2215 qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
2216 if (ret < 0) {
2217 qmi_txn_cancel(&txn);
2218 ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
2219 goto out;
2220 }
2221
2222 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2223 if (ret < 0)
2224 goto out;
2225
2226 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2227 ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
2228 resp.resp.result, resp.resp.error);
2229 ret = -EINVAL;
2230 goto out;
2231 }
2232
2233 out:
2234 return ret;
2235 }
2236
ath12k_qmi_phy_cap_send(struct ath12k_base * ab)2237 static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
2238 {
2239 struct qmi_wlanfw_phy_cap_req_msg_v01 req = {};
2240 struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {};
2241 struct qmi_txn txn;
2242 int ret;
2243
2244 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2245 qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp);
2246 if (ret < 0)
2247 goto out;
2248
2249 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2250 QMI_WLANFW_PHY_CAP_REQ_V01,
2251 QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN,
2252 qmi_wlanfw_phy_cap_req_msg_v01_ei, &req);
2253 if (ret < 0) {
2254 qmi_txn_cancel(&txn);
2255 ath12k_warn(ab, "failed to send phy capability request: %d\n", ret);
2256 goto out;
2257 }
2258
2259 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2260 if (ret < 0)
2261 goto out;
2262
2263 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2264 ret = -EOPNOTSUPP;
2265 goto out;
2266 }
2267
2268 if (resp.single_chip_mlo_support_valid &&
2269 resp.single_chip_mlo_support)
2270 ab->single_chip_mlo_supp = true;
2271
2272 if (!resp.num_phy_valid) {
2273 ret = -ENODATA;
2274 goto out;
2275 }
2276
2277 ab->qmi.num_radios = resp.num_phy;
2278
2279 ath12k_dbg(ab, ATH12K_DBG_QMI,
2280 "phy capability resp valid %d num_phy %d valid %d board_id %d valid %d single_chip_mlo_support %d\n",
2281 resp.num_phy_valid, resp.num_phy,
2282 resp.board_id_valid, resp.board_id,
2283 resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support);
2284
2285 return;
2286
2287 out:
2288 /* If PHY capability not advertised then rely on default num link */
2289 ab->qmi.num_radios = ab->hw_params->def_num_link;
2290
2291 ath12k_dbg(ab, ATH12K_DBG_QMI,
2292 "no valid response from PHY capability, choose default num_phy %d\n",
2293 ab->qmi.num_radios);
2294 }
2295
ath12k_qmi_fw_ind_register_send(struct ath12k_base * ab)2296 static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab)
2297 {
2298 struct qmi_wlanfw_ind_register_req_msg_v01 *req;
2299 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
2300 struct qmi_handle *handle = &ab->qmi.handle;
2301 struct qmi_txn txn;
2302 int ret;
2303
2304 req = kzalloc(sizeof(*req), GFP_KERNEL);
2305 if (!req)
2306 return -ENOMEM;
2307
2308 resp = kzalloc(sizeof(*resp), GFP_KERNEL);
2309 if (!resp) {
2310 ret = -ENOMEM;
2311 goto resp_out;
2312 }
2313
2314 req->client_id_valid = 1;
2315 req->client_id = QMI_WLANFW_CLIENT_ID;
2316 req->fw_ready_enable_valid = 1;
2317 req->fw_ready_enable = 1;
2318 req->request_mem_enable_valid = 1;
2319 req->request_mem_enable = 1;
2320 req->fw_mem_ready_enable_valid = 1;
2321 req->fw_mem_ready_enable = 1;
2322 req->cal_done_enable_valid = 1;
2323 req->cal_done_enable = 1;
2324 req->fw_init_done_enable_valid = 1;
2325 req->fw_init_done_enable = 1;
2326
2327 req->pin_connect_result_enable_valid = 0;
2328 req->pin_connect_result_enable = 0;
2329
2330 ret = qmi_txn_init(handle, &txn,
2331 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
2332 if (ret < 0)
2333 goto out;
2334
2335 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2336 QMI_WLANFW_IND_REGISTER_REQ_V01,
2337 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
2338 qmi_wlanfw_ind_register_req_msg_v01_ei, req);
2339 if (ret < 0) {
2340 qmi_txn_cancel(&txn);
2341 ath12k_warn(ab, "Failed to send indication register request, err = %d\n",
2342 ret);
2343 goto out;
2344 }
2345
2346 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2347 if (ret < 0) {
2348 ath12k_warn(ab, "failed to register fw indication %d\n", ret);
2349 goto out;
2350 }
2351
2352 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
2353 ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
2354 resp->resp.result, resp->resp.error);
2355 ret = -EINVAL;
2356 goto out;
2357 }
2358
2359 out:
2360 kfree(resp);
2361 resp_out:
2362 kfree(req);
2363 return ret;
2364 }
2365
2366 /* clang stack usage explodes if this is inlined */
2367 static noinline_for_stack
ath12k_qmi_respond_fw_mem_request(struct ath12k_base * ab)2368 int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab)
2369 {
2370 struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
2371 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {};
2372 struct qmi_txn txn;
2373 int ret = 0, i;
2374 bool delayed;
2375
2376 req = kzalloc(sizeof(*req), GFP_KERNEL);
2377 if (!req)
2378 return -ENOMEM;
2379
2380 /* Some targets by default request a block of big contiguous
2381 * DMA memory, it's hard to allocate from kernel. So host returns
2382 * failure to firmware and firmware then request multiple blocks of
2383 * small chunk size memory.
2384 */
2385 if (ab->qmi.target_mem_delayed) {
2386 delayed = true;
2387 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n",
2388 ab->qmi.mem_seg_count);
2389 } else {
2390 delayed = false;
2391 req->mem_seg_len = ab->qmi.mem_seg_count;
2392 for (i = 0; i < req->mem_seg_len ; i++) {
2393 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
2394 req->mem_seg[i].size = ab->qmi.target_mem[i].size;
2395 req->mem_seg[i].type = ab->qmi.target_mem[i].type;
2396 ath12k_dbg(ab, ATH12K_DBG_QMI,
2397 "qmi req mem_seg[%d] %pad %u %u\n", i,
2398 &ab->qmi.target_mem[i].paddr,
2399 ab->qmi.target_mem[i].size,
2400 ab->qmi.target_mem[i].type);
2401 }
2402 }
2403
2404 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2405 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
2406 if (ret < 0)
2407 goto out;
2408
2409 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2410 QMI_WLANFW_RESPOND_MEM_REQ_V01,
2411 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
2412 qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
2413 if (ret < 0) {
2414 qmi_txn_cancel(&txn);
2415 ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n",
2416 ret);
2417 goto out;
2418 }
2419
2420 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2421 if (ret < 0) {
2422 ath12k_warn(ab, "qmi failed memory request, err = %d\n", ret);
2423 goto out;
2424 }
2425
2426 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2427 /* the error response is expected when
2428 * target_mem_delayed is true.
2429 */
2430 if (delayed && resp.resp.error == 0)
2431 goto out;
2432
2433 ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
2434 resp.resp.result, resp.resp.error);
2435 ret = -EINVAL;
2436 goto out;
2437 }
2438 out:
2439 kfree(req);
2440 return ret;
2441 }
2442
ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk,int idx)2443 static void ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base *ab,
2444 struct target_mem_chunk *chunk,
2445 int idx)
2446 {
2447 struct ath12k_hw_group *ag = ab->ag;
2448 struct target_mem_chunk *mlo_chunk;
2449
2450 lockdep_assert_held(&ag->mutex);
2451
2452 if (!ag->mlo_mem.init_done || ag->num_started)
2453 return;
2454
2455 if (idx >= ARRAY_SIZE(ag->mlo_mem.chunk)) {
2456 ath12k_warn(ab, "invalid index for MLO memory chunk free: %d\n", idx);
2457 return;
2458 }
2459
2460 mlo_chunk = &ag->mlo_mem.chunk[idx];
2461 if (mlo_chunk->v.addr) {
2462 dma_free_coherent(ab->dev,
2463 mlo_chunk->size,
2464 mlo_chunk->v.addr,
2465 mlo_chunk->paddr);
2466 mlo_chunk->v.addr = NULL;
2467 }
2468
2469 mlo_chunk->paddr = 0;
2470 mlo_chunk->size = 0;
2471 chunk->v.addr = NULL;
2472 chunk->paddr = 0;
2473 chunk->size = 0;
2474 }
2475
ath12k_qmi_free_target_mem_chunk(struct ath12k_base * ab)2476 static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
2477 {
2478 struct ath12k_hw_group *ag = ab->ag;
2479 int i, mlo_idx;
2480
2481 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2482 if (!ab->qmi.target_mem[i].v.addr)
2483 continue;
2484
2485 if (ab->qmi.target_mem[i].type == MLO_GLOBAL_MEM_REGION_TYPE) {
2486 ath12k_qmi_free_mlo_mem_chunk(ab,
2487 &ab->qmi.target_mem[i],
2488 mlo_idx++);
2489 } else {
2490 dma_free_coherent(ab->dev,
2491 ab->qmi.target_mem[i].prev_size,
2492 ab->qmi.target_mem[i].v.addr,
2493 ab->qmi.target_mem[i].paddr);
2494 ab->qmi.target_mem[i].v.addr = NULL;
2495 }
2496 }
2497
2498 if (!ag->num_started && ag->mlo_mem.init_done) {
2499 ag->mlo_mem.init_done = false;
2500 ag->mlo_mem.mlo_mem_size = 0;
2501 }
2502 }
2503
ath12k_qmi_alloc_chunk(struct ath12k_base * ab,struct target_mem_chunk * chunk)2504 static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
2505 struct target_mem_chunk *chunk)
2506 {
2507 /* Firmware reloads in recovery/resume.
2508 * In such cases, no need to allocate memory for FW again.
2509 */
2510 if (chunk->v.addr) {
2511 if (chunk->prev_type == chunk->type &&
2512 chunk->prev_size == chunk->size)
2513 goto this_chunk_done;
2514
2515 /* cannot reuse the existing chunk */
2516 dma_free_coherent(ab->dev, chunk->prev_size,
2517 chunk->v.addr, chunk->paddr);
2518 chunk->v.addr = NULL;
2519 }
2520
2521 chunk->v.addr = dma_alloc_coherent(ab->dev,
2522 chunk->size,
2523 &chunk->paddr,
2524 GFP_KERNEL | __GFP_NOWARN);
2525 if (!chunk->v.addr) {
2526 if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
2527 ab->qmi.target_mem_delayed = true;
2528 ath12k_warn(ab,
2529 "qmi dma allocation failed (%d B type %u), will try later with small size\n",
2530 chunk->size,
2531 chunk->type);
2532 ath12k_qmi_free_target_mem_chunk(ab);
2533 return -EAGAIN;
2534 }
2535 ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
2536 chunk->type, chunk->size);
2537 return -ENOMEM;
2538 }
2539 chunk->prev_type = chunk->type;
2540 chunk->prev_size = chunk->size;
2541 this_chunk_done:
2542 return 0;
2543 }
2544
ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base * ab)2545 static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
2546 {
2547 struct target_mem_chunk *chunk, *mlo_chunk;
2548 struct ath12k_hw_group *ag = ab->ag;
2549 int i, mlo_idx, ret;
2550 int mlo_size = 0;
2551
2552 mutex_lock(&ag->mutex);
2553
2554 if (!ag->mlo_mem.init_done) {
2555 memset(ag->mlo_mem.chunk, 0, sizeof(ag->mlo_mem.chunk));
2556 ag->mlo_mem.init_done = true;
2557 }
2558
2559 ab->qmi.target_mem_delayed = false;
2560
2561 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) {
2562 chunk = &ab->qmi.target_mem[i];
2563
2564 /* Allocate memory for the region and the functionality supported
2565 * on the host. For the non-supported memory region, host does not
2566 * allocate memory, assigns NULL and FW will handle this without crashing.
2567 */
2568 switch (chunk->type) {
2569 case HOST_DDR_REGION_TYPE:
2570 case M3_DUMP_REGION_TYPE:
2571 case PAGEABLE_MEM_REGION_TYPE:
2572 case CALDB_MEM_REGION_TYPE:
2573 ret = ath12k_qmi_alloc_chunk(ab, chunk);
2574 if (ret)
2575 goto err;
2576 break;
2577 case MLO_GLOBAL_MEM_REGION_TYPE:
2578 mlo_size += chunk->size;
2579 if (ag->mlo_mem.mlo_mem_size &&
2580 mlo_size > ag->mlo_mem.mlo_mem_size) {
2581 ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d",
2582 mlo_size, ag->mlo_mem.mlo_mem_size);
2583 ret = -EINVAL;
2584 goto err;
2585 }
2586
2587 mlo_chunk = &ag->mlo_mem.chunk[mlo_idx];
2588 if (mlo_chunk->paddr) {
2589 if (chunk->size != mlo_chunk->size) {
2590 ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d",
2591 mlo_idx, chunk->size, mlo_chunk->size);
2592 ret = -EINVAL;
2593 goto err;
2594 }
2595 } else {
2596 mlo_chunk->size = chunk->size;
2597 mlo_chunk->type = chunk->type;
2598 ret = ath12k_qmi_alloc_chunk(ab, mlo_chunk);
2599 if (ret)
2600 goto err;
2601 memset(mlo_chunk->v.addr, 0, mlo_chunk->size);
2602 }
2603
2604 chunk->paddr = mlo_chunk->paddr;
2605 chunk->v.addr = mlo_chunk->v.addr;
2606 mlo_idx++;
2607
2608 break;
2609 default:
2610 ath12k_warn(ab, "memory type %u not supported\n",
2611 chunk->type);
2612 chunk->paddr = 0;
2613 chunk->v.addr = NULL;
2614 break;
2615 }
2616 }
2617
2618 if (!ag->mlo_mem.mlo_mem_size) {
2619 ag->mlo_mem.mlo_mem_size = mlo_size;
2620 } else if (ag->mlo_mem.mlo_mem_size != mlo_size) {
2621 ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d",
2622 ag->mlo_mem.mlo_mem_size, mlo_size);
2623 ret = -EINVAL;
2624 goto err;
2625 }
2626
2627 mutex_unlock(&ag->mutex);
2628
2629 return 0;
2630
2631 err:
2632 ath12k_qmi_free_target_mem_chunk(ab);
2633
2634 mutex_unlock(&ag->mutex);
2635
2636 /* The firmware will attempt to request memory in smaller chunks
2637 * on the next try. However, the current caller should be notified
2638 * that this instance of request parsing was successful.
2639 * Therefore, return 0 only.
2640 */
2641 if (ret == -EAGAIN)
2642 ret = 0;
2643
2644 return ret;
2645 }
2646
2647 /* clang stack usage explodes if this is inlined */
2648 static noinline_for_stack
ath12k_qmi_request_target_cap(struct ath12k_base * ab)2649 int ath12k_qmi_request_target_cap(struct ath12k_base *ab)
2650 {
2651 struct qmi_wlanfw_cap_req_msg_v01 req = {};
2652 struct qmi_wlanfw_cap_resp_msg_v01 resp = {};
2653 struct qmi_txn txn;
2654 unsigned int board_id = ATH12K_BOARD_ID_DEFAULT;
2655 int ret = 0;
2656 int r;
2657 int i;
2658
2659 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2660 qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
2661 if (ret < 0)
2662 goto out;
2663
2664 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2665 QMI_WLANFW_CAP_REQ_V01,
2666 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
2667 qmi_wlanfw_cap_req_msg_v01_ei, &req);
2668 if (ret < 0) {
2669 qmi_txn_cancel(&txn);
2670 ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n",
2671 ret);
2672 goto out;
2673 }
2674
2675 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2676 if (ret < 0) {
2677 ath12k_warn(ab, "qmi failed target cap request %d\n", ret);
2678 goto out;
2679 }
2680
2681 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2682 ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
2683 resp.resp.result, resp.resp.error);
2684 ret = -EINVAL;
2685 goto out;
2686 }
2687
2688 if (resp.chip_info_valid) {
2689 ab->qmi.target.chip_id = resp.chip_info.chip_id;
2690 ab->qmi.target.chip_family = resp.chip_info.chip_family;
2691 }
2692
2693 if (resp.board_info_valid)
2694 ab->qmi.target.board_id = resp.board_info.board_id;
2695 else
2696 ab->qmi.target.board_id = board_id;
2697
2698 if (resp.soc_info_valid)
2699 ab->qmi.target.soc_id = resp.soc_info.soc_id;
2700
2701 if (resp.fw_version_info_valid) {
2702 ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
2703 strscpy(ab->qmi.target.fw_build_timestamp,
2704 resp.fw_version_info.fw_build_timestamp,
2705 sizeof(ab->qmi.target.fw_build_timestamp));
2706 }
2707
2708 if (resp.fw_build_id_valid)
2709 strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
2710 sizeof(ab->qmi.target.fw_build_id));
2711
2712 if (resp.dev_mem_info_valid) {
2713 for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) {
2714 ab->qmi.dev_mem[i].start =
2715 resp.dev_mem[i].start;
2716 ab->qmi.dev_mem[i].size =
2717 resp.dev_mem[i].size;
2718 ath12k_dbg(ab, ATH12K_DBG_QMI,
2719 "devmem [%d] start 0x%llx size %llu\n", i,
2720 ab->qmi.dev_mem[i].start,
2721 ab->qmi.dev_mem[i].size);
2722 }
2723 }
2724
2725 if (resp.eeprom_caldata_read_timeout_valid) {
2726 ab->qmi.target.eeprom_caldata = resp.eeprom_caldata_read_timeout;
2727 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi cal data supported from eeprom\n");
2728 }
2729
2730 ath12k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
2731 ab->qmi.target.chip_id, ab->qmi.target.chip_family,
2732 ab->qmi.target.board_id, ab->qmi.target.soc_id);
2733
2734 ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
2735 ab->qmi.target.fw_version,
2736 ab->qmi.target.fw_build_timestamp,
2737 ab->qmi.target.fw_build_id);
2738
2739 r = ath12k_core_check_smbios(ab);
2740 if (r)
2741 ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n");
2742
2743 out:
2744 return ret;
2745 }
2746
ath12k_qmi_load_file_target_mem(struct ath12k_base * ab,const u8 * data,u32 len,u8 type)2747 static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab,
2748 const u8 *data, u32 len, u8 type)
2749 {
2750 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2751 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {};
2752 struct qmi_txn txn;
2753 const u8 *temp = data;
2754 int ret = 0;
2755 u32 remaining = len;
2756
2757 req = kzalloc(sizeof(*req), GFP_KERNEL);
2758 if (!req)
2759 return -ENOMEM;
2760
2761 while (remaining) {
2762 req->valid = 1;
2763 req->file_id_valid = 1;
2764 req->file_id = ab->qmi.target.board_id;
2765 req->total_size_valid = 1;
2766 req->total_size = remaining;
2767 req->seg_id_valid = 1;
2768 req->data_valid = 1;
2769 req->bdf_type = type;
2770 req->bdf_type_valid = 1;
2771 req->end_valid = 1;
2772 req->end = 0;
2773
2774 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2775 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2776 } else {
2777 req->data_len = remaining;
2778 req->end = 1;
2779 }
2780
2781 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2782 req->data_valid = 0;
2783 req->end = 1;
2784 req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2785 } else {
2786 memcpy(req->data, temp, req->data_len);
2787 }
2788
2789 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2790 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2791 &resp);
2792 if (ret < 0)
2793 goto out;
2794
2795 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
2796 type);
2797
2798 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2799 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2800 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2801 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2802 if (ret < 0) {
2803 qmi_txn_cancel(&txn);
2804 goto out;
2805 }
2806
2807 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
2808 if (ret < 0)
2809 goto out;
2810
2811 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2812 ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2813 resp.resp.result, resp.resp.error);
2814 ret = -EINVAL;
2815 goto out;
2816 }
2817
2818 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) {
2819 remaining = 0;
2820 } else {
2821 remaining -= req->data_len;
2822 temp += req->data_len;
2823 req->seg_id++;
2824 ath12k_dbg(ab, ATH12K_DBG_QMI,
2825 "qmi bdf download request remaining %i\n",
2826 remaining);
2827 }
2828 }
2829
2830 out:
2831 kfree(req);
2832 return ret;
2833 }
2834
2835 /* clang stack usage explodes if this is inlined */
2836 static noinline_for_stack
ath12k_qmi_load_bdf_qmi(struct ath12k_base * ab,enum ath12k_qmi_bdf_type type)2837 int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab,
2838 enum ath12k_qmi_bdf_type type)
2839 {
2840 struct device *dev = ab->dev;
2841 char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE];
2842 const struct firmware *fw_entry;
2843 struct ath12k_board_data bd;
2844 u32 fw_size, file_type;
2845 int ret = 0;
2846 const u8 *tmp;
2847
2848 memset(&bd, 0, sizeof(bd));
2849
2850 switch (type) {
2851 case ATH12K_QMI_BDF_TYPE_ELF:
2852 ret = ath12k_core_fetch_bdf(ab, &bd);
2853 if (ret) {
2854 ath12k_warn(ab, "qmi failed to load bdf:\n");
2855 goto out;
2856 }
2857
2858 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
2859 type = ATH12K_QMI_BDF_TYPE_ELF;
2860 else
2861 type = ATH12K_QMI_BDF_TYPE_BIN;
2862
2863 break;
2864 case ATH12K_QMI_BDF_TYPE_REGDB:
2865 ret = ath12k_core_fetch_regdb(ab, &bd);
2866 if (ret) {
2867 ath12k_warn(ab, "qmi failed to load regdb bin:\n");
2868 goto out;
2869 }
2870 break;
2871 case ATH12K_QMI_BDF_TYPE_CALIBRATION:
2872
2873 if (ab->qmi.target.eeprom_caldata) {
2874 file_type = ATH12K_QMI_FILE_TYPE_EEPROM;
2875 tmp = filename;
2876 fw_size = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE;
2877 } else {
2878 file_type = ATH12K_QMI_FILE_TYPE_CALDATA;
2879
2880 /* cal-<bus>-<id>.bin */
2881 snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
2882 ath12k_bus_str(ab->hif.bus), dev_name(dev));
2883 fw_entry = ath12k_core_firmware_request(ab, filename);
2884 if (!IS_ERR(fw_entry))
2885 goto success;
2886
2887 fw_entry = ath12k_core_firmware_request(ab,
2888 ATH12K_DEFAULT_CAL_FILE);
2889 if (IS_ERR(fw_entry)) {
2890 ret = PTR_ERR(fw_entry);
2891 ath12k_warn(ab,
2892 "qmi failed to load CAL data file:%s\n",
2893 filename);
2894 goto out;
2895 }
2896
2897 success:
2898 fw_size = min_t(u32, ab->hw_params->fw.board_size,
2899 fw_entry->size);
2900 tmp = fw_entry->data;
2901 }
2902 ret = ath12k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
2903 if (ret < 0) {
2904 ath12k_warn(ab, "qmi failed to load caldata\n");
2905 goto out_qmi_cal;
2906 }
2907
2908 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi caldata downloaded: type: %u\n",
2909 file_type);
2910
2911 out_qmi_cal:
2912 if (!ab->qmi.target.eeprom_caldata)
2913 release_firmware(fw_entry);
2914 return ret;
2915 default:
2916 ath12k_warn(ab, "unknown file type for load %d", type);
2917 goto out;
2918 }
2919
2920 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf_type %d\n", type);
2921
2922 fw_size = min_t(u32, ab->hw_params->fw.board_size, bd.len);
2923
2924 ret = ath12k_qmi_load_file_target_mem(ab, bd.data, fw_size, type);
2925 if (ret < 0)
2926 ath12k_warn(ab, "qmi failed to load bdf file\n");
2927
2928 out:
2929 ath12k_core_free_bdf(ab, &bd);
2930 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi BDF download sequence completed\n");
2931
2932 return ret;
2933 }
2934
ath12k_qmi_m3_free(struct ath12k_base * ab)2935 static void ath12k_qmi_m3_free(struct ath12k_base *ab)
2936 {
2937 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2938
2939 if (!m3_mem->vaddr)
2940 return;
2941
2942 dma_free_coherent(ab->dev, m3_mem->size,
2943 m3_mem->vaddr, m3_mem->paddr);
2944 m3_mem->vaddr = NULL;
2945 m3_mem->size = 0;
2946 }
2947
ath12k_qmi_m3_load(struct ath12k_base * ab)2948 static int ath12k_qmi_m3_load(struct ath12k_base *ab)
2949 {
2950 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2951 const struct firmware *fw = NULL;
2952 const void *m3_data;
2953 char path[100];
2954 size_t m3_len;
2955 int ret;
2956
2957 if (ab->fw.m3_data && ab->fw.m3_len > 0) {
2958 /* firmware-N.bin had a m3 firmware file so use that */
2959 m3_data = ab->fw.m3_data;
2960 m3_len = ab->fw.m3_len;
2961 } else {
2962 /* No m3 file in firmware-N.bin so try to request old
2963 * separate m3.bin.
2964 */
2965 fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE);
2966 if (IS_ERR(fw)) {
2967 ret = PTR_ERR(fw);
2968 ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE,
2969 path, sizeof(path));
2970 ath12k_err(ab, "failed to load %s: %d\n", path, ret);
2971 return ret;
2972 }
2973
2974 m3_data = fw->data;
2975 m3_len = fw->size;
2976 }
2977
2978 /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */
2979 if (m3_mem->vaddr) {
2980 if (m3_mem->size >= m3_len)
2981 goto skip_m3_alloc;
2982
2983 /* Old buffer is too small, free and reallocate */
2984 ath12k_qmi_m3_free(ab);
2985 }
2986
2987 m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2988 m3_len, &m3_mem->paddr,
2989 GFP_KERNEL);
2990 if (!m3_mem->vaddr) {
2991 ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2992 fw->size);
2993 ret = -ENOMEM;
2994 goto out;
2995 }
2996
2997 skip_m3_alloc:
2998 memcpy(m3_mem->vaddr, m3_data, m3_len);
2999 m3_mem->size = m3_len;
3000
3001 ret = 0;
3002
3003 out:
3004 release_firmware(fw);
3005
3006 return ret;
3007 }
3008
3009 /* clang stack usage explodes if this is inlined */
3010 static noinline_for_stack
ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base * ab)3011 int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab)
3012 {
3013 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
3014 struct qmi_wlanfw_m3_info_req_msg_v01 req = {};
3015 struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {};
3016 struct qmi_txn txn;
3017 int ret = 0;
3018
3019 ret = ath12k_qmi_m3_load(ab);
3020 if (ret) {
3021 ath12k_err(ab, "failed to load m3 firmware: %d", ret);
3022 return ret;
3023 }
3024
3025 req.addr = m3_mem->paddr;
3026 req.size = m3_mem->size;
3027
3028 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3029 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
3030 if (ret < 0)
3031 goto out;
3032
3033 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3034 QMI_WLANFW_M3_INFO_REQ_V01,
3035 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
3036 qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
3037 if (ret < 0) {
3038 qmi_txn_cancel(&txn);
3039 ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
3040 ret);
3041 goto out;
3042 }
3043
3044 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3045 if (ret < 0) {
3046 ath12k_warn(ab, "qmi failed M3 information request %d\n", ret);
3047 goto out;
3048 }
3049
3050 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3051 ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
3052 resp.resp.result, resp.resp.error);
3053 ret = -EINVAL;
3054 goto out;
3055 }
3056 out:
3057 return ret;
3058 }
3059
ath12k_qmi_wlanfw_mode_send(struct ath12k_base * ab,u32 mode)3060 static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab,
3061 u32 mode)
3062 {
3063 struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {};
3064 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {};
3065 struct qmi_txn txn;
3066 int ret = 0;
3067
3068 req.mode = mode;
3069 req.hw_debug_valid = 1;
3070 req.hw_debug = 0;
3071
3072 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3073 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
3074 if (ret < 0)
3075 goto out;
3076
3077 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3078 QMI_WLANFW_WLAN_MODE_REQ_V01,
3079 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
3080 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
3081 if (ret < 0) {
3082 qmi_txn_cancel(&txn);
3083 ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
3084 mode, ret);
3085 goto out;
3086 }
3087
3088 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3089 if (ret < 0) {
3090 if (mode == ATH12K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
3091 ath12k_warn(ab, "WLFW service is dis-connected\n");
3092 return 0;
3093 }
3094 ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
3095 mode, ret);
3096 goto out;
3097 }
3098
3099 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3100 ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
3101 mode, resp.resp.result, resp.resp.error);
3102 ret = -EINVAL;
3103 goto out;
3104 }
3105
3106 out:
3107 return ret;
3108 }
3109
ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base * ab)3110 static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab)
3111 {
3112 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
3113 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {};
3114 struct ce_pipe_config *ce_cfg;
3115 struct service_to_pipe *svc_cfg;
3116 struct qmi_txn txn;
3117 int ret = 0, pipe_num;
3118
3119 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
3120 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
3121
3122 req = kzalloc(sizeof(*req), GFP_KERNEL);
3123 if (!req)
3124 return -ENOMEM;
3125
3126 req->host_version_valid = 1;
3127 strscpy(req->host_version, ATH12K_HOST_VERSION_STRING,
3128 sizeof(req->host_version));
3129
3130 req->tgt_cfg_valid = 1;
3131 /* This is number of CE configs */
3132 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
3133 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
3134 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
3135 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
3136 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
3137 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
3138 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
3139 }
3140
3141 req->svc_cfg_valid = 1;
3142 /* This is number of Service/CE configs */
3143 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
3144 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
3145 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
3146 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
3147 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
3148 }
3149
3150 /* set shadow v3 configuration */
3151 if (ab->hw_params->supports_shadow_regs) {
3152 req->shadow_reg_v3_valid = 1;
3153 req->shadow_reg_v3_len = min_t(u32,
3154 ab->qmi.ce_cfg.shadow_reg_v3_len,
3155 QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01);
3156 memcpy(&req->shadow_reg_v3, ab->qmi.ce_cfg.shadow_reg_v3,
3157 sizeof(u32) * req->shadow_reg_v3_len);
3158 } else {
3159 req->shadow_reg_v3_valid = 0;
3160 }
3161
3162 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3163 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
3164 if (ret < 0)
3165 goto out;
3166
3167 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3168 QMI_WLANFW_WLAN_CFG_REQ_V01,
3169 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
3170 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
3171 if (ret < 0) {
3172 qmi_txn_cancel(&txn);
3173 ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
3174 ret);
3175 goto out;
3176 }
3177
3178 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3179 if (ret < 0) {
3180 ath12k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
3181 goto out;
3182 }
3183
3184 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3185 ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
3186 resp.resp.result, resp.resp.error);
3187 ret = -EINVAL;
3188 goto out;
3189 }
3190
3191 out:
3192 kfree(req);
3193 return ret;
3194 }
3195
ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base * ab)3196 static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab)
3197 {
3198 struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
3199 struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
3200 struct qmi_txn txn;
3201 int ret;
3202
3203 req.enable_fwlog_valid = true;
3204 req.enable_fwlog = 1;
3205
3206 ret = qmi_txn_init(&ab->qmi.handle, &txn,
3207 qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
3208 if (ret < 0)
3209 goto out;
3210
3211 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
3212 ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01,
3213 QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
3214 qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
3215 if (ret < 0) {
3216 qmi_txn_cancel(&txn);
3217 ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n",
3218 ret);
3219 goto out;
3220 }
3221
3222 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS));
3223 if (ret < 0) {
3224 ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret);
3225 goto out;
3226 }
3227
3228 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
3229 ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n",
3230 resp.resp.result, resp.resp.error);
3231 ret = -EINVAL;
3232 goto out;
3233 }
3234
3235 out:
3236 return ret;
3237 }
3238
ath12k_qmi_firmware_stop(struct ath12k_base * ab)3239 void ath12k_qmi_firmware_stop(struct ath12k_base *ab)
3240 {
3241 int ret;
3242
3243 clear_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags);
3244
3245 ret = ath12k_qmi_wlanfw_mode_send(ab, ATH12K_FIRMWARE_MODE_OFF);
3246 if (ret < 0) {
3247 ath12k_warn(ab, "qmi failed to send wlan mode off\n");
3248 return;
3249 }
3250 }
3251
ath12k_qmi_firmware_start(struct ath12k_base * ab,u32 mode)3252 int ath12k_qmi_firmware_start(struct ath12k_base *ab,
3253 u32 mode)
3254 {
3255 int ret;
3256
3257 ret = ath12k_qmi_wlanfw_wlan_ini_send(ab);
3258 if (ret < 0) {
3259 ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret);
3260 return ret;
3261 }
3262
3263 ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab);
3264 if (ret < 0) {
3265 ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
3266 return ret;
3267 }
3268
3269 ret = ath12k_qmi_wlanfw_mode_send(ab, mode);
3270 if (ret < 0) {
3271 ath12k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
3272 return ret;
3273 }
3274
3275 return 0;
3276 }
3277
3278 static int
ath12k_qmi_driver_event_post(struct ath12k_qmi * qmi,enum ath12k_qmi_event_type type,void * data)3279 ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi,
3280 enum ath12k_qmi_event_type type,
3281 void *data)
3282 {
3283 struct ath12k_qmi_driver_event *event;
3284
3285 event = kzalloc(sizeof(*event), GFP_ATOMIC);
3286 if (!event)
3287 return -ENOMEM;
3288
3289 event->type = type;
3290 event->data = data;
3291
3292 spin_lock(&qmi->event_lock);
3293 list_add_tail(&event->list, &qmi->event_list);
3294 spin_unlock(&qmi->event_lock);
3295
3296 queue_work(qmi->event_wq, &qmi->event_work);
3297
3298 return 0;
3299 }
3300
ath12k_qmi_trigger_host_cap(struct ath12k_base * ab)3301 void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab)
3302 {
3303 struct ath12k_qmi *qmi = &ab->qmi;
3304
3305 spin_lock(&qmi->event_lock);
3306
3307 if (ath12k_qmi_get_event_block(qmi))
3308 ath12k_qmi_set_event_block(qmi, false);
3309
3310 spin_unlock(&qmi->event_lock);
3311
3312 ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n",
3313 ab->device_id);
3314
3315 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL);
3316 }
3317
ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group * ag)3318 static bool ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group *ag)
3319 {
3320 struct ath12k_base *ab;
3321 int i;
3322
3323 for (i = 0; i < ag->num_devices; i++) {
3324 ab = ag->ab[i];
3325
3326 if (!(ab && ab->qmi.num_radios != U8_MAX))
3327 return false;
3328 }
3329
3330 return true;
3331 }
3332
ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group * ag)3333 static struct ath12k_base *ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group *ag)
3334 {
3335 struct ath12k_base *ab;
3336 int i;
3337
3338 lockdep_assert_held(&ag->mutex);
3339
3340 for (i = 0; i < ag->num_devices; i++) {
3341 ab = ag->ab[i];
3342 if (!ab)
3343 continue;
3344
3345 spin_lock(&ab->qmi.event_lock);
3346
3347 if (ath12k_qmi_get_event_block(&ab->qmi)) {
3348 spin_unlock(&ab->qmi.event_lock);
3349 return ab;
3350 }
3351
3352 spin_unlock(&ab->qmi.event_lock);
3353 }
3354
3355 return NULL;
3356 }
3357
3358 /* clang stack usage explodes if this is inlined */
3359 static noinline_for_stack
ath12k_qmi_event_server_arrive(struct ath12k_qmi * qmi)3360 int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi)
3361 {
3362 struct ath12k_base *ab = qmi->ab, *block_ab;
3363 struct ath12k_hw_group *ag = ab->ag;
3364 int ret;
3365
3366 ath12k_qmi_phy_cap_send(ab);
3367
3368 ret = ath12k_qmi_fw_ind_register_send(ab);
3369 if (ret < 0) {
3370 ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
3371 return ret;
3372 }
3373
3374 spin_lock(&qmi->event_lock);
3375
3376 ath12k_qmi_set_event_block(qmi, true);
3377
3378 spin_unlock(&qmi->event_lock);
3379
3380 mutex_lock(&ag->mutex);
3381
3382 if (ath12k_qmi_hw_group_host_cap_ready(ag)) {
3383 ath12k_core_hw_group_set_mlo_capable(ag);
3384
3385 block_ab = ath12k_qmi_hw_group_find_blocked(ag);
3386 if (block_ab)
3387 ath12k_qmi_trigger_host_cap(block_ab);
3388 }
3389
3390 mutex_unlock(&ag->mutex);
3391
3392 return ret;
3393 }
3394
3395 /* clang stack usage explodes if this is inlined */
3396 static noinline_for_stack
ath12k_qmi_event_mem_request(struct ath12k_qmi * qmi)3397 int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi)
3398 {
3399 struct ath12k_base *ab = qmi->ab;
3400 int ret;
3401
3402 ret = ath12k_qmi_respond_fw_mem_request(ab);
3403 if (ret < 0) {
3404 ath12k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
3405 return ret;
3406 }
3407
3408 return ret;
3409 }
3410
3411 /* clang stack usage explodes if this is inlined */
3412 static noinline_for_stack
ath12k_qmi_event_load_bdf(struct ath12k_qmi * qmi)3413 int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi)
3414 {
3415 struct ath12k_base *ab = qmi->ab;
3416 int ret;
3417
3418 ret = ath12k_qmi_request_target_cap(ab);
3419 if (ret < 0) {
3420 ath12k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
3421 return ret;
3422 }
3423
3424 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_REGDB);
3425 if (ret < 0) {
3426 ath12k_warn(ab, "qmi failed to load regdb file:%d\n", ret);
3427 return ret;
3428 }
3429
3430 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_ELF);
3431 if (ret < 0) {
3432 ath12k_warn(ab, "qmi failed to load board data file:%d\n", ret);
3433 return ret;
3434 }
3435
3436 if (ab->hw_params->download_calib) {
3437 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION);
3438 if (ret < 0)
3439 ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret);
3440 }
3441
3442 ret = ath12k_qmi_wlanfw_m3_info_send(ab);
3443 if (ret < 0) {
3444 ath12k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
3445 return ret;
3446 }
3447
3448 return ret;
3449 }
3450
ath12k_qmi_msg_mem_request_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * data)3451 static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
3452 struct sockaddr_qrtr *sq,
3453 struct qmi_txn *txn,
3454 const void *data)
3455 {
3456 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3457 struct ath12k_base *ab = qmi->ab;
3458 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
3459 int i, ret;
3460
3461 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware request memory request\n");
3462
3463 if (msg->mem_seg_len == 0 ||
3464 msg->mem_seg_len > ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
3465 ath12k_warn(ab, "Invalid memory segment length: %u\n",
3466 msg->mem_seg_len);
3467
3468 ab->qmi.mem_seg_count = msg->mem_seg_len;
3469
3470 for (i = 0; i < qmi->mem_seg_count ; i++) {
3471 ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
3472 ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
3473 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n",
3474 msg->mem_seg[i].type, msg->mem_seg[i].size);
3475 }
3476
3477 ret = ath12k_qmi_alloc_target_mem_chunk(ab);
3478 if (ret) {
3479 ath12k_warn(ab, "qmi failed to alloc target memory: %d\n",
3480 ret);
3481 return;
3482 }
3483
3484 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL);
3485 }
3486
ath12k_qmi_msg_mem_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3487 static void ath12k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
3488 struct sockaddr_qrtr *sq,
3489 struct qmi_txn *txn,
3490 const void *decoded)
3491 {
3492 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3493 struct ath12k_base *ab = qmi->ab;
3494
3495 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware memory ready indication\n");
3496 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_MEM_READY, NULL);
3497 }
3498
ath12k_qmi_msg_fw_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)3499 static void ath12k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
3500 struct sockaddr_qrtr *sq,
3501 struct qmi_txn *txn,
3502 const void *decoded)
3503 {
3504 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3505 struct ath12k_base *ab = qmi->ab;
3506
3507 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware ready\n");
3508 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_READY, NULL);
3509 }
3510
3511 static const struct qmi_msg_handler ath12k_qmi_msg_handlers[] = {
3512 {
3513 .type = QMI_INDICATION,
3514 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
3515 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
3516 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
3517 .fn = ath12k_qmi_msg_mem_request_cb,
3518 },
3519 {
3520 .type = QMI_INDICATION,
3521 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
3522 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
3523 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
3524 .fn = ath12k_qmi_msg_mem_ready_cb,
3525 },
3526 {
3527 .type = QMI_INDICATION,
3528 .msg_id = QMI_WLFW_FW_READY_IND_V01,
3529 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
3530 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
3531 .fn = ath12k_qmi_msg_fw_ready_cb,
3532 },
3533
3534 /* end of list */
3535 {},
3536 };
3537
ath12k_qmi_ops_new_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3538 static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
3539 struct qmi_service *service)
3540 {
3541 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3542 struct ath12k_base *ab = qmi->ab;
3543 struct sockaddr_qrtr *sq = &qmi->sq;
3544 int ret;
3545
3546 sq->sq_family = AF_QIPCRTR;
3547 sq->sq_node = service->node;
3548 sq->sq_port = service->port;
3549
3550 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
3551 sizeof(*sq), 0);
3552 if (ret) {
3553 ath12k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
3554 return ret;
3555 }
3556
3557 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw qmi service connected\n");
3558 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_ARRIVE, NULL);
3559
3560 return ret;
3561 }
3562
ath12k_qmi_ops_del_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)3563 static void ath12k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
3564 struct qmi_service *service)
3565 {
3566 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle);
3567 struct ath12k_base *ab = qmi->ab;
3568
3569 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw del server\n");
3570 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_EXIT, NULL);
3571 }
3572
3573 static const struct qmi_ops ath12k_qmi_ops = {
3574 .new_server = ath12k_qmi_ops_new_server,
3575 .del_server = ath12k_qmi_ops_del_server,
3576 };
3577
ath12k_qmi_event_host_cap(struct ath12k_qmi * qmi)3578 static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi)
3579 {
3580 struct ath12k_base *ab = qmi->ab;
3581 int ret;
3582
3583 ret = ath12k_qmi_host_cap_send(ab);
3584 if (ret < 0) {
3585 ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n",
3586 ab->device_id, ret);
3587 return ret;
3588 }
3589
3590 return ret;
3591 }
3592
ath12k_qmi_driver_event_work(struct work_struct * work)3593 static void ath12k_qmi_driver_event_work(struct work_struct *work)
3594 {
3595 struct ath12k_qmi *qmi = container_of(work, struct ath12k_qmi,
3596 event_work);
3597 struct ath12k_qmi_driver_event *event;
3598 struct ath12k_base *ab = qmi->ab;
3599 int ret;
3600
3601 spin_lock(&qmi->event_lock);
3602 while (!list_empty(&qmi->event_list)) {
3603 event = list_first_entry(&qmi->event_list,
3604 struct ath12k_qmi_driver_event, list);
3605 list_del(&event->list);
3606 spin_unlock(&qmi->event_lock);
3607
3608 if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags))
3609 goto skip;
3610
3611 switch (event->type) {
3612 case ATH12K_QMI_EVENT_SERVER_ARRIVE:
3613 ret = ath12k_qmi_event_server_arrive(qmi);
3614 if (ret < 0)
3615 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3616 break;
3617 case ATH12K_QMI_EVENT_SERVER_EXIT:
3618 set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags);
3619 break;
3620 case ATH12K_QMI_EVENT_REQUEST_MEM:
3621 ret = ath12k_qmi_event_mem_request(qmi);
3622 if (ret < 0)
3623 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3624 break;
3625 case ATH12K_QMI_EVENT_FW_MEM_READY:
3626 ret = ath12k_qmi_event_load_bdf(qmi);
3627 if (ret < 0)
3628 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3629 break;
3630 case ATH12K_QMI_EVENT_FW_READY:
3631 clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3632 if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) {
3633 if (ab->is_reset)
3634 ath12k_hal_dump_srng_stats(ab);
3635
3636 set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags);
3637 queue_work(ab->workqueue, &ab->restart_work);
3638 break;
3639 }
3640
3641 clear_bit(ATH12K_FLAG_CRASH_FLUSH,
3642 &ab->dev_flags);
3643 ret = ath12k_core_qmi_firmware_ready(ab);
3644 if (!ret)
3645 set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE,
3646 &ab->dev_flags);
3647
3648 break;
3649 case ATH12K_QMI_EVENT_HOST_CAP:
3650 ret = ath12k_qmi_event_host_cap(qmi);
3651 if (ret < 0)
3652 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags);
3653 break;
3654 default:
3655 ath12k_warn(ab, "invalid event type: %d", event->type);
3656 break;
3657 }
3658
3659 skip:
3660 kfree(event);
3661 spin_lock(&qmi->event_lock);
3662 }
3663 spin_unlock(&qmi->event_lock);
3664 }
3665
ath12k_qmi_init_service(struct ath12k_base * ab)3666 int ath12k_qmi_init_service(struct ath12k_base *ab)
3667 {
3668 int ret;
3669
3670 memset(&ab->qmi.target, 0, sizeof(struct target_info));
3671 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
3672 ab->qmi.ab = ab;
3673
3674 ab->qmi.target_mem_mode = ATH12K_QMI_TARGET_MEM_MODE_DEFAULT;
3675 ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX,
3676 &ath12k_qmi_ops, ath12k_qmi_msg_handlers);
3677 if (ret < 0) {
3678 ath12k_warn(ab, "failed to initialize qmi handle\n");
3679 return ret;
3680 }
3681
3682 ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0);
3683 if (!ab->qmi.event_wq) {
3684 ath12k_err(ab, "failed to allocate workqueue\n");
3685 return -EFAULT;
3686 }
3687
3688 INIT_LIST_HEAD(&ab->qmi.event_list);
3689 spin_lock_init(&ab->qmi.event_lock);
3690 INIT_WORK(&ab->qmi.event_work, ath12k_qmi_driver_event_work);
3691
3692 ret = qmi_add_lookup(&ab->qmi.handle, ATH12K_QMI_WLFW_SERVICE_ID_V01,
3693 ATH12K_QMI_WLFW_SERVICE_VERS_V01,
3694 ab->qmi.service_ins_id);
3695 if (ret < 0) {
3696 ath12k_warn(ab, "failed to add qmi lookup\n");
3697 destroy_workqueue(ab->qmi.event_wq);
3698 return ret;
3699 }
3700
3701 return ret;
3702 }
3703
ath12k_qmi_deinit_service(struct ath12k_base * ab)3704 void ath12k_qmi_deinit_service(struct ath12k_base *ab)
3705 {
3706 if (!ab->qmi.ab)
3707 return;
3708
3709 qmi_handle_release(&ab->qmi.handle);
3710 cancel_work_sync(&ab->qmi.event_work);
3711 destroy_workqueue(ab->qmi.event_wq);
3712 ath12k_qmi_m3_free(ab);
3713 ath12k_qmi_free_target_mem_chunk(ab);
3714 ab->qmi.ab = NULL;
3715 }
3716
ath12k_qmi_free_resource(struct ath12k_base * ab)3717 void ath12k_qmi_free_resource(struct ath12k_base *ab)
3718 {
3719 ath12k_qmi_free_target_mem_chunk(ab);
3720 ath12k_qmi_m3_free(ab);
3721 }
3722