1// SPDX-License-Identifier: BSD-3-Clause-Clear 2/* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 */ 5 6#include <linux/elf.h> 7 8#include "qmi.h" 9#include "core.h" 10#include "debug.h" 11#include <linux/of.h> 12#include <linux/firmware.h> 13 14#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 15#define HOST_CSTATE_BIT 0x04 16 17static struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = { 18 { 19 .data_type = QMI_OPT_FLAG, 20 .elem_len = 1, 21 .elem_size = sizeof(u8), 22 .array_type = NO_ARRAY, 23 .tlv_type = 0x10, 24 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 25 num_clients_valid), 26 }, 27 { 28 .data_type = QMI_UNSIGNED_4_BYTE, 29 .elem_len = 1, 30 .elem_size = sizeof(u32), 31 .array_type = NO_ARRAY, 32 .tlv_type = 0x10, 33 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 34 num_clients), 35 }, 36 { 37 .data_type = QMI_OPT_FLAG, 38 .elem_len = 1, 39 .elem_size = sizeof(u8), 40 .array_type = NO_ARRAY, 41 .tlv_type = 0x11, 42 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 43 wake_msi_valid), 44 }, 45 { 46 .data_type = QMI_UNSIGNED_4_BYTE, 47 .elem_len = 1, 48 .elem_size = sizeof(u32), 49 .array_type = NO_ARRAY, 50 .tlv_type = 0x11, 51 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 52 wake_msi), 53 }, 54 { 55 .data_type = QMI_OPT_FLAG, 56 .elem_len = 1, 57 .elem_size = sizeof(u8), 58 .array_type = NO_ARRAY, 59 .tlv_type = 0x12, 60 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 61 gpios_valid), 62 }, 63 { 64 .data_type = QMI_DATA_LEN, 65 .elem_len = 1, 66 .elem_size = sizeof(u8), 67 .array_type = NO_ARRAY, 68 .tlv_type = 0x12, 69 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 70 gpios_len), 71 }, 72 { 73 .data_type = QMI_UNSIGNED_4_BYTE, 74 .elem_len = QMI_WLFW_MAX_NUM_GPIO_V01, 75 .elem_size = sizeof(u32), 76 .array_type = VAR_LEN_ARRAY, 77 .tlv_type = 0x12, 78 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 79 gpios), 80 }, 81 { 82 .data_type = QMI_OPT_FLAG, 83 .elem_len = 1, 84 .elem_size = sizeof(u8), 85 .array_type = NO_ARRAY, 86 .tlv_type = 0x13, 87 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 88 nm_modem_valid), 89 }, 90 { 91 .data_type = QMI_UNSIGNED_1_BYTE, 92 .elem_len = 1, 93 .elem_size = sizeof(u8), 94 .array_type = NO_ARRAY, 95 .tlv_type = 0x13, 96 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 97 nm_modem), 98 }, 99 { 100 .data_type = QMI_OPT_FLAG, 101 .elem_len = 1, 102 .elem_size = sizeof(u8), 103 .array_type = NO_ARRAY, 104 .tlv_type = 0x14, 105 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 106 bdf_support_valid), 107 }, 108 { 109 .data_type = QMI_UNSIGNED_1_BYTE, 110 .elem_len = 1, 111 .elem_size = sizeof(u8), 112 .array_type = NO_ARRAY, 113 .tlv_type = 0x14, 114 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 115 bdf_support), 116 }, 117 { 118 .data_type = QMI_OPT_FLAG, 119 .elem_len = 1, 120 .elem_size = sizeof(u8), 121 .array_type = NO_ARRAY, 122 .tlv_type = 0x15, 123 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 124 bdf_cache_support_valid), 125 }, 126 { 127 .data_type = QMI_UNSIGNED_1_BYTE, 128 .elem_len = 1, 129 .elem_size = sizeof(u8), 130 .array_type = NO_ARRAY, 131 .tlv_type = 0x15, 132 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 133 bdf_cache_support), 134 }, 135 { 136 .data_type = QMI_OPT_FLAG, 137 .elem_len = 1, 138 .elem_size = sizeof(u8), 139 .array_type = NO_ARRAY, 140 .tlv_type = 0x16, 141 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 142 m3_support_valid), 143 }, 144 { 145 .data_type = QMI_UNSIGNED_1_BYTE, 146 .elem_len = 1, 147 .elem_size = sizeof(u8), 148 .array_type = NO_ARRAY, 149 .tlv_type = 0x16, 150 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 151 m3_support), 152 }, 153 { 154 .data_type = QMI_OPT_FLAG, 155 .elem_len = 1, 156 .elem_size = sizeof(u8), 157 .array_type = NO_ARRAY, 158 .tlv_type = 0x17, 159 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 160 m3_cache_support_valid), 161 }, 162 { 163 .data_type = QMI_UNSIGNED_1_BYTE, 164 .elem_len = 1, 165 .elem_size = sizeof(u8), 166 .array_type = NO_ARRAY, 167 .tlv_type = 0x17, 168 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 169 m3_cache_support), 170 }, 171 { 172 .data_type = QMI_OPT_FLAG, 173 .elem_len = 1, 174 .elem_size = sizeof(u8), 175 .array_type = NO_ARRAY, 176 .tlv_type = 0x18, 177 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 178 cal_filesys_support_valid), 179 }, 180 { 181 .data_type = QMI_UNSIGNED_1_BYTE, 182 .elem_len = 1, 183 .elem_size = sizeof(u8), 184 .array_type = NO_ARRAY, 185 .tlv_type = 0x18, 186 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 187 cal_filesys_support), 188 }, 189 { 190 .data_type = QMI_OPT_FLAG, 191 .elem_len = 1, 192 .elem_size = sizeof(u8), 193 .array_type = NO_ARRAY, 194 .tlv_type = 0x19, 195 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 196 cal_cache_support_valid), 197 }, 198 { 199 .data_type = QMI_UNSIGNED_1_BYTE, 200 .elem_len = 1, 201 .elem_size = sizeof(u8), 202 .array_type = NO_ARRAY, 203 .tlv_type = 0x19, 204 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 205 cal_cache_support), 206 }, 207 { 208 .data_type = QMI_OPT_FLAG, 209 .elem_len = 1, 210 .elem_size = sizeof(u8), 211 .array_type = NO_ARRAY, 212 .tlv_type = 0x1A, 213 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 214 cal_done_valid), 215 }, 216 { 217 .data_type = QMI_UNSIGNED_1_BYTE, 218 .elem_len = 1, 219 .elem_size = sizeof(u8), 220 .array_type = NO_ARRAY, 221 .tlv_type = 0x1A, 222 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 223 cal_done), 224 }, 225 { 226 .data_type = QMI_OPT_FLAG, 227 .elem_len = 1, 228 .elem_size = sizeof(u8), 229 .array_type = NO_ARRAY, 230 .tlv_type = 0x1B, 231 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 232 mem_bucket_valid), 233 }, 234 { 235 .data_type = QMI_UNSIGNED_4_BYTE, 236 .elem_len = 1, 237 .elem_size = sizeof(u32), 238 .array_type = NO_ARRAY, 239 .tlv_type = 0x1B, 240 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 241 mem_bucket), 242 }, 243 { 244 .data_type = QMI_OPT_FLAG, 245 .elem_len = 1, 246 .elem_size = sizeof(u8), 247 .array_type = NO_ARRAY, 248 .tlv_type = 0x1C, 249 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 250 mem_cfg_mode_valid), 251 }, 252 { 253 .data_type = QMI_UNSIGNED_1_BYTE, 254 .elem_len = 1, 255 .elem_size = sizeof(u8), 256 .array_type = NO_ARRAY, 257 .tlv_type = 0x1C, 258 .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01, 259 mem_cfg_mode), 260 }, 261 { 262 .data_type = QMI_EOTI, 263 .array_type = NO_ARRAY, 264 .tlv_type = QMI_COMMON_TLV_TYPE, 265 }, 266}; 267 268static struct qmi_elem_info qmi_wlanfw_host_cap_resp_msg_v01_ei[] = { 269 { 270 .data_type = QMI_STRUCT, 271 .elem_len = 1, 272 .elem_size = sizeof(struct qmi_response_type_v01), 273 .array_type = NO_ARRAY, 274 .tlv_type = 0x02, 275 .offset = offsetof(struct qmi_wlanfw_host_cap_resp_msg_v01, resp), 276 .ei_array = qmi_response_type_v01_ei, 277 }, 278 { 279 .data_type = QMI_EOTI, 280 .array_type = NO_ARRAY, 281 .tlv_type = QMI_COMMON_TLV_TYPE, 282 }, 283}; 284 285static struct qmi_elem_info qmi_wlanfw_ind_register_req_msg_v01_ei[] = { 286 { 287 .data_type = QMI_OPT_FLAG, 288 .elem_len = 1, 289 .elem_size = sizeof(u8), 290 .array_type = NO_ARRAY, 291 .tlv_type = 0x10, 292 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 293 fw_ready_enable_valid), 294 }, 295 { 296 .data_type = QMI_UNSIGNED_1_BYTE, 297 .elem_len = 1, 298 .elem_size = sizeof(u8), 299 .array_type = NO_ARRAY, 300 .tlv_type = 0x10, 301 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 302 fw_ready_enable), 303 }, 304 { 305 .data_type = QMI_OPT_FLAG, 306 .elem_len = 1, 307 .elem_size = sizeof(u8), 308 .array_type = NO_ARRAY, 309 .tlv_type = 0x11, 310 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 311 initiate_cal_download_enable_valid), 312 }, 313 { 314 .data_type = QMI_UNSIGNED_1_BYTE, 315 .elem_len = 1, 316 .elem_size = sizeof(u8), 317 .array_type = NO_ARRAY, 318 .tlv_type = 0x11, 319 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 320 initiate_cal_download_enable), 321 }, 322 { 323 .data_type = QMI_OPT_FLAG, 324 .elem_len = 1, 325 .elem_size = sizeof(u8), 326 .array_type = NO_ARRAY, 327 .tlv_type = 0x12, 328 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 329 initiate_cal_update_enable_valid), 330 }, 331 { 332 .data_type = QMI_UNSIGNED_1_BYTE, 333 .elem_len = 1, 334 .elem_size = sizeof(u8), 335 .array_type = NO_ARRAY, 336 .tlv_type = 0x12, 337 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 338 initiate_cal_update_enable), 339 }, 340 { 341 .data_type = QMI_OPT_FLAG, 342 .elem_len = 1, 343 .elem_size = sizeof(u8), 344 .array_type = NO_ARRAY, 345 .tlv_type = 0x13, 346 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 347 msa_ready_enable_valid), 348 }, 349 { 350 .data_type = QMI_UNSIGNED_1_BYTE, 351 .elem_len = 1, 352 .elem_size = sizeof(u8), 353 .array_type = NO_ARRAY, 354 .tlv_type = 0x13, 355 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 356 msa_ready_enable), 357 }, 358 { 359 .data_type = QMI_OPT_FLAG, 360 .elem_len = 1, 361 .elem_size = sizeof(u8), 362 .array_type = NO_ARRAY, 363 .tlv_type = 0x14, 364 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 365 pin_connect_result_enable_valid), 366 }, 367 { 368 .data_type = QMI_UNSIGNED_1_BYTE, 369 .elem_len = 1, 370 .elem_size = sizeof(u8), 371 .array_type = NO_ARRAY, 372 .tlv_type = 0x14, 373 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 374 pin_connect_result_enable), 375 }, 376 { 377 .data_type = QMI_OPT_FLAG, 378 .elem_len = 1, 379 .elem_size = sizeof(u8), 380 .array_type = NO_ARRAY, 381 .tlv_type = 0x15, 382 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 383 client_id_valid), 384 }, 385 { 386 .data_type = QMI_UNSIGNED_4_BYTE, 387 .elem_len = 1, 388 .elem_size = sizeof(u32), 389 .array_type = NO_ARRAY, 390 .tlv_type = 0x15, 391 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 392 client_id), 393 }, 394 { 395 .data_type = QMI_OPT_FLAG, 396 .elem_len = 1, 397 .elem_size = sizeof(u8), 398 .array_type = NO_ARRAY, 399 .tlv_type = 0x16, 400 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 401 request_mem_enable_valid), 402 }, 403 { 404 .data_type = QMI_UNSIGNED_1_BYTE, 405 .elem_len = 1, 406 .elem_size = sizeof(u8), 407 .array_type = NO_ARRAY, 408 .tlv_type = 0x16, 409 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 410 request_mem_enable), 411 }, 412 { 413 .data_type = QMI_OPT_FLAG, 414 .elem_len = 1, 415 .elem_size = sizeof(u8), 416 .array_type = NO_ARRAY, 417 .tlv_type = 0x17, 418 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 419 fw_mem_ready_enable_valid), 420 }, 421 { 422 .data_type = QMI_UNSIGNED_1_BYTE, 423 .elem_len = 1, 424 .elem_size = sizeof(u8), 425 .array_type = NO_ARRAY, 426 .tlv_type = 0x17, 427 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 428 fw_mem_ready_enable), 429 }, 430 { 431 .data_type = QMI_OPT_FLAG, 432 .elem_len = 1, 433 .elem_size = sizeof(u8), 434 .array_type = NO_ARRAY, 435 .tlv_type = 0x18, 436 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 437 fw_init_done_enable_valid), 438 }, 439 { 440 .data_type = QMI_UNSIGNED_1_BYTE, 441 .elem_len = 1, 442 .elem_size = sizeof(u8), 443 .array_type = NO_ARRAY, 444 .tlv_type = 0x18, 445 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 446 fw_init_done_enable), 447 }, 448 449 { 450 .data_type = QMI_OPT_FLAG, 451 .elem_len = 1, 452 .elem_size = sizeof(u8), 453 .array_type = NO_ARRAY, 454 .tlv_type = 0x19, 455 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 456 rejuvenate_enable_valid), 457 }, 458 { 459 .data_type = QMI_UNSIGNED_1_BYTE, 460 .elem_len = 1, 461 .elem_size = sizeof(u8), 462 .array_type = NO_ARRAY, 463 .tlv_type = 0x19, 464 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 465 rejuvenate_enable), 466 }, 467 { 468 .data_type = QMI_OPT_FLAG, 469 .elem_len = 1, 470 .elem_size = sizeof(u8), 471 .array_type = NO_ARRAY, 472 .tlv_type = 0x1A, 473 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 474 xo_cal_enable_valid), 475 }, 476 { 477 .data_type = QMI_UNSIGNED_1_BYTE, 478 .elem_len = 1, 479 .elem_size = sizeof(u8), 480 .array_type = NO_ARRAY, 481 .tlv_type = 0x1A, 482 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 483 xo_cal_enable), 484 }, 485 { 486 .data_type = QMI_OPT_FLAG, 487 .elem_len = 1, 488 .elem_size = sizeof(u8), 489 .array_type = NO_ARRAY, 490 .tlv_type = 0x1B, 491 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 492 cal_done_enable_valid), 493 }, 494 { 495 .data_type = QMI_UNSIGNED_1_BYTE, 496 .elem_len = 1, 497 .elem_size = sizeof(u8), 498 .array_type = NO_ARRAY, 499 .tlv_type = 0x1B, 500 .offset = offsetof(struct qmi_wlanfw_ind_register_req_msg_v01, 501 cal_done_enable), 502 }, 503 { 504 .data_type = QMI_EOTI, 505 .array_type = NO_ARRAY, 506 .tlv_type = QMI_COMMON_TLV_TYPE, 507 }, 508}; 509 510static struct qmi_elem_info qmi_wlanfw_ind_register_resp_msg_v01_ei[] = { 511 { 512 .data_type = QMI_STRUCT, 513 .elem_len = 1, 514 .elem_size = sizeof(struct qmi_response_type_v01), 515 .array_type = NO_ARRAY, 516 .tlv_type = 0x02, 517 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01, 518 resp), 519 .ei_array = qmi_response_type_v01_ei, 520 }, 521 { 522 .data_type = QMI_OPT_FLAG, 523 .elem_len = 1, 524 .elem_size = sizeof(u8), 525 .array_type = NO_ARRAY, 526 .tlv_type = 0x10, 527 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01, 528 fw_status_valid), 529 }, 530 { 531 .data_type = QMI_UNSIGNED_8_BYTE, 532 .elem_len = 1, 533 .elem_size = sizeof(u64), 534 .array_type = NO_ARRAY, 535 .tlv_type = 0x10, 536 .offset = offsetof(struct qmi_wlanfw_ind_register_resp_msg_v01, 537 fw_status), 538 }, 539 { 540 .data_type = QMI_EOTI, 541 .array_type = NO_ARRAY, 542 .tlv_type = QMI_COMMON_TLV_TYPE, 543 }, 544}; 545 546static struct qmi_elem_info qmi_wlanfw_mem_cfg_s_v01_ei[] = { 547 { 548 .data_type = QMI_UNSIGNED_8_BYTE, 549 .elem_len = 1, 550 .elem_size = sizeof(u64), 551 .array_type = NO_ARRAY, 552 .tlv_type = 0, 553 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, offset), 554 }, 555 { 556 .data_type = QMI_UNSIGNED_4_BYTE, 557 .elem_len = 1, 558 .elem_size = sizeof(u32), 559 .array_type = NO_ARRAY, 560 .tlv_type = 0, 561 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, size), 562 }, 563 { 564 .data_type = QMI_UNSIGNED_1_BYTE, 565 .elem_len = 1, 566 .elem_size = sizeof(u8), 567 .array_type = NO_ARRAY, 568 .tlv_type = 0, 569 .offset = offsetof(struct qmi_wlanfw_mem_cfg_s_v01, secure_flag), 570 }, 571 { 572 .data_type = QMI_EOTI, 573 .array_type = NO_ARRAY, 574 .tlv_type = QMI_COMMON_TLV_TYPE, 575 }, 576}; 577 578static struct qmi_elem_info qmi_wlanfw_mem_seg_s_v01_ei[] = { 579 { 580 .data_type = QMI_UNSIGNED_4_BYTE, 581 .elem_len = 1, 582 .elem_size = sizeof(u32), 583 .array_type = NO_ARRAY, 584 .tlv_type = 0, 585 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, 586 size), 587 }, 588 { 589 .data_type = QMI_SIGNED_4_BYTE_ENUM, 590 .elem_len = 1, 591 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01), 592 .array_type = NO_ARRAY, 593 .tlv_type = 0, 594 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, type), 595 }, 596 { 597 .data_type = QMI_DATA_LEN, 598 .elem_len = 1, 599 .elem_size = sizeof(u8), 600 .array_type = NO_ARRAY, 601 .tlv_type = 0, 602 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg_len), 603 }, 604 { 605 .data_type = QMI_STRUCT, 606 .elem_len = QMI_WLANFW_MAX_NUM_MEM_CFG_V01, 607 .elem_size = sizeof(struct qmi_wlanfw_mem_cfg_s_v01), 608 .array_type = VAR_LEN_ARRAY, 609 .tlv_type = 0, 610 .offset = offsetof(struct qmi_wlanfw_mem_seg_s_v01, mem_cfg), 611 .ei_array = qmi_wlanfw_mem_cfg_s_v01_ei, 612 }, 613 { 614 .data_type = QMI_EOTI, 615 .array_type = NO_ARRAY, 616 .tlv_type = QMI_COMMON_TLV_TYPE, 617 }, 618}; 619 620static struct qmi_elem_info qmi_wlanfw_request_mem_ind_msg_v01_ei[] = { 621 { 622 .data_type = QMI_DATA_LEN, 623 .elem_len = 1, 624 .elem_size = sizeof(u8), 625 .array_type = NO_ARRAY, 626 .tlv_type = 0x01, 627 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01, 628 mem_seg_len), 629 }, 630 { 631 .data_type = QMI_STRUCT, 632 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01, 633 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_s_v01), 634 .array_type = VAR_LEN_ARRAY, 635 .tlv_type = 0x01, 636 .offset = offsetof(struct qmi_wlanfw_request_mem_ind_msg_v01, 637 mem_seg), 638 .ei_array = qmi_wlanfw_mem_seg_s_v01_ei, 639 }, 640 { 641 .data_type = QMI_EOTI, 642 .array_type = NO_ARRAY, 643 .tlv_type = QMI_COMMON_TLV_TYPE, 644 }, 645}; 646 647static struct qmi_elem_info qmi_wlanfw_mem_seg_resp_s_v01_ei[] = { 648 { 649 .data_type = QMI_UNSIGNED_8_BYTE, 650 .elem_len = 1, 651 .elem_size = sizeof(u64), 652 .array_type = NO_ARRAY, 653 .tlv_type = 0, 654 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, addr), 655 }, 656 { 657 .data_type = QMI_UNSIGNED_4_BYTE, 658 .elem_len = 1, 659 .elem_size = sizeof(u32), 660 .array_type = NO_ARRAY, 661 .tlv_type = 0, 662 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, size), 663 }, 664 { 665 .data_type = QMI_SIGNED_4_BYTE_ENUM, 666 .elem_len = 1, 667 .elem_size = sizeof(enum qmi_wlanfw_mem_type_enum_v01), 668 .array_type = NO_ARRAY, 669 .tlv_type = 0, 670 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, type), 671 }, 672 { 673 .data_type = QMI_UNSIGNED_1_BYTE, 674 .elem_len = 1, 675 .elem_size = sizeof(u8), 676 .array_type = NO_ARRAY, 677 .tlv_type = 0, 678 .offset = offsetof(struct qmi_wlanfw_mem_seg_resp_s_v01, restore), 679 }, 680 { 681 .data_type = QMI_EOTI, 682 .array_type = NO_ARRAY, 683 .tlv_type = QMI_COMMON_TLV_TYPE, 684 }, 685}; 686 687static struct qmi_elem_info qmi_wlanfw_respond_mem_req_msg_v01_ei[] = { 688 { 689 .data_type = QMI_DATA_LEN, 690 .elem_len = 1, 691 .elem_size = sizeof(u8), 692 .array_type = NO_ARRAY, 693 .tlv_type = 0x01, 694 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01, 695 mem_seg_len), 696 }, 697 { 698 .data_type = QMI_STRUCT, 699 .elem_len = ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01, 700 .elem_size = sizeof(struct qmi_wlanfw_mem_seg_resp_s_v01), 701 .array_type = VAR_LEN_ARRAY, 702 .tlv_type = 0x01, 703 .offset = offsetof(struct qmi_wlanfw_respond_mem_req_msg_v01, 704 mem_seg), 705 .ei_array = qmi_wlanfw_mem_seg_resp_s_v01_ei, 706 }, 707 { 708 .data_type = QMI_EOTI, 709 .array_type = NO_ARRAY, 710 .tlv_type = QMI_COMMON_TLV_TYPE, 711 }, 712}; 713 714static struct qmi_elem_info qmi_wlanfw_respond_mem_resp_msg_v01_ei[] = { 715 { 716 .data_type = QMI_STRUCT, 717 .elem_len = 1, 718 .elem_size = sizeof(struct qmi_response_type_v01), 719 .array_type = NO_ARRAY, 720 .tlv_type = 0x02, 721 .offset = offsetof(struct qmi_wlanfw_respond_mem_resp_msg_v01, 722 resp), 723 .ei_array = qmi_response_type_v01_ei, 724 }, 725 { 726 .data_type = QMI_EOTI, 727 .array_type = NO_ARRAY, 728 .tlv_type = QMI_COMMON_TLV_TYPE, 729 }, 730}; 731 732static struct qmi_elem_info qmi_wlanfw_cap_req_msg_v01_ei[] = { 733 { 734 .data_type = QMI_EOTI, 735 .array_type = NO_ARRAY, 736 .tlv_type = QMI_COMMON_TLV_TYPE, 737 }, 738}; 739 740static struct qmi_elem_info qmi_wlanfw_rf_chip_info_s_v01_ei[] = { 741 { 742 .data_type = QMI_UNSIGNED_4_BYTE, 743 .elem_len = 1, 744 .elem_size = sizeof(u32), 745 .array_type = NO_ARRAY, 746 .tlv_type = 0, 747 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01, 748 chip_id), 749 }, 750 { 751 .data_type = QMI_UNSIGNED_4_BYTE, 752 .elem_len = 1, 753 .elem_size = sizeof(u32), 754 .array_type = NO_ARRAY, 755 .tlv_type = 0, 756 .offset = offsetof(struct qmi_wlanfw_rf_chip_info_s_v01, 757 chip_family), 758 }, 759 { 760 .data_type = QMI_EOTI, 761 .array_type = NO_ARRAY, 762 .tlv_type = QMI_COMMON_TLV_TYPE, 763 }, 764}; 765 766static struct qmi_elem_info qmi_wlanfw_rf_board_info_s_v01_ei[] = { 767 { 768 .data_type = QMI_UNSIGNED_4_BYTE, 769 .elem_len = 1, 770 .elem_size = sizeof(u32), 771 .array_type = NO_ARRAY, 772 .tlv_type = 0, 773 .offset = offsetof(struct qmi_wlanfw_rf_board_info_s_v01, 774 board_id), 775 }, 776 { 777 .data_type = QMI_EOTI, 778 .array_type = NO_ARRAY, 779 .tlv_type = QMI_COMMON_TLV_TYPE, 780 }, 781}; 782 783static struct qmi_elem_info qmi_wlanfw_soc_info_s_v01_ei[] = { 784 { 785 .data_type = QMI_UNSIGNED_4_BYTE, 786 .elem_len = 1, 787 .elem_size = sizeof(u32), 788 .array_type = NO_ARRAY, 789 .tlv_type = 0, 790 .offset = offsetof(struct qmi_wlanfw_soc_info_s_v01, soc_id), 791 }, 792 { 793 .data_type = QMI_EOTI, 794 .array_type = NO_ARRAY, 795 .tlv_type = QMI_COMMON_TLV_TYPE, 796 }, 797}; 798 799static struct qmi_elem_info qmi_wlanfw_fw_version_info_s_v01_ei[] = { 800 { 801 .data_type = QMI_UNSIGNED_4_BYTE, 802 .elem_len = 1, 803 .elem_size = sizeof(u32), 804 .array_type = NO_ARRAY, 805 .tlv_type = 0, 806 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01, 807 fw_version), 808 }, 809 { 810 .data_type = QMI_STRING, 811 .elem_len = ATH11K_QMI_WLANFW_MAX_TIMESTAMP_LEN_V01 + 1, 812 .elem_size = sizeof(char), 813 .array_type = NO_ARRAY, 814 .tlv_type = 0, 815 .offset = offsetof(struct qmi_wlanfw_fw_version_info_s_v01, 816 fw_build_timestamp), 817 }, 818 { 819 .data_type = QMI_EOTI, 820 .array_type = NO_ARRAY, 821 .tlv_type = QMI_COMMON_TLV_TYPE, 822 }, 823}; 824 825static struct qmi_elem_info qmi_wlanfw_cap_resp_msg_v01_ei[] = { 826 { 827 .data_type = QMI_STRUCT, 828 .elem_len = 1, 829 .elem_size = sizeof(struct qmi_response_type_v01), 830 .array_type = NO_ARRAY, 831 .tlv_type = 0x02, 832 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, resp), 833 .ei_array = qmi_response_type_v01_ei, 834 }, 835 { 836 .data_type = QMI_OPT_FLAG, 837 .elem_len = 1, 838 .elem_size = sizeof(u8), 839 .array_type = NO_ARRAY, 840 .tlv_type = 0x10, 841 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 842 chip_info_valid), 843 }, 844 { 845 .data_type = QMI_STRUCT, 846 .elem_len = 1, 847 .elem_size = sizeof(struct qmi_wlanfw_rf_chip_info_s_v01), 848 .array_type = NO_ARRAY, 849 .tlv_type = 0x10, 850 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 851 chip_info), 852 .ei_array = qmi_wlanfw_rf_chip_info_s_v01_ei, 853 }, 854 { 855 .data_type = QMI_OPT_FLAG, 856 .elem_len = 1, 857 .elem_size = sizeof(u8), 858 .array_type = NO_ARRAY, 859 .tlv_type = 0x11, 860 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 861 board_info_valid), 862 }, 863 { 864 .data_type = QMI_STRUCT, 865 .elem_len = 1, 866 .elem_size = sizeof(struct qmi_wlanfw_rf_board_info_s_v01), 867 .array_type = NO_ARRAY, 868 .tlv_type = 0x11, 869 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 870 board_info), 871 .ei_array = qmi_wlanfw_rf_board_info_s_v01_ei, 872 }, 873 { 874 .data_type = QMI_OPT_FLAG, 875 .elem_len = 1, 876 .elem_size = sizeof(u8), 877 .array_type = NO_ARRAY, 878 .tlv_type = 0x12, 879 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 880 soc_info_valid), 881 }, 882 { 883 .data_type = QMI_STRUCT, 884 .elem_len = 1, 885 .elem_size = sizeof(struct qmi_wlanfw_soc_info_s_v01), 886 .array_type = NO_ARRAY, 887 .tlv_type = 0x12, 888 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 889 soc_info), 890 .ei_array = qmi_wlanfw_soc_info_s_v01_ei, 891 }, 892 { 893 .data_type = QMI_OPT_FLAG, 894 .elem_len = 1, 895 .elem_size = sizeof(u8), 896 .array_type = NO_ARRAY, 897 .tlv_type = 0x13, 898 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 899 fw_version_info_valid), 900 }, 901 { 902 .data_type = QMI_STRUCT, 903 .elem_len = 1, 904 .elem_size = sizeof(struct qmi_wlanfw_fw_version_info_s_v01), 905 .array_type = NO_ARRAY, 906 .tlv_type = 0x13, 907 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 908 fw_version_info), 909 .ei_array = qmi_wlanfw_fw_version_info_s_v01_ei, 910 }, 911 { 912 .data_type = QMI_OPT_FLAG, 913 .elem_len = 1, 914 .elem_size = sizeof(u8), 915 .array_type = NO_ARRAY, 916 .tlv_type = 0x14, 917 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 918 fw_build_id_valid), 919 }, 920 { 921 .data_type = QMI_STRING, 922 .elem_len = ATH11K_QMI_WLANFW_MAX_BUILD_ID_LEN_V01 + 1, 923 .elem_size = sizeof(char), 924 .array_type = NO_ARRAY, 925 .tlv_type = 0x14, 926 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 927 fw_build_id), 928 }, 929 { 930 .data_type = QMI_OPT_FLAG, 931 .elem_len = 1, 932 .elem_size = sizeof(u8), 933 .array_type = NO_ARRAY, 934 .tlv_type = 0x15, 935 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 936 num_macs_valid), 937 }, 938 { 939 .data_type = QMI_UNSIGNED_1_BYTE, 940 .elem_len = 1, 941 .elem_size = sizeof(u8), 942 .array_type = NO_ARRAY, 943 .tlv_type = 0x15, 944 .offset = offsetof(struct qmi_wlanfw_cap_resp_msg_v01, 945 num_macs), 946 }, 947 { 948 .data_type = QMI_EOTI, 949 .array_type = NO_ARRAY, 950 .tlv_type = QMI_COMMON_TLV_TYPE, 951 }, 952}; 953 954static struct qmi_elem_info qmi_wlanfw_bdf_download_req_msg_v01_ei[] = { 955 { 956 .data_type = QMI_UNSIGNED_1_BYTE, 957 .elem_len = 1, 958 .elem_size = sizeof(u8), 959 .array_type = NO_ARRAY, 960 .tlv_type = 0x01, 961 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 962 valid), 963 }, 964 { 965 .data_type = QMI_OPT_FLAG, 966 .elem_len = 1, 967 .elem_size = sizeof(u8), 968 .array_type = NO_ARRAY, 969 .tlv_type = 0x10, 970 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 971 file_id_valid), 972 }, 973 { 974 .data_type = QMI_SIGNED_4_BYTE_ENUM, 975 .elem_len = 1, 976 .elem_size = sizeof(enum qmi_wlanfw_cal_temp_id_enum_v01), 977 .array_type = NO_ARRAY, 978 .tlv_type = 0x10, 979 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 980 file_id), 981 }, 982 { 983 .data_type = QMI_OPT_FLAG, 984 .elem_len = 1, 985 .elem_size = sizeof(u8), 986 .array_type = NO_ARRAY, 987 .tlv_type = 0x11, 988 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 989 total_size_valid), 990 }, 991 { 992 .data_type = QMI_UNSIGNED_4_BYTE, 993 .elem_len = 1, 994 .elem_size = sizeof(u32), 995 .array_type = NO_ARRAY, 996 .tlv_type = 0x11, 997 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 998 total_size), 999 }, 1000 { 1001 .data_type = QMI_OPT_FLAG, 1002 .elem_len = 1, 1003 .elem_size = sizeof(u8), 1004 .array_type = NO_ARRAY, 1005 .tlv_type = 0x12, 1006 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1007 seg_id_valid), 1008 }, 1009 { 1010 .data_type = QMI_UNSIGNED_4_BYTE, 1011 .elem_len = 1, 1012 .elem_size = sizeof(u32), 1013 .array_type = NO_ARRAY, 1014 .tlv_type = 0x12, 1015 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1016 seg_id), 1017 }, 1018 { 1019 .data_type = QMI_OPT_FLAG, 1020 .elem_len = 1, 1021 .elem_size = sizeof(u8), 1022 .array_type = NO_ARRAY, 1023 .tlv_type = 0x13, 1024 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1025 data_valid), 1026 }, 1027 { 1028 .data_type = QMI_DATA_LEN, 1029 .elem_len = 1, 1030 .elem_size = sizeof(u16), 1031 .array_type = NO_ARRAY, 1032 .tlv_type = 0x13, 1033 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1034 data_len), 1035 }, 1036 { 1037 .data_type = QMI_UNSIGNED_1_BYTE, 1038 .elem_len = QMI_WLANFW_MAX_DATA_SIZE_V01, 1039 .elem_size = sizeof(u8), 1040 .array_type = VAR_LEN_ARRAY, 1041 .tlv_type = 0x13, 1042 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1043 data), 1044 }, 1045 { 1046 .data_type = QMI_OPT_FLAG, 1047 .elem_len = 1, 1048 .elem_size = sizeof(u8), 1049 .array_type = NO_ARRAY, 1050 .tlv_type = 0x14, 1051 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1052 end_valid), 1053 }, 1054 { 1055 .data_type = QMI_UNSIGNED_1_BYTE, 1056 .elem_len = 1, 1057 .elem_size = sizeof(u8), 1058 .array_type = NO_ARRAY, 1059 .tlv_type = 0x14, 1060 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1061 end), 1062 }, 1063 { 1064 .data_type = QMI_OPT_FLAG, 1065 .elem_len = 1, 1066 .elem_size = sizeof(u8), 1067 .array_type = NO_ARRAY, 1068 .tlv_type = 0x15, 1069 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1070 bdf_type_valid), 1071 }, 1072 { 1073 .data_type = QMI_UNSIGNED_1_BYTE, 1074 .elem_len = 1, 1075 .elem_size = sizeof(u8), 1076 .array_type = NO_ARRAY, 1077 .tlv_type = 0x15, 1078 .offset = offsetof(struct qmi_wlanfw_bdf_download_req_msg_v01, 1079 bdf_type), 1080 }, 1081 1082 { 1083 .data_type = QMI_EOTI, 1084 .array_type = NO_ARRAY, 1085 .tlv_type = QMI_COMMON_TLV_TYPE, 1086 }, 1087}; 1088 1089static struct qmi_elem_info qmi_wlanfw_bdf_download_resp_msg_v01_ei[] = { 1090 { 1091 .data_type = QMI_STRUCT, 1092 .elem_len = 1, 1093 .elem_size = sizeof(struct qmi_response_type_v01), 1094 .array_type = NO_ARRAY, 1095 .tlv_type = 0x02, 1096 .offset = offsetof(struct qmi_wlanfw_bdf_download_resp_msg_v01, 1097 resp), 1098 .ei_array = qmi_response_type_v01_ei, 1099 }, 1100 { 1101 .data_type = QMI_EOTI, 1102 .array_type = NO_ARRAY, 1103 .tlv_type = QMI_COMMON_TLV_TYPE, 1104 }, 1105}; 1106 1107static struct qmi_elem_info qmi_wlanfw_m3_info_req_msg_v01_ei[] = { 1108 { 1109 .data_type = QMI_UNSIGNED_8_BYTE, 1110 .elem_len = 1, 1111 .elem_size = sizeof(u64), 1112 .array_type = NO_ARRAY, 1113 .tlv_type = 0x01, 1114 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, addr), 1115 }, 1116 { 1117 .data_type = QMI_UNSIGNED_4_BYTE, 1118 .elem_len = 1, 1119 .elem_size = sizeof(u32), 1120 .array_type = NO_ARRAY, 1121 .tlv_type = 0x02, 1122 .offset = offsetof(struct qmi_wlanfw_m3_info_req_msg_v01, size), 1123 }, 1124 { 1125 .data_type = QMI_EOTI, 1126 .array_type = NO_ARRAY, 1127 .tlv_type = QMI_COMMON_TLV_TYPE, 1128 }, 1129}; 1130 1131static struct qmi_elem_info qmi_wlanfw_m3_info_resp_msg_v01_ei[] = { 1132 { 1133 .data_type = QMI_STRUCT, 1134 .elem_len = 1, 1135 .elem_size = sizeof(struct qmi_response_type_v01), 1136 .array_type = NO_ARRAY, 1137 .tlv_type = 0x02, 1138 .offset = offsetof(struct qmi_wlanfw_m3_info_resp_msg_v01, resp), 1139 .ei_array = qmi_response_type_v01_ei, 1140 }, 1141 { 1142 .data_type = QMI_EOTI, 1143 .array_type = NO_ARRAY, 1144 .tlv_type = QMI_COMMON_TLV_TYPE, 1145 }, 1146}; 1147 1148static struct qmi_elem_info qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei[] = { 1149 { 1150 .data_type = QMI_UNSIGNED_4_BYTE, 1151 .elem_len = 1, 1152 .elem_size = sizeof(u32), 1153 .array_type = NO_ARRAY, 1154 .tlv_type = 0, 1155 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01, 1156 pipe_num), 1157 }, 1158 { 1159 .data_type = QMI_SIGNED_4_BYTE_ENUM, 1160 .elem_len = 1, 1161 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01), 1162 .array_type = NO_ARRAY, 1163 .tlv_type = 0, 1164 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01, 1165 pipe_dir), 1166 }, 1167 { 1168 .data_type = QMI_UNSIGNED_4_BYTE, 1169 .elem_len = 1, 1170 .elem_size = sizeof(u32), 1171 .array_type = NO_ARRAY, 1172 .tlv_type = 0, 1173 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01, 1174 nentries), 1175 }, 1176 { 1177 .data_type = QMI_UNSIGNED_4_BYTE, 1178 .elem_len = 1, 1179 .elem_size = sizeof(u32), 1180 .array_type = NO_ARRAY, 1181 .tlv_type = 0, 1182 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01, 1183 nbytes_max), 1184 }, 1185 { 1186 .data_type = QMI_UNSIGNED_4_BYTE, 1187 .elem_len = 1, 1188 .elem_size = sizeof(u32), 1189 .array_type = NO_ARRAY, 1190 .tlv_type = 0, 1191 .offset = offsetof(struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01, 1192 flags), 1193 }, 1194 { 1195 .data_type = QMI_EOTI, 1196 .array_type = NO_ARRAY, 1197 .tlv_type = QMI_COMMON_TLV_TYPE, 1198 }, 1199}; 1200 1201static struct qmi_elem_info qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei[] = { 1202 { 1203 .data_type = QMI_UNSIGNED_4_BYTE, 1204 .elem_len = 1, 1205 .elem_size = sizeof(u32), 1206 .array_type = NO_ARRAY, 1207 .tlv_type = 0, 1208 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01, 1209 service_id), 1210 }, 1211 { 1212 .data_type = QMI_SIGNED_4_BYTE_ENUM, 1213 .elem_len = 1, 1214 .elem_size = sizeof(enum qmi_wlanfw_pipedir_enum_v01), 1215 .array_type = NO_ARRAY, 1216 .tlv_type = 0, 1217 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01, 1218 pipe_dir), 1219 }, 1220 { 1221 .data_type = QMI_UNSIGNED_4_BYTE, 1222 .elem_len = 1, 1223 .elem_size = sizeof(u32), 1224 .array_type = NO_ARRAY, 1225 .tlv_type = 0, 1226 .offset = offsetof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01, 1227 pipe_num), 1228 }, 1229 { 1230 .data_type = QMI_EOTI, 1231 .array_type = NO_ARRAY, 1232 .tlv_type = QMI_COMMON_TLV_TYPE, 1233 }, 1234}; 1235 1236static struct qmi_elem_info qmi_wlanfw_shadow_reg_cfg_s_v01_ei[] = { 1237 { 1238 .data_type = QMI_UNSIGNED_2_BYTE, 1239 .elem_len = 1, 1240 .elem_size = sizeof(u16), 1241 .array_type = NO_ARRAY, 1242 .tlv_type = 0, 1243 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, id), 1244 }, 1245 { 1246 .data_type = QMI_UNSIGNED_2_BYTE, 1247 .elem_len = 1, 1248 .elem_size = sizeof(u16), 1249 .array_type = NO_ARRAY, 1250 .tlv_type = 0, 1251 .offset = offsetof(struct qmi_wlanfw_shadow_reg_cfg_s_v01, 1252 offset), 1253 }, 1254 { 1255 .data_type = QMI_EOTI, 1256 .array_type = QMI_COMMON_TLV_TYPE, 1257 }, 1258}; 1259 1260static struct qmi_elem_info qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei[] = { 1261 { 1262 .data_type = QMI_UNSIGNED_4_BYTE, 1263 .elem_len = 1, 1264 .elem_size = sizeof(u32), 1265 .array_type = NO_ARRAY, 1266 .tlv_type = 0, 1267 .offset = offsetof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01, 1268 addr), 1269 }, 1270 { 1271 .data_type = QMI_EOTI, 1272 .array_type = NO_ARRAY, 1273 .tlv_type = QMI_COMMON_TLV_TYPE, 1274 }, 1275}; 1276 1277static struct qmi_elem_info qmi_wlanfw_wlan_mode_req_msg_v01_ei[] = { 1278 { 1279 .data_type = QMI_UNSIGNED_4_BYTE, 1280 .elem_len = 1, 1281 .elem_size = sizeof(u32), 1282 .array_type = NO_ARRAY, 1283 .tlv_type = 0x01, 1284 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01, 1285 mode), 1286 }, 1287 { 1288 .data_type = QMI_OPT_FLAG, 1289 .elem_len = 1, 1290 .elem_size = sizeof(u8), 1291 .array_type = NO_ARRAY, 1292 .tlv_type = 0x10, 1293 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01, 1294 hw_debug_valid), 1295 }, 1296 { 1297 .data_type = QMI_UNSIGNED_1_BYTE, 1298 .elem_len = 1, 1299 .elem_size = sizeof(u8), 1300 .array_type = NO_ARRAY, 1301 .tlv_type = 0x10, 1302 .offset = offsetof(struct qmi_wlanfw_wlan_mode_req_msg_v01, 1303 hw_debug), 1304 }, 1305 { 1306 .data_type = QMI_EOTI, 1307 .array_type = NO_ARRAY, 1308 .tlv_type = QMI_COMMON_TLV_TYPE, 1309 }, 1310}; 1311 1312static struct qmi_elem_info qmi_wlanfw_wlan_mode_resp_msg_v01_ei[] = { 1313 { 1314 .data_type = QMI_STRUCT, 1315 .elem_len = 1, 1316 .elem_size = sizeof(struct qmi_response_type_v01), 1317 .array_type = NO_ARRAY, 1318 .tlv_type = 0x02, 1319 .offset = offsetof(struct qmi_wlanfw_wlan_mode_resp_msg_v01, 1320 resp), 1321 .ei_array = qmi_response_type_v01_ei, 1322 }, 1323 { 1324 .data_type = QMI_EOTI, 1325 .array_type = NO_ARRAY, 1326 .tlv_type = QMI_COMMON_TLV_TYPE, 1327 }, 1328}; 1329 1330static struct qmi_elem_info qmi_wlanfw_wlan_cfg_req_msg_v01_ei[] = { 1331 { 1332 .data_type = QMI_OPT_FLAG, 1333 .elem_len = 1, 1334 .elem_size = sizeof(u8), 1335 .array_type = NO_ARRAY, 1336 .tlv_type = 0x10, 1337 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1338 host_version_valid), 1339 }, 1340 { 1341 .data_type = QMI_STRING, 1342 .elem_len = QMI_WLANFW_MAX_STR_LEN_V01 + 1, 1343 .elem_size = sizeof(char), 1344 .array_type = NO_ARRAY, 1345 .tlv_type = 0x10, 1346 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1347 host_version), 1348 }, 1349 { 1350 .data_type = QMI_OPT_FLAG, 1351 .elem_len = 1, 1352 .elem_size = sizeof(u8), 1353 .array_type = NO_ARRAY, 1354 .tlv_type = 0x11, 1355 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1356 tgt_cfg_valid), 1357 }, 1358 { 1359 .data_type = QMI_DATA_LEN, 1360 .elem_len = 1, 1361 .elem_size = sizeof(u8), 1362 .array_type = NO_ARRAY, 1363 .tlv_type = 0x11, 1364 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1365 tgt_cfg_len), 1366 }, 1367 { 1368 .data_type = QMI_STRUCT, 1369 .elem_len = QMI_WLANFW_MAX_NUM_CE_V01, 1370 .elem_size = sizeof( 1371 struct qmi_wlanfw_ce_tgt_pipe_cfg_s_v01), 1372 .array_type = VAR_LEN_ARRAY, 1373 .tlv_type = 0x11, 1374 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1375 tgt_cfg), 1376 .ei_array = qmi_wlanfw_ce_tgt_pipe_cfg_s_v01_ei, 1377 }, 1378 { 1379 .data_type = QMI_OPT_FLAG, 1380 .elem_len = 1, 1381 .elem_size = sizeof(u8), 1382 .array_type = NO_ARRAY, 1383 .tlv_type = 0x12, 1384 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1385 svc_cfg_valid), 1386 }, 1387 { 1388 .data_type = QMI_DATA_LEN, 1389 .elem_len = 1, 1390 .elem_size = sizeof(u8), 1391 .array_type = NO_ARRAY, 1392 .tlv_type = 0x12, 1393 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1394 svc_cfg_len), 1395 }, 1396 { 1397 .data_type = QMI_STRUCT, 1398 .elem_len = QMI_WLANFW_MAX_NUM_SVC_V01, 1399 .elem_size = sizeof(struct qmi_wlanfw_ce_svc_pipe_cfg_s_v01), 1400 .array_type = VAR_LEN_ARRAY, 1401 .tlv_type = 0x12, 1402 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1403 svc_cfg), 1404 .ei_array = qmi_wlanfw_ce_svc_pipe_cfg_s_v01_ei, 1405 }, 1406 { 1407 .data_type = QMI_OPT_FLAG, 1408 .elem_len = 1, 1409 .elem_size = sizeof(u8), 1410 .array_type = NO_ARRAY, 1411 .tlv_type = 0x13, 1412 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1413 shadow_reg_valid), 1414 }, 1415 { 1416 .data_type = QMI_DATA_LEN, 1417 .elem_len = 1, 1418 .elem_size = sizeof(u8), 1419 .array_type = NO_ARRAY, 1420 .tlv_type = 0x13, 1421 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1422 shadow_reg_len), 1423 }, 1424 { 1425 .data_type = QMI_STRUCT, 1426 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V01, 1427 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_cfg_s_v01), 1428 .array_type = VAR_LEN_ARRAY, 1429 .tlv_type = 0x13, 1430 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1431 shadow_reg), 1432 .ei_array = qmi_wlanfw_shadow_reg_cfg_s_v01_ei, 1433 }, 1434 { 1435 .data_type = QMI_OPT_FLAG, 1436 .elem_len = 1, 1437 .elem_size = sizeof(u8), 1438 .array_type = NO_ARRAY, 1439 .tlv_type = 0x14, 1440 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1441 shadow_reg_v2_valid), 1442 }, 1443 { 1444 .data_type = QMI_DATA_LEN, 1445 .elem_len = 1, 1446 .elem_size = sizeof(u8), 1447 .array_type = NO_ARRAY, 1448 .tlv_type = 0x14, 1449 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1450 shadow_reg_v2_len), 1451 }, 1452 { 1453 .data_type = QMI_STRUCT, 1454 .elem_len = QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01, 1455 .elem_size = sizeof(struct qmi_wlanfw_shadow_reg_v2_cfg_s_v01), 1456 .array_type = VAR_LEN_ARRAY, 1457 .tlv_type = 0x14, 1458 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_req_msg_v01, 1459 shadow_reg_v2), 1460 .ei_array = qmi_wlanfw_shadow_reg_v2_cfg_s_v01_ei, 1461 }, 1462 { 1463 .data_type = QMI_EOTI, 1464 .array_type = NO_ARRAY, 1465 .tlv_type = QMI_COMMON_TLV_TYPE, 1466 }, 1467}; 1468 1469static struct qmi_elem_info qmi_wlanfw_wlan_cfg_resp_msg_v01_ei[] = { 1470 { 1471 .data_type = QMI_STRUCT, 1472 .elem_len = 1, 1473 .elem_size = sizeof(struct qmi_response_type_v01), 1474 .array_type = NO_ARRAY, 1475 .tlv_type = 0x02, 1476 .offset = offsetof(struct qmi_wlanfw_wlan_cfg_resp_msg_v01, resp), 1477 .ei_array = qmi_response_type_v01_ei, 1478 }, 1479 { 1480 .data_type = QMI_EOTI, 1481 .array_type = NO_ARRAY, 1482 .tlv_type = QMI_COMMON_TLV_TYPE, 1483 }, 1484}; 1485 1486static struct qmi_elem_info qmi_wlanfw_mem_ready_ind_msg_v01_ei[] = { 1487 { 1488 .data_type = QMI_EOTI, 1489 .array_type = NO_ARRAY, 1490 }, 1491}; 1492 1493static struct qmi_elem_info qmi_wlanfw_fw_ready_ind_msg_v01_ei[] = { 1494 { 1495 .data_type = QMI_EOTI, 1496 .array_type = NO_ARRAY, 1497 }, 1498}; 1499 1500static struct qmi_elem_info qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei[] = { 1501 { 1502 .data_type = QMI_EOTI, 1503 .array_type = NO_ARRAY, 1504 }, 1505}; 1506 1507static int ath11k_qmi_host_cap_send(struct ath11k_base *ab) 1508{ 1509 struct qmi_wlanfw_host_cap_req_msg_v01 req; 1510 struct qmi_wlanfw_host_cap_resp_msg_v01 resp; 1511 struct qmi_txn txn = {}; 1512 int ret = 0; 1513 1514 memset(&req, 0, sizeof(req)); 1515 memset(&resp, 0, sizeof(resp)); 1516 1517 req.num_clients_valid = 1; 1518 req.num_clients = 1; 1519 req.mem_cfg_mode = ab->qmi.target_mem_mode; 1520 req.mem_cfg_mode_valid = 1; 1521 req.bdf_support_valid = 1; 1522 req.bdf_support = 1; 1523 1524 if (ab->bus_params.m3_fw_support) { 1525 req.m3_support_valid = 1; 1526 req.m3_support = 1; 1527 req.m3_cache_support_valid = 1; 1528 req.m3_cache_support = 1; 1529 } else { 1530 req.m3_support_valid = 0; 1531 req.m3_support = 0; 1532 req.m3_cache_support_valid = 0; 1533 req.m3_cache_support = 0; 1534 } 1535 1536 req.cal_done_valid = 1; 1537 req.cal_done = ab->qmi.cal_done; 1538 1539 if (ab->hw_params.internal_sleep_clock) { 1540 req.nm_modem_valid = 1; 1541 1542 /* Notify firmware that this is non-qualcomm platform. */ 1543 req.nm_modem |= HOST_CSTATE_BIT; 1544 1545 /* Notify firmware about the sleep clock selection, 1546 * nm_modem_bit[1] is used for this purpose. Host driver on 1547 * non-qualcomm platforms should select internal sleep 1548 * clock. 1549 */ 1550 req.nm_modem |= SLEEP_CLOCK_SELECT_INTERNAL_BIT; 1551 } 1552 1553 ret = qmi_txn_init(&ab->qmi.handle, &txn, 1554 qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp); 1555 if (ret < 0) 1556 goto out; 1557 1558 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 1559 QMI_WLANFW_HOST_CAP_REQ_V01, 1560 QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN, 1561 qmi_wlanfw_host_cap_req_msg_v01_ei, &req); 1562 if (ret < 0) { 1563 ath11k_warn(ab, "Failed to send host capability request,err = %d\n", ret); 1564 goto out; 1565 } 1566 1567 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 1568 if (ret < 0) 1569 goto out; 1570 1571 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 1572 ath11k_warn(ab, "Host capability request failed, result: %d, err: %d\n", 1573 resp.resp.result, resp.resp.error); 1574 ret = -EINVAL; 1575 goto out; 1576 } 1577 1578out: 1579 return ret; 1580} 1581 1582static int ath11k_qmi_fw_ind_register_send(struct ath11k_base *ab) 1583{ 1584 struct qmi_wlanfw_ind_register_req_msg_v01 *req; 1585 struct qmi_wlanfw_ind_register_resp_msg_v01 *resp; 1586 struct qmi_handle *handle = &ab->qmi.handle; 1587 struct qmi_txn txn; 1588 int ret; 1589 1590 req = kzalloc(sizeof(*req), GFP_KERNEL); 1591 if (!req) 1592 return -ENOMEM; 1593 1594 resp = kzalloc(sizeof(*resp), GFP_KERNEL); 1595 if (!resp) { 1596 ret = -ENOMEM; 1597 goto resp_out; 1598 } 1599 1600 req->client_id_valid = 1; 1601 req->client_id = QMI_WLANFW_CLIENT_ID; 1602 req->fw_ready_enable_valid = 1; 1603 req->fw_ready_enable = 1; 1604 req->request_mem_enable_valid = 1; 1605 req->request_mem_enable = 1; 1606 req->fw_mem_ready_enable_valid = 1; 1607 req->fw_mem_ready_enable = 1; 1608 req->cal_done_enable_valid = 1; 1609 req->cal_done_enable = 1; 1610 req->fw_init_done_enable_valid = 1; 1611 req->fw_init_done_enable = 1; 1612 1613 req->pin_connect_result_enable_valid = 0; 1614 req->pin_connect_result_enable = 0; 1615 1616 ret = qmi_txn_init(handle, &txn, 1617 qmi_wlanfw_ind_register_resp_msg_v01_ei, resp); 1618 if (ret < 0) 1619 goto out; 1620 1621 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 1622 QMI_WLANFW_IND_REGISTER_REQ_V01, 1623 QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN, 1624 qmi_wlanfw_ind_register_req_msg_v01_ei, req); 1625 if (ret < 0) { 1626 ath11k_warn(ab, "Failed to send indication register request, err = %d\n", 1627 ret); 1628 goto out; 1629 } 1630 1631 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 1632 if (ret < 0) { 1633 ath11k_warn(ab, "failed to register fw indication %d\n", ret); 1634 goto out; 1635 } 1636 1637 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { 1638 ath11k_warn(ab, "FW Ind register request failed, result: %d, err: %d\n", 1639 resp->resp.result, resp->resp.error); 1640 ret = -EINVAL; 1641 goto out; 1642 } 1643 1644out: 1645 kfree(resp); 1646resp_out: 1647 kfree(req); 1648 return ret; 1649} 1650 1651static int ath11k_qmi_respond_fw_mem_request(struct ath11k_base *ab) 1652{ 1653 struct qmi_wlanfw_respond_mem_req_msg_v01 *req; 1654 struct qmi_wlanfw_respond_mem_resp_msg_v01 resp; 1655 struct qmi_txn txn = {}; 1656 int ret = 0, i; 1657 bool delayed; 1658 1659 req = kzalloc(sizeof(*req), GFP_KERNEL); 1660 if (!req) 1661 return -ENOMEM; 1662 1663 memset(&resp, 0, sizeof(resp)); 1664 1665 /* For QCA6390 by default FW requests a block of ~4M contiguous 1666 * DMA memory, it's hard to allocate from OS. So host returns 1667 * failure to FW and FW will then request mulitple blocks of small 1668 * chunk size memory. 1669 */ 1670 if (!ab->bus_params.fixed_mem_region && ab->qmi.target_mem_delayed) { 1671 delayed = true; 1672 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi delays mem_request %d\n", 1673 ab->qmi.mem_seg_count); 1674 memset(req, 0, sizeof(*req)); 1675 } else { 1676 delayed = false; 1677 req->mem_seg_len = ab->qmi.mem_seg_count; 1678 1679 for (i = 0; i < req->mem_seg_len ; i++) { 1680 req->mem_seg[i].addr = ab->qmi.target_mem[i].paddr; 1681 req->mem_seg[i].size = ab->qmi.target_mem[i].size; 1682 req->mem_seg[i].type = ab->qmi.target_mem[i].type; 1683 } 1684 } 1685 1686 ret = qmi_txn_init(&ab->qmi.handle, &txn, 1687 qmi_wlanfw_respond_mem_resp_msg_v01_ei, &resp); 1688 if (ret < 0) 1689 goto out; 1690 1691 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 1692 QMI_WLANFW_RESPOND_MEM_REQ_V01, 1693 QMI_WLANFW_RESPOND_MEM_REQ_MSG_V01_MAX_LEN, 1694 qmi_wlanfw_respond_mem_req_msg_v01_ei, req); 1695 if (ret < 0) { 1696 ath11k_warn(ab, "qmi failed to respond memory request, err = %d\n", 1697 ret); 1698 goto out; 1699 } 1700 1701 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 1702 if (ret < 0) { 1703 ath11k_warn(ab, "qmi failed memory request, err = %d\n", ret); 1704 goto out; 1705 } 1706 1707 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 1708 /* the error response is expected when 1709 * target_mem_delayed is true. 1710 */ 1711 if (delayed && resp.resp.error == 0) 1712 goto out; 1713 1714 ath11k_warn(ab, "Respond mem req failed, result: %d, err: %d\n", 1715 resp.resp.result, resp.resp.error); 1716 ret = -EINVAL; 1717 goto out; 1718 } 1719out: 1720 kfree(req); 1721 return ret; 1722} 1723 1724static void ath11k_qmi_free_target_mem_chunk(struct ath11k_base *ab) 1725{ 1726 int i; 1727 1728 if (ab->bus_params.fixed_mem_region) 1729 return; 1730 1731 for (i = 0; i < ab->qmi.mem_seg_count; i++) { 1732 if (!ab->qmi.target_mem[i].vaddr) 1733 continue; 1734 1735 dma_free_coherent(ab->dev, 1736 ab->qmi.target_mem[i].size, 1737 ab->qmi.target_mem[i].vaddr, 1738 ab->qmi.target_mem[i].paddr); 1739 ab->qmi.target_mem[i].vaddr = NULL; 1740 } 1741} 1742 1743static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) 1744{ 1745 int i; 1746 struct target_mem_chunk *chunk; 1747 1748 ab->qmi.target_mem_delayed = false; 1749 1750 for (i = 0; i < ab->qmi.mem_seg_count; i++) { 1751 chunk = &ab->qmi.target_mem[i]; 1752 chunk->vaddr = dma_alloc_coherent(ab->dev, 1753 chunk->size, 1754 &chunk->paddr, 1755 GFP_KERNEL); 1756 if (!chunk->vaddr) { 1757 if (ab->qmi.mem_seg_count <= 2) { 1758 ath11k_dbg(ab, ATH11K_DBG_QMI, 1759 "qmi dma allocation failed (%d B type %u), will try later with small size\n", 1760 chunk->size, 1761 chunk->type); 1762 ath11k_qmi_free_target_mem_chunk(ab); 1763 ab->qmi.target_mem_delayed = true; 1764 return 0; 1765 } 1766 ath11k_err(ab, "failed to alloc memory, size: 0x%x, type: %u\n", 1767 chunk->size, 1768 chunk->type); 1769 return -EINVAL; 1770 } 1771 } 1772 1773 return 0; 1774} 1775 1776static int ath11k_qmi_assign_target_mem_chunk(struct ath11k_base *ab) 1777{ 1778 int i, idx; 1779 1780 for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) { 1781 switch (ab->qmi.target_mem[i].type) { 1782 case BDF_MEM_REGION_TYPE: 1783 ab->qmi.target_mem[idx].paddr = ab->hw_params.bdf_addr; 1784 ab->qmi.target_mem[idx].vaddr = NULL; 1785 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; 1786 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; 1787 idx++; 1788 break; 1789 case CALDB_MEM_REGION_TYPE: 1790 if (ab->qmi.target_mem[i].size > ATH11K_QMI_CALDB_SIZE) { 1791 ath11k_warn(ab, "qmi mem size is low to load caldata\n"); 1792 return -EINVAL; 1793 } 1794 /* TODO ath11k does not support cold boot calibration */ 1795 ab->qmi.target_mem[idx].paddr = 0; 1796 ab->qmi.target_mem[idx].vaddr = NULL; 1797 ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size; 1798 ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type; 1799 idx++; 1800 break; 1801 default: 1802 ath11k_warn(ab, "qmi ignore invalid mem req type %d\n", 1803 ab->qmi.target_mem[i].type); 1804 break; 1805 } 1806 } 1807 ab->qmi.mem_seg_count = idx; 1808 1809 return 0; 1810} 1811 1812static int ath11k_qmi_request_target_cap(struct ath11k_base *ab) 1813{ 1814 struct qmi_wlanfw_cap_req_msg_v01 req; 1815 struct qmi_wlanfw_cap_resp_msg_v01 resp; 1816 struct qmi_txn txn = {}; 1817 int ret = 0; 1818 1819 memset(&req, 0, sizeof(req)); 1820 memset(&resp, 0, sizeof(resp)); 1821 1822 ret = qmi_txn_init(&ab->qmi.handle, &txn, 1823 qmi_wlanfw_cap_resp_msg_v01_ei, &resp); 1824 if (ret < 0) 1825 goto out; 1826 1827 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 1828 QMI_WLANFW_CAP_REQ_V01, 1829 QMI_WLANFW_CAP_REQ_MSG_V01_MAX_LEN, 1830 qmi_wlanfw_cap_req_msg_v01_ei, &req); 1831 if (ret < 0) { 1832 ath11k_warn(ab, "qmi failed to send target cap request, err = %d\n", 1833 ret); 1834 goto out; 1835 } 1836 1837 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 1838 if (ret < 0) { 1839 ath11k_warn(ab, "qmi failed target cap request %d\n", ret); 1840 goto out; 1841 } 1842 1843 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 1844 ath11k_warn(ab, "qmi targetcap req failed, result: %d, err: %d\n", 1845 resp.resp.result, resp.resp.error); 1846 ret = -EINVAL; 1847 goto out; 1848 } 1849 1850 if (resp.chip_info_valid) { 1851 ab->qmi.target.chip_id = resp.chip_info.chip_id; 1852 ab->qmi.target.chip_family = resp.chip_info.chip_family; 1853 } 1854 1855 if (resp.board_info_valid) 1856 ab->qmi.target.board_id = resp.board_info.board_id; 1857 else 1858 ab->qmi.target.board_id = 0xFF; 1859 1860 if (resp.soc_info_valid) 1861 ab->qmi.target.soc_id = resp.soc_info.soc_id; 1862 1863 if (resp.fw_version_info_valid) { 1864 ab->qmi.target.fw_version = resp.fw_version_info.fw_version; 1865 strlcpy(ab->qmi.target.fw_build_timestamp, 1866 resp.fw_version_info.fw_build_timestamp, 1867 sizeof(ab->qmi.target.fw_build_timestamp)); 1868 } 1869 1870 if (resp.fw_build_id_valid) 1871 strlcpy(ab->qmi.target.fw_build_id, resp.fw_build_id, 1872 sizeof(ab->qmi.target.fw_build_id)); 1873 1874 ath11k_info(ab, "chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x\n", 1875 ab->qmi.target.chip_id, ab->qmi.target.chip_family, 1876 ab->qmi.target.board_id, ab->qmi.target.soc_id); 1877 1878 ath11k_info(ab, "fw_version 0x%x fw_build_timestamp %s fw_build_id %s", 1879 ab->qmi.target.fw_version, 1880 ab->qmi.target.fw_build_timestamp, 1881 ab->qmi.target.fw_build_id); 1882 1883out: 1884 return ret; 1885} 1886 1887static int 1888ath11k_qmi_prepare_bdf_download(struct ath11k_base *ab, int type, 1889 struct qmi_wlanfw_bdf_download_req_msg_v01 *req, 1890 void __iomem *bdf_addr) 1891{ 1892 const struct firmware *fw_entry; 1893 struct ath11k_board_data bd; 1894 u32 fw_size; 1895 int ret; 1896 1897 switch (type) { 1898 case ATH11K_QMI_FILE_TYPE_BDF_GOLDEN: 1899 memset(&bd, 0, sizeof(bd)); 1900 1901 ret = ath11k_core_fetch_bdf(ab, &bd); 1902 if (ret) { 1903 ath11k_warn(ab, "qmi failed to load BDF\n"); 1904 return ret; 1905 } 1906 1907 fw_size = min_t(u32, ab->hw_params.fw.board_size, bd.len); 1908 memcpy_toio(bdf_addr, bd.data, fw_size); 1909 ath11k_core_free_bdf(ab, &bd); 1910 break; 1911 case ATH11K_QMI_FILE_TYPE_CALDATA: 1912 fw_entry = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_CAL_FILE); 1913 if (IS_ERR(fw_entry)) { 1914 ret = PTR_ERR(fw_entry); 1915 ath11k_warn(ab, "failed to load %s: %d\n", 1916 ATH11K_DEFAULT_CAL_FILE, ret); 1917 return ret; 1918 } 1919 1920 fw_size = min_t(u32, ab->hw_params.fw.board_size, 1921 fw_entry->size); 1922 1923 memcpy_toio(bdf_addr + ATH11K_QMI_CALDATA_OFFSET, 1924 fw_entry->data, fw_size); 1925 1926 release_firmware(fw_entry); 1927 break; 1928 default: 1929 return -EINVAL; 1930 } 1931 1932 req->total_size = fw_size; 1933 return 0; 1934} 1935 1936static int ath11k_qmi_load_bdf_fixed_addr(struct ath11k_base *ab) 1937{ 1938 struct qmi_wlanfw_bdf_download_req_msg_v01 *req; 1939 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp; 1940 struct qmi_txn txn = {}; 1941 void __iomem *bdf_addr = NULL; 1942 int type, ret; 1943 1944 req = kzalloc(sizeof(*req), GFP_KERNEL); 1945 if (!req) 1946 return -ENOMEM; 1947 memset(&resp, 0, sizeof(resp)); 1948 1949 bdf_addr = ioremap(ab->hw_params.bdf_addr, ATH11K_QMI_BDF_MAX_SIZE); 1950 if (!bdf_addr) { 1951 ath11k_warn(ab, "qmi ioremap error for BDF\n"); 1952 ret = -EIO; 1953 goto out; 1954 } 1955 1956 for (type = 0; type < ATH11K_QMI_MAX_FILE_TYPE; type++) { 1957 req->valid = 1; 1958 req->file_id_valid = 1; 1959 req->file_id = ab->qmi.target.board_id; 1960 req->total_size_valid = 1; 1961 req->seg_id_valid = 1; 1962 req->seg_id = type; 1963 req->data_valid = 0; 1964 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; 1965 req->bdf_type = 0; 1966 req->bdf_type_valid = 0; 1967 req->end_valid = 1; 1968 req->end = 1; 1969 1970 ret = ath11k_qmi_prepare_bdf_download(ab, type, req, bdf_addr); 1971 if (ret < 0) 1972 goto out_qmi_bdf; 1973 1974 ret = qmi_txn_init(&ab->qmi.handle, &txn, 1975 qmi_wlanfw_bdf_download_resp_msg_v01_ei, 1976 &resp); 1977 if (ret < 0) 1978 goto out_qmi_bdf; 1979 1980 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 1981 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01, 1982 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN, 1983 qmi_wlanfw_bdf_download_req_msg_v01_ei, req); 1984 if (ret < 0) { 1985 qmi_txn_cancel(&txn); 1986 goto out_qmi_bdf; 1987 } 1988 1989 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 1990 if (ret < 0) 1991 goto out_qmi_bdf; 1992 1993 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 1994 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n", 1995 resp.resp.result, resp.resp.error); 1996 ret = -EINVAL; 1997 goto out_qmi_bdf; 1998 } 1999 } 2000 2001out_qmi_bdf: 2002 iounmap(bdf_addr); 2003out: 2004 kfree(req); 2005 return ret; 2006} 2007 2008static int ath11k_qmi_load_bdf_qmi(struct ath11k_base *ab) 2009{ 2010 struct qmi_wlanfw_bdf_download_req_msg_v01 *req; 2011 struct qmi_wlanfw_bdf_download_resp_msg_v01 resp; 2012 struct ath11k_board_data bd; 2013 unsigned int remaining; 2014 struct qmi_txn txn = {}; 2015 int ret; 2016 const u8 *temp; 2017 int bdf_type; 2018 2019 req = kzalloc(sizeof(*req), GFP_KERNEL); 2020 if (!req) 2021 return -ENOMEM; 2022 memset(&resp, 0, sizeof(resp)); 2023 2024 memset(&bd, 0, sizeof(bd)); 2025 ret = ath11k_core_fetch_bdf(ab, &bd); 2026 if (ret) { 2027 ath11k_warn(ab, "qmi failed to load bdf:\n"); 2028 goto out; 2029 } 2030 2031 temp = bd.data; 2032 remaining = bd.len; 2033 2034 if (bd.len >= SELFMAG && memcmp(bd.data, ELFMAG, SELFMAG) == 0) 2035 bdf_type = ATH11K_QMI_BDF_TYPE_ELF; 2036 else 2037 bdf_type = ATH11K_QMI_BDF_TYPE_BIN; 2038 2039 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi bdf_type %d\n", bdf_type); 2040 2041 while (remaining) { 2042 req->valid = 1; 2043 req->file_id_valid = 1; 2044 req->file_id = ab->qmi.target.board_id; 2045 req->total_size_valid = 1; 2046 req->total_size = bd.len; 2047 req->seg_id_valid = 1; 2048 req->data_valid = 1; 2049 req->data_len = ATH11K_QMI_MAX_BDF_FILE_NAME_SIZE; 2050 req->bdf_type = bdf_type; 2051 req->bdf_type_valid = 1; 2052 req->end_valid = 1; 2053 req->end = 0; 2054 2055 if (remaining > QMI_WLANFW_MAX_DATA_SIZE_V01) { 2056 req->data_len = QMI_WLANFW_MAX_DATA_SIZE_V01; 2057 } else { 2058 req->data_len = remaining; 2059 req->end = 1; 2060 } 2061 2062 memcpy(req->data, temp, req->data_len); 2063 2064 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2065 qmi_wlanfw_bdf_download_resp_msg_v01_ei, 2066 &resp); 2067 if (ret < 0) 2068 goto out_qmi_bdf; 2069 2070 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2071 QMI_WLANFW_BDF_DOWNLOAD_REQ_V01, 2072 QMI_WLANFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_LEN, 2073 qmi_wlanfw_bdf_download_req_msg_v01_ei, req); 2074 if (ret < 0) { 2075 qmi_txn_cancel(&txn); 2076 goto out_qmi_bdf; 2077 } 2078 2079 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 2080 if (ret < 0) 2081 goto out_qmi_bdf; 2082 2083 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2084 ath11k_warn(ab, "qmi BDF download failed, result: %d, err: %d\n", 2085 resp.resp.result, resp.resp.error); 2086 ret = resp.resp.result; 2087 goto out_qmi_bdf; 2088 } 2089 remaining -= req->data_len; 2090 temp += req->data_len; 2091 req->seg_id++; 2092 } 2093 2094out_qmi_bdf: 2095 ath11k_core_free_bdf(ab, &bd); 2096 2097out: 2098 kfree(req); 2099 return ret; 2100} 2101 2102static int ath11k_qmi_m3_load(struct ath11k_base *ab) 2103{ 2104 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2105 const struct firmware *fw; 2106 char path[100]; 2107 int ret; 2108 2109 if (m3_mem->vaddr || m3_mem->size) 2110 return 0; 2111 2112 fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE); 2113 if (IS_ERR(fw)) { 2114 ret = PTR_ERR(fw); 2115 ath11k_core_create_firmware_path(ab, ATH11K_M3_FILE, 2116 path, sizeof(path)); 2117 ath11k_err(ab, "failed to load %s: %d\n", path, ret); 2118 return ret; 2119 } 2120 2121 m3_mem->vaddr = dma_alloc_coherent(ab->dev, 2122 fw->size, &m3_mem->paddr, 2123 GFP_KERNEL); 2124 if (!m3_mem->vaddr) { 2125 ath11k_err(ab, "failed to allocate memory for M3 with size %zu\n", 2126 fw->size); 2127 release_firmware(fw); 2128 return -ENOMEM; 2129 } 2130 2131 memcpy(m3_mem->vaddr, fw->data, fw->size); 2132 m3_mem->size = fw->size; 2133 release_firmware(fw); 2134 2135 return 0; 2136} 2137 2138static void ath11k_qmi_m3_free(struct ath11k_base *ab) 2139{ 2140 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2141 2142 if (!ab->bus_params.m3_fw_support || !m3_mem->vaddr) 2143 return; 2144 2145 dma_free_coherent(ab->dev, m3_mem->size, 2146 m3_mem->vaddr, m3_mem->paddr); 2147 m3_mem->vaddr = NULL; 2148} 2149 2150static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab) 2151{ 2152 struct m3_mem_region *m3_mem = &ab->qmi.m3_mem; 2153 struct qmi_wlanfw_m3_info_req_msg_v01 req; 2154 struct qmi_wlanfw_m3_info_resp_msg_v01 resp; 2155 struct qmi_txn txn = {}; 2156 int ret = 0; 2157 2158 memset(&req, 0, sizeof(req)); 2159 memset(&resp, 0, sizeof(resp)); 2160 2161 if (ab->bus_params.m3_fw_support) { 2162 ret = ath11k_qmi_m3_load(ab); 2163 if (ret) { 2164 ath11k_err(ab, "failed to load m3 firmware: %d", ret); 2165 return ret; 2166 } 2167 2168 req.addr = m3_mem->paddr; 2169 req.size = m3_mem->size; 2170 } else { 2171 req.addr = 0; 2172 req.size = 0; 2173 } 2174 2175 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2176 qmi_wlanfw_m3_info_resp_msg_v01_ei, &resp); 2177 if (ret < 0) 2178 goto out; 2179 2180 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2181 QMI_WLANFW_M3_INFO_REQ_V01, 2182 QMI_WLANFW_M3_INFO_REQ_MSG_V01_MAX_MSG_LEN, 2183 qmi_wlanfw_m3_info_req_msg_v01_ei, &req); 2184 if (ret < 0) { 2185 ath11k_warn(ab, "qmi failed to send M3 information request, err = %d\n", 2186 ret); 2187 goto out; 2188 } 2189 2190 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 2191 if (ret < 0) { 2192 ath11k_warn(ab, "qmi failed M3 information request %d\n", ret); 2193 goto out; 2194 } 2195 2196 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2197 ath11k_warn(ab, "qmi M3 info request failed, result: %d, err: %d\n", 2198 resp.resp.result, resp.resp.error); 2199 ret = -EINVAL; 2200 goto out; 2201 } 2202out: 2203 return ret; 2204} 2205 2206static int ath11k_qmi_wlanfw_mode_send(struct ath11k_base *ab, 2207 u32 mode) 2208{ 2209 struct qmi_wlanfw_wlan_mode_req_msg_v01 req; 2210 struct qmi_wlanfw_wlan_mode_resp_msg_v01 resp; 2211 struct qmi_txn txn = {}; 2212 int ret = 0; 2213 2214 memset(&req, 0, sizeof(req)); 2215 memset(&resp, 0, sizeof(resp)); 2216 2217 req.mode = mode; 2218 req.hw_debug_valid = 1; 2219 req.hw_debug = 0; 2220 2221 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2222 qmi_wlanfw_wlan_mode_resp_msg_v01_ei, &resp); 2223 if (ret < 0) 2224 goto out; 2225 2226 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2227 QMI_WLANFW_WLAN_MODE_REQ_V01, 2228 QMI_WLANFW_WLAN_MODE_REQ_MSG_V01_MAX_LEN, 2229 qmi_wlanfw_wlan_mode_req_msg_v01_ei, &req); 2230 if (ret < 0) { 2231 ath11k_warn(ab, "qmi failed to send mode request, mode: %d, err = %d\n", 2232 mode, ret); 2233 goto out; 2234 } 2235 2236 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 2237 if (ret < 0) { 2238 if (mode == ATH11K_FIRMWARE_MODE_OFF && ret == -ENETRESET) { 2239 ath11k_warn(ab, "WLFW service is dis-connected\n"); 2240 return 0; 2241 } 2242 ath11k_warn(ab, "qmi failed set mode request, mode: %d, err = %d\n", 2243 mode, ret); 2244 goto out; 2245 } 2246 2247 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2248 ath11k_warn(ab, "Mode request failed, mode: %d, result: %d err: %d\n", 2249 mode, resp.resp.result, resp.resp.error); 2250 ret = -EINVAL; 2251 goto out; 2252 } 2253 2254out: 2255 return ret; 2256} 2257 2258static int ath11k_qmi_wlanfw_wlan_cfg_send(struct ath11k_base *ab) 2259{ 2260 struct qmi_wlanfw_wlan_cfg_req_msg_v01 *req; 2261 struct qmi_wlanfw_wlan_cfg_resp_msg_v01 resp; 2262 struct ce_pipe_config *ce_cfg; 2263 struct service_to_pipe *svc_cfg; 2264 struct qmi_txn txn = {}; 2265 int ret = 0, pipe_num; 2266 2267 ce_cfg = (struct ce_pipe_config *)ab->qmi.ce_cfg.tgt_ce; 2268 svc_cfg = (struct service_to_pipe *)ab->qmi.ce_cfg.svc_to_ce_map; 2269 2270 req = kzalloc(sizeof(*req), GFP_KERNEL); 2271 if (!req) 2272 return -ENOMEM; 2273 2274 memset(&resp, 0, sizeof(resp)); 2275 2276 req->host_version_valid = 1; 2277 strlcpy(req->host_version, ATH11K_HOST_VERSION_STRING, 2278 sizeof(req->host_version)); 2279 2280 req->tgt_cfg_valid = 1; 2281 /* This is number of CE configs */ 2282 req->tgt_cfg_len = ab->qmi.ce_cfg.tgt_ce_len; 2283 for (pipe_num = 0; pipe_num < req->tgt_cfg_len ; pipe_num++) { 2284 req->tgt_cfg[pipe_num].pipe_num = ce_cfg[pipe_num].pipenum; 2285 req->tgt_cfg[pipe_num].pipe_dir = ce_cfg[pipe_num].pipedir; 2286 req->tgt_cfg[pipe_num].nentries = ce_cfg[pipe_num].nentries; 2287 req->tgt_cfg[pipe_num].nbytes_max = ce_cfg[pipe_num].nbytes_max; 2288 req->tgt_cfg[pipe_num].flags = ce_cfg[pipe_num].flags; 2289 } 2290 2291 req->svc_cfg_valid = 1; 2292 /* This is number of Service/CE configs */ 2293 req->svc_cfg_len = ab->qmi.ce_cfg.svc_to_ce_map_len; 2294 for (pipe_num = 0; pipe_num < req->svc_cfg_len; pipe_num++) { 2295 req->svc_cfg[pipe_num].service_id = svc_cfg[pipe_num].service_id; 2296 req->svc_cfg[pipe_num].pipe_dir = svc_cfg[pipe_num].pipedir; 2297 req->svc_cfg[pipe_num].pipe_num = svc_cfg[pipe_num].pipenum; 2298 } 2299 req->shadow_reg_valid = 0; 2300 2301 /* set shadow v2 configuration */ 2302 if (ab->hw_params.supports_shadow_regs) { 2303 req->shadow_reg_v2_valid = 1; 2304 req->shadow_reg_v2_len = min_t(u32, 2305 ab->qmi.ce_cfg.shadow_reg_v2_len, 2306 QMI_WLANFW_MAX_NUM_SHADOW_REG_V2_V01); 2307 memcpy(&req->shadow_reg_v2, ab->qmi.ce_cfg.shadow_reg_v2, 2308 sizeof(u32) * req->shadow_reg_v2_len); 2309 } else { 2310 req->shadow_reg_v2_valid = 0; 2311 } 2312 2313 ret = qmi_txn_init(&ab->qmi.handle, &txn, 2314 qmi_wlanfw_wlan_cfg_resp_msg_v01_ei, &resp); 2315 if (ret < 0) 2316 goto out; 2317 2318 ret = qmi_send_request(&ab->qmi.handle, NULL, &txn, 2319 QMI_WLANFW_WLAN_CFG_REQ_V01, 2320 QMI_WLANFW_WLAN_CFG_REQ_MSG_V01_MAX_LEN, 2321 qmi_wlanfw_wlan_cfg_req_msg_v01_ei, req); 2322 if (ret < 0) { 2323 ath11k_warn(ab, "qmi failed to send wlan config request, err = %d\n", 2324 ret); 2325 goto out; 2326 } 2327 2328 ret = qmi_txn_wait(&txn, msecs_to_jiffies(ATH11K_QMI_WLANFW_TIMEOUT_MS)); 2329 if (ret < 0) { 2330 ath11k_warn(ab, "qmi failed wlan config request, err = %d\n", ret); 2331 goto out; 2332 } 2333 2334 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 2335 ath11k_warn(ab, "qmi wlan config request failed, result: %d, err: %d\n", 2336 resp.resp.result, resp.resp.error); 2337 ret = -EINVAL; 2338 goto out; 2339 } 2340 2341out: 2342 kfree(req); 2343 return ret; 2344} 2345 2346void ath11k_qmi_firmware_stop(struct ath11k_base *ab) 2347{ 2348 int ret; 2349 2350 ret = ath11k_qmi_wlanfw_mode_send(ab, ATH11K_FIRMWARE_MODE_OFF); 2351 if (ret < 0) { 2352 ath11k_warn(ab, "qmi failed to send wlan mode off\n"); 2353 return; 2354 } 2355} 2356 2357int ath11k_qmi_firmware_start(struct ath11k_base *ab, 2358 u32 mode) 2359{ 2360 int ret; 2361 2362 ret = ath11k_qmi_wlanfw_wlan_cfg_send(ab); 2363 if (ret < 0) { 2364 ath11k_warn(ab, "qmi failed to send wlan cfg:%d\n", ret); 2365 return ret; 2366 } 2367 2368 ret = ath11k_qmi_wlanfw_mode_send(ab, mode); 2369 if (ret < 0) { 2370 ath11k_warn(ab, "qmi failed to send wlan fw mode:%d\n", ret); 2371 return ret; 2372 } 2373 2374 return 0; 2375} 2376 2377static int 2378ath11k_qmi_driver_event_post(struct ath11k_qmi *qmi, 2379 enum ath11k_qmi_event_type type, 2380 void *data) 2381{ 2382 struct ath11k_qmi_driver_event *event; 2383 2384 event = kzalloc(sizeof(*event), GFP_ATOMIC); 2385 if (!event) 2386 return -ENOMEM; 2387 2388 event->type = type; 2389 event->data = data; 2390 2391 spin_lock(&qmi->event_lock); 2392 list_add_tail(&event->list, &qmi->event_list); 2393 spin_unlock(&qmi->event_lock); 2394 2395 queue_work(qmi->event_wq, &qmi->event_work); 2396 2397 return 0; 2398} 2399 2400static void ath11k_qmi_event_server_arrive(struct ath11k_qmi *qmi) 2401{ 2402 struct ath11k_base *ab = qmi->ab; 2403 int ret; 2404 2405 ret = ath11k_qmi_fw_ind_register_send(ab); 2406 if (ret < 0) { 2407 ath11k_warn(ab, "qmi failed to send FW indication QMI:%d\n", ret); 2408 return; 2409 } 2410 2411 ret = ath11k_qmi_host_cap_send(ab); 2412 if (ret < 0) { 2413 ath11k_warn(ab, "qmi failed to send host cap QMI:%d\n", ret); 2414 return; 2415 } 2416} 2417 2418static void ath11k_qmi_event_mem_request(struct ath11k_qmi *qmi) 2419{ 2420 struct ath11k_base *ab = qmi->ab; 2421 int ret; 2422 2423 ret = ath11k_qmi_respond_fw_mem_request(ab); 2424 if (ret < 0) { 2425 ath11k_warn(ab, "qmi failed to respond fw mem req:%d\n", ret); 2426 return; 2427 } 2428} 2429 2430static void ath11k_qmi_event_load_bdf(struct ath11k_qmi *qmi) 2431{ 2432 struct ath11k_base *ab = qmi->ab; 2433 int ret; 2434 2435 ret = ath11k_qmi_request_target_cap(ab); 2436 if (ret < 0) { 2437 ath11k_warn(ab, "qmi failed to req target capabilities:%d\n", ret); 2438 return; 2439 } 2440 2441 if (ab->bus_params.fixed_bdf_addr) 2442 ret = ath11k_qmi_load_bdf_fixed_addr(ab); 2443 else 2444 ret = ath11k_qmi_load_bdf_qmi(ab); 2445 if (ret < 0) { 2446 ath11k_warn(ab, "qmi failed to load board data file:%d\n", ret); 2447 return; 2448 } 2449 2450 ret = ath11k_qmi_wlanfw_m3_info_send(ab); 2451 if (ret < 0) { 2452 ath11k_warn(ab, "qmi failed to send m3 info req:%d\n", ret); 2453 return; 2454 } 2455} 2456 2457static void ath11k_qmi_msg_mem_request_cb(struct qmi_handle *qmi_hdl, 2458 struct sockaddr_qrtr *sq, 2459 struct qmi_txn *txn, 2460 const void *data) 2461{ 2462 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); 2463 struct ath11k_base *ab = qmi->ab; 2464 const struct qmi_wlanfw_request_mem_ind_msg_v01 *msg = data; 2465 int i, ret; 2466 2467 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware request memory request\n"); 2468 2469 if (msg->mem_seg_len == 0 || 2470 msg->mem_seg_len > ATH11K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01) 2471 ath11k_warn(ab, "Invalid memory segment length: %u\n", 2472 msg->mem_seg_len); 2473 2474 ab->qmi.mem_seg_count = msg->mem_seg_len; 2475 2476 for (i = 0; i < qmi->mem_seg_count ; i++) { 2477 ab->qmi.target_mem[i].type = msg->mem_seg[i].type; 2478 ab->qmi.target_mem[i].size = msg->mem_seg[i].size; 2479 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi mem seg type %d size %d\n", 2480 msg->mem_seg[i].type, msg->mem_seg[i].size); 2481 } 2482 2483 if (ab->bus_params.fixed_mem_region) { 2484 ret = ath11k_qmi_assign_target_mem_chunk(ab); 2485 if (ret) { 2486 ath11k_warn(ab, "qmi failed to assign target memory: %d\n", 2487 ret); 2488 return; 2489 } 2490 } else { 2491 ret = ath11k_qmi_alloc_target_mem_chunk(ab); 2492 if (ret) { 2493 ath11k_warn(ab, "qmi failed to alloc target memory: %d\n", 2494 ret); 2495 return; 2496 } 2497 } 2498 2499 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_REQUEST_MEM, NULL); 2500} 2501 2502static void ath11k_qmi_msg_mem_ready_cb(struct qmi_handle *qmi_hdl, 2503 struct sockaddr_qrtr *sq, 2504 struct qmi_txn *txn, 2505 const void *decoded) 2506{ 2507 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); 2508 struct ath11k_base *ab = qmi->ab; 2509 2510 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware memory ready indication\n"); 2511 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_MEM_READY, NULL); 2512} 2513 2514static void ath11k_qmi_msg_fw_ready_cb(struct qmi_handle *qmi_hdl, 2515 struct sockaddr_qrtr *sq, 2516 struct qmi_txn *txn, 2517 const void *decoded) 2518{ 2519 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); 2520 struct ath11k_base *ab = qmi->ab; 2521 2522 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi firmware ready\n"); 2523 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_FW_READY, NULL); 2524} 2525 2526static void ath11k_qmi_msg_cold_boot_cal_done_cb(struct qmi_handle *qmi, 2527 struct sockaddr_qrtr *sq, 2528 struct qmi_txn *txn, 2529 const void *decoded) 2530{ 2531} 2532 2533static const struct qmi_msg_handler ath11k_qmi_msg_handlers[] = { 2534 { 2535 .type = QMI_INDICATION, 2536 .msg_id = QMI_WLFW_REQUEST_MEM_IND_V01, 2537 .ei = qmi_wlanfw_request_mem_ind_msg_v01_ei, 2538 .decoded_size = sizeof(struct qmi_wlanfw_request_mem_ind_msg_v01), 2539 .fn = ath11k_qmi_msg_mem_request_cb, 2540 }, 2541 { 2542 .type = QMI_INDICATION, 2543 .msg_id = QMI_WLFW_FW_MEM_READY_IND_V01, 2544 .ei = qmi_wlanfw_mem_ready_ind_msg_v01_ei, 2545 .decoded_size = sizeof(struct qmi_wlanfw_fw_mem_ready_ind_msg_v01), 2546 .fn = ath11k_qmi_msg_mem_ready_cb, 2547 }, 2548 { 2549 .type = QMI_INDICATION, 2550 .msg_id = QMI_WLFW_FW_READY_IND_V01, 2551 .ei = qmi_wlanfw_fw_ready_ind_msg_v01_ei, 2552 .decoded_size = sizeof(struct qmi_wlanfw_fw_ready_ind_msg_v01), 2553 .fn = ath11k_qmi_msg_fw_ready_cb, 2554 }, 2555 { 2556 .type = QMI_INDICATION, 2557 .msg_id = QMI_WLFW_COLD_BOOT_CAL_DONE_IND_V01, 2558 .ei = qmi_wlanfw_cold_boot_cal_done_ind_msg_v01_ei, 2559 .decoded_size = 2560 sizeof(struct qmi_wlanfw_fw_cold_cal_done_ind_msg_v01), 2561 .fn = ath11k_qmi_msg_cold_boot_cal_done_cb, 2562 }, 2563}; 2564 2565static int ath11k_qmi_ops_new_server(struct qmi_handle *qmi_hdl, 2566 struct qmi_service *service) 2567{ 2568 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); 2569 struct ath11k_base *ab = qmi->ab; 2570 struct sockaddr_qrtr *sq = &qmi->sq; 2571 int ret; 2572 2573 sq->sq_family = AF_QIPCRTR; 2574 sq->sq_node = service->node; 2575 sq->sq_port = service->port; 2576 2577 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)sq, 2578 sizeof(*sq), 0); 2579 if (ret) { 2580 ath11k_warn(ab, "qmi failed to connect to remote service %d\n", ret); 2581 return ret; 2582 } 2583 2584 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw qmi service connected\n"); 2585 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_ARRIVE, NULL); 2586 2587 return 0; 2588} 2589 2590static void ath11k_qmi_ops_del_server(struct qmi_handle *qmi_hdl, 2591 struct qmi_service *service) 2592{ 2593 struct ath11k_qmi *qmi = container_of(qmi_hdl, struct ath11k_qmi, handle); 2594 struct ath11k_base *ab = qmi->ab; 2595 2596 ath11k_dbg(ab, ATH11K_DBG_QMI, "qmi wifi fw del server\n"); 2597 ath11k_qmi_driver_event_post(qmi, ATH11K_QMI_EVENT_SERVER_EXIT, NULL); 2598} 2599 2600static const struct qmi_ops ath11k_qmi_ops = { 2601 .new_server = ath11k_qmi_ops_new_server, 2602 .del_server = ath11k_qmi_ops_del_server, 2603}; 2604 2605static void ath11k_qmi_driver_event_work(struct work_struct *work) 2606{ 2607 struct ath11k_qmi *qmi = container_of(work, struct ath11k_qmi, 2608 event_work); 2609 struct ath11k_qmi_driver_event *event; 2610 struct ath11k_base *ab = qmi->ab; 2611 2612 spin_lock(&qmi->event_lock); 2613 while (!list_empty(&qmi->event_list)) { 2614 event = list_first_entry(&qmi->event_list, 2615 struct ath11k_qmi_driver_event, list); 2616 list_del(&event->list); 2617 spin_unlock(&qmi->event_lock); 2618 2619 if (test_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags)) { 2620 kfree(event); 2621 return; 2622 } 2623 2624 switch (event->type) { 2625 case ATH11K_QMI_EVENT_SERVER_ARRIVE: 2626 ath11k_qmi_event_server_arrive(qmi); 2627 break; 2628 case ATH11K_QMI_EVENT_SERVER_EXIT: 2629 set_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); 2630 set_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); 2631 break; 2632 case ATH11K_QMI_EVENT_REQUEST_MEM: 2633 ath11k_qmi_event_mem_request(qmi); 2634 break; 2635 case ATH11K_QMI_EVENT_FW_MEM_READY: 2636 ath11k_qmi_event_load_bdf(qmi); 2637 break; 2638 case ATH11K_QMI_EVENT_FW_READY: 2639 if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags)) { 2640 ath11k_hal_dump_srng_stats(ab); 2641 queue_work(ab->workqueue, &ab->restart_work); 2642 break; 2643 } 2644 2645 ath11k_core_qmi_firmware_ready(ab); 2646 ab->qmi.cal_done = 1; 2647 set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags); 2648 2649 break; 2650 case ATH11K_QMI_EVENT_COLD_BOOT_CAL_DONE: 2651 break; 2652 default: 2653 ath11k_warn(ab, "invalid event type: %d", event->type); 2654 break; 2655 } 2656 kfree(event); 2657 spin_lock(&qmi->event_lock); 2658 } 2659 spin_unlock(&qmi->event_lock); 2660} 2661 2662int ath11k_qmi_init_service(struct ath11k_base *ab) 2663{ 2664 int ret; 2665 2666 memset(&ab->qmi.target, 0, sizeof(struct target_info)); 2667 memset(&ab->qmi.target_mem, 0, sizeof(struct target_mem_chunk)); 2668 ab->qmi.ab = ab; 2669 2670 ab->qmi.target_mem_mode = ATH11K_QMI_TARGET_MEM_MODE_DEFAULT; 2671 ret = qmi_handle_init(&ab->qmi.handle, ATH11K_QMI_RESP_LEN_MAX, 2672 &ath11k_qmi_ops, ath11k_qmi_msg_handlers); 2673 if (ret < 0) { 2674 ath11k_warn(ab, "failed to initialize qmi handle\n"); 2675 return ret; 2676 } 2677 2678 ab->qmi.event_wq = alloc_workqueue("ath11k_qmi_driver_event", 2679 WQ_UNBOUND, 1); 2680 if (!ab->qmi.event_wq) { 2681 ath11k_err(ab, "failed to allocate workqueue\n"); 2682 return -EFAULT; 2683 } 2684 2685 INIT_LIST_HEAD(&ab->qmi.event_list); 2686 spin_lock_init(&ab->qmi.event_lock); 2687 INIT_WORK(&ab->qmi.event_work, ath11k_qmi_driver_event_work); 2688 2689 ret = qmi_add_lookup(&ab->qmi.handle, ATH11K_QMI_WLFW_SERVICE_ID_V01, 2690 ATH11K_QMI_WLFW_SERVICE_VERS_V01, 2691 ab->qmi.service_ins_id); 2692 if (ret < 0) { 2693 ath11k_warn(ab, "failed to add qmi lookup\n"); 2694 destroy_workqueue(ab->qmi.event_wq); 2695 return ret; 2696 } 2697 2698 return ret; 2699} 2700 2701void ath11k_qmi_deinit_service(struct ath11k_base *ab) 2702{ 2703 qmi_handle_release(&ab->qmi.handle); 2704 cancel_work_sync(&ab->qmi.event_work); 2705 destroy_workqueue(ab->qmi.event_wq); 2706 ath11k_qmi_m3_free(ab); 2707 ath11k_qmi_free_target_mem_chunk(ab); 2708} 2709 2710