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