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