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