blob: 65d3c6ba35ae6c6d5ed87f20e080cd7939c6dd29 [file] [log] [blame]
Kalle Valod5c65152019-11-23 09:58:40 +02001// SPDX-License-Identifier: BSD-3-Clause-Clear
2/*
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4 */
5
Ben Greear616c16a2020-09-29 20:15:29 +03006#include <linux/elf.h>
7
Kalle Valod5c65152019-11-23 09:58:40 +02008#include "qmi.h"
9#include "core.h"
10#include "debug.h"
11#include <linux/of.h>
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +020012#include <linux/of_address.h>
13#include <linux/ioport.h>
Kalle Valod5c65152019-11-23 09:58:40 +020014#include <linux/firmware.h>
15
Carl Huang727fae12020-08-14 10:10:29 +030016#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
17#define HOST_CSTATE_BIT 0x04
18
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +053019bool ath11k_cold_boot_cal = 1;
20EXPORT_SYMBOL(ath11k_cold_boot_cal);
21module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644);
22MODULE_PARM_DESC(cold_boot_cal,
23 "Decrease the channel switch time but increase the driver load time (Default: true)");
24
Kalle Valod5c65152019-11-23 09:58:40 +020025static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
26 {
27 .data_type = QMI_OPT_FLAG,
28 .elem_len = 1,
29 .elem_size = sizeof(u8),
30 .array_type = NO_ARRAY,
31 .tlv_type = 0x10,
32 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
33 num_clients_valid),
34 },
35 {
36 .data_type = QMI_UNSIGNED_4_BYTE,
37 .elem_len = 1,
38 .elem_size = sizeof(u32),
39 .array_type = NO_ARRAY,
40 .tlv_type = 0x10,
41 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
42 num_clients),
43 },
44 {
45 .data_type = QMI_OPT_FLAG,
46 .elem_len = 1,
47 .elem_size = sizeof(u8),
48 .array_type = NO_ARRAY,
49 .tlv_type = 0x11,
50 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
51 wake_msi_valid),
52 },
53 {
54 .data_type = QMI_UNSIGNED_4_BYTE,
55 .elem_len = 1,
56 .elem_size = sizeof(u32),
57 .array_type = NO_ARRAY,
58 .tlv_type = 0x11,
59 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
60 wake_msi),
61 },
62 {
63 .data_type = QMI_OPT_FLAG,
64 .elem_len = 1,
65 .elem_size = sizeof(u8),
66 .array_type = NO_ARRAY,
67 .tlv_type = 0x12,
68 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
69 gpios_valid),
70 },
71 {
72 .data_type = QMI_DATA_LEN,
73 .elem_len = 1,
74 .elem_size = sizeof(u8),
75 .array_type = NO_ARRAY,
76 .tlv_type = 0x12,
77 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
78 gpios_len),
79 },
80 {
81 .data_type = QMI_UNSIGNED_4_BYTE,
82 .elem_len = QMI_WLFW_MAX_NUM_GPIO_V01,
83 .elem_size = sizeof(u32),
84 .array_type = VAR_LEN_ARRAY,
85 .tlv_type = 0x12,
86 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
87 gpios),
88 },
89 {
90 .data_type = QMI_OPT_FLAG,
91 .elem_len = 1,
92 .elem_size = sizeof(u8),
93 .array_type = NO_ARRAY,
94 .tlv_type = 0x13,
95 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
96 nm_modem_valid),
97 },
98 {
99 .data_type = QMI_UNSIGNED_1_BYTE,
100 .elem_len = 1,
101 .elem_size = sizeof(u8),
102 .array_type = NO_ARRAY,
103 .tlv_type = 0x13,
104 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
105 nm_modem),
106 },
107 {
108 .data_type = QMI_OPT_FLAG,
109 .elem_len = 1,
110 .elem_size = sizeof(u8),
111 .array_type = NO_ARRAY,
112 .tlv_type = 0x14,
113 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
114 bdf_support_valid),
115 },
116 {
117 .data_type = QMI_UNSIGNED_1_BYTE,
118 .elem_len = 1,
119 .elem_size = sizeof(u8),
120 .array_type = NO_ARRAY,
121 .tlv_type = 0x14,
122 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
123 bdf_support),
124 },
125 {
126 .data_type = QMI_OPT_FLAG,
127 .elem_len = 1,
128 .elem_size = sizeof(u8),
129 .array_type = NO_ARRAY,
130 .tlv_type = 0x15,
131 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
132 bdf_cache_support_valid),
133 },
134 {
135 .data_type = QMI_UNSIGNED_1_BYTE,
136 .elem_len = 1,
137 .elem_size = sizeof(u8),
138 .array_type = NO_ARRAY,
139 .tlv_type = 0x15,
140 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
141 bdf_cache_support),
142 },
143 {
144 .data_type = QMI_OPT_FLAG,
145 .elem_len = 1,
146 .elem_size = sizeof(u8),
147 .array_type = NO_ARRAY,
148 .tlv_type = 0x16,
149 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
150 m3_support_valid),
151 },
152 {
153 .data_type = QMI_UNSIGNED_1_BYTE,
154 .elem_len = 1,
155 .elem_size = sizeof(u8),
156 .array_type = NO_ARRAY,
157 .tlv_type = 0x16,
158 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
159 m3_support),
160 },
161 {
162 .data_type = QMI_OPT_FLAG,
163 .elem_len = 1,
164 .elem_size = sizeof(u8),
165 .array_type = NO_ARRAY,
166 .tlv_type = 0x17,
167 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
168 m3_cache_support_valid),
169 },
170 {
171 .data_type = QMI_UNSIGNED_1_BYTE,
172 .elem_len = 1,
173 .elem_size = sizeof(u8),
174 .array_type = NO_ARRAY,
175 .tlv_type = 0x17,
176 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
177 m3_cache_support),
178 },
179 {
180 .data_type = QMI_OPT_FLAG,
181 .elem_len = 1,
182 .elem_size = sizeof(u8),
183 .array_type = NO_ARRAY,
184 .tlv_type = 0x18,
185 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
186 cal_filesys_support_valid),
187 },
188 {
189 .data_type = QMI_UNSIGNED_1_BYTE,
190 .elem_len = 1,
191 .elem_size = sizeof(u8),
192 .array_type = NO_ARRAY,
193 .tlv_type = 0x18,
194 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
195 cal_filesys_support),
196 },
197 {
198 .data_type = QMI_OPT_FLAG,
199 .elem_len = 1,
200 .elem_size = sizeof(u8),
201 .array_type = NO_ARRAY,
202 .tlv_type = 0x19,
203 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
204 cal_cache_support_valid),
205 },
206 {
207 .data_type = QMI_UNSIGNED_1_BYTE,
208 .elem_len = 1,
209 .elem_size = sizeof(u8),
210 .array_type = NO_ARRAY,
211 .tlv_type = 0x19,
212 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
213 cal_cache_support),
214 },
215 {
216 .data_type = QMI_OPT_FLAG,
217 .elem_len = 1,
218 .elem_size = sizeof(u8),
219 .array_type = NO_ARRAY,
220 .tlv_type = 0x1A,
221 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
222 cal_done_valid),
223 },
224 {
225 .data_type = QMI_UNSIGNED_1_BYTE,
226 .elem_len = 1,
227 .elem_size = sizeof(u8),
228 .array_type = NO_ARRAY,
229 .tlv_type = 0x1A,
230 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
231 cal_done),
232 },
233 {
234 .data_type = QMI_OPT_FLAG,
235 .elem_len = 1,
236 .elem_size = sizeof(u8),
237 .array_type = NO_ARRAY,
238 .tlv_type = 0x1B,
239 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
240 mem_bucket_valid),
241 },
242 {
243 .data_type = QMI_UNSIGNED_4_BYTE,
244 .elem_len = 1,
245 .elem_size = sizeof(u32),
246 .array_type = NO_ARRAY,
247 .tlv_type = 0x1B,
248 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
249 mem_bucket),
250 },
251 {
252 .data_type = QMI_OPT_FLAG,
253 .elem_len = 1,
254 .elem_size = sizeof(u8),
255 .array_type = NO_ARRAY,
256 .tlv_type = 0x1C,
257 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
258 mem_cfg_mode_valid),
259 },
260 {
261 .data_type = QMI_UNSIGNED_1_BYTE,
262 .elem_len = 1,
263 .elem_size = sizeof(u8),
264 .array_type = NO_ARRAY,
265 .tlv_type = 0x1C,
266 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
267 mem_cfg_mode),
268 },
269 {
270 .data_type = QMI_EOTI,
271 .array_type = NO_ARRAY,
272 .tlv_type = QMI_COMMON_TLV_TYPE,
273 },
274};
275
276static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
277 {
278 .data_type = QMI_STRUCT,
279 .elem_len = 1,
280 .elem_size = sizeof(struct qmi_response_type_v01),
281 .array_type = NO_ARRAY,
282 .tlv_type = 0x02,
283 .offset = offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
284 .ei_array = qmi_response_type_v01_ei,
285 },
286 {
287 .data_type = QMI_EOTI,
288 .array_type = NO_ARRAY,
289 .tlv_type = QMI_COMMON_TLV_TYPE,
290 },
291};
292
293static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
294 {
295 .data_type = QMI_OPT_FLAG,
296 .elem_len = 1,
297 .elem_size = sizeof(u8),
298 .array_type = NO_ARRAY,
299 .tlv_type = 0x10,
300 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
301 fw_ready_enable_valid),
302 },
303 {
304 .data_type = QMI_UNSIGNED_1_BYTE,
305 .elem_len = 1,
306 .elem_size = sizeof(u8),
307 .array_type = NO_ARRAY,
308 .tlv_type = 0x10,
309 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
310 fw_ready_enable),
311 },
312 {
313 .data_type = QMI_OPT_FLAG,
314 .elem_len = 1,
315 .elem_size = sizeof(u8),
316 .array_type = NO_ARRAY,
317 .tlv_type = 0x11,
318 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
319 initiate_cal_download_enable_valid),
320 },
321 {
322 .data_type = QMI_UNSIGNED_1_BYTE,
323 .elem_len = 1,
324 .elem_size = sizeof(u8),
325 .array_type = NO_ARRAY,
326 .tlv_type = 0x11,
327 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
328 initiate_cal_download_enable),
329 },
330 {
331 .data_type = QMI_OPT_FLAG,
332 .elem_len = 1,
333 .elem_size = sizeof(u8),
334 .array_type = NO_ARRAY,
335 .tlv_type = 0x12,
336 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
337 initiate_cal_update_enable_valid),
338 },
339 {
340 .data_type = QMI_UNSIGNED_1_BYTE,
341 .elem_len = 1,
342 .elem_size = sizeof(u8),
343 .array_type = NO_ARRAY,
344 .tlv_type = 0x12,
345 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
346 initiate_cal_update_enable),
347 },
348 {
349 .data_type = QMI_OPT_FLAG,
350 .elem_len = 1,
351 .elem_size = sizeof(u8),
352 .array_type = NO_ARRAY,
353 .tlv_type = 0x13,
354 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
355 msa_ready_enable_valid),
356 },
357 {
358 .data_type = QMI_UNSIGNED_1_BYTE,
359 .elem_len = 1,
360 .elem_size = sizeof(u8),
361 .array_type = NO_ARRAY,
362 .tlv_type = 0x13,
363 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
364 msa_ready_enable),
365 },
366 {
367 .data_type = QMI_OPT_FLAG,
368 .elem_len = 1,
369 .elem_size = sizeof(u8),
370 .array_type = NO_ARRAY,
371 .tlv_type = 0x14,
372 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
373 pin_connect_result_enable_valid),
374 },
375 {
376 .data_type = QMI_UNSIGNED_1_BYTE,
377 .elem_len = 1,
378 .elem_size = sizeof(u8),
379 .array_type = NO_ARRAY,
380 .tlv_type = 0x14,
381 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
382 pin_connect_result_enable),
383 },
384 {
385 .data_type = QMI_OPT_FLAG,
386 .elem_len = 1,
387 .elem_size = sizeof(u8),
388 .array_type = NO_ARRAY,
389 .tlv_type = 0x15,
390 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
391 client_id_valid),
392 },
393 {
394 .data_type = QMI_UNSIGNED_4_BYTE,
395 .elem_len = 1,
396 .elem_size = sizeof(u32),
397 .array_type = NO_ARRAY,
398 .tlv_type = 0x15,
399 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
400 client_id),
401 },
402 {
403 .data_type = QMI_OPT_FLAG,
404 .elem_len = 1,
405 .elem_size = sizeof(u8),
406 .array_type = NO_ARRAY,
407 .tlv_type = 0x16,
408 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
409 request_mem_enable_valid),
410 },
411 {
412 .data_type = QMI_UNSIGNED_1_BYTE,
413 .elem_len = 1,
414 .elem_size = sizeof(u8),
415 .array_type = NO_ARRAY,
416 .tlv_type = 0x16,
417 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
418 request_mem_enable),
419 },
420 {
421 .data_type = QMI_OPT_FLAG,
422 .elem_len = 1,
423 .elem_size = sizeof(u8),
424 .array_type = NO_ARRAY,
425 .tlv_type = 0x17,
426 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
427 fw_mem_ready_enable_valid),
428 },
429 {
430 .data_type = QMI_UNSIGNED_1_BYTE,
431 .elem_len = 1,
432 .elem_size = sizeof(u8),
433 .array_type = NO_ARRAY,
434 .tlv_type = 0x17,
435 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
436 fw_mem_ready_enable),
437 },
438 {
439 .data_type = QMI_OPT_FLAG,
440 .elem_len = 1,
441 .elem_size = sizeof(u8),
442 .array_type = NO_ARRAY,
443 .tlv_type = 0x18,
444 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
445 fw_init_done_enable_valid),
446 },
447 {
448 .data_type = QMI_UNSIGNED_1_BYTE,
449 .elem_len = 1,
450 .elem_size = sizeof(u8),
451 .array_type = NO_ARRAY,
452 .tlv_type = 0x18,
453 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
454 fw_init_done_enable),
455 },
456
457 {
458 .data_type = QMI_OPT_FLAG,
459 .elem_len = 1,
460 .elem_size = sizeof(u8),
461 .array_type = NO_ARRAY,
462 .tlv_type = 0x19,
463 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
464 rejuvenate_enable_valid),
465 },
466 {
467 .data_type = QMI_UNSIGNED_1_BYTE,
468 .elem_len = 1,
469 .elem_size = sizeof(u8),
470 .array_type = NO_ARRAY,
471 .tlv_type = 0x19,
472 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
473 rejuvenate_enable),
474 },
475 {
476 .data_type = QMI_OPT_FLAG,
477 .elem_len = 1,
478 .elem_size = sizeof(u8),
479 .array_type = NO_ARRAY,
480 .tlv_type = 0x1A,
481 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
482 xo_cal_enable_valid),
483 },
484 {
485 .data_type = QMI_UNSIGNED_1_BYTE,
486 .elem_len = 1,
487 .elem_size = sizeof(u8),
488 .array_type = NO_ARRAY,
489 .tlv_type = 0x1A,
490 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
491 xo_cal_enable),
492 },
493 {
494 .data_type = QMI_OPT_FLAG,
495 .elem_len = 1,
496 .elem_size = sizeof(u8),
497 .array_type = NO_ARRAY,
498 .tlv_type = 0x1B,
499 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
500 cal_done_enable_valid),
501 },
502 {
503 .data_type = QMI_UNSIGNED_1_BYTE,
504 .elem_len = 1,
505 .elem_size = sizeof(u8),
506 .array_type = NO_ARRAY,
507 .tlv_type = 0x1B,
508 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
509 cal_done_enable),
510 },
511 {
512 .data_type = QMI_EOTI,
513 .array_type = NO_ARRAY,
514 .tlv_type = QMI_COMMON_TLV_TYPE,
515 },
516};
517
518static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
519 {
520 .data_type = QMI_STRUCT,
521 .elem_len = 1,
522 .elem_size = sizeof(struct qmi_response_type_v01),
523 .array_type = NO_ARRAY,
524 .tlv_type = 0x02,
525 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
526 resp),
527 .ei_array = qmi_response_type_v01_ei,
528 },
529 {
530 .data_type = QMI_OPT_FLAG,
531 .elem_len = 1,
532 .elem_size = sizeof(u8),
533 .array_type = NO_ARRAY,
534 .tlv_type = 0x10,
535 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
536 fw_status_valid),
537 },
538 {
539 .data_type = QMI_UNSIGNED_8_BYTE,
540 .elem_len = 1,
541 .elem_size = sizeof(u64),
542 .array_type = NO_ARRAY,
543 .tlv_type = 0x10,
544 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
545 fw_status),
546 },
547 {
548 .data_type = QMI_EOTI,
549 .array_type = NO_ARRAY,
550 .tlv_type = QMI_COMMON_TLV_TYPE,
551 },
552};
553
554static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
555 {
556 .data_type = QMI_UNSIGNED_8_BYTE,
557 .elem_len = 1,
558 .elem_size = sizeof(u64),
559 .array_type = NO_ARRAY,
560 .tlv_type = 0,
561 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
562 },
563 {
564 .data_type = QMI_UNSIGNED_4_BYTE,
565 .elem_len = 1,
566 .elem_size = sizeof(u32),
567 .array_type = NO_ARRAY,
568 .tlv_type = 0,
569 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
570 },
571 {
572 .data_type = QMI_UNSIGNED_1_BYTE,
573 .elem_len = 1,
574 .elem_size = sizeof(u8),
575 .array_type = NO_ARRAY,
576 .tlv_type = 0,
577 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
578 },
579 {
580 .data_type = QMI_EOTI,
581 .array_type = NO_ARRAY,
582 .tlv_type = QMI_COMMON_TLV_TYPE,
583 },
584};
585
586static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
587 {
588 .data_type = QMI_UNSIGNED_4_BYTE,
589 .elem_len = 1,
590 .elem_size = sizeof(u32),
591 .array_type = NO_ARRAY,
592 .tlv_type = 0,
593 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01,
594 size),
595 },
596 {
597 .data_type = QMI_SIGNED_4_BYTE_ENUM,
598 .elem_len = 1,
599 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
600 .array_type = NO_ARRAY,
601 .tlv_type = 0,
602 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
603 },
604 {
605 .data_type = QMI_DATA_LEN,
606 .elem_len = 1,
607 .elem_size = sizeof(u8),
608 .array_type = NO_ARRAY,
609 .tlv_type = 0,
610 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
611 },
612 {
613 .data_type = QMI_STRUCT,
614 .elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
615 .elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
616 .array_type = VAR_LEN_ARRAY,
617 .tlv_type = 0,
618 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
619 .ei_array = qmi_wlanfw_mem_cfg_s_v01_ei,
620 },
621 {
622 .data_type = QMI_EOTI,
623 .array_type = NO_ARRAY,
624 .tlv_type = QMI_COMMON_TLV_TYPE,
625 },
626};
627
628static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
629 {
630 .data_type = QMI_DATA_LEN,
631 .elem_len = 1,
632 .elem_size = sizeof(u8),
633 .array_type = NO_ARRAY,
634 .tlv_type = 0x01,
635 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
636 mem_seg_len),
637 },
638 {
639 .data_type = QMI_STRUCT,
640 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
641 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01),
642 .array_type = VAR_LEN_ARRAY,
643 .tlv_type = 0x01,
644 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
645 mem_seg),
646 .ei_array = qmi_wlanfw_mem_seg_s_v01_ei,
647 },
648 {
649 .data_type = QMI_EOTI,
650 .array_type = NO_ARRAY,
651 .tlv_type = QMI_COMMON_TLV_TYPE,
652 },
653};
654
655static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
656 {
657 .data_type = QMI_UNSIGNED_8_BYTE,
658 .elem_len = 1,
659 .elem_size = sizeof(u64),
660 .array_type = NO_ARRAY,
661 .tlv_type = 0,
662 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
663 },
664 {
665 .data_type = QMI_UNSIGNED_4_BYTE,
666 .elem_len = 1,
667 .elem_size = sizeof(u32),
668 .array_type = NO_ARRAY,
669 .tlv_type = 0,
670 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
671 },
672 {
673 .data_type = QMI_SIGNED_4_BYTE_ENUM,
674 .elem_len = 1,
675 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
676 .array_type = NO_ARRAY,
677 .tlv_type = 0,
678 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
679 },
680 {
681 .data_type = QMI_UNSIGNED_1_BYTE,
682 .elem_len = 1,
683 .elem_size = sizeof(u8),
684 .array_type = NO_ARRAY,
685 .tlv_type = 0,
686 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
687 },
688 {
689 .data_type = QMI_EOTI,
690 .array_type = NO_ARRAY,
691 .tlv_type = QMI_COMMON_TLV_TYPE,
692 },
693};
694
695static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
696 {
697 .data_type = QMI_DATA_LEN,
698 .elem_len = 1,
699 .elem_size = sizeof(u8),
700 .array_type = NO_ARRAY,
701 .tlv_type = 0x01,
702 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
703 mem_seg_len),
704 },
705 {
706 .data_type = QMI_STRUCT,
707 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
708 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
709 .array_type = VAR_LEN_ARRAY,
710 .tlv_type = 0x01,
711 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
712 mem_seg),
713 .ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei,
714 },
715 {
716 .data_type = QMI_EOTI,
717 .array_type = NO_ARRAY,
718 .tlv_type = QMI_COMMON_TLV_TYPE,
719 },
720};
721
722static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
723 {
724 .data_type = QMI_STRUCT,
725 .elem_len = 1,
726 .elem_size = sizeof(struct qmi_response_type_v01),
727 .array_type = NO_ARRAY,
728 .tlv_type = 0x02,
729 .offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
730 resp),
731 .ei_array = qmi_response_type_v01_ei,
732 },
733 {
734 .data_type = QMI_EOTI,
735 .array_type = NO_ARRAY,
736 .tlv_type = QMI_COMMON_TLV_TYPE,
737 },
738};
739
740static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
741 {
742 .data_type = QMI_EOTI,
743 .array_type = NO_ARRAY,
744 .tlv_type = QMI_COMMON_TLV_TYPE,
745 },
746};
747
748static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
749 {
750 .data_type = QMI_UNSIGNED_4_BYTE,
751 .elem_len = 1,
752 .elem_size = sizeof(u32),
753 .array_type = NO_ARRAY,
754 .tlv_type = 0,
755 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
756 chip_id),
757 },
758 {
759 .data_type = QMI_UNSIGNED_4_BYTE,
760 .elem_len = 1,
761 .elem_size = sizeof(u32),
762 .array_type = NO_ARRAY,
763 .tlv_type = 0,
764 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
765 chip_family),
766 },
767 {
768 .data_type = QMI_EOTI,
769 .array_type = NO_ARRAY,
770 .tlv_type = QMI_COMMON_TLV_TYPE,
771 },
772};
773
774static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
775 {
776 .data_type = QMI_UNSIGNED_4_BYTE,
777 .elem_len = 1,
778 .elem_size = sizeof(u32),
779 .array_type = NO_ARRAY,
780 .tlv_type = 0,
781 .offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
782 board_id),
783 },
784 {
785 .data_type = QMI_EOTI,
786 .array_type = NO_ARRAY,
787 .tlv_type = QMI_COMMON_TLV_TYPE,
788 },
789};
790
791static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
792 {
793 .data_type = QMI_UNSIGNED_4_BYTE,
794 .elem_len = 1,
795 .elem_size = sizeof(u32),
796 .array_type = NO_ARRAY,
797 .tlv_type = 0,
798 .offset = offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
799 },
800 {
801 .data_type = QMI_EOTI,
802 .array_type = NO_ARRAY,
803 .tlv_type = QMI_COMMON_TLV_TYPE,
804 },
805};
806
807static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
808 {
809 .data_type = QMI_UNSIGNED_4_BYTE,
810 .elem_len = 1,
811 .elem_size = sizeof(u32),
812 .array_type = NO_ARRAY,
813 .tlv_type = 0,
814 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
815 fw_version),
816 },
817 {
818 .data_type = QMI_STRING,
819 .elem_len = ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
820 .elem_size = sizeof(char),
821 .array_type = NO_ARRAY,
822 .tlv_type = 0,
823 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
824 fw_build_timestamp),
825 },
826 {
827 .data_type = QMI_EOTI,
828 .array_type = NO_ARRAY,
829 .tlv_type = QMI_COMMON_TLV_TYPE,
830 },
831};
832
833static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
834 {
835 .data_type = QMI_STRUCT,
836 .elem_len = 1,
837 .elem_size = sizeof(struct qmi_response_type_v01),
838 .array_type = NO_ARRAY,
839 .tlv_type = 0x02,
840 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
841 .ei_array = qmi_response_type_v01_ei,
842 },
843 {
844 .data_type = QMI_OPT_FLAG,
845 .elem_len = 1,
846 .elem_size = sizeof(u8),
847 .array_type = NO_ARRAY,
848 .tlv_type = 0x10,
849 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
850 chip_info_valid),
851 },
852 {
853 .data_type = QMI_STRUCT,
854 .elem_len = 1,
855 .elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
856 .array_type = NO_ARRAY,
857 .tlv_type = 0x10,
858 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
859 chip_info),
860 .ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei,
861 },
862 {
863 .data_type = QMI_OPT_FLAG,
864 .elem_len = 1,
865 .elem_size = sizeof(u8),
866 .array_type = NO_ARRAY,
867 .tlv_type = 0x11,
868 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
869 board_info_valid),
870 },
871 {
872 .data_type = QMI_STRUCT,
873 .elem_len = 1,
874 .elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
875 .array_type = NO_ARRAY,
876 .tlv_type = 0x11,
877 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
878 board_info),
879 .ei_array = qmi_wlanfw_rf_board_info_s_v01_ei,
880 },
881 {
882 .data_type = QMI_OPT_FLAG,
883 .elem_len = 1,
884 .elem_size = sizeof(u8),
885 .array_type = NO_ARRAY,
886 .tlv_type = 0x12,
887 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
888 soc_info_valid),
889 },
890 {
891 .data_type = QMI_STRUCT,
892 .elem_len = 1,
893 .elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01),
894 .array_type = NO_ARRAY,
895 .tlv_type = 0x12,
896 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
897 soc_info),
898 .ei_array = qmi_wlanfw_soc_info_s_v01_ei,
899 },
900 {
901 .data_type = QMI_OPT_FLAG,
902 .elem_len = 1,
903 .elem_size = sizeof(u8),
904 .array_type = NO_ARRAY,
905 .tlv_type = 0x13,
906 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
907 fw_version_info_valid),
908 },
909 {
910 .data_type = QMI_STRUCT,
911 .elem_len = 1,
912 .elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
913 .array_type = NO_ARRAY,
914 .tlv_type = 0x13,
915 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
916 fw_version_info),
917 .ei_array = qmi_wlanfw_fw_version_info_s_v01_ei,
918 },
919 {
920 .data_type = QMI_OPT_FLAG,
921 .elem_len = 1,
922 .elem_size = sizeof(u8),
923 .array_type = NO_ARRAY,
924 .tlv_type = 0x14,
925 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
926 fw_build_id_valid),
927 },
928 {
929 .data_type = QMI_STRING,
930 .elem_len = ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
931 .elem_size = sizeof(char),
932 .array_type = NO_ARRAY,
933 .tlv_type = 0x14,
934 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
935 fw_build_id),
936 },
937 {
938 .data_type = QMI_OPT_FLAG,
939 .elem_len = 1,
940 .elem_size = sizeof(u8),
941 .array_type = NO_ARRAY,
942 .tlv_type = 0x15,
943 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
944 num_macs_valid),
945 },
946 {
947 .data_type = QMI_UNSIGNED_1_BYTE,
948 .elem_len = 1,
949 .elem_size = sizeof(u8),
950 .array_type = NO_ARRAY,
951 .tlv_type = 0x15,
952 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
953 num_macs),
954 },
955 {
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +0300956 .data_type = QMI_OPT_FLAG,
957 .elem_len = 1,
958 .elem_size = sizeof(u8),
959 .array_type = NO_ARRAY,
960 .tlv_type = 0x16,
961 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
962 voltage_mv_valid),
963 },
964 {
965 .data_type = QMI_UNSIGNED_4_BYTE,
966 .elem_len = 1,
967 .elem_size = sizeof(u32),
968 .array_type = NO_ARRAY,
969 .tlv_type = 0x16,
970 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
971 voltage_mv),
972 },
973 {
974 .data_type = QMI_OPT_FLAG,
975 .elem_len = 1,
976 .elem_size = sizeof(u8),
977 .array_type = NO_ARRAY,
978 .tlv_type = 0x17,
979 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
980 time_freq_hz_valid),
981 },
982 {
983 .data_type = QMI_UNSIGNED_4_BYTE,
984 .elem_len = 1,
985 .elem_size = sizeof(u32),
986 .array_type = NO_ARRAY,
987 .tlv_type = 0x17,
988 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
989 time_freq_hz),
990 },
991 {
992 .data_type = QMI_OPT_FLAG,
993 .elem_len = 1,
994 .elem_size = sizeof(u8),
995 .array_type = NO_ARRAY,
996 .tlv_type = 0x18,
997 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
998 otp_version_valid),
999 },
1000 {
1001 .data_type = QMI_UNSIGNED_4_BYTE,
1002 .elem_len = 1,
1003 .elem_size = sizeof(u32),
1004 .array_type = NO_ARRAY,
1005 .tlv_type = 0x18,
1006 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1007 otp_version),
1008 },
1009 {
1010 .data_type = QMI_OPT_FLAG,
1011 .elem_len = 1,
1012 .elem_size = sizeof(u8),
1013 .array_type = NO_ARRAY,
1014 .tlv_type = 0x19,
1015 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1016 eeprom_read_timeout_valid),
1017 },
1018 {
1019 .data_type = QMI_UNSIGNED_4_BYTE,
1020 .elem_len = 1,
1021 .elem_size = sizeof(u32),
1022 .array_type = NO_ARRAY,
1023 .tlv_type = 0x19,
1024 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
1025 eeprom_read_timeout),
1026 },
1027 {
Kalle Valod5c65152019-11-23 09:58:40 +02001028 .data_type = QMI_EOTI,
1029 .array_type = NO_ARRAY,
1030 .tlv_type = QMI_COMMON_TLV_TYPE,
1031 },
1032};
1033
1034static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
1035 {
1036 .data_type = QMI_UNSIGNED_1_BYTE,
1037 .elem_len = 1,
1038 .elem_size = sizeof(u8),
1039 .array_type = NO_ARRAY,
1040 .tlv_type = 0x01,
1041 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1042 valid),
1043 },
1044 {
1045 .data_type = QMI_OPT_FLAG,
1046 .elem_len = 1,
1047 .elem_size = sizeof(u8),
1048 .array_type = NO_ARRAY,
1049 .tlv_type = 0x10,
1050 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1051 file_id_valid),
1052 },
1053 {
1054 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1055 .elem_len = 1,
1056 .elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
1057 .array_type = NO_ARRAY,
1058 .tlv_type = 0x10,
1059 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1060 file_id),
1061 },
1062 {
1063 .data_type = QMI_OPT_FLAG,
1064 .elem_len = 1,
1065 .elem_size = sizeof(u8),
1066 .array_type = NO_ARRAY,
1067 .tlv_type = 0x11,
1068 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1069 total_size_valid),
1070 },
1071 {
1072 .data_type = QMI_UNSIGNED_4_BYTE,
1073 .elem_len = 1,
1074 .elem_size = sizeof(u32),
1075 .array_type = NO_ARRAY,
1076 .tlv_type = 0x11,
1077 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1078 total_size),
1079 },
1080 {
1081 .data_type = QMI_OPT_FLAG,
1082 .elem_len = 1,
1083 .elem_size = sizeof(u8),
1084 .array_type = NO_ARRAY,
1085 .tlv_type = 0x12,
1086 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1087 seg_id_valid),
1088 },
1089 {
1090 .data_type = QMI_UNSIGNED_4_BYTE,
1091 .elem_len = 1,
1092 .elem_size = sizeof(u32),
1093 .array_type = NO_ARRAY,
1094 .tlv_type = 0x12,
1095 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1096 seg_id),
1097 },
1098 {
1099 .data_type = QMI_OPT_FLAG,
1100 .elem_len = 1,
1101 .elem_size = sizeof(u8),
1102 .array_type = NO_ARRAY,
1103 .tlv_type = 0x13,
1104 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1105 data_valid),
1106 },
1107 {
1108 .data_type = QMI_DATA_LEN,
1109 .elem_len = 1,
1110 .elem_size = sizeof(u16),
1111 .array_type = NO_ARRAY,
1112 .tlv_type = 0x13,
1113 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1114 data_len),
1115 },
1116 {
1117 .data_type = QMI_UNSIGNED_1_BYTE,
1118 .elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01,
1119 .elem_size = sizeof(u8),
1120 .array_type = VAR_LEN_ARRAY,
1121 .tlv_type = 0x13,
1122 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1123 data),
1124 },
1125 {
1126 .data_type = QMI_OPT_FLAG,
1127 .elem_len = 1,
1128 .elem_size = sizeof(u8),
1129 .array_type = NO_ARRAY,
1130 .tlv_type = 0x14,
1131 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1132 end_valid),
1133 },
1134 {
1135 .data_type = QMI_UNSIGNED_1_BYTE,
1136 .elem_len = 1,
1137 .elem_size = sizeof(u8),
1138 .array_type = NO_ARRAY,
1139 .tlv_type = 0x14,
1140 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1141 end),
1142 },
1143 {
1144 .data_type = QMI_OPT_FLAG,
1145 .elem_len = 1,
1146 .elem_size = sizeof(u8),
1147 .array_type = NO_ARRAY,
1148 .tlv_type = 0x15,
1149 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1150 bdf_type_valid),
1151 },
1152 {
1153 .data_type = QMI_UNSIGNED_1_BYTE,
1154 .elem_len = 1,
1155 .elem_size = sizeof(u8),
1156 .array_type = NO_ARRAY,
1157 .tlv_type = 0x15,
1158 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1159 bdf_type),
1160 },
1161
1162 {
1163 .data_type = QMI_EOTI,
1164 .array_type = NO_ARRAY,
1165 .tlv_type = QMI_COMMON_TLV_TYPE,
1166 },
1167};
1168
1169static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1170 {
1171 .data_type = QMI_STRUCT,
1172 .elem_len = 1,
1173 .elem_size = sizeof(struct qmi_response_type_v01),
1174 .array_type = NO_ARRAY,
1175 .tlv_type = 0x02,
1176 .offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1177 resp),
1178 .ei_array = qmi_response_type_v01_ei,
1179 },
1180 {
1181 .data_type = QMI_EOTI,
1182 .array_type = NO_ARRAY,
1183 .tlv_type = QMI_COMMON_TLV_TYPE,
1184 },
1185};
1186
1187static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1188 {
1189 .data_type = QMI_UNSIGNED_8_BYTE,
1190 .elem_len = 1,
1191 .elem_size = sizeof(u64),
1192 .array_type = NO_ARRAY,
1193 .tlv_type = 0x01,
1194 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1195 },
1196 {
1197 .data_type = QMI_UNSIGNED_4_BYTE,
1198 .elem_len = 1,
1199 .elem_size = sizeof(u32),
1200 .array_type = NO_ARRAY,
1201 .tlv_type = 0x02,
1202 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1203 },
1204 {
1205 .data_type = QMI_EOTI,
1206 .array_type = NO_ARRAY,
1207 .tlv_type = QMI_COMMON_TLV_TYPE,
1208 },
1209};
1210
1211static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1212 {
1213 .data_type = QMI_STRUCT,
1214 .elem_len = 1,
1215 .elem_size = sizeof(struct qmi_response_type_v01),
1216 .array_type = NO_ARRAY,
1217 .tlv_type = 0x02,
1218 .offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1219 .ei_array = qmi_response_type_v01_ei,
1220 },
1221 {
1222 .data_type = QMI_EOTI,
1223 .array_type = NO_ARRAY,
1224 .tlv_type = QMI_COMMON_TLV_TYPE,
1225 },
1226};
1227
1228static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
1229 {
1230 .data_type = QMI_UNSIGNED_4_BYTE,
1231 .elem_len = 1,
1232 .elem_size = sizeof(u32),
1233 .array_type = NO_ARRAY,
1234 .tlv_type = 0,
1235 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1236 pipe_num),
1237 },
1238 {
1239 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1240 .elem_len = 1,
1241 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1242 .array_type = NO_ARRAY,
1243 .tlv_type = 0,
1244 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1245 pipe_dir),
1246 },
1247 {
1248 .data_type = QMI_UNSIGNED_4_BYTE,
1249 .elem_len = 1,
1250 .elem_size = sizeof(u32),
1251 .array_type = NO_ARRAY,
1252 .tlv_type = 0,
1253 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1254 nentries),
1255 },
1256 {
1257 .data_type = QMI_UNSIGNED_4_BYTE,
1258 .elem_len = 1,
1259 .elem_size = sizeof(u32),
1260 .array_type = NO_ARRAY,
1261 .tlv_type = 0,
1262 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1263 nbytes_max),
1264 },
1265 {
1266 .data_type = QMI_UNSIGNED_4_BYTE,
1267 .elem_len = 1,
1268 .elem_size = sizeof(u32),
1269 .array_type = NO_ARRAY,
1270 .tlv_type = 0,
1271 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1272 flags),
1273 },
1274 {
1275 .data_type = QMI_EOTI,
1276 .array_type = NO_ARRAY,
1277 .tlv_type = QMI_COMMON_TLV_TYPE,
1278 },
1279};
1280
1281static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
1282 {
1283 .data_type = QMI_UNSIGNED_4_BYTE,
1284 .elem_len = 1,
1285 .elem_size = sizeof(u32),
1286 .array_type = NO_ARRAY,
1287 .tlv_type = 0,
1288 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1289 service_id),
1290 },
1291 {
1292 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1293 .elem_len = 1,
1294 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1295 .array_type = NO_ARRAY,
1296 .tlv_type = 0,
1297 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1298 pipe_dir),
1299 },
1300 {
1301 .data_type = QMI_UNSIGNED_4_BYTE,
1302 .elem_len = 1,
1303 .elem_size = sizeof(u32),
1304 .array_type = NO_ARRAY,
1305 .tlv_type = 0,
1306 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1307 pipe_num),
1308 },
1309 {
1310 .data_type = QMI_EOTI,
1311 .array_type = NO_ARRAY,
1312 .tlv_type = QMI_COMMON_TLV_TYPE,
1313 },
1314};
1315
1316static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1317 {
1318 .data_type = QMI_UNSIGNED_2_BYTE,
1319 .elem_len = 1,
1320 .elem_size = sizeof(u16),
1321 .array_type = NO_ARRAY,
1322 .tlv_type = 0,
1323 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1324 },
1325 {
1326 .data_type = QMI_UNSIGNED_2_BYTE,
1327 .elem_len = 1,
1328 .elem_size = sizeof(u16),
1329 .array_type = NO_ARRAY,
1330 .tlv_type = 0,
1331 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1332 offset),
1333 },
1334 {
1335 .data_type = QMI_EOTI,
1336 .array_type = QMI_COMMON_TLV_TYPE,
1337 },
1338};
1339
1340static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {
1341 {
1342 .data_type = QMI_UNSIGNED_4_BYTE,
1343 .elem_len = 1,
1344 .elem_size = sizeof(u32),
1345 .array_type = NO_ARRAY,
1346 .tlv_type = 0,
1347 .offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,
1348 addr),
1349 },
1350 {
1351 .data_type = QMI_EOTI,
1352 .array_type = NO_ARRAY,
1353 .tlv_type = QMI_COMMON_TLV_TYPE,
1354 },
1355};
1356
1357static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1358 {
1359 .data_type = QMI_UNSIGNED_4_BYTE,
1360 .elem_len = 1,
1361 .elem_size = sizeof(u32),
1362 .array_type = NO_ARRAY,
1363 .tlv_type = 0x01,
1364 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1365 mode),
1366 },
1367 {
1368 .data_type = QMI_OPT_FLAG,
1369 .elem_len = 1,
1370 .elem_size = sizeof(u8),
1371 .array_type = NO_ARRAY,
1372 .tlv_type = 0x10,
1373 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1374 hw_debug_valid),
1375 },
1376 {
1377 .data_type = QMI_UNSIGNED_1_BYTE,
1378 .elem_len = 1,
1379 .elem_size = sizeof(u8),
1380 .array_type = NO_ARRAY,
1381 .tlv_type = 0x10,
1382 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1383 hw_debug),
1384 },
1385 {
1386 .data_type = QMI_EOTI,
1387 .array_type = NO_ARRAY,
1388 .tlv_type = QMI_COMMON_TLV_TYPE,
1389 },
1390};
1391
1392static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1393 {
1394 .data_type = QMI_STRUCT,
1395 .elem_len = 1,
1396 .elem_size = sizeof(struct qmi_response_type_v01),
1397 .array_type = NO_ARRAY,
1398 .tlv_type = 0x02,
1399 .offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1400 resp),
1401 .ei_array = qmi_response_type_v01_ei,
1402 },
1403 {
1404 .data_type = QMI_EOTI,
1405 .array_type = NO_ARRAY,
1406 .tlv_type = QMI_COMMON_TLV_TYPE,
1407 },
1408};
1409
1410static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1411 {
1412 .data_type = QMI_OPT_FLAG,
1413 .elem_len = 1,
1414 .elem_size = sizeof(u8),
1415 .array_type = NO_ARRAY,
1416 .tlv_type = 0x10,
1417 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1418 host_version_valid),
1419 },
1420 {
1421 .data_type = QMI_STRING,
1422 .elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1423 .elem_size = sizeof(char),
1424 .array_type = NO_ARRAY,
1425 .tlv_type = 0x10,
1426 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1427 host_version),
1428 },
1429 {
1430 .data_type = QMI_OPT_FLAG,
1431 .elem_len = 1,
1432 .elem_size = sizeof(u8),
1433 .array_type = NO_ARRAY,
1434 .tlv_type = 0x11,
1435 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1436 tgt_cfg_valid),
1437 },
1438 {
1439 .data_type = QMI_DATA_LEN,
1440 .elem_len = 1,
1441 .elem_size = sizeof(u8),
1442 .array_type = NO_ARRAY,
1443 .tlv_type = 0x11,
1444 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1445 tgt_cfg_len),
1446 },
1447 {
1448 .data_type = QMI_STRUCT,
1449 .elem_len = QMI_WLANFW_MAX_NUM_CE_V01,
1450 .elem_size = sizeof(
1451 struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1452 .array_type = VAR_LEN_ARRAY,
1453 .tlv_type = 0x11,
1454 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1455 tgt_cfg),
1456 .ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1457 },
1458 {
1459 .data_type = QMI_OPT_FLAG,
1460 .elem_len = 1,
1461 .elem_size = sizeof(u8),
1462 .array_type = NO_ARRAY,
1463 .tlv_type = 0x12,
1464 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1465 svc_cfg_valid),
1466 },
1467 {
1468 .data_type = QMI_DATA_LEN,
1469 .elem_len = 1,
1470 .elem_size = sizeof(u8),
1471 .array_type = NO_ARRAY,
1472 .tlv_type = 0x12,
1473 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1474 svc_cfg_len),
1475 },
1476 {
1477 .data_type = QMI_STRUCT,
1478 .elem_len = QMI_WLANFW_MAX_NUM_SVC_V01,
1479 .elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1480 .array_type = VAR_LEN_ARRAY,
1481 .tlv_type = 0x12,
1482 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1483 svc_cfg),
1484 .ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1485 },
1486 {
1487 .data_type = QMI_OPT_FLAG,
1488 .elem_len = 1,
1489 .elem_size = sizeof(u8),
1490 .array_type = NO_ARRAY,
1491 .tlv_type = 0x13,
1492 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1493 shadow_reg_valid),
1494 },
1495 {
1496 .data_type = QMI_DATA_LEN,
1497 .elem_len = 1,
1498 .elem_size = sizeof(u8),
1499 .array_type = NO_ARRAY,
1500 .tlv_type = 0x13,
1501 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1502 shadow_reg_len),
1503 },
1504 {
1505 .data_type = QMI_STRUCT,
1506 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1507 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1508 .array_type = VAR_LEN_ARRAY,
1509 .tlv_type = 0x13,
1510 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1511 shadow_reg),
1512 .ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1513 },
1514 {
1515 .data_type = QMI_OPT_FLAG,
1516 .elem_len = 1,
1517 .elem_size = sizeof(u8),
1518 .array_type = NO_ARRAY,
1519 .tlv_type = 0x14,
1520 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1521 shadow_reg_v2_valid),
1522 },
1523 {
1524 .data_type = QMI_DATA_LEN,
1525 .elem_len = 1,
1526 .elem_size = sizeof(u8),
1527 .array_type = NO_ARRAY,
1528 .tlv_type = 0x14,
1529 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1530 shadow_reg_v2_len),
1531 },
1532 {
1533 .data_type = QMI_STRUCT,
1534 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,
1535 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),
1536 .array_type = VAR_LEN_ARRAY,
1537 .tlv_type = 0x14,
1538 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1539 shadow_reg_v2),
1540 .ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,
1541 },
1542 {
1543 .data_type = QMI_EOTI,
1544 .array_type = NO_ARRAY,
1545 .tlv_type = QMI_COMMON_TLV_TYPE,
1546 },
1547};
1548
1549static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1550 {
1551 .data_type = QMI_STRUCT,
1552 .elem_len = 1,
1553 .elem_size = sizeof(struct qmi_response_type_v01),
1554 .array_type = NO_ARRAY,
1555 .tlv_type = 0x02,
1556 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1557 .ei_array = qmi_response_type_v01_ei,
1558 },
1559 {
1560 .data_type = QMI_EOTI,
1561 .array_type = NO_ARRAY,
1562 .tlv_type = QMI_COMMON_TLV_TYPE,
1563 },
1564};
1565
1566static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1567 {
1568 .data_type = QMI_EOTI,
1569 .array_type = NO_ARRAY,
1570 },
1571};
1572
1573static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1574 {
1575 .data_type = QMI_EOTI,
1576 .array_type = NO_ARRAY,
1577 },
1578};
1579
1580static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {
1581 {
1582 .data_type = QMI_EOTI,
1583 .array_type = NO_ARRAY,
1584 },
1585};
1586
Cheng Wang42da1cc2021-12-20 20:10:53 +08001587static struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {
1588 {
1589 .data_type = QMI_OPT_FLAG,
1590 .elem_len = 1,
1591 .elem_size = sizeof(u8),
1592 .array_type = NO_ARRAY,
1593 .tlv_type = 0x10,
1594 .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1595 enablefwlog_valid),
1596 },
1597 {
1598 .data_type = QMI_UNSIGNED_1_BYTE,
1599 .elem_len = 1,
1600 .elem_size = sizeof(u8),
1601 .array_type = NO_ARRAY,
1602 .tlv_type = 0x10,
1603 .offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,
1604 enablefwlog),
1605 },
1606 {
1607 .data_type = QMI_EOTI,
1608 .array_type = NO_ARRAY,
1609 .tlv_type = QMI_COMMON_TLV_TYPE,
1610 },
1611};
1612
1613static struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {
1614 {
1615 .data_type = QMI_STRUCT,
1616 .elem_len = 1,
1617 .elem_size = sizeof(struct qmi_response_type_v01),
1618 .array_type = NO_ARRAY,
1619 .tlv_type = 0x02,
1620 .offset = offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,
1621 resp),
1622 .ei_array = qmi_response_type_v01_ei,
1623 },
1624 {
1625 .data_type = QMI_EOTI,
1626 .array_type = NO_ARRAY,
1627 .tlv_type = QMI_COMMON_TLV_TYPE,
1628 },
1629};
1630
Kalle Valod5c65152019-11-23 09:58:40 +02001631static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
1632{
1633 struct qmi_wlanfw_host_cap_req_msg_v01 req;
1634 struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05301635 struct qmi_txn txn;
Kalle Valod5c65152019-11-23 09:58:40 +02001636 int ret = 0;
1637
1638 memset(&req, 0, sizeof(req));
1639 memset(&resp, 0, sizeof(resp));
1640
1641 req.num_clients_valid = 1;
1642 req.num_clients = 1;
1643 req.mem_cfg_mode = ab->qmi.target_mem_mode;
1644 req.mem_cfg_mode_valid = 1;
1645 req.bdf_support_valid = 1;
1646 req.bdf_support = 1;
1647
Govind Singh56970452020-08-14 10:10:20 +03001648 if (ab->bus_params.m3_fw_support) {
1649 req.m3_support_valid = 1;
1650 req.m3_support = 1;
1651 req.m3_cache_support_valid = 1;
1652 req.m3_cache_support = 1;
1653 } else {
1654 req.m3_support_valid = 0;
1655 req.m3_support = 0;
1656 req.m3_cache_support_valid = 0;
1657 req.m3_cache_support = 0;
1658 }
Kalle Valod5c65152019-11-23 09:58:40 +02001659
1660 req.cal_done_valid = 1;
1661 req.cal_done = ab->qmi.cal_done;
1662
Carl Huang727fae12020-08-14 10:10:29 +03001663 if (ab->hw_params.internal_sleep_clock) {
1664 req.nm_modem_valid = 1;
1665
1666 /* Notify firmware that this is non-qualcomm platform. */
1667 req.nm_modem |= HOST_CSTATE_BIT;
1668
1669 /* Notify firmware about the sleep clock selection,
1670 * nm_modem_bit[1] is used for this purpose. Host driver on
1671 * non-qualcomm platforms should select internal sleep
1672 * clock.
1673 */
1674 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
1675 }
1676
Kalle Valobf458d72021-02-22 09:35:49 +02001677 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi host cap request\n");
1678
Kalle Valod5c65152019-11-23 09:58:40 +02001679 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1680 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
1681 if (ret < 0)
1682 goto out;
1683
1684 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1685 QMI_WLANFW_HOST_CAP_REQ_V01,
1686 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
1687 qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
1688 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05301689 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02001690 ath11k_warn(ab, "failed to send host capability request: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02001691 goto out;
1692 }
1693
1694 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1695 if (ret < 0)
1696 goto out;
1697
1698 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02001699 ath11k_warn(ab, "host capability request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02001700 resp.resp.result, resp.resp.error);
1701 ret = -EINVAL;
1702 goto out;
1703 }
1704
1705out:
1706 return ret;
1707}
1708
1709static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)
1710{
1711 struct qmi_wlanfw_ind_register_req_msg_v01 *req;
1712 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
1713 struct qmi_handle *handle = &ab->qmi.handle;
1714 struct qmi_txn txn;
Christophe JAILLETe7bcc142020-11-24 17:59:16 +02001715 int ret;
Kalle Valod5c65152019-11-23 09:58:40 +02001716
1717 req = kzalloc(sizeof(*req), GFP_KERNEL);
1718 if (!req)
1719 return -ENOMEM;
1720
1721 resp = kzalloc(sizeof(*resp), GFP_KERNEL);
Christophe JAILLETe7bcc142020-11-24 17:59:16 +02001722 if (!resp) {
1723 ret = -ENOMEM;
Kalle Valod5c65152019-11-23 09:58:40 +02001724 goto resp_out;
Christophe JAILLETe7bcc142020-11-24 17:59:16 +02001725 }
Kalle Valod5c65152019-11-23 09:58:40 +02001726
1727 req->client_id_valid = 1;
1728 req->client_id = QMI_WLANFW_CLIENT_ID;
1729 req->fw_ready_enable_valid = 1;
1730 req->fw_ready_enable = 1;
1731 req->request_mem_enable_valid = 1;
1732 req->request_mem_enable = 1;
1733 req->fw_mem_ready_enable_valid = 1;
1734 req->fw_mem_ready_enable = 1;
1735 req->cal_done_enable_valid = 1;
1736 req->cal_done_enable = 1;
1737 req->fw_init_done_enable_valid = 1;
1738 req->fw_init_done_enable = 1;
1739
1740 req->pin_connect_result_enable_valid = 0;
1741 req->pin_connect_result_enable = 0;
1742
1743 ret = qmi_txn_init(handle, &txn,
1744 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
1745 if (ret < 0)
1746 goto out;
1747
Kalle Valobf458d72021-02-22 09:35:49 +02001748 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi indication register request\n");
1749
Kalle Valod5c65152019-11-23 09:58:40 +02001750 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1751 QMI_WLANFW_IND_REGISTER_REQ_V01,
1752 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
1753 qmi_wlanfw_ind_register_req_msg_v01_ei, req);
1754 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05301755 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02001756 ath11k_warn(ab, "failed to send indication register request: %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02001757 ret);
1758 goto out;
1759 }
1760
1761 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1762 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02001763 ath11k_warn(ab, "failed to register fw indication: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02001764 goto out;
1765 }
1766
1767 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02001768 ath11k_warn(ab, "firmware indication register request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02001769 resp->resp.result, resp->resp.error);
1770 ret = -EINVAL;
1771 goto out;
1772 }
1773
1774out:
1775 kfree(resp);
1776resp_out:
1777 kfree(req);
1778 return ret;
1779}
1780
1781static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
1782{
1783 struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
1784 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05301785 struct qmi_txn txn;
Kalle Valod5c65152019-11-23 09:58:40 +02001786 int ret = 0, i;
Carl Huangf6f92962020-12-17 09:04:57 +02001787 bool delayed;
Kalle Valod5c65152019-11-23 09:58:40 +02001788
1789 req = kzalloc(sizeof(*req), GFP_KERNEL);
1790 if (!req)
1791 return -ENOMEM;
1792
1793 memset(&resp, 0, sizeof(resp));
1794
Carl Huang26f3a022020-08-14 10:10:26 +03001795 /* For QCA6390 by default FW requests a block of ~4M contiguous
1796 * DMA memory, it's hard to allocate from OS. So host returns
1797 * failure to FW and FW will then request mulitple blocks of small
1798 * chunk size memory.
1799 */
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02001800 if (!(ab->bus_params.fixed_mem_region ||
1801 test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&
1802 ab->qmi.target_mem_delayed) {
Carl Huangf6f92962020-12-17 09:04:57 +02001803 delayed = true;
Carl Huang26f3a022020-08-14 10:10:26 +03001804 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n",
1805 ab->qmi.mem_seg_count);
1806 memset(req, 0, sizeof(*req));
1807 } else {
Carl Huangf6f92962020-12-17 09:04:57 +02001808 delayed = false;
Carl Huang26f3a022020-08-14 10:10:26 +03001809 req->mem_seg_len = ab->qmi.mem_seg_count;
1810
1811 for (i = 0; i < req->mem_seg_len ; i++) {
1812 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
1813 req->mem_seg[i].size = ab->qmi.target_mem[i].size;
1814 req->mem_seg[i].type = ab->qmi.target_mem[i].type;
Kalle Valod5395a52021-02-11 13:05:49 +02001815 ath11k_dbg(ab, ATH11K_DBG_QMI,
Geert Uytterhoevenebb9d342021-02-21 19:27:54 +01001816 "qmi req mem_seg[%d] %pad %u %u\n", i,
1817 &ab->qmi.target_mem[i].paddr,
Kalle Valod5395a52021-02-11 13:05:49 +02001818 ab->qmi.target_mem[i].size,
1819 ab->qmi.target_mem[i].type);
Carl Huang26f3a022020-08-14 10:10:26 +03001820 }
1821 }
Kalle Valod5c65152019-11-23 09:58:40 +02001822
1823 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1824 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
1825 if (ret < 0)
1826 goto out;
1827
Kalle Valobf458d72021-02-22 09:35:49 +02001828 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi respond memory request delayed %i\n",
1829 delayed);
1830
Kalle Valod5c65152019-11-23 09:58:40 +02001831 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1832 QMI_WLANFW_RESPOND_MEM_REQ_V01,
1833 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
1834 qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
1835 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05301836 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02001837 ath11k_warn(ab, "failed to respond qmi memory request: %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02001838 ret);
1839 goto out;
1840 }
1841
1842 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1843 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02001844 ath11k_warn(ab, "failed to wait qmi memory request: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02001845 goto out;
1846 }
1847
1848 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Carl Huangf6f92962020-12-17 09:04:57 +02001849 /* the error response is expected when
1850 * target_mem_delayed is true.
1851 */
1852 if (delayed && resp.resp.error == 0)
1853 goto out;
1854
Kalle Valo097e9f02021-02-22 09:35:56 +02001855 ath11k_warn(ab, "qmi respond memory request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02001856 resp.resp.result, resp.resp.error);
1857 ret = -EINVAL;
1858 goto out;
1859 }
1860out:
1861 kfree(req);
1862 return ret;
1863}
1864
Govind Singh6eb6ea52020-08-14 10:10:21 +03001865static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)
1866{
1867 int i;
1868
Govind Singh6eb6ea52020-08-14 10:10:21 +03001869 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02001870 if ((ab->bus_params.fixed_mem_region ||
1871 test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&
1872 ab->qmi.target_mem[i].iaddr)
1873 iounmap(ab->qmi.target_mem[i].iaddr);
1874
Govind Singh6eb6ea52020-08-14 10:10:21 +03001875 if (!ab->qmi.target_mem[i].vaddr)
1876 continue;
1877
1878 dma_free_coherent(ab->dev,
1879 ab->qmi.target_mem[i].size,
1880 ab->qmi.target_mem[i].vaddr,
1881 ab->qmi.target_mem[i].paddr);
1882 ab->qmi.target_mem[i].vaddr = NULL;
1883 }
1884}
1885
Kalle Valod5c65152019-11-23 09:58:40 +02001886static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
1887{
Govind Singh6eb6ea52020-08-14 10:10:21 +03001888 int i;
1889 struct target_mem_chunk *chunk;
1890
Carl Huangf6f92962020-12-17 09:04:57 +02001891 ab->qmi.target_mem_delayed = false;
1892
Govind Singh6eb6ea52020-08-14 10:10:21 +03001893 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1894 chunk = &ab->qmi.target_mem[i];
1895 chunk->vaddr = dma_alloc_coherent(ab->dev,
1896 chunk->size,
1897 &chunk->paddr,
Aaron Mab9b59482021-09-28 12:05:43 +03001898 GFP_KERNEL | __GFP_NOWARN);
Govind Singh6eb6ea52020-08-14 10:10:21 +03001899 if (!chunk->vaddr) {
Anilkumar Kolli5f67d302021-02-16 09:16:03 +02001900 if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {
Carl Huangf6f92962020-12-17 09:04:57 +02001901 ath11k_dbg(ab, ATH11K_DBG_QMI,
1902 "qmi dma allocation failed (%d B type %u), will try later with small size\n",
1903 chunk->size,
1904 chunk->type);
1905 ath11k_qmi_free_target_mem_chunk(ab);
1906 ab->qmi.target_mem_delayed = true;
1907 return 0;
1908 }
Kalle Valo097e9f02021-02-22 09:35:56 +02001909
1910 ath11k_err(ab, "failed to allocate dma memory for qmi (%d B type %u)\n",
Govind Singh6eb6ea52020-08-14 10:10:21 +03001911 chunk->size,
1912 chunk->type);
1913 return -EINVAL;
1914 }
1915 }
1916
1917 return 0;
1918}
1919
1920static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
1921{
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02001922 struct device *dev = ab->dev;
1923 struct device_node *hremote_node = NULL;
1924 struct resource res;
1925 u32 host_ddr_sz;
1926 int i, idx, ret;
Kalle Valod5c65152019-11-23 09:58:40 +02001927
1928 for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
1929 switch (ab->qmi.target_mem[i].type) {
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02001930 case HOST_DDR_REGION_TYPE:
1931 hremote_node = of_parse_phandle(dev->of_node, "memory-region", 0);
1932 if (!hremote_node) {
1933 ath11k_dbg(ab, ATH11K_DBG_QMI,
1934 "qmi fail to get hremote_node\n");
1935 return ret;
1936 }
1937
1938 ret = of_address_to_resource(hremote_node, 0, &res);
1939 if (ret) {
1940 ath11k_dbg(ab, ATH11K_DBG_QMI,
1941 "qmi fail to get reg from hremote\n");
1942 return ret;
1943 }
1944
1945 if (res.end - res.start + 1 < ab->qmi.target_mem[i].size) {
1946 ath11k_dbg(ab, ATH11K_DBG_QMI,
1947 "qmi fail to assign memory of sz\n");
1948 return -EINVAL;
1949 }
1950
1951 ab->qmi.target_mem[idx].paddr = res.start;
1952 ab->qmi.target_mem[idx].iaddr =
1953 ioremap(ab->qmi.target_mem[idx].paddr,
1954 ab->qmi.target_mem[i].size);
1955 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1956 host_ddr_sz = ab->qmi.target_mem[i].size;
1957 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1958 idx++;
1959 break;
Kalle Valod5c65152019-11-23 09:58:40 +02001960 case BDF_MEM_REGION_TYPE:
Anilkumar Kolli3b94ae42020-06-16 17:00:48 +03001961 ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
Govind Singh6eb6ea52020-08-14 10:10:21 +03001962 ab->qmi.target_mem[idx].vaddr = NULL;
Kalle Valod5c65152019-11-23 09:58:40 +02001963 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1964 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1965 idx++;
1966 break;
1967 case CALDB_MEM_REGION_TYPE:
1968 if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {
1969 ath11k_warn(ab, "qmi mem size is low to load caldata\n");
1970 return -EINVAL;
1971 }
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05301972
1973 if (ath11k_cold_boot_cal && ab->hw_params.cold_boot_calib) {
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02001974 if (hremote_node) {
1975 ab->qmi.target_mem[idx].paddr =
1976 res.start + host_ddr_sz;
1977 ab->qmi.target_mem[idx].iaddr =
1978 ioremap(ab->qmi.target_mem[idx].paddr,
1979 ab->qmi.target_mem[i].size);
1980 } else {
1981 ab->qmi.target_mem[idx].paddr =
1982 ATH11K_QMI_CALDB_ADDRESS;
1983 }
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05301984 } else {
1985 ab->qmi.target_mem[idx].paddr = 0;
1986 ab->qmi.target_mem[idx].vaddr = NULL;
1987 }
Kalle Valod5c65152019-11-23 09:58:40 +02001988 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1989 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1990 idx++;
1991 break;
1992 default:
1993 ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
1994 ab->qmi.target_mem[i].type);
1995 break;
1996 }
1997 }
1998 ab->qmi.mem_seg_count = idx;
1999
2000 return 0;
2001}
2002
2003static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
2004{
2005 struct qmi_wlanfw_cap_req_msg_v01 req;
2006 struct qmi_wlanfw_cap_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302007 struct qmi_txn txn;
Kalle Valod5c65152019-11-23 09:58:40 +02002008 int ret = 0;
Sven Eckelmann14f43c52020-10-15 15:15:01 +02002009 int r;
Kalle Valod5c65152019-11-23 09:58:40 +02002010
2011 memset(&req, 0, sizeof(req));
2012 memset(&resp, 0, sizeof(resp));
2013
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002014 ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,
2015 &resp);
Kalle Valod5c65152019-11-23 09:58:40 +02002016 if (ret < 0)
2017 goto out;
2018
Kalle Valobf458d72021-02-22 09:35:49 +02002019 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi target cap request\n");
2020
Kalle Valod5c65152019-11-23 09:58:40 +02002021 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2022 QMI_WLANFW_CAP_REQ_V01,
2023 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
2024 qmi_wlanfw_cap_req_msg_v01_ei, &req);
2025 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302026 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02002027 ath11k_warn(ab, "failed to send qmi cap request: %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002028 ret);
2029 goto out;
2030 }
2031
2032 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2033 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002034 ath11k_warn(ab, "failed to wait qmi cap request: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002035 goto out;
2036 }
2037
2038 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002039 ath11k_warn(ab, "qmi cap request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002040 resp.resp.result, resp.resp.error);
2041 ret = -EINVAL;
2042 goto out;
2043 }
2044
2045 if (resp.chip_info_valid) {
2046 ab->qmi.target.chip_id = resp.chip_info.chip_id;
2047 ab->qmi.target.chip_family = resp.chip_info.chip_family;
2048 }
2049
2050 if (resp.board_info_valid)
2051 ab->qmi.target.board_id = resp.board_info.board_id;
2052 else
2053 ab->qmi.target.board_id = 0xFF;
2054
2055 if (resp.soc_info_valid)
2056 ab->qmi.target.soc_id = resp.soc_info.soc_id;
2057
2058 if (resp.fw_version_info_valid) {
2059 ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
2060 strlcpy(ab->qmi.target.fw_build_timestamp,
2061 resp.fw_version_info.fw_build_timestamp,
2062 sizeof(ab->qmi.target.fw_build_timestamp));
2063 }
2064
2065 if (resp.fw_build_id_valid)
2066 strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
2067 sizeof(ab->qmi.target.fw_build_id));
2068
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002069 if (resp.eeprom_read_timeout_valid) {
2070 ab->qmi.target.eeprom_caldata =
2071 resp.eeprom_read_timeout;
2072 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cal data supported from eeprom\n");
2073 }
2074
Kalle Valo6e5dd032020-06-16 17:00:53 +03002075 ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002076 ab->qmi.target.chip_id, ab->qmi.target.chip_family,
2077 ab->qmi.target.board_id, ab->qmi.target.soc_id);
2078
Kalle Valo6e5dd032020-06-16 17:00:53 +03002079 ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
Kalle Valod5c65152019-11-23 09:58:40 +02002080 ab->qmi.target.fw_version,
2081 ab->qmi.target.fw_build_timestamp,
2082 ab->qmi.target.fw_build_id);
2083
Sven Eckelmann14f43c52020-10-15 15:15:01 +02002084 r = ath11k_core_check_dt(ab);
2085 if (r)
2086 ath11k_dbg(ab, ATH11K_DBG_QMI, "DT bdf variant name not set.\n");
2087
Kalle Valod5c65152019-11-23 09:58:40 +02002088out:
2089 return ret;
2090}
2091
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002092static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,
2093 const u8 *data, u32 len, u8 type)
Kalle Valod5c65152019-11-23 09:58:40 +02002094{
2095 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2096 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302097 struct qmi_txn txn;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002098 const u8 *temp = data;
Kalle Valod5c65152019-11-23 09:58:40 +02002099 void __iomem *bdf_addr = NULL;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002100 int ret;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002101 u32 remaining = len;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002102
2103 req = kzalloc(sizeof(*req), GFP_KERNEL);
2104 if (!req)
2105 return -ENOMEM;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002106
Govind Singh6eb6ea52020-08-14 10:10:21 +03002107 memset(&resp, 0, sizeof(resp));
2108
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002109 if (ab->bus_params.fixed_bdf_addr) {
2110 bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);
2111 if (!bdf_addr) {
2112 ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");
2113 ret = -EIO;
2114 goto err_free_req;
2115 }
Govind Singh6eb6ea52020-08-14 10:10:21 +03002116 }
2117
Govind Singh6eb6ea52020-08-14 10:10:21 +03002118 while (remaining) {
2119 req->valid = 1;
2120 req->file_id_valid = 1;
2121 req->file_id = ab->qmi.target.board_id;
2122 req->total_size_valid = 1;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002123 req->total_size = remaining;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002124 req->seg_id_valid = 1;
2125 req->data_valid = 1;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002126 req->bdf_type = type;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002127 req->bdf_type_valid = 1;
2128 req->end_valid = 1;
2129 req->end = 0;
2130
2131 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2132 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2133 } else {
2134 req->data_len = remaining;
2135 req->end = 1;
2136 }
2137
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002138 if (ab->bus_params.fixed_bdf_addr ||
2139 type == ATH11K_QMI_FILE_TYPE_EEPROM) {
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002140 req->data_valid = 0;
2141 req->end = 1;
2142 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
2143 } else {
2144 memcpy(req->data, temp, req->data_len);
2145 }
2146
2147 if (ab->bus_params.fixed_bdf_addr) {
2148 if (type == ATH11K_QMI_FILE_TYPE_CALDATA)
2149 bdf_addr += ab->hw_params.fw.cal_offset;
2150
2151 memcpy_toio(bdf_addr, temp, len);
2152 }
Govind Singh6eb6ea52020-08-14 10:10:21 +03002153
2154 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2155 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2156 &resp);
2157 if (ret < 0)
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002158 goto err_iounmap;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002159
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002160 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download req fixed addr type %d\n",
2161 type);
Kalle Valobf458d72021-02-22 09:35:49 +02002162
Govind Singh6eb6ea52020-08-14 10:10:21 +03002163 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2164 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2165 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2166 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2167 if (ret < 0) {
2168 qmi_txn_cancel(&txn);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002169 goto err_iounmap;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002170 }
2171
2172 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002173 if (ret < 0) {
2174 ath11k_warn(ab, "failed to wait board file download request: %d\n",
2175 ret);
2176 goto err_iounmap;
2177 }
Govind Singh6eb6ea52020-08-14 10:10:21 +03002178
2179 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002180 ath11k_warn(ab, "board file download request failed: %d %d\n",
Govind Singh6eb6ea52020-08-14 10:10:21 +03002181 resp.resp.result, resp.resp.error);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002182 ret = -EINVAL;
2183 goto err_iounmap;
Govind Singh6eb6ea52020-08-14 10:10:21 +03002184 }
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002185
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002186 if (ab->bus_params.fixed_bdf_addr ||
2187 type == ATH11K_QMI_FILE_TYPE_EEPROM) {
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002188 remaining = 0;
2189 } else {
2190 remaining -= req->data_len;
2191 temp += req->data_len;
2192 req->seg_id++;
2193 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf download request remaining %i\n",
2194 remaining);
2195 }
Govind Singh6eb6ea52020-08-14 10:10:21 +03002196 }
2197
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002198err_iounmap:
2199 if (ab->bus_params.fixed_bdf_addr)
2200 iounmap(bdf_addr);
Govind Singh6eb6ea52020-08-14 10:10:21 +03002201
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002202err_free_req:
Govind Singh6eb6ea52020-08-14 10:10:21 +03002203 kfree(req);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002204
2205 return ret;
2206}
2207
Wen Gong01417e52021-12-20 01:23:55 -05002208static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab,
2209 bool regdb)
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002210{
Anilkumar Kollie82dfe72021-09-28 12:05:39 +03002211 struct device *dev = ab->dev;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002212 char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];
2213 const struct firmware *fw_entry;
2214 struct ath11k_board_data bd;
2215 u32 fw_size, file_type;
2216 int ret = 0, bdf_type;
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002217 const u8 *tmp;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002218
2219 memset(&bd, 0, sizeof(bd));
Wen Gong01417e52021-12-20 01:23:55 -05002220
2221 if (regdb) {
2222 ret = ath11k_core_fetch_regdb(ab, &bd);
2223 } else {
2224 ret = ath11k_core_fetch_bdf(ab, &bd);
2225 if (ret)
2226 ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002227 }
2228
Wen Gong01417e52021-12-20 01:23:55 -05002229 if (ret)
2230 goto out;
2231
2232 if (regdb)
2233 bdf_type = ATH11K_QMI_BDF_TYPE_REGDB;
2234 else if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002235 bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
2236 else
2237 bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
2238
2239 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
2240
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002241 fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
2242
2243 ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);
2244 if (ret < 0) {
2245 ath11k_warn(ab, "qmi failed to load bdf file\n");
2246 goto out;
2247 }
2248
Wen Gong01417e52021-12-20 01:23:55 -05002249 /* QCA6390/WCN6855 does not support cal data, skip it */
2250 if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF || bdf_type == ATH11K_QMI_BDF_TYPE_REGDB)
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002251 goto out;
2252
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002253 if (ab->qmi.target.eeprom_caldata) {
2254 file_type = ATH11K_QMI_FILE_TYPE_EEPROM;
2255 tmp = filename;
2256 fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
2257 } else {
2258 file_type = ATH11K_QMI_FILE_TYPE_CALDATA;
Anilkumar Kollie82dfe72021-09-28 12:05:39 +03002259
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002260 /* cal-<bus>-<id>.bin */
2261 snprintf(filename, sizeof(filename), "cal-%s-%s.bin",
2262 ath11k_bus_str(ab->hif.bus), dev_name(dev));
2263 fw_entry = ath11k_core_firmware_request(ab, filename);
2264 if (!IS_ERR(fw_entry))
2265 goto success;
Anilkumar Kollie82dfe72021-09-28 12:05:39 +03002266
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002267 fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
2268 if (IS_ERR(fw_entry)) {
2269 ret = PTR_ERR(fw_entry);
2270 ath11k_warn(ab,
2271 "qmi failed to load CAL data file:%s\n",
2272 filename);
2273 goto out;
2274 }
2275success:
2276 fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);
2277 tmp = fw_entry->data;
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002278 }
2279
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002280 ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002281 if (ret < 0) {
2282 ath11k_warn(ab, "qmi failed to load caldata\n");
2283 goto out_qmi_cal;
2284 }
2285
Anilkumar Kollie82dfe72021-09-28 12:05:39 +03002286 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi caldata type: %u\n", file_type);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002287
2288out_qmi_cal:
Anilkumar Kolli4ba3b052021-09-28 12:05:39 +03002289 if (!ab->qmi.target.eeprom_caldata)
2290 release_firmware(fw_entry);
Anilkumar Kolli336e7b52021-09-28 12:05:39 +03002291out:
2292 ath11k_core_free_bdf(ab, &bd);
2293 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi BDF download sequence completed\n");
2294
Govind Singh6eb6ea52020-08-14 10:10:21 +03002295 return ret;
2296}
2297
Govind Singh56970452020-08-14 10:10:20 +03002298static int ath11k_qmi_m3_load(struct ath11k_base *ab)
2299{
2300 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2301 const struct firmware *fw;
2302 char path[100];
2303 int ret;
2304
2305 if (m3_mem->vaddr || m3_mem->size)
2306 return 0;
2307
2308 fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
2309 if (IS_ERR(fw)) {
2310 ret = PTR_ERR(fw);
2311 ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,
2312 path, sizeof(path));
2313 ath11k_err(ab, "failed to load %s: %d\n", path, ret);
2314 return ret;
2315 }
2316
2317 m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2318 fw->size, &m3_mem->paddr,
2319 GFP_KERNEL);
2320 if (!m3_mem->vaddr) {
2321 ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2322 fw->size);
2323 release_firmware(fw);
2324 return -ENOMEM;
2325 }
2326
2327 memcpy(m3_mem->vaddr, fw->data, fw->size);
2328 m3_mem->size = fw->size;
2329 release_firmware(fw);
2330
2331 return 0;
2332}
2333
2334static void ath11k_qmi_m3_free(struct ath11k_base *ab)
2335{
2336 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2337
2338 if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr)
2339 return;
2340
2341 dma_free_coherent(ab->dev, m3_mem->size,
2342 m3_mem->vaddr, m3_mem->paddr);
2343 m3_mem->vaddr = NULL;
2344}
2345
Kalle Valod5c65152019-11-23 09:58:40 +02002346static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
2347{
Govind Singh56970452020-08-14 10:10:20 +03002348 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
Kalle Valod5c65152019-11-23 09:58:40 +02002349 struct qmi_wlanfw_m3_info_req_msg_v01 req;
2350 struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302351 struct qmi_txn txn;
Kalle Valod5c65152019-11-23 09:58:40 +02002352 int ret = 0;
2353
2354 memset(&req, 0, sizeof(req));
2355 memset(&resp, 0, sizeof(resp));
Govind Singh56970452020-08-14 10:10:20 +03002356
2357 if (ab->bus_params.m3_fw_support) {
2358 ret = ath11k_qmi_m3_load(ab);
2359 if (ret) {
2360 ath11k_err(ab, "failed to load m3 firmware: %d", ret);
2361 return ret;
2362 }
2363
2364 req.addr = m3_mem->paddr;
2365 req.size = m3_mem->size;
2366 } else {
2367 req.addr = 0;
2368 req.size = 0;
2369 }
Kalle Valod5c65152019-11-23 09:58:40 +02002370
2371 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2372 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
2373 if (ret < 0)
2374 goto out;
2375
Kalle Valobf458d72021-02-22 09:35:49 +02002376 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi m3 info req\n");
2377
Kalle Valod5c65152019-11-23 09:58:40 +02002378 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2379 QMI_WLANFW_M3_INFO_REQ_V01,
2380 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
2381 qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
2382 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302383 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02002384 ath11k_warn(ab, "failed to send m3 information request: %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002385 ret);
2386 goto out;
2387 }
2388
2389 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2390 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002391 ath11k_warn(ab, "failed to wait m3 information request: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002392 goto out;
2393 }
2394
2395 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002396 ath11k_warn(ab, "m3 info request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002397 resp.resp.result, resp.resp.error);
2398 ret = -EINVAL;
2399 goto out;
2400 }
2401out:
2402 return ret;
2403}
2404
2405static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
2406 u32 mode)
2407{
2408 struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
2409 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302410 struct qmi_txn txn;
Kalle Valod5c65152019-11-23 09:58:40 +02002411 int ret = 0;
2412
2413 memset(&req, 0, sizeof(req));
2414 memset(&resp, 0, sizeof(resp));
2415
2416 req.mode = mode;
2417 req.hw_debug_valid = 1;
2418 req.hw_debug = 0;
2419
2420 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2421 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
2422 if (ret < 0)
2423 goto out;
2424
Kalle Valobf458d72021-02-22 09:35:49 +02002425 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wlan mode req mode %d\n", mode);
2426
Kalle Valod5c65152019-11-23 09:58:40 +02002427 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2428 QMI_WLANFW_WLAN_MODE_REQ_V01,
2429 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
2430 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
2431 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302432 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02002433 ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002434 mode, ret);
2435 goto out;
2436 }
2437
2438 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2439 if (ret < 0) {
2440 if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
2441 ath11k_warn(ab, "WLFW service is dis-connected\n");
2442 return 0;
2443 }
Kalle Valo097e9f02021-02-22 09:35:56 +02002444 ath11k_warn(ab, "failed to wait wlan mode request (mode %d): %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002445 mode, ret);
2446 goto out;
2447 }
2448
2449 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002450 ath11k_warn(ab, "wlan mode request failed (mode: %d): %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002451 mode, resp.resp.result, resp.resp.error);
2452 ret = -EINVAL;
2453 goto out;
2454 }
2455
2456out:
2457 return ret;
2458}
2459
2460static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
2461{
2462 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
2463 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
2464 struct ce_pipe_config *ce_cfg;
2465 struct service_to_pipe *svc_cfg;
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302466 struct qmi_txn txn;
Anilkumar Kolli0c408512019-11-27 14:08:50 +00002467 int ret = 0, pipe_num;
Kalle Valod5c65152019-11-23 09:58:40 +02002468
2469 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
2470 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
2471
2472 req = kzalloc(sizeof(*req), GFP_KERNEL);
2473 if (!req)
2474 return -ENOMEM;
2475
2476 memset(&resp, 0, sizeof(resp));
2477
2478 req->host_version_valid = 1;
2479 strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING,
2480 sizeof(req->host_version));
2481
2482 req->tgt_cfg_valid = 1;
2483 /* This is number of CE configs */
Anilkumar Kolli0c408512019-11-27 14:08:50 +00002484 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
Carl Huang6c809d02020-08-14 10:10:28 +03002485 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
Anilkumar Kolli0c408512019-11-27 14:08:50 +00002486 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
2487 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
2488 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
2489 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
2490 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
Kalle Valod5c65152019-11-23 09:58:40 +02002491 }
2492
2493 req->svc_cfg_valid = 1;
2494 /* This is number of Service/CE configs */
Anilkumar Kolli0c408512019-11-27 14:08:50 +00002495 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
2496 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
2497 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
2498 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
2499 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
Kalle Valod5c65152019-11-23 09:58:40 +02002500 }
2501 req->shadow_reg_valid = 0;
Carl Huange838c142020-10-01 12:34:44 +03002502
2503 /* set shadow v2 configuration */
2504 if (ab->hw_params.supports_shadow_regs) {
2505 req->shadow_reg_v2_valid = 1;
2506 req->shadow_reg_v2_len = min_t(u32,
2507 ab->qmi.ce_cfg.shadow_reg_v2_len,
2508 QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);
2509 memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,
2510 sizeof(u32) * req->shadow_reg_v2_len);
2511 } else {
2512 req->shadow_reg_v2_valid = 0;
2513 }
Kalle Valod5c65152019-11-23 09:58:40 +02002514
2515 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2516 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
2517 if (ret < 0)
2518 goto out;
2519
Kalle Valobf458d72021-02-22 09:35:49 +02002520 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wlan cfg req\n");
2521
Kalle Valod5c65152019-11-23 09:58:40 +02002522 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2523 QMI_WLANFW_WLAN_CFG_REQ_V01,
2524 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
2525 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
2526 if (ret < 0) {
Anilkumar Kolli1ad6e4b2021-11-02 18:22:38 +05302527 qmi_txn_cancel(&txn);
Kalle Valo097e9f02021-02-22 09:35:56 +02002528 ath11k_warn(ab, "failed to send wlan config request: %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002529 ret);
2530 goto out;
2531 }
2532
2533 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2534 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002535 ath11k_warn(ab, "failed to wait wlan config request: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002536 goto out;
2537 }
2538
2539 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002540 ath11k_warn(ab, "wlan config request failed: %d %d\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002541 resp.resp.result, resp.resp.error);
2542 ret = -EINVAL;
2543 goto out;
2544 }
2545
2546out:
2547 kfree(req);
2548 return ret;
2549}
2550
Cheng Wang42da1cc2021-12-20 20:10:53 +08002551static int ath11k_qmi_wlanfw_wlan_ini_send(struct ath11k_base *ab, bool enable)
2552{
2553 int ret;
2554 struct qmi_txn txn;
2555 struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};
2556 struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};
2557
2558 req.enablefwlog_valid = true;
2559 req.enablefwlog = enable ? 1 : 0;
2560
2561 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2562 qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);
2563 if (ret < 0)
2564 goto out;
2565
2566 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2567 QMI_WLANFW_WLAN_INI_REQ_V01,
2568 QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,
2569 qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);
2570 if (ret < 0) {
2571 ath11k_warn(ab, "qmi failed to send wlan ini request, err = %d\n",
2572 ret);
2573 qmi_txn_cancel(&txn);
2574 goto out;
2575 }
2576
2577 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2578 if (ret < 0) {
2579 ath11k_warn(ab, "qmi failed wlan ini request, err = %d\n", ret);
2580 goto out;
2581 }
2582
2583 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2584 ath11k_warn(ab, "qmi wlan ini request failed, result: %d, err: %d\n",
2585 resp.resp.result, resp.resp.error);
2586 ret = -EINVAL;
2587 }
2588
2589out:
2590 return ret;
2591}
2592
Kalle Valod5c65152019-11-23 09:58:40 +02002593void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
2594{
2595 int ret;
2596
Kalle Valobf458d72021-02-22 09:35:49 +02002597 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware stop\n");
2598
Kalle Valod5c65152019-11-23 09:58:40 +02002599 ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
2600 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002601 ath11k_warn(ab, "qmi failed to send wlan mode off: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002602 return;
2603 }
2604}
2605
2606int ath11k_qmi_firmware_start(struct ath11k_base *ab,
2607 u32 mode)
2608{
2609 int ret;
2610
Kalle Valobf458d72021-02-22 09:35:49 +02002611 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware start\n");
2612
Cheng Wang42da1cc2021-12-20 20:10:53 +08002613 if (ab->hw_params.fw_wmi_diag_event) {
2614 ret = ath11k_qmi_wlanfw_wlan_ini_send(ab, true);
2615 if (ret < 0) {
2616 ath11k_warn(ab, "qmi failed to send wlan fw ini:%d\n", ret);
2617 return ret;
2618 }
2619 }
2620
Kalle Valod5c65152019-11-23 09:58:40 +02002621 ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
2622 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002623 ath11k_warn(ab, "qmi failed to send wlan cfg: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002624 return ret;
2625 }
2626
2627 ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
2628 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002629 ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002630 return ret;
2631 }
2632
2633 return 0;
2634}
2635
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302636static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)
2637{
2638 int timeout;
2639 int ret;
2640
2641 ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);
2642 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002643 ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302644 return ret;
2645 }
2646
2647 ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");
2648
2649 timeout = wait_event_timeout(ab->qmi.cold_boot_waitq,
2650 (ab->qmi.cal_done == 1),
2651 ATH11K_COLD_BOOT_FW_RESET_DELAY);
2652 if (timeout <= 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002653 ath11k_warn(ab, "coldboot calibration timed out\n");
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302654 return 0;
2655 }
2656
2657 ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration done\n");
2658
2659 return 0;
2660}
2661
Kalle Valod5c65152019-11-23 09:58:40 +02002662static int
2663ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
2664 enum ath11k_qmi_event_type type,
2665 void *data)
2666{
2667 struct ath11k_qmi_driver_event *event;
2668
2669 event = kzalloc(sizeof(*event), GFP_ATOMIC);
2670 if (!event)
2671 return -ENOMEM;
2672
2673 event->type = type;
2674 event->data = data;
2675
2676 spin_lock(&qmi->event_lock);
2677 list_add_tail(&event->list, &qmi->event_list);
2678 spin_unlock(&qmi->event_lock);
2679
2680 queue_work(qmi->event_wq, &qmi->event_work);
2681
2682 return 0;
2683}
2684
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002685static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
Kalle Valod5c65152019-11-23 09:58:40 +02002686{
2687 struct ath11k_base *ab = qmi->ab;
2688 int ret;
2689
2690 ret = ath11k_qmi_fw_ind_register_send(ab);
2691 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002692 ath11k_warn(ab, "failed to send qmi firmware indication: %d\n",
2693 ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002694 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002695 }
2696
2697 ret = ath11k_qmi_host_cap_send(ab);
2698 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002699 ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002700 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002701 }
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002702
2703 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002704}
2705
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002706static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
Kalle Valod5c65152019-11-23 09:58:40 +02002707{
2708 struct ath11k_base *ab = qmi->ab;
2709 int ret;
2710
2711 ret = ath11k_qmi_respond_fw_mem_request(ab);
2712 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002713 ath11k_warn(ab, "qmi failed to respond fw mem req: %d\n", ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002714 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002715 }
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002716
2717 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002718}
2719
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002720static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
Kalle Valod5c65152019-11-23 09:58:40 +02002721{
2722 struct ath11k_base *ab = qmi->ab;
2723 int ret;
2724
2725 ret = ath11k_qmi_request_target_cap(ab);
2726 if (ret < 0) {
Colin Ian King6dc89f02021-03-16 09:19:24 +00002727 ath11k_warn(ab, "failed to request qmi target capabilities: %d\n",
Kalle Valo097e9f02021-02-22 09:35:56 +02002728 ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002729 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002730 }
2731
Wen Gong01417e52021-12-20 01:23:55 -05002732 if (ab->hw_params.supports_regdb)
2733 ath11k_qmi_load_bdf_qmi(ab, true);
2734
2735 ret = ath11k_qmi_load_bdf_qmi(ab, false);
Kalle Valod5c65152019-11-23 09:58:40 +02002736 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002737 ath11k_warn(ab, "failed to load board data file: %d\n", ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002738 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002739 }
2740
2741 ret = ath11k_qmi_wlanfw_m3_info_send(ab);
2742 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002743 ath11k_warn(ab, "failed to send qmi m3 info req: %d\n", ret);
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002744 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002745 }
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002746
2747 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002748}
2749
2750static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
2751 struct sockaddr_qrtr *sq,
2752 struct qmi_txn *txn,
2753 const void *data)
2754{
2755 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2756 struct ath11k_base *ab = qmi->ab;
2757 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
2758 int i, ret;
2759
2760 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware request memory request\n");
2761
2762 if (msg->mem_seg_len == 0 ||
2763 msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
Kalle Valo097e9f02021-02-22 09:35:56 +02002764 ath11k_warn(ab, "invalid memory segment length: %u\n",
Kalle Valod5c65152019-11-23 09:58:40 +02002765 msg->mem_seg_len);
2766
2767 ab->qmi.mem_seg_count = msg->mem_seg_len;
2768
2769 for (i = 0; i < qmi->mem_seg_count ; i++) {
2770 ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
2771 ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
2772 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi mem seg type %d size %d\n",
2773 msg->mem_seg[i].type, msg->mem_seg[i].size);
2774 }
2775
Anilkumar Kolli6ac04bd2021-12-14 17:39:43 +02002776 if (ab->bus_params.fixed_mem_region ||
2777 test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {
Govind Singh6eb6ea52020-08-14 10:10:21 +03002778 ret = ath11k_qmi_assign_target_mem_chunk(ab);
Carl Huang26f3a022020-08-14 10:10:26 +03002779 if (ret) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002780 ath11k_warn(ab, "failed to assign qmi target memory: %d\n",
Carl Huang26f3a022020-08-14 10:10:26 +03002781 ret);
2782 return;
2783 }
Carl Huangf6f92962020-12-17 09:04:57 +02002784 } else {
Govind Singh6eb6ea52020-08-14 10:10:21 +03002785 ret = ath11k_qmi_alloc_target_mem_chunk(ab);
Carl Huang26f3a022020-08-14 10:10:26 +03002786 if (ret) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002787 ath11k_warn(ab, "failed to allocate qmi target memory: %d\n",
Carl Huang26f3a022020-08-14 10:10:26 +03002788 ret);
2789 return;
2790 }
Kalle Valod5c65152019-11-23 09:58:40 +02002791 }
2792
2793 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);
2794}
2795
2796static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
2797 struct sockaddr_qrtr *sq,
2798 struct qmi_txn *txn,
2799 const void *decoded)
2800{
2801 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2802 struct ath11k_base *ab = qmi->ab;
2803
2804 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware memory ready indication\n");
2805 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);
2806}
2807
2808static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
2809 struct sockaddr_qrtr *sq,
2810 struct qmi_txn *txn,
2811 const void *decoded)
2812{
2813 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2814 struct ath11k_base *ab = qmi->ab;
2815
2816 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
2817 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
2818}
2819
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302820static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,
Kalle Valod5c65152019-11-23 09:58:40 +02002821 struct sockaddr_qrtr *sq,
2822 struct qmi_txn *txn,
2823 const void *decoded)
2824{
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302825 struct ath11k_qmi *qmi = container_of(qmi_hdl,
2826 struct ath11k_qmi, handle);
2827 struct ath11k_base *ab = qmi->ab;
2828
2829 ab->qmi.cal_done = 1;
2830 wake_up(&ab->qmi.cold_boot_waitq);
2831 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi cold boot calibration done\n");
Kalle Valod5c65152019-11-23 09:58:40 +02002832}
2833
2834static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
2835 {
2836 .type = QMI_INDICATION,
2837 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
2838 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
Carl Huangf44dd332020-08-14 10:10:27 +03002839 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
Kalle Valod5c65152019-11-23 09:58:40 +02002840 .fn = ath11k_qmi_msg_mem_request_cb,
2841 },
2842 {
2843 .type = QMI_INDICATION,
2844 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
2845 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
Carl Huangf44dd332020-08-14 10:10:27 +03002846 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
Kalle Valod5c65152019-11-23 09:58:40 +02002847 .fn = ath11k_qmi_msg_mem_ready_cb,
2848 },
2849 {
2850 .type = QMI_INDICATION,
2851 .msg_id = QMI_WLFW_FW_READY_IND_V01,
2852 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
Carl Huangf44dd332020-08-14 10:10:27 +03002853 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
Kalle Valod5c65152019-11-23 09:58:40 +02002854 .fn = ath11k_qmi_msg_fw_ready_cb,
2855 },
2856 {
2857 .type = QMI_INDICATION,
2858 .msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,
2859 .ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,
2860 .decoded_size =
Carl Huangf44dd332020-08-14 10:10:27 +03002861 sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
Kalle Valod5c65152019-11-23 09:58:40 +02002862 .fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
2863 },
2864};
2865
2866static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
2867 struct qmi_service *service)
2868{
2869 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2870 struct ath11k_base *ab = qmi->ab;
2871 struct sockaddr_qrtr *sq = &qmi->sq;
2872 int ret;
2873
2874 sq->sq_family = AF_QIPCRTR;
2875 sq->sq_node = service->node;
2876 sq->sq_port = service->port;
2877
2878 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
2879 sizeof(*sq), 0);
2880 if (ret) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002881 ath11k_warn(ab, "failed to connect to qmi remote service: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002882 return ret;
2883 }
2884
2885 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n");
2886 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);
2887
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002888 return ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002889}
2890
2891static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
2892 struct qmi_service *service)
2893{
2894 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2895 struct ath11k_base *ab = qmi->ab;
2896
2897 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw del server\n");
2898 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);
2899}
2900
2901static const struct qmi_ops ath11k_qmi_ops = {
2902 .new_server = ath11k_qmi_ops_new_server,
2903 .del_server = ath11k_qmi_ops_del_server,
2904};
2905
2906static void ath11k_qmi_driver_event_work(struct work_struct *work)
2907{
2908 struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
2909 event_work);
2910 struct ath11k_qmi_driver_event *event;
2911 struct ath11k_base *ab = qmi->ab;
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002912 int ret;
Kalle Valod5c65152019-11-23 09:58:40 +02002913
2914 spin_lock(&qmi->event_lock);
2915 while (!list_empty(&qmi->event_list)) {
2916 event = list_first_entry(&qmi->event_list,
2917 struct ath11k_qmi_driver_event, list);
2918 list_del(&event->list);
2919 spin_unlock(&qmi->event_lock);
2920
Baochen Qiang72de7992021-09-28 14:00:44 +03002921 if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
2922 kfree(event);
Kalle Valod5c65152019-11-23 09:58:40 +02002923 return;
Baochen Qiang72de7992021-09-28 14:00:44 +03002924 }
Kalle Valod5c65152019-11-23 09:58:40 +02002925
2926 switch (event->type) {
2927 case ATH11K_QMI_EVENT_SERVER_ARRIVE:
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002928 ret = ath11k_qmi_event_server_arrive(qmi);
2929 if (ret < 0)
2930 set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
Kalle Valod5c65152019-11-23 09:58:40 +02002931 break;
2932 case ATH11K_QMI_EVENT_SERVER_EXIT:
2933 set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
2934 set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2935 break;
2936 case ATH11K_QMI_EVENT_REQUEST_MEM:
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002937 ret = ath11k_qmi_event_mem_request(qmi);
2938 if (ret < 0)
2939 set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
Kalle Valod5c65152019-11-23 09:58:40 +02002940 break;
2941 case ATH11K_QMI_EVENT_FW_MEM_READY:
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002942 ret = ath11k_qmi_event_load_bdf(qmi);
2943 if (ret < 0)
2944 set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
Kalle Valod5c65152019-11-23 09:58:40 +02002945 break;
2946 case ATH11K_QMI_EVENT_FW_READY:
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02002947 clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
Kalle Valod5c65152019-11-23 09:58:40 +02002948 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
Manikanta Pubbisetty51189352020-03-17 15:02:14 +05302949 ath11k_hal_dump_srng_stats(ab);
Kalle Valod5c65152019-11-23 09:58:40 +02002950 queue_work(ab->workqueue, &ab->restart_work);
2951 break;
2952 }
2953
Govindaraj Saminathan02f9d3c2020-10-16 20:58:31 +05302954 if (ath11k_cold_boot_cal && ab->qmi.cal_done == 0 &&
2955 ab->hw_params.cold_boot_calib) {
2956 ath11k_qmi_process_coldboot_calibration(ab);
2957 } else {
2958 clear_bit(ATH11K_FLAG_CRASH_FLUSH,
2959 &ab->dev_flags);
2960 clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2961 ath11k_core_qmi_firmware_ready(ab);
2962 set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
2963 }
Kalle Valod5c65152019-11-23 09:58:40 +02002964
2965 break;
2966 case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
2967 break;
2968 default:
Kalle Valo097e9f02021-02-22 09:35:56 +02002969 ath11k_warn(ab, "invalid qmi event type: %d", event->type);
Kalle Valod5c65152019-11-23 09:58:40 +02002970 break;
2971 }
2972 kfree(event);
2973 spin_lock(&qmi->event_lock);
2974 }
2975 spin_unlock(&qmi->event_lock);
2976}
2977
2978int ath11k_qmi_init_service(struct ath11k_base *ab)
2979{
2980 int ret;
2981
2982 memset(&ab->qmi.target, 0, sizeof(struct target_info));
2983 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
2984 ab->qmi.ab = ab;
2985
Seevalamuthu Mariappanbeefee72021-12-13 11:53:08 +02002986 ab->qmi.target_mem_mode = ab->hw_params.fw_mem_mode;
Kalle Valod5c65152019-11-23 09:58:40 +02002987 ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
2988 &ath11k_qmi_ops, ath11k_qmi_msg_handlers);
2989 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02002990 ath11k_warn(ab, "failed to initialize qmi handle: %d\n", ret);
Kalle Valod5c65152019-11-23 09:58:40 +02002991 return ret;
2992 }
2993
2994 ab->qmi.event_wq = alloc_workqueue("ath11k_qmi_driver_event",
2995 WQ_UNBOUND, 1);
2996 if (!ab->qmi.event_wq) {
2997 ath11k_err(ab, "failed to allocate workqueue\n");
2998 return -EFAULT;
2999 }
3000
3001 INIT_LIST_HEAD(&ab->qmi.event_list);
3002 spin_lock_init(&ab->qmi.event_lock);
3003 INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);
3004
3005 ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,
3006 ATH11K_QMI_WLFW_SERVICE_VERS_V01,
Govind Singheb8de042020-08-14 10:10:22 +03003007 ab->qmi.service_ins_id);
Kalle Valod5c65152019-11-23 09:58:40 +02003008 if (ret < 0) {
Kalle Valo097e9f02021-02-22 09:35:56 +02003009 ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);
Wang Yufen28f16322020-07-20 17:36:44 +08003010 destroy_workqueue(ab->qmi.event_wq);
Kalle Valod5c65152019-11-23 09:58:40 +02003011 return ret;
3012 }
3013
3014 return ret;
3015}
3016
3017void ath11k_qmi_deinit_service(struct ath11k_base *ab)
3018{
3019 qmi_handle_release(&ab->qmi.handle);
3020 cancel_work_sync(&ab->qmi.event_work);
3021 destroy_workqueue(ab->qmi.event_wq);
Govind Singh56970452020-08-14 10:10:20 +03003022 ath11k_qmi_m3_free(ab);
Govind Singh6eb6ea52020-08-14 10:10:21 +03003023 ath11k_qmi_free_target_mem_chunk(ab);
Kalle Valod5c65152019-11-23 09:58:40 +02003024}
Anilkumar Kolli61a57e52020-12-08 09:52:55 +02003025EXPORT_SYMBOL(ath11k_qmi_deinit_service);
Kalle Valod5c65152019-11-23 09:58:40 +02003026