Skip to content

Commit 5962f37

Browse files
Anilkumar Kollikvalo
authored andcommitted
ath11k: Reuse the available memory after firmware reload
Ath11k allocates memory when firmware requests memory in QMI. Coldboot calibration and firmware recovery uses firmware reload. On firmware reload, firmware sends memory request again. If Ath11k allocates memory on first firmware boot, reuse the available memory. Also check if the segment type and size is same on the next firmware boot. Reuse if segment type/size is same as previous firmware boot else free the segment and allocate the segment with size/type. Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.6.0.1-00752-QCAHKSWPL_SILICONZ-1 Signed-off-by: Anilkumar Kolli <[email protected]> Signed-off-by: Kalle Valo <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 4255a07 commit 5962f37

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

drivers/net/wireless/ath/ath11k/core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1777,7 +1777,6 @@ static void ath11k_core_reset(struct work_struct *work)
17771777
ATH11K_RECOVER_START_TIMEOUT_HZ);
17781778

17791779
ath11k_hif_power_down(ab);
1780-
ath11k_qmi_free_resource(ab);
17811780
ath11k_hif_power_up(ab);
17821781

17831782
ath11k_dbg(ab, ATH11K_DBG_BOOT, "reset started\n");

drivers/net/wireless/ath/ath11k/qmi.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1970,6 +1970,21 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
19701970

19711971
for (i = 0; i < ab->qmi.mem_seg_count; i++) {
19721972
chunk = &ab->qmi.target_mem[i];
1973+
1974+
/* Firmware reloads in coldboot/firmware recovery.
1975+
* in such case, no need to allocate memory for FW again.
1976+
*/
1977+
if (chunk->vaddr) {
1978+
if (chunk->prev_type == chunk->type ||
1979+
chunk->prev_size == chunk->size)
1980+
continue;
1981+
1982+
/* cannot reuse the existing chunk */
1983+
dma_free_coherent(ab->dev, chunk->size,
1984+
chunk->vaddr, chunk->paddr);
1985+
chunk->vaddr = NULL;
1986+
}
1987+
19731988
chunk->vaddr = dma_alloc_coherent(ab->dev,
19741989
chunk->size,
19751990
&chunk->paddr,
@@ -1990,6 +2005,8 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab)
19902005
chunk->type);
19912006
return -EINVAL;
19922007
}
2008+
chunk->prev_type = chunk->type;
2009+
chunk->prev_size = chunk->size;
19932010
}
19942011

19952012
return 0;
@@ -2466,9 +2483,6 @@ static int ath11k_qmi_m3_load(struct ath11k_base *ab)
24662483
char path[100];
24672484
int ret;
24682485

2469-
if (m3_mem->vaddr || m3_mem->size)
2470-
return 0;
2471-
24722486
fw = ath11k_core_firmware_request(ab, ATH11K_M3_FILE);
24732487
if (IS_ERR(fw)) {
24742488
ret = PTR_ERR(fw);
@@ -2478,6 +2492,9 @@ static int ath11k_qmi_m3_load(struct ath11k_base *ab)
24782492
return ret;
24792493
}
24802494

2495+
if (m3_mem->vaddr || m3_mem->size)
2496+
goto skip_m3_alloc;
2497+
24812498
m3_mem->vaddr = dma_alloc_coherent(ab->dev,
24822499
fw->size, &m3_mem->paddr,
24832500
GFP_KERNEL);
@@ -2488,6 +2505,7 @@ static int ath11k_qmi_m3_load(struct ath11k_base *ab)
24882505
return -ENOMEM;
24892506
}
24902507

2508+
skip_m3_alloc:
24912509
memcpy(m3_mem->vaddr, fw->data, fw->size);
24922510
m3_mem->size = fw->size;
24932511
release_firmware(fw);

drivers/net/wireless/ath/ath11k/qmi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ struct ath11k_qmi_event_msg {
9797
struct target_mem_chunk {
9898
u32 size;
9999
u32 type;
100+
u32 prev_size;
101+
u32 prev_type;
100102
dma_addr_t paddr;
101103
u32 *vaddr;
102104
void __iomem *iaddr;

0 commit comments

Comments
 (0)