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