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