diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/qmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/qmi.c | 74 |
1 files changed, 20 insertions, 54 deletions
diff --git a/drivers/net/wireless/ath/ath10k/qmi.c b/drivers/net/wireless/ath/ath10k/qmi.c index 85dce43c5439..5468a41e928e 100644 --- a/drivers/net/wireless/ath/ath10k/qmi.c +++ b/drivers/net/wireless/ath/ath10k/qmi.c @@ -122,8 +122,8 @@ static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi) int ret; int i; - req.msa_addr = qmi->msa_pa; - req.size = qmi->msa_mem_size; + req.msa_addr = ar->msa.paddr; + req.size = ar->msa.mem_size; ret = qmi_txn_init(&qmi->qmi_hdl, &txn, wlfw_msa_info_resp_msg_v01_ei, &resp); @@ -157,12 +157,12 @@ static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi) goto out; } - max_mapped_addr = qmi->msa_pa + qmi->msa_mem_size; + max_mapped_addr = ar->msa.paddr + ar->msa.mem_size; qmi->nr_mem_region = resp.mem_region_info_len; for (i = 0; i < resp.mem_region_info_len; i++) { - if (resp.mem_region_info[i].size > qmi->msa_mem_size || + if (resp.mem_region_info[i].size > ar->msa.mem_size || resp.mem_region_info[i].region_addr > max_mapped_addr || - resp.mem_region_info[i].region_addr < qmi->msa_pa || + resp.mem_region_info[i].region_addr < ar->msa.paddr || resp.mem_region_info[i].size + resp.mem_region_info[i].region_addr > max_mapped_addr) { ath10k_err(ar, "received out of range memory region address 0x%llx with size 0x%x, aborting\n", @@ -961,7 +961,16 @@ static void ath10k_qmi_del_server(struct qmi_handle *qmi_hdl, container_of(qmi_hdl, struct ath10k_qmi, qmi_hdl); qmi->fw_ready = false; - ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, NULL); + + /* + * The del_server event is to be processed only if coming from + * the qmi server. The qmi infrastructure sends del_server, when + * any client releases the qmi handle. In this case do not process + * this del_server event. + */ + if (qmi->state == ATH10K_QMI_STATE_INIT_DONE) + ath10k_qmi_driver_event_post(qmi, ATH10K_QMI_EVENT_SERVER_EXIT, + NULL); } static struct qmi_ops ath10k_qmi_ops = { @@ -1006,54 +1015,10 @@ static void ath10k_qmi_driver_event_work(struct work_struct *work) spin_unlock(&qmi->event_lock); } -static int ath10k_qmi_setup_msa_resources(struct ath10k_qmi *qmi, u32 msa_size) -{ - struct ath10k *ar = qmi->ar; - struct device *dev = ar->dev; - struct device_node *node; - struct resource r; - int ret; - - node = of_parse_phandle(dev->of_node, "memory-region", 0); - if (node) { - ret = of_address_to_resource(node, 0, &r); - if (ret) { - dev_err(dev, "failed to resolve msa fixed region\n"); - return ret; - } - of_node_put(node); - - qmi->msa_pa = r.start; - qmi->msa_mem_size = resource_size(&r); - qmi->msa_va = devm_memremap(dev, qmi->msa_pa, qmi->msa_mem_size, - MEMREMAP_WT); - if (IS_ERR(qmi->msa_va)) { - dev_err(dev, "failed to map memory region: %pa\n", &r.start); - return PTR_ERR(qmi->msa_va); - } - } else { - qmi->msa_va = dmam_alloc_coherent(dev, msa_size, - &qmi->msa_pa, GFP_KERNEL); - if (!qmi->msa_va) { - ath10k_err(ar, "failed to allocate dma memory for msa region\n"); - return -ENOMEM; - } - qmi->msa_mem_size = msa_size; - } - - if (of_property_read_bool(dev->of_node, "qcom,msa-fixed-perm")) - qmi->msa_fixed_perm = true; - - ath10k_dbg(ar, ATH10K_DBG_QMI, "msa pa: %pad , msa va: 0x%p\n", - &qmi->msa_pa, - qmi->msa_va); - - return 0; -} - int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) { struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); + struct device *dev = ar->dev; struct ath10k_qmi *qmi; int ret; @@ -1064,9 +1029,8 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) qmi->ar = ar; ar_snoc->qmi = qmi; - ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); - if (ret) - goto err; + if (of_property_read_bool(dev->of_node, "qcom,msa-fixed-perm")) + qmi->msa_fixed_perm = true; ret = qmi_handle_init(&qmi->qmi_hdl, WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, @@ -1091,6 +1055,7 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) if (ret) goto err_qmi_lookup; + qmi->state = ATH10K_QMI_STATE_INIT_DONE; return 0; err_qmi_lookup: @@ -1109,6 +1074,7 @@ int ath10k_qmi_deinit(struct ath10k *ar) struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); struct ath10k_qmi *qmi = ar_snoc->qmi; + qmi->state = ATH10K_QMI_STATE_DEINIT; qmi_handle_release(&qmi->qmi_hdl); cancel_work_sync(&qmi->event_work); destroy_workqueue(qmi->event_wq); |