[PATCH ath-next] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
Aaradhana Sahu
aaradhana.sahu at oss.qualcomm.com
Sun May 31 20:18:50 PDT 2026
On AHB platforms, firmware operates in two modes: fixed-memory mode where
firmware uses hardcoded addresses for memory regions such as BDF and does
not request HOST_DDR memory from the host, and dynamic-memory mode where
firmware expects the host to provide memory addresses including HOST_DDR
after the Q6 read-only region and relies on host allocation for all memory
types.
Introduce QMI capability negotiation to support both modes. Add a new QMI
PHY capability flag dynamic_ddr_support which is advertised by firmware to
indicate it supports dynamic memory mode. When the host detects this
capability, set the dynamic_mem_support flag in the host capability message
to signal the host is ready to provide dynamic memory allocation. This
triggers firmware to send the HOST_DDR memory request and use the
host-provided address.
For backward compatibility, if firmware doesn't advertise
dynamic_ddr_support, the firmware continues to operate in fixed-memory mode
where firmware uses predefined addresses.
Tested-on: IPQ5332 hw1.0 AHB WLAN.WBE.1.6-01275-QCAHKSWPL_SILICONZ-1
Signed-off-by: Aaradhana Sahu <aaradhana.sahu at oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/qmi.c | 50 +++++++++++++++++++++++++--
drivers/net/wireless/ath/ath12k/qmi.h | 10 ++++--
2 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c
index fd762b5d7bb5..85406d6e6da1 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.c
+++ b/drivers/net/wireless/ath/ath12k/qmi.c
@@ -506,6 +506,24 @@ static const struct qmi_elem_info qmi_wlanfw_host_cap_req_msg_v01_ei[] = {
.offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
feature_list),
},
+ {
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x33,
+ .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
+ dynamic_mem_support_valid),
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x33,
+ .offset = offsetof(struct qmi_wlanfw_host_cap_req_msg_v01,
+ dynamic_mem_support),
+ },
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
@@ -602,6 +620,24 @@ static const struct qmi_elem_info qmi_wlanfw_phy_cap_resp_msg_v01_ei[] = {
.offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
single_chip_mlo_support),
},
+ {
+ .data_type = QMI_OPT_FLAG,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x17,
+ .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+ dynamic_ddr_support_valid),
+ },
+ {
+ .data_type = QMI_UNSIGNED_1_BYTE,
+ .elem_len = 1,
+ .elem_size = sizeof(u8),
+ .array_type = NO_ARRAY,
+ .tlv_type = 0x17,
+ .offset = offsetof(struct qmi_wlanfw_phy_cap_resp_msg_v01,
+ dynamic_ddr_support),
+ },
{
.data_type = QMI_EOTI,
.array_type = NO_ARRAY,
@@ -2248,6 +2284,11 @@ int ath12k_qmi_host_cap_send(struct ath12k_base *ab)
if (ret < 0)
goto out;
+ if (ab->qmi.dynamic_ddr_support) {
+ req.dynamic_mem_support_valid = 1;
+ req.dynamic_mem_support = 1;
+ }
+
ret = qmi_txn_init(&ab->qmi.handle, &txn,
qmi_wlanfw_host_cap_resp_msg_v01_ei, &resp);
if (ret < 0)
@@ -2319,11 +2360,14 @@ static void ath12k_qmi_phy_cap_send(struct ath12k_base *ab)
ab->qmi.num_radios = resp.num_phy;
+ if (resp.dynamic_ddr_support_valid)
+ ab->qmi.dynamic_ddr_support = resp.dynamic_ddr_support;
+
ath12k_dbg(ab, ATH12K_DBG_QMI,
- "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d\n",
+ "phy capability resp valid %d single_chip_mlo_support %d valid %d num_phy %d valid %d board_id %d dynamic_ddr_valid %d dynamic_ddr_support %d\n",
resp.single_chip_mlo_support_valid, resp.single_chip_mlo_support,
- resp.num_phy_valid, resp.num_phy,
- resp.board_id_valid, resp.board_id);
+ resp.num_phy_valid, resp.num_phy, resp.board_id_valid, resp.board_id,
+ resp.dynamic_ddr_support_valid, resp.dynamic_ddr_support);
return;
diff --git a/drivers/net/wireless/ath/ath12k/qmi.h b/drivers/net/wireless/ath/ath12k/qmi.h
index 2a63e214eb42..dbde76e5a78d 100644
--- a/drivers/net/wireless/ath/ath12k/qmi.h
+++ b/drivers/net/wireless/ath/ath12k/qmi.h
@@ -156,9 +156,10 @@ struct ath12k_qmi {
struct m3_mem_region aux_uc_mem;
unsigned int service_ins_id;
struct dev_mem_info dev_mem[ATH12K_QMI_WLFW_MAX_DEV_MEM_NUM_V01];
+ u8 dynamic_ddr_support;
};
-#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 261
+#define QMI_WLANFW_HOST_CAP_REQ_MSG_V01_MAX_LEN 265
#define QMI_WLANFW_HOST_CAP_REQ_V01 0x0034
#define QMI_WLANFW_HOST_CAP_RESP_MSG_V01_MAX_LEN 7
#define QMI_WLFW_HOST_CAP_RESP_V01 0x0034
@@ -258,7 +259,8 @@ struct qmi_wlanfw_host_cap_req_msg_v01 {
struct wlfw_host_mlo_chip_info_s_v01 mlo_chip_info[QMI_WLFW_MAX_NUM_MLO_CHIPS_V01];
u8 feature_list_valid;
u64 feature_list;
-
+ u8 dynamic_mem_support_valid;
+ u8 dynamic_mem_support;
};
struct qmi_wlanfw_host_cap_resp_msg_v01 {
@@ -267,7 +269,7 @@ struct qmi_wlanfw_host_cap_resp_msg_v01 {
#define QMI_WLANFW_PHY_CAP_REQ_MSG_V01_MAX_LEN 0
#define QMI_WLANFW_PHY_CAP_REQ_V01 0x0057
-#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN 18
+#define QMI_WLANFW_PHY_CAP_RESP_MSG_V01_MAX_LEN 22
#define QMI_WLANFW_PHY_CAP_RESP_V01 0x0057
struct qmi_wlanfw_phy_cap_req_msg_v01 {
@@ -281,6 +283,8 @@ struct qmi_wlanfw_phy_cap_resp_msg_v01 {
u32 board_id;
u8 single_chip_mlo_support_valid;
u8 single_chip_mlo_support;
+ u8 dynamic_ddr_support_valid;
+ u8 dynamic_ddr_support;
};
#define QMI_WLANFW_IND_REGISTER_REQ_MSG_V01_MAX_LEN 54
base-commit: e6b476e4ea19919b4c06ba2f5504258ab5d5d9aa
--
2.34.1
More information about the ath12k
mailing list