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
ath11k_fw_stats_pdevs_free(struct list_head * head)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
ath11k_fw_stats_vdevs_free(struct list_head * head)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
ath11k_fw_stats_bcn_free(struct list_head * head)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
ath11k_fw_stats_init(struct ath11k * ar)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
ath11k_fw_stats_free(struct ath11k_fw_stats * stats)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
ath11k_core_coldboot_cal_support(struct ath11k_base * ab)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 */
ath11k_core_continue_suspend_resume(struct ath11k_base * ab)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
ath11k_core_suspend_wow(struct ath11k_base * ab)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
ath11k_core_suspend_default(struct ath11k_base * ab)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
ath11k_core_suspend(struct ath11k_base * ab)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
ath11k_core_suspend_late(struct ath11k_base * ab)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
ath11k_core_resume_early(struct ath11k_base * ab)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
ath11k_core_resume_default(struct ath11k_base * ab)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
ath11k_core_resume_wow(struct ath11k_base * ab)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
ath11k_core_resume(struct ath11k_base * ab)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
ath11k_core_check_cc_code_bdfext(const struct dmi_header * hdr,void * data)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
ath11k_core_check_smbios(struct ath11k_base * ab)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
ath11k_core_check_dt(struct ath11k_base * ab)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
__ath11k_core_create_board_name(struct ath11k_base * ab,char * name,size_t name_len,bool with_variant,enum ath11k_bdf_name_type name_type)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
ath11k_core_create_board_name(struct ath11k_base * ab,char * name,size_t name_len)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
ath11k_core_create_fallback_board_name(struct ath11k_base * ab,char * name,size_t name_len)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
ath11k_core_create_bus_type_board_name(struct ath11k_base * ab,char * name,size_t name_len)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
ath11k_core_create_chip_id_board_name(struct ath11k_base * ab,char * name,size_t name_len)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
ath11k_core_firmware_request(struct ath11k_base * ab,const char * file)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
ath11k_core_free_bdf(struct ath11k_base * ab,struct ath11k_board_data * bd)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
ath11k_core_parse_bd_ie_board(struct ath11k_base * ab,struct ath11k_board_data * bd,const void * buf,size_t buf_len,const char * boardname,int ie_id,int name_id,int data_id)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
ath11k_core_fetch_board_data_api_n(struct ath11k_base * ab,struct ath11k_board_data * bd,const char * boardname,int ie_id_match,int name_id,int data_id)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
ath11k_core_fetch_board_data_api_1(struct ath11k_base * ab,struct ath11k_board_data * bd,const char * name)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
ath11k_core_fetch_bdf(struct ath11k_base * ab,struct ath11k_board_data * bd)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
ath11k_core_fetch_regdb(struct ath11k_base * ab,struct ath11k_board_data * bd)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
ath11k_core_stop(struct ath11k_base * ab)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
ath11k_core_soc_create(struct ath11k_base * ab)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
ath11k_core_soc_destroy(struct ath11k_base * ab)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
ath11k_core_pdev_create(struct ath11k_base * ab)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
ath11k_core_pdev_suspend_target(struct ath11k_base * ab)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
ath11k_core_pdev_destroy(struct ath11k_base * ab)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
ath11k_core_start(struct ath11k_base * ab)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
ath11k_core_start_firmware(struct ath11k_base * ab,enum ath11k_firmware_mode mode)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
ath11k_core_qmi_firmware_ready(struct ath11k_base * ab)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
ath11k_core_reconfigure_on_crash(struct ath11k_base * ab)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
ath11k_core_halt(struct ath11k * ar)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
ath11k_update_11d(struct work_struct * work)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
ath11k_core_pre_reconfigure_recovery(struct ath11k_base * ab)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
ath11k_core_post_reconfigure_recovery(struct ath11k_base * ab)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
ath11k_core_restart(struct work_struct * work)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
ath11k_core_reset(struct work_struct * work)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
ath11k_init_hw_params(struct ath11k_base * ab)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
ath11k_core_pre_init(struct ath11k_base * ab)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
ath11k_core_pm_notify(struct notifier_block * nb,unsigned long action,void * nouse)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
ath11k_core_pm_notifier_register(struct ath11k_base * ab)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
ath11k_core_pm_notifier_unregister(struct ath11k_base * ab)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
ath11k_core_init(struct ath11k_base * ab)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
ath11k_core_deinit(struct ath11k_base * ab)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
ath11k_core_free(struct ath11k_base * ab)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
ath11k_core_alloc(struct device * dev,size_t priv_size,enum ath11k_bus bus)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