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 ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 510 struct qmi_txn txn; 511 int ret; 512 513 resp = kzalloc(sizeof(*resp), GFP_KERNEL); 514 if (!resp) 515 return -ENOMEM; 516 517 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp); 518 if (ret < 0) 519 goto out; 520 521 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 522 QMI_WLFW_CAP_REQ_V01, 523 WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN, 524 wlfw_cap_req_msg_v01_ei, &req); 525 if (ret < 0) { 526 qmi_txn_cancel(&txn); 527 ath10k_err(ar, "failed to send capability request: %d\n", ret); 528 goto out; 529 } 530 531 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 532 if (ret < 0) 533 goto out; 534 535 if (resp->resp.result != QMI_RESULT_SUCCESS_V01) { 536 ath10k_err(ar, "capability req rejected: %d\n", resp->resp.error); 537 ret = -EINVAL; 538 goto out; 539 } 540 541 if (resp->chip_info_valid) { 542 qmi->chip_info.chip_id = resp->chip_info.chip_id; 543 qmi->chip_info.chip_family = resp->chip_info.chip_family; 544 } 545 546 if (resp->board_info_valid) 547 qmi->board_info.board_id = resp->board_info.board_id; 548 else 549 qmi->board_info.board_id = 0xFF; 550 551 if (resp->soc_info_valid) 552 qmi->soc_info.soc_id = resp->soc_info.soc_id; 553 554 if (resp->fw_version_info_valid) { 555 qmi->fw_version = resp->fw_version_info.fw_version; 556 strlcpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp, 557 sizeof(qmi->fw_build_timestamp)); 558 } 559 560 if (resp->fw_build_id_valid) 561 strlcpy(qmi->fw_build_id, resp->fw_build_id, 562 MAX_BUILD_ID_LEN + 1); 563 564 if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) { 565 ath10k_info(ar, "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x", 566 qmi->chip_info.chip_id, qmi->chip_info.chip_family, 567 qmi->board_info.board_id, qmi->soc_info.soc_id); 568 ath10k_info(ar, "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 572 kfree(resp); 573 return 0; 574 575 out: 576 kfree(resp); 577 return ret; 578 } 579 580 static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi) 581 { 582 struct wlfw_host_cap_resp_msg_v01 resp = {}; 583 struct wlfw_host_cap_req_msg_v01 req = {}; 584 struct ath10k *ar = qmi->ar; 585 struct qmi_txn txn; 586 int ret; 587 588 req.daemon_support_valid = 1; 589 req.daemon_support = 0; 590 591 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 592 wlfw_host_cap_resp_msg_v01_ei, &resp); 593 if (ret < 0) 594 goto out; 595 596 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 597 QMI_WLFW_HOST_CAP_REQ_V01, 598 WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN, 599 wlfw_host_cap_req_msg_v01_ei, &req); 600 if (ret < 0) { 601 qmi_txn_cancel(&txn); 602 ath10k_err(ar, "failed to send host capability request: %d\n", ret); 603 goto out; 604 } 605 606 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 607 if (ret < 0) 608 goto out; 609 610 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 611 ath10k_err(ar, "host capability request rejected: %d\n", resp.resp.error); 612 ret = -EINVAL; 613 goto out; 614 } 615 616 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi host capability request completed\n"); 617 return 0; 618 619 out: 620 return ret; 621 } 622 623 static int 624 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi) 625 { 626 struct wlfw_ind_register_resp_msg_v01 resp = {}; 627 struct wlfw_ind_register_req_msg_v01 req = {}; 628 struct ath10k *ar = qmi->ar; 629 struct qmi_txn txn; 630 int ret; 631 632 req.client_id_valid = 1; 633 req.client_id = ATH10K_QMI_CLIENT_ID; 634 req.fw_ready_enable_valid = 1; 635 req.fw_ready_enable = 1; 636 req.msa_ready_enable_valid = 1; 637 req.msa_ready_enable = 1; 638 639 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 640 wlfw_ind_register_resp_msg_v01_ei, &resp); 641 if (ret < 0) 642 goto out; 643 644 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 645 QMI_WLFW_IND_REGISTER_REQ_V01, 646 WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN, 647 wlfw_ind_register_req_msg_v01_ei, &req); 648 if (ret < 0) { 649 qmi_txn_cancel(&txn); 650 ath10k_err(ar, "failed to send indication registered request: %d\n", ret); 651 goto out; 652 } 653 654 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 655 if (ret < 0) 656 goto out; 657 658 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 659 ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error); 660 ret = -EINVAL; 661 goto out; 662 } 663 664 if (resp.fw_status_valid) { 665 if (resp.fw_status & QMI_WLFW_FW_READY_V01) 666 qmi->fw_ready = true; 667 } 668 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n"); 669 return 0; 670 671 out: 672 return ret; 673 } 674 675 static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi) 676 { 677 struct ath10k *ar = qmi->ar; 678 int ret; 679 680 ret = ath10k_qmi_ind_register_send_sync_msg(qmi); 681 if (ret) 682 return; 683 684 if (qmi->fw_ready) { 685 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 686 return; 687 } 688 689 ret = ath10k_qmi_host_cap_send_sync(qmi); 690 if (ret) 691 return; 692 693 ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi); 694 if (ret) 695 return; 696 697 ret = ath10k_qmi_setup_msa_permissions(qmi); 698 if (ret) 699 return; 700 701 ret = ath10k_qmi_msa_ready_send_sync_msg(qmi); 702 if (ret) 703 goto err_setup_msa; 704 705 ret = ath10k_qmi_cap_send_sync_msg(qmi); 706 if (ret) 707 goto err_setup_msa; 708 709 return; 710 711 err_setup_msa: 712 ath10k_qmi_remove_msa_permission(qmi); 713 } 714 715 static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi) 716 { 717 struct ath10k *ar = qmi->ar; 718 719 ar->hif.bus = ATH10K_BUS_SNOC; 720 ar->id.qmi_ids_valid = true; 721 ar->id.qmi_board_id = qmi->board_info.board_id; 722 ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR; 723 724 return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD); 725 } 726 727 static int 728 ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi, 729 enum ath10k_qmi_driver_event_type type, 730 void *data) 731 { 732 struct ath10k_qmi_driver_event *event; 733 734 event = kzalloc(sizeof(*event), GFP_ATOMIC); 735 if (!event) 736 return -ENOMEM; 737 738 event->type = type; 739 event->data = data; 740 741 spin_lock(&qmi->event_lock); 742 list_add_tail(&event->list, &qmi->event_list); 743 spin_unlock(&qmi->event_lock); 744 745 queue_work(qmi->event_wq, &qmi->event_work); 746 747 return 0; 748 } 749 750 static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi) 751 { 752 struct ath10k *ar = qmi->ar; 753 754 ath10k_qmi_remove_msa_permission(qmi); 755 ath10k_core_free_board_files(ar); 756 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND); 757 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n"); 758 } 759 760 static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi) 761 { 762 int ret; 763 764 ret = ath10k_qmi_fetch_board_file(qmi); 765 if (ret) 766 goto out; 767 768 ret = ath10k_qmi_bdf_dnld_send_sync(qmi); 769 if (ret) 770 goto out; 771 772 ret = ath10k_qmi_send_cal_report_req(qmi); 773 774 out: 775 return; 776 } 777 778 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi) 779 { 780 struct ath10k *ar = qmi->ar; 781 782 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n"); 783 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 784 785 return 0; 786 } 787 788 static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl, 789 struct sockaddr_qrtr *sq, 790 struct qmi_txn *txn, const void *data) 791 { 792 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 793 794 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL); 795 } 796 797 static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl, 798 struct sockaddr_qrtr *sq, 799 struct qmi_txn *txn, const void *data) 800 { 801 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 802 803 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL); 804 } 805 806 static struct qmi_msg_handler qmi_msg_handler[] = { 807 { 808 .type = QMI_INDICATION, 809 .msg_id = QMI_WLFW_FW_READY_IND_V01, 810 .ei = wlfw_fw_ready_ind_msg_v01_ei, 811 .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01), 812 .fn = ath10k_qmi_fw_ready_ind, 813 }, 814 { 815 .type = QMI_INDICATION, 816 .msg_id = QMI_WLFW_MSA_READY_IND_V01, 817 .ei = wlfw_msa_ready_ind_msg_v01_ei, 818 .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01), 819 .fn = ath10k_qmi_msa_ready_ind, 820 }, 821 {} 822 }; 823 824 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl, 825 struct qmi_service *service) 826 { 827 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 828 struct sockaddr_qrtr *sq = &qmi->sq; 829 struct ath10k *ar = qmi->ar; 830 int ret; 831 832 sq->sq_family = AF_QIPCRTR; 833 sq->sq_node = service->node; 834 sq->sq_port = service->port; 835 836 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n"); 837 838 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq, 839 sizeof(qmi->sq), 0); 840 if (ret) { 841 ath10k_err(ar, "failed to connect to a remote QMI service port\n"); 842 return ret; 843 } 844 845 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n"); 846 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL); 847 848 return ret; 849 } 850 851 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, 852 struct qmi_service *service) 853 { 854 struct ath10k_qmi *qmi = 855 container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 856 857 qmi->fw_ready = false; 858 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); 859 } 860 861 static struct qmi_ops ath10k_qmi_ops = { 862 .new_server = ath10k_qmi_new_server, 863 .del_server = ath10k_qmi_del_server, 864 }; 865 866 static void ath10k_qmi_driver_event_work(struct work_struct *work) 867 { 868 struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi, 869 event_work); 870 struct ath10k_qmi_driver_event *event; 871 struct ath10k *ar = qmi->ar; 872 873 spin_lock(&qmi->event_lock); 874 while (!list_empty(&qmi->event_list)) { 875 event = list_first_entry(&qmi->event_list, 876 struct ath10k_qmi_driver_event, list); 877 list_del(&event->list); 878 spin_unlock(&qmi->event_lock); 879 880 switch (event->type) { 881 case ATH10K_QMI_EVENT_SERVER_ARRIVE: 882 ath10k_qmi_event_server_arrive(qmi); 883 break; 884 case ATH10K_QMI_EVENT_SERVER_EXIT: 885 ath10k_qmi_event_server_exit(qmi); 886 break; 887 case ATH10K_QMI_EVENT_FW_READY_IND: 888 ath10k_qmi_event_fw_ready_ind(qmi); 889 break; 890 case ATH10K_QMI_EVENT_MSA_READY_IND: 891 ath10k_qmi_event_msa_ready(qmi); 892 break; 893 default: 894 ath10k_warn(ar, "invalid event type: %d", event->type); 895 break; 896 } 897 kfree(event); 898 spin_lock(&qmi->event_lock); 899 } 900 spin_unlock(&qmi->event_lock); 901 } 902 903 static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size) 904 { 905 struct ath10k *ar = qmi->ar; 906 struct device *dev = ar->dev; 907 struct device_node *node; 908 struct resource r; 909 int ret; 910 911 node = of_parse_phandle(dev->of_node, "memory-region", 0); 912 if (node) { 913 ret = of_address_to_resource(node, 0, &r); 914 if (ret) { 915 dev_err(dev, "failed to resolve msa fixed region\n"); 916 return ret; 917 } 918 of_node_put(node); 919 920 qmi->msa_pa = r.start; 921 qmi->msa_mem_size = resource_size(&r); 922 qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size, 923 MEMREMAP_WT); 924 if (IS_ERR(qmi->msa_va)) { 925 dev_err(dev, "failed to map memory region: %pa\n", &r.start); 926 return PTR_ERR(qmi->msa_va); 927 } 928 } else { 929 qmi->msa_va = dmam_alloc_coherent(dev, msa_size, 930 &qmi->msa_pa, GFP_KERNEL); 931 if (!qmi->msa_va) { 932 ath10k_err(ar, "failed to allocate dma memory for msa region\n"); 933 return -ENOMEM; 934 } 935 qmi->msa_mem_size = msa_size; 936 } 937 938 ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n", 939 &qmi->msa_pa, 940 qmi->msa_va); 941 942 return 0; 943 } 944 945 int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) 946 { 947 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 948 struct ath10k_qmi *qmi; 949 int ret; 950 951 qmi = kzalloc(sizeof(*qmi), GFP_KERNEL); 952 if (!qmi) 953 return -ENOMEM; 954 955 qmi->ar = ar; 956 ar_snoc->qmi = qmi; 957 958 ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); 959 if (ret) 960 goto err; 961 962 ret = qmi_handle_init(&qmi->qmi_hdl, 963 WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, 964 &ath10k_qmi_ops, qmi_msg_handler); 965 if (ret) 966 goto err; 967 968 qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event", 969 WQ_UNBOUND, 1); 970 if (!qmi->event_wq) { 971 ath10k_err(ar, "failed to allocate workqueue\n"); 972 ret = -EFAULT; 973 goto err_release_qmi_handle; 974 } 975 976 INIT_LIST_HEAD(&qmi->event_list); 977 spin_lock_init(&qmi->event_lock); 978 INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work); 979 980 ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01, 981 WLFW_SERVICE_VERS_V01, 0); 982 if (ret) 983 goto err_qmi_lookup; 984 985 return 0; 986 987 err_qmi_lookup: 988 destroy_workqueue(qmi->event_wq); 989 990 err_release_qmi_handle: 991 qmi_handle_release(&qmi->qmi_hdl); 992 993 err: 994 kfree(qmi); 995 return ret; 996 } 997 998 int ath10k_qmi_deinit(struct ath10k *ar) 999 { 1000 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1001 struct ath10k_qmi *qmi = ar_snoc->qmi; 1002 1003 qmi_handle_release(&qmi->qmi_hdl); 1004 cancel_work_sync(&qmi->event_work); 1005 destroy_workqueue(qmi->event_wq); 1006 ar_snoc->qmi = NULL; 1007 1008 return 0; 1009 } 1010