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