1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4 */
5
6 #include <linux/elf.h>
7
8 #include "qmi.h"
9 #include "core.h"
10 #include "debug.h"
11 #include <linux/of.h>
12 #include <linux/firmware.h>
13
14 #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
15 #define HOST_CSTATE_BIT 0x04
16
17 static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
18 {
19 .data_type = QMI_OPT_FLAG,
20 .elem_len = 1,
21 .elem_size = sizeof(u8),
22 .array_type = NO_ARRAY,
23 .tlv_type = 0x10,
24 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
25 num_clients_valid),
26 },
27 {
28 .data_type = QMI_UNSIGNED_4_BYTE,
29 .elem_len = 1,
30 .elem_size = sizeof(u32),
31 .array_type = NO_ARRAY,
32 .tlv_type = 0x10,
33 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
34 num_clients),
35 },
36 {
37 .data_type = QMI_OPT_FLAG,
38 .elem_len = 1,
39 .elem_size = sizeof(u8),
40 .array_type = NO_ARRAY,
41 .tlv_type = 0x11,
42 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
43 wake_msi_valid),
44 },
45 {
46 .data_type = QMI_UNSIGNED_4_BYTE,
47 .elem_len = 1,
48 .elem_size = sizeof(u32),
49 .array_type = NO_ARRAY,
50 .tlv_type = 0x11,
51 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
52 wake_msi),
53 },
54 {
55 .data_type = QMI_OPT_FLAG,
56 .elem_len = 1,
57 .elem_size = sizeof(u8),
58 .array_type = NO_ARRAY,
59 .tlv_type = 0x12,
60 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
61 gpios_valid),
62 },
63 {
64 .data_type = QMI_DATA_LEN,
65 .elem_len = 1,
66 .elem_size = sizeof(u8),
67 .array_type = NO_ARRAY,
68 .tlv_type = 0x12,
69 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
70 gpios_len),
71 },
72 {
73 .data_type = QMI_UNSIGNED_4_BYTE,
74 .elem_len = QMI_WLFW_MAX_NUM_GPIO_V01,
75 .elem_size = sizeof(u32),
76 .array_type = VAR_LEN_ARRAY,
77 .tlv_type = 0x12,
78 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
79 gpios),
80 },
81 {
82 .data_type = QMI_OPT_FLAG,
83 .elem_len = 1,
84 .elem_size = sizeof(u8),
85 .array_type = NO_ARRAY,
86 .tlv_type = 0x13,
87 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
88 nm_modem_valid),
89 },
90 {
91 .data_type = QMI_UNSIGNED_1_BYTE,
92 .elem_len = 1,
93 .elem_size = sizeof(u8),
94 .array_type = NO_ARRAY,
95 .tlv_type = 0x13,
96 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
97 nm_modem),
98 },
99 {
100 .data_type = QMI_OPT_FLAG,
101 .elem_len = 1,
102 .elem_size = sizeof(u8),
103 .array_type = NO_ARRAY,
104 .tlv_type = 0x14,
105 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
106 bdf_support_valid),
107 },
108 {
109 .data_type = QMI_UNSIGNED_1_BYTE,
110 .elem_len = 1,
111 .elem_size = sizeof(u8),
112 .array_type = NO_ARRAY,
113 .tlv_type = 0x14,
114 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
115 bdf_support),
116 },
117 {
118 .data_type = QMI_OPT_FLAG,
119 .elem_len = 1,
120 .elem_size = sizeof(u8),
121 .array_type = NO_ARRAY,
122 .tlv_type = 0x15,
123 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
124 bdf_cache_support_valid),
125 },
126 {
127 .data_type = QMI_UNSIGNED_1_BYTE,
128 .elem_len = 1,
129 .elem_size = sizeof(u8),
130 .array_type = NO_ARRAY,
131 .tlv_type = 0x15,
132 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
133 bdf_cache_support),
134 },
135 {
136 .data_type = QMI_OPT_FLAG,
137 .elem_len = 1,
138 .elem_size = sizeof(u8),
139 .array_type = NO_ARRAY,
140 .tlv_type = 0x16,
141 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
142 m3_support_valid),
143 },
144 {
145 .data_type = QMI_UNSIGNED_1_BYTE,
146 .elem_len = 1,
147 .elem_size = sizeof(u8),
148 .array_type = NO_ARRAY,
149 .tlv_type = 0x16,
150 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
151 m3_support),
152 },
153 {
154 .data_type = QMI_OPT_FLAG,
155 .elem_len = 1,
156 .elem_size = sizeof(u8),
157 .array_type = NO_ARRAY,
158 .tlv_type = 0x17,
159 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
160 m3_cache_support_valid),
161 },
162 {
163 .data_type = QMI_UNSIGNED_1_BYTE,
164 .elem_len = 1,
165 .elem_size = sizeof(u8),
166 .array_type = NO_ARRAY,
167 .tlv_type = 0x17,
168 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
169 m3_cache_support),
170 },
171 {
172 .data_type = QMI_OPT_FLAG,
173 .elem_len = 1,
174 .elem_size = sizeof(u8),
175 .array_type = NO_ARRAY,
176 .tlv_type = 0x18,
177 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
178 cal_filesys_support_valid),
179 },
180 {
181 .data_type = QMI_UNSIGNED_1_BYTE,
182 .elem_len = 1,
183 .elem_size = sizeof(u8),
184 .array_type = NO_ARRAY,
185 .tlv_type = 0x18,
186 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
187 cal_filesys_support),
188 },
189 {
190 .data_type = QMI_OPT_FLAG,
191 .elem_len = 1,
192 .elem_size = sizeof(u8),
193 .array_type = NO_ARRAY,
194 .tlv_type = 0x19,
195 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
196 cal_cache_support_valid),
197 },
198 {
199 .data_type = QMI_UNSIGNED_1_BYTE,
200 .elem_len = 1,
201 .elem_size = sizeof(u8),
202 .array_type = NO_ARRAY,
203 .tlv_type = 0x19,
204 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
205 cal_cache_support),
206 },
207 {
208 .data_type = QMI_OPT_FLAG,
209 .elem_len = 1,
210 .elem_size = sizeof(u8),
211 .array_type = NO_ARRAY,
212 .tlv_type = 0x1A,
213 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
214 cal_done_valid),
215 },
216 {
217 .data_type = QMI_UNSIGNED_1_BYTE,
218 .elem_len = 1,
219 .elem_size = sizeof(u8),
220 .array_type = NO_ARRAY,
221 .tlv_type = 0x1A,
222 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
223 cal_done),
224 },
225 {
226 .data_type = QMI_OPT_FLAG,
227 .elem_len = 1,
228 .elem_size = sizeof(u8),
229 .array_type = NO_ARRAY,
230 .tlv_type = 0x1B,
231 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
232 mem_bucket_valid),
233 },
234 {
235 .data_type = QMI_UNSIGNED_4_BYTE,
236 .elem_len = 1,
237 .elem_size = sizeof(u32),
238 .array_type = NO_ARRAY,
239 .tlv_type = 0x1B,
240 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
241 mem_bucket),
242 },
243 {
244 .data_type = QMI_OPT_FLAG,
245 .elem_len = 1,
246 .elem_size = sizeof(u8),
247 .array_type = NO_ARRAY,
248 .tlv_type = 0x1C,
249 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
250 mem_cfg_mode_valid),
251 },
252 {
253 .data_type = QMI_UNSIGNED_1_BYTE,
254 .elem_len = 1,
255 .elem_size = sizeof(u8),
256 .array_type = NO_ARRAY,
257 .tlv_type = 0x1C,
258 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
259 mem_cfg_mode),
260 },
261 {
262 .data_type = QMI_EOTI,
263 .array_type = NO_ARRAY,
264 .tlv_type = QMI_COMMON_TLV_TYPE,
265 },
266 };
267
268 static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {
269 {
270 .data_type = QMI_STRUCT,
271 .elem_len = 1,
272 .elem_size = sizeof(struct qmi_response_type_v01),
273 .array_type = NO_ARRAY,
274 .tlv_type = 0x02,
275 .offset = offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),
276 .ei_array = qmi_response_type_v01_ei,
277 },
278 {
279 .data_type = QMI_EOTI,
280 .array_type = NO_ARRAY,
281 .tlv_type = QMI_COMMON_TLV_TYPE,
282 },
283 };
284
285 static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {
286 {
287 .data_type = QMI_OPT_FLAG,
288 .elem_len = 1,
289 .elem_size = sizeof(u8),
290 .array_type = NO_ARRAY,
291 .tlv_type = 0x10,
292 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
293 fw_ready_enable_valid),
294 },
295 {
296 .data_type = QMI_UNSIGNED_1_BYTE,
297 .elem_len = 1,
298 .elem_size = sizeof(u8),
299 .array_type = NO_ARRAY,
300 .tlv_type = 0x10,
301 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
302 fw_ready_enable),
303 },
304 {
305 .data_type = QMI_OPT_FLAG,
306 .elem_len = 1,
307 .elem_size = sizeof(u8),
308 .array_type = NO_ARRAY,
309 .tlv_type = 0x11,
310 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
311 initiate_cal_download_enable_valid),
312 },
313 {
314 .data_type = QMI_UNSIGNED_1_BYTE,
315 .elem_len = 1,
316 .elem_size = sizeof(u8),
317 .array_type = NO_ARRAY,
318 .tlv_type = 0x11,
319 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
320 initiate_cal_download_enable),
321 },
322 {
323 .data_type = QMI_OPT_FLAG,
324 .elem_len = 1,
325 .elem_size = sizeof(u8),
326 .array_type = NO_ARRAY,
327 .tlv_type = 0x12,
328 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
329 initiate_cal_update_enable_valid),
330 },
331 {
332 .data_type = QMI_UNSIGNED_1_BYTE,
333 .elem_len = 1,
334 .elem_size = sizeof(u8),
335 .array_type = NO_ARRAY,
336 .tlv_type = 0x12,
337 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
338 initiate_cal_update_enable),
339 },
340 {
341 .data_type = QMI_OPT_FLAG,
342 .elem_len = 1,
343 .elem_size = sizeof(u8),
344 .array_type = NO_ARRAY,
345 .tlv_type = 0x13,
346 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
347 msa_ready_enable_valid),
348 },
349 {
350 .data_type = QMI_UNSIGNED_1_BYTE,
351 .elem_len = 1,
352 .elem_size = sizeof(u8),
353 .array_type = NO_ARRAY,
354 .tlv_type = 0x13,
355 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
356 msa_ready_enable),
357 },
358 {
359 .data_type = QMI_OPT_FLAG,
360 .elem_len = 1,
361 .elem_size = sizeof(u8),
362 .array_type = NO_ARRAY,
363 .tlv_type = 0x14,
364 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
365 pin_connect_result_enable_valid),
366 },
367 {
368 .data_type = QMI_UNSIGNED_1_BYTE,
369 .elem_len = 1,
370 .elem_size = sizeof(u8),
371 .array_type = NO_ARRAY,
372 .tlv_type = 0x14,
373 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
374 pin_connect_result_enable),
375 },
376 {
377 .data_type = QMI_OPT_FLAG,
378 .elem_len = 1,
379 .elem_size = sizeof(u8),
380 .array_type = NO_ARRAY,
381 .tlv_type = 0x15,
382 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
383 client_id_valid),
384 },
385 {
386 .data_type = QMI_UNSIGNED_4_BYTE,
387 .elem_len = 1,
388 .elem_size = sizeof(u32),
389 .array_type = NO_ARRAY,
390 .tlv_type = 0x15,
391 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
392 client_id),
393 },
394 {
395 .data_type = QMI_OPT_FLAG,
396 .elem_len = 1,
397 .elem_size = sizeof(u8),
398 .array_type = NO_ARRAY,
399 .tlv_type = 0x16,
400 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
401 request_mem_enable_valid),
402 },
403 {
404 .data_type = QMI_UNSIGNED_1_BYTE,
405 .elem_len = 1,
406 .elem_size = sizeof(u8),
407 .array_type = NO_ARRAY,
408 .tlv_type = 0x16,
409 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
410 request_mem_enable),
411 },
412 {
413 .data_type = QMI_OPT_FLAG,
414 .elem_len = 1,
415 .elem_size = sizeof(u8),
416 .array_type = NO_ARRAY,
417 .tlv_type = 0x17,
418 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
419 fw_mem_ready_enable_valid),
420 },
421 {
422 .data_type = QMI_UNSIGNED_1_BYTE,
423 .elem_len = 1,
424 .elem_size = sizeof(u8),
425 .array_type = NO_ARRAY,
426 .tlv_type = 0x17,
427 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
428 fw_mem_ready_enable),
429 },
430 {
431 .data_type = QMI_OPT_FLAG,
432 .elem_len = 1,
433 .elem_size = sizeof(u8),
434 .array_type = NO_ARRAY,
435 .tlv_type = 0x18,
436 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
437 fw_init_done_enable_valid),
438 },
439 {
440 .data_type = QMI_UNSIGNED_1_BYTE,
441 .elem_len = 1,
442 .elem_size = sizeof(u8),
443 .array_type = NO_ARRAY,
444 .tlv_type = 0x18,
445 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
446 fw_init_done_enable),
447 },
448
449 {
450 .data_type = QMI_OPT_FLAG,
451 .elem_len = 1,
452 .elem_size = sizeof(u8),
453 .array_type = NO_ARRAY,
454 .tlv_type = 0x19,
455 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
456 rejuvenate_enable_valid),
457 },
458 {
459 .data_type = QMI_UNSIGNED_1_BYTE,
460 .elem_len = 1,
461 .elem_size = sizeof(u8),
462 .array_type = NO_ARRAY,
463 .tlv_type = 0x19,
464 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
465 rejuvenate_enable),
466 },
467 {
468 .data_type = QMI_OPT_FLAG,
469 .elem_len = 1,
470 .elem_size = sizeof(u8),
471 .array_type = NO_ARRAY,
472 .tlv_type = 0x1A,
473 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
474 xo_cal_enable_valid),
475 },
476 {
477 .data_type = QMI_UNSIGNED_1_BYTE,
478 .elem_len = 1,
479 .elem_size = sizeof(u8),
480 .array_type = NO_ARRAY,
481 .tlv_type = 0x1A,
482 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
483 xo_cal_enable),
484 },
485 {
486 .data_type = QMI_OPT_FLAG,
487 .elem_len = 1,
488 .elem_size = sizeof(u8),
489 .array_type = NO_ARRAY,
490 .tlv_type = 0x1B,
491 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
492 cal_done_enable_valid),
493 },
494 {
495 .data_type = QMI_UNSIGNED_1_BYTE,
496 .elem_len = 1,
497 .elem_size = sizeof(u8),
498 .array_type = NO_ARRAY,
499 .tlv_type = 0x1B,
500 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,
501 cal_done_enable),
502 },
503 {
504 .data_type = QMI_EOTI,
505 .array_type = NO_ARRAY,
506 .tlv_type = QMI_COMMON_TLV_TYPE,
507 },
508 };
509
510 static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {
511 {
512 .data_type = QMI_STRUCT,
513 .elem_len = 1,
514 .elem_size = sizeof(struct qmi_response_type_v01),
515 .array_type = NO_ARRAY,
516 .tlv_type = 0x02,
517 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
518 resp),
519 .ei_array = qmi_response_type_v01_ei,
520 },
521 {
522 .data_type = QMI_OPT_FLAG,
523 .elem_len = 1,
524 .elem_size = sizeof(u8),
525 .array_type = NO_ARRAY,
526 .tlv_type = 0x10,
527 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
528 fw_status_valid),
529 },
530 {
531 .data_type = QMI_UNSIGNED_8_BYTE,
532 .elem_len = 1,
533 .elem_size = sizeof(u64),
534 .array_type = NO_ARRAY,
535 .tlv_type = 0x10,
536 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,
537 fw_status),
538 },
539 {
540 .data_type = QMI_EOTI,
541 .array_type = NO_ARRAY,
542 .tlv_type = QMI_COMMON_TLV_TYPE,
543 },
544 };
545
546 static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {
547 {
548 .data_type = QMI_UNSIGNED_8_BYTE,
549 .elem_len = 1,
550 .elem_size = sizeof(u64),
551 .array_type = NO_ARRAY,
552 .tlv_type = 0,
553 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),
554 },
555 {
556 .data_type = QMI_UNSIGNED_4_BYTE,
557 .elem_len = 1,
558 .elem_size = sizeof(u32),
559 .array_type = NO_ARRAY,
560 .tlv_type = 0,
561 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),
562 },
563 {
564 .data_type = QMI_UNSIGNED_1_BYTE,
565 .elem_len = 1,
566 .elem_size = sizeof(u8),
567 .array_type = NO_ARRAY,
568 .tlv_type = 0,
569 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),
570 },
571 {
572 .data_type = QMI_EOTI,
573 .array_type = NO_ARRAY,
574 .tlv_type = QMI_COMMON_TLV_TYPE,
575 },
576 };
577
578 static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {
579 {
580 .data_type = QMI_UNSIGNED_4_BYTE,
581 .elem_len = 1,
582 .elem_size = sizeof(u32),
583 .array_type = NO_ARRAY,
584 .tlv_type = 0,
585 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01,
586 size),
587 },
588 {
589 .data_type = QMI_SIGNED_4_BYTE_ENUM,
590 .elem_len = 1,
591 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
592 .array_type = NO_ARRAY,
593 .tlv_type = 0,
594 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),
595 },
596 {
597 .data_type = QMI_DATA_LEN,
598 .elem_len = 1,
599 .elem_size = sizeof(u8),
600 .array_type = NO_ARRAY,
601 .tlv_type = 0,
602 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),
603 },
604 {
605 .data_type = QMI_STRUCT,
606 .elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01,
607 .elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01),
608 .array_type = VAR_LEN_ARRAY,
609 .tlv_type = 0,
610 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),
611 .ei_array = qmi_wlanfw_mem_cfg_s_v01_ei,
612 },
613 {
614 .data_type = QMI_EOTI,
615 .array_type = NO_ARRAY,
616 .tlv_type = QMI_COMMON_TLV_TYPE,
617 },
618 };
619
620 static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {
621 {
622 .data_type = QMI_DATA_LEN,
623 .elem_len = 1,
624 .elem_size = sizeof(u8),
625 .array_type = NO_ARRAY,
626 .tlv_type = 0x01,
627 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
628 mem_seg_len),
629 },
630 {
631 .data_type = QMI_STRUCT,
632 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
633 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01),
634 .array_type = VAR_LEN_ARRAY,
635 .tlv_type = 0x01,
636 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,
637 mem_seg),
638 .ei_array = qmi_wlanfw_mem_seg_s_v01_ei,
639 },
640 {
641 .data_type = QMI_EOTI,
642 .array_type = NO_ARRAY,
643 .tlv_type = QMI_COMMON_TLV_TYPE,
644 },
645 };
646
647 static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {
648 {
649 .data_type = QMI_UNSIGNED_8_BYTE,
650 .elem_len = 1,
651 .elem_size = sizeof(u64),
652 .array_type = NO_ARRAY,
653 .tlv_type = 0,
654 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),
655 },
656 {
657 .data_type = QMI_UNSIGNED_4_BYTE,
658 .elem_len = 1,
659 .elem_size = sizeof(u32),
660 .array_type = NO_ARRAY,
661 .tlv_type = 0,
662 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),
663 },
664 {
665 .data_type = QMI_SIGNED_4_BYTE_ENUM,
666 .elem_len = 1,
667 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),
668 .array_type = NO_ARRAY,
669 .tlv_type = 0,
670 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),
671 },
672 {
673 .data_type = QMI_UNSIGNED_1_BYTE,
674 .elem_len = 1,
675 .elem_size = sizeof(u8),
676 .array_type = NO_ARRAY,
677 .tlv_type = 0,
678 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),
679 },
680 {
681 .data_type = QMI_EOTI,
682 .array_type = NO_ARRAY,
683 .tlv_type = QMI_COMMON_TLV_TYPE,
684 },
685 };
686
687 static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {
688 {
689 .data_type = QMI_DATA_LEN,
690 .elem_len = 1,
691 .elem_size = sizeof(u8),
692 .array_type = NO_ARRAY,
693 .tlv_type = 0x01,
694 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
695 mem_seg_len),
696 },
697 {
698 .data_type = QMI_STRUCT,
699 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,
700 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),
701 .array_type = VAR_LEN_ARRAY,
702 .tlv_type = 0x01,
703 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,
704 mem_seg),
705 .ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei,
706 },
707 {
708 .data_type = QMI_EOTI,
709 .array_type = NO_ARRAY,
710 .tlv_type = QMI_COMMON_TLV_TYPE,
711 },
712 };
713
714 static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {
715 {
716 .data_type = QMI_STRUCT,
717 .elem_len = 1,
718 .elem_size = sizeof(struct qmi_response_type_v01),
719 .array_type = NO_ARRAY,
720 .tlv_type = 0x02,
721 .offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,
722 resp),
723 .ei_array = qmi_response_type_v01_ei,
724 },
725 {
726 .data_type = QMI_EOTI,
727 .array_type = NO_ARRAY,
728 .tlv_type = QMI_COMMON_TLV_TYPE,
729 },
730 };
731
732 static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {
733 {
734 .data_type = QMI_EOTI,
735 .array_type = NO_ARRAY,
736 .tlv_type = QMI_COMMON_TLV_TYPE,
737 },
738 };
739
740 static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {
741 {
742 .data_type = QMI_UNSIGNED_4_BYTE,
743 .elem_len = 1,
744 .elem_size = sizeof(u32),
745 .array_type = NO_ARRAY,
746 .tlv_type = 0,
747 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
748 chip_id),
749 },
750 {
751 .data_type = QMI_UNSIGNED_4_BYTE,
752 .elem_len = 1,
753 .elem_size = sizeof(u32),
754 .array_type = NO_ARRAY,
755 .tlv_type = 0,
756 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,
757 chip_family),
758 },
759 {
760 .data_type = QMI_EOTI,
761 .array_type = NO_ARRAY,
762 .tlv_type = QMI_COMMON_TLV_TYPE,
763 },
764 };
765
766 static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {
767 {
768 .data_type = QMI_UNSIGNED_4_BYTE,
769 .elem_len = 1,
770 .elem_size = sizeof(u32),
771 .array_type = NO_ARRAY,
772 .tlv_type = 0,
773 .offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01,
774 board_id),
775 },
776 {
777 .data_type = QMI_EOTI,
778 .array_type = NO_ARRAY,
779 .tlv_type = QMI_COMMON_TLV_TYPE,
780 },
781 };
782
783 static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {
784 {
785 .data_type = QMI_UNSIGNED_4_BYTE,
786 .elem_len = 1,
787 .elem_size = sizeof(u32),
788 .array_type = NO_ARRAY,
789 .tlv_type = 0,
790 .offset = offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),
791 },
792 {
793 .data_type = QMI_EOTI,
794 .array_type = NO_ARRAY,
795 .tlv_type = QMI_COMMON_TLV_TYPE,
796 },
797 };
798
799 static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {
800 {
801 .data_type = QMI_UNSIGNED_4_BYTE,
802 .elem_len = 1,
803 .elem_size = sizeof(u32),
804 .array_type = NO_ARRAY,
805 .tlv_type = 0,
806 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
807 fw_version),
808 },
809 {
810 .data_type = QMI_STRING,
811 .elem_len = ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,
812 .elem_size = sizeof(char),
813 .array_type = NO_ARRAY,
814 .tlv_type = 0,
815 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,
816 fw_build_timestamp),
817 },
818 {
819 .data_type = QMI_EOTI,
820 .array_type = NO_ARRAY,
821 .tlv_type = QMI_COMMON_TLV_TYPE,
822 },
823 };
824
825 static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {
826 {
827 .data_type = QMI_STRUCT,
828 .elem_len = 1,
829 .elem_size = sizeof(struct qmi_response_type_v01),
830 .array_type = NO_ARRAY,
831 .tlv_type = 0x02,
832 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),
833 .ei_array = qmi_response_type_v01_ei,
834 },
835 {
836 .data_type = QMI_OPT_FLAG,
837 .elem_len = 1,
838 .elem_size = sizeof(u8),
839 .array_type = NO_ARRAY,
840 .tlv_type = 0x10,
841 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
842 chip_info_valid),
843 },
844 {
845 .data_type = QMI_STRUCT,
846 .elem_len = 1,
847 .elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),
848 .array_type = NO_ARRAY,
849 .tlv_type = 0x10,
850 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
851 chip_info),
852 .ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei,
853 },
854 {
855 .data_type = QMI_OPT_FLAG,
856 .elem_len = 1,
857 .elem_size = sizeof(u8),
858 .array_type = NO_ARRAY,
859 .tlv_type = 0x11,
860 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
861 board_info_valid),
862 },
863 {
864 .data_type = QMI_STRUCT,
865 .elem_len = 1,
866 .elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01),
867 .array_type = NO_ARRAY,
868 .tlv_type = 0x11,
869 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
870 board_info),
871 .ei_array = qmi_wlanfw_rf_board_info_s_v01_ei,
872 },
873 {
874 .data_type = QMI_OPT_FLAG,
875 .elem_len = 1,
876 .elem_size = sizeof(u8),
877 .array_type = NO_ARRAY,
878 .tlv_type = 0x12,
879 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
880 soc_info_valid),
881 },
882 {
883 .data_type = QMI_STRUCT,
884 .elem_len = 1,
885 .elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01),
886 .array_type = NO_ARRAY,
887 .tlv_type = 0x12,
888 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
889 soc_info),
890 .ei_array = qmi_wlanfw_soc_info_s_v01_ei,
891 },
892 {
893 .data_type = QMI_OPT_FLAG,
894 .elem_len = 1,
895 .elem_size = sizeof(u8),
896 .array_type = NO_ARRAY,
897 .tlv_type = 0x13,
898 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
899 fw_version_info_valid),
900 },
901 {
902 .data_type = QMI_STRUCT,
903 .elem_len = 1,
904 .elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01),
905 .array_type = NO_ARRAY,
906 .tlv_type = 0x13,
907 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
908 fw_version_info),
909 .ei_array = qmi_wlanfw_fw_version_info_s_v01_ei,
910 },
911 {
912 .data_type = QMI_OPT_FLAG,
913 .elem_len = 1,
914 .elem_size = sizeof(u8),
915 .array_type = NO_ARRAY,
916 .tlv_type = 0x14,
917 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
918 fw_build_id_valid),
919 },
920 {
921 .data_type = QMI_STRING,
922 .elem_len = ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,
923 .elem_size = sizeof(char),
924 .array_type = NO_ARRAY,
925 .tlv_type = 0x14,
926 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
927 fw_build_id),
928 },
929 {
930 .data_type = QMI_OPT_FLAG,
931 .elem_len = 1,
932 .elem_size = sizeof(u8),
933 .array_type = NO_ARRAY,
934 .tlv_type = 0x15,
935 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
936 num_macs_valid),
937 },
938 {
939 .data_type = QMI_UNSIGNED_1_BYTE,
940 .elem_len = 1,
941 .elem_size = sizeof(u8),
942 .array_type = NO_ARRAY,
943 .tlv_type = 0x15,
944 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,
945 num_macs),
946 },
947 {
948 .data_type = QMI_EOTI,
949 .array_type = NO_ARRAY,
950 .tlv_type = QMI_COMMON_TLV_TYPE,
951 },
952 };
953
954 static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {
955 {
956 .data_type = QMI_UNSIGNED_1_BYTE,
957 .elem_len = 1,
958 .elem_size = sizeof(u8),
959 .array_type = NO_ARRAY,
960 .tlv_type = 0x01,
961 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
962 valid),
963 },
964 {
965 .data_type = QMI_OPT_FLAG,
966 .elem_len = 1,
967 .elem_size = sizeof(u8),
968 .array_type = NO_ARRAY,
969 .tlv_type = 0x10,
970 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
971 file_id_valid),
972 },
973 {
974 .data_type = QMI_SIGNED_4_BYTE_ENUM,
975 .elem_len = 1,
976 .elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),
977 .array_type = NO_ARRAY,
978 .tlv_type = 0x10,
979 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
980 file_id),
981 },
982 {
983 .data_type = QMI_OPT_FLAG,
984 .elem_len = 1,
985 .elem_size = sizeof(u8),
986 .array_type = NO_ARRAY,
987 .tlv_type = 0x11,
988 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
989 total_size_valid),
990 },
991 {
992 .data_type = QMI_UNSIGNED_4_BYTE,
993 .elem_len = 1,
994 .elem_size = sizeof(u32),
995 .array_type = NO_ARRAY,
996 .tlv_type = 0x11,
997 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
998 total_size),
999 },
1000 {
1001 .data_type = QMI_OPT_FLAG,
1002 .elem_len = 1,
1003 .elem_size = sizeof(u8),
1004 .array_type = NO_ARRAY,
1005 .tlv_type = 0x12,
1006 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1007 seg_id_valid),
1008 },
1009 {
1010 .data_type = QMI_UNSIGNED_4_BYTE,
1011 .elem_len = 1,
1012 .elem_size = sizeof(u32),
1013 .array_type = NO_ARRAY,
1014 .tlv_type = 0x12,
1015 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1016 seg_id),
1017 },
1018 {
1019 .data_type = QMI_OPT_FLAG,
1020 .elem_len = 1,
1021 .elem_size = sizeof(u8),
1022 .array_type = NO_ARRAY,
1023 .tlv_type = 0x13,
1024 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1025 data_valid),
1026 },
1027 {
1028 .data_type = QMI_DATA_LEN,
1029 .elem_len = 1,
1030 .elem_size = sizeof(u16),
1031 .array_type = NO_ARRAY,
1032 .tlv_type = 0x13,
1033 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1034 data_len),
1035 },
1036 {
1037 .data_type = QMI_UNSIGNED_1_BYTE,
1038 .elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01,
1039 .elem_size = sizeof(u8),
1040 .array_type = VAR_LEN_ARRAY,
1041 .tlv_type = 0x13,
1042 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1043 data),
1044 },
1045 {
1046 .data_type = QMI_OPT_FLAG,
1047 .elem_len = 1,
1048 .elem_size = sizeof(u8),
1049 .array_type = NO_ARRAY,
1050 .tlv_type = 0x14,
1051 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1052 end_valid),
1053 },
1054 {
1055 .data_type = QMI_UNSIGNED_1_BYTE,
1056 .elem_len = 1,
1057 .elem_size = sizeof(u8),
1058 .array_type = NO_ARRAY,
1059 .tlv_type = 0x14,
1060 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1061 end),
1062 },
1063 {
1064 .data_type = QMI_OPT_FLAG,
1065 .elem_len = 1,
1066 .elem_size = sizeof(u8),
1067 .array_type = NO_ARRAY,
1068 .tlv_type = 0x15,
1069 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1070 bdf_type_valid),
1071 },
1072 {
1073 .data_type = QMI_UNSIGNED_1_BYTE,
1074 .elem_len = 1,
1075 .elem_size = sizeof(u8),
1076 .array_type = NO_ARRAY,
1077 .tlv_type = 0x15,
1078 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,
1079 bdf_type),
1080 },
1081
1082 {
1083 .data_type = QMI_EOTI,
1084 .array_type = NO_ARRAY,
1085 .tlv_type = QMI_COMMON_TLV_TYPE,
1086 },
1087 };
1088
1089 static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {
1090 {
1091 .data_type = QMI_STRUCT,
1092 .elem_len = 1,
1093 .elem_size = sizeof(struct qmi_response_type_v01),
1094 .array_type = NO_ARRAY,
1095 .tlv_type = 0x02,
1096 .offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,
1097 resp),
1098 .ei_array = qmi_response_type_v01_ei,
1099 },
1100 {
1101 .data_type = QMI_EOTI,
1102 .array_type = NO_ARRAY,
1103 .tlv_type = QMI_COMMON_TLV_TYPE,
1104 },
1105 };
1106
1107 static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {
1108 {
1109 .data_type = QMI_UNSIGNED_8_BYTE,
1110 .elem_len = 1,
1111 .elem_size = sizeof(u64),
1112 .array_type = NO_ARRAY,
1113 .tlv_type = 0x01,
1114 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),
1115 },
1116 {
1117 .data_type = QMI_UNSIGNED_4_BYTE,
1118 .elem_len = 1,
1119 .elem_size = sizeof(u32),
1120 .array_type = NO_ARRAY,
1121 .tlv_type = 0x02,
1122 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),
1123 },
1124 {
1125 .data_type = QMI_EOTI,
1126 .array_type = NO_ARRAY,
1127 .tlv_type = QMI_COMMON_TLV_TYPE,
1128 },
1129 };
1130
1131 static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {
1132 {
1133 .data_type = QMI_STRUCT,
1134 .elem_len = 1,
1135 .elem_size = sizeof(struct qmi_response_type_v01),
1136 .array_type = NO_ARRAY,
1137 .tlv_type = 0x02,
1138 .offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),
1139 .ei_array = qmi_response_type_v01_ei,
1140 },
1141 {
1142 .data_type = QMI_EOTI,
1143 .array_type = NO_ARRAY,
1144 .tlv_type = QMI_COMMON_TLV_TYPE,
1145 },
1146 };
1147
1148 static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {
1149 {
1150 .data_type = QMI_UNSIGNED_4_BYTE,
1151 .elem_len = 1,
1152 .elem_size = sizeof(u32),
1153 .array_type = NO_ARRAY,
1154 .tlv_type = 0,
1155 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1156 pipe_num),
1157 },
1158 {
1159 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1160 .elem_len = 1,
1161 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1162 .array_type = NO_ARRAY,
1163 .tlv_type = 0,
1164 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1165 pipe_dir),
1166 },
1167 {
1168 .data_type = QMI_UNSIGNED_4_BYTE,
1169 .elem_len = 1,
1170 .elem_size = sizeof(u32),
1171 .array_type = NO_ARRAY,
1172 .tlv_type = 0,
1173 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1174 nentries),
1175 },
1176 {
1177 .data_type = QMI_UNSIGNED_4_BYTE,
1178 .elem_len = 1,
1179 .elem_size = sizeof(u32),
1180 .array_type = NO_ARRAY,
1181 .tlv_type = 0,
1182 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1183 nbytes_max),
1184 },
1185 {
1186 .data_type = QMI_UNSIGNED_4_BYTE,
1187 .elem_len = 1,
1188 .elem_size = sizeof(u32),
1189 .array_type = NO_ARRAY,
1190 .tlv_type = 0,
1191 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,
1192 flags),
1193 },
1194 {
1195 .data_type = QMI_EOTI,
1196 .array_type = NO_ARRAY,
1197 .tlv_type = QMI_COMMON_TLV_TYPE,
1198 },
1199 };
1200
1201 static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {
1202 {
1203 .data_type = QMI_UNSIGNED_4_BYTE,
1204 .elem_len = 1,
1205 .elem_size = sizeof(u32),
1206 .array_type = NO_ARRAY,
1207 .tlv_type = 0,
1208 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1209 service_id),
1210 },
1211 {
1212 .data_type = QMI_SIGNED_4_BYTE_ENUM,
1213 .elem_len = 1,
1214 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),
1215 .array_type = NO_ARRAY,
1216 .tlv_type = 0,
1217 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1218 pipe_dir),
1219 },
1220 {
1221 .data_type = QMI_UNSIGNED_4_BYTE,
1222 .elem_len = 1,
1223 .elem_size = sizeof(u32),
1224 .array_type = NO_ARRAY,
1225 .tlv_type = 0,
1226 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,
1227 pipe_num),
1228 },
1229 {
1230 .data_type = QMI_EOTI,
1231 .array_type = NO_ARRAY,
1232 .tlv_type = QMI_COMMON_TLV_TYPE,
1233 },
1234 };
1235
1236 static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {
1237 {
1238 .data_type = QMI_UNSIGNED_2_BYTE,
1239 .elem_len = 1,
1240 .elem_size = sizeof(u16),
1241 .array_type = NO_ARRAY,
1242 .tlv_type = 0,
1243 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),
1244 },
1245 {
1246 .data_type = QMI_UNSIGNED_2_BYTE,
1247 .elem_len = 1,
1248 .elem_size = sizeof(u16),
1249 .array_type = NO_ARRAY,
1250 .tlv_type = 0,
1251 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,
1252 offset),
1253 },
1254 {
1255 .data_type = QMI_EOTI,
1256 .array_type = QMI_COMMON_TLV_TYPE,
1257 },
1258 };
1259
1260 static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {
1261 {
1262 .data_type = QMI_UNSIGNED_4_BYTE,
1263 .elem_len = 1,
1264 .elem_size = sizeof(u32),
1265 .array_type = NO_ARRAY,
1266 .tlv_type = 0,
1267 .offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,
1268 addr),
1269 },
1270 {
1271 .data_type = QMI_EOTI,
1272 .array_type = NO_ARRAY,
1273 .tlv_type = QMI_COMMON_TLV_TYPE,
1274 },
1275 };
1276
1277 static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {
1278 {
1279 .data_type = QMI_UNSIGNED_4_BYTE,
1280 .elem_len = 1,
1281 .elem_size = sizeof(u32),
1282 .array_type = NO_ARRAY,
1283 .tlv_type = 0x01,
1284 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1285 mode),
1286 },
1287 {
1288 .data_type = QMI_OPT_FLAG,
1289 .elem_len = 1,
1290 .elem_size = sizeof(u8),
1291 .array_type = NO_ARRAY,
1292 .tlv_type = 0x10,
1293 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1294 hw_debug_valid),
1295 },
1296 {
1297 .data_type = QMI_UNSIGNED_1_BYTE,
1298 .elem_len = 1,
1299 .elem_size = sizeof(u8),
1300 .array_type = NO_ARRAY,
1301 .tlv_type = 0x10,
1302 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,
1303 hw_debug),
1304 },
1305 {
1306 .data_type = QMI_EOTI,
1307 .array_type = NO_ARRAY,
1308 .tlv_type = QMI_COMMON_TLV_TYPE,
1309 },
1310 };
1311
1312 static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {
1313 {
1314 .data_type = QMI_STRUCT,
1315 .elem_len = 1,
1316 .elem_size = sizeof(struct qmi_response_type_v01),
1317 .array_type = NO_ARRAY,
1318 .tlv_type = 0x02,
1319 .offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,
1320 resp),
1321 .ei_array = qmi_response_type_v01_ei,
1322 },
1323 {
1324 .data_type = QMI_EOTI,
1325 .array_type = NO_ARRAY,
1326 .tlv_type = QMI_COMMON_TLV_TYPE,
1327 },
1328 };
1329
1330 static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {
1331 {
1332 .data_type = QMI_OPT_FLAG,
1333 .elem_len = 1,
1334 .elem_size = sizeof(u8),
1335 .array_type = NO_ARRAY,
1336 .tlv_type = 0x10,
1337 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1338 host_version_valid),
1339 },
1340 {
1341 .data_type = QMI_STRING,
1342 .elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1,
1343 .elem_size = sizeof(char),
1344 .array_type = NO_ARRAY,
1345 .tlv_type = 0x10,
1346 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1347 host_version),
1348 },
1349 {
1350 .data_type = QMI_OPT_FLAG,
1351 .elem_len = 1,
1352 .elem_size = sizeof(u8),
1353 .array_type = NO_ARRAY,
1354 .tlv_type = 0x11,
1355 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1356 tgt_cfg_valid),
1357 },
1358 {
1359 .data_type = QMI_DATA_LEN,
1360 .elem_len = 1,
1361 .elem_size = sizeof(u8),
1362 .array_type = NO_ARRAY,
1363 .tlv_type = 0x11,
1364 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1365 tgt_cfg_len),
1366 },
1367 {
1368 .data_type = QMI_STRUCT,
1369 .elem_len = QMI_WLANFW_MAX_NUM_CE_V01,
1370 .elem_size = sizeof(
1371 struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),
1372 .array_type = VAR_LEN_ARRAY,
1373 .tlv_type = 0x11,
1374 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1375 tgt_cfg),
1376 .ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,
1377 },
1378 {
1379 .data_type = QMI_OPT_FLAG,
1380 .elem_len = 1,
1381 .elem_size = sizeof(u8),
1382 .array_type = NO_ARRAY,
1383 .tlv_type = 0x12,
1384 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1385 svc_cfg_valid),
1386 },
1387 {
1388 .data_type = QMI_DATA_LEN,
1389 .elem_len = 1,
1390 .elem_size = sizeof(u8),
1391 .array_type = NO_ARRAY,
1392 .tlv_type = 0x12,
1393 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1394 svc_cfg_len),
1395 },
1396 {
1397 .data_type = QMI_STRUCT,
1398 .elem_len = QMI_WLANFW_MAX_NUM_SVC_V01,
1399 .elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),
1400 .array_type = VAR_LEN_ARRAY,
1401 .tlv_type = 0x12,
1402 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1403 svc_cfg),
1404 .ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,
1405 },
1406 {
1407 .data_type = QMI_OPT_FLAG,
1408 .elem_len = 1,
1409 .elem_size = sizeof(u8),
1410 .array_type = NO_ARRAY,
1411 .tlv_type = 0x13,
1412 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1413 shadow_reg_valid),
1414 },
1415 {
1416 .data_type = QMI_DATA_LEN,
1417 .elem_len = 1,
1418 .elem_size = sizeof(u8),
1419 .array_type = NO_ARRAY,
1420 .tlv_type = 0x13,
1421 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1422 shadow_reg_len),
1423 },
1424 {
1425 .data_type = QMI_STRUCT,
1426 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,
1427 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),
1428 .array_type = VAR_LEN_ARRAY,
1429 .tlv_type = 0x13,
1430 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1431 shadow_reg),
1432 .ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei,
1433 },
1434 {
1435 .data_type = QMI_OPT_FLAG,
1436 .elem_len = 1,
1437 .elem_size = sizeof(u8),
1438 .array_type = NO_ARRAY,
1439 .tlv_type = 0x14,
1440 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1441 shadow_reg_v2_valid),
1442 },
1443 {
1444 .data_type = QMI_DATA_LEN,
1445 .elem_len = 1,
1446 .elem_size = sizeof(u8),
1447 .array_type = NO_ARRAY,
1448 .tlv_type = 0x14,
1449 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1450 shadow_reg_v2_len),
1451 },
1452 {
1453 .data_type = QMI_STRUCT,
1454 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,
1455 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),
1456 .array_type = VAR_LEN_ARRAY,
1457 .tlv_type = 0x14,
1458 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,
1459 shadow_reg_v2),
1460 .ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,
1461 },
1462 {
1463 .data_type = QMI_EOTI,
1464 .array_type = NO_ARRAY,
1465 .tlv_type = QMI_COMMON_TLV_TYPE,
1466 },
1467 };
1468
1469 static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {
1470 {
1471 .data_type = QMI_STRUCT,
1472 .elem_len = 1,
1473 .elem_size = sizeof(struct qmi_response_type_v01),
1474 .array_type = NO_ARRAY,
1475 .tlv_type = 0x02,
1476 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),
1477 .ei_array = qmi_response_type_v01_ei,
1478 },
1479 {
1480 .data_type = QMI_EOTI,
1481 .array_type = NO_ARRAY,
1482 .tlv_type = QMI_COMMON_TLV_TYPE,
1483 },
1484 };
1485
1486 static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {
1487 {
1488 .data_type = QMI_EOTI,
1489 .array_type = NO_ARRAY,
1490 },
1491 };
1492
1493 static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {
1494 {
1495 .data_type = QMI_EOTI,
1496 .array_type = NO_ARRAY,
1497 },
1498 };
1499
1500 static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {
1501 {
1502 .data_type = QMI_EOTI,
1503 .array_type = NO_ARRAY,
1504 },
1505 };
1506
ath11k_qmi_host_cap_send(struct ath11k_base * ab)1507 static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)
1508 {
1509 struct qmi_wlanfw_host_cap_req_msg_v01 req;
1510 struct qmi_wlanfw_host_cap_resp_msg_v01 resp;
1511 struct qmi_txn txn = {};
1512 int ret = 0;
1513
1514 memset(&req, 0, sizeof(req));
1515 memset(&resp, 0, sizeof(resp));
1516
1517 req.num_clients_valid = 1;
1518 req.num_clients = 1;
1519 req.mem_cfg_mode = ab->qmi.target_mem_mode;
1520 req.mem_cfg_mode_valid = 1;
1521 req.bdf_support_valid = 1;
1522 req.bdf_support = 1;
1523
1524 if (ab->bus_params.m3_fw_support) {
1525 req.m3_support_valid = 1;
1526 req.m3_support = 1;
1527 req.m3_cache_support_valid = 1;
1528 req.m3_cache_support = 1;
1529 } else {
1530 req.m3_support_valid = 0;
1531 req.m3_support = 0;
1532 req.m3_cache_support_valid = 0;
1533 req.m3_cache_support = 0;
1534 }
1535
1536 req.cal_done_valid = 1;
1537 req.cal_done = ab->qmi.cal_done;
1538
1539 if (ab->hw_params.internal_sleep_clock) {
1540 req.nm_modem_valid = 1;
1541
1542 /* Notify firmware that this is non-qualcomm platform. */
1543 req.nm_modem |= HOST_CSTATE_BIT;
1544
1545 /* Notify firmware about the sleep clock selection,
1546 * nm_modem_bit[1] is used for this purpose. Host driver on
1547 * non-qualcomm platforms should select internal sleep
1548 * clock.
1549 */
1550 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;
1551 }
1552
1553 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1554 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
1555 if (ret < 0)
1556 goto out;
1557
1558 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1559 QMI_WLANFW_HOST_CAP_REQ_V01,
1560 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,
1561 qmi_wlanfw_host_cap_req_msg_v01_ei, &req);
1562 if (ret < 0) {
1563 ath11k_warn(ab, "Failed to send host capability request,err = %d\n", ret);
1564 goto out;
1565 }
1566
1567 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1568 if (ret < 0)
1569 goto out;
1570
1571 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1572 ath11k_warn(ab, "Host capability request failed, result: %d, err: %d\n",
1573 resp.resp.result, resp.resp.error);
1574 ret = -EINVAL;
1575 goto out;
1576 }
1577
1578 out:
1579 return ret;
1580 }
1581
ath11k_qmi_fw_ind_register_send(struct ath11k_base * ab)1582 static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)
1583 {
1584 struct qmi_wlanfw_ind_register_req_msg_v01 *req;
1585 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;
1586 struct qmi_handle *handle = &ab->qmi.handle;
1587 struct qmi_txn txn;
1588 int ret = 0;
1589
1590 req = kzalloc(sizeof(*req), GFP_KERNEL);
1591 if (!req)
1592 return -ENOMEM;
1593
1594 resp = kzalloc(sizeof(*resp), GFP_KERNEL);
1595 if (!resp)
1596 goto resp_out;
1597
1598 req->client_id_valid = 1;
1599 req->client_id = QMI_WLANFW_CLIENT_ID;
1600 req->fw_ready_enable_valid = 1;
1601 req->fw_ready_enable = 1;
1602 req->request_mem_enable_valid = 1;
1603 req->request_mem_enable = 1;
1604 req->fw_mem_ready_enable_valid = 1;
1605 req->fw_mem_ready_enable = 1;
1606 req->cal_done_enable_valid = 1;
1607 req->cal_done_enable = 1;
1608 req->fw_init_done_enable_valid = 1;
1609 req->fw_init_done_enable = 1;
1610
1611 req->pin_connect_result_enable_valid = 0;
1612 req->pin_connect_result_enable = 0;
1613
1614 ret = qmi_txn_init(handle, &txn,
1615 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
1616 if (ret < 0)
1617 goto out;
1618
1619 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1620 QMI_WLANFW_IND_REGISTER_REQ_V01,
1621 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
1622 qmi_wlanfw_ind_register_req_msg_v01_ei, req);
1623 if (ret < 0) {
1624 ath11k_warn(ab, "Failed to send indication register request, err = %d\n",
1625 ret);
1626 goto out;
1627 }
1628
1629 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1630 if (ret < 0) {
1631 ath11k_warn(ab, "failed to register fw indication %d\n", ret);
1632 goto out;
1633 }
1634
1635 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1636 ath11k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
1637 resp->resp.result, resp->resp.error);
1638 ret = -EINVAL;
1639 goto out;
1640 }
1641
1642 out:
1643 kfree(resp);
1644 resp_out:
1645 kfree(req);
1646 return ret;
1647 }
1648
ath11k_qmi_respond_fw_mem_request(struct ath11k_base * ab)1649 static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
1650 {
1651 struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
1652 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
1653 struct qmi_txn txn = {};
1654 int ret = 0, i;
1655
1656 req = kzalloc(sizeof(*req), GFP_KERNEL);
1657 if (!req)
1658 return -ENOMEM;
1659
1660 memset(&resp, 0, sizeof(resp));
1661
1662 /* For QCA6390 by default FW requests a block of ~4M contiguous
1663 * DMA memory, it's hard to allocate from OS. So host returns
1664 * failure to FW and FW will then request mulitple blocks of small
1665 * chunk size memory.
1666 */
1667 if (!ab->bus_params.fixed_mem_region && ab->qmi.mem_seg_count <= 2) {
1668 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n",
1669 ab->qmi.mem_seg_count);
1670 memset(req, 0, sizeof(*req));
1671 } else {
1672 req->mem_seg_len = ab->qmi.mem_seg_count;
1673
1674 for (i = 0; i < req->mem_seg_len ; i++) {
1675 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
1676 req->mem_seg[i].size = ab->qmi.target_mem[i].size;
1677 req->mem_seg[i].type = ab->qmi.target_mem[i].type;
1678 }
1679 }
1680
1681 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1682 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
1683 if (ret < 0)
1684 goto out;
1685
1686 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1687 QMI_WLANFW_RESPOND_MEM_REQ_V01,
1688 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
1689 qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
1690 if (ret < 0) {
1691 ath11k_warn(ab, "qmi failed to respond memory request, err = %d\n",
1692 ret);
1693 goto out;
1694 }
1695
1696 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1697 if (ret < 0) {
1698 ath11k_warn(ab, "qmi failed memory request, err = %d\n", ret);
1699 goto out;
1700 }
1701
1702 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1703 ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
1704 resp.resp.result, resp.resp.error);
1705 ret = -EINVAL;
1706 goto out;
1707 }
1708 out:
1709 kfree(req);
1710 return ret;
1711 }
1712
ath11k_qmi_free_target_mem_chunk(struct ath11k_base * ab)1713 static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)
1714 {
1715 int i;
1716
1717 if (ab->bus_params.fixed_mem_region)
1718 return;
1719
1720 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1721 if (!ab->qmi.target_mem[i].vaddr)
1722 continue;
1723
1724 dma_free_coherent(ab->dev,
1725 ab->qmi.target_mem[i].size,
1726 ab->qmi.target_mem[i].vaddr,
1727 ab->qmi.target_mem[i].paddr);
1728 ab->qmi.target_mem[i].vaddr = NULL;
1729 }
1730 }
1731
ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base * ab)1732 static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
1733 {
1734 int i;
1735 struct target_mem_chunk *chunk;
1736
1737 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1738 chunk = &ab->qmi.target_mem[i];
1739 chunk->vaddr = dma_alloc_coherent(ab->dev,
1740 chunk->size,
1741 &chunk->paddr,
1742 GFP_KERNEL);
1743 if (!chunk->vaddr) {
1744 ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n",
1745 chunk->size,
1746 chunk->type);
1747 return -EINVAL;
1748 }
1749 }
1750
1751 return 0;
1752 }
1753
ath11k_qmi_assign_target_mem_chunk(struct ath11k_base * ab)1754 static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
1755 {
1756 int i, idx;
1757
1758 for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
1759 switch (ab->qmi.target_mem[i].type) {
1760 case BDF_MEM_REGION_TYPE:
1761 ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
1762 ab->qmi.target_mem[idx].vaddr = NULL;
1763 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1764 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1765 idx++;
1766 break;
1767 case CALDB_MEM_REGION_TYPE:
1768 if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {
1769 ath11k_warn(ab, "qmi mem size is low to load caldata\n");
1770 return -EINVAL;
1771 }
1772 /* TODO ath11k does not support cold boot calibration */
1773 ab->qmi.target_mem[idx].paddr = 0;
1774 ab->qmi.target_mem[idx].vaddr = NULL;
1775 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1776 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1777 idx++;
1778 break;
1779 default:
1780 ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
1781 ab->qmi.target_mem[i].type);
1782 break;
1783 }
1784 }
1785 ab->qmi.mem_seg_count = idx;
1786
1787 return 0;
1788 }
1789
ath11k_qmi_request_target_cap(struct ath11k_base * ab)1790 static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
1791 {
1792 struct qmi_wlanfw_cap_req_msg_v01 req;
1793 struct qmi_wlanfw_cap_resp_msg_v01 resp;
1794 struct qmi_txn txn = {};
1795 int ret = 0;
1796
1797 memset(&req, 0, sizeof(req));
1798 memset(&resp, 0, sizeof(resp));
1799
1800 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1801 qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
1802 if (ret < 0)
1803 goto out;
1804
1805 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1806 QMI_WLANFW_CAP_REQ_V01,
1807 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
1808 qmi_wlanfw_cap_req_msg_v01_ei, &req);
1809 if (ret < 0) {
1810 ath11k_warn(ab, "qmi failed to send target cap request, err = %d\n",
1811 ret);
1812 goto out;
1813 }
1814
1815 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1816 if (ret < 0) {
1817 ath11k_warn(ab, "qmi failed target cap request %d\n", ret);
1818 goto out;
1819 }
1820
1821 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1822 ath11k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
1823 resp.resp.result, resp.resp.error);
1824 ret = -EINVAL;
1825 goto out;
1826 }
1827
1828 if (resp.chip_info_valid) {
1829 ab->qmi.target.chip_id = resp.chip_info.chip_id;
1830 ab->qmi.target.chip_family = resp.chip_info.chip_family;
1831 }
1832
1833 if (resp.board_info_valid)
1834 ab->qmi.target.board_id = resp.board_info.board_id;
1835 else
1836 ab->qmi.target.board_id = 0xFF;
1837
1838 if (resp.soc_info_valid)
1839 ab->qmi.target.soc_id = resp.soc_info.soc_id;
1840
1841 if (resp.fw_version_info_valid) {
1842 ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
1843 strlcpy(ab->qmi.target.fw_build_timestamp,
1844 resp.fw_version_info.fw_build_timestamp,
1845 sizeof(ab->qmi.target.fw_build_timestamp));
1846 }
1847
1848 if (resp.fw_build_id_valid)
1849 strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
1850 sizeof(ab->qmi.target.fw_build_id));
1851
1852 ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
1853 ab->qmi.target.chip_id, ab->qmi.target.chip_family,
1854 ab->qmi.target.board_id, ab->qmi.target.soc_id);
1855
1856 ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
1857 ab->qmi.target.fw_version,
1858 ab->qmi.target.fw_build_timestamp,
1859 ab->qmi.target.fw_build_id);
1860
1861 out:
1862 return ret;
1863 }
1864
1865 static int
ath11k_qmi_prepare_bdf_download(struct ath11k_base * ab,int type,struct qmi_wlanfw_bdf_download_req_msg_v01 * req,void __iomem * bdf_addr)1866 ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
1867 struct qmi_wlanfw_bdf_download_req_msg_v01 *req,
1868 void __iomem *bdf_addr)
1869 {
1870 const struct firmware *fw_entry;
1871 struct ath11k_board_data bd;
1872 u32 fw_size;
1873 int ret;
1874
1875 switch (type) {
1876 case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
1877 memset(&bd, 0, sizeof(bd));
1878
1879 ret = ath11k_core_fetch_bdf(ab, &bd);
1880 if (ret) {
1881 ath11k_warn(ab, "qmi failed to load BDF\n");
1882 return ret;
1883 }
1884
1885 fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
1886 memcpy_toio(bdf_addr, bd.data, fw_size);
1887 ath11k_core_free_bdf(ab, &bd);
1888 break;
1889 case ATH11K_QMI_FILE_TYPE_CALDATA:
1890 fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
1891 if (IS_ERR(fw_entry)) {
1892 ret = PTR_ERR(fw_entry);
1893 ath11k_warn(ab, "failed to load %s: %d\n",
1894 ATH11K_DEFAULT_CAL_FILE, ret);
1895 return ret;
1896 }
1897
1898 fw_size = min_t(u32, ab->hw_params.fw.board_size,
1899 fw_entry->size);
1900
1901 memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET,
1902 fw_entry->data, fw_size);
1903
1904 release_firmware(fw_entry);
1905 break;
1906 default:
1907 return -EINVAL;
1908 }
1909
1910 req->total_size = fw_size;
1911 return 0;
1912 }
1913
ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base * ab)1914 static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
1915 {
1916 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
1917 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
1918 struct qmi_txn txn = {};
1919 void __iomem *bdf_addr = NULL;
1920 int type, ret;
1921
1922 req = kzalloc(sizeof(*req), GFP_KERNEL);
1923 if (!req)
1924 return -ENOMEM;
1925 memset(&resp, 0, sizeof(resp));
1926
1927 bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
1928 if (!bdf_addr) {
1929 ath11k_warn(ab, "qmi ioremap error for BDF\n");
1930 ret = -EIO;
1931 goto out;
1932 }
1933
1934 for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) {
1935 req->valid = 1;
1936 req->file_id_valid = 1;
1937 req->file_id = ab->qmi.target.board_id;
1938 req->total_size_valid = 1;
1939 req->seg_id_valid = 1;
1940 req->seg_id = type;
1941 req->data_valid = 0;
1942 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
1943 req->bdf_type = 0;
1944 req->bdf_type_valid = 0;
1945 req->end_valid = 1;
1946 req->end = 1;
1947
1948 ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr);
1949 if (ret < 0)
1950 goto out_qmi_bdf;
1951
1952 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1953 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
1954 &resp);
1955 if (ret < 0)
1956 goto out_qmi_bdf;
1957
1958 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1959 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
1960 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
1961 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
1962 if (ret < 0) {
1963 qmi_txn_cancel(&txn);
1964 goto out_qmi_bdf;
1965 }
1966
1967 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1968 if (ret < 0)
1969 goto out_qmi_bdf;
1970
1971 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1972 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
1973 resp.resp.result, resp.resp.error);
1974 ret = -EINVAL;
1975 goto out_qmi_bdf;
1976 }
1977 }
1978
1979 out_qmi_bdf:
1980 iounmap(bdf_addr);
1981 out:
1982 kfree(req);
1983 return ret;
1984 }
1985
ath11k_qmi_load_bdf_qmi(struct ath11k_base * ab)1986 static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
1987 {
1988 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
1989 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
1990 struct ath11k_board_data bd;
1991 unsigned int remaining;
1992 struct qmi_txn txn = {};
1993 int ret;
1994 const u8 *temp;
1995 int bdf_type;
1996
1997 req = kzalloc(sizeof(*req), GFP_KERNEL);
1998 if (!req)
1999 return -ENOMEM;
2000 memset(&resp, 0, sizeof(resp));
2001
2002 memset(&bd, 0, sizeof(bd));
2003 ret = ath11k_core_fetch_bdf(ab, &bd);
2004 if (ret) {
2005 ath11k_warn(ab, "qmi failed to load bdf:\n");
2006 goto out;
2007 }
2008
2009 temp = bd.data;
2010 remaining = bd.len;
2011
2012 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
2013 bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
2014 else
2015 bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
2016
2017 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
2018
2019 while (remaining) {
2020 req->valid = 1;
2021 req->file_id_valid = 1;
2022 req->file_id = ab->qmi.target.board_id;
2023 req->total_size_valid = 1;
2024 req->total_size = bd.len;
2025 req->seg_id_valid = 1;
2026 req->data_valid = 1;
2027 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
2028 req->bdf_type = bdf_type;
2029 req->bdf_type_valid = 1;
2030 req->end_valid = 1;
2031 req->end = 0;
2032
2033 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2034 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2035 } else {
2036 req->data_len = remaining;
2037 req->end = 1;
2038 }
2039
2040 memcpy(req->data, temp, req->data_len);
2041
2042 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2043 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2044 &resp);
2045 if (ret < 0)
2046 goto out_qmi_bdf;
2047
2048 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2049 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2050 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2051 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2052 if (ret < 0) {
2053 qmi_txn_cancel(&txn);
2054 goto out_qmi_bdf;
2055 }
2056
2057 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2058 if (ret < 0)
2059 goto out_qmi_bdf;
2060
2061 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2062 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2063 resp.resp.result, resp.resp.error);
2064 ret = resp.resp.result;
2065 goto out_qmi_bdf;
2066 }
2067 remaining -= req->data_len;
2068 temp += req->data_len;
2069 req->seg_id++;
2070 }
2071
2072 out_qmi_bdf:
2073 ath11k_core_free_bdf(ab, &bd);
2074
2075 out:
2076 kfree(req);
2077 return ret;
2078 }
2079
ath11k_qmi_m3_load(struct ath11k_base * ab)2080 static int ath11k_qmi_m3_load(struct ath11k_base *ab)
2081 {
2082 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2083 const struct firmware *fw;
2084 char path[100];
2085 int ret;
2086
2087 if (m3_mem->vaddr || m3_mem->size)
2088 return 0;
2089
2090 fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
2091 if (IS_ERR(fw)) {
2092 ret = PTR_ERR(fw);
2093 ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,
2094 path, sizeof(path));
2095 ath11k_err(ab, "failed to load %s: %d\n", path, ret);
2096 return ret;
2097 }
2098
2099 m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2100 fw->size, &m3_mem->paddr,
2101 GFP_KERNEL);
2102 if (!m3_mem->vaddr) {
2103 ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2104 fw->size);
2105 release_firmware(fw);
2106 return -ENOMEM;
2107 }
2108
2109 memcpy(m3_mem->vaddr, fw->data, fw->size);
2110 m3_mem->size = fw->size;
2111 release_firmware(fw);
2112
2113 return 0;
2114 }
2115
ath11k_qmi_m3_free(struct ath11k_base * ab)2116 static void ath11k_qmi_m3_free(struct ath11k_base *ab)
2117 {
2118 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2119
2120 if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr)
2121 return;
2122
2123 dma_free_coherent(ab->dev, m3_mem->size,
2124 m3_mem->vaddr, m3_mem->paddr);
2125 m3_mem->vaddr = NULL;
2126 }
2127
ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base * ab)2128 static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
2129 {
2130 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2131 struct qmi_wlanfw_m3_info_req_msg_v01 req;
2132 struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
2133 struct qmi_txn txn = {};
2134 int ret = 0;
2135
2136 memset(&req, 0, sizeof(req));
2137 memset(&resp, 0, sizeof(resp));
2138
2139 if (ab->bus_params.m3_fw_support) {
2140 ret = ath11k_qmi_m3_load(ab);
2141 if (ret) {
2142 ath11k_err(ab, "failed to load m3 firmware: %d", ret);
2143 return ret;
2144 }
2145
2146 req.addr = m3_mem->paddr;
2147 req.size = m3_mem->size;
2148 } else {
2149 req.addr = 0;
2150 req.size = 0;
2151 }
2152
2153 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2154 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
2155 if (ret < 0)
2156 goto out;
2157
2158 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2159 QMI_WLANFW_M3_INFO_REQ_V01,
2160 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
2161 qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
2162 if (ret < 0) {
2163 ath11k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
2164 ret);
2165 goto out;
2166 }
2167
2168 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2169 if (ret < 0) {
2170 ath11k_warn(ab, "qmi failed M3 information request %d\n", ret);
2171 goto out;
2172 }
2173
2174 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2175 ath11k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
2176 resp.resp.result, resp.resp.error);
2177 ret = -EINVAL;
2178 goto out;
2179 }
2180 out:
2181 return ret;
2182 }
2183
ath11k_qmi_wlanfw_mode_send(struct ath11k_base * ab,u32 mode)2184 static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
2185 u32 mode)
2186 {
2187 struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
2188 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
2189 struct qmi_txn txn = {};
2190 int ret = 0;
2191
2192 memset(&req, 0, sizeof(req));
2193 memset(&resp, 0, sizeof(resp));
2194
2195 req.mode = mode;
2196 req.hw_debug_valid = 1;
2197 req.hw_debug = 0;
2198
2199 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2200 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
2201 if (ret < 0)
2202 goto out;
2203
2204 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2205 QMI_WLANFW_WLAN_MODE_REQ_V01,
2206 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
2207 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
2208 if (ret < 0) {
2209 ath11k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
2210 mode, ret);
2211 goto out;
2212 }
2213
2214 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2215 if (ret < 0) {
2216 if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
2217 ath11k_warn(ab, "WLFW service is dis-connected\n");
2218 return 0;
2219 }
2220 ath11k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
2221 mode, ret);
2222 goto out;
2223 }
2224
2225 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2226 ath11k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
2227 mode, resp.resp.result, resp.resp.error);
2228 ret = -EINVAL;
2229 goto out;
2230 }
2231
2232 out:
2233 return ret;
2234 }
2235
ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base * ab)2236 static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
2237 {
2238 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
2239 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
2240 struct ce_pipe_config *ce_cfg;
2241 struct service_to_pipe *svc_cfg;
2242 struct qmi_txn txn = {};
2243 int ret = 0, pipe_num;
2244
2245 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
2246 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
2247
2248 req = kzalloc(sizeof(*req), GFP_KERNEL);
2249 if (!req)
2250 return -ENOMEM;
2251
2252 memset(&resp, 0, sizeof(resp));
2253
2254 req->host_version_valid = 1;
2255 strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING,
2256 sizeof(req->host_version));
2257
2258 req->tgt_cfg_valid = 1;
2259 /* This is number of CE configs */
2260 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
2261 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
2262 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
2263 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
2264 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
2265 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
2266 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
2267 }
2268
2269 req->svc_cfg_valid = 1;
2270 /* This is number of Service/CE configs */
2271 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
2272 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
2273 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
2274 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
2275 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
2276 }
2277 req->shadow_reg_valid = 0;
2278
2279 /* set shadow v2 configuration */
2280 if (ab->hw_params.supports_shadow_regs) {
2281 req->shadow_reg_v2_valid = 1;
2282 req->shadow_reg_v2_len = min_t(u32,
2283 ab->qmi.ce_cfg.shadow_reg_v2_len,
2284 QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);
2285 memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,
2286 sizeof(u32) * req->shadow_reg_v2_len);
2287 } else {
2288 req->shadow_reg_v2_valid = 0;
2289 }
2290
2291 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2292 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
2293 if (ret < 0)
2294 goto out;
2295
2296 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2297 QMI_WLANFW_WLAN_CFG_REQ_V01,
2298 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
2299 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
2300 if (ret < 0) {
2301 ath11k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
2302 ret);
2303 goto out;
2304 }
2305
2306 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2307 if (ret < 0) {
2308 ath11k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
2309 goto out;
2310 }
2311
2312 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2313 ath11k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
2314 resp.resp.result, resp.resp.error);
2315 ret = -EINVAL;
2316 goto out;
2317 }
2318
2319 out:
2320 kfree(req);
2321 return ret;
2322 }
2323
ath11k_qmi_firmware_stop(struct ath11k_base * ab)2324 void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
2325 {
2326 int ret;
2327
2328 ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
2329 if (ret < 0) {
2330 ath11k_warn(ab, "qmi failed to send wlan mode off\n");
2331 return;
2332 }
2333 }
2334
ath11k_qmi_firmware_start(struct ath11k_base * ab,u32 mode)2335 int ath11k_qmi_firmware_start(struct ath11k_base *ab,
2336 u32 mode)
2337 {
2338 int ret;
2339
2340 ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
2341 if (ret < 0) {
2342 ath11k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
2343 return ret;
2344 }
2345
2346 ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
2347 if (ret < 0) {
2348 ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
2349 return ret;
2350 }
2351
2352 return 0;
2353 }
2354
2355 static int
ath11k_qmi_driver_event_post(struct ath11k_qmi * qmi,enum ath11k_qmi_event_type type,void * data)2356 ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
2357 enum ath11k_qmi_event_type type,
2358 void *data)
2359 {
2360 struct ath11k_qmi_driver_event *event;
2361
2362 event = kzalloc(sizeof(*event), GFP_ATOMIC);
2363 if (!event)
2364 return -ENOMEM;
2365
2366 event->type = type;
2367 event->data = data;
2368
2369 spin_lock(&qmi->event_lock);
2370 list_add_tail(&event->list, &qmi->event_list);
2371 spin_unlock(&qmi->event_lock);
2372
2373 queue_work(qmi->event_wq, &qmi->event_work);
2374
2375 return 0;
2376 }
2377
ath11k_qmi_event_server_arrive(struct ath11k_qmi * qmi)2378 static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
2379 {
2380 struct ath11k_base *ab = qmi->ab;
2381 int ret;
2382
2383 ret = ath11k_qmi_fw_ind_register_send(ab);
2384 if (ret < 0) {
2385 ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
2386 return;
2387 }
2388
2389 ret = ath11k_qmi_host_cap_send(ab);
2390 if (ret < 0) {
2391 ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret);
2392 return;
2393 }
2394 }
2395
ath11k_qmi_event_mem_request(struct ath11k_qmi * qmi)2396 static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
2397 {
2398 struct ath11k_base *ab = qmi->ab;
2399 int ret;
2400
2401 ret = ath11k_qmi_respond_fw_mem_request(ab);
2402 if (ret < 0) {
2403 ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
2404 return;
2405 }
2406 }
2407
ath11k_qmi_event_load_bdf(struct ath11k_qmi * qmi)2408 static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
2409 {
2410 struct ath11k_base *ab = qmi->ab;
2411 int ret;
2412
2413 ret = ath11k_qmi_request_target_cap(ab);
2414 if (ret < 0) {
2415 ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
2416 return;
2417 }
2418
2419 if (ab->bus_params.fixed_bdf_addr)
2420 ret = ath11k_qmi_load_bdf_fixed_addr(ab);
2421 else
2422 ret = ath11k_qmi_load_bdf_qmi(ab);
2423 if (ret < 0) {
2424 ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
2425 return;
2426 }
2427
2428 ret = ath11k_qmi_wlanfw_m3_info_send(ab);
2429 if (ret < 0) {
2430 ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
2431 return;
2432 }
2433 }
2434
ath11k_qmi_msg_mem_request_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * data)2435 static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
2436 struct sockaddr_qrtr *sq,
2437 struct qmi_txn *txn,
2438 const void *data)
2439 {
2440 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2441 struct ath11k_base *ab = qmi->ab;
2442 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
2443 int i, ret;
2444
2445 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware request memory request\n");
2446
2447 if (msg->mem_seg_len == 0 ||
2448 msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
2449 ath11k_warn(ab, "Invalid memory segment length: %u\n",
2450 msg->mem_seg_len);
2451
2452 ab->qmi.mem_seg_count = msg->mem_seg_len;
2453
2454 for (i = 0; i < qmi->mem_seg_count ; i++) {
2455 ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
2456 ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
2457 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi mem seg type %d size %d\n",
2458 msg->mem_seg[i].type, msg->mem_seg[i].size);
2459 }
2460
2461 if (ab->bus_params.fixed_mem_region) {
2462 ret = ath11k_qmi_assign_target_mem_chunk(ab);
2463 if (ret) {
2464 ath11k_warn(ab, "qmi failed to assign target memory: %d\n",
2465 ret);
2466 return;
2467 }
2468 } else if (msg->mem_seg_len > 2) {
2469 ret = ath11k_qmi_alloc_target_mem_chunk(ab);
2470 if (ret) {
2471 ath11k_warn(ab, "qmi failed to alloc target memory: %d\n",
2472 ret);
2473 return;
2474 }
2475 }
2476
2477 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);
2478 }
2479
ath11k_qmi_msg_mem_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2480 static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
2481 struct sockaddr_qrtr *sq,
2482 struct qmi_txn *txn,
2483 const void *decoded)
2484 {
2485 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2486 struct ath11k_base *ab = qmi->ab;
2487
2488 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware memory ready indication\n");
2489 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);
2490 }
2491
ath11k_qmi_msg_fw_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2492 static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
2493 struct sockaddr_qrtr *sq,
2494 struct qmi_txn *txn,
2495 const void *decoded)
2496 {
2497 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2498 struct ath11k_base *ab = qmi->ab;
2499
2500 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
2501 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
2502 }
2503
ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle * qmi,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2504 static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi,
2505 struct sockaddr_qrtr *sq,
2506 struct qmi_txn *txn,
2507 const void *decoded)
2508 {
2509 }
2510
2511 static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
2512 {
2513 .type = QMI_INDICATION,
2514 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
2515 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
2516 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
2517 .fn = ath11k_qmi_msg_mem_request_cb,
2518 },
2519 {
2520 .type = QMI_INDICATION,
2521 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
2522 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
2523 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
2524 .fn = ath11k_qmi_msg_mem_ready_cb,
2525 },
2526 {
2527 .type = QMI_INDICATION,
2528 .msg_id = QMI_WLFW_FW_READY_IND_V01,
2529 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
2530 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
2531 .fn = ath11k_qmi_msg_fw_ready_cb,
2532 },
2533 {
2534 .type = QMI_INDICATION,
2535 .msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,
2536 .ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,
2537 .decoded_size =
2538 sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
2539 .fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
2540 },
2541 };
2542
ath11k_qmi_ops_new_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)2543 static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
2544 struct qmi_service *service)
2545 {
2546 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2547 struct ath11k_base *ab = qmi->ab;
2548 struct sockaddr_qrtr *sq = &qmi->sq;
2549 int ret;
2550
2551 sq->sq_family = AF_QIPCRTR;
2552 sq->sq_node = service->node;
2553 sq->sq_port = service->port;
2554
2555 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
2556 sizeof(*sq), 0);
2557 if (ret) {
2558 ath11k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
2559 return ret;
2560 }
2561
2562 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n");
2563 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);
2564
2565 return 0;
2566 }
2567
ath11k_qmi_ops_del_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)2568 static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
2569 struct qmi_service *service)
2570 {
2571 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2572 struct ath11k_base *ab = qmi->ab;
2573
2574 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw del server\n");
2575 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);
2576 }
2577
2578 static const struct qmi_ops ath11k_qmi_ops = {
2579 .new_server = ath11k_qmi_ops_new_server,
2580 .del_server = ath11k_qmi_ops_del_server,
2581 };
2582
ath11k_qmi_driver_event_work(struct work_struct * work)2583 static void ath11k_qmi_driver_event_work(struct work_struct *work)
2584 {
2585 struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
2586 event_work);
2587 struct ath11k_qmi_driver_event *event;
2588 struct ath11k_base *ab = qmi->ab;
2589
2590 spin_lock(&qmi->event_lock);
2591 while (!list_empty(&qmi->event_list)) {
2592 event = list_first_entry(&qmi->event_list,
2593 struct ath11k_qmi_driver_event, list);
2594 list_del(&event->list);
2595 spin_unlock(&qmi->event_lock);
2596
2597 if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags))
2598 return;
2599
2600 switch (event->type) {
2601 case ATH11K_QMI_EVENT_SERVER_ARRIVE:
2602 ath11k_qmi_event_server_arrive(qmi);
2603 break;
2604 case ATH11K_QMI_EVENT_SERVER_EXIT:
2605 set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
2606 set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2607 break;
2608 case ATH11K_QMI_EVENT_REQUEST_MEM:
2609 ath11k_qmi_event_mem_request(qmi);
2610 break;
2611 case ATH11K_QMI_EVENT_FW_MEM_READY:
2612 ath11k_qmi_event_load_bdf(qmi);
2613 break;
2614 case ATH11K_QMI_EVENT_FW_READY:
2615 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
2616 ath11k_hal_dump_srng_stats(ab);
2617 queue_work(ab->workqueue, &ab->restart_work);
2618 break;
2619 }
2620
2621 ath11k_core_qmi_firmware_ready(ab);
2622 ab->qmi.cal_done = 1;
2623 set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
2624
2625 break;
2626 case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
2627 break;
2628 default:
2629 ath11k_warn(ab, "invalid event type: %d", event->type);
2630 break;
2631 }
2632 kfree(event);
2633 spin_lock(&qmi->event_lock);
2634 }
2635 spin_unlock(&qmi->event_lock);
2636 }
2637
ath11k_qmi_init_service(struct ath11k_base * ab)2638 int ath11k_qmi_init_service(struct ath11k_base *ab)
2639 {
2640 int ret;
2641
2642 memset(&ab->qmi.target, 0, sizeof(struct target_info));
2643 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
2644 ab->qmi.ab = ab;
2645
2646 ab->qmi.target_mem_mode = ATH11K_QMI_TARGET_MEM_MODE_DEFAULT;
2647 ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
2648 &ath11k_qmi_ops, ath11k_qmi_msg_handlers);
2649 if (ret < 0) {
2650 ath11k_warn(ab, "failed to initialize qmi handle\n");
2651 return ret;
2652 }
2653
2654 ab->qmi.event_wq = alloc_workqueue("ath11k_qmi_driver_event",
2655 WQ_UNBOUND, 1);
2656 if (!ab->qmi.event_wq) {
2657 ath11k_err(ab, "failed to allocate workqueue\n");
2658 return -EFAULT;
2659 }
2660
2661 INIT_LIST_HEAD(&ab->qmi.event_list);
2662 spin_lock_init(&ab->qmi.event_lock);
2663 INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);
2664
2665 ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,
2666 ATH11K_QMI_WLFW_SERVICE_VERS_V01,
2667 ab->qmi.service_ins_id);
2668 if (ret < 0) {
2669 ath11k_warn(ab, "failed to add qmi lookup\n");
2670 destroy_workqueue(ab->qmi.event_wq);
2671 return ret;
2672 }
2673
2674 return ret;
2675 }
2676
ath11k_qmi_deinit_service(struct ath11k_base * ab)2677 void ath11k_qmi_deinit_service(struct ath11k_base *ab)
2678 {
2679 qmi_handle_release(&ab->qmi.handle);
2680 cancel_work_sync(&ab->qmi.event_work);
2681 destroy_workqueue(ab->qmi.event_wq);
2682 ath11k_qmi_m3_free(ab);
2683 ath11k_qmi_free_target_mem_chunk(ab);
2684 }
2685
2686