Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling
@ 2026-06-11  3:33 Aaradhana Sahu
  2026-06-11  3:33 ` [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup Aaradhana Sahu
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-11  3:33 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

The current implementation relies on index-based device tree reserved
memory lookup. Different platform variants define reserved memory
regions in different orders and combinations, making the index-based
lookup fragile across platforms.

Currently, the driver allocates the HOST_DDR_REGION_TYPE
starting from the base of the Q6 region, which overlaps the Q6 read-only
firmware section. This causes firmware assertions during QMI memory
allocation, as the firmware expects writable regions to be placed after the
read-only section.

Address these issues by:
- switching to name-based reserved memory lookup to remove dependency on
  device tree node ordering,
- refactoring QMI memory assignment logic to reduce code duplication and
  improve maintainability,
- placing HOST_DDR and BDF regions after the Q6 read-only firmware section
  using the bdf_addr_offset parameter.

This series ensure correct reserved memory handling across different
platform variants, prevent overlapping memory allocations, and maintain
backward compatibility by reusing existing reserved memory region names
defined in device tree bindings.

Overview:
  - Patch [1/3] switches to name-based reserved memory lookup for platform
    compatibility.
  - Patch [2/3] refactors QMI memory assignment to eliminate code
    duplication.
  - Patch [3/3] fixes memory allocation to place HOST_DDR and BDF regions
    after Q6 read-only section.

Aaradhana Sahu (3):
  wifi: ath12k: switch to name-based reserved memory lookup
  wifi: ath12k: refactor QMI memory assignment
  wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region

 drivers/net/wireless/ath/ath12k/ahb.c  |  18 +--
 drivers/net/wireless/ath/ath12k/core.c |  25 ----
 drivers/net/wireless/ath/ath12k/core.h |   2 -
 drivers/net/wireless/ath/ath12k/qmi.c  | 168 ++++++++++---------------
 4 files changed, 78 insertions(+), 135 deletions(-)


base-commit: 83f028be15fe071efbee8e27837538d6cca77e87
-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup
  2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
@ 2026-06-11  3:33 ` Aaradhana Sahu
  2026-06-30  0:30   ` Jeff Johnson
  2026-06-11  3:33 ` [PATCH ath-next 2/3] wifi: ath12k: refactor QMI memory assignment Aaradhana Sahu
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-11  3:33 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

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

Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/ahb.c  | 18 ++++++------
 drivers/net/wireless/ath/ath12k/core.c | 25 -----------------
 drivers/net/wireless/ath/ath12k/core.h |  2 --
 drivers/net/wireless/ath/ath12k/qmi.c  | 38 +++++++++++++-------------
 4 files changed, 29 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 30733a244454..695b605a92fd 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -15,6 +15,7 @@
 #include "ahb.h"
 #include "debug.h"
 #include "hif.h"
+#include <linux/of_reserved_mem.h>
 
 #define ATH12K_IRQ_CE0_OFFSET 4
 #define ATH12K_MAX_UPDS 1
@@ -338,24 +339,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);
 	}
 
diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c
index 742d4fd1b598..617d039b9237 100644
--- a/drivers/net/wireless/ath/ath12k/core.c
+++ b/drivers/net/wireless/ath/ath12k/core.c
@@ -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)
 {
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index fc5127b5c1a3..ba2f617d8e5f 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -1294,8 +1294,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)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..0176d6a4bf8c 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -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
@@ -2727,20 +2728,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",
@@ -2751,7 +2752,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);
@@ -2764,13 +2765,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",
@@ -2781,7 +2782,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);
@@ -2806,13 +2807,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",
@@ -2823,7 +2823,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);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH ath-next 2/3] wifi: ath12k: refactor QMI memory assignment
  2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
  2026-06-11  3:33 ` [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup Aaradhana Sahu
@ 2026-06-11  3:33 ` Aaradhana Sahu
  2026-06-11  3:33 ` [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region Aaradhana Sahu
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-11  3:33 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

ath12k_qmi_assign_target_mem_chunk() uses a large switch-case to handle
both memory region identification and allocation for each memory request
type, leading to redundant allocation logic.

Refactor this by introducing ath12k_qmi_get_mem_reg_name() to map memory
request types to their corresponding reserved memory region names.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/qmi.c | 157 ++++++++++----------------
 1 file changed, 61 insertions(+), 96 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 0176d6a4bf8c..5bf045971c94 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -2726,120 +2726,85 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
 	return ret;
 }
 
+static const char *ath12k_qmi_get_mem_reg_name(int mem_type)
+{
+	switch (mem_type) {
+	case HOST_DDR_REGION_TYPE:
+	case BDF_MEM_REGION_TYPE:
+		return "q6-region";
+	case M3_DUMP_REGION_TYPE:
+		return "m3-dump";
+	case CALDB_MEM_REGION_TYPE:
+		return "q6-caldb";
+	case MLO_GLOBAL_MEM_REGION_TYPE:
+		return "mlo-global-mem";
+	default:
+		return NULL;
+	}
+}
+
 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 {
 	struct device_node *np = ab->dev->of_node;
+	struct target_mem_chunk *chunk;
 	size_t avail_rmem_size;
 	struct resource res;
+	const char *rname;
 	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:
-			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
-									&res);
-			if (ret)
-				goto out;
-
-			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",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
-
-			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);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		case BDF_MEM_REGION_TYPE:
-			ret = of_reserved_mem_region_to_resource_byname(np, "q6-region",
-									&res);
-			if (ret)
-				goto out;
-
-			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",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].paddr =
-				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);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		case CALDB_MEM_REGION_TYPE:
-			/* Cold boot calibration is not enabled in Ath12k. Hence,
+		chunk = &ab->qmi.target_mem[i];
+		if (chunk->type == CALDB_MEM_REGION_TYPE) {
+			/*
+			 * Cold boot calibration is not enabled in Ath12k. Hence,
 			 * assign paddr = 0.
 			 * Once cold boot calibration is enabled add support to
 			 * assign reserved memory from DT.
 			 */
 			ab->qmi.target_mem[idx].paddr = 0;
 			ab->qmi.target_mem[idx].v.ioaddr = NULL;
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
+			ab->qmi.target_mem[idx].size = chunk->size;
+			ab->qmi.target_mem[idx].type = chunk->type;
 			idx++;
-			break;
-		case M3_DUMP_REGION_TYPE:
-			ret = of_reserved_mem_region_to_resource_byname(np, "m3-dump",
-									&res);
-			if (ret)
-				goto out;
-
-			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",
-					   ab->qmi.target_mem[i].type,
-					   ab->qmi.target_mem[i].size,
-					   avail_rmem_size);
-				ret = -EINVAL;
-				goto out;
-			}
+			continue;
+		}
 
-			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);
-			if (!ab->qmi.target_mem[idx].v.ioaddr) {
-				ret = -EIO;
-				goto out;
-			}
-			ab->qmi.target_mem[idx].size = ab->qmi.target_mem[i].size;
-			ab->qmi.target_mem[idx].type = ab->qmi.target_mem[i].type;
-			idx++;
-			break;
-		default:
+		rname = ath12k_qmi_get_mem_reg_name(chunk->type);
+		if (!rname) {
 			ath12k_warn(ab, "qmi ignore invalid mem req type %u\n",
-				    ab->qmi.target_mem[i].type);
-			break;
+				    chunk->type);
+			continue;
+		}
+
+		ret = of_reserved_mem_region_to_resource_byname(np, rname, &res);
+		if (ret)
+			goto out;
+
+		avail_rmem_size = resource_size(&res);
+		if (chunk->type == BDF_MEM_REGION_TYPE) {
+			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
+			res.start += ab->hw_params->bdf_addr_offset;
 		}
+
+		if (avail_rmem_size < chunk->size) {
+			ath12k_dbg(ab, ATH12K_DBG_QMI,
+				   "failed to assign mem type %u req size %u avail size %zu\n",
+				   chunk->type, chunk->size, avail_rmem_size);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		ab->qmi.target_mem[idx].paddr = res.start;
+		ab->qmi.target_mem[idx].v.ioaddr = ioremap(ab->qmi.target_mem[idx].paddr,
+							   chunk->size);
+		if (!ab->qmi.target_mem[idx].v.ioaddr) {
+			ret = -EIO;
+			goto out;
+		}
+
+		ab->qmi.target_mem[idx].size = chunk->size;
+		ab->qmi.target_mem[idx].type = chunk->type;
+		idx++;
 	}
 	ab->qmi.mem_seg_count = idx;
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
  2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
  2026-06-11  3:33 ` [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup Aaradhana Sahu
  2026-06-11  3:33 ` [PATCH ath-next 2/3] wifi: ath12k: refactor QMI memory assignment Aaradhana Sahu
@ 2026-06-11  3:33 ` Aaradhana Sahu
  2026-06-30  0:36   ` Jeff Johnson
  2026-06-29  2:15 ` [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Baochen Qiang
  2026-06-29  6:30 ` Rameshkumar Sundaram
  4 siblings, 1 reply; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-11  3:33 UTC (permalink / raw)
  To: ath12k; +Cc: linux-wireless, Aaradhana Sahu

Currently, the Q6 region contains a read-only firmware region along with
the BDF_MEM_REGION_TYPE and HOST_DDR_REGION_TYPE memory areas. The firmware
expects these writable memory regions to be assigned after the Q6 read-only
section.

However, the ath12k driver currently allocates the HOST_DDR_REGION_TYPE
starting from the base of the Q6 region, which includes the read-only
firmware area. As a result, the allocated memory regions overlap with the
read-only section, causing the firmware to assert during QMI memory
allocation. The Q6 memory region layout is as follows:

		Q6 Reserved Memory
	+--------------------------------------+
	|                                      |
	|  Read-only Firmware Region           |
	|  (Q6 RO Region)                      |
	|                                      |
	+--------------------------------------+ <--- bdf_addr_offset
	|  Writable Memory Region              |
	|  (BDF + HOST_DDR allocations)        |
	|                                      |
	+--------------------------------------+

Fix this by allocating the required memory regions only after the end of
the read-only region in the Q6 address space. The bdf_addr_offset parameter
indicates where the writable region starts. Both HOST_DDR and BDF regions
are allocated sequentially after this offset, with each region placed
immediately after the previous one to avoid gaps and overlaps.

Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1

Fixes: 6757079c5890 ("wifi: ath12k: add support for fixed QMI firmware memory")
Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
---
 drivers/net/wireless/ath/ath12k/qmi.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index 5bf045971c94..11f57b0755ea 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -2746,8 +2746,8 @@ static const char *ath12k_qmi_get_mem_reg_name(int mem_type)
 static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 {
 	struct device_node *np = ab->dev->of_node;
+	size_t avail_rmem_size, offset = 0;
 	struct target_mem_chunk *chunk;
-	size_t avail_rmem_size;
 	struct resource res;
 	const char *rname;
 	int i, idx, ret;
@@ -2781,9 +2781,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
 			goto out;
 
 		avail_rmem_size = resource_size(&res);
-		if (chunk->type == BDF_MEM_REGION_TYPE) {
+		if (chunk->type == BDF_MEM_REGION_TYPE ||
+		    chunk->type == HOST_DDR_REGION_TYPE) {
 			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
-			res.start += ab->hw_params->bdf_addr_offset;
+			avail_rmem_size -= offset;
+			res.start += ab->hw_params->bdf_addr_offset + offset;
+			offset += chunk->size;
 		}
 
 		if (avail_rmem_size < chunk->size) {
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling
  2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
                   ` (2 preceding siblings ...)
  2026-06-11  3:33 ` [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region Aaradhana Sahu
@ 2026-06-29  2:15 ` Baochen Qiang
  2026-06-29  6:30 ` Rameshkumar Sundaram
  4 siblings, 0 replies; 10+ messages in thread
From: Baochen Qiang @ 2026-06-29  2:15 UTC (permalink / raw)
  To: Aaradhana Sahu, ath12k; +Cc: linux-wireless



On 6/11/2026 11:33 AM, Aaradhana Sahu wrote:
> The current implementation relies on index-based device tree reserved
> memory lookup. Different platform variants define reserved memory
> regions in different orders and combinations, making the index-based
> lookup fragile across platforms.
> 
> Currently, the driver allocates the HOST_DDR_REGION_TYPE
> starting from the base of the Q6 region, which overlaps the Q6 read-only
> firmware section. This causes firmware assertions during QMI memory
> allocation, as the firmware expects writable regions to be placed after the
> read-only section.
> 
> Address these issues by:
> - switching to name-based reserved memory lookup to remove dependency on
>   device tree node ordering,
> - refactoring QMI memory assignment logic to reduce code duplication and
>   improve maintainability,
> - placing HOST_DDR and BDF regions after the Q6 read-only firmware section
>   using the bdf_addr_offset parameter.
> 
> This series ensure correct reserved memory handling across different
> platform variants, prevent overlapping memory allocations, and maintain
> backward compatibility by reusing existing reserved memory region names
> defined in device tree bindings.
> 
> Overview:
>   - Patch [1/3] switches to name-based reserved memory lookup for platform
>     compatibility.
>   - Patch [2/3] refactors QMI memory assignment to eliminate code
>     duplication.
>   - Patch [3/3] fixes memory allocation to place HOST_DDR and BDF regions
>     after Q6 read-only section.
> 
> Aaradhana Sahu (3):
>   wifi: ath12k: switch to name-based reserved memory lookup
>   wifi: ath12k: refactor QMI memory assignment
>   wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
> 
>  drivers/net/wireless/ath/ath12k/ahb.c  |  18 +--
>  drivers/net/wireless/ath/ath12k/core.c |  25 ----
>  drivers/net/wireless/ath/ath12k/core.h |   2 -
>  drivers/net/wireless/ath/ath12k/qmi.c  | 168 ++++++++++---------------
>  4 files changed, 78 insertions(+), 135 deletions(-)
> 
> 
> base-commit: 83f028be15fe071efbee8e27837538d6cca77e87

Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling
  2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
                   ` (3 preceding siblings ...)
  2026-06-29  2:15 ` [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Baochen Qiang
@ 2026-06-29  6:30 ` Rameshkumar Sundaram
  4 siblings, 0 replies; 10+ messages in thread
From: Rameshkumar Sundaram @ 2026-06-29  6:30 UTC (permalink / raw)
  To: Aaradhana Sahu, ath12k; +Cc: linux-wireless

On 6/11/2026 9:03 AM, Aaradhana Sahu wrote:
> The current implementation relies on index-based device tree reserved
> memory lookup. Different platform variants define reserved memory
> regions in different orders and combinations, making the index-based
> lookup fragile across platforms.
> 
> Currently, the driver allocates the HOST_DDR_REGION_TYPE
> starting from the base of the Q6 region, which overlaps the Q6 read-only
> firmware section. This causes firmware assertions during QMI memory
> allocation, as the firmware expects writable regions to be placed after the
> read-only section.
> 
> Address these issues by:
> - switching to name-based reserved memory lookup to remove dependency on
>    device tree node ordering,
> - refactoring QMI memory assignment logic to reduce code duplication and
>    improve maintainability,
> - placing HOST_DDR and BDF regions after the Q6 read-only firmware section
>    using the bdf_addr_offset parameter.
> 
> This series ensure correct reserved memory handling across different
> platform variants, prevent overlapping memory allocations, and maintain
> backward compatibility by reusing existing reserved memory region names
> defined in device tree bindings.
> 
> Overview:
>    - Patch [1/3] switches to name-based reserved memory lookup for platform
>      compatibility.
>    - Patch [2/3] refactors QMI memory assignment to eliminate code
>      duplication.
>    - Patch [3/3] fixes memory allocation to place HOST_DDR and BDF regions
>      after Q6 read-only section.
> 
> Aaradhana Sahu (3):
>    wifi: ath12k: switch to name-based reserved memory lookup
>    wifi: ath12k: refactor QMI memory assignment
>    wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
> 
>   drivers/net/wireless/ath/ath12k/ahb.c  |  18 +--
>   drivers/net/wireless/ath/ath12k/core.c |  25 ----
>   drivers/net/wireless/ath/ath12k/core.h |   2 -
>   drivers/net/wireless/ath/ath12k/qmi.c  | 168 ++++++++++---------------
>   4 files changed, 78 insertions(+), 135 deletions(-)
> 
> 
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup
  2026-06-11  3:33 ` [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup Aaradhana Sahu
@ 2026-06-30  0:30   ` Jeff Johnson
  2026-06-30  5:42     ` Aaradhana Sahu
  0 siblings, 1 reply; 10+ messages in thread
From: Jeff Johnson @ 2026-06-30  0:30 UTC (permalink / raw)
  To: Aaradhana Sahu, ath12k; +Cc: linux-wireless

On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
> 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
> 
> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
> ---
>  drivers/net/wireless/ath/ath12k/ahb.c  | 18 ++++++------
>  drivers/net/wireless/ath/ath12k/core.c | 25 -----------------
>  drivers/net/wireless/ath/ath12k/core.h |  2 --
>  drivers/net/wireless/ath/ath12k/qmi.c  | 38 +++++++++++++-------------
>  4 files changed, 29 insertions(+), 54 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
> index 30733a244454..695b605a92fd 100644
> --- a/drivers/net/wireless/ath/ath12k/ahb.c
> +++ b/drivers/net/wireless/ath/ath12k/ahb.c
> @@ -15,6 +15,7 @@
>  #include "ahb.h"
>  #include "debug.h"
>  #include "hif.h"
> +#include <linux/of_reserved_mem.h>

system includes should come before the local includes. I'd fix this in my tree
except there is another issue in the 3/3 patch so I'll want a v2 for the
entire series.


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
  2026-06-11  3:33 ` [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region Aaradhana Sahu
@ 2026-06-30  0:36   ` Jeff Johnson
  2026-06-30  5:30     ` Aaradhana Sahu
  0 siblings, 1 reply; 10+ messages in thread
From: Jeff Johnson @ 2026-06-30  0:36 UTC (permalink / raw)
  To: Aaradhana Sahu, ath12k; +Cc: linux-wireless

On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
> @@ -2781,9 +2781,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
>  			goto out;
>  
>  		avail_rmem_size = resource_size(&res);
> -		if (chunk->type == BDF_MEM_REGION_TYPE) {
> +		if (chunk->type == BDF_MEM_REGION_TYPE ||
> +		    chunk->type == HOST_DDR_REGION_TYPE) {
>  			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
> -			res.start += ab->hw_params->bdf_addr_offset;
> +			avail_rmem_size -= offset;
> +			res.start += ab->hw_params->bdf_addr_offset + offset;
> +			offset += chunk->size;

avail_rmem_size is size_t (unsigned).
If bdf_addr_offset + offset >= resource_size(&res) (e.g., DT
misconfiguration), the subtraction silently wraps to a huge value, the
avail_rmem_size < chunk->size guard passes incorrectly, and ioremap proceeds
out-of-bounds.

So seems there should be a test to sanitize the DT values.

>  		}
>  
>  		if (avail_rmem_size < chunk->size) {


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region
  2026-06-30  0:36   ` Jeff Johnson
@ 2026-06-30  5:30     ` Aaradhana Sahu
  0 siblings, 0 replies; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-30  5:30 UTC (permalink / raw)
  To: Jeff Johnson, ath12k; +Cc: linux-wireless



On 6/30/2026 6:06 AM, Jeff Johnson wrote:
> On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
>> @@ -2781,9 +2781,12 @@ static int ath12k_qmi_assign_target_mem_chunk(struct ath12k_base *ab)
>>  			goto out;
>>  
>>  		avail_rmem_size = resource_size(&res);
>> -		if (chunk->type == BDF_MEM_REGION_TYPE) {
>> +		if (chunk->type == BDF_MEM_REGION_TYPE ||
>> +		    chunk->type == HOST_DDR_REGION_TYPE) {
>>  			avail_rmem_size -= ab->hw_params->bdf_addr_offset;
>> -			res.start += ab->hw_params->bdf_addr_offset;
>> +			avail_rmem_size -= offset;
>> +			res.start += ab->hw_params->bdf_addr_offset + offset;
>> +			offset += chunk->size;
> 
> avail_rmem_size is size_t (unsigned).
> If bdf_addr_offset + offset >= resource_size(&res) (e.g., DT
> misconfiguration), the subtraction silently wraps to a huge value, the
> avail_rmem_size < chunk->size guard passes incorrectly, and ioremap proceeds
> out-of-bounds.
> 
> So seems there should be a test to sanitize the DT values.
> 

Sure, I will address this in the next version.

>>  		}
>>  
>>  		if (avail_rmem_size < chunk->size) {
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup
  2026-06-30  0:30   ` Jeff Johnson
@ 2026-06-30  5:42     ` Aaradhana Sahu
  0 siblings, 0 replies; 10+ messages in thread
From: Aaradhana Sahu @ 2026-06-30  5:42 UTC (permalink / raw)
  To: Jeff Johnson, ath12k; +Cc: linux-wireless



On 6/30/2026 6:00 AM, Jeff Johnson wrote:
> On 6/10/2026 8:33 PM, Aaradhana Sahu wrote:
>> 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
>>
>> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
>> ---
>>  drivers/net/wireless/ath/ath12k/ahb.c  | 18 ++++++------
>>  drivers/net/wireless/ath/ath12k/core.c | 25 -----------------
>>  drivers/net/wireless/ath/ath12k/core.h |  2 --
>>  drivers/net/wireless/ath/ath12k/qmi.c  | 38 +++++++++++++-------------
>>  4 files changed, 29 insertions(+), 54 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
>> index 30733a244454..695b605a92fd 100644
>> --- a/drivers/net/wireless/ath/ath12k/ahb.c
>> +++ b/drivers/net/wireless/ath/ath12k/ahb.c
>> @@ -15,6 +15,7 @@
>>  #include "ahb.h"
>>  #include "debug.h"
>>  #include "hif.h"
>> +#include <linux/of_reserved_mem.h>
> 
> system includes should come before the local includes. I'd fix this in my tree
> except there is another issue in the 3/3 patch so I'll want a v2 for the
> entire series.
> 

Sure, I will fix this and the 3/3 patch review comments and send the next version
of the series. 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-06-30  5:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-11  3:33 [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Aaradhana Sahu
2026-06-11  3:33 ` [PATCH ath-next 1/3] wifi: ath12k: switch to name-based reserved memory lookup Aaradhana Sahu
2026-06-30  0:30   ` Jeff Johnson
2026-06-30  5:42     ` Aaradhana Sahu
2026-06-11  3:33 ` [PATCH ath-next 2/3] wifi: ath12k: refactor QMI memory assignment Aaradhana Sahu
2026-06-11  3:33 ` [PATCH ath-next 3/3] wifi: ath12k: allocate HOST_DDR and BDF regions after Q6 RO region Aaradhana Sahu
2026-06-30  0:36   ` Jeff Johnson
2026-06-30  5:30     ` Aaradhana Sahu
2026-06-29  2:15 ` [PATCH ath-next 0/3] wifi: ath12k: Fix memory allocation and improve reserved memory handling Baochen Qiang
2026-06-29  6:30 ` Rameshkumar Sundaram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox