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