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