Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause-Clear
0002 /*
0003  * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
0004  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
0005  */
0006 
0007 #include <linux/module.h>
0008 #include <linux/slab.h>
0009 #include <linux/remoteproc.h>
0010 #include <linux/firmware.h>
0011 #include <linux/of.h>
0012 
0013 #include "core.h"
0014 #include "dp_tx.h"
0015 #include "dp_rx.h"
0016 #include "debug.h"
0017 #include "hif.h"
0018 #include "wow.h"
0019 
0020 unsigned int ath11k_debug_mask;
0021 EXPORT_SYMBOL(ath11k_debug_mask);
0022 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
0023 MODULE_PARM_DESC(debug_mask, "Debugging mask");
0024 
0025 static unsigned int ath11k_crypto_mode;
0026 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
0027 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
0028 
0029 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
0030 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
0031 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
0032 MODULE_PARM_DESC(frame_mode,
0033          "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
0034 
0035 static const struct ath11k_hw_params ath11k_hw_params[] = {
0036     {
0037         .hw_rev = ATH11K_HW_IPQ8074,
0038         .name = "ipq8074 hw2.0",
0039         .fw = {
0040             .dir = "IPQ8074/hw2.0",
0041             .board_size = 256 * 1024,
0042             .cal_offset = 128 * 1024,
0043         },
0044         .max_radios = 3,
0045         .bdf_addr = 0x4B0C0000,
0046         .hw_ops = &ipq8074_ops,
0047         .ring_mask = &ath11k_hw_ring_mask_ipq8074,
0048         .internal_sleep_clock = false,
0049         .regs = &ipq8074_regs,
0050         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
0051         .host_ce_config = ath11k_host_ce_config_ipq8074,
0052         .ce_count = 12,
0053         .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
0054         .target_ce_count = 11,
0055         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
0056         .svc_to_ce_map_len = 21,
0057         .single_pdev_only = false,
0058         .rxdma1_enable = true,
0059         .num_rxmda_per_pdev = 1,
0060         .rx_mac_buf_ring = false,
0061         .vdev_start_delay = false,
0062         .htt_peer_map_v2 = true,
0063 
0064         .spectral = {
0065             .fft_sz = 2,
0066             /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes.
0067              * so added pad size as 2 bytes to compensate the BIN size
0068              */
0069             .fft_pad_sz = 2,
0070             .summary_pad_sz = 0,
0071             .fft_hdr_len = 16,
0072             .max_fft_bins = 512,
0073         },
0074 
0075         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0076                     BIT(NL80211_IFTYPE_AP) |
0077                     BIT(NL80211_IFTYPE_MESH_POINT),
0078         .supports_monitor = true,
0079         .full_monitor_mode = false,
0080         .supports_shadow_regs = false,
0081         .idle_ps = false,
0082         .supports_sta_ps = false,
0083         .cold_boot_calib = true,
0084         .fw_mem_mode = 0,
0085         .num_vdevs = 16 + 1,
0086         .num_peers = 512,
0087         .supports_suspend = false,
0088         .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0089         .supports_regdb = false,
0090         .fix_l1ss = true,
0091         .credit_flow = false,
0092         .max_tx_ring = DP_TCL_NUM_RING_MAX,
0093         .hal_params = &ath11k_hw_hal_params_ipq8074,
0094         .supports_dynamic_smps_6ghz = false,
0095         .alloc_cacheable_memory = true,
0096         .supports_rssi_stats = false,
0097         .fw_wmi_diag_event = false,
0098         .current_cc_support = false,
0099         .dbr_debug_support = true,
0100         .global_reset = false,
0101         .bios_sar_capa = NULL,
0102         .m3_fw_support = false,
0103         .fixed_bdf_addr = true,
0104         .fixed_mem_region = true,
0105         .static_window_map = false,
0106         .hybrid_bus_type = false,
0107         .fixed_fw_mem = false,
0108         .support_off_channel_tx = false,
0109     },
0110     {
0111         .hw_rev = ATH11K_HW_IPQ6018_HW10,
0112         .name = "ipq6018 hw1.0",
0113         .fw = {
0114             .dir = "IPQ6018/hw1.0",
0115             .board_size = 256 * 1024,
0116             .cal_offset = 128 * 1024,
0117         },
0118         .max_radios = 2,
0119         .bdf_addr = 0x4ABC0000,
0120         .hw_ops = &ipq6018_ops,
0121         .ring_mask = &ath11k_hw_ring_mask_ipq8074,
0122         .internal_sleep_clock = false,
0123         .regs = &ipq8074_regs,
0124         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
0125         .host_ce_config = ath11k_host_ce_config_ipq8074,
0126         .ce_count = 12,
0127         .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
0128         .target_ce_count = 11,
0129         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
0130         .svc_to_ce_map_len = 19,
0131         .single_pdev_only = false,
0132         .rxdma1_enable = true,
0133         .num_rxmda_per_pdev = 1,
0134         .rx_mac_buf_ring = false,
0135         .vdev_start_delay = false,
0136         .htt_peer_map_v2 = true,
0137 
0138         .spectral = {
0139             .fft_sz = 4,
0140             .fft_pad_sz = 0,
0141             .summary_pad_sz = 0,
0142             .fft_hdr_len = 16,
0143             .max_fft_bins = 512,
0144         },
0145 
0146         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0147                     BIT(NL80211_IFTYPE_AP) |
0148                     BIT(NL80211_IFTYPE_MESH_POINT),
0149         .supports_monitor = true,
0150         .full_monitor_mode = false,
0151         .supports_shadow_regs = false,
0152         .idle_ps = false,
0153         .supports_sta_ps = false,
0154         .cold_boot_calib = true,
0155         .fw_mem_mode = 0,
0156         .num_vdevs = 16 + 1,
0157         .num_peers = 512,
0158         .supports_suspend = false,
0159         .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0160         .supports_regdb = false,
0161         .fix_l1ss = true,
0162         .credit_flow = false,
0163         .max_tx_ring = DP_TCL_NUM_RING_MAX,
0164         .hal_params = &ath11k_hw_hal_params_ipq8074,
0165         .supports_dynamic_smps_6ghz = false,
0166         .alloc_cacheable_memory = true,
0167         .supports_rssi_stats = false,
0168         .fw_wmi_diag_event = false,
0169         .current_cc_support = false,
0170         .dbr_debug_support = true,
0171         .global_reset = false,
0172         .bios_sar_capa = NULL,
0173         .m3_fw_support = false,
0174         .fixed_bdf_addr = true,
0175         .fixed_mem_region = true,
0176         .static_window_map = false,
0177         .hybrid_bus_type = false,
0178         .fixed_fw_mem = false,
0179         .support_off_channel_tx = false,
0180     },
0181     {
0182         .name = "qca6390 hw2.0",
0183         .hw_rev = ATH11K_HW_QCA6390_HW20,
0184         .fw = {
0185             .dir = "QCA6390/hw2.0",
0186             .board_size = 256 * 1024,
0187             .cal_offset = 128 * 1024,
0188         },
0189         .max_radios = 3,
0190         .bdf_addr = 0x4B0C0000,
0191         .hw_ops = &qca6390_ops,
0192         .ring_mask = &ath11k_hw_ring_mask_qca6390,
0193         .internal_sleep_clock = true,
0194         .regs = &qca6390_regs,
0195         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0196         .host_ce_config = ath11k_host_ce_config_qca6390,
0197         .ce_count = 9,
0198         .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0199         .target_ce_count = 9,
0200         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0201         .svc_to_ce_map_len = 14,
0202         .single_pdev_only = true,
0203         .rxdma1_enable = false,
0204         .num_rxmda_per_pdev = 2,
0205         .rx_mac_buf_ring = true,
0206         .vdev_start_delay = true,
0207         .htt_peer_map_v2 = false,
0208 
0209         .spectral = {
0210             .fft_sz = 0,
0211             .fft_pad_sz = 0,
0212             .summary_pad_sz = 0,
0213             .fft_hdr_len = 0,
0214             .max_fft_bins = 0,
0215         },
0216 
0217         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0218                     BIT(NL80211_IFTYPE_AP),
0219         .supports_monitor = false,
0220         .full_monitor_mode = false,
0221         .supports_shadow_regs = true,
0222         .idle_ps = true,
0223         .supports_sta_ps = true,
0224         .cold_boot_calib = false,
0225         .fw_mem_mode = 0,
0226         .num_vdevs = 16 + 1,
0227         .num_peers = 512,
0228         .supports_suspend = true,
0229         .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
0230         .supports_regdb = false,
0231         .fix_l1ss = true,
0232         .credit_flow = true,
0233         .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0234         .hal_params = &ath11k_hw_hal_params_qca6390,
0235         .supports_dynamic_smps_6ghz = false,
0236         .alloc_cacheable_memory = false,
0237         .supports_rssi_stats = true,
0238         .fw_wmi_diag_event = true,
0239         .current_cc_support = true,
0240         .dbr_debug_support = false,
0241         .global_reset = true,
0242         .bios_sar_capa = NULL,
0243         .m3_fw_support = true,
0244         .fixed_bdf_addr = false,
0245         .fixed_mem_region = false,
0246         .static_window_map = false,
0247         .hybrid_bus_type = false,
0248         .fixed_fw_mem = false,
0249         .support_off_channel_tx = true,
0250     },
0251     {
0252         .name = "qcn9074 hw1.0",
0253         .hw_rev = ATH11K_HW_QCN9074_HW10,
0254         .fw = {
0255             .dir = "QCN9074/hw1.0",
0256             .board_size = 256 * 1024,
0257             .cal_offset = 128 * 1024,
0258         },
0259         .max_radios = 1,
0260         .single_pdev_only = false,
0261         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
0262         .hw_ops = &qcn9074_ops,
0263         .ring_mask = &ath11k_hw_ring_mask_qcn9074,
0264         .internal_sleep_clock = false,
0265         .regs = &qcn9074_regs,
0266         .host_ce_config = ath11k_host_ce_config_qcn9074,
0267         .ce_count = 6,
0268         .target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
0269         .target_ce_count = 9,
0270         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
0271         .svc_to_ce_map_len = 18,
0272         .rxdma1_enable = true,
0273         .num_rxmda_per_pdev = 1,
0274         .rx_mac_buf_ring = false,
0275         .vdev_start_delay = false,
0276         .htt_peer_map_v2 = true,
0277 
0278         .spectral = {
0279             .fft_sz = 2,
0280             .fft_pad_sz = 0,
0281             .summary_pad_sz = 16,
0282             .fft_hdr_len = 24,
0283             .max_fft_bins = 1024,
0284         },
0285 
0286         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0287                     BIT(NL80211_IFTYPE_AP) |
0288                     BIT(NL80211_IFTYPE_MESH_POINT),
0289         .supports_monitor = true,
0290         .full_monitor_mode = true,
0291         .supports_shadow_regs = false,
0292         .idle_ps = false,
0293         .supports_sta_ps = false,
0294         .cold_boot_calib = false,
0295         .fw_mem_mode = 2,
0296         .num_vdevs = 8,
0297         .num_peers = 128,
0298         .supports_suspend = false,
0299         .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
0300         .supports_regdb = false,
0301         .fix_l1ss = true,
0302         .credit_flow = false,
0303         .max_tx_ring = DP_TCL_NUM_RING_MAX,
0304         .hal_params = &ath11k_hw_hal_params_ipq8074,
0305         .supports_dynamic_smps_6ghz = true,
0306         .alloc_cacheable_memory = true,
0307         .supports_rssi_stats = false,
0308         .fw_wmi_diag_event = false,
0309         .current_cc_support = false,
0310         .dbr_debug_support = true,
0311         .global_reset = false,
0312         .bios_sar_capa = NULL,
0313         .m3_fw_support = true,
0314         .fixed_bdf_addr = false,
0315         .fixed_mem_region = false,
0316         .static_window_map = true,
0317         .hybrid_bus_type = false,
0318         .fixed_fw_mem = false,
0319         .support_off_channel_tx = false,
0320     },
0321     {
0322         .name = "wcn6855 hw2.0",
0323         .hw_rev = ATH11K_HW_WCN6855_HW20,
0324         .fw = {
0325             .dir = "WCN6855/hw2.0",
0326             .board_size = 256 * 1024,
0327             .cal_offset = 128 * 1024,
0328         },
0329         .max_radios = 3,
0330         .bdf_addr = 0x4B0C0000,
0331         .hw_ops = &wcn6855_ops,
0332         .ring_mask = &ath11k_hw_ring_mask_qca6390,
0333         .internal_sleep_clock = true,
0334         .regs = &wcn6855_regs,
0335         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0336         .host_ce_config = ath11k_host_ce_config_qca6390,
0337         .ce_count = 9,
0338         .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0339         .target_ce_count = 9,
0340         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0341         .svc_to_ce_map_len = 14,
0342         .single_pdev_only = true,
0343         .rxdma1_enable = false,
0344         .num_rxmda_per_pdev = 2,
0345         .rx_mac_buf_ring = true,
0346         .vdev_start_delay = true,
0347         .htt_peer_map_v2 = false,
0348 
0349         .spectral = {
0350             .fft_sz = 0,
0351             .fft_pad_sz = 0,
0352             .summary_pad_sz = 0,
0353             .fft_hdr_len = 0,
0354             .max_fft_bins = 0,
0355         },
0356 
0357         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0358                     BIT(NL80211_IFTYPE_AP),
0359         .supports_monitor = false,
0360         .full_monitor_mode = false,
0361         .supports_shadow_regs = true,
0362         .idle_ps = true,
0363         .supports_sta_ps = true,
0364         .cold_boot_calib = false,
0365         .fw_mem_mode = 0,
0366         .num_vdevs = 16 + 1,
0367         .num_peers = 512,
0368         .supports_suspend = true,
0369         .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
0370         .supports_regdb = true,
0371         .fix_l1ss = false,
0372         .credit_flow = true,
0373         .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0374         .hal_params = &ath11k_hw_hal_params_qca6390,
0375         .supports_dynamic_smps_6ghz = false,
0376         .alloc_cacheable_memory = false,
0377         .supports_rssi_stats = true,
0378         .fw_wmi_diag_event = true,
0379         .current_cc_support = true,
0380         .dbr_debug_support = false,
0381         .global_reset = true,
0382         .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
0383         .m3_fw_support = true,
0384         .fixed_bdf_addr = false,
0385         .fixed_mem_region = false,
0386         .static_window_map = false,
0387         .hybrid_bus_type = false,
0388         .fixed_fw_mem = false,
0389         .support_off_channel_tx = true,
0390     },
0391     {
0392         .name = "wcn6855 hw2.1",
0393         .hw_rev = ATH11K_HW_WCN6855_HW21,
0394         .fw = {
0395             .dir = "WCN6855/hw2.1",
0396             .board_size = 256 * 1024,
0397             .cal_offset = 128 * 1024,
0398         },
0399         .max_radios = 3,
0400         .bdf_addr = 0x4B0C0000,
0401         .hw_ops = &wcn6855_ops,
0402         .ring_mask = &ath11k_hw_ring_mask_qca6390,
0403         .internal_sleep_clock = true,
0404         .regs = &wcn6855_regs,
0405         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
0406         .host_ce_config = ath11k_host_ce_config_qca6390,
0407         .ce_count = 9,
0408         .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0409         .target_ce_count = 9,
0410         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0411         .svc_to_ce_map_len = 14,
0412         .single_pdev_only = true,
0413         .rxdma1_enable = false,
0414         .num_rxmda_per_pdev = 2,
0415         .rx_mac_buf_ring = true,
0416         .vdev_start_delay = true,
0417         .htt_peer_map_v2 = false,
0418 
0419         .spectral = {
0420             .fft_sz = 0,
0421             .fft_pad_sz = 0,
0422             .summary_pad_sz = 0,
0423             .fft_hdr_len = 0,
0424             .max_fft_bins = 0,
0425         },
0426 
0427         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0428                     BIT(NL80211_IFTYPE_AP),
0429         .supports_monitor = false,
0430         .supports_shadow_regs = true,
0431         .idle_ps = true,
0432         .supports_sta_ps = true,
0433         .cold_boot_calib = false,
0434         .fw_mem_mode = 0,
0435         .num_vdevs = 16 + 1,
0436         .num_peers = 512,
0437         .supports_suspend = true,
0438         .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
0439         .supports_regdb = true,
0440         .fix_l1ss = false,
0441         .credit_flow = true,
0442         .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0443         .hal_params = &ath11k_hw_hal_params_qca6390,
0444         .supports_dynamic_smps_6ghz = false,
0445         .alloc_cacheable_memory = false,
0446         .supports_rssi_stats = true,
0447         .fw_wmi_diag_event = true,
0448         .current_cc_support = true,
0449         .dbr_debug_support = false,
0450         .global_reset = true,
0451         .bios_sar_capa = &ath11k_hw_sar_capa_wcn6855,
0452         .m3_fw_support = true,
0453         .fixed_bdf_addr = false,
0454         .fixed_mem_region = false,
0455         .static_window_map = false,
0456         .hybrid_bus_type = false,
0457         .fixed_fw_mem = false,
0458         .support_off_channel_tx = true,
0459     },
0460     {
0461         .name = "wcn6750 hw1.0",
0462         .hw_rev = ATH11K_HW_WCN6750_HW10,
0463         .fw = {
0464             .dir = "WCN6750/hw1.0",
0465             .board_size = 256 * 1024,
0466             .cal_offset = 128 * 1024,
0467         },
0468         .max_radios = 1,
0469         .bdf_addr = 0x4B0C0000,
0470         .hw_ops = &wcn6750_ops,
0471         .ring_mask = &ath11k_hw_ring_mask_qca6390,
0472         .internal_sleep_clock = false,
0473         .regs = &wcn6750_regs,
0474         .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_WCN6750,
0475         .host_ce_config = ath11k_host_ce_config_qca6390,
0476         .ce_count = 9,
0477         .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
0478         .target_ce_count = 9,
0479         .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
0480         .svc_to_ce_map_len = 14,
0481         .single_pdev_only = true,
0482         .rxdma1_enable = false,
0483         .num_rxmda_per_pdev = 1,
0484         .rx_mac_buf_ring = true,
0485         .vdev_start_delay = true,
0486         .htt_peer_map_v2 = false,
0487 
0488         .spectral = {
0489             .fft_sz = 0,
0490             .fft_pad_sz = 0,
0491             .summary_pad_sz = 0,
0492             .fft_hdr_len = 0,
0493             .max_fft_bins = 0,
0494         },
0495 
0496         .interface_modes = BIT(NL80211_IFTYPE_STATION) |
0497                     BIT(NL80211_IFTYPE_AP),
0498         .supports_monitor = false,
0499         .supports_shadow_regs = true,
0500         .idle_ps = true,
0501         .supports_sta_ps = true,
0502         .cold_boot_calib = false,
0503         .fw_mem_mode = 0,
0504         .num_vdevs = 16 + 1,
0505         .num_peers = 512,
0506         .supports_suspend = false,
0507         .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
0508         .supports_regdb = true,
0509         .fix_l1ss = false,
0510         .credit_flow = true,
0511         .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390,
0512         .hal_params = &ath11k_hw_hal_params_qca6390,
0513         .supports_dynamic_smps_6ghz = false,
0514         .alloc_cacheable_memory = false,
0515         .supports_rssi_stats = true,
0516         .fw_wmi_diag_event = false,
0517         .current_cc_support = true,
0518         .dbr_debug_support = false,
0519         .global_reset = false,
0520         .bios_sar_capa = NULL,
0521         .m3_fw_support = false,
0522         .fixed_bdf_addr = false,
0523         .fixed_mem_region = false,
0524         .static_window_map = true,
0525         .hybrid_bus_type = true,
0526         .fixed_fw_mem = true,
0527         .support_off_channel_tx = false,
0528     },
0529 };
0530 
0531 static inline struct ath11k_pdev *ath11k_core_get_single_pdev(struct ath11k_base *ab)
0532 {
0533     WARN_ON(!ab->hw_params.single_pdev_only);
0534 
0535     return &ab->pdevs[0];
0536 }
0537 
0538 int ath11k_core_suspend(struct ath11k_base *ab)
0539 {
0540     int ret;
0541     struct ath11k_pdev *pdev;
0542     struct ath11k *ar;
0543 
0544     if (!ab->hw_params.supports_suspend)
0545         return -EOPNOTSUPP;
0546 
0547     /* so far single_pdev_only chips have supports_suspend as true
0548      * and only the first pdev is valid.
0549      */
0550     pdev = ath11k_core_get_single_pdev(ab);
0551     ar = pdev->ar;
0552     if (!ar || ar->state != ATH11K_STATE_OFF)
0553         return 0;
0554 
0555     ret = ath11k_dp_rx_pktlog_stop(ab, true);
0556     if (ret) {
0557         ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
0558                 ret);
0559         return ret;
0560     }
0561 
0562     ret = ath11k_mac_wait_tx_complete(ar);
0563     if (ret) {
0564         ath11k_warn(ab, "failed to wait tx complete: %d\n", ret);
0565         return ret;
0566     }
0567 
0568     ret = ath11k_wow_enable(ab);
0569     if (ret) {
0570         ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
0571         return ret;
0572     }
0573 
0574     ret = ath11k_dp_rx_pktlog_stop(ab, false);
0575     if (ret) {
0576         ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
0577                 ret);
0578         return ret;
0579     }
0580 
0581     ath11k_ce_stop_shadow_timers(ab);
0582     ath11k_dp_stop_shadow_timers(ab);
0583 
0584     ath11k_hif_irq_disable(ab);
0585     ath11k_hif_ce_irq_disable(ab);
0586 
0587     ret = ath11k_hif_suspend(ab);
0588     if (ret) {
0589         ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
0590         return ret;
0591     }
0592 
0593     return 0;
0594 }
0595 EXPORT_SYMBOL(ath11k_core_suspend);
0596 
0597 int ath11k_core_resume(struct ath11k_base *ab)
0598 {
0599     int ret;
0600     struct ath11k_pdev *pdev;
0601     struct ath11k *ar;
0602 
0603     if (!ab->hw_params.supports_suspend)
0604         return -EOPNOTSUPP;
0605 
0606     /* so far signle_pdev_only chips have supports_suspend as true
0607      * and only the first pdev is valid.
0608      */
0609     pdev = ath11k_core_get_single_pdev(ab);
0610     ar = pdev->ar;
0611     if (!ar || ar->state != ATH11K_STATE_OFF)
0612         return 0;
0613 
0614     ret = ath11k_hif_resume(ab);
0615     if (ret) {
0616         ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
0617         return ret;
0618     }
0619 
0620     ath11k_hif_ce_irq_enable(ab);
0621     ath11k_hif_irq_enable(ab);
0622 
0623     ret = ath11k_dp_rx_pktlog_start(ab);
0624     if (ret) {
0625         ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
0626                 ret);
0627         return ret;
0628     }
0629 
0630     ret = ath11k_wow_wakeup(ab);
0631     if (ret) {
0632         ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
0633         return ret;
0634     }
0635 
0636     return 0;
0637 }
0638 EXPORT_SYMBOL(ath11k_core_resume);
0639 
0640 static void ath11k_core_check_cc_code_bdfext(const struct dmi_header *hdr, void *data)
0641 {
0642     struct ath11k_base *ab = data;
0643     const char *magic = ATH11K_SMBIOS_BDF_EXT_MAGIC;
0644     struct ath11k_smbios_bdf *smbios = (struct ath11k_smbios_bdf *)hdr;
0645     ssize_t copied;
0646     size_t len;
0647     int i;
0648 
0649     if (ab->qmi.target.bdf_ext[0] != '\0')
0650         return;
0651 
0652     if (hdr->type != ATH11K_SMBIOS_BDF_EXT_TYPE)
0653         return;
0654 
0655     if (hdr->length != ATH11K_SMBIOS_BDF_EXT_LENGTH) {
0656         ath11k_dbg(ab, ATH11K_DBG_BOOT,
0657                "wrong smbios bdf ext type length (%d).\n",
0658                hdr->length);
0659         return;
0660     }
0661 
0662     spin_lock_bh(&ab->base_lock);
0663 
0664     switch (smbios->country_code_flag) {
0665     case ATH11K_SMBIOS_CC_ISO:
0666         ab->new_alpha2[0] = (smbios->cc_code >> 8) & 0xff;
0667         ab->new_alpha2[1] = smbios->cc_code & 0xff;
0668         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios cc_code %c%c\n",
0669                ab->new_alpha2[0], ab->new_alpha2[1]);
0670         break;
0671     case ATH11K_SMBIOS_CC_WW:
0672         ab->new_alpha2[0] = '0';
0673         ab->new_alpha2[1] = '0';
0674         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot smbios worldwide regdomain\n");
0675         break;
0676     default:
0677         ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot ignore smbios country code setting %d\n",
0678                smbios->country_code_flag);
0679         break;
0680     }
0681 
0682     spin_unlock_bh(&ab->base_lock);
0683 
0684     if (!smbios->bdf_enabled) {
0685         ath11k_dbg(ab, ATH11K_DBG_BOOT, "bdf variant name not found.\n");
0686         return;
0687     }
0688 
0689     /* Only one string exists (per spec) */
0690     if (memcmp(smbios->bdf_ext, magic, strlen(magic)) != 0) {
0691         ath11k_dbg(ab, ATH11K_DBG_BOOT,
0692                "bdf variant magic does not match.\n");
0693         return;
0694     }
0695 
0696     len = min_t(size_t,
0697             strlen(smbios->bdf_ext), sizeof(ab->qmi.target.bdf_ext));
0698     for (i = 0; i < len; i++) {
0699         if (!isascii(smbios->bdf_ext[i]) || !isprint(smbios->bdf_ext[i])) {
0700             ath11k_dbg(ab, ATH11K_DBG_BOOT,
0701                    "bdf variant name contains non ascii chars.\n");
0702             return;
0703         }
0704     }
0705 
0706     /* Copy extension name without magic prefix */
0707     copied = strscpy(ab->qmi.target.bdf_ext, smbios->bdf_ext + strlen(magic),
0708              sizeof(ab->qmi.target.bdf_ext));
0709     if (copied < 0) {
0710         ath11k_dbg(ab, ATH11K_DBG_BOOT,
0711                "bdf variant string is longer than the buffer can accommodate\n");
0712         return;
0713     }
0714 
0715     ath11k_dbg(ab, ATH11K_DBG_BOOT,
0716            "found and validated bdf variant smbios_type 0x%x bdf %s\n",
0717            ATH11K_SMBIOS_BDF_EXT_TYPE, ab->qmi.target.bdf_ext);
0718 }
0719 
0720 int ath11k_core_check_smbios(struct ath11k_base *ab)
0721 {
0722     ab->qmi.target.bdf_ext[0] = '\0';
0723     dmi_walk(ath11k_core_check_cc_code_bdfext, ab);
0724 
0725     if (ab->qmi.target.bdf_ext[0] == '\0')
0726         return -ENODATA;
0727 
0728     return 0;
0729 }
0730 
0731 int ath11k_core_check_dt(struct ath11k_base *ab)
0732 {
0733     size_t max_len = sizeof(ab->qmi.target.bdf_ext);
0734     const char *variant = NULL;
0735     struct device_node *node;
0736 
0737     node = ab->dev->of_node;
0738     if (!node)
0739         return -ENOENT;
0740 
0741     of_property_read_string(node, "qcom,ath11k-calibration-variant",
0742                 &variant);
0743     if (!variant)
0744         return -ENODATA;
0745 
0746     if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
0747         ath11k_dbg(ab, ATH11K_DBG_BOOT,
0748                "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
0749                 variant);
0750 
0751     return 0;
0752 }
0753 
0754 static int __ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
0755                        size_t name_len, bool with_variant)
0756 {
0757     /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
0758     char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
0759 
0760     if (with_variant && ab->qmi.target.bdf_ext[0] != '\0')
0761         scnprintf(variant, sizeof(variant), ",variant=%s",
0762               ab->qmi.target.bdf_ext);
0763 
0764     switch (ab->id.bdf_search) {
0765     case ATH11K_BDF_SEARCH_BUS_AND_BOARD:
0766         scnprintf(name, name_len,
0767               "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s",
0768               ath11k_bus_str(ab->hif.bus),
0769               ab->id.vendor, ab->id.device,
0770               ab->id.subsystem_vendor,
0771               ab->id.subsystem_device,
0772               ab->qmi.target.chip_id,
0773               ab->qmi.target.board_id,
0774               variant);
0775         break;
0776     default:
0777         scnprintf(name, name_len,
0778               "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
0779               ath11k_bus_str(ab->hif.bus),
0780               ab->qmi.target.chip_id,
0781               ab->qmi.target.board_id, variant);
0782         break;
0783     }
0784 
0785     ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
0786 
0787     return 0;
0788 }
0789 
0790 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
0791                      size_t name_len)
0792 {
0793     return __ath11k_core_create_board_name(ab, name, name_len, true);
0794 }
0795 
0796 static int ath11k_core_create_fallback_board_name(struct ath11k_base *ab, char *name,
0797                           size_t name_len)
0798 {
0799     return __ath11k_core_create_board_name(ab, name, name_len, false);
0800 }
0801 
0802 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
0803                             const char *file)
0804 {
0805     const struct firmware *fw;
0806     char path[100];
0807     int ret;
0808 
0809     if (file == NULL)
0810         return ERR_PTR(-ENOENT);
0811 
0812     ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
0813 
0814     ret = firmware_request_nowarn(&fw, path, ab->dev);
0815     if (ret)
0816         return ERR_PTR(ret);
0817 
0818     ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
0819            path, fw->size);
0820 
0821     return fw;
0822 }
0823 
0824 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
0825 {
0826     if (!IS_ERR(bd->fw))
0827         release_firmware(bd->fw);
0828 
0829     memset(bd, 0, sizeof(*bd));
0830 }
0831 
0832 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
0833                      struct ath11k_board_data *bd,
0834                      const void *buf, size_t buf_len,
0835                      const char *boardname,
0836                      int ie_id,
0837                      int name_id,
0838                      int data_id)
0839 {
0840     const struct ath11k_fw_ie *hdr;
0841     bool name_match_found;
0842     int ret, board_ie_id;
0843     size_t board_ie_len;
0844     const void *board_ie_data;
0845 
0846     name_match_found = false;
0847 
0848     /* go through ATH11K_BD_IE_BOARD_/ATH11K_BD_IE_REGDB_ elements */
0849     while (buf_len > sizeof(struct ath11k_fw_ie)) {
0850         hdr = buf;
0851         board_ie_id = le32_to_cpu(hdr->id);
0852         board_ie_len = le32_to_cpu(hdr->len);
0853         board_ie_data = hdr->data;
0854 
0855         buf_len -= sizeof(*hdr);
0856         buf += sizeof(*hdr);
0857 
0858         if (buf_len < ALIGN(board_ie_len, 4)) {
0859             ath11k_err(ab, "invalid %s length: %zu < %zu\n",
0860                    ath11k_bd_ie_type_str(ie_id),
0861                    buf_len, ALIGN(board_ie_len, 4));
0862             ret = -EINVAL;
0863             goto out;
0864         }
0865 
0866         if (board_ie_id == name_id) {
0867             ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
0868                     board_ie_data, board_ie_len);
0869 
0870             if (board_ie_len != strlen(boardname))
0871                 goto next;
0872 
0873             ret = memcmp(board_ie_data, boardname, strlen(boardname));
0874             if (ret)
0875                 goto next;
0876 
0877             name_match_found = true;
0878             ath11k_dbg(ab, ATH11K_DBG_BOOT,
0879                    "boot found match %s for name '%s'",
0880                    ath11k_bd_ie_type_str(ie_id),
0881                    boardname);
0882         } else if (board_ie_id == data_id) {
0883             if (!name_match_found)
0884                 /* no match found */
0885                 goto next;
0886 
0887             ath11k_dbg(ab, ATH11K_DBG_BOOT,
0888                    "boot found %s for '%s'",
0889                    ath11k_bd_ie_type_str(ie_id),
0890                    boardname);
0891 
0892             bd->data = board_ie_data;
0893             bd->len = board_ie_len;
0894 
0895             ret = 0;
0896             goto out;
0897         } else {
0898             ath11k_warn(ab, "unknown %s id found: %d\n",
0899                     ath11k_bd_ie_type_str(ie_id),
0900                     board_ie_id);
0901         }
0902 next:
0903         /* jump over the padding */
0904         board_ie_len = ALIGN(board_ie_len, 4);
0905 
0906         buf_len -= board_ie_len;
0907         buf += board_ie_len;
0908     }
0909 
0910     /* no match found */
0911     ret = -ENOENT;
0912 
0913 out:
0914     return ret;
0915 }
0916 
0917 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
0918                           struct ath11k_board_data *bd,
0919                           const char *boardname,
0920                           int ie_id_match,
0921                           int name_id,
0922                           int data_id)
0923 {
0924     size_t len, magic_len;
0925     const u8 *data;
0926     char *filename, filepath[100];
0927     size_t ie_len;
0928     struct ath11k_fw_ie *hdr;
0929     int ret, ie_id;
0930 
0931     filename = ATH11K_BOARD_API2_FILE;
0932 
0933     if (!bd->fw)
0934         bd->fw = ath11k_core_firmware_request(ab, filename);
0935 
0936     if (IS_ERR(bd->fw))
0937         return PTR_ERR(bd->fw);
0938 
0939     data = bd->fw->data;
0940     len = bd->fw->size;
0941 
0942     ath11k_core_create_firmware_path(ab, filename,
0943                      filepath, sizeof(filepath));
0944 
0945     /* magic has extra null byte padded */
0946     magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
0947     if (len < magic_len) {
0948         ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
0949                filepath, len);
0950         ret = -EINVAL;
0951         goto err;
0952     }
0953 
0954     if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
0955         ath11k_err(ab, "found invalid board magic\n");
0956         ret = -EINVAL;
0957         goto err;
0958     }
0959 
0960     /* magic is padded to 4 bytes */
0961     magic_len = ALIGN(magic_len, 4);
0962     if (len < magic_len) {
0963         ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
0964                filepath, len);
0965         ret = -EINVAL;
0966         goto err;
0967     }
0968 
0969     data += magic_len;
0970     len -= magic_len;
0971 
0972     while (len > sizeof(struct ath11k_fw_ie)) {
0973         hdr = (struct ath11k_fw_ie *)data;
0974         ie_id = le32_to_cpu(hdr->id);
0975         ie_len = le32_to_cpu(hdr->len);
0976 
0977         len -= sizeof(*hdr);
0978         data = hdr->data;
0979 
0980         if (len < ALIGN(ie_len, 4)) {
0981             ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
0982                    ie_id, ie_len, len);
0983             ret = -EINVAL;
0984             goto err;
0985         }
0986 
0987         if (ie_id == ie_id_match) {
0988             ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
0989                                 ie_len,
0990                                 boardname,
0991                                 ie_id_match,
0992                                 name_id,
0993                                 data_id);
0994             if (ret == -ENOENT)
0995                 /* no match found, continue */
0996                 goto next;
0997             else if (ret)
0998                 /* there was an error, bail out */
0999                 goto err;
1000             /* either found or error, so stop searching */
1001             goto out;
1002         }
1003 next:
1004         /* jump over the padding */
1005         ie_len = ALIGN(ie_len, 4);
1006 
1007         len -= ie_len;
1008         data += ie_len;
1009     }
1010 
1011 out:
1012     if (!bd->data || !bd->len) {
1013         ath11k_dbg(ab, ATH11K_DBG_BOOT,
1014                "failed to fetch %s for %s from %s\n",
1015                ath11k_bd_ie_type_str(ie_id_match),
1016                boardname, filepath);
1017         ret = -ENODATA;
1018         goto err;
1019     }
1020 
1021     return 0;
1022 
1023 err:
1024     ath11k_core_free_bdf(ab, bd);
1025     return ret;
1026 }
1027 
1028 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
1029                        struct ath11k_board_data *bd,
1030                        const char *name)
1031 {
1032     bd->fw = ath11k_core_firmware_request(ab, name);
1033 
1034     if (IS_ERR(bd->fw))
1035         return PTR_ERR(bd->fw);
1036 
1037     bd->data = bd->fw->data;
1038     bd->len = bd->fw->size;
1039 
1040     return 0;
1041 }
1042 
1043 #define BOARD_NAME_SIZE 200
1044 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
1045 {
1046     char boardname[BOARD_NAME_SIZE], fallback_boardname[BOARD_NAME_SIZE];
1047     char *filename, filepath[100];
1048     int ret;
1049 
1050     filename = ATH11K_BOARD_API2_FILE;
1051 
1052     ret = ath11k_core_create_board_name(ab, boardname, sizeof(boardname));
1053     if (ret) {
1054         ath11k_err(ab, "failed to create board name: %d", ret);
1055         return ret;
1056     }
1057 
1058     ab->bd_api = 2;
1059     ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1060                          ATH11K_BD_IE_BOARD,
1061                          ATH11K_BD_IE_BOARD_NAME,
1062                          ATH11K_BD_IE_BOARD_DATA);
1063     if (!ret)
1064         goto success;
1065 
1066     ret = ath11k_core_create_fallback_board_name(ab, fallback_boardname,
1067                              sizeof(fallback_boardname));
1068     if (ret) {
1069         ath11k_err(ab, "failed to create fallback board name: %d", ret);
1070         return ret;
1071     }
1072 
1073     ret = ath11k_core_fetch_board_data_api_n(ab, bd, fallback_boardname,
1074                          ATH11K_BD_IE_BOARD,
1075                          ATH11K_BD_IE_BOARD_NAME,
1076                          ATH11K_BD_IE_BOARD_DATA);
1077     if (!ret)
1078         goto success;
1079 
1080     ab->bd_api = 1;
1081     ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE);
1082     if (ret) {
1083         ath11k_core_create_firmware_path(ab, filename,
1084                          filepath, sizeof(filepath));
1085         ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1086                boardname, filepath);
1087         if (memcmp(boardname, fallback_boardname, strlen(boardname)))
1088             ath11k_err(ab, "failed to fetch board data for %s from %s\n",
1089                    fallback_boardname, filepath);
1090 
1091         ath11k_err(ab, "failed to fetch board.bin from %s\n",
1092                ab->hw_params.fw.dir);
1093         return ret;
1094     }
1095 
1096 success:
1097     ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
1098     return 0;
1099 }
1100 
1101 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd)
1102 {
1103     char boardname[BOARD_NAME_SIZE];
1104     int ret;
1105 
1106     ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
1107     if (ret) {
1108         ath11k_dbg(ab, ATH11K_DBG_BOOT,
1109                "failed to create board name for regdb: %d", ret);
1110         goto exit;
1111     }
1112 
1113     ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname,
1114                          ATH11K_BD_IE_REGDB,
1115                          ATH11K_BD_IE_REGDB_NAME,
1116                          ATH11K_BD_IE_REGDB_DATA);
1117     if (!ret)
1118         goto exit;
1119 
1120     ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME);
1121     if (ret)
1122         ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n",
1123                ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir);
1124 
1125 exit:
1126     if (!ret)
1127         ath11k_dbg(ab, ATH11K_DBG_BOOT, "fetched regdb\n");
1128 
1129     return ret;
1130 }
1131 
1132 static void ath11k_core_stop(struct ath11k_base *ab)
1133 {
1134     if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
1135         ath11k_qmi_firmware_stop(ab);
1136 
1137     ath11k_hif_stop(ab);
1138     ath11k_wmi_detach(ab);
1139     ath11k_dp_pdev_reo_cleanup(ab);
1140 
1141     /* De-Init of components as needed */
1142 }
1143 
1144 static int ath11k_core_soc_create(struct ath11k_base *ab)
1145 {
1146     int ret;
1147 
1148     ret = ath11k_qmi_init_service(ab);
1149     if (ret) {
1150         ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
1151         return ret;
1152     }
1153 
1154     ret = ath11k_debugfs_soc_create(ab);
1155     if (ret) {
1156         ath11k_err(ab, "failed to create ath11k debugfs\n");
1157         goto err_qmi_deinit;
1158     }
1159 
1160     ret = ath11k_hif_power_up(ab);
1161     if (ret) {
1162         ath11k_err(ab, "failed to power up :%d\n", ret);
1163         goto err_debugfs_reg;
1164     }
1165 
1166     return 0;
1167 
1168 err_debugfs_reg:
1169     ath11k_debugfs_soc_destroy(ab);
1170 err_qmi_deinit:
1171     ath11k_qmi_deinit_service(ab);
1172     return ret;
1173 }
1174 
1175 static void ath11k_core_soc_destroy(struct ath11k_base *ab)
1176 {
1177     ath11k_debugfs_soc_destroy(ab);
1178     ath11k_dp_free(ab);
1179     ath11k_reg_free(ab);
1180     ath11k_qmi_deinit_service(ab);
1181 }
1182 
1183 static int ath11k_core_pdev_create(struct ath11k_base *ab)
1184 {
1185     int ret;
1186 
1187     ret = ath11k_debugfs_pdev_create(ab);
1188     if (ret) {
1189         ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
1190         return ret;
1191     }
1192 
1193     ret = ath11k_dp_pdev_alloc(ab);
1194     if (ret) {
1195         ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
1196         goto err_pdev_debug;
1197     }
1198 
1199     ret = ath11k_mac_register(ab);
1200     if (ret) {
1201         ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
1202         goto err_dp_pdev_free;
1203     }
1204 
1205     ret = ath11k_thermal_register(ab);
1206     if (ret) {
1207         ath11k_err(ab, "could not register thermal device: %d\n",
1208                ret);
1209         goto err_mac_unregister;
1210     }
1211 
1212     ret = ath11k_spectral_init(ab);
1213     if (ret) {
1214         ath11k_err(ab, "failed to init spectral %d\n", ret);
1215         goto err_thermal_unregister;
1216     }
1217 
1218     return 0;
1219 
1220 err_thermal_unregister:
1221     ath11k_thermal_unregister(ab);
1222 err_mac_unregister:
1223     ath11k_mac_unregister(ab);
1224 err_dp_pdev_free:
1225     ath11k_dp_pdev_free(ab);
1226 err_pdev_debug:
1227     ath11k_debugfs_pdev_destroy(ab);
1228 
1229     return ret;
1230 }
1231 
1232 static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
1233 {
1234     ath11k_spectral_deinit(ab);
1235     ath11k_thermal_unregister(ab);
1236     ath11k_mac_unregister(ab);
1237     ath11k_hif_irq_disable(ab);
1238     ath11k_dp_pdev_free(ab);
1239     ath11k_debugfs_pdev_destroy(ab);
1240 }
1241 
1242 static int ath11k_core_start(struct ath11k_base *ab)
1243 {
1244     int ret;
1245 
1246     ret = ath11k_wmi_attach(ab);
1247     if (ret) {
1248         ath11k_err(ab, "failed to attach wmi: %d\n", ret);
1249         return ret;
1250     }
1251 
1252     ret = ath11k_htc_init(ab);
1253     if (ret) {
1254         ath11k_err(ab, "failed to init htc: %d\n", ret);
1255         goto err_wmi_detach;
1256     }
1257 
1258     ret = ath11k_hif_start(ab);
1259     if (ret) {
1260         ath11k_err(ab, "failed to start HIF: %d\n", ret);
1261         goto err_wmi_detach;
1262     }
1263 
1264     ret = ath11k_htc_wait_target(&ab->htc);
1265     if (ret) {
1266         ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
1267         goto err_hif_stop;
1268     }
1269 
1270     ret = ath11k_dp_htt_connect(&ab->dp);
1271     if (ret) {
1272         ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
1273         goto err_hif_stop;
1274     }
1275 
1276     ret = ath11k_wmi_connect(ab);
1277     if (ret) {
1278         ath11k_err(ab, "failed to connect wmi: %d\n", ret);
1279         goto err_hif_stop;
1280     }
1281 
1282     ret = ath11k_htc_start(&ab->htc);
1283     if (ret) {
1284         ath11k_err(ab, "failed to start HTC: %d\n", ret);
1285         goto err_hif_stop;
1286     }
1287 
1288     ret = ath11k_wmi_wait_for_service_ready(ab);
1289     if (ret) {
1290         ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
1291                ret);
1292         goto err_hif_stop;
1293     }
1294 
1295     ret = ath11k_mac_allocate(ab);
1296     if (ret) {
1297         ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
1298                ret);
1299         goto err_hif_stop;
1300     }
1301 
1302     ath11k_dp_pdev_pre_alloc(ab);
1303 
1304     ret = ath11k_dp_pdev_reo_setup(ab);
1305     if (ret) {
1306         ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
1307         goto err_mac_destroy;
1308     }
1309 
1310     ret = ath11k_wmi_cmd_init(ab);
1311     if (ret) {
1312         ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
1313         goto err_reo_cleanup;
1314     }
1315 
1316     ret = ath11k_wmi_wait_for_unified_ready(ab);
1317     if (ret) {
1318         ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
1319                ret);
1320         goto err_reo_cleanup;
1321     }
1322 
1323     /* put hardware to DBS mode */
1324     if (ab->hw_params.single_pdev_only && ab->hw_params.num_rxmda_per_pdev > 1) {
1325         ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
1326         if (ret) {
1327             ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
1328             goto err_hif_stop;
1329         }
1330     }
1331 
1332     ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
1333     if (ret) {
1334         ath11k_err(ab, "failed to send htt version request message: %d\n",
1335                ret);
1336         goto err_reo_cleanup;
1337     }
1338 
1339     return 0;
1340 
1341 err_reo_cleanup:
1342     ath11k_dp_pdev_reo_cleanup(ab);
1343 err_mac_destroy:
1344     ath11k_mac_destroy(ab);
1345 err_hif_stop:
1346     ath11k_hif_stop(ab);
1347 err_wmi_detach:
1348     ath11k_wmi_detach(ab);
1349 
1350     return ret;
1351 }
1352 
1353 static int ath11k_core_start_firmware(struct ath11k_base *ab,
1354                       enum ath11k_firmware_mode mode)
1355 {
1356     int ret;
1357 
1358     ath11k_ce_get_shadow_config(ab, &ab->qmi.ce_cfg.shadow_reg_v2,
1359                     &ab->qmi.ce_cfg.shadow_reg_v2_len);
1360 
1361     ret = ath11k_qmi_firmware_start(ab, mode);
1362     if (ret) {
1363         ath11k_err(ab, "failed to send firmware start: %d\n", ret);
1364         return ret;
1365     }
1366 
1367     return ret;
1368 }
1369 
1370 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
1371 {
1372     int ret;
1373 
1374     ret = ath11k_core_start_firmware(ab, ATH11K_FIRMWARE_MODE_NORMAL);
1375     if (ret) {
1376         ath11k_err(ab, "failed to start firmware: %d\n", ret);
1377         return ret;
1378     }
1379 
1380     ret = ath11k_ce_init_pipes(ab);
1381     if (ret) {
1382         ath11k_err(ab, "failed to initialize CE: %d\n", ret);
1383         goto err_firmware_stop;
1384     }
1385 
1386     ret = ath11k_dp_alloc(ab);
1387     if (ret) {
1388         ath11k_err(ab, "failed to init DP: %d\n", ret);
1389         goto err_firmware_stop;
1390     }
1391 
1392     switch (ath11k_crypto_mode) {
1393     case ATH11K_CRYPT_MODE_SW:
1394         set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1395         set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1396         break;
1397     case ATH11K_CRYPT_MODE_HW:
1398         clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
1399         clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1400         break;
1401     default:
1402         ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
1403         return -EINVAL;
1404     }
1405 
1406     if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
1407         set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
1408 
1409     mutex_lock(&ab->core_lock);
1410     ret = ath11k_core_start(ab);
1411     if (ret) {
1412         ath11k_err(ab, "failed to start core: %d\n", ret);
1413         goto err_dp_free;
1414     }
1415 
1416     ret = ath11k_core_pdev_create(ab);
1417     if (ret) {
1418         ath11k_err(ab, "failed to create pdev core: %d\n", ret);
1419         goto err_core_stop;
1420     }
1421     ath11k_hif_irq_enable(ab);
1422     mutex_unlock(&ab->core_lock);
1423 
1424     return 0;
1425 
1426 err_core_stop:
1427     ath11k_core_stop(ab);
1428     ath11k_mac_destroy(ab);
1429 err_dp_free:
1430     ath11k_dp_free(ab);
1431     mutex_unlock(&ab->core_lock);
1432 err_firmware_stop:
1433     ath11k_qmi_firmware_stop(ab);
1434 
1435     return ret;
1436 }
1437 
1438 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
1439 {
1440     int ret;
1441 
1442     mutex_lock(&ab->core_lock);
1443     ath11k_thermal_unregister(ab);
1444     ath11k_hif_irq_disable(ab);
1445     ath11k_dp_pdev_free(ab);
1446     ath11k_spectral_deinit(ab);
1447     ath11k_hif_stop(ab);
1448     ath11k_wmi_detach(ab);
1449     ath11k_dp_pdev_reo_cleanup(ab);
1450     mutex_unlock(&ab->core_lock);
1451 
1452     ath11k_dp_free(ab);
1453     ath11k_hal_srng_deinit(ab);
1454 
1455     ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1;
1456 
1457     ret = ath11k_hal_srng_init(ab);
1458     if (ret)
1459         return ret;
1460 
1461     clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
1462 
1463     ret = ath11k_core_qmi_firmware_ready(ab);
1464     if (ret)
1465         goto err_hal_srng_deinit;
1466 
1467     clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
1468 
1469     return 0;
1470 
1471 err_hal_srng_deinit:
1472     ath11k_hal_srng_deinit(ab);
1473     return ret;
1474 }
1475 
1476 void ath11k_core_halt(struct ath11k *ar)
1477 {
1478     struct ath11k_base *ab = ar->ab;
1479 
1480     lockdep_assert_held(&ar->conf_mutex);
1481 
1482     ar->num_created_vdevs = 0;
1483     ar->allocated_vdev_map = 0;
1484 
1485     ath11k_mac_scan_finish(ar);
1486     ath11k_mac_peer_cleanup_all(ar);
1487     cancel_delayed_work_sync(&ar->scan.timeout);
1488     cancel_work_sync(&ar->regd_update_work);
1489     cancel_work_sync(&ab->update_11d_work);
1490 
1491     rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
1492     synchronize_rcu();
1493     INIT_LIST_HEAD(&ar->arvifs);
1494     idr_init(&ar->txmgmt_idr);
1495 }
1496 
1497 static void ath11k_update_11d(struct work_struct *work)
1498 {
1499     struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work);
1500     struct ath11k *ar;
1501     struct ath11k_pdev *pdev;
1502     struct wmi_set_current_country_params set_current_param = {};
1503     int ret, i;
1504 
1505     spin_lock_bh(&ab->base_lock);
1506     memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2);
1507     spin_unlock_bh(&ab->base_lock);
1508 
1509     ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n",
1510            set_current_param.alpha2[0],
1511            set_current_param.alpha2[1]);
1512 
1513     for (i = 0; i < ab->num_radios; i++) {
1514         pdev = &ab->pdevs[i];
1515         ar = pdev->ar;
1516 
1517         memcpy(&ar->alpha2, &set_current_param.alpha2, 2);
1518         ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param);
1519         if (ret)
1520             ath11k_warn(ar->ab,
1521                     "pdev id %d failed set current country code: %d\n",
1522                     i, ret);
1523     }
1524 }
1525 
1526 static void ath11k_core_pre_reconfigure_recovery(struct ath11k_base *ab)
1527 {
1528     struct ath11k *ar;
1529     struct ath11k_pdev *pdev;
1530     int i;
1531 
1532     spin_lock_bh(&ab->base_lock);
1533     ab->stats.fw_crash_counter++;
1534     spin_unlock_bh(&ab->base_lock);
1535 
1536     for (i = 0; i < ab->num_radios; i++) {
1537         pdev = &ab->pdevs[i];
1538         ar = pdev->ar;
1539         if (!ar || ar->state == ATH11K_STATE_OFF)
1540             continue;
1541 
1542         ieee80211_stop_queues(ar->hw);
1543         ath11k_mac_drain_tx(ar);
1544         ar->state_11d = ATH11K_11D_IDLE;
1545         complete(&ar->completed_11d_scan);
1546         complete(&ar->scan.started);
1547         complete(&ar->scan.completed);
1548         complete(&ar->scan.on_channel);
1549         complete(&ar->peer_assoc_done);
1550         complete(&ar->peer_delete_done);
1551         complete(&ar->install_key_done);
1552         complete(&ar->vdev_setup_done);
1553         complete(&ar->vdev_delete_done);
1554         complete(&ar->bss_survey_done);
1555         complete(&ar->thermal.wmi_sync);
1556 
1557         wake_up(&ar->dp.tx_empty_waitq);
1558         idr_for_each(&ar->txmgmt_idr,
1559                  ath11k_mac_tx_mgmt_pending_free, ar);
1560         idr_destroy(&ar->txmgmt_idr);
1561         wake_up(&ar->txmgmt_empty_waitq);
1562     }
1563 
1564     wake_up(&ab->wmi_ab.tx_credits_wq);
1565     wake_up(&ab->peer_mapping_wq);
1566 }
1567 
1568 static void ath11k_core_post_reconfigure_recovery(struct ath11k_base *ab)
1569 {
1570     struct ath11k *ar;
1571     struct ath11k_pdev *pdev;
1572     int i;
1573 
1574     for (i = 0; i < ab->num_radios; i++) {
1575         pdev = &ab->pdevs[i];
1576         ar = pdev->ar;
1577         if (!ar || ar->state == ATH11K_STATE_OFF)
1578             continue;
1579 
1580         mutex_lock(&ar->conf_mutex);
1581 
1582         switch (ar->state) {
1583         case ATH11K_STATE_ON:
1584             ar->state = ATH11K_STATE_RESTARTING;
1585             ath11k_core_halt(ar);
1586             ieee80211_restart_hw(ar->hw);
1587             break;
1588         case ATH11K_STATE_OFF:
1589             ath11k_warn(ab,
1590                     "cannot restart radio %d that hasn't been started\n",
1591                     i);
1592             break;
1593         case ATH11K_STATE_RESTARTING:
1594             break;
1595         case ATH11K_STATE_RESTARTED:
1596             ar->state = ATH11K_STATE_WEDGED;
1597             fallthrough;
1598         case ATH11K_STATE_WEDGED:
1599             ath11k_warn(ab,
1600                     "device is wedged, will not restart radio %d\n", i);
1601             break;
1602         }
1603         mutex_unlock(&ar->conf_mutex);
1604     }
1605     complete(&ab->driver_recovery);
1606 }
1607 
1608 static void ath11k_core_restart(struct work_struct *work)
1609 {
1610     struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
1611     int ret;
1612 
1613     if (!ab->is_reset)
1614         ath11k_core_pre_reconfigure_recovery(ab);
1615 
1616     ret = ath11k_core_reconfigure_on_crash(ab);
1617     if (ret) {
1618         ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
1619         return;
1620     }
1621 
1622     if (ab->is_reset)
1623         complete_all(&ab->reconfigure_complete);
1624 
1625     if (!ab->is_reset)
1626         ath11k_core_post_reconfigure_recovery(ab);
1627 }
1628 
1629 static void ath11k_core_reset(struct work_struct *work)
1630 {
1631     struct ath11k_base *ab = container_of(work, struct ath11k_base, reset_work);
1632     int reset_count, fail_cont_count;
1633     long time_left;
1634 
1635     if (!(test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))) {
1636         ath11k_warn(ab, "ignore reset dev flags 0x%lx\n", ab->dev_flags);
1637         return;
1638     }
1639 
1640     /* Sometimes the recovery will fail and then the next all recovery fail,
1641      * this is to avoid infinite recovery since it can not recovery success.
1642      */
1643     fail_cont_count = atomic_read(&ab->fail_cont_count);
1644 
1645     if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FINAL)
1646         return;
1647 
1648     if (fail_cont_count >= ATH11K_RESET_MAX_FAIL_COUNT_FIRST &&
1649         time_before(jiffies, ab->reset_fail_timeout))
1650         return;
1651 
1652     reset_count = atomic_inc_return(&ab->reset_count);
1653 
1654     if (reset_count > 1) {
1655         /* Sometimes it happened another reset worker before the previous one
1656          * completed, then the second reset worker will destroy the previous one,
1657          * thus below is to avoid that.
1658          */
1659         ath11k_warn(ab, "already resetting count %d\n", reset_count);
1660 
1661         reinit_completion(&ab->reset_complete);
1662         time_left = wait_for_completion_timeout(&ab->reset_complete,
1663                             ATH11K_RESET_TIMEOUT_HZ);
1664 
1665         if (time_left) {
1666             ath11k_dbg(ab, ATH11K_DBG_BOOT, "to skip reset\n");
1667             atomic_dec(&ab->reset_count);
1668             return;
1669         }
1670 
1671         ab->reset_fail_timeout = jiffies + ATH11K_RESET_FAIL_TIMEOUT_HZ;
1672         /* Record the continuous recovery fail count when recovery failed*/
1673         atomic_inc(&ab->fail_cont_count);
1674     }
1675 
1676     ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset starting\n");
1677 
1678     ab->is_reset = true;
1679     atomic_set(&ab->recovery_count, 0);
1680     reinit_completion(&ab->recovery_start);
1681     atomic_set(&ab->recovery_start_count, 0);
1682 
1683     ath11k_core_pre_reconfigure_recovery(ab);
1684 
1685     reinit_completion(&ab->reconfigure_complete);
1686     ath11k_core_post_reconfigure_recovery(ab);
1687 
1688     ath11k_dbg(ab, ATH11K_DBG_BOOT, "waiting recovery start...\n");
1689 
1690     time_left = wait_for_completion_timeout(&ab->recovery_start,
1691                         ATH11K_RECOVER_START_TIMEOUT_HZ);
1692 
1693     ath11k_hif_power_down(ab);
1694     ath11k_hif_power_up(ab);
1695 
1696     ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");
1697 }
1698 
1699 static int ath11k_init_hw_params(struct ath11k_base *ab)
1700 {
1701     const struct ath11k_hw_params *hw_params = NULL;
1702     int i;
1703 
1704     for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1705         hw_params = &ath11k_hw_params[i];
1706 
1707         if (hw_params->hw_rev == ab->hw_rev)
1708             break;
1709     }
1710 
1711     if (i == ARRAY_SIZE(ath11k_hw_params)) {
1712         ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1713         return -EINVAL;
1714     }
1715 
1716     ab->hw_params = *hw_params;
1717 
1718     ath11k_info(ab, "%s\n", ab->hw_params.name);
1719 
1720     return 0;
1721 }
1722 
1723 int ath11k_core_pre_init(struct ath11k_base *ab)
1724 {
1725     int ret;
1726 
1727     ret = ath11k_init_hw_params(ab);
1728     if (ret) {
1729         ath11k_err(ab, "failed to get hw params: %d\n", ret);
1730         return ret;
1731     }
1732 
1733     return 0;
1734 }
1735 EXPORT_SYMBOL(ath11k_core_pre_init);
1736 
1737 int ath11k_core_init(struct ath11k_base *ab)
1738 {
1739     int ret;
1740 
1741     ret = ath11k_core_soc_create(ab);
1742     if (ret) {
1743         ath11k_err(ab, "failed to create soc core: %d\n", ret);
1744         return ret;
1745     }
1746 
1747     return 0;
1748 }
1749 EXPORT_SYMBOL(ath11k_core_init);
1750 
1751 void ath11k_core_deinit(struct ath11k_base *ab)
1752 {
1753     mutex_lock(&ab->core_lock);
1754 
1755     ath11k_core_pdev_destroy(ab);
1756     ath11k_core_stop(ab);
1757 
1758     mutex_unlock(&ab->core_lock);
1759 
1760     ath11k_hif_power_down(ab);
1761     ath11k_mac_destroy(ab);
1762     ath11k_core_soc_destroy(ab);
1763 }
1764 EXPORT_SYMBOL(ath11k_core_deinit);
1765 
1766 void ath11k_core_free(struct ath11k_base *ab)
1767 {
1768     destroy_workqueue(ab->workqueue_aux);
1769     destroy_workqueue(ab->workqueue);
1770 
1771     kfree(ab);
1772 }
1773 EXPORT_SYMBOL(ath11k_core_free);
1774 
1775 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1776                       enum ath11k_bus bus)
1777 {
1778     struct ath11k_base *ab;
1779 
1780     ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1781     if (!ab)
1782         return NULL;
1783 
1784     init_completion(&ab->driver_recovery);
1785 
1786     ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1787     if (!ab->workqueue)
1788         goto err_sc_free;
1789 
1790     ab->workqueue_aux = create_singlethread_workqueue("ath11k_aux_wq");
1791     if (!ab->workqueue_aux)
1792         goto err_free_wq;
1793 
1794     mutex_init(&ab->core_lock);
1795     mutex_init(&ab->tbl_mtx_lock);
1796     spin_lock_init(&ab->base_lock);
1797     mutex_init(&ab->vdev_id_11d_lock);
1798     init_completion(&ab->reset_complete);
1799     init_completion(&ab->reconfigure_complete);
1800     init_completion(&ab->recovery_start);
1801 
1802     INIT_LIST_HEAD(&ab->peers);
1803     init_waitqueue_head(&ab->peer_mapping_wq);
1804     init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1805     init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1806     INIT_WORK(&ab->restart_work, ath11k_core_restart);
1807     INIT_WORK(&ab->update_11d_work, ath11k_update_11d);
1808     INIT_WORK(&ab->reset_work, ath11k_core_reset);
1809     timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1810     init_completion(&ab->htc_suspend);
1811     init_completion(&ab->wow.wakeup_completed);
1812 
1813     ab->dev = dev;
1814     ab->hif.bus = bus;
1815 
1816     return ab;
1817 
1818 err_free_wq:
1819     destroy_workqueue(ab->workqueue);
1820 err_sc_free:
1821     kfree(ab);
1822     return NULL;
1823 }
1824 EXPORT_SYMBOL(ath11k_core_alloc);
1825 
1826 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1827 MODULE_LICENSE("Dual BSD/GPL");