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;
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 ret = -ENOMEM;
1597 goto resp_out;
1598 }
1599
1600 req->client_id_valid = 1;
1601 req->client_id = QMI_WLANFW_CLIENT_ID;
1602 req->fw_ready_enable_valid = 1;
1603 req->fw_ready_enable = 1;
1604 req->request_mem_enable_valid = 1;
1605 req->request_mem_enable = 1;
1606 req->fw_mem_ready_enable_valid = 1;
1607 req->fw_mem_ready_enable = 1;
1608 req->cal_done_enable_valid = 1;
1609 req->cal_done_enable = 1;
1610 req->fw_init_done_enable_valid = 1;
1611 req->fw_init_done_enable = 1;
1612
1613 req->pin_connect_result_enable_valid = 0;
1614 req->pin_connect_result_enable = 0;
1615
1616 ret = qmi_txn_init(handle, &txn,
1617 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);
1618 if (ret < 0)
1619 goto out;
1620
1621 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1622 QMI_WLANFW_IND_REGISTER_REQ_V01,
1623 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,
1624 qmi_wlanfw_ind_register_req_msg_v01_ei, req);
1625 if (ret < 0) {
1626 ath11k_warn(ab, "Failed to send indication register request, err = %d\n",
1627 ret);
1628 goto out;
1629 }
1630
1631 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1632 if (ret < 0) {
1633 ath11k_warn(ab, "failed to register fw indication %d\n", ret);
1634 goto out;
1635 }
1636
1637 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
1638 ath11k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n",
1639 resp->resp.result, resp->resp.error);
1640 ret = -EINVAL;
1641 goto out;
1642 }
1643
1644 out:
1645 kfree(resp);
1646 resp_out:
1647 kfree(req);
1648 return ret;
1649 }
1650
ath11k_qmi_respond_fw_mem_request(struct ath11k_base * ab)1651 static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)
1652 {
1653 struct qmi_wlanfw_respond_mem_req_msg_v01 *req;
1654 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;
1655 struct qmi_txn txn = {};
1656 int ret = 0, i;
1657 bool delayed;
1658
1659 req = kzalloc(sizeof(*req), GFP_KERNEL);
1660 if (!req)
1661 return -ENOMEM;
1662
1663 memset(&resp, 0, sizeof(resp));
1664
1665 /* For QCA6390 by default FW requests a block of ~4M contiguous
1666 * DMA memory, it's hard to allocate from OS. So host returns
1667 * failure to FW and FW will then request mulitple blocks of small
1668 * chunk size memory.
1669 */
1670 if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) {
1671 delayed = true;
1672 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n",
1673 ab->qmi.mem_seg_count);
1674 memset(req, 0, sizeof(*req));
1675 } else {
1676 delayed = false;
1677 req->mem_seg_len = ab->qmi.mem_seg_count;
1678
1679 for (i = 0; i < req->mem_seg_len ; i++) {
1680 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;
1681 req->mem_seg[i].size = ab->qmi.target_mem[i].size;
1682 req->mem_seg[i].type = ab->qmi.target_mem[i].type;
1683 }
1684 }
1685
1686 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1687 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);
1688 if (ret < 0)
1689 goto out;
1690
1691 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1692 QMI_WLANFW_RESPOND_MEM_REQ_V01,
1693 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,
1694 qmi_wlanfw_respond_mem_req_msg_v01_ei, req);
1695 if (ret < 0) {
1696 ath11k_warn(ab, "qmi failed to respond memory request, err = %d\n",
1697 ret);
1698 goto out;
1699 }
1700
1701 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1702 if (ret < 0) {
1703 ath11k_warn(ab, "qmi failed memory request, err = %d\n", ret);
1704 goto out;
1705 }
1706
1707 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1708 /* the error response is expected when
1709 * target_mem_delayed is true.
1710 */
1711 if (delayed && resp.resp.error == 0)
1712 goto out;
1713
1714 ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n",
1715 resp.resp.result, resp.resp.error);
1716 ret = -EINVAL;
1717 goto out;
1718 }
1719 out:
1720 kfree(req);
1721 return ret;
1722 }
1723
ath11k_qmi_free_target_mem_chunk(struct ath11k_base * ab)1724 static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)
1725 {
1726 int i;
1727
1728 if (ab->bus_params.fixed_mem_region)
1729 return;
1730
1731 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1732 if (!ab->qmi.target_mem[i].vaddr)
1733 continue;
1734
1735 dma_free_coherent(ab->dev,
1736 ab->qmi.target_mem[i].size,
1737 ab->qmi.target_mem[i].vaddr,
1738 ab->qmi.target_mem[i].paddr);
1739 ab->qmi.target_mem[i].vaddr = NULL;
1740 }
1741 }
1742
ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base * ab)1743 static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
1744 {
1745 int i;
1746 struct target_mem_chunk *chunk;
1747
1748 ab->qmi.target_mem_delayed = false;
1749
1750 for (i = 0; i < ab->qmi.mem_seg_count; i++) {
1751 chunk = &ab->qmi.target_mem[i];
1752 chunk->vaddr = dma_alloc_coherent(ab->dev,
1753 chunk->size,
1754 &chunk->paddr,
1755 GFP_KERNEL);
1756 if (!chunk->vaddr) {
1757 if (ab->qmi.mem_seg_count <= 2) {
1758 ath11k_dbg(ab, ATH11K_DBG_QMI,
1759 "qmi dma allocation failed (%d B type %u), will try later with small size\n",
1760 chunk->size,
1761 chunk->type);
1762 ath11k_qmi_free_target_mem_chunk(ab);
1763 ab->qmi.target_mem_delayed = true;
1764 return 0;
1765 }
1766 ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n",
1767 chunk->size,
1768 chunk->type);
1769 return -EINVAL;
1770 }
1771 }
1772
1773 return 0;
1774 }
1775
ath11k_qmi_assign_target_mem_chunk(struct ath11k_base * ab)1776 static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)
1777 {
1778 int i, idx;
1779
1780 for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
1781 switch (ab->qmi.target_mem[i].type) {
1782 case BDF_MEM_REGION_TYPE:
1783 ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;
1784 ab->qmi.target_mem[idx].vaddr = NULL;
1785 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1786 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1787 idx++;
1788 break;
1789 case CALDB_MEM_REGION_TYPE:
1790 if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {
1791 ath11k_warn(ab, "qmi mem size is low to load caldata\n");
1792 return -EINVAL;
1793 }
1794 /* TODO ath11k does not support cold boot calibration */
1795 ab->qmi.target_mem[idx].paddr = 0;
1796 ab->qmi.target_mem[idx].vaddr = NULL;
1797 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
1798 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
1799 idx++;
1800 break;
1801 default:
1802 ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",
1803 ab->qmi.target_mem[i].type);
1804 break;
1805 }
1806 }
1807 ab->qmi.mem_seg_count = idx;
1808
1809 return 0;
1810 }
1811
ath11k_qmi_request_target_cap(struct ath11k_base * ab)1812 static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)
1813 {
1814 struct qmi_wlanfw_cap_req_msg_v01 req;
1815 struct qmi_wlanfw_cap_resp_msg_v01 resp;
1816 struct qmi_txn txn = {};
1817 int ret = 0;
1818
1819 memset(&req, 0, sizeof(req));
1820 memset(&resp, 0, sizeof(resp));
1821
1822 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1823 qmi_wlanfw_cap_resp_msg_v01_ei, &resp);
1824 if (ret < 0)
1825 goto out;
1826
1827 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1828 QMI_WLANFW_CAP_REQ_V01,
1829 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,
1830 qmi_wlanfw_cap_req_msg_v01_ei, &req);
1831 if (ret < 0) {
1832 ath11k_warn(ab, "qmi failed to send target cap request, err = %d\n",
1833 ret);
1834 goto out;
1835 }
1836
1837 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1838 if (ret < 0) {
1839 ath11k_warn(ab, "qmi failed target cap request %d\n", ret);
1840 goto out;
1841 }
1842
1843 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1844 ath11k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n",
1845 resp.resp.result, resp.resp.error);
1846 ret = -EINVAL;
1847 goto out;
1848 }
1849
1850 if (resp.chip_info_valid) {
1851 ab->qmi.target.chip_id = resp.chip_info.chip_id;
1852 ab->qmi.target.chip_family = resp.chip_info.chip_family;
1853 }
1854
1855 if (resp.board_info_valid)
1856 ab->qmi.target.board_id = resp.board_info.board_id;
1857 else
1858 ab->qmi.target.board_id = 0xFF;
1859
1860 if (resp.soc_info_valid)
1861 ab->qmi.target.soc_id = resp.soc_info.soc_id;
1862
1863 if (resp.fw_version_info_valid) {
1864 ab->qmi.target.fw_version = resp.fw_version_info.fw_version;
1865 strlcpy(ab->qmi.target.fw_build_timestamp,
1866 resp.fw_version_info.fw_build_timestamp,
1867 sizeof(ab->qmi.target.fw_build_timestamp));
1868 }
1869
1870 if (resp.fw_build_id_valid)
1871 strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id,
1872 sizeof(ab->qmi.target.fw_build_id));
1873
1874 ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",
1875 ab->qmi.target.chip_id, ab->qmi.target.chip_family,
1876 ab->qmi.target.board_id, ab->qmi.target.soc_id);
1877
1878 ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
1879 ab->qmi.target.fw_version,
1880 ab->qmi.target.fw_build_timestamp,
1881 ab->qmi.target.fw_build_id);
1882
1883 out:
1884 return ret;
1885 }
1886
1887 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)1888 ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type,
1889 struct qmi_wlanfw_bdf_download_req_msg_v01 *req,
1890 void __iomem *bdf_addr)
1891 {
1892 const struct firmware *fw_entry;
1893 struct ath11k_board_data bd;
1894 u32 fw_size;
1895 int ret;
1896
1897 switch (type) {
1898 case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN:
1899 memset(&bd, 0, sizeof(bd));
1900
1901 ret = ath11k_core_fetch_bdf(ab, &bd);
1902 if (ret) {
1903 ath11k_warn(ab, "qmi failed to load BDF\n");
1904 return ret;
1905 }
1906
1907 fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);
1908 memcpy_toio(bdf_addr, bd.data, fw_size);
1909 ath11k_core_free_bdf(ab, &bd);
1910 break;
1911 case ATH11K_QMI_FILE_TYPE_CALDATA:
1912 fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);
1913 if (IS_ERR(fw_entry)) {
1914 ret = PTR_ERR(fw_entry);
1915 ath11k_warn(ab, "failed to load %s: %d\n",
1916 ATH11K_DEFAULT_CAL_FILE, ret);
1917 return ret;
1918 }
1919
1920 fw_size = min_t(u32, ab->hw_params.fw.board_size,
1921 fw_entry->size);
1922
1923 memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET,
1924 fw_entry->data, fw_size);
1925
1926 release_firmware(fw_entry);
1927 break;
1928 default:
1929 return -EINVAL;
1930 }
1931
1932 req->total_size = fw_size;
1933 return 0;
1934 }
1935
ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base * ab)1936 static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab)
1937 {
1938 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
1939 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
1940 struct qmi_txn txn = {};
1941 void __iomem *bdf_addr = NULL;
1942 int type, ret;
1943
1944 req = kzalloc(sizeof(*req), GFP_KERNEL);
1945 if (!req)
1946 return -ENOMEM;
1947 memset(&resp, 0, sizeof(resp));
1948
1949 bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE);
1950 if (!bdf_addr) {
1951 ath11k_warn(ab, "qmi ioremap error for BDF\n");
1952 ret = -EIO;
1953 goto out;
1954 }
1955
1956 for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) {
1957 req->valid = 1;
1958 req->file_id_valid = 1;
1959 req->file_id = ab->qmi.target.board_id;
1960 req->total_size_valid = 1;
1961 req->seg_id_valid = 1;
1962 req->seg_id = type;
1963 req->data_valid = 0;
1964 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
1965 req->bdf_type = 0;
1966 req->bdf_type_valid = 0;
1967 req->end_valid = 1;
1968 req->end = 1;
1969
1970 ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr);
1971 if (ret < 0)
1972 goto out_qmi_bdf;
1973
1974 ret = qmi_txn_init(&ab->qmi.handle, &txn,
1975 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
1976 &resp);
1977 if (ret < 0)
1978 goto out_qmi_bdf;
1979
1980 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
1981 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
1982 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
1983 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
1984 if (ret < 0) {
1985 qmi_txn_cancel(&txn);
1986 goto out_qmi_bdf;
1987 }
1988
1989 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
1990 if (ret < 0)
1991 goto out_qmi_bdf;
1992
1993 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
1994 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
1995 resp.resp.result, resp.resp.error);
1996 ret = -EINVAL;
1997 goto out_qmi_bdf;
1998 }
1999 }
2000
2001 out_qmi_bdf:
2002 iounmap(bdf_addr);
2003 out:
2004 kfree(req);
2005 return ret;
2006 }
2007
ath11k_qmi_load_bdf_qmi(struct ath11k_base * ab)2008 static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab)
2009 {
2010 struct qmi_wlanfw_bdf_download_req_msg_v01 *req;
2011 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;
2012 struct ath11k_board_data bd;
2013 unsigned int remaining;
2014 struct qmi_txn txn = {};
2015 int ret;
2016 const u8 *temp;
2017 int bdf_type;
2018
2019 req = kzalloc(sizeof(*req), GFP_KERNEL);
2020 if (!req)
2021 return -ENOMEM;
2022 memset(&resp, 0, sizeof(resp));
2023
2024 memset(&bd, 0, sizeof(bd));
2025 ret = ath11k_core_fetch_bdf(ab, &bd);
2026 if (ret) {
2027 ath11k_warn(ab, "qmi failed to load bdf:\n");
2028 goto out;
2029 }
2030
2031 temp = bd.data;
2032 remaining = bd.len;
2033
2034 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)
2035 bdf_type = ATH11K_QMI_BDF_TYPE_ELF;
2036 else
2037 bdf_type = ATH11K_QMI_BDF_TYPE_BIN;
2038
2039 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type);
2040
2041 while (remaining) {
2042 req->valid = 1;
2043 req->file_id_valid = 1;
2044 req->file_id = ab->qmi.target.board_id;
2045 req->total_size_valid = 1;
2046 req->total_size = bd.len;
2047 req->seg_id_valid = 1;
2048 req->data_valid = 1;
2049 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;
2050 req->bdf_type = bdf_type;
2051 req->bdf_type_valid = 1;
2052 req->end_valid = 1;
2053 req->end = 0;
2054
2055 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {
2056 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;
2057 } else {
2058 req->data_len = remaining;
2059 req->end = 1;
2060 }
2061
2062 memcpy(req->data, temp, req->data_len);
2063
2064 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2065 qmi_wlanfw_bdf_download_resp_msg_v01_ei,
2066 &resp);
2067 if (ret < 0)
2068 goto out_qmi_bdf;
2069
2070 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2071 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,
2072 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,
2073 qmi_wlanfw_bdf_download_req_msg_v01_ei, req);
2074 if (ret < 0) {
2075 qmi_txn_cancel(&txn);
2076 goto out_qmi_bdf;
2077 }
2078
2079 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2080 if (ret < 0)
2081 goto out_qmi_bdf;
2082
2083 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2084 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n",
2085 resp.resp.result, resp.resp.error);
2086 ret = resp.resp.result;
2087 goto out_qmi_bdf;
2088 }
2089 remaining -= req->data_len;
2090 temp += req->data_len;
2091 req->seg_id++;
2092 }
2093
2094 out_qmi_bdf:
2095 ath11k_core_free_bdf(ab, &bd);
2096
2097 out:
2098 kfree(req);
2099 return ret;
2100 }
2101
ath11k_qmi_m3_load(struct ath11k_base * ab)2102 static int ath11k_qmi_m3_load(struct ath11k_base *ab)
2103 {
2104 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2105 const struct firmware *fw;
2106 char path[100];
2107 int ret;
2108
2109 if (m3_mem->vaddr || m3_mem->size)
2110 return 0;
2111
2112 fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
2113 if (IS_ERR(fw)) {
2114 ret = PTR_ERR(fw);
2115 ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,
2116 path, sizeof(path));
2117 ath11k_err(ab, "failed to load %s: %d\n", path, ret);
2118 return ret;
2119 }
2120
2121 m3_mem->vaddr = dma_alloc_coherent(ab->dev,
2122 fw->size, &m3_mem->paddr,
2123 GFP_KERNEL);
2124 if (!m3_mem->vaddr) {
2125 ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",
2126 fw->size);
2127 release_firmware(fw);
2128 return -ENOMEM;
2129 }
2130
2131 memcpy(m3_mem->vaddr, fw->data, fw->size);
2132 m3_mem->size = fw->size;
2133 release_firmware(fw);
2134
2135 return 0;
2136 }
2137
ath11k_qmi_m3_free(struct ath11k_base * ab)2138 static void ath11k_qmi_m3_free(struct ath11k_base *ab)
2139 {
2140 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2141
2142 if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr)
2143 return;
2144
2145 dma_free_coherent(ab->dev, m3_mem->size,
2146 m3_mem->vaddr, m3_mem->paddr);
2147 m3_mem->vaddr = NULL;
2148 }
2149
ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base * ab)2150 static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
2151 {
2152 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;
2153 struct qmi_wlanfw_m3_info_req_msg_v01 req;
2154 struct qmi_wlanfw_m3_info_resp_msg_v01 resp;
2155 struct qmi_txn txn = {};
2156 int ret = 0;
2157
2158 memset(&req, 0, sizeof(req));
2159 memset(&resp, 0, sizeof(resp));
2160
2161 if (ab->bus_params.m3_fw_support) {
2162 ret = ath11k_qmi_m3_load(ab);
2163 if (ret) {
2164 ath11k_err(ab, "failed to load m3 firmware: %d", ret);
2165 return ret;
2166 }
2167
2168 req.addr = m3_mem->paddr;
2169 req.size = m3_mem->size;
2170 } else {
2171 req.addr = 0;
2172 req.size = 0;
2173 }
2174
2175 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2176 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);
2177 if (ret < 0)
2178 goto out;
2179
2180 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2181 QMI_WLANFW_M3_INFO_REQ_V01,
2182 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,
2183 qmi_wlanfw_m3_info_req_msg_v01_ei, &req);
2184 if (ret < 0) {
2185 ath11k_warn(ab, "qmi failed to send M3 information request, err = %d\n",
2186 ret);
2187 goto out;
2188 }
2189
2190 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2191 if (ret < 0) {
2192 ath11k_warn(ab, "qmi failed M3 information request %d\n", ret);
2193 goto out;
2194 }
2195
2196 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2197 ath11k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n",
2198 resp.resp.result, resp.resp.error);
2199 ret = -EINVAL;
2200 goto out;
2201 }
2202 out:
2203 return ret;
2204 }
2205
ath11k_qmi_wlanfw_mode_send(struct ath11k_base * ab,u32 mode)2206 static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,
2207 u32 mode)
2208 {
2209 struct qmi_wlanfw_wlan_mode_req_msg_v01 req;
2210 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;
2211 struct qmi_txn txn = {};
2212 int ret = 0;
2213
2214 memset(&req, 0, sizeof(req));
2215 memset(&resp, 0, sizeof(resp));
2216
2217 req.mode = mode;
2218 req.hw_debug_valid = 1;
2219 req.hw_debug = 0;
2220
2221 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2222 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);
2223 if (ret < 0)
2224 goto out;
2225
2226 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2227 QMI_WLANFW_WLAN_MODE_REQ_V01,
2228 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,
2229 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);
2230 if (ret < 0) {
2231 ath11k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n",
2232 mode, ret);
2233 goto out;
2234 }
2235
2236 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2237 if (ret < 0) {
2238 if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {
2239 ath11k_warn(ab, "WLFW service is dis-connected\n");
2240 return 0;
2241 }
2242 ath11k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n",
2243 mode, ret);
2244 goto out;
2245 }
2246
2247 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2248 ath11k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n",
2249 mode, resp.resp.result, resp.resp.error);
2250 ret = -EINVAL;
2251 goto out;
2252 }
2253
2254 out:
2255 return ret;
2256 }
2257
ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base * ab)2258 static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)
2259 {
2260 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;
2261 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;
2262 struct ce_pipe_config *ce_cfg;
2263 struct service_to_pipe *svc_cfg;
2264 struct qmi_txn txn = {};
2265 int ret = 0, pipe_num;
2266
2267 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;
2268 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;
2269
2270 req = kzalloc(sizeof(*req), GFP_KERNEL);
2271 if (!req)
2272 return -ENOMEM;
2273
2274 memset(&resp, 0, sizeof(resp));
2275
2276 req->host_version_valid = 1;
2277 strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING,
2278 sizeof(req->host_version));
2279
2280 req->tgt_cfg_valid = 1;
2281 /* This is number of CE configs */
2282 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;
2283 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {
2284 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;
2285 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;
2286 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;
2287 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;
2288 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;
2289 }
2290
2291 req->svc_cfg_valid = 1;
2292 /* This is number of Service/CE configs */
2293 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;
2294 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {
2295 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;
2296 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;
2297 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;
2298 }
2299 req->shadow_reg_valid = 0;
2300
2301 /* set shadow v2 configuration */
2302 if (ab->hw_params.supports_shadow_regs) {
2303 req->shadow_reg_v2_valid = 1;
2304 req->shadow_reg_v2_len = min_t(u32,
2305 ab->qmi.ce_cfg.shadow_reg_v2_len,
2306 QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);
2307 memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,
2308 sizeof(u32) * req->shadow_reg_v2_len);
2309 } else {
2310 req->shadow_reg_v2_valid = 0;
2311 }
2312
2313 ret = qmi_txn_init(&ab->qmi.handle, &txn,
2314 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);
2315 if (ret < 0)
2316 goto out;
2317
2318 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,
2319 QMI_WLANFW_WLAN_CFG_REQ_V01,
2320 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,
2321 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);
2322 if (ret < 0) {
2323 ath11k_warn(ab, "qmi failed to send wlan config request, err = %d\n",
2324 ret);
2325 goto out;
2326 }
2327
2328 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));
2329 if (ret < 0) {
2330 ath11k_warn(ab, "qmi failed wlan config request, err = %d\n", ret);
2331 goto out;
2332 }
2333
2334 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
2335 ath11k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n",
2336 resp.resp.result, resp.resp.error);
2337 ret = -EINVAL;
2338 goto out;
2339 }
2340
2341 out:
2342 kfree(req);
2343 return ret;
2344 }
2345
ath11k_qmi_firmware_stop(struct ath11k_base * ab)2346 void ath11k_qmi_firmware_stop(struct ath11k_base *ab)
2347 {
2348 int ret;
2349
2350 ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);
2351 if (ret < 0) {
2352 ath11k_warn(ab, "qmi failed to send wlan mode off\n");
2353 return;
2354 }
2355 }
2356
ath11k_qmi_firmware_start(struct ath11k_base * ab,u32 mode)2357 int ath11k_qmi_firmware_start(struct ath11k_base *ab,
2358 u32 mode)
2359 {
2360 int ret;
2361
2362 ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);
2363 if (ret < 0) {
2364 ath11k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret);
2365 return ret;
2366 }
2367
2368 ret = ath11k_qmi_wlanfw_mode_send(ab, mode);
2369 if (ret < 0) {
2370 ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret);
2371 return ret;
2372 }
2373
2374 return 0;
2375 }
2376
2377 static int
ath11k_qmi_driver_event_post(struct ath11k_qmi * qmi,enum ath11k_qmi_event_type type,void * data)2378 ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,
2379 enum ath11k_qmi_event_type type,
2380 void *data)
2381 {
2382 struct ath11k_qmi_driver_event *event;
2383
2384 event = kzalloc(sizeof(*event), GFP_ATOMIC);
2385 if (!event)
2386 return -ENOMEM;
2387
2388 event->type = type;
2389 event->data = data;
2390
2391 spin_lock(&qmi->event_lock);
2392 list_add_tail(&event->list, &qmi->event_list);
2393 spin_unlock(&qmi->event_lock);
2394
2395 queue_work(qmi->event_wq, &qmi->event_work);
2396
2397 return 0;
2398 }
2399
ath11k_qmi_event_server_arrive(struct ath11k_qmi * qmi)2400 static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)
2401 {
2402 struct ath11k_base *ab = qmi->ab;
2403 int ret;
2404
2405 ret = ath11k_qmi_fw_ind_register_send(ab);
2406 if (ret < 0) {
2407 ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret);
2408 return;
2409 }
2410
2411 ret = ath11k_qmi_host_cap_send(ab);
2412 if (ret < 0) {
2413 ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret);
2414 return;
2415 }
2416 }
2417
ath11k_qmi_event_mem_request(struct ath11k_qmi * qmi)2418 static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)
2419 {
2420 struct ath11k_base *ab = qmi->ab;
2421 int ret;
2422
2423 ret = ath11k_qmi_respond_fw_mem_request(ab);
2424 if (ret < 0) {
2425 ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret);
2426 return;
2427 }
2428 }
2429
ath11k_qmi_event_load_bdf(struct ath11k_qmi * qmi)2430 static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)
2431 {
2432 struct ath11k_base *ab = qmi->ab;
2433 int ret;
2434
2435 ret = ath11k_qmi_request_target_cap(ab);
2436 if (ret < 0) {
2437 ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret);
2438 return;
2439 }
2440
2441 if (ab->bus_params.fixed_bdf_addr)
2442 ret = ath11k_qmi_load_bdf_fixed_addr(ab);
2443 else
2444 ret = ath11k_qmi_load_bdf_qmi(ab);
2445 if (ret < 0) {
2446 ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret);
2447 return;
2448 }
2449
2450 ret = ath11k_qmi_wlanfw_m3_info_send(ab);
2451 if (ret < 0) {
2452 ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret);
2453 return;
2454 }
2455 }
2456
ath11k_qmi_msg_mem_request_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * data)2457 static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,
2458 struct sockaddr_qrtr *sq,
2459 struct qmi_txn *txn,
2460 const void *data)
2461 {
2462 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2463 struct ath11k_base *ab = qmi->ab;
2464 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;
2465 int i, ret;
2466
2467 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware request memory request\n");
2468
2469 if (msg->mem_seg_len == 0 ||
2470 msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)
2471 ath11k_warn(ab, "Invalid memory segment length: %u\n",
2472 msg->mem_seg_len);
2473
2474 ab->qmi.mem_seg_count = msg->mem_seg_len;
2475
2476 for (i = 0; i < qmi->mem_seg_count ; i++) {
2477 ab->qmi.target_mem[i].type = msg->mem_seg[i].type;
2478 ab->qmi.target_mem[i].size = msg->mem_seg[i].size;
2479 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi mem seg type %d size %d\n",
2480 msg->mem_seg[i].type, msg->mem_seg[i].size);
2481 }
2482
2483 if (ab->bus_params.fixed_mem_region) {
2484 ret = ath11k_qmi_assign_target_mem_chunk(ab);
2485 if (ret) {
2486 ath11k_warn(ab, "qmi failed to assign target memory: %d\n",
2487 ret);
2488 return;
2489 }
2490 } else {
2491 ret = ath11k_qmi_alloc_target_mem_chunk(ab);
2492 if (ret) {
2493 ath11k_warn(ab, "qmi failed to alloc target memory: %d\n",
2494 ret);
2495 return;
2496 }
2497 }
2498
2499 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);
2500 }
2501
ath11k_qmi_msg_mem_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2502 static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,
2503 struct sockaddr_qrtr *sq,
2504 struct qmi_txn *txn,
2505 const void *decoded)
2506 {
2507 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2508 struct ath11k_base *ab = qmi->ab;
2509
2510 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware memory ready indication\n");
2511 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);
2512 }
2513
ath11k_qmi_msg_fw_ready_cb(struct qmi_handle * qmi_hdl,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2514 static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,
2515 struct sockaddr_qrtr *sq,
2516 struct qmi_txn *txn,
2517 const void *decoded)
2518 {
2519 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2520 struct ath11k_base *ab = qmi->ab;
2521
2522 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n");
2523 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);
2524 }
2525
ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle * qmi,struct sockaddr_qrtr * sq,struct qmi_txn * txn,const void * decoded)2526 static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi,
2527 struct sockaddr_qrtr *sq,
2528 struct qmi_txn *txn,
2529 const void *decoded)
2530 {
2531 }
2532
2533 static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {
2534 {
2535 .type = QMI_INDICATION,
2536 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,
2537 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,
2538 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),
2539 .fn = ath11k_qmi_msg_mem_request_cb,
2540 },
2541 {
2542 .type = QMI_INDICATION,
2543 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,
2544 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,
2545 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),
2546 .fn = ath11k_qmi_msg_mem_ready_cb,
2547 },
2548 {
2549 .type = QMI_INDICATION,
2550 .msg_id = QMI_WLFW_FW_READY_IND_V01,
2551 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,
2552 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),
2553 .fn = ath11k_qmi_msg_fw_ready_cb,
2554 },
2555 {
2556 .type = QMI_INDICATION,
2557 .msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,
2558 .ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,
2559 .decoded_size =
2560 sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),
2561 .fn = ath11k_qmi_msg_cold_boot_cal_done_cb,
2562 },
2563 };
2564
ath11k_qmi_ops_new_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)2565 static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,
2566 struct qmi_service *service)
2567 {
2568 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2569 struct ath11k_base *ab = qmi->ab;
2570 struct sockaddr_qrtr *sq = &qmi->sq;
2571 int ret;
2572
2573 sq->sq_family = AF_QIPCRTR;
2574 sq->sq_node = service->node;
2575 sq->sq_port = service->port;
2576
2577 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,
2578 sizeof(*sq), 0);
2579 if (ret) {
2580 ath11k_warn(ab, "qmi failed to connect to remote service %d\n", ret);
2581 return ret;
2582 }
2583
2584 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n");
2585 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);
2586
2587 return 0;
2588 }
2589
ath11k_qmi_ops_del_server(struct qmi_handle * qmi_hdl,struct qmi_service * service)2590 static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,
2591 struct qmi_service *service)
2592 {
2593 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);
2594 struct ath11k_base *ab = qmi->ab;
2595
2596 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw del server\n");
2597 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);
2598 }
2599
2600 static const struct qmi_ops ath11k_qmi_ops = {
2601 .new_server = ath11k_qmi_ops_new_server,
2602 .del_server = ath11k_qmi_ops_del_server,
2603 };
2604
ath11k_qmi_driver_event_work(struct work_struct * work)2605 static void ath11k_qmi_driver_event_work(struct work_struct *work)
2606 {
2607 struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,
2608 event_work);
2609 struct ath11k_qmi_driver_event *event;
2610 struct ath11k_base *ab = qmi->ab;
2611
2612 spin_lock(&qmi->event_lock);
2613 while (!list_empty(&qmi->event_list)) {
2614 event = list_first_entry(&qmi->event_list,
2615 struct ath11k_qmi_driver_event, list);
2616 list_del(&event->list);
2617 spin_unlock(&qmi->event_lock);
2618
2619 if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {
2620 kfree(event);
2621 return;
2622 }
2623
2624 switch (event->type) {
2625 case ATH11K_QMI_EVENT_SERVER_ARRIVE:
2626 ath11k_qmi_event_server_arrive(qmi);
2627 break;
2628 case ATH11K_QMI_EVENT_SERVER_EXIT:
2629 set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
2630 set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2631 break;
2632 case ATH11K_QMI_EVENT_REQUEST_MEM:
2633 ath11k_qmi_event_mem_request(qmi);
2634 break;
2635 case ATH11K_QMI_EVENT_FW_MEM_READY:
2636 ath11k_qmi_event_load_bdf(qmi);
2637 break;
2638 case ATH11K_QMI_EVENT_FW_READY:
2639 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {
2640 ath11k_hal_dump_srng_stats(ab);
2641 queue_work(ab->workqueue, &ab->restart_work);
2642 break;
2643 }
2644
2645 ath11k_core_qmi_firmware_ready(ab);
2646 ab->qmi.cal_done = 1;
2647 set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
2648
2649 break;
2650 case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:
2651 break;
2652 default:
2653 ath11k_warn(ab, "invalid event type: %d", event->type);
2654 break;
2655 }
2656 kfree(event);
2657 spin_lock(&qmi->event_lock);
2658 }
2659 spin_unlock(&qmi->event_lock);
2660 }
2661
ath11k_qmi_init_service(struct ath11k_base * ab)2662 int ath11k_qmi_init_service(struct ath11k_base *ab)
2663 {
2664 int ret;
2665
2666 memset(&ab->qmi.target, 0, sizeof(struct target_info));
2667 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));
2668 ab->qmi.ab = ab;
2669
2670 ab->qmi.target_mem_mode = ATH11K_QMI_TARGET_MEM_MODE_DEFAULT;
2671 ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,
2672 &ath11k_qmi_ops, ath11k_qmi_msg_handlers);
2673 if (ret < 0) {
2674 ath11k_warn(ab, "failed to initialize qmi handle\n");
2675 return ret;
2676 }
2677
2678 ab->qmi.event_wq = alloc_workqueue("ath11k_qmi_driver_event",
2679 WQ_UNBOUND, 1);
2680 if (!ab->qmi.event_wq) {
2681 ath11k_err(ab, "failed to allocate workqueue\n");
2682 return -EFAULT;
2683 }
2684
2685 INIT_LIST_HEAD(&ab->qmi.event_list);
2686 spin_lock_init(&ab->qmi.event_lock);
2687 INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);
2688
2689 ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,
2690 ATH11K_QMI_WLFW_SERVICE_VERS_V01,
2691 ab->qmi.service_ins_id);
2692 if (ret < 0) {
2693 ath11k_warn(ab, "failed to add qmi lookup\n");
2694 destroy_workqueue(ab->qmi.event_wq);
2695 return ret;
2696 }
2697
2698 return ret;
2699 }
2700
ath11k_qmi_deinit_service(struct ath11k_base * ab)2701 void ath11k_qmi_deinit_service(struct ath11k_base *ab)
2702 {
2703 qmi_handle_release(&ab->qmi.handle);
2704 cancel_work_sync(&ab->qmi.event_work);
2705 destroy_workqueue(ab->qmi.event_wq);
2706 ath11k_qmi_m3_free(ab);
2707 ath11k_qmi_free_target_mem_chunk(ab);
2708 }
2709
2710