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
21unsigned int ath11k_debug_mask;
22EXPORT_SYMBOL(ath11k_debug_mask);
23module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
24MODULE_PARM_DESC(debug_mask, "Debugging mask");
25
26static unsigned int ath11k_crypto_mode;
27module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
28MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
29
30/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
31unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
32module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
33MODULE_PARM_DESC(frame_mode,
34		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
35
36bool ath11k_ftm_mode;
37module_param_named(ftm_mode, ath11k_ftm_mode, bool, 0444);
38MODULE_PARM_DESC(ftm_mode, "Boots up in factory test mode");
39
40static 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
802static 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
809void 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
819void 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
829void 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
839void 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
848void 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
855bool 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
867int 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}
924EXPORT_SYMBOL(ath11k_core_suspend);
925
926int 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}
967EXPORT_SYMBOL(ath11k_core_resume);
968
969static 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
1049int 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
1060int 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
1083enum ath11k_bdf_name_type {
1084	ATH11K_BDF_NAME_FULL,
1085	ATH11K_BDF_NAME_BUS_NAME,
1086	ATH11K_BDF_NAME_CHIP_ID,
1087};
1088
1089static 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
1141static 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
1148static 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
1155static 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
1162static 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
1169const 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
1191void 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
1199static 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		}
1269next:
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
1280out:
1281	return ret;
1282}
1283
1284static 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		}
1370next:
1371		/* jump over the padding */
1372		ie_len = ALIGN(ie_len, 4);
1373
1374		len -= ie_len;
1375		data += ie_len;
1376	}
1377
1378out:
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
1390err:
1391	ath11k_core_free_bdf(ab, bd);
1392	return ret;
1393}
1394
1395int 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
1411int 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
1498exit:
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
1509int 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
1548exit:
1549	if (!ret)
1550		ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");
1551
1552	return ret;
1553}
1554
1555static 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
1567static 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
1596err_debugfs_reg:
1597	ath11k_debugfs_soc_destroy(ab);
1598err_qmi_deinit:
1599	ath11k_qmi_deinit_service(ab);
1600	return ret;
1601}
1602
1603static 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
1611static 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
1648err_thermal_unregister:
1649	ath11k_thermal_unregister(ab);
1650err_mac_unregister:
1651	ath11k_mac_unregister(ab);
1652err_dp_pdev_free:
1653	ath11k_dp_pdev_free(ab);
1654err_pdev_debug:
1655	ath11k_debugfs_pdev_destroy(ab);
1656
1657	return ret;
1658}
1659
1660static 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
1670static 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
1769err_reo_cleanup:
1770	ath11k_dp_pdev_reo_cleanup(ab);
1771err_mac_destroy:
1772	ath11k_mac_destroy(ab);
1773err_hif_stop:
1774	ath11k_hif_stop(ab);
1775err_wmi_detach:
1776	ath11k_wmi_detach(ab);
1777
1778	return ret;
1779}
1780
1781static 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
1798int 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
1854err_core_stop:
1855	ath11k_core_stop(ab);
1856	ath11k_mac_destroy(ab);
1857err_dp_free:
1858	ath11k_dp_free(ab);
1859	mutex_unlock(&ab->core_lock);
1860err_firmware_stop:
1861	ath11k_qmi_firmware_stop(ab);
1862
1863	return ret;
1864}
1865
1866static 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
1898err_hal_srng_deinit:
1899	ath11k_hal_srng_deinit(ab);
1900	return ret;
1901}
1902
1903void 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
1924static 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
1953void 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
2002static 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
2047static 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
2065static 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
2138static 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
2162int 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}
2180EXPORT_SYMBOL(ath11k_core_pre_init);
2181
2182int 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}
2194EXPORT_SYMBOL(ath11k_core_init);
2195
2196void 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}
2210EXPORT_SYMBOL(ath11k_core_deinit);
2211
2212void ath11k_core_free(struct ath11k_base *ab)
2213{
2214	destroy_workqueue(ab->workqueue_aux);
2215	destroy_workqueue(ab->workqueue);
2216
2217	kfree(ab);
2218}
2219EXPORT_SYMBOL(ath11k_core_free);
2220
2221struct 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
2264err_free_wq:
2265	destroy_workqueue(ab->workqueue);
2266err_sc_free:
2267	kfree(ab);
2268	return NULL;
2269}
2270EXPORT_SYMBOL(ath11k_core_alloc);
2271
2272MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
2273MODULE_LICENSE("Dual BSD/GPL");
2274