* [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD
@ 2026-08-11 5:43 Aaradhana Sahu
2026-08-11 9:08 ` Vasanthakumar Thiagarajan
2026-08-12 2:03 ` Baochen Qiang
0 siblings, 2 replies; 4+ messages in thread
From: Aaradhana Sahu @ 2026-08-11 5:43 UTC (permalink / raw)
To: ath12k
Cc: linux-wireless, jjohnson, quic_kiranv, baochen.qiang,
vasanthakumar.thiagarajan, Aaradhana Sahu
IPQ5332 platform uses a MultiPD architecture where multiple firmware
instances share common read-only code segments. The driver currently
loads only the per-UserPD firmware, which leaves the shared read-only
firmware unloaded.
Add support for loading the shared read-only firmware once before the
UserPDs are powered up. The shared segment contains common code that is
identical across all UserPDs and reduces the total firmware memory
requirement.
Store the reserved memory mapping in struct ath12k_ahb_rproc_info so it can
be shared by all UserPDs and mapped only once. Keep the mapping valid
across UserPD power cycles, and unmap it when the last UserPD is removed.
Shut down the shared firmware from the rproc deconfiguration path when the
last UserPD is removed.
Also, pass NULL for the reloc_base parameter because the driver uses fixed
memory regions configured through device tree and does not need the
adjusted physical address after relocation.
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 | 166 +++++++++++++++++---
drivers/net/wireless/ath/ath12k/ahb.h | 9 ++
drivers/net/wireless/ath/ath12k/wifi7/ahb.c | 3 +
3 files changed, 157 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 0fc55c9169e1..3985f4e1c067 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -347,35 +347,60 @@ static void ath12k_ahb_stop(struct ath12k_base *ab)
ath12k_ce_cleanup_pipes(ab);
}
+static int ath12k_ahb_get_fw_load_region(struct ath12k_base *ab)
+{
+ struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
+ struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
+ struct device *dev = ab->dev;
+ struct resource res;
+ int ret;
+
+ if (rproc_info->mem_region)
+ return 0;
+
+ ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region", &res);
+ if (ret)
+ return ret;
+
+ rproc_info->mem_phys = res.start;
+ rproc_info->mem_size = resource_size(&res);
+ rproc_info->mem_region = memremap(rproc_info->mem_phys, rproc_info->mem_size,
+ MEMREMAP_WC);
+ if (!rproc_info->mem_region) {
+ ath12k_err(ab, "unable to map memory region: %pa+%zx\n",
+ &res.start, rproc_info->mem_size);
+ rproc_info->mem_phys = 0;
+ rproc_info->mem_size = 0;
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+static void ath12k_ahb_put_fw_load_region(struct ath12k_ahb_rproc_info *rproc_info)
+{
+ memunmap(rproc_info->mem_region);
+ rproc_info->mem_region = NULL;
+ rproc_info->mem_phys = 0;
+ rproc_info->mem_size = 0;
+}
+
static int ath12k_ahb_power_up(struct ath12k_base *ab)
{
struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
+ struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
char fw_name[ATH12K_USERPD_FW_NAME_LEN];
char fw2_name[ATH12K_USERPD_FW_NAME_LEN];
struct device *dev = ab->dev;
const struct firmware *fw, *fw2;
unsigned long time_left;
- phys_addr_t mem_phys;
- struct resource res;
- void *mem_region;
- size_t mem_size;
u32 pasid;
int ret;
- ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region",
- &res);
+ ret = ath12k_ahb_get_fw_load_region(ab);
if (ret)
return ret;
- 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+%zx\n",
- &res.start, mem_size);
- return PTR_ERR(mem_region);
- }
-
snprintf(fw_name, sizeof(fw_name), "%s/%s/%s%d%s", ATH12K_FW_DIR,
ab->hw_params->fw.dir, ATH12K_AHB_FW_PREFIX, ab_ahb->userpd_id,
ATH12K_AHB_FW_SUFFIX);
@@ -400,11 +425,13 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
/* Load FW image to a reserved memory location */
if (ab_ahb->scm_auth_enabled)
- ret = qcom_mdt_load(dev, fw, fw_name, pasid, mem_region,
- mem_phys, mem_size, &mem_phys);
+ ret = qcom_mdt_load(dev, fw, fw_name, pasid, rproc_info->mem_region,
+ rproc_info->mem_phys, rproc_info->mem_size,
+ NULL);
else
- ret = qcom_mdt_load_no_init(dev, fw, fw_name, mem_region,
- mem_phys, mem_size, &mem_phys);
+ ret = qcom_mdt_load_no_init(dev, fw, fw_name, rproc_info->mem_region,
+ rproc_info->mem_phys, rproc_info->mem_size,
+ NULL);
if (ret) {
ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
goto err_fw;
@@ -428,8 +455,9 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
goto err_fw2;
}
- ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, mem_region, mem_phys,
- mem_size, &mem_phys);
+ ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, rproc_info->mem_region,
+ rproc_info->mem_phys, rproc_info->mem_size,
+ NULL);
if (ret) {
ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
goto err_fw2;
@@ -877,6 +905,7 @@ static struct ath12k_ahb_rproc_info *ath12k_ahb_rproc_info_alloc(struct ath12k_b
rproc_info->rootpd_booted_by_driver = false;
rproc_info->userpd[ab_ahb->userpd_id - 1] = ab_ahb;
rproc_info->num_userpd = 1;
+ rproc_info->shared_fw_loaded = false;
init_completion(&rproc_info->rootpd_ready);
ab_ahb->rproc_info = rproc_info;
@@ -961,6 +990,76 @@ static int ath12k_ahb_boot_root_pd(struct ath12k_base *ab)
return 0;
}
+static int ath12k_ahb_load_auth_shared_fw(struct ath12k_base *ab,
+ struct ath12k_ahb_rproc_info *rproc_info,
+ const char *fw_name, u32 pasid)
+{
+ int ret;
+
+ const struct firmware *fw __free(firmware) = NULL;
+ ret = request_firmware(&fw, fw_name, ab->dev);
+ if (ret) {
+ ath12k_err(ab, "failed to request shared firmware %s: %d\n",
+ fw_name, ret);
+ return ret;
+ }
+
+ if (!fw->size) {
+ ath12k_err(ab, "Invalid firmware size\n");
+ return -EINVAL;
+ }
+
+ ath12k_dbg(ab, ATH12K_DBG_AHB, "loading firmware %s, size %zd\n", fw_name,
+ fw->size);
+
+ ret = qcom_mdt_load(ab->dev, fw, fw_name, pasid, rproc_info->mem_region,
+ rproc_info->mem_phys, rproc_info->mem_size, NULL);
+ if (ret) {
+ ath12k_err(ab, "failed to load RO firmware %s: %d\n", fw_name, ret);
+ return ret;
+ }
+
+ ret = qcom_pas_auth_and_reset(pasid);
+ if (ret)
+ ath12k_err(ab, "failed to authenticate and boot shared firmware: %d\n",
+ ret);
+ return ret;
+}
+
+static int ath12k_ahb_load_shared_firmware(struct ath12k_base *ab)
+{
+ struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
+ struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
+ char fw_name[ATH12K_USERPD_FW_NAME_LEN];
+ u32 pasid;
+ int ret;
+
+ lockdep_assert_held(&ath12k_rproc_info_lock);
+
+ if (!ab_ahb->supports_multipd)
+ return 0;
+
+ ret = ath12k_ahb_get_fw_load_region(ab);
+ if (ret)
+ return ret;
+
+ snprintf(fw_name, sizeof(fw_name), "%s/%s/%s%d%s", ATH12K_FW_DIR,
+ ab->hw_params->fw.dir, ATH12K_AHB_FW_PREFIX, ATH12K_AHB_RO_ID,
+ ATH12K_AHB_FW_SUFFIX);
+
+ pasid = u32_encode_bits(ATH12K_AHB_RO_ID, ATH12K_USERPD_ID_MASK) |
+ ATH12K_AHB_UPD_SWID;
+
+ ret = ath12k_ahb_load_auth_shared_fw(ab, rproc_info, fw_name, pasid);
+ if (ret) {
+ ath12k_ahb_put_fw_load_region(rproc_info);
+ return ret;
+ }
+
+ rproc_info->shared_fw_loaded = true;
+ return 0;
+}
+
static int ath12k_ahb_configure_rproc(struct ath12k_base *ab)
{
int ret;
@@ -989,6 +1088,15 @@ static int ath12k_ahb_configure_rproc(struct ath12k_base *ab)
g_rproc_info->rootpd_booted_by_driver = true;
}
+ if (!g_rproc_info->shared_fw_loaded) {
+ ret = ath12k_ahb_load_shared_firmware(ab);
+ if (ret) {
+ if (g_rproc_info->rootpd_booted_by_driver)
+ rproc_shutdown(g_rproc_info->tgt_rproc);
+ goto err_unreg_notifier;
+ }
+ }
+
mutex_unlock(&ath12k_rproc_info_lock);
return 0;
@@ -1012,6 +1120,8 @@ static void ath12k_ahb_deconfigure_rproc(struct ath12k_base *ab)
{
struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
+ u32 pasid;
+ int ret;
lockdep_assert_held(&ath12k_rproc_info_lock);
@@ -1023,6 +1133,20 @@ static void ath12k_ahb_deconfigure_rproc(struct ath12k_base *ab)
if (!g_rproc_info->num_userpd) {
ath12k_ahb_unregister_rproc_notifier();
+ if (g_rproc_info->shared_fw_loaded) {
+ pasid = u32_encode_bits(ATH12K_AHB_RO_ID, ATH12K_USERPD_ID_MASK) |
+ ATH12K_AHB_UPD_SWID;
+ ret = qcom_pas_shutdown(pasid);
+ if (ret)
+ ath12k_err(ab, "pas shutdown failed for shared firmware: %d\n",
+ ret);
+
+ g_rproc_info->shared_fw_loaded = false;
+ }
+
+ if (g_rproc_info->mem_region)
+ ath12k_ahb_put_fw_load_region(g_rproc_info);
+
if (g_rproc_info->rootpd_booted_by_driver &&
g_rproc_info->tgt_rproc->state == RPROC_RUNNING)
rproc_shutdown(g_rproc_info->tgt_rproc);
diff --git a/drivers/net/wireless/ath/ath12k/ahb.h b/drivers/net/wireless/ath/ath12k/ahb.h
index cdb58b07338f..46a4420d41bd 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.h
+++ b/drivers/net/wireless/ath/ath12k/ahb.h
@@ -30,6 +30,9 @@
#define ATH12K_USERPD_ID_MASK GENMASK(10, 8)
#define ATH12K_USERPD_FW_NAME_LEN 35
+/* Shared read-only firmware ID, mandated by MultiPD firmware architecture */
+#define ATH12K_AHB_RO_ID 4
+
enum ath12k_ahb_userpd_id {
ATH12K_AHB_USERPD_ID_0 = 1,
ATH12K_AHB_USERPD_ID_1,
@@ -46,6 +49,7 @@ struct ath12k_ahb_desc {
enum ath12k_hw_rev hw_rev;
bool auth_enabled;
const struct ath12k_hif_ops *ops;
+ bool supports_multipd;
};
enum ath12k_ahb_smp2p_msg_id {
@@ -77,6 +81,10 @@ struct ath12k_ahb_rproc_info {
u8 num_userpd;
bool rootpd_booted_by_driver;
struct ath12k_ahb *userpd[ATH12K_MAX_DEVICES];
+ bool shared_fw_loaded;
+ phys_addr_t mem_phys;
+ size_t mem_size;
+ void *mem_region;
};
struct ath12k_ahb {
@@ -95,6 +103,7 @@ struct ath12k_ahb {
const struct ath12k_ahb_device_family_ops *device_family_ops;
bool scm_auth_enabled;
struct ath12k_ahb_rproc_info *rproc_info;
+ bool supports_multipd;
};
struct ath12k_ahb_driver {
diff --git a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c
index 98a6606ffd76..a8f5cf8cc2a6 100644
--- a/drivers/net/wireless/ath/ath12k/wifi7/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/wifi7/ahb.c
@@ -35,11 +35,13 @@ static const struct ath12k_ahb_desc ath12k_wifi7_ahb_desc[] = {
.hw_rev = ATH12K_HW_IPQ5332_HW10,
.auth_enabled = true,
.ops = &ath12k_ahb_hif_ops,
+ .supports_multipd = true,
},
[ATH12K_HW_IPQ5424_HW10] = {
.hw_rev = ATH12K_HW_IPQ5424_HW10,
.auth_enabled = false,
.ops = &ath12k_ahb_hif_ops,
+ .supports_multipd = false,
},
};
@@ -106,6 +108,7 @@ static int ath12k_wifi7_ahb_probe(struct platform_device *pdev)
ab->hw_rev = desc->hw_rev;
ab->hif.ops = desc->ops;
ab_ahb->scm_auth_enabled = desc->auth_enabled;
+ ab_ahb->supports_multipd = desc->supports_multipd;
ab_ahb->userpd_id = ath12k_wifi7_ahb_get_userpd_id(ab);
if (!ab_ahb->userpd_id)
return -EOPNOTSUPP;
base-commit: e07447e654476262558bee570f4cf456e2b32565
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD
2026-08-11 5:43 [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD Aaradhana Sahu
@ 2026-08-11 9:08 ` Vasanthakumar Thiagarajan
2026-08-12 13:57 ` Jeff Johnson
2026-08-12 2:03 ` Baochen Qiang
1 sibling, 1 reply; 4+ messages in thread
From: Vasanthakumar Thiagarajan @ 2026-08-11 9:08 UTC (permalink / raw)
To: Aaradhana Sahu, ath12k
Cc: linux-wireless, jjohnson, quic_kiranv, baochen.qiang
On 8/11/2026 11:13 AM, Aaradhana Sahu wrote:
> IPQ5332 platform uses a MultiPD architecture where multiple firmware
> instances share common read-only code segments. The driver currently
> loads only the per-UserPD firmware, which leaves the shared read-only
> firmware unloaded.
>
> Add support for loading the shared read-only firmware once before the
> UserPDs are powered up. The shared segment contains common code that is
> identical across all UserPDs and reduces the total firmware memory
> requirement.
>
> Store the reserved memory mapping in struct ath12k_ahb_rproc_info so it can
> be shared by all UserPDs and mapped only once. Keep the mapping valid
> across UserPD power cycles, and unmap it when the last UserPD is removed.
>
> Shut down the shared firmware from the rproc deconfiguration path when the
> last UserPD is removed.
>
> Also, pass NULL for the reloc_base parameter because the driver uses fixed
> memory regions configured through device tree and does not need the
> adjusted physical address after relocation.
>
> 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 | 166 +++++++++++++++++---
> drivers/net/wireless/ath/ath12k/ahb.h | 9 ++
> drivers/net/wireless/ath/ath12k/wifi7/ahb.c | 3 +
> 3 files changed, 157 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
> index 0fc55c9169e1..3985f4e1c067 100644
> --- a/drivers/net/wireless/ath/ath12k/ahb.c
> +++ b/drivers/net/wireless/ath/ath12k/ahb.c
> @@ -347,35 +347,60 @@ static void ath12k_ahb_stop(struct ath12k_base *ab)
> ath12k_ce_cleanup_pipes(ab);
> }
>
> +static int ath12k_ahb_get_fw_load_region(struct ath12k_base *ab)
> +{
> + struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
> + struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
> + struct device *dev = ab->dev;
> + struct resource res;
> + int ret;
> +
> + if (rproc_info->mem_region)
> + return 0;
> +
> + ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region", &res);
> + if (ret)
> + return ret;
> +
> + rproc_info->mem_phys = res.start;
> + rproc_info->mem_size = resource_size(&res);
> + rproc_info->mem_region = memremap(rproc_info->mem_phys, rproc_info->mem_size,
> + MEMREMAP_WC);
> + if (!rproc_info->mem_region) {
> + ath12k_err(ab, "unable to map memory region: %pa+%zx\n",
> + &res.start, rproc_info->mem_size);
> + rproc_info->mem_phys = 0;
> + rproc_info->mem_size = 0;
> + return -ENOMEM;
> + }
> +
> + return 0;
> +}
> +
> +static void ath12k_ahb_put_fw_load_region(struct ath12k_ahb_rproc_info *rproc_info)
> +{
> + memunmap(rproc_info->mem_region);
> + rproc_info->mem_region = NULL;
> + rproc_info->mem_phys = 0;
> + rproc_info->mem_size = 0;
> +}
> +
> static int ath12k_ahb_power_up(struct ath12k_base *ab)
> {
> struct ath12k_ahb *ab_ahb = ath12k_ab_to_ahb(ab);
> + struct ath12k_ahb_rproc_info *rproc_info = ab_ahb->rproc_info;
> char fw_name[ATH12K_USERPD_FW_NAME_LEN];
> char fw2_name[ATH12K_USERPD_FW_NAME_LEN];
> struct device *dev = ab->dev;
> const struct firmware *fw, *fw2;
> unsigned long time_left;
> - phys_addr_t mem_phys;
> - struct resource res;
> - void *mem_region;
> - size_t mem_size;
> u32 pasid;
> int ret;
>
> - ret = of_reserved_mem_region_to_resource_byname(dev->of_node, "q6-region",
> - &res);
> + ret = ath12k_ahb_get_fw_load_region(ab);
> if (ret)
> return ret;
>
> - 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+%zx\n",
> - &res.start, mem_size);
> - return PTR_ERR(mem_region);
> - }
> -
> snprintf(fw_name, sizeof(fw_name), "%s/%s/%s%d%s", ATH12K_FW_DIR,
> ab->hw_params->fw.dir, ATH12K_AHB_FW_PREFIX, ab_ahb->userpd_id,
> ATH12K_AHB_FW_SUFFIX);
> @@ -400,11 +425,13 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
>
> /* Load FW image to a reserved memory location */
> if (ab_ahb->scm_auth_enabled)
> - ret = qcom_mdt_load(dev, fw, fw_name, pasid, mem_region,
> - mem_phys, mem_size, &mem_phys);
> + ret = qcom_mdt_load(dev, fw, fw_name, pasid, rproc_info->mem_region,
> + rproc_info->mem_phys, rproc_info->mem_size,
> + NULL);
> else
> - ret = qcom_mdt_load_no_init(dev, fw, fw_name, mem_region,
> - mem_phys, mem_size, &mem_phys);
> + ret = qcom_mdt_load_no_init(dev, fw, fw_name, rproc_info->mem_region,
> + rproc_info->mem_phys, rproc_info->mem_size,
> + NULL);
> if (ret) {
> ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
> goto err_fw;
> @@ -428,8 +455,9 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
> goto err_fw2;
> }
>
> - ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, mem_region, mem_phys,
> - mem_size, &mem_phys);
> + ret = qcom_mdt_load_no_init(dev, fw2, fw2_name, rproc_info->mem_region,
> + rproc_info->mem_phys, rproc_info->mem_size,
> + NULL);
> if (ret) {
> ath12k_err(ab, "Failed to load MDT segments: %d\n", ret);
> goto err_fw2;
> @@ -877,6 +905,7 @@ static struct ath12k_ahb_rproc_info *ath12k_ahb_rproc_info_alloc(struct ath12k_b
> rproc_info->rootpd_booted_by_driver = false;
> rproc_info->userpd[ab_ahb->userpd_id - 1] = ab_ahb;
> rproc_info->num_userpd = 1;
> + rproc_info->shared_fw_loaded = false;
> init_completion(&rproc_info->rootpd_ready);
> ab_ahb->rproc_info = rproc_info;
>
> @@ -961,6 +990,76 @@ static int ath12k_ahb_boot_root_pd(struct ath12k_base *ab)
> return 0;
> }
>
> +static int ath12k_ahb_load_auth_shared_fw(struct ath12k_base *ab,
> + struct ath12k_ahb_rproc_info *rproc_info,
> + const char *fw_name, u32 pasid)
> +{
> + int ret;
> +
nit: move this empty line below after the declaration part.
> + const struct firmware *fw __free(firmware) = NULL;
With that nit addressed
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD
2026-08-11 5:43 [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD Aaradhana Sahu
2026-08-11 9:08 ` Vasanthakumar Thiagarajan
@ 2026-08-12 2:03 ` Baochen Qiang
1 sibling, 0 replies; 4+ messages in thread
From: Baochen Qiang @ 2026-08-12 2:03 UTC (permalink / raw)
To: Aaradhana Sahu, ath12k
Cc: linux-wireless, jjohnson, quic_kiranv, vasanthakumar.thiagarajan
On 8/11/2026 1:43 PM, Aaradhana Sahu wrote:
> IPQ5332 platform uses a MultiPD architecture where multiple firmware
> instances share common read-only code segments. The driver currently
> loads only the per-UserPD firmware, which leaves the shared read-only
> firmware unloaded.
>
> Add support for loading the shared read-only firmware once before the
> UserPDs are powered up. The shared segment contains common code that is
> identical across all UserPDs and reduces the total firmware memory
> requirement.
>
> Store the reserved memory mapping in struct ath12k_ahb_rproc_info so it can
> be shared by all UserPDs and mapped only once. Keep the mapping valid
> across UserPD power cycles, and unmap it when the last UserPD is removed.
>
> Shut down the shared firmware from the rproc deconfiguration path when the
> last UserPD is removed.
>
> Also, pass NULL for the reloc_base parameter because the driver uses fixed
> memory regions configured through device tree and does not need the
> adjusted physical address after relocation.
>
> Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
>
> Signed-off-by: Aaradhana Sahu <aaradhana.sahu@oss.qualcomm.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD
2026-08-11 9:08 ` Vasanthakumar Thiagarajan
@ 2026-08-12 13:57 ` Jeff Johnson
0 siblings, 0 replies; 4+ messages in thread
From: Jeff Johnson @ 2026-08-12 13:57 UTC (permalink / raw)
To: Vasanthakumar Thiagarajan, Aaradhana Sahu, ath12k
Cc: linux-wireless, jjohnson, quic_kiranv, baochen.qiang
On 8/11/2026 2:08 AM, Vasanthakumar Thiagarajan wrote:
> On 8/11/2026 11:13 AM, Aaradhana Sahu wrote:
>> +static int ath12k_ahb_load_auth_shared_fw(struct ath12k_base *ab,
>> + struct ath12k_ahb_rproc_info *rproc_info,
>> + const char *fw_name, u32 pasid)
>> +{
>> + int ret;
>> +
>
> nit: move this empty line below after the declaration part.
>
>> + const struct firmware *fw __free(firmware) = NULL;
Note the when using __free() the declaration should be contiguous with the
assignment, so the current format is correct. That is one exception to the
rule about having declarations separate from code.
/jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-12 13:57 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 5:43 [PATCH ath-next] wifi: ath12k: add support to load shared firmware on multiPD Aaradhana Sahu
2026-08-11 9:08 ` Vasanthakumar Thiagarajan
2026-08-12 13:57 ` Jeff Johnson
2026-08-12 2:03 ` Baochen Qiang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox