[PATCH ath-next] wifi: ath12k: add QMI capability negotiation for dynamic memory mode
Rameshkumar Sundaram
rameshkumar.sundaram at oss.qualcomm.com
Thu Jun 18 02:29:13 PDT 2026
On 6/18/2026 2:22 PM, Aaradhana Sahu wrote:
>
>
> On 6/18/2026 12:18 PM, Rameshkumar Sundaram wrote:
>> On 6/1/2026 8:48 AM, Aaradhana Sahu wrote:
>>> 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
>>
>> this is not used anywhere, but since you're touching it should this be 26 ? response TLV 7, num_phy 4, board_id 7, existing single_chip_mlo_support 4, and new dynamic_ddr_support 4
>>
>>
>> --
>> Ramesh
>
> I checked the driver and found there are several unused QMI_*_RESP_MSG_LEN macros.
> Since this macro is not used anywhere, I think it is better to remove this
> change from the current patch.
> I will send a separate cleanup patch to remove all unused QMI macros.
>
> Hope that’s fine with you.
>
I couldn’t trace the history either.
My guess is that the response-length macro was retained either as schema
documentation or to keep it consistent with the generated QMI definitions.
Jeff may be able to confirm the original intent.
--
--
Ramesh
More information about the ath12k
mailing list