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