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 int ath10k_qmi_set_fw_log_mode(struct ath10k *ar, u8 fw_log_mode) 624 { 625 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 626 struct wlfw_ini_resp_msg_v01 resp = {}; 627 struct ath10k_qmi *qmi = ar_snoc->qmi; 628 struct wlfw_ini_req_msg_v01 req = {}; 629 struct qmi_txn txn; 630 int ret; 631 632 req.enablefwlog_valid = 1; 633 req.enablefwlog = fw_log_mode; 634 635 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_ini_resp_msg_v01_ei, 636 &resp); 637 if (ret < 0) 638 goto out; 639 640 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 641 QMI_WLFW_INI_REQ_V01, 642 WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN, 643 wlfw_ini_req_msg_v01_ei, &req); 644 if (ret < 0) { 645 qmi_txn_cancel(&txn); 646 ath10k_err(ar, "fail to send fw log reqest: %d\n", ret); 647 goto out; 648 } 649 650 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 651 if (ret < 0) 652 goto out; 653 654 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 655 ath10k_err(ar, "fw log request rejectedr: %d\n", 656 resp.resp.error); 657 ret = -EINVAL; 658 goto out; 659 } 660 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi fw log request completed, mode: %d\n", 661 fw_log_mode); 662 return 0; 663 664 out: 665 return ret; 666 } 667 668 static int 669 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi) 670 { 671 struct wlfw_ind_register_resp_msg_v01 resp = {}; 672 struct wlfw_ind_register_req_msg_v01 req = {}; 673 struct ath10k *ar = qmi->ar; 674 struct qmi_txn txn; 675 int ret; 676 677 req.client_id_valid = 1; 678 req.client_id = ATH10K_QMI_CLIENT_ID; 679 req.fw_ready_enable_valid = 1; 680 req.fw_ready_enable = 1; 681 req.msa_ready_enable_valid = 1; 682 req.msa_ready_enable = 1; 683 684 ret = qmi_txn_init(&qmi->qmi_hdl, &txn, 685 wlfw_ind_register_resp_msg_v01_ei, &resp); 686 if (ret < 0) 687 goto out; 688 689 ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn, 690 QMI_WLFW_IND_REGISTER_REQ_V01, 691 WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN, 692 wlfw_ind_register_req_msg_v01_ei, &req); 693 if (ret < 0) { 694 qmi_txn_cancel(&txn); 695 ath10k_err(ar, "failed to send indication registered request: %d\n", ret); 696 goto out; 697 } 698 699 ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ); 700 if (ret < 0) 701 goto out; 702 703 if (resp.resp.result != QMI_RESULT_SUCCESS_V01) { 704 ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error); 705 ret = -EINVAL; 706 goto out; 707 } 708 709 if (resp.fw_status_valid) { 710 if (resp.fw_status & QMI_WLFW_FW_READY_V01) 711 qmi->fw_ready = true; 712 } 713 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n"); 714 return 0; 715 716 out: 717 return ret; 718 } 719 720 static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi) 721 { 722 struct ath10k *ar = qmi->ar; 723 int ret; 724 725 ret = ath10k_qmi_ind_register_send_sync_msg(qmi); 726 if (ret) 727 return; 728 729 if (qmi->fw_ready) { 730 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 731 return; 732 } 733 734 ret = ath10k_qmi_host_cap_send_sync(qmi); 735 if (ret) 736 return; 737 738 ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi); 739 if (ret) 740 return; 741 742 ret = ath10k_qmi_setup_msa_permissions(qmi); 743 if (ret) 744 return; 745 746 ret = ath10k_qmi_msa_ready_send_sync_msg(qmi); 747 if (ret) 748 goto err_setup_msa; 749 750 ret = ath10k_qmi_cap_send_sync_msg(qmi); 751 if (ret) 752 goto err_setup_msa; 753 754 return; 755 756 err_setup_msa: 757 ath10k_qmi_remove_msa_permission(qmi); 758 } 759 760 static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi) 761 { 762 struct ath10k *ar = qmi->ar; 763 764 ar->hif.bus = ATH10K_BUS_SNOC; 765 ar->id.qmi_ids_valid = true; 766 ar->id.qmi_board_id = qmi->board_info.board_id; 767 ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR; 768 769 return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD); 770 } 771 772 static int 773 ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi, 774 enum ath10k_qmi_driver_event_type type, 775 void *data) 776 { 777 struct ath10k_qmi_driver_event *event; 778 779 event = kzalloc(sizeof(*event), GFP_ATOMIC); 780 if (!event) 781 return -ENOMEM; 782 783 event->type = type; 784 event->data = data; 785 786 spin_lock(&qmi->event_lock); 787 list_add_tail(&event->list, &qmi->event_list); 788 spin_unlock(&qmi->event_lock); 789 790 queue_work(qmi->event_wq, &qmi->event_work); 791 792 return 0; 793 } 794 795 static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi) 796 { 797 struct ath10k *ar = qmi->ar; 798 799 ath10k_qmi_remove_msa_permission(qmi); 800 ath10k_core_free_board_files(ar); 801 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND); 802 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n"); 803 } 804 805 static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi) 806 { 807 int ret; 808 809 ret = ath10k_qmi_fetch_board_file(qmi); 810 if (ret) 811 goto out; 812 813 ret = ath10k_qmi_bdf_dnld_send_sync(qmi); 814 if (ret) 815 goto out; 816 817 ret = ath10k_qmi_send_cal_report_req(qmi); 818 819 out: 820 return; 821 } 822 823 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi) 824 { 825 struct ath10k *ar = qmi->ar; 826 827 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n"); 828 ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND); 829 830 return 0; 831 } 832 833 static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl, 834 struct sockaddr_qrtr *sq, 835 struct qmi_txn *txn, const void *data) 836 { 837 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 838 839 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL); 840 } 841 842 static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl, 843 struct sockaddr_qrtr *sq, 844 struct qmi_txn *txn, const void *data) 845 { 846 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 847 848 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL); 849 } 850 851 static struct qmi_msg_handler qmi_msg_handler[] = { 852 { 853 .type = QMI_INDICATION, 854 .msg_id = QMI_WLFW_FW_READY_IND_V01, 855 .ei = wlfw_fw_ready_ind_msg_v01_ei, 856 .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01), 857 .fn = ath10k_qmi_fw_ready_ind, 858 }, 859 { 860 .type = QMI_INDICATION, 861 .msg_id = QMI_WLFW_MSA_READY_IND_V01, 862 .ei = wlfw_msa_ready_ind_msg_v01_ei, 863 .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01), 864 .fn = ath10k_qmi_msa_ready_ind, 865 }, 866 {} 867 }; 868 869 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl, 870 struct qmi_service *service) 871 { 872 struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 873 struct sockaddr_qrtr *sq = &qmi->sq; 874 struct ath10k *ar = qmi->ar; 875 int ret; 876 877 sq->sq_family = AF_QIPCRTR; 878 sq->sq_node = service->node; 879 sq->sq_port = service->port; 880 881 ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n"); 882 883 ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq, 884 sizeof(qmi->sq), 0); 885 if (ret) { 886 ath10k_err(ar, "failed to connect to a remote QMI service port\n"); 887 return ret; 888 } 889 890 ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n"); 891 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL); 892 893 return ret; 894 } 895 896 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, 897 struct qmi_service *service) 898 { 899 struct ath10k_qmi *qmi = 900 container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); 901 902 qmi->fw_ready = false; 903 ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); 904 } 905 906 static struct qmi_ops ath10k_qmi_ops = { 907 .new_server = ath10k_qmi_new_server, 908 .del_server = ath10k_qmi_del_server, 909 }; 910 911 static void ath10k_qmi_driver_event_work(struct work_struct *work) 912 { 913 struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi, 914 event_work); 915 struct ath10k_qmi_driver_event *event; 916 struct ath10k *ar = qmi->ar; 917 918 spin_lock(&qmi->event_lock); 919 while (!list_empty(&qmi->event_list)) { 920 event = list_first_entry(&qmi->event_list, 921 struct ath10k_qmi_driver_event, list); 922 list_del(&event->list); 923 spin_unlock(&qmi->event_lock); 924 925 switch (event->type) { 926 case ATH10K_QMI_EVENT_SERVER_ARRIVE: 927 ath10k_qmi_event_server_arrive(qmi); 928 break; 929 case ATH10K_QMI_EVENT_SERVER_EXIT: 930 ath10k_qmi_event_server_exit(qmi); 931 break; 932 case ATH10K_QMI_EVENT_FW_READY_IND: 933 ath10k_qmi_event_fw_ready_ind(qmi); 934 break; 935 case ATH10K_QMI_EVENT_MSA_READY_IND: 936 ath10k_qmi_event_msa_ready(qmi); 937 break; 938 default: 939 ath10k_warn(ar, "invalid event type: %d", event->type); 940 break; 941 } 942 kfree(event); 943 spin_lock(&qmi->event_lock); 944 } 945 spin_unlock(&qmi->event_lock); 946 } 947 948 static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size) 949 { 950 struct ath10k *ar = qmi->ar; 951 struct device *dev = ar->dev; 952 struct device_node *node; 953 struct resource r; 954 int ret; 955 956 node = of_parse_phandle(dev->of_node, "memory-region", 0); 957 if (node) { 958 ret = of_address_to_resource(node, 0, &r); 959 if (ret) { 960 dev_err(dev, "failed to resolve msa fixed region\n"); 961 return ret; 962 } 963 of_node_put(node); 964 965 qmi->msa_pa = r.start; 966 qmi->msa_mem_size = resource_size(&r); 967 qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size, 968 MEMREMAP_WT); 969 if (IS_ERR(qmi->msa_va)) { 970 dev_err(dev, "failed to map memory region: %pa\n", &r.start); 971 return PTR_ERR(qmi->msa_va); 972 } 973 } else { 974 qmi->msa_va = dmam_alloc_coherent(dev, msa_size, 975 &qmi->msa_pa, GFP_KERNEL); 976 if (!qmi->msa_va) { 977 ath10k_err(ar, "failed to allocate dma memory for msa region\n"); 978 return -ENOMEM; 979 } 980 qmi->msa_mem_size = msa_size; 981 } 982 983 ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n", 984 &qmi->msa_pa, 985 qmi->msa_va); 986 987 return 0; 988 } 989 990 int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) 991 { 992 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 993 struct ath10k_qmi *qmi; 994 int ret; 995 996 qmi = kzalloc(sizeof(*qmi), GFP_KERNEL); 997 if (!qmi) 998 return -ENOMEM; 999 1000 qmi->ar = ar; 1001 ar_snoc->qmi = qmi; 1002 1003 ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); 1004 if (ret) 1005 goto err; 1006 1007 ret = qmi_handle_init(&qmi->qmi_hdl, 1008 WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, 1009 &ath10k_qmi_ops, qmi_msg_handler); 1010 if (ret) 1011 goto err; 1012 1013 qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event", 1014 WQ_UNBOUND, 1); 1015 if (!qmi->event_wq) { 1016 ath10k_err(ar, "failed to allocate workqueue\n"); 1017 ret = -EFAULT; 1018 goto err_release_qmi_handle; 1019 } 1020 1021 INIT_LIST_HEAD(&qmi->event_list); 1022 spin_lock_init(&qmi->event_lock); 1023 INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work); 1024 1025 ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01, 1026 WLFW_SERVICE_VERS_V01, 0); 1027 if (ret) 1028 goto err_qmi_lookup; 1029 1030 return 0; 1031 1032 err_qmi_lookup: 1033 destroy_workqueue(qmi->event_wq); 1034 1035 err_release_qmi_handle: 1036 qmi_handle_release(&qmi->qmi_hdl); 1037 1038 err: 1039 kfree(qmi); 1040 return ret; 1041 } 1042 1043 int ath10k_qmi_deinit(struct ath10k *ar) 1044 { 1045 struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); 1046 struct ath10k_qmi *qmi = ar_snoc->qmi; 1047 1048 qmi_handle_release(&qmi->qmi_hdl); 1049 cancel_work_sync(&qmi->event_work); 1050 destroy_workqueue(qmi->event_wq); 1051 kfree(qmi); 1052 ar_snoc->qmi = NULL; 1053 1054 return 0; 1055 } 1056