xref: /linux/drivers/net/wireless/ath/ath11k/core.c (revision 94737ef56b610d94a24fadfb8386fc17dbd79ddd)
1 // SPDX-License-Identifier: BSD-3-Clause-Clear
2 /*
3  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
4  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
5  */
6 
7 #include <linux/module.h>
8 #include <linux/slab.h>
9 #include <linux/remoteproc.h>
10 #include <linux/firmware.h>
11 #include <linux/of.h>
12 
13 #include "core.h"
14 #include "dp_tx.h"
15 #include "dp_rx.h"
16 #include "debug.h"
17 #include "hif.h"
18 #include "wow.h"
19 
20 unsigned int ath11k_debug_mask;
21 EXPORT_SYMBOL(ath11k_debug_mask);
22 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
23 MODULE_PARM_DESC(debug_mask, "Debugging mask");
24 
25 static unsigned int ath11k_crypto_mode;
26 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
27 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
28 
29 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
30 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
31 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
32 MODULE_PARM_DESC(frame_mode,
33 		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
34 
35 static const struct ath11k_hw_params ath11k_hw_params[] = {
36 	{
37 		.hw_rev = ATH11K_HW_IPQ8074,
38 		.name = "ipq8074 hw2.0",
39 		.fw = {
40 			.dir = "IPQ8074/hw2.0",
41 			.board_size = 256 * 1024,
42 			.cal_offset = 128 * 1024,
43 		},
44 		.max_radios = 3,
45 		.bdf_addr = 0x4B0C0000,
46 		.hw_ops = &ipq8074_ops,
47 		.ring_mask = &ath11k_hw_ring_mask_ipq8074,
48 		.internal_sleep_clock = false,
49 		.regs = &ipq8074_regs,
50 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
51 		.host_ce_config = ath11k_host_ce_config_ipq8074,
52 		.ce_count = 12,
53 		.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
54 		.target_ce_count = 11,
55 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
56 		.svc_to_ce_map_len = 21,
57 		.rfkill_pin = 0,
58 		.rfkill_cfg = 0,
59 		.rfkill_on_level = 0,
60 		.single_pdev_only = false,
61 		.rxdma1_enable = true,
62 		.num_rxmda_per_pdev = 1,
63 		.rx_mac_buf_ring = false,
64 		.vdev_start_delay = false,
65 		.htt_peer_map_v2 = true,
66 
67 		.spectral = {
68 			.fft_sz = 2,
69 			/* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
70 			 * so added pad size as 2 bytes to compensate the BIN size
71 			 */
72 			.fft_pad_sz = 2,
73 			.summary_pad_sz = 0,
74 			.fft_hdr_len = 16,
75 			.max_fft_bins = 512,
76 		},
77 
78 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
79 					BIT(NL80211_IFTYPE_AP) |
80 					BIT(NL80211_IFTYPE_MESH_POINT),
81 		.supports_monitor = true,
82 		.full_monitor_mode = false,
83 		.supports_shadow_regs = false,
84 		.idle_ps = false,
85 		.supports_sta_ps = false,
86 		.cold_boot_calib = true,
87 		.fw_mem_mode = 0,
88 		.num_vdevs = 16 + 1,
89 		.num_peers = 512,
90 		.supports_suspend = false,
91 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
92 		.supports_regdb = false,
93 		.fix_l1ss = true,
94 		.credit_flow = false,
95 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
96 		.hal_params = &ath11k_hw_hal_params_ipq8074,
97 		.supports_dynamic_smps_6ghz = false,
98 		.alloc_cacheable_memory = true,
99 		.supports_rssi_stats = false,
100 		.fw_wmi_diag_event = false,
101 		.current_cc_support = false,
102 		.dbr_debug_support = true,
103 		.global_reset = false,
104 		.bios_sar_capa = NULL,
105 		.m3_fw_support = false,
106 		.fixed_bdf_addr = true,
107 		.fixed_mem_region = true,
108 		.static_window_map = false,
109 		.hybrid_bus_type = false,
110 		.dp_window_idx = 0,
111 		.ce_window_idx = 0,
112 		.fixed_fw_mem = false,
113 	},
114 	{
115 		.hw_rev = ATH11K_HW_IPQ6018_HW10,
116 		.name = "ipq6018 hw1.0",
117 		.fw = {
118 			.dir = "IPQ6018/hw1.0",
119 			.board_size = 256 * 1024,
120 			.cal_offset = 128 * 1024,
121 		},
122 		.max_radios = 2,
123 		.bdf_addr = 0x4ABC0000,
124 		.hw_ops = &ipq6018_ops,
125 		.ring_mask = &ath11k_hw_ring_mask_ipq8074,
126 		.internal_sleep_clock = false,
127 		.regs = &ipq8074_regs,
128 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
129 		.host_ce_config = ath11k_host_ce_config_ipq8074,
130 		.ce_count = 12,
131 		.target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
132 		.target_ce_count = 11,
133 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
134 		.svc_to_ce_map_len = 19,
135 		.rfkill_pin = 0,
136 		.rfkill_cfg = 0,
137 		.rfkill_on_level = 0,
138 		.single_pdev_only = false,
139 		.rxdma1_enable = true,
140 		.num_rxmda_per_pdev = 1,
141 		.rx_mac_buf_ring = false,
142 		.vdev_start_delay = false,
143 		.htt_peer_map_v2 = true,
144 
145 		.spectral = {
146 			.fft_sz = 4,
147 			.fft_pad_sz = 0,
148 			.summary_pad_sz = 0,
149 			.fft_hdr_len = 16,
150 			.max_fft_bins = 512,
151 		},
152 
153 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
154 					BIT(NL80211_IFTYPE_AP) |
155 					BIT(NL80211_IFTYPE_MESH_POINT),
156 		.supports_monitor = true,
157 		.full_monitor_mode = false,
158 		.supports_shadow_regs = false,
159 		.idle_ps = false,
160 		.supports_sta_ps = false,
161 		.cold_boot_calib = true,
162 		.fw_mem_mode = 0,
163 		.num_vdevs = 16 + 1,
164 		.num_peers = 512,
165 		.supports_suspend = false,
166 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
167 		.supports_regdb = false,
168 		.fix_l1ss = true,
169 		.credit_flow = false,
170 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
171 		.hal_params = &ath11k_hw_hal_params_ipq8074,
172 		.supports_dynamic_smps_6ghz = false,
173 		.alloc_cacheable_memory = true,
174 		.supports_rssi_stats = false,
175 		.fw_wmi_diag_event = false,
176 		.current_cc_support = false,
177 		.dbr_debug_support = true,
178 		.global_reset = false,
179 		.bios_sar_capa = NULL,
180 		.m3_fw_support = false,
181 		.fixed_bdf_addr = true,
182 		.fixed_mem_region = true,
183 		.static_window_map = false,
184 		.hybrid_bus_type = false,
185 		.dp_window_idx = 0,
186 		.ce_window_idx = 0,
187 		.fixed_fw_mem = false,
188 	},
189 	{
190 		.name = "qca6390 hw2.0",
191 		.hw_rev = ATH11K_HW_QCA6390_HW20,
192 		.fw = {
193 			.dir = "QCA6390/hw2.0",
194 			.board_size = 256 * 1024,
195 			.cal_offset = 128 * 1024,
196 		},
197 		.max_radios = 3,
198 		.bdf_addr = 0x4B0C0000,
199 		.hw_ops = &qca6390_ops,
200 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
201 		.internal_sleep_clock = true,
202 		.regs = &qca6390_regs,
203 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
204 		.host_ce_config = ath11k_host_ce_config_qca6390,
205 		.ce_count = 9,
206 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
207 		.target_ce_count = 9,
208 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
209 		.svc_to_ce_map_len = 14,
210 		.rfkill_pin = 48,
211 		.rfkill_cfg = 0,
212 		.rfkill_on_level = 1,
213 		.single_pdev_only = true,
214 		.rxdma1_enable = false,
215 		.num_rxmda_per_pdev = 2,
216 		.rx_mac_buf_ring = true,
217 		.vdev_start_delay = true,
218 		.htt_peer_map_v2 = false,
219 
220 		.spectral = {
221 			.fft_sz = 0,
222 			.fft_pad_sz = 0,
223 			.summary_pad_sz = 0,
224 			.fft_hdr_len = 0,
225 			.max_fft_bins = 0,
226 		},
227 
228 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
229 					BIT(NL80211_IFTYPE_AP),
230 		.supports_monitor = false,
231 		.full_monitor_mode = false,
232 		.supports_shadow_regs = true,
233 		.idle_ps = true,
234 		.supports_sta_ps = true,
235 		.cold_boot_calib = false,
236 		.fw_mem_mode = 0,
237 		.num_vdevs = 16 + 1,
238 		.num_peers = 512,
239 		.supports_suspend = true,
240 		.hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
241 		.supports_regdb = false,
242 		.fix_l1ss = true,
243 		.credit_flow = true,
244 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
245 		.hal_params = &ath11k_hw_hal_params_qca6390,
246 		.supports_dynamic_smps_6ghz = false,
247 		.alloc_cacheable_memory = false,
248 		.supports_rssi_stats = true,
249 		.fw_wmi_diag_event = true,
250 		.current_cc_support = true,
251 		.dbr_debug_support = false,
252 		.global_reset = true,
253 		.bios_sar_capa = NULL,
254 		.m3_fw_support = true,
255 		.fixed_bdf_addr = false,
256 		.fixed_mem_region = false,
257 		.static_window_map = false,
258 		.hybrid_bus_type = false,
259 		.dp_window_idx = 0,
260 		.ce_window_idx = 0,
261 		.fixed_fw_mem = false,
262 	},
263 	{
264 		.name = "qcn9074 hw1.0",
265 		.hw_rev = ATH11K_HW_QCN9074_HW10,
266 		.fw = {
267 			.dir = "QCN9074/hw1.0",
268 			.board_size = 256 * 1024,
269 			.cal_offset = 128 * 1024,
270 		},
271 		.max_radios = 1,
272 		.single_pdev_only = false,
273 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
274 		.hw_ops = &qcn9074_ops,
275 		.ring_mask = &ath11k_hw_ring_mask_qcn9074,
276 		.internal_sleep_clock = false,
277 		.regs = &qcn9074_regs,
278 		.host_ce_config = ath11k_host_ce_config_qcn9074,
279 		.ce_count = 6,
280 		.target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
281 		.target_ce_count = 9,
282 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
283 		.svc_to_ce_map_len = 18,
284 		.rfkill_pin = 0,
285 		.rfkill_cfg = 0,
286 		.rfkill_on_level = 0,
287 		.rxdma1_enable = true,
288 		.num_rxmda_per_pdev = 1,
289 		.rx_mac_buf_ring = false,
290 		.vdev_start_delay = false,
291 		.htt_peer_map_v2 = true,
292 
293 		.spectral = {
294 			.fft_sz = 2,
295 			.fft_pad_sz = 0,
296 			.summary_pad_sz = 16,
297 			.fft_hdr_len = 24,
298 			.max_fft_bins = 1024,
299 		},
300 
301 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
302 					BIT(NL80211_IFTYPE_AP) |
303 					BIT(NL80211_IFTYPE_MESH_POINT),
304 		.supports_monitor = true,
305 		.full_monitor_mode = true,
306 		.supports_shadow_regs = false,
307 		.idle_ps = false,
308 		.supports_sta_ps = false,
309 		.cold_boot_calib = false,
310 		.fw_mem_mode = 2,
311 		.num_vdevs = 8,
312 		.num_peers = 128,
313 		.supports_suspend = false,
314 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
315 		.supports_regdb = false,
316 		.fix_l1ss = true,
317 		.credit_flow = false,
318 		.max_tx_ring = DP_TCL_NUM_RING_MAX,
319 		.hal_params = &ath11k_hw_hal_params_ipq8074,
320 		.supports_dynamic_smps_6ghz = true,
321 		.alloc_cacheable_memory = true,
322 		.supports_rssi_stats = false,
323 		.fw_wmi_diag_event = false,
324 		.current_cc_support = false,
325 		.dbr_debug_support = true,
326 		.global_reset = false,
327 		.bios_sar_capa = NULL,
328 		.m3_fw_support = true,
329 		.fixed_bdf_addr = false,
330 		.fixed_mem_region = false,
331 		.static_window_map = true,
332 		.hybrid_bus_type = false,
333 		.dp_window_idx = 3,
334 		.ce_window_idx = 2,
335 		.fixed_fw_mem = false,
336 	},
337 	{
338 		.name = "wcn6855 hw2.0",
339 		.hw_rev = ATH11K_HW_WCN6855_HW20,
340 		.fw = {
341 			.dir = "WCN6855/hw2.0",
342 			.board_size = 256 * 1024,
343 			.cal_offset = 128 * 1024,
344 		},
345 		.max_radios = 3,
346 		.bdf_addr = 0x4B0C0000,
347 		.hw_ops = &wcn6855_ops,
348 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
349 		.internal_sleep_clock = true,
350 		.regs = &wcn6855_regs,
351 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
352 		.host_ce_config = ath11k_host_ce_config_qca6390,
353 		.ce_count = 9,
354 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
355 		.target_ce_count = 9,
356 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
357 		.svc_to_ce_map_len = 14,
358 		.rfkill_pin = 0,
359 		.rfkill_cfg = 0,
360 		.rfkill_on_level = 0,
361 		.single_pdev_only = true,
362 		.rxdma1_enable = false,
363 		.num_rxmda_per_pdev = 2,
364 		.rx_mac_buf_ring = true,
365 		.vdev_start_delay = true,
366 		.htt_peer_map_v2 = false,
367 
368 		.spectral = {
369 			.fft_sz = 0,
370 			.fft_pad_sz = 0,
371 			.summary_pad_sz = 0,
372 			.fft_hdr_len = 0,
373 			.max_fft_bins = 0,
374 		},
375 
376 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
377 					BIT(NL80211_IFTYPE_AP),
378 		.supports_monitor = false,
379 		.full_monitor_mode = false,
380 		.supports_shadow_regs = true,
381 		.idle_ps = true,
382 		.supports_sta_ps = true,
383 		.cold_boot_calib = false,
384 		.fw_mem_mode = 0,
385 		.num_vdevs = 16 + 1,
386 		.num_peers = 512,
387 		.supports_suspend = true,
388 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
389 		.supports_regdb = true,
390 		.fix_l1ss = false,
391 		.credit_flow = true,
392 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
393 		.hal_params = &ath11k_hw_hal_params_qca6390,
394 		.supports_dynamic_smps_6ghz = false,
395 		.alloc_cacheable_memory = false,
396 		.supports_rssi_stats = true,
397 		.fw_wmi_diag_event = true,
398 		.current_cc_support = true,
399 		.dbr_debug_support = false,
400 		.global_reset = true,
401 		.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
402 		.m3_fw_support = true,
403 		.fixed_bdf_addr = false,
404 		.fixed_mem_region = false,
405 		.static_window_map = false,
406 		.hybrid_bus_type = false,
407 		.dp_window_idx = 0,
408 		.ce_window_idx = 0,
409 		.fixed_fw_mem = false,
410 	},
411 	{
412 		.name = "wcn6855 hw2.1",
413 		.hw_rev = ATH11K_HW_WCN6855_HW21,
414 		.fw = {
415 			.dir = "WCN6855/hw2.1",
416 			.board_size = 256 * 1024,
417 			.cal_offset = 128 * 1024,
418 		},
419 		.max_radios = 3,
420 		.bdf_addr = 0x4B0C0000,
421 		.hw_ops = &wcn6855_ops,
422 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
423 		.internal_sleep_clock = true,
424 		.regs = &wcn6855_regs,
425 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
426 		.host_ce_config = ath11k_host_ce_config_qca6390,
427 		.ce_count = 9,
428 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
429 		.target_ce_count = 9,
430 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
431 		.svc_to_ce_map_len = 14,
432 		.rfkill_pin = 0,
433 		.rfkill_cfg = 0,
434 		.rfkill_on_level = 0,
435 		.single_pdev_only = true,
436 		.rxdma1_enable = false,
437 		.num_rxmda_per_pdev = 2,
438 		.rx_mac_buf_ring = true,
439 		.vdev_start_delay = true,
440 		.htt_peer_map_v2 = false,
441 
442 		.spectral = {
443 			.fft_sz = 0,
444 			.fft_pad_sz = 0,
445 			.summary_pad_sz = 0,
446 			.fft_hdr_len = 0,
447 			.max_fft_bins = 0,
448 		},
449 
450 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
451 					BIT(NL80211_IFTYPE_AP),
452 		.supports_monitor = false,
453 		.supports_shadow_regs = true,
454 		.idle_ps = true,
455 		.supports_sta_ps = true,
456 		.cold_boot_calib = false,
457 		.fw_mem_mode = 0,
458 		.num_vdevs = 16 + 1,
459 		.num_peers = 512,
460 		.supports_suspend = true,
461 		.hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
462 		.supports_regdb = true,
463 		.fix_l1ss = false,
464 		.credit_flow = true,
465 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
466 		.hal_params = &ath11k_hw_hal_params_qca6390,
467 		.supports_dynamic_smps_6ghz = false,
468 		.alloc_cacheable_memory = false,
469 		.supports_rssi_stats = true,
470 		.fw_wmi_diag_event = true,
471 		.current_cc_support = true,
472 		.dbr_debug_support = false,
473 		.global_reset = true,
474 		.bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
475 		.m3_fw_support = true,
476 		.fixed_bdf_addr = false,
477 		.fixed_mem_region = false,
478 		.static_window_map = false,
479 		.hybrid_bus_type = false,
480 		.dp_window_idx = 0,
481 		.ce_window_idx = 0,
482 		.fixed_fw_mem = false,
483 	},
484 	{
485 		.name = "wcn6750 hw1.0",
486 		.hw_rev = ATH11K_HW_WCN6750_HW10,
487 		.fw = {
488 			.dir = "WCN6750/hw1.0",
489 			.board_size = 256 * 1024,
490 			.cal_offset = 128 * 1024,
491 		},
492 		.max_radios = 1,
493 		.bdf_addr = 0x4B0C0000,
494 		.hw_ops = &wcn6750_ops,
495 		.ring_mask = &ath11k_hw_ring_mask_qca6390,
496 		.internal_sleep_clock = false,
497 		.regs = &wcn6750_regs,
498 		.qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750,
499 		.host_ce_config = ath11k_host_ce_config_qca6390,
500 		.ce_count = 9,
501 		.target_ce_config = ath11k_target_ce_config_wlan_qca6390,
502 		.target_ce_count = 9,
503 		.svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
504 		.svc_to_ce_map_len = 14,
505 		.rfkill_pin = 0,
506 		.rfkill_cfg = 0,
507 		.rfkill_on_level = 0,
508 		.single_pdev_only = true,
509 		.rxdma1_enable = false,
510 		.num_rxmda_per_pdev = 1,
511 		.rx_mac_buf_ring = true,
512 		.vdev_start_delay = true,
513 		.htt_peer_map_v2 = false,
514 
515 		.spectral = {
516 			.fft_sz = 0,
517 			.fft_pad_sz = 0,
518 			.summary_pad_sz = 0,
519 			.fft_hdr_len = 0,
520 			.max_fft_bins = 0,
521 		},
522 
523 		.interface_modes = BIT(NL80211_IFTYPE_STATION) |
524 					BIT(NL80211_IFTYPE_AP),
525 		.supports_monitor = false,
526 		.supports_shadow_regs = true,
527 		.idle_ps = true,
528 		.supports_sta_ps = true,
529 		.cold_boot_calib = false,
530 		.fw_mem_mode = 0,
531 		.num_vdevs = 16 + 1,
532 		.num_peers = 512,
533 		.supports_suspend = false,
534 		.hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
535 		.supports_regdb = true,
536 		.fix_l1ss = false,
537 		.credit_flow = true,
538 		.max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
539 		.hal_params = &ath11k_hw_hal_params_qca6390,
540 		.supports_dynamic_smps_6ghz = false,
541 		.alloc_cacheable_memory = false,
542 		.supports_rssi_stats = true,
543 		.fw_wmi_diag_event = false,
544 		.current_cc_support = true,
545 		.dbr_debug_support = false,
546 		.global_reset = false,
547 		.bios_sar_capa = NULL,
548 		.m3_fw_support = false,
549 		.fixed_bdf_addr = false,
550 		.fixed_mem_region = false,
551 		.static_window_map = true,
552 		.hybrid_bus_type = true,
553 		.dp_window_idx = 1,
554 		.ce_window_idx = 2,
555 		.fixed_fw_mem = true,
556 	},
557 };
558 
559 static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
560 {
561 	WARN_ON(!ab->hw_params.single_pdev_only);
562 
563 	return &ab->pdevs[0];
564 }
565 
566 int ath11k_core_suspend(struct ath11k_base *ab)
567 {
568 	int ret;
569 	struct ath11k_pdev *pdev;
570 	struct ath11k *ar;
571 
572 	if (!ab->hw_params.supports_suspend)
573 		return -EOPNOTSUPP;
574 
575 	/* so far single_pdev_only chips have supports_suspend as true
576 	 * and only the first pdev is valid.
577 	 */
578 	pdev = ath11k_core_get_single_pdev(ab);
579 	ar = pdev->ar;
580 	if (!ar || ar->state != ATH11K_STATE_OFF)
581 		return 0;
582 
583 	ret = ath11k_dp_rx_pktlog_stop(ab, true);
584 	if (ret) {
585 		ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
586 			    ret);
587 		return ret;
588 	}
589 
590 	ret = ath11k_mac_wait_tx_complete(ar);
591 	if (ret) {
592 		ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
593 		return ret;
594 	}
595 
596 	ret = ath11k_wow_enable(ab);
597 	if (ret) {
598 		ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
599 		return ret;
600 	}
601 
602 	ret = ath11k_dp_rx_pktlog_stop(ab, false);
603 	if (ret) {
604 		ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
605 			    ret);
606 		return ret;
607 	}
608 
609 	ath11k_ce_stop_shadow_timers(ab);
610 	ath11k_dp_stop_shadow_timers(ab);
611 
612 	ath11k_hif_irq_disable(ab);
613 	ath11k_hif_ce_irq_disable(ab);
614 
615 	ret = ath11k_hif_suspend(ab);
616 	if (ret) {
617 		ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
618 		return ret;
619 	}
620 
621 	return 0;
622 }
623 EXPORT_SYMBOL(ath11k_core_suspend);
624 
625 int ath11k_core_resume(struct ath11k_base *ab)
626 {
627 	int ret;
628 	struct ath11k_pdev *pdev;
629 	struct ath11k *ar;
630 
631 	if (!ab->hw_params.supports_suspend)
632 		return -EOPNOTSUPP;
633 
634 	/* so far signle_pdev_only chips have supports_suspend as true
635 	 * and only the first pdev is valid.
636 	 */
637 	pdev = ath11k_core_get_single_pdev(ab);
638 	ar = pdev->ar;
639 	if (!ar || ar->state != ATH11K_STATE_OFF)
640 		return 0;
641 
642 	ret = ath11k_hif_resume(ab);
643 	if (ret) {
644 		ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
645 		return ret;
646 	}
647 
648 	ath11k_hif_ce_irq_enable(ab);
649 	ath11k_hif_irq_enable(ab);
650 
651 	ret = ath11k_dp_rx_pktlog_start(ab);
652 	if (ret) {
653 		ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
654 			    ret);
655 		return ret;
656 	}
657 
658 	ret = ath11k_wow_wakeup(ab);
659 	if (ret) {
660 		ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
661 		return ret;
662 	}
663 
664 	return 0;
665 }
666 EXPORT_SYMBOL(ath11k_core_resume);
667 
668 static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
669 {
670 	struct ath11k_base *ab = data;
671 	const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC;
672 	struct ath11k_smbios_bdf *smbios = (struct ath11k_smbios_bdf *)hdr;
673 	ssize_t copied;
674 	size_t len;
675 	int i;
676 
677 	if (ab->qmi.target.bdf_ext[0] != '\0')
678 		return;
679 
680 	if (hdr->type != ATH11K_SMBIOS_BDF_EXT_TYPE)
681 		return;
682 
683 	if (hdr->length != ATH11K_SMBIOS_BDF_EXT_LENGTH) {
684 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
685 			   "wrong smbios bdf ext type length (%d).\n",
686 			   hdr->length);
687 		return;
688 	}
689 
690 	spin_lock_bh(&ab->base_lock);
691 
692 	switch (smbios->country_code_flag) {
693 	case ATH11K_SMBIOS_CC_ISO:
694 		ab->new_alpha2[0] = (smbios->cc_code >> 8) & 0xff;
695 		ab->new_alpha2[1] = smbios->cc_code & 0xff;
696 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios cc_code %c%c\n",
697 			   ab->new_alpha2[0], ab->new_alpha2[1]);
698 		break;
699 	case ATH11K_SMBIOS_CC_WW:
700 		ab->new_alpha2[0] = '0';
701 		ab->new_alpha2[1] = '0';
702 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios worldwide regdomain\n");
703 		break;
704 	default:
705 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot ignore smbios country code setting %d\n",
706 			   smbios->country_code_flag);
707 		break;
708 	}
709 
710 	spin_unlock_bh(&ab->base_lock);
711 
712 	if (!smbios->bdf_enabled) {
713 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n");
714 		return;
715 	}
716 
717 	/* Only one string exists (per spec) */
718 	if (memcmp(smbios->bdf_ext, magic, strlen(magic)) != 0) {
719 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
720 			   "bdf variant magic does not match.\n");
721 		return;
722 	}
723 
724 	len = min_t(size_t,
725 		    strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext));
726 	for (i = 0; i < len; i++) {
727 		if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) {
728 			ath11k_dbg(ab, ATH11K_DBG_BOOT,
729 				   "bdf variant name contains non ascii chars.\n");
730 			return;
731 		}
732 	}
733 
734 	/* Copy extension name without magic prefix */
735 	copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic),
736 			 sizeof(ab->qmi.target.bdf_ext));
737 	if (copied < 0) {
738 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
739 			   "bdf variant string is longer than the buffer can accommodate\n");
740 		return;
741 	}
742 
743 	ath11k_dbg(ab, ATH11K_DBG_BOOT,
744 		   "found and validated bdf variant smbios_type 0x%x bdf %s\n",
745 		   ATH11K_SMBIOS_BDF_EXT_TYPE, ab->qmi.target.bdf_ext);
746 }
747 
748 int ath11k_core_check_smbios(struct ath11k_base *ab)
749 {
750 	ab->qmi.target.bdf_ext[0] = '\0';
751 	dmi_walk(ath11k_core_check_cc_code_bdfext, ab);
752 
753 	if (ab->qmi.target.bdf_ext[0] == '\0')
754 		return -ENODATA;
755 
756 	return 0;
757 }
758 
759 int ath11k_core_check_dt(struct ath11k_base *ab)
760 {
761 	size_t max_len = sizeof(ab->qmi.target.bdf_ext);
762 	const char *variant = NULL;
763 	struct device_node *node;
764 
765 	node = ab->dev->of_node;
766 	if (!node)
767 		return -ENOENT;
768 
769 	of_property_read_string(node, "qcom,ath11k-calibration-variant",
770 				&variant);
771 	if (!variant)
772 		return -ENODATA;
773 
774 	if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
775 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
776 			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
777 			    variant);
778 
779 	return 0;
780 }
781 
782 static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
783 					   size_t name_len, bool with_variant)
784 {
785 	/* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
786 	char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
787 
788 	if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
789 		scnprintf(variant, sizeof(variant), ",variant=%s",
790 			  ab->qmi.target.bdf_ext);
791 
792 	switch (ab->id.bdf_search) {
793 	case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
794 		scnprintf(name, name_len,
795 			  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
796 			  ath11k_bus_str(ab->hif.bus),
797 			  ab->id.vendor, ab->id.device,
798 			  ab->id.subsystem_vendor,
799 			  ab->id.subsystem_device,
800 			  ab->qmi.target.chip_id,
801 			  ab->qmi.target.board_id,
802 			  variant);
803 		break;
804 	default:
805 		scnprintf(name, name_len,
806 			  "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
807 			  ath11k_bus_str(ab->hif.bus),
808 			  ab->qmi.target.chip_id,
809 			  ab->qmi.target.board_id, variant);
810 		break;
811 	}
812 
813 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
814 
815 	return 0;
816 }
817 
818 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
819 					 size_t name_len)
820 {
821 	return __ath11k_core_create_board_name(ab, name, name_len, true);
822 }
823 
824 static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
825 						  size_t name_len)
826 {
827 	return __ath11k_core_create_board_name(ab, name, name_len, false);
828 }
829 
830 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
831 						    const char *file)
832 {
833 	const struct firmware *fw;
834 	char path[100];
835 	int ret;
836 
837 	if (file == NULL)
838 		return ERR_PTR(-ENOENT);
839 
840 	ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
841 
842 	ret = firmware_request_nowarn(&fw, path, ab->dev);
843 	if (ret)
844 		return ERR_PTR(ret);
845 
846 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
847 		   path, fw->size);
848 
849 	return fw;
850 }
851 
852 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
853 {
854 	if (!IS_ERR(bd->fw))
855 		release_firmware(bd->fw);
856 
857 	memset(bd, 0, sizeof(*bd));
858 }
859 
860 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
861 					 struct ath11k_board_data *bd,
862 					 const void *buf, size_t buf_len,
863 					 const char *boardname,
864 					 int ie_id,
865 					 int name_id,
866 					 int data_id)
867 {
868 	const struct ath11k_fw_ie *hdr;
869 	bool name_match_found;
870 	int ret, board_ie_id;
871 	size_t board_ie_len;
872 	const void *board_ie_data;
873 
874 	name_match_found = false;
875 
876 	/* go through ATH11K_BD_IE_BOARD_/ATH11K_BD_IE_REGDB_ elements */
877 	while (buf_len > sizeof(struct ath11k_fw_ie)) {
878 		hdr = buf;
879 		board_ie_id = le32_to_cpu(hdr->id);
880 		board_ie_len = le32_to_cpu(hdr->len);
881 		board_ie_data = hdr->data;
882 
883 		buf_len -= sizeof(*hdr);
884 		buf += sizeof(*hdr);
885 
886 		if (buf_len < ALIGN(board_ie_len, 4)) {
887 			ath11k_err(ab, "invalid %s length: %zu < %zu\n",
888 				   ath11k_bd_ie_type_str(ie_id),
889 				   buf_len, ALIGN(board_ie_len, 4));
890 			ret = -EINVAL;
891 			goto out;
892 		}
893 
894 		if (board_ie_id == name_id) {
895 			ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
896 					board_ie_data, board_ie_len);
897 
898 			if (board_ie_len != strlen(boardname))
899 				goto next;
900 
901 			ret = memcmp(board_ie_data, boardname, strlen(boardname));
902 			if (ret)
903 				goto next;
904 
905 			name_match_found = true;
906 			ath11k_dbg(ab, ATH11K_DBG_BOOT,
907 				   "boot found match %s for name '%s'",
908 				   ath11k_bd_ie_type_str(ie_id),
909 				   boardname);
910 		} else if (board_ie_id == data_id) {
911 			if (!name_match_found)
912 				/* no match found */
913 				goto next;
914 
915 			ath11k_dbg(ab, ATH11K_DBG_BOOT,
916 				   "boot found %s for '%s'",
917 				   ath11k_bd_ie_type_str(ie_id),
918 				   boardname);
919 
920 			bd->data = board_ie_data;
921 			bd->len = board_ie_len;
922 
923 			ret = 0;
924 			goto out;
925 		} else {
926 			ath11k_warn(ab, "unknown %s id found: %d\n",
927 				    ath11k_bd_ie_type_str(ie_id),
928 				    board_ie_id);
929 		}
930 next:
931 		/* jump over the padding */
932 		board_ie_len = ALIGN(board_ie_len, 4);
933 
934 		buf_len -= board_ie_len;
935 		buf += board_ie_len;
936 	}
937 
938 	/* no match found */
939 	ret = -ENOENT;
940 
941 out:
942 	return ret;
943 }
944 
945 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
946 					      struct ath11k_board_data *bd,
947 					      const char *boardname,
948 					      int ie_id_match,
949 					      int name_id,
950 					      int data_id)
951 {
952 	size_t len, magic_len;
953 	const u8 *data;
954 	char *filename, filepath[100];
955 	size_t ie_len;
956 	struct ath11k_fw_ie *hdr;
957 	int ret, ie_id;
958 
959 	filename = ATH11K_BOARD_API2_FILE;
960 
961 	if (!bd->fw)
962 		bd->fw = ath11k_core_firmware_request(ab, filename);
963 
964 	if (IS_ERR(bd->fw))
965 		return PTR_ERR(bd->fw);
966 
967 	data = bd->fw->data;
968 	len = bd->fw->size;
969 
970 	ath11k_core_create_firmware_path(ab, filename,
971 					 filepath, sizeof(filepath));
972 
973 	/* magic has extra null byte padded */
974 	magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
975 	if (len < magic_len) {
976 		ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
977 			   filepath, len);
978 		ret = -EINVAL;
979 		goto err;
980 	}
981 
982 	if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
983 		ath11k_err(ab, "found invalid board magic\n");
984 		ret = -EINVAL;
985 		goto err;
986 	}
987 
988 	/* magic is padded to 4 bytes */
989 	magic_len = ALIGN(magic_len, 4);
990 	if (len < magic_len) {
991 		ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
992 			   filepath, len);
993 		ret = -EINVAL;
994 		goto err;
995 	}
996 
997 	data += magic_len;
998 	len -= magic_len;
999 
1000 	while (len > sizeof(struct ath11k_fw_ie)) {
1001 		hdr = (struct ath11k_fw_ie *)data;
1002 		ie_id = le32_to_cpu(hdr->id);
1003 		ie_len = le32_to_cpu(hdr->len);
1004 
1005 		len -= sizeof(*hdr);
1006 		data = hdr->data;
1007 
1008 		if (len < ALIGN(ie_len, 4)) {
1009 			ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
1010 				   ie_id, ie_len, len);
1011 			ret = -EINVAL;
1012 			goto err;
1013 		}
1014 
1015 		if (ie_id == ie_id_match) {
1016 			ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
1017 							    ie_len,
1018 							    boardname,
1019 							    ie_id_match,
1020 							    name_id,
1021 							    data_id);
1022 			if (ret == -ENOENT)
1023 				/* no match found, continue */
1024 				goto next;
1025 			else if (ret)
1026 				/* there was an error, bail out */
1027 				goto err;
1028 			/* either found or error, so stop searching */
1029 			goto out;
1030 		}
1031 next:
1032 		/* jump over the padding */
1033 		ie_len = ALIGN(ie_len, 4);
1034 
1035 		len -= ie_len;
1036 		data += ie_len;
1037 	}
1038 
1039 out:
1040 	if (!bd->data || !bd->len) {
1041 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
1042 			   "failed to fetch %s for %s from %s\n",
1043 			   ath11k_bd_ie_type_str(ie_id_match),
1044 			   boardname, filepath);
1045 		ret = -ENODATA;
1046 		goto err;
1047 	}
1048 
1049 	return 0;
1050 
1051 err:
1052 	ath11k_core_free_bdf(ab, bd);
1053 	return ret;
1054 }
1055 
1056 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
1057 				       struct ath11k_board_data *bd,
1058 				       const char *name)
1059 {
1060 	bd->fw = ath11k_core_firmware_request(ab, name);
1061 
1062 	if (IS_ERR(bd->fw))
1063 		return PTR_ERR(bd->fw);
1064 
1065 	bd->data = bd->fw->data;
1066 	bd->len = bd->fw->size;
1067 
1068 	return 0;
1069 }
1070 
1071 #define BOARD_NAME_SIZE 200
1072 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
1073 {
1074 	char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
1075 	char *filename, filepath[100];
1076 	int ret;
1077 
1078 	filename = ATH11K_BOARD_API2_FILE;
1079 
1080 	ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
1081 	if (ret) {
1082 		ath11k_err(ab, "failed to create board name: %d", ret);
1083 		return ret;
1084 	}
1085 
1086 	ab->bd_api = 2;
1087 	ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1088 						 ATH11K_BD_IE_BOARD,
1089 						 ATH11K_BD_IE_BOARD_NAME,
1090 						 ATH11K_BD_IE_BOARD_DATA);
1091 	if (!ret)
1092 		goto success;
1093 
1094 	ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
1095 						     sizeof(fallback_boardname));
1096 	if (ret) {
1097 		ath11k_err(ab, "failed to create fallback board name: %d", ret);
1098 		return ret;
1099 	}
1100 
1101 	ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
1102 						 ATH11K_BD_IE_BOARD,
1103 						 ATH11K_BD_IE_BOARD_NAME,
1104 						 ATH11K_BD_IE_BOARD_DATA);
1105 	if (!ret)
1106 		goto success;
1107 
1108 	ab->bd_api = 1;
1109 	ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
1110 	if (ret) {
1111 		ath11k_core_create_firmware_path(ab, filename,
1112 						 filepath, sizeof(filepath));
1113 		ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1114 			   boardname, filepath);
1115 		if (memcmp(boardname, fallback_boardname, strlen(boardname)))
1116 			ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1117 				   fallback_boardname, filepath);
1118 
1119 		ath11k_err(ab, "failed to fetch board.bin from %s\n",
1120 			   ab->hw_params.fw.dir);
1121 		return ret;
1122 	}
1123 
1124 success:
1125 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
1126 	return 0;
1127 }
1128 
1129 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
1130 {
1131 	char boardname[BOARD_NAME_SIZE];
1132 	int ret;
1133 
1134 	ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
1135 	if (ret) {
1136 		ath11k_dbg(ab, ATH11K_DBG_BOOT,
1137 			   "failed to create board name for regdb: %d", ret);
1138 		goto exit;
1139 	}
1140 
1141 	ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1142 						 ATH11K_BD_IE_REGDB,
1143 						 ATH11K_BD_IE_REGDB_NAME,
1144 						 ATH11K_BD_IE_REGDB_DATA);
1145 	if (!ret)
1146 		goto exit;
1147 
1148 	ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
1149 	if (ret)
1150 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
1151 			   ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
1152 
1153 exit:
1154 	if (!ret)
1155 		ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");
1156 
1157 	return ret;
1158 }
1159 
1160 static void ath11k_core_stop(struct ath11k_base *ab)
1161 {
1162 	if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
1163 		ath11k_qmi_firmware_stop(ab);
1164 
1165 	ath11k_hif_stop(ab);
1166 	ath11k_wmi_detach(ab);
1167 	ath11k_dp_pdev_reo_cleanup(ab);
1168 
1169 	/* De-Init of components as needed */
1170 }
1171 
1172 static int ath11k_core_soc_create(struct ath11k_base *ab)
1173 {
1174 	int ret;
1175 
1176 	ret = ath11k_qmi_init_service(ab);
1177 	if (ret) {
1178 		ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
1179 		return ret;
1180 	}
1181 
1182 	ret = ath11k_debugfs_soc_create(ab);
1183 	if (ret) {
1184 		ath11k_err(ab, "failed to create ath11k debugfs\n");
1185 		goto err_qmi_deinit;
1186 	}
1187 
1188 	ret = ath11k_hif_power_up(ab);
1189 	if (ret) {
1190 		ath11k_err(ab, "failed to power up :%d\n", ret);
1191 		goto err_debugfs_reg;
1192 	}
1193 
1194 	return 0;
1195 
1196 err_debugfs_reg:
1197 	ath11k_debugfs_soc_destroy(ab);
1198 err_qmi_deinit:
1199 	ath11k_qmi_deinit_service(ab);
1200 	return ret;
1201 }
1202 
1203 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
1204 {
1205 	ath11k_debugfs_soc_destroy(ab);
1206 	ath11k_dp_free(ab);
1207 	ath11k_reg_free(ab);
1208 	ath11k_qmi_deinit_service(ab);
1209 }
1210 
1211 static int ath11k_core_pdev_create(struct ath11k_base *ab)
1212 {
1213 	int ret;
1214 
1215 	ret = ath11k_debugfs_pdev_create(ab);
1216 	if (ret) {
1217 		ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
1218 		return ret;
1219 	}
1220 
1221 	ret = ath11k_mac_register(ab);
1222 	if (ret) {
1223 		ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
1224 		goto err_pdev_debug;
1225 	}
1226 
1227 	ret = ath11k_dp_pdev_alloc(ab);
1228 	if (ret) {
1229 		ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
1230 		goto err_mac_unregister;
1231 	}
1232 
1233 	ret = ath11k_thermal_register(ab);
1234 	if (ret) {
1235 		ath11k_err(ab, "could not register thermal device: %d\n",
1236 			   ret);
1237 		goto err_dp_pdev_free;
1238 	}
1239 
1240 	ret = ath11k_spectral_init(ab);
1241 	if (ret) {
1242 		ath11k_err(ab, "failed to init spectral %d\n", ret);
1243 		goto err_thermal_unregister;
1244 	}
1245 
1246 	return 0;
1247 
1248 err_thermal_unregister:
1249 	ath11k_thermal_unregister(ab);
1250 err_dp_pdev_free:
1251 	ath11k_dp_pdev_free(ab);
1252 err_mac_unregister:
1253 	ath11k_mac_unregister(ab);
1254 err_pdev_debug:
1255 	ath11k_debugfs_pdev_destroy(ab);
1256 
1257 	return ret;
1258 }
1259 
1260 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
1261 {
1262 	ath11k_spectral_deinit(ab);
1263 	ath11k_thermal_unregister(ab);
1264 	ath11k_mac_unregister(ab);
1265 	ath11k_hif_irq_disable(ab);
1266 	ath11k_dp_pdev_free(ab);
1267 	ath11k_debugfs_pdev_destroy(ab);
1268 }
1269 
1270 static int ath11k_core_start(struct ath11k_base *ab)
1271 {
1272 	int ret;
1273 
1274 	ret = ath11k_wmi_attach(ab);
1275 	if (ret) {
1276 		ath11k_err(ab, "failed to attach wmi: %d\n", ret);
1277 		return ret;
1278 	}
1279 
1280 	ret = ath11k_htc_init(ab);
1281 	if (ret) {
1282 		ath11k_err(ab, "failed to init htc: %d\n", ret);
1283 		goto err_wmi_detach;
1284 	}
1285 
1286 	ret = ath11k_hif_start(ab);
1287 	if (ret) {
1288 		ath11k_err(ab, "failed to start HIF: %d\n", ret);
1289 		goto err_wmi_detach;
1290 	}
1291 
1292 	ret = ath11k_htc_wait_target(&ab->htc);
1293 	if (ret) {
1294 		ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
1295 		goto err_hif_stop;
1296 	}
1297 
1298 	ret = ath11k_dp_htt_connect(&ab->dp);
1299 	if (ret) {
1300 		ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
1301 		goto err_hif_stop;
1302 	}
1303 
1304 	ret = ath11k_wmi_connect(ab);
1305 	if (ret) {
1306 		ath11k_err(ab, "failed to connect wmi: %d\n", ret);
1307 		goto err_hif_stop;
1308 	}
1309 
1310 	ret = ath11k_htc_start(&ab->htc);
1311 	if (ret) {
1312 		ath11k_err(ab, "failed to start HTC: %d\n", ret);
1313 		goto err_hif_stop;
1314 	}
1315 
1316 	ret = ath11k_wmi_wait_for_service_ready(ab);
1317 	if (ret) {
1318 		ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
1319 			   ret);
1320 		goto err_hif_stop;
1321 	}
1322 
1323 	ret = ath11k_mac_allocate(ab);
1324 	if (ret) {
1325 		ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
1326 			   ret);
1327 		goto err_hif_stop;
1328 	}
1329 
1330 	ath11k_dp_pdev_pre_alloc(ab);
1331 
1332 	ret = ath11k_dp_pdev_reo_setup(ab);
1333 	if (ret) {
1334 		ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
1335 		goto err_mac_destroy;
1336 	}
1337 
1338 	ret = ath11k_wmi_cmd_init(ab);
1339 	if (ret) {
1340 		ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
1341 		goto err_reo_cleanup;
1342 	}
1343 
1344 	ret = ath11k_wmi_wait_for_unified_ready(ab);
1345 	if (ret) {
1346 		ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
1347 			   ret);
1348 		goto err_reo_cleanup;
1349 	}
1350 
1351 	/* put hardware to DBS mode */
1352 	if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) {
1353 		ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
1354 		if (ret) {
1355 			ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
1356 			goto err_hif_stop;
1357 		}
1358 	}
1359 
1360 	ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
1361 	if (ret) {
1362 		ath11k_err(ab, "failed to send htt version request message: %d\n",
1363 			   ret);
1364 		goto err_reo_cleanup;
1365 	}
1366 
1367 	return 0;
1368 
1369 err_reo_cleanup:
1370 	ath11k_dp_pdev_reo_cleanup(ab);
1371 err_mac_destroy:
1372 	ath11k_mac_destroy(ab);
1373 err_hif_stop:
1374 	ath11k_hif_stop(ab);
1375 err_wmi_detach:
1376 	ath11k_wmi_detach(ab);
1377 
1378 	return ret;
1379 }
1380 
1381 static int ath11k_core_start_firmware(struct ath11k_base *ab,
1382 				      enum ath11k_firmware_mode mode)
1383 {
1384 	int ret;
1385 
1386 	ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2,
1387 				    &ab->qmi.ce_cfg.shadow_reg_v2_len);
1388 
1389 	ret = ath11k_qmi_firmware_start(ab, mode);
1390 	if (ret) {
1391 		ath11k_err(ab, "failed to send firmware start: %d\n", ret);
1392 		return ret;
1393 	}
1394 
1395 	return ret;
1396 }
1397 
1398 static int ath11k_core_rfkill_config(struct ath11k_base *ab)
1399 {
1400 	struct ath11k *ar;
1401 	int ret = 0, i;
1402 
1403 	if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL))
1404 		return 0;
1405 
1406 	for (i = 0; i < ab->num_radios; i++) {
1407 		ar = ab->pdevs[i].ar;
1408 
1409 		ret = ath11k_mac_rfkill_config(ar);
1410 		if (ret && ret != -EOPNOTSUPP) {
1411 			ath11k_warn(ab, "failed to configure rfkill: %d", ret);
1412 			return ret;
1413 		}
1414 	}
1415 
1416 	return ret;
1417 }
1418 
1419 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
1420 {
1421 	int ret;
1422 
1423 	ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL);
1424 	if (ret) {
1425 		ath11k_err(ab, "failed to start firmware: %d\n", ret);
1426 		return ret;
1427 	}
1428 
1429 	ret = ath11k_ce_init_pipes(ab);
1430 	if (ret) {
1431 		ath11k_err(ab, "failed to initialize CE: %d\n", ret);
1432 		goto err_firmware_stop;
1433 	}
1434 
1435 	ret = ath11k_dp_alloc(ab);
1436 	if (ret) {
1437 		ath11k_err(ab, "failed to init DP: %d\n", ret);
1438 		goto err_firmware_stop;
1439 	}
1440 
1441 	switch (ath11k_crypto_mode) {
1442 	case ATH11K_CRYPT_MODE_SW:
1443 		set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1444 		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1445 		break;
1446 	case ATH11K_CRYPT_MODE_HW:
1447 		clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1448 		clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1449 		break;
1450 	default:
1451 		ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
1452 		return -EINVAL;
1453 	}
1454 
1455 	if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
1456 		set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1457 
1458 	mutex_lock(&ab->core_lock);
1459 	ret = ath11k_core_start(ab);
1460 	if (ret) {
1461 		ath11k_err(ab, "failed to start core: %d\n", ret);
1462 		goto err_dp_free;
1463 	}
1464 
1465 	ret = ath11k_core_pdev_create(ab);
1466 	if (ret) {
1467 		ath11k_err(ab, "failed to create pdev core: %d\n", ret);
1468 		goto err_core_stop;
1469 	}
1470 	ath11k_hif_irq_enable(ab);
1471 
1472 	ret = ath11k_core_rfkill_config(ab);
1473 	if (ret && ret != -EOPNOTSUPP) {
1474 		ath11k_err(ab, "failed to config rfkill: %d\n", ret);
1475 		goto err_core_stop;
1476 	}
1477 
1478 	mutex_unlock(&ab->core_lock);
1479 
1480 	return 0;
1481 
1482 err_core_stop:
1483 	ath11k_core_stop(ab);
1484 	ath11k_mac_destroy(ab);
1485 err_dp_free:
1486 	ath11k_dp_free(ab);
1487 	mutex_unlock(&ab->core_lock);
1488 err_firmware_stop:
1489 	ath11k_qmi_firmware_stop(ab);
1490 
1491 	return ret;
1492 }
1493 
1494 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
1495 {
1496 	int ret;
1497 
1498 	mutex_lock(&ab->core_lock);
1499 	ath11k_thermal_unregister(ab);
1500 	ath11k_hif_irq_disable(ab);
1501 	ath11k_dp_pdev_free(ab);
1502 	ath11k_spectral_deinit(ab);
1503 	ath11k_hif_stop(ab);
1504 	ath11k_wmi_detach(ab);
1505 	ath11k_dp_pdev_reo_cleanup(ab);
1506 	mutex_unlock(&ab->core_lock);
1507 
1508 	ath11k_dp_free(ab);
1509 	ath11k_hal_srng_deinit(ab);
1510 
1511 	ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
1512 
1513 	ret = ath11k_hal_srng_init(ab);
1514 	if (ret)
1515 		return ret;
1516 
1517 	clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
1518 
1519 	ret = ath11k_core_qmi_firmware_ready(ab);
1520 	if (ret)
1521 		goto err_hal_srng_deinit;
1522 
1523 	clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
1524 
1525 	return 0;
1526 
1527 err_hal_srng_deinit:
1528 	ath11k_hal_srng_deinit(ab);
1529 	return ret;
1530 }
1531 
1532 void ath11k_core_halt(struct ath11k *ar)
1533 {
1534 	struct ath11k_base *ab = ar->ab;
1535 
1536 	lockdep_assert_held(&ar->conf_mutex);
1537 
1538 	ar->num_created_vdevs = 0;
1539 	ar->allocated_vdev_map = 0;
1540 
1541 	ath11k_mac_scan_finish(ar);
1542 	ath11k_mac_peer_cleanup_all(ar);
1543 	cancel_delayed_work_sync(&ar->scan.timeout);
1544 	cancel_work_sync(&ar->regd_update_work);
1545 	cancel_work_sync(&ab->update_11d_work);
1546 	cancel_work_sync(&ab->rfkill_work);
1547 
1548 	rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
1549 	synchronize_rcu();
1550 	INIT_LIST_HEAD(&ar->arvifs);
1551 	idr_init(&ar->txmgmt_idr);
1552 }
1553 
1554 static void ath11k_rfkill_work(struct work_struct *work)
1555 {
1556 	struct ath11k_base *ab = container_of(work, struct ath11k_base, rfkill_work);
1557 	struct ath11k *ar;
1558 	bool rfkill_radio_on;
1559 	int i;
1560 
1561 	spin_lock_bh(&ab->base_lock);
1562 	rfkill_radio_on = ab->rfkill_radio_on;
1563 	spin_unlock_bh(&ab->base_lock);
1564 
1565 	for (i = 0; i < ab->num_radios; i++) {
1566 		ar = ab->pdevs[i].ar;
1567 		if (!ar)
1568 			continue;
1569 
1570 		/* notify cfg80211 radio state change */
1571 		ath11k_mac_rfkill_enable_radio(ar, rfkill_radio_on);
1572 		wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on);
1573 	}
1574 }
1575 
1576 static void ath11k_update_11d(struct work_struct *work)
1577 {
1578 	struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
1579 	struct ath11k *ar;
1580 	struct ath11k_pdev *pdev;
1581 	struct wmi_set_current_country_params set_current_param = {};
1582 	int ret, i;
1583 
1584 	spin_lock_bh(&ab->base_lock);
1585 	memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
1586 	spin_unlock_bh(&ab->base_lock);
1587 
1588 	ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
1589 		   set_current_param.alpha2[0],
1590 		   set_current_param.alpha2[1]);
1591 
1592 	for (i = 0; i < ab->num_radios; i++) {
1593 		pdev = &ab->pdevs[i];
1594 		ar = pdev->ar;
1595 
1596 		memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
1597 		ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
1598 		if (ret)
1599 			ath11k_warn(ar->ab,
1600 				    "pdev id %d failed set current country code: %d\n",
1601 				    i, ret);
1602 	}
1603 }
1604 
1605 static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
1606 {
1607 	struct ath11k *ar;
1608 	struct ath11k_pdev *pdev;
1609 	int i;
1610 
1611 	spin_lock_bh(&ab->base_lock);
1612 	ab->stats.fw_crash_counter++;
1613 	spin_unlock_bh(&ab->base_lock);
1614 
1615 	for (i = 0; i < ab->num_radios; i++) {
1616 		pdev = &ab->pdevs[i];
1617 		ar = pdev->ar;
1618 		if (!ar || ar->state == ATH11K_STATE_OFF)
1619 			continue;
1620 
1621 		ieee80211_stop_queues(ar->hw);
1622 		ath11k_mac_drain_tx(ar);
1623 		complete(&ar->completed_11d_scan);
1624 		complete(&ar->scan.started);
1625 		complete(&ar->scan.completed);
1626 		complete(&ar->peer_assoc_done);
1627 		complete(&ar->peer_delete_done);
1628 		complete(&ar->install_key_done);
1629 		complete(&ar->vdev_setup_done);
1630 		complete(&ar->vdev_delete_done);
1631 		complete(&ar->bss_survey_done);
1632 		complete(&ar->thermal.wmi_sync);
1633 
1634 		wake_up(&ar->dp.tx_empty_waitq);
1635 		idr_for_each(&ar->txmgmt_idr,
1636 			     ath11k_mac_tx_mgmt_pending_free, ar);
1637 		idr_destroy(&ar->txmgmt_idr);
1638 		wake_up(&ar->txmgmt_empty_waitq);
1639 	}
1640 
1641 	wake_up(&ab->wmi_ab.tx_credits_wq);
1642 	wake_up(&ab->peer_mapping_wq);
1643 }
1644 
1645 static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
1646 {
1647 	struct ath11k *ar;
1648 	struct ath11k_pdev *pdev;
1649 	int i;
1650 
1651 	for (i = 0; i < ab->num_radios; i++) {
1652 		pdev = &ab->pdevs[i];
1653 		ar = pdev->ar;
1654 		if (!ar || ar->state == ATH11K_STATE_OFF)
1655 			continue;
1656 
1657 		mutex_lock(&ar->conf_mutex);
1658 
1659 		switch (ar->state) {
1660 		case ATH11K_STATE_ON:
1661 			ar->state = ATH11K_STATE_RESTARTING;
1662 			ath11k_core_halt(ar);
1663 			ieee80211_restart_hw(ar->hw);
1664 			break;
1665 		case ATH11K_STATE_OFF:
1666 			ath11k_warn(ab,
1667 				    "cannot restart radio %d that hasn't been started\n",
1668 				    i);
1669 			break;
1670 		case ATH11K_STATE_RESTARTING:
1671 			break;
1672 		case ATH11K_STATE_RESTARTED:
1673 			ar->state = ATH11K_STATE_WEDGED;
1674 			fallthrough;
1675 		case ATH11K_STATE_WEDGED:
1676 			ath11k_warn(ab,
1677 				    "device is wedged, will not restart radio %d\n", i);
1678 			break;
1679 		}
1680 		mutex_unlock(&ar->conf_mutex);
1681 	}
1682 	complete(&ab->driver_recovery);
1683 }
1684 
1685 static void ath11k_core_restart(struct work_struct *work)
1686 {
1687 	struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
1688 	int ret;
1689 
1690 	if (!ab->is_reset)
1691 		ath11k_core_pre_reconfigure_recovery(ab);
1692 
1693 	ret = ath11k_core_reconfigure_on_crash(ab);
1694 	if (ret) {
1695 		ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
1696 		return;
1697 	}
1698 
1699 	if (ab->is_reset)
1700 		complete_all(&ab->reconfigure_complete);
1701 
1702 	if (!ab->is_reset)
1703 		ath11k_core_post_reconfigure_recovery(ab);
1704 }
1705 
1706 static void ath11k_core_reset(struct work_struct *work)
1707 {
1708 	struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work);
1709 	int reset_count, fail_cont_count;
1710 	long time_left;
1711 
1712 	if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) {
1713 		ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags);
1714 		return;
1715 	}
1716 
1717 	/* Sometimes the recovery will fail and then the next all recovery fail,
1718 	 * this is to avoid infinite recovery since it can not recovery success.
1719 	 */
1720 	fail_cont_count = atomic_read(&ab->fail_cont_count);
1721 
1722 	if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL)
1723 		return;
1724 
1725 	if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST &&
1726 	    time_before(jiffies, ab->reset_fail_timeout))
1727 		return;
1728 
1729 	reset_count = atomic_inc_return(&ab->reset_count);
1730 
1731 	if (reset_count > 1) {
1732 		/* Sometimes it happened another reset worker before the previous one
1733 		 * completed, then the second reset worker will destroy the previous one,
1734 		 * thus below is to avoid that.
1735 		 */
1736 		ath11k_warn(ab, "already resetting count %d\n", reset_count);
1737 
1738 		reinit_completion(&ab->reset_complete);
1739 		time_left = wait_for_completion_timeout(&ab->reset_complete,
1740 							ATH11K_RESET_TIMEOUT_HZ);
1741 
1742 		if (time_left) {
1743 			ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n");
1744 			atomic_dec(&ab->reset_count);
1745 			return;
1746 		}
1747 
1748 		ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ;
1749 		/* Record the continuous recovery fail count when recovery failed*/
1750 		atomic_inc(&ab->fail_cont_count);
1751 	}
1752 
1753 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n");
1754 
1755 	ab->is_reset = true;
1756 	atomic_set(&ab->recovery_count, 0);
1757 	reinit_completion(&ab->recovery_start);
1758 	atomic_set(&ab->recovery_start_count, 0);
1759 
1760 	ath11k_core_pre_reconfigure_recovery(ab);
1761 
1762 	reinit_completion(&ab->reconfigure_complete);
1763 	ath11k_core_post_reconfigure_recovery(ab);
1764 
1765 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
1766 
1767 	time_left = wait_for_completion_timeout(&ab->recovery_start,
1768 						ATH11K_RECOVER_START_TIMEOUT_HZ);
1769 
1770 	ath11k_hif_power_down(ab);
1771 	ath11k_qmi_free_resource(ab);
1772 	ath11k_hif_power_up(ab);
1773 
1774 	ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
1775 }
1776 
1777 static int ath11k_init_hw_params(struct ath11k_base *ab)
1778 {
1779 	const struct ath11k_hw_params *hw_params = NULL;
1780 	int i;
1781 
1782 	for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1783 		hw_params = &ath11k_hw_params[i];
1784 
1785 		if (hw_params->hw_rev == ab->hw_rev)
1786 			break;
1787 	}
1788 
1789 	if (i == ARRAY_SIZE(ath11k_hw_params)) {
1790 		ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1791 		return -EINVAL;
1792 	}
1793 
1794 	ab->hw_params = *hw_params;
1795 
1796 	ath11k_info(ab, "%s\n", ab->hw_params.name);
1797 
1798 	return 0;
1799 }
1800 
1801 int ath11k_core_pre_init(struct ath11k_base *ab)
1802 {
1803 	int ret;
1804 
1805 	ret = ath11k_init_hw_params(ab);
1806 	if (ret) {
1807 		ath11k_err(ab, "failed to get hw params: %d\n", ret);
1808 		return ret;
1809 	}
1810 
1811 	return 0;
1812 }
1813 EXPORT_SYMBOL(ath11k_core_pre_init);
1814 
1815 int ath11k_core_init(struct ath11k_base *ab)
1816 {
1817 	int ret;
1818 
1819 	ret = ath11k_core_soc_create(ab);
1820 	if (ret) {
1821 		ath11k_err(ab, "failed to create soc core: %d\n", ret);
1822 		return ret;
1823 	}
1824 
1825 	return 0;
1826 }
1827 EXPORT_SYMBOL(ath11k_core_init);
1828 
1829 void ath11k_core_deinit(struct ath11k_base *ab)
1830 {
1831 	mutex_lock(&ab->core_lock);
1832 
1833 	ath11k_core_pdev_destroy(ab);
1834 	ath11k_core_stop(ab);
1835 
1836 	mutex_unlock(&ab->core_lock);
1837 
1838 	ath11k_hif_power_down(ab);
1839 	ath11k_mac_destroy(ab);
1840 	ath11k_core_soc_destroy(ab);
1841 }
1842 EXPORT_SYMBOL(ath11k_core_deinit);
1843 
1844 void ath11k_core_free(struct ath11k_base *ab)
1845 {
1846 	destroy_workqueue(ab->workqueue_aux);
1847 	destroy_workqueue(ab->workqueue);
1848 
1849 	kfree(ab);
1850 }
1851 EXPORT_SYMBOL(ath11k_core_free);
1852 
1853 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1854 				      enum ath11k_bus bus)
1855 {
1856 	struct ath11k_base *ab;
1857 
1858 	ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1859 	if (!ab)
1860 		return NULL;
1861 
1862 	init_completion(&ab->driver_recovery);
1863 
1864 	ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1865 	if (!ab->workqueue)
1866 		goto err_sc_free;
1867 
1868 	ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq");
1869 	if (!ab->workqueue_aux)
1870 		goto err_free_wq;
1871 
1872 	mutex_init(&ab->core_lock);
1873 	mutex_init(&ab->tbl_mtx_lock);
1874 	spin_lock_init(&ab->base_lock);
1875 	mutex_init(&ab->vdev_id_11d_lock);
1876 	init_completion(&ab->reset_complete);
1877 	init_completion(&ab->reconfigure_complete);
1878 	init_completion(&ab->recovery_start);
1879 
1880 	INIT_LIST_HEAD(&ab->peers);
1881 	init_waitqueue_head(&ab->peer_mapping_wq);
1882 	init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1883 	init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1884 	INIT_WORK(&ab->restart_work, ath11k_core_restart);
1885 	INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
1886 	INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work);
1887 	INIT_WORK(&ab->reset_work, ath11k_core_reset);
1888 	timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1889 	init_completion(&ab->htc_suspend);
1890 	init_completion(&ab->wow.wakeup_completed);
1891 
1892 	ab->dev = dev;
1893 	ab->hif.bus = bus;
1894 
1895 	return ab;
1896 
1897 err_free_wq:
1898 	destroy_workqueue(ab->workqueue);
1899 err_sc_free:
1900 	kfree(ab);
1901 	return NULL;
1902 }
1903 EXPORT_SYMBOL(ath11k_core_alloc);
1904 
1905 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1906 MODULE_LICENSE("Dual BSD/GPL");
1907