Linux Audio

Check our new training course

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