wifi: ath12k: refactor ath12k_qmi_alloc_target_mem_chunk()

Currently, all QMI target memory types share the same allocation logic within
ath12k_qmi_alloc_target_mem_chunk(). However, for Multi-Link Operation (MLO),
the firmware requests a new MLO global memory region. This memory is shared
across different firmware (SoC) participating in the MLO. To accommodate this
logic change, refactor ath12k_qmi_alloc_target_mem_chunk() and introduce a
helper function ath12k_qmi_alloc_chunk() for memory chunk allocation.
Subsequent patch will add MLO global memory allocation logic.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.1.1-00210-QCAHKSWPL_SILICONZ-1
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3

Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Signed-off-by: Raj Kumar Bhagat <quic_rajkbhag@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://patch.msgid.link/20241211153432.775335-5-kvalo@kernel.org
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
Karthikeyan Periyasamy 2024-12-11 17:34:28 +02:00 committed by Jeff Johnson
parent 08a4c51c6e
commit 786f34b5b4

View File

@ -2423,9 +2423,50 @@ static void ath12k_qmi_free_target_mem_chunk(struct ath12k_base *ab)
}
}
static int ath12k_qmi_alloc_chunk(struct ath12k_base *ab,
struct target_mem_chunk *chunk)
{
/* Firmware reloads in recovery/resume.
* In such cases, no need to allocate memory for FW again.
*/
if (chunk->v.addr) {
if (chunk->prev_type == chunk->type &&
chunk->prev_size == chunk->size)
goto this_chunk_done;
/* cannot reuse the existing chunk */
dma_free_coherent(ab->dev, chunk->prev_size,
chunk->v.addr, chunk->paddr);
chunk->v.addr = NULL;
}
chunk->v.addr = dma_alloc_coherent(ab->dev,
chunk->size,
&chunk->paddr,
GFP_KERNEL | __GFP_NOWARN);
if (!chunk->v.addr) {
if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
ab->qmi.target_mem_delayed = true;
ath12k_warn(ab,
"qmi dma allocation failed (%d B type %u), will try later with small size\n",
chunk->size,
chunk->type);
ath12k_qmi_free_target_mem_chunk(ab);
return 0;
}
ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
chunk->type, chunk->size);
return -ENOMEM;
}
chunk->prev_type = chunk->type;
chunk->prev_size = chunk->size;
this_chunk_done:
return 0;
}
static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
{
int i;
int i, ret = 0;
struct target_mem_chunk *chunk;
ab->qmi.target_mem_delayed = false;
@ -2442,42 +2483,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
case M3_DUMP_REGION_TYPE:
case PAGEABLE_MEM_REGION_TYPE:
case CALDB_MEM_REGION_TYPE:
/* Firmware reloads in recovery/resume.
* In such cases, no need to allocate memory for FW again.
*/
if (chunk->v.addr) {
if (chunk->prev_type == chunk->type &&
chunk->prev_size == chunk->size)
goto this_chunk_done;
/* cannot reuse the existing chunk */
dma_free_coherent(ab->dev, chunk->prev_size,
chunk->v.addr, chunk->paddr);
chunk->v.addr = NULL;
}
chunk->v.addr = dma_alloc_coherent(ab->dev,
chunk->size,
&chunk->paddr,
GFP_KERNEL | __GFP_NOWARN);
if (!chunk->v.addr) {
if (chunk->size > ATH12K_QMI_MAX_CHUNK_SIZE) {
ab->qmi.target_mem_delayed = true;
ath12k_warn(ab,
"qmi dma allocation failed (%d B type %u), will try later with small size\n",
chunk->size,
chunk->type);
ath12k_qmi_free_target_mem_chunk(ab);
return 0;
}
ath12k_warn(ab, "memory allocation failure for %u size: %d\n",
chunk->type, chunk->size);
return -ENOMEM;
}
chunk->prev_type = chunk->type;
chunk->prev_size = chunk->size;
this_chunk_done:
ret = ath12k_qmi_alloc_chunk(ab, chunk);
break;
default:
ath12k_warn(ab, "memory type %u not supported\n",
@ -2487,7 +2493,7 @@ static int ath12k_qmi_alloc_target_mem_chunk(struct ath12k_base *ab)
break;
}
}
return 0;
return ret;
}
/* clang stack usage explodes if this is inlined */