Linux Audio

Check our new training course

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