brintos

brintos / linux-shallow public Read only

0
0
Text · 97.6 KiB · b329428 Raw
3744 lines · c
1// SPDX-License-Identifier: ISC2/*3 * Copyright (c) 2005-2011 Atheros Communications Inc.4 * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.5 * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.6 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.7 */8 9#include <linux/module.h>10#include <linux/firmware.h>11#include <linux/of.h>12#include <linux/property.h>13#include <linux/dmi.h>14#include <linux/ctype.h>15#include <linux/pm_qos.h>16#include <linux/nvmem-consumer.h>17#include <asm/byteorder.h>18 19#include "core.h"20#include "mac.h"21#include "htc.h"22#include "hif.h"23#include "wmi.h"24#include "bmi.h"25#include "debug.h"26#include "htt.h"27#include "testmode.h"28#include "wmi-ops.h"29#include "coredump.h"30#include "leds.h"31 32unsigned int ath10k_debug_mask;33EXPORT_SYMBOL(ath10k_debug_mask);34 35static unsigned int ath10k_cryptmode_param;36static bool uart_print;37static bool skip_otp;38static bool fw_diag_log;39 40/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */41unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;42 43unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |44				     BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);45 46/* FIXME: most of these should be readonly */47module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);48module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);49module_param(uart_print, bool, 0644);50module_param(skip_otp, bool, 0644);51module_param(fw_diag_log, bool, 0644);52module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);53module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);54 55MODULE_PARM_DESC(debug_mask, "Debugging mask");56MODULE_PARM_DESC(uart_print, "Uart target debugging");57MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");58MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");59MODULE_PARM_DESC(frame_mode,60		 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");61MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");62MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");63 64static const struct ath10k_hw_params ath10k_hw_params_list[] = {65	{66		.id = QCA988X_HW_2_0_VERSION,67		.dev_id = QCA988X_2_0_DEVICE_ID,68		.bus = ATH10K_BUS_PCI,69		.name = "qca988x hw2.0",70		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,71		.uart_pin = 7,72		.led_pin = 1,73		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,74		.otp_exe_param = 0,75		.channel_counters_freq_hz = 88000,76		.max_probe_resp_desc_thres = 0,77		.cal_data_len = 2116,78		.fw = {79			.dir = QCA988X_HW_2_0_FW_DIR,80			.board_size = QCA988X_BOARD_DATA_SZ,81			.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,82		},83		.rx_desc_ops = &qca988x_rx_desc_ops,84		.hw_ops = &qca988x_ops,85		.decap_align_bytes = 4,86		.spectral_bin_discard = 0,87		.spectral_bin_offset = 0,88		.vht160_mcs_rx_highest = 0,89		.vht160_mcs_tx_highest = 0,90		.n_cipher_suites = 8,91		.ast_skid_limit = 0x10,92		.num_wds_entries = 0x20,93		.target_64bit = false,94		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,95		.shadow_reg_support = false,96		.rri_on_ddr = false,97		.hw_filter_reset_required = true,98		.fw_diag_ce_download = false,99		.credit_size_workaround = false,100		.tx_stats_over_pktlog = true,101		.dynamic_sar_support = false,102		.hw_restart_disconnect = false,103		.use_fw_tx_credits = true,104		.delay_unmap_buffer = false,105		.mcast_frame_registration = false,106	},107	{108		.id = QCA988X_HW_2_0_VERSION,109		.dev_id = QCA988X_2_0_DEVICE_ID_UBNT,110		.name = "qca988x hw2.0 ubiquiti",111		.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,112		.uart_pin = 7,113		.led_pin = 0,114		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,115		.otp_exe_param = 0,116		.channel_counters_freq_hz = 88000,117		.max_probe_resp_desc_thres = 0,118		.cal_data_len = 2116,119		.fw = {120			.dir = QCA988X_HW_2_0_FW_DIR,121			.board_size = QCA988X_BOARD_DATA_SZ,122			.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,123		},124		.rx_desc_ops = &qca988x_rx_desc_ops,125		.hw_ops = &qca988x_ops,126		.decap_align_bytes = 4,127		.spectral_bin_discard = 0,128		.spectral_bin_offset = 0,129		.vht160_mcs_rx_highest = 0,130		.vht160_mcs_tx_highest = 0,131		.n_cipher_suites = 8,132		.ast_skid_limit = 0x10,133		.num_wds_entries = 0x20,134		.target_64bit = false,135		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,136		.shadow_reg_support = false,137		.rri_on_ddr = false,138		.hw_filter_reset_required = true,139		.fw_diag_ce_download = false,140		.credit_size_workaround = false,141		.tx_stats_over_pktlog = true,142		.dynamic_sar_support = false,143		.hw_restart_disconnect = false,144		.use_fw_tx_credits = true,145		.delay_unmap_buffer = false,146		.mcast_frame_registration = false,147	},148	{149		.id = QCA9887_HW_1_0_VERSION,150		.dev_id = QCA9887_1_0_DEVICE_ID,151		.bus = ATH10K_BUS_PCI,152		.name = "qca9887 hw1.0",153		.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,154		.uart_pin = 7,155		.led_pin = 1,156		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,157		.otp_exe_param = 0,158		.channel_counters_freq_hz = 88000,159		.max_probe_resp_desc_thres = 0,160		.cal_data_len = 2116,161		.fw = {162			.dir = QCA9887_HW_1_0_FW_DIR,163			.board_size = QCA9887_BOARD_DATA_SZ,164			.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,165		},166		.rx_desc_ops = &qca988x_rx_desc_ops,167		.hw_ops = &qca988x_ops,168		.decap_align_bytes = 4,169		.spectral_bin_discard = 0,170		.spectral_bin_offset = 0,171		.vht160_mcs_rx_highest = 0,172		.vht160_mcs_tx_highest = 0,173		.n_cipher_suites = 8,174		.ast_skid_limit = 0x10,175		.num_wds_entries = 0x20,176		.target_64bit = false,177		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,178		.shadow_reg_support = false,179		.rri_on_ddr = false,180		.hw_filter_reset_required = true,181		.fw_diag_ce_download = false,182		.credit_size_workaround = false,183		.tx_stats_over_pktlog = false,184		.dynamic_sar_support = false,185		.hw_restart_disconnect = false,186		.use_fw_tx_credits = true,187		.delay_unmap_buffer = false,188		.mcast_frame_registration = false,189	},190	{191		.id = QCA6174_HW_3_2_VERSION,192		.dev_id = QCA6174_3_2_DEVICE_ID,193		.bus = ATH10K_BUS_SDIO,194		.name = "qca6174 hw3.2 sdio",195		.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,196		.uart_pin = 19,197		.led_pin = 0,198		.otp_exe_param = 0,199		.channel_counters_freq_hz = 88000,200		.max_probe_resp_desc_thres = 0,201		.cal_data_len = 0,202		.fw = {203			.dir = QCA6174_HW_3_0_FW_DIR,204			.board_size = QCA6174_BOARD_DATA_SZ,205			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,206		},207		.rx_desc_ops = &qca988x_rx_desc_ops,208		.hw_ops = &qca6174_sdio_ops,209		.hw_clk = qca6174_clk,210		.target_cpu_freq = 176000000,211		.decap_align_bytes = 4,212		.n_cipher_suites = 8,213		.num_peers = 10,214		.ast_skid_limit = 0x10,215		.num_wds_entries = 0x20,216		.uart_pin_workaround = true,217		.tx_stats_over_pktlog = false,218		.credit_size_workaround = false,219		.bmi_large_size_download = true,220		.supports_peer_stats_info = true,221		.dynamic_sar_support = true,222		.hw_restart_disconnect = false,223		.use_fw_tx_credits = true,224		.delay_unmap_buffer = false,225		.mcast_frame_registration = false,226	},227	{228		.id = QCA6174_HW_2_1_VERSION,229		.dev_id = QCA6164_2_1_DEVICE_ID,230		.bus = ATH10K_BUS_PCI,231		.name = "qca6164 hw2.1",232		.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,233		.uart_pin = 6,234		.led_pin = 0,235		.otp_exe_param = 0,236		.channel_counters_freq_hz = 88000,237		.max_probe_resp_desc_thres = 0,238		.cal_data_len = 8124,239		.fw = {240			.dir = QCA6174_HW_2_1_FW_DIR,241			.board_size = QCA6174_BOARD_DATA_SZ,242			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,243		},244		.rx_desc_ops = &qca988x_rx_desc_ops,245		.hw_ops = &qca988x_ops,246		.decap_align_bytes = 4,247		.spectral_bin_discard = 0,248		.spectral_bin_offset = 0,249		.vht160_mcs_rx_highest = 0,250		.vht160_mcs_tx_highest = 0,251		.n_cipher_suites = 8,252		.ast_skid_limit = 0x10,253		.num_wds_entries = 0x20,254		.target_64bit = false,255		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,256		.shadow_reg_support = false,257		.rri_on_ddr = false,258		.hw_filter_reset_required = true,259		.fw_diag_ce_download = false,260		.credit_size_workaround = false,261		.tx_stats_over_pktlog = false,262		.dynamic_sar_support = false,263		.hw_restart_disconnect = false,264		.use_fw_tx_credits = true,265		.delay_unmap_buffer = false,266		.mcast_frame_registration = false,267	},268	{269		.id = QCA6174_HW_2_1_VERSION,270		.dev_id = QCA6174_2_1_DEVICE_ID,271		.bus = ATH10K_BUS_PCI,272		.name = "qca6174 hw2.1",273		.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,274		.uart_pin = 6,275		.led_pin = 0,276		.otp_exe_param = 0,277		.channel_counters_freq_hz = 88000,278		.max_probe_resp_desc_thres = 0,279		.cal_data_len = 8124,280		.fw = {281			.dir = QCA6174_HW_2_1_FW_DIR,282			.board_size = QCA6174_BOARD_DATA_SZ,283			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,284		},285		.rx_desc_ops = &qca988x_rx_desc_ops,286		.hw_ops = &qca988x_ops,287		.decap_align_bytes = 4,288		.spectral_bin_discard = 0,289		.spectral_bin_offset = 0,290		.vht160_mcs_rx_highest = 0,291		.vht160_mcs_tx_highest = 0,292		.n_cipher_suites = 8,293		.ast_skid_limit = 0x10,294		.num_wds_entries = 0x20,295		.target_64bit = false,296		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,297		.shadow_reg_support = false,298		.rri_on_ddr = false,299		.hw_filter_reset_required = true,300		.fw_diag_ce_download = false,301		.credit_size_workaround = false,302		.tx_stats_over_pktlog = false,303		.dynamic_sar_support = false,304		.hw_restart_disconnect = false,305		.use_fw_tx_credits = true,306		.delay_unmap_buffer = false,307		.mcast_frame_registration = false,308	},309	{310		.id = QCA6174_HW_3_0_VERSION,311		.dev_id = QCA6174_2_1_DEVICE_ID,312		.bus = ATH10K_BUS_PCI,313		.name = "qca6174 hw3.0",314		.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,315		.uart_pin = 6,316		.led_pin = 0,317		.otp_exe_param = 0,318		.channel_counters_freq_hz = 88000,319		.max_probe_resp_desc_thres = 0,320		.cal_data_len = 8124,321		.fw = {322			.dir = QCA6174_HW_3_0_FW_DIR,323			.board_size = QCA6174_BOARD_DATA_SZ,324			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,325		},326		.rx_desc_ops = &qca988x_rx_desc_ops,327		.hw_ops = &qca988x_ops,328		.decap_align_bytes = 4,329		.spectral_bin_discard = 0,330		.spectral_bin_offset = 0,331		.vht160_mcs_rx_highest = 0,332		.vht160_mcs_tx_highest = 0,333		.n_cipher_suites = 8,334		.ast_skid_limit = 0x10,335		.num_wds_entries = 0x20,336		.target_64bit = false,337		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,338		.shadow_reg_support = false,339		.rri_on_ddr = false,340		.hw_filter_reset_required = true,341		.fw_diag_ce_download = false,342		.credit_size_workaround = false,343		.tx_stats_over_pktlog = false,344		.dynamic_sar_support = false,345		.hw_restart_disconnect = false,346		.use_fw_tx_credits = true,347		.delay_unmap_buffer = false,348		.mcast_frame_registration = false,349	},350	{351		.id = QCA6174_HW_3_2_VERSION,352		.dev_id = QCA6174_2_1_DEVICE_ID,353		.bus = ATH10K_BUS_PCI,354		.name = "qca6174 hw3.2",355		.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,356		.uart_pin = 6,357		.led_pin = 0,358		.otp_exe_param = 0,359		.channel_counters_freq_hz = 88000,360		.max_probe_resp_desc_thres = 0,361		.cal_data_len = 8124,362		.fw = {363			/* uses same binaries as hw3.0 */364			.dir = QCA6174_HW_3_0_FW_DIR,365			.board_size = QCA6174_BOARD_DATA_SZ,366			.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,367		},368		.rx_desc_ops = &qca988x_rx_desc_ops,369		.hw_ops = &qca6174_ops,370		.hw_clk = qca6174_clk,371		.target_cpu_freq = 176000000,372		.decap_align_bytes = 4,373		.spectral_bin_discard = 0,374		.spectral_bin_offset = 0,375		.vht160_mcs_rx_highest = 0,376		.vht160_mcs_tx_highest = 0,377		.n_cipher_suites = 8,378		.ast_skid_limit = 0x10,379		.num_wds_entries = 0x20,380		.target_64bit = false,381		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,382		.shadow_reg_support = false,383		.rri_on_ddr = false,384		.hw_filter_reset_required = true,385		.fw_diag_ce_download = true,386		.credit_size_workaround = false,387		.tx_stats_over_pktlog = false,388		.supports_peer_stats_info = true,389		.dynamic_sar_support = true,390		.hw_restart_disconnect = false,391		.use_fw_tx_credits = true,392		.delay_unmap_buffer = false,393		.mcast_frame_registration = true,394	},395	{396		.id = QCA99X0_HW_2_0_DEV_VERSION,397		.dev_id = QCA99X0_2_0_DEVICE_ID,398		.bus = ATH10K_BUS_PCI,399		.name = "qca99x0 hw2.0",400		.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,401		.uart_pin = 7,402		.led_pin = 17,403		.otp_exe_param = 0x00000700,404		.continuous_frag_desc = true,405		.cck_rate_map_rev2 = true,406		.channel_counters_freq_hz = 150000,407		.max_probe_resp_desc_thres = 24,408		.tx_chain_mask = 0xf,409		.rx_chain_mask = 0xf,410		.max_spatial_stream = 4,411		.cal_data_len = 12064,412		.fw = {413			.dir = QCA99X0_HW_2_0_FW_DIR,414			.board_size = QCA99X0_BOARD_DATA_SZ,415			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,416		},417		.sw_decrypt_mcast_mgmt = true,418		.rx_desc_ops = &qca99x0_rx_desc_ops,419		.hw_ops = &qca99x0_ops,420		.decap_align_bytes = 1,421		.spectral_bin_discard = 4,422		.spectral_bin_offset = 0,423		.vht160_mcs_rx_highest = 0,424		.vht160_mcs_tx_highest = 0,425		.n_cipher_suites = 11,426		.ast_skid_limit = 0x10,427		.num_wds_entries = 0x20,428		.target_64bit = false,429		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,430		.shadow_reg_support = false,431		.rri_on_ddr = false,432		.hw_filter_reset_required = true,433		.fw_diag_ce_download = false,434		.credit_size_workaround = false,435		.tx_stats_over_pktlog = false,436		.dynamic_sar_support = false,437		.hw_restart_disconnect = false,438		.use_fw_tx_credits = true,439		.delay_unmap_buffer = false,440		.mcast_frame_registration = false,441	},442	{443		.id = QCA9984_HW_1_0_DEV_VERSION,444		.dev_id = QCA9984_1_0_DEVICE_ID,445		.bus = ATH10K_BUS_PCI,446		.name = "qca9984/qca9994 hw1.0",447		.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,448		.uart_pin = 7,449		.led_pin = 17,450		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,451		.otp_exe_param = 0x00000700,452		.continuous_frag_desc = true,453		.cck_rate_map_rev2 = true,454		.channel_counters_freq_hz = 150000,455		.max_probe_resp_desc_thres = 24,456		.tx_chain_mask = 0xf,457		.rx_chain_mask = 0xf,458		.max_spatial_stream = 4,459		.cal_data_len = 12064,460		.fw = {461			.dir = QCA9984_HW_1_0_FW_DIR,462			.board_size = QCA99X0_BOARD_DATA_SZ,463			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,464			.ext_board_size = QCA99X0_EXT_BOARD_DATA_SZ,465		},466		.sw_decrypt_mcast_mgmt = true,467		.rx_desc_ops = &qca99x0_rx_desc_ops,468		.hw_ops = &qca99x0_ops,469		.decap_align_bytes = 1,470		.spectral_bin_discard = 12,471		.spectral_bin_offset = 8,472 473		/* Can do only 2x2 VHT160 or 80+80. 1560Mbps is 4x4 80Mhz474		 * or 2x2 160Mhz, long-guard-interval.475		 */476		.vht160_mcs_rx_highest = 1560,477		.vht160_mcs_tx_highest = 1560,478		.n_cipher_suites = 11,479		.ast_skid_limit = 0x10,480		.num_wds_entries = 0x20,481		.target_64bit = false,482		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,483		.shadow_reg_support = false,484		.rri_on_ddr = false,485		.hw_filter_reset_required = true,486		.fw_diag_ce_download = false,487		.credit_size_workaround = false,488		.tx_stats_over_pktlog = false,489		.dynamic_sar_support = false,490		.hw_restart_disconnect = false,491		.use_fw_tx_credits = true,492		.delay_unmap_buffer = false,493		.mcast_frame_registration = false,494	},495	{496		.id = QCA9888_HW_2_0_DEV_VERSION,497		.dev_id = QCA9888_2_0_DEVICE_ID,498		.bus = ATH10K_BUS_PCI,499		.name = "qca9888 hw2.0",500		.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,501		.uart_pin = 7,502		.led_pin = 17,503		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,504		.otp_exe_param = 0x00000700,505		.continuous_frag_desc = true,506		.channel_counters_freq_hz = 150000,507		.max_probe_resp_desc_thres = 24,508		.tx_chain_mask = 3,509		.rx_chain_mask = 3,510		.max_spatial_stream = 2,511		.cal_data_len = 12064,512		.fw = {513			.dir = QCA9888_HW_2_0_FW_DIR,514			.board_size = QCA99X0_BOARD_DATA_SZ,515			.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,516		},517		.sw_decrypt_mcast_mgmt = true,518		.rx_desc_ops = &qca99x0_rx_desc_ops,519		.hw_ops = &qca99x0_ops,520		.decap_align_bytes = 1,521		.spectral_bin_discard = 12,522		.spectral_bin_offset = 8,523 524		/* Can do only 1x1 VHT160 or 80+80. 780Mbps is 2x2 80Mhz or525		 * 1x1 160Mhz, long-guard-interval.526		 */527		.vht160_mcs_rx_highest = 780,528		.vht160_mcs_tx_highest = 780,529		.n_cipher_suites = 11,530		.ast_skid_limit = 0x10,531		.num_wds_entries = 0x20,532		.target_64bit = false,533		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,534		.shadow_reg_support = false,535		.rri_on_ddr = false,536		.hw_filter_reset_required = true,537		.fw_diag_ce_download = false,538		.credit_size_workaround = false,539		.tx_stats_over_pktlog = false,540		.dynamic_sar_support = false,541		.hw_restart_disconnect = false,542		.use_fw_tx_credits = true,543		.delay_unmap_buffer = false,544		.mcast_frame_registration = false,545	},546	{547		.id = QCA9377_HW_1_0_DEV_VERSION,548		.dev_id = QCA9377_1_0_DEVICE_ID,549		.bus = ATH10K_BUS_PCI,550		.name = "qca9377 hw1.0",551		.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,552		.uart_pin = 6,553		.led_pin = 0,554		.otp_exe_param = 0,555		.channel_counters_freq_hz = 88000,556		.max_probe_resp_desc_thres = 0,557		.cal_data_len = 8124,558		.fw = {559			.dir = QCA9377_HW_1_0_FW_DIR,560			.board_size = QCA9377_BOARD_DATA_SZ,561			.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,562		},563		.rx_desc_ops = &qca988x_rx_desc_ops,564		.hw_ops = &qca988x_ops,565		.decap_align_bytes = 4,566		.spectral_bin_discard = 0,567		.spectral_bin_offset = 0,568		.vht160_mcs_rx_highest = 0,569		.vht160_mcs_tx_highest = 0,570		.n_cipher_suites = 8,571		.ast_skid_limit = 0x10,572		.num_wds_entries = 0x20,573		.target_64bit = false,574		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,575		.shadow_reg_support = false,576		.rri_on_ddr = false,577		.hw_filter_reset_required = true,578		.fw_diag_ce_download = false,579		.credit_size_workaround = false,580		.tx_stats_over_pktlog = false,581		.dynamic_sar_support = false,582		.hw_restart_disconnect = false,583		.use_fw_tx_credits = true,584		.delay_unmap_buffer = false,585		.mcast_frame_registration = false,586	},587	{588		.id = QCA9377_HW_1_1_DEV_VERSION,589		.dev_id = QCA9377_1_0_DEVICE_ID,590		.bus = ATH10K_BUS_PCI,591		.name = "qca9377 hw1.1",592		.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,593		.uart_pin = 6,594		.led_pin = 0,595		.otp_exe_param = 0,596		.channel_counters_freq_hz = 88000,597		.max_probe_resp_desc_thres = 0,598		.cal_data_len = 8124,599		.fw = {600			.dir = QCA9377_HW_1_0_FW_DIR,601			.board_size = QCA9377_BOARD_DATA_SZ,602			.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,603		},604		.rx_desc_ops = &qca988x_rx_desc_ops,605		.hw_ops = &qca6174_ops,606		.hw_clk = qca6174_clk,607		.target_cpu_freq = 176000000,608		.decap_align_bytes = 4,609		.spectral_bin_discard = 0,610		.spectral_bin_offset = 0,611		.vht160_mcs_rx_highest = 0,612		.vht160_mcs_tx_highest = 0,613		.n_cipher_suites = 8,614		.ast_skid_limit = 0x10,615		.num_wds_entries = 0x20,616		.target_64bit = false,617		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,618		.shadow_reg_support = false,619		.rri_on_ddr = false,620		.hw_filter_reset_required = true,621		.fw_diag_ce_download = true,622		.credit_size_workaround = false,623		.tx_stats_over_pktlog = false,624		.dynamic_sar_support = false,625		.hw_restart_disconnect = false,626		.use_fw_tx_credits = true,627		.delay_unmap_buffer = false,628		.mcast_frame_registration = false,629	},630	{631		.id = QCA9377_HW_1_1_DEV_VERSION,632		.dev_id = QCA9377_1_0_DEVICE_ID,633		.bus = ATH10K_BUS_SDIO,634		.name = "qca9377 hw1.1 sdio",635		.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,636		.uart_pin = 19,637		.led_pin = 0,638		.otp_exe_param = 0,639		.channel_counters_freq_hz = 88000,640		.max_probe_resp_desc_thres = 0,641		.cal_data_len = 8124,642		.fw = {643			.dir = QCA9377_HW_1_0_FW_DIR,644			.board_size = QCA9377_BOARD_DATA_SZ,645			.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,646		},647		.rx_desc_ops = &qca988x_rx_desc_ops,648		.hw_ops = &qca6174_ops,649		.hw_clk = qca6174_clk,650		.target_cpu_freq = 176000000,651		.decap_align_bytes = 4,652		.n_cipher_suites = 8,653		.num_peers = TARGET_QCA9377_HL_NUM_PEERS,654		.ast_skid_limit = 0x10,655		.num_wds_entries = 0x20,656		.uart_pin_workaround = true,657		.credit_size_workaround = true,658		.dynamic_sar_support = false,659		.hw_restart_disconnect = false,660		.use_fw_tx_credits = true,661		.delay_unmap_buffer = false,662		.mcast_frame_registration = false,663	},664	{665		.id = QCA4019_HW_1_0_DEV_VERSION,666		.dev_id = 0,667		.bus = ATH10K_BUS_AHB,668		.name = "qca4019 hw1.0",669		.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,670		.uart_pin = 7,671		.led_pin = 0,672		.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,673		.otp_exe_param = 0x0010000,674		.continuous_frag_desc = true,675		.cck_rate_map_rev2 = true,676		.channel_counters_freq_hz = 125000,677		.max_probe_resp_desc_thres = 24,678		.tx_chain_mask = 0x3,679		.rx_chain_mask = 0x3,680		.max_spatial_stream = 2,681		.cal_data_len = 12064,682		.fw = {683			.dir = QCA4019_HW_1_0_FW_DIR,684			.board_size = QCA4019_BOARD_DATA_SZ,685			.board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,686		},687		.sw_decrypt_mcast_mgmt = true,688		.rx_desc_ops = &qca99x0_rx_desc_ops,689		.hw_ops = &qca99x0_ops,690		.decap_align_bytes = 1,691		.spectral_bin_discard = 4,692		.spectral_bin_offset = 0,693		.vht160_mcs_rx_highest = 0,694		.vht160_mcs_tx_highest = 0,695		.n_cipher_suites = 11,696		.ast_skid_limit = 0x10,697		.num_wds_entries = 0x20,698		.target_64bit = false,699		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,700		.shadow_reg_support = false,701		.rri_on_ddr = false,702		.hw_filter_reset_required = true,703		.fw_diag_ce_download = false,704		.credit_size_workaround = false,705		.tx_stats_over_pktlog = false,706		.dynamic_sar_support = false,707		.hw_restart_disconnect = false,708		.use_fw_tx_credits = true,709		.delay_unmap_buffer = false,710		.mcast_frame_registration = false,711	},712	{713		.id = WCN3990_HW_1_0_DEV_VERSION,714		.dev_id = 0,715		.bus = ATH10K_BUS_SNOC,716		.name = "wcn3990 hw1.0",717		.led_pin = 0,718		.continuous_frag_desc = true,719		.tx_chain_mask = 0x7,720		.rx_chain_mask = 0x7,721		.max_spatial_stream = 4,722		.fw = {723			.dir = WCN3990_HW_1_0_FW_DIR,724			.board_size = WCN3990_BOARD_DATA_SZ,725			.board_ext_size = WCN3990_BOARD_EXT_DATA_SZ,726		},727		.sw_decrypt_mcast_mgmt = true,728		.rx_desc_ops = &wcn3990_rx_desc_ops,729		.hw_ops = &wcn3990_ops,730		.decap_align_bytes = 1,731		.num_peers = TARGET_HL_TLV_NUM_PEERS,732		.n_cipher_suites = 11,733		.ast_skid_limit = TARGET_HL_TLV_AST_SKID_LIMIT,734		.num_wds_entries = TARGET_HL_TLV_NUM_WDS_ENTRIES,735		.target_64bit = true,736		.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC,737		.shadow_reg_support = true,738		.rri_on_ddr = true,739		.hw_filter_reset_required = false,740		.fw_diag_ce_download = false,741		.credit_size_workaround = false,742		.tx_stats_over_pktlog = false,743		.dynamic_sar_support = true,744		.hw_restart_disconnect = true,745		.use_fw_tx_credits = false,746		.delay_unmap_buffer = true,747		.mcast_frame_registration = false,748	},749};750 751static const char *const ath10k_core_fw_feature_str[] = {752	[ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",753	[ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",754	[ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",755	[ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",756	[ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",757	[ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",758	[ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",759	[ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",760	[ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",761	[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",762	[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",763	[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",764	[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",765	[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",766	[ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",767	[ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",768	[ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",769	[ATH10K_FW_FEATURE_NO_PS] = "no-ps",770	[ATH10K_FW_FEATURE_MGMT_TX_BY_REF] = "mgmt-tx-by-reference",771	[ATH10K_FW_FEATURE_NON_BMI] = "non-bmi",772	[ATH10K_FW_FEATURE_SINGLE_CHAN_INFO_PER_CHANNEL] = "single-chan-info-per-channel",773	[ATH10K_FW_FEATURE_PEER_FIXED_RATE] = "peer-fixed-rate",774	[ATH10K_FW_FEATURE_IRAM_RECOVERY] = "iram-recovery",775};776 777static unsigned int ath10k_core_get_fw_feature_str(char *buf,778						   size_t buf_len,779						   enum ath10k_fw_features feat)780{781	/* make sure that ath10k_core_fw_feature_str[] gets updated */782	BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=783		     ATH10K_FW_FEATURE_COUNT);784 785	if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||786	    WARN_ON(!ath10k_core_fw_feature_str[feat])) {787		return scnprintf(buf, buf_len, "bit%d", feat);788	}789 790	return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);791}792 793void ath10k_core_get_fw_features_str(struct ath10k *ar,794				     char *buf,795				     size_t buf_len)796{797	size_t len = 0;798	int i;799 800	for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {801		if (test_bit(i, ar->normal_mode_fw.fw_file.fw_features)) {802			if (len > 0)803				len += scnprintf(buf + len, buf_len - len, ",");804 805			len += ath10k_core_get_fw_feature_str(buf + len,806							      buf_len - len,807							      i);808		}809	}810}811 812static void ath10k_send_suspend_complete(struct ath10k *ar)813{814	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");815 816	complete(&ar->target_suspend);817}818 819static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode)820{821	bool mtu_workaround = ar->hw_params.credit_size_workaround;822	int ret;823	u32 param = 0;824 825	ret = ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);826	if (ret)827		return ret;828 829	ret = ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);830	if (ret)831		return ret;832 833	ret = ath10k_bmi_read32(ar, hi_acs_flags, &param);834	if (ret)835		return ret;836 837	param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET;838 839	if (mode == ATH10K_FIRMWARE_MODE_NORMAL && !mtu_workaround)840		param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;841	else842		param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE;843 844	if (mode == ATH10K_FIRMWARE_MODE_UTF)845		param &= ~HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;846	else847		param |= HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET;848 849	ret = ath10k_bmi_write32(ar, hi_acs_flags, param);850	if (ret)851		return ret;852 853	ret = ath10k_bmi_read32(ar, hi_option_flag2, &param);854	if (ret)855		return ret;856 857	param |= HI_OPTION_SDIO_CRASH_DUMP_ENHANCEMENT_HOST;858 859	ret = ath10k_bmi_write32(ar, hi_option_flag2, param);860	if (ret)861		return ret;862 863	return 0;864}865 866static int ath10k_init_configure_target(struct ath10k *ar)867{868	u32 param_host;869	int ret;870 871	/* tell target which HTC version it is used*/872	ret = ath10k_bmi_write32(ar, hi_app_host_interest,873				 HTC_PROTOCOL_VERSION);874	if (ret) {875		ath10k_err(ar, "settings HTC version failed\n");876		return ret;877	}878 879	/* set the firmware mode to STA/IBSS/AP */880	ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);881	if (ret) {882		ath10k_err(ar, "setting firmware mode (1/2) failed\n");883		return ret;884	}885 886	/* TODO following parameters need to be re-visited. */887	/* num_device */888	param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);889	/* Firmware mode */890	/* FIXME: Why FW_MODE_AP ??.*/891	param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);892	/* mac_addr_method */893	param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);894	/* firmware_bridge */895	param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);896	/* fwsubmode */897	param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);898 899	ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);900	if (ret) {901		ath10k_err(ar, "setting firmware mode (2/2) failed\n");902		return ret;903	}904 905	/* We do all byte-swapping on the host */906	ret = ath10k_bmi_write32(ar, hi_be, 0);907	if (ret) {908		ath10k_err(ar, "setting host CPU BE mode failed\n");909		return ret;910	}911 912	/* FW descriptor/Data swap flags */913	ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);914 915	if (ret) {916		ath10k_err(ar, "setting FW data/desc swap flags failed\n");917		return ret;918	}919 920	/* Some devices have a special sanity check that verifies the PCI921	 * Device ID is written to this host interest var. It is known to be922	 * required to boot QCA6164.923	 */924	ret = ath10k_bmi_write32(ar, hi_hci_uart_pwr_mgmt_params_ext,925				 ar->dev_id);926	if (ret) {927		ath10k_err(ar, "failed to set pwr_mgmt_params: %d\n", ret);928		return ret;929	}930 931	return 0;932}933 934static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,935						   const char *dir,936						   const char *file)937{938	char filename[100];939	const struct firmware *fw;940	int ret;941 942	if (file == NULL)943		return ERR_PTR(-ENOENT);944 945	if (dir == NULL)946		dir = ".";947 948	if (ar->board_name) {949		snprintf(filename, sizeof(filename), "%s/%s/%s",950			 dir, ar->board_name, file);951		ret = firmware_request_nowarn(&fw, filename, ar->dev);952		ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n",953			   filename, ret);954		if (!ret)955			return fw;956	}957 958	snprintf(filename, sizeof(filename), "%s/%s", dir, file);959	ret = firmware_request_nowarn(&fw, filename, ar->dev);960	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n",961		   filename, ret);962	if (ret)963		return ERR_PTR(ret);964 965	return fw;966}967 968static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,969				      size_t data_len)970{971	u32 board_data_size = ar->hw_params.fw.board_size;972	u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;973	u32 board_ext_data_addr;974	int ret;975 976	ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);977	if (ret) {978		ath10k_err(ar, "could not read board ext data addr (%d)\n",979			   ret);980		return ret;981	}982 983	ath10k_dbg(ar, ATH10K_DBG_BOOT,984		   "boot push board extended data addr 0x%x\n",985		   board_ext_data_addr);986 987	if (board_ext_data_addr == 0)988		return 0;989 990	if (data_len != (board_data_size + board_ext_data_size)) {991		ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",992			   data_len, board_data_size, board_ext_data_size);993		return -EINVAL;994	}995 996	ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,997				      data + board_data_size,998				      board_ext_data_size);999	if (ret) {1000		ath10k_err(ar, "could not write board ext data (%d)\n", ret);1001		return ret;1002	}1003 1004	ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,1005				 (board_ext_data_size << 16) | 1);1006	if (ret) {1007		ath10k_err(ar, "could not write board ext data bit (%d)\n",1008			   ret);1009		return ret;1010	}1011 1012	return 0;1013}1014 1015static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)1016{1017	u32 result, address;1018	u8 board_id, chip_id;1019	bool ext_bid_support;1020	int ret, bmi_board_id_param;1021 1022	address = ar->hw_params.patch_load_addr;1023 1024	if (!ar->normal_mode_fw.fw_file.otp_data ||1025	    !ar->normal_mode_fw.fw_file.otp_len) {1026		ath10k_warn(ar,1027			    "failed to retrieve board id because of invalid otp\n");1028		return -ENODATA;1029	}1030 1031	if (ar->id.bmi_ids_valid) {1032		ath10k_dbg(ar, ATH10K_DBG_BOOT,1033			   "boot already acquired valid otp board id,skip download, board_id %d chip_id %d\n",1034			   ar->id.bmi_board_id, ar->id.bmi_chip_id);1035		goto skip_otp_download;1036	}1037 1038	ath10k_dbg(ar, ATH10K_DBG_BOOT,1039		   "boot upload otp to 0x%x len %zd for board id\n",1040		   address, ar->normal_mode_fw.fw_file.otp_len);1041 1042	ret = ath10k_bmi_fast_download(ar, address,1043				       ar->normal_mode_fw.fw_file.otp_data,1044				       ar->normal_mode_fw.fw_file.otp_len);1045	if (ret) {1046		ath10k_err(ar, "could not write otp for board id check: %d\n",1047			   ret);1048		return ret;1049	}1050 1051	if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||1052	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||1053	    ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)1054		bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;1055	else1056		bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;1057 1058	ret = ath10k_bmi_execute(ar, address, bmi_board_id_param, &result);1059	if (ret) {1060		ath10k_err(ar, "could not execute otp for board id check: %d\n",1061			   ret);1062		return ret;1063	}1064 1065	board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);1066	chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);1067	ext_bid_support = (result & ATH10K_BMI_EXT_BOARD_ID_SUPPORT);1068 1069	ath10k_dbg(ar, ATH10K_DBG_BOOT,1070		   "boot get otp board id result 0x%08x board_id %d chip_id %d ext_bid_support %d\n",1071		   result, board_id, chip_id, ext_bid_support);1072 1073	ar->id.ext_bid_supported = ext_bid_support;1074 1075	if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||1076	    (board_id == 0)) {1077		ath10k_dbg(ar, ATH10K_DBG_BOOT,1078			   "board id does not exist in otp, ignore it\n");1079		return -EOPNOTSUPP;1080	}1081 1082	ar->id.bmi_ids_valid = true;1083	ar->id.bmi_board_id = board_id;1084	ar->id.bmi_chip_id = chip_id;1085 1086skip_otp_download:1087 1088	return 0;1089}1090 1091static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)1092{1093	struct ath10k *ar = data;1094	const char *bdf_ext;1095	const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;1096	u8 bdf_enabled;1097	int i;1098 1099	if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)1100		return;1101 1102	if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {1103		ath10k_dbg(ar, ATH10K_DBG_BOOT,1104			   "wrong smbios bdf ext type length (%d).\n",1105			   hdr->length);1106		return;1107	}1108 1109	bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);1110	if (!bdf_enabled) {1111		ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");1112		return;1113	}1114 1115	/* Only one string exists (per spec) */1116	bdf_ext = (char *)hdr + hdr->length;1117 1118	if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {1119		ath10k_dbg(ar, ATH10K_DBG_BOOT,1120			   "bdf variant magic does not match.\n");1121		return;1122	}1123 1124	for (i = 0; i < strlen(bdf_ext); i++) {1125		if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {1126			ath10k_dbg(ar, ATH10K_DBG_BOOT,1127				   "bdf variant name contains non ascii chars.\n");1128			return;1129		}1130	}1131 1132	/* Copy extension name without magic suffix */1133	if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),1134		    sizeof(ar->id.bdf_ext)) < 0) {1135		ath10k_dbg(ar, ATH10K_DBG_BOOT,1136			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",1137			    bdf_ext);1138		return;1139	}1140 1141	ath10k_dbg(ar, ATH10K_DBG_BOOT,1142		   "found and validated bdf variant smbios_type 0x%x bdf %s\n",1143		   ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);1144}1145 1146static int ath10k_core_check_smbios(struct ath10k *ar)1147{1148	ar->id.bdf_ext[0] = '\0';1149	dmi_walk(ath10k_core_check_bdfext, ar);1150 1151	if (ar->id.bdf_ext[0] == '\0')1152		return -ENODATA;1153 1154	return 0;1155}1156 1157int ath10k_core_check_dt(struct ath10k *ar)1158{1159	struct device_node *node;1160	const char *variant = NULL;1161 1162	node = ar->dev->of_node;1163	if (!node)1164		return -ENOENT;1165 1166	of_property_read_string(node, "qcom,ath10k-calibration-variant",1167				&variant);1168	if (!variant)1169		return -ENODATA;1170 1171	if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0)1172		ath10k_dbg(ar, ATH10K_DBG_BOOT,1173			   "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",1174			    variant);1175 1176	return 0;1177}1178EXPORT_SYMBOL(ath10k_core_check_dt);1179 1180static int ath10k_download_fw(struct ath10k *ar)1181{1182	u32 address, data_len;1183	const void *data;1184	int ret;1185	struct pm_qos_request latency_qos;1186 1187	address = ar->hw_params.patch_load_addr;1188 1189	data = ar->running_fw->fw_file.firmware_data;1190	data_len = ar->running_fw->fw_file.firmware_len;1191 1192	ret = ath10k_swap_code_seg_configure(ar, &ar->running_fw->fw_file);1193	if (ret) {1194		ath10k_err(ar, "failed to configure fw code swap: %d\n",1195			   ret);1196		return ret;1197	}1198 1199	ath10k_dbg(ar, ATH10K_DBG_BOOT,1200		   "boot uploading firmware image %pK len %d\n",1201		   data, data_len);1202 1203	/* Check if device supports to download firmware via1204	 * diag copy engine. Downloading firmware via diag CE1205	 * greatly reduces the time to download firmware.1206	 */1207	if (ar->hw_params.fw_diag_ce_download) {1208		ret = ath10k_hw_diag_fast_download(ar, address,1209						   data, data_len);1210		if (ret == 0)1211			/* firmware upload via diag ce was successful */1212			return 0;1213 1214		ath10k_warn(ar,1215			    "failed to upload firmware via diag ce, trying BMI: %d",1216			    ret);1217	}1218 1219	memset(&latency_qos, 0, sizeof(latency_qos));1220	cpu_latency_qos_add_request(&latency_qos, 0);1221 1222	ret = ath10k_bmi_fast_download(ar, address, data, data_len);1223 1224	cpu_latency_qos_remove_request(&latency_qos);1225 1226	return ret;1227}1228 1229void ath10k_core_free_board_files(struct ath10k *ar)1230{1231	if (!IS_ERR(ar->normal_mode_fw.board))1232		release_firmware(ar->normal_mode_fw.board);1233 1234	if (!IS_ERR(ar->normal_mode_fw.ext_board))1235		release_firmware(ar->normal_mode_fw.ext_board);1236 1237	ar->normal_mode_fw.board = NULL;1238	ar->normal_mode_fw.board_data = NULL;1239	ar->normal_mode_fw.board_len = 0;1240	ar->normal_mode_fw.ext_board = NULL;1241	ar->normal_mode_fw.ext_board_data = NULL;1242	ar->normal_mode_fw.ext_board_len = 0;1243}1244EXPORT_SYMBOL(ath10k_core_free_board_files);1245 1246static void ath10k_core_free_firmware_files(struct ath10k *ar)1247{1248	if (!IS_ERR(ar->normal_mode_fw.fw_file.firmware))1249		release_firmware(ar->normal_mode_fw.fw_file.firmware);1250 1251	if (!IS_ERR(ar->cal_file))1252		release_firmware(ar->cal_file);1253 1254	if (!IS_ERR(ar->pre_cal_file))1255		release_firmware(ar->pre_cal_file);1256 1257	ath10k_swap_code_seg_release(ar, &ar->normal_mode_fw.fw_file);1258 1259	ar->normal_mode_fw.fw_file.otp_data = NULL;1260	ar->normal_mode_fw.fw_file.otp_len = 0;1261 1262	ar->normal_mode_fw.fw_file.firmware = NULL;1263	ar->normal_mode_fw.fw_file.firmware_data = NULL;1264	ar->normal_mode_fw.fw_file.firmware_len = 0;1265 1266	ar->cal_file = NULL;1267	ar->pre_cal_file = NULL;1268}1269 1270static int ath10k_fetch_cal_file(struct ath10k *ar)1271{1272	char filename[100];1273 1274	/* pre-cal-<bus>-<id>.bin */1275	scnprintf(filename, sizeof(filename), "pre-cal-%s-%s.bin",1276		  ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));1277 1278	ar->pre_cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);1279	if (!IS_ERR(ar->pre_cal_file))1280		goto success;1281 1282	/* cal-<bus>-<id>.bin */1283	scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",1284		  ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));1285 1286	ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);1287	if (IS_ERR(ar->cal_file))1288		/* calibration file is optional, don't print any warnings */1289		return PTR_ERR(ar->cal_file);1290success:1291	ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",1292		   ATH10K_FW_DIR, filename);1293 1294	return 0;1295}1296 1297static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)1298{1299	const struct firmware *fw;1300	char boardname[100];1301 1302	if (bd_ie_type == ATH10K_BD_IE_BOARD) {1303		scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",1304			  ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));1305 1306		ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,1307								ar->hw_params.fw.dir,1308								boardname);1309		if (IS_ERR(ar->normal_mode_fw.board)) {1310			fw = ath10k_fetch_fw_file(ar,1311						  ar->hw_params.fw.dir,1312						  ATH10K_BOARD_DATA_FILE);1313			ar->normal_mode_fw.board = fw;1314		}1315 1316		if (IS_ERR(ar->normal_mode_fw.board))1317			return PTR_ERR(ar->normal_mode_fw.board);1318 1319		ar->normal_mode_fw.board_data = ar->normal_mode_fw.board->data;1320		ar->normal_mode_fw.board_len = ar->normal_mode_fw.board->size;1321	} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {1322		fw = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,1323					  ATH10K_EBOARD_DATA_FILE);1324		ar->normal_mode_fw.ext_board = fw;1325		if (IS_ERR(ar->normal_mode_fw.ext_board))1326			return PTR_ERR(ar->normal_mode_fw.ext_board);1327 1328		ar->normal_mode_fw.ext_board_data = ar->normal_mode_fw.ext_board->data;1329		ar->normal_mode_fw.ext_board_len = ar->normal_mode_fw.ext_board->size;1330	}1331 1332	return 0;1333}1334 1335static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,1336					 const void *buf, size_t buf_len,1337					 const char *boardname,1338					 int bd_ie_type)1339{1340	const struct ath10k_fw_ie *hdr;1341	bool name_match_found;1342	int ret, board_ie_id;1343	size_t board_ie_len;1344	const void *board_ie_data;1345 1346	name_match_found = false;1347 1348	/* go through ATH10K_BD_IE_BOARD_ elements */1349	while (buf_len > sizeof(struct ath10k_fw_ie)) {1350		hdr = buf;1351		board_ie_id = le32_to_cpu(hdr->id);1352		board_ie_len = le32_to_cpu(hdr->len);1353		board_ie_data = hdr->data;1354 1355		buf_len -= sizeof(*hdr);1356		buf += sizeof(*hdr);1357 1358		if (buf_len < ALIGN(board_ie_len, 4)) {1359			ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",1360				   buf_len, ALIGN(board_ie_len, 4));1361			ret = -EINVAL;1362			goto out;1363		}1364 1365		switch (board_ie_id) {1366		case ATH10K_BD_IE_BOARD_NAME:1367			ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",1368					board_ie_data, board_ie_len);1369 1370			if (board_ie_len != strlen(boardname))1371				break;1372 1373			ret = memcmp(board_ie_data, boardname, strlen(boardname));1374			if (ret)1375				break;1376 1377			name_match_found = true;1378			ath10k_dbg(ar, ATH10K_DBG_BOOT,1379				   "boot found match for name '%s'",1380				   boardname);1381			break;1382		case ATH10K_BD_IE_BOARD_DATA:1383			if (!name_match_found)1384				/* no match found */1385				break;1386 1387			if (bd_ie_type == ATH10K_BD_IE_BOARD) {1388				ath10k_dbg(ar, ATH10K_DBG_BOOT,1389					   "boot found board data for '%s'",1390						boardname);1391 1392				ar->normal_mode_fw.board_data = board_ie_data;1393				ar->normal_mode_fw.board_len = board_ie_len;1394			} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {1395				ath10k_dbg(ar, ATH10K_DBG_BOOT,1396					   "boot found eboard data for '%s'",1397						boardname);1398 1399				ar->normal_mode_fw.ext_board_data = board_ie_data;1400				ar->normal_mode_fw.ext_board_len = board_ie_len;1401			}1402 1403			ret = 0;1404			goto out;1405		default:1406			ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",1407				    board_ie_id);1408			break;1409		}1410 1411		/* jump over the padding */1412		board_ie_len = ALIGN(board_ie_len, 4);1413 1414		buf_len -= board_ie_len;1415		buf += board_ie_len;1416	}1417 1418	/* no match found */1419	ret = -ENOENT;1420 1421out:1422	return ret;1423}1424 1425static int ath10k_core_search_bd(struct ath10k *ar,1426				 const char *boardname,1427				 const u8 *data,1428				 size_t len)1429{1430	size_t ie_len;1431	struct ath10k_fw_ie *hdr;1432	int ret = -ENOENT, ie_id;1433 1434	while (len > sizeof(struct ath10k_fw_ie)) {1435		hdr = (struct ath10k_fw_ie *)data;1436		ie_id = le32_to_cpu(hdr->id);1437		ie_len = le32_to_cpu(hdr->len);1438 1439		len -= sizeof(*hdr);1440		data = hdr->data;1441 1442		if (len < ALIGN(ie_len, 4)) {1443			ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",1444				   ie_id, ie_len, len);1445			return -EINVAL;1446		}1447 1448		switch (ie_id) {1449		case ATH10K_BD_IE_BOARD:1450			ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,1451							    boardname,1452							    ATH10K_BD_IE_BOARD);1453			if (ret == -ENOENT)1454				/* no match found, continue */1455				break;1456 1457			/* either found or error, so stop searching */1458			goto out;1459		case ATH10K_BD_IE_BOARD_EXT:1460			ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,1461							    boardname,1462							    ATH10K_BD_IE_BOARD_EXT);1463			if (ret == -ENOENT)1464				/* no match found, continue */1465				break;1466 1467			/* either found or error, so stop searching */1468			goto out;1469		}1470 1471		/* jump over the padding */1472		ie_len = ALIGN(ie_len, 4);1473 1474		len -= ie_len;1475		data += ie_len;1476	}1477 1478out:1479	/* return result of parse_bd_ie_board() or -ENOENT */1480	return ret;1481}1482 1483static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,1484					      const char *boardname,1485					      const char *fallback_boardname1,1486					      const char *fallback_boardname2,1487					      const char *filename)1488{1489	size_t len, magic_len;1490	const u8 *data;1491	int ret;1492 1493	/* Skip if already fetched during board data download */1494	if (!ar->normal_mode_fw.board)1495		ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,1496								ar->hw_params.fw.dir,1497								filename);1498	if (IS_ERR(ar->normal_mode_fw.board))1499		return PTR_ERR(ar->normal_mode_fw.board);1500 1501	data = ar->normal_mode_fw.board->data;1502	len = ar->normal_mode_fw.board->size;1503 1504	/* magic has extra null byte padded */1505	magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;1506	if (len < magic_len) {1507		ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",1508			   ar->hw_params.fw.dir, filename, len);1509		ret = -EINVAL;1510		goto err;1511	}1512 1513	if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {1514		ath10k_err(ar, "found invalid board magic\n");1515		ret = -EINVAL;1516		goto err;1517	}1518 1519	/* magic is padded to 4 bytes */1520	magic_len = ALIGN(magic_len, 4);1521	if (len < magic_len) {1522		ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",1523			   ar->hw_params.fw.dir, filename, len);1524		ret = -EINVAL;1525		goto err;1526	}1527 1528	data += magic_len;1529	len -= magic_len;1530 1531	/* attempt to find boardname in the IE list */1532	ret = ath10k_core_search_bd(ar, boardname, data, len);1533 1534	/* if we didn't find it and have a fallback name, try that */1535	if (ret == -ENOENT && fallback_boardname1)1536		ret = ath10k_core_search_bd(ar, fallback_boardname1, data, len);1537 1538	if (ret == -ENOENT && fallback_boardname2)1539		ret = ath10k_core_search_bd(ar, fallback_boardname2, data, len);1540 1541	if (ret == -ENOENT) {1542		ath10k_err(ar,1543			   "failed to fetch board data for %s from %s/%s\n",1544			   boardname, ar->hw_params.fw.dir, filename);1545		ret = -ENODATA;1546	}1547 1548	if (ret)1549		goto err;1550 1551	return 0;1552 1553err:1554	ath10k_core_free_board_files(ar);1555	return ret;1556}1557 1558static int ath10k_core_create_board_name(struct ath10k *ar, char *name,1559					 size_t name_len, bool with_variant,1560					 bool with_chip_id)1561{1562	/* strlen(',variant=') + strlen(ar->id.bdf_ext) */1563	char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };1564 1565	if (with_variant && ar->id.bdf_ext[0] != '\0')1566		scnprintf(variant, sizeof(variant), ",variant=%s",1567			  ar->id.bdf_ext);1568 1569	if (ar->id.bmi_ids_valid) {1570		scnprintf(name, name_len,1571			  "bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s",1572			  ath10k_bus_str(ar->hif.bus),1573			  ar->id.bmi_chip_id,1574			  ar->id.bmi_board_id, variant);1575		goto out;1576	}1577 1578	if (ar->id.qmi_ids_valid) {1579		if (with_chip_id)1580			scnprintf(name, name_len,1581				  "bus=%s,qmi-board-id=%x,qmi-chip-id=%x%s",1582				  ath10k_bus_str(ar->hif.bus),1583				  ar->id.qmi_board_id, ar->id.qmi_chip_id,1584				  variant);1585		else1586			scnprintf(name, name_len,1587				  "bus=%s,qmi-board-id=%x",1588				  ath10k_bus_str(ar->hif.bus),1589				  ar->id.qmi_board_id);1590		goto out;1591	}1592 1593	scnprintf(name, name_len,1594		  "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",1595		  ath10k_bus_str(ar->hif.bus),1596		  ar->id.vendor, ar->id.device,1597		  ar->id.subsystem_vendor, ar->id.subsystem_device, variant);1598out:1599	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);1600 1601	return 0;1602}1603 1604static int ath10k_core_create_eboard_name(struct ath10k *ar, char *name,1605					  size_t name_len)1606{1607	if (ar->id.bmi_ids_valid) {1608		scnprintf(name, name_len,1609			  "bus=%s,bmi-chip-id=%d,bmi-eboard-id=%d",1610			  ath10k_bus_str(ar->hif.bus),1611			  ar->id.bmi_chip_id,1612			  ar->id.bmi_eboard_id);1613 1614		ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using eboard name '%s'\n", name);1615		return 0;1616	}1617	/* Fallback if returned board id is zero */1618	return -1;1619}1620 1621int ath10k_core_fetch_board_file(struct ath10k *ar, int bd_ie_type)1622{1623	char boardname[100], fallback_boardname1[100], fallback_boardname2[100];1624	int ret;1625 1626	if (bd_ie_type == ATH10K_BD_IE_BOARD) {1627		/* With variant and chip id */1628		ret = ath10k_core_create_board_name(ar, boardname,1629						    sizeof(boardname), true,1630						    true);1631		if (ret) {1632			ath10k_err(ar, "failed to create board name: %d", ret);1633			return ret;1634		}1635 1636		/* Without variant and only chip-id */1637		ret = ath10k_core_create_board_name(ar, fallback_boardname1,1638						    sizeof(boardname), false,1639						    true);1640		if (ret) {1641			ath10k_err(ar, "failed to create 1st fallback board name: %d",1642				   ret);1643			return ret;1644		}1645 1646		/* Without variant and without chip-id */1647		ret = ath10k_core_create_board_name(ar, fallback_boardname2,1648						    sizeof(boardname), false,1649						    false);1650		if (ret) {1651			ath10k_err(ar, "failed to create 2nd fallback board name: %d",1652				   ret);1653			return ret;1654		}1655	} else if (bd_ie_type == ATH10K_BD_IE_BOARD_EXT) {1656		ret = ath10k_core_create_eboard_name(ar, boardname,1657						     sizeof(boardname));1658		if (ret) {1659			ath10k_err(ar, "fallback to eboard.bin since board id 0");1660			goto fallback;1661		}1662	}1663 1664	ar->bd_api = 2;1665	ret = ath10k_core_fetch_board_data_api_n(ar, boardname,1666						 fallback_boardname1,1667						 fallback_boardname2,1668						 ATH10K_BOARD_API2_FILE);1669	if (!ret)1670		goto success;1671 1672fallback:1673	ar->bd_api = 1;1674	ret = ath10k_core_fetch_board_data_api_1(ar, bd_ie_type);1675	if (ret) {1676		ath10k_err(ar, "failed to fetch board-2.bin or board.bin from %s\n",1677			   ar->hw_params.fw.dir);1678		return ret;1679	}1680 1681success:1682	ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);1683	return 0;1684}1685EXPORT_SYMBOL(ath10k_core_fetch_board_file);1686 1687static int ath10k_core_get_ext_board_id_from_otp(struct ath10k *ar)1688{1689	u32 result, address;1690	u8 ext_board_id;1691	int ret;1692 1693	address = ar->hw_params.patch_load_addr;1694 1695	if (!ar->normal_mode_fw.fw_file.otp_data ||1696	    !ar->normal_mode_fw.fw_file.otp_len) {1697		ath10k_warn(ar,1698			    "failed to retrieve extended board id due to otp binary missing\n");1699		return -ENODATA;1700	}1701 1702	ath10k_dbg(ar, ATH10K_DBG_BOOT,1703		   "boot upload otp to 0x%x len %zd for ext board id\n",1704		   address, ar->normal_mode_fw.fw_file.otp_len);1705 1706	ret = ath10k_bmi_fast_download(ar, address,1707				       ar->normal_mode_fw.fw_file.otp_data,1708				       ar->normal_mode_fw.fw_file.otp_len);1709	if (ret) {1710		ath10k_err(ar, "could not write otp for ext board id check: %d\n",1711			   ret);1712		return ret;1713	}1714 1715	ret = ath10k_bmi_execute(ar, address, BMI_PARAM_GET_EXT_BOARD_ID, &result);1716	if (ret) {1717		ath10k_err(ar, "could not execute otp for ext board id check: %d\n",1718			   ret);1719		return ret;1720	}1721 1722	if (!result) {1723		ath10k_dbg(ar, ATH10K_DBG_BOOT,1724			   "ext board id does not exist in otp, ignore it\n");1725		return -EOPNOTSUPP;1726	}1727 1728	ext_board_id = result & ATH10K_BMI_EBOARD_ID_STATUS_MASK;1729 1730	ath10k_dbg(ar, ATH10K_DBG_BOOT,1731		   "boot get otp ext board id result 0x%08x ext_board_id %d\n",1732		   result, ext_board_id);1733 1734	ar->id.bmi_eboard_id = ext_board_id;1735 1736	return 0;1737}1738 1739static int ath10k_download_board_data(struct ath10k *ar, const void *data,1740				      size_t data_len)1741{1742	u32 board_data_size = ar->hw_params.fw.board_size;1743	u32 eboard_data_size = ar->hw_params.fw.ext_board_size;1744	u32 board_address;1745	u32 ext_board_address;1746	int ret;1747 1748	ret = ath10k_push_board_ext_data(ar, data, data_len);1749	if (ret) {1750		ath10k_err(ar, "could not push board ext data (%d)\n", ret);1751		goto exit;1752	}1753 1754	ret = ath10k_bmi_read32(ar, hi_board_data, &board_address);1755	if (ret) {1756		ath10k_err(ar, "could not read board data addr (%d)\n", ret);1757		goto exit;1758	}1759 1760	ret = ath10k_bmi_write_memory(ar, board_address, data,1761				      min_t(u32, board_data_size,1762					    data_len));1763	if (ret) {1764		ath10k_err(ar, "could not write board data (%d)\n", ret);1765		goto exit;1766	}1767 1768	ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);1769	if (ret) {1770		ath10k_err(ar, "could not write board data bit (%d)\n", ret);1771		goto exit;1772	}1773 1774	if (!ar->id.ext_bid_supported)1775		goto exit;1776 1777	/* Extended board data download */1778	ret = ath10k_core_get_ext_board_id_from_otp(ar);1779	if (ret == -EOPNOTSUPP) {1780		/* Not fetching ext_board_data if ext board id is 0 */1781		ath10k_dbg(ar, ATH10K_DBG_BOOT, "otp returned ext board id 0\n");1782		return 0;1783	} else if (ret) {1784		ath10k_err(ar, "failed to get extended board id: %d\n", ret);1785		goto exit;1786	}1787 1788	ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD_EXT);1789	if (ret)1790		goto exit;1791 1792	if (ar->normal_mode_fw.ext_board_data) {1793		ext_board_address = board_address + EXT_BOARD_ADDRESS_OFFSET;1794		ath10k_dbg(ar, ATH10K_DBG_BOOT,1795			   "boot writing ext board data to addr 0x%x",1796			   ext_board_address);1797		ret = ath10k_bmi_write_memory(ar, ext_board_address,1798					      ar->normal_mode_fw.ext_board_data,1799					      min_t(u32, eboard_data_size, data_len));1800		if (ret)1801			ath10k_err(ar, "failed to write ext board data: %d\n", ret);1802	}1803 1804exit:1805	return ret;1806}1807 1808static int ath10k_download_and_run_otp(struct ath10k *ar)1809{1810	u32 result, address = ar->hw_params.patch_load_addr;1811	u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;1812	int ret;1813 1814	ret = ath10k_download_board_data(ar,1815					 ar->running_fw->board_data,1816					 ar->running_fw->board_len);1817	if (ret) {1818		ath10k_err(ar, "failed to download board data: %d\n", ret);1819		return ret;1820	}1821 1822	/* OTP is optional */1823 1824	if (!ar->running_fw->fw_file.otp_data ||1825	    !ar->running_fw->fw_file.otp_len) {1826		ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",1827			    ar->running_fw->fw_file.otp_data,1828			    ar->running_fw->fw_file.otp_len);1829		return 0;1830	}1831 1832	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",1833		   address, ar->running_fw->fw_file.otp_len);1834 1835	ret = ath10k_bmi_fast_download(ar, address,1836				       ar->running_fw->fw_file.otp_data,1837				       ar->running_fw->fw_file.otp_len);1838	if (ret) {1839		ath10k_err(ar, "could not write otp (%d)\n", ret);1840		return ret;1841	}1842 1843	/* As of now pre-cal is valid for 10_4 variants */1844	if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||1845	    ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||1846	    ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)1847		bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;1848 1849	ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);1850	if (ret) {1851		ath10k_err(ar, "could not execute otp (%d)\n", ret);1852		return ret;1853	}1854 1855	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);1856 1857	if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,1858				   ar->running_fw->fw_file.fw_features)) &&1859	    result != 0) {1860		ath10k_err(ar, "otp calibration failed: %d", result);1861		return -EINVAL;1862	}1863 1864	return 0;1865}1866 1867static int ath10k_download_cal_file(struct ath10k *ar,1868				    const struct firmware *file)1869{1870	int ret;1871 1872	if (!file)1873		return -ENOENT;1874 1875	if (IS_ERR(file))1876		return PTR_ERR(file);1877 1878	ret = ath10k_download_board_data(ar, file->data, file->size);1879	if (ret) {1880		ath10k_err(ar, "failed to download cal_file data: %d\n", ret);1881		return ret;1882	}1883 1884	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");1885 1886	return 0;1887}1888 1889static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)1890{1891	struct device_node *node;1892	int data_len;1893	void *data;1894	int ret;1895 1896	node = ar->dev->of_node;1897	if (!node)1898		/* Device Tree is optional, don't print any warnings if1899		 * there's no node for ath10k.1900		 */1901		return -ENOENT;1902 1903	if (!of_get_property(node, dt_name, &data_len)) {1904		/* The calibration data node is optional */1905		return -ENOENT;1906	}1907 1908	if (data_len != ar->hw_params.cal_data_len) {1909		ath10k_warn(ar, "invalid calibration data length in DT: %d\n",1910			    data_len);1911		ret = -EMSGSIZE;1912		goto out;1913	}1914 1915	data = kmalloc(data_len, GFP_KERNEL);1916	if (!data) {1917		ret = -ENOMEM;1918		goto out;1919	}1920 1921	ret = of_property_read_u8_array(node, dt_name, data, data_len);1922	if (ret) {1923		ath10k_warn(ar, "failed to read calibration data from DT: %d\n",1924			    ret);1925		goto out_free;1926	}1927 1928	ret = ath10k_download_board_data(ar, data, data_len);1929	if (ret) {1930		ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",1931			    ret);1932		goto out_free;1933	}1934 1935	ret = 0;1936 1937out_free:1938	kfree(data);1939 1940out:1941	return ret;1942}1943 1944static int ath10k_download_cal_eeprom(struct ath10k *ar)1945{1946	size_t data_len;1947	void *data = NULL;1948	int ret;1949 1950	ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);1951	if (ret) {1952		if (ret != -EOPNOTSUPP)1953			ath10k_warn(ar, "failed to read calibration data from EEPROM: %d\n",1954				    ret);1955		goto out_free;1956	}1957 1958	ret = ath10k_download_board_data(ar, data, data_len);1959	if (ret) {1960		ath10k_warn(ar, "failed to download calibration data from EEPROM: %d\n",1961			    ret);1962		goto out_free;1963	}1964 1965	ret = 0;1966 1967out_free:1968	kfree(data);1969 1970	return ret;1971}1972 1973static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)1974{1975	struct nvmem_cell *cell;1976	void *buf;1977	size_t len;1978	int ret;1979 1980	cell = devm_nvmem_cell_get(ar->dev, cell_name);1981	if (IS_ERR(cell)) {1982		ret = PTR_ERR(cell);1983		return ret;1984	}1985 1986	buf = nvmem_cell_read(cell, &len);1987	if (IS_ERR(buf))1988		return PTR_ERR(buf);1989 1990	if (ar->hw_params.cal_data_len != len) {1991		kfree(buf);1992		ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",1993			    cell_name, len, ar->hw_params.cal_data_len);1994		return -EMSGSIZE;1995	}1996 1997	ret = ath10k_download_board_data(ar, buf, len);1998	kfree(buf);1999	if (ret)2000		ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",2001			    cell_name, ret);2002 2003	return ret;2004}2005 2006int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,2007				     struct ath10k_fw_file *fw_file)2008{2009	size_t magic_len, len, ie_len;2010	int ie_id, i, index, bit, ret;2011	struct ath10k_fw_ie *hdr;2012	const u8 *data;2013	__le32 *timestamp, *version;2014 2015	/* first fetch the firmware file (firmware-*.bin) */2016	fw_file->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,2017						 name);2018	if (IS_ERR(fw_file->firmware))2019		return PTR_ERR(fw_file->firmware);2020 2021	data = fw_file->firmware->data;2022	len = fw_file->firmware->size;2023 2024	/* magic also includes the null byte, check that as well */2025	magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;2026 2027	if (len < magic_len) {2028		ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",2029			   ar->hw_params.fw.dir, name, len);2030		ret = -EINVAL;2031		goto err;2032	}2033 2034	if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {2035		ath10k_err(ar, "invalid firmware magic\n");2036		ret = -EINVAL;2037		goto err;2038	}2039 2040	/* jump over the padding */2041	magic_len = ALIGN(magic_len, 4);2042 2043	len -= magic_len;2044	data += magic_len;2045 2046	/* loop elements */2047	while (len > sizeof(struct ath10k_fw_ie)) {2048		hdr = (struct ath10k_fw_ie *)data;2049 2050		ie_id = le32_to_cpu(hdr->id);2051		ie_len = le32_to_cpu(hdr->len);2052 2053		len -= sizeof(*hdr);2054		data += sizeof(*hdr);2055 2056		if (len < ie_len) {2057			ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",2058				   ie_id, len, ie_len);2059			ret = -EINVAL;2060			goto err;2061		}2062 2063		switch (ie_id) {2064		case ATH10K_FW_IE_FW_VERSION:2065			if (ie_len > sizeof(fw_file->fw_version) - 1)2066				break;2067 2068			memcpy(fw_file->fw_version, data, ie_len);2069			fw_file->fw_version[ie_len] = '\0';2070 2071			ath10k_dbg(ar, ATH10K_DBG_BOOT,2072				   "found fw version %s\n",2073				    fw_file->fw_version);2074			break;2075		case ATH10K_FW_IE_TIMESTAMP:2076			if (ie_len != sizeof(u32))2077				break;2078 2079			timestamp = (__le32 *)data;2080 2081			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",2082				   le32_to_cpup(timestamp));2083			break;2084		case ATH10K_FW_IE_FEATURES:2085			ath10k_dbg(ar, ATH10K_DBG_BOOT,2086				   "found firmware features ie (%zd B)\n",2087				   ie_len);2088 2089			for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {2090				index = i / 8;2091				bit = i % 8;2092 2093				if (index == ie_len)2094					break;2095 2096				if (data[index] & (1 << bit)) {2097					ath10k_dbg(ar, ATH10K_DBG_BOOT,2098						   "Enabling feature bit: %i\n",2099						   i);2100					__set_bit(i, fw_file->fw_features);2101				}2102			}2103 2104			ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",2105					fw_file->fw_features,2106					sizeof(fw_file->fw_features));2107			break;2108		case ATH10K_FW_IE_FW_IMAGE:2109			ath10k_dbg(ar, ATH10K_DBG_BOOT,2110				   "found fw image ie (%zd B)\n",2111				   ie_len);2112 2113			fw_file->firmware_data = data;2114			fw_file->firmware_len = ie_len;2115 2116			break;2117		case ATH10K_FW_IE_OTP_IMAGE:2118			ath10k_dbg(ar, ATH10K_DBG_BOOT,2119				   "found otp image ie (%zd B)\n",2120				   ie_len);2121 2122			fw_file->otp_data = data;2123			fw_file->otp_len = ie_len;2124 2125			break;2126		case ATH10K_FW_IE_WMI_OP_VERSION:2127			if (ie_len != sizeof(u32))2128				break;2129 2130			version = (__le32 *)data;2131 2132			fw_file->wmi_op_version = le32_to_cpup(version);2133 2134			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",2135				   fw_file->wmi_op_version);2136			break;2137		case ATH10K_FW_IE_HTT_OP_VERSION:2138			if (ie_len != sizeof(u32))2139				break;2140 2141			version = (__le32 *)data;2142 2143			fw_file->htt_op_version = le32_to_cpup(version);2144 2145			ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",2146				   fw_file->htt_op_version);2147			break;2148		case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:2149			ath10k_dbg(ar, ATH10K_DBG_BOOT,2150				   "found fw code swap image ie (%zd B)\n",2151				   ie_len);2152			fw_file->codeswap_data = data;2153			fw_file->codeswap_len = ie_len;2154			break;2155		default:2156			ath10k_warn(ar, "Unknown FW IE: %u\n",2157				    le32_to_cpu(hdr->id));2158			break;2159		}2160 2161		/* jump over the padding */2162		ie_len = ALIGN(ie_len, 4);2163 2164		len -= ie_len;2165		data += ie_len;2166	}2167 2168	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, fw_file->fw_features) &&2169	    (!fw_file->firmware_data || !fw_file->firmware_len)) {2170		ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",2171			    ar->hw_params.fw.dir, name);2172		ret = -ENOMEDIUM;2173		goto err;2174	}2175 2176	return 0;2177 2178err:2179	ath10k_core_free_firmware_files(ar);2180	return ret;2181}2182 2183static void ath10k_core_get_fw_name(struct ath10k *ar, char *fw_name,2184				    size_t fw_name_len, int fw_api)2185{2186	switch (ar->hif.bus) {2187	case ATH10K_BUS_SDIO:2188	case ATH10K_BUS_USB:2189		scnprintf(fw_name, fw_name_len, "%s-%s-%d.bin",2190			  ATH10K_FW_FILE_BASE, ath10k_bus_str(ar->hif.bus),2191			  fw_api);2192		break;2193	case ATH10K_BUS_PCI:2194	case ATH10K_BUS_AHB:2195	case ATH10K_BUS_SNOC:2196		scnprintf(fw_name, fw_name_len, "%s-%d.bin",2197			  ATH10K_FW_FILE_BASE, fw_api);2198		break;2199	}2200}2201 2202static int ath10k_core_fetch_firmware_files(struct ath10k *ar)2203{2204	int ret, i;2205	char fw_name[100];2206 2207	/* calibration file is optional, don't check for any errors */2208	ath10k_fetch_cal_file(ar);2209 2210	for (i = ATH10K_FW_API_MAX; i >= ATH10K_FW_API_MIN; i--) {2211		ar->fw_api = i;2212		ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n",2213			   ar->fw_api);2214 2215		ath10k_core_get_fw_name(ar, fw_name, sizeof(fw_name), ar->fw_api);2216		ret = ath10k_core_fetch_firmware_api_n(ar, fw_name,2217						       &ar->normal_mode_fw.fw_file);2218		if (!ret)2219			goto success;2220	}2221 2222	/* we end up here if we couldn't fetch any firmware */2223 2224	ath10k_err(ar, "Failed to find firmware-N.bin (N between %d and %d) from %s: %d",2225		   ATH10K_FW_API_MIN, ATH10K_FW_API_MAX, ar->hw_params.fw.dir,2226		   ret);2227 2228	return ret;2229 2230success:2231	ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);2232 2233	return 0;2234}2235 2236static int ath10k_core_pre_cal_download(struct ath10k *ar)2237{2238	int ret;2239 2240	ret = ath10k_download_cal_nvmem(ar, "pre-calibration");2241	if (ret == 0) {2242		ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;2243		goto success;2244	} else if (ret == -EPROBE_DEFER) {2245		return ret;2246	}2247 2248	ath10k_dbg(ar, ATH10K_DBG_BOOT,2249		   "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",2250		   ret);2251 2252	ret = ath10k_download_cal_file(ar, ar->pre_cal_file);2253	if (ret == 0) {2254		ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;2255		goto success;2256	}2257 2258	ath10k_dbg(ar, ATH10K_DBG_BOOT,2259		   "boot did not find a pre calibration file, try DT next: %d\n",2260		   ret);2261 2262	ret = ath10k_download_cal_dt(ar, "qcom,ath10k-pre-calibration-data");2263	if (ret) {2264		ath10k_dbg(ar, ATH10K_DBG_BOOT,2265			   "unable to load pre cal data from DT: %d\n", ret);2266		return ret;2267	}2268	ar->cal_mode = ATH10K_PRE_CAL_MODE_DT;2269 2270success:2271	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",2272		   ath10k_cal_mode_str(ar->cal_mode));2273 2274	return 0;2275}2276 2277static int ath10k_core_pre_cal_config(struct ath10k *ar)2278{2279	int ret;2280 2281	ret = ath10k_core_pre_cal_download(ar);2282	if (ret) {2283		ath10k_dbg(ar, ATH10K_DBG_BOOT,2284			   "failed to load pre cal data: %d\n", ret);2285		return ret;2286	}2287 2288	ret = ath10k_core_get_board_id_from_otp(ar);2289	if (ret) {2290		ath10k_err(ar, "failed to get board id: %d\n", ret);2291		return ret;2292	}2293 2294	ret = ath10k_download_and_run_otp(ar);2295	if (ret) {2296		ath10k_err(ar, "failed to run otp: %d\n", ret);2297		return ret;2298	}2299 2300	ath10k_dbg(ar, ATH10K_DBG_BOOT,2301		   "pre cal configuration done successfully\n");2302 2303	return 0;2304}2305 2306static int ath10k_download_cal_data(struct ath10k *ar)2307{2308	int ret;2309 2310	ret = ath10k_core_pre_cal_config(ar);2311	if (ret == 0)2312		return 0;2313 2314	ath10k_dbg(ar, ATH10K_DBG_BOOT,2315		   "pre cal download procedure failed, try cal file: %d\n",2316		   ret);2317 2318	ret = ath10k_download_cal_nvmem(ar, "calibration");2319	if (ret == 0) {2320		ar->cal_mode = ATH10K_CAL_MODE_NVMEM;2321		goto done;2322	} else if (ret == -EPROBE_DEFER) {2323		return ret;2324	}2325 2326	ath10k_dbg(ar, ATH10K_DBG_BOOT,2327		   "boot did not find a calibration nvmem-cell, try file next: %d\n",2328		   ret);2329 2330	ret = ath10k_download_cal_file(ar, ar->cal_file);2331	if (ret == 0) {2332		ar->cal_mode = ATH10K_CAL_MODE_FILE;2333		goto done;2334	}2335 2336	ath10k_dbg(ar, ATH10K_DBG_BOOT,2337		   "boot did not find a calibration file, try DT next: %d\n",2338		   ret);2339 2340	ret = ath10k_download_cal_dt(ar, "qcom,ath10k-calibration-data");2341	if (ret == 0) {2342		ar->cal_mode = ATH10K_CAL_MODE_DT;2343		goto done;2344	}2345 2346	ath10k_dbg(ar, ATH10K_DBG_BOOT,2347		   "boot did not find DT entry, try target EEPROM next: %d\n",2348		   ret);2349 2350	ret = ath10k_download_cal_eeprom(ar);2351	if (ret == 0) {2352		ar->cal_mode = ATH10K_CAL_MODE_EEPROM;2353		goto done;2354	}2355 2356	ath10k_dbg(ar, ATH10K_DBG_BOOT,2357		   "boot did not find target EEPROM entry, try OTP next: %d\n",2358		   ret);2359 2360	ret = ath10k_download_and_run_otp(ar);2361	if (ret) {2362		ath10k_err(ar, "failed to run otp: %d\n", ret);2363		return ret;2364	}2365 2366	ar->cal_mode = ATH10K_CAL_MODE_OTP;2367 2368done:2369	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",2370		   ath10k_cal_mode_str(ar->cal_mode));2371	return 0;2372}2373 2374static void ath10k_core_fetch_btcoex_dt(struct ath10k *ar)2375{2376	struct device_node *node;2377	u8 coex_support = 0;2378	int ret;2379 2380	node = ar->dev->of_node;2381	if (!node)2382		goto out;2383 2384	ret = of_property_read_u8(node, "qcom,coexist-support", &coex_support);2385	if (ret) {2386		ar->coex_support = true;2387		goto out;2388	}2389 2390	if (coex_support) {2391		ar->coex_support = true;2392	} else {2393		ar->coex_support = false;2394		ar->coex_gpio_pin = -1;2395		goto out;2396	}2397 2398	ret = of_property_read_u32(node, "qcom,coexist-gpio-pin",2399				   &ar->coex_gpio_pin);2400	if (ret)2401		ar->coex_gpio_pin = -1;2402 2403out:2404	ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot coex_support %d coex_gpio_pin %d\n",2405		   ar->coex_support, ar->coex_gpio_pin);2406}2407 2408static int ath10k_init_uart(struct ath10k *ar)2409{2410	int ret;2411 2412	/*2413	 * Explicitly setting UART prints to zero as target turns it on2414	 * based on scratch registers.2415	 */2416	ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);2417	if (ret) {2418		ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);2419		return ret;2420	}2421 2422	if (!uart_print) {2423		if (ar->hw_params.uart_pin_workaround) {2424			ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin,2425						 ar->hw_params.uart_pin);2426			if (ret) {2427				ath10k_warn(ar, "failed to set UART TX pin: %d",2428					    ret);2429				return ret;2430			}2431		}2432 2433		return 0;2434	}2435 2436	ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);2437	if (ret) {2438		ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);2439		return ret;2440	}2441 2442	ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);2443	if (ret) {2444		ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);2445		return ret;2446	}2447 2448	/* Set the UART baud rate to 19200. */2449	ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);2450	if (ret) {2451		ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);2452		return ret;2453	}2454 2455	ath10k_info(ar, "UART prints enabled\n");2456	return 0;2457}2458 2459static int ath10k_init_hw_params(struct ath10k *ar)2460{2461	const struct ath10k_hw_params *hw_params;2462	int i;2463 2464	for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {2465		hw_params = &ath10k_hw_params_list[i];2466 2467		if (hw_params->bus == ar->hif.bus &&2468		    hw_params->id == ar->target_version &&2469		    hw_params->dev_id == ar->dev_id)2470			break;2471	}2472 2473	if (i == ARRAY_SIZE(ath10k_hw_params_list)) {2474		ath10k_err(ar, "Unsupported hardware version: 0x%x\n",2475			   ar->target_version);2476		return -EINVAL;2477	}2478 2479	ar->hw_params = *hw_params;2480 2481	ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",2482		   ar->hw_params.name, ar->target_version);2483 2484	return 0;2485}2486 2487void ath10k_core_start_recovery(struct ath10k *ar)2488{2489	if (test_and_set_bit(ATH10K_FLAG_RESTARTING, &ar->dev_flags)) {2490		ath10k_warn(ar, "already restarting\n");2491		return;2492	}2493 2494	queue_work(ar->workqueue, &ar->restart_work);2495}2496EXPORT_SYMBOL(ath10k_core_start_recovery);2497 2498void ath10k_core_napi_enable(struct ath10k *ar)2499{2500	lockdep_assert_held(&ar->conf_mutex);2501 2502	if (test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags))2503		return;2504 2505	napi_enable(&ar->napi);2506	set_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags);2507}2508EXPORT_SYMBOL(ath10k_core_napi_enable);2509 2510void ath10k_core_napi_sync_disable(struct ath10k *ar)2511{2512	lockdep_assert_held(&ar->conf_mutex);2513 2514	if (!test_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags))2515		return;2516 2517	napi_synchronize(&ar->napi);2518	napi_disable(&ar->napi);2519	clear_bit(ATH10K_FLAG_NAPI_ENABLED, &ar->dev_flags);2520}2521EXPORT_SYMBOL(ath10k_core_napi_sync_disable);2522 2523static void ath10k_core_restart(struct work_struct *work)2524{2525	struct ath10k *ar = container_of(work, struct ath10k, restart_work);2526	int ret;2527 2528	set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);2529 2530	/* Place a barrier to make sure the compiler doesn't reorder2531	 * CRASH_FLUSH and calling other functions.2532	 */2533	barrier();2534 2535	ieee80211_stop_queues(ar->hw);2536	ath10k_drain_tx(ar);2537	complete(&ar->scan.started);2538	complete(&ar->scan.completed);2539	complete(&ar->scan.on_channel);2540	complete(&ar->offchan_tx_completed);2541	complete(&ar->install_key_done);2542	complete(&ar->vdev_setup_done);2543	complete(&ar->vdev_delete_done);2544	complete(&ar->thermal.wmi_sync);2545	complete(&ar->bss_survey_done);2546	wake_up(&ar->htt.empty_tx_wq);2547	wake_up(&ar->wmi.tx_credits_wq);2548	wake_up(&ar->peer_mapping_wq);2549 2550	/* TODO: We can have one instance of cancelling coverage_class_work by2551	 * moving it to ath10k_halt(), so that both stop() and restart() would2552	 * call that but it takes conf_mutex() and if we call cancel_work_sync()2553	 * with conf_mutex it will deadlock.2554	 */2555	cancel_work_sync(&ar->set_coverage_class_work);2556 2557	mutex_lock(&ar->conf_mutex);2558 2559	switch (ar->state) {2560	case ATH10K_STATE_ON:2561		ar->state = ATH10K_STATE_RESTARTING;2562		ath10k_halt(ar);2563		ath10k_scan_finish(ar);2564		ieee80211_restart_hw(ar->hw);2565		break;2566	case ATH10K_STATE_OFF:2567		/* this can happen if driver is being unloaded2568		 * or if the crash happens during FW probing2569		 */2570		ath10k_warn(ar, "cannot restart a device that hasn't been started\n");2571		break;2572	case ATH10K_STATE_RESTARTING:2573		/* hw restart might be requested from multiple places */2574		break;2575	case ATH10K_STATE_RESTARTED:2576		ar->state = ATH10K_STATE_WEDGED;2577		fallthrough;2578	case ATH10K_STATE_WEDGED:2579		ath10k_warn(ar, "device is wedged, will not restart\n");2580		break;2581	case ATH10K_STATE_UTF:2582		ath10k_warn(ar, "firmware restart in UTF mode not supported\n");2583		break;2584	}2585 2586	mutex_unlock(&ar->conf_mutex);2587 2588	ret = ath10k_coredump_submit(ar);2589	if (ret)2590		ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d",2591			    ret);2592 2593	complete(&ar->driver_recovery);2594}2595 2596static void ath10k_core_set_coverage_class_work(struct work_struct *work)2597{2598	struct ath10k *ar = container_of(work, struct ath10k,2599					 set_coverage_class_work);2600 2601	if (ar->hw_params.hw_ops->set_coverage_class)2602		ar->hw_params.hw_ops->set_coverage_class(ar, -1);2603}2604 2605static int ath10k_core_init_firmware_features(struct ath10k *ar)2606{2607	struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;2608	int max_num_peers;2609 2610	if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&2611	    !test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {2612		ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");2613		return -EINVAL;2614	}2615 2616	if (fw_file->wmi_op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {2617		ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",2618			   ATH10K_FW_WMI_OP_VERSION_MAX, fw_file->wmi_op_version);2619		return -EINVAL;2620	}2621 2622	ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;2623	switch (ath10k_cryptmode_param) {2624	case ATH10K_CRYPT_MODE_HW:2625		clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);2626		clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);2627		break;2628	case ATH10K_CRYPT_MODE_SW:2629		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,2630			      fw_file->fw_features)) {2631			ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");2632			return -EINVAL;2633		}2634 2635		set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);2636		set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);2637		break;2638	default:2639		ath10k_info(ar, "invalid cryptmode: %d\n",2640			    ath10k_cryptmode_param);2641		return -EINVAL;2642	}2643 2644	ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;2645	ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;2646 2647	if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {2648		if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,2649			      fw_file->fw_features)) {2650			ath10k_err(ar, "rawmode = 1 requires support from firmware");2651			return -EINVAL;2652		}2653		set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);2654	}2655 2656	if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {2657		ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;2658 2659		/* Workaround:2660		 *2661		 * Firmware A-MSDU aggregation breaks with RAW Tx encap mode2662		 * and causes enormous performance issues (malformed frames,2663		 * etc).2664		 *2665		 * Disabling A-MSDU makes RAW mode stable with heavy traffic2666		 * albeit a bit slower compared to regular operation.2667		 */2668		ar->htt.max_num_amsdu = 1;2669	}2670 2671	/* Backwards compatibility for firmwares without2672	 * ATH10K_FW_IE_WMI_OP_VERSION.2673	 */2674	if (fw_file->wmi_op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {2675		if (test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {2676			if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,2677				     fw_file->fw_features))2678				fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_2;2679			else2680				fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_1;2681		} else {2682			fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;2683		}2684	}2685 2686	switch (fw_file->wmi_op_version) {2687	case ATH10K_FW_WMI_OP_VERSION_MAIN:2688		max_num_peers = TARGET_NUM_PEERS;2689		ar->max_num_stations = TARGET_NUM_STATIONS;2690		ar->max_num_vdevs = TARGET_NUM_VDEVS;2691		ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;2692		ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |2693			WMI_STAT_PEER;2694		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;2695		break;2696	case ATH10K_FW_WMI_OP_VERSION_10_1:2697	case ATH10K_FW_WMI_OP_VERSION_10_2:2698	case ATH10K_FW_WMI_OP_VERSION_10_2_4:2699		if (ath10k_peer_stats_enabled(ar)) {2700			max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;2701			ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;2702		} else {2703			max_num_peers = TARGET_10X_NUM_PEERS;2704			ar->max_num_stations = TARGET_10X_NUM_STATIONS;2705		}2706		ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;2707		ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;2708		ar->fw_stats_req_mask = WMI_STAT_PEER;2709		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;2710		break;2711	case ATH10K_FW_WMI_OP_VERSION_TLV:2712		max_num_peers = TARGET_TLV_NUM_PEERS;2713		ar->max_num_stations = TARGET_TLV_NUM_STATIONS;2714		ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;2715		ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;2716		if (ar->hif.bus == ATH10K_BUS_SDIO)2717			ar->htt.max_num_pending_tx =2718				TARGET_TLV_NUM_MSDU_DESC_HL;2719		else2720			ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;2721		ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;2722		ar->fw_stats_req_mask = WMI_TLV_STAT_PDEV | WMI_TLV_STAT_VDEV |2723			WMI_TLV_STAT_PEER | WMI_TLV_STAT_PEER_EXTD;2724		ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;2725		ar->wmi.mgmt_max_num_pending_tx = TARGET_TLV_MGMT_NUM_MSDU_DESC;2726		break;2727	case ATH10K_FW_WMI_OP_VERSION_10_4:2728		max_num_peers = TARGET_10_4_NUM_PEERS;2729		ar->max_num_stations = TARGET_10_4_NUM_STATIONS;2730		ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;2731		ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;2732		ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;2733		ar->fw_stats_req_mask = WMI_10_4_STAT_PEER |2734					WMI_10_4_STAT_PEER_EXTD |2735					WMI_10_4_STAT_VDEV_EXTD;2736		ar->max_spatial_stream = ar->hw_params.max_spatial_stream;2737		ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS;2738 2739		if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,2740			     fw_file->fw_features))2741			ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC_PFC;2742		else2743			ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC;2744		break;2745	case ATH10K_FW_WMI_OP_VERSION_UNSET:2746	case ATH10K_FW_WMI_OP_VERSION_MAX:2747	default:2748		WARN_ON(1);2749		return -EINVAL;2750	}2751 2752	if (ar->hw_params.num_peers)2753		ar->max_num_peers = ar->hw_params.num_peers;2754	else2755		ar->max_num_peers = max_num_peers;2756 2757	/* Backwards compatibility for firmwares without2758	 * ATH10K_FW_IE_HTT_OP_VERSION.2759	 */2760	if (fw_file->htt_op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {2761		switch (fw_file->wmi_op_version) {2762		case ATH10K_FW_WMI_OP_VERSION_MAIN:2763			fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;2764			break;2765		case ATH10K_FW_WMI_OP_VERSION_10_1:2766		case ATH10K_FW_WMI_OP_VERSION_10_2:2767		case ATH10K_FW_WMI_OP_VERSION_10_2_4:2768			fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_10_1;2769			break;2770		case ATH10K_FW_WMI_OP_VERSION_TLV:2771			fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;2772			break;2773		case ATH10K_FW_WMI_OP_VERSION_10_4:2774		case ATH10K_FW_WMI_OP_VERSION_UNSET:2775		case ATH10K_FW_WMI_OP_VERSION_MAX:2776			ath10k_err(ar, "htt op version not found from fw meta data");2777			return -EINVAL;2778		}2779	}2780 2781	return 0;2782}2783 2784static int ath10k_core_reset_rx_filter(struct ath10k *ar)2785{2786	int ret;2787	int vdev_id;2788	int vdev_type;2789	int vdev_subtype;2790	const u8 *vdev_addr;2791 2792	vdev_id = 0;2793	vdev_type = WMI_VDEV_TYPE_STA;2794	vdev_subtype = ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);2795	vdev_addr = ar->mac_addr;2796 2797	ret = ath10k_wmi_vdev_create(ar, vdev_id, vdev_type, vdev_subtype,2798				     vdev_addr);2799	if (ret) {2800		ath10k_err(ar, "failed to create dummy vdev: %d\n", ret);2801		return ret;2802	}2803 2804	ret = ath10k_wmi_vdev_delete(ar, vdev_id);2805	if (ret) {2806		ath10k_err(ar, "failed to delete dummy vdev: %d\n", ret);2807		return ret;2808	}2809 2810	/* WMI and HTT may use separate HIF pipes and are not guaranteed to be2811	 * serialized properly implicitly.2812	 *2813	 * Moreover (most) WMI commands have no explicit acknowledges. It is2814	 * possible to infer it implicitly by poking firmware with echo2815	 * command - getting a reply means all preceding comments have been2816	 * (mostly) processed.2817	 *2818	 * In case of vdev create/delete this is sufficient.2819	 *2820	 * Without this it's possible to end up with a race when HTT Rx ring is2821	 * started before vdev create/delete hack is complete allowing a short2822	 * window of opportunity to receive (and Tx ACK) a bunch of frames.2823	 */2824	ret = ath10k_wmi_barrier(ar);2825	if (ret) {2826		ath10k_err(ar, "failed to ping firmware: %d\n", ret);2827		return ret;2828	}2829 2830	return 0;2831}2832 2833static int ath10k_core_compat_services(struct ath10k *ar)2834{2835	struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;2836 2837	/* all 10.x firmware versions support thermal throttling but don't2838	 * advertise the support via service flags so we have to hardcode2839	 * it here2840	 */2841	switch (fw_file->wmi_op_version) {2842	case ATH10K_FW_WMI_OP_VERSION_10_1:2843	case ATH10K_FW_WMI_OP_VERSION_10_2:2844	case ATH10K_FW_WMI_OP_VERSION_10_2_4:2845	case ATH10K_FW_WMI_OP_VERSION_10_4:2846		set_bit(WMI_SERVICE_THERM_THROT, ar->wmi.svc_map);2847		break;2848	default:2849		break;2850	}2851 2852	return 0;2853}2854 2855#define TGT_IRAM_READ_PER_ITR (8 * 1024)2856 2857static int ath10k_core_copy_target_iram(struct ath10k *ar)2858{2859	const struct ath10k_hw_mem_layout *hw_mem;2860	const struct ath10k_mem_region *tmp, *mem_region = NULL;2861	dma_addr_t paddr;2862	void *vaddr = NULL;2863	u8 num_read_itr;2864	int i, ret;2865	u32 len, remaining_len;2866 2867	/* copy target iram feature must work also when2868	 * ATH10K_FW_CRASH_DUMP_RAM_DATA is disabled, so2869	 * _ath10k_coredump_get_mem_layout() to accomplist that2870	 */2871	hw_mem = _ath10k_coredump_get_mem_layout(ar);2872	if (!hw_mem)2873		/* if CONFIG_DEV_COREDUMP is disabled we get NULL, then2874		 * just silently disable the feature by doing nothing2875		 */2876		return 0;2877 2878	for (i = 0; i < hw_mem->region_table.size; i++) {2879		tmp = &hw_mem->region_table.regions[i];2880		if (tmp->type == ATH10K_MEM_REGION_TYPE_REG) {2881			mem_region = tmp;2882			break;2883		}2884	}2885 2886	if (!mem_region)2887		return -ENOMEM;2888 2889	for (i = 0; i < ar->wmi.num_mem_chunks; i++) {2890		if (ar->wmi.mem_chunks[i].req_id ==2891		    WMI_IRAM_RECOVERY_HOST_MEM_REQ_ID) {2892			vaddr = ar->wmi.mem_chunks[i].vaddr;2893			len = ar->wmi.mem_chunks[i].len;2894			break;2895		}2896	}2897 2898	if (!vaddr || !len) {2899		ath10k_warn(ar, "No allocated memory for IRAM back up");2900		return -ENOMEM;2901	}2902 2903	len = (len < mem_region->len) ? len : mem_region->len;2904	paddr = mem_region->start;2905	num_read_itr = len / TGT_IRAM_READ_PER_ITR;2906	remaining_len = len % TGT_IRAM_READ_PER_ITR;2907	for (i = 0; i < num_read_itr; i++) {2908		ret = ath10k_hif_diag_read(ar, paddr, vaddr,2909					   TGT_IRAM_READ_PER_ITR);2910		if (ret) {2911			ath10k_warn(ar, "failed to copy firmware IRAM contents: %d",2912				    ret);2913			return ret;2914		}2915 2916		paddr += TGT_IRAM_READ_PER_ITR;2917		vaddr += TGT_IRAM_READ_PER_ITR;2918	}2919 2920	if (remaining_len) {2921		ret = ath10k_hif_diag_read(ar, paddr, vaddr, remaining_len);2922		if (ret) {2923			ath10k_warn(ar, "failed to copy firmware IRAM contents: %d",2924				    ret);2925			return ret;2926		}2927	}2928 2929	ath10k_dbg(ar, ATH10K_DBG_BOOT, "target IRAM back up completed\n");2930 2931	return 0;2932}2933 2934int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,2935		      const struct ath10k_fw_components *fw)2936{2937	int status;2938	u32 val;2939 2940	lockdep_assert_held(&ar->conf_mutex);2941 2942	clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);2943 2944	ar->running_fw = fw;2945 2946	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,2947		      ar->running_fw->fw_file.fw_features)) {2948		ath10k_bmi_start(ar);2949 2950		/* Enable hardware clock to speed up firmware download */2951		if (ar->hw_params.hw_ops->enable_pll_clk) {2952			status = ar->hw_params.hw_ops->enable_pll_clk(ar);2953			ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot enable pll ret %d\n",2954				   status);2955		}2956 2957		if (ath10k_init_configure_target(ar)) {2958			status = -EINVAL;2959			goto err;2960		}2961 2962		status = ath10k_download_cal_data(ar);2963		if (status)2964			goto err;2965 2966		/* Some of qca988x solutions are having global reset issue2967		 * during target initialization. Bypassing PLL setting before2968		 * downloading firmware and letting the SoC run on REF_CLK is2969		 * fixing the problem. Corresponding firmware change is also2970		 * needed to set the clock source once the target is2971		 * initialized.2972		 */2973		if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,2974			     ar->running_fw->fw_file.fw_features)) {2975			status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);2976			if (status) {2977				ath10k_err(ar, "could not write to skip_clock_init: %d\n",2978					   status);2979				goto err;2980			}2981		}2982 2983		status = ath10k_download_fw(ar);2984		if (status)2985			goto err;2986 2987		status = ath10k_init_uart(ar);2988		if (status)2989			goto err;2990 2991		if (ar->hif.bus == ATH10K_BUS_SDIO) {2992			status = ath10k_init_sdio(ar, mode);2993			if (status) {2994				ath10k_err(ar, "failed to init SDIO: %d\n", status);2995				goto err;2996			}2997		}2998	}2999 3000	ar->htc.htc_ops.target_send_suspend_complete =3001		ath10k_send_suspend_complete;3002 3003	status = ath10k_htc_init(ar);3004	if (status) {3005		ath10k_err(ar, "could not init HTC (%d)\n", status);3006		goto err;3007	}3008 3009	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,3010		      ar->running_fw->fw_file.fw_features)) {3011		status = ath10k_bmi_done(ar);3012		if (status)3013			goto err;3014	}3015 3016	status = ath10k_wmi_attach(ar);3017	if (status) {3018		ath10k_err(ar, "WMI attach failed: %d\n", status);3019		goto err;3020	}3021 3022	status = ath10k_htt_init(ar);3023	if (status) {3024		ath10k_err(ar, "failed to init htt: %d\n", status);3025		goto err_wmi_detach;3026	}3027 3028	status = ath10k_htt_tx_start(&ar->htt);3029	if (status) {3030		ath10k_err(ar, "failed to alloc htt tx: %d\n", status);3031		goto err_wmi_detach;3032	}3033 3034	/* If firmware indicates Full Rx Reorder support it must be used in a3035	 * slightly different manner. Let HTT code know.3036	 */3037	ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER,3038						ar->wmi.svc_map));3039 3040	status = ath10k_htt_rx_alloc(&ar->htt);3041	if (status) {3042		ath10k_err(ar, "failed to alloc htt rx: %d\n", status);3043		goto err_htt_tx_detach;3044	}3045 3046	status = ath10k_hif_start(ar);3047	if (status) {3048		ath10k_err(ar, "could not start HIF: %d\n", status);3049		goto err_htt_rx_detach;3050	}3051 3052	status = ath10k_htc_wait_target(&ar->htc);3053	if (status) {3054		ath10k_err(ar, "failed to connect to HTC: %d\n", status);3055		goto err_hif_stop;3056	}3057 3058	status = ath10k_hif_start_post(ar);3059	if (status) {3060		ath10k_err(ar, "failed to swap mailbox: %d\n", status);3061		goto err_hif_stop;3062	}3063 3064	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {3065		status = ath10k_htt_connect(&ar->htt);3066		if (status) {3067			ath10k_err(ar, "failed to connect htt (%d)\n", status);3068			goto err_hif_stop;3069		}3070	}3071 3072	status = ath10k_wmi_connect(ar);3073	if (status) {3074		ath10k_err(ar, "could not connect wmi: %d\n", status);3075		goto err_hif_stop;3076	}3077 3078	status = ath10k_htc_start(&ar->htc);3079	if (status) {3080		ath10k_err(ar, "failed to start htc: %d\n", status);3081		goto err_hif_stop;3082	}3083 3084	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {3085		status = ath10k_wmi_wait_for_service_ready(ar);3086		if (status) {3087			ath10k_warn(ar, "wmi service ready event not received");3088			goto err_hif_stop;3089		}3090	}3091 3092	ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",3093		   ar->hw->wiphy->fw_version);3094 3095	if (test_bit(ATH10K_FW_FEATURE_IRAM_RECOVERY,3096		     ar->running_fw->fw_file.fw_features)) {3097		status = ath10k_core_copy_target_iram(ar);3098		if (status) {3099			ath10k_warn(ar, "failed to copy target iram contents: %d",3100				    status);3101			goto err_hif_stop;3102		}3103	}3104 3105	if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&3106	    mode == ATH10K_FIRMWARE_MODE_NORMAL) {3107		val = 0;3108		if (ath10k_peer_stats_enabled(ar))3109			val = WMI_10_4_PEER_STATS;3110 3111		/* Enable vdev stats by default */3112		val |= WMI_10_4_VDEV_STATS;3113 3114		if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))3115			val |= WMI_10_4_BSS_CHANNEL_INFO_64;3116 3117		ath10k_core_fetch_btcoex_dt(ar);3118 3119		/* 10.4 firmware supports BT-Coex without reloading firmware3120		 * via pdev param. To support Bluetooth coexistence pdev param,3121		 * WMI_COEX_GPIO_SUPPORT of extended resource config should be3122		 * enabled always.3123		 *3124		 * We can still enable BTCOEX if firmware has the support3125		 * even though btceox_support value is3126		 * ATH10K_DT_BTCOEX_NOT_FOUND3127		 */3128 3129		if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&3130		    test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,3131			     ar->running_fw->fw_file.fw_features) &&3132		    ar->coex_support)3133			val |= WMI_10_4_COEX_GPIO_SUPPORT;3134 3135		if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,3136			     ar->wmi.svc_map))3137			val |= WMI_10_4_TDLS_EXPLICIT_MODE_ONLY;3138 3139		if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,3140			     ar->wmi.svc_map))3141			val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;3142 3143		if (test_bit(WMI_SERVICE_TX_DATA_ACK_RSSI,3144			     ar->wmi.svc_map))3145			val |= WMI_10_4_TX_DATA_ACK_RSSI;3146 3147		if (test_bit(WMI_SERVICE_REPORT_AIRTIME, ar->wmi.svc_map))3148			val |= WMI_10_4_REPORT_AIRTIME;3149 3150		if (test_bit(WMI_SERVICE_EXT_PEER_TID_CONFIGS_SUPPORT,3151			     ar->wmi.svc_map))3152			val |= WMI_10_4_EXT_PEER_TID_CONFIGS_SUPPORT;3153 3154		status = ath10k_mac_ext_resource_config(ar, val);3155		if (status) {3156			ath10k_err(ar,3157				   "failed to send ext resource cfg command : %d\n",3158				   status);3159			goto err_hif_stop;3160		}3161	}3162 3163	status = ath10k_wmi_cmd_init(ar);3164	if (status) {3165		ath10k_err(ar, "could not send WMI init command (%d)\n",3166			   status);3167		goto err_hif_stop;3168	}3169 3170	status = ath10k_wmi_wait_for_unified_ready(ar);3171	if (status) {3172		ath10k_err(ar, "wmi unified ready event not received\n");3173		goto err_hif_stop;3174	}3175 3176	status = ath10k_core_compat_services(ar);3177	if (status) {3178		ath10k_err(ar, "compat services failed: %d\n", status);3179		goto err_hif_stop;3180	}3181 3182	status = ath10k_wmi_pdev_set_base_macaddr(ar, ar->mac_addr);3183	if (status && status != -EOPNOTSUPP) {3184		ath10k_err(ar,3185			   "failed to set base mac address: %d\n", status);3186		goto err_hif_stop;3187	}3188 3189	/* Some firmware revisions do not properly set up hardware rx filter3190	 * registers.3191	 *3192	 * A known example from QCA9880 and 10.2.4 is that MAC_PCU_ADDR1_MASK3193	 * is filled with 0s instead of 1s allowing HW to respond with ACKs to3194	 * any frames that matches MAC_PCU_RX_FILTER which is also3195	 * misconfigured to accept anything.3196	 *3197	 * The ADDR1 is programmed using internal firmware structure field and3198	 * can't be (easily/sanely) reached from the driver explicitly. It is3199	 * possible to implicitly make it correct by creating a dummy vdev and3200	 * then deleting it.3201	 */3202	if (ar->hw_params.hw_filter_reset_required &&3203	    mode == ATH10K_FIRMWARE_MODE_NORMAL) {3204		status = ath10k_core_reset_rx_filter(ar);3205		if (status) {3206			ath10k_err(ar,3207				   "failed to reset rx filter: %d\n", status);3208			goto err_hif_stop;3209		}3210	}3211 3212	status = ath10k_htt_rx_ring_refill(ar);3213	if (status) {3214		ath10k_err(ar, "failed to refill htt rx ring: %d\n", status);3215		goto err_hif_stop;3216	}3217 3218	if (ar->max_num_vdevs >= 64)3219		ar->free_vdev_map = 0xFFFFFFFFFFFFFFFFLL;3220	else3221		ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;3222 3223	INIT_LIST_HEAD(&ar->arvifs);3224 3225	/* we don't care about HTT in UTF mode */3226	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {3227		status = ath10k_htt_setup(&ar->htt);3228		if (status) {3229			ath10k_err(ar, "failed to setup htt: %d\n", status);3230			goto err_hif_stop;3231		}3232	}3233 3234	status = ath10k_debug_start(ar);3235	if (status)3236		goto err_hif_stop;3237 3238	status = ath10k_hif_set_target_log_mode(ar, fw_diag_log);3239	if (status && status != -EOPNOTSUPP) {3240		ath10k_warn(ar, "set target log mode failed: %d\n", status);3241		goto err_hif_stop;3242	}3243 3244	status = ath10k_leds_start(ar);3245	if (status)3246		goto err_hif_stop;3247 3248	return 0;3249 3250err_hif_stop:3251	ath10k_hif_stop(ar);3252err_htt_rx_detach:3253	ath10k_htt_rx_free(&ar->htt);3254err_htt_tx_detach:3255	ath10k_htt_tx_free(&ar->htt);3256err_wmi_detach:3257	ath10k_wmi_detach(ar);3258err:3259	return status;3260}3261EXPORT_SYMBOL(ath10k_core_start);3262 3263int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)3264{3265	int ret;3266	unsigned long time_left;3267 3268	reinit_completion(&ar->target_suspend);3269 3270	ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);3271	if (ret) {3272		ath10k_warn(ar, "could not suspend target (%d)\n", ret);3273		return ret;3274	}3275 3276	time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);3277 3278	if (!time_left) {3279		ath10k_warn(ar, "suspend timed out - target pause event never came\n");3280		return -ETIMEDOUT;3281	}3282 3283	return 0;3284}3285 3286void ath10k_core_stop(struct ath10k *ar)3287{3288	lockdep_assert_held(&ar->conf_mutex);3289	ath10k_debug_stop(ar);3290 3291	/* try to suspend target */3292	if (ar->state != ATH10K_STATE_RESTARTING &&3293	    ar->state != ATH10K_STATE_UTF)3294		ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);3295 3296	ath10k_hif_stop(ar);3297	ath10k_htt_tx_stop(&ar->htt);3298	ath10k_htt_rx_free(&ar->htt);3299	ath10k_wmi_detach(ar);3300 3301	ar->id.bmi_ids_valid = false;3302}3303EXPORT_SYMBOL(ath10k_core_stop);3304 3305/* mac80211 manages fw/hw initialization through start/stop hooks. However in3306 * order to know what hw capabilities should be advertised to mac80211 it is3307 * necessary to load the firmware (and tear it down immediately since start3308 * hook will try to init it again) before registering3309 */3310static int ath10k_core_probe_fw(struct ath10k *ar)3311{3312	struct bmi_target_info target_info;3313	int ret = 0;3314 3315	ret = ath10k_hif_power_up(ar, ATH10K_FIRMWARE_MODE_NORMAL);3316	if (ret) {3317		ath10k_err(ar, "could not power on hif bus (%d)\n", ret);3318		return ret;3319	}3320 3321	switch (ar->hif.bus) {3322	case ATH10K_BUS_SDIO:3323		memset(&target_info, 0, sizeof(target_info));3324		ret = ath10k_bmi_get_target_info_sdio(ar, &target_info);3325		if (ret) {3326			ath10k_err(ar, "could not get target info (%d)\n", ret);3327			goto err_power_down;3328		}3329		ar->target_version = target_info.version;3330		ar->hw->wiphy->hw_version = target_info.version;3331		break;3332	case ATH10K_BUS_PCI:3333	case ATH10K_BUS_AHB:3334	case ATH10K_BUS_USB:3335		memset(&target_info, 0, sizeof(target_info));3336		ret = ath10k_bmi_get_target_info(ar, &target_info);3337		if (ret) {3338			ath10k_err(ar, "could not get target info (%d)\n", ret);3339			goto err_power_down;3340		}3341		ar->target_version = target_info.version;3342		ar->hw->wiphy->hw_version = target_info.version;3343		break;3344	case ATH10K_BUS_SNOC:3345		memset(&target_info, 0, sizeof(target_info));3346		ret = ath10k_hif_get_target_info(ar, &target_info);3347		if (ret) {3348			ath10k_err(ar, "could not get target info (%d)\n", ret);3349			goto err_power_down;3350		}3351		ar->target_version = target_info.version;3352		ar->hw->wiphy->hw_version = target_info.version;3353		break;3354	default:3355		ath10k_err(ar, "incorrect hif bus type: %d\n", ar->hif.bus);3356	}3357 3358	ret = ath10k_init_hw_params(ar);3359	if (ret) {3360		ath10k_err(ar, "could not get hw params (%d)\n", ret);3361		goto err_power_down;3362	}3363 3364	ret = ath10k_core_fetch_firmware_files(ar);3365	if (ret) {3366		ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);3367		goto err_power_down;3368	}3369 3370	BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=3371		     sizeof(ar->normal_mode_fw.fw_file.fw_version));3372	memcpy(ar->hw->wiphy->fw_version, ar->normal_mode_fw.fw_file.fw_version,3373	       sizeof(ar->hw->wiphy->fw_version));3374 3375	ath10k_debug_print_hwfw_info(ar);3376 3377	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,3378		      ar->normal_mode_fw.fw_file.fw_features)) {3379		ret = ath10k_core_pre_cal_download(ar);3380		if (ret) {3381			/* pre calibration data download is not necessary3382			 * for all the chipsets. Ignore failures and continue.3383			 */3384			ath10k_dbg(ar, ATH10K_DBG_BOOT,3385				   "could not load pre cal data: %d\n", ret);3386		}3387 3388		ret = ath10k_core_get_board_id_from_otp(ar);3389		if (ret && ret != -EOPNOTSUPP) {3390			ath10k_err(ar, "failed to get board id from otp: %d\n",3391				   ret);3392			goto err_free_firmware_files;3393		}3394 3395		ret = ath10k_core_check_smbios(ar);3396		if (ret)3397			ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n");3398 3399		ret = ath10k_core_check_dt(ar);3400		if (ret)3401			ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");3402 3403		ret = ath10k_core_fetch_board_file(ar, ATH10K_BD_IE_BOARD);3404		if (ret) {3405			ath10k_err(ar, "failed to fetch board file: %d\n", ret);3406			goto err_free_firmware_files;3407		}3408 3409		ath10k_debug_print_board_info(ar);3410	}3411 3412	device_get_mac_address(ar->dev, ar->mac_addr);3413 3414	ret = ath10k_core_init_firmware_features(ar);3415	if (ret) {3416		ath10k_err(ar, "fatal problem with firmware features: %d\n",3417			   ret);3418		goto err_free_firmware_files;3419	}3420 3421	if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,3422		      ar->normal_mode_fw.fw_file.fw_features)) {3423		ret = ath10k_swap_code_seg_init(ar,3424						&ar->normal_mode_fw.fw_file);3425		if (ret) {3426			ath10k_err(ar, "failed to initialize code swap segment: %d\n",3427				   ret);3428			goto err_free_firmware_files;3429		}3430	}3431 3432	mutex_lock(&ar->conf_mutex);3433 3434	ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,3435				&ar->normal_mode_fw);3436	if (ret) {3437		ath10k_err(ar, "could not init core (%d)\n", ret);3438		goto err_unlock;3439	}3440 3441	ath10k_debug_print_boot_info(ar);3442	ath10k_core_stop(ar);3443 3444	mutex_unlock(&ar->conf_mutex);3445 3446	ath10k_hif_power_down(ar);3447	return 0;3448 3449err_unlock:3450	mutex_unlock(&ar->conf_mutex);3451 3452err_free_firmware_files:3453	ath10k_core_free_firmware_files(ar);3454 3455err_power_down:3456	ath10k_hif_power_down(ar);3457 3458	return ret;3459}3460 3461static void ath10k_core_register_work(struct work_struct *work)3462{3463	struct ath10k *ar = container_of(work, struct ath10k, register_work);3464	int status;3465 3466	/* peer stats are enabled by default */3467	set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);3468 3469	status = ath10k_core_probe_fw(ar);3470	if (status) {3471		ath10k_err(ar, "could not probe fw (%d)\n", status);3472		goto err;3473	}3474 3475	status = ath10k_mac_register(ar);3476	if (status) {3477		ath10k_err(ar, "could not register to mac80211 (%d)\n", status);3478		goto err_release_fw;3479	}3480 3481	status = ath10k_coredump_register(ar);3482	if (status) {3483		ath10k_err(ar, "unable to register coredump\n");3484		goto err_unregister_mac;3485	}3486 3487	status = ath10k_debug_register(ar);3488	if (status) {3489		ath10k_err(ar, "unable to initialize debugfs\n");3490		goto err_unregister_coredump;3491	}3492 3493	status = ath10k_spectral_create(ar);3494	if (status) {3495		ath10k_err(ar, "failed to initialize spectral\n");3496		goto err_debug_destroy;3497	}3498 3499	status = ath10k_thermal_register(ar);3500	if (status) {3501		ath10k_err(ar, "could not register thermal device: %d\n",3502			   status);3503		goto err_spectral_destroy;3504	}3505 3506	status = ath10k_leds_register(ar);3507	if (status) {3508		ath10k_err(ar, "could not register leds: %d\n",3509			   status);3510		goto err_thermal_unregister;3511	}3512 3513	set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);3514	return;3515 3516err_thermal_unregister:3517	ath10k_thermal_unregister(ar);3518err_spectral_destroy:3519	ath10k_spectral_destroy(ar);3520err_debug_destroy:3521	ath10k_debug_destroy(ar);3522err_unregister_coredump:3523	ath10k_coredump_unregister(ar);3524err_unregister_mac:3525	ath10k_mac_unregister(ar);3526err_release_fw:3527	ath10k_core_free_firmware_files(ar);3528err:3529	/* TODO: It's probably a good idea to release device from the driver3530	 * but calling device_release_driver() here will cause a deadlock.3531	 */3532	return;3533}3534 3535int ath10k_core_register(struct ath10k *ar,3536			 const struct ath10k_bus_params *bus_params)3537{3538	ar->bus_param = *bus_params;3539 3540	queue_work(ar->workqueue, &ar->register_work);3541 3542	return 0;3543}3544EXPORT_SYMBOL(ath10k_core_register);3545 3546void ath10k_core_unregister(struct ath10k *ar)3547{3548	cancel_work_sync(&ar->register_work);3549 3550	if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))3551		return;3552 3553	ath10k_leds_unregister(ar);3554 3555	ath10k_thermal_unregister(ar);3556	/* Stop spectral before unregistering from mac80211 to remove the3557	 * relayfs debugfs file cleanly. Otherwise the parent debugfs tree3558	 * would be already be free'd recursively, leading to a double free.3559	 */3560	ath10k_spectral_destroy(ar);3561 3562	/* We must unregister from mac80211 before we stop HTC and HIF.3563	 * Otherwise we will fail to submit commands to FW and mac80211 will be3564	 * unhappy about callback failures.3565	 */3566	ath10k_mac_unregister(ar);3567 3568	ath10k_testmode_destroy(ar);3569 3570	ath10k_core_free_firmware_files(ar);3571	ath10k_core_free_board_files(ar);3572 3573	ath10k_debug_unregister(ar);3574}3575EXPORT_SYMBOL(ath10k_core_unregister);3576 3577struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,3578				  enum ath10k_bus bus,3579				  enum ath10k_hw_rev hw_rev,3580				  const struct ath10k_hif_ops *hif_ops)3581{3582	struct ath10k *ar;3583	int ret;3584 3585	ar = ath10k_mac_create(priv_size);3586	if (!ar)3587		return NULL;3588 3589	ar->ath_common.priv = ar;3590	ar->ath_common.hw = ar->hw;3591	ar->dev = dev;3592	ar->hw_rev = hw_rev;3593	ar->hif.ops = hif_ops;3594	ar->hif.bus = bus;3595 3596	switch (hw_rev) {3597	case ATH10K_HW_QCA988X:3598	case ATH10K_HW_QCA9887:3599		ar->regs = &qca988x_regs;3600		ar->hw_ce_regs = &qcax_ce_regs;3601		ar->hw_values = &qca988x_values;3602		break;3603	case ATH10K_HW_QCA6174:3604	case ATH10K_HW_QCA9377:3605		ar->regs = &qca6174_regs;3606		ar->hw_ce_regs = &qcax_ce_regs;3607		ar->hw_values = &qca6174_values;3608		break;3609	case ATH10K_HW_QCA99X0:3610	case ATH10K_HW_QCA9984:3611		ar->regs = &qca99x0_regs;3612		ar->hw_ce_regs = &qcax_ce_regs;3613		ar->hw_values = &qca99x0_values;3614		break;3615	case ATH10K_HW_QCA9888:3616		ar->regs = &qca99x0_regs;3617		ar->hw_ce_regs = &qcax_ce_regs;3618		ar->hw_values = &qca9888_values;3619		break;3620	case ATH10K_HW_QCA4019:3621		ar->regs = &qca4019_regs;3622		ar->hw_ce_regs = &qcax_ce_regs;3623		ar->hw_values = &qca4019_values;3624		break;3625	case ATH10K_HW_WCN3990:3626		ar->regs = &wcn3990_regs;3627		ar->hw_ce_regs = &wcn3990_ce_regs;3628		ar->hw_values = &wcn3990_values;3629		break;3630	default:3631		ath10k_err(ar, "unsupported core hardware revision %d\n",3632			   hw_rev);3633		ret = -EOPNOTSUPP;3634		goto err_free_mac;3635	}3636 3637	init_completion(&ar->scan.started);3638	init_completion(&ar->scan.completed);3639	init_completion(&ar->scan.on_channel);3640	init_completion(&ar->target_suspend);3641	init_completion(&ar->driver_recovery);3642	init_completion(&ar->wow.wakeup_completed);3643 3644	init_completion(&ar->install_key_done);3645	init_completion(&ar->vdev_setup_done);3646	init_completion(&ar->vdev_delete_done);3647	init_completion(&ar->thermal.wmi_sync);3648	init_completion(&ar->bss_survey_done);3649	init_completion(&ar->peer_delete_done);3650	init_completion(&ar->peer_stats_info_complete);3651 3652	INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);3653 3654	ar->workqueue = create_singlethread_workqueue("ath10k_wq");3655	if (!ar->workqueue)3656		goto err_free_mac;3657 3658	ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");3659	if (!ar->workqueue_aux)3660		goto err_free_wq;3661 3662	ar->workqueue_tx_complete =3663		create_singlethread_workqueue("ath10k_tx_complete_wq");3664	if (!ar->workqueue_tx_complete)3665		goto err_free_aux_wq;3666 3667	mutex_init(&ar->conf_mutex);3668	mutex_init(&ar->dump_mutex);3669	spin_lock_init(&ar->data_lock);3670 3671	for (int ac = 0; ac < IEEE80211_NUM_ACS; ac++)3672		spin_lock_init(&ar->queue_lock[ac]);3673 3674	INIT_LIST_HEAD(&ar->peers);3675	init_waitqueue_head(&ar->peer_mapping_wq);3676	init_waitqueue_head(&ar->htt.empty_tx_wq);3677	init_waitqueue_head(&ar->wmi.tx_credits_wq);3678 3679	skb_queue_head_init(&ar->htt.rx_indication_head);3680 3681	init_completion(&ar->offchan_tx_completed);3682	INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);3683	skb_queue_head_init(&ar->offchan_tx_queue);3684 3685	INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);3686	skb_queue_head_init(&ar->wmi_mgmt_tx_queue);3687 3688	INIT_WORK(&ar->register_work, ath10k_core_register_work);3689	INIT_WORK(&ar->restart_work, ath10k_core_restart);3690	INIT_WORK(&ar->set_coverage_class_work,3691		  ath10k_core_set_coverage_class_work);3692 3693	ar->napi_dev = alloc_netdev_dummy(0);3694	if (!ar->napi_dev)3695		goto err_free_tx_complete;3696 3697	ret = ath10k_coredump_create(ar);3698	if (ret)3699		goto err_free_netdev;3700 3701	ret = ath10k_debug_create(ar);3702	if (ret)3703		goto err_free_coredump;3704 3705	return ar;3706 3707err_free_coredump:3708	ath10k_coredump_destroy(ar);3709err_free_netdev:3710	free_netdev(ar->napi_dev);3711err_free_tx_complete:3712	destroy_workqueue(ar->workqueue_tx_complete);3713err_free_aux_wq:3714	destroy_workqueue(ar->workqueue_aux);3715err_free_wq:3716	destroy_workqueue(ar->workqueue);3717err_free_mac:3718	ath10k_mac_destroy(ar);3719 3720	return NULL;3721}3722EXPORT_SYMBOL(ath10k_core_create);3723 3724void ath10k_core_destroy(struct ath10k *ar)3725{3726	destroy_workqueue(ar->workqueue);3727 3728	destroy_workqueue(ar->workqueue_aux);3729 3730	destroy_workqueue(ar->workqueue_tx_complete);3731 3732	free_netdev(ar->napi_dev);3733	ath10k_debug_destroy(ar);3734	ath10k_coredump_destroy(ar);3735	ath10k_htt_tx_destroy(&ar->htt);3736	ath10k_wmi_free_host_mem(ar);3737	ath10k_mac_destroy(ar);3738}3739EXPORT_SYMBOL(ath10k_core_destroy);3740 3741MODULE_AUTHOR("Qualcomm Atheros");3742MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ac wireless LAN cards.");3743MODULE_LICENSE("Dual BSD/GPL");3744