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: Rakesh Pillai <pillair@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1586971906-20985-3-git-send-email-pillair@codeaurora.org
This commit is contained in:
parent
85325c24d5
commit
727fec790e
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue