Path: blob/main/sys/contrib/dev/athk/ath11k/qmi.c
106844 views
// SPDX-License-Identifier: BSD-3-Clause-Clear1/*2* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.4* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.5*/67#if defined(__FreeBSD__)8#define LINUXKPI_PARAM_PREFIX ath11k_qmi_9#endif1011#include <linux/elf.h>12#include <linux/export.h>1314#if defined(__FreeBSD__)15#include <linux/workqueue.h>16#include <linux/firmware.h>17#include <linux/socket.h>18#include <linux/wait.h>19#endif20#include "qmi.h"21#include "core.h"22#include "debug.h"23#include "hif.h"24#if defined(CONFIG_OF)25#include <linux/of.h>26#include <linux/of_address.h>27#endif28#include <linux/of_reserved_mem.h>29#include <linux/ioport.h>30#if defined(__linux__)31#include <linux/firmware.h>32#endif33#include <linux/of_irq.h>3435#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x0236#define HOST_CSTATE_BIT 0x0437#define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x0838#define PLATFORM_CAP_PCIE_PME_D3COLD 0x103940#define FW_BUILD_ID_MASK "QC_IMAGE_VERSION_STRING="4142bool ath11k_cold_boot_cal = 1;43EXPORT_SYMBOL(ath11k_cold_boot_cal);44module_param_named(cold_boot_cal, ath11k_cold_boot_cal, bool, 0644);45MODULE_PARM_DESC(cold_boot_cal,46"Decrease the channel switch time but increase the driver load time (Default: true)");4748static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {49{50.data_type = QMI_OPT_FLAG,51.elem_len = 1,52.elem_size = sizeof(u8),53.array_type = NO_ARRAY,54.tlv_type = 0x10,55.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,56num_clients_valid),57},58{59.data_type = QMI_UNSIGNED_4_BYTE,60.elem_len = 1,61.elem_size = sizeof(u32),62.array_type = NO_ARRAY,63.tlv_type = 0x10,64.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,65num_clients),66},67{68.data_type = QMI_OPT_FLAG,69.elem_len = 1,70.elem_size = sizeof(u8),71.array_type = NO_ARRAY,72.tlv_type = 0x11,73.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,74wake_msi_valid),75},76{77.data_type = QMI_UNSIGNED_4_BYTE,78.elem_len = 1,79.elem_size = sizeof(u32),80.array_type = NO_ARRAY,81.tlv_type = 0x11,82.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,83wake_msi),84},85{86.data_type = QMI_OPT_FLAG,87.elem_len = 1,88.elem_size = sizeof(u8),89.array_type = NO_ARRAY,90.tlv_type = 0x12,91.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,92gpios_valid),93},94{95.data_type = QMI_DATA_LEN,96.elem_len = 1,97.elem_size = sizeof(u8),98.array_type = NO_ARRAY,99.tlv_type = 0x12,100.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,101gpios_len),102},103{104.data_type = QMI_UNSIGNED_4_BYTE,105.elem_len = QMI_WLFW_MAX_NUM_GPIO_V01,106.elem_size = sizeof(u32),107.array_type = VAR_LEN_ARRAY,108.tlv_type = 0x12,109.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,110gpios),111},112{113.data_type = QMI_OPT_FLAG,114.elem_len = 1,115.elem_size = sizeof(u8),116.array_type = NO_ARRAY,117.tlv_type = 0x13,118.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,119nm_modem_valid),120},121{122.data_type = QMI_UNSIGNED_1_BYTE,123.elem_len = 1,124.elem_size = sizeof(u8),125.array_type = NO_ARRAY,126.tlv_type = 0x13,127.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,128nm_modem),129},130{131.data_type = QMI_OPT_FLAG,132.elem_len = 1,133.elem_size = sizeof(u8),134.array_type = NO_ARRAY,135.tlv_type = 0x14,136.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,137bdf_support_valid),138},139{140.data_type = QMI_UNSIGNED_1_BYTE,141.elem_len = 1,142.elem_size = sizeof(u8),143.array_type = NO_ARRAY,144.tlv_type = 0x14,145.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,146bdf_support),147},148{149.data_type = QMI_OPT_FLAG,150.elem_len = 1,151.elem_size = sizeof(u8),152.array_type = NO_ARRAY,153.tlv_type = 0x15,154.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,155bdf_cache_support_valid),156},157{158.data_type = QMI_UNSIGNED_1_BYTE,159.elem_len = 1,160.elem_size = sizeof(u8),161.array_type = NO_ARRAY,162.tlv_type = 0x15,163.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,164bdf_cache_support),165},166{167.data_type = QMI_OPT_FLAG,168.elem_len = 1,169.elem_size = sizeof(u8),170.array_type = NO_ARRAY,171.tlv_type = 0x16,172.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,173m3_support_valid),174},175{176.data_type = QMI_UNSIGNED_1_BYTE,177.elem_len = 1,178.elem_size = sizeof(u8),179.array_type = NO_ARRAY,180.tlv_type = 0x16,181.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,182m3_support),183},184{185.data_type = QMI_OPT_FLAG,186.elem_len = 1,187.elem_size = sizeof(u8),188.array_type = NO_ARRAY,189.tlv_type = 0x17,190.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,191m3_cache_support_valid),192},193{194.data_type = QMI_UNSIGNED_1_BYTE,195.elem_len = 1,196.elem_size = sizeof(u8),197.array_type = NO_ARRAY,198.tlv_type = 0x17,199.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,200m3_cache_support),201},202{203.data_type = QMI_OPT_FLAG,204.elem_len = 1,205.elem_size = sizeof(u8),206.array_type = NO_ARRAY,207.tlv_type = 0x18,208.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,209cal_filesys_support_valid),210},211{212.data_type = QMI_UNSIGNED_1_BYTE,213.elem_len = 1,214.elem_size = sizeof(u8),215.array_type = NO_ARRAY,216.tlv_type = 0x18,217.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,218cal_filesys_support),219},220{221.data_type = QMI_OPT_FLAG,222.elem_len = 1,223.elem_size = sizeof(u8),224.array_type = NO_ARRAY,225.tlv_type = 0x19,226.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,227cal_cache_support_valid),228},229{230.data_type = QMI_UNSIGNED_1_BYTE,231.elem_len = 1,232.elem_size = sizeof(u8),233.array_type = NO_ARRAY,234.tlv_type = 0x19,235.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,236cal_cache_support),237},238{239.data_type = QMI_OPT_FLAG,240.elem_len = 1,241.elem_size = sizeof(u8),242.array_type = NO_ARRAY,243.tlv_type = 0x1A,244.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,245cal_done_valid),246},247{248.data_type = QMI_UNSIGNED_1_BYTE,249.elem_len = 1,250.elem_size = sizeof(u8),251.array_type = NO_ARRAY,252.tlv_type = 0x1A,253.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,254cal_done),255},256{257.data_type = QMI_OPT_FLAG,258.elem_len = 1,259.elem_size = sizeof(u8),260.array_type = NO_ARRAY,261.tlv_type = 0x1B,262.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,263mem_bucket_valid),264},265{266.data_type = QMI_UNSIGNED_4_BYTE,267.elem_len = 1,268.elem_size = sizeof(u32),269.array_type = NO_ARRAY,270.tlv_type = 0x1B,271.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,272mem_bucket),273},274{275.data_type = QMI_OPT_FLAG,276.elem_len = 1,277.elem_size = sizeof(u8),278.array_type = NO_ARRAY,279.tlv_type = 0x1C,280.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,281mem_cfg_mode_valid),282},283{284.data_type = QMI_UNSIGNED_1_BYTE,285.elem_len = 1,286.elem_size = sizeof(u8),287.array_type = NO_ARRAY,288.tlv_type = 0x1C,289.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,290mem_cfg_mode),291},292{293.data_type = QMI_EOTI,294.array_type = NO_ARRAY,295.tlv_type = QMI_COMMON_TLV_TYPE,296},297};298299static const struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = {300{301.data_type = QMI_STRUCT,302.elem_len = 1,303.elem_size = sizeof(struct qmi_response_type_v01),304.array_type = NO_ARRAY,305.tlv_type = 0x02,306.offset = offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp),307.ei_array = qmi_response_type_v01_ei,308},309{310.data_type = QMI_EOTI,311.array_type = NO_ARRAY,312.tlv_type = QMI_COMMON_TLV_TYPE,313},314};315316static const struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = {317{318.data_type = QMI_OPT_FLAG,319.elem_len = 1,320.elem_size = sizeof(u8),321.array_type = NO_ARRAY,322.tlv_type = 0x10,323.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,324fw_ready_enable_valid),325},326{327.data_type = QMI_UNSIGNED_1_BYTE,328.elem_len = 1,329.elem_size = sizeof(u8),330.array_type = NO_ARRAY,331.tlv_type = 0x10,332.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,333fw_ready_enable),334},335{336.data_type = QMI_OPT_FLAG,337.elem_len = 1,338.elem_size = sizeof(u8),339.array_type = NO_ARRAY,340.tlv_type = 0x11,341.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,342initiate_cal_download_enable_valid),343},344{345.data_type = QMI_UNSIGNED_1_BYTE,346.elem_len = 1,347.elem_size = sizeof(u8),348.array_type = NO_ARRAY,349.tlv_type = 0x11,350.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,351initiate_cal_download_enable),352},353{354.data_type = QMI_OPT_FLAG,355.elem_len = 1,356.elem_size = sizeof(u8),357.array_type = NO_ARRAY,358.tlv_type = 0x12,359.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,360initiate_cal_update_enable_valid),361},362{363.data_type = QMI_UNSIGNED_1_BYTE,364.elem_len = 1,365.elem_size = sizeof(u8),366.array_type = NO_ARRAY,367.tlv_type = 0x12,368.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,369initiate_cal_update_enable),370},371{372.data_type = QMI_OPT_FLAG,373.elem_len = 1,374.elem_size = sizeof(u8),375.array_type = NO_ARRAY,376.tlv_type = 0x13,377.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,378msa_ready_enable_valid),379},380{381.data_type = QMI_UNSIGNED_1_BYTE,382.elem_len = 1,383.elem_size = sizeof(u8),384.array_type = NO_ARRAY,385.tlv_type = 0x13,386.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,387msa_ready_enable),388},389{390.data_type = QMI_OPT_FLAG,391.elem_len = 1,392.elem_size = sizeof(u8),393.array_type = NO_ARRAY,394.tlv_type = 0x14,395.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,396pin_connect_result_enable_valid),397},398{399.data_type = QMI_UNSIGNED_1_BYTE,400.elem_len = 1,401.elem_size = sizeof(u8),402.array_type = NO_ARRAY,403.tlv_type = 0x14,404.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,405pin_connect_result_enable),406},407{408.data_type = QMI_OPT_FLAG,409.elem_len = 1,410.elem_size = sizeof(u8),411.array_type = NO_ARRAY,412.tlv_type = 0x15,413.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,414client_id_valid),415},416{417.data_type = QMI_UNSIGNED_4_BYTE,418.elem_len = 1,419.elem_size = sizeof(u32),420.array_type = NO_ARRAY,421.tlv_type = 0x15,422.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,423client_id),424},425{426.data_type = QMI_OPT_FLAG,427.elem_len = 1,428.elem_size = sizeof(u8),429.array_type = NO_ARRAY,430.tlv_type = 0x16,431.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,432request_mem_enable_valid),433},434{435.data_type = QMI_UNSIGNED_1_BYTE,436.elem_len = 1,437.elem_size = sizeof(u8),438.array_type = NO_ARRAY,439.tlv_type = 0x16,440.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,441request_mem_enable),442},443{444.data_type = QMI_OPT_FLAG,445.elem_len = 1,446.elem_size = sizeof(u8),447.array_type = NO_ARRAY,448.tlv_type = 0x17,449.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,450fw_mem_ready_enable_valid),451},452{453.data_type = QMI_UNSIGNED_1_BYTE,454.elem_len = 1,455.elem_size = sizeof(u8),456.array_type = NO_ARRAY,457.tlv_type = 0x17,458.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,459fw_mem_ready_enable),460},461{462.data_type = QMI_OPT_FLAG,463.elem_len = 1,464.elem_size = sizeof(u8),465.array_type = NO_ARRAY,466.tlv_type = 0x18,467.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,468fw_init_done_enable_valid),469},470{471.data_type = QMI_UNSIGNED_1_BYTE,472.elem_len = 1,473.elem_size = sizeof(u8),474.array_type = NO_ARRAY,475.tlv_type = 0x18,476.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,477fw_init_done_enable),478},479480{481.data_type = QMI_OPT_FLAG,482.elem_len = 1,483.elem_size = sizeof(u8),484.array_type = NO_ARRAY,485.tlv_type = 0x19,486.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,487rejuvenate_enable_valid),488},489{490.data_type = QMI_UNSIGNED_1_BYTE,491.elem_len = 1,492.elem_size = sizeof(u8),493.array_type = NO_ARRAY,494.tlv_type = 0x19,495.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,496rejuvenate_enable),497},498{499.data_type = QMI_OPT_FLAG,500.elem_len = 1,501.elem_size = sizeof(u8),502.array_type = NO_ARRAY,503.tlv_type = 0x1A,504.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,505xo_cal_enable_valid),506},507{508.data_type = QMI_UNSIGNED_1_BYTE,509.elem_len = 1,510.elem_size = sizeof(u8),511.array_type = NO_ARRAY,512.tlv_type = 0x1A,513.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,514xo_cal_enable),515},516{517.data_type = QMI_OPT_FLAG,518.elem_len = 1,519.elem_size = sizeof(u8),520.array_type = NO_ARRAY,521.tlv_type = 0x1B,522.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,523cal_done_enable_valid),524},525{526.data_type = QMI_UNSIGNED_1_BYTE,527.elem_len = 1,528.elem_size = sizeof(u8),529.array_type = NO_ARRAY,530.tlv_type = 0x1B,531.offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01,532cal_done_enable),533},534{535.data_type = QMI_EOTI,536.array_type = NO_ARRAY,537.tlv_type = QMI_COMMON_TLV_TYPE,538},539};540541static const struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = {542{543.data_type = QMI_STRUCT,544.elem_len = 1,545.elem_size = sizeof(struct qmi_response_type_v01),546.array_type = NO_ARRAY,547.tlv_type = 0x02,548.offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,549resp),550.ei_array = qmi_response_type_v01_ei,551},552{553.data_type = QMI_OPT_FLAG,554.elem_len = 1,555.elem_size = sizeof(u8),556.array_type = NO_ARRAY,557.tlv_type = 0x10,558.offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,559fw_status_valid),560},561{562.data_type = QMI_UNSIGNED_8_BYTE,563.elem_len = 1,564.elem_size = sizeof(u64),565.array_type = NO_ARRAY,566.tlv_type = 0x10,567.offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01,568fw_status),569},570{571.data_type = QMI_EOTI,572.array_type = NO_ARRAY,573.tlv_type = QMI_COMMON_TLV_TYPE,574},575};576577static const struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = {578{579.data_type = QMI_UNSIGNED_8_BYTE,580.elem_len = 1,581.elem_size = sizeof(u64),582.array_type = NO_ARRAY,583.tlv_type = 0,584.offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset),585},586{587.data_type = QMI_UNSIGNED_4_BYTE,588.elem_len = 1,589.elem_size = sizeof(u32),590.array_type = NO_ARRAY,591.tlv_type = 0,592.offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size),593},594{595.data_type = QMI_UNSIGNED_1_BYTE,596.elem_len = 1,597.elem_size = sizeof(u8),598.array_type = NO_ARRAY,599.tlv_type = 0,600.offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag),601},602{603.data_type = QMI_EOTI,604.array_type = NO_ARRAY,605.tlv_type = QMI_COMMON_TLV_TYPE,606},607};608609static const struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = {610{611.data_type = QMI_UNSIGNED_4_BYTE,612.elem_len = 1,613.elem_size = sizeof(u32),614.array_type = NO_ARRAY,615.tlv_type = 0,616.offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01,617size),618},619{620.data_type = QMI_SIGNED_4_BYTE_ENUM,621.elem_len = 1,622.elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),623.array_type = NO_ARRAY,624.tlv_type = 0,625.offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type),626},627{628.data_type = QMI_DATA_LEN,629.elem_len = 1,630.elem_size = sizeof(u8),631.array_type = NO_ARRAY,632.tlv_type = 0,633.offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len),634},635{636.data_type = QMI_STRUCT,637.elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01,638.elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01),639.array_type = VAR_LEN_ARRAY,640.tlv_type = 0,641.offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg),642.ei_array = qmi_wlanfw_mem_cfg_s_v01_ei,643},644{645.data_type = QMI_EOTI,646.array_type = NO_ARRAY,647.tlv_type = QMI_COMMON_TLV_TYPE,648},649};650651static const struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = {652{653.data_type = QMI_DATA_LEN,654.elem_len = 1,655.elem_size = sizeof(u8),656.array_type = NO_ARRAY,657.tlv_type = 0x01,658.offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,659mem_seg_len),660},661{662.data_type = QMI_STRUCT,663.elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,664.elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01),665.array_type = VAR_LEN_ARRAY,666.tlv_type = 0x01,667.offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01,668mem_seg),669.ei_array = qmi_wlanfw_mem_seg_s_v01_ei,670},671{672.data_type = QMI_EOTI,673.array_type = NO_ARRAY,674.tlv_type = QMI_COMMON_TLV_TYPE,675},676};677678static const struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = {679{680.data_type = QMI_UNSIGNED_8_BYTE,681.elem_len = 1,682.elem_size = sizeof(u64),683.array_type = NO_ARRAY,684.tlv_type = 0,685.offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr),686},687{688.data_type = QMI_UNSIGNED_4_BYTE,689.elem_len = 1,690.elem_size = sizeof(u32),691.array_type = NO_ARRAY,692.tlv_type = 0,693.offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size),694},695{696.data_type = QMI_SIGNED_4_BYTE_ENUM,697.elem_len = 1,698.elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01),699.array_type = NO_ARRAY,700.tlv_type = 0,701.offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type),702},703{704.data_type = QMI_UNSIGNED_1_BYTE,705.elem_len = 1,706.elem_size = sizeof(u8),707.array_type = NO_ARRAY,708.tlv_type = 0,709.offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore),710},711{712.data_type = QMI_EOTI,713.array_type = NO_ARRAY,714.tlv_type = QMI_COMMON_TLV_TYPE,715},716};717718static const struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = {719{720.data_type = QMI_DATA_LEN,721.elem_len = 1,722.elem_size = sizeof(u8),723.array_type = NO_ARRAY,724.tlv_type = 0x01,725.offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,726mem_seg_len),727},728{729.data_type = QMI_STRUCT,730.elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01,731.elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01),732.array_type = VAR_LEN_ARRAY,733.tlv_type = 0x01,734.offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01,735mem_seg),736.ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei,737},738{739.data_type = QMI_EOTI,740.array_type = NO_ARRAY,741.tlv_type = QMI_COMMON_TLV_TYPE,742},743};744745static const struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = {746{747.data_type = QMI_STRUCT,748.elem_len = 1,749.elem_size = sizeof(struct qmi_response_type_v01),750.array_type = NO_ARRAY,751.tlv_type = 0x02,752.offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01,753resp),754.ei_array = qmi_response_type_v01_ei,755},756{757.data_type = QMI_EOTI,758.array_type = NO_ARRAY,759.tlv_type = QMI_COMMON_TLV_TYPE,760},761};762763static const struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = {764{765.data_type = QMI_EOTI,766.array_type = NO_ARRAY,767.tlv_type = QMI_COMMON_TLV_TYPE,768},769};770771static const struct qmi_elem_info qmi_wlanfw_device_info_req_msg_v01_ei[] = {772{773.data_type = QMI_EOTI,774.array_type = NO_ARRAY,775.tlv_type = QMI_COMMON_TLV_TYPE,776},777};778779static const struct qmi_elem_info qmi_wlfw_device_info_resp_msg_v01_ei[] = {780{781.data_type = QMI_STRUCT,782.elem_len = 1,783.elem_size = sizeof(struct qmi_response_type_v01),784.array_type = NO_ARRAY,785.tlv_type = 0x02,786.offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,787resp),788.ei_array = qmi_response_type_v01_ei,789},790{791.data_type = QMI_OPT_FLAG,792.elem_len = 1,793.elem_size = sizeof(u8),794.array_type = NO_ARRAY,795.tlv_type = 0x10,796.offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,797bar_addr_valid),798},799{800.data_type = QMI_UNSIGNED_8_BYTE,801.elem_len = 1,802.elem_size = sizeof(u64),803.array_type = NO_ARRAY,804.tlv_type = 0x10,805.offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,806bar_addr),807},808{809.data_type = QMI_OPT_FLAG,810.elem_len = 1,811.elem_size = sizeof(u8),812.array_type = NO_ARRAY,813.tlv_type = 0x11,814.offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,815bar_size_valid),816},817{818.data_type = QMI_UNSIGNED_4_BYTE,819.elem_len = 1,820.elem_size = sizeof(u32),821.array_type = NO_ARRAY,822.tlv_type = 0x11,823.offset = offsetof(struct qmi_wlanfw_device_info_resp_msg_v01,824bar_size),825},826{827.data_type = QMI_EOTI,828.array_type = NO_ARRAY,829.tlv_type = QMI_COMMON_TLV_TYPE,830},831};832833static const struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = {834{835.data_type = QMI_UNSIGNED_4_BYTE,836.elem_len = 1,837.elem_size = sizeof(u32),838.array_type = NO_ARRAY,839.tlv_type = 0,840.offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,841chip_id),842},843{844.data_type = QMI_UNSIGNED_4_BYTE,845.elem_len = 1,846.elem_size = sizeof(u32),847.array_type = NO_ARRAY,848.tlv_type = 0,849.offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01,850chip_family),851},852{853.data_type = QMI_EOTI,854.array_type = NO_ARRAY,855.tlv_type = QMI_COMMON_TLV_TYPE,856},857};858859static const struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = {860{861.data_type = QMI_UNSIGNED_4_BYTE,862.elem_len = 1,863.elem_size = sizeof(u32),864.array_type = NO_ARRAY,865.tlv_type = 0,866.offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01,867board_id),868},869{870.data_type = QMI_EOTI,871.array_type = NO_ARRAY,872.tlv_type = QMI_COMMON_TLV_TYPE,873},874};875876static const struct qmi_elem_info qmi_wlanfw_soc_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_soc_info_s_v01, soc_id),884},885{886.data_type = QMI_EOTI,887.array_type = NO_ARRAY,888.tlv_type = QMI_COMMON_TLV_TYPE,889},890};891892static const struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = {893{894.data_type = QMI_UNSIGNED_4_BYTE,895.elem_len = 1,896.elem_size = sizeof(u32),897.array_type = NO_ARRAY,898.tlv_type = 0,899.offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,900fw_version),901},902{903.data_type = QMI_STRING,904.elem_len = ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1,905.elem_size = sizeof(char),906.array_type = NO_ARRAY,907.tlv_type = 0,908.offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01,909fw_build_timestamp),910},911{912.data_type = QMI_EOTI,913.array_type = NO_ARRAY,914.tlv_type = QMI_COMMON_TLV_TYPE,915},916};917918static const struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = {919{920.data_type = QMI_STRUCT,921.elem_len = 1,922.elem_size = sizeof(struct qmi_response_type_v01),923.array_type = NO_ARRAY,924.tlv_type = 0x02,925.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp),926.ei_array = qmi_response_type_v01_ei,927},928{929.data_type = QMI_OPT_FLAG,930.elem_len = 1,931.elem_size = sizeof(u8),932.array_type = NO_ARRAY,933.tlv_type = 0x10,934.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,935chip_info_valid),936},937{938.data_type = QMI_STRUCT,939.elem_len = 1,940.elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01),941.array_type = NO_ARRAY,942.tlv_type = 0x10,943.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,944chip_info),945.ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei,946},947{948.data_type = QMI_OPT_FLAG,949.elem_len = 1,950.elem_size = sizeof(u8),951.array_type = NO_ARRAY,952.tlv_type = 0x11,953.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,954board_info_valid),955},956{957.data_type = QMI_STRUCT,958.elem_len = 1,959.elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01),960.array_type = NO_ARRAY,961.tlv_type = 0x11,962.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,963board_info),964.ei_array = qmi_wlanfw_rf_board_info_s_v01_ei,965},966{967.data_type = QMI_OPT_FLAG,968.elem_len = 1,969.elem_size = sizeof(u8),970.array_type = NO_ARRAY,971.tlv_type = 0x12,972.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,973soc_info_valid),974},975{976.data_type = QMI_STRUCT,977.elem_len = 1,978.elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01),979.array_type = NO_ARRAY,980.tlv_type = 0x12,981.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,982soc_info),983.ei_array = qmi_wlanfw_soc_info_s_v01_ei,984},985{986.data_type = QMI_OPT_FLAG,987.elem_len = 1,988.elem_size = sizeof(u8),989.array_type = NO_ARRAY,990.tlv_type = 0x13,991.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,992fw_version_info_valid),993},994{995.data_type = QMI_STRUCT,996.elem_len = 1,997.elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01),998.array_type = NO_ARRAY,999.tlv_type = 0x13,1000.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1001fw_version_info),1002.ei_array = qmi_wlanfw_fw_version_info_s_v01_ei,1003},1004{1005.data_type = QMI_OPT_FLAG,1006.elem_len = 1,1007.elem_size = sizeof(u8),1008.array_type = NO_ARRAY,1009.tlv_type = 0x14,1010.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1011fw_build_id_valid),1012},1013{1014.data_type = QMI_STRING,1015.elem_len = ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1,1016.elem_size = sizeof(char),1017.array_type = NO_ARRAY,1018.tlv_type = 0x14,1019.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1020fw_build_id),1021},1022{1023.data_type = QMI_OPT_FLAG,1024.elem_len = 1,1025.elem_size = sizeof(u8),1026.array_type = NO_ARRAY,1027.tlv_type = 0x15,1028.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1029num_macs_valid),1030},1031{1032.data_type = QMI_UNSIGNED_1_BYTE,1033.elem_len = 1,1034.elem_size = sizeof(u8),1035.array_type = NO_ARRAY,1036.tlv_type = 0x15,1037.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1038num_macs),1039},1040{1041.data_type = QMI_OPT_FLAG,1042.elem_len = 1,1043.elem_size = sizeof(u8),1044.array_type = NO_ARRAY,1045.tlv_type = 0x16,1046.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1047voltage_mv_valid),1048},1049{1050.data_type = QMI_UNSIGNED_4_BYTE,1051.elem_len = 1,1052.elem_size = sizeof(u32),1053.array_type = NO_ARRAY,1054.tlv_type = 0x16,1055.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1056voltage_mv),1057},1058{1059.data_type = QMI_OPT_FLAG,1060.elem_len = 1,1061.elem_size = sizeof(u8),1062.array_type = NO_ARRAY,1063.tlv_type = 0x17,1064.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1065time_freq_hz_valid),1066},1067{1068.data_type = QMI_UNSIGNED_4_BYTE,1069.elem_len = 1,1070.elem_size = sizeof(u32),1071.array_type = NO_ARRAY,1072.tlv_type = 0x17,1073.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1074time_freq_hz),1075},1076{1077.data_type = QMI_OPT_FLAG,1078.elem_len = 1,1079.elem_size = sizeof(u8),1080.array_type = NO_ARRAY,1081.tlv_type = 0x18,1082.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1083otp_version_valid),1084},1085{1086.data_type = QMI_UNSIGNED_4_BYTE,1087.elem_len = 1,1088.elem_size = sizeof(u32),1089.array_type = NO_ARRAY,1090.tlv_type = 0x18,1091.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1092otp_version),1093},1094{1095.data_type = QMI_OPT_FLAG,1096.elem_len = 1,1097.elem_size = sizeof(u8),1098.array_type = NO_ARRAY,1099.tlv_type = 0x19,1100.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1101eeprom_read_timeout_valid),1102},1103{1104.data_type = QMI_UNSIGNED_4_BYTE,1105.elem_len = 1,1106.elem_size = sizeof(u32),1107.array_type = NO_ARRAY,1108.tlv_type = 0x19,1109.offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01,1110eeprom_read_timeout),1111},1112{1113.data_type = QMI_EOTI,1114.array_type = NO_ARRAY,1115.tlv_type = QMI_COMMON_TLV_TYPE,1116},1117};11181119static const struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = {1120{1121.data_type = QMI_UNSIGNED_1_BYTE,1122.elem_len = 1,1123.elem_size = sizeof(u8),1124.array_type = NO_ARRAY,1125.tlv_type = 0x01,1126.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1127valid),1128},1129{1130.data_type = QMI_OPT_FLAG,1131.elem_len = 1,1132.elem_size = sizeof(u8),1133.array_type = NO_ARRAY,1134.tlv_type = 0x10,1135.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1136file_id_valid),1137},1138{1139.data_type = QMI_SIGNED_4_BYTE_ENUM,1140.elem_len = 1,1141.elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01),1142.array_type = NO_ARRAY,1143.tlv_type = 0x10,1144.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1145file_id),1146},1147{1148.data_type = QMI_OPT_FLAG,1149.elem_len = 1,1150.elem_size = sizeof(u8),1151.array_type = NO_ARRAY,1152.tlv_type = 0x11,1153.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1154total_size_valid),1155},1156{1157.data_type = QMI_UNSIGNED_4_BYTE,1158.elem_len = 1,1159.elem_size = sizeof(u32),1160.array_type = NO_ARRAY,1161.tlv_type = 0x11,1162.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1163total_size),1164},1165{1166.data_type = QMI_OPT_FLAG,1167.elem_len = 1,1168.elem_size = sizeof(u8),1169.array_type = NO_ARRAY,1170.tlv_type = 0x12,1171.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1172seg_id_valid),1173},1174{1175.data_type = QMI_UNSIGNED_4_BYTE,1176.elem_len = 1,1177.elem_size = sizeof(u32),1178.array_type = NO_ARRAY,1179.tlv_type = 0x12,1180.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1181seg_id),1182},1183{1184.data_type = QMI_OPT_FLAG,1185.elem_len = 1,1186.elem_size = sizeof(u8),1187.array_type = NO_ARRAY,1188.tlv_type = 0x13,1189.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1190data_valid),1191},1192{1193.data_type = QMI_DATA_LEN,1194.elem_len = 1,1195.elem_size = sizeof(u16),1196.array_type = NO_ARRAY,1197.tlv_type = 0x13,1198.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1199data_len),1200},1201{1202.data_type = QMI_UNSIGNED_1_BYTE,1203.elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01,1204.elem_size = sizeof(u8),1205.array_type = VAR_LEN_ARRAY,1206.tlv_type = 0x13,1207.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1208data),1209},1210{1211.data_type = QMI_OPT_FLAG,1212.elem_len = 1,1213.elem_size = sizeof(u8),1214.array_type = NO_ARRAY,1215.tlv_type = 0x14,1216.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1217end_valid),1218},1219{1220.data_type = QMI_UNSIGNED_1_BYTE,1221.elem_len = 1,1222.elem_size = sizeof(u8),1223.array_type = NO_ARRAY,1224.tlv_type = 0x14,1225.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1226end),1227},1228{1229.data_type = QMI_OPT_FLAG,1230.elem_len = 1,1231.elem_size = sizeof(u8),1232.array_type = NO_ARRAY,1233.tlv_type = 0x15,1234.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1235bdf_type_valid),1236},1237{1238.data_type = QMI_UNSIGNED_1_BYTE,1239.elem_len = 1,1240.elem_size = sizeof(u8),1241.array_type = NO_ARRAY,1242.tlv_type = 0x15,1243.offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01,1244bdf_type),1245},12461247{1248.data_type = QMI_EOTI,1249.array_type = NO_ARRAY,1250.tlv_type = QMI_COMMON_TLV_TYPE,1251},1252};12531254static const struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = {1255{1256.data_type = QMI_STRUCT,1257.elem_len = 1,1258.elem_size = sizeof(struct qmi_response_type_v01),1259.array_type = NO_ARRAY,1260.tlv_type = 0x02,1261.offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01,1262resp),1263.ei_array = qmi_response_type_v01_ei,1264},1265{1266.data_type = QMI_EOTI,1267.array_type = NO_ARRAY,1268.tlv_type = QMI_COMMON_TLV_TYPE,1269},1270};12711272static const struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = {1273{1274.data_type = QMI_UNSIGNED_8_BYTE,1275.elem_len = 1,1276.elem_size = sizeof(u64),1277.array_type = NO_ARRAY,1278.tlv_type = 0x01,1279.offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr),1280},1281{1282.data_type = QMI_UNSIGNED_4_BYTE,1283.elem_len = 1,1284.elem_size = sizeof(u32),1285.array_type = NO_ARRAY,1286.tlv_type = 0x02,1287.offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size),1288},1289{1290.data_type = QMI_EOTI,1291.array_type = NO_ARRAY,1292.tlv_type = QMI_COMMON_TLV_TYPE,1293},1294};12951296static const struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = {1297{1298.data_type = QMI_STRUCT,1299.elem_len = 1,1300.elem_size = sizeof(struct qmi_response_type_v01),1301.array_type = NO_ARRAY,1302.tlv_type = 0x02,1303.offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp),1304.ei_array = qmi_response_type_v01_ei,1305},1306{1307.data_type = QMI_EOTI,1308.array_type = NO_ARRAY,1309.tlv_type = QMI_COMMON_TLV_TYPE,1310},1311};13121313static const struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = {1314{1315.data_type = QMI_UNSIGNED_4_BYTE,1316.elem_len = 1,1317.elem_size = sizeof(u32),1318.array_type = NO_ARRAY,1319.tlv_type = 0,1320.offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1321pipe_num),1322},1323{1324.data_type = QMI_SIGNED_4_BYTE_ENUM,1325.elem_len = 1,1326.elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),1327.array_type = NO_ARRAY,1328.tlv_type = 0,1329.offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1330pipe_dir),1331},1332{1333.data_type = QMI_UNSIGNED_4_BYTE,1334.elem_len = 1,1335.elem_size = sizeof(u32),1336.array_type = NO_ARRAY,1337.tlv_type = 0,1338.offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1339nentries),1340},1341{1342.data_type = QMI_UNSIGNED_4_BYTE,1343.elem_len = 1,1344.elem_size = sizeof(u32),1345.array_type = NO_ARRAY,1346.tlv_type = 0,1347.offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1348nbytes_max),1349},1350{1351.data_type = QMI_UNSIGNED_4_BYTE,1352.elem_len = 1,1353.elem_size = sizeof(u32),1354.array_type = NO_ARRAY,1355.tlv_type = 0,1356.offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01,1357flags),1358},1359{1360.data_type = QMI_EOTI,1361.array_type = NO_ARRAY,1362.tlv_type = QMI_COMMON_TLV_TYPE,1363},1364};13651366static const struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = {1367{1368.data_type = QMI_UNSIGNED_4_BYTE,1369.elem_len = 1,1370.elem_size = sizeof(u32),1371.array_type = NO_ARRAY,1372.tlv_type = 0,1373.offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1374service_id),1375},1376{1377.data_type = QMI_SIGNED_4_BYTE_ENUM,1378.elem_len = 1,1379.elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01),1380.array_type = NO_ARRAY,1381.tlv_type = 0,1382.offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1383pipe_dir),1384},1385{1386.data_type = QMI_UNSIGNED_4_BYTE,1387.elem_len = 1,1388.elem_size = sizeof(u32),1389.array_type = NO_ARRAY,1390.tlv_type = 0,1391.offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01,1392pipe_num),1393},1394{1395.data_type = QMI_EOTI,1396.array_type = NO_ARRAY,1397.tlv_type = QMI_COMMON_TLV_TYPE,1398},1399};14001401static const struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = {1402{1403.data_type = QMI_UNSIGNED_2_BYTE,1404.elem_len = 1,1405.elem_size = sizeof(u16),1406.array_type = NO_ARRAY,1407.tlv_type = 0,1408.offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id),1409},1410{1411.data_type = QMI_UNSIGNED_2_BYTE,1412.elem_len = 1,1413.elem_size = sizeof(u16),1414.array_type = NO_ARRAY,1415.tlv_type = 0,1416.offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01,1417offset),1418},1419{1420.data_type = QMI_EOTI,1421.array_type = QMI_COMMON_TLV_TYPE,1422},1423};14241425static const struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = {1426{1427.data_type = QMI_UNSIGNED_4_BYTE,1428.elem_len = 1,1429.elem_size = sizeof(u32),1430.array_type = NO_ARRAY,1431.tlv_type = 0,1432.offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01,1433addr),1434},1435{1436.data_type = QMI_EOTI,1437.array_type = NO_ARRAY,1438.tlv_type = QMI_COMMON_TLV_TYPE,1439},1440};14411442static const struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = {1443{1444.data_type = QMI_UNSIGNED_4_BYTE,1445.elem_len = 1,1446.elem_size = sizeof(u32),1447.array_type = NO_ARRAY,1448.tlv_type = 0x01,1449.offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1450mode),1451},1452{1453.data_type = QMI_OPT_FLAG,1454.elem_len = 1,1455.elem_size = sizeof(u8),1456.array_type = NO_ARRAY,1457.tlv_type = 0x10,1458.offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1459hw_debug_valid),1460},1461{1462.data_type = QMI_UNSIGNED_1_BYTE,1463.elem_len = 1,1464.elem_size = sizeof(u8),1465.array_type = NO_ARRAY,1466.tlv_type = 0x10,1467.offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01,1468hw_debug),1469},1470{1471.data_type = QMI_EOTI,1472.array_type = NO_ARRAY,1473.tlv_type = QMI_COMMON_TLV_TYPE,1474},1475};14761477static const struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = {1478{1479.data_type = QMI_STRUCT,1480.elem_len = 1,1481.elem_size = sizeof(struct qmi_response_type_v01),1482.array_type = NO_ARRAY,1483.tlv_type = 0x02,1484.offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01,1485resp),1486.ei_array = qmi_response_type_v01_ei,1487},1488{1489.data_type = QMI_EOTI,1490.array_type = NO_ARRAY,1491.tlv_type = QMI_COMMON_TLV_TYPE,1492},1493};14941495static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = {1496{1497.data_type = QMI_OPT_FLAG,1498.elem_len = 1,1499.elem_size = sizeof(u8),1500.array_type = NO_ARRAY,1501.tlv_type = 0x10,1502.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1503host_version_valid),1504},1505{1506.data_type = QMI_STRING,1507.elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1,1508.elem_size = sizeof(char),1509.array_type = NO_ARRAY,1510.tlv_type = 0x10,1511.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1512host_version),1513},1514{1515.data_type = QMI_OPT_FLAG,1516.elem_len = 1,1517.elem_size = sizeof(u8),1518.array_type = NO_ARRAY,1519.tlv_type = 0x11,1520.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1521tgt_cfg_valid),1522},1523{1524.data_type = QMI_DATA_LEN,1525.elem_len = 1,1526.elem_size = sizeof(u8),1527.array_type = NO_ARRAY,1528.tlv_type = 0x11,1529.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1530tgt_cfg_len),1531},1532{1533.data_type = QMI_STRUCT,1534.elem_len = QMI_WLANFW_MAX_NUM_CE_V01,1535.elem_size = sizeof(1536struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01),1537.array_type = VAR_LEN_ARRAY,1538.tlv_type = 0x11,1539.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1540tgt_cfg),1541.ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei,1542},1543{1544.data_type = QMI_OPT_FLAG,1545.elem_len = 1,1546.elem_size = sizeof(u8),1547.array_type = NO_ARRAY,1548.tlv_type = 0x12,1549.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1550svc_cfg_valid),1551},1552{1553.data_type = QMI_DATA_LEN,1554.elem_len = 1,1555.elem_size = sizeof(u8),1556.array_type = NO_ARRAY,1557.tlv_type = 0x12,1558.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1559svc_cfg_len),1560},1561{1562.data_type = QMI_STRUCT,1563.elem_len = QMI_WLANFW_MAX_NUM_SVC_V01,1564.elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01),1565.array_type = VAR_LEN_ARRAY,1566.tlv_type = 0x12,1567.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1568svc_cfg),1569.ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei,1570},1571{1572.data_type = QMI_OPT_FLAG,1573.elem_len = 1,1574.elem_size = sizeof(u8),1575.array_type = NO_ARRAY,1576.tlv_type = 0x13,1577.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1578shadow_reg_valid),1579},1580{1581.data_type = QMI_DATA_LEN,1582.elem_len = 1,1583.elem_size = sizeof(u8),1584.array_type = NO_ARRAY,1585.tlv_type = 0x13,1586.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1587shadow_reg_len),1588},1589{1590.data_type = QMI_STRUCT,1591.elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01,1592.elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01),1593.array_type = VAR_LEN_ARRAY,1594.tlv_type = 0x13,1595.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1596shadow_reg),1597.ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei,1598},1599{1600.data_type = QMI_OPT_FLAG,1601.elem_len = 1,1602.elem_size = sizeof(u8),1603.array_type = NO_ARRAY,1604.tlv_type = 0x14,1605.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1606shadow_reg_v2_valid),1607},1608{1609.data_type = QMI_DATA_LEN,1610.elem_len = 1,1611.elem_size = sizeof(u8),1612.array_type = NO_ARRAY,1613.tlv_type = 0x14,1614.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1615shadow_reg_v2_len),1616},1617{1618.data_type = QMI_STRUCT,1619.elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01,1620.elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01),1621.array_type = VAR_LEN_ARRAY,1622.tlv_type = 0x14,1623.offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01,1624shadow_reg_v2),1625.ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei,1626},1627{1628.data_type = QMI_EOTI,1629.array_type = NO_ARRAY,1630.tlv_type = QMI_COMMON_TLV_TYPE,1631},1632};16331634static const struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = {1635{1636.data_type = QMI_STRUCT,1637.elem_len = 1,1638.elem_size = sizeof(struct qmi_response_type_v01),1639.array_type = NO_ARRAY,1640.tlv_type = 0x02,1641.offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp),1642.ei_array = qmi_response_type_v01_ei,1643},1644{1645.data_type = QMI_EOTI,1646.array_type = NO_ARRAY,1647.tlv_type = QMI_COMMON_TLV_TYPE,1648},1649};16501651static const struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = {1652{1653.data_type = QMI_EOTI,1654.array_type = NO_ARRAY,1655},1656};16571658static const struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = {1659{1660.data_type = QMI_EOTI,1661.array_type = NO_ARRAY,1662},1663};16641665static const struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = {1666{1667.data_type = QMI_EOTI,1668.array_type = NO_ARRAY,1669},1670};16711672static const struct qmi_elem_info qmi_wlanfw_wlan_ini_req_msg_v01_ei[] = {1673{1674.data_type = QMI_OPT_FLAG,1675.elem_len = 1,1676.elem_size = sizeof(u8),1677.array_type = NO_ARRAY,1678.tlv_type = 0x10,1679.offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,1680enablefwlog_valid),1681},1682{1683.data_type = QMI_UNSIGNED_1_BYTE,1684.elem_len = 1,1685.elem_size = sizeof(u8),1686.array_type = NO_ARRAY,1687.tlv_type = 0x10,1688.offset = offsetof(struct qmi_wlanfw_wlan_ini_req_msg_v01,1689enablefwlog),1690},1691{1692.data_type = QMI_EOTI,1693.array_type = NO_ARRAY,1694.tlv_type = QMI_COMMON_TLV_TYPE,1695},1696};16971698static const struct qmi_elem_info qmi_wlanfw_wlan_ini_resp_msg_v01_ei[] = {1699{1700.data_type = QMI_STRUCT,1701.elem_len = 1,1702.elem_size = sizeof(struct qmi_response_type_v01),1703.array_type = NO_ARRAY,1704.tlv_type = 0x02,1705.offset = offsetof(struct qmi_wlanfw_wlan_ini_resp_msg_v01,1706resp),1707.ei_array = qmi_response_type_v01_ei,1708},1709{1710.data_type = QMI_EOTI,1711.array_type = NO_ARRAY,1712.tlv_type = QMI_COMMON_TLV_TYPE,1713},1714};17151716static const struct qmi_elem_info qmi_wlfw_fw_init_done_ind_msg_v01_ei[] = {1717{1718.data_type = QMI_EOTI,1719.array_type = NO_ARRAY,1720},1721};17221723/* clang stack usage explodes if this is inlined */1724static noinline_for_stack1725int ath11k_qmi_host_cap_send(struct ath11k_base *ab)1726{1727struct qmi_wlanfw_host_cap_req_msg_v01 req;1728struct qmi_wlanfw_host_cap_resp_msg_v01 resp;1729struct qmi_txn txn;1730int ret = 0;17311732memset(&req, 0, sizeof(req));1733memset(&resp, 0, sizeof(resp));17341735req.num_clients_valid = 1;1736req.num_clients = 1;1737req.mem_cfg_mode = ab->qmi.target_mem_mode;1738req.mem_cfg_mode_valid = 1;1739req.bdf_support_valid = 1;1740req.bdf_support = 1;17411742if (ab->hw_params.m3_fw_support) {1743req.m3_support_valid = 1;1744req.m3_support = 1;1745req.m3_cache_support_valid = 1;1746req.m3_cache_support = 1;1747} else {1748req.m3_support_valid = 0;1749req.m3_support = 0;1750req.m3_cache_support_valid = 0;1751req.m3_cache_support = 0;1752}17531754req.cal_done_valid = 1;1755req.cal_done = ab->qmi.cal_done;17561757if (ab->hw_params.internal_sleep_clock) {1758req.nm_modem_valid = 1;17591760/* Notify firmware that this is non-qualcomm platform. */1761req.nm_modem |= HOST_CSTATE_BIT;17621763/* Notify firmware about the sleep clock selection,1764* nm_modem_bit[1] is used for this purpose. Host driver on1765* non-qualcomm platforms should select internal sleep1766* clock.1767*/1768req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT;1769}17701771if (ab->hw_params.global_reset)1772req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET;17731774req.nm_modem |= PLATFORM_CAP_PCIE_PME_D3COLD;17751776ath11k_dbg(ab, ATH11K_DBG_QMI, "host cap request\n");17771778ret = qmi_txn_init(&ab->qmi.handle, &txn,1779qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);1780if (ret < 0)1781goto out;17821783ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1784QMI_WLANFW_HOST_CAP_REQ_V01,1785QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN,1786qmi_wlanfw_host_cap_req_msg_v01_ei, &req);1787if (ret < 0) {1788qmi_txn_cancel(&txn);1789ath11k_warn(ab, "failed to send host capability request: %d\n", ret);1790goto out;1791}17921793ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1794if (ret < 0)1795goto out;17961797if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {1798ath11k_warn(ab, "host capability request failed: %d %d\n",1799resp.resp.result, resp.resp.error);1800ret = -EINVAL;1801goto out;1802}18031804out:1805return ret;1806}18071808static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab)1809{1810struct qmi_wlanfw_ind_register_req_msg_v01 *req;1811struct qmi_wlanfw_ind_register_resp_msg_v01 *resp;1812struct qmi_handle *handle = &ab->qmi.handle;1813struct qmi_txn txn;1814int ret;18151816req = kzalloc(sizeof(*req), GFP_KERNEL);1817if (!req)1818return -ENOMEM;18191820resp = kzalloc(sizeof(*resp), GFP_KERNEL);1821if (!resp) {1822ret = -ENOMEM;1823goto resp_out;1824}18251826req->client_id_valid = 1;1827req->client_id = QMI_WLANFW_CLIENT_ID;1828req->fw_ready_enable_valid = 1;1829req->fw_ready_enable = 1;1830req->cal_done_enable_valid = 1;1831req->cal_done_enable = 1;1832req->fw_init_done_enable_valid = 1;1833req->fw_init_done_enable = 1;18341835req->pin_connect_result_enable_valid = 0;1836req->pin_connect_result_enable = 0;18371838/* WCN6750 doesn't request for DDR memory via QMI,1839* instead it uses a fixed 12MB reserved memory1840* region in DDR.1841*/1842if (!ab->hw_params.fixed_fw_mem) {1843req->request_mem_enable_valid = 1;1844req->request_mem_enable = 1;1845req->fw_mem_ready_enable_valid = 1;1846req->fw_mem_ready_enable = 1;1847}18481849ret = qmi_txn_init(handle, &txn,1850qmi_wlanfw_ind_register_resp_msg_v01_ei, resp);1851if (ret < 0)1852goto out;18531854ath11k_dbg(ab, ATH11K_DBG_QMI, "indication register request\n");18551856ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1857QMI_WLANFW_IND_REGISTER_REQ_V01,1858QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN,1859qmi_wlanfw_ind_register_req_msg_v01_ei, req);1860if (ret < 0) {1861qmi_txn_cancel(&txn);1862ath11k_warn(ab, "failed to send indication register request: %d\n",1863ret);1864goto out;1865}18661867ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1868if (ret < 0) {1869ath11k_warn(ab, "failed to register fw indication: %d\n", ret);1870goto out;1871}18721873if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {1874ath11k_warn(ab, "firmware indication register request failed: %d %d\n",1875resp->resp.result, resp->resp.error);1876ret = -EINVAL;1877goto out;1878}18791880out:1881kfree(resp);1882resp_out:1883kfree(req);1884return ret;1885}18861887static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab)1888{1889struct qmi_wlanfw_respond_mem_req_msg_v01 *req;1890struct qmi_wlanfw_respond_mem_resp_msg_v01 resp;1891struct qmi_txn txn;1892int ret = 0, i;1893bool delayed;18941895req = kzalloc(sizeof(*req), GFP_KERNEL);1896if (!req)1897return -ENOMEM;18981899memset(&resp, 0, sizeof(resp));19001901/* For QCA6390 by default FW requests a block of ~4M contiguous1902* DMA memory, it's hard to allocate from OS. So host returns1903* failure to FW and FW will then request multiple blocks of small1904* chunk size memory.1905*/1906if (!(ab->hw_params.fixed_mem_region ||1907test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) &&1908ab->qmi.target_mem_delayed) {1909delayed = true;1910ath11k_dbg(ab, ATH11K_DBG_QMI, "delays mem_request %d\n",1911ab->qmi.mem_seg_count);1912memset(req, 0, sizeof(*req));1913} else {1914delayed = false;1915req->mem_seg_len = ab->qmi.mem_seg_count;19161917for (i = 0; i < req->mem_seg_len ; i++) {1918req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr;1919req->mem_seg[i].size = ab->qmi.target_mem[i].size;1920req->mem_seg[i].type = ab->qmi.target_mem[i].type;1921ath11k_dbg(ab, ATH11K_DBG_QMI,1922"req mem_seg[%d] %pad %u %u\n", i,1923&ab->qmi.target_mem[i].paddr,1924ab->qmi.target_mem[i].size,1925ab->qmi.target_mem[i].type);1926}1927}19281929ret = qmi_txn_init(&ab->qmi.handle, &txn,1930qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp);1931if (ret < 0)1932goto out;19331934ath11k_dbg(ab, ATH11K_DBG_QMI, "respond memory request delayed %i\n",1935delayed);19361937ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,1938QMI_WLANFW_RESPOND_MEM_REQ_V01,1939QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN,1940qmi_wlanfw_respond_mem_req_msg_v01_ei, req);1941if (ret < 0) {1942qmi_txn_cancel(&txn);1943ath11k_warn(ab, "failed to respond qmi memory request: %d\n",1944ret);1945goto out;1946}19471948ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));1949if (ret < 0) {1950ath11k_warn(ab, "failed to wait qmi memory request: %d\n", ret);1951goto out;1952}19531954if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {1955/* the error response is expected when1956* target_mem_delayed is true.1957*/1958if (delayed && resp.resp.error == 0)1959goto out;19601961ath11k_warn(ab, "qmi respond memory request failed: %d %d\n",1962resp.resp.result, resp.resp.error);1963ret = -EINVAL;1964goto out;1965}1966out:1967kfree(req);1968return ret;1969}19701971static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab)1972{1973int i;19741975for (i = 0; i < ab->qmi.mem_seg_count; i++) {1976if (!ab->qmi.target_mem[i].anyaddr)1977continue;19781979if (ab->hw_params.fixed_mem_region ||1980test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {1981iounmap(ab->qmi.target_mem[i].iaddr);1982ab->qmi.target_mem[i].iaddr = NULL;1983continue;1984}19851986dma_free_coherent(ab->dev,1987ab->qmi.target_mem[i].prev_size,1988ab->qmi.target_mem[i].vaddr,1989ab->qmi.target_mem[i].paddr);1990ab->qmi.target_mem[i].vaddr = NULL;1991}1992}19931994static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)1995{1996int i;1997struct target_mem_chunk *chunk;19981999ab->qmi.target_mem_delayed = false;20002001for (i = 0; i < ab->qmi.mem_seg_count; i++) {2002chunk = &ab->qmi.target_mem[i];20032004/* Firmware reloads in coldboot/firmware recovery.2005* in such case, no need to allocate memory for FW again.2006*/2007if (chunk->vaddr) {2008if (chunk->prev_type == chunk->type &&2009chunk->prev_size == chunk->size)2010continue;20112012if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {2013ath11k_dbg(ab, ATH11K_DBG_QMI,2014"size/type mismatch (current %d %u) (prev %d %u), try later with small size\n",2015chunk->size, chunk->type,2016chunk->prev_size, chunk->prev_type);2017ab->qmi.target_mem_delayed = true;2018return 0;2019}20202021/* cannot reuse the existing chunk */2022dma_free_coherent(ab->dev, chunk->prev_size,2023chunk->vaddr, chunk->paddr);2024chunk->vaddr = NULL;2025}20262027chunk->vaddr = dma_alloc_coherent(ab->dev,2028chunk->size,2029&chunk->paddr,2030GFP_KERNEL | __GFP_NOWARN);2031if (!chunk->vaddr) {2032if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) {2033ath11k_dbg(ab, ATH11K_DBG_QMI,2034"dma allocation failed (%d B type %u), will try later with small size\n",2035chunk->size,2036chunk->type);2037ath11k_qmi_free_target_mem_chunk(ab);2038ab->qmi.target_mem_delayed = true;2039return 0;2040}20412042ath11k_err(ab, "failed to allocate dma memory for qmi (%d B type %u)\n",2043chunk->size,2044chunk->type);2045return -EINVAL;2046}2047chunk->prev_type = chunk->type;2048chunk->prev_size = chunk->size;2049}20502051return 0;2052}20532054static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab)2055{2056#if defined(__linux__)2057struct device *dev = ab->dev;2058struct resource res = {};2059u32 host_ddr_sz;2060int i, idx, ret;2061#elif defined(__FreeBSD__)2062int i, idx;2063#endif20642065for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {2066switch (ab->qmi.target_mem[i].type) {2067#if defined(__linux__)2068case HOST_DDR_REGION_TYPE:2069ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res);2070if (ret) {2071ath11k_dbg(ab, ATH11K_DBG_QMI,2072"fail to get reg from hremote\n");2073return ret;2074}20752076if (res.end - res.start + 1 < ab->qmi.target_mem[i].size) {2077ath11k_dbg(ab, ATH11K_DBG_QMI,2078"fail to assign memory of sz\n");2079return -EINVAL;2080}20812082ab->qmi.target_mem[idx].paddr = res.start;2083ab->qmi.target_mem[idx].iaddr =2084ioremap(ab->qmi.target_mem[idx].paddr,2085ab->qmi.target_mem[i].size);2086if (!ab->qmi.target_mem[idx].iaddr)2087return -EIO;20882089ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2090host_ddr_sz = ab->qmi.target_mem[i].size;2091ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2092idx++;2093break;2094#endif2095case BDF_MEM_REGION_TYPE:2096ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr;2097ab->qmi.target_mem[idx].iaddr = NULL;2098ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2099ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2100idx++;2101break;2102#if defined(__linux__)2103case CALDB_MEM_REGION_TYPE:2104if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) {2105ath11k_warn(ab, "qmi mem size is low to load caldata\n");2106return -EINVAL;2107}21082109if (ath11k_core_coldboot_cal_support(ab)) {2110if (resource_size(&res)) {2111ab->qmi.target_mem[idx].paddr =2112res.start + host_ddr_sz;2113ab->qmi.target_mem[idx].iaddr =2114ioremap(ab->qmi.target_mem[idx].paddr,2115ab->qmi.target_mem[i].size);2116if (!ab->qmi.target_mem[idx].iaddr)2117return -EIO;2118} else {2119ab->qmi.target_mem[idx].paddr =2120ATH11K_QMI_CALDB_ADDRESS;2121ab->qmi.target_mem[idx].iaddr = NULL;2122}2123} else {2124ab->qmi.target_mem[idx].paddr = 0;2125ab->qmi.target_mem[idx].iaddr = NULL;2126}2127ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;2128ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;2129idx++;2130break;2131#endif2132default:2133ath11k_warn(ab, "qmi ignore invalid mem req type %d\n",2134ab->qmi.target_mem[i].type);2135break;2136}2137}2138ab->qmi.mem_seg_count = idx;21392140return 0;2141}21422143static int ath11k_qmi_request_device_info(struct ath11k_base *ab)2144{2145struct qmi_wlanfw_device_info_req_msg_v01 req = {};2146struct qmi_wlanfw_device_info_resp_msg_v01 resp = {};2147struct qmi_txn txn;2148void __iomem *bar_addr_va;2149int ret;21502151/* device info message req is only sent for hybrid bus devices */2152if (!ab->hw_params.hybrid_bus_type)2153return 0;21542155ret = qmi_txn_init(&ab->qmi.handle, &txn,2156qmi_wlfw_device_info_resp_msg_v01_ei, &resp);2157if (ret < 0)2158goto out;21592160ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2161QMI_WLANFW_DEVICE_INFO_REQ_V01,2162QMI_WLANFW_DEVICE_INFO_REQ_MSG_V01_MAX_LEN,2163qmi_wlanfw_device_info_req_msg_v01_ei, &req);2164if (ret < 0) {2165qmi_txn_cancel(&txn);2166ath11k_warn(ab, "failed to send qmi target device info request: %d\n",2167ret);2168goto out;2169}21702171ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2172if (ret < 0) {2173ath11k_warn(ab, "failed to wait qmi target device info request: %d\n",2174ret);2175goto out;2176}21772178if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2179ath11k_warn(ab, "qmi device info request failed: %d %d\n",2180resp.resp.result, resp.resp.error);2181ret = -EINVAL;2182goto out;2183}21842185if (!resp.bar_addr_valid || !resp.bar_size_valid) {2186ath11k_warn(ab, "qmi device info response invalid: %d %d\n",2187resp.resp.result, resp.resp.error);2188ret = -EINVAL;2189goto out;2190}21912192if (!resp.bar_addr ||2193resp.bar_size != ATH11K_QMI_DEVICE_BAR_SIZE) {2194#if defined(__linux__)2195ath11k_warn(ab, "qmi device info invalid address and size: %llu %u\n",2196resp.bar_addr, resp.bar_size);2197#elif defined(__FreeBSD__)2198ath11k_warn(ab, "qmi device info invalid address and size: %ju %u\n",2199(uintmax_t)resp.bar_addr, resp.bar_size);2200#endif2201ret = -EINVAL;2202goto out;2203}22042205bar_addr_va = devm_ioremap(ab->dev, resp.bar_addr, resp.bar_size);22062207if (!bar_addr_va) {2208ath11k_warn(ab, "qmi device info ioremap failed\n");2209ab->mem_len = 0;2210ret = -EIO;2211goto out;2212}22132214ab->mem = bar_addr_va;2215ab->mem_len = resp.bar_size;22162217if (!ab->hw_params.ce_remap)2218ab->mem_ce = ab->mem;22192220return 0;2221out:2222return ret;2223}22242225static int ath11k_qmi_request_target_cap(struct ath11k_base *ab)2226{2227struct qmi_wlanfw_cap_req_msg_v01 req;2228struct qmi_wlanfw_cap_resp_msg_v01 resp;2229struct qmi_txn txn;2230int ret = 0;2231int r;2232char *fw_build_id;2233int fw_build_id_mask_len;22342235memset(&req, 0, sizeof(req));2236memset(&resp, 0, sizeof(resp));22372238ret = qmi_txn_init(&ab->qmi.handle, &txn, qmi_wlanfw_cap_resp_msg_v01_ei,2239&resp);2240if (ret < 0)2241goto out;22422243ath11k_dbg(ab, ATH11K_DBG_QMI, "target cap request\n");22442245ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2246QMI_WLANFW_CAP_REQ_V01,2247QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN,2248qmi_wlanfw_cap_req_msg_v01_ei, &req);2249if (ret < 0) {2250qmi_txn_cancel(&txn);2251ath11k_warn(ab, "failed to send qmi cap request: %d\n",2252ret);2253goto out;2254}22552256ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2257if (ret < 0) {2258ath11k_warn(ab, "failed to wait qmi cap request: %d\n", ret);2259goto out;2260}22612262if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2263ath11k_warn(ab, "qmi cap request failed: %d %d\n",2264resp.resp.result, resp.resp.error);2265ret = -EINVAL;2266goto out;2267}22682269if (resp.chip_info_valid) {2270ab->qmi.target.chip_id = resp.chip_info.chip_id;2271ab->qmi.target.chip_family = resp.chip_info.chip_family;2272}22732274if (resp.board_info_valid)2275ab->qmi.target.board_id = resp.board_info.board_id;2276else2277ab->qmi.target.board_id = 0xFF;22782279if (resp.soc_info_valid)2280ab->qmi.target.soc_id = resp.soc_info.soc_id;22812282if (resp.fw_version_info_valid) {2283ab->qmi.target.fw_version = resp.fw_version_info.fw_version;2284strscpy(ab->qmi.target.fw_build_timestamp,2285resp.fw_version_info.fw_build_timestamp,2286sizeof(ab->qmi.target.fw_build_timestamp));2287}22882289if (resp.fw_build_id_valid)2290strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id,2291sizeof(ab->qmi.target.fw_build_id));22922293if (resp.eeprom_read_timeout_valid) {2294ab->qmi.target.eeprom_caldata =2295resp.eeprom_read_timeout;2296ath11k_dbg(ab, ATH11K_DBG_QMI, "cal data supported from eeprom\n");2297}22982299fw_build_id = ab->qmi.target.fw_build_id;2300fw_build_id_mask_len = strlen(FW_BUILD_ID_MASK);2301if (!strncmp(fw_build_id, FW_BUILD_ID_MASK, fw_build_id_mask_len))2302fw_build_id = fw_build_id + fw_build_id_mask_len;23032304ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n",2305ab->qmi.target.chip_id, ab->qmi.target.chip_family,2306ab->qmi.target.board_id, ab->qmi.target.soc_id);23072308ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s",2309ab->qmi.target.fw_version,2310ab->qmi.target.fw_build_timestamp,2311fw_build_id);23122313r = ath11k_core_check_smbios(ab);2314if (r)2315ath11k_dbg(ab, ATH11K_DBG_QMI, "SMBIOS bdf variant name not set.\n");23162317r = ath11k_core_check_dt(ab);2318if (r)2319ath11k_dbg(ab, ATH11K_DBG_QMI, "DT bdf variant name not set.\n");23202321out:2322return ret;2323}23242325static int ath11k_qmi_load_file_target_mem(struct ath11k_base *ab,2326const u8 *data, u32 len, u8 type)2327{2328struct qmi_wlanfw_bdf_download_req_msg_v01 *req;2329struct qmi_wlanfw_bdf_download_resp_msg_v01 resp;2330struct qmi_txn txn;2331const u8 *temp = data;2332#if defined(__linux__)2333void __iomem *bdf_addr = NULL;2334#elif defined(__FreeBSD__)2335char __iomem *bdf_addr = NULL;2336#endif2337int ret = 0;2338u32 remaining = len;23392340req = kzalloc(sizeof(*req), GFP_KERNEL);2341if (!req)2342return -ENOMEM;23432344memset(&resp, 0, sizeof(resp));23452346if (ab->hw_params.fixed_bdf_addr) {2347bdf_addr = ioremap(ab->hw_params.bdf_addr, ab->hw_params.fw.board_size);2348if (!bdf_addr) {2349ath11k_warn(ab, "qmi ioremap error for bdf_addr\n");2350ret = -EIO;2351goto err_free_req;2352}2353}23542355while (remaining) {2356req->valid = 1;2357req->file_id_valid = 1;2358req->file_id = ab->qmi.target.board_id;2359req->total_size_valid = 1;2360req->total_size = remaining;2361req->seg_id_valid = 1;2362req->data_valid = 1;2363req->bdf_type = type;2364req->bdf_type_valid = 1;2365req->end_valid = 1;2366req->end = 0;23672368if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) {2369req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01;2370} else {2371req->data_len = remaining;2372req->end = 1;2373}23742375if (ab->hw_params.fixed_bdf_addr ||2376type == ATH11K_QMI_FILE_TYPE_EEPROM) {2377req->data_valid = 0;2378req->end = 1;2379req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;2380} else {2381memcpy(req->data, temp, req->data_len);2382}23832384if (ab->hw_params.fixed_bdf_addr) {2385if (type == ATH11K_QMI_FILE_TYPE_CALDATA)2386bdf_addr += ab->hw_params.fw.cal_offset;23872388memcpy_toio(bdf_addr, temp, len);2389}23902391ret = qmi_txn_init(&ab->qmi.handle, &txn,2392qmi_wlanfw_bdf_download_resp_msg_v01_ei,2393&resp);2394if (ret < 0)2395goto err_iounmap;23962397ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download req fixed addr type %d\n",2398type);23992400ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2401QMI_WLANFW_BDF_DOWNLOAD_REQ_V01,2402QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN,2403qmi_wlanfw_bdf_download_req_msg_v01_ei, req);2404if (ret < 0) {2405qmi_txn_cancel(&txn);2406goto err_iounmap;2407}24082409ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2410if (ret < 0) {2411ath11k_warn(ab, "failed to wait board file download request: %d\n",2412ret);2413goto err_iounmap;2414}24152416if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2417ath11k_warn(ab, "board file download request failed: %d %d\n",2418resp.resp.result, resp.resp.error);2419ret = -EINVAL;2420goto err_iounmap;2421}24222423if (ab->hw_params.fixed_bdf_addr ||2424type == ATH11K_QMI_FILE_TYPE_EEPROM) {2425remaining = 0;2426} else {2427remaining -= req->data_len;2428temp += req->data_len;2429req->seg_id++;2430ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf download request remaining %i\n",2431remaining);2432}2433}24342435err_iounmap:2436if (ab->hw_params.fixed_bdf_addr)2437iounmap(bdf_addr);24382439err_free_req:2440kfree(req);24412442return ret;2443}24442445static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab,2446bool regdb)2447{2448struct device *dev = ab->dev;2449char filename[ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE];2450const struct firmware *fw_entry;2451struct ath11k_board_data bd;2452u32 fw_size, file_type;2453int ret = 0, bdf_type;2454const u8 *tmp;24552456memset(&bd, 0, sizeof(bd));24572458if (regdb) {2459ret = ath11k_core_fetch_regdb(ab, &bd);2460} else {2461ret = ath11k_core_fetch_bdf(ab, &bd);2462if (ret)2463ath11k_warn(ab, "qmi failed to fetch board file: %d\n", ret);2464}24652466if (ret)2467goto out;24682469if (regdb)2470bdf_type = ATH11K_QMI_BDF_TYPE_REGDB;2471else if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0)2472bdf_type = ATH11K_QMI_BDF_TYPE_ELF;2473else2474bdf_type = ATH11K_QMI_BDF_TYPE_BIN;24752476ath11k_dbg(ab, ATH11K_DBG_QMI, "bdf_type %d\n", bdf_type);24772478fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len);24792480ret = ath11k_qmi_load_file_target_mem(ab, bd.data, fw_size, bdf_type);2481if (ret < 0) {2482ath11k_warn(ab, "qmi failed to load bdf file\n");2483goto out;2484}24852486/* QCA6390/WCN6855 does not support cal data, skip it */2487if (bdf_type == ATH11K_QMI_BDF_TYPE_ELF || bdf_type == ATH11K_QMI_BDF_TYPE_REGDB)2488goto out;24892490if (ab->qmi.target.eeprom_caldata) {2491file_type = ATH11K_QMI_FILE_TYPE_EEPROM;2492tmp = filename;2493fw_size = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE;2494} else {2495file_type = ATH11K_QMI_FILE_TYPE_CALDATA;24962497/* cal-<bus>-<id>.bin */2498snprintf(filename, sizeof(filename), "cal-%s-%s.bin",2499ath11k_bus_str(ab->hif.bus), dev_name(dev));2500fw_entry = ath11k_core_firmware_request(ab, filename);2501if (!IS_ERR(fw_entry))2502goto success;25032504fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE);2505if (IS_ERR(fw_entry)) {2506/* Caldata may not be present during first time calibration in2507* factory hence allow to boot without loading caldata in ftm mode2508*/2509if (ath11k_ftm_mode) {2510ath11k_info(ab,2511"Booting without cal data file in factory test mode\n");2512return 0;2513}2514ret = PTR_ERR(fw_entry);2515ath11k_warn(ab,2516"qmi failed to load CAL data file:%s\n",2517filename);2518goto out;2519}2520success:2521fw_size = min_t(u32, ab->hw_params.fw.board_size, fw_entry->size);2522tmp = fw_entry->data;2523}25242525ret = ath11k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type);2526if (ret < 0) {2527ath11k_warn(ab, "qmi failed to load caldata\n");2528goto out_qmi_cal;2529}25302531ath11k_dbg(ab, ATH11K_DBG_QMI, "caldata type: %u\n", file_type);25322533out_qmi_cal:2534if (!ab->qmi.target.eeprom_caldata)2535release_firmware(fw_entry);2536out:2537ath11k_core_free_bdf(ab, &bd);2538ath11k_dbg(ab, ATH11K_DBG_QMI, "BDF download sequence completed\n");25392540return ret;2541}25422543static int ath11k_qmi_m3_load(struct ath11k_base *ab)2544{2545struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;2546const struct firmware *fw = NULL;2547const void *m3_data;2548char path[100];2549size_t m3_len;2550int ret;25512552if (m3_mem->vaddr)2553/* m3 firmware buffer is already available in the DMA buffer */2554return 0;25552556if (ab->fw.m3_data && ab->fw.m3_len > 0) {2557/* firmware-N.bin had a m3 firmware file so use that */2558m3_data = ab->fw.m3_data;2559m3_len = ab->fw.m3_len;2560} else {2561/* No m3 file in firmware-N.bin so try to request old2562* separate m3.bin.2563*/2564fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);2565if (IS_ERR(fw)) {2566ret = PTR_ERR(fw);2567ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE,2568path, sizeof(path));2569ath11k_err(ab, "failed to load %s: %d\n", path, ret);2570return ret;2571}25722573m3_data = fw->data;2574m3_len = fw->size;2575}25762577m3_mem->vaddr = dma_alloc_coherent(ab->dev,2578m3_len, &m3_mem->paddr,2579GFP_KERNEL);2580if (!m3_mem->vaddr) {2581ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n",2582m3_len);2583ret = -ENOMEM;2584goto out;2585}25862587memcpy(m3_mem->vaddr, m3_data, m3_len);2588m3_mem->size = m3_len;25892590ret = 0;25912592out:2593release_firmware(fw);25942595return ret;2596}25972598static void ath11k_qmi_m3_free(struct ath11k_base *ab)2599{2600struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;26012602if (!ab->hw_params.m3_fw_support || !m3_mem->vaddr)2603return;26042605dma_free_coherent(ab->dev, m3_mem->size,2606m3_mem->vaddr, m3_mem->paddr);2607m3_mem->vaddr = NULL;2608m3_mem->size = 0;2609}26102611/* clang stack usage explodes if this is inlined */2612static noinline_for_stack2613int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)2614{2615struct m3_mem_region *m3_mem = &ab->qmi.m3_mem;2616struct qmi_wlanfw_m3_info_req_msg_v01 req;2617struct qmi_wlanfw_m3_info_resp_msg_v01 resp;2618struct qmi_txn txn;2619int ret = 0;26202621memset(&req, 0, sizeof(req));2622memset(&resp, 0, sizeof(resp));26232624if (ab->hw_params.m3_fw_support) {2625ret = ath11k_qmi_m3_load(ab);2626if (ret) {2627ath11k_err(ab, "failed to load m3 firmware: %d", ret);2628return ret;2629}26302631req.addr = m3_mem->paddr;2632req.size = m3_mem->size;2633} else {2634req.addr = 0;2635req.size = 0;2636}26372638ret = qmi_txn_init(&ab->qmi.handle, &txn,2639qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp);2640if (ret < 0)2641goto out;26422643ath11k_dbg(ab, ATH11K_DBG_QMI, "m3 info req\n");26442645ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2646QMI_WLANFW_M3_INFO_REQ_V01,2647QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN,2648qmi_wlanfw_m3_info_req_msg_v01_ei, &req);2649if (ret < 0) {2650qmi_txn_cancel(&txn);2651ath11k_warn(ab, "failed to send m3 information request: %d\n",2652ret);2653goto out;2654}26552656ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2657if (ret < 0) {2658ath11k_warn(ab, "failed to wait m3 information request: %d\n", ret);2659goto out;2660}26612662if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2663ath11k_warn(ab, "m3 info request failed: %d %d\n",2664resp.resp.result, resp.resp.error);2665ret = -EINVAL;2666goto out;2667}2668out:2669return ret;2670}26712672static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab,2673u32 mode)2674{2675struct qmi_wlanfw_wlan_mode_req_msg_v01 req;2676struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp;2677struct qmi_txn txn;2678int ret = 0;26792680memset(&req, 0, sizeof(req));2681memset(&resp, 0, sizeof(resp));26822683req.mode = mode;2684req.hw_debug_valid = 1;2685req.hw_debug = 0;26862687ret = qmi_txn_init(&ab->qmi.handle, &txn,2688qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp);2689if (ret < 0)2690goto out;26912692ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan mode req mode %d\n", mode);26932694ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2695QMI_WLANFW_WLAN_MODE_REQ_V01,2696QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN,2697qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req);2698if (ret < 0) {2699qmi_txn_cancel(&txn);2700ath11k_warn(ab, "failed to send wlan mode request (mode %d): %d\n",2701mode, ret);2702goto out;2703}27042705ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2706if (ret < 0) {2707if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) {2708ath11k_warn(ab, "WLFW service is dis-connected\n");2709return 0;2710}2711ath11k_warn(ab, "failed to wait wlan mode request (mode %d): %d\n",2712mode, ret);2713goto out;2714}27152716if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2717ath11k_warn(ab, "wlan mode request failed (mode: %d): %d %d\n",2718mode, resp.resp.result, resp.resp.error);2719ret = -EINVAL;2720goto out;2721}27222723out:2724return ret;2725}27262727static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab)2728{2729struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req;2730struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp;2731#if defined(__linux__)2732struct ce_pipe_config *ce_cfg;2733struct service_to_pipe *svc_cfg;2734#elif defined(__FreeBSD__)2735const struct ce_pipe_config *ce_cfg;2736const struct service_to_pipe *svc_cfg;2737#endif2738struct qmi_txn txn;2739int ret = 0, pipe_num;27402741#if defined(__linux__)2742ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;2743svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;2744#elif defined(__FreeBSD__)2745ce_cfg = (const struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce;2746svc_cfg = (const struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map;2747#endif27482749req = kzalloc(sizeof(*req), GFP_KERNEL);2750if (!req)2751return -ENOMEM;27522753memset(&resp, 0, sizeof(resp));27542755req->host_version_valid = 1;2756strscpy(req->host_version, ATH11K_HOST_VERSION_STRING,2757sizeof(req->host_version));27582759req->tgt_cfg_valid = 1;2760/* This is number of CE configs */2761req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len;2762for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) {2763req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum;2764req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir;2765req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries;2766req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max;2767req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags;2768}27692770req->svc_cfg_valid = 1;2771/* This is number of Service/CE configs */2772req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len;2773for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) {2774req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id;2775req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir;2776req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum;2777}2778req->shadow_reg_valid = 0;27792780/* set shadow v2 configuration */2781if (ab->hw_params.supports_shadow_regs) {2782req->shadow_reg_v2_valid = 1;2783req->shadow_reg_v2_len = min_t(u32,2784ab->qmi.ce_cfg.shadow_reg_v2_len,2785QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01);2786memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2,2787sizeof(u32) * req->shadow_reg_v2_len);2788} else {2789req->shadow_reg_v2_valid = 0;2790}27912792ret = qmi_txn_init(&ab->qmi.handle, &txn,2793qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp);2794if (ret < 0)2795goto out;27962797ath11k_dbg(ab, ATH11K_DBG_QMI, "wlan cfg req\n");27982799ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2800QMI_WLANFW_WLAN_CFG_REQ_V01,2801QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN,2802qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req);2803if (ret < 0) {2804qmi_txn_cancel(&txn);2805ath11k_warn(ab, "failed to send wlan config request: %d\n",2806ret);2807goto out;2808}28092810ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2811if (ret < 0) {2812ath11k_warn(ab, "failed to wait wlan config request: %d\n", ret);2813goto out;2814}28152816if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2817ath11k_warn(ab, "wlan config request failed: %d %d\n",2818resp.resp.result, resp.resp.error);2819ret = -EINVAL;2820goto out;2821}28222823out:2824kfree(req);2825return ret;2826}28272828static int ath11k_qmi_wlanfw_wlan_ini_send(struct ath11k_base *ab, bool enable)2829{2830int ret;2831struct qmi_txn txn;2832struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {};2833struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {};28342835req.enablefwlog_valid = true;2836req.enablefwlog = enable ? 1 : 0;28372838ret = qmi_txn_init(&ab->qmi.handle, &txn,2839qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp);2840if (ret < 0)2841goto out;28422843ret = qmi_send_request(&ab->qmi.handle, NULL, &txn,2844QMI_WLANFW_WLAN_INI_REQ_V01,2845QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN,2846qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req);2847if (ret < 0) {2848ath11k_warn(ab, "qmi failed to send wlan ini request, err = %d\n",2849ret);2850qmi_txn_cancel(&txn);2851goto out;2852}28532854ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS));2855if (ret < 0) {2856ath11k_warn(ab, "qmi failed wlan ini request, err = %d\n", ret);2857goto out;2858}28592860if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {2861ath11k_warn(ab, "qmi wlan ini request failed, result: %d, err: %d\n",2862resp.resp.result, resp.resp.error);2863ret = -EINVAL;2864}28652866out:2867return ret;2868}28692870void ath11k_qmi_firmware_stop(struct ath11k_base *ab)2871{2872int ret;28732874ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware stop\n");28752876ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF);2877if (ret < 0) {2878ath11k_warn(ab, "qmi failed to send wlan mode off: %d\n", ret);2879return;2880}2881}28822883int ath11k_qmi_firmware_start(struct ath11k_base *ab,2884u32 mode)2885{2886int ret;28872888ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware start\n");28892890if (ab->hw_params.fw_wmi_diag_event) {2891ret = ath11k_qmi_wlanfw_wlan_ini_send(ab, true);2892if (ret < 0) {2893ath11k_warn(ab, "qmi failed to send wlan fw ini:%d\n", ret);2894return ret;2895}2896}28972898ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab);2899if (ret < 0) {2900ath11k_warn(ab, "qmi failed to send wlan cfg: %d\n", ret);2901return ret;2902}29032904ret = ath11k_qmi_wlanfw_mode_send(ab, mode);2905if (ret < 0) {2906ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);2907return ret;2908}29092910return 0;2911}29122913int ath11k_qmi_fwreset_from_cold_boot(struct ath11k_base *ab)2914{2915long time_left;29162917if (!ath11k_core_coldboot_cal_support(ab) ||2918ab->hw_params.cbcal_restart_fw == 0)2919return 0;29202921ath11k_dbg(ab, ATH11K_DBG_QMI, "wait for cold boot done\n");29222923time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,2924(ab->qmi.cal_done == 1),2925ATH11K_COLD_BOOT_FW_RESET_DELAY);29262927if (time_left <= 0) {2928ath11k_warn(ab, "Coldboot Calibration timed out\n");2929return -ETIMEDOUT;2930}29312932/* reset the firmware */2933ath11k_hif_power_down(ab, false);2934ath11k_hif_power_up(ab);2935ath11k_dbg(ab, ATH11K_DBG_QMI, "exit wait for cold boot done\n");2936return 0;2937}2938EXPORT_SYMBOL(ath11k_qmi_fwreset_from_cold_boot);29392940static int ath11k_qmi_process_coldboot_calibration(struct ath11k_base *ab)2941{2942long time_left;2943int ret;29442945ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_COLD_BOOT);2946if (ret < 0) {2947ath11k_warn(ab, "qmi failed to send wlan fw mode: %d\n", ret);2948return ret;2949}29502951ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration wait started\n");29522953time_left = wait_event_timeout(ab->qmi.cold_boot_waitq,2954(ab->qmi.cal_done == 1),2955ATH11K_COLD_BOOT_FW_RESET_DELAY);2956if (time_left <= 0) {2957ath11k_warn(ab, "coldboot calibration timed out\n");2958return 0;2959}29602961ath11k_dbg(ab, ATH11K_DBG_QMI, "Coldboot calibration done\n");29622963return 0;2964}29652966static int2967ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi,2968enum ath11k_qmi_event_type type,2969void *data)2970{2971struct ath11k_qmi_driver_event *event;29722973event = kzalloc(sizeof(*event), GFP_ATOMIC);2974if (!event)2975return -ENOMEM;29762977event->type = type;2978event->data = data;29792980spin_lock(&qmi->event_lock);2981list_add_tail(&event->list, &qmi->event_list);2982spin_unlock(&qmi->event_lock);29832984queue_work(qmi->event_wq, &qmi->event_work);29852986return 0;2987}29882989static int ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi)2990{2991struct ath11k_base *ab = qmi->ab;2992int ret;29932994ret = ath11k_qmi_respond_fw_mem_request(ab);2995if (ret < 0) {2996ath11k_warn(ab, "qmi failed to respond fw mem req: %d\n", ret);2997return ret;2998}29993000return ret;3001}30023003static int ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi)3004{3005struct ath11k_base *ab = qmi->ab;3006int ret;30073008ret = ath11k_qmi_request_target_cap(ab);3009if (ret < 0) {3010ath11k_warn(ab, "failed to request qmi target capabilities: %d\n",3011ret);3012return ret;3013}30143015ret = ath11k_qmi_request_device_info(ab);3016if (ret < 0) {3017ath11k_warn(ab, "failed to request qmi device info: %d\n", ret);3018return ret;3019}30203021if (ab->hw_params.supports_regdb)3022ath11k_qmi_load_bdf_qmi(ab, true);30233024ret = ath11k_qmi_load_bdf_qmi(ab, false);3025if (ret < 0) {3026ath11k_warn(ab, "failed to load board data file: %d\n", ret);3027return ret;3028}30293030return 0;3031}30323033static int ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi)3034{3035struct ath11k_base *ab = qmi->ab;3036int ret;30373038ret = ath11k_qmi_fw_ind_register_send(ab);3039if (ret < 0) {3040ath11k_warn(ab, "failed to send qmi firmware indication: %d\n",3041ret);3042return ret;3043}30443045ret = ath11k_qmi_host_cap_send(ab);3046if (ret < 0) {3047ath11k_warn(ab, "failed to send qmi host cap: %d\n", ret);3048return ret;3049}30503051if (!ab->hw_params.fixed_fw_mem)3052return ret;30533054ret = ath11k_qmi_event_load_bdf(qmi);3055if (ret < 0) {3056ath11k_warn(ab, "qmi failed to download BDF:%d\n", ret);3057return ret;3058}30593060return ret;3061}30623063static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl,3064struct sockaddr_qrtr *sq,3065struct qmi_txn *txn,3066const void *data)3067{3068struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3069struct ath11k_base *ab = qmi->ab;3070const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data;3071int i, ret;30723073ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware request memory request\n");30743075if (msg->mem_seg_len == 0 ||3076msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01)3077ath11k_warn(ab, "invalid memory segment length: %u\n",3078msg->mem_seg_len);30793080ab->qmi.mem_seg_count = msg->mem_seg_len;30813082for (i = 0; i < qmi->mem_seg_count ; i++) {3083ab->qmi.target_mem[i].type = msg->mem_seg[i].type;3084ab->qmi.target_mem[i].size = msg->mem_seg[i].size;3085ath11k_dbg(ab, ATH11K_DBG_QMI, "mem seg type %d size %d\n",3086msg->mem_seg[i].type, msg->mem_seg[i].size);3087}30883089if (ab->hw_params.fixed_mem_region ||3090test_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags)) {3091ret = ath11k_qmi_assign_target_mem_chunk(ab);3092if (ret) {3093ath11k_warn(ab, "failed to assign qmi target memory: %d\n",3094ret);3095return;3096}3097} else {3098ret = ath11k_qmi_alloc_target_mem_chunk(ab);3099if (ret) {3100ath11k_warn(ab, "failed to allocate qmi target memory: %d\n",3101ret);3102return;3103}3104}31053106ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL);3107}31083109static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl,3110struct sockaddr_qrtr *sq,3111struct qmi_txn *txn,3112const void *decoded)3113{3114struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3115struct ath11k_base *ab = qmi->ab;31163117ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware memory ready indication\n");3118ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL);3119}31203121static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl,3122struct sockaddr_qrtr *sq,3123struct qmi_txn *txn,3124const void *decoded)3125{3126struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3127struct ath11k_base *ab = qmi->ab;31283129ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware ready\n");31303131if (!ab->qmi.cal_done) {3132ab->qmi.cal_done = 1;3133wake_up(&ab->qmi.cold_boot_waitq);3134}31353136ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL);3137}31383139static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi_hdl,3140struct sockaddr_qrtr *sq,3141struct qmi_txn *txn,3142const void *decoded)3143{3144struct ath11k_qmi *qmi = container_of(qmi_hdl,3145struct ath11k_qmi, handle);3146struct ath11k_base *ab = qmi->ab;31473148ab->qmi.cal_done = 1;3149wake_up(&ab->qmi.cold_boot_waitq);3150ath11k_dbg(ab, ATH11K_DBG_QMI, "cold boot calibration done\n");3151}31523153static void ath11k_qmi_msg_fw_init_done_cb(struct qmi_handle *qmi_hdl,3154struct sockaddr_qrtr *sq,3155struct qmi_txn *txn,3156const void *decoded)3157{3158struct ath11k_qmi *qmi = container_of(qmi_hdl,3159struct ath11k_qmi, handle);3160struct ath11k_base *ab = qmi->ab;31613162ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_INIT_DONE, NULL);3163ath11k_dbg(ab, ATH11K_DBG_QMI, "firmware init done\n");3164}31653166static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = {3167{3168.type = QMI_INDICATION,3169.msg_id = QMI_WLFW_REQUEST_MEM_IND_V01,3170.ei = qmi_wlanfw_request_mem_ind_msg_v01_ei,3171.decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01),3172.fn = ath11k_qmi_msg_mem_request_cb,3173},3174{3175.type = QMI_INDICATION,3176.msg_id = QMI_WLFW_FW_MEM_READY_IND_V01,3177.ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei,3178.decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01),3179.fn = ath11k_qmi_msg_mem_ready_cb,3180},3181{3182.type = QMI_INDICATION,3183.msg_id = QMI_WLFW_FW_READY_IND_V01,3184.ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei,3185.decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01),3186.fn = ath11k_qmi_msg_fw_ready_cb,3187},3188{3189.type = QMI_INDICATION,3190.msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01,3191.ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei,3192.decoded_size =3193sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01),3194.fn = ath11k_qmi_msg_cold_boot_cal_done_cb,3195},3196{3197.type = QMI_INDICATION,3198.msg_id = QMI_WLFW_FW_INIT_DONE_IND_V01,3199.ei = qmi_wlfw_fw_init_done_ind_msg_v01_ei,3200.decoded_size =3201sizeof(struct qmi_wlfw_fw_init_done_ind_msg_v01),3202.fn = ath11k_qmi_msg_fw_init_done_cb,3203},32043205/* end of list */3206{},3207};32083209static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl,3210struct qmi_service *service)3211{3212struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3213struct ath11k_base *ab = qmi->ab;3214struct sockaddr_qrtr *sq = &qmi->sq;3215int ret;32163217sq->sq_family = AF_QIPCRTR;3218sq->sq_node = service->node;3219sq->sq_port = service->port;32203221ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq,3222sizeof(*sq), 0);3223if (ret) {3224ath11k_warn(ab, "failed to connect to qmi remote service: %d\n", ret);3225return ret;3226}32273228ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw qmi service connected\n");3229ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL);32303231return ret;3232}32333234static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl,3235struct qmi_service *service)3236{3237struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle);3238struct ath11k_base *ab = qmi->ab;32393240ath11k_dbg(ab, ATH11K_DBG_QMI, "wifi fw del server\n");3241ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL);3242}32433244static const struct qmi_ops ath11k_qmi_ops = {3245.new_server = ath11k_qmi_ops_new_server,3246.del_server = ath11k_qmi_ops_del_server,3247};32483249static void ath11k_qmi_driver_event_work(struct work_struct *work)3250{3251struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi,3252event_work);3253struct ath11k_qmi_driver_event *event;3254struct ath11k_base *ab = qmi->ab;3255int ret;32563257spin_lock(&qmi->event_lock);3258while (!list_empty(&qmi->event_list)) {3259event = list_first_entry(&qmi->event_list,3260struct ath11k_qmi_driver_event, list);3261list_del(&event->list);3262spin_unlock(&qmi->event_lock);32633264if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) {3265kfree(event);3266return;3267}32683269switch (event->type) {3270case ATH11K_QMI_EVENT_SERVER_ARRIVE:3271ret = ath11k_qmi_event_server_arrive(qmi);3272if (ret < 0)3273set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3274break;3275case ATH11K_QMI_EVENT_SERVER_EXIT:3276set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);3277set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);32783279if (!ab->is_reset)3280ath11k_core_pre_reconfigure_recovery(ab);3281break;3282case ATH11K_QMI_EVENT_REQUEST_MEM:3283ret = ath11k_qmi_event_mem_request(qmi);3284if (ret < 0)3285set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3286break;3287case ATH11K_QMI_EVENT_FW_MEM_READY:3288ret = ath11k_qmi_event_load_bdf(qmi);3289if (ret < 0) {3290set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3291break;3292}32933294ret = ath11k_qmi_wlanfw_m3_info_send(ab);3295if (ret < 0) {3296ath11k_warn(ab,3297"failed to send qmi m3 info req: %d\n", ret);3298set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3299}33003301break;3302case ATH11K_QMI_EVENT_FW_INIT_DONE:3303clear_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3304if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) {3305if (ab->is_reset)3306ath11k_hal_dump_srng_stats(ab);3307queue_work(ab->workqueue, &ab->restart_work);3308break;3309}33103311if (ab->qmi.cal_done == 0 &&3312ath11k_core_coldboot_cal_support(ab)) {3313ath11k_qmi_process_coldboot_calibration(ab);3314} else {3315clear_bit(ATH11K_FLAG_CRASH_FLUSH,3316&ab->dev_flags);3317clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);3318ret = ath11k_core_qmi_firmware_ready(ab);3319if (ret) {3320set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);3321break;3322}3323set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);3324}33253326break;3327case ATH11K_QMI_EVENT_FW_READY:3328/* For targets requiring a FW restart upon cold3329* boot completion, there is no need to process3330* FW ready; such targets will receive FW init3331* done message after FW restart.3332*/3333if (ab->hw_params.cbcal_restart_fw)3334break;33353336clear_bit(ATH11K_FLAG_CRASH_FLUSH,3337&ab->dev_flags);3338clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);3339ath11k_core_qmi_firmware_ready(ab);3340set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);33413342break;3343case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE:3344break;3345default:3346ath11k_warn(ab, "invalid qmi event type: %d", event->type);3347break;3348}3349kfree(event);3350spin_lock(&qmi->event_lock);3351}3352spin_unlock(&qmi->event_lock);3353}33543355int ath11k_qmi_init_service(struct ath11k_base *ab)3356{3357int ret;33583359memset(&ab->qmi.target, 0, sizeof(struct target_info));3360memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk));3361ab->qmi.ab = ab;33623363ab->qmi.target_mem_mode = ab->hw_params.fw_mem_mode;3364ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX,3365&ath11k_qmi_ops, ath11k_qmi_msg_handlers);3366if (ret < 0) {3367ath11k_warn(ab, "failed to initialize qmi handle: %d\n", ret);3368return ret;3369}33703371ab->qmi.event_wq = alloc_ordered_workqueue("ath11k_qmi_driver_event", 0);3372if (!ab->qmi.event_wq) {3373ath11k_err(ab, "failed to allocate workqueue\n");3374return -EFAULT;3375}33763377INIT_LIST_HEAD(&ab->qmi.event_list);3378spin_lock_init(&ab->qmi.event_lock);3379INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work);33803381ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01,3382ATH11K_QMI_WLFW_SERVICE_VERS_V01,3383ab->qmi.service_ins_id);3384if (ret < 0) {3385ath11k_warn(ab, "failed to add qmi lookup: %d\n", ret);3386destroy_workqueue(ab->qmi.event_wq);3387return ret;3388}33893390return ret;3391}33923393void ath11k_qmi_deinit_service(struct ath11k_base *ab)3394{3395qmi_handle_release(&ab->qmi.handle);3396cancel_work_sync(&ab->qmi.event_work);3397destroy_workqueue(ab->qmi.event_wq);3398ath11k_qmi_m3_free(ab);3399ath11k_qmi_free_target_mem_chunk(ab);3400}3401EXPORT_SYMBOL(ath11k_qmi_deinit_service);34023403void ath11k_qmi_free_resource(struct ath11k_base *ab)3404{3405ath11k_qmi_free_target_mem_chunk(ab);3406ath11k_qmi_m3_free(ab);3407}340834093410