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