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