Skip to content

Commit

Permalink
ath10k: Setup the msa resources before qmi init
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Rakesh Pillai authored and Kalle Valo committed May 5, 2020
1 parent 85325c2 commit 727fec7
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 63 deletions.
5 changes: 5 additions & 0 deletions drivers/net/wireless/ath/ath10k/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
61 changes: 8 additions & 53 deletions drivers/net/wireless/ath/ath10k/qmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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;

Expand All @@ -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,
Expand Down
3 changes: 0 additions & 3 deletions drivers/net/wireless/ath/ath10k/qmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
64 changes: 57 additions & 7 deletions drivers/net/wireless/ath/ath10k/snoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 727fec7

Please sign in to comment.