1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021-2025 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 0x02 16 #define HOST_CSTATE_BIT 0x04 17 #define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08 18 #define ATH12K_QMI_MAX_CHUNK_SIZE 2097152 19 20 static 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 64 static 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 514 static 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 531 static 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 539 static 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 610 static 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 835 static 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 871 static 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 903 static 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 945 static 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 972 static 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 1012 static 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 1039 static 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 1057 static 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 1065 static 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 1091 static 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 1108 static 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 1124 static 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 1150 static 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 1176 static 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 1430 static 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 1565 static 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 1583 static 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 1607 static 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 1624 static 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 1677 static 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 1712 static 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 1736 static 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 1753 static 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 1788 static 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 1806 static 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 1944 static 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 1961 static 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 1968 static 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 1975 static 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 2001 static 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 2019 static void ath12k_host_cap_hw_link_id_init(struct ath12k_hw_group *ag) 2020 { 2021 struct ath12k_base *ab, *partner_ab; 2022 int i, j, hw_id_base; 2023 2024 for (i = 0; i < ag->num_devices; i++) { 2025 hw_id_base = 0; 2026 ab = ag->ab[i]; 2027 2028 for (j = 0; j < ag->num_devices; j++) { 2029 partner_ab = ag->ab[j]; 2030 2031 if (partner_ab->wsi_info.index >= ab->wsi_info.index) 2032 continue; 2033 2034 hw_id_base += partner_ab->qmi.num_radios; 2035 } 2036 2037 ab->wsi_info.hw_link_id_base = hw_id_base; 2038 } 2039 2040 ag->hw_link_id_init_done = true; 2041 } 2042 2043 static int ath12k_host_cap_parse_mlo(struct ath12k_base *ab, 2044 struct qmi_wlanfw_host_cap_req_msg_v01 *req) 2045 { 2046 struct wlfw_host_mlo_chip_info_s_v01 *info; 2047 struct ath12k_hw_group *ag = ab->ag; 2048 struct ath12k_base *partner_ab; 2049 u8 hw_link_id = 0; 2050 int i, j, ret; 2051 2052 if (!ag->mlo_capable) { 2053 ath12k_dbg(ab, ATH12K_DBG_QMI, 2054 "MLO is disabled hence skip QMI MLO cap"); 2055 return 0; 2056 } 2057 2058 if (!ab->qmi.num_radios || ab->qmi.num_radios == U8_MAX) { 2059 ag->mlo_capable = false; 2060 ath12k_dbg(ab, ATH12K_DBG_QMI, 2061 "skip QMI MLO cap due to invalid num_radio %d\n", 2062 ab->qmi.num_radios); 2063 return 0; 2064 } 2065 2066 if (ab->device_id == ATH12K_INVALID_DEVICE_ID) { 2067 ath12k_err(ab, "failed to send MLO cap due to invalid device id\n"); 2068 return -EINVAL; 2069 } 2070 2071 req->mlo_capable_valid = 1; 2072 req->mlo_capable = 1; 2073 req->mlo_chip_id_valid = 1; 2074 req->mlo_chip_id = ab->device_id; 2075 req->mlo_group_id_valid = 1; 2076 req->mlo_group_id = ag->id; 2077 req->max_mlo_peer_valid = 1; 2078 /* Max peer number generally won't change for the same device 2079 * but needs to be synced with host driver. 2080 */ 2081 req->max_mlo_peer = ab->hw_params->max_mlo_peer; 2082 req->mlo_num_chips_valid = 1; 2083 req->mlo_num_chips = ag->num_devices; 2084 2085 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo capability advertisement device_id %d group_id %d num_devices %d", 2086 req->mlo_chip_id, req->mlo_group_id, req->mlo_num_chips); 2087 2088 mutex_lock(&ag->mutex); 2089 2090 if (!ag->hw_link_id_init_done) 2091 ath12k_host_cap_hw_link_id_init(ag); 2092 2093 for (i = 0; i < ag->num_devices; i++) { 2094 info = &req->mlo_chip_info[i]; 2095 partner_ab = ag->ab[i]; 2096 2097 if (partner_ab->device_id == ATH12K_INVALID_DEVICE_ID) { 2098 ath12k_err(ab, "failed to send MLO cap due to invalid partner device id\n"); 2099 ret = -EINVAL; 2100 goto device_cleanup; 2101 } 2102 2103 info->chip_id = partner_ab->device_id; 2104 info->num_local_links = partner_ab->qmi.num_radios; 2105 2106 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo device id %d num_link %d\n", 2107 info->chip_id, info->num_local_links); 2108 2109 for (j = 0; j < info->num_local_links; j++) { 2110 info->hw_link_id[j] = partner_ab->wsi_info.hw_link_id_base + j; 2111 info->valid_mlo_link_id[j] = 1; 2112 2113 ath12k_dbg(ab, ATH12K_DBG_QMI, "mlo hw_link_id %d\n", 2114 info->hw_link_id[j]); 2115 2116 hw_link_id++; 2117 } 2118 } 2119 2120 if (hw_link_id <= 0) 2121 ag->mlo_capable = false; 2122 2123 req->mlo_chip_info_valid = 1; 2124 2125 mutex_unlock(&ag->mutex); 2126 2127 return 0; 2128 2129 device_cleanup: 2130 for (i = i - 1; i >= 0; i--) { 2131 info = &req->mlo_chip_info[i]; 2132 2133 memset(info, 0, sizeof(*info)); 2134 } 2135 2136 req->mlo_num_chips = 0; 2137 req->mlo_num_chips_valid = 0; 2138 2139 req->max_mlo_peer = 0; 2140 req->max_mlo_peer_valid = 0; 2141 req->mlo_group_id = 0; 2142 req->mlo_group_id_valid = 0; 2143 req->mlo_chip_id = 0; 2144 req->mlo_chip_id_valid = 0; 2145 req->mlo_capable = 0; 2146 req->mlo_capable_valid = 0; 2147 2148 ag->mlo_capable = false; 2149 2150 mutex_unlock(&ag->mutex); 2151 2152 return ret; 2153 } 2154 2155 /* clang stack usage explodes if this is inlined */ 2156 static noinline_for_stack 2157 int ath12k_qmi_host_cap_send(struct ath12k_base *ab) 2158 { 2159 struct qmi_wlanfw_host_cap_req_msg_v01 req = {}; 2160 struct qmi_wlanfw_host_cap_resp_msg_v01 resp = {}; 2161 struct qmi_txn txn; 2162 int ret = 0; 2163 2164 req.num_clients_valid = 1; 2165 req.num_clients = 1; 2166 req.mem_cfg_mode = ab->qmi.target_mem_mode; 2167 req.mem_cfg_mode_valid = 1; 2168 req.bdf_support_valid = 1; 2169 req.bdf_support = 1; 2170 2171 req.m3_support_valid = 1; 2172 req.m3_support = 1; 2173 req.m3_cache_support_valid = 1; 2174 req.m3_cache_support = 1; 2175 2176 req.cal_done_valid = 1; 2177 req.cal_done = ab->qmi.cal_done; 2178 2179 if (ab->hw_params->qmi_cnss_feature_bitmap) { 2180 req.feature_list_valid = 1; 2181 req.feature_list = ab->hw_params->qmi_cnss_feature_bitmap; 2182 } 2183 2184 /* BRINGUP: here we are piggybacking a lot of stuff using 2185 * internal_sleep_clock, should it be split? 2186 */ 2187 if (ab->hw_params->internal_sleep_clock) { 2188 req.nm_modem_valid = 1; 2189 2190 /* Notify firmware that this is non-qualcomm platform. */ 2191 req.nm_modem |= HOST_CSTATE_BIT; 2192 2193 /* Notify firmware about the sleep clock selection, 2194 * nm_modem_bit[1] is used for this purpose. Host driver on 2195 * non-qualcomm platforms should select internal sleep 2196 * clock. 2197 */ 2198 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT; 2199 req.nm_modem |= PLATFORM_CAP_PCIE_GLOBAL_RESET; 2200 } 2201 2202 ret = ath12k_host_cap_parse_mlo(ab, &req); 2203 if (ret < 0) 2204 goto out; 2205 2206 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2207 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp); 2208 if (ret < 0) 2209 goto out; 2210 2211 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2212 QMI_WLANFW_HOST_CAP_REQ_V01, 2213 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN, 2214 qmi_wlanfw_host_cap_req_msg_v01_ei, &req); 2215 if (ret < 0) { 2216 qmi_txn_cancel(&txn); 2217 ath12k_warn(ab, "Failed to send host capability request,err = %d\n", ret); 2218 goto out; 2219 } 2220 2221 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 2222 if (ret < 0) 2223 goto out; 2224 2225 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2226 ath12k_warn(ab, "Host capability request failed, result: %d, err: %d\n", 2227 resp.resp.result, resp.resp.error); 2228 ret = -EINVAL; 2229 goto out; 2230 } 2231 2232 out: 2233 return ret; 2234 } 2235 2236 static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab) 2237 { 2238 struct qmi_wlanfw_phy_cap_req_msg_v01 req = {}; 2239 struct qmi_wlanfw_phy_cap_resp_msg_v01 resp = {}; 2240 struct qmi_txn txn; 2241 int ret; 2242 2243 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2244 qmi_wlanfw_phy_cap_resp_msg_v01_ei, &resp); 2245 if (ret < 0) 2246 goto out; 2247 2248 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2249 QMI_WLANFW_PHY_CAP_REQ_V01, 2250 QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN, 2251 qmi_wlanfw_phy_cap_req_msg_v01_ei, &req); 2252 if (ret < 0) { 2253 qmi_txn_cancel(&txn); 2254 ath12k_warn(ab, "failed to send phy capability request: %d\n", 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 goto out; 2261 2262 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2263 ret = -EOPNOTSUPP; 2264 goto out; 2265 } 2266 2267 if (!resp.num_phy_valid) { 2268 ret = -ENODATA; 2269 goto out; 2270 } 2271 2272 ab->qmi.num_radios = resp.num_phy; 2273 2274 ath12k_dbg(ab, ATH12K_DBG_QMI, 2275 "phy capability resp valid %d num_phy %d valid %d board_id %d\n", 2276 resp.num_phy_valid, resp.num_phy, 2277 resp.board_id_valid, resp.board_id); 2278 2279 return; 2280 2281 out: 2282 /* If PHY capability not advertised then rely on default num link */ 2283 ab->qmi.num_radios = ab->hw_params->def_num_link; 2284 2285 ath12k_dbg(ab, ATH12K_DBG_QMI, 2286 "no valid response from PHY capability, choose default num_phy %d\n", 2287 ab->qmi.num_radios); 2288 } 2289 2290 static int ath12k_qmi_fw_ind_register_send(struct ath12k_base *ab) 2291 { 2292 struct qmi_wlanfw_ind_register_req_msg_v01 *req; 2293 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp; 2294 struct qmi_handle *handle = &ab->qmi.handle; 2295 struct qmi_txn txn; 2296 int ret; 2297 2298 req = kzalloc(sizeof(*req), GFP_KERNEL); 2299 if (!req) 2300 return -ENOMEM; 2301 2302 resp = kzalloc(sizeof(*resp), GFP_KERNEL); 2303 if (!resp) { 2304 ret = -ENOMEM; 2305 goto resp_out; 2306 } 2307 2308 req->client_id_valid = 1; 2309 req->client_id = QMI_WLANFW_CLIENT_ID; 2310 req->fw_ready_enable_valid = 1; 2311 req->fw_ready_enable = 1; 2312 req->request_mem_enable_valid = 1; 2313 req->request_mem_enable = 1; 2314 req->fw_mem_ready_enable_valid = 1; 2315 req->fw_mem_ready_enable = 1; 2316 req->cal_done_enable_valid = 1; 2317 req->cal_done_enable = 1; 2318 req->fw_init_done_enable_valid = 1; 2319 req->fw_init_done_enable = 1; 2320 2321 req->pin_connect_result_enable_valid = 0; 2322 req->pin_connect_result_enable = 0; 2323 2324 ret = qmi_txn_init(handle, &txn, 2325 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp); 2326 if (ret < 0) 2327 goto out; 2328 2329 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2330 QMI_WLANFW_IND_REGISTER_REQ_V01, 2331 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN, 2332 qmi_wlanfw_ind_register_req_msg_v01_ei, req); 2333 if (ret < 0) { 2334 qmi_txn_cancel(&txn); 2335 ath12k_warn(ab, "Failed to send indication register request, err = %d\n", 2336 ret); 2337 goto out; 2338 } 2339 2340 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 2341 if (ret < 0) { 2342 ath12k_warn(ab, "failed to register fw indication %d\n", ret); 2343 goto out; 2344 } 2345 2346 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { 2347 ath12k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n", 2348 resp->resp.result, resp->resp.error); 2349 ret = -EINVAL; 2350 goto out; 2351 } 2352 2353 out: 2354 kfree(resp); 2355 resp_out: 2356 kfree(req); 2357 return ret; 2358 } 2359 2360 /* clang stack usage explodes if this is inlined */ 2361 static noinline_for_stack 2362 int ath12k_qmi_respond_fw_mem_request(struct ath12k_base *ab) 2363 { 2364 struct qmi_wlanfw_respond_mem_req_msg_v01 *req; 2365 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp = {}; 2366 struct qmi_txn txn; 2367 int ret = 0, i; 2368 bool delayed; 2369 2370 req = kzalloc(sizeof(*req), GFP_KERNEL); 2371 if (!req) 2372 return -ENOMEM; 2373 2374 /* Some targets by default request a block of big contiguous 2375 * DMA memory, it's hard to allocate from kernel. So host returns 2376 * failure to firmware and firmware then request multiple blocks of 2377 * small chunk size memory. 2378 */ 2379 if (ab->qmi.target_mem_delayed) { 2380 delayed = true; 2381 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi delays mem_request %d\n", 2382 ab->qmi.mem_seg_count); 2383 } else { 2384 delayed = false; 2385 req->mem_seg_len = ab->qmi.mem_seg_count; 2386 for (i = 0; i < req->mem_seg_len ; i++) { 2387 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr; 2388 req->mem_seg[i].size = ab->qmi.target_mem[i].size; 2389 req->mem_seg[i].type = ab->qmi.target_mem[i].type; 2390 ath12k_dbg(ab, ATH12K_DBG_QMI, 2391 "qmi req mem_seg[%d] %pad %u %u\n", i, 2392 &ab->qmi.target_mem[i].paddr, 2393 ab->qmi.target_mem[i].size, 2394 ab->qmi.target_mem[i].type); 2395 } 2396 } 2397 2398 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2399 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp); 2400 if (ret < 0) 2401 goto out; 2402 2403 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2404 QMI_WLANFW_RESPOND_MEM_REQ_V01, 2405 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN, 2406 qmi_wlanfw_respond_mem_req_msg_v01_ei, req); 2407 if (ret < 0) { 2408 qmi_txn_cancel(&txn); 2409 ath12k_warn(ab, "qmi failed to respond memory request, err = %d\n", 2410 ret); 2411 goto out; 2412 } 2413 2414 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 2415 if (ret < 0) { 2416 ath12k_warn(ab, "qmi failed memory request, err = %d\n", ret); 2417 goto out; 2418 } 2419 2420 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2421 /* the error response is expected when 2422 * target_mem_delayed is true. 2423 */ 2424 if (delayed && resp.resp.error == 0) 2425 goto out; 2426 2427 ath12k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", 2428 resp.resp.result, resp.resp.error); 2429 ret = -EINVAL; 2430 goto out; 2431 } 2432 out: 2433 kfree(req); 2434 return ret; 2435 } 2436 2437 static void ath12k_qmi_free_mlo_mem_chunk(struct ath12k_base *ab, 2438 struct target_mem_chunk *chunk, 2439 int idx) 2440 { 2441 struct ath12k_hw_group *ag = ab->ag; 2442 struct target_mem_chunk *mlo_chunk; 2443 2444 lockdep_assert_held(&ag->mutex); 2445 2446 if (!ag->mlo_mem.init_done || ag->num_started) 2447 return; 2448 2449 if (idx >= ARRAY_SIZE(ag->mlo_mem.chunk)) { 2450 ath12k_warn(ab, "invalid index for MLO memory chunk free: %d\n", idx); 2451 return; 2452 } 2453 2454 mlo_chunk = &ag->mlo_mem.chunk[idx]; 2455 if (mlo_chunk->v.addr) { 2456 dma_free_coherent(ab->dev, 2457 mlo_chunk->size, 2458 mlo_chunk->v.addr, 2459 mlo_chunk->paddr); 2460 mlo_chunk->v.addr = NULL; 2461 } 2462 2463 mlo_chunk->paddr = 0; 2464 mlo_chunk->size = 0; 2465 chunk->v.addr = NULL; 2466 chunk->paddr = 0; 2467 chunk->size = 0; 2468 } 2469 2470 static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab) 2471 { 2472 struct ath12k_hw_group *ag = ab->ag; 2473 int i, mlo_idx; 2474 2475 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) { 2476 if (!ab->qmi.target_mem[i].v.addr) 2477 continue; 2478 2479 if (ab->qmi.target_mem[i].type == MLO_GLOBAL_MEM_REGION_TYPE) { 2480 ath12k_qmi_free_mlo_mem_chunk(ab, 2481 &ab->qmi.target_mem[i], 2482 mlo_idx++); 2483 } else { 2484 dma_free_coherent(ab->dev, 2485 ab->qmi.target_mem[i].prev_size, 2486 ab->qmi.target_mem[i].v.addr, 2487 ab->qmi.target_mem[i].paddr); 2488 ab->qmi.target_mem[i].v.addr = NULL; 2489 } 2490 } 2491 2492 if (!ag->num_started && ag->mlo_mem.init_done) { 2493 ag->mlo_mem.init_done = false; 2494 ag->mlo_mem.mlo_mem_size = 0; 2495 } 2496 } 2497 2498 static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab, 2499 struct target_mem_chunk *chunk) 2500 { 2501 /* Firmware reloads in recovery/resume. 2502 * In such cases, no need to allocate memory for FW again. 2503 */ 2504 if (chunk->v.addr) { 2505 if (chunk->prev_type == chunk->type && 2506 chunk->prev_size == chunk->size) 2507 goto this_chunk_done; 2508 2509 /* cannot reuse the existing chunk */ 2510 dma_free_coherent(ab->dev, chunk->prev_size, 2511 chunk->v.addr, chunk->paddr); 2512 chunk->v.addr = NULL; 2513 } 2514 2515 chunk->v.addr = dma_alloc_coherent(ab->dev, 2516 chunk->size, 2517 &chunk->paddr, 2518 GFP_KERNEL | __GFP_NOWARN); 2519 if (!chunk->v.addr) { 2520 if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) { 2521 ab->qmi.target_mem_delayed = true; 2522 ath12k_warn(ab, 2523 "qmi dma allocation failed (%d B type %u), will try later with small size\n", 2524 chunk->size, 2525 chunk->type); 2526 ath12k_qmi_free_target_mem_chunk(ab); 2527 return -EAGAIN; 2528 } 2529 ath12k_warn(ab, "memory allocation failure for %u size: %d\n", 2530 chunk->type, chunk->size); 2531 return -ENOMEM; 2532 } 2533 chunk->prev_type = chunk->type; 2534 chunk->prev_size = chunk->size; 2535 this_chunk_done: 2536 return 0; 2537 } 2538 2539 static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab) 2540 { 2541 struct target_mem_chunk *chunk, *mlo_chunk; 2542 struct ath12k_hw_group *ag = ab->ag; 2543 int i, mlo_idx, ret; 2544 int mlo_size = 0; 2545 2546 mutex_lock(&ag->mutex); 2547 2548 if (!ag->mlo_mem.init_done) { 2549 memset(ag->mlo_mem.chunk, 0, sizeof(ag->mlo_mem.chunk)); 2550 ag->mlo_mem.init_done = true; 2551 } 2552 2553 ab->qmi.target_mem_delayed = false; 2554 2555 for (i = 0, mlo_idx = 0; i < ab->qmi.mem_seg_count; i++) { 2556 chunk = &ab->qmi.target_mem[i]; 2557 2558 /* Allocate memory for the region and the functionality supported 2559 * on the host. For the non-supported memory region, host does not 2560 * allocate memory, assigns NULL and FW will handle this without crashing. 2561 */ 2562 switch (chunk->type) { 2563 case HOST_DDR_REGION_TYPE: 2564 case M3_DUMP_REGION_TYPE: 2565 case PAGEABLE_MEM_REGION_TYPE: 2566 case CALDB_MEM_REGION_TYPE: 2567 ret = ath12k_qmi_alloc_chunk(ab, chunk); 2568 if (ret) 2569 goto err; 2570 break; 2571 case MLO_GLOBAL_MEM_REGION_TYPE: 2572 mlo_size += chunk->size; 2573 if (ag->mlo_mem.mlo_mem_size && 2574 mlo_size > ag->mlo_mem.mlo_mem_size) { 2575 ath12k_err(ab, "QMI MLO memory allocation failure, requested size %d is more than allocated size %d", 2576 mlo_size, ag->mlo_mem.mlo_mem_size); 2577 ret = -EINVAL; 2578 goto err; 2579 } 2580 2581 mlo_chunk = &ag->mlo_mem.chunk[mlo_idx]; 2582 if (mlo_chunk->paddr) { 2583 if (chunk->size != mlo_chunk->size) { 2584 ath12k_err(ab, "QMI MLO chunk memory allocation failure for index %d, requested size %d is more than allocated size %d", 2585 mlo_idx, chunk->size, mlo_chunk->size); 2586 ret = -EINVAL; 2587 goto err; 2588 } 2589 } else { 2590 mlo_chunk->size = chunk->size; 2591 mlo_chunk->type = chunk->type; 2592 ret = ath12k_qmi_alloc_chunk(ab, mlo_chunk); 2593 if (ret) 2594 goto err; 2595 memset(mlo_chunk->v.addr, 0, mlo_chunk->size); 2596 } 2597 2598 chunk->paddr = mlo_chunk->paddr; 2599 chunk->v.addr = mlo_chunk->v.addr; 2600 mlo_idx++; 2601 2602 break; 2603 default: 2604 ath12k_warn(ab, "memory type %u not supported\n", 2605 chunk->type); 2606 chunk->paddr = 0; 2607 chunk->v.addr = NULL; 2608 break; 2609 } 2610 } 2611 2612 if (!ag->mlo_mem.mlo_mem_size) { 2613 ag->mlo_mem.mlo_mem_size = mlo_size; 2614 } else if (ag->mlo_mem.mlo_mem_size != mlo_size) { 2615 ath12k_err(ab, "QMI MLO memory size error, expected size is %d but requested size is %d", 2616 ag->mlo_mem.mlo_mem_size, mlo_size); 2617 ret = -EINVAL; 2618 goto err; 2619 } 2620 2621 mutex_unlock(&ag->mutex); 2622 2623 return 0; 2624 2625 err: 2626 ath12k_qmi_free_target_mem_chunk(ab); 2627 2628 mutex_unlock(&ag->mutex); 2629 2630 /* The firmware will attempt to request memory in smaller chunks 2631 * on the next try. However, the current caller should be notified 2632 * that this instance of request parsing was successful. 2633 * Therefore, return 0 only. 2634 */ 2635 if (ret == -EAGAIN) 2636 ret = 0; 2637 2638 return ret; 2639 } 2640 2641 /* clang stack usage explodes if this is inlined */ 2642 static noinline_for_stack 2643 int ath12k_qmi_request_target_cap(struct ath12k_base *ab) 2644 { 2645 struct qmi_wlanfw_cap_req_msg_v01 req = {}; 2646 struct qmi_wlanfw_cap_resp_msg_v01 resp = {}; 2647 struct qmi_txn txn; 2648 unsigned int board_id = ATH12K_BOARD_ID_DEFAULT; 2649 int ret = 0; 2650 int r; 2651 int i; 2652 2653 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2654 qmi_wlanfw_cap_resp_msg_v01_ei, &resp); 2655 if (ret < 0) 2656 goto out; 2657 2658 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2659 QMI_WLANFW_CAP_REQ_V01, 2660 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN, 2661 qmi_wlanfw_cap_req_msg_v01_ei, &req); 2662 if (ret < 0) { 2663 qmi_txn_cancel(&txn); 2664 ath12k_warn(ab, "qmi failed to send target cap request, err = %d\n", 2665 ret); 2666 goto out; 2667 } 2668 2669 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 2670 if (ret < 0) { 2671 ath12k_warn(ab, "qmi failed target cap request %d\n", ret); 2672 goto out; 2673 } 2674 2675 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2676 ath12k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n", 2677 resp.resp.result, resp.resp.error); 2678 ret = -EINVAL; 2679 goto out; 2680 } 2681 2682 if (resp.chip_info_valid) { 2683 ab->qmi.target.chip_id = resp.chip_info.chip_id; 2684 ab->qmi.target.chip_family = resp.chip_info.chip_family; 2685 } 2686 2687 if (resp.board_info_valid) 2688 ab->qmi.target.board_id = resp.board_info.board_id; 2689 else 2690 ab->qmi.target.board_id = board_id; 2691 2692 if (resp.soc_info_valid) 2693 ab->qmi.target.soc_id = resp.soc_info.soc_id; 2694 2695 if (resp.fw_version_info_valid) { 2696 ab->qmi.target.fw_version = resp.fw_version_info.fw_version; 2697 strscpy(ab->qmi.target.fw_build_timestamp, 2698 resp.fw_version_info.fw_build_timestamp, 2699 sizeof(ab->qmi.target.fw_build_timestamp)); 2700 } 2701 2702 if (resp.fw_build_id_valid) 2703 strscpy(ab->qmi.target.fw_build_id, resp.fw_build_id, 2704 sizeof(ab->qmi.target.fw_build_id)); 2705 2706 if (resp.dev_mem_info_valid) { 2707 for (i = 0; i < ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01; i++) { 2708 ab->qmi.dev_mem[i].start = 2709 resp.dev_mem[i].start; 2710 ab->qmi.dev_mem[i].size = 2711 resp.dev_mem[i].size; 2712 ath12k_dbg(ab, ATH12K_DBG_QMI, 2713 "devmem [%d] start 0x%llx size %llu\n", i, 2714 ab->qmi.dev_mem[i].start, 2715 ab->qmi.dev_mem[i].size); 2716 } 2717 } 2718 2719 if (resp.eeprom_caldata_read_timeout_valid) { 2720 ab->qmi.target.eeprom_caldata = resp.eeprom_caldata_read_timeout; 2721 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi cal data supported from eeprom\n"); 2722 } 2723 2724 ath12k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n", 2725 ab->qmi.target.chip_id, ab->qmi.target.chip_family, 2726 ab->qmi.target.board_id, ab->qmi.target.soc_id); 2727 2728 ath12k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s", 2729 ab->qmi.target.fw_version, 2730 ab->qmi.target.fw_build_timestamp, 2731 ab->qmi.target.fw_build_id); 2732 2733 r = ath12k_core_check_smbios(ab); 2734 if (r) 2735 ath12k_dbg(ab, ATH12K_DBG_QMI, "SMBIOS bdf variant name not set.\n"); 2736 2737 r = ath12k_acpi_start(ab); 2738 if (r) 2739 /* ACPI is optional so continue in case of an error */ 2740 ath12k_dbg(ab, ATH12K_DBG_BOOT, "acpi failed: %d\n", r); 2741 2742 r = ath12k_acpi_check_bdf_variant_name(ab); 2743 if (r) 2744 ath12k_dbg(ab, ATH12K_DBG_BOOT, "ACPI bdf variant name not set.\n"); 2745 2746 out: 2747 return ret; 2748 } 2749 2750 static int ath12k_qmi_load_file_target_mem(struct ath12k_base *ab, 2751 const u8 *data, u32 len, u8 type) 2752 { 2753 struct qmi_wlanfw_bdf_download_req_msg_v01 *req; 2754 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp = {}; 2755 struct qmi_txn txn; 2756 const u8 *temp = data; 2757 int ret = 0; 2758 u32 remaining = len; 2759 2760 req = kzalloc(sizeof(*req), GFP_KERNEL); 2761 if (!req) 2762 return -ENOMEM; 2763 2764 while (remaining) { 2765 req->valid = 1; 2766 req->file_id_valid = 1; 2767 req->file_id = ab->qmi.target.board_id; 2768 req->total_size_valid = 1; 2769 req->total_size = remaining; 2770 req->seg_id_valid = 1; 2771 req->data_valid = 1; 2772 req->bdf_type = type; 2773 req->bdf_type_valid = 1; 2774 req->end_valid = 1; 2775 req->end = 0; 2776 2777 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) { 2778 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01; 2779 } else { 2780 req->data_len = remaining; 2781 req->end = 1; 2782 } 2783 2784 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) { 2785 req->data_valid = 0; 2786 req->end = 1; 2787 req->data_len = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE; 2788 } else { 2789 memcpy(req->data, temp, req->data_len); 2790 } 2791 2792 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2793 qmi_wlanfw_bdf_download_resp_msg_v01_ei, 2794 &resp); 2795 if (ret < 0) 2796 goto out; 2797 2798 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf download req fixed addr type %d\n", 2799 type); 2800 2801 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2802 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01, 2803 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN, 2804 qmi_wlanfw_bdf_download_req_msg_v01_ei, req); 2805 if (ret < 0) { 2806 qmi_txn_cancel(&txn); 2807 goto out; 2808 } 2809 2810 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 2811 if (ret < 0) 2812 goto out; 2813 2814 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2815 ath12k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n", 2816 resp.resp.result, resp.resp.error); 2817 ret = -EINVAL; 2818 goto out; 2819 } 2820 2821 if (type == ATH12K_QMI_FILE_TYPE_EEPROM) { 2822 remaining = 0; 2823 } else { 2824 remaining -= req->data_len; 2825 temp += req->data_len; 2826 req->seg_id++; 2827 ath12k_dbg(ab, ATH12K_DBG_QMI, 2828 "qmi bdf download request remaining %i\n", 2829 remaining); 2830 } 2831 } 2832 2833 out: 2834 kfree(req); 2835 return ret; 2836 } 2837 2838 /* clang stack usage explodes if this is inlined */ 2839 static noinline_for_stack 2840 int ath12k_qmi_load_bdf_qmi(struct ath12k_base *ab, 2841 enum ath12k_qmi_bdf_type type) 2842 { 2843 struct device *dev = ab->dev; 2844 char filename[ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE]; 2845 const struct firmware *fw_entry; 2846 struct ath12k_board_data bd; 2847 u32 fw_size, file_type; 2848 int ret = 0; 2849 const u8 *tmp; 2850 2851 memset(&bd, 0, sizeof(bd)); 2852 2853 switch (type) { 2854 case ATH12K_QMI_BDF_TYPE_ELF: 2855 ret = ath12k_core_fetch_bdf(ab, &bd); 2856 if (ret) { 2857 ath12k_warn(ab, "qmi failed to load bdf:\n"); 2858 goto out; 2859 } 2860 2861 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0) 2862 type = ATH12K_QMI_BDF_TYPE_ELF; 2863 else 2864 type = ATH12K_QMI_BDF_TYPE_BIN; 2865 2866 break; 2867 case ATH12K_QMI_BDF_TYPE_REGDB: 2868 ret = ath12k_core_fetch_regdb(ab, &bd); 2869 if (ret) { 2870 ath12k_warn(ab, "qmi failed to load regdb bin:\n"); 2871 goto out; 2872 } 2873 break; 2874 case ATH12K_QMI_BDF_TYPE_CALIBRATION: 2875 2876 if (ab->qmi.target.eeprom_caldata) { 2877 file_type = ATH12K_QMI_FILE_TYPE_EEPROM; 2878 tmp = filename; 2879 fw_size = ATH12K_QMI_MAX_BDF_FILE_NAME_SIZE; 2880 } else { 2881 file_type = ATH12K_QMI_FILE_TYPE_CALDATA; 2882 2883 /* cal-<bus>-<id>.bin */ 2884 snprintf(filename, sizeof(filename), "cal-%s-%s.bin", 2885 ath12k_bus_str(ab->hif.bus), dev_name(dev)); 2886 fw_entry = ath12k_core_firmware_request(ab, filename); 2887 if (!IS_ERR(fw_entry)) 2888 goto success; 2889 2890 fw_entry = ath12k_core_firmware_request(ab, 2891 ATH12K_DEFAULT_CAL_FILE); 2892 if (IS_ERR(fw_entry)) { 2893 ret = PTR_ERR(fw_entry); 2894 ath12k_warn(ab, 2895 "qmi failed to load CAL data file:%s\n", 2896 filename); 2897 goto out; 2898 } 2899 2900 success: 2901 fw_size = min_t(u32, ab->hw_params->fw.board_size, 2902 fw_entry->size); 2903 tmp = fw_entry->data; 2904 } 2905 ret = ath12k_qmi_load_file_target_mem(ab, tmp, fw_size, file_type); 2906 if (ret < 0) { 2907 ath12k_warn(ab, "qmi failed to load caldata\n"); 2908 goto out_qmi_cal; 2909 } 2910 2911 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi caldata downloaded: type: %u\n", 2912 file_type); 2913 2914 out_qmi_cal: 2915 if (!ab->qmi.target.eeprom_caldata) 2916 release_firmware(fw_entry); 2917 return ret; 2918 default: 2919 ath12k_warn(ab, "unknown file type for load %d", type); 2920 goto out; 2921 } 2922 2923 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi bdf_type %d\n", type); 2924 2925 fw_size = min_t(u32, ab->hw_params->fw.board_size, bd.len); 2926 2927 ret = ath12k_qmi_load_file_target_mem(ab, bd.data, fw_size, type); 2928 if (ret < 0) 2929 ath12k_warn(ab, "qmi failed to load bdf file\n"); 2930 2931 out: 2932 ath12k_core_free_bdf(ab, &bd); 2933 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi BDF download sequence completed\n"); 2934 2935 return ret; 2936 } 2937 2938 static void ath12k_qmi_m3_free(struct ath12k_base *ab) 2939 { 2940 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2941 2942 if (!m3_mem->vaddr) 2943 return; 2944 2945 dma_free_coherent(ab->dev, m3_mem->size, 2946 m3_mem->vaddr, m3_mem->paddr); 2947 m3_mem->vaddr = NULL; 2948 m3_mem->size = 0; 2949 } 2950 2951 static int ath12k_qmi_m3_load(struct ath12k_base *ab) 2952 { 2953 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2954 const struct firmware *fw = NULL; 2955 const void *m3_data; 2956 char path[100]; 2957 size_t m3_len; 2958 int ret; 2959 2960 if (ab->fw.m3_data && ab->fw.m3_len > 0) { 2961 /* firmware-N.bin had a m3 firmware file so use that */ 2962 m3_data = ab->fw.m3_data; 2963 m3_len = ab->fw.m3_len; 2964 } else { 2965 /* No m3 file in firmware-N.bin so try to request old 2966 * separate m3.bin. 2967 */ 2968 fw = ath12k_core_firmware_request(ab, ATH12K_M3_FILE); 2969 if (IS_ERR(fw)) { 2970 ret = PTR_ERR(fw); 2971 ath12k_core_create_firmware_path(ab, ATH12K_M3_FILE, 2972 path, sizeof(path)); 2973 ath12k_err(ab, "failed to load %s: %d\n", path, ret); 2974 return ret; 2975 } 2976 2977 m3_data = fw->data; 2978 m3_len = fw->size; 2979 } 2980 2981 /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */ 2982 if (m3_mem->vaddr) { 2983 if (m3_mem->size >= m3_len) 2984 goto skip_m3_alloc; 2985 2986 /* Old buffer is too small, free and reallocate */ 2987 ath12k_qmi_m3_free(ab); 2988 } 2989 2990 m3_mem->vaddr = dma_alloc_coherent(ab->dev, 2991 m3_len, &m3_mem->paddr, 2992 GFP_KERNEL); 2993 if (!m3_mem->vaddr) { 2994 ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n", 2995 fw->size); 2996 ret = -ENOMEM; 2997 goto out; 2998 } 2999 3000 skip_m3_alloc: 3001 memcpy(m3_mem->vaddr, m3_data, m3_len); 3002 m3_mem->size = m3_len; 3003 3004 ret = 0; 3005 3006 out: 3007 release_firmware(fw); 3008 3009 return ret; 3010 } 3011 3012 /* clang stack usage explodes if this is inlined */ 3013 static noinline_for_stack 3014 int ath12k_qmi_wlanfw_m3_info_send(struct ath12k_base *ab) 3015 { 3016 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 3017 struct qmi_wlanfw_m3_info_req_msg_v01 req = {}; 3018 struct qmi_wlanfw_m3_info_resp_msg_v01 resp = {}; 3019 struct qmi_txn txn; 3020 int ret = 0; 3021 3022 ret = ath12k_qmi_m3_load(ab); 3023 if (ret) { 3024 ath12k_err(ab, "failed to load m3 firmware: %d", ret); 3025 return ret; 3026 } 3027 3028 req.addr = m3_mem->paddr; 3029 req.size = m3_mem->size; 3030 3031 ret = qmi_txn_init(&ab->qmi.handle, &txn, 3032 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp); 3033 if (ret < 0) 3034 goto out; 3035 3036 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 3037 QMI_WLANFW_M3_INFO_REQ_V01, 3038 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN, 3039 qmi_wlanfw_m3_info_req_msg_v01_ei, &req); 3040 if (ret < 0) { 3041 qmi_txn_cancel(&txn); 3042 ath12k_warn(ab, "qmi failed to send M3 information request, err = %d\n", 3043 ret); 3044 goto out; 3045 } 3046 3047 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 3048 if (ret < 0) { 3049 ath12k_warn(ab, "qmi failed M3 information request %d\n", ret); 3050 goto out; 3051 } 3052 3053 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 3054 ath12k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n", 3055 resp.resp.result, resp.resp.error); 3056 ret = -EINVAL; 3057 goto out; 3058 } 3059 out: 3060 return ret; 3061 } 3062 3063 static int ath12k_qmi_wlanfw_mode_send(struct ath12k_base *ab, 3064 u32 mode) 3065 { 3066 struct qmi_wlanfw_wlan_mode_req_msg_v01 req = {}; 3067 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp = {}; 3068 struct qmi_txn txn; 3069 int ret = 0; 3070 3071 req.mode = mode; 3072 req.hw_debug_valid = 1; 3073 req.hw_debug = 0; 3074 3075 ret = qmi_txn_init(&ab->qmi.handle, &txn, 3076 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp); 3077 if (ret < 0) 3078 goto out; 3079 3080 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 3081 QMI_WLANFW_WLAN_MODE_REQ_V01, 3082 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN, 3083 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req); 3084 if (ret < 0) { 3085 qmi_txn_cancel(&txn); 3086 ath12k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n", 3087 mode, ret); 3088 goto out; 3089 } 3090 3091 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 3092 if (ret < 0) { 3093 if (mode == ATH12K_FIRMWARE_MODE_OFF && ret == -ENETRESET) { 3094 ath12k_warn(ab, "WLFW service is dis-connected\n"); 3095 return 0; 3096 } 3097 ath12k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n", 3098 mode, ret); 3099 goto out; 3100 } 3101 3102 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 3103 ath12k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n", 3104 mode, resp.resp.result, resp.resp.error); 3105 ret = -EINVAL; 3106 goto out; 3107 } 3108 3109 out: 3110 return ret; 3111 } 3112 3113 static int ath12k_qmi_wlanfw_wlan_cfg_send(struct ath12k_base *ab) 3114 { 3115 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req; 3116 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp = {}; 3117 struct ce_pipe_config *ce_cfg; 3118 struct service_to_pipe *svc_cfg; 3119 struct qmi_txn txn; 3120 int ret = 0, pipe_num; 3121 3122 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce; 3123 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map; 3124 3125 req = kzalloc(sizeof(*req), GFP_KERNEL); 3126 if (!req) 3127 return -ENOMEM; 3128 3129 req->host_version_valid = 1; 3130 strscpy(req->host_version, ATH12K_HOST_VERSION_STRING, 3131 sizeof(req->host_version)); 3132 3133 req->tgt_cfg_valid = 1; 3134 /* This is number of CE configs */ 3135 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len; 3136 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) { 3137 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum; 3138 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir; 3139 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries; 3140 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max; 3141 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags; 3142 } 3143 3144 req->svc_cfg_valid = 1; 3145 /* This is number of Service/CE configs */ 3146 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len; 3147 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) { 3148 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id; 3149 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir; 3150 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum; 3151 } 3152 3153 /* set shadow v3 configuration */ 3154 if (ab->hw_params->supports_shadow_regs) { 3155 req->shadow_reg_v3_valid = 1; 3156 req->shadow_reg_v3_len = min_t(u32, 3157 ab->qmi.ce_cfg.shadow_reg_v3_len, 3158 QMI_WLANFW_MAX_NUM_SHADOW_REG_V3_V01); 3159 memcpy(&req->shadow_reg_v3, ab->qmi.ce_cfg.shadow_reg_v3, 3160 sizeof(u32) * req->shadow_reg_v3_len); 3161 } else { 3162 req->shadow_reg_v3_valid = 0; 3163 } 3164 3165 ret = qmi_txn_init(&ab->qmi.handle, &txn, 3166 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp); 3167 if (ret < 0) 3168 goto out; 3169 3170 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 3171 QMI_WLANFW_WLAN_CFG_REQ_V01, 3172 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN, 3173 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req); 3174 if (ret < 0) { 3175 qmi_txn_cancel(&txn); 3176 ath12k_warn(ab, "qmi failed to send wlan config request, err = %d\n", 3177 ret); 3178 goto out; 3179 } 3180 3181 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 3182 if (ret < 0) { 3183 ath12k_warn(ab, "qmi failed wlan config request, err = %d\n", ret); 3184 goto out; 3185 } 3186 3187 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 3188 ath12k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n", 3189 resp.resp.result, resp.resp.error); 3190 ret = -EINVAL; 3191 goto out; 3192 } 3193 3194 out: 3195 kfree(req); 3196 return ret; 3197 } 3198 3199 static int ath12k_qmi_wlanfw_wlan_ini_send(struct ath12k_base *ab) 3200 { 3201 struct qmi_wlanfw_wlan_ini_resp_msg_v01 resp = {}; 3202 struct qmi_wlanfw_wlan_ini_req_msg_v01 req = {}; 3203 struct qmi_txn txn; 3204 int ret; 3205 3206 req.enable_fwlog_valid = true; 3207 req.enable_fwlog = 1; 3208 3209 ret = qmi_txn_init(&ab->qmi.handle, &txn, 3210 qmi_wlanfw_wlan_ini_resp_msg_v01_ei, &resp); 3211 if (ret < 0) 3212 goto out; 3213 3214 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 3215 ATH12K_QMI_WLANFW_WLAN_INI_REQ_V01, 3216 QMI_WLANFW_WLAN_INI_REQ_MSG_V01_MAX_LEN, 3217 qmi_wlanfw_wlan_ini_req_msg_v01_ei, &req); 3218 if (ret < 0) { 3219 qmi_txn_cancel(&txn); 3220 ath12k_warn(ab, "failed to send QMI wlan ini request: %d\n", 3221 ret); 3222 goto out; 3223 } 3224 3225 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH12K_QMI_WLANFW_TIMEOUT_MS)); 3226 if (ret < 0) { 3227 ath12k_warn(ab, "failed to receive QMI wlan ini request: %d\n", ret); 3228 goto out; 3229 } 3230 3231 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 3232 ath12k_warn(ab, "QMI wlan ini response failure: %d %d\n", 3233 resp.resp.result, resp.resp.error); 3234 ret = -EINVAL; 3235 goto out; 3236 } 3237 3238 out: 3239 return ret; 3240 } 3241 3242 void ath12k_qmi_firmware_stop(struct ath12k_base *ab) 3243 { 3244 int ret; 3245 3246 clear_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags); 3247 3248 ret = ath12k_qmi_wlanfw_mode_send(ab, ATH12K_FIRMWARE_MODE_OFF); 3249 if (ret < 0) { 3250 ath12k_warn(ab, "qmi failed to send wlan mode off\n"); 3251 return; 3252 } 3253 } 3254 3255 int ath12k_qmi_firmware_start(struct ath12k_base *ab, 3256 u32 mode) 3257 { 3258 int ret; 3259 3260 ret = ath12k_qmi_wlanfw_wlan_ini_send(ab); 3261 if (ret < 0) { 3262 ath12k_warn(ab, "qmi failed to send wlan fw ini: %d\n", ret); 3263 return ret; 3264 } 3265 3266 ret = ath12k_qmi_wlanfw_wlan_cfg_send(ab); 3267 if (ret < 0) { 3268 ath12k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret); 3269 return ret; 3270 } 3271 3272 ret = ath12k_qmi_wlanfw_mode_send(ab, mode); 3273 if (ret < 0) { 3274 ath12k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret); 3275 return ret; 3276 } 3277 3278 return 0; 3279 } 3280 3281 static int 3282 ath12k_qmi_driver_event_post(struct ath12k_qmi *qmi, 3283 enum ath12k_qmi_event_type type, 3284 void *data) 3285 { 3286 struct ath12k_qmi_driver_event *event; 3287 3288 event = kzalloc(sizeof(*event), GFP_ATOMIC); 3289 if (!event) 3290 return -ENOMEM; 3291 3292 event->type = type; 3293 event->data = data; 3294 3295 spin_lock(&qmi->event_lock); 3296 list_add_tail(&event->list, &qmi->event_list); 3297 spin_unlock(&qmi->event_lock); 3298 3299 queue_work(qmi->event_wq, &qmi->event_work); 3300 3301 return 0; 3302 } 3303 3304 void ath12k_qmi_trigger_host_cap(struct ath12k_base *ab) 3305 { 3306 struct ath12k_qmi *qmi = &ab->qmi; 3307 3308 spin_lock(&qmi->event_lock); 3309 3310 if (ath12k_qmi_get_event_block(qmi)) 3311 ath12k_qmi_set_event_block(qmi, false); 3312 3313 spin_unlock(&qmi->event_lock); 3314 3315 ath12k_dbg(ab, ATH12K_DBG_QMI, "trigger host cap for device id %d\n", 3316 ab->device_id); 3317 3318 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_HOST_CAP, NULL); 3319 } 3320 3321 static bool ath12k_qmi_hw_group_host_cap_ready(struct ath12k_hw_group *ag) 3322 { 3323 struct ath12k_base *ab; 3324 int i; 3325 3326 for (i = 0; i < ag->num_devices; i++) { 3327 ab = ag->ab[i]; 3328 3329 if (!(ab && ab->qmi.num_radios != U8_MAX)) 3330 return false; 3331 } 3332 3333 return true; 3334 } 3335 3336 static struct ath12k_base *ath12k_qmi_hw_group_find_blocked(struct ath12k_hw_group *ag) 3337 { 3338 struct ath12k_base *ab; 3339 int i; 3340 3341 lockdep_assert_held(&ag->mutex); 3342 3343 for (i = 0; i < ag->num_devices; i++) { 3344 ab = ag->ab[i]; 3345 if (!ab) 3346 continue; 3347 3348 spin_lock(&ab->qmi.event_lock); 3349 3350 if (ath12k_qmi_get_event_block(&ab->qmi)) { 3351 spin_unlock(&ab->qmi.event_lock); 3352 return ab; 3353 } 3354 3355 spin_unlock(&ab->qmi.event_lock); 3356 } 3357 3358 return NULL; 3359 } 3360 3361 /* clang stack usage explodes if this is inlined */ 3362 static noinline_for_stack 3363 int ath12k_qmi_event_server_arrive(struct ath12k_qmi *qmi) 3364 { 3365 struct ath12k_base *ab = qmi->ab, *block_ab; 3366 struct ath12k_hw_group *ag = ab->ag; 3367 int ret; 3368 3369 ath12k_qmi_phy_cap_send(ab); 3370 3371 ret = ath12k_qmi_fw_ind_register_send(ab); 3372 if (ret < 0) { 3373 ath12k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret); 3374 return ret; 3375 } 3376 3377 spin_lock(&qmi->event_lock); 3378 3379 ath12k_qmi_set_event_block(qmi, true); 3380 3381 spin_unlock(&qmi->event_lock); 3382 3383 mutex_lock(&ag->mutex); 3384 3385 if (ath12k_qmi_hw_group_host_cap_ready(ag)) { 3386 ath12k_core_hw_group_set_mlo_capable(ag); 3387 3388 block_ab = ath12k_qmi_hw_group_find_blocked(ag); 3389 if (block_ab) 3390 ath12k_qmi_trigger_host_cap(block_ab); 3391 } 3392 3393 mutex_unlock(&ag->mutex); 3394 3395 return ret; 3396 } 3397 3398 /* clang stack usage explodes if this is inlined */ 3399 static noinline_for_stack 3400 int ath12k_qmi_event_mem_request(struct ath12k_qmi *qmi) 3401 { 3402 struct ath12k_base *ab = qmi->ab; 3403 int ret; 3404 3405 ret = ath12k_qmi_respond_fw_mem_request(ab); 3406 if (ret < 0) { 3407 ath12k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret); 3408 return ret; 3409 } 3410 3411 return ret; 3412 } 3413 3414 /* clang stack usage explodes if this is inlined */ 3415 static noinline_for_stack 3416 int ath12k_qmi_event_load_bdf(struct ath12k_qmi *qmi) 3417 { 3418 struct ath12k_base *ab = qmi->ab; 3419 int ret; 3420 3421 ret = ath12k_qmi_request_target_cap(ab); 3422 if (ret < 0) { 3423 ath12k_warn(ab, "qmi failed to req target capabilities:%d\n", ret); 3424 return ret; 3425 } 3426 3427 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_REGDB); 3428 if (ret < 0) { 3429 ath12k_warn(ab, "qmi failed to load regdb file:%d\n", ret); 3430 return ret; 3431 } 3432 3433 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_ELF); 3434 if (ret < 0) { 3435 ath12k_warn(ab, "qmi failed to load board data file:%d\n", ret); 3436 return ret; 3437 } 3438 3439 if (ab->hw_params->download_calib) { 3440 ret = ath12k_qmi_load_bdf_qmi(ab, ATH12K_QMI_BDF_TYPE_CALIBRATION); 3441 if (ret < 0) 3442 ath12k_warn(ab, "qmi failed to load calibrated data :%d\n", ret); 3443 } 3444 3445 ret = ath12k_qmi_wlanfw_m3_info_send(ab); 3446 if (ret < 0) { 3447 ath12k_warn(ab, "qmi failed to send m3 info req:%d\n", ret); 3448 return ret; 3449 } 3450 3451 return ret; 3452 } 3453 3454 static void ath12k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, 3455 struct sockaddr_qrtr *sq, 3456 struct qmi_txn *txn, 3457 const void *data) 3458 { 3459 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle); 3460 struct ath12k_base *ab = qmi->ab; 3461 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data; 3462 int i, ret; 3463 3464 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware request memory request\n"); 3465 3466 if (msg->mem_seg_len == 0 || 3467 msg->mem_seg_len > ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01) 3468 ath12k_warn(ab, "Invalid memory segment length: %u\n", 3469 msg->mem_seg_len); 3470 3471 ab->qmi.mem_seg_count = msg->mem_seg_len; 3472 3473 for (i = 0; i < qmi->mem_seg_count ; i++) { 3474 ab->qmi.target_mem[i].type = msg->mem_seg[i].type; 3475 ab->qmi.target_mem[i].size = msg->mem_seg[i].size; 3476 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi mem seg type %d size %d\n", 3477 msg->mem_seg[i].type, msg->mem_seg[i].size); 3478 } 3479 3480 ret = ath12k_qmi_alloc_target_mem_chunk(ab); 3481 if (ret) { 3482 ath12k_warn(ab, "qmi failed to alloc target memory: %d\n", 3483 ret); 3484 return; 3485 } 3486 3487 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_REQUEST_MEM, NULL); 3488 } 3489 3490 static void ath12k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl, 3491 struct sockaddr_qrtr *sq, 3492 struct qmi_txn *txn, 3493 const void *decoded) 3494 { 3495 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle); 3496 struct ath12k_base *ab = qmi->ab; 3497 3498 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware memory ready indication\n"); 3499 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_MEM_READY, NULL); 3500 } 3501 3502 static void ath12k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl, 3503 struct sockaddr_qrtr *sq, 3504 struct qmi_txn *txn, 3505 const void *decoded) 3506 { 3507 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle); 3508 struct ath12k_base *ab = qmi->ab; 3509 3510 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi firmware ready\n"); 3511 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_FW_READY, NULL); 3512 } 3513 3514 static const struct qmi_msg_handler ath12k_qmi_msg_handlers[] = { 3515 { 3516 .type = QMI_INDICATION, 3517 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01, 3518 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei, 3519 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01), 3520 .fn = ath12k_qmi_msg_mem_request_cb, 3521 }, 3522 { 3523 .type = QMI_INDICATION, 3524 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01, 3525 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei, 3526 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01), 3527 .fn = ath12k_qmi_msg_mem_ready_cb, 3528 }, 3529 { 3530 .type = QMI_INDICATION, 3531 .msg_id = QMI_WLFW_FW_READY_IND_V01, 3532 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei, 3533 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01), 3534 .fn = ath12k_qmi_msg_fw_ready_cb, 3535 }, 3536 3537 /* end of list */ 3538 {}, 3539 }; 3540 3541 static int ath12k_qmi_ops_new_server(struct qmi_handle *qmi_hdl, 3542 struct qmi_service *service) 3543 { 3544 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle); 3545 struct ath12k_base *ab = qmi->ab; 3546 struct sockaddr_qrtr *sq = &qmi->sq; 3547 int ret; 3548 3549 sq->sq_family = AF_QIPCRTR; 3550 sq->sq_node = service->node; 3551 sq->sq_port = service->port; 3552 3553 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq, 3554 sizeof(*sq), 0); 3555 if (ret) { 3556 ath12k_warn(ab, "qmi failed to connect to remote service %d\n", ret); 3557 return ret; 3558 } 3559 3560 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw qmi service connected\n"); 3561 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_ARRIVE, NULL); 3562 3563 return ret; 3564 } 3565 3566 static void ath12k_qmi_ops_del_server(struct qmi_handle *qmi_hdl, 3567 struct qmi_service *service) 3568 { 3569 struct ath12k_qmi *qmi = container_of(qmi_hdl, struct ath12k_qmi, handle); 3570 struct ath12k_base *ab = qmi->ab; 3571 3572 ath12k_dbg(ab, ATH12K_DBG_QMI, "qmi wifi fw del server\n"); 3573 ath12k_qmi_driver_event_post(qmi, ATH12K_QMI_EVENT_SERVER_EXIT, NULL); 3574 } 3575 3576 static const struct qmi_ops ath12k_qmi_ops = { 3577 .new_server = ath12k_qmi_ops_new_server, 3578 .del_server = ath12k_qmi_ops_del_server, 3579 }; 3580 3581 static int ath12k_qmi_event_host_cap(struct ath12k_qmi *qmi) 3582 { 3583 struct ath12k_base *ab = qmi->ab; 3584 int ret; 3585 3586 ret = ath12k_qmi_host_cap_send(ab); 3587 if (ret < 0) { 3588 ath12k_warn(ab, "failed to send qmi host cap for device id %d: %d\n", 3589 ab->device_id, ret); 3590 return ret; 3591 } 3592 3593 return ret; 3594 } 3595 3596 static void ath12k_qmi_driver_event_work(struct work_struct *work) 3597 { 3598 struct ath12k_qmi *qmi = container_of(work, struct ath12k_qmi, 3599 event_work); 3600 struct ath12k_qmi_driver_event *event; 3601 struct ath12k_base *ab = qmi->ab; 3602 int ret; 3603 3604 spin_lock(&qmi->event_lock); 3605 while (!list_empty(&qmi->event_list)) { 3606 event = list_first_entry(&qmi->event_list, 3607 struct ath12k_qmi_driver_event, list); 3608 list_del(&event->list); 3609 spin_unlock(&qmi->event_lock); 3610 3611 if (test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags)) 3612 goto skip; 3613 3614 switch (event->type) { 3615 case ATH12K_QMI_EVENT_SERVER_ARRIVE: 3616 ret = ath12k_qmi_event_server_arrive(qmi); 3617 if (ret < 0) 3618 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags); 3619 break; 3620 case ATH12K_QMI_EVENT_SERVER_EXIT: 3621 set_bit(ATH12K_FLAG_CRASH_FLUSH, &ab->dev_flags); 3622 break; 3623 case ATH12K_QMI_EVENT_REQUEST_MEM: 3624 ret = ath12k_qmi_event_mem_request(qmi); 3625 if (ret < 0) 3626 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags); 3627 break; 3628 case ATH12K_QMI_EVENT_FW_MEM_READY: 3629 ret = ath12k_qmi_event_load_bdf(qmi); 3630 if (ret < 0) 3631 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags); 3632 break; 3633 case ATH12K_QMI_EVENT_FW_READY: 3634 clear_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags); 3635 if (test_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, &ab->dev_flags)) { 3636 if (ab->is_reset) 3637 ath12k_hal_dump_srng_stats(ab); 3638 3639 set_bit(ATH12K_FLAG_RECOVERY, &ab->dev_flags); 3640 queue_work(ab->workqueue, &ab->restart_work); 3641 break; 3642 } 3643 3644 clear_bit(ATH12K_FLAG_CRASH_FLUSH, 3645 &ab->dev_flags); 3646 ret = ath12k_core_qmi_firmware_ready(ab); 3647 if (!ret) 3648 set_bit(ATH12K_FLAG_QMI_FW_READY_COMPLETE, 3649 &ab->dev_flags); 3650 3651 break; 3652 case ATH12K_QMI_EVENT_HOST_CAP: 3653 ret = ath12k_qmi_event_host_cap(qmi); 3654 if (ret < 0) 3655 set_bit(ATH12K_FLAG_QMI_FAIL, &ab->dev_flags); 3656 break; 3657 default: 3658 ath12k_warn(ab, "invalid event type: %d", event->type); 3659 break; 3660 } 3661 3662 skip: 3663 kfree(event); 3664 spin_lock(&qmi->event_lock); 3665 } 3666 spin_unlock(&qmi->event_lock); 3667 } 3668 3669 int ath12k_qmi_init_service(struct ath12k_base *ab) 3670 { 3671 int ret; 3672 3673 memset(&ab->qmi.target, 0, sizeof(struct target_info)); 3674 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk)); 3675 ab->qmi.ab = ab; 3676 3677 ab->qmi.target_mem_mode = ATH12K_QMI_TARGET_MEM_MODE_DEFAULT; 3678 ret = qmi_handle_init(&ab->qmi.handle, ATH12K_QMI_RESP_LEN_MAX, 3679 &ath12k_qmi_ops, ath12k_qmi_msg_handlers); 3680 if (ret < 0) { 3681 ath12k_warn(ab, "failed to initialize qmi handle\n"); 3682 return ret; 3683 } 3684 3685 ab->qmi.event_wq = alloc_ordered_workqueue("ath12k_qmi_driver_event", 0); 3686 if (!ab->qmi.event_wq) { 3687 ath12k_err(ab, "failed to allocate workqueue\n"); 3688 return -EFAULT; 3689 } 3690 3691 INIT_LIST_HEAD(&ab->qmi.event_list); 3692 spin_lock_init(&ab->qmi.event_lock); 3693 INIT_WORK(&ab->qmi.event_work, ath12k_qmi_driver_event_work); 3694 3695 ret = qmi_add_lookup(&ab->qmi.handle, ATH12K_QMI_WLFW_SERVICE_ID_V01, 3696 ATH12K_QMI_WLFW_SERVICE_VERS_V01, 3697 ab->qmi.service_ins_id); 3698 if (ret < 0) { 3699 ath12k_warn(ab, "failed to add qmi lookup\n"); 3700 destroy_workqueue(ab->qmi.event_wq); 3701 return ret; 3702 } 3703 3704 return ret; 3705 } 3706 3707 void ath12k_qmi_deinit_service(struct ath12k_base *ab) 3708 { 3709 if (!ab->qmi.ab) 3710 return; 3711 3712 qmi_handle_release(&ab->qmi.handle); 3713 cancel_work_sync(&ab->qmi.event_work); 3714 destroy_workqueue(ab->qmi.event_wq); 3715 ath12k_qmi_m3_free(ab); 3716 ath12k_qmi_free_target_mem_chunk(ab); 3717 ab->qmi.ab = NULL; 3718 } 3719 3720 void ath12k_qmi_free_resource(struct ath12k_base *ab) 3721 { 3722 ath12k_qmi_free_target_mem_chunk(ab); 3723 ath12k_qmi_m3_free(ab); 3724 } 3725