File Index
Files and directories
Sign in
FILE

core.c

File preview with syntax highlighting.

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