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