1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (c) 2018 The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/completion.h> 7 #include <linux/device.h> 8 #include <linux/debugfs.h> 9 #include <linux/idr.h> 10 #include <linux/kernel.h> 11 #include <linux/of.h> 12 #include <linux/of_address.h> 13 #include <linux/module.h> 14 #include <linux/net.h> 15 #include <linux/platform_device.h> 16 #include <linux/qcom_scm.h> 17 #include <linux/string.h> 18 #include <net/sock.h> 19 20 #include "debug.h" 21 #include "snoc.h" 22 23 #define ATH10K_QMI_CLIENT_ID 0x4b4e454c 24 #define ATH10K_QMI_TIMEOUT 30 25 26 static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi, 27 struct ath10k_msa_mem_info *mem_info) 28 { 29 struct qcom_scm_vmperm dst_perms[3]; 30 struct ath10k *ar = qmi->ar; 31 unsigned int src_perms; 32 u32 perm_count; 33 int ret; 34 35 src_perms = BIT(QCOM_SCM_VMID_HLOS); 36 37 dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA; 38 dst_perms[0].perm = QCOM_SCM_PERM_RW; 39 dst_perms[1].vmid = QCOM_SCM_VMID_WLAN; 40 dst_perms[1].perm = QCOM_SCM_PERM_RW; 41 42 if (mem_info->secure) { 43 perm_count = 2; 44 } else { 45 dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE; 46 dst_perms[2].perm = QCOM_SCM_PERM_RW; 47 perm_count = 3; 48 } 49 50 ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size, 51 &src_perms, dst_perms, perm_count); 52 if (ret < 0) 53 ath10k_err(ar, "failed to assign msa map permissions: %d\n", ret); 54 55 return ret; 56 } 57 58 static int ath10k_qmi_unmap_msa_permission(struct ath10k_qmi *qmi, 59 struct ath10k_msa_mem_info *mem_info) 60 { 61 struct qcom_scm_vmperm dst_perms; 62 struct ath10k *ar = qmi->ar; 63 unsigned int src_perms; 64 int ret; 65 66 src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN); 67 68 if (!mem_info->secure) 69 src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE); 70 71 dst_perms.vmid = QCOM_SCM_VMID_HLOS; 72 dst_perms.perm = QCOM_SCM_PERM_RW; 73 74 ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size, 75 &src_perms, &dst_perms, 1); 76 if (ret < 0) 77 ath10k_err(ar, "failed to unmap msa permissions: %d\n", ret); 78 79 return ret; 80 } 81 82 static int ath10k_qmi_setup_msa_permissions(struct ath10k_qmi *qmi) 83 { 84 int ret; 85 int i; 86 87 for (i = 0; i < qmi->nr_mem_region; i++) { 88 ret = ath10k_qmi_map_msa_permission(qmi, &qmi->mem_region[i]); 89 if (ret) 90 goto err_unmap; 91 } 92 93 return 0; 94 95 err_unmap: 96 for (i--; i >= 0; i--) 97 ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]); 98 return ret; 99 } 100 101 static void ath10k_qmi_remove_msa_permission(struct ath10k_qmi *qmi) 102 { 103 int i; 104 105 for (i = 0; i < qmi->nr_mem_region; i++) 106 ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]); 107 } 108 109 static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi) 110 { 111 struct wlfw_msa_info_resp_msg_v01 resp = {}; 112 struct wlfw_msa_info_req_msg_v01 req = {}; 113 struct ath10k *ar = qmi->ar; 114 struct qmi_txn txn; 115 int ret; 116 int i; 117 118 req.msa_addr = qmi->msa_pa; 119 req.size = qmi->msa_mem_size; 120 121 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 122 wlfw_msa_info_resp_msg_v01_ei, &resp); 123 if (ret < 0) 124 goto out; 125 126 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 127 QMI_WLFW_MSA_INFO_REQ_V01, 128 WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN, 129 wlfw_msa_info_req_msg_v01_ei, &req); 130 if (ret < 0) { 131 qmi_txn_cancel(&txn); 132 ath10k_err(ar, "failed to send msa mem info req: %d\n", ret); 133 goto out; 134 } 135 136 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 137 if (ret < 0) 138 goto out; 139 140 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 141 ath10k_err(ar, "msa info req rejected: %d\n", resp.resp.error); 142 ret = -EINVAL; 143 goto out; 144 } 145 146 if (resp.mem_region_info_len > QMI_WLFW_MAX_MEM_REG_V01) { 147 ath10k_err(ar, "invalid memory region length received: %d\n", 148 resp.mem_region_info_len); 149 ret = -EINVAL; 150 goto out; 151 } 152 153 qmi->nr_mem_region = resp.mem_region_info_len; 154 for (i = 0; i < resp.mem_region_info_len; i++) { 155 qmi->mem_region[i].addr = resp.mem_region_info[i].region_addr; 156 qmi->mem_region[i].size = resp.mem_region_info[i].size; 157 qmi->mem_region[i].secure = resp.mem_region_info[i].secure_flag; 158 ath10k_dbg(ar, ATH10K_DBG_QMI, 159 "qmi msa mem region %d addr 0x%pa size 0x%x flag 0x%08x\n", 160 i, &qmi->mem_region[i].addr, 161 qmi->mem_region[i].size, 162 qmi->mem_region[i].secure); 163 } 164 165 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem info request completed\n"); 166 return 0; 167 168 out: 169 return ret; 170 } 171 172 static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi) 173 { 174 struct wlfw_msa_ready_resp_msg_v01 resp = {}; 175 struct wlfw_msa_ready_req_msg_v01 req = {}; 176 struct ath10k *ar = qmi->ar; 177 struct qmi_txn txn; 178 int ret; 179 180 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 181 wlfw_msa_ready_resp_msg_v01_ei, &resp); 182 if (ret < 0) 183 goto out; 184 185 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 186 QMI_WLFW_MSA_READY_REQ_V01, 187 WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN, 188 wlfw_msa_ready_req_msg_v01_ei, &req); 189 if (ret < 0) { 190 qmi_txn_cancel(&txn); 191 ath10k_err(ar, "failed to send msa mem ready request: %d\n", ret); 192 goto out; 193 } 194 195 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 196 if (ret < 0) 197 goto out; 198 199 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 200 ath10k_err(ar, "msa ready request rejected: %d\n", resp.resp.error); 201 ret = -EINVAL; 202 } 203 204 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem ready request completed\n"); 205 return 0; 206 207 out: 208 return ret; 209 } 210 211 static int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi) 212 { 213 struct wlfw_bdf_download_resp_msg_v01 resp = {}; 214 struct wlfw_bdf_download_req_msg_v01 *req; 215 struct ath10k *ar = qmi->ar; 216 unsigned int remaining; 217 struct qmi_txn txn; 218 const u8 *temp; 219 int ret; 220 221 req = kzalloc(sizeof(*req), GFP_KERNEL); 222 if (!req) 223 return -ENOMEM; 224 225 temp = ar->normal_mode_fw.board_data; 226 remaining = ar->normal_mode_fw.board_len; 227 228 while (remaining) { 229 req->valid = 1; 230 req->file_id_valid = 1; 231 req->file_id = 0; 232 req->total_size_valid = 1; 233 req->total_size = ar->normal_mode_fw.board_len; 234 req->seg_id_valid = 1; 235 req->data_valid = 1; 236 req->end_valid = 1; 237 238 if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) { 239 req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01; 240 } else { 241 req->data_len = remaining; 242 req->end = 1; 243 } 244 245 memcpy(req->data, temp, req->data_len); 246 247 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 248 wlfw_bdf_download_resp_msg_v01_ei, 249 &resp); 250 if (ret < 0) 251 goto out; 252 253 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 254 QMI_WLFW_BDF_DOWNLOAD_REQ_V01, 255 WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, 256 wlfw_bdf_download_req_msg_v01_ei, req); 257 if (ret < 0) { 258 qmi_txn_cancel(&txn); 259 goto out; 260 } 261 262 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 263 264 if (ret < 0) 265 goto out; 266 267 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 268 ath10k_err(ar, "failed to download board data file: %d\n", 269 resp.resp.error); 270 ret = -EINVAL; 271 goto out; 272 } 273 274 remaining -= req->data_len; 275 temp += req->data_len; 276 req->seg_id++; 277 } 278 279 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi bdf download request completed\n"); 280 281 kfree(req); 282 return 0; 283 284 out: 285 kfree(req); 286 return ret; 287 } 288 289 static int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi) 290 { 291 struct wlfw_cal_report_resp_msg_v01 resp = {}; 292 struct wlfw_cal_report_req_msg_v01 req = {}; 293 struct ath10k *ar = qmi->ar; 294 struct qmi_txn txn; 295 int i, j = 0; 296 int ret; 297 298 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cal_report_resp_msg_v01_ei, 299 &resp); 300 if (ret < 0) 301 goto out; 302 303 for (i = 0; i < QMI_WLFW_MAX_NUM_CAL_V01; i++) { 304 if (qmi->cal_data[i].total_size && 305 qmi->cal_data[i].data) { 306 req.meta_data[j] = qmi->cal_data[i].cal_id; 307 j++; 308 } 309 } 310 req.meta_data_len = j; 311 312 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 313 QMI_WLFW_CAL_REPORT_REQ_V01, 314 WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN, 315 wlfw_cal_report_req_msg_v01_ei, &req); 316 if (ret < 0) { 317 qmi_txn_cancel(&txn); 318 ath10k_err(ar, "failed to send calibration request: %d\n", ret); 319 goto out; 320 } 321 322 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 323 if (ret < 0) 324 goto out; 325 326 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 327 ath10k_err(ar, "calibration request rejected: %d\n", resp.resp.error); 328 ret = -EINVAL; 329 goto out; 330 } 331 332 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi cal report request completed\n"); 333 return 0; 334 335 out: 336 return ret; 337 } 338 339 static int 340 ath10k_qmi_mode_send_sync_msg(struct ath10k *ar, enum wlfw_driver_mode_enum_v01 mode) 341 { 342 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 343 struct ath10k_qmi *qmi = ar_snoc->qmi; 344 struct wlfw_wlan_mode_resp_msg_v01 resp = {}; 345 struct wlfw_wlan_mode_req_msg_v01 req = {}; 346 struct qmi_txn txn; 347 int ret; 348 349 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 350 wlfw_wlan_mode_resp_msg_v01_ei, 351 &resp); 352 if (ret < 0) 353 goto out; 354 355 req.mode = mode; 356 req.hw_debug_valid = 1; 357 req.hw_debug = 0; 358 359 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 360 QMI_WLFW_WLAN_MODE_REQ_V01, 361 WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN, 362 wlfw_wlan_mode_req_msg_v01_ei, &req); 363 if (ret < 0) { 364 qmi_txn_cancel(&txn); 365 ath10k_err(ar, "failed to send wlan mode %d request: %d\n", mode, ret); 366 goto out; 367 } 368 369 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 370 if (ret < 0) 371 goto out; 372 373 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 374 ath10k_err(ar, "more request rejected: %d\n", resp.resp.error); 375 ret = -EINVAL; 376 goto out; 377 } 378 379 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wlan mode req completed: %d\n", mode); 380 return 0; 381 382 out: 383 return ret; 384 } 385 386 static int 387 ath10k_qmi_cfg_send_sync_msg(struct ath10k *ar, 388 struct ath10k_qmi_wlan_enable_cfg *config, 389 const char *version) 390 { 391 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 392 struct ath10k_qmi *qmi = ar_snoc->qmi; 393 struct wlfw_wlan_cfg_resp_msg_v01 resp = {}; 394 struct wlfw_wlan_cfg_req_msg_v01 *req; 395 struct qmi_txn txn; 396 int ret; 397 u32 i; 398 399 req = kzalloc(sizeof(*req), GFP_KERNEL); 400 if (!req) 401 return -ENOMEM; 402 403 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 404 wlfw_wlan_cfg_resp_msg_v01_ei, 405 &resp); 406 if (ret < 0) 407 goto out; 408 409 req->host_version_valid = 0; 410 411 req->tgt_cfg_valid = 1; 412 if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01) 413 req->tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01; 414 else 415 req->tgt_cfg_len = config->num_ce_tgt_cfg; 416 for (i = 0; i < req->tgt_cfg_len; i++) { 417 req->tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num; 418 req->tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir; 419 req->tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries; 420 req->tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max; 421 req->tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags; 422 } 423 424 req->svc_cfg_valid = 1; 425 if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01) 426 req->svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01; 427 else 428 req->svc_cfg_len = config->num_ce_svc_pipe_cfg; 429 for (i = 0; i < req->svc_cfg_len; i++) { 430 req->svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id; 431 req->svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir; 432 req->svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num; 433 } 434 435 req->shadow_reg_valid = 1; 436 if (config->num_shadow_reg_cfg > 437 QMI_WLFW_MAX_NUM_SHADOW_REG_V01) 438 req->shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01; 439 else 440 req->shadow_reg_len = config->num_shadow_reg_cfg; 441 442 memcpy(req->shadow_reg, config->shadow_reg_cfg, 443 sizeof(struct wlfw_shadow_reg_cfg_s_v01) * req->shadow_reg_len); 444 445 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 446 QMI_WLFW_WLAN_CFG_REQ_V01, 447 WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN, 448 wlfw_wlan_cfg_req_msg_v01_ei, req); 449 if (ret < 0) { 450 qmi_txn_cancel(&txn); 451 ath10k_err(ar, "failed to send config request: %d\n", ret); 452 goto out; 453 } 454 455 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 456 if (ret < 0) 457 goto out; 458 459 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 460 ath10k_err(ar, "config request rejected: %d\n", resp.resp.error); 461 ret = -EINVAL; 462 goto out; 463 } 464 465 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi config request completed\n"); 466 kfree(req); 467 return 0; 468 469 out: 470 kfree(req); 471 return ret; 472 } 473 474 int ath10k_qmi_wlan_enable(struct ath10k *ar, 475 struct ath10k_qmi_wlan_enable_cfg *config, 476 enum wlfw_driver_mode_enum_v01 mode, 477 const char *version) 478 { 479 int ret; 480 481 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi mode %d config %p\n", 482 mode, config); 483 484 ret = ath10k_qmi_cfg_send_sync_msg(ar, config, version); 485 if (ret) { 486 ath10k_err(ar, "failed to send qmi config: %d\n", ret); 487 return ret; 488 } 489 490 ret = ath10k_qmi_mode_send_sync_msg(ar, mode); 491 if (ret) { 492 ath10k_err(ar, "failed to send qmi mode: %d\n", ret); 493 return ret; 494 } 495 496 return 0; 497 } 498 499 int ath10k_qmi_wlan_disable(struct ath10k *ar) 500 { 501 return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01); 502 } 503 504 static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi) 505 { 506 struct wlfw_cap_resp_msg_v01 *resp; 507 struct wlfw_cap_req_msg_v01 req = {}; 508 struct ath10k *ar = qmi->ar; 509 struct qmi_txn txn; 510 int ret; 511 512 resp = kzalloc(sizeof(*resp), GFP_KERNEL); 513 if (!resp) 514 return -ENOMEM; 515 516 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp); 517 if (ret < 0) 518 goto out; 519 520 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 521 QMI_WLFW_CAP_REQ_V01, 522 WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN, 523 wlfw_cap_req_msg_v01_ei, &req); 524 if (ret < 0) { 525 qmi_txn_cancel(&txn); 526 ath10k_err(ar, "failed to send capability request: %d\n", ret); 527 goto out; 528 } 529 530 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 531 if (ret < 0) 532 goto out; 533 534 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { 535 ath10k_err(ar, "capability req rejected: %d\n", resp->resp.error); 536 ret = -EINVAL; 537 goto out; 538 } 539 540 if (resp->chip_info_valid) { 541 qmi->chip_info.chip_id = resp->chip_info.chip_id; 542 qmi->chip_info.chip_family = resp->chip_info.chip_family; 543 } 544 545 if (resp->board_info_valid) 546 qmi->board_info.board_id = resp->board_info.board_id; 547 else 548 qmi->board_info.board_id = 0xFF; 549 550 if (resp->soc_info_valid) 551 qmi->soc_info.soc_id = resp->soc_info.soc_id; 552 553 if (resp->fw_version_info_valid) { 554 qmi->fw_version = resp->fw_version_info.fw_version; 555 strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp, 556 sizeof(qmi->fw_build_timestamp)); 557 } 558 559 if (resp->fw_build_id_valid) 560 strlcpy(qmi->fw_build_id, resp->fw_build_id, 561 MAX_BUILD_ID_LEN + 1); 562 563 ath10k_dbg(ar, ATH10K_DBG_QMI, 564 "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x", 565 qmi->chip_info.chip_id, qmi->chip_info.chip_family, 566 qmi->board_info.board_id, qmi->soc_info.soc_id); 567 ath10k_dbg(ar, ATH10K_DBG_QMI, 568 "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s", 569 qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id); 570 571 kfree(resp); 572 return 0; 573 574 out: 575 kfree(resp); 576 return ret; 577 } 578 579 static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi) 580 { 581 struct wlfw_host_cap_resp_msg_v01 resp = {}; 582 struct wlfw_host_cap_req_msg_v01 req = {}; 583 struct ath10k *ar = qmi->ar; 584 struct qmi_txn txn; 585 int ret; 586 587 req.daemon_support_valid = 1; 588 req.daemon_support = 0; 589 590 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 591 wlfw_host_cap_resp_msg_v01_ei, &resp); 592 if (ret < 0) 593 goto out; 594 595 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 596 QMI_WLFW_HOST_CAP_REQ_V01, 597 WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN, 598 wlfw_host_cap_req_msg_v01_ei, &req); 599 if (ret < 0) { 600 qmi_txn_cancel(&txn); 601 ath10k_err(ar, "failed to send host capability request: %d\n", ret); 602 goto out; 603 } 604 605 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 606 if (ret < 0) 607 goto out; 608 609 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 610 ath10k_err(ar, "host capability request rejected: %d\n", resp.resp.error); 611 ret = -EINVAL; 612 goto out; 613 } 614 615 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi host capability request completed\n"); 616 return 0; 617 618 out: 619 return ret; 620 } 621 622 static int 623 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi) 624 { 625 struct wlfw_ind_register_resp_msg_v01 resp = {}; 626 struct wlfw_ind_register_req_msg_v01 req = {}; 627 struct ath10k *ar = qmi->ar; 628 struct qmi_txn txn; 629 int ret; 630 631 req.client_id_valid = 1; 632 req.client_id = ATH10K_QMI_CLIENT_ID; 633 req.fw_ready_enable_valid = 1; 634 req.fw_ready_enable = 1; 635 req.msa_ready_enable_valid = 1; 636 req.msa_ready_enable = 1; 637 638 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 639 wlfw_ind_register_resp_msg_v01_ei, &resp); 640 if (ret < 0) 641 goto out; 642 643 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 644 QMI_WLFW_IND_REGISTER_REQ_V01, 645 WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN, 646 wlfw_ind_register_req_msg_v01_ei, &req); 647 if (ret < 0) { 648 qmi_txn_cancel(&txn); 649 ath10k_err(ar, "failed to send indication registered request: %d\n", ret); 650 goto out; 651 } 652 653 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 654 if (ret < 0) 655 goto out; 656 657 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 658 ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error); 659 ret = -EINVAL; 660 goto out; 661 } 662 663 if (resp.fw_status_valid) { 664 if (resp.fw_status & QMI_WLFW_FW_READY_V01) 665 qmi->fw_ready = true; 666 } 667 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n"); 668 return 0; 669 670 out: 671 return ret; 672 } 673 674 static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi) 675 { 676 struct ath10k *ar = qmi->ar; 677 int ret; 678 679 ret = ath10k_qmi_ind_register_send_sync_msg(qmi); 680 if (ret) 681 return; 682 683 if (qmi->fw_ready) { 684 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 685 return; 686 } 687 688 ret = ath10k_qmi_host_cap_send_sync(qmi); 689 if (ret) 690 return; 691 692 ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi); 693 if (ret) 694 return; 695 696 ret = ath10k_qmi_setup_msa_permissions(qmi); 697 if (ret) 698 return; 699 700 ret = ath10k_qmi_msa_ready_send_sync_msg(qmi); 701 if (ret) 702 goto err_setup_msa; 703 704 ret = ath10k_qmi_cap_send_sync_msg(qmi); 705 if (ret) 706 goto err_setup_msa; 707 708 return; 709 710 err_setup_msa: 711 ath10k_qmi_remove_msa_permission(qmi); 712 } 713 714 static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi) 715 { 716 struct ath10k *ar = qmi->ar; 717 718 ar->hif.bus = ATH10K_BUS_SNOC; 719 ar->id.qmi_ids_valid = true; 720 ar->id.qmi_board_id = qmi->board_info.board_id; 721 ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR; 722 723 return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD); 724 } 725 726 static int 727 ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi, 728 enum ath10k_qmi_driver_event_type type, 729 void *data) 730 { 731 struct ath10k_qmi_driver_event *event; 732 733 event = kzalloc(sizeof(*event), GFP_ATOMIC); 734 if (!event) 735 return -ENOMEM; 736 737 event->type = type; 738 event->data = data; 739 740 spin_lock(&qmi->event_lock); 741 list_add_tail(&event->list, &qmi->event_list); 742 spin_unlock(&qmi->event_lock); 743 744 queue_work(qmi->event_wq, &qmi->event_work); 745 746 return 0; 747 } 748 749 static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi) 750 { 751 struct ath10k *ar = qmi->ar; 752 753 ath10k_qmi_remove_msa_permission(qmi); 754 ath10k_core_free_board_files(ar); 755 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND); 756 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n"); 757 } 758 759 static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi) 760 { 761 int ret; 762 763 ret = ath10k_qmi_fetch_board_file(qmi); 764 if (ret) 765 goto out; 766 767 ret = ath10k_qmi_bdf_dnld_send_sync(qmi); 768 if (ret) 769 goto out; 770 771 ret = ath10k_qmi_send_cal_report_req(qmi); 772 773 out: 774 return; 775 } 776 777 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi) 778 { 779 struct ath10k *ar = qmi->ar; 780 781 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n"); 782 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 783 784 return 0; 785 } 786 787 static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl, 788 struct sockaddr_qrtr *sq, 789 struct qmi_txn *txn, const void *data) 790 { 791 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 792 793 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL); 794 } 795 796 static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl, 797 struct sockaddr_qrtr *sq, 798 struct qmi_txn *txn, const void *data) 799 { 800 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 801 802 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL); 803 } 804 805 static struct qmi_msg_handler qmi_msg_handler[] = { 806 { 807 .type = QMI_INDICATION, 808 .msg_id = QMI_WLFW_FW_READY_IND_V01, 809 .ei = wlfw_fw_ready_ind_msg_v01_ei, 810 .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01), 811 .fn = ath10k_qmi_fw_ready_ind, 812 }, 813 { 814 .type = QMI_INDICATION, 815 .msg_id = QMI_WLFW_MSA_READY_IND_V01, 816 .ei = wlfw_msa_ready_ind_msg_v01_ei, 817 .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01), 818 .fn = ath10k_qmi_msa_ready_ind, 819 }, 820 {} 821 }; 822 823 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl, 824 struct qmi_service *service) 825 { 826 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 827 struct sockaddr_qrtr *sq = &qmi->sq; 828 struct ath10k *ar = qmi->ar; 829 int ret; 830 831 sq->sq_family = AF_QIPCRTR; 832 sq->sq_node = service->node; 833 sq->sq_port = service->port; 834 835 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n"); 836 837 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq, 838 sizeof(qmi->sq), 0); 839 if (ret) { 840 ath10k_err(ar, "failed to connect to a remote QMI service port\n"); 841 return ret; 842 } 843 844 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n"); 845 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL); 846 847 return ret; 848 } 849 850 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, 851 struct qmi_service *service) 852 { 853 struct ath10k_qmi *qmi = 854 container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 855 856 qmi->fw_ready = false; 857 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); 858 } 859 860 static struct qmi_ops ath10k_qmi_ops = { 861 .new_server = ath10k_qmi_new_server, 862 .del_server = ath10k_qmi_del_server, 863 }; 864 865 static void ath10k_qmi_driver_event_work(struct work_struct *work) 866 { 867 struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi, 868 event_work); 869 struct ath10k_qmi_driver_event *event; 870 struct ath10k *ar = qmi->ar; 871 872 spin_lock(&qmi->event_lock); 873 while (!list_empty(&qmi->event_list)) { 874 event = list_first_entry(&qmi->event_list, 875 struct ath10k_qmi_driver_event, list); 876 list_del(&event->list); 877 spin_unlock(&qmi->event_lock); 878 879 switch (event->type) { 880 case ATH10K_QMI_EVENT_SERVER_ARRIVE: 881 ath10k_qmi_event_server_arrive(qmi); 882 break; 883 case ATH10K_QMI_EVENT_SERVER_EXIT: 884 ath10k_qmi_event_server_exit(qmi); 885 break; 886 case ATH10K_QMI_EVENT_FW_READY_IND: 887 ath10k_qmi_event_fw_ready_ind(qmi); 888 break; 889 case ATH10K_QMI_EVENT_MSA_READY_IND: 890 ath10k_qmi_event_msa_ready(qmi); 891 break; 892 default: 893 ath10k_warn(ar, "invalid event type: %d", event->type); 894 break; 895 } 896 kfree(event); 897 spin_lock(&qmi->event_lock); 898 } 899 spin_unlock(&qmi->event_lock); 900 } 901 902 static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size) 903 { 904 struct ath10k *ar = qmi->ar; 905 struct device *dev = ar->dev; 906 struct device_node *node; 907 struct resource r; 908 int ret; 909 910 node = of_parse_phandle(dev->of_node, "memory-region", 0); 911 if (node) { 912 ret = of_address_to_resource(node, 0, &r); 913 if (ret) { 914 dev_err(dev, "failed to resolve msa fixed region\n"); 915 return ret; 916 } 917 of_node_put(node); 918 919 qmi->msa_pa = r.start; 920 qmi->msa_mem_size = resource_size(&r); 921 qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size, 922 MEMREMAP_WT); 923 if (IS_ERR(qmi->msa_va)) { 924 dev_err(dev, "failed to map memory region: %pa\n", &r.start); 925 return PTR_ERR(qmi->msa_va); 926 } 927 } else { 928 qmi->msa_va = dmam_alloc_coherent(dev, msa_size, 929 &qmi->msa_pa, GFP_KERNEL); 930 if (!qmi->msa_va) { 931 ath10k_err(ar, "failed to allocate dma memory for msa region\n"); 932 return -ENOMEM; 933 } 934 qmi->msa_mem_size = msa_size; 935 } 936 937 ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n", 938 &qmi->msa_pa, 939 qmi->msa_va); 940 941 return 0; 942 } 943 944 int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) 945 { 946 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 947 struct ath10k_qmi *qmi; 948 int ret; 949 950 qmi = kzalloc(sizeof(*qmi), GFP_KERNEL); 951 if (!qmi) 952 return -ENOMEM; 953 954 qmi->ar = ar; 955 ar_snoc->qmi = qmi; 956 957 ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); 958 if (ret) 959 goto err; 960 961 ret = qmi_handle_init(&qmi->qmi_hdl, 962 WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, 963 &ath10k_qmi_ops, qmi_msg_handler); 964 if (ret) 965 goto err; 966 967 qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event", 968 WQ_UNBOUND, 1); 969 if (!qmi->event_wq) { 970 ath10k_err(ar, "failed to allocate workqueue\n"); 971 ret = -EFAULT; 972 goto err_release_qmi_handle; 973 } 974 975 INIT_LIST_HEAD(&qmi->event_list); 976 spin_lock_init(&qmi->event_lock); 977 INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work); 978 979 ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01, 980 WLFW_SERVICE_VERS_V01, 0); 981 if (ret) 982 goto err_qmi_lookup; 983 984 return 0; 985 986 err_qmi_lookup: 987 destroy_workqueue(qmi->event_wq); 988 989 err_release_qmi_handle: 990 qmi_handle_release(&qmi->qmi_hdl); 991 992 err: 993 kfree(qmi); 994 return ret; 995 } 996 997 int ath10k_qmi_deinit(struct ath10k *ar) 998 { 999 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1000 struct ath10k_qmi *qmi = ar_snoc->qmi; 1001 1002 qmi_handle_release(&qmi->qmi_hdl); 1003 cancel_work_sync(&qmi->event_work); 1004 destroy_workqueue(qmi->event_wq); 1005 ar_snoc->qmi = NULL; 1006 1007 return 0; 1008 } 1009