[PATCH ath-next] wifi: ath12k: add QMI capability negotiation for dynamic memory mode

Aaradhana Sahu aaradhana.sahu at oss.qualcomm.com
Thu Jun 18 23:21:53 PDT 2026



On 6/19/2026 4:55 AM, Jeff Johnson wrote:
> On 6/18/2026 2:29 AM, Rameshkumar Sundaram wrote:
>> 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.
> 
> I suspect this was from the code generator and was just pulled in.
> Concur we should just drop this (and have a cleanup patch to remove any others
> that are unused).
> 
> And this V01 naming convention seems broken since we've regularly extended
> messages and yet still call them V01. I would have expected each extension
> would have incremented the version number...
> 
> And I also think it is strange to pass the message length anyway since the
> serializer should be able to figure that out -- having the clients pass that
> means the clients must know the details of the serialization algorithm which
> is a layering violation. But that is a preexisting issue with the QMI interface.
> 
> /jeff
> 
> /jeff
>>
> 

Thanks for the clarification. I will drop this change in the next version and
send a separate cleanup patch to remove the unused QMI response length macros.




More information about the ath12k mailing list