Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/athk/ath11k/core.c
105221 views
1
// SPDX-License-Identifier: BSD-3-Clause-Clear
2
/*
3
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4
* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
5
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6
*/
7
8
#if defined(__FreeBSD__)
9
#define LINUXKPI_PARAM_PREFIX ath11k_core_
10
#endif
11
12
#include <linux/export.h>
13
#include <linux/module.h>
14
#include <linux/slab.h>
15
#include <linux/remoteproc.h>
16
#include <linux/firmware.h>
17
#if defined(CONFIG_OF)
18
#include <linux/of.h>
19
#endif
20
#if defined(__FreeBSD__)
21
#include <linux/delay.h>
22
#endif
23
24
#include "core.h"
25
#include "dp_tx.h"
26
#include "dp_rx.h"
27
#include "debug.h"
28
#include "hif.h"
29
#include "wow.h"
30
#include "fw.h"
31
32
unsigned int ath11k_debug_mask;
33
EXPORT_SYMBOL(ath11k_debug_mask);
34
module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
35
MODULE_PARM_DESC(debug_mask, "Debugging mask");
36
37
static unsigned int ath11k_crypto_mode;
38
module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
39
MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
40
41
/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
42
unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
43
module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
44
MODULE_PARM_DESC(frame_mode,
45
"Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
46
47
bool ath11k_ftm_mode;
48
module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444);
49
MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
50
51
static const struct ath11k_hw_params ath11k_hw_params[] = {
52
{
53
.hw_rev = ATH11K_HW_IPQ8074,
54
.name = "ipq8074 hw2.0",
55
.fw = {
56
.dir = "IPQ8074/hw2.0",
57
.board_size = 256 * 1024,
58
.cal_offset = 128 * 1024,
59
},
60
.max_radios = 3,
61
.bdf_addr = 0x4B0C0000,
62
.hw_ops = &ipq8074_ops,
63
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
64
.internal_sleep_clock = false,
65
.regs = &ipq8074_regs,
66
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
67
.host_ce_config = ath11k_host_ce_config_ipq8074,
68
.ce_count = 12,
69
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
70
.target_ce_count = 11,
71
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
72
.svc_to_ce_map_len = 21,
73
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
74
.single_pdev_only = false,
75
.rxdma1_enable = true,
76
.num_rxdma_per_pdev = 1,
77
.rx_mac_buf_ring = false,
78
.vdev_start_delay = false,
79
.htt_peer_map_v2 = true,
80
81
.spectral = {
82
.fft_sz = 2,
83
/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
84
* so added pad size as 2 bytes to compensate the BIN size
85
*/
86
.fft_pad_sz = 2,
87
.summary_pad_sz = 0,
88
.fft_hdr_len = 16,
89
.max_fft_bins = 512,
90
.fragment_160mhz = true,
91
},
92
93
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
94
BIT(NL80211_IFTYPE_AP) |
95
BIT(NL80211_IFTYPE_MESH_POINT),
96
.supports_monitor = true,
97
.full_monitor_mode = false,
98
.supports_shadow_regs = false,
99
.idle_ps = false,
100
.supports_sta_ps = false,
101
.coldboot_cal_mm = true,
102
.coldboot_cal_ftm = true,
103
.cbcal_restart_fw = true,
104
.fw_mem_mode = 0,
105
.num_vdevs = 16 + 1,
106
.num_peers = 512,
107
.supports_suspend = false,
108
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
109
.supports_regdb = false,
110
.fix_l1ss = true,
111
.credit_flow = false,
112
.max_tx_ring = DP_TCL_NUM_RING_MAX,
113
.hal_params = &ath11k_hw_hal_params_ipq8074,
114
.supports_dynamic_smps_6ghz = false,
115
.alloc_cacheable_memory = true,
116
.supports_rssi_stats = false,
117
.fw_wmi_diag_event = false,
118
.current_cc_support = false,
119
.dbr_debug_support = true,
120
.global_reset = false,
121
.bios_sar_capa = NULL,
122
.m3_fw_support = false,
123
.fixed_bdf_addr = true,
124
.fixed_mem_region = true,
125
.static_window_map = false,
126
.hybrid_bus_type = false,
127
.fixed_fw_mem = false,
128
.support_off_channel_tx = false,
129
.supports_multi_bssid = false,
130
131
.sram_dump = {},
132
133
.tcl_ring_retry = true,
134
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
135
.smp2p_wow_exit = false,
136
.support_dual_stations = false,
137
.pdev_suspend = false,
138
},
139
{
140
.hw_rev = ATH11K_HW_IPQ6018_HW10,
141
.name = "ipq6018 hw1.0",
142
.fw = {
143
.dir = "IPQ6018/hw1.0",
144
.board_size = 256 * 1024,
145
.cal_offset = 128 * 1024,
146
},
147
.max_radios = 2,
148
.bdf_addr = 0x4ABC0000,
149
.hw_ops = &ipq6018_ops,
150
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
151
.internal_sleep_clock = false,
152
.regs = &ipq8074_regs,
153
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
154
.host_ce_config = ath11k_host_ce_config_ipq8074,
155
.ce_count = 12,
156
.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
157
.target_ce_count = 11,
158
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
159
.svc_to_ce_map_len = 19,
160
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
161
.single_pdev_only = false,
162
.rxdma1_enable = true,
163
.num_rxdma_per_pdev = 1,
164
.rx_mac_buf_ring = false,
165
.vdev_start_delay = false,
166
.htt_peer_map_v2 = true,
167
168
.spectral = {
169
.fft_sz = 4,
170
.fft_pad_sz = 0,
171
.summary_pad_sz = 0,
172
.fft_hdr_len = 16,
173
.max_fft_bins = 512,
174
.fragment_160mhz = true,
175
},
176
177
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
178
BIT(NL80211_IFTYPE_AP) |
179
BIT(NL80211_IFTYPE_MESH_POINT),
180
.supports_monitor = true,
181
.full_monitor_mode = false,
182
.supports_shadow_regs = false,
183
.idle_ps = false,
184
.supports_sta_ps = false,
185
.coldboot_cal_mm = true,
186
.coldboot_cal_ftm = true,
187
.cbcal_restart_fw = true,
188
.fw_mem_mode = 0,
189
.num_vdevs = 16 + 1,
190
.num_peers = 512,
191
.supports_suspend = false,
192
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
193
.supports_regdb = false,
194
.fix_l1ss = true,
195
.credit_flow = false,
196
.max_tx_ring = DP_TCL_NUM_RING_MAX,
197
.hal_params = &ath11k_hw_hal_params_ipq8074,
198
.supports_dynamic_smps_6ghz = false,
199
.alloc_cacheable_memory = true,
200
.supports_rssi_stats = false,
201
.fw_wmi_diag_event = false,
202
.current_cc_support = false,
203
.dbr_debug_support = true,
204
.global_reset = false,
205
.bios_sar_capa = NULL,
206
.m3_fw_support = false,
207
.fixed_bdf_addr = true,
208
.fixed_mem_region = true,
209
.static_window_map = false,
210
.hybrid_bus_type = false,
211
.fixed_fw_mem = false,
212
.support_off_channel_tx = false,
213
.supports_multi_bssid = false,
214
215
.sram_dump = {},
216
217
.tcl_ring_retry = true,
218
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
219
.smp2p_wow_exit = false,
220
.support_fw_mac_sequence = false,
221
.support_dual_stations = false,
222
.pdev_suspend = false,
223
},
224
{
225
.name = "qca6390 hw2.0",
226
.hw_rev = ATH11K_HW_QCA6390_HW20,
227
.fw = {
228
.dir = "QCA6390/hw2.0",
229
.board_size = 256 * 1024,
230
.cal_offset = 128 * 1024,
231
},
232
.max_radios = 3,
233
.bdf_addr = 0x4B0C0000,
234
.hw_ops = &qca6390_ops,
235
.ring_mask = &ath11k_hw_ring_mask_qca6390,
236
.internal_sleep_clock = true,
237
.regs = &qca6390_regs,
238
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
239
.host_ce_config = ath11k_host_ce_config_qca6390,
240
.ce_count = 9,
241
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
242
.target_ce_count = 9,
243
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
244
.svc_to_ce_map_len = 14,
245
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
246
.single_pdev_only = true,
247
.rxdma1_enable = false,
248
.num_rxdma_per_pdev = 2,
249
.rx_mac_buf_ring = true,
250
.vdev_start_delay = true,
251
.htt_peer_map_v2 = false,
252
253
.spectral = {
254
.fft_sz = 0,
255
.fft_pad_sz = 0,
256
.summary_pad_sz = 0,
257
.fft_hdr_len = 0,
258
.max_fft_bins = 0,
259
.fragment_160mhz = false,
260
},
261
262
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
263
BIT(NL80211_IFTYPE_AP) |
264
BIT(NL80211_IFTYPE_P2P_DEVICE) |
265
BIT(NL80211_IFTYPE_P2P_CLIENT) |
266
BIT(NL80211_IFTYPE_P2P_GO),
267
.supports_monitor = false,
268
.full_monitor_mode = false,
269
.supports_shadow_regs = true,
270
.idle_ps = true,
271
.supports_sta_ps = true,
272
.coldboot_cal_mm = false,
273
.coldboot_cal_ftm = false,
274
.cbcal_restart_fw = false,
275
.fw_mem_mode = 0,
276
.num_vdevs = 2 + 1,
277
.num_peers = 512,
278
.supports_suspend = true,
279
.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
280
.supports_regdb = false,
281
.fix_l1ss = true,
282
.credit_flow = true,
283
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
284
.hal_params = &ath11k_hw_hal_params_qca6390,
285
.supports_dynamic_smps_6ghz = false,
286
.alloc_cacheable_memory = false,
287
.supports_rssi_stats = true,
288
.fw_wmi_diag_event = true,
289
.current_cc_support = true,
290
.dbr_debug_support = false,
291
.global_reset = true,
292
.bios_sar_capa = NULL,
293
.m3_fw_support = true,
294
.fixed_bdf_addr = false,
295
.fixed_mem_region = false,
296
.static_window_map = false,
297
.hybrid_bus_type = false,
298
.fixed_fw_mem = false,
299
.support_off_channel_tx = true,
300
.supports_multi_bssid = true,
301
302
.sram_dump = {
303
.start = 0x01400000,
304
.end = 0x0171ffff,
305
},
306
307
.tcl_ring_retry = true,
308
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
309
.smp2p_wow_exit = false,
310
.support_fw_mac_sequence = true,
311
.support_dual_stations = true,
312
.pdev_suspend = false,
313
},
314
{
315
.name = "qcn9074 hw1.0",
316
.hw_rev = ATH11K_HW_QCN9074_HW10,
317
.fw = {
318
.dir = "QCN9074/hw1.0",
319
.board_size = 256 * 1024,
320
.cal_offset = 128 * 1024,
321
},
322
.max_radios = 1,
323
.single_pdev_only = false,
324
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
325
.hw_ops = &qcn9074_ops,
326
.ring_mask = &ath11k_hw_ring_mask_qcn9074,
327
.internal_sleep_clock = false,
328
.regs = &qcn9074_regs,
329
.host_ce_config = ath11k_host_ce_config_qcn9074,
330
.ce_count = 6,
331
.target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
332
.target_ce_count = 9,
333
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
334
.svc_to_ce_map_len = 18,
335
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
336
.rxdma1_enable = true,
337
.num_rxdma_per_pdev = 1,
338
.rx_mac_buf_ring = false,
339
.vdev_start_delay = false,
340
.htt_peer_map_v2 = true,
341
342
.spectral = {
343
.fft_sz = 2,
344
.fft_pad_sz = 0,
345
.summary_pad_sz = 16,
346
.fft_hdr_len = 24,
347
.max_fft_bins = 1024,
348
.fragment_160mhz = false,
349
},
350
351
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
352
BIT(NL80211_IFTYPE_AP) |
353
BIT(NL80211_IFTYPE_MESH_POINT),
354
.supports_monitor = true,
355
.full_monitor_mode = true,
356
.supports_shadow_regs = false,
357
.idle_ps = false,
358
.supports_sta_ps = false,
359
.coldboot_cal_mm = false,
360
.coldboot_cal_ftm = true,
361
.cbcal_restart_fw = true,
362
.fw_mem_mode = 2,
363
.num_vdevs = 8,
364
.num_peers = 128,
365
.supports_suspend = false,
366
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
367
.supports_regdb = false,
368
.fix_l1ss = true,
369
.credit_flow = false,
370
.max_tx_ring = DP_TCL_NUM_RING_MAX,
371
.hal_params = &ath11k_hw_hal_params_ipq8074,
372
.supports_dynamic_smps_6ghz = true,
373
.alloc_cacheable_memory = true,
374
.supports_rssi_stats = false,
375
.fw_wmi_diag_event = false,
376
.current_cc_support = false,
377
.dbr_debug_support = true,
378
.global_reset = false,
379
.bios_sar_capa = NULL,
380
.m3_fw_support = true,
381
.fixed_bdf_addr = false,
382
.fixed_mem_region = false,
383
.static_window_map = true,
384
.hybrid_bus_type = false,
385
.fixed_fw_mem = false,
386
.support_off_channel_tx = false,
387
.supports_multi_bssid = false,
388
389
.sram_dump = {},
390
391
.tcl_ring_retry = true,
392
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
393
.smp2p_wow_exit = false,
394
.support_fw_mac_sequence = false,
395
.support_dual_stations = false,
396
.pdev_suspend = false,
397
},
398
{
399
.name = "wcn6855 hw2.0",
400
.hw_rev = ATH11K_HW_WCN6855_HW20,
401
.fw = {
402
.dir = "WCN6855/hw2.0",
403
.board_size = 256 * 1024,
404
.cal_offset = 128 * 1024,
405
},
406
.max_radios = 3,
407
.bdf_addr = 0x4B0C0000,
408
.hw_ops = &wcn6855_ops,
409
.ring_mask = &ath11k_hw_ring_mask_qca6390,
410
.internal_sleep_clock = true,
411
.regs = &wcn6855_regs,
412
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
413
.host_ce_config = ath11k_host_ce_config_qca6390,
414
.ce_count = 9,
415
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
416
.target_ce_count = 9,
417
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
418
.svc_to_ce_map_len = 14,
419
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
420
.single_pdev_only = true,
421
.rxdma1_enable = false,
422
.num_rxdma_per_pdev = 2,
423
.rx_mac_buf_ring = true,
424
.vdev_start_delay = true,
425
.htt_peer_map_v2 = false,
426
427
.spectral = {
428
.fft_sz = 0,
429
.fft_pad_sz = 0,
430
.summary_pad_sz = 0,
431
.fft_hdr_len = 0,
432
.max_fft_bins = 0,
433
.fragment_160mhz = false,
434
},
435
436
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
437
BIT(NL80211_IFTYPE_AP) |
438
BIT(NL80211_IFTYPE_P2P_DEVICE) |
439
BIT(NL80211_IFTYPE_P2P_CLIENT) |
440
BIT(NL80211_IFTYPE_P2P_GO),
441
.supports_monitor = false,
442
.full_monitor_mode = false,
443
.supports_shadow_regs = true,
444
.idle_ps = true,
445
.supports_sta_ps = true,
446
.coldboot_cal_mm = false,
447
.coldboot_cal_ftm = false,
448
.cbcal_restart_fw = false,
449
.fw_mem_mode = 0,
450
.num_vdevs = 2 + 1,
451
.num_peers = 512,
452
.supports_suspend = true,
453
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
454
.supports_regdb = true,
455
.fix_l1ss = false,
456
.credit_flow = true,
457
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
458
.hal_params = &ath11k_hw_hal_params_qca6390,
459
.supports_dynamic_smps_6ghz = false,
460
.alloc_cacheable_memory = false,
461
.supports_rssi_stats = true,
462
.fw_wmi_diag_event = true,
463
.current_cc_support = true,
464
.dbr_debug_support = false,
465
.global_reset = true,
466
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
467
.m3_fw_support = true,
468
.fixed_bdf_addr = false,
469
.fixed_mem_region = false,
470
.static_window_map = false,
471
.hybrid_bus_type = false,
472
.fixed_fw_mem = false,
473
.support_off_channel_tx = true,
474
.supports_multi_bssid = true,
475
476
.sram_dump = {
477
.start = 0x01400000,
478
.end = 0x0177ffff,
479
},
480
481
.tcl_ring_retry = true,
482
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
483
.smp2p_wow_exit = false,
484
.support_fw_mac_sequence = true,
485
.support_dual_stations = true,
486
.pdev_suspend = false,
487
},
488
{
489
.name = "wcn6855 hw2.1",
490
.hw_rev = ATH11K_HW_WCN6855_HW21,
491
.fw = {
492
.dir = "WCN6855/hw2.1",
493
.board_size = 256 * 1024,
494
.cal_offset = 128 * 1024,
495
},
496
.max_radios = 3,
497
.bdf_addr = 0x4B0C0000,
498
.hw_ops = &wcn6855_ops,
499
.ring_mask = &ath11k_hw_ring_mask_qca6390,
500
.internal_sleep_clock = true,
501
.regs = &wcn6855_regs,
502
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
503
.host_ce_config = ath11k_host_ce_config_qca6390,
504
.ce_count = 9,
505
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
506
.target_ce_count = 9,
507
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
508
.svc_to_ce_map_len = 14,
509
.single_pdev_only = true,
510
.rxdma1_enable = false,
511
.num_rxdma_per_pdev = 2,
512
.rx_mac_buf_ring = true,
513
.vdev_start_delay = true,
514
.htt_peer_map_v2 = false,
515
516
.spectral = {
517
.fft_sz = 0,
518
.fft_pad_sz = 0,
519
.summary_pad_sz = 0,
520
.fft_hdr_len = 0,
521
.max_fft_bins = 0,
522
.fragment_160mhz = false,
523
},
524
525
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
526
BIT(NL80211_IFTYPE_AP) |
527
BIT(NL80211_IFTYPE_P2P_DEVICE) |
528
BIT(NL80211_IFTYPE_P2P_CLIENT) |
529
BIT(NL80211_IFTYPE_P2P_GO),
530
.supports_monitor = false,
531
.supports_shadow_regs = true,
532
.idle_ps = true,
533
.supports_sta_ps = true,
534
.coldboot_cal_mm = false,
535
.coldboot_cal_ftm = false,
536
.cbcal_restart_fw = false,
537
.fw_mem_mode = 0,
538
.num_vdevs = 2 + 1,
539
.num_peers = 512,
540
.supports_suspend = true,
541
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
542
.supports_regdb = true,
543
.fix_l1ss = false,
544
.credit_flow = true,
545
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
546
.hal_params = &ath11k_hw_hal_params_qca6390,
547
.supports_dynamic_smps_6ghz = false,
548
.alloc_cacheable_memory = false,
549
.supports_rssi_stats = true,
550
.fw_wmi_diag_event = true,
551
.current_cc_support = true,
552
.dbr_debug_support = false,
553
.global_reset = true,
554
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
555
.m3_fw_support = true,
556
.fixed_bdf_addr = false,
557
.fixed_mem_region = false,
558
.static_window_map = false,
559
.hybrid_bus_type = false,
560
.fixed_fw_mem = false,
561
.support_off_channel_tx = true,
562
.supports_multi_bssid = true,
563
564
.sram_dump = {
565
.start = 0x01400000,
566
.end = 0x0177ffff,
567
},
568
569
.tcl_ring_retry = true,
570
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
571
.smp2p_wow_exit = false,
572
.support_fw_mac_sequence = true,
573
.support_dual_stations = true,
574
.pdev_suspend = false,
575
},
576
{
577
.name = "wcn6750 hw1.0",
578
.hw_rev = ATH11K_HW_WCN6750_HW10,
579
.fw = {
580
.dir = "WCN6750/hw1.0",
581
.board_size = 256 * 1024,
582
.cal_offset = 128 * 1024,
583
},
584
.max_radios = 1,
585
.bdf_addr = 0x4B0C0000,
586
.hw_ops = &wcn6750_ops,
587
.ring_mask = &ath11k_hw_ring_mask_wcn6750,
588
.internal_sleep_clock = false,
589
.regs = &wcn6750_regs,
590
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750,
591
.host_ce_config = ath11k_host_ce_config_qca6390,
592
.ce_count = 9,
593
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
594
.target_ce_count = 9,
595
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
596
.svc_to_ce_map_len = 14,
597
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
598
.single_pdev_only = true,
599
.rxdma1_enable = false,
600
.num_rxdma_per_pdev = 1,
601
.rx_mac_buf_ring = true,
602
.vdev_start_delay = true,
603
.htt_peer_map_v2 = false,
604
605
.spectral = {
606
.fft_sz = 0,
607
.fft_pad_sz = 0,
608
.summary_pad_sz = 0,
609
.fft_hdr_len = 0,
610
.max_fft_bins = 0,
611
.fragment_160mhz = false,
612
},
613
614
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
615
BIT(NL80211_IFTYPE_AP),
616
.supports_monitor = false,
617
.supports_shadow_regs = true,
618
.idle_ps = true,
619
.supports_sta_ps = true,
620
.coldboot_cal_mm = true,
621
.coldboot_cal_ftm = true,
622
.cbcal_restart_fw = false,
623
.fw_mem_mode = 0,
624
.num_vdevs = 3,
625
.num_peers = 512,
626
.supports_suspend = false,
627
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
628
.supports_regdb = true,
629
.fix_l1ss = false,
630
.credit_flow = true,
631
.max_tx_ring = DP_TCL_NUM_RING_MAX,
632
.hal_params = &ath11k_hw_hal_params_wcn6750,
633
.supports_dynamic_smps_6ghz = false,
634
.alloc_cacheable_memory = false,
635
.supports_rssi_stats = true,
636
.fw_wmi_diag_event = true,
637
.current_cc_support = true,
638
.dbr_debug_support = false,
639
.global_reset = false,
640
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
641
.m3_fw_support = false,
642
.fixed_bdf_addr = false,
643
.fixed_mem_region = false,
644
.static_window_map = true,
645
.hybrid_bus_type = true,
646
.fixed_fw_mem = true,
647
.support_off_channel_tx = true,
648
.supports_multi_bssid = true,
649
650
.sram_dump = {},
651
652
.tcl_ring_retry = false,
653
.tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
654
.smp2p_wow_exit = true,
655
.support_fw_mac_sequence = true,
656
.support_dual_stations = false,
657
.pdev_suspend = true,
658
},
659
{
660
.hw_rev = ATH11K_HW_IPQ5018_HW10,
661
.name = "ipq5018 hw1.0",
662
.fw = {
663
.dir = "IPQ5018/hw1.0",
664
.board_size = 256 * 1024,
665
.cal_offset = 128 * 1024,
666
},
667
.max_radios = MAX_RADIOS_5018,
668
.bdf_addr = 0x4BA00000,
669
/* hal_desc_sz and hw ops are similar to qcn9074 */
670
.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
671
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
672
.ring_mask = &ath11k_hw_ring_mask_ipq8074,
673
.credit_flow = false,
674
.max_tx_ring = 1,
675
.spectral = {
676
.fft_sz = 2,
677
.fft_pad_sz = 0,
678
.summary_pad_sz = 16,
679
.fft_hdr_len = 24,
680
.max_fft_bins = 1024,
681
},
682
.internal_sleep_clock = false,
683
.regs = &ipq5018_regs,
684
.hw_ops = &ipq5018_ops,
685
.host_ce_config = ath11k_host_ce_config_qcn9074,
686
.ce_count = CE_CNT_5018,
687
.target_ce_config = ath11k_target_ce_config_wlan_ipq5018,
688
.target_ce_count = TARGET_CE_CNT_5018,
689
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq5018,
690
.svc_to_ce_map_len = SVC_CE_MAP_LEN_5018,
691
.ce_ie_addr = &ath11k_ce_ie_addr_ipq5018,
692
.ce_remap = &ath11k_ce_remap_ipq5018,
693
.rxdma1_enable = true,
694
.num_rxdma_per_pdev = RXDMA_PER_PDEV_5018,
695
.rx_mac_buf_ring = false,
696
.vdev_start_delay = false,
697
.htt_peer_map_v2 = true,
698
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
699
BIT(NL80211_IFTYPE_AP) |
700
BIT(NL80211_IFTYPE_MESH_POINT),
701
.supports_monitor = false,
702
.supports_sta_ps = false,
703
.supports_shadow_regs = false,
704
.fw_mem_mode = 0,
705
.num_vdevs = 16 + 1,
706
.num_peers = 512,
707
.supports_regdb = false,
708
.idle_ps = false,
709
.supports_suspend = false,
710
.hal_params = &ath11k_hw_hal_params_ipq8074,
711
.single_pdev_only = false,
712
.coldboot_cal_mm = true,
713
.coldboot_cal_ftm = true,
714
.cbcal_restart_fw = true,
715
.fix_l1ss = true,
716
.supports_dynamic_smps_6ghz = false,
717
.alloc_cacheable_memory = true,
718
.supports_rssi_stats = false,
719
.fw_wmi_diag_event = false,
720
.current_cc_support = false,
721
.dbr_debug_support = true,
722
.global_reset = false,
723
.bios_sar_capa = NULL,
724
.m3_fw_support = false,
725
.fixed_bdf_addr = true,
726
.fixed_mem_region = true,
727
.static_window_map = false,
728
.hybrid_bus_type = false,
729
.fixed_fw_mem = false,
730
.support_off_channel_tx = false,
731
.supports_multi_bssid = false,
732
733
.sram_dump = {},
734
735
.tcl_ring_retry = true,
736
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
737
.smp2p_wow_exit = false,
738
.support_fw_mac_sequence = false,
739
.support_dual_stations = false,
740
.pdev_suspend = false,
741
},
742
{
743
.name = "qca2066 hw2.1",
744
.hw_rev = ATH11K_HW_QCA2066_HW21,
745
.fw = {
746
.dir = "QCA2066/hw2.1",
747
.board_size = 256 * 1024,
748
.cal_offset = 128 * 1024,
749
},
750
.max_radios = 3,
751
.bdf_addr = 0x4B0C0000,
752
.hw_ops = &wcn6855_ops,
753
.ring_mask = &ath11k_hw_ring_mask_qca6390,
754
.internal_sleep_clock = true,
755
.regs = &wcn6855_regs,
756
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
757
.host_ce_config = ath11k_host_ce_config_qca6390,
758
.ce_count = 9,
759
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
760
.target_ce_count = 9,
761
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
762
.svc_to_ce_map_len = 14,
763
.ce_ie_addr = &ath11k_ce_ie_addr_ipq8074,
764
.single_pdev_only = true,
765
.rxdma1_enable = false,
766
.num_rxdma_per_pdev = 2,
767
.rx_mac_buf_ring = true,
768
.vdev_start_delay = true,
769
.htt_peer_map_v2 = false,
770
771
.spectral = {
772
.fft_sz = 0,
773
.fft_pad_sz = 0,
774
.summary_pad_sz = 0,
775
.fft_hdr_len = 0,
776
.max_fft_bins = 0,
777
.fragment_160mhz = false,
778
},
779
780
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
781
BIT(NL80211_IFTYPE_AP) |
782
BIT(NL80211_IFTYPE_P2P_DEVICE) |
783
BIT(NL80211_IFTYPE_P2P_CLIENT) |
784
BIT(NL80211_IFTYPE_P2P_GO),
785
.supports_monitor = false,
786
.full_monitor_mode = false,
787
.supports_shadow_regs = true,
788
.idle_ps = true,
789
.supports_sta_ps = true,
790
.coldboot_cal_mm = false,
791
.coldboot_cal_ftm = false,
792
.cbcal_restart_fw = false,
793
.fw_mem_mode = 0,
794
.num_vdevs = 2 + 1,
795
.num_peers = 512,
796
.supports_suspend = true,
797
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
798
.supports_regdb = true,
799
.fix_l1ss = false,
800
.credit_flow = true,
801
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
802
.hal_params = &ath11k_hw_hal_params_qca6390,
803
.supports_dynamic_smps_6ghz = false,
804
.alloc_cacheable_memory = false,
805
.supports_rssi_stats = true,
806
.fw_wmi_diag_event = true,
807
.current_cc_support = true,
808
.dbr_debug_support = false,
809
.global_reset = true,
810
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
811
.m3_fw_support = true,
812
.fixed_bdf_addr = false,
813
.fixed_mem_region = false,
814
.static_window_map = false,
815
.hybrid_bus_type = false,
816
.fixed_fw_mem = false,
817
.support_off_channel_tx = true,
818
.supports_multi_bssid = true,
819
820
.sram_dump = {
821
.start = 0x01400000,
822
.end = 0x0177ffff,
823
},
824
825
.tcl_ring_retry = true,
826
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
827
.smp2p_wow_exit = false,
828
.support_fw_mac_sequence = true,
829
.support_dual_stations = true,
830
},
831
{
832
.name = "qca6698aq hw2.1",
833
.hw_rev = ATH11K_HW_QCA6698AQ_HW21,
834
.fw = {
835
.dir = "QCA6698AQ/hw2.1",
836
.board_size = 256 * 1024,
837
.cal_offset = 128 * 1024,
838
},
839
.max_radios = 3,
840
.bdf_addr = 0x4B0C0000,
841
.hw_ops = &wcn6855_ops,
842
.ring_mask = &ath11k_hw_ring_mask_qca6390,
843
.internal_sleep_clock = true,
844
.regs = &wcn6855_regs,
845
.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
846
.host_ce_config = ath11k_host_ce_config_qca6390,
847
.ce_count = 9,
848
.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
849
.target_ce_count = 9,
850
.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
851
.svc_to_ce_map_len = 14,
852
.single_pdev_only = true,
853
.rxdma1_enable = false,
854
.num_rxdma_per_pdev = 2,
855
.rx_mac_buf_ring = true,
856
.vdev_start_delay = true,
857
.htt_peer_map_v2 = false,
858
859
.spectral = {
860
.fft_sz = 0,
861
.fft_pad_sz = 0,
862
.summary_pad_sz = 0,
863
.fft_hdr_len = 0,
864
.max_fft_bins = 0,
865
.fragment_160mhz = false,
866
},
867
868
.interface_modes = BIT(NL80211_IFTYPE_STATION) |
869
BIT(NL80211_IFTYPE_AP) |
870
BIT(NL80211_IFTYPE_P2P_DEVICE) |
871
BIT(NL80211_IFTYPE_P2P_CLIENT) |
872
BIT(NL80211_IFTYPE_P2P_GO),
873
.supports_monitor = false,
874
.supports_shadow_regs = true,
875
.idle_ps = true,
876
.supports_sta_ps = true,
877
.coldboot_cal_mm = false,
878
.coldboot_cal_ftm = false,
879
.cbcal_restart_fw = false,
880
.fw_mem_mode = 0,
881
.num_vdevs = 2 + 1,
882
.num_peers = 512,
883
.supports_suspend = true,
884
.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
885
.supports_regdb = true,
886
.fix_l1ss = false,
887
.credit_flow = true,
888
.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
889
.hal_params = &ath11k_hw_hal_params_qca6390,
890
.supports_dynamic_smps_6ghz = false,
891
.alloc_cacheable_memory = false,
892
.supports_rssi_stats = true,
893
.fw_wmi_diag_event = true,
894
.current_cc_support = true,
895
.dbr_debug_support = false,
896
.global_reset = true,
897
.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
898
.m3_fw_support = true,
899
.fixed_bdf_addr = false,
900
.fixed_mem_region = false,
901
.static_window_map = false,
902
.hybrid_bus_type = false,
903
.fixed_fw_mem = false,
904
.support_off_channel_tx = true,
905
.supports_multi_bssid = true,
906
907
.sram_dump = {
908
.start = 0x01400000,
909
.end = 0x0177ffff,
910
},
911
912
.tcl_ring_retry = true,
913
.tx_ring_size = DP_TCL_DATA_RING_SIZE,
914
.smp2p_wow_exit = false,
915
.support_fw_mac_sequence = true,
916
.support_dual_stations = true,
917
.pdev_suspend = false,
918
},
919
};
920
921
static const struct dmi_system_id ath11k_pm_quirk_table[] = {
922
{
923
.driver_data = (void *)ATH11K_PM_WOW,
924
.matches = { /* X13 G4 AMD #1 */
925
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
926
DMI_MATCH(DMI_PRODUCT_NAME, "21J3"),
927
},
928
},
929
{
930
.driver_data = (void *)ATH11K_PM_WOW,
931
.matches = { /* X13 G4 AMD #2 */
932
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
933
DMI_MATCH(DMI_PRODUCT_NAME, "21J4"),
934
},
935
},
936
{
937
.driver_data = (void *)ATH11K_PM_WOW,
938
.matches = { /* T14 G4 AMD #1 */
939
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
940
DMI_MATCH(DMI_PRODUCT_NAME, "21K3"),
941
},
942
},
943
{
944
.driver_data = (void *)ATH11K_PM_WOW,
945
.matches = { /* T14 G4 AMD #2 */
946
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
947
DMI_MATCH(DMI_PRODUCT_NAME, "21K4"),
948
},
949
},
950
{
951
.driver_data = (void *)ATH11K_PM_WOW,
952
.matches = { /* P14s G4 AMD #1 */
953
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
954
DMI_MATCH(DMI_PRODUCT_NAME, "21K5"),
955
},
956
},
957
{
958
.driver_data = (void *)ATH11K_PM_WOW,
959
.matches = { /* P14s G4 AMD #2 */
960
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
961
DMI_MATCH(DMI_PRODUCT_NAME, "21K6"),
962
},
963
},
964
{
965
.driver_data = (void *)ATH11K_PM_WOW,
966
.matches = { /* T16 G2 AMD #1 */
967
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
968
DMI_MATCH(DMI_PRODUCT_NAME, "21K7"),
969
},
970
},
971
{
972
.driver_data = (void *)ATH11K_PM_WOW,
973
.matches = { /* T16 G2 AMD #2 */
974
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
975
DMI_MATCH(DMI_PRODUCT_NAME, "21K8"),
976
},
977
},
978
{
979
.driver_data = (void *)ATH11K_PM_WOW,
980
.matches = { /* P16s G2 AMD #1 */
981
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
982
DMI_MATCH(DMI_PRODUCT_NAME, "21K9"),
983
},
984
},
985
{
986
.driver_data = (void *)ATH11K_PM_WOW,
987
.matches = { /* P16s G2 AMD #2 */
988
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
989
DMI_MATCH(DMI_PRODUCT_NAME, "21KA"),
990
},
991
},
992
{
993
.driver_data = (void *)ATH11K_PM_WOW,
994
.matches = { /* T14s G4 AMD #1 */
995
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
996
DMI_MATCH(DMI_PRODUCT_NAME, "21F8"),
997
},
998
},
999
{
1000
.driver_data = (void *)ATH11K_PM_WOW,
1001
.matches = { /* T14s G4 AMD #2 */
1002
DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
1003
DMI_MATCH(DMI_PRODUCT_NAME, "21F9"),
1004
},
1005
},
1006
{}
1007
};
1008
1009
void ath11k_fw_stats_pdevs_free(struct list_head *head)
1010
{
1011
struct ath11k_fw_stats_pdev *i, *tmp;
1012
1013
list_for_each_entry_safe(i, tmp, head, list) {
1014
list_del(&i->list);
1015
kfree(i);
1016
}
1017
}
1018
1019
void ath11k_fw_stats_vdevs_free(struct list_head *head)
1020
{
1021
struct ath11k_fw_stats_vdev *i, *tmp;
1022
1023
list_for_each_entry_safe(i, tmp, head, list) {
1024
list_del(&i->list);
1025
kfree(i);
1026
}
1027
}
1028
1029
void ath11k_fw_stats_bcn_free(struct list_head *head)
1030
{
1031
struct ath11k_fw_stats_bcn *i, *tmp;
1032
1033
list_for_each_entry_safe(i, tmp, head, list) {
1034
list_del(&i->list);
1035
kfree(i);
1036
}
1037
}
1038
1039
void ath11k_fw_stats_init(struct ath11k *ar)
1040
{
1041
INIT_LIST_HEAD(&ar->fw_stats.pdevs);
1042
INIT_LIST_HEAD(&ar->fw_stats.vdevs);
1043
INIT_LIST_HEAD(&ar->fw_stats.bcn);
1044
1045
init_completion(&ar->fw_stats_complete);
1046
init_completion(&ar->fw_stats_done);
1047
}
1048
1049
void ath11k_fw_stats_free(struct ath11k_fw_stats *stats)
1050
{
1051
ath11k_fw_stats_pdevs_free(&stats->pdevs);
1052
ath11k_fw_stats_vdevs_free(&stats->vdevs);
1053
ath11k_fw_stats_bcn_free(&stats->bcn);
1054
}
1055
1056
bool ath11k_core_coldboot_cal_support(struct ath11k_base *ab)
1057
{
1058
if (!ath11k_cold_boot_cal)
1059
return false;
1060
1061
if (ath11k_ftm_mode)
1062
return ab->hw_params.coldboot_cal_ftm;
1063
1064
else
1065
return ab->hw_params.coldboot_cal_mm;
1066
}
1067
1068
/* Check if we need to continue with suspend/resume operation.
1069
* Return:
1070
* a negative value: error happens and don't continue.
1071
* 0: no error but don't continue.
1072
* positive value: no error and do continue.
1073
*/
1074
static int ath11k_core_continue_suspend_resume(struct ath11k_base *ab)
1075
{
1076
struct ath11k *ar;
1077
1078
if (!ab->hw_params.supports_suspend)
1079
return -EOPNOTSUPP;
1080
1081
/* so far single_pdev_only chips have supports_suspend as true
1082
* so pass 0 as a dummy pdev_id here.
1083
*/
1084
ar = ab->pdevs[0].ar;
1085
if (!ar || ar->state != ATH11K_STATE_OFF)
1086
return 0;
1087
1088
return 1;
1089
}
1090
1091
static int ath11k_core_suspend_wow(struct ath11k_base *ab)
1092
{
1093
int ret;
1094
1095
ret = ath11k_dp_rx_pktlog_stop(ab, true);
1096
if (ret) {
1097
ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
1098
ret);
1099
return ret;
1100
}
1101
1102
/* So far only single_pdev_only devices can reach here,
1103
* so it is valid to handle the first, and the only, pdev.
1104
*/
1105
ret = ath11k_mac_wait_tx_complete(ab->pdevs[0].ar);
1106
if (ret) {
1107
ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
1108
return ret;
1109
}
1110
1111
ret = ath11k_wow_enable(ab);
1112
if (ret) {
1113
ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
1114
return ret;
1115
}
1116
1117
ret = ath11k_dp_rx_pktlog_stop(ab, false);
1118
if (ret) {
1119
ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
1120
ret);
1121
return ret;
1122
}
1123
1124
ath11k_ce_stop_shadow_timers(ab);
1125
ath11k_dp_stop_shadow_timers(ab);
1126
1127
ath11k_hif_irq_disable(ab);
1128
ath11k_hif_ce_irq_disable(ab);
1129
1130
ret = ath11k_hif_suspend(ab);
1131
if (ret) {
1132
ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
1133
return ret;
1134
}
1135
1136
return 0;
1137
}
1138
1139
static int ath11k_core_suspend_default(struct ath11k_base *ab)
1140
{
1141
int ret;
1142
1143
ret = ath11k_dp_rx_pktlog_stop(ab, true);
1144
if (ret) {
1145
ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
1146
ret);
1147
return ret;
1148
}
1149
1150
/* So far only single_pdev_only devices can reach here,
1151
* so it is valid to handle the first, and the only, pdev.
1152
*/
1153
ret = ath11k_mac_wait_tx_complete(ab->pdevs[0].ar);
1154
if (ret) {
1155
ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
1156
return ret;
1157
}
1158
1159
ret = ath11k_dp_rx_pktlog_stop(ab, false);
1160
if (ret) {
1161
ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
1162
ret);
1163
return ret;
1164
}
1165
1166
ath11k_ce_stop_shadow_timers(ab);
1167
ath11k_dp_stop_shadow_timers(ab);
1168
1169
/* PM framework skips suspend_late/resume_early callbacks
1170
* if other devices report errors in their suspend callbacks.
1171
* However ath11k_core_resume() would still be called because
1172
* here we return success thus kernel put us on dpm_suspended_list.
1173
* Since we won't go through a power down/up cycle, there is
1174
* no chance to call complete(&ab->restart_completed) in
1175
* ath11k_core_restart(), making ath11k_core_resume() timeout.
1176
* So call it here to avoid this issue. This also works in case
1177
* no error happens thus suspend_late/resume_early get called,
1178
* because it will be reinitialized in ath11k_core_resume_early().
1179
*/
1180
complete(&ab->restart_completed);
1181
1182
return 0;
1183
}
1184
1185
int ath11k_core_suspend(struct ath11k_base *ab)
1186
{
1187
int ret;
1188
1189
ret = ath11k_core_continue_suspend_resume(ab);
1190
if (ret <= 0)
1191
return ret;
1192
1193
if (ab->actual_pm_policy == ATH11K_PM_WOW)
1194
return ath11k_core_suspend_wow(ab);
1195
1196
return ath11k_core_suspend_default(ab);
1197
}
1198
EXPORT_SYMBOL(ath11k_core_suspend);
1199
1200
int ath11k_core_suspend_late(struct ath11k_base *ab)
1201
{
1202
int ret;
1203
1204
ret = ath11k_core_continue_suspend_resume(ab);
1205
if (ret <= 0)
1206
return ret;
1207
1208
if (ab->actual_pm_policy == ATH11K_PM_WOW)
1209
return 0;
1210
1211
ath11k_hif_irq_disable(ab);
1212
ath11k_hif_ce_irq_disable(ab);
1213
1214
ath11k_hif_power_down(ab, true);
1215
1216
return 0;
1217
}
1218
EXPORT_SYMBOL(ath11k_core_suspend_late);
1219
1220
int ath11k_core_resume_early(struct ath11k_base *ab)
1221
{
1222
int ret;
1223
1224
ret = ath11k_core_continue_suspend_resume(ab);
1225
if (ret <= 0)
1226
return ret;
1227
1228
if (ab->actual_pm_policy == ATH11K_PM_WOW)
1229
return 0;
1230
1231
reinit_completion(&ab->restart_completed);
1232
ret = ath11k_hif_power_up(ab);
1233
if (ret)
1234
ath11k_warn(ab, "failed to power up hif during resume: %d\n", ret);
1235
1236
return ret;
1237
}
1238
EXPORT_SYMBOL(ath11k_core_resume_early);
1239
1240
static int ath11k_core_resume_default(struct ath11k_base *ab)
1241
{
1242
struct ath11k *ar;
1243
long time_left;
1244
int ret;
1245
1246
time_left = wait_for_completion_timeout(&ab->restart_completed,
1247
ATH11K_RESET_TIMEOUT_HZ);
1248
if (time_left == 0) {
1249
ath11k_warn(ab, "timeout while waiting for restart complete");
1250
return -ETIMEDOUT;
1251
}
1252
1253
/* So far only single_pdev_only devices can reach here,
1254
* so it is valid to handle the first, and the only, pdev.
1255
*/
1256
ar = ab->pdevs[0].ar;
1257
if (ab->hw_params.current_cc_support &&
1258
ar->alpha2[0] != 0 && ar->alpha2[1] != 0) {
1259
ret = ath11k_reg_set_cc(ar);
1260
if (ret) {
1261
ath11k_warn(ab, "failed to set country code during resume: %d\n",
1262
ret);
1263
return ret;
1264
}
1265
}
1266
1267
ret = ath11k_dp_rx_pktlog_start(ab);
1268
if (ret)
1269
ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
1270
ret);
1271
1272
return ret;
1273
}
1274
1275
static int ath11k_core_resume_wow(struct ath11k_base *ab)
1276
{
1277
int ret;
1278
1279
ret = ath11k_hif_resume(ab);
1280
if (ret) {
1281
ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
1282
return ret;
1283
}
1284
1285
ath11k_hif_ce_irq_enable(ab);
1286
ath11k_hif_irq_enable(ab);
1287
1288
ret = ath11k_dp_rx_pktlog_start(ab);
1289
if (ret) {
1290
ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
1291
ret);
1292
return ret;
1293
}
1294
1295
ret = ath11k_wow_wakeup(ab);
1296
if (ret) {
1297
ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
1298
return ret;
1299
}
1300
1301
return 0;
1302
}
1303
1304
int ath11k_core_resume(struct ath11k_base *ab)
1305
{
1306
int ret;
1307
1308
ret = ath11k_core_continue_suspend_resume(ab);
1309
if (ret <= 0)
1310
return ret;
1311
1312
if (ab->actual_pm_policy == ATH11K_PM_WOW)
1313
return ath11k_core_resume_wow(ab);
1314
1315
return ath11k_core_resume_default(ab);
1316
}
1317
EXPORT_SYMBOL(ath11k_core_resume);
1318
1319
static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
1320
{
1321
struct ath11k_base *ab = data;
1322
const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC;
1323
#if defined(__linux__)
1324
struct ath11k_smbios_bdf *smbios = (struct ath11k_smbios_bdf *)hdr;
1325
#elif defined(__FreeBSD__)
1326
const struct ath11k_smbios_bdf *smbios = (const struct ath11k_smbios_bdf *)hdr;
1327
#endif
1328
ssize_t copied;
1329
size_t len;
1330
int i;
1331
1332
if (ab->qmi.target.bdf_ext[0] != '\0')
1333
return;
1334
1335
if (hdr->type != ATH11K_SMBIOS_BDF_EXT_TYPE)
1336
return;
1337
1338
if (hdr->length != ATH11K_SMBIOS_BDF_EXT_LENGTH) {
1339
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1340
"wrong smbios bdf ext type length (%d).\n",
1341
hdr->length);
1342
return;
1343
}
1344
1345
spin_lock_bh(&ab->base_lock);
1346
1347
switch (smbios->country_code_flag) {
1348
case ATH11K_SMBIOS_CC_ISO:
1349
ab->new_alpha2[0] = (smbios->cc_code >> 8) & 0xff;
1350
ab->new_alpha2[1] = smbios->cc_code & 0xff;
1351
ath11k_dbg(ab, ATH11K_DBG_BOOT, "smbios cc_code %c%c\n",
1352
ab->new_alpha2[0], ab->new_alpha2[1]);
1353
break;
1354
case ATH11K_SMBIOS_CC_WW:
1355
ab->new_alpha2[0] = '0';
1356
ab->new_alpha2[1] = '0';
1357
ath11k_dbg(ab, ATH11K_DBG_BOOT, "smbios worldwide regdomain\n");
1358
break;
1359
default:
1360
ath11k_dbg(ab, ATH11K_DBG_BOOT, "ignore smbios country code setting %d\n",
1361
smbios->country_code_flag);
1362
break;
1363
}
1364
1365
spin_unlock_bh(&ab->base_lock);
1366
1367
if (!smbios->bdf_enabled) {
1368
ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n");
1369
return;
1370
}
1371
1372
/* Only one string exists (per spec) */
1373
if (memcmp(smbios->bdf_ext, magic, strlen(magic)) != 0) {
1374
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1375
"bdf variant magic does not match.\n");
1376
return;
1377
}
1378
1379
len = min_t(size_t,
1380
strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext));
1381
for (i = 0; i < len; i++) {
1382
if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) {
1383
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1384
"bdf variant name contains non ascii chars.\n");
1385
return;
1386
}
1387
}
1388
1389
/* Copy extension name without magic prefix */
1390
copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic),
1391
sizeof(ab->qmi.target.bdf_ext));
1392
if (copied < 0) {
1393
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1394
"bdf variant string is longer than the buffer can accommodate\n");
1395
return;
1396
}
1397
1398
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1399
"found and validated bdf variant smbios_type 0x%x bdf %s\n",
1400
ATH11K_SMBIOS_BDF_EXT_TYPE, ab->qmi.target.bdf_ext);
1401
}
1402
1403
int ath11k_core_check_smbios(struct ath11k_base *ab)
1404
{
1405
ab->qmi.target.bdf_ext[0] = '\0';
1406
dmi_walk(ath11k_core_check_cc_code_bdfext, ab);
1407
1408
if (ab->qmi.target.bdf_ext[0] == '\0')
1409
return -ENODATA;
1410
1411
return 0;
1412
}
1413
1414
int ath11k_core_check_dt(struct ath11k_base *ab)
1415
{
1416
#if defined(__linux__)
1417
size_t max_len = sizeof(ab->qmi.target.bdf_ext);
1418
const char *variant = NULL;
1419
struct device_node *node;
1420
1421
node = ab->dev->of_node;
1422
if (!node)
1423
return -ENOENT;
1424
1425
of_property_read_string(node, "qcom,calibration-variant",
1426
&variant);
1427
if (!variant)
1428
of_property_read_string(node, "qcom,ath11k-calibration-variant",
1429
&variant);
1430
if (!variant)
1431
return -ENODATA;
1432
1433
if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
1434
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1435
"bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
1436
variant);
1437
1438
return 0;
1439
#elif defined(__FreeBSD__)
1440
return -ENOENT;
1441
#endif
1442
}
1443
1444
enum ath11k_bdf_name_type {
1445
ATH11K_BDF_NAME_FULL,
1446
ATH11K_BDF_NAME_BUS_NAME,
1447
ATH11K_BDF_NAME_CHIP_ID,
1448
};
1449
1450
static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
1451
size_t name_len, bool with_variant,
1452
enum ath11k_bdf_name_type name_type)
1453
{
1454
/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
1455
char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = {};
1456
1457
if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
1458
scnprintf(variant, sizeof(variant), ",variant=%s",
1459
ab->qmi.target.bdf_ext);
1460
1461
switch (ab->id.bdf_search) {
1462
case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
1463
switch (name_type) {
1464
case ATH11K_BDF_NAME_FULL:
1465
scnprintf(name, name_len,
1466
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
1467
ath11k_bus_str(ab->hif.bus),
1468
ab->id.vendor, ab->id.device,
1469
ab->id.subsystem_vendor,
1470
ab->id.subsystem_device,
1471
ab->qmi.target.chip_id,
1472
ab->qmi.target.board_id,
1473
variant);
1474
break;
1475
case ATH11K_BDF_NAME_BUS_NAME:
1476
scnprintf(name, name_len,
1477
"bus=%s",
1478
ath11k_bus_str(ab->hif.bus));
1479
break;
1480
case ATH11K_BDF_NAME_CHIP_ID:
1481
scnprintf(name, name_len,
1482
"bus=%s,qmi-chip-id=%d",
1483
ath11k_bus_str(ab->hif.bus),
1484
ab->qmi.target.chip_id);
1485
break;
1486
}
1487
break;
1488
default:
1489
scnprintf(name, name_len,
1490
"bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
1491
ath11k_bus_str(ab->hif.bus),
1492
ab->qmi.target.chip_id,
1493
ab->qmi.target.board_id, variant);
1494
break;
1495
}
1496
1497
ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board name '%s'\n", name);
1498
1499
return 0;
1500
}
1501
1502
static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
1503
size_t name_len)
1504
{
1505
return __ath11k_core_create_board_name(ab, name, name_len, true,
1506
ATH11K_BDF_NAME_FULL);
1507
}
1508
1509
static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
1510
size_t name_len)
1511
{
1512
return __ath11k_core_create_board_name(ab, name, name_len, false,
1513
ATH11K_BDF_NAME_FULL);
1514
}
1515
1516
static int ath11k_core_create_bus_type_board_name(struct ath11k_base *ab, char *name,
1517
size_t name_len)
1518
{
1519
return __ath11k_core_create_board_name(ab, name, name_len, false,
1520
ATH11K_BDF_NAME_BUS_NAME);
1521
}
1522
1523
static int ath11k_core_create_chip_id_board_name(struct ath11k_base *ab, char *name,
1524
size_t name_len)
1525
{
1526
return __ath11k_core_create_board_name(ab, name, name_len, false,
1527
ATH11K_BDF_NAME_CHIP_ID);
1528
}
1529
1530
const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
1531
const char *file)
1532
{
1533
const struct firmware *fw;
1534
char path[100];
1535
int ret;
1536
1537
if (file == NULL)
1538
return ERR_PTR(-ENOENT);
1539
1540
ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
1541
1542
ret = firmware_request_nowarn(&fw, path, ab->dev);
1543
if (ret)
1544
return ERR_PTR(ret);
1545
1546
ath11k_dbg(ab, ATH11K_DBG_BOOT, "firmware request %s size %zu\n",
1547
path, fw->size);
1548
1549
return fw;
1550
}
1551
1552
void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
1553
{
1554
if (!IS_ERR(bd->fw))
1555
release_firmware(bd->fw);
1556
1557
memset(bd, 0, sizeof(*bd));
1558
}
1559
1560
static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
1561
struct ath11k_board_data *bd,
1562
#if defined(__linux__)
1563
const void *buf, size_t buf_len,
1564
#elif defined(__FreeBSD__)
1565
const u8 *buf, size_t buf_len,
1566
#endif
1567
const char *boardname,
1568
int ie_id,
1569
int name_id,
1570
int data_id)
1571
{
1572
const struct ath11k_fw_ie *hdr;
1573
bool name_match_found;
1574
int ret, board_ie_id;
1575
size_t board_ie_len;
1576
const void *board_ie_data;
1577
1578
name_match_found = false;
1579
1580
/* go through ATH11K_BD_IE_BOARD_/ATH11K_BD_IE_REGDB_ elements */
1581
while (buf_len > sizeof(struct ath11k_fw_ie)) {
1582
#if defined(__linux__)
1583
hdr = buf;
1584
#elif defined(__FreeBSD__)
1585
hdr = (const struct ath11k_fw_ie *)buf;
1586
#endif
1587
board_ie_id = le32_to_cpu(hdr->id);
1588
board_ie_len = le32_to_cpu(hdr->len);
1589
board_ie_data = hdr->data;
1590
1591
buf_len -= sizeof(*hdr);
1592
buf += sizeof(*hdr);
1593
1594
if (buf_len < ALIGN(board_ie_len, 4)) {
1595
ath11k_err(ab, "invalid %s length: %zu < %zu\n",
1596
ath11k_bd_ie_type_str(ie_id),
1597
buf_len, ALIGN(board_ie_len, 4));
1598
ret = -EINVAL;
1599
goto out;
1600
}
1601
1602
if (board_ie_id == name_id) {
1603
ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
1604
board_ie_data, board_ie_len);
1605
1606
if (board_ie_len != strlen(boardname))
1607
goto next;
1608
1609
ret = memcmp(board_ie_data, boardname, strlen(boardname));
1610
if (ret)
1611
goto next;
1612
1613
name_match_found = true;
1614
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1615
"found match %s for name '%s'",
1616
ath11k_bd_ie_type_str(ie_id),
1617
boardname);
1618
} else if (board_ie_id == data_id) {
1619
if (!name_match_found)
1620
/* no match found */
1621
goto next;
1622
1623
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1624
"found %s for '%s'",
1625
ath11k_bd_ie_type_str(ie_id),
1626
boardname);
1627
1628
bd->data = board_ie_data;
1629
bd->len = board_ie_len;
1630
1631
ret = 0;
1632
goto out;
1633
} else {
1634
ath11k_warn(ab, "unknown %s id found: %d\n",
1635
ath11k_bd_ie_type_str(ie_id),
1636
board_ie_id);
1637
}
1638
next:
1639
/* jump over the padding */
1640
board_ie_len = ALIGN(board_ie_len, 4);
1641
1642
buf_len -= board_ie_len;
1643
buf += board_ie_len;
1644
}
1645
1646
/* no match found */
1647
ret = -ENOENT;
1648
1649
out:
1650
return ret;
1651
}
1652
1653
static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
1654
struct ath11k_board_data *bd,
1655
const char *boardname,
1656
int ie_id_match,
1657
int name_id,
1658
int data_id)
1659
{
1660
size_t len, magic_len;
1661
const u8 *data;
1662
char *filename, filepath[100];
1663
size_t ie_len;
1664
#if defined(__linux__)
1665
struct ath11k_fw_ie *hdr;
1666
#elif defined(__FreeBSD__)
1667
const struct ath11k_fw_ie *hdr;
1668
#endif
1669
int ret, ie_id;
1670
1671
filename = ATH11K_BOARD_API2_FILE;
1672
1673
if (!bd->fw)
1674
bd->fw = ath11k_core_firmware_request(ab, filename);
1675
1676
if (IS_ERR(bd->fw))
1677
return PTR_ERR(bd->fw);
1678
1679
data = bd->fw->data;
1680
len = bd->fw->size;
1681
1682
ath11k_core_create_firmware_path(ab, filename,
1683
filepath, sizeof(filepath));
1684
1685
/* magic has extra null byte padded */
1686
magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
1687
if (len < magic_len) {
1688
ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
1689
filepath, len);
1690
ret = -EINVAL;
1691
goto err;
1692
}
1693
1694
if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
1695
ath11k_err(ab, "found invalid board magic\n");
1696
ret = -EINVAL;
1697
goto err;
1698
}
1699
1700
/* magic is padded to 4 bytes */
1701
magic_len = ALIGN(magic_len, 4);
1702
if (len < magic_len) {
1703
ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
1704
filepath, len);
1705
ret = -EINVAL;
1706
goto err;
1707
}
1708
1709
data += magic_len;
1710
len -= magic_len;
1711
1712
while (len > sizeof(struct ath11k_fw_ie)) {
1713
#if defined(__linux__)
1714
hdr = (struct ath11k_fw_ie *)data;
1715
#elif defined(__FreeBSD__)
1716
hdr = (const struct ath11k_fw_ie *)data;
1717
#endif
1718
ie_id = le32_to_cpu(hdr->id);
1719
ie_len = le32_to_cpu(hdr->len);
1720
1721
len -= sizeof(*hdr);
1722
data = hdr->data;
1723
1724
if (len < ALIGN(ie_len, 4)) {
1725
ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
1726
ie_id, ie_len, len);
1727
ret = -EINVAL;
1728
goto err;
1729
}
1730
1731
if (ie_id == ie_id_match) {
1732
ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
1733
ie_len,
1734
boardname,
1735
ie_id_match,
1736
name_id,
1737
data_id);
1738
if (ret == -ENOENT)
1739
/* no match found, continue */
1740
goto next;
1741
else if (ret)
1742
/* there was an error, bail out */
1743
goto err;
1744
/* either found or error, so stop searching */
1745
goto out;
1746
}
1747
next:
1748
/* jump over the padding */
1749
ie_len = ALIGN(ie_len, 4);
1750
1751
len -= ie_len;
1752
data += ie_len;
1753
}
1754
1755
out:
1756
if (!bd->data || !bd->len) {
1757
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1758
"failed to fetch %s for %s from %s\n",
1759
ath11k_bd_ie_type_str(ie_id_match),
1760
boardname, filepath);
1761
ret = -ENODATA;
1762
goto err;
1763
}
1764
1765
return 0;
1766
1767
err:
1768
ath11k_core_free_bdf(ab, bd);
1769
return ret;
1770
}
1771
1772
int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
1773
struct ath11k_board_data *bd,
1774
const char *name)
1775
{
1776
bd->fw = ath11k_core_firmware_request(ab, name);
1777
1778
if (IS_ERR(bd->fw))
1779
return PTR_ERR(bd->fw);
1780
1781
bd->data = bd->fw->data;
1782
bd->len = bd->fw->size;
1783
1784
return 0;
1785
}
1786
1787
#define BOARD_NAME_SIZE 200
1788
int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
1789
{
1790
char *boardname = NULL, *fallback_boardname = NULL, *chip_id_boardname = NULL;
1791
char *filename, filepath[100];
1792
int bd_api;
1793
int ret = 0;
1794
1795
filename = ATH11K_BOARD_API2_FILE;
1796
boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
1797
if (!boardname) {
1798
ret = -ENOMEM;
1799
goto exit;
1800
}
1801
1802
ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
1803
if (ret) {
1804
ath11k_err(ab, "failed to create board name: %d", ret);
1805
goto exit;
1806
}
1807
1808
bd_api = 2;
1809
ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1810
ATH11K_BD_IE_BOARD,
1811
ATH11K_BD_IE_BOARD_NAME,
1812
ATH11K_BD_IE_BOARD_DATA);
1813
if (!ret)
1814
goto exit;
1815
1816
fallback_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
1817
if (!fallback_boardname) {
1818
ret = -ENOMEM;
1819
goto exit;
1820
}
1821
1822
ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
1823
BOARD_NAME_SIZE);
1824
if (ret) {
1825
ath11k_err(ab, "failed to create fallback board name: %d", ret);
1826
goto exit;
1827
}
1828
1829
ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
1830
ATH11K_BD_IE_BOARD,
1831
ATH11K_BD_IE_BOARD_NAME,
1832
ATH11K_BD_IE_BOARD_DATA);
1833
if (!ret)
1834
goto exit;
1835
1836
chip_id_boardname = kzalloc(BOARD_NAME_SIZE, GFP_KERNEL);
1837
if (!chip_id_boardname) {
1838
ret = -ENOMEM;
1839
goto exit;
1840
}
1841
1842
ret = ath11k_core_create_chip_id_board_name(ab, chip_id_boardname,
1843
BOARD_NAME_SIZE);
1844
if (ret) {
1845
ath11k_err(ab, "failed to create chip id board name: %d", ret);
1846
goto exit;
1847
}
1848
1849
ret = ath11k_core_fetch_board_data_api_n(ab, bd, chip_id_boardname,
1850
ATH11K_BD_IE_BOARD,
1851
ATH11K_BD_IE_BOARD_NAME,
1852
ATH11K_BD_IE_BOARD_DATA);
1853
1854
if (!ret)
1855
goto exit;
1856
1857
bd_api = 1;
1858
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
1859
if (ret) {
1860
ath11k_core_create_firmware_path(ab, filename,
1861
filepath, sizeof(filepath));
1862
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1863
boardname, filepath);
1864
if (memcmp(boardname, fallback_boardname, strlen(boardname)))
1865
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1866
fallback_boardname, filepath);
1867
1868
ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1869
chip_id_boardname, filepath);
1870
1871
ath11k_err(ab, "failed to fetch board.bin from %s\n",
1872
ab->hw_params.fw.dir);
1873
}
1874
1875
exit:
1876
kfree(boardname);
1877
kfree(fallback_boardname);
1878
kfree(chip_id_boardname);
1879
1880
if (!ret)
1881
ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", bd_api);
1882
1883
return ret;
1884
}
1885
1886
int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
1887
{
1888
char boardname[BOARD_NAME_SIZE], default_boardname[BOARD_NAME_SIZE];
1889
int ret;
1890
1891
ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
1892
if (ret) {
1893
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1894
"failed to create board name for regdb: %d", ret);
1895
goto exit;
1896
}
1897
1898
ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1899
ATH11K_BD_IE_REGDB,
1900
ATH11K_BD_IE_REGDB_NAME,
1901
ATH11K_BD_IE_REGDB_DATA);
1902
if (!ret)
1903
goto exit;
1904
1905
ret = ath11k_core_create_bus_type_board_name(ab, default_boardname,
1906
BOARD_NAME_SIZE);
1907
if (ret) {
1908
ath11k_dbg(ab, ATH11K_DBG_BOOT,
1909
"failed to create default board name for regdb: %d", ret);
1910
goto exit;
1911
}
1912
1913
ret = ath11k_core_fetch_board_data_api_n(ab, bd, default_boardname,
1914
ATH11K_BD_IE_REGDB,
1915
ATH11K_BD_IE_REGDB_NAME,
1916
ATH11K_BD_IE_REGDB_DATA);
1917
if (!ret)
1918
goto exit;
1919
1920
ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
1921
if (ret)
1922
ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
1923
ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
1924
1925
exit:
1926
if (!ret)
1927
ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");
1928
1929
return ret;
1930
}
1931
1932
static void ath11k_core_stop(struct ath11k_base *ab)
1933
{
1934
if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
1935
ath11k_qmi_firmware_stop(ab);
1936
1937
ath11k_hif_stop(ab);
1938
ath11k_wmi_detach(ab);
1939
ath11k_dp_pdev_reo_cleanup(ab);
1940
1941
/* De-Init of components as needed */
1942
}
1943
1944
static int ath11k_core_soc_create(struct ath11k_base *ab)
1945
{
1946
int ret;
1947
1948
if (ath11k_ftm_mode) {
1949
ab->fw_mode = ATH11K_FIRMWARE_MODE_FTM;
1950
ath11k_info(ab, "Booting in factory test mode\n");
1951
}
1952
1953
ret = ath11k_qmi_init_service(ab);
1954
if (ret) {
1955
ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
1956
return ret;
1957
}
1958
1959
ret = ath11k_debugfs_soc_create(ab);
1960
if (ret) {
1961
ath11k_err(ab, "failed to create ath11k debugfs\n");
1962
goto err_qmi_deinit;
1963
}
1964
1965
ret = ath11k_hif_power_up(ab);
1966
if (ret) {
1967
ath11k_err(ab, "failed to power up :%d\n", ret);
1968
goto err_debugfs_reg;
1969
}
1970
1971
return 0;
1972
1973
err_debugfs_reg:
1974
ath11k_debugfs_soc_destroy(ab);
1975
err_qmi_deinit:
1976
ath11k_qmi_deinit_service(ab);
1977
return ret;
1978
}
1979
1980
static void ath11k_core_soc_destroy(struct ath11k_base *ab)
1981
{
1982
ath11k_debugfs_soc_destroy(ab);
1983
ath11k_dp_free(ab);
1984
ath11k_reg_free(ab);
1985
ath11k_qmi_deinit_service(ab);
1986
}
1987
1988
static int ath11k_core_pdev_create(struct ath11k_base *ab)
1989
{
1990
int ret;
1991
1992
ret = ath11k_debugfs_pdev_create(ab);
1993
if (ret) {
1994
ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
1995
return ret;
1996
}
1997
1998
ret = ath11k_dp_pdev_alloc(ab);
1999
if (ret) {
2000
ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
2001
goto err_pdev_debug;
2002
}
2003
2004
ret = ath11k_mac_register(ab);
2005
if (ret) {
2006
ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
2007
goto err_dp_pdev_free;
2008
}
2009
2010
ret = ath11k_thermal_register(ab);
2011
if (ret) {
2012
ath11k_err(ab, "could not register thermal device: %d\n",
2013
ret);
2014
goto err_mac_unregister;
2015
}
2016
2017
ret = ath11k_spectral_init(ab);
2018
if (ret) {
2019
ath11k_err(ab, "failed to init spectral %d\n", ret);
2020
goto err_thermal_unregister;
2021
}
2022
2023
return 0;
2024
2025
err_thermal_unregister:
2026
ath11k_thermal_unregister(ab);
2027
err_mac_unregister:
2028
ath11k_mac_unregister(ab);
2029
err_dp_pdev_free:
2030
ath11k_dp_pdev_free(ab);
2031
err_pdev_debug:
2032
ath11k_debugfs_pdev_destroy(ab);
2033
2034
return ret;
2035
}
2036
2037
static void ath11k_core_pdev_suspend_target(struct ath11k_base *ab)
2038
{
2039
struct ath11k *ar;
2040
struct ath11k_pdev *pdev;
2041
unsigned long time_left;
2042
int ret;
2043
int i;
2044
2045
if (!ab->hw_params.pdev_suspend)
2046
return;
2047
2048
for (i = 0; i < ab->num_radios; i++) {
2049
pdev = &ab->pdevs[i];
2050
ar = pdev->ar;
2051
2052
reinit_completion(&ab->htc_suspend);
2053
2054
ret = ath11k_wmi_pdev_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR,
2055
pdev->pdev_id);
2056
if (ret) {
2057
ath11k_warn(ab, "could not suspend target :%d\n", ret);
2058
/* pointless to try other pdevs */
2059
return;
2060
}
2061
2062
time_left = wait_for_completion_timeout(&ab->htc_suspend, 3 * HZ);
2063
2064
if (!time_left) {
2065
ath11k_warn(ab, "suspend timed out - target pause event never came\n");
2066
/* pointless to try other pdevs */
2067
return;
2068
}
2069
}
2070
}
2071
2072
static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
2073
{
2074
ath11k_spectral_deinit(ab);
2075
ath11k_thermal_unregister(ab);
2076
ath11k_mac_unregister(ab);
2077
ath11k_core_pdev_suspend_target(ab);
2078
ath11k_hif_irq_disable(ab);
2079
ath11k_dp_pdev_free(ab);
2080
ath11k_debugfs_pdev_destroy(ab);
2081
}
2082
2083
static int ath11k_core_start(struct ath11k_base *ab)
2084
{
2085
int ret;
2086
2087
ret = ath11k_wmi_attach(ab);
2088
if (ret) {
2089
ath11k_err(ab, "failed to attach wmi: %d\n", ret);
2090
return ret;
2091
}
2092
2093
ret = ath11k_htc_init(ab);
2094
if (ret) {
2095
ath11k_err(ab, "failed to init htc: %d\n", ret);
2096
goto err_wmi_detach;
2097
}
2098
2099
ret = ath11k_hif_start(ab);
2100
if (ret) {
2101
ath11k_err(ab, "failed to start HIF: %d\n", ret);
2102
goto err_wmi_detach;
2103
}
2104
2105
ret = ath11k_htc_wait_target(&ab->htc);
2106
if (ret) {
2107
ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
2108
goto err_hif_stop;
2109
}
2110
2111
ret = ath11k_dp_htt_connect(&ab->dp);
2112
if (ret) {
2113
ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
2114
goto err_hif_stop;
2115
}
2116
2117
ret = ath11k_wmi_connect(ab);
2118
if (ret) {
2119
ath11k_err(ab, "failed to connect wmi: %d\n", ret);
2120
goto err_hif_stop;
2121
}
2122
2123
ret = ath11k_htc_start(&ab->htc);
2124
if (ret) {
2125
ath11k_err(ab, "failed to start HTC: %d\n", ret);
2126
goto err_hif_stop;
2127
}
2128
2129
ret = ath11k_wmi_wait_for_service_ready(ab);
2130
if (ret) {
2131
ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
2132
ret);
2133
goto err_hif_stop;
2134
}
2135
2136
ret = ath11k_mac_allocate(ab);
2137
if (ret) {
2138
ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
2139
ret);
2140
goto err_hif_stop;
2141
}
2142
2143
ath11k_dp_pdev_pre_alloc(ab);
2144
2145
ret = ath11k_dp_pdev_reo_setup(ab);
2146
if (ret) {
2147
ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
2148
goto err_mac_destroy;
2149
}
2150
2151
ret = ath11k_wmi_cmd_init(ab);
2152
if (ret) {
2153
ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
2154
goto err_reo_cleanup;
2155
}
2156
2157
ret = ath11k_wmi_wait_for_unified_ready(ab);
2158
if (ret) {
2159
ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
2160
ret);
2161
goto err_reo_cleanup;
2162
}
2163
2164
/* put hardware to DBS mode */
2165
if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxdma_per_pdev > 1) {
2166
ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
2167
if (ret) {
2168
ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
2169
goto err_hif_stop;
2170
}
2171
}
2172
2173
ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
2174
if (ret) {
2175
ath11k_err(ab, "failed to send htt version request message: %d\n",
2176
ret);
2177
goto err_reo_cleanup;
2178
}
2179
2180
return 0;
2181
2182
err_reo_cleanup:
2183
ath11k_dp_pdev_reo_cleanup(ab);
2184
err_mac_destroy:
2185
ath11k_mac_destroy(ab);
2186
err_hif_stop:
2187
ath11k_hif_stop(ab);
2188
err_wmi_detach:
2189
ath11k_wmi_detach(ab);
2190
2191
return ret;
2192
}
2193
2194
static int ath11k_core_start_firmware(struct ath11k_base *ab,
2195
enum ath11k_firmware_mode mode)
2196
{
2197
int ret;
2198
2199
ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2,
2200
&ab->qmi.ce_cfg.shadow_reg_v2_len);
2201
2202
ret = ath11k_qmi_firmware_start(ab, mode);
2203
if (ret) {
2204
ath11k_err(ab, "failed to send firmware start: %d\n", ret);
2205
return ret;
2206
}
2207
2208
return ret;
2209
}
2210
2211
int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
2212
{
2213
int ret;
2214
2215
switch (ath11k_crypto_mode) {
2216
case ATH11K_CRYPT_MODE_SW:
2217
set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2218
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2219
break;
2220
case ATH11K_CRYPT_MODE_HW:
2221
clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
2222
clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2223
break;
2224
default:
2225
ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
2226
return -EINVAL;
2227
}
2228
2229
ret = ath11k_core_start_firmware(ab, ab->fw_mode);
2230
if (ret) {
2231
ath11k_err(ab, "failed to start firmware: %d\n", ret);
2232
return ret;
2233
}
2234
2235
ret = ath11k_ce_init_pipes(ab);
2236
if (ret) {
2237
ath11k_err(ab, "failed to initialize CE: %d\n", ret);
2238
goto err_firmware_stop;
2239
}
2240
2241
ret = ath11k_dp_alloc(ab);
2242
if (ret) {
2243
ath11k_err(ab, "failed to init DP: %d\n", ret);
2244
goto err_firmware_stop;
2245
}
2246
2247
if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
2248
set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
2249
2250
mutex_lock(&ab->core_lock);
2251
ret = ath11k_core_start(ab);
2252
if (ret) {
2253
ath11k_err(ab, "failed to start core: %d\n", ret);
2254
goto err_dp_free;
2255
}
2256
2257
ret = ath11k_core_pdev_create(ab);
2258
if (ret) {
2259
ath11k_err(ab, "failed to create pdev core: %d\n", ret);
2260
goto err_core_stop;
2261
}
2262
ath11k_hif_irq_enable(ab);
2263
mutex_unlock(&ab->core_lock);
2264
2265
return 0;
2266
2267
err_core_stop:
2268
ath11k_core_stop(ab);
2269
ath11k_mac_destroy(ab);
2270
err_dp_free:
2271
ath11k_dp_free(ab);
2272
mutex_unlock(&ab->core_lock);
2273
err_firmware_stop:
2274
ath11k_qmi_firmware_stop(ab);
2275
2276
return ret;
2277
}
2278
2279
static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
2280
{
2281
int ret;
2282
2283
mutex_lock(&ab->core_lock);
2284
ath11k_thermal_unregister(ab);
2285
ath11k_dp_pdev_free(ab);
2286
ath11k_spectral_deinit(ab);
2287
ath11k_ce_cleanup_pipes(ab);
2288
ath11k_wmi_detach(ab);
2289
ath11k_dp_pdev_reo_cleanup(ab);
2290
mutex_unlock(&ab->core_lock);
2291
2292
ath11k_dp_free(ab);
2293
ath11k_hal_srng_clear(ab);
2294
2295
ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
2296
2297
clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
2298
2299
ret = ath11k_core_qmi_firmware_ready(ab);
2300
if (ret)
2301
goto err_hal_srng_deinit;
2302
2303
clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
2304
2305
return 0;
2306
2307
err_hal_srng_deinit:
2308
ath11k_hal_srng_deinit(ab);
2309
return ret;
2310
}
2311
2312
void ath11k_core_halt(struct ath11k *ar)
2313
{
2314
struct ath11k_base *ab = ar->ab;
2315
struct list_head *pos, *n;
2316
2317
lockdep_assert_held(&ar->conf_mutex);
2318
2319
ar->num_created_vdevs = 0;
2320
ar->allocated_vdev_map = 0;
2321
2322
ath11k_mac_scan_finish(ar);
2323
ath11k_mac_peer_cleanup_all(ar);
2324
cancel_delayed_work_sync(&ar->scan.timeout);
2325
cancel_work_sync(&ar->channel_update_work);
2326
cancel_work_sync(&ar->regd_update_work);
2327
cancel_work_sync(&ab->update_11d_work);
2328
2329
rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
2330
synchronize_rcu();
2331
2332
spin_lock_bh(&ar->data_lock);
2333
list_for_each_safe(pos, n, &ar->arvifs)
2334
list_del_init(pos);
2335
spin_unlock_bh(&ar->data_lock);
2336
2337
idr_init(&ar->txmgmt_idr);
2338
}
2339
2340
static void ath11k_update_11d(struct work_struct *work)
2341
{
2342
struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
2343
struct ath11k *ar;
2344
struct ath11k_pdev *pdev;
2345
int ret, i;
2346
2347
for (i = 0; i < ab->num_radios; i++) {
2348
pdev = &ab->pdevs[i];
2349
ar = pdev->ar;
2350
2351
spin_lock_bh(&ab->base_lock);
2352
memcpy(&ar->alpha2, &ab->new_alpha2, 2);
2353
spin_unlock_bh(&ab->base_lock);
2354
2355
ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c for pdev %d\n",
2356
ar->alpha2[0], ar->alpha2[1], i);
2357
2358
ret = ath11k_reg_set_cc(ar);
2359
if (ret)
2360
ath11k_warn(ar->ab,
2361
"pdev id %d failed set current country code: %d\n",
2362
i, ret);
2363
}
2364
}
2365
2366
void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
2367
{
2368
struct ath11k *ar;
2369
struct ath11k_pdev *pdev;
2370
int i;
2371
2372
spin_lock_bh(&ab->base_lock);
2373
ab->stats.fw_crash_counter++;
2374
spin_unlock_bh(&ab->base_lock);
2375
2376
for (i = 0; i < ab->num_radios; i++) {
2377
pdev = &ab->pdevs[i];
2378
ar = pdev->ar;
2379
if (!ar || ar->state == ATH11K_STATE_OFF ||
2380
ar->state == ATH11K_STATE_FTM)
2381
continue;
2382
2383
ieee80211_stop_queues(ar->hw);
2384
ath11k_mac_drain_tx(ar);
2385
ar->state_11d = ATH11K_11D_IDLE;
2386
complete(&ar->completed_11d_scan);
2387
complete(&ar->scan.started);
2388
complete_all(&ar->scan.completed);
2389
complete(&ar->scan.on_channel);
2390
complete(&ar->peer_assoc_done);
2391
complete(&ar->peer_delete_done);
2392
complete(&ar->install_key_done);
2393
complete(&ar->vdev_setup_done);
2394
complete(&ar->vdev_delete_done);
2395
complete(&ar->bss_survey_done);
2396
complete(&ar->thermal.wmi_sync);
2397
2398
wake_up(&ar->dp.tx_empty_waitq);
2399
idr_for_each(&ar->txmgmt_idr,
2400
ath11k_mac_tx_mgmt_pending_free, ar);
2401
idr_destroy(&ar->txmgmt_idr);
2402
wake_up(&ar->txmgmt_empty_waitq);
2403
2404
ar->monitor_vdev_id = -1;
2405
clear_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags);
2406
clear_bit(ATH11K_FLAG_MONITOR_VDEV_CREATED, &ar->monitor_flags);
2407
}
2408
2409
wake_up(&ab->wmi_ab.tx_credits_wq);
2410
wake_up(&ab->peer_mapping_wq);
2411
2412
reinit_completion(&ab->driver_recovery);
2413
}
2414
2415
static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
2416
{
2417
struct ath11k *ar;
2418
struct ath11k_pdev *pdev;
2419
int i;
2420
2421
for (i = 0; i < ab->num_radios; i++) {
2422
pdev = &ab->pdevs[i];
2423
ar = pdev->ar;
2424
if (!ar || ar->state == ATH11K_STATE_OFF)
2425
continue;
2426
2427
mutex_lock(&ar->conf_mutex);
2428
2429
switch (ar->state) {
2430
case ATH11K_STATE_ON:
2431
ar->state = ATH11K_STATE_RESTARTING;
2432
ath11k_core_halt(ar);
2433
ieee80211_restart_hw(ar->hw);
2434
break;
2435
case ATH11K_STATE_OFF:
2436
ath11k_warn(ab,
2437
"cannot restart radio %d that hasn't been started\n",
2438
i);
2439
break;
2440
case ATH11K_STATE_RESTARTING:
2441
break;
2442
case ATH11K_STATE_RESTARTED:
2443
ar->state = ATH11K_STATE_WEDGED;
2444
fallthrough;
2445
case ATH11K_STATE_WEDGED:
2446
ath11k_warn(ab,
2447
"device is wedged, will not restart radio %d\n", i);
2448
break;
2449
case ATH11K_STATE_FTM:
2450
ath11k_dbg(ab, ATH11K_DBG_TESTMODE,
2451
"fw mode reset done radio %d\n", i);
2452
break;
2453
}
2454
2455
mutex_unlock(&ar->conf_mutex);
2456
}
2457
complete(&ab->driver_recovery);
2458
}
2459
2460
static void ath11k_core_restart(struct work_struct *work)
2461
{
2462
struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
2463
int ret;
2464
2465
ret = ath11k_core_reconfigure_on_crash(ab);
2466
if (ret) {
2467
ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
2468
return;
2469
}
2470
2471
if (ab->is_reset)
2472
complete_all(&ab->reconfigure_complete);
2473
2474
if (!ab->is_reset)
2475
ath11k_core_post_reconfigure_recovery(ab);
2476
2477
complete(&ab->restart_completed);
2478
}
2479
2480
static void ath11k_core_reset(struct work_struct *work)
2481
{
2482
struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work);
2483
int reset_count, fail_cont_count;
2484
long time_left;
2485
2486
if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) {
2487
ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags);
2488
return;
2489
}
2490
2491
/* Sometimes the recovery will fail and then the next all recovery fail,
2492
* this is to avoid infinite recovery since it can not recovery success.
2493
*/
2494
fail_cont_count = atomic_read(&ab->fail_cont_count);
2495
2496
if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL)
2497
return;
2498
2499
if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST &&
2500
time_before(jiffies, ab->reset_fail_timeout))
2501
return;
2502
2503
reset_count = atomic_inc_return(&ab->reset_count);
2504
2505
if (reset_count > 1) {
2506
/* Sometimes it happened another reset worker before the previous one
2507
* completed, then the second reset worker will destroy the previous one,
2508
* thus below is to avoid that.
2509
*/
2510
ath11k_warn(ab, "already resetting count %d\n", reset_count);
2511
2512
reinit_completion(&ab->reset_complete);
2513
time_left = wait_for_completion_timeout(&ab->reset_complete,
2514
ATH11K_RESET_TIMEOUT_HZ);
2515
2516
if (time_left) {
2517
ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n");
2518
atomic_dec(&ab->reset_count);
2519
return;
2520
}
2521
2522
ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ;
2523
/* Record the continuous recovery fail count when recovery failed*/
2524
atomic_inc(&ab->fail_cont_count);
2525
}
2526
2527
ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n");
2528
2529
ab->is_reset = true;
2530
atomic_set(&ab->recovery_count, 0);
2531
reinit_completion(&ab->recovery_start);
2532
atomic_set(&ab->recovery_start_count, 0);
2533
2534
ath11k_coredump_collect(ab);
2535
ath11k_core_pre_reconfigure_recovery(ab);
2536
2537
reinit_completion(&ab->reconfigure_complete);
2538
ath11k_core_post_reconfigure_recovery(ab);
2539
2540
ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
2541
2542
time_left = wait_for_completion_timeout(&ab->recovery_start,
2543
ATH11K_RECOVER_START_TIMEOUT_HZ);
2544
2545
ath11k_hif_irq_disable(ab);
2546
ath11k_hif_ce_irq_disable(ab);
2547
2548
ath11k_hif_power_down(ab, false);
2549
ath11k_hif_power_up(ab);
2550
2551
ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
2552
}
2553
2554
static int ath11k_init_hw_params(struct ath11k_base *ab)
2555
{
2556
const struct ath11k_hw_params *hw_params = NULL;
2557
int i;
2558
2559
for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
2560
hw_params = &ath11k_hw_params[i];
2561
2562
if (hw_params->hw_rev == ab->hw_rev)
2563
break;
2564
}
2565
2566
if (i == ARRAY_SIZE(ath11k_hw_params)) {
2567
ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
2568
return -EINVAL;
2569
}
2570
2571
ab->hw_params = *hw_params;
2572
2573
ath11k_info(ab, "%s\n", ab->hw_params.name);
2574
2575
return 0;
2576
}
2577
2578
int ath11k_core_pre_init(struct ath11k_base *ab)
2579
{
2580
int ret;
2581
2582
ret = ath11k_init_hw_params(ab);
2583
if (ret) {
2584
ath11k_err(ab, "failed to get hw params: %d\n", ret);
2585
return ret;
2586
}
2587
2588
ret = ath11k_fw_pre_init(ab);
2589
if (ret) {
2590
ath11k_err(ab, "failed to pre init firmware: %d", ret);
2591
return ret;
2592
}
2593
2594
return 0;
2595
}
2596
EXPORT_SYMBOL(ath11k_core_pre_init);
2597
2598
static int ath11k_core_pm_notify(struct notifier_block *nb,
2599
unsigned long action, void *nouse)
2600
{
2601
struct ath11k_base *ab = container_of(nb, struct ath11k_base,
2602
pm_nb);
2603
2604
switch (action) {
2605
case PM_SUSPEND_PREPARE:
2606
ab->actual_pm_policy = ab->pm_policy;
2607
break;
2608
case PM_HIBERNATION_PREPARE:
2609
ab->actual_pm_policy = ATH11K_PM_DEFAULT;
2610
break;
2611
default:
2612
break;
2613
}
2614
2615
return NOTIFY_OK;
2616
}
2617
2618
static int ath11k_core_pm_notifier_register(struct ath11k_base *ab)
2619
{
2620
ab->pm_nb.notifier_call = ath11k_core_pm_notify;
2621
return register_pm_notifier(&ab->pm_nb);
2622
}
2623
2624
void ath11k_core_pm_notifier_unregister(struct ath11k_base *ab)
2625
{
2626
int ret;
2627
2628
ret = unregister_pm_notifier(&ab->pm_nb);
2629
if (ret)
2630
/* just warn here, there is nothing can be done in fail case */
2631
ath11k_warn(ab, "failed to unregister PM notifier %d\n", ret);
2632
}
2633
EXPORT_SYMBOL(ath11k_core_pm_notifier_unregister);
2634
2635
int ath11k_core_init(struct ath11k_base *ab)
2636
{
2637
const struct dmi_system_id *dmi_id;
2638
int ret;
2639
2640
dmi_id = dmi_first_match(ath11k_pm_quirk_table);
2641
if (dmi_id)
2642
ab->pm_policy = (kernel_ulong_t)dmi_id->driver_data;
2643
else
2644
ab->pm_policy = ATH11K_PM_DEFAULT;
2645
2646
ath11k_dbg(ab, ATH11K_DBG_BOOT, "pm policy %u\n", ab->pm_policy);
2647
2648
ret = ath11k_core_pm_notifier_register(ab);
2649
if (ret) {
2650
ath11k_err(ab, "failed to register PM notifier: %d\n", ret);
2651
return ret;
2652
}
2653
2654
ret = ath11k_core_soc_create(ab);
2655
if (ret) {
2656
ath11k_err(ab, "failed to create soc core: %d\n", ret);
2657
goto err_unregister_pm_notifier;
2658
}
2659
2660
return 0;
2661
2662
err_unregister_pm_notifier:
2663
ath11k_core_pm_notifier_unregister(ab);
2664
2665
return ret;
2666
}
2667
EXPORT_SYMBOL(ath11k_core_init);
2668
2669
void ath11k_core_deinit(struct ath11k_base *ab)
2670
{
2671
mutex_lock(&ab->core_lock);
2672
2673
ath11k_core_pdev_destroy(ab);
2674
ath11k_core_stop(ab);
2675
2676
mutex_unlock(&ab->core_lock);
2677
2678
ath11k_hif_power_down(ab, false);
2679
ath11k_mac_destroy(ab);
2680
ath11k_core_soc_destroy(ab);
2681
ath11k_core_pm_notifier_unregister(ab);
2682
}
2683
EXPORT_SYMBOL(ath11k_core_deinit);
2684
2685
void ath11k_core_free(struct ath11k_base *ab)
2686
{
2687
destroy_workqueue(ab->workqueue_aux);
2688
destroy_workqueue(ab->workqueue);
2689
2690
kfree(ab);
2691
}
2692
EXPORT_SYMBOL(ath11k_core_free);
2693
2694
struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
2695
enum ath11k_bus bus)
2696
{
2697
struct ath11k_base *ab;
2698
2699
ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
2700
if (!ab)
2701
return NULL;
2702
2703
init_completion(&ab->driver_recovery);
2704
2705
ab->workqueue = create_singlethread_workqueue("ath11k_wq");
2706
if (!ab->workqueue)
2707
goto err_sc_free;
2708
2709
ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq");
2710
if (!ab->workqueue_aux)
2711
goto err_free_wq;
2712
2713
mutex_init(&ab->core_lock);
2714
mutex_init(&ab->tbl_mtx_lock);
2715
spin_lock_init(&ab->base_lock);
2716
mutex_init(&ab->vdev_id_11d_lock);
2717
init_completion(&ab->reset_complete);
2718
init_completion(&ab->reconfigure_complete);
2719
init_completion(&ab->recovery_start);
2720
2721
INIT_LIST_HEAD(&ab->peers);
2722
init_waitqueue_head(&ab->peer_mapping_wq);
2723
init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
2724
init_waitqueue_head(&ab->qmi.cold_boot_waitq);
2725
INIT_WORK(&ab->restart_work, ath11k_core_restart);
2726
INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
2727
INIT_WORK(&ab->reset_work, ath11k_core_reset);
2728
INIT_WORK(&ab->dump_work, ath11k_coredump_upload);
2729
timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
2730
init_completion(&ab->htc_suspend);
2731
init_completion(&ab->wow.wakeup_completed);
2732
init_completion(&ab->restart_completed);
2733
2734
ab->dev = dev;
2735
ab->hif.bus = bus;
2736
2737
return ab;
2738
2739
err_free_wq:
2740
destroy_workqueue(ab->workqueue);
2741
err_sc_free:
2742
kfree(ab);
2743
return NULL;
2744
}
2745
EXPORT_SYMBOL(ath11k_core_alloc);
2746
2747
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
2748
MODULE_LICENSE("Dual BSD/GPL");
2749
2750