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