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