Commit 727fec79 authored by Rakesh Pillai's avatar Rakesh Pillai Committed by Kalle Valo
Browse files

ath10k: Setup the msa resources before qmi init



Move the msa resources setup out of qmi init and
setup the msa resources as a part of probe before
the qmi init is done.

Tested HW: WCN3990
Tested FW: WLAN.HL.3.1-01040-QCAHLSWMTPLZ-1

Signed-off-by: default avatarRakesh Pillai <pillair@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/1586971906-20985-3-git-send-email-pillair@codeaurora.org
parent 85325c24
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -975,6 +975,11 @@ struct ath10k {
	struct ieee80211_hw *hw;
	struct ieee80211_ops *ops;
	struct device *dev;
	struct msa_region {
		dma_addr_t paddr;
		u32 mem_size;
		void *vaddr;
	} msa;
	u8 mac_addr[ETH_ALEN];

	enum ath10k_hw_rev hw_rev;
+8 −53
Original line number Diff line number Diff line
@@ -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",
@@ -1006,54 +1006,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 +1020,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,
+0 −3
Original line number Diff line number Diff line
@@ -93,9 +93,6 @@ struct ath10k_qmi {
	spinlock_t event_lock; /* spinlock for qmi event list */
	u32 nr_mem_region;
	struct ath10k_msa_mem_info mem_region[MAX_NUM_MEMORY_REGIONS];
	dma_addr_t msa_pa;
	u32 msa_mem_size;
	void *msa_va;
	struct ath10k_qmi_chip_info chip_info;
	struct ath10k_qmi_board_info board_info;
	struct ath10k_qmi_soc_info soc_info;
+57 −7
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regulator/consumer.h>
#include <linux/of_address.h>

#include "ce.h"
#include "coredump.h"
@@ -1393,7 +1394,6 @@ static int ath10k_hw_power_off(struct ath10k *ar)
static void ath10k_msa_dump_memory(struct ath10k *ar,
				   struct ath10k_fw_crash_data *crash_data)
{
	struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
	const struct ath10k_hw_mem_layout *mem_layout;
	const struct ath10k_mem_region *current_region;
	struct ath10k_dump_ram_data_hdr *hdr;
@@ -1419,15 +1419,15 @@ static void ath10k_msa_dump_memory(struct ath10k *ar,
	buf_len -= sizeof(*hdr);

	hdr->region_type = cpu_to_le32(current_region->type);
	hdr->start = cpu_to_le32((unsigned long)ar_snoc->qmi->msa_va);
	hdr->length = cpu_to_le32(ar_snoc->qmi->msa_mem_size);
	hdr->start = cpu_to_le32((unsigned long)ar->msa.vaddr);
	hdr->length = cpu_to_le32(ar->msa.mem_size);

	if (current_region->len < ar_snoc->qmi->msa_mem_size) {
		memcpy(buf, ar_snoc->qmi->msa_va, current_region->len);
	if (current_region->len < ar->msa.mem_size) {
		memcpy(buf, ar->msa.vaddr, current_region->len);
		ath10k_warn(ar, "msa dump length is less than msa size %x, %x\n",
			    current_region->len, ar_snoc->qmi->msa_mem_size);
			    current_region->len, ar->msa.mem_size);
	} else {
		memcpy(buf, ar_snoc->qmi->msa_va, ar_snoc->qmi->msa_mem_size);
		memcpy(buf, ar->msa.vaddr, ar->msa.mem_size);
	}
}

@@ -1455,6 +1455,50 @@ void ath10k_snoc_fw_crashed_dump(struct ath10k *ar)
	mutex_unlock(&ar->dump_mutex);
}

static int ath10k_setup_msa_resources(struct ath10k *ar, u32 msa_size)
{
	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);

		ar->msa.paddr = r.start;
		ar->msa.mem_size = resource_size(&r);
		ar->msa.vaddr = devm_memremap(dev, ar->msa.paddr,
					      ar->msa.mem_size,
					      MEMREMAP_WT);
		if (IS_ERR(ar->msa.vaddr)) {
			dev_err(dev, "failed to map memory region: %pa\n",
				&r.start);
			return PTR_ERR(ar->msa.vaddr);
		}
	} else {
		ar->msa.vaddr = dmam_alloc_coherent(dev, msa_size,
						    &ar->msa.paddr,
						    GFP_KERNEL);
		if (!ar->msa.vaddr) {
			ath10k_err(ar, "failed to allocate dma memory for msa region\n");
			return -ENOMEM;
		}
		ar->msa.mem_size = msa_size;
	}

	ath10k_dbg(ar, ATH10K_DBG_QMI, "qmi msa.paddr: %pad , msa.vaddr: 0x%p\n",
		   &ar->msa.paddr,
		   ar->msa.vaddr);

	return 0;
}

static const struct of_device_id ath10k_snoc_dt_match[] = {
	{ .compatible = "qcom,wcn3990-wifi",
	 .data = &drv_priv,
@@ -1557,6 +1601,12 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
		goto err_free_irq;
	}

	ret = ath10k_setup_msa_resources(ar, msa_size);
	if (ret) {
		ath10k_warn(ar, "failed to setup msa resources: %d\n", ret);
		goto err_power_off;
	}

	ret = ath10k_qmi_init(ar, msa_size);
	if (ret) {
		ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);