When a target memory chunk fails to allocate, ath12k_qmi_alloc_chunk() compares the requested chunk size against ATH12K_QMI_MAX_CHUNK_SIZE to decide whether to ask the firmware to retry with smaller chunks (-EAGAIN) or to give up (-ENOMEM). This threshold is the boundary that tells a first (big) request apart from a retry (small) request, so it has to match the size the firmware actually falls back to on retry. That fallback size is not the same across all firmware, though. On WCN7850 and QCC2072 the firmware splits the request into 512 KB chunks on retry, whereas on QCN9274, IPQ5332 and IPQ5424 the firmware retries with larger 2 MB segments instead of 512 KB. A single hardcoded 2 MB threshold is therefore wrong for the former, and a hardcoded 512 KB threshold would be wrong for the latter. Replace the hardcoded ATH12K_QMI_MAX_CHUNK_SIZE with a per-device qmi_max_chunk_size parameter: SZ_512K for WCN7850 and QCC2072, SZ_2M for QCN9274, IPQ5332 and IPQ5424. No functional change for the latter (the value stays 2 MB); the former now use the correct 512 KB boundary. Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 Tested-on: QCC2072 hw1.0 PCI WLAN.COL.1.0.c2-00074-QCACOLSWPL_V1_TO_SILICONZ-1 Signed-off-by: Baochen Qiang --- drivers/net/wireless/ath/ath12k/hw.h | 1 + drivers/net/wireless/ath/ath12k/qmi.c | 3 +-- drivers/net/wireless/ath/ath12k/wifi7/hw.c | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/ath/ath12k/hw.h b/drivers/net/wireless/ath/ath12k/hw.h index bb1c104e1a65..78a13b169e99 100644 --- a/drivers/net/wireless/ath/ath12k/hw.h +++ b/drivers/net/wireless/ath/ath12k/hw.h @@ -167,6 +167,7 @@ struct ath12k_hw_params { u8 max_radios; bool single_pdev_only:1; u32 qmi_service_ins_id; + u32 qmi_max_chunk_size; bool internal_sleep_clock:1; const struct ath12k_hw_ops *hw_ops; diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c index bb61c78e5c29..f96d847ac92f 100644 --- a/drivers/net/wireless/ath/ath12k/qmi.c +++ b/drivers/net/wireless/ath/ath12k/qmi.c @@ -18,7 +18,6 @@ #define SLEEP_CLOCK_SELECT_INTERNAL_BIT 0x02 #define HOST_CSTATE_BIT 0x04 #define PLATFORM_CAP_PCIE_GLOBAL_RESET 0x08 -#define ATH12K_QMI_MAX_CHUNK_SIZE 2097152 static const struct qmi_elem_info wlfw_host_mlo_chip_info_s_v01_ei[] = { { @@ -2655,7 +2654,7 @@ static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab, &chunk->paddr, GFP_KERNEL | __GFP_NOWARN); if (!chunk->v.addr) { - if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) { + if (chunk->size > ab->hw_params->qmi_max_chunk_size) { ab->qmi.target_mem_delayed = true; ath12k_warn(ab, "qmi dma allocation failed (%u B type %u), will try later with small size\n", diff --git a/drivers/net/wireless/ath/ath12k/wifi7/hw.c b/drivers/net/wireless/ath/ath12k/wifi7/hw.c index 296180fbdc21..23a855018bc4 100644 --- a/drivers/net/wireless/ath/ath12k/wifi7/hw.c +++ b/drivers/net/wireless/ath/ath12k/wifi7/hw.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "../debug.h" #include "../core.h" @@ -369,6 +370,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 1, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274, + .qmi_max_chunk_size = SZ_2M, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, @@ -461,6 +463,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 1, .single_pdev_only = true, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, + .qmi_max_chunk_size = SZ_512K, .internal_sleep_clock = true, .hw_ops = &wcn7850_ops, @@ -553,6 +556,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 2, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9274, + .qmi_max_chunk_size = SZ_2M, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, @@ -643,6 +647,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 1, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332, + .qmi_max_chunk_size = SZ_2M, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, @@ -728,6 +733,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 1, .single_pdev_only = true, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_WCN7850, + .qmi_max_chunk_size = SZ_512K, .internal_sleep_clock = true, .hw_ops = &qcc2072_ops, @@ -821,6 +827,7 @@ static const struct ath12k_hw_params ath12k_wifi7_hw_params[] = { .max_radios = 1, .single_pdev_only = false, .qmi_service_ins_id = ATH12K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ5332, + .qmi_max_chunk_size = SZ_2M, .internal_sleep_clock = false, .hw_ops = &qcn9274_ops, -- 2.25.1