brintos

brintos / linux-shallow public Read only

0
0
Text · 84.1 KiB · f477afd Raw
3355 lines · c
1// SPDX-License-Identifier: BSD-3-Clause-Clear2/*3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.4 * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.5 */6 7#include <linux/elf.h>8 9#include "qmi.h"10#include "core.h"11#include "debug.h"12#include "hif.h"13#include <linux/of.h>14#include <linux/of_address.h>15#include <linux/ioport.h>16#include <linux/firmware.h>17#include <linux/of_irq.h>18 19#define SLEEP_CLOCK_SELECT_INTERNAL_BIT	0x0220#define HOST_CSTATE_BIT			0x0421#define PLATFORM_CAP_PCIE_GLOBAL_RESET	0x0822#define PLATFORM_CAP_PCIE_PME_D3COLD	0x1023 24#define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING="25 26bool ath11k_cold_boot_cal = 1;27EXPORT_SYMBOL(ath11k_cold_boot_cal);28module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644);29MODULE_PARM_DESC(cold_boot_cal,30		 "Decrease the channel switch time but increase the driver load time (Default: true)");31 32static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {33	{34		.data_type	= QMI_OPT_FLAG,35		.elem_len	= 1,36		.elem_size	= sizeof(u8),37		.array_type	= NO_ARRAY,38		.tlv_type	= 0x10,39		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,40					   num_clients_valid),41	},42	{43		.data_type	= QMI_UNSIGNED_4_BYTE,44		.elem_len	= 1,45		.elem_size	= sizeof(u32),46		.array_type	= NO_ARRAY,47		.tlv_type	= 0x10,48		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,49					   num_clients),50	},51	{52		.data_type	= QMI_OPT_FLAG,53		.elem_len	= 1,54		.elem_size	= sizeof(u8),55		.array_type	= NO_ARRAY,56		.tlv_type	= 0x11,57		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,58					   wake_msi_valid),59	},60	{61		.data_type	= QMI_UNSIGNED_4_BYTE,62		.elem_len	= 1,63		.elem_size	= sizeof(u32),64		.array_type	= NO_ARRAY,65		.tlv_type	= 0x11,66		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,67					   wake_msi),68	},69	{70		.data_type	= QMI_OPT_FLAG,71		.elem_len	= 1,72		.elem_size	= sizeof(u8),73		.array_type	= NO_ARRAY,74		.tlv_type	= 0x12,75		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,76					   gpios_valid),77	},78	{79		.data_type	= QMI_DATA_LEN,80		.elem_len	= 1,81		.elem_size	= sizeof(u8),82		.array_type	= NO_ARRAY,83		.tlv_type	= 0x12,84		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,85					   gpios_len),86	},87	{88		.data_type	= QMI_UNSIGNED_4_BYTE,89		.elem_len	= QMI_WLFW_MAX_NUM_GPIO_V01,90		.elem_size	= sizeof(u32),91		.array_type	= VAR_LEN_ARRAY,92		.tlv_type	= 0x12,93		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,94					   gpios),95	},96	{97		.data_type	= QMI_OPT_FLAG,98		.elem_len	= 1,99		.elem_size	= sizeof(u8),100		.array_type	= NO_ARRAY,101		.tlv_type	= 0x13,102		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,103					   nm_modem_valid),104	},105	{106		.data_type	= QMI_UNSIGNED_1_BYTE,107		.elem_len	= 1,108		.elem_size	= sizeof(u8),109		.array_type	= NO_ARRAY,110		.tlv_type	= 0x13,111		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,112					   nm_modem),113	},114	{115		.data_type	= QMI_OPT_FLAG,116		.elem_len	= 1,117		.elem_size	= sizeof(u8),118		.array_type	= NO_ARRAY,119		.tlv_type	= 0x14,120		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,121					   bdf_support_valid),122	},123	{124		.data_type	= QMI_UNSIGNED_1_BYTE,125		.elem_len	= 1,126		.elem_size	= sizeof(u8),127		.array_type	= NO_ARRAY,128		.tlv_type	= 0x14,129		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,130					   bdf_support),131	},132	{133		.data_type	= QMI_OPT_FLAG,134		.elem_len	= 1,135		.elem_size	= sizeof(u8),136		.array_type	= NO_ARRAY,137		.tlv_type	= 0x15,138		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,139					   bdf_cache_support_valid),140	},141	{142		.data_type	= QMI_UNSIGNED_1_BYTE,143		.elem_len	= 1,144		.elem_size	= sizeof(u8),145		.array_type	= NO_ARRAY,146		.tlv_type	= 0x15,147		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,148					   bdf_cache_support),149	},150	{151		.data_type	= QMI_OPT_FLAG,152		.elem_len	= 1,153		.elem_size	= sizeof(u8),154		.array_type	= NO_ARRAY,155		.tlv_type	= 0x16,156		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,157					   m3_support_valid),158	},159	{160		.data_type	= QMI_UNSIGNED_1_BYTE,161		.elem_len	= 1,162		.elem_size	= sizeof(u8),163		.array_type	= NO_ARRAY,164		.tlv_type	= 0x16,165		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,166					   m3_support),167	},168	{169		.data_type	= QMI_OPT_FLAG,170		.elem_len	= 1,171		.elem_size	= sizeof(u8),172		.array_type	= NO_ARRAY,173		.tlv_type	= 0x17,174		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,175					   m3_cache_support_valid),176	},177	{178		.data_type	= QMI_UNSIGNED_1_BYTE,179		.elem_len	= 1,180		.elem_size	= sizeof(u8),181		.array_type	= NO_ARRAY,182		.tlv_type	= 0x17,183		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,184					   m3_cache_support),185	},186	{187		.data_type	= QMI_OPT_FLAG,188		.elem_len	= 1,189		.elem_size	= sizeof(u8),190		.array_type	= NO_ARRAY,191		.tlv_type	= 0x18,192		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,193					   cal_filesys_support_valid),194	},195	{196		.data_type	= QMI_UNSIGNED_1_BYTE,197		.elem_len	= 1,198		.elem_size	= sizeof(u8),199		.array_type	= NO_ARRAY,200		.tlv_type	= 0x18,201		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,202					   cal_filesys_support),203	},204	{205		.data_type	= QMI_OPT_FLAG,206		.elem_len	= 1,207		.elem_size	= sizeof(u8),208		.array_type	= NO_ARRAY,209		.tlv_type	= 0x19,210		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,211					   cal_cache_support_valid),212	},213	{214		.data_type	= QMI_UNSIGNED_1_BYTE,215		.elem_len	= 1,216		.elem_size	= sizeof(u8),217		.array_type	= NO_ARRAY,218		.tlv_type	= 0x19,219		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,220					   cal_cache_support),221	},222	{223		.data_type	= QMI_OPT_FLAG,224		.elem_len	= 1,225		.elem_size	= sizeof(u8),226		.array_type	= NO_ARRAY,227		.tlv_type	= 0x1A,228		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,229					   cal_done_valid),230	},231	{232		.data_type	= QMI_UNSIGNED_1_BYTE,233		.elem_len	= 1,234		.elem_size	= sizeof(u8),235		.array_type	= NO_ARRAY,236		.tlv_type	= 0x1A,237		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,238					   cal_done),239	},240	{241		.data_type	= QMI_OPT_FLAG,242		.elem_len	= 1,243		.elem_size	= sizeof(u8),244		.array_type	= NO_ARRAY,245		.tlv_type	= 0x1B,246		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,247					   mem_bucket_valid),248	},249	{250		.data_type	= QMI_UNSIGNED_4_BYTE,251		.elem_len	= 1,252		.elem_size	= sizeof(u32),253		.array_type	= NO_ARRAY,254		.tlv_type	= 0x1B,255		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,256					   mem_bucket),257	},258	{259		.data_type	= QMI_OPT_FLAG,260		.elem_len	= 1,261		.elem_size	= sizeof(u8),262		.array_type	= NO_ARRAY,263		.tlv_type	= 0x1C,264		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,265					   mem_cfg_mode_valid),266	},267	{268		.data_type	= QMI_UNSIGNED_1_BYTE,269		.elem_len	= 1,270		.elem_size	= sizeof(u8),271		.array_type	= NO_ARRAY,272		.tlv_type	= 0x1C,273		.offset		= offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,274					   mem_cfg_mode),275	},276	{277		.data_type	= QMI_EOTI,278		.array_type	= NO_ARRAY,279		.tlv_type	= QMI_COMMON_TLV_TYPE,280	},281};282 283static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {284	{285		.data_type	= QMI_STRUCT,286		.elem_len	= 1,287		.elem_size	= sizeof(struct qmi_response_type_v01),288		.array_type	= NO_ARRAY,289		.tlv_type	= 0x02,290		.offset		= offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),291		.ei_array	= qmi_response_type_v01_ei,292	},293	{294		.data_type	= QMI_EOTI,295		.array_type	= NO_ARRAY,296		.tlv_type	= QMI_COMMON_TLV_TYPE,297	},298};299 300static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {301	{302		.data_type	= QMI_OPT_FLAG,303		.elem_len	= 1,304		.elem_size	= sizeof(u8),305		.array_type	= NO_ARRAY,306		.tlv_type	= 0x10,307		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,308					   fw_ready_enable_valid),309	},310	{311		.data_type	= QMI_UNSIGNED_1_BYTE,312		.elem_len	= 1,313		.elem_size	= sizeof(u8),314		.array_type	= NO_ARRAY,315		.tlv_type	= 0x10,316		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,317					   fw_ready_enable),318	},319	{320		.data_type	= QMI_OPT_FLAG,321		.elem_len	= 1,322		.elem_size	= sizeof(u8),323		.array_type	= NO_ARRAY,324		.tlv_type	= 0x11,325		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,326					   initiate_cal_download_enable_valid),327	},328	{329		.data_type	= QMI_UNSIGNED_1_BYTE,330		.elem_len	= 1,331		.elem_size	= sizeof(u8),332		.array_type	= NO_ARRAY,333		.tlv_type	= 0x11,334		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,335					   initiate_cal_download_enable),336	},337	{338		.data_type	= QMI_OPT_FLAG,339		.elem_len	= 1,340		.elem_size	= sizeof(u8),341		.array_type	= NO_ARRAY,342		.tlv_type	= 0x12,343		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,344					   initiate_cal_update_enable_valid),345	},346	{347		.data_type	= QMI_UNSIGNED_1_BYTE,348		.elem_len	= 1,349		.elem_size	= sizeof(u8),350		.array_type	= NO_ARRAY,351		.tlv_type	= 0x12,352		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,353					   initiate_cal_update_enable),354	},355	{356		.data_type	= QMI_OPT_FLAG,357		.elem_len	= 1,358		.elem_size	= sizeof(u8),359		.array_type	= NO_ARRAY,360		.tlv_type	= 0x13,361		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,362					   msa_ready_enable_valid),363	},364	{365		.data_type	= QMI_UNSIGNED_1_BYTE,366		.elem_len	= 1,367		.elem_size	= sizeof(u8),368		.array_type	= NO_ARRAY,369		.tlv_type	= 0x13,370		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,371					   msa_ready_enable),372	},373	{374		.data_type	= QMI_OPT_FLAG,375		.elem_len	= 1,376		.elem_size	= sizeof(u8),377		.array_type	= NO_ARRAY,378		.tlv_type	= 0x14,379		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,380					   pin_connect_result_enable_valid),381	},382	{383		.data_type	= QMI_UNSIGNED_1_BYTE,384		.elem_len	= 1,385		.elem_size	= sizeof(u8),386		.array_type	= NO_ARRAY,387		.tlv_type	= 0x14,388		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,389					   pin_connect_result_enable),390	},391	{392		.data_type	= QMI_OPT_FLAG,393		.elem_len	= 1,394		.elem_size	= sizeof(u8),395		.array_type	= NO_ARRAY,396		.tlv_type	= 0x15,397		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,398					   client_id_valid),399	},400	{401		.data_type	= QMI_UNSIGNED_4_BYTE,402		.elem_len	= 1,403		.elem_size	= sizeof(u32),404		.array_type	= NO_ARRAY,405		.tlv_type	= 0x15,406		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,407					   client_id),408	},409	{410		.data_type	= QMI_OPT_FLAG,411		.elem_len	= 1,412		.elem_size	= sizeof(u8),413		.array_type	= NO_ARRAY,414		.tlv_type	= 0x16,415		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,416					   request_mem_enable_valid),417	},418	{419		.data_type	= QMI_UNSIGNED_1_BYTE,420		.elem_len	= 1,421		.elem_size	= sizeof(u8),422		.array_type	= NO_ARRAY,423		.tlv_type	= 0x16,424		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,425					   request_mem_enable),426	},427	{428		.data_type	= QMI_OPT_FLAG,429		.elem_len	= 1,430		.elem_size	= sizeof(u8),431		.array_type	= NO_ARRAY,432		.tlv_type	= 0x17,433		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,434					   fw_mem_ready_enable_valid),435	},436	{437		.data_type	= QMI_UNSIGNED_1_BYTE,438		.elem_len	= 1,439		.elem_size	= sizeof(u8),440		.array_type	= NO_ARRAY,441		.tlv_type	= 0x17,442		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,443					   fw_mem_ready_enable),444	},445	{446		.data_type	= QMI_OPT_FLAG,447		.elem_len	= 1,448		.elem_size	= sizeof(u8),449		.array_type	= NO_ARRAY,450		.tlv_type	= 0x18,451		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,452					   fw_init_done_enable_valid),453	},454	{455		.data_type	= QMI_UNSIGNED_1_BYTE,456		.elem_len	= 1,457		.elem_size	= sizeof(u8),458		.array_type	= NO_ARRAY,459		.tlv_type	= 0x18,460		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,461					   fw_init_done_enable),462	},463 464	{465		.data_type	= QMI_OPT_FLAG,466		.elem_len	= 1,467		.elem_size	= sizeof(u8),468		.array_type	= NO_ARRAY,469		.tlv_type	= 0x19,470		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,471					   rejuvenate_enable_valid),472	},473	{474		.data_type	= QMI_UNSIGNED_1_BYTE,475		.elem_len	= 1,476		.elem_size	= sizeof(u8),477		.array_type	= NO_ARRAY,478		.tlv_type	= 0x19,479		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,480					   rejuvenate_enable),481	},482	{483		.data_type	= QMI_OPT_FLAG,484		.elem_len	= 1,485		.elem_size	= sizeof(u8),486		.array_type	= NO_ARRAY,487		.tlv_type	= 0x1A,488		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,489					   xo_cal_enable_valid),490	},491	{492		.data_type	= QMI_UNSIGNED_1_BYTE,493		.elem_len	= 1,494		.elem_size	= sizeof(u8),495		.array_type	= NO_ARRAY,496		.tlv_type	= 0x1A,497		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,498					   xo_cal_enable),499	},500	{501		.data_type	= QMI_OPT_FLAG,502		.elem_len	= 1,503		.elem_size	= sizeof(u8),504		.array_type	= NO_ARRAY,505		.tlv_type	= 0x1B,506		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,507					   cal_done_enable_valid),508	},509	{510		.data_type	= QMI_UNSIGNED_1_BYTE,511		.elem_len	= 1,512		.elem_size	= sizeof(u8),513		.array_type	= NO_ARRAY,514		.tlv_type	= 0x1B,515		.offset		= offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,516					   cal_done_enable),517	},518	{519		.data_type	= QMI_EOTI,520		.array_type	= NO_ARRAY,521		.tlv_type	= QMI_COMMON_TLV_TYPE,522	},523};524 525static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {526	{527		.data_type	= QMI_STRUCT,528		.elem_len	= 1,529		.elem_size	= sizeof(struct qmi_response_type_v01),530		.array_type	= NO_ARRAY,531		.tlv_type	= 0x02,532		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,533					   resp),534		.ei_array	= qmi_response_type_v01_ei,535	},536	{537		.data_type	= QMI_OPT_FLAG,538		.elem_len	= 1,539		.elem_size	= sizeof(u8),540		.array_type	= NO_ARRAY,541		.tlv_type	= 0x10,542		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,543					   fw_status_valid),544	},545	{546		.data_type	= QMI_UNSIGNED_8_BYTE,547		.elem_len	= 1,548		.elem_size	= sizeof(u64),549		.array_type	= NO_ARRAY,550		.tlv_type	= 0x10,551		.offset		= offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,552					   fw_status),553	},554	{555		.data_type	= QMI_EOTI,556		.array_type	= NO_ARRAY,557		.tlv_type	= QMI_COMMON_TLV_TYPE,558	},559};560 561static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {562	{563		.data_type	= QMI_UNSIGNED_8_BYTE,564		.elem_len	= 1,565		.elem_size	= sizeof(u64),566		.array_type	= NO_ARRAY,567		.tlv_type	= 0,568		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),569	},570	{571		.data_type	= QMI_UNSIGNED_4_BYTE,572		.elem_len	= 1,573		.elem_size	= sizeof(u32),574		.array_type	= NO_ARRAY,575		.tlv_type	= 0,576		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),577	},578	{579		.data_type	= QMI_UNSIGNED_1_BYTE,580		.elem_len	= 1,581		.elem_size	= sizeof(u8),582		.array_type	= NO_ARRAY,583		.tlv_type	= 0,584		.offset		= offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),585	},586	{587		.data_type	= QMI_EOTI,588		.array_type	= NO_ARRAY,589		.tlv_type	= QMI_COMMON_TLV_TYPE,590	},591};592 593static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {594	{595		.data_type	= QMI_UNSIGNED_4_BYTE,596		.elem_len	= 1,597		.elem_size	= sizeof(u32),598		.array_type	= NO_ARRAY,599		.tlv_type	= 0,600		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01,601				  size),602	},603	{604		.data_type	= QMI_SIGNED_4_BYTE_ENUM,605		.elem_len	= 1,606		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),607		.array_type	= NO_ARRAY,608		.tlv_type	= 0,609		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),610	},611	{612		.data_type	= QMI_DATA_LEN,613		.elem_len	= 1,614		.elem_size	= sizeof(u8),615		.array_type	= NO_ARRAY,616		.tlv_type	= 0,617		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),618	},619	{620		.data_type	= QMI_STRUCT,621		.elem_len	= QMI_WLANFW_MAX_NUM_MEM_CFG_V01,622		.elem_size	= sizeof(struct qmi_wlanfw_mem_cfg_s_v01),623		.array_type	= VAR_LEN_ARRAY,624		.tlv_type	= 0,625		.offset		= offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),626		.ei_array	= qmi_wlanfw_mem_cfg_s_v01_ei,627	},628	{629		.data_type	= QMI_EOTI,630		.array_type	= NO_ARRAY,631		.tlv_type	= QMI_COMMON_TLV_TYPE,632	},633};634 635static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {636	{637		.data_type	= QMI_DATA_LEN,638		.elem_len	= 1,639		.elem_size	= sizeof(u8),640		.array_type	= NO_ARRAY,641		.tlv_type	= 0x01,642		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,643					   mem_seg_len),644	},645	{646		.data_type	= QMI_STRUCT,647		.elem_len	= ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,648		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_s_v01),649		.array_type	= VAR_LEN_ARRAY,650		.tlv_type	= 0x01,651		.offset		= offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,652					   mem_seg),653		.ei_array	= qmi_wlanfw_mem_seg_s_v01_ei,654	},655	{656		.data_type	= QMI_EOTI,657		.array_type	= NO_ARRAY,658		.tlv_type	= QMI_COMMON_TLV_TYPE,659	},660};661 662static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {663	{664		.data_type	= QMI_UNSIGNED_8_BYTE,665		.elem_len	= 1,666		.elem_size	= sizeof(u64),667		.array_type	= NO_ARRAY,668		.tlv_type	= 0,669		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),670	},671	{672		.data_type	= QMI_UNSIGNED_4_BYTE,673		.elem_len	= 1,674		.elem_size	= sizeof(u32),675		.array_type	= NO_ARRAY,676		.tlv_type	= 0,677		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),678	},679	{680		.data_type	= QMI_SIGNED_4_BYTE_ENUM,681		.elem_len	= 1,682		.elem_size	= sizeof(enum qmi_wlanfw_mem_type_enum_v01),683		.array_type	= NO_ARRAY,684		.tlv_type	= 0,685		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),686	},687	{688		.data_type	= QMI_UNSIGNED_1_BYTE,689		.elem_len	= 1,690		.elem_size	= sizeof(u8),691		.array_type	= NO_ARRAY,692		.tlv_type	= 0,693		.offset		= offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),694	},695	{696		.data_type	= QMI_EOTI,697		.array_type	= NO_ARRAY,698		.tlv_type	= QMI_COMMON_TLV_TYPE,699	},700};701 702static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {703	{704		.data_type	= QMI_DATA_LEN,705		.elem_len	= 1,706		.elem_size	= sizeof(u8),707		.array_type	= NO_ARRAY,708		.tlv_type	= 0x01,709		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,710					   mem_seg_len),711	},712	{713		.data_type	= QMI_STRUCT,714		.elem_len	= ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,715		.elem_size	= sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),716		.array_type	= VAR_LEN_ARRAY,717		.tlv_type	= 0x01,718		.offset		= offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,719					   mem_seg),720		.ei_array	= qmi_wlanfw_mem_seg_resp_s_v01_ei,721	},722	{723		.data_type	= QMI_EOTI,724		.array_type	= NO_ARRAY,725		.tlv_type	= QMI_COMMON_TLV_TYPE,726	},727};728 729static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {730	{731		.data_type	= QMI_STRUCT,732		.elem_len	= 1,733		.elem_size	= sizeof(struct qmi_response_type_v01),734		.array_type	= NO_ARRAY,735		.tlv_type	= 0x02,736		.offset		= offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,737					   resp),738		.ei_array	= qmi_response_type_v01_ei,739	},740	{741		.data_type	= QMI_EOTI,742		.array_type	= NO_ARRAY,743		.tlv_type	= QMI_COMMON_TLV_TYPE,744	},745};746 747static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {748	{749		.data_type	= QMI_EOTI,750		.array_type	= NO_ARRAY,751		.tlv_type	= QMI_COMMON_TLV_TYPE,752	},753};754 755static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = {756	{757		.data_type      = QMI_EOTI,758		.array_type     = NO_ARRAY,759		.tlv_type       = QMI_COMMON_TLV_TYPE,760	},761};762 763static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = {764	{765		.data_type	= QMI_STRUCT,766		.elem_len	= 1,767		.elem_size	= sizeof(struct qmi_response_type_v01),768		.array_type	= NO_ARRAY,769		.tlv_type	= 0x02,770		.offset		= offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,771					   resp),772		.ei_array	= qmi_response_type_v01_ei,773	},774	{775		.data_type	= QMI_OPT_FLAG,776		.elem_len	= 1,777		.elem_size	= sizeof(u8),778		.array_type	= NO_ARRAY,779		.tlv_type	= 0x10,780		.offset		= offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,781					   bar_addr_valid),782	},783	{784		.data_type	= QMI_UNSIGNED_8_BYTE,785		.elem_len	= 1,786		.elem_size	= sizeof(u64),787		.array_type	= NO_ARRAY,788		.tlv_type	= 0x10,789		.offset		= offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,790					   bar_addr),791	},792	{793		.data_type	= QMI_OPT_FLAG,794		.elem_len	= 1,795		.elem_size	= sizeof(u8),796		.array_type	= NO_ARRAY,797		.tlv_type	= 0x11,798		.offset		= offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,799					   bar_size_valid),800	},801	{802		.data_type	= QMI_UNSIGNED_4_BYTE,803		.elem_len	= 1,804		.elem_size	= sizeof(u32),805		.array_type	= NO_ARRAY,806		.tlv_type	= 0x11,807		.offset		= offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,808					   bar_size),809	},810	{811		.data_type	= QMI_EOTI,812		.array_type	= NO_ARRAY,813		.tlv_type	= QMI_COMMON_TLV_TYPE,814	},815};816 817static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {818	{819		.data_type	= QMI_UNSIGNED_4_BYTE,820		.elem_len	= 1,821		.elem_size	= sizeof(u32),822		.array_type	= NO_ARRAY,823		.tlv_type	= 0,824		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,825					   chip_id),826	},827	{828		.data_type	= QMI_UNSIGNED_4_BYTE,829		.elem_len	= 1,830		.elem_size	= sizeof(u32),831		.array_type	= NO_ARRAY,832		.tlv_type	= 0,833		.offset		= offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,834					   chip_family),835	},836	{837		.data_type	= QMI_EOTI,838		.array_type	= NO_ARRAY,839		.tlv_type	= QMI_COMMON_TLV_TYPE,840	},841};842 843static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {844	{845		.data_type	= QMI_UNSIGNED_4_BYTE,846		.elem_len	= 1,847		.elem_size	= sizeof(u32),848		.array_type	= NO_ARRAY,849		.tlv_type	= 0,850		.offset		= offsetof(struct qmi_wlanfw_rf_board_info_s_v01,851					   board_id),852	},853	{854		.data_type	= QMI_EOTI,855		.array_type	= NO_ARRAY,856		.tlv_type	= QMI_COMMON_TLV_TYPE,857	},858};859 860static const struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = {861	{862		.data_type	= QMI_UNSIGNED_4_BYTE,863		.elem_len	= 1,864		.elem_size	= sizeof(u32),865		.array_type	= NO_ARRAY,866		.tlv_type	= 0,867		.offset		= offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id),868	},869	{870		.data_type	= QMI_EOTI,871		.array_type	= NO_ARRAY,872		.tlv_type	= QMI_COMMON_TLV_TYPE,873	},874};875 876static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {877	{878		.data_type	= QMI_UNSIGNED_4_BYTE,879		.elem_len	= 1,880		.elem_size	= sizeof(u32),881		.array_type	= NO_ARRAY,882		.tlv_type	= 0,883		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,884					   fw_version),885	},886	{887		.data_type	= QMI_STRING,888		.elem_len	= ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,889		.elem_size	= sizeof(char),890		.array_type	= NO_ARRAY,891		.tlv_type	= 0,892		.offset		= offsetof(struct qmi_wlanfw_fw_version_info_s_v01,893					   fw_build_timestamp),894	},895	{896		.data_type	= QMI_EOTI,897		.array_type	= NO_ARRAY,898		.tlv_type	= QMI_COMMON_TLV_TYPE,899	},900};901 902static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {903	{904		.data_type	= QMI_STRUCT,905		.elem_len	= 1,906		.elem_size	= sizeof(struct qmi_response_type_v01),907		.array_type	= NO_ARRAY,908		.tlv_type	= 0x02,909		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),910		.ei_array	= qmi_response_type_v01_ei,911	},912	{913		.data_type	= QMI_OPT_FLAG,914		.elem_len	= 1,915		.elem_size	= sizeof(u8),916		.array_type	= NO_ARRAY,917		.tlv_type	= 0x10,918		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,919					   chip_info_valid),920	},921	{922		.data_type	= QMI_STRUCT,923		.elem_len	= 1,924		.elem_size	= sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),925		.array_type	= NO_ARRAY,926		.tlv_type	= 0x10,927		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,928					   chip_info),929		.ei_array	= qmi_wlanfw_rf_chip_info_s_v01_ei,930	},931	{932		.data_type	= QMI_OPT_FLAG,933		.elem_len	= 1,934		.elem_size	= sizeof(u8),935		.array_type	= NO_ARRAY,936		.tlv_type	= 0x11,937		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,938					   board_info_valid),939	},940	{941		.data_type	= QMI_STRUCT,942		.elem_len	= 1,943		.elem_size	= sizeof(struct qmi_wlanfw_rf_board_info_s_v01),944		.array_type	= NO_ARRAY,945		.tlv_type	= 0x11,946		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,947					   board_info),948		.ei_array	= qmi_wlanfw_rf_board_info_s_v01_ei,949	},950	{951		.data_type	= QMI_OPT_FLAG,952		.elem_len	= 1,953		.elem_size	= sizeof(u8),954		.array_type	= NO_ARRAY,955		.tlv_type	= 0x12,956		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,957					   soc_info_valid),958	},959	{960		.data_type	= QMI_STRUCT,961		.elem_len	= 1,962		.elem_size	= sizeof(struct qmi_wlanfw_soc_info_s_v01),963		.array_type	= NO_ARRAY,964		.tlv_type	= 0x12,965		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,966					   soc_info),967		.ei_array	= qmi_wlanfw_soc_info_s_v01_ei,968	},969	{970		.data_type	= QMI_OPT_FLAG,971		.elem_len	= 1,972		.elem_size	= sizeof(u8),973		.array_type	= NO_ARRAY,974		.tlv_type	= 0x13,975		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,976					   fw_version_info_valid),977	},978	{979		.data_type	= QMI_STRUCT,980		.elem_len	= 1,981		.elem_size	= sizeof(struct qmi_wlanfw_fw_version_info_s_v01),982		.array_type	= NO_ARRAY,983		.tlv_type	= 0x13,984		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,985					   fw_version_info),986		.ei_array	= qmi_wlanfw_fw_version_info_s_v01_ei,987	},988	{989		.data_type	= QMI_OPT_FLAG,990		.elem_len	= 1,991		.elem_size	= sizeof(u8),992		.array_type	= NO_ARRAY,993		.tlv_type	= 0x14,994		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,995					   fw_build_id_valid),996	},997	{998		.data_type	= QMI_STRING,999		.elem_len	= ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,1000		.elem_size	= sizeof(char),1001		.array_type	= NO_ARRAY,1002		.tlv_type	= 0x14,1003		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1004					   fw_build_id),1005	},1006	{1007		.data_type	= QMI_OPT_FLAG,1008		.elem_len	= 1,1009		.elem_size	= sizeof(u8),1010		.array_type	= NO_ARRAY,1011		.tlv_type	= 0x15,1012		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1013					   num_macs_valid),1014	},1015	{1016		.data_type	= QMI_UNSIGNED_1_BYTE,1017		.elem_len	= 1,1018		.elem_size	= sizeof(u8),1019		.array_type	= NO_ARRAY,1020		.tlv_type	= 0x15,1021		.offset		= offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1022					   num_macs),1023	},1024	{1025		.data_type      = QMI_OPT_FLAG,1026		.elem_len       = 1,1027		.elem_size      = sizeof(u8),1028		.array_type     = NO_ARRAY,1029		.tlv_type       = 0x16,1030		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1031					   voltage_mv_valid),1032	},1033	{1034		.data_type      = QMI_UNSIGNED_4_BYTE,1035		.elem_len       = 1,1036		.elem_size      = sizeof(u32),1037		.array_type     = NO_ARRAY,1038		.tlv_type       = 0x16,1039		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1040					   voltage_mv),1041	},1042	{1043		.data_type      = QMI_OPT_FLAG,1044		.elem_len       = 1,1045		.elem_size      = sizeof(u8),1046		.array_type     = NO_ARRAY,1047		.tlv_type       = 0x17,1048		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1049					   time_freq_hz_valid),1050	},1051	{1052		.data_type      = QMI_UNSIGNED_4_BYTE,1053		.elem_len       = 1,1054		.elem_size      = sizeof(u32),1055		.array_type     = NO_ARRAY,1056		.tlv_type       = 0x17,1057		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1058					   time_freq_hz),1059	},1060	{1061		.data_type      = QMI_OPT_FLAG,1062		.elem_len       = 1,1063		.elem_size      = sizeof(u8),1064		.array_type     = NO_ARRAY,1065		.tlv_type       = 0x18,1066		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1067					   otp_version_valid),1068	},1069	{1070		.data_type      = QMI_UNSIGNED_4_BYTE,1071		.elem_len       = 1,1072		.elem_size      = sizeof(u32),1073		.array_type     = NO_ARRAY,1074		.tlv_type       = 0x18,1075		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1076					   otp_version),1077	},1078	{1079		.data_type      = QMI_OPT_FLAG,1080		.elem_len       = 1,1081		.elem_size      = sizeof(u8),1082		.array_type     = NO_ARRAY,1083		.tlv_type       = 0x19,1084		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1085					   eeprom_read_timeout_valid),1086	},1087	{1088		.data_type      = QMI_UNSIGNED_4_BYTE,1089		.elem_len       = 1,1090		.elem_size      = sizeof(u32),1091		.array_type     = NO_ARRAY,1092		.tlv_type       = 0x19,1093		.offset         = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1094					   eeprom_read_timeout),1095	},1096	{1097		.data_type	= QMI_EOTI,1098		.array_type	= NO_ARRAY,1099		.tlv_type	= QMI_COMMON_TLV_TYPE,1100	},1101};1102 1103static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {1104	{1105		.data_type	= QMI_UNSIGNED_1_BYTE,1106		.elem_len	= 1,1107		.elem_size	= sizeof(u8),1108		.array_type	= NO_ARRAY,1109		.tlv_type	= 0x01,1110		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1111					   valid),1112	},1113	{1114		.data_type	= QMI_OPT_FLAG,1115		.elem_len	= 1,1116		.elem_size	= sizeof(u8),1117		.array_type	= NO_ARRAY,1118		.tlv_type	= 0x10,1119		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1120					   file_id_valid),1121	},1122	{1123		.data_type	= QMI_SIGNED_4_BYTE_ENUM,1124		.elem_len	= 1,1125		.elem_size	= sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),1126		.array_type	= NO_ARRAY,1127		.tlv_type	= 0x10,1128		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1129					   file_id),1130	},1131	{1132		.data_type	= QMI_OPT_FLAG,1133		.elem_len	= 1,1134		.elem_size	= sizeof(u8),1135		.array_type	= NO_ARRAY,1136		.tlv_type	= 0x11,1137		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1138					   total_size_valid),1139	},1140	{1141		.data_type	= QMI_UNSIGNED_4_BYTE,1142		.elem_len	= 1,1143		.elem_size	= sizeof(u32),1144		.array_type	= NO_ARRAY,1145		.tlv_type	= 0x11,1146		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1147					   total_size),1148	},1149	{1150		.data_type	= QMI_OPT_FLAG,1151		.elem_len	= 1,1152		.elem_size	= sizeof(u8),1153		.array_type	= NO_ARRAY,1154		.tlv_type	= 0x12,1155		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1156					   seg_id_valid),1157	},1158	{1159		.data_type	= QMI_UNSIGNED_4_BYTE,1160		.elem_len	= 1,1161		.elem_size	= sizeof(u32),1162		.array_type	= NO_ARRAY,1163		.tlv_type	= 0x12,1164		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1165					   seg_id),1166	},1167	{1168		.data_type	= QMI_OPT_FLAG,1169		.elem_len	= 1,1170		.elem_size	= sizeof(u8),1171		.array_type	= NO_ARRAY,1172		.tlv_type	= 0x13,1173		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1174					   data_valid),1175	},1176	{1177		.data_type	= QMI_DATA_LEN,1178		.elem_len	= 1,1179		.elem_size	= sizeof(u16),1180		.array_type	= NO_ARRAY,1181		.tlv_type	= 0x13,1182		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1183					   data_len),1184	},1185	{1186		.data_type	= QMI_UNSIGNED_1_BYTE,1187		.elem_len	= QMI_WLANFW_MAX_DATA_SIZE_V01,1188		.elem_size	= sizeof(u8),1189		.array_type	= VAR_LEN_ARRAY,1190		.tlv_type	= 0x13,1191		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1192					   data),1193	},1194	{1195		.data_type	= QMI_OPT_FLAG,1196		.elem_len	= 1,1197		.elem_size	= sizeof(u8),1198		.array_type	= NO_ARRAY,1199		.tlv_type	= 0x14,1200		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1201					   end_valid),1202	},1203	{1204		.data_type	= QMI_UNSIGNED_1_BYTE,1205		.elem_len	= 1,1206		.elem_size	= sizeof(u8),1207		.array_type	= NO_ARRAY,1208		.tlv_type	= 0x14,1209		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1210					   end),1211	},1212	{1213		.data_type	= QMI_OPT_FLAG,1214		.elem_len	= 1,1215		.elem_size	= sizeof(u8),1216		.array_type	= NO_ARRAY,1217		.tlv_type	= 0x15,1218		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1219					   bdf_type_valid),1220	},1221	{1222		.data_type	= QMI_UNSIGNED_1_BYTE,1223		.elem_len	= 1,1224		.elem_size	= sizeof(u8),1225		.array_type	= NO_ARRAY,1226		.tlv_type	= 0x15,1227		.offset		= offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1228					   bdf_type),1229	},1230 1231	{1232		.data_type	= QMI_EOTI,1233		.array_type	= NO_ARRAY,1234		.tlv_type	= QMI_COMMON_TLV_TYPE,1235	},1236};1237 1238static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {1239	{1240		.data_type	= QMI_STRUCT,1241		.elem_len	= 1,1242		.elem_size	= sizeof(struct qmi_response_type_v01),1243		.array_type	= NO_ARRAY,1244		.tlv_type	= 0x02,1245		.offset		= offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,1246					   resp),1247		.ei_array	= qmi_response_type_v01_ei,1248	},1249	{1250		.data_type	= QMI_EOTI,1251		.array_type	= NO_ARRAY,1252		.tlv_type	= QMI_COMMON_TLV_TYPE,1253	},1254};1255 1256static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {1257	{1258		.data_type	= QMI_UNSIGNED_8_BYTE,1259		.elem_len	= 1,1260		.elem_size	= sizeof(u64),1261		.array_type	= NO_ARRAY,1262		.tlv_type	= 0x01,1263		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),1264	},1265	{1266		.data_type	= QMI_UNSIGNED_4_BYTE,1267		.elem_len	= 1,1268		.elem_size	= sizeof(u32),1269		.array_type	= NO_ARRAY,1270		.tlv_type	= 0x02,1271		.offset		= offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),1272	},1273	{1274		.data_type	= QMI_EOTI,1275		.array_type	= NO_ARRAY,1276		.tlv_type	= QMI_COMMON_TLV_TYPE,1277	},1278};1279 1280static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {1281	{1282		.data_type	= QMI_STRUCT,1283		.elem_len	= 1,1284		.elem_size	= sizeof(struct qmi_response_type_v01),1285		.array_type	= NO_ARRAY,1286		.tlv_type	= 0x02,1287		.offset		= offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),1288		.ei_array	= qmi_response_type_v01_ei,1289	},1290	{1291		.data_type	= QMI_EOTI,1292		.array_type	= NO_ARRAY,1293		.tlv_type	= QMI_COMMON_TLV_TYPE,1294	},1295};1296 1297static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {1298	{1299		.data_type	= QMI_UNSIGNED_4_BYTE,1300		.elem_len	= 1,1301		.elem_size	= sizeof(u32),1302		.array_type	= NO_ARRAY,1303		.tlv_type	= 0,1304		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1305					   pipe_num),1306	},1307	{1308		.data_type	= QMI_SIGNED_4_BYTE_ENUM,1309		.elem_len	= 1,1310		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),1311		.array_type	= NO_ARRAY,1312		.tlv_type	= 0,1313		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1314					   pipe_dir),1315	},1316	{1317		.data_type	= QMI_UNSIGNED_4_BYTE,1318		.elem_len	= 1,1319		.elem_size	= sizeof(u32),1320		.array_type	= NO_ARRAY,1321		.tlv_type	= 0,1322		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1323					   nentries),1324	},1325	{1326		.data_type	= QMI_UNSIGNED_4_BYTE,1327		.elem_len	= 1,1328		.elem_size	= sizeof(u32),1329		.array_type	= NO_ARRAY,1330		.tlv_type	= 0,1331		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1332					   nbytes_max),1333	},1334	{1335		.data_type	= QMI_UNSIGNED_4_BYTE,1336		.elem_len	= 1,1337		.elem_size	= sizeof(u32),1338		.array_type	= NO_ARRAY,1339		.tlv_type	= 0,1340		.offset		= offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1341					   flags),1342	},1343	{1344		.data_type	= QMI_EOTI,1345		.array_type	= NO_ARRAY,1346		.tlv_type	= QMI_COMMON_TLV_TYPE,1347	},1348};1349 1350static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {1351	{1352		.data_type	= QMI_UNSIGNED_4_BYTE,1353		.elem_len	= 1,1354		.elem_size	= sizeof(u32),1355		.array_type	= NO_ARRAY,1356		.tlv_type	= 0,1357		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1358					   service_id),1359	},1360	{1361		.data_type	= QMI_SIGNED_4_BYTE_ENUM,1362		.elem_len	= 1,1363		.elem_size	= sizeof(enum qmi_wlanfw_pipedir_enum_v01),1364		.array_type	= NO_ARRAY,1365		.tlv_type	= 0,1366		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1367					   pipe_dir),1368	},1369	{1370		.data_type	= QMI_UNSIGNED_4_BYTE,1371		.elem_len	= 1,1372		.elem_size	= sizeof(u32),1373		.array_type	= NO_ARRAY,1374		.tlv_type	= 0,1375		.offset		= offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1376					   pipe_num),1377	},1378	{1379		.data_type	= QMI_EOTI,1380		.array_type	= NO_ARRAY,1381		.tlv_type	= QMI_COMMON_TLV_TYPE,1382	},1383};1384 1385static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {1386	{1387		.data_type	= QMI_UNSIGNED_2_BYTE,1388		.elem_len	= 1,1389		.elem_size	= sizeof(u16),1390		.array_type	= NO_ARRAY,1391		.tlv_type	= 0,1392		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),1393	},1394	{1395		.data_type	= QMI_UNSIGNED_2_BYTE,1396		.elem_len	= 1,1397		.elem_size	= sizeof(u16),1398		.array_type	= NO_ARRAY,1399		.tlv_type	= 0,1400		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,1401					   offset),1402	},1403	{1404		.data_type	= QMI_EOTI,1405		.array_type	= QMI_COMMON_TLV_TYPE,1406	},1407};1408 1409static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {1410	{1411		.data_type	= QMI_UNSIGNED_4_BYTE,1412		.elem_len	= 1,1413		.elem_size	= sizeof(u32),1414		.array_type	= NO_ARRAY,1415		.tlv_type	= 0,1416		.offset		= offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,1417					   addr),1418	},1419	{1420		.data_type	= QMI_EOTI,1421		.array_type	= NO_ARRAY,1422		.tlv_type	= QMI_COMMON_TLV_TYPE,1423	},1424};1425 1426static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {1427	{1428		.data_type	= QMI_UNSIGNED_4_BYTE,1429		.elem_len	= 1,1430		.elem_size	= sizeof(u32),1431		.array_type	= NO_ARRAY,1432		.tlv_type	= 0x01,1433		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1434					   mode),1435	},1436	{1437		.data_type	= QMI_OPT_FLAG,1438		.elem_len	= 1,1439		.elem_size	= sizeof(u8),1440		.array_type	= NO_ARRAY,1441		.tlv_type	= 0x10,1442		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1443					   hw_debug_valid),1444	},1445	{1446		.data_type	= QMI_UNSIGNED_1_BYTE,1447		.elem_len	= 1,1448		.elem_size	= sizeof(u8),1449		.array_type	= NO_ARRAY,1450		.tlv_type	= 0x10,1451		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1452					   hw_debug),1453	},1454	{1455		.data_type	= QMI_EOTI,1456		.array_type	= NO_ARRAY,1457		.tlv_type	= QMI_COMMON_TLV_TYPE,1458	},1459};1460 1461static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {1462	{1463		.data_type	= QMI_STRUCT,1464		.elem_len	= 1,1465		.elem_size	= sizeof(struct qmi_response_type_v01),1466		.array_type	= NO_ARRAY,1467		.tlv_type	= 0x02,1468		.offset		= offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,1469					   resp),1470		.ei_array	= qmi_response_type_v01_ei,1471	},1472	{1473		.data_type	= QMI_EOTI,1474		.array_type	= NO_ARRAY,1475		.tlv_type	= QMI_COMMON_TLV_TYPE,1476	},1477};1478 1479static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {1480	{1481		.data_type	= QMI_OPT_FLAG,1482		.elem_len	= 1,1483		.elem_size	= sizeof(u8),1484		.array_type	= NO_ARRAY,1485		.tlv_type	= 0x10,1486		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1487					   host_version_valid),1488	},1489	{1490		.data_type	= QMI_STRING,1491		.elem_len	= QMI_WLANFW_MAX_STR_LEN_V01 + 1,1492		.elem_size	= sizeof(char),1493		.array_type	= NO_ARRAY,1494		.tlv_type	= 0x10,1495		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1496					   host_version),1497	},1498	{1499		.data_type	= QMI_OPT_FLAG,1500		.elem_len	= 1,1501		.elem_size	= sizeof(u8),1502		.array_type	= NO_ARRAY,1503		.tlv_type	= 0x11,1504		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1505					   tgt_cfg_valid),1506	},1507	{1508		.data_type	= QMI_DATA_LEN,1509		.elem_len	= 1,1510		.elem_size	= sizeof(u8),1511		.array_type	= NO_ARRAY,1512		.tlv_type	= 0x11,1513		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1514					   tgt_cfg_len),1515	},1516	{1517		.data_type	= QMI_STRUCT,1518		.elem_len	= QMI_WLANFW_MAX_NUM_CE_V01,1519		.elem_size	= sizeof(1520				struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),1521		.array_type	= VAR_LEN_ARRAY,1522		.tlv_type	= 0x11,1523		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1524					   tgt_cfg),1525		.ei_array	= qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,1526	},1527	{1528		.data_type	= QMI_OPT_FLAG,1529		.elem_len	= 1,1530		.elem_size	= sizeof(u8),1531		.array_type	= NO_ARRAY,1532		.tlv_type	= 0x12,1533		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1534					   svc_cfg_valid),1535	},1536	{1537		.data_type	= QMI_DATA_LEN,1538		.elem_len	= 1,1539		.elem_size	= sizeof(u8),1540		.array_type	= NO_ARRAY,1541		.tlv_type	= 0x12,1542		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1543					   svc_cfg_len),1544	},1545	{1546		.data_type	= QMI_STRUCT,1547		.elem_len	= QMI_WLANFW_MAX_NUM_SVC_V01,1548		.elem_size	= sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),1549		.array_type	= VAR_LEN_ARRAY,1550		.tlv_type	= 0x12,1551		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1552					   svc_cfg),1553		.ei_array	= qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,1554	},1555	{1556		.data_type	= QMI_OPT_FLAG,1557		.elem_len	= 1,1558		.elem_size	= sizeof(u8),1559		.array_type	= NO_ARRAY,1560		.tlv_type	= 0x13,1561		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1562					   shadow_reg_valid),1563	},1564	{1565		.data_type	= QMI_DATA_LEN,1566		.elem_len	= 1,1567		.elem_size	= sizeof(u8),1568		.array_type	= NO_ARRAY,1569		.tlv_type	= 0x13,1570		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1571					   shadow_reg_len),1572	},1573	{1574		.data_type	= QMI_STRUCT,1575		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,1576		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),1577		.array_type	= VAR_LEN_ARRAY,1578		.tlv_type	= 0x13,1579		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1580					   shadow_reg),1581		.ei_array	= qmi_wlanfw_shadow_reg_cfg_s_v01_ei,1582	},1583	{1584		.data_type	= QMI_OPT_FLAG,1585		.elem_len	= 1,1586		.elem_size	= sizeof(u8),1587		.array_type	= NO_ARRAY,1588		.tlv_type	= 0x14,1589		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1590					   shadow_reg_v2_valid),1591	},1592	{1593		.data_type	= QMI_DATA_LEN,1594		.elem_len	= 1,1595		.elem_size	= sizeof(u8),1596		.array_type	= NO_ARRAY,1597		.tlv_type	= 0x14,1598		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1599					   shadow_reg_v2_len),1600	},1601	{1602		.data_type	= QMI_STRUCT,1603		.elem_len	= QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,1604		.elem_size	= sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),1605		.array_type	= VAR_LEN_ARRAY,1606		.tlv_type	= 0x14,1607		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1608					   shadow_reg_v2),1609		.ei_array	= qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,1610	},1611	{1612		.data_type	= QMI_EOTI,1613		.array_type	= NO_ARRAY,1614		.tlv_type	= QMI_COMMON_TLV_TYPE,1615	},1616};1617 1618static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {1619	{1620		.data_type	= QMI_STRUCT,1621		.elem_len	= 1,1622		.elem_size	= sizeof(struct qmi_response_type_v01),1623		.array_type	= NO_ARRAY,1624		.tlv_type	= 0x02,1625		.offset		= offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),1626		.ei_array	= qmi_response_type_v01_ei,1627	},1628	{1629		.data_type	= QMI_EOTI,1630		.array_type	= NO_ARRAY,1631		.tlv_type	= QMI_COMMON_TLV_TYPE,1632	},1633};1634 1635static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {1636	{1637		.data_type = QMI_EOTI,1638		.array_type = NO_ARRAY,1639	},1640};1641 1642static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {1643	{1644		.data_type = QMI_EOTI,1645		.array_type = NO_ARRAY,1646	},1647};1648 1649static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {1650	{1651		.data_type = QMI_EOTI,1652		.array_type = NO_ARRAY,1653	},1654};1655 1656static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {1657	{1658		.data_type	= QMI_OPT_FLAG,1659		.elem_len	= 1,1660		.elem_size	= sizeof(u8),1661		.array_type	= NO_ARRAY,1662		.tlv_type	= 0x10,1663		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,1664					   enablefwlog_valid),1665	},1666	{1667		.data_type	= QMI_UNSIGNED_1_BYTE,1668		.elem_len	= 1,1669		.elem_size	= sizeof(u8),1670		.array_type	= NO_ARRAY,1671		.tlv_type	= 0x10,1672		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,1673					   enablefwlog),1674	},1675	{1676		.data_type	= QMI_EOTI,1677		.array_type	= NO_ARRAY,1678		.tlv_type	= QMI_COMMON_TLV_TYPE,1679	},1680};1681 1682static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {1683	{1684		.data_type	= QMI_STRUCT,1685		.elem_len	= 1,1686		.elem_size	= sizeof(struct qmi_response_type_v01),1687		.array_type	= NO_ARRAY,1688		.tlv_type	= 0x02,1689		.offset		= offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,1690					   resp),1691		.ei_array	= qmi_response_type_v01_ei,1692	},1693	{1694		.data_type	= QMI_EOTI,1695		.array_type	= NO_ARRAY,1696		.tlv_type	= QMI_COMMON_TLV_TYPE,1697	},1698};1699 1700static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = {1701	{1702		.data_type = QMI_EOTI,1703		.array_type = NO_ARRAY,1704	},1705};1706 1707static int ath11k_qmi_host_cap_send(struct ath11k_base *ab)1708{1709	struct qmi_wlanfw_host_cap_req_msg_v01 req;1710	struct qmi_wlanfw_host_cap_resp_msg_v01 resp;1711	struct qmi_txn txn;1712	int ret = 0;1713 1714	memset(&req, 0, sizeof(req));1715	memset(&resp, 0, sizeof(resp));1716 1717	req.num_clients_valid = 1;1718	req.num_clients = 1;1719	req.mem_cfg_mode = ab->qmi.target_mem_mode;1720	req.mem_cfg_mode_valid = 1;1721	req.bdf_support_valid = 1;1722	req.bdf_support = 1;1723 1724	if (ab->hw_params.m3_fw_support) {1725		req.m3_support_valid = 1;1726		req.m3_support = 1;1727		req.m3_cache_support_valid = 1;1728		req.m3_cache_support = 1;1729	} else {1730		req.m3_support_valid = 0;1731		req.m3_support = 0;1732		req.m3_cache_support_valid = 0;1733		req.m3_cache_support = 0;1734	}1735 1736	req.cal_done_valid = 1;1737	req.cal_done = ab->qmi.cal_done;1738 1739	if (ab->hw_params.internal_sleep_clock) {1740		req.nm_modem_valid = 1;1741 1742		/* Notify firmware that this is non-qualcomm platform. */1743		req.nm_modem |= HOST_CSTATE_BIT;1744 1745		/* Notify firmware about the sleep clock selection,1746		 * nm_modem_bit[1] is used for this purpose. Host driver on1747		 * non-qualcomm platforms should select internal sleep1748		 * clock.1749		 */1750		req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;1751	}1752 1753	if (ab->hw_params.global_reset)1754		req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;1755 1756	req.nm_modem |= PLATFORM_CAP_PCIE_PME_D3COLD;1757 1758	ath11k_dbg(ab, ATH11K_DBG_QMI, "host cap request\n");1759 1760	ret = qmi_txn_init(&ab->qmi.handle, &txn,1761			   qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);1762	if (ret < 0)1763		goto out;1764 1765	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1766			       QMI_WLANFW_HOST_CAP_REQ_V01,1767			       QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,1768			       qmi_wlanfw_host_cap_req_msg_v01_ei, &req);1769	if (ret < 0) {1770		qmi_txn_cancel(&txn);1771		ath11k_warn(ab, "failed to send host capability request: %d\n", ret);1772		goto out;1773	}1774 1775	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1776	if (ret < 0)1777		goto out;1778 1779	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {1780		ath11k_warn(ab, "host capability request failed: %d %d\n",1781			    resp.resp.result, resp.resp.error);1782		ret = -EINVAL;1783		goto out;1784	}1785 1786out:1787	return ret;1788}1789 1790static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)1791{1792	struct qmi_wlanfw_ind_register_req_msg_v01 *req;1793	struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;1794	struct qmi_handle *handle = &ab->qmi.handle;1795	struct qmi_txn txn;1796	int ret;1797 1798	req = kzalloc(sizeof(*req), GFP_KERNEL);1799	if (!req)1800		return -ENOMEM;1801 1802	resp = kzalloc(sizeof(*resp), GFP_KERNEL);1803	if (!resp) {1804		ret = -ENOMEM;1805		goto resp_out;1806	}1807 1808	req->client_id_valid = 1;1809	req->client_id = QMI_WLANFW_CLIENT_ID;1810	req->fw_ready_enable_valid = 1;1811	req->fw_ready_enable = 1;1812	req->cal_done_enable_valid = 1;1813	req->cal_done_enable = 1;1814	req->fw_init_done_enable_valid = 1;1815	req->fw_init_done_enable = 1;1816 1817	req->pin_connect_result_enable_valid = 0;1818	req->pin_connect_result_enable = 0;1819 1820	/* WCN6750 doesn't request for DDR memory via QMI,1821	 * instead it uses a fixed 12MB reserved memory1822	 * region in DDR.1823	 */1824	if (!ab->hw_params.fixed_fw_mem) {1825		req->request_mem_enable_valid = 1;1826		req->request_mem_enable = 1;1827		req->fw_mem_ready_enable_valid = 1;1828		req->fw_mem_ready_enable = 1;1829	}1830 1831	ret = qmi_txn_init(handle, &txn,1832			   qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);1833	if (ret < 0)1834		goto out;1835 1836	ath11k_dbg(ab, ATH11K_DBG_QMI, "indication register request\n");1837 1838	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1839			       QMI_WLANFW_IND_REGISTER_REQ_V01,1840			       QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,1841			       qmi_wlanfw_ind_register_req_msg_v01_ei, req);1842	if (ret < 0) {1843		qmi_txn_cancel(&txn);1844		ath11k_warn(ab, "failed to send indication register request: %d\n",1845			    ret);1846		goto out;1847	}1848 1849	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1850	if (ret < 0) {1851		ath11k_warn(ab, "failed to register fw indication: %d\n", ret);1852		goto out;1853	}1854 1855	if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {1856		ath11k_warn(ab, "firmware indication register request failed: %d %d\n",1857			    resp->resp.result, resp->resp.error);1858		ret = -EINVAL;1859		goto out;1860	}1861 1862out:1863	kfree(resp);1864resp_out:1865	kfree(req);1866	return ret;1867}1868 1869static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)1870{1871	struct qmi_wlanfw_respond_mem_req_msg_v01 *req;1872	struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;1873	struct qmi_txn txn;1874	int ret = 0, i;1875	bool delayed;1876 1877	req = kzalloc(sizeof(*req), GFP_KERNEL);1878	if (!req)1879		return -ENOMEM;1880 1881	memset(&resp, 0, sizeof(resp));1882 1883	/* For QCA6390 by default FW requests a block of ~4M contiguous1884	 * DMA memory, it's hard to allocate from OS. So host returns1885	 * failure to FW and FW will then request multiple blocks of small1886	 * chunk size memory.1887	 */1888	if (!(ab->hw_params.fixed_mem_region ||1889	      test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&1890	      ab->qmi.target_mem_delayed) {1891		delayed = true;1892		ath11k_dbg(ab, ATH11K_DBG_QMI, "delays mem_request %d\n",1893			   ab->qmi.mem_seg_count);1894		memset(req, 0, sizeof(*req));1895	} else {1896		delayed = false;1897		req->mem_seg_len = ab->qmi.mem_seg_count;1898 1899		for (i = 0; i < req->mem_seg_len ; i++) {1900			req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;1901			req->mem_seg[i].size = ab->qmi.target_mem[i].size;1902			req->mem_seg[i].type = ab->qmi.target_mem[i].type;1903			ath11k_dbg(ab, ATH11K_DBG_QMI,1904				   "req mem_seg[%d] %pad %u %u\n", i,1905				    &ab->qmi.target_mem[i].paddr,1906				    ab->qmi.target_mem[i].size,1907				    ab->qmi.target_mem[i].type);1908		}1909	}1910 1911	ret = qmi_txn_init(&ab->qmi.handle, &txn,1912			   qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);1913	if (ret < 0)1914		goto out;1915 1916	ath11k_dbg(ab, ATH11K_DBG_QMI, "respond memory request delayed %i\n",1917		   delayed);1918 1919	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1920			       QMI_WLANFW_RESPOND_MEM_REQ_V01,1921			       QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,1922			       qmi_wlanfw_respond_mem_req_msg_v01_ei, req);1923	if (ret < 0) {1924		qmi_txn_cancel(&txn);1925		ath11k_warn(ab, "failed to respond qmi memory request: %d\n",1926			    ret);1927		goto out;1928	}1929 1930	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1931	if (ret < 0) {1932		ath11k_warn(ab, "failed to wait qmi memory request: %d\n", ret);1933		goto out;1934	}1935 1936	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {1937		/* the error response is expected when1938		 * target_mem_delayed is true.1939		 */1940		if (delayed && resp.resp.error == 0)1941			goto out;1942 1943		ath11k_warn(ab, "qmi respond memory request failed: %d %d\n",1944			    resp.resp.result, resp.resp.error);1945		ret = -EINVAL;1946		goto out;1947	}1948out:1949	kfree(req);1950	return ret;1951}1952 1953static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)1954{1955	int i;1956 1957	for (i = 0; i < ab->qmi.mem_seg_count; i++) {1958		if ((ab->hw_params.fixed_mem_region ||1959		     test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&1960		     ab->qmi.target_mem[i].iaddr)1961			iounmap(ab->qmi.target_mem[i].iaddr);1962 1963		if (!ab->qmi.target_mem[i].vaddr)1964			continue;1965 1966		dma_free_coherent(ab->dev,1967				  ab->qmi.target_mem[i].prev_size,1968				  ab->qmi.target_mem[i].vaddr,1969				  ab->qmi.target_mem[i].paddr);1970		ab->qmi.target_mem[i].vaddr = NULL;1971	}1972}1973 1974static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)1975{1976	int i;1977	struct target_mem_chunk *chunk;1978 1979	ab->qmi.target_mem_delayed = false;1980 1981	for (i = 0; i < ab->qmi.mem_seg_count; i++) {1982		chunk = &ab->qmi.target_mem[i];1983 1984		/* Firmware reloads in coldboot/firmware recovery.1985		 * in such case, no need to allocate memory for FW again.1986		 */1987		if (chunk->vaddr) {1988			if (chunk->prev_type == chunk->type &&1989			    chunk->prev_size == chunk->size)1990				continue;1991 1992			/* cannot reuse the existing chunk */1993			dma_free_coherent(ab->dev, chunk->prev_size,1994					  chunk->vaddr, chunk->paddr);1995			chunk->vaddr = NULL;1996		}1997 1998		chunk->vaddr = dma_alloc_coherent(ab->dev,1999						  chunk->size,2000						  &chunk->paddr,2001						  GFP_KERNEL | __GFP_NOWARN);2002		if (!chunk->vaddr) {2003			if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {2004				ath11k_dbg(ab, ATH11K_DBG_QMI,2005					   "dma allocation failed (%d B type %u), will try later with small size\n",2006					    chunk->size,2007					    chunk->type);2008				ath11k_qmi_free_target_mem_chunk(ab);2009				ab->qmi.target_mem_delayed = true;2010				return 0;2011			}2012 2013			ath11k_err(ab, "failed to allocate dma memory for qmi (%d B type %u)\n",2014				   chunk->size,2015				   chunk->type);2016			return -EINVAL;2017		}2018		chunk->prev_type = chunk->type;2019		chunk->prev_size = chunk->size;2020	}2021 2022	return 0;2023}2024 2025static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)2026{2027	struct device *dev = ab->dev;2028	struct device_node *hremote_node = NULL;2029	struct resource res;2030	u32 host_ddr_sz;2031	int i, idx, ret;2032 2033	for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {2034		switch (ab->qmi.target_mem[i].type) {2035		case HOST_DDR_REGION_TYPE:2036			hremote_node = of_parse_phandle(dev->of_node, "memory-region", 0);2037			if (!hremote_node) {2038				ath11k_dbg(ab, ATH11K_DBG_QMI,2039					   "fail to get hremote_node\n");2040				return -ENODEV;2041			}2042 2043			ret = of_address_to_resource(hremote_node, 0, &res);2044			of_node_put(hremote_node);2045			if (ret) {2046				ath11k_dbg(ab, ATH11K_DBG_QMI,2047					   "fail to get reg from hremote\n");2048				return ret;2049			}2050 2051			if (res.end - res.start + 1 < ab->qmi.target_mem[i].size) {2052				ath11k_dbg(ab, ATH11K_DBG_QMI,2053					   "fail to assign memory of sz\n");2054				return -EINVAL;2055			}2056 2057			ab->qmi.target_mem[idx].paddr = res.start;2058			ab->qmi.target_mem[idx].iaddr =2059				ioremap(ab->qmi.target_mem[idx].paddr,2060					ab->qmi.target_mem[i].size);2061			if (!ab->qmi.target_mem[idx].iaddr)2062				return -EIO;2063 2064			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2065			host_ddr_sz = ab->qmi.target_mem[i].size;2066			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2067			idx++;2068			break;2069		case BDF_MEM_REGION_TYPE:2070			ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;2071			ab->qmi.target_mem[idx].vaddr = NULL;2072			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2073			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2074			idx++;2075			break;2076		case CALDB_MEM_REGION_TYPE:2077			if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {2078				ath11k_warn(ab, "qmi mem size is low to load caldata\n");2079				return -EINVAL;2080			}2081 2082			if (ath11k_core_coldboot_cal_support(ab)) {2083				if (hremote_node) {2084					ab->qmi.target_mem[idx].paddr =2085							res.start + host_ddr_sz;2086					ab->qmi.target_mem[idx].iaddr =2087						ioremap(ab->qmi.target_mem[idx].paddr,2088							ab->qmi.target_mem[i].size);2089					if (!ab->qmi.target_mem[idx].iaddr)2090						return -EIO;2091				} else {2092					ab->qmi.target_mem[idx].paddr =2093						ATH11K_QMI_CALDB_ADDRESS;2094				}2095			} else {2096				ab->qmi.target_mem[idx].paddr = 0;2097				ab->qmi.target_mem[idx].vaddr = NULL;2098			}2099			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2100			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2101			idx++;2102			break;2103		default:2104			ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",2105				    ab->qmi.target_mem[i].type);2106			break;2107		}2108	}2109	ab->qmi.mem_seg_count = idx;2110 2111	return 0;2112}2113 2114static int ath11k_qmi_request_device_info(struct ath11k_base *ab)2115{2116	struct qmi_wlanfw_device_info_req_msg_v01 req = {};2117	struct qmi_wlanfw_device_info_resp_msg_v01 resp = {};2118	struct qmi_txn txn;2119	void __iomem *bar_addr_va;2120	int ret;2121 2122	/* device info message req is only sent for hybrid bus devices */2123	if (!ab->hw_params.hybrid_bus_type)2124		return 0;2125 2126	ret = qmi_txn_init(&ab->qmi.handle, &txn,2127			   qmi_wlfw_device_info_resp_msg_v01_ei, &resp);2128	if (ret < 0)2129		goto out;2130 2131	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2132			       QMI_WLANFW_DEVICE_INFO_REQ_V01,2133			       QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01_MAX_LEN,2134			       qmi_wlanfw_device_info_req_msg_v01_ei, &req);2135	if (ret < 0) {2136		qmi_txn_cancel(&txn);2137		ath11k_warn(ab, "failed to send qmi target device info request: %d\n",2138			    ret);2139		goto out;2140	}2141 2142	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2143	if (ret < 0) {2144		ath11k_warn(ab, "failed to wait qmi target device info request: %d\n",2145			    ret);2146		goto out;2147	}2148 2149	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2150		ath11k_warn(ab, "qmi device info request failed: %d %d\n",2151			    resp.resp.result, resp.resp.error);2152		ret = -EINVAL;2153		goto out;2154	}2155 2156	if (!resp.bar_addr_valid || !resp.bar_size_valid) {2157		ath11k_warn(ab, "qmi device info response invalid: %d %d\n",2158			    resp.resp.result, resp.resp.error);2159		ret = -EINVAL;2160		goto out;2161	}2162 2163	if (!resp.bar_addr ||2164	    resp.bar_size != ATH11K_QMI_DEVICE_BAR_SIZE) {2165		ath11k_warn(ab, "qmi device info invalid address and size: %llu %u\n",2166			    resp.bar_addr, resp.bar_size);2167		ret = -EINVAL;2168		goto out;2169	}2170 2171	bar_addr_va = devm_ioremap(ab->dev, resp.bar_addr, resp.bar_size);2172 2173	if (!bar_addr_va) {2174		ath11k_warn(ab, "qmi device info ioremap failed\n");2175		ab->mem_len = 0;2176		ret = -EIO;2177		goto out;2178	}2179 2180	ab->mem = bar_addr_va;2181	ab->mem_len = resp.bar_size;2182 2183	return 0;2184out:2185	return ret;2186}2187 2188static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)2189{2190	struct qmi_wlanfw_cap_req_msg_v01 req;2191	struct qmi_wlanfw_cap_resp_msg_v01 resp;2192	struct qmi_txn txn;2193	int ret = 0;2194	int r;2195	char *fw_build_id;2196	int fw_build_id_mask_len;2197 2198	memset(&req, 0, sizeof(req));2199	memset(&resp, 0, sizeof(resp));2200 2201	ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,2202			   &resp);2203	if (ret < 0)2204		goto out;2205 2206	ath11k_dbg(ab, ATH11K_DBG_QMI, "target cap request\n");2207 2208	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2209			       QMI_WLANFW_CAP_REQ_V01,2210			       QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,2211			       qmi_wlanfw_cap_req_msg_v01_ei, &req);2212	if (ret < 0) {2213		qmi_txn_cancel(&txn);2214		ath11k_warn(ab, "failed to send qmi cap request: %d\n",2215			    ret);2216		goto out;2217	}2218 2219	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2220	if (ret < 0) {2221		ath11k_warn(ab, "failed to wait qmi cap request: %d\n", ret);2222		goto out;2223	}2224 2225	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2226		ath11k_warn(ab, "qmi cap request failed: %d %d\n",2227			    resp.resp.result, resp.resp.error);2228		ret = -EINVAL;2229		goto out;2230	}2231 2232	if (resp.chip_info_valid) {2233		ab->qmi.target.chip_id = resp.chip_info.chip_id;2234		ab->qmi.target.chip_family = resp.chip_info.chip_family;2235	}2236 2237	if (resp.board_info_valid)2238		ab->qmi.target.board_id = resp.board_info.board_id;2239	else2240		ab->qmi.target.board_id = 0xFF;2241 2242	if (resp.soc_info_valid)2243		ab->qmi.target.soc_id = resp.soc_info.soc_id;2244 2245	if (resp.fw_version_info_valid) {2246		ab->qmi.target.fw_version = resp.fw_version_info.fw_version;2247		strscpy(ab->qmi.target.fw_build_timestamp,2248			resp.fw_version_info.fw_build_timestamp,2249			sizeof(ab->qmi.target.fw_build_timestamp));2250	}2251 2252	if (resp.fw_build_id_valid)2253		strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,2254			sizeof(ab->qmi.target.fw_build_id));2255 2256	if (resp.eeprom_read_timeout_valid) {2257		ab->qmi.target.eeprom_caldata =2258					resp.eeprom_read_timeout;2259		ath11k_dbg(ab, ATH11K_DBG_QMI, "cal data supported from eeprom\n");2260	}2261 2262	fw_build_id = ab->qmi.target.fw_build_id;2263	fw_build_id_mask_len = strlen(FW_BUILD_ID_MASK);2264	if (!strncmp(fw_build_id, FW_BUILD_ID_MASK, fw_build_id_mask_len))2265		fw_build_id = fw_build_id + fw_build_id_mask_len;2266 2267	ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",2268		    ab->qmi.target.chip_id, ab->qmi.target.chip_family,2269		    ab->qmi.target.board_id, ab->qmi.target.soc_id);2270 2271	ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",2272		    ab->qmi.target.fw_version,2273		    ab->qmi.target.fw_build_timestamp,2274		    fw_build_id);2275 2276	r = ath11k_core_check_smbios(ab);2277	if (r)2278		ath11k_dbg(ab, ATH11K_DBG_QMI, "SMBIOS bdf variant name not set.\n");2279 2280	r = ath11k_core_check_dt(ab);2281	if (r)2282		ath11k_dbg(ab, ATH11K_DBG_QMI, "DT bdf variant name not set.\n");2283 2284out:2285	return ret;2286}2287 2288static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,2289					   const u8 *data, u32 len, u8 type)2290{2291	struct qmi_wlanfw_bdf_download_req_msg_v01 *req;2292	struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;2293	struct qmi_txn txn;2294	const u8 *temp = data;2295	void __iomem *bdf_addr = NULL;2296	int ret = 0;2297	u32 remaining = len;2298 2299	req = kzalloc(sizeof(*req), GFP_KERNEL);2300	if (!req)2301		return -ENOMEM;2302 2303	memset(&resp, 0, sizeof(resp));2304 2305	if (ab->hw_params.fixed_bdf_addr) {2306		bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);2307		if (!bdf_addr) {2308			ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");2309			ret = -EIO;2310			goto err_free_req;2311		}2312	}2313 2314	while (remaining) {2315		req->valid = 1;2316		req->file_id_valid = 1;2317		req->file_id = ab->qmi.target.board_id;2318		req->total_size_valid = 1;2319		req->total_size = remaining;2320		req->seg_id_valid = 1;2321		req->data_valid = 1;2322		req->bdf_type = type;2323		req->bdf_type_valid = 1;2324		req->end_valid = 1;2325		req->end = 0;2326 2327		if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {2328			req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;2329		} else {2330			req->data_len = remaining;2331			req->end = 1;2332		}2333 2334		if (ab->hw_params.fixed_bdf_addr ||2335		    type == ATH11K_QMI_FILE_TYPE_EEPROM) {2336			req->data_valid = 0;2337			req->end = 1;2338			req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;2339		} else {2340			memcpy(req->data, temp, req->data_len);2341		}2342 2343		if (ab->hw_params.fixed_bdf_addr) {2344			if (type == ATH11K_QMI_FILE_TYPE_CALDATA)2345				bdf_addr += ab->hw_params.fw.cal_offset;2346 2347			memcpy_toio(bdf_addr, temp, len);2348		}2349 2350		ret = qmi_txn_init(&ab->qmi.handle, &txn,2351				   qmi_wlanfw_bdf_download_resp_msg_v01_ei,2352				   &resp);2353		if (ret < 0)2354			goto err_iounmap;2355 2356		ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download req fixed addr type %d\n",2357			   type);2358 2359		ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2360				       QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,2361				       QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,2362				       qmi_wlanfw_bdf_download_req_msg_v01_ei, req);2363		if (ret < 0) {2364			qmi_txn_cancel(&txn);2365			goto err_iounmap;2366		}2367 2368		ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2369		if (ret < 0) {2370			ath11k_warn(ab, "failed to wait board file download request: %d\n",2371				    ret);2372			goto err_iounmap;2373		}2374 2375		if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2376			ath11k_warn(ab, "board file download request failed: %d %d\n",2377				    resp.resp.result, resp.resp.error);2378			ret = -EINVAL;2379			goto err_iounmap;2380		}2381 2382		if (ab->hw_params.fixed_bdf_addr ||2383		    type == ATH11K_QMI_FILE_TYPE_EEPROM) {2384			remaining = 0;2385		} else {2386			remaining -= req->data_len;2387			temp += req->data_len;2388			req->seg_id++;2389			ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download request remaining %i\n",2390				   remaining);2391		}2392	}2393 2394err_iounmap:2395	if (ab->hw_params.fixed_bdf_addr)2396		iounmap(bdf_addr);2397 2398err_free_req:2399	kfree(req);2400 2401	return ret;2402}2403 2404static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab,2405				   bool regdb)2406{2407	struct device *dev = ab->dev;2408	char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];2409	const struct firmware *fw_entry;2410	struct ath11k_board_data bd;2411	u32 fw_size, file_type;2412	int ret = 0, bdf_type;2413	const u8 *tmp;2414 2415	memset(&bd, 0, sizeof(bd));2416 2417	if (regdb) {2418		ret = ath11k_core_fetch_regdb(ab, &bd);2419	} else {2420		ret = ath11k_core_fetch_bdf(ab, &bd);2421		if (ret)2422			ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);2423	}2424 2425	if (ret)2426		goto out;2427 2428	if (regdb)2429		bdf_type = ATH11K_QMI_BDF_TYPE_REGDB;2430	else if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)2431		bdf_type = ATH11K_QMI_BDF_TYPE_ELF;2432	else2433		bdf_type = ATH11K_QMI_BDF_TYPE_BIN;2434 2435	ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf_type %d\n", bdf_type);2436 2437	fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);2438 2439	ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);2440	if (ret < 0) {2441		ath11k_warn(ab, "qmi failed to load bdf file\n");2442		goto out;2443	}2444 2445	/* QCA6390/WCN6855 does not support cal data, skip it */2446	if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF || bdf_type == ATH11K_QMI_BDF_TYPE_REGDB)2447		goto out;2448 2449	if (ab->qmi.target.eeprom_caldata) {2450		file_type = ATH11K_QMI_FILE_TYPE_EEPROM;2451		tmp = filename;2452		fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;2453	} else {2454		file_type = ATH11K_QMI_FILE_TYPE_CALDATA;2455 2456		/* cal-<bus>-<id>.bin */2457		snprintf(filename, sizeof(filename), "cal-%s-%s.bin",2458			 ath11k_bus_str(ab->hif.bus), dev_name(dev));2459		fw_entry = ath11k_core_firmware_request(ab, filename);2460		if (!IS_ERR(fw_entry))2461			goto success;2462 2463		fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);2464		if (IS_ERR(fw_entry)) {2465			/* Caldata may not be present during first time calibration in2466			 * factory hence allow to boot without loading caldata in ftm mode2467			 */2468			if (ath11k_ftm_mode) {2469				ath11k_info(ab,2470					    "Booting without cal data file in factory test mode\n");2471				return 0;2472			}2473			ret = PTR_ERR(fw_entry);2474			ath11k_warn(ab,2475				    "qmi failed to load CAL data file:%s\n",2476				    filename);2477			goto out;2478		}2479success:2480		fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);2481		tmp = fw_entry->data;2482	}2483 2484	ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);2485	if (ret < 0) {2486		ath11k_warn(ab, "qmi failed to load caldata\n");2487		goto out_qmi_cal;2488	}2489 2490	ath11k_dbg(ab, ATH11K_DBG_QMI, "caldata type: %u\n", file_type);2491 2492out_qmi_cal:2493	if (!ab->qmi.target.eeprom_caldata)2494		release_firmware(fw_entry);2495out:2496	ath11k_core_free_bdf(ab, &bd);2497	ath11k_dbg(ab, ATH11K_DBG_QMI, "BDF download sequence completed\n");2498 2499	return ret;2500}2501 2502static int ath11k_qmi_m3_load(struct ath11k_base *ab)2503{2504	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;2505	const struct firmware *fw = NULL;2506	const void *m3_data;2507	char path[100];2508	size_t m3_len;2509	int ret;2510 2511	if (m3_mem->vaddr)2512		/* m3 firmware buffer is already available in the DMA buffer */2513		return 0;2514 2515	if (ab->fw.m3_data && ab->fw.m3_len > 0) {2516		/* firmware-N.bin had a m3 firmware file so use that */2517		m3_data = ab->fw.m3_data;2518		m3_len = ab->fw.m3_len;2519	} else {2520		/* No m3 file in firmware-N.bin so try to request old2521		 * separate m3.bin.2522		 */2523		fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);2524		if (IS_ERR(fw)) {2525			ret = PTR_ERR(fw);2526			ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,2527							 path, sizeof(path));2528			ath11k_err(ab, "failed to load %s: %d\n", path, ret);2529			return ret;2530		}2531 2532		m3_data = fw->data;2533		m3_len = fw->size;2534	}2535 2536	m3_mem->vaddr = dma_alloc_coherent(ab->dev,2537					   m3_len, &m3_mem->paddr,2538					   GFP_KERNEL);2539	if (!m3_mem->vaddr) {2540		ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",2541			   fw->size);2542		ret = -ENOMEM;2543		goto out;2544	}2545 2546	memcpy(m3_mem->vaddr, m3_data, m3_len);2547	m3_mem->size = m3_len;2548 2549	ret = 0;2550 2551out:2552	release_firmware(fw);2553 2554	return ret;2555}2556 2557static void ath11k_qmi_m3_free(struct ath11k_base *ab)2558{2559	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;2560 2561	if (!ab->hw_params.m3_fw_support || !m3_mem->vaddr)2562		return;2563 2564	dma_free_coherent(ab->dev, m3_mem->size,2565			  m3_mem->vaddr, m3_mem->paddr);2566	m3_mem->vaddr = NULL;2567	m3_mem->size = 0;2568}2569 2570static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)2571{2572	struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;2573	struct qmi_wlanfw_m3_info_req_msg_v01 req;2574	struct qmi_wlanfw_m3_info_resp_msg_v01 resp;2575	struct qmi_txn txn;2576	int ret = 0;2577 2578	memset(&req, 0, sizeof(req));2579	memset(&resp, 0, sizeof(resp));2580 2581	if (ab->hw_params.m3_fw_support) {2582		ret = ath11k_qmi_m3_load(ab);2583		if (ret) {2584			ath11k_err(ab, "failed to load m3 firmware: %d", ret);2585			return ret;2586		}2587 2588		req.addr = m3_mem->paddr;2589		req.size = m3_mem->size;2590	} else {2591		req.addr = 0;2592		req.size = 0;2593	}2594 2595	ret = qmi_txn_init(&ab->qmi.handle, &txn,2596			   qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);2597	if (ret < 0)2598		goto out;2599 2600	ath11k_dbg(ab, ATH11K_DBG_QMI, "m3 info req\n");2601 2602	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2603			       QMI_WLANFW_M3_INFO_REQ_V01,2604			       QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,2605			       qmi_wlanfw_m3_info_req_msg_v01_ei, &req);2606	if (ret < 0) {2607		qmi_txn_cancel(&txn);2608		ath11k_warn(ab, "failed to send m3 information request: %d\n",2609			    ret);2610		goto out;2611	}2612 2613	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2614	if (ret < 0) {2615		ath11k_warn(ab, "failed to wait m3 information request: %d\n", ret);2616		goto out;2617	}2618 2619	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2620		ath11k_warn(ab, "m3 info request failed: %d %d\n",2621			    resp.resp.result, resp.resp.error);2622		ret = -EINVAL;2623		goto out;2624	}2625out:2626	return ret;2627}2628 2629static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,2630				       u32 mode)2631{2632	struct qmi_wlanfw_wlan_mode_req_msg_v01 req;2633	struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;2634	struct qmi_txn txn;2635	int ret = 0;2636 2637	memset(&req, 0, sizeof(req));2638	memset(&resp, 0, sizeof(resp));2639 2640	req.mode = mode;2641	req.hw_debug_valid = 1;2642	req.hw_debug = 0;2643 2644	ret = qmi_txn_init(&ab->qmi.handle, &txn,2645			   qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);2646	if (ret < 0)2647		goto out;2648 2649	ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan mode req mode %d\n", mode);2650 2651	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2652			       QMI_WLANFW_WLAN_MODE_REQ_V01,2653			       QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,2654			       qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);2655	if (ret < 0) {2656		qmi_txn_cancel(&txn);2657		ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",2658			    mode, ret);2659		goto out;2660	}2661 2662	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2663	if (ret < 0) {2664		if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {2665			ath11k_warn(ab, "WLFW service is dis-connected\n");2666			return 0;2667		}2668		ath11k_warn(ab, "failed to wait wlan mode request (mode %d): %d\n",2669			    mode, ret);2670		goto out;2671	}2672 2673	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2674		ath11k_warn(ab, "wlan mode request failed (mode: %d): %d %d\n",2675			    mode, resp.resp.result, resp.resp.error);2676		ret = -EINVAL;2677		goto out;2678	}2679 2680out:2681	return ret;2682}2683 2684static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)2685{2686	struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;2687	struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;2688	struct ce_pipe_config *ce_cfg;2689	struct service_to_pipe *svc_cfg;2690	struct qmi_txn txn;2691	int ret = 0, pipe_num;2692 2693	ce_cfg	= (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;2694	svc_cfg	= (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;2695 2696	req = kzalloc(sizeof(*req), GFP_KERNEL);2697	if (!req)2698		return -ENOMEM;2699 2700	memset(&resp, 0, sizeof(resp));2701 2702	req->host_version_valid = 1;2703	strscpy(req->host_version, ATH11K_HOST_VERSION_STRING,2704		sizeof(req->host_version));2705 2706	req->tgt_cfg_valid = 1;2707	/* This is number of CE configs */2708	req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;2709	for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {2710		req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;2711		req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;2712		req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;2713		req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;2714		req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;2715	}2716 2717	req->svc_cfg_valid = 1;2718	/* This is number of Service/CE configs */2719	req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;2720	for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {2721		req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;2722		req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;2723		req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;2724	}2725	req->shadow_reg_valid = 0;2726 2727	/* set shadow v2 configuration */2728	if (ab->hw_params.supports_shadow_regs) {2729		req->shadow_reg_v2_valid = 1;2730		req->shadow_reg_v2_len = min_t(u32,2731					       ab->qmi.ce_cfg.shadow_reg_v2_len,2732					       QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);2733		memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,2734		       sizeof(u32) * req->shadow_reg_v2_len);2735	} else {2736		req->shadow_reg_v2_valid = 0;2737	}2738 2739	ret = qmi_txn_init(&ab->qmi.handle, &txn,2740			   qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);2741	if (ret < 0)2742		goto out;2743 2744	ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan cfg req\n");2745 2746	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2747			       QMI_WLANFW_WLAN_CFG_REQ_V01,2748			       QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,2749			       qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);2750	if (ret < 0) {2751		qmi_txn_cancel(&txn);2752		ath11k_warn(ab, "failed to send wlan config request: %d\n",2753			    ret);2754		goto out;2755	}2756 2757	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2758	if (ret < 0) {2759		ath11k_warn(ab, "failed to wait wlan config request: %d\n", ret);2760		goto out;2761	}2762 2763	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2764		ath11k_warn(ab, "wlan config request failed: %d %d\n",2765			    resp.resp.result, resp.resp.error);2766		ret = -EINVAL;2767		goto out;2768	}2769 2770out:2771	kfree(req);2772	return ret;2773}2774 2775static int ath11k_qmi_wlanfw_wlan_ini_send(struct ath11k_base *ab, bool enable)2776{2777	int ret;2778	struct qmi_txn txn;2779	struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};2780	struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};2781 2782	req.enablefwlog_valid = true;2783	req.enablefwlog = enable ? 1 : 0;2784 2785	ret = qmi_txn_init(&ab->qmi.handle, &txn,2786			   qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);2787	if (ret < 0)2788		goto out;2789 2790	ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2791			       QMI_WLANFW_WLAN_INI_REQ_V01,2792			       QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,2793			       qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);2794	if (ret < 0) {2795		ath11k_warn(ab, "qmi failed to send wlan ini request, err = %d\n",2796			    ret);2797		qmi_txn_cancel(&txn);2798		goto out;2799	}2800 2801	ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2802	if (ret < 0) {2803		ath11k_warn(ab, "qmi failed wlan ini request, err = %d\n", ret);2804		goto out;2805	}2806 2807	if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2808		ath11k_warn(ab, "qmi wlan ini request failed, result: %d, err: %d\n",2809			    resp.resp.result, resp.resp.error);2810		ret = -EINVAL;2811	}2812 2813out:2814	return ret;2815}2816 2817void ath11k_qmi_firmware_stop(struct ath11k_base *ab)2818{2819	int ret;2820 2821	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware stop\n");2822 2823	ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);2824	if (ret < 0) {2825		ath11k_warn(ab, "qmi failed to send wlan mode off: %d\n", ret);2826		return;2827	}2828}2829 2830int ath11k_qmi_firmware_start(struct ath11k_base *ab,2831			      u32 mode)2832{2833	int ret;2834 2835	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware start\n");2836 2837	if (ab->hw_params.fw_wmi_diag_event) {2838		ret = ath11k_qmi_wlanfw_wlan_ini_send(ab, true);2839		if (ret < 0) {2840			ath11k_warn(ab, "qmi failed to send wlan fw ini:%d\n", ret);2841			return ret;2842		}2843	}2844 2845	ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);2846	if (ret < 0) {2847		ath11k_warn(ab, "qmi failed to send wlan cfg: %d\n", ret);2848		return ret;2849	}2850 2851	ret = ath11k_qmi_wlanfw_mode_send(ab, mode);2852	if (ret < 0) {2853		ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);2854		return ret;2855	}2856 2857	return 0;2858}2859 2860int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab)2861{2862	long time_left;2863 2864	if (!ath11k_core_coldboot_cal_support(ab) ||2865	    ab->hw_params.cbcal_restart_fw == 0)2866		return 0;2867 2868	ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");2869 2870	time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,2871				       (ab->qmi.cal_done == 1),2872				       ATH11K_COLD_BOOT_FW_RESET_DELAY);2873 2874	if (time_left <= 0) {2875		ath11k_warn(ab, "Coldboot Calibration timed out\n");2876		return -ETIMEDOUT;2877	}2878 2879	/* reset the firmware */2880	ath11k_hif_power_down(ab);2881	ath11k_hif_power_up(ab);2882	ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n");2883	return 0;2884}2885EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot);2886 2887static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)2888{2889	long time_left;2890	int ret;2891 2892	ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);2893	if (ret < 0) {2894		ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);2895		return ret;2896	}2897 2898	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");2899 2900	time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,2901				       (ab->qmi.cal_done  == 1),2902				       ATH11K_COLD_BOOT_FW_RESET_DELAY);2903	if (time_left <= 0) {2904		ath11k_warn(ab, "coldboot calibration timed out\n");2905		return 0;2906	}2907 2908	ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration done\n");2909 2910	return 0;2911}2912 2913static int2914ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,2915			     enum ath11k_qmi_event_type type,2916			     void *data)2917{2918	struct ath11k_qmi_driver_event *event;2919 2920	event = kzalloc(sizeof(*event), GFP_ATOMIC);2921	if (!event)2922		return -ENOMEM;2923 2924	event->type = type;2925	event->data = data;2926 2927	spin_lock(&qmi->event_lock);2928	list_add_tail(&event->list, &qmi->event_list);2929	spin_unlock(&qmi->event_lock);2930 2931	queue_work(qmi->event_wq, &qmi->event_work);2932 2933	return 0;2934}2935 2936static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)2937{2938	struct ath11k_base *ab = qmi->ab;2939	int ret;2940 2941	ret = ath11k_qmi_respond_fw_mem_request(ab);2942	if (ret < 0) {2943		ath11k_warn(ab, "qmi failed to respond fw mem req: %d\n", ret);2944		return ret;2945	}2946 2947	return ret;2948}2949 2950static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)2951{2952	struct ath11k_base *ab = qmi->ab;2953	int ret;2954 2955	ret = ath11k_qmi_request_target_cap(ab);2956	if (ret < 0) {2957		ath11k_warn(ab, "failed to request qmi target capabilities: %d\n",2958			    ret);2959		return ret;2960	}2961 2962	ret = ath11k_qmi_request_device_info(ab);2963	if (ret < 0) {2964		ath11k_warn(ab, "failed to request qmi device info: %d\n", ret);2965		return ret;2966	}2967 2968	if (ab->hw_params.supports_regdb)2969		ath11k_qmi_load_bdf_qmi(ab, true);2970 2971	ret = ath11k_qmi_load_bdf_qmi(ab, false);2972	if (ret < 0) {2973		ath11k_warn(ab, "failed to load board data file: %d\n", ret);2974		return ret;2975	}2976 2977	return 0;2978}2979 2980static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)2981{2982	struct ath11k_base *ab = qmi->ab;2983	int ret;2984 2985	ret = ath11k_qmi_fw_ind_register_send(ab);2986	if (ret < 0) {2987		ath11k_warn(ab, "failed to send qmi firmware indication: %d\n",2988			    ret);2989		return ret;2990	}2991 2992	ret = ath11k_qmi_host_cap_send(ab);2993	if (ret < 0) {2994		ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret);2995		return ret;2996	}2997 2998	if (!ab->hw_params.fixed_fw_mem)2999		return ret;3000 3001	ret = ath11k_qmi_event_load_bdf(qmi);3002	if (ret < 0) {3003		ath11k_warn(ab, "qmi failed to download BDF:%d\n", ret);3004		return ret;3005	}3006 3007	return ret;3008}3009 3010static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,3011					  struct sockaddr_qrtr *sq,3012					  struct qmi_txn *txn,3013					  const void *data)3014{3015	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3016	struct ath11k_base *ab = qmi->ab;3017	const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;3018	int i, ret;3019 3020	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware request memory request\n");3021 3022	if (msg->mem_seg_len == 0 ||3023	    msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)3024		ath11k_warn(ab, "invalid memory segment length: %u\n",3025			    msg->mem_seg_len);3026 3027	ab->qmi.mem_seg_count = msg->mem_seg_len;3028 3029	for (i = 0; i < qmi->mem_seg_count ; i++) {3030		ab->qmi.target_mem[i].type = msg->mem_seg[i].type;3031		ab->qmi.target_mem[i].size = msg->mem_seg[i].size;3032		ath11k_dbg(ab, ATH11K_DBG_QMI, "mem seg type %d size %d\n",3033			   msg->mem_seg[i].type, msg->mem_seg[i].size);3034	}3035 3036	if (ab->hw_params.fixed_mem_region ||3037	    test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {3038		ret = ath11k_qmi_assign_target_mem_chunk(ab);3039		if (ret) {3040			ath11k_warn(ab, "failed to assign qmi target memory: %d\n",3041				    ret);3042			return;3043		}3044	} else {3045		ret = ath11k_qmi_alloc_target_mem_chunk(ab);3046		if (ret) {3047			ath11k_warn(ab, "failed to allocate qmi target memory: %d\n",3048				    ret);3049			return;3050		}3051	}3052 3053	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);3054}3055 3056static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,3057					struct sockaddr_qrtr *sq,3058					struct qmi_txn *txn,3059					const void *decoded)3060{3061	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3062	struct ath11k_base *ab = qmi->ab;3063 3064	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware memory ready indication\n");3065	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);3066}3067 3068static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,3069				       struct sockaddr_qrtr *sq,3070				       struct qmi_txn *txn,3071				       const void *decoded)3072{3073	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3074	struct ath11k_base *ab = qmi->ab;3075 3076	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware ready\n");3077 3078	if (!ab->qmi.cal_done) {3079		ab->qmi.cal_done = 1;3080		wake_up(&ab->qmi.cold_boot_waitq);3081	}3082 3083	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);3084}3085 3086static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,3087						 struct sockaddr_qrtr *sq,3088						 struct qmi_txn *txn,3089						 const void *decoded)3090{3091	struct ath11k_qmi *qmi = container_of(qmi_hdl,3092					      struct ath11k_qmi, handle);3093	struct ath11k_base *ab = qmi->ab;3094 3095	ab->qmi.cal_done = 1;3096	wake_up(&ab->qmi.cold_boot_waitq);3097	ath11k_dbg(ab, ATH11K_DBG_QMI, "cold boot calibration done\n");3098}3099 3100static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl,3101					   struct sockaddr_qrtr *sq,3102					   struct qmi_txn *txn,3103					   const void *decoded)3104{3105	struct ath11k_qmi *qmi = container_of(qmi_hdl,3106					      struct ath11k_qmi, handle);3107	struct ath11k_base *ab = qmi->ab;3108 3109	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL);3110	ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware init done\n");3111}3112 3113static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {3114	{3115		.type = QMI_INDICATION,3116		.msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,3117		.ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,3118		.decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),3119		.fn = ath11k_qmi_msg_mem_request_cb,3120	},3121	{3122		.type = QMI_INDICATION,3123		.msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,3124		.ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,3125		.decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),3126		.fn = ath11k_qmi_msg_mem_ready_cb,3127	},3128	{3129		.type = QMI_INDICATION,3130		.msg_id = QMI_WLFW_FW_READY_IND_V01,3131		.ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,3132		.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),3133		.fn = ath11k_qmi_msg_fw_ready_cb,3134	},3135	{3136		.type = QMI_INDICATION,3137		.msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,3138		.ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,3139		.decoded_size =3140			sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),3141		.fn = ath11k_qmi_msg_cold_boot_cal_done_cb,3142	},3143	{3144		.type = QMI_INDICATION,3145		.msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,3146		.ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei,3147		.decoded_size =3148			sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),3149		.fn = ath11k_qmi_msg_fw_init_done_cb,3150	},3151 3152	/* end of list */3153	{},3154};3155 3156static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,3157				     struct qmi_service *service)3158{3159	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3160	struct ath11k_base *ab = qmi->ab;3161	struct sockaddr_qrtr *sq = &qmi->sq;3162	int ret;3163 3164	sq->sq_family = AF_QIPCRTR;3165	sq->sq_node = service->node;3166	sq->sq_port = service->port;3167 3168	ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,3169			     sizeof(*sq), 0);3170	if (ret) {3171		ath11k_warn(ab, "failed to connect to qmi remote service: %d\n", ret);3172		return ret;3173	}3174 3175	ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw qmi service connected\n");3176	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);3177 3178	return ret;3179}3180 3181static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,3182				      struct qmi_service *service)3183{3184	struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3185	struct ath11k_base *ab = qmi->ab;3186 3187	ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw del server\n");3188	ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);3189}3190 3191static const struct qmi_ops ath11k_qmi_ops = {3192	.new_server = ath11k_qmi_ops_new_server,3193	.del_server = ath11k_qmi_ops_del_server,3194};3195 3196static void ath11k_qmi_driver_event_work(struct work_struct *work)3197{3198	struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,3199					      event_work);3200	struct ath11k_qmi_driver_event *event;3201	struct ath11k_base *ab = qmi->ab;3202	int ret;3203 3204	spin_lock(&qmi->event_lock);3205	while (!list_empty(&qmi->event_list)) {3206		event = list_first_entry(&qmi->event_list,3207					 struct ath11k_qmi_driver_event, list);3208		list_del(&event->list);3209		spin_unlock(&qmi->event_lock);3210 3211		if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {3212			kfree(event);3213			return;3214		}3215 3216		switch (event->type) {3217		case ATH11K_QMI_EVENT_SERVER_ARRIVE:3218			ret = ath11k_qmi_event_server_arrive(qmi);3219			if (ret < 0)3220				set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3221			break;3222		case ATH11K_QMI_EVENT_SERVER_EXIT:3223			set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);3224			set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);3225 3226			if (!ab->is_reset)3227				ath11k_core_pre_reconfigure_recovery(ab);3228			break;3229		case ATH11K_QMI_EVENT_REQUEST_MEM:3230			ret = ath11k_qmi_event_mem_request(qmi);3231			if (ret < 0)3232				set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3233			break;3234		case ATH11K_QMI_EVENT_FW_MEM_READY:3235			ret = ath11k_qmi_event_load_bdf(qmi);3236			if (ret < 0) {3237				set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3238				break;3239			}3240 3241			ret = ath11k_qmi_wlanfw_m3_info_send(ab);3242			if (ret < 0) {3243				ath11k_warn(ab,3244					    "failed to send qmi m3 info req: %d\n", ret);3245				set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3246			}3247 3248			break;3249		case ATH11K_QMI_EVENT_FW_INIT_DONE:3250			clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3251			if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {3252				if (ab->is_reset)3253					ath11k_hal_dump_srng_stats(ab);3254				queue_work(ab->workqueue, &ab->restart_work);3255				break;3256			}3257 3258			if (ab->qmi.cal_done == 0 &&3259			    ath11k_core_coldboot_cal_support(ab)) {3260				ath11k_qmi_process_coldboot_calibration(ab);3261			} else {3262				clear_bit(ATH11K_FLAG_CRASH_FLUSH,3263					  &ab->dev_flags);3264				clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);3265				ret = ath11k_core_qmi_firmware_ready(ab);3266				if (ret) {3267					set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3268					break;3269				}3270				set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);3271			}3272 3273			break;3274		case ATH11K_QMI_EVENT_FW_READY:3275			/* For targets requiring a FW restart upon cold3276			 * boot completion, there is no need to process3277			 * FW ready; such targets will receive FW init3278			 * done message after FW restart.3279			 */3280			if (ab->hw_params.cbcal_restart_fw)3281				break;3282 3283			clear_bit(ATH11K_FLAG_CRASH_FLUSH,3284				  &ab->dev_flags);3285			clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);3286			ath11k_core_qmi_firmware_ready(ab);3287			set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);3288 3289			break;3290		case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:3291			break;3292		default:3293			ath11k_warn(ab, "invalid qmi event type: %d", event->type);3294			break;3295		}3296		kfree(event);3297		spin_lock(&qmi->event_lock);3298	}3299	spin_unlock(&qmi->event_lock);3300}3301 3302int ath11k_qmi_init_service(struct ath11k_base *ab)3303{3304	int ret;3305 3306	memset(&ab->qmi.target, 0, sizeof(struct target_info));3307	memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));3308	ab->qmi.ab = ab;3309 3310	ab->qmi.target_mem_mode = ab->hw_params.fw_mem_mode;3311	ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,3312			      &ath11k_qmi_ops, ath11k_qmi_msg_handlers);3313	if (ret < 0) {3314		ath11k_warn(ab, "failed to initialize qmi handle: %d\n", ret);3315		return ret;3316	}3317 3318	ab->qmi.event_wq = alloc_ordered_workqueue("ath11k_qmi_driver_event", 0);3319	if (!ab->qmi.event_wq) {3320		ath11k_err(ab, "failed to allocate workqueue\n");3321		return -EFAULT;3322	}3323 3324	INIT_LIST_HEAD(&ab->qmi.event_list);3325	spin_lock_init(&ab->qmi.event_lock);3326	INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);3327 3328	ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,3329			     ATH11K_QMI_WLFW_SERVICE_VERS_V01,3330			     ab->qmi.service_ins_id);3331	if (ret < 0) {3332		ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);3333		destroy_workqueue(ab->qmi.event_wq);3334		return ret;3335	}3336 3337	return ret;3338}3339 3340void ath11k_qmi_deinit_service(struct ath11k_base *ab)3341{3342	qmi_handle_release(&ab->qmi.handle);3343	cancel_work_sync(&ab->qmi.event_work);3344	destroy_workqueue(ab->qmi.event_wq);3345	ath11k_qmi_m3_free(ab);3346	ath11k_qmi_free_target_mem_chunk(ab);3347}3348EXPORT_SYMBOL(ath11k_qmi_deinit_service);3349 3350void ath11k_qmi_free_resource(struct ath11k_base *ab)3351{3352	ath11k_qmi_free_target_mem_chunk(ab);3353	ath11k_qmi_m3_free(ab);3354}3355