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