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

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
...@@ -975,6 +975,11 @@ struct ath10k { ...@@ -975,6 +975,11 @@ struct ath10k {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct ieee80211_ops *ops; struct ieee80211_ops *ops;
struct device *dev; struct device *dev;
struct msa_region {
dma_addr_t paddr;
u32 mem_size;
void *vaddr;
} msa;
u8 mac_addr[ETH_ALEN]; u8 mac_addr[ETH_ALEN];
enum ath10k_hw_rev hw_rev; enum ath10k_hw_rev hw_rev;
......
...@@ -122,8 +122,8 @@ static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi) ...@@ -122,8 +122,8 @@ static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
int ret; int ret;
int i; int i;
req.msa_addr = qmi->msa_pa; req.msa_addr = ar->msa.paddr;
req.size = qmi->msa_mem_size; req.size = ar->msa.mem_size;
ret = qmi_txn_init(&qmi->qmi_hdl, &txn, ret = qmi_txn_init(&qmi->qmi_hdl, &txn,
wlfw_msa_info_resp_msg_v01_ei, &resp); 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) ...@@ -157,12 +157,12 @@ static int ath10k_qmi_msa_mem_info_send_sync_msg(struct ath10k_qmi *qmi)
goto out; 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; qmi->nr_mem_region = resp.mem_region_info_len;
for (i = 0; i < resp.mem_region_info_len; i++) { 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 > 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].size +
resp.mem_region_info[i].region_addr > max_mapped_addr) { 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", 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) ...@@ -1006,54 +1006,10 @@ static void ath10k_qmi_driver_event_work(struct work_struct *work)
spin_unlock(&qmi->event_lock); 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) int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
{ {
struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar); struct ath10k_snoc *ar_snoc = ath10k_snoc_priv(ar);
struct device *dev = ar->dev;
struct ath10k_qmi *qmi; struct ath10k_qmi *qmi;
int ret; int ret;
...@@ -1064,9 +1020,8 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size) ...@@ -1064,9 +1020,8 @@ int ath10k_qmi_init(struct ath10k *ar, u32 msa_size)
qmi->ar = ar; qmi->ar = ar;
ar_snoc->qmi = qmi; ar_snoc->qmi = qmi;
ret = ath10k_qmi_setup_msa_resources(qmi, msa_size); if (of_property_read_bool(dev->of_node, "qcom,msa-fixed-perm"))
if (ret) qmi->msa_fixed_perm = true;
goto err;
ret = qmi_handle_init(&qmi->qmi_hdl, ret = qmi_handle_init(&qmi->qmi_hdl,
WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN, WLFW_BDF_DOWNLOAD_REQ_MSG_V01_MAX_MSG_LEN,
......
...@@ -93,9 +93,6 @@ struct ath10k_qmi { ...@@ -93,9 +93,6 @@ struct ath10k_qmi {
spinlock_t event_lock; /* spinlock for qmi event list */ spinlock_t event_lock; /* spinlock for qmi event list */
u32 nr_mem_region; u32 nr_mem_region;
struct ath10k_msa_mem_info mem_region[MAX_NUM_MEMORY_REGIONS]; 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_chip_info chip_info;
struct ath10k_qmi_board_info board_info; struct ath10k_qmi_board_info board_info;
struct ath10k_qmi_soc_info soc_info; struct ath10k_qmi_soc_info soc_info;
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/of_address.h>
#include "ce.h" #include "ce.h"
#include "coredump.h" #include "coredump.h"
...@@ -1393,7 +1394,6 @@ static int ath10k_hw_power_off(struct ath10k *ar) ...@@ -1393,7 +1394,6 @@ static int ath10k_hw_power_off(struct ath10k *ar)
static void ath10k_msa_dump_memory(struct ath10k *ar, static void ath10k_msa_dump_memory(struct ath10k *ar,
struct ath10k_fw_crash_data *crash_data) 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_hw_mem_layout *mem_layout;
const struct ath10k_mem_region *current_region; const struct ath10k_mem_region *current_region;
struct ath10k_dump_ram_data_hdr *hdr; struct ath10k_dump_ram_data_hdr *hdr;
...@@ -1419,15 +1419,15 @@ static void ath10k_msa_dump_memory(struct ath10k *ar, ...@@ -1419,15 +1419,15 @@ static void ath10k_msa_dump_memory(struct ath10k *ar,
buf_len -= sizeof(*hdr); buf_len -= sizeof(*hdr);
hdr->region_type = cpu_to_le32(current_region->type); hdr->region_type = cpu_to_le32(current_region->type);
hdr->start = cpu_to_le32((unsigned long)ar_snoc->qmi->msa_va); hdr->start = cpu_to_le32((unsigned long)ar->msa.vaddr);
hdr->length = cpu_to_le32(ar_snoc->qmi->msa_mem_size); hdr->length = cpu_to_le32(ar->msa.mem_size);
if (current_region->len < ar_snoc->qmi->msa_mem_size) { if (current_region->len < ar->msa.mem_size) {
memcpy(buf, ar_snoc->qmi->msa_va, current_region->len); memcpy(buf, ar->msa.vaddr, current_region->len);
ath10k_warn(ar, "msa dump length is less than msa size %x, %x\n", 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 { } 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) ...@@ -1455,6 +1455,50 @@ void ath10k_snoc_fw_crashed_dump(struct ath10k *ar)
mutex_unlock(&ar->dump_mutex); 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[] = { static const struct of_device_id ath10k_snoc_dt_match[] = {
{ .compatible = "qcom,wcn3990-wifi", { .compatible = "qcom,wcn3990-wifi",
.data = &drv_priv, .data = &drv_priv,
...@@ -1557,6 +1601,12 @@ static int ath10k_snoc_probe(struct platform_device *pdev) ...@@ -1557,6 +1601,12 @@ static int ath10k_snoc_probe(struct platform_device *pdev)
goto err_free_irq; 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); ret = ath10k_qmi_init(ar, msa_size);
if (ret) { if (ret) {
ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret); ath10k_warn(ar, "failed to register wlfw qmi client: %d\n", ret);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment