2283 lines · c
1// SPDX-License-Identifier: BSD-3-Clause-Clear2/*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 size74 */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 = false,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 else876 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 true889 * 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 true948 * 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 2001423int 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 one2101 * 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");2283