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:
Aaradhana Sahu
2026-06-30 11:50:46 +05:30
committed by Jeff Johnson
parent e23d90cfcb
commit 3fe59edd19
4 changed files with 29 additions and 54 deletions

View File

@@ -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);
}

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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);