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