Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.10.11.
   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");