Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/athk/ath10k/core.c
48375 views
1
// SPDX-License-Identifier: ISC
2
/*
3
* Copyright (c) 2005-2011 Atheros Communications Inc.
4
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
5
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
6
*/
7
8
#if defined(__FreeBSD__)
9
#define LINUXKPI_PARAM_PREFIX ath10k_core_
10
#endif
11
12
#include <linux/module.h>
13
#include <linux/firmware.h>
14
#if defined(__linux__) || (defined(__FreeBSD__) && defined(CONFIG_OF))
15
#include <linux/of.h>
16
#endif
17
#include <linux/property.h>
18
#include <linux/dmi.h>
19
#include <linux/ctype.h>
20
#include <linux/pm_qos.h>
21
#include <linux/nvmem-consumer.h>
22
#include <asm/byteorder.h>
23
24
#include "core.h"
25
#include "mac.h"
26
#include "htc.h"
27
#include "hif.h"
28
#include "wmi.h"
29
#include "bmi.h"
30
#include "debug.h"
31
#include "htt.h"
32
#include "testmode.h"
33
#include "wmi-ops.h"
34
#include "coredump.h"
35
#if defined(CONFIG_FWLOG)
36
#include "fwlog.h"
37
#endif
38
39
unsigned int ath10k_debug_mask;
40
EXPORT_SYMBOL(ath10k_debug_mask);
41
42
static unsigned int ath10k_cryptmode_param;
43
static bool uart_print;
44
static bool skip_otp;
45
static bool fw_diag_log;
46
47
/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
48
unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
49
50
unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
51
BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
52
53
/* FIXME: most of these should be readonly */
54
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
55
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
56
module_param(uart_print, bool, 0644);
57
module_param(skip_otp, bool, 0644);
58
module_param(fw_diag_log, bool, 0644);
59
module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
60
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
61
62
MODULE_PARM_DESC(debug_mask, "Debugging mask");
63
MODULE_PARM_DESC(uart_print, "Uart target debugging");
64
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
65
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
66
MODULE_PARM_DESC(frame_mode,
67
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
68
MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
69
MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
70
71
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
72
{
73
.id = QCA988X_HW_2_0_VERSION,
74
.dev_id = QCA988X_2_0_DEVICE_ID,
75
.bus = ATH10K_BUS_PCI,
76
.name = "qca988x hw2.0",
77
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
78
.uart_pin = 7,
79
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
80
.otp_exe_param = 0,
81
.channel_counters_freq_hz = 88000,
82
.max_probe_resp_desc_thres = 0,
83
.cal_data_len = 2116,
84
.fw = {
85
.dir = QCA988X_HW_2_0_FW_DIR,
86
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
87
.board_size = QCA988X_BOARD_DATA_SZ,
88
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
89
},
90
.rx_desc_ops = &qca988x_rx_desc_ops,
91
.hw_ops = &qca988x_ops,
92
.decap_align_bytes = 4,
93
.spectral_bin_discard = 0,
94
.spectral_bin_offset = 0,
95
.vht160_mcs_rx_highest = 0,
96
.vht160_mcs_tx_highest = 0,
97
.n_cipher_suites = 8,
98
.ast_skid_limit = 0x10,
99
.num_wds_entries = 0x20,
100
.target_64bit = false,
101
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
102
.shadow_reg_support = false,
103
.rri_on_ddr = false,
104
.hw_filter_reset_required = true,
105
.fw_diag_ce_download = false,
106
.credit_size_workaround = false,
107
.tx_stats_over_pktlog = true,
108
.dynamic_sar_support = false,
109
.hw_restart_disconnect = false,
110
.use_fw_tx_credits = true,
111
.delay_unmap_buffer = false,
112
},
113
{
114
.id = QCA988X_HW_2_0_VERSION,
115
.dev_id = QCA988X_2_0_DEVICE_ID_UBNT,
116
.name = "qca988x hw2.0 ubiquiti",
117
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
118
.uart_pin = 7,
119
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
120
.otp_exe_param = 0,
121
.channel_counters_freq_hz = 88000,
122
.max_probe_resp_desc_thres = 0,
123
.cal_data_len = 2116,
124
.fw = {
125
.dir = QCA988X_HW_2_0_FW_DIR,
126
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
127
.board_size = QCA988X_BOARD_DATA_SZ,
128
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
129
},
130
.rx_desc_ops = &qca988x_rx_desc_ops,
131
.hw_ops = &qca988x_ops,
132
.decap_align_bytes = 4,
133
.spectral_bin_discard = 0,
134
.spectral_bin_offset = 0,
135
.vht160_mcs_rx_highest = 0,
136
.vht160_mcs_tx_highest = 0,
137
.n_cipher_suites = 8,
138
.ast_skid_limit = 0x10,
139
.num_wds_entries = 0x20,
140
.target_64bit = false,
141
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
142
.shadow_reg_support = false,
143
.rri_on_ddr = false,
144
.hw_filter_reset_required = true,
145
.fw_diag_ce_download = false,
146
.credit_size_workaround = false,
147
.tx_stats_over_pktlog = true,
148
.dynamic_sar_support = false,
149
.hw_restart_disconnect = false,
150
.use_fw_tx_credits = true,
151
.delay_unmap_buffer = false,
152
},
153
{
154
.id = QCA9887_HW_1_0_VERSION,
155
.dev_id = QCA9887_1_0_DEVICE_ID,
156
.bus = ATH10K_BUS_PCI,
157
.name = "qca9887 hw1.0",
158
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
159
.uart_pin = 7,
160
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
161
.otp_exe_param = 0,
162
.channel_counters_freq_hz = 88000,
163
.max_probe_resp_desc_thres = 0,
164
.cal_data_len = 2116,
165
.fw = {
166
.dir = QCA9887_HW_1_0_FW_DIR,
167
.board = QCA9887_HW_1_0_BOARD_DATA_FILE,
168
.board_size = QCA9887_BOARD_DATA_SZ,
169
.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
170
},
171
.rx_desc_ops = &qca988x_rx_desc_ops,
172
.hw_ops = &qca988x_ops,
173
.decap_align_bytes = 4,
174
.spectral_bin_discard = 0,
175
.spectral_bin_offset = 0,
176
.vht160_mcs_rx_highest = 0,
177
.vht160_mcs_tx_highest = 0,
178
.n_cipher_suites = 8,
179
.ast_skid_limit = 0x10,
180
.num_wds_entries = 0x20,
181
.target_64bit = false,
182
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
183
.shadow_reg_support = false,
184
.rri_on_ddr = false,
185
.hw_filter_reset_required = true,
186
.fw_diag_ce_download = false,
187
.credit_size_workaround = false,
188
.tx_stats_over_pktlog = false,
189
.dynamic_sar_support = false,
190
.hw_restart_disconnect = false,
191
.use_fw_tx_credits = true,
192
.delay_unmap_buffer = false,
193
},
194
{
195
.id = QCA6174_HW_3_2_VERSION,
196
.dev_id = QCA6174_3_2_DEVICE_ID,
197
.bus = ATH10K_BUS_SDIO,
198
.name = "qca6174 hw3.2 sdio",
199
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
200
.uart_pin = 19,
201
.otp_exe_param = 0,
202
.channel_counters_freq_hz = 88000,
203
.max_probe_resp_desc_thres = 0,
204
.cal_data_len = 0,
205
.fw = {
206
.dir = QCA6174_HW_3_0_FW_DIR,
207
.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
208
.board_size = QCA6174_BOARD_DATA_SZ,
209
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
210
},
211
.rx_desc_ops = &qca988x_rx_desc_ops,
212
.hw_ops = &qca6174_sdio_ops,
213
.hw_clk = qca6174_clk,
214
.target_cpu_freq = 176000000,
215
.decap_align_bytes = 4,
216
.n_cipher_suites = 8,
217
.num_peers = 10,
218
.ast_skid_limit = 0x10,
219
.num_wds_entries = 0x20,
220
.uart_pin_workaround = true,
221
.tx_stats_over_pktlog = false,
222
.credit_size_workaround = false,
223
.bmi_large_size_download = true,
224
.supports_peer_stats_info = true,
225
.dynamic_sar_support = true,
226
.hw_restart_disconnect = false,
227
.use_fw_tx_credits = true,
228
.delay_unmap_buffer = false,
229
},
230
{
231
.id = QCA6174_HW_2_1_VERSION,
232
.dev_id = QCA6164_2_1_DEVICE_ID,
233
.bus = ATH10K_BUS_PCI,
234
.name = "qca6164 hw2.1",
235
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
236
.uart_pin = 6,
237
.otp_exe_param = 0,
238
.channel_counters_freq_hz = 88000,
239
.max_probe_resp_desc_thres = 0,
240
.cal_data_len = 8124,
241
.fw = {
242
.dir = QCA6174_HW_2_1_FW_DIR,
243
.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
244
.board_size = QCA6174_BOARD_DATA_SZ,
245
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
246
},
247
.rx_desc_ops = &qca988x_rx_desc_ops,
248
.hw_ops = &qca988x_ops,
249
.decap_align_bytes = 4,
250
.spectral_bin_discard = 0,
251
.spectral_bin_offset = 0,
252
.vht160_mcs_rx_highest = 0,
253
.vht160_mcs_tx_highest = 0,
254
.n_cipher_suites = 8,
255
.ast_skid_limit = 0x10,
256
.num_wds_entries = 0x20,
257
.target_64bit = false,
258
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
259
.shadow_reg_support = false,
260
.rri_on_ddr = false,
261
.hw_filter_reset_required = true,
262
.fw_diag_ce_download = false,
263
.credit_size_workaround = false,
264
.tx_stats_over_pktlog = false,
265
.dynamic_sar_support = false,
266
.hw_restart_disconnect = false,
267
.use_fw_tx_credits = true,
268
.delay_unmap_buffer = false,
269
},
270
{
271
.id = QCA6174_HW_2_1_VERSION,
272
.dev_id = QCA6174_2_1_DEVICE_ID,
273
.bus = ATH10K_BUS_PCI,
274
.name = "qca6174 hw2.1",
275
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
276
.uart_pin = 6,
277
.otp_exe_param = 0,
278
.channel_counters_freq_hz = 88000,
279
.max_probe_resp_desc_thres = 0,
280
.cal_data_len = 8124,
281
.fw = {
282
.dir = QCA6174_HW_2_1_FW_DIR,
283
.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
284
.board_size = QCA6174_BOARD_DATA_SZ,
285
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
286
},
287
.rx_desc_ops = &qca988x_rx_desc_ops,
288
.hw_ops = &qca988x_ops,
289
.decap_align_bytes = 4,
290
.spectral_bin_discard = 0,
291
.spectral_bin_offset = 0,
292
.vht160_mcs_rx_highest = 0,
293
.vht160_mcs_tx_highest = 0,
294
.n_cipher_suites = 8,
295
.ast_skid_limit = 0x10,
296
.num_wds_entries = 0x20,
297
.target_64bit = false,
298
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
299
.shadow_reg_support = false,
300
.rri_on_ddr = false,
301
.hw_filter_reset_required = true,
302
.fw_diag_ce_download = false,
303
.credit_size_workaround = false,
304
.tx_stats_over_pktlog = false,
305
.dynamic_sar_support = false,
306
.hw_restart_disconnect = false,
307
.use_fw_tx_credits = true,
308
.delay_unmap_buffer = false,
309
},
310
{
311
.id = QCA6174_HW_3_0_VERSION,
312
.dev_id = QCA6174_2_1_DEVICE_ID,
313
.bus = ATH10K_BUS_PCI,
314
.name = "qca6174 hw3.0",
315
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
316
.uart_pin = 6,
317
.otp_exe_param = 0,
318
.channel_counters_freq_hz = 88000,
319
.max_probe_resp_desc_thres = 0,
320
.cal_data_len = 8124,
321
.fw = {
322
.dir = QCA6174_HW_3_0_FW_DIR,
323
.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
324
.board_size = QCA6174_BOARD_DATA_SZ,
325
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
326
},
327
.rx_desc_ops = &qca988x_rx_desc_ops,
328
.hw_ops = &qca988x_ops,
329
.decap_align_bytes = 4,
330
.spectral_bin_discard = 0,
331
.spectral_bin_offset = 0,
332
.vht160_mcs_rx_highest = 0,
333
.vht160_mcs_tx_highest = 0,
334
.n_cipher_suites = 8,
335
.ast_skid_limit = 0x10,
336
.num_wds_entries = 0x20,
337
.target_64bit = false,
338
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
339
.shadow_reg_support = false,
340
.rri_on_ddr = false,
341
.hw_filter_reset_required = true,
342
.fw_diag_ce_download = false,
343
.credit_size_workaround = false,
344
.tx_stats_over_pktlog = false,
345
.dynamic_sar_support = false,
346
.hw_restart_disconnect = false,
347
.use_fw_tx_credits = true,
348
.delay_unmap_buffer = false,
349
},
350
{
351
.id = QCA6174_HW_3_2_VERSION,
352
.dev_id = QCA6174_2_1_DEVICE_ID,
353
.bus = ATH10K_BUS_PCI,
354
.name = "qca6174 hw3.2",
355
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
356
.uart_pin = 6,
357
.otp_exe_param = 0,
358
.channel_counters_freq_hz = 88000,
359
.max_probe_resp_desc_thres = 0,
360
.cal_data_len = 8124,
361
.fw = {
362
/* uses same binaries as hw3.0 */
363
.dir = QCA6174_HW_3_0_FW_DIR,
364
.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
365
.board_size = QCA6174_BOARD_DATA_SZ,
366
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
367
},
368
.rx_desc_ops = &qca988x_rx_desc_ops,
369
.hw_ops = &qca6174_ops,
370
.hw_clk = qca6174_clk,
371
.target_cpu_freq = 176000000,
372
.decap_align_bytes = 4,
373
.spectral_bin_discard = 0,
374
.spectral_bin_offset = 0,
375
.vht160_mcs_rx_highest = 0,
376
.vht160_mcs_tx_highest = 0,
377
.n_cipher_suites = 8,
378
.ast_skid_limit = 0x10,
379
.num_wds_entries = 0x20,
380
.target_64bit = false,
381
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
382
.shadow_reg_support = false,
383
.rri_on_ddr = false,
384
.hw_filter_reset_required = true,
385
.fw_diag_ce_download = true,
386
.credit_size_workaround = false,
387
.tx_stats_over_pktlog = false,
388
.supports_peer_stats_info = true,
389
.dynamic_sar_support = true,
390
.hw_restart_disconnect = false,
391
.use_fw_tx_credits = true,
392
.delay_unmap_buffer = false,
393
},
394
{
395
.id = QCA99X0_HW_2_0_DEV_VERSION,
396
.dev_id = QCA99X0_2_0_DEVICE_ID,
397
.bus = ATH10K_BUS_PCI,
398
.name = "qca99x0 hw2.0",
399
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
400
.uart_pin = 7,
401
.otp_exe_param = 0x00000700,
402
.continuous_frag_desc = true,
403
.cck_rate_map_rev2 = true,
404
.channel_counters_freq_hz = 150000,
405
.max_probe_resp_desc_thres = 24,
406
.tx_chain_mask = 0xf,
407
.rx_chain_mask = 0xf,
408
.max_spatial_stream = 4,
409
.cal_data_len = 12064,
410
.fw = {
411
.dir = QCA99X0_HW_2_0_FW_DIR,
412
.board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
413
.board_size = QCA99X0_BOARD_DATA_SZ,
414
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
415
},
416
.sw_decrypt_mcast_mgmt = true,
417
.rx_desc_ops = &qca99x0_rx_desc_ops,
418
.hw_ops = &qca99x0_ops,
419
.decap_align_bytes = 1,
420
.spectral_bin_discard = 4,
421
.spectral_bin_offset = 0,
422
.vht160_mcs_rx_highest = 0,
423
.vht160_mcs_tx_highest = 0,
424
.n_cipher_suites = 11,
425
.ast_skid_limit = 0x10,
426
.num_wds_entries = 0x20,
427
.target_64bit = false,
428
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
429
.shadow_reg_support = false,
430
.rri_on_ddr = false,
431
.hw_filter_reset_required = true,
432
.fw_diag_ce_download = false,
433
.credit_size_workaround = false,
434
.tx_stats_over_pktlog = false,
435
.dynamic_sar_support = false,
436
.hw_restart_disconnect = false,
437
.use_fw_tx_credits = true,
438
.delay_unmap_buffer = false,
439
},
440
{
441
.id = QCA9984_HW_1_0_DEV_VERSION,
442
.dev_id = QCA9984_1_0_DEVICE_ID,
443
.bus = ATH10K_BUS_PCI,
444
.name = "qca9984/qca9994 hw1.0",
445
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
446
.uart_pin = 7,
447
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
448
.otp_exe_param = 0x00000700,
449
.continuous_frag_desc = true,
450
.cck_rate_map_rev2 = true,
451
.channel_counters_freq_hz = 150000,
452
.max_probe_resp_desc_thres = 24,
453
.tx_chain_mask = 0xf,
454
.rx_chain_mask = 0xf,
455
.max_spatial_stream = 4,
456
.cal_data_len = 12064,
457
.fw = {
458
.dir = QCA9984_HW_1_0_FW_DIR,
459
.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
460
.eboard = QCA9984_HW_1_0_EBOARD_DATA_FILE,
461
.board_size = QCA99X0_BOARD_DATA_SZ,
462
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
463
.ext_board_size = QCA99X0_EXT_BOARD_DATA_SZ,
464
},
465
.sw_decrypt_mcast_mgmt = true,
466
.rx_desc_ops = &qca99x0_rx_desc_ops,
467
.hw_ops = &qca99x0_ops,
468
.decap_align_bytes = 1,
469
.spectral_bin_discard = 12,
470
.spectral_bin_offset = 8,
471
472
/* Can do only 2x2 VHT160 or 80+80. 1560Mbps is 4x4 80Mhz
473
* or 2x2 160Mhz, long-guard-interval.
474
*/
475
.vht160_mcs_rx_highest = 1560,
476
.vht160_mcs_tx_highest = 1560,
477
.n_cipher_suites = 11,
478
.ast_skid_limit = 0x10,
479
.num_wds_entries = 0x20,
480
.target_64bit = false,
481
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
482
.shadow_reg_support = false,
483
.rri_on_ddr = false,
484
.hw_filter_reset_required = true,
485
.fw_diag_ce_download = false,
486
.credit_size_workaround = false,
487
.tx_stats_over_pktlog = false,
488
.dynamic_sar_support = false,
489
.hw_restart_disconnect = false,
490
.use_fw_tx_credits = true,
491
.delay_unmap_buffer = false,
492
},
493
{
494
.id = QCA9888_HW_2_0_DEV_VERSION,
495
.dev_id = QCA9888_2_0_DEVICE_ID,
496
.bus = ATH10K_BUS_PCI,
497
.name = "qca9888 hw2.0",
498
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
499
.uart_pin = 7,
500
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
501
.otp_exe_param = 0x00000700,
502
.continuous_frag_desc = true,
503
.channel_counters_freq_hz = 150000,
504
.max_probe_resp_desc_thres = 24,
505
.tx_chain_mask = 3,
506
.rx_chain_mask = 3,
507
.max_spatial_stream = 2,
508
.cal_data_len = 12064,
509
.fw = {
510
.dir = QCA9888_HW_2_0_FW_DIR,
511
.board = QCA9888_HW_2_0_BOARD_DATA_FILE,
512
.board_size = QCA99X0_BOARD_DATA_SZ,
513
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
514
},
515
.sw_decrypt_mcast_mgmt = true,
516
.rx_desc_ops = &qca99x0_rx_desc_ops,
517
.hw_ops = &qca99x0_ops,
518
.decap_align_bytes = 1,
519
.spectral_bin_discard = 12,
520
.spectral_bin_offset = 8,
521
522
/* Can do only 1x1 VHT160 or 80+80. 780Mbps is 2x2 80Mhz or
523
* 1x1 160Mhz, long-guard-interval.
524
*/
525
.vht160_mcs_rx_highest = 780,
526
.vht160_mcs_tx_highest = 780,
527
.n_cipher_suites = 11,
528
.ast_skid_limit = 0x10,
529
.num_wds_entries = 0x20,
530
.target_64bit = false,
531
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
532
.shadow_reg_support = false,
533
.rri_on_ddr = false,
534
.hw_filter_reset_required = true,
535
.fw_diag_ce_download = false,
536
.credit_size_workaround = false,
537
.tx_stats_over_pktlog = false,
538
.dynamic_sar_support = false,
539
.hw_restart_disconnect = false,
540
.use_fw_tx_credits = true,
541
.delay_unmap_buffer = false,
542
},
543
{
544
.id = QCA9377_HW_1_0_DEV_VERSION,
545
.dev_id = QCA9377_1_0_DEVICE_ID,
546
.bus = ATH10K_BUS_PCI,
547
.name = "qca9377 hw1.0",
548
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
549
.uart_pin = 6,
550
.otp_exe_param = 0,
551
.channel_counters_freq_hz = 88000,
552
.max_probe_resp_desc_thres = 0,
553
.cal_data_len = 8124,
554
.fw = {
555
.dir = QCA9377_HW_1_0_FW_DIR,
556
.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
557
.board_size = QCA9377_BOARD_DATA_SZ,
558
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
559
},
560
.rx_desc_ops = &qca988x_rx_desc_ops,
561
.hw_ops = &qca988x_ops,
562
.decap_align_bytes = 4,
563
.spectral_bin_discard = 0,
564
.spectral_bin_offset = 0,
565
.vht160_mcs_rx_highest = 0,
566
.vht160_mcs_tx_highest = 0,
567
.n_cipher_suites = 8,
568
.ast_skid_limit = 0x10,
569
.num_wds_entries = 0x20,
570
.target_64bit = false,
571
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
572
.shadow_reg_support = false,
573
.rri_on_ddr = false,
574
.hw_filter_reset_required = true,
575
.fw_diag_ce_download = false,
576
.credit_size_workaround = false,
577
.tx_stats_over_pktlog = false,
578
.dynamic_sar_support = false,
579
.hw_restart_disconnect = false,
580
.use_fw_tx_credits = true,
581
.delay_unmap_buffer = false,
582
},
583
{
584
.id = QCA9377_HW_1_1_DEV_VERSION,
585
.dev_id = QCA9377_1_0_DEVICE_ID,
586
.bus = ATH10K_BUS_PCI,
587
.name = "qca9377 hw1.1",
588
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
589
.uart_pin = 6,
590
.otp_exe_param = 0,
591
.channel_counters_freq_hz = 88000,
592
.max_probe_resp_desc_thres = 0,
593
.cal_data_len = 8124,
594
.fw = {
595
.dir = QCA9377_HW_1_0_FW_DIR,
596
.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
597
.board_size = QCA9377_BOARD_DATA_SZ,
598
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
599
},
600
.rx_desc_ops = &qca988x_rx_desc_ops,
601
.hw_ops = &qca6174_ops,
602
.hw_clk = qca6174_clk,
603
.target_cpu_freq = 176000000,
604
.decap_align_bytes = 4,
605
.spectral_bin_discard = 0,
606
.spectral_bin_offset = 0,
607
.vht160_mcs_rx_highest = 0,
608
.vht160_mcs_tx_highest = 0,
609
.n_cipher_suites = 8,
610
.ast_skid_limit = 0x10,
611
.num_wds_entries = 0x20,
612
.target_64bit = false,
613
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
614
.shadow_reg_support = false,
615
.rri_on_ddr = false,
616
.hw_filter_reset_required = true,
617
.fw_diag_ce_download = true,
618
.credit_size_workaround = false,
619
.tx_stats_over_pktlog = false,
620
.dynamic_sar_support = false,
621
.hw_restart_disconnect = false,
622
.use_fw_tx_credits = true,
623
.delay_unmap_buffer = false,
624
},
625
{
626
.id = QCA9377_HW_1_1_DEV_VERSION,
627
.dev_id = QCA9377_1_0_DEVICE_ID,
628
.bus = ATH10K_BUS_SDIO,
629
.name = "qca9377 hw1.1 sdio",
630
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
631
.uart_pin = 19,
632
.otp_exe_param = 0,
633
.channel_counters_freq_hz = 88000,
634
.max_probe_resp_desc_thres = 0,
635
.cal_data_len = 8124,
636
.fw = {
637
.dir = QCA9377_HW_1_0_FW_DIR,
638
.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
639
.board_size = QCA9377_BOARD_DATA_SZ,
640
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
641
},
642
.rx_desc_ops = &qca988x_rx_desc_ops,
643
.hw_ops = &qca6174_ops,
644
.hw_clk = qca6174_clk,
645
.target_cpu_freq = 176000000,
646
.decap_align_bytes = 4,
647
.n_cipher_suites = 8,
648
.num_peers = TARGET_QCA9377_HL_NUM_PEERS,
649
.ast_skid_limit = 0x10,
650
.num_wds_entries = 0x20,
651
.uart_pin_workaround = true,
652
.credit_size_workaround = true,
653
.dynamic_sar_support = false,
654
.hw_restart_disconnect = false,
655
.use_fw_tx_credits = true,
656
.delay_unmap_buffer = false,
657
},
658
{
659
.id = QCA4019_HW_1_0_DEV_VERSION,
660
.dev_id = 0,
661
.bus = ATH10K_BUS_AHB,
662
.name = "qca4019 hw1.0",
663
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
664
.uart_pin = 7,
665
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
666
.otp_exe_param = 0x0010000,
667
.continuous_frag_desc = true,
668
.cck_rate_map_rev2 = true,
669
.channel_counters_freq_hz = 125000,
670
.max_probe_resp_desc_thres = 24,
671
.tx_chain_mask = 0x3,
672
.rx_chain_mask = 0x3,
673
.max_spatial_stream = 2,
674
.cal_data_len = 12064,
675
.fw = {
676
.dir = QCA4019_HW_1_0_FW_DIR,
677
.board = QCA4019_HW_1_0_BOARD_DATA_FILE,
678
.board_size = QCA4019_BOARD_DATA_SZ,
679
.board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
680
},
681
.sw_decrypt_mcast_mgmt = true,
682
.rx_desc_ops = &qca99x0_rx_desc_ops,
683
.hw_ops = &qca99x0_ops,
684
.decap_align_bytes = 1,
685
.spectral_bin_discard = 4,
686
.spectral_bin_offset = 0,
687
.vht160_mcs_rx_highest = 0,
688
.vht160_mcs_tx_highest = 0,
689
.n_cipher_suites = 11,
690
.ast_skid_limit = 0x10,
691
.num_wds_entries = 0x20,
692
.target_64bit = false,
693
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
694
.shadow_reg_support = false,
695
.rri_on_ddr = false,
696
.hw_filter_reset_required = true,
697
.fw_diag_ce_download = false,
698
.credit_size_workaround = false,
699
.tx_stats_over_pktlog = false,
700
.dynamic_sar_support = false,
701
.hw_restart_disconnect = false,
702
.use_fw_tx_credits = true,
703
.delay_unmap_buffer = false,
704
},
705
{
706
.id = WCN3990_HW_1_0_DEV_VERSION,
707
.dev_id = 0,
708
.bus = ATH10K_BUS_SNOC,
709
.name = "wcn3990 hw1.0",
710
.continuous_frag_desc = true,
711
.tx_chain_mask = 0x7,
712
.rx_chain_mask = 0x7,
713
.max_spatial_stream = 4,
714
.fw = {
715
.dir = WCN3990_HW_1_0_FW_DIR,
716
},
717
.sw_decrypt_mcast_mgmt = true,
718
.rx_desc_ops = &wcn3990_rx_desc_ops,
719
.hw_ops = &wcn3990_ops,
720
.decap_align_bytes = 1,
721
.num_peers = TARGET_HL_TLV_NUM_PEERS,
722
.n_cipher_suites = 11,
723
.ast_skid_limit = TARGET_HL_TLV_AST_SKID_LIMIT,
724
.num_wds_entries = TARGET_HL_TLV_NUM_WDS_ENTRIES,
725
.target_64bit = true,
726
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC,
727
.shadow_reg_support = true,
728
.rri_on_ddr = true,
729
.hw_filter_reset_required = false,
730
.fw_diag_ce_download = false,
731
.credit_size_workaround = false,
732
.tx_stats_over_pktlog = false,
733
.dynamic_sar_support = true,
734
.hw_restart_disconnect = true,
735
.use_fw_tx_credits = false,
736
.delay_unmap_buffer = true,
737
},
738
};
739
740
static const char *const ath10k_core_fw_feature_str[] = {
741
[ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
742
[ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
743
[ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
744
[ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
745
[ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",
746
[ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",
747
[ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",
748
[ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
749
[ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
750
[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
751
[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
752
[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
753
[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
754
[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
755
[ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
756
[ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
757
[ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",
758
[ATH10K_FW_FEATURE_NO_PS] = "no-ps",
759
[ATH10K_FW_FEATURE_MGMT_TX_BY_REF] = "mgmt-tx-by-reference",
760
[ATH10K_FW_FEATURE_NON_BMI] = "non-bmi",
761
[ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL] = "single-chan-info-per-channel",
762
[ATH10K_FW_FEATURE_PEER_FIXED_RATE] = "peer-fixed-rate",
763
[ATH10K_FW_FEATURE_IRAM_RECOVERY] = "iram-recovery",
764
};
765
766
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
767
size_t buf_len,
768
enum ath10k_fw_features feat)
769
{
770
/* make sure that ath10k_core_fw_feature_str[] gets updated */
771
BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=
772
ATH10K_FW_FEATURE_COUNT);
773
774
if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
775
WARN_ON(!ath10k_core_fw_feature_str[feat])) {
776
return scnprintf(buf, buf_len, "bit%d", feat);
777
}
778
779
return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);
780
}
781
782
void ath10k_core_get_fw_features_str(struct ath10k *ar,
783
char *buf,
784
size_t buf_len)
785
{
786
size_t len = 0;
787
int i;
788
789
for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
790
if (test_bit(i, ar->normal_mode_fw.fw_file.fw_features)) {
791
if (len > 0)
792
len += scnprintf(buf + len, buf_len - len, ",");
793
794
len += ath10k_core_get_fw_feature_str(buf + len,
795
buf_len - len,
796
i);
797
}
798
}
799
}
800
801
static void ath10k_send_suspend_complete(struct ath10k *ar)
802
{
803
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
804
805
complete(&ar->target_suspend);
806
}
807
808
static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)
809
{
810
bool mtu_workaround = ar->hw_params.credit_size_workaround;
811
int ret;
812
u32 param = 0;
813
814
ret = ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
815
if (ret)
816
return ret;
817
818
ret = ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
819
if (ret)
820
return ret;
821
822
ret = ath10k_bmi_read32(ar, hi_acs_flags, &param);
823
if (ret)
824
return ret;
825
826
param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;
827
828
if (mode == ATH10K_FIRMWARE_MODE_NORMAL && !mtu_workaround)
829
param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
830
else
831
param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;
832
833
if (mode == ATH10K_FIRMWARE_MODE_UTF)
834
param &= ~HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
835
else
836
param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;
837
838
ret = ath10k_bmi_write32(ar, hi_acs_flags, param);
839
if (ret)
840
return ret;
841
842
ret = ath10k_bmi_read32(ar, hi_option_flag2, &param);
843
if (ret)
844
return ret;
845
846
param |= HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_HOST;
847
848
ret = ath10k_bmi_write32(ar, hi_option_flag2, param);
849
if (ret)
850
return ret;
851
852
return 0;
853
}
854
855
static int ath10k_init_configure_target(struct ath10k *ar)
856
{
857
u32 param_host;
858
int ret;
859
860
/* tell target which HTC version it is used*/
861
ret = ath10k_bmi_write32(ar, hi_app_host_interest,
862
HTC_PROTOCOL_VERSION);
863
if (ret) {
864
ath10k_err(ar, "settings HTC version failed\n");
865
return ret;
866
}
867
868
/* set the firmware mode to STA/IBSS/AP */
869
ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
870
if (ret) {
871
ath10k_err(ar, "setting firmware mode (1/2) failed\n");
872
return ret;
873
}
874
875
/* TODO following parameters need to be re-visited. */
876
/* num_device */
877
param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
878
/* Firmware mode */
879
/* FIXME: Why FW_MODE_AP ??.*/
880
param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
881
/* mac_addr_method */
882
param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
883
/* firmware_bridge */
884
param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
885
/* fwsubmode */
886
param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
887
888
ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
889
if (ret) {
890
ath10k_err(ar, "setting firmware mode (2/2) failed\n");
891
return ret;
892
}
893
894
/* We do all byte-swapping on the host */
895
ret = ath10k_bmi_write32(ar, hi_be, 0);
896
if (ret) {
897
ath10k_err(ar, "setting host CPU BE mode failed\n");
898
return ret;
899
}
900
901
/* FW descriptor/Data swap flags */
902
ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
903
904
if (ret) {
905
ath10k_err(ar, "setting FW data/desc swap flags failed\n");
906
return ret;
907
}
908
909
/* Some devices have a special sanity check that verifies the PCI
910
* Device ID is written to this host interest var. It is known to be
911
* required to boot QCA6164.
912
*/
913
ret = ath10k_bmi_write32(ar, hi_hci_uart_pwr_mgmt_params_ext,
914
ar->dev_id);
915
if (ret) {
916
ath10k_err(ar, "failed to set pwr_mgmt_params: %d\n", ret);
917
return ret;
918
}
919
920
return 0;
921
}
922
923
static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
924
const char *dir,
925
const char *file)
926
{
927
char filename[100];
928
const struct firmware *fw;
929
int ret;
930
931
if (file == NULL)
932
return ERR_PTR(-ENOENT);
933
934
if (dir == NULL)
935
dir = ".";
936
937
snprintf(filename, sizeof(filename), "%s/%s", dir, file);
938
ret = firmware_request_nowarn(&fw, filename, ar->dev);
939
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n",
940
filename, ret);
941
942
if (ret)
943
return ERR_PTR(ret);
944
945
return fw;
946
}
947
948
#if defined(__linux__)
949
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
950
#elif defined(__FreeBSD__)
951
static int ath10k_push_board_ext_data(struct ath10k *ar, const u8 *data,
952
#endif
953
size_t data_len)
954
{
955
u32 board_data_size = ar->hw_params.fw.board_size;
956
u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
957
u32 board_ext_data_addr;
958
int ret;
959
960
ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
961
if (ret) {
962
ath10k_err(ar, "could not read board ext data addr (%d)\n",
963
ret);
964
return ret;
965
}
966
967
ath10k_dbg(ar, ATH10K_DBG_BOOT,
968
"boot push board extended data addr 0x%x\n",
969
board_ext_data_addr);
970
971
if (board_ext_data_addr == 0)
972
return 0;
973
974
if (data_len != (board_data_size + board_ext_data_size)) {
975
ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
976
data_len, board_data_size, board_ext_data_size);
977
return -EINVAL;
978
}
979
980
ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
981
data + board_data_size,
982
board_ext_data_size);
983
if (ret) {
984
ath10k_err(ar, "could not write board ext data (%d)\n", ret);
985
return ret;
986
}
987
988
ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
989
(board_ext_data_size << 16) | 1);
990
if (ret) {
991
ath10k_err(ar, "could not write board ext data bit (%d)\n",
992
ret);
993
return ret;
994
}
995
996
return 0;
997
}
998
999
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
1000
{
1001
u32 result, address;
1002
u8 board_id, chip_id;
1003
bool ext_bid_support;
1004
int ret, bmi_board_id_param;
1005
1006
address = ar->hw_params.patch_load_addr;
1007
1008
if (!ar->normal_mode_fw.fw_file.otp_data ||
1009
!ar->normal_mode_fw.fw_file.otp_len) {
1010
ath10k_warn(ar,
1011
"failed to retrieve board id because of invalid otp\n");
1012
return -ENODATA;
1013
}
1014
1015
if (ar->id.bmi_ids_valid) {
1016
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1017
"boot already acquired valid otp board id,skip download, board_id %d chip_id %d\n",
1018
ar->id.bmi_board_id, ar->id.bmi_chip_id);
1019
goto skip_otp_download;
1020
}
1021
1022
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1023
"boot upload otp to 0x%x len %zd for board id\n",
1024
address, ar->normal_mode_fw.fw_file.otp_len);
1025
1026
ret = ath10k_bmi_fast_download(ar, address,
1027
ar->normal_mode_fw.fw_file.otp_data,
1028
ar->normal_mode_fw.fw_file.otp_len);
1029
if (ret) {
1030
ath10k_err(ar, "could not write otp for board id check: %d\n",
1031
ret);
1032
return ret;
1033
}
1034
1035
if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
1036
ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
1037
ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
1038
bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
1039
else
1040
bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
1041
1042
ret = ath10k_bmi_execute(ar, address, bmi_board_id_param, &result);
1043
if (ret) {
1044
ath10k_err(ar, "could not execute otp for board id check: %d\n",
1045
ret);
1046
return ret;
1047
}
1048
1049
board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
1050
chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
1051
ext_bid_support = (result & ATH10K_BMI_EXT_BOARD_ID_SUPPORT);
1052
1053
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1054
"boot get otp board id result 0x%08x board_id %d chip_id %d ext_bid_support %d\n",
1055
result, board_id, chip_id, ext_bid_support);
1056
1057
ar->id.ext_bid_supported = ext_bid_support;
1058
1059
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||
1060
(board_id == 0)) {
1061
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1062
"board id does not exist in otp, ignore it\n");
1063
return -EOPNOTSUPP;
1064
}
1065
1066
ar->id.bmi_ids_valid = true;
1067
ar->id.bmi_board_id = board_id;
1068
ar->id.bmi_chip_id = chip_id;
1069
1070
skip_otp_download:
1071
1072
return 0;
1073
}
1074
1075
static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
1076
{
1077
struct ath10k *ar = data;
1078
const char *bdf_ext;
1079
const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
1080
u8 bdf_enabled;
1081
int i;
1082
1083
if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
1084
return;
1085
1086
if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
1087
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1088
"wrong smbios bdf ext type length (%d).\n",
1089
hdr->length);
1090
return;
1091
}
1092
1093
#if defined(__linux__)
1094
bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
1095
#elif defined(__FreeBSD__)
1096
bdf_enabled = *((const u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
1097
#endif
1098
if (!bdf_enabled) {
1099
ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
1100
return;
1101
}
1102
1103
/* Only one string exists (per spec) */
1104
#if defined(__linux__)
1105
bdf_ext = (char *)hdr + hdr->length;
1106
#elif defined(__FreeBSD__)
1107
bdf_ext = (const char *)hdr + hdr->length;
1108
#endif
1109
1110
if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
1111
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1112
"bdf variant magic does not match.\n");
1113
return;
1114
}
1115
1116
for (i = 0; i < strlen(bdf_ext); i++) {
1117
if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
1118
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1119
"bdf variant name contains non ascii chars.\n");
1120
return;
1121
}
1122
}
1123
1124
/* Copy extension name without magic suffix */
1125
if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
1126
sizeof(ar->id.bdf_ext)) < 0) {
1127
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1128
"bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
1129
bdf_ext);
1130
return;
1131
}
1132
1133
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1134
"found and validated bdf variant smbios_type 0x%x bdf %s\n",
1135
ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
1136
}
1137
1138
static int ath10k_core_check_smbios(struct ath10k *ar)
1139
{
1140
ar->id.bdf_ext[0] = '\0';
1141
dmi_walk(ath10k_core_check_bdfext, ar);
1142
1143
if (ar->id.bdf_ext[0] == '\0')
1144
return -ENODATA;
1145
1146
return 0;
1147
}
1148
1149
int ath10k_core_check_dt(struct ath10k *ar)
1150
{
1151
#if defined(__linux__) || (defined(__FreeBSD__) && defined(CONFIG_OF))
1152
struct device_node *node;
1153
const char *variant = NULL;
1154
1155
node = ar->dev->of_node;
1156
if (!node)
1157
return -ENOENT;
1158
1159
of_property_read_string(node, "qcom,ath10k-calibration-variant",
1160
&variant);
1161
if (!variant)
1162
return -ENODATA;
1163
1164
if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0)
1165
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1166
"bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
1167
variant);
1168
1169
return 0;
1170
#else
1171
return -ENOENT;
1172
#endif
1173
}
1174
EXPORT_SYMBOL(ath10k_core_check_dt);
1175
1176
static int ath10k_download_fw(struct ath10k *ar)
1177
{
1178
u32 address, data_len;
1179
const void *data;
1180
int ret;
1181
struct pm_qos_request latency_qos;
1182
1183
address = ar->hw_params.patch_load_addr;
1184
1185
data = ar->running_fw->fw_file.firmware_data;
1186
data_len = ar->running_fw->fw_file.firmware_len;
1187
1188
ret = ath10k_swap_code_seg_configure(ar, &ar->running_fw->fw_file);
1189
if (ret) {
1190
ath10k_err(ar, "failed to configure fw code swap: %d\n",
1191
ret);
1192
return ret;
1193
}
1194
1195
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1196
"boot uploading firmware image %pK len %d\n",
1197
data, data_len);
1198
1199
/* Check if device supports to download firmware via
1200
* diag copy engine. Downloading firmware via diag CE
1201
* greatly reduces the time to download firmware.
1202
*/
1203
if (ar->hw_params.fw_diag_ce_download) {
1204
ret = ath10k_hw_diag_fast_download(ar, address,
1205
data, data_len);
1206
if (ret == 0)
1207
/* firmware upload via diag ce was successful */
1208
return 0;
1209
1210
ath10k_warn(ar,
1211
"failed to upload firmware via diag ce, trying BMI: %d",
1212
ret);
1213
}
1214
1215
memset(&latency_qos, 0, sizeof(latency_qos));
1216
cpu_latency_qos_add_request(&latency_qos, 0);
1217
1218
ret = ath10k_bmi_fast_download(ar, address, data, data_len);
1219
1220
cpu_latency_qos_remove_request(&latency_qos);
1221
1222
return ret;
1223
}
1224
1225
void ath10k_core_free_board_files(struct ath10k *ar)
1226
{
1227
if (!IS_ERR(ar->normal_mode_fw.board))
1228
release_firmware(ar->normal_mode_fw.board);
1229
1230
if (!IS_ERR(ar->normal_mode_fw.ext_board))
1231
release_firmware(ar->normal_mode_fw.ext_board);
1232
1233
ar->normal_mode_fw.board = NULL;
1234
ar->normal_mode_fw.board_data = NULL;
1235
ar->normal_mode_fw.board_len = 0;
1236
ar->normal_mode_fw.ext_board = NULL;
1237
ar->normal_mode_fw.ext_board_data = NULL;
1238
ar->normal_mode_fw.ext_board_len = 0;
1239
}
1240
EXPORT_SYMBOL(ath10k_core_free_board_files);
1241
1242
static void ath10k_core_free_firmware_files(struct ath10k *ar)
1243
{
1244
if (!IS_ERR(ar->normal_mode_fw.fw_file.firmware))
1245
release_firmware(ar->normal_mode_fw.fw_file.firmware);
1246
1247
if (!IS_ERR(ar->cal_file))
1248
release_firmware(ar->cal_file);
1249
1250
if (!IS_ERR(ar->pre_cal_file))
1251
release_firmware(ar->pre_cal_file);
1252
1253
ath10k_swap_code_seg_release(ar, &ar->normal_mode_fw.fw_file);
1254
1255
ar->normal_mode_fw.fw_file.otp_data = NULL;
1256
ar->normal_mode_fw.fw_file.otp_len = 0;
1257
1258
ar->normal_mode_fw.fw_file.firmware = NULL;
1259
ar->normal_mode_fw.fw_file.firmware_data = NULL;
1260
ar->normal_mode_fw.fw_file.firmware_len = 0;
1261
1262
ar->cal_file = NULL;
1263
ar->pre_cal_file = NULL;
1264
}
1265
1266
static int ath10k_fetch_cal_file(struct ath10k *ar)
1267
{
1268
char filename[100];
1269
1270
/* pre-cal-<bus>-<id>.bin */
1271
scnprintf(filename, sizeof(filename), "pre-cal-%s-%s.bin",
1272
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
1273
1274
ar->pre_cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
1275
if (!IS_ERR(ar->pre_cal_file))
1276
goto success;
1277
1278
/* cal-<bus>-<id>.bin */
1279
scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
1280
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
1281
1282
ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
1283
if (IS_ERR(ar->cal_file))
1284
/* calibration file is optional, don't print any warnings */
1285
return PTR_ERR(ar->cal_file);
1286
success:
1287
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
1288
ATH10K_FW_DIR, filename);
1289
1290
return 0;
1291
}
1292
1293
static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
1294
{
1295
const struct firmware *fw;
1296
char boardname[100];
1297
1298
if (bd_ie_type == ATH10K_BD_IE_BOARD) {
1299
if (!ar->hw_params.fw.board) {
1300
ath10k_err(ar, "failed to find board file fw entry\n");
1301
return -EINVAL;
1302
}
1303
1304
scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",
1305
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
1306
1307
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
1308
ar->hw_params.fw.dir,
1309
boardname);
1310
if (IS_ERR(ar->normal_mode_fw.board)) {
1311
fw = ath10k_fetch_fw_file(ar,
1312
ar->hw_params.fw.dir,
1313
ar->hw_params.fw.board);
1314
ar->normal_mode_fw.board = fw;
1315
}
1316
1317
if (IS_ERR(ar->normal_mode_fw.board))
1318
return PTR_ERR(ar->normal_mode_fw.board);
1319
1320
ar->normal_mode_fw.board_data = ar->normal_mode_fw.board->data;
1321
ar->normal_mode_fw.board_len = ar->normal_mode_fw.board->size;
1322
} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
1323
if (!ar->hw_params.fw.eboard) {
1324
ath10k_err(ar, "failed to find eboard file fw entry\n");
1325
return -EINVAL;
1326
}
1327
1328
fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
1329
ar->hw_params.fw.eboard);
1330
ar->normal_mode_fw.ext_board = fw;
1331
if (IS_ERR(ar->normal_mode_fw.ext_board))
1332
return PTR_ERR(ar->normal_mode_fw.ext_board);
1333
1334
ar->normal_mode_fw.ext_board_data = ar->normal_mode_fw.ext_board->data;
1335
ar->normal_mode_fw.ext_board_len = ar->normal_mode_fw.ext_board->size;
1336
}
1337
1338
return 0;
1339
}
1340
1341
static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
1342
#if defined(__linux__)
1343
const void *buf, size_t buf_len,
1344
#elif defined(__FreeBSD__)
1345
const u8 *buf, size_t buf_len,
1346
#endif
1347
const char *boardname,
1348
int bd_ie_type)
1349
{
1350
const struct ath10k_fw_ie *hdr;
1351
bool name_match_found;
1352
int ret, board_ie_id;
1353
size_t board_ie_len;
1354
const void *board_ie_data;
1355
1356
name_match_found = false;
1357
1358
/* go through ATH10K_BD_IE_BOARD_ elements */
1359
while (buf_len > sizeof(struct ath10k_fw_ie)) {
1360
#if defined(__linux__)
1361
hdr = buf;
1362
#elif defined(__FreeBSD__)
1363
hdr = (const void *)buf;
1364
#endif
1365
board_ie_id = le32_to_cpu(hdr->id);
1366
board_ie_len = le32_to_cpu(hdr->len);
1367
board_ie_data = hdr->data;
1368
1369
buf_len -= sizeof(*hdr);
1370
buf += sizeof(*hdr);
1371
1372
if (buf_len < ALIGN(board_ie_len, 4)) {
1373
ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",
1374
buf_len, ALIGN(board_ie_len, 4));
1375
ret = -EINVAL;
1376
goto out;
1377
}
1378
1379
switch (board_ie_id) {
1380
case ATH10K_BD_IE_BOARD_NAME:
1381
ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",
1382
board_ie_data, board_ie_len);
1383
1384
if (board_ie_len != strlen(boardname))
1385
break;
1386
1387
ret = memcmp(board_ie_data, boardname, strlen(boardname));
1388
if (ret)
1389
break;
1390
1391
name_match_found = true;
1392
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1393
"boot found match for name '%s'",
1394
boardname);
1395
break;
1396
case ATH10K_BD_IE_BOARD_DATA:
1397
if (!name_match_found)
1398
/* no match found */
1399
break;
1400
1401
if (bd_ie_type == ATH10K_BD_IE_BOARD) {
1402
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1403
"boot found board data for '%s'",
1404
boardname);
1405
1406
ar->normal_mode_fw.board_data = board_ie_data;
1407
ar->normal_mode_fw.board_len = board_ie_len;
1408
} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
1409
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1410
"boot found eboard data for '%s'",
1411
boardname);
1412
1413
ar->normal_mode_fw.ext_board_data = board_ie_data;
1414
ar->normal_mode_fw.ext_board_len = board_ie_len;
1415
}
1416
1417
ret = 0;
1418
goto out;
1419
default:
1420
ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",
1421
board_ie_id);
1422
break;
1423
}
1424
1425
/* jump over the padding */
1426
board_ie_len = ALIGN(board_ie_len, 4);
1427
1428
buf_len -= board_ie_len;
1429
buf += board_ie_len;
1430
}
1431
1432
/* no match found */
1433
ret = -ENOENT;
1434
1435
out:
1436
return ret;
1437
}
1438
1439
static int ath10k_core_search_bd(struct ath10k *ar,
1440
const char *boardname,
1441
const u8 *data,
1442
size_t len)
1443
{
1444
size_t ie_len;
1445
#if defined(__linux__)
1446
struct ath10k_fw_ie *hdr;
1447
#elif defined(__FreeBSD__)
1448
const struct ath10k_fw_ie *hdr;
1449
#endif
1450
int ret = -ENOENT, ie_id;
1451
1452
while (len > sizeof(struct ath10k_fw_ie)) {
1453
#if defined(__linux__)
1454
hdr = (struct ath10k_fw_ie *)data;
1455
#elif defined(__FreeBSD__)
1456
hdr = (const struct ath10k_fw_ie *)data;
1457
#endif
1458
ie_id = le32_to_cpu(hdr->id);
1459
ie_len = le32_to_cpu(hdr->len);
1460
1461
len -= sizeof(*hdr);
1462
data = hdr->data;
1463
1464
if (len < ALIGN(ie_len, 4)) {
1465
ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
1466
ie_id, ie_len, len);
1467
return -EINVAL;
1468
}
1469
1470
switch (ie_id) {
1471
case ATH10K_BD_IE_BOARD:
1472
ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
1473
boardname,
1474
ATH10K_BD_IE_BOARD);
1475
if (ret == -ENOENT)
1476
/* no match found, continue */
1477
break;
1478
1479
/* either found or error, so stop searching */
1480
goto out;
1481
case ATH10K_BD_IE_BOARD_EXT:
1482
ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
1483
boardname,
1484
ATH10K_BD_IE_BOARD_EXT);
1485
if (ret == -ENOENT)
1486
/* no match found, continue */
1487
break;
1488
1489
/* either found or error, so stop searching */
1490
goto out;
1491
}
1492
1493
/* jump over the padding */
1494
ie_len = ALIGN(ie_len, 4);
1495
1496
len -= ie_len;
1497
data += ie_len;
1498
}
1499
1500
out:
1501
/* return result of parse_bd_ie_board() or -ENOENT */
1502
return ret;
1503
}
1504
1505
static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
1506
const char *boardname,
1507
const char *fallback_boardname1,
1508
const char *fallback_boardname2,
1509
const char *filename)
1510
{
1511
size_t len, magic_len;
1512
const u8 *data;
1513
int ret;
1514
1515
/* Skip if already fetched during board data download */
1516
if (!ar->normal_mode_fw.board)
1517
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
1518
ar->hw_params.fw.dir,
1519
filename);
1520
if (IS_ERR(ar->normal_mode_fw.board))
1521
return PTR_ERR(ar->normal_mode_fw.board);
1522
1523
data = ar->normal_mode_fw.board->data;
1524
len = ar->normal_mode_fw.board->size;
1525
1526
/* magic has extra null byte padded */
1527
magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;
1528
if (len < magic_len) {
1529
ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",
1530
ar->hw_params.fw.dir, filename, len);
1531
ret = -EINVAL;
1532
goto err;
1533
}
1534
1535
if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {
1536
ath10k_err(ar, "found invalid board magic\n");
1537
ret = -EINVAL;
1538
goto err;
1539
}
1540
1541
/* magic is padded to 4 bytes */
1542
magic_len = ALIGN(magic_len, 4);
1543
if (len < magic_len) {
1544
ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",
1545
ar->hw_params.fw.dir, filename, len);
1546
ret = -EINVAL;
1547
goto err;
1548
}
1549
1550
data += magic_len;
1551
len -= magic_len;
1552
1553
/* attempt to find boardname in the IE list */
1554
ret = ath10k_core_search_bd(ar, boardname, data, len);
1555
1556
/* if we didn't find it and have a fallback name, try that */
1557
if (ret == -ENOENT && fallback_boardname1)
1558
ret = ath10k_core_search_bd(ar, fallback_boardname1, data, len);
1559
1560
if (ret == -ENOENT && fallback_boardname2)
1561
ret = ath10k_core_search_bd(ar, fallback_boardname2, data, len);
1562
1563
if (ret == -ENOENT) {
1564
ath10k_err(ar,
1565
"failed to fetch board data for %s from %s/%s\n",
1566
boardname, ar->hw_params.fw.dir, filename);
1567
ret = -ENODATA;
1568
}
1569
1570
if (ret)
1571
goto err;
1572
1573
return 0;
1574
1575
err:
1576
ath10k_core_free_board_files(ar);
1577
return ret;
1578
}
1579
1580
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
1581
size_t name_len, bool with_variant,
1582
bool with_chip_id)
1583
{
1584
/* strlen(',variant=') + strlen(ar->id.bdf_ext) */
1585
char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
1586
1587
if (with_variant && ar->id.bdf_ext[0] != '\0')
1588
scnprintf(variant, sizeof(variant), ",variant=%s",
1589
ar->id.bdf_ext);
1590
1591
if (ar->id.bmi_ids_valid) {
1592
scnprintf(name, name_len,
1593
"bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s",
1594
ath10k_bus_str(ar->hif.bus),
1595
ar->id.bmi_chip_id,
1596
ar->id.bmi_board_id, variant);
1597
goto out;
1598
}
1599
1600
if (ar->id.qmi_ids_valid) {
1601
if (with_chip_id)
1602
scnprintf(name, name_len,
1603
"bus=%s,qmi-board-id=%x,qmi-chip-id=%x%s",
1604
ath10k_bus_str(ar->hif.bus),
1605
ar->id.qmi_board_id, ar->id.qmi_chip_id,
1606
variant);
1607
else
1608
scnprintf(name, name_len,
1609
"bus=%s,qmi-board-id=%x",
1610
ath10k_bus_str(ar->hif.bus),
1611
ar->id.qmi_board_id);
1612
goto out;
1613
}
1614
1615
scnprintf(name, name_len,
1616
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
1617
ath10k_bus_str(ar->hif.bus),
1618
ar->id.vendor, ar->id.device,
1619
ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
1620
out:
1621
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
1622
1623
return 0;
1624
}
1625
1626
static int ath10k_core_create_eboard_name(struct ath10k *ar, char *name,
1627
size_t name_len)
1628
{
1629
if (ar->id.bmi_ids_valid) {
1630
scnprintf(name, name_len,
1631
"bus=%s,bmi-chip-id=%d,bmi-eboard-id=%d",
1632
ath10k_bus_str(ar->hif.bus),
1633
ar->id.bmi_chip_id,
1634
ar->id.bmi_eboard_id);
1635
1636
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using eboard name '%s'\n", name);
1637
return 0;
1638
}
1639
/* Fallback if returned board id is zero */
1640
return -1;
1641
}
1642
1643
int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type)
1644
{
1645
char boardname[100], fallback_boardname1[100], fallback_boardname2[100];
1646
int ret;
1647
1648
if (bd_ie_type == ATH10K_BD_IE_BOARD) {
1649
/* With variant and chip id */
1650
ret = ath10k_core_create_board_name(ar, boardname,
1651
sizeof(boardname), true,
1652
true);
1653
if (ret) {
1654
ath10k_err(ar, "failed to create board name: %d", ret);
1655
return ret;
1656
}
1657
1658
/* Without variant and only chip-id */
1659
ret = ath10k_core_create_board_name(ar, fallback_boardname1,
1660
sizeof(boardname), false,
1661
true);
1662
if (ret) {
1663
ath10k_err(ar, "failed to create 1st fallback board name: %d",
1664
ret);
1665
return ret;
1666
}
1667
1668
/* Without variant and without chip-id */
1669
ret = ath10k_core_create_board_name(ar, fallback_boardname2,
1670
sizeof(boardname), false,
1671
false);
1672
if (ret) {
1673
ath10k_err(ar, "failed to create 2nd fallback board name: %d",
1674
ret);
1675
return ret;
1676
}
1677
} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {
1678
ret = ath10k_core_create_eboard_name(ar, boardname,
1679
sizeof(boardname));
1680
if (ret) {
1681
ath10k_err(ar, "fallback to eboard.bin since board id 0");
1682
goto fallback;
1683
}
1684
}
1685
1686
ar->bd_api = 2;
1687
ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
1688
fallback_boardname1,
1689
fallback_boardname2,
1690
ATH10K_BOARD_API2_FILE);
1691
if (!ret)
1692
goto success;
1693
1694
fallback:
1695
ar->bd_api = 1;
1696
ret = ath10k_core_fetch_board_data_api_1(ar, bd_ie_type);
1697
if (ret) {
1698
ath10k_err(ar, "failed to fetch board-2.bin or board.bin from %s\n",
1699
ar->hw_params.fw.dir);
1700
return ret;
1701
}
1702
1703
success:
1704
ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);
1705
return 0;
1706
}
1707
EXPORT_SYMBOL(ath10k_core_fetch_board_file);
1708
1709
static int ath10k_core_get_ext_board_id_from_otp(struct ath10k *ar)
1710
{
1711
u32 result, address;
1712
u8 ext_board_id;
1713
int ret;
1714
1715
address = ar->hw_params.patch_load_addr;
1716
1717
if (!ar->normal_mode_fw.fw_file.otp_data ||
1718
!ar->normal_mode_fw.fw_file.otp_len) {
1719
ath10k_warn(ar,
1720
"failed to retrieve extended board id due to otp binary missing\n");
1721
return -ENODATA;
1722
}
1723
1724
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1725
"boot upload otp to 0x%x len %zd for ext board id\n",
1726
address, ar->normal_mode_fw.fw_file.otp_len);
1727
1728
ret = ath10k_bmi_fast_download(ar, address,
1729
ar->normal_mode_fw.fw_file.otp_data,
1730
ar->normal_mode_fw.fw_file.otp_len);
1731
if (ret) {
1732
ath10k_err(ar, "could not write otp for ext board id check: %d\n",
1733
ret);
1734
return ret;
1735
}
1736
1737
ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EXT_BOARD_ID, &result);
1738
if (ret) {
1739
ath10k_err(ar, "could not execute otp for ext board id check: %d\n",
1740
ret);
1741
return ret;
1742
}
1743
1744
if (!result) {
1745
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1746
"ext board id does not exist in otp, ignore it\n");
1747
return -EOPNOTSUPP;
1748
}
1749
1750
ext_board_id = result & ATH10K_BMI_EBOARD_ID_STATUS_MASK;
1751
1752
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1753
"boot get otp ext board id result 0x%08x ext_board_id %d\n",
1754
result, ext_board_id);
1755
1756
ar->id.bmi_eboard_id = ext_board_id;
1757
1758
return 0;
1759
}
1760
1761
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
1762
size_t data_len)
1763
{
1764
u32 board_data_size = ar->hw_params.fw.board_size;
1765
u32 eboard_data_size = ar->hw_params.fw.ext_board_size;
1766
u32 board_address;
1767
u32 ext_board_address;
1768
int ret;
1769
1770
ret = ath10k_push_board_ext_data(ar, data, data_len);
1771
if (ret) {
1772
ath10k_err(ar, "could not push board ext data (%d)\n", ret);
1773
goto exit;
1774
}
1775
1776
ret = ath10k_bmi_read32(ar, hi_board_data, &board_address);
1777
if (ret) {
1778
ath10k_err(ar, "could not read board data addr (%d)\n", ret);
1779
goto exit;
1780
}
1781
1782
ret = ath10k_bmi_write_memory(ar, board_address, data,
1783
min_t(u32, board_data_size,
1784
data_len));
1785
if (ret) {
1786
ath10k_err(ar, "could not write board data (%d)\n", ret);
1787
goto exit;
1788
}
1789
1790
ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
1791
if (ret) {
1792
ath10k_err(ar, "could not write board data bit (%d)\n", ret);
1793
goto exit;
1794
}
1795
1796
if (!ar->id.ext_bid_supported)
1797
goto exit;
1798
1799
/* Extended board data download */
1800
ret = ath10k_core_get_ext_board_id_from_otp(ar);
1801
if (ret == -EOPNOTSUPP) {
1802
/* Not fetching ext_board_data if ext board id is 0 */
1803
ath10k_dbg(ar, ATH10K_DBG_BOOT, "otp returned ext board id 0\n");
1804
return 0;
1805
} else if (ret) {
1806
ath10k_err(ar, "failed to get extended board id: %d\n", ret);
1807
goto exit;
1808
}
1809
1810
ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD_EXT);
1811
if (ret)
1812
goto exit;
1813
1814
if (ar->normal_mode_fw.ext_board_data) {
1815
ext_board_address = board_address + EXT_BOARD_ADDRESS_OFFSET;
1816
ath10k_dbg(ar, ATH10K_DBG_BOOT,
1817
"boot writing ext board data to addr 0x%x",
1818
ext_board_address);
1819
ret = ath10k_bmi_write_memory(ar, ext_board_address,
1820
ar->normal_mode_fw.ext_board_data,
1821
min_t(u32, eboard_data_size, data_len));
1822
if (ret)
1823
ath10k_err(ar, "failed to write ext board data: %d\n", ret);
1824
}
1825
1826
exit:
1827
return ret;
1828
}
1829
1830
static int ath10k_download_and_run_otp(struct ath10k *ar)
1831
{
1832
u32 result, address = ar->hw_params.patch_load_addr;
1833
u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
1834
int ret;
1835
1836
ret = ath10k_download_board_data(ar,
1837
ar->running_fw->board_data,
1838
ar->running_fw->board_len);
1839
if (ret) {
1840
ath10k_err(ar, "failed to download board data: %d\n", ret);
1841
return ret;
1842
}
1843
1844
/* OTP is optional */
1845
1846
if (!ar->running_fw->fw_file.otp_data ||
1847
!ar->running_fw->fw_file.otp_len) {
1848
ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
1849
ar->running_fw->fw_file.otp_data,
1850
ar->running_fw->fw_file.otp_len);
1851
return 0;
1852
}
1853
1854
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
1855
address, ar->running_fw->fw_file.otp_len);
1856
1857
ret = ath10k_bmi_fast_download(ar, address,
1858
ar->running_fw->fw_file.otp_data,
1859
ar->running_fw->fw_file.otp_len);
1860
if (ret) {
1861
ath10k_err(ar, "could not write otp (%d)\n", ret);
1862
return ret;
1863
}
1864
1865
/* As of now pre-cal is valid for 10_4 variants */
1866
if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
1867
ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
1868
ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
1869
bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
1870
1871
ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
1872
if (ret) {
1873
ath10k_err(ar, "could not execute otp (%d)\n", ret);
1874
return ret;
1875
}
1876
1877
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
1878
1879
if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
1880
ar->running_fw->fw_file.fw_features)) &&
1881
result != 0) {
1882
ath10k_err(ar, "otp calibration failed: %d", result);
1883
return -EINVAL;
1884
}
1885
1886
return 0;
1887
}
1888
1889
static int ath10k_download_cal_file(struct ath10k *ar,
1890
const struct firmware *file)
1891
{
1892
int ret;
1893
1894
if (!file)
1895
return -ENOENT;
1896
1897
if (IS_ERR(file))
1898
return PTR_ERR(file);
1899
1900
ret = ath10k_download_board_data(ar, file->data, file->size);
1901
if (ret) {
1902
ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
1903
return ret;
1904
}
1905
1906
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
1907
1908
return 0;
1909
}
1910
1911
static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)
1912
{
1913
#if defined(__linux__) || (defined(__FreeBSD__) && defined(CONFIG_OF))
1914
struct device_node *node;
1915
int data_len;
1916
void *data;
1917
int ret;
1918
1919
node = ar->dev->of_node;
1920
if (!node)
1921
/* Device Tree is optional, don't print any warnings if
1922
* there's no node for ath10k.
1923
*/
1924
return -ENOENT;
1925
1926
if (!of_get_property(node, dt_name, &data_len)) {
1927
/* The calibration data node is optional */
1928
return -ENOENT;
1929
}
1930
1931
if (data_len != ar->hw_params.cal_data_len) {
1932
ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
1933
data_len);
1934
ret = -EMSGSIZE;
1935
goto out;
1936
}
1937
1938
data = kmalloc(data_len, GFP_KERNEL);
1939
if (!data) {
1940
ret = -ENOMEM;
1941
goto out;
1942
}
1943
1944
ret = of_property_read_u8_array(node, dt_name, data, data_len);
1945
if (ret) {
1946
ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
1947
ret);
1948
goto out_free;
1949
}
1950
1951
ret = ath10k_download_board_data(ar, data, data_len);
1952
if (ret) {
1953
ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
1954
ret);
1955
goto out_free;
1956
}
1957
1958
ret = 0;
1959
1960
out_free:
1961
kfree(data);
1962
1963
out:
1964
return ret;
1965
#else
1966
return -ENOENT;
1967
#endif
1968
}
1969
1970
static int ath10k_download_cal_eeprom(struct ath10k *ar)
1971
{
1972
size_t data_len;
1973
void *data = NULL;
1974
int ret;
1975
1976
ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);
1977
if (ret) {
1978
if (ret != -EOPNOTSUPP)
1979
ath10k_warn(ar, "failed to read calibration data from EEPROM: %d\n",
1980
ret);
1981
goto out_free;
1982
}
1983
1984
ret = ath10k_download_board_data(ar, data, data_len);
1985
if (ret) {
1986
ath10k_warn(ar, "failed to download calibration data from EEPROM: %d\n",
1987
ret);
1988
goto out_free;
1989
}
1990
1991
ret = 0;
1992
1993
out_free:
1994
kfree(data);
1995
1996
return ret;
1997
}
1998
1999
static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
2000
{
2001
#if defined(__linux__)
2002
struct nvmem_cell *cell;
2003
void *buf;
2004
size_t len;
2005
#endif
2006
int ret;
2007
2008
#if defined(__linux__)
2009
cell = devm_nvmem_cell_get(ar->dev, cell_name);
2010
if (IS_ERR(cell)) {
2011
ret = PTR_ERR(cell);
2012
return ret;
2013
}
2014
2015
buf = nvmem_cell_read(cell, &len);
2016
if (IS_ERR(buf))
2017
return PTR_ERR(buf);
2018
2019
if (ar->hw_params.cal_data_len != len) {
2020
kfree(buf);
2021
ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
2022
cell_name, len, ar->hw_params.cal_data_len);
2023
return -EMSGSIZE;
2024
}
2025
2026
ret = ath10k_download_board_data(ar, buf, len);
2027
kfree(buf);
2028
#elif defined(__FreeBSD__)
2029
ret = -ENXIO;
2030
#endif
2031
if (ret)
2032
ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
2033
cell_name, ret);
2034
2035
return ret;
2036
}
2037
2038
int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
2039
struct ath10k_fw_file *fw_file)
2040
{
2041
size_t magic_len, len, ie_len;
2042
int ie_id, i, index, bit, ret;
2043
#if defined(__linux__)
2044
struct ath10k_fw_ie *hdr;
2045
#elif defined(__FreeBSD__)
2046
const struct ath10k_fw_ie *hdr;
2047
#endif
2048
const u8 *data;
2049
#if defined(__linux__)
2050
__le32 *timestamp, *version;
2051
#elif defined(__FreeBSD__)
2052
const __le32 *timestamp, *version;
2053
#endif
2054
2055
/* first fetch the firmware file (firmware-*.bin) */
2056
fw_file->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
2057
name);
2058
if (IS_ERR(fw_file->firmware))
2059
return PTR_ERR(fw_file->firmware);
2060
2061
data = fw_file->firmware->data;
2062
len = fw_file->firmware->size;
2063
2064
/* magic also includes the null byte, check that as well */
2065
magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
2066
2067
if (len < magic_len) {
2068
ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
2069
ar->hw_params.fw.dir, name, len);
2070
ret = -EINVAL;
2071
goto err;
2072
}
2073
2074
if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
2075
ath10k_err(ar, "invalid firmware magic\n");
2076
ret = -EINVAL;
2077
goto err;
2078
}
2079
2080
/* jump over the padding */
2081
magic_len = ALIGN(magic_len, 4);
2082
2083
len -= magic_len;
2084
data += magic_len;
2085
2086
/* loop elements */
2087
while (len > sizeof(struct ath10k_fw_ie)) {
2088
#if defined(__linux__)
2089
hdr = (struct ath10k_fw_ie *)data;
2090
#elif defined(__FreeBSD__)
2091
hdr = (const struct ath10k_fw_ie *)data;
2092
#endif
2093
2094
ie_id = le32_to_cpu(hdr->id);
2095
ie_len = le32_to_cpu(hdr->len);
2096
2097
len -= sizeof(*hdr);
2098
data += sizeof(*hdr);
2099
2100
if (len < ie_len) {
2101
ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
2102
ie_id, len, ie_len);
2103
ret = -EINVAL;
2104
goto err;
2105
}
2106
2107
switch (ie_id) {
2108
case ATH10K_FW_IE_FW_VERSION:
2109
if (ie_len > sizeof(fw_file->fw_version) - 1)
2110
break;
2111
2112
memcpy(fw_file->fw_version, data, ie_len);
2113
fw_file->fw_version[ie_len] = '\0';
2114
2115
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2116
"found fw version %s\n",
2117
fw_file->fw_version);
2118
break;
2119
case ATH10K_FW_IE_TIMESTAMP:
2120
if (ie_len != sizeof(u32))
2121
break;
2122
2123
#if defined(__linux__)
2124
timestamp = (__le32 *)data;
2125
#elif defined(__FreeBSD__)
2126
timestamp = (const __le32 *)data;
2127
#endif
2128
2129
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
2130
le32_to_cpup(timestamp));
2131
break;
2132
case ATH10K_FW_IE_FEATURES:
2133
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2134
"found firmware features ie (%zd B)\n",
2135
ie_len);
2136
2137
for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
2138
index = i / 8;
2139
bit = i % 8;
2140
2141
if (index == ie_len)
2142
break;
2143
2144
if (data[index] & (1 << bit)) {
2145
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2146
"Enabling feature bit: %i\n",
2147
i);
2148
__set_bit(i, fw_file->fw_features);
2149
}
2150
}
2151
2152
ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
2153
fw_file->fw_features,
2154
sizeof(fw_file->fw_features));
2155
break;
2156
case ATH10K_FW_IE_FW_IMAGE:
2157
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2158
"found fw image ie (%zd B)\n",
2159
ie_len);
2160
2161
fw_file->firmware_data = data;
2162
fw_file->firmware_len = ie_len;
2163
2164
break;
2165
case ATH10K_FW_IE_OTP_IMAGE:
2166
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2167
"found otp image ie (%zd B)\n",
2168
ie_len);
2169
2170
fw_file->otp_data = data;
2171
fw_file->otp_len = ie_len;
2172
2173
break;
2174
case ATH10K_FW_IE_WMI_OP_VERSION:
2175
if (ie_len != sizeof(u32))
2176
break;
2177
2178
#if defined(__linux__)
2179
version = (__le32 *)data;
2180
#elif defined(__FreeBSD__)
2181
version = (const __le32 *)data;
2182
#endif
2183
2184
fw_file->wmi_op_version = le32_to_cpup(version);
2185
2186
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
2187
fw_file->wmi_op_version);
2188
break;
2189
case ATH10K_FW_IE_HTT_OP_VERSION:
2190
if (ie_len != sizeof(u32))
2191
break;
2192
2193
#if defined(__linux__)
2194
version = (__le32 *)data;
2195
#elif defined(__FreeBSD__)
2196
version = (const __le32 *)data;
2197
#endif
2198
2199
fw_file->htt_op_version = le32_to_cpup(version);
2200
2201
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
2202
fw_file->htt_op_version);
2203
break;
2204
case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
2205
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2206
"found fw code swap image ie (%zd B)\n",
2207
ie_len);
2208
fw_file->codeswap_data = data;
2209
fw_file->codeswap_len = ie_len;
2210
break;
2211
default:
2212
ath10k_warn(ar, "Unknown FW IE: %u\n",
2213
le32_to_cpu(hdr->id));
2214
break;
2215
}
2216
2217
/* jump over the padding */
2218
ie_len = ALIGN(ie_len, 4);
2219
2220
len -= ie_len;
2221
data += ie_len;
2222
}
2223
2224
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, fw_file->fw_features) &&
2225
(!fw_file->firmware_data || !fw_file->firmware_len)) {
2226
ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
2227
ar->hw_params.fw.dir, name);
2228
ret = -ENOMEDIUM;
2229
goto err;
2230
}
2231
2232
return 0;
2233
2234
err:
2235
ath10k_core_free_firmware_files(ar);
2236
return ret;
2237
}
2238
2239
static void ath10k_core_get_fw_name(struct ath10k *ar, char *fw_name,
2240
size_t fw_name_len, int fw_api)
2241
{
2242
switch (ar->hif.bus) {
2243
case ATH10K_BUS_SDIO:
2244
case ATH10K_BUS_USB:
2245
scnprintf(fw_name, fw_name_len, "%s-%s-%d.bin",
2246
ATH10K_FW_FILE_BASE, ath10k_bus_str(ar->hif.bus),
2247
fw_api);
2248
break;
2249
case ATH10K_BUS_PCI:
2250
case ATH10K_BUS_AHB:
2251
case ATH10K_BUS_SNOC:
2252
scnprintf(fw_name, fw_name_len, "%s-%d.bin",
2253
ATH10K_FW_FILE_BASE, fw_api);
2254
break;
2255
}
2256
}
2257
2258
static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
2259
{
2260
int ret, i;
2261
char fw_name[100];
2262
2263
/* calibration file is optional, don't check for any errors */
2264
ath10k_fetch_cal_file(ar);
2265
2266
for (i = ATH10K_FW_API_MAX; i >= ATH10K_FW_API_MIN; i--) {
2267
ar->fw_api = i;
2268
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n",
2269
ar->fw_api);
2270
2271
ath10k_core_get_fw_name(ar, fw_name, sizeof(fw_name), ar->fw_api);
2272
ret = ath10k_core_fetch_firmware_api_n(ar, fw_name,
2273
&ar->normal_mode_fw.fw_file);
2274
if (!ret)
2275
goto success;
2276
}
2277
2278
/* we end up here if we couldn't fetch any firmware */
2279
2280
ath10k_err(ar, "Failed to find firmware-N.bin (N between %d and %d) from %s: %d",
2281
ATH10K_FW_API_MIN, ATH10K_FW_API_MAX, ar->hw_params.fw.dir,
2282
ret);
2283
2284
return ret;
2285
2286
success:
2287
ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
2288
2289
return 0;
2290
}
2291
2292
static int ath10k_core_pre_cal_download(struct ath10k *ar)
2293
{
2294
int ret;
2295
2296
ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
2297
if (ret == 0) {
2298
ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
2299
goto success;
2300
} else if (ret == -EPROBE_DEFER) {
2301
return ret;
2302
}
2303
2304
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2305
"boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
2306
ret);
2307
2308
ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
2309
if (ret == 0) {
2310
ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
2311
goto success;
2312
}
2313
2314
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2315
"boot did not find a pre calibration file, try DT next: %d\n",
2316
ret);
2317
2318
ret = ath10k_download_cal_dt(ar, "qcom,ath10k-pre-calibration-data");
2319
if (ret) {
2320
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2321
"unable to load pre cal data from DT: %d\n", ret);
2322
return ret;
2323
}
2324
ar->cal_mode = ATH10K_PRE_CAL_MODE_DT;
2325
2326
success:
2327
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
2328
ath10k_cal_mode_str(ar->cal_mode));
2329
2330
return 0;
2331
}
2332
2333
static int ath10k_core_pre_cal_config(struct ath10k *ar)
2334
{
2335
int ret;
2336
2337
ret = ath10k_core_pre_cal_download(ar);
2338
if (ret) {
2339
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2340
"failed to load pre cal data: %d\n", ret);
2341
return ret;
2342
}
2343
2344
ret = ath10k_core_get_board_id_from_otp(ar);
2345
if (ret) {
2346
ath10k_err(ar, "failed to get board id: %d\n", ret);
2347
return ret;
2348
}
2349
2350
ret = ath10k_download_and_run_otp(ar);
2351
if (ret) {
2352
ath10k_err(ar, "failed to run otp: %d\n", ret);
2353
return ret;
2354
}
2355
2356
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2357
"pre cal configuration done successfully\n");
2358
2359
return 0;
2360
}
2361
2362
static int ath10k_download_cal_data(struct ath10k *ar)
2363
{
2364
int ret;
2365
2366
ret = ath10k_core_pre_cal_config(ar);
2367
if (ret == 0)
2368
return 0;
2369
2370
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2371
"pre cal download procedure failed, try cal file: %d\n",
2372
ret);
2373
2374
ret = ath10k_download_cal_nvmem(ar, "calibration");
2375
if (ret == 0) {
2376
ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
2377
goto done;
2378
} else if (ret == -EPROBE_DEFER) {
2379
return ret;
2380
}
2381
2382
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2383
"boot did not find a calibration nvmem-cell, try file next: %d\n",
2384
ret);
2385
2386
ret = ath10k_download_cal_file(ar, ar->cal_file);
2387
if (ret == 0) {
2388
ar->cal_mode = ATH10K_CAL_MODE_FILE;
2389
goto done;
2390
}
2391
2392
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2393
"boot did not find a calibration file, try DT next: %d\n",
2394
ret);
2395
2396
ret = ath10k_download_cal_dt(ar, "qcom,ath10k-calibration-data");
2397
if (ret == 0) {
2398
ar->cal_mode = ATH10K_CAL_MODE_DT;
2399
goto done;
2400
}
2401
2402
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2403
"boot did not find DT entry, try target EEPROM next: %d\n",
2404
ret);
2405
2406
ret = ath10k_download_cal_eeprom(ar);
2407
if (ret == 0) {
2408
ar->cal_mode = ATH10K_CAL_MODE_EEPROM;
2409
goto done;
2410
}
2411
2412
ath10k_dbg(ar, ATH10K_DBG_BOOT,
2413
"boot did not find target EEPROM entry, try OTP next: %d\n",
2414
ret);
2415
2416
ret = ath10k_download_and_run_otp(ar);
2417
if (ret) {
2418
ath10k_err(ar, "failed to run otp: %d\n", ret);
2419
return ret;
2420
}
2421
2422
ar->cal_mode = ATH10K_CAL_MODE_OTP;
2423
2424
done:
2425
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
2426
ath10k_cal_mode_str(ar->cal_mode));
2427
return 0;
2428
}
2429
2430
static void ath10k_core_fetch_btcoex_dt(struct ath10k *ar)
2431
{
2432
#if defined(__linux__) || (defined(__FreeBSD__) && defined(CONFIG_OF))
2433
struct device_node *node;
2434
u8 coex_support = 0;
2435
int ret;
2436
2437
node = ar->dev->of_node;
2438
if (!node)
2439
goto out;
2440
2441
ret = of_property_read_u8(node, "qcom,coexist-support", &coex_support);
2442
if (ret) {
2443
ar->coex_support = true;
2444
goto out;
2445
}
2446
2447
if (coex_support) {
2448
ar->coex_support = true;
2449
} else {
2450
ar->coex_support = false;
2451
ar->coex_gpio_pin = -1;
2452
goto out;
2453
}
2454
2455
ret = of_property_read_u32(node, "qcom,coexist-gpio-pin",
2456
&ar->coex_gpio_pin);
2457
if (ret)
2458
ar->coex_gpio_pin = -1;
2459
2460
out:
2461
#endif
2462
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot coex_support %d coex_gpio_pin %d\n",
2463
ar->coex_support, ar->coex_gpio_pin);
2464
}
2465
2466
static int ath10k_init_uart(struct ath10k *ar)
2467
{
2468
int ret;
2469
2470
/*
2471
* Explicitly setting UART prints to zero as target turns it on
2472
* based on scratch registers.
2473
*/
2474
ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
2475
if (ret) {
2476
ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
2477
return ret;
2478
}
2479
2480
if (!uart_print) {
2481
if (ar->hw_params.uart_pin_workaround) {
2482
ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin,
2483
ar->hw_params.uart_pin);
2484
if (ret) {
2485
ath10k_warn(ar, "failed to set UART TX pin: %d",
2486
ret);
2487
return ret;
2488
}
2489
}
2490
2491
return 0;
2492
}
2493
2494
ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
2495
if (ret) {
2496
ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
2497
return ret;
2498
}
2499
2500
ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
2501
if (ret) {
2502
ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
2503
return ret;
2504
}
2505
2506
/* Set the UART baud rate to 19200. */
2507
ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
2508
if (ret) {
2509
ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
2510
return ret;
2511
}
2512
2513
ath10k_info(ar, "UART prints enabled\n");
2514
return 0;
2515
}
2516
2517
static int ath10k_init_hw_params(struct ath10k *ar)
2518
{
2519
const struct ath10k_hw_params *hw_params;
2520
int i;
2521
2522
for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
2523
hw_params = &ath10k_hw_params_list[i];
2524
2525
if (hw_params->bus == ar->hif.bus &&
2526
hw_params->id == ar->target_version &&
2527
hw_params->dev_id == ar->dev_id)
2528
break;
2529
}
2530
2531
if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
2532
ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
2533
ar->target_version);
2534
return -EINVAL;
2535
}
2536
2537
ar->hw_params = *hw_params;
2538
2539
ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
2540
ar->hw_params.name, ar->target_version);
2541
2542
return 0;
2543
}
2544
2545
void ath10k_core_start_recovery(struct ath10k *ar)
2546
{
2547
if (test_and_set_bit(ATH10K_FLAG_RESTARTING, &ar->dev_flags)) {
2548
ath10k_warn(ar, "already restarting\n");
2549
return;
2550
}
2551
2552
queue_work(ar->workqueue, &ar->restart_work);
2553
}
2554
EXPORT_SYMBOL(ath10k_core_start_recovery);
2555
2556
void ath10k_core_napi_enable(struct ath10k *ar)
2557
{
2558
lockdep_assert_held(&ar->conf_mutex);
2559
2560
if (test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags))
2561
return;
2562
2563
napi_enable(&ar->napi);
2564
set_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags);
2565
}
2566
EXPORT_SYMBOL(ath10k_core_napi_enable);
2567
2568
void ath10k_core_napi_sync_disable(struct ath10k *ar)
2569
{
2570
lockdep_assert_held(&ar->conf_mutex);
2571
2572
if (!test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags))
2573
return;
2574
2575
napi_synchronize(&ar->napi);
2576
napi_disable(&ar->napi);
2577
clear_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags);
2578
}
2579
EXPORT_SYMBOL(ath10k_core_napi_sync_disable);
2580
2581
static void ath10k_core_restart(struct work_struct *work)
2582
{
2583
struct ath10k *ar = container_of(work, struct ath10k, restart_work);
2584
int ret;
2585
2586
set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
2587
2588
/* Place a barrier to make sure the compiler doesn't reorder
2589
* CRASH_FLUSH and calling other functions.
2590
*/
2591
barrier();
2592
2593
ieee80211_stop_queues(ar->hw);
2594
ath10k_drain_tx(ar);
2595
complete(&ar->scan.started);
2596
complete(&ar->scan.completed);
2597
complete(&ar->scan.on_channel);
2598
complete(&ar->offchan_tx_completed);
2599
complete(&ar->install_key_done);
2600
complete(&ar->vdev_setup_done);
2601
complete(&ar->vdev_delete_done);
2602
complete(&ar->thermal.wmi_sync);
2603
complete(&ar->bss_survey_done);
2604
wake_up(&ar->htt.empty_tx_wq);
2605
wake_up(&ar->wmi.tx_credits_wq);
2606
wake_up(&ar->peer_mapping_wq);
2607
2608
/* TODO: We can have one instance of cancelling coverage_class_work by
2609
* moving it to ath10k_halt(), so that both stop() and restart() would
2610
* call that but it takes conf_mutex() and if we call cancel_work_sync()
2611
* with conf_mutex it will deadlock.
2612
*/
2613
cancel_work_sync(&ar->set_coverage_class_work);
2614
2615
mutex_lock(&ar->conf_mutex);
2616
2617
switch (ar->state) {
2618
case ATH10K_STATE_ON:
2619
ar->state = ATH10K_STATE_RESTARTING;
2620
ath10k_halt(ar);
2621
ath10k_scan_finish(ar);
2622
ieee80211_restart_hw(ar->hw);
2623
break;
2624
case ATH10K_STATE_OFF:
2625
/* this can happen if driver is being unloaded
2626
* or if the crash happens during FW probing
2627
*/
2628
ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
2629
break;
2630
case ATH10K_STATE_RESTARTING:
2631
/* hw restart might be requested from multiple places */
2632
break;
2633
case ATH10K_STATE_RESTARTED:
2634
ar->state = ATH10K_STATE_WEDGED;
2635
fallthrough;
2636
case ATH10K_STATE_WEDGED:
2637
ath10k_warn(ar, "device is wedged, will not restart\n");
2638
break;
2639
case ATH10K_STATE_UTF:
2640
ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
2641
break;
2642
}
2643
2644
mutex_unlock(&ar->conf_mutex);
2645
2646
ret = ath10k_coredump_submit(ar);
2647
if (ret)
2648
ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d",
2649
ret);
2650
2651
complete(&ar->driver_recovery);
2652
}
2653
2654
static void ath10k_core_set_coverage_class_work(struct work_struct *work)
2655
{
2656
struct ath10k *ar = container_of(work, struct ath10k,
2657
set_coverage_class_work);
2658
2659
if (ar->hw_params.hw_ops->set_coverage_class)
2660
ar->hw_params.hw_ops->set_coverage_class(ar, -1);
2661
}
2662
2663
static int ath10k_core_init_firmware_features(struct ath10k *ar)
2664
{
2665
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
2666
int max_num_peers;
2667
2668
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
2669
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
2670
ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
2671
return -EINVAL;
2672
}
2673
2674
if (fw_file->wmi_op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
2675
ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
2676
ATH10K_FW_WMI_OP_VERSION_MAX, fw_file->wmi_op_version);
2677
return -EINVAL;
2678
}
2679
2680
ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
2681
switch (ath10k_cryptmode_param) {
2682
case ATH10K_CRYPT_MODE_HW:
2683
clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
2684
clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
2685
break;
2686
case ATH10K_CRYPT_MODE_SW:
2687
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
2688
fw_file->fw_features)) {
2689
ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");
2690
return -EINVAL;
2691
}
2692
2693
set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
2694
set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
2695
break;
2696
default:
2697
ath10k_info(ar, "invalid cryptmode: %d\n",
2698
ath10k_cryptmode_param);
2699
return -EINVAL;
2700
}
2701
2702
ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
2703
ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
2704
2705
if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
2706
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
2707
fw_file->fw_features)) {
2708
ath10k_err(ar, "rawmode = 1 requires support from firmware");
2709
return -EINVAL;
2710
}
2711
set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
2712
}
2713
2714
if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
2715
ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;
2716
2717
/* Workaround:
2718
*
2719
* Firmware A-MSDU aggregation breaks with RAW Tx encap mode
2720
* and causes enormous performance issues (malformed frames,
2721
* etc).
2722
*
2723
* Disabling A-MSDU makes RAW mode stable with heavy traffic
2724
* albeit a bit slower compared to regular operation.
2725
*/
2726
ar->htt.max_num_amsdu = 1;
2727
}
2728
2729
/* Backwards compatibility for firmwares without
2730
* ATH10K_FW_IE_WMI_OP_VERSION.
2731
*/
2732
if (fw_file->wmi_op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
2733
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
2734
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
2735
fw_file->fw_features))
2736
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
2737
else
2738
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
2739
} else {
2740
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
2741
}
2742
}
2743
2744
switch (fw_file->wmi_op_version) {
2745
case ATH10K_FW_WMI_OP_VERSION_MAIN:
2746
max_num_peers = TARGET_NUM_PEERS;
2747
ar->max_num_stations = TARGET_NUM_STATIONS;
2748
ar->max_num_vdevs = TARGET_NUM_VDEVS;
2749
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
2750
ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
2751
WMI_STAT_PEER;
2752
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
2753
break;
2754
case ATH10K_FW_WMI_OP_VERSION_10_1:
2755
case ATH10K_FW_WMI_OP_VERSION_10_2:
2756
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
2757
if (ath10k_peer_stats_enabled(ar)) {
2758
max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
2759
ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
2760
} else {
2761
max_num_peers = TARGET_10X_NUM_PEERS;
2762
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
2763
}
2764
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
2765
ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
2766
ar->fw_stats_req_mask = WMI_STAT_PEER;
2767
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
2768
#if defined(CONFIG_FWLOG)
2769
ar->fwlog_max_moduleid = ATH10K_FWLOG_MODULE_ID_MAX_10_2_4;
2770
#endif
2771
break;
2772
case ATH10K_FW_WMI_OP_VERSION_TLV:
2773
max_num_peers = TARGET_TLV_NUM_PEERS;
2774
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
2775
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
2776
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
2777
if (ar->hif.bus == ATH10K_BUS_SDIO)
2778
ar->htt.max_num_pending_tx =
2779
TARGET_TLV_NUM_MSDU_DESC_HL;
2780
else
2781
ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
2782
ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
2783
ar->fw_stats_req_mask = WMI_TLV_STAT_PDEV | WMI_TLV_STAT_VDEV |
2784
WMI_TLV_STAT_PEER | WMI_TLV_STAT_PEER_EXTD;
2785
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
2786
ar->wmi.mgmt_max_num_pending_tx = TARGET_TLV_MGMT_NUM_MSDU_DESC;
2787
break;
2788
case ATH10K_FW_WMI_OP_VERSION_10_4:
2789
max_num_peers = TARGET_10_4_NUM_PEERS;
2790
ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
2791
ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
2792
ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
2793
ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;
2794
ar->fw_stats_req_mask = WMI_10_4_STAT_PEER |
2795
WMI_10_4_STAT_PEER_EXTD |
2796
WMI_10_4_STAT_VDEV_EXTD;
2797
ar->max_spatial_stream = ar->hw_params.max_spatial_stream;
2798
ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS;
2799
2800
if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
2801
fw_file->fw_features))
2802
ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC_PFC;
2803
else
2804
ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC;
2805
break;
2806
case ATH10K_FW_WMI_OP_VERSION_UNSET:
2807
case ATH10K_FW_WMI_OP_VERSION_MAX:
2808
default:
2809
WARN_ON(1);
2810
return -EINVAL;
2811
}
2812
2813
if (ar->hw_params.num_peers)
2814
ar->max_num_peers = ar->hw_params.num_peers;
2815
else
2816
ar->max_num_peers = max_num_peers;
2817
2818
/* Backwards compatibility for firmwares without
2819
* ATH10K_FW_IE_HTT_OP_VERSION.
2820
*/
2821
if (fw_file->htt_op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
2822
switch (fw_file->wmi_op_version) {
2823
case ATH10K_FW_WMI_OP_VERSION_MAIN:
2824
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
2825
break;
2826
case ATH10K_FW_WMI_OP_VERSION_10_1:
2827
case ATH10K_FW_WMI_OP_VERSION_10_2:
2828
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
2829
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
2830
break;
2831
case ATH10K_FW_WMI_OP_VERSION_TLV:
2832
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
2833
break;
2834
case ATH10K_FW_WMI_OP_VERSION_10_4:
2835
case ATH10K_FW_WMI_OP_VERSION_UNSET:
2836
case ATH10K_FW_WMI_OP_VERSION_MAX:
2837
ath10k_err(ar, "htt op version not found from fw meta data");
2838
return -EINVAL;
2839
}
2840
}
2841
2842
return 0;
2843
}
2844
2845
static int ath10k_core_reset_rx_filter(struct ath10k *ar)
2846
{
2847
int ret;
2848
int vdev_id;
2849
int vdev_type;
2850
int vdev_subtype;
2851
const u8 *vdev_addr;
2852
2853
vdev_id = 0;
2854
vdev_type = WMI_VDEV_TYPE_STA;
2855
vdev_subtype = ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
2856
vdev_addr = ar->mac_addr;
2857
2858
ret = ath10k_wmi_vdev_create(ar, vdev_id, vdev_type, vdev_subtype,
2859
vdev_addr);
2860
if (ret) {
2861
ath10k_err(ar, "failed to create dummy vdev: %d\n", ret);
2862
return ret;
2863
}
2864
2865
ret = ath10k_wmi_vdev_delete(ar, vdev_id);
2866
if (ret) {
2867
ath10k_err(ar, "failed to delete dummy vdev: %d\n", ret);
2868
return ret;
2869
}
2870
2871
/* WMI and HTT may use separate HIF pipes and are not guaranteed to be
2872
* serialized properly implicitly.
2873
*
2874
* Moreover (most) WMI commands have no explicit acknowledges. It is
2875
* possible to infer it implicitly by poking firmware with echo
2876
* command - getting a reply means all preceding comments have been
2877
* (mostly) processed.
2878
*
2879
* In case of vdev create/delete this is sufficient.
2880
*
2881
* Without this it's possible to end up with a race when HTT Rx ring is
2882
* started before vdev create/delete hack is complete allowing a short
2883
* window of opportunity to receive (and Tx ACK) a bunch of frames.
2884
*/
2885
ret = ath10k_wmi_barrier(ar);
2886
if (ret) {
2887
ath10k_err(ar, "failed to ping firmware: %d\n", ret);
2888
return ret;
2889
}
2890
2891
return 0;
2892
}
2893
2894
static int ath10k_core_compat_services(struct ath10k *ar)
2895
{
2896
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
2897
2898
/* all 10.x firmware versions support thermal throttling but don't
2899
* advertise the support via service flags so we have to hardcode
2900
* it here
2901
*/
2902
switch (fw_file->wmi_op_version) {
2903
case ATH10K_FW_WMI_OP_VERSION_10_1:
2904
case ATH10K_FW_WMI_OP_VERSION_10_2:
2905
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
2906
case ATH10K_FW_WMI_OP_VERSION_10_4:
2907
set_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map);
2908
break;
2909
default:
2910
break;
2911
}
2912
2913
return 0;
2914
}
2915
2916
#define TGT_IRAM_READ_PER_ITR (8 * 1024)
2917
2918
static int ath10k_core_copy_target_iram(struct ath10k *ar)
2919
{
2920
const struct ath10k_hw_mem_layout *hw_mem;
2921
const struct ath10k_mem_region *tmp, *mem_region = NULL;
2922
dma_addr_t paddr;
2923
void *vaddr = NULL;
2924
u8 num_read_itr;
2925
int i, ret;
2926
u32 len, remaining_len;
2927
2928
/* copy target iram feature must work also when
2929
* ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so
2930
* _ath10k_coredump_get_mem_layout() to accomplist that
2931
*/
2932
hw_mem = _ath10k_coredump_get_mem_layout(ar);
2933
if (!hw_mem)
2934
/* if CONFIG_DEV_COREDUMP is disabled we get NULL, then
2935
* just silently disable the feature by doing nothing
2936
*/
2937
return 0;
2938
2939
for (i = 0; i < hw_mem->region_table.size; i++) {
2940
tmp = &hw_mem->region_table.regions[i];
2941
if (tmp->type == ATH10K_MEM_REGION_TYPE_REG) {
2942
mem_region = tmp;
2943
break;
2944
}
2945
}
2946
2947
if (!mem_region)
2948
return -ENOMEM;
2949
2950
for (i = 0; i < ar->wmi.num_mem_chunks; i++) {
2951
if (ar->wmi.mem_chunks[i].req_id ==
2952
WMI_IRAM_RECOVERY_HOST_MEM_REQ_ID) {
2953
vaddr = ar->wmi.mem_chunks[i].vaddr;
2954
len = ar->wmi.mem_chunks[i].len;
2955
break;
2956
}
2957
}
2958
2959
if (!vaddr || !len) {
2960
ath10k_warn(ar, "No allocated memory for IRAM back up");
2961
return -ENOMEM;
2962
}
2963
2964
len = (len < mem_region->len) ? len : mem_region->len;
2965
paddr = mem_region->start;
2966
num_read_itr = len / TGT_IRAM_READ_PER_ITR;
2967
remaining_len = len % TGT_IRAM_READ_PER_ITR;
2968
for (i = 0; i < num_read_itr; i++) {
2969
ret = ath10k_hif_diag_read(ar, paddr, vaddr,
2970
TGT_IRAM_READ_PER_ITR);
2971
if (ret) {
2972
ath10k_warn(ar, "failed to copy firmware IRAM contents: %d",
2973
ret);
2974
return ret;
2975
}
2976
2977
paddr += TGT_IRAM_READ_PER_ITR;
2978
#if defined(__linux__)
2979
vaddr += TGT_IRAM_READ_PER_ITR;
2980
#elif defined(__FreeBSD__)
2981
vaddr = (void *)((uintptr_t)vaddr + TGT_IRAM_READ_PER_ITR);
2982
#endif
2983
}
2984
2985
if (remaining_len) {
2986
ret = ath10k_hif_diag_read(ar, paddr, vaddr, remaining_len);
2987
if (ret) {
2988
ath10k_warn(ar, "failed to copy firmware IRAM contents: %d",
2989
ret);
2990
return ret;
2991
}
2992
}
2993
2994
ath10k_dbg(ar, ATH10K_DBG_BOOT, "target IRAM back up completed\n");
2995
2996
return 0;
2997
}
2998
2999
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
3000
const struct ath10k_fw_components *fw)
3001
{
3002
int status;
3003
u32 val;
3004
3005
lockdep_assert_held(&ar->conf_mutex);
3006
3007
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
3008
3009
ar->running_fw = fw;
3010
3011
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
3012
ar->running_fw->fw_file.fw_features)) {
3013
ath10k_bmi_start(ar);
3014
3015
/* Enable hardware clock to speed up firmware download */
3016
if (ar->hw_params.hw_ops->enable_pll_clk) {
3017
status = ar->hw_params.hw_ops->enable_pll_clk(ar);
3018
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot enable pll ret %d\n",
3019
status);
3020
}
3021
3022
if (ath10k_init_configure_target(ar)) {
3023
status = -EINVAL;
3024
goto err;
3025
}
3026
3027
status = ath10k_download_cal_data(ar);
3028
if (status)
3029
goto err;
3030
3031
/* Some of qca988x solutions are having global reset issue
3032
* during target initialization. Bypassing PLL setting before
3033
* downloading firmware and letting the SoC run on REF_CLK is
3034
* fixing the problem. Corresponding firmware change is also
3035
* needed to set the clock source once the target is
3036
* initialized.
3037
*/
3038
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
3039
ar->running_fw->fw_file.fw_features)) {
3040
status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
3041
if (status) {
3042
ath10k_err(ar, "could not write to skip_clock_init: %d\n",
3043
status);
3044
goto err;
3045
}
3046
}
3047
3048
status = ath10k_download_fw(ar);
3049
if (status)
3050
goto err;
3051
3052
status = ath10k_init_uart(ar);
3053
if (status)
3054
goto err;
3055
3056
if (ar->hif.bus == ATH10K_BUS_SDIO) {
3057
status = ath10k_init_sdio(ar, mode);
3058
if (status) {
3059
ath10k_err(ar, "failed to init SDIO: %d\n", status);
3060
goto err;
3061
}
3062
}
3063
}
3064
3065
ar->htc.htc_ops.target_send_suspend_complete =
3066
ath10k_send_suspend_complete;
3067
3068
status = ath10k_htc_init(ar);
3069
if (status) {
3070
ath10k_err(ar, "could not init HTC (%d)\n", status);
3071
goto err;
3072
}
3073
3074
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
3075
ar->running_fw->fw_file.fw_features)) {
3076
status = ath10k_bmi_done(ar);
3077
if (status)
3078
goto err;
3079
}
3080
3081
status = ath10k_wmi_attach(ar);
3082
if (status) {
3083
ath10k_err(ar, "WMI attach failed: %d\n", status);
3084
goto err;
3085
}
3086
3087
status = ath10k_htt_init(ar);
3088
if (status) {
3089
ath10k_err(ar, "failed to init htt: %d\n", status);
3090
goto err_wmi_detach;
3091
}
3092
3093
status = ath10k_htt_tx_start(&ar->htt);
3094
if (status) {
3095
ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
3096
goto err_wmi_detach;
3097
}
3098
3099
/* If firmware indicates Full Rx Reorder support it must be used in a
3100
* slightly different manner. Let HTT code know.
3101
*/
3102
ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,
3103
ar->wmi.svc_map));
3104
3105
status = ath10k_htt_rx_alloc(&ar->htt);
3106
if (status) {
3107
ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
3108
goto err_htt_tx_detach;
3109
}
3110
3111
status = ath10k_hif_start(ar);
3112
if (status) {
3113
ath10k_err(ar, "could not start HIF: %d\n", status);
3114
goto err_htt_rx_detach;
3115
}
3116
3117
status = ath10k_htc_wait_target(&ar->htc);
3118
if (status) {
3119
ath10k_err(ar, "failed to connect to HTC: %d\n", status);
3120
goto err_hif_stop;
3121
}
3122
3123
status = ath10k_hif_start_post(ar);
3124
if (status) {
3125
ath10k_err(ar, "failed to swap mailbox: %d\n", status);
3126
goto err_hif_stop;
3127
}
3128
3129
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
3130
status = ath10k_htt_connect(&ar->htt);
3131
if (status) {
3132
ath10k_err(ar, "failed to connect htt (%d)\n", status);
3133
goto err_hif_stop;
3134
}
3135
}
3136
3137
status = ath10k_wmi_connect(ar);
3138
if (status) {
3139
ath10k_err(ar, "could not connect wmi: %d\n", status);
3140
goto err_hif_stop;
3141
}
3142
3143
status = ath10k_htc_start(&ar->htc);
3144
if (status) {
3145
ath10k_err(ar, "failed to start htc: %d\n", status);
3146
goto err_hif_stop;
3147
}
3148
3149
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
3150
status = ath10k_wmi_wait_for_service_ready(ar);
3151
if (status) {
3152
ath10k_warn(ar, "wmi service ready event not received");
3153
goto err_hif_stop;
3154
}
3155
}
3156
3157
ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
3158
ar->hw->wiphy->fw_version);
3159
3160
if (test_bit(ATH10K_FW_FEATURE_IRAM_RECOVERY,
3161
ar->running_fw->fw_file.fw_features)) {
3162
status = ath10k_core_copy_target_iram(ar);
3163
if (status) {
3164
ath10k_warn(ar, "failed to copy target iram contents: %d",
3165
status);
3166
goto err_hif_stop;
3167
}
3168
}
3169
3170
if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&
3171
mode == ATH10K_FIRMWARE_MODE_NORMAL) {
3172
val = 0;
3173
if (ath10k_peer_stats_enabled(ar))
3174
val = WMI_10_4_PEER_STATS;
3175
3176
/* Enable vdev stats by default */
3177
val |= WMI_10_4_VDEV_STATS;
3178
3179
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
3180
val |= WMI_10_4_BSS_CHANNEL_INFO_64;
3181
3182
ath10k_core_fetch_btcoex_dt(ar);
3183
3184
/* 10.4 firmware supports BT-Coex without reloading firmware
3185
* via pdev param. To support Bluetooth coexistence pdev param,
3186
* WMI_COEX_GPIO_SUPPORT of extended resource config should be
3187
* enabled always.
3188
*
3189
* We can still enable BTCOEX if firmware has the support
3190
* even though btceox_support value is
3191
* ATH10K_DT_BTCOEX_NOT_FOUND
3192
*/
3193
3194
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
3195
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
3196
ar->running_fw->fw_file.fw_features) &&
3197
ar->coex_support)
3198
val |= WMI_10_4_COEX_GPIO_SUPPORT;
3199
3200
if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
3201
ar->wmi.svc_map))
3202
val |= WMI_10_4_TDLS_EXPLICIT_MODE_ONLY;
3203
3204
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,
3205
ar->wmi.svc_map))
3206
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
3207
3208
if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI,
3209
ar->wmi.svc_map))
3210
val |= WMI_10_4_TX_DATA_ACK_RSSI;
3211
3212
if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))
3213
val |= WMI_10_4_REPORT_AIRTIME;
3214
3215
if (test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,
3216
ar->wmi.svc_map))
3217
val |= WMI_10_4_EXT_PEER_TID_CONFIGS_SUPPORT;
3218
3219
status = ath10k_mac_ext_resource_config(ar, val);
3220
if (status) {
3221
ath10k_err(ar,
3222
"failed to send ext resource cfg command : %d\n",
3223
status);
3224
goto err_hif_stop;
3225
}
3226
}
3227
3228
status = ath10k_wmi_cmd_init(ar);
3229
if (status) {
3230
ath10k_err(ar, "could not send WMI init command (%d)\n",
3231
status);
3232
goto err_hif_stop;
3233
}
3234
3235
status = ath10k_wmi_wait_for_unified_ready(ar);
3236
if (status) {
3237
ath10k_err(ar, "wmi unified ready event not received\n");
3238
goto err_hif_stop;
3239
}
3240
3241
status = ath10k_core_compat_services(ar);
3242
if (status) {
3243
ath10k_err(ar, "compat services failed: %d\n", status);
3244
goto err_hif_stop;
3245
}
3246
3247
status = ath10k_wmi_pdev_set_base_macaddr(ar, ar->mac_addr);
3248
if (status && status != -EOPNOTSUPP) {
3249
ath10k_err(ar,
3250
"failed to set base mac address: %d\n", status);
3251
goto err_hif_stop;
3252
}
3253
3254
/* Some firmware revisions do not properly set up hardware rx filter
3255
* registers.
3256
*
3257
* A known example from QCA9880 and 10.2.4 is that MAC_PCU_ADDR1_MASK
3258
* is filled with 0s instead of 1s allowing HW to respond with ACKs to
3259
* any frames that matches MAC_PCU_RX_FILTER which is also
3260
* misconfigured to accept anything.
3261
*
3262
* The ADDR1 is programmed using internal firmware structure field and
3263
* can't be (easily/sanely) reached from the driver explicitly. It is
3264
* possible to implicitly make it correct by creating a dummy vdev and
3265
* then deleting it.
3266
*/
3267
if (ar->hw_params.hw_filter_reset_required &&
3268
mode == ATH10K_FIRMWARE_MODE_NORMAL) {
3269
status = ath10k_core_reset_rx_filter(ar);
3270
if (status) {
3271
ath10k_err(ar,
3272
"failed to reset rx filter: %d\n", status);
3273
goto err_hif_stop;
3274
}
3275
}
3276
3277
status = ath10k_htt_rx_ring_refill(ar);
3278
if (status) {
3279
ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);
3280
goto err_hif_stop;
3281
}
3282
3283
if (ar->max_num_vdevs >= 64)
3284
ar->free_vdev_map = 0xFFFFFFFFFFFFFFFFLL;
3285
else
3286
ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
3287
3288
INIT_LIST_HEAD(&ar->arvifs);
3289
3290
/* we don't care about HTT in UTF mode */
3291
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
3292
status = ath10k_htt_setup(&ar->htt);
3293
if (status) {
3294
ath10k_err(ar, "failed to setup htt: %d\n", status);
3295
goto err_hif_stop;
3296
}
3297
}
3298
3299
status = ath10k_debug_start(ar);
3300
if (status)
3301
goto err_hif_stop;
3302
3303
status = ath10k_hif_set_target_log_mode(ar, fw_diag_log);
3304
if (status && status != -EOPNOTSUPP) {
3305
ath10k_warn(ar, "set target log mode failed: %d\n", status);
3306
goto err_hif_stop;
3307
}
3308
3309
return 0;
3310
3311
err_hif_stop:
3312
ath10k_hif_stop(ar);
3313
err_htt_rx_detach:
3314
ath10k_htt_rx_free(&ar->htt);
3315
err_htt_tx_detach:
3316
ath10k_htt_tx_free(&ar->htt);
3317
err_wmi_detach:
3318
ath10k_wmi_detach(ar);
3319
err:
3320
return status;
3321
}
3322
EXPORT_SYMBOL(ath10k_core_start);
3323
3324
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
3325
{
3326
int ret;
3327
unsigned long time_left;
3328
3329
reinit_completion(&ar->target_suspend);
3330
3331
ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
3332
if (ret) {
3333
ath10k_warn(ar, "could not suspend target (%d)\n", ret);
3334
return ret;
3335
}
3336
3337
time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
3338
3339
if (!time_left) {
3340
ath10k_warn(ar, "suspend timed out - target pause event never came\n");
3341
return -ETIMEDOUT;
3342
}
3343
3344
return 0;
3345
}
3346
3347
void ath10k_core_stop(struct ath10k *ar)
3348
{
3349
lockdep_assert_held(&ar->conf_mutex);
3350
ath10k_debug_stop(ar);
3351
3352
/* try to suspend target */
3353
if (ar->state != ATH10K_STATE_RESTARTING &&
3354
ar->state != ATH10K_STATE_UTF)
3355
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
3356
3357
ath10k_hif_stop(ar);
3358
ath10k_htt_tx_stop(&ar->htt);
3359
ath10k_htt_rx_free(&ar->htt);
3360
ath10k_wmi_detach(ar);
3361
3362
ar->id.bmi_ids_valid = false;
3363
}
3364
EXPORT_SYMBOL(ath10k_core_stop);
3365
3366
/* mac80211 manages fw/hw initialization through start/stop hooks. However in
3367
* order to know what hw capabilities should be advertised to mac80211 it is
3368
* necessary to load the firmware (and tear it down immediately since start
3369
* hook will try to init it again) before registering
3370
*/
3371
static int ath10k_core_probe_fw(struct ath10k *ar)
3372
{
3373
struct bmi_target_info target_info;
3374
int ret = 0;
3375
3376
ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);
3377
if (ret) {
3378
ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
3379
return ret;
3380
}
3381
3382
switch (ar->hif.bus) {
3383
case ATH10K_BUS_SDIO:
3384
memset(&target_info, 0, sizeof(target_info));
3385
ret = ath10k_bmi_get_target_info_sdio(ar, &target_info);
3386
if (ret) {
3387
ath10k_err(ar, "could not get target info (%d)\n", ret);
3388
goto err_power_down;
3389
}
3390
ar->target_version = target_info.version;
3391
ar->hw->wiphy->hw_version = target_info.version;
3392
break;
3393
case ATH10K_BUS_PCI:
3394
case ATH10K_BUS_AHB:
3395
case ATH10K_BUS_USB:
3396
memset(&target_info, 0, sizeof(target_info));
3397
ret = ath10k_bmi_get_target_info(ar, &target_info);
3398
if (ret) {
3399
ath10k_err(ar, "could not get target info (%d)\n", ret);
3400
goto err_power_down;
3401
}
3402
ar->target_version = target_info.version;
3403
ar->hw->wiphy->hw_version = target_info.version;
3404
break;
3405
case ATH10K_BUS_SNOC:
3406
memset(&target_info, 0, sizeof(target_info));
3407
ret = ath10k_hif_get_target_info(ar, &target_info);
3408
if (ret) {
3409
ath10k_err(ar, "could not get target info (%d)\n", ret);
3410
goto err_power_down;
3411
}
3412
ar->target_version = target_info.version;
3413
ar->hw->wiphy->hw_version = target_info.version;
3414
break;
3415
default:
3416
ath10k_err(ar, "incorrect hif bus type: %d\n", ar->hif.bus);
3417
}
3418
3419
ret = ath10k_init_hw_params(ar);
3420
if (ret) {
3421
ath10k_err(ar, "could not get hw params (%d)\n", ret);
3422
goto err_power_down;
3423
}
3424
3425
ret = ath10k_core_fetch_firmware_files(ar);
3426
if (ret) {
3427
ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
3428
goto err_power_down;
3429
}
3430
3431
BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
3432
sizeof(ar->normal_mode_fw.fw_file.fw_version));
3433
memcpy(ar->hw->wiphy->fw_version, ar->normal_mode_fw.fw_file.fw_version,
3434
sizeof(ar->hw->wiphy->fw_version));
3435
3436
ath10k_debug_print_hwfw_info(ar);
3437
3438
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
3439
ar->normal_mode_fw.fw_file.fw_features)) {
3440
ret = ath10k_core_pre_cal_download(ar);
3441
if (ret) {
3442
/* pre calibration data download is not necessary
3443
* for all the chipsets. Ignore failures and continue.
3444
*/
3445
ath10k_dbg(ar, ATH10K_DBG_BOOT,
3446
"could not load pre cal data: %d\n", ret);
3447
}
3448
3449
ret = ath10k_core_get_board_id_from_otp(ar);
3450
if (ret && ret != -EOPNOTSUPP) {
3451
ath10k_err(ar, "failed to get board id from otp: %d\n",
3452
ret);
3453
goto err_free_firmware_files;
3454
}
3455
3456
ret = ath10k_core_check_smbios(ar);
3457
if (ret)
3458
ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n");
3459
3460
ret = ath10k_core_check_dt(ar);
3461
if (ret)
3462
ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");
3463
3464
ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD);
3465
if (ret) {
3466
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
3467
goto err_free_firmware_files;
3468
}
3469
3470
ath10k_debug_print_board_info(ar);
3471
}
3472
3473
device_get_mac_address(ar->dev, ar->mac_addr);
3474
3475
ret = ath10k_core_init_firmware_features(ar);
3476
if (ret) {
3477
ath10k_err(ar, "fatal problem with firmware features: %d\n",
3478
ret);
3479
goto err_free_firmware_files;
3480
}
3481
3482
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
3483
ar->normal_mode_fw.fw_file.fw_features)) {
3484
ret = ath10k_swap_code_seg_init(ar,
3485
&ar->normal_mode_fw.fw_file);
3486
if (ret) {
3487
ath10k_err(ar, "failed to initialize code swap segment: %d\n",
3488
ret);
3489
goto err_free_firmware_files;
3490
}
3491
}
3492
3493
mutex_lock(&ar->conf_mutex);
3494
3495
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
3496
&ar->normal_mode_fw);
3497
if (ret) {
3498
ath10k_err(ar, "could not init core (%d)\n", ret);
3499
goto err_unlock;
3500
}
3501
3502
ath10k_debug_print_boot_info(ar);
3503
ath10k_core_stop(ar);
3504
3505
mutex_unlock(&ar->conf_mutex);
3506
3507
ath10k_hif_power_down(ar);
3508
return 0;
3509
3510
err_unlock:
3511
mutex_unlock(&ar->conf_mutex);
3512
3513
err_free_firmware_files:
3514
ath10k_core_free_firmware_files(ar);
3515
3516
err_power_down:
3517
ath10k_hif_power_down(ar);
3518
3519
return ret;
3520
}
3521
3522
static void ath10k_core_register_work(struct work_struct *work)
3523
{
3524
struct ath10k *ar = container_of(work, struct ath10k, register_work);
3525
int status;
3526
3527
/* peer stats are enabled by default */
3528
set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
3529
3530
status = ath10k_core_probe_fw(ar);
3531
if (status) {
3532
ath10k_err(ar, "could not probe fw (%d)\n", status);
3533
goto err;
3534
}
3535
3536
status = ath10k_mac_register(ar);
3537
if (status) {
3538
ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
3539
goto err_release_fw;
3540
}
3541
3542
status = ath10k_coredump_register(ar);
3543
if (status) {
3544
ath10k_err(ar, "unable to register coredump\n");
3545
goto err_unregister_mac;
3546
}
3547
3548
status = ath10k_debug_register(ar);
3549
if (status) {
3550
ath10k_err(ar, "unable to initialize debugfs\n");
3551
goto err_unregister_coredump;
3552
}
3553
3554
status = ath10k_spectral_create(ar);
3555
if (status) {
3556
ath10k_err(ar, "failed to initialize spectral\n");
3557
goto err_debug_destroy;
3558
}
3559
3560
status = ath10k_thermal_register(ar);
3561
if (status) {
3562
ath10k_err(ar, "could not register thermal device: %d\n",
3563
status);
3564
goto err_spectral_destroy;
3565
}
3566
#if defined(CONFIG_FWLOG)
3567
ath10k_fwlog_register(ar);
3568
#endif
3569
3570
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
3571
return;
3572
3573
err_spectral_destroy:
3574
ath10k_spectral_destroy(ar);
3575
err_debug_destroy:
3576
ath10k_debug_destroy(ar);
3577
err_unregister_coredump:
3578
ath10k_coredump_unregister(ar);
3579
err_unregister_mac:
3580
ath10k_mac_unregister(ar);
3581
err_release_fw:
3582
ath10k_core_free_firmware_files(ar);
3583
err:
3584
/* TODO: It's probably a good idea to release device from the driver
3585
* but calling device_release_driver() here will cause a deadlock.
3586
*/
3587
return;
3588
}
3589
3590
int ath10k_core_register(struct ath10k *ar,
3591
const struct ath10k_bus_params *bus_params)
3592
{
3593
ar->bus_param = *bus_params;
3594
3595
queue_work(ar->workqueue, &ar->register_work);
3596
3597
return 0;
3598
}
3599
EXPORT_SYMBOL(ath10k_core_register);
3600
3601
void ath10k_core_unregister(struct ath10k *ar)
3602
{
3603
cancel_work_sync(&ar->register_work);
3604
3605
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
3606
return;
3607
3608
ath10k_thermal_unregister(ar);
3609
/* Stop spectral before unregistering from mac80211 to remove the
3610
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
3611
* would be already be free'd recursively, leading to a double free.
3612
*/
3613
ath10k_spectral_destroy(ar);
3614
3615
/* We must unregister from mac80211 before we stop HTC and HIF.
3616
* Otherwise we will fail to submit commands to FW and mac80211 will be
3617
* unhappy about callback failures.
3618
*/
3619
ath10k_mac_unregister(ar);
3620
3621
ath10k_testmode_destroy(ar);
3622
3623
ath10k_core_free_firmware_files(ar);
3624
ath10k_core_free_board_files(ar);
3625
3626
ath10k_debug_unregister(ar);
3627
#if defined(CONFIG_FWLOG)
3628
ath10k_fwlog_unregister(ar);
3629
#endif
3630
}
3631
EXPORT_SYMBOL(ath10k_core_unregister);
3632
3633
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
3634
enum ath10k_bus bus,
3635
enum ath10k_hw_rev hw_rev,
3636
const struct ath10k_hif_ops *hif_ops)
3637
{
3638
struct ath10k *ar;
3639
int ret;
3640
3641
ar = ath10k_mac_create(priv_size);
3642
if (!ar)
3643
return NULL;
3644
3645
ar->ath_common.priv = ar;
3646
ar->ath_common.hw = ar->hw;
3647
ar->dev = dev;
3648
ar->hw_rev = hw_rev;
3649
ar->hif.ops = hif_ops;
3650
ar->hif.bus = bus;
3651
3652
switch (hw_rev) {
3653
case ATH10K_HW_QCA988X:
3654
case ATH10K_HW_QCA9887:
3655
ar->regs = &qca988x_regs;
3656
ar->hw_ce_regs = &qcax_ce_regs;
3657
ar->hw_values = &qca988x_values;
3658
break;
3659
case ATH10K_HW_QCA6174:
3660
case ATH10K_HW_QCA9377:
3661
ar->regs = &qca6174_regs;
3662
ar->hw_ce_regs = &qcax_ce_regs;
3663
ar->hw_values = &qca6174_values;
3664
break;
3665
case ATH10K_HW_QCA99X0:
3666
case ATH10K_HW_QCA9984:
3667
ar->regs = &qca99x0_regs;
3668
ar->hw_ce_regs = &qcax_ce_regs;
3669
ar->hw_values = &qca99x0_values;
3670
break;
3671
case ATH10K_HW_QCA9888:
3672
ar->regs = &qca99x0_regs;
3673
ar->hw_ce_regs = &qcax_ce_regs;
3674
ar->hw_values = &qca9888_values;
3675
break;
3676
case ATH10K_HW_QCA4019:
3677
ar->regs = &qca4019_regs;
3678
ar->hw_ce_regs = &qcax_ce_regs;
3679
ar->hw_values = &qca4019_values;
3680
break;
3681
case ATH10K_HW_WCN3990:
3682
ar->regs = &wcn3990_regs;
3683
ar->hw_ce_regs = &wcn3990_ce_regs;
3684
ar->hw_values = &wcn3990_values;
3685
break;
3686
default:
3687
ath10k_err(ar, "unsupported core hardware revision %d\n",
3688
hw_rev);
3689
ret = -ENOTSUPP;
3690
goto err_free_mac;
3691
}
3692
3693
init_completion(&ar->scan.started);
3694
init_completion(&ar->scan.completed);
3695
init_completion(&ar->scan.on_channel);
3696
init_completion(&ar->target_suspend);
3697
init_completion(&ar->driver_recovery);
3698
init_completion(&ar->wow.wakeup_completed);
3699
3700
init_completion(&ar->install_key_done);
3701
init_completion(&ar->vdev_setup_done);
3702
init_completion(&ar->vdev_delete_done);
3703
init_completion(&ar->thermal.wmi_sync);
3704
init_completion(&ar->bss_survey_done);
3705
init_completion(&ar->peer_delete_done);
3706
init_completion(&ar->peer_stats_info_complete);
3707
3708
INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
3709
3710
ar->workqueue = create_singlethread_workqueue("ath10k_wq");
3711
if (!ar->workqueue)
3712
goto err_free_mac;
3713
3714
ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");
3715
if (!ar->workqueue_aux)
3716
goto err_free_wq;
3717
3718
ar->workqueue_tx_complete =
3719
create_singlethread_workqueue("ath10k_tx_complete_wq");
3720
if (!ar->workqueue_tx_complete)
3721
goto err_free_aux_wq;
3722
3723
mutex_init(&ar->conf_mutex);
3724
mutex_init(&ar->dump_mutex);
3725
spin_lock_init(&ar->data_lock);
3726
3727
for (int ac = 0; ac < IEEE80211_NUM_ACS; ac++)
3728
spin_lock_init(&ar->queue_lock[ac]);
3729
3730
INIT_LIST_HEAD(&ar->peers);
3731
init_waitqueue_head(&ar->peer_mapping_wq);
3732
init_waitqueue_head(&ar->htt.empty_tx_wq);
3733
init_waitqueue_head(&ar->wmi.tx_credits_wq);
3734
3735
skb_queue_head_init(&ar->htt.rx_indication_head);
3736
3737
init_completion(&ar->offchan_tx_completed);
3738
INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
3739
skb_queue_head_init(&ar->offchan_tx_queue);
3740
3741
INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);
3742
skb_queue_head_init(&ar->wmi_mgmt_tx_queue);
3743
3744
INIT_WORK(&ar->register_work, ath10k_core_register_work);
3745
INIT_WORK(&ar->restart_work, ath10k_core_restart);
3746
INIT_WORK(&ar->set_coverage_class_work,
3747
ath10k_core_set_coverage_class_work);
3748
3749
init_dummy_netdev(&ar->napi_dev);
3750
3751
ret = ath10k_coredump_create(ar);
3752
if (ret)
3753
goto err_free_tx_complete;
3754
3755
ret = ath10k_debug_create(ar);
3756
if (ret)
3757
goto err_free_coredump;
3758
3759
return ar;
3760
3761
err_free_coredump:
3762
ath10k_coredump_destroy(ar);
3763
err_free_tx_complete:
3764
destroy_workqueue(ar->workqueue_tx_complete);
3765
err_free_aux_wq:
3766
destroy_workqueue(ar->workqueue_aux);
3767
err_free_wq:
3768
destroy_workqueue(ar->workqueue);
3769
err_free_mac:
3770
ath10k_mac_destroy(ar);
3771
3772
return NULL;
3773
}
3774
EXPORT_SYMBOL(ath10k_core_create);
3775
3776
void ath10k_core_destroy(struct ath10k *ar)
3777
{
3778
destroy_workqueue(ar->workqueue);
3779
3780
destroy_workqueue(ar->workqueue_aux);
3781
3782
destroy_workqueue(ar->workqueue_tx_complete);
3783
3784
ath10k_debug_destroy(ar);
3785
ath10k_coredump_destroy(ar);
3786
ath10k_htt_tx_destroy(&ar->htt);
3787
ath10k_wmi_free_host_mem(ar);
3788
ath10k_mac_destroy(ar);
3789
}
3790
EXPORT_SYMBOL(ath10k_core_destroy);
3791
3792
MODULE_AUTHOR("Qualcomm Atheros");
3793
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ac wireless LAN cards.");
3794
MODULE_LICENSE("Dual BSD/GPL");
3795
3796