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