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