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