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