mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 13:23:02 -04:00
wifi: ath12k: switch to name-based reserved memory lookup
The driver currently retrieves reserved memory regions using index-based lookup, which depends on the ordering of reserved-memory nodes in the device tree. Since different platforms define these regions in varying orders and combinations, this approach is not compatible and can result in incorrect memory region access. Switch to looking up memory regions by name instead of index so it does not depend on node order. Use names already defined in qcom,ipq5332-wifi.yaml, so there are no backward compatibility issues. Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1 Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com> Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com> Link: https://patch.msgid.link/20260630062048.1615178-2-aaradhana.sahu@oss.qualcomm.com Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
committed by
Jeff Johnson
parent
e23d90cfcb
commit
3fe59edd19
@@ -12,6 +12,7 @@
|
||||
#include <linux/remoteproc.h>
|
||||
#include <linux/soc/qcom/mdt_loader.h>
|
||||
#include <linux/soc/qcom/smem_state.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
#include "ahb.h"
|
||||
#include "debug.h"
|
||||
#include "hif.h"
|
||||
@@ -337,24 +338,25 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
|
||||
char fw2_name[ATH12K_USERPD_FW_NAME_LEN];
|
||||
struct device *dev = ab->dev;
|
||||
const struct firmware *fw, *fw2;
|
||||
struct reserved_mem *rmem = NULL;
|
||||
unsigned long time_left;
|
||||
phys_addr_t mem_phys;
|
||||
struct resource res;
|
||||
void *mem_region;
|
||||
size_t mem_size;
|
||||
u32 pasid;
|
||||
int ret;
|
||||
|
||||
rmem = ath12k_core_get_reserved_mem(ab, 0);
|
||||
if (!rmem)
|
||||
return -ENODEV;
|
||||
ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region",
|
||||
&res);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
mem_phys = rmem->base;
|
||||
mem_size = rmem->size;
|
||||
mem_phys = res.start;
|
||||
mem_size = resource_size(&res);
|
||||
mem_region = devm_memremap(dev, mem_phys, mem_size, MEMREMAP_WC);
|
||||
if (IS_ERR(mem_region)) {
|
||||
ath12k_err(ab, "unable to map memory region: %pa+%pa\n",
|
||||
&rmem->base, &rmem->size);
|
||||
ath12k_err(ab, "unable to map memory region: %pa+%zx\n",
|
||||
&res.start, mem_size);
|
||||
return PTR_ERR(mem_region);
|
||||
}
|
||||
|
||||
|
||||
@@ -637,31 +637,6 @@ u32 ath12k_core_get_max_peers_per_radio(struct ath12k_base *ab)
|
||||
}
|
||||
EXPORT_SYMBOL(ath12k_core_get_max_peers_per_radio);
|
||||
|
||||
struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab,
|
||||
int index)
|
||||
{
|
||||
struct device *dev = ab->dev;
|
||||
struct reserved_mem *rmem;
|
||||
struct device_node *node;
|
||||
|
||||
node = of_parse_phandle(dev->of_node, "memory-region", index);
|
||||
if (!node) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"failed to parse memory-region for index %d\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rmem = of_reserved_mem_lookup(node);
|
||||
of_node_put(node);
|
||||
if (!rmem) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_BOOT,
|
||||
"unable to get memory-region for index %d\n", index);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rmem;
|
||||
}
|
||||
|
||||
static inline
|
||||
void ath12k_core_to_group_ref_get(struct ath12k_base *ab)
|
||||
{
|
||||
|
||||
@@ -1295,8 +1295,6 @@ void ath12k_fw_stats_init(struct ath12k *ar);
|
||||
void ath12k_fw_stats_bcn_free(struct list_head *head);
|
||||
void ath12k_fw_stats_free(struct ath12k_fw_stats *stats);
|
||||
void ath12k_fw_stats_reset(struct ath12k *ar);
|
||||
struct reserved_mem *ath12k_core_get_reserved_mem(struct ath12k_base *ab,
|
||||
int index);
|
||||
enum ath12k_qmi_mem_mode ath12k_core_get_memory_mode(struct ath12k_base *ab);
|
||||
|
||||
static inline const char *ath12k_scan_state_str(enum ath12k_scan_state state)
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/of_reserved_mem.h>
|
||||
|
||||
#define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02
|
||||
#define HOST_CSTATE_BIT 0x04
|
||||
@@ -2778,20 +2779,20 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
|
||||
|
||||
static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
{
|
||||
struct reserved_mem *rmem;
|
||||
struct device_node *np = ab->dev->of_node;
|
||||
size_t avail_rmem_size;
|
||||
struct resource res;
|
||||
int i, idx, ret;
|
||||
|
||||
for (i = 0, idx = 0; i < ab->qmi.mem_seg_count; i++) {
|
||||
switch (ab->qmi.target_mem[i].type) {
|
||||
case HOST_DDR_REGION_TYPE:
|
||||
rmem = ath12k_core_get_reserved_mem(ab, 0);
|
||||
if (!rmem) {
|
||||
ret = -ENODEV;
|
||||
ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
|
||||
&res);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
avail_rmem_size = rmem->size;
|
||||
avail_rmem_size = resource_size(&res);
|
||||
if (avail_rmem_size < ab->qmi.target_mem[i].size) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"failed to assign mem type %u req size %u avail size %zu\n",
|
||||
@@ -2802,7 +2803,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ab->qmi.target_mem[idx].paddr = rmem->base;
|
||||
ab->qmi.target_mem[idx].paddr = res.start;
|
||||
ab->qmi.target_mem[idx].v.ioaddr =
|
||||
ioremap(ab->qmi.target_mem[idx].paddr,
|
||||
ab->qmi.target_mem[i].size);
|
||||
@@ -2815,13 +2816,13 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
idx++;
|
||||
break;
|
||||
case BDF_MEM_REGION_TYPE:
|
||||
rmem = ath12k_core_get_reserved_mem(ab, 0);
|
||||
if (!rmem) {
|
||||
ret = -ENODEV;
|
||||
ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
|
||||
&res);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
avail_rmem_size = rmem->size - ab->hw_params->bdf_addr_offset;
|
||||
avail_rmem_size = resource_size(&res) -
|
||||
ab->hw_params->bdf_addr_offset;
|
||||
if (avail_rmem_size < ab->qmi.target_mem[i].size) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"failed to assign mem type %u req size %u avail size %zu\n",
|
||||
@@ -2832,7 +2833,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
goto out;
|
||||
}
|
||||
ab->qmi.target_mem[idx].paddr =
|
||||
rmem->base + ab->hw_params->bdf_addr_offset;
|
||||
res.start + ab->hw_params->bdf_addr_offset;
|
||||
ab->qmi.target_mem[idx].v.ioaddr =
|
||||
ioremap(ab->qmi.target_mem[idx].paddr,
|
||||
ab->qmi.target_mem[i].size);
|
||||
@@ -2857,13 +2858,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
idx++;
|
||||
break;
|
||||
case M3_DUMP_REGION_TYPE:
|
||||
rmem = ath12k_core_get_reserved_mem(ab, 1);
|
||||
if (!rmem) {
|
||||
ret = -EINVAL;
|
||||
ret = of_reserved_mem_region_to_resource_byname(np, "m3-dump",
|
||||
&res);
|
||||
if (ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
avail_rmem_size = rmem->size;
|
||||
avail_rmem_size = resource_size(&res);
|
||||
if (avail_rmem_size < ab->qmi.target_mem[i].size) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_QMI,
|
||||
"failed to assign mem type %u req size %u avail size %zu\n",
|
||||
@@ -2874,7 +2874,7 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ab->qmi.target_mem[idx].paddr = rmem->base;
|
||||
ab->qmi.target_mem[idx].paddr = res.start;
|
||||
ab->qmi.target_mem[idx].v.ioaddr =
|
||||
ioremap(ab->qmi.target_mem[idx].paddr,
|
||||
ab->qmi.target_mem[i].size);
|
||||
|
||||
Reference in New Issue
Block a user