Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /*
0003  * Copyright (c) 2018 The Linux Foundation. All rights reserved.
0004  */
0005 
0006 #include <linux/completion.h>
0007 #include <linux/device.h>
0008 #include <linux/debugfs.h>
0009 #include <linux/idr.h>
0010 #include <linux/kernel.h>
0011 #include <linux/of.h>
0012 #include <linux/of_address.h>
0013 #include <linux/module.h>
0014 #include <linux/net.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/qcom_scm.h>
0017 #include <linux/string.h>
0018 #include <net/sock.h>
0019 
0020 #include "debug.h"
0021 #include "snoc.h"
0022 
0023 #define ATH10K_QMI_CLIENT_ID        0x4b4e454c
0024 #define ATH10K_QMI_TIMEOUT      30
0025 
0026 static int ath10k_qmi_map_msa_permission(struct ath10k_qmi *qmi,
0027                      struct ath10k_msa_mem_info *mem_info)
0028 {
0029     struct qcom_scm_vmperm dst_perms[3];
0030     struct ath10k *ar = qmi->ar;
0031     unsigned int src_perms;
0032     u32 perm_count;
0033     int ret;
0034 
0035     src_perms = BIT(QCOM_SCM_VMID_HLOS);
0036 
0037     dst_perms[0].vmid = QCOM_SCM_VMID_MSS_MSA;
0038     dst_perms[0].perm = QCOM_SCM_PERM_RW;
0039     dst_perms[1].vmid = QCOM_SCM_VMID_WLAN;
0040     dst_perms[1].perm = QCOM_SCM_PERM_RW;
0041 
0042     if (mem_info->secure) {
0043         perm_count = 2;
0044     } else {
0045         dst_perms[2].vmid = QCOM_SCM_VMID_WLAN_CE;
0046         dst_perms[2].perm = QCOM_SCM_PERM_RW;
0047         perm_count = 3;
0048     }
0049 
0050     ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size,
0051                   &src_perms, dst_perms, perm_count);
0052     if (ret < 0)
0053         ath10k_err(ar, "failed to assign msa map permissions: %d\n", ret);
0054 
0055     return ret;
0056 }
0057 
0058 static int ath10k_qmi_unmap_msa_permission(struct ath10k_qmi *qmi,
0059                        struct ath10k_msa_mem_info *mem_info)
0060 {
0061     struct qcom_scm_vmperm dst_perms;
0062     struct ath10k *ar = qmi->ar;
0063     unsigned int src_perms;
0064     int ret;
0065 
0066     src_perms = BIT(QCOM_SCM_VMID_MSS_MSA) | BIT(QCOM_SCM_VMID_WLAN);
0067 
0068     if (!mem_info->secure)
0069         src_perms |= BIT(QCOM_SCM_VMID_WLAN_CE);
0070 
0071     dst_perms.vmid = QCOM_SCM_VMID_HLOS;
0072     dst_perms.perm = QCOM_SCM_PERM_RW;
0073 
0074     ret = qcom_scm_assign_mem(mem_info->addr, mem_info->size,
0075                   &src_perms, &dst_perms, 1);
0076     if (ret < 0)
0077         ath10k_err(ar, "failed to unmap msa permissions: %d\n", ret);
0078 
0079     return ret;
0080 }
0081 
0082 static int ath10k_qmi_setup_msa_permissions(struct ath10k_qmi *qmi)
0083 {
0084     int ret;
0085     int i;
0086 
0087     if (qmi->msa_fixed_perm)
0088         return 0;
0089 
0090     for (i = 0; i < qmi->nr_mem_region; i++) {
0091         ret = ath10k_qmi_map_msa_permission(qmi, &qmi->mem_region[i]);
0092         if (ret)
0093             goto err_unmap;
0094     }
0095 
0096     return 0;
0097 
0098 err_unmap:
0099     for (i--; i >= 0; i--)
0100         ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]);
0101     return ret;
0102 }
0103 
0104 static void ath10k_qmi_remove_msa_permission(struct ath10k_qmi *qmi)
0105 {
0106     int i;
0107 
0108     if (qmi->msa_fixed_perm)
0109         return;
0110 
0111     for (i = 0; i < qmi->nr_mem_region; i++)
0112         ath10k_qmi_unmap_msa_permission(qmi, &qmi->mem_region[i]);
0113 }
0114 
0115 static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
0116 {
0117     struct wlfw_msa_info_resp_msg_v01 resp = {};
0118     struct wlfw_msa_info_req_msg_v01 req = {};
0119     struct ath10k *ar = qmi->ar;
0120     phys_addr_t max_mapped_addr;
0121     struct qmi_txn txn;
0122     int ret;
0123     int i;
0124 
0125     req.msa_addr = ar->msa.paddr;
0126     req.size = ar->msa.mem_size;
0127 
0128     ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0129                wlfw_msa_info_resp_msg_v01_ei, &resp);
0130     if (ret < 0)
0131         goto out;
0132 
0133     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0134                    QMI_WLFW_MSA_INFO_REQ_V01,
0135                    WLFW_MSA_INFO_REQ_MSG_V01_MAX_MSG_LEN,
0136                    wlfw_msa_info_req_msg_v01_ei, &req);
0137     if (ret < 0) {
0138         qmi_txn_cancel(&txn);
0139         ath10k_err(ar, "failed to send msa mem info req: %d\n", ret);
0140         goto out;
0141     }
0142 
0143     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0144     if (ret < 0)
0145         goto out;
0146 
0147     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0148         ath10k_err(ar, "msa info req rejected: %d\n", resp.resp.error);
0149         ret = -EINVAL;
0150         goto out;
0151     }
0152 
0153     if (resp.mem_region_info_len > QMI_WLFW_MAX_MEM_REG_V01) {
0154         ath10k_err(ar, "invalid memory region length received: %d\n",
0155                resp.mem_region_info_len);
0156         ret = -EINVAL;
0157         goto out;
0158     }
0159 
0160     max_mapped_addr = ar->msa.paddr + ar->msa.mem_size;
0161     qmi->nr_mem_region = resp.mem_region_info_len;
0162     for (i = 0; i < resp.mem_region_info_len; i++) {
0163         if (resp.mem_region_info[i].size > ar->msa.mem_size ||
0164             resp.mem_region_info[i].region_addr > max_mapped_addr ||
0165             resp.mem_region_info[i].region_addr < ar->msa.paddr ||
0166             resp.mem_region_info[i].size +
0167             resp.mem_region_info[i].region_addr > max_mapped_addr) {
0168             ath10k_err(ar, "received out of range memory region address 0x%llx with size 0x%x, aborting\n",
0169                    resp.mem_region_info[i].region_addr,
0170                    resp.mem_region_info[i].size);
0171             ret = -EINVAL;
0172             goto fail_unwind;
0173         }
0174         qmi->mem_region[i].addr = resp.mem_region_info[i].region_addr;
0175         qmi->mem_region[i].size = resp.mem_region_info[i].size;
0176         qmi->mem_region[i].secure = resp.mem_region_info[i].secure_flag;
0177         ath10k_dbg(ar, ATH10K_DBG_QMI,
0178                "qmi msa mem region %d addr 0x%pa size 0x%x flag 0x%08x\n",
0179                i, &qmi->mem_region[i].addr,
0180                qmi->mem_region[i].size,
0181                qmi->mem_region[i].secure);
0182     }
0183 
0184     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem info request completed\n");
0185     return 0;
0186 
0187 fail_unwind:
0188     memset(&qmi->mem_region[0], 0, sizeof(qmi->mem_region[0]) * i);
0189 out:
0190     return ret;
0191 }
0192 
0193 static int ath10k_qmi_msa_ready_send_sync_msg(struct ath10k_qmi *qmi)
0194 {
0195     struct wlfw_msa_ready_resp_msg_v01 resp = {};
0196     struct wlfw_msa_ready_req_msg_v01 req = {};
0197     struct ath10k *ar = qmi->ar;
0198     struct qmi_txn txn;
0199     int ret;
0200 
0201     ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0202                wlfw_msa_ready_resp_msg_v01_ei, &resp);
0203     if (ret < 0)
0204         goto out;
0205 
0206     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0207                    QMI_WLFW_MSA_READY_REQ_V01,
0208                    WLFW_MSA_READY_REQ_MSG_V01_MAX_MSG_LEN,
0209                    wlfw_msa_ready_req_msg_v01_ei, &req);
0210     if (ret < 0) {
0211         qmi_txn_cancel(&txn);
0212         ath10k_err(ar, "failed to send msa mem ready request: %d\n", ret);
0213         goto out;
0214     }
0215 
0216     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0217     if (ret < 0)
0218         goto out;
0219 
0220     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0221         ath10k_err(ar, "msa ready request rejected: %d\n", resp.resp.error);
0222         ret = -EINVAL;
0223     }
0224 
0225     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa mem ready request completed\n");
0226     return 0;
0227 
0228 out:
0229     return ret;
0230 }
0231 
0232 static int ath10k_qmi_bdf_dnld_send_sync(struct ath10k_qmi *qmi)
0233 {
0234     struct wlfw_bdf_download_resp_msg_v01 resp = {};
0235     struct wlfw_bdf_download_req_msg_v01 *req;
0236     struct ath10k *ar = qmi->ar;
0237     unsigned int remaining;
0238     struct qmi_txn txn;
0239     const u8 *temp;
0240     int ret;
0241 
0242     req = kzalloc(sizeof(*req), GFP_KERNEL);
0243     if (!req)
0244         return -ENOMEM;
0245 
0246     temp = ar->normal_mode_fw.board_data;
0247     remaining = ar->normal_mode_fw.board_len;
0248 
0249     while (remaining) {
0250         req->valid = 1;
0251         req->file_id_valid = 1;
0252         req->file_id = 0;
0253         req->total_size_valid = 1;
0254         req->total_size = ar->normal_mode_fw.board_len;
0255         req->seg_id_valid = 1;
0256         req->data_valid = 1;
0257         req->end_valid = 1;
0258 
0259         if (remaining > QMI_WLFW_MAX_DATA_SIZE_V01) {
0260             req->data_len = QMI_WLFW_MAX_DATA_SIZE_V01;
0261         } else {
0262             req->data_len = remaining;
0263             req->end = 1;
0264         }
0265 
0266         memcpy(req->data, temp, req->data_len);
0267 
0268         ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0269                    wlfw_bdf_download_resp_msg_v01_ei,
0270                    &resp);
0271         if (ret < 0)
0272             goto out;
0273 
0274         ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0275                        QMI_WLFW_BDF_DOWNLOAD_REQ_V01,
0276                        WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
0277                        wlfw_bdf_download_req_msg_v01_ei, req);
0278         if (ret < 0) {
0279             qmi_txn_cancel(&txn);
0280             goto out;
0281         }
0282 
0283         ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0284 
0285         if (ret < 0)
0286             goto out;
0287 
0288         /* end = 1 triggers a CRC check on the BDF.  If this fails, we
0289          * get a QMI_ERR_MALFORMED_MSG_V01 error, but the FW is still
0290          * willing to use the BDF.  For some platforms, all the valid
0291          * released BDFs fail this CRC check, so attempt to detect this
0292          * scenario and treat it as non-fatal.
0293          */
0294         if (resp.resp.result != QMI_RESULT_SUCCESS_V01 &&
0295             !(req->end == 1 &&
0296               resp.resp.result == QMI_ERR_MALFORMED_MSG_V01)) {
0297             ath10k_err(ar, "failed to download board data file: %d\n",
0298                    resp.resp.error);
0299             ret = -EINVAL;
0300             goto out;
0301         }
0302 
0303         remaining -= req->data_len;
0304         temp += req->data_len;
0305         req->seg_id++;
0306     }
0307 
0308     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi bdf download request completed\n");
0309 
0310     kfree(req);
0311     return 0;
0312 
0313 out:
0314     kfree(req);
0315     return ret;
0316 }
0317 
0318 static int ath10k_qmi_send_cal_report_req(struct ath10k_qmi *qmi)
0319 {
0320     struct wlfw_cal_report_resp_msg_v01 resp = {};
0321     struct wlfw_cal_report_req_msg_v01 req = {};
0322     struct ath10k *ar = qmi->ar;
0323     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0324     struct qmi_txn txn;
0325     int i, j = 0;
0326     int ret;
0327 
0328     if (ar_snoc->xo_cal_supported) {
0329         req.xo_cal_data_valid = 1;
0330         req.xo_cal_data = ar_snoc->xo_cal_data;
0331     }
0332 
0333     ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cal_report_resp_msg_v01_ei,
0334                &resp);
0335     if (ret < 0)
0336         goto out;
0337 
0338     for (i = 0; i < QMI_WLFW_MAX_NUM_CAL_V01; i++) {
0339         if (qmi->cal_data[i].total_size &&
0340             qmi->cal_data[i].data) {
0341             req.meta_data[j] = qmi->cal_data[i].cal_id;
0342             j++;
0343         }
0344     }
0345     req.meta_data_len = j;
0346 
0347     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0348                    QMI_WLFW_CAL_REPORT_REQ_V01,
0349                    WLFW_CAL_REPORT_REQ_MSG_V01_MAX_MSG_LEN,
0350                    wlfw_cal_report_req_msg_v01_ei, &req);
0351     if (ret < 0) {
0352         qmi_txn_cancel(&txn);
0353         ath10k_err(ar, "failed to send calibration request: %d\n", ret);
0354         goto out;
0355     }
0356 
0357     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0358     if (ret < 0)
0359         goto out;
0360 
0361     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0362         ath10k_err(ar, "calibration request rejected: %d\n", resp.resp.error);
0363         ret = -EINVAL;
0364         goto out;
0365     }
0366 
0367     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi cal report request completed\n");
0368     return 0;
0369 
0370 out:
0371     return ret;
0372 }
0373 
0374 static int
0375 ath10k_qmi_mode_send_sync_msg(struct ath10k *ar, enum wlfw_driver_mode_enum_v01 mode)
0376 {
0377     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0378     struct ath10k_qmi *qmi = ar_snoc->qmi;
0379     struct wlfw_wlan_mode_resp_msg_v01 resp = {};
0380     struct wlfw_wlan_mode_req_msg_v01 req = {};
0381     struct qmi_txn txn;
0382     int ret;
0383 
0384     ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0385                wlfw_wlan_mode_resp_msg_v01_ei,
0386                &resp);
0387     if (ret < 0)
0388         goto out;
0389 
0390     req.mode = mode;
0391     req.hw_debug_valid = 1;
0392     req.hw_debug = 0;
0393 
0394     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0395                    QMI_WLFW_WLAN_MODE_REQ_V01,
0396                    WLFW_WLAN_MODE_REQ_MSG_V01_MAX_MSG_LEN,
0397                    wlfw_wlan_mode_req_msg_v01_ei, &req);
0398     if (ret < 0) {
0399         qmi_txn_cancel(&txn);
0400         ath10k_err(ar, "failed to send wlan mode %d request: %d\n", mode, ret);
0401         goto out;
0402     }
0403 
0404     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0405     if (ret < 0)
0406         goto out;
0407 
0408     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0409         ath10k_err(ar, "more request rejected: %d\n", resp.resp.error);
0410         ret = -EINVAL;
0411         goto out;
0412     }
0413 
0414     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wlan mode req completed: %d\n", mode);
0415     return 0;
0416 
0417 out:
0418     return ret;
0419 }
0420 
0421 static int
0422 ath10k_qmi_cfg_send_sync_msg(struct ath10k *ar,
0423                  struct ath10k_qmi_wlan_enable_cfg *config,
0424                  const char *version)
0425 {
0426     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0427     struct ath10k_qmi *qmi = ar_snoc->qmi;
0428     struct wlfw_wlan_cfg_resp_msg_v01 resp = {};
0429     struct wlfw_wlan_cfg_req_msg_v01 *req;
0430     struct qmi_txn txn;
0431     int ret;
0432     u32 i;
0433 
0434     req = kzalloc(sizeof(*req), GFP_KERNEL);
0435     if (!req)
0436         return -ENOMEM;
0437 
0438     ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0439                wlfw_wlan_cfg_resp_msg_v01_ei,
0440                &resp);
0441     if (ret < 0)
0442         goto out;
0443 
0444     req->host_version_valid = 0;
0445 
0446     req->tgt_cfg_valid = 1;
0447     if (config->num_ce_tgt_cfg > QMI_WLFW_MAX_NUM_CE_V01)
0448         req->tgt_cfg_len = QMI_WLFW_MAX_NUM_CE_V01;
0449     else
0450         req->tgt_cfg_len = config->num_ce_tgt_cfg;
0451     for (i = 0; i < req->tgt_cfg_len; i++) {
0452         req->tgt_cfg[i].pipe_num = config->ce_tgt_cfg[i].pipe_num;
0453         req->tgt_cfg[i].pipe_dir = config->ce_tgt_cfg[i].pipe_dir;
0454         req->tgt_cfg[i].nentries = config->ce_tgt_cfg[i].nentries;
0455         req->tgt_cfg[i].nbytes_max = config->ce_tgt_cfg[i].nbytes_max;
0456         req->tgt_cfg[i].flags = config->ce_tgt_cfg[i].flags;
0457     }
0458 
0459     req->svc_cfg_valid = 1;
0460     if (config->num_ce_svc_pipe_cfg > QMI_WLFW_MAX_NUM_SVC_V01)
0461         req->svc_cfg_len = QMI_WLFW_MAX_NUM_SVC_V01;
0462     else
0463         req->svc_cfg_len = config->num_ce_svc_pipe_cfg;
0464     for (i = 0; i < req->svc_cfg_len; i++) {
0465         req->svc_cfg[i].service_id = config->ce_svc_cfg[i].service_id;
0466         req->svc_cfg[i].pipe_dir = config->ce_svc_cfg[i].pipe_dir;
0467         req->svc_cfg[i].pipe_num = config->ce_svc_cfg[i].pipe_num;
0468     }
0469 
0470     req->shadow_reg_valid = 1;
0471     if (config->num_shadow_reg_cfg >
0472         QMI_WLFW_MAX_NUM_SHADOW_REG_V01)
0473         req->shadow_reg_len = QMI_WLFW_MAX_NUM_SHADOW_REG_V01;
0474     else
0475         req->shadow_reg_len = config->num_shadow_reg_cfg;
0476 
0477     memcpy(req->shadow_reg, config->shadow_reg_cfg,
0478            sizeof(struct wlfw_shadow_reg_cfg_s_v01) * req->shadow_reg_len);
0479 
0480     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0481                    QMI_WLFW_WLAN_CFG_REQ_V01,
0482                    WLFW_WLAN_CFG_REQ_MSG_V01_MAX_MSG_LEN,
0483                    wlfw_wlan_cfg_req_msg_v01_ei, req);
0484     if (ret < 0) {
0485         qmi_txn_cancel(&txn);
0486         ath10k_err(ar, "failed to send config request: %d\n", ret);
0487         goto out;
0488     }
0489 
0490     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0491     if (ret < 0)
0492         goto out;
0493 
0494     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0495         ath10k_err(ar, "config request rejected: %d\n", resp.resp.error);
0496         ret = -EINVAL;
0497         goto out;
0498     }
0499 
0500     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi config request completed\n");
0501     kfree(req);
0502     return 0;
0503 
0504 out:
0505     kfree(req);
0506     return ret;
0507 }
0508 
0509 int ath10k_qmi_wlan_enable(struct ath10k *ar,
0510                struct ath10k_qmi_wlan_enable_cfg *config,
0511                enum wlfw_driver_mode_enum_v01 mode,
0512                const char *version)
0513 {
0514     int ret;
0515 
0516     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi mode %d config %p\n",
0517            mode, config);
0518 
0519     ret = ath10k_qmi_cfg_send_sync_msg(ar, config, version);
0520     if (ret) {
0521         ath10k_err(ar, "failed to send qmi config: %d\n", ret);
0522         return ret;
0523     }
0524 
0525     ret = ath10k_qmi_mode_send_sync_msg(ar, mode);
0526     if (ret) {
0527         ath10k_err(ar, "failed to send qmi mode: %d\n", ret);
0528         return ret;
0529     }
0530 
0531     return 0;
0532 }
0533 
0534 int ath10k_qmi_wlan_disable(struct ath10k *ar)
0535 {
0536     return ath10k_qmi_mode_send_sync_msg(ar, QMI_WLFW_OFF_V01);
0537 }
0538 
0539 static int ath10k_qmi_cap_send_sync_msg(struct ath10k_qmi *qmi)
0540 {
0541     struct wlfw_cap_resp_msg_v01 *resp;
0542     struct wlfw_cap_req_msg_v01 req = {};
0543     struct ath10k *ar = qmi->ar;
0544     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0545     struct qmi_txn txn;
0546     int ret;
0547 
0548     resp = kzalloc(sizeof(*resp), GFP_KERNEL);
0549     if (!resp)
0550         return -ENOMEM;
0551 
0552     ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_cap_resp_msg_v01_ei, resp);
0553     if (ret < 0)
0554         goto out;
0555 
0556     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0557                    QMI_WLFW_CAP_REQ_V01,
0558                    WLFW_CAP_REQ_MSG_V01_MAX_MSG_LEN,
0559                    wlfw_cap_req_msg_v01_ei, &req);
0560     if (ret < 0) {
0561         qmi_txn_cancel(&txn);
0562         ath10k_err(ar, "failed to send capability request: %d\n", ret);
0563         goto out;
0564     }
0565 
0566     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0567     if (ret < 0)
0568         goto out;
0569 
0570     if (resp->resp.result != QMI_RESULT_SUCCESS_V01) {
0571         ath10k_err(ar, "capability req rejected: %d\n", resp->resp.error);
0572         ret = -EINVAL;
0573         goto out;
0574     }
0575 
0576     if (resp->chip_info_valid) {
0577         qmi->chip_info.chip_id = resp->chip_info.chip_id;
0578         qmi->chip_info.chip_family = resp->chip_info.chip_family;
0579     } else {
0580         qmi->chip_info.chip_id = 0xFF;
0581     }
0582 
0583     if (resp->board_info_valid)
0584         qmi->board_info.board_id = resp->board_info.board_id;
0585     else
0586         qmi->board_info.board_id = 0xFF;
0587 
0588     if (resp->soc_info_valid)
0589         qmi->soc_info.soc_id = resp->soc_info.soc_id;
0590 
0591     if (resp->fw_version_info_valid) {
0592         qmi->fw_version = resp->fw_version_info.fw_version;
0593         strscpy(qmi->fw_build_timestamp, resp->fw_version_info.fw_build_timestamp,
0594             sizeof(qmi->fw_build_timestamp));
0595     }
0596 
0597     if (resp->fw_build_id_valid)
0598         strscpy(qmi->fw_build_id, resp->fw_build_id,
0599             MAX_BUILD_ID_LEN + 1);
0600 
0601     if (!test_bit(ATH10K_SNOC_FLAG_REGISTERED, &ar_snoc->flags)) {
0602         ath10k_info(ar, "qmi chip_id 0x%x chip_family 0x%x board_id 0x%x soc_id 0x%x",
0603                 qmi->chip_info.chip_id, qmi->chip_info.chip_family,
0604                 qmi->board_info.board_id, qmi->soc_info.soc_id);
0605         ath10k_info(ar, "qmi fw_version 0x%x fw_build_timestamp %s fw_build_id %s",
0606                 qmi->fw_version, qmi->fw_build_timestamp, qmi->fw_build_id);
0607     }
0608 
0609     kfree(resp);
0610     return 0;
0611 
0612 out:
0613     kfree(resp);
0614     return ret;
0615 }
0616 
0617 static int ath10k_qmi_host_cap_send_sync(struct ath10k_qmi *qmi)
0618 {
0619     struct wlfw_host_cap_resp_msg_v01 resp = {};
0620     struct wlfw_host_cap_req_msg_v01 req = {};
0621     struct qmi_elem_info *req_ei;
0622     struct ath10k *ar = qmi->ar;
0623     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0624     struct qmi_txn txn;
0625     int ret;
0626 
0627     req.daemon_support_valid = 1;
0628     req.daemon_support = 0;
0629 
0630     ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_host_cap_resp_msg_v01_ei,
0631                &resp);
0632     if (ret < 0)
0633         goto out;
0634 
0635     if (test_bit(ATH10K_SNOC_FLAG_8BIT_HOST_CAP_QUIRK, &ar_snoc->flags))
0636         req_ei = wlfw_host_cap_8bit_req_msg_v01_ei;
0637     else
0638         req_ei = wlfw_host_cap_req_msg_v01_ei;
0639 
0640     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0641                    QMI_WLFW_HOST_CAP_REQ_V01,
0642                    WLFW_HOST_CAP_REQ_MSG_V01_MAX_MSG_LEN,
0643                    req_ei, &req);
0644     if (ret < 0) {
0645         qmi_txn_cancel(&txn);
0646         ath10k_err(ar, "failed to send host capability request: %d\n", ret);
0647         goto out;
0648     }
0649 
0650     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0651     if (ret < 0)
0652         goto out;
0653 
0654     /* older FW didn't support this request, which is not fatal */
0655     if (resp.resp.result != QMI_RESULT_SUCCESS_V01 &&
0656         resp.resp.error != QMI_ERR_NOT_SUPPORTED_V01) {
0657         ath10k_err(ar, "host capability request rejected: %d\n", resp.resp.error);
0658         ret = -EINVAL;
0659         goto out;
0660     }
0661 
0662     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi host capability request completed\n");
0663     return 0;
0664 
0665 out:
0666     return ret;
0667 }
0668 
0669 int ath10k_qmi_set_fw_log_mode(struct ath10k *ar, u8 fw_log_mode)
0670 {
0671     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0672     struct wlfw_ini_resp_msg_v01 resp = {};
0673     struct ath10k_qmi *qmi = ar_snoc->qmi;
0674     struct wlfw_ini_req_msg_v01 req = {};
0675     struct qmi_txn txn;
0676     int ret;
0677 
0678     req.enablefwlog_valid = 1;
0679     req.enablefwlog = fw_log_mode;
0680 
0681     ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_ini_resp_msg_v01_ei,
0682                &resp);
0683     if (ret < 0)
0684         goto out;
0685 
0686     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0687                    QMI_WLFW_INI_REQ_V01,
0688                    WLFW_INI_REQ_MSG_V01_MAX_MSG_LEN,
0689                    wlfw_ini_req_msg_v01_ei, &req);
0690     if (ret < 0) {
0691         qmi_txn_cancel(&txn);
0692         ath10k_err(ar, "failed to send fw log request: %d\n", ret);
0693         goto out;
0694     }
0695 
0696     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0697     if (ret < 0)
0698         goto out;
0699 
0700     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0701         ath10k_err(ar, "fw log request rejected: %d\n",
0702                resp.resp.error);
0703         ret = -EINVAL;
0704         goto out;
0705     }
0706     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi fw log request completed, mode: %d\n",
0707            fw_log_mode);
0708     return 0;
0709 
0710 out:
0711     return ret;
0712 }
0713 
0714 static int
0715 ath10k_qmi_ind_register_send_sync_msg(struct ath10k_qmi *qmi)
0716 {
0717     struct wlfw_ind_register_resp_msg_v01 resp = {};
0718     struct wlfw_ind_register_req_msg_v01 req = {};
0719     struct ath10k *ar = qmi->ar;
0720     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0721     struct qmi_txn txn;
0722     int ret;
0723 
0724     req.client_id_valid = 1;
0725     req.client_id = ATH10K_QMI_CLIENT_ID;
0726     req.fw_ready_enable_valid = 1;
0727     req.fw_ready_enable = 1;
0728     req.msa_ready_enable_valid = 1;
0729     req.msa_ready_enable = 1;
0730 
0731     if (ar_snoc->xo_cal_supported) {
0732         req.xo_cal_enable_valid = 1;
0733         req.xo_cal_enable = 1;
0734     }
0735 
0736     ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
0737                wlfw_ind_register_resp_msg_v01_ei, &resp);
0738     if (ret < 0)
0739         goto out;
0740 
0741     ret = qmi_send_request(&qmi->qmi_hdl, NULL, &txn,
0742                    QMI_WLFW_IND_REGISTER_REQ_V01,
0743                    WLFW_IND_REGISTER_REQ_MSG_V01_MAX_MSG_LEN,
0744                    wlfw_ind_register_req_msg_v01_ei, &req);
0745     if (ret < 0) {
0746         qmi_txn_cancel(&txn);
0747         ath10k_err(ar, "failed to send indication registered request: %d\n", ret);
0748         goto out;
0749     }
0750 
0751     ret = qmi_txn_wait(&txn, ATH10K_QMI_TIMEOUT * HZ);
0752     if (ret < 0)
0753         goto out;
0754 
0755     if (resp.resp.result != QMI_RESULT_SUCCESS_V01) {
0756         ath10k_err(ar, "indication request rejected: %d\n", resp.resp.error);
0757         ret = -EINVAL;
0758         goto out;
0759     }
0760 
0761     if (resp.fw_status_valid) {
0762         if (resp.fw_status & QMI_WLFW_FW_READY_V01)
0763             qmi->fw_ready = true;
0764     }
0765     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi indication register request completed\n");
0766     return 0;
0767 
0768 out:
0769     return ret;
0770 }
0771 
0772 static void ath10k_qmi_event_server_arrive(struct ath10k_qmi *qmi)
0773 {
0774     struct ath10k *ar = qmi->ar;
0775     int ret;
0776 
0777     ret = ath10k_qmi_ind_register_send_sync_msg(qmi);
0778     if (ret)
0779         return;
0780 
0781     if (qmi->fw_ready) {
0782         ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND);
0783         return;
0784     }
0785 
0786     ret = ath10k_qmi_host_cap_send_sync(qmi);
0787     if (ret)
0788         return;
0789 
0790     ret = ath10k_qmi_msa_mem_info_send_sync_msg(qmi);
0791     if (ret)
0792         return;
0793 
0794     /*
0795      * HACK: sleep for a while inbetween receiving the msa info response
0796      * and the XPU update to prevent SDM845 from crashing due to a security
0797      * violation, when running MPSS.AT.4.0.c2-01184-SDM845_GEN_PACK-1.
0798      */
0799     msleep(20);
0800 
0801     ret = ath10k_qmi_setup_msa_permissions(qmi);
0802     if (ret)
0803         return;
0804 
0805     ret = ath10k_qmi_msa_ready_send_sync_msg(qmi);
0806     if (ret)
0807         goto err_setup_msa;
0808 
0809     ret = ath10k_qmi_cap_send_sync_msg(qmi);
0810     if (ret)
0811         goto err_setup_msa;
0812 
0813     return;
0814 
0815 err_setup_msa:
0816     ath10k_qmi_remove_msa_permission(qmi);
0817 }
0818 
0819 static int ath10k_qmi_fetch_board_file(struct ath10k_qmi *qmi)
0820 {
0821     struct ath10k *ar = qmi->ar;
0822     int ret;
0823 
0824     ar->hif.bus = ATH10K_BUS_SNOC;
0825     ar->id.qmi_ids_valid = true;
0826     ar->id.qmi_board_id = qmi->board_info.board_id;
0827     ar->id.qmi_chip_id = qmi->chip_info.chip_id;
0828     ar->hw_params.fw.dir = WCN3990_HW_1_0_FW_DIR;
0829 
0830     ret = ath10k_core_check_dt(ar);
0831     if (ret)
0832         ath10k_dbg(ar, ATH10K_DBG_QMI, "DT bdf variant name not set.\n");
0833 
0834     return ath10k_core_fetch_board_file(qmi->ar, ATH10K_BD_IE_BOARD);
0835 }
0836 
0837 static int
0838 ath10k_qmi_driver_event_post(struct ath10k_qmi *qmi,
0839                  enum ath10k_qmi_driver_event_type type,
0840                  void *data)
0841 {
0842     struct ath10k_qmi_driver_event *event;
0843 
0844     event = kzalloc(sizeof(*event), GFP_ATOMIC);
0845     if (!event)
0846         return -ENOMEM;
0847 
0848     event->type = type;
0849     event->data = data;
0850 
0851     spin_lock(&qmi->event_lock);
0852     list_add_tail(&event->list, &qmi->event_list);
0853     spin_unlock(&qmi->event_lock);
0854 
0855     queue_work(qmi->event_wq, &qmi->event_work);
0856 
0857     return 0;
0858 }
0859 
0860 static void ath10k_qmi_event_server_exit(struct ath10k_qmi *qmi)
0861 {
0862     struct ath10k *ar = qmi->ar;
0863     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
0864 
0865     ath10k_qmi_remove_msa_permission(qmi);
0866     ath10k_core_free_board_files(ar);
0867     if (!test_bit(ATH10K_SNOC_FLAG_UNREGISTERING, &ar_snoc->flags) &&
0868         !test_bit(ATH10K_SNOC_FLAG_MODEM_STOPPED, &ar_snoc->flags))
0869         ath10k_snoc_fw_crashed_dump(ar);
0870 
0871     ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_DOWN_IND);
0872     ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service disconnected\n");
0873 }
0874 
0875 static void ath10k_qmi_event_msa_ready(struct ath10k_qmi *qmi)
0876 {
0877     int ret;
0878 
0879     ret = ath10k_qmi_fetch_board_file(qmi);
0880     if (ret)
0881         goto out;
0882 
0883     ret = ath10k_qmi_bdf_dnld_send_sync(qmi);
0884     if (ret)
0885         goto out;
0886 
0887     ret = ath10k_qmi_send_cal_report_req(qmi);
0888 
0889 out:
0890     return;
0891 }
0892 
0893 static int ath10k_qmi_event_fw_ready_ind(struct ath10k_qmi *qmi)
0894 {
0895     struct ath10k *ar = qmi->ar;
0896 
0897     ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw ready event received\n");
0898     ath10k_snoc_fw_indication(ar, ATH10K_QMI_EVENT_FW_READY_IND);
0899 
0900     return 0;
0901 }
0902 
0903 static void ath10k_qmi_fw_ready_ind(struct qmi_handle *qmi_hdl,
0904                     struct sockaddr_qrtr *sq,
0905                     struct qmi_txn *txn, const void *data)
0906 {
0907     struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
0908 
0909     ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_FW_READY_IND, NULL);
0910 }
0911 
0912 static void ath10k_qmi_msa_ready_ind(struct qmi_handle *qmi_hdl,
0913                      struct sockaddr_qrtr *sq,
0914                      struct qmi_txn *txn, const void *data)
0915 {
0916     struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
0917 
0918     ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_MSA_READY_IND, NULL);
0919 }
0920 
0921 static const struct qmi_msg_handler qmi_msg_handler[] = {
0922     {
0923         .type = QMI_INDICATION,
0924         .msg_id = QMI_WLFW_FW_READY_IND_V01,
0925         .ei = wlfw_fw_ready_ind_msg_v01_ei,
0926         .decoded_size = sizeof(struct wlfw_fw_ready_ind_msg_v01),
0927         .fn = ath10k_qmi_fw_ready_ind,
0928     },
0929     {
0930         .type = QMI_INDICATION,
0931         .msg_id = QMI_WLFW_MSA_READY_IND_V01,
0932         .ei = wlfw_msa_ready_ind_msg_v01_ei,
0933         .decoded_size = sizeof(struct wlfw_msa_ready_ind_msg_v01),
0934         .fn = ath10k_qmi_msa_ready_ind,
0935     },
0936     {}
0937 };
0938 
0939 static int ath10k_qmi_new_server(struct qmi_handle *qmi_hdl,
0940                  struct qmi_service *service)
0941 {
0942     struct ath10k_qmi *qmi = container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
0943     struct sockaddr_qrtr *sq = &qmi->sq;
0944     struct ath10k *ar = qmi->ar;
0945     int ret;
0946 
0947     sq->sq_family = AF_QIPCRTR;
0948     sq->sq_node = service->node;
0949     sq->sq_port = service->port;
0950 
0951     ath10k_dbg(ar, ATH10K_DBG_QMI, "wifi fw qmi service found\n");
0952 
0953     ret = kernel_connect(qmi_hdl->sock, (struct sockaddr *)&qmi->sq,
0954                  sizeof(qmi->sq), 0);
0955     if (ret) {
0956         ath10k_err(ar, "failed to connect to a remote QMI service port\n");
0957         return ret;
0958     }
0959 
0960     ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi wifi fw qmi service connected\n");
0961     ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_ARRIVE, NULL);
0962 
0963     return ret;
0964 }
0965 
0966 static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl,
0967                   struct qmi_service *service)
0968 {
0969     struct ath10k_qmi *qmi =
0970         container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl);
0971 
0972     qmi->fw_ready = false;
0973 
0974     /*
0975      * The del_server event is to be processed only if coming from
0976      * the qmi server. The qmi infrastructure sends del_server, when
0977      * any client releases the qmi handle. In this case do not process
0978      * this del_server event.
0979      */
0980     if (qmi->state == ATH10K_QMI_STATE_INIT_DONE)
0981         ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT,
0982                          NULL);
0983 }
0984 
0985 static const struct qmi_ops ath10k_qmi_ops = {
0986     .new_server = ath10k_qmi_new_server,
0987     .del_server = ath10k_qmi_del_server,
0988 };
0989 
0990 static void ath10k_qmi_driver_event_work(struct work_struct *work)
0991 {
0992     struct ath10k_qmi *qmi = container_of(work, struct ath10k_qmi,
0993                           event_work);
0994     struct ath10k_qmi_driver_event *event;
0995     struct ath10k *ar = qmi->ar;
0996 
0997     spin_lock(&qmi->event_lock);
0998     while (!list_empty(&qmi->event_list)) {
0999         event = list_first_entry(&qmi->event_list,
1000                      struct ath10k_qmi_driver_event, list);
1001         list_del(&event->list);
1002         spin_unlock(&qmi->event_lock);
1003 
1004         switch (event->type) {
1005         case ATH10K_QMI_EVENT_SERVER_ARRIVE:
1006             ath10k_qmi_event_server_arrive(qmi);
1007             break;
1008         case ATH10K_QMI_EVENT_SERVER_EXIT:
1009             ath10k_qmi_event_server_exit(qmi);
1010             break;
1011         case ATH10K_QMI_EVENT_FW_READY_IND:
1012             ath10k_qmi_event_fw_ready_ind(qmi);
1013             break;
1014         case ATH10K_QMI_EVENT_MSA_READY_IND:
1015             ath10k_qmi_event_msa_ready(qmi);
1016             break;
1017         default:
1018             ath10k_warn(ar, "invalid event type: %d", event->type);
1019             break;
1020         }
1021         kfree(event);
1022         spin_lock(&qmi->event_lock);
1023     }
1024     spin_unlock(&qmi->event_lock);
1025 }
1026 
1027 int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
1028 {
1029     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1030     struct device *dev = ar->dev;
1031     struct ath10k_qmi *qmi;
1032     int ret;
1033 
1034     qmi = kzalloc(sizeof(*qmi), GFP_KERNEL);
1035     if (!qmi)
1036         return -ENOMEM;
1037 
1038     qmi->ar = ar;
1039     ar_snoc->qmi = qmi;
1040 
1041     if (of_property_read_bool(dev->of_node, "qcom,msa-fixed-perm"))
1042         qmi->msa_fixed_perm = true;
1043 
1044     ret = qmi_handle_init(&qmi->qmi_hdl,
1045                   WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
1046                   &ath10k_qmi_ops, qmi_msg_handler);
1047     if (ret)
1048         goto err;
1049 
1050     qmi->event_wq = alloc_workqueue("ath10k_qmi_driver_event",
1051                     WQ_UNBOUND, 1);
1052     if (!qmi->event_wq) {
1053         ath10k_err(ar, "failed to allocate workqueue\n");
1054         ret = -EFAULT;
1055         goto err_release_qmi_handle;
1056     }
1057 
1058     INIT_LIST_HEAD(&qmi->event_list);
1059     spin_lock_init(&qmi->event_lock);
1060     INIT_WORK(&qmi->event_work, ath10k_qmi_driver_event_work);
1061 
1062     ret = qmi_add_lookup(&qmi->qmi_hdl, WLFW_SERVICE_ID_V01,
1063                  WLFW_SERVICE_VERS_V01, 0);
1064     if (ret)
1065         goto err_qmi_lookup;
1066 
1067     qmi->state = ATH10K_QMI_STATE_INIT_DONE;
1068     return 0;
1069 
1070 err_qmi_lookup:
1071     destroy_workqueue(qmi->event_wq);
1072 
1073 err_release_qmi_handle:
1074     qmi_handle_release(&qmi->qmi_hdl);
1075 
1076 err:
1077     kfree(qmi);
1078     return ret;
1079 }
1080 
1081 int ath10k_qmi_deinit(struct ath10k *ar)
1082 {
1083     struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
1084     struct ath10k_qmi *qmi = ar_snoc->qmi;
1085 
1086     qmi->state = ATH10K_QMI_STATE_DEINIT;
1087     qmi_handle_release(&qmi->qmi_hdl);
1088     cancel_work_sync(&qmi->event_work);
1089     destroy_workqueue(qmi->event_wq);
1090     kfree(qmi);
1091     ar_snoc->qmi = NULL;
1092 
1093     return 0;
1094 }