brintos

brintos / linux-shallow public Read only

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