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