d5d80a395d75e87a995047073887bd37158767f8
[openwrt/openwrt.git] /
1 wifi: ath11k: Fix DMA buffer allocation to resolve SWIOTLB issues
2 Currently, the driver allocates cacheable DMA buffers for rings like
3 HAL_REO_DST and HAL_WBM2SW_RELEASE. The buffers for HAL_WBM2SW_RELEASE
4 are large (1024 KiB), exceeding the SWIOTLB slot size of 256 KiB. This
5 leads to "swiotlb buffer is full" error messages on systems without an
6 IOMMU that use SWIOTLB, causing driver initialization failures. The driver
7 calls dma_map_single() with these large buffers obtained from kzalloc(),
8 resulting in ring initialization errors on systems without an IOMMU that
9 use SWIOTLB.
10
11 To address these issues, replace the flawed buffer allocation mechanism
12 with the appropriate DMA API. Specifically, use dma_alloc_noncoherent()
13 for cacheable DMA buffers, ensuring proper freeing of buffers with
14 dma_free_noncoherent().
15
16 Error log:
17 [ 10.194343] ath11k_pci 0000:04:00.0: swiotlb buffer is full (sz:1048583 bytes), total 32768 (slots), used 2529 (slots)
18 [ 10.194406] ath11k_pci 0000:04:00.0: failed to set up tcl_comp ring (0) :-12
19 [ 10.194781] ath11k_pci 0000:04:00.0: failed to init DP: -12
20
21 Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
22 Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3
23
24 Reported-by: Tim Harvey <tharvey@gateworks.com>
25 Closes: https://lore.kernel.org/all/20241210041133.GA17116@lst.de/
26 Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
27 Tested-by: Tim Harvey <tharvey@gateworks.com>
28 Link: https://patch.msgid.link/20250119164219.647059-2-quic_ppranees@quicinc.com
29 Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
30 --- a/drivers/net/wireless/ath/ath11k/dp.c
31 +++ b/drivers/net/wireless/ath/ath11k/dp.c
32 @@ -1,7 +1,7 @@
33 // SPDX-License-Identifier: BSD-3-Clause-Clear
34 /*
35 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
36 - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved.
37 + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
38 */
39
40 #include <crypto/hash.h>
41 @@ -104,14 +104,12 @@ void ath11k_dp_srng_cleanup(struct ath11
42 if (!ring->vaddr_unaligned)
43 return;
44
45 - if (ring->cached) {
46 - dma_unmap_single(ab->dev, ring->paddr_unaligned, ring->size,
47 - DMA_FROM_DEVICE);
48 - kfree(ring->vaddr_unaligned);
49 - } else {
50 + if (ring->cached)
51 + dma_free_noncoherent(ab->dev, ring->size, ring->vaddr_unaligned,
52 + ring->paddr_unaligned, DMA_FROM_DEVICE);
53 + else
54 dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned,
55 ring->paddr_unaligned);
56 - }
57
58 ring->vaddr_unaligned = NULL;
59 }
60 @@ -249,25 +247,14 @@ int ath11k_dp_srng_setup(struct ath11k_b
61 default:
62 cached = false;
63 }
64 -
65 - if (cached) {
66 - ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL);
67 - if (!ring->vaddr_unaligned)
68 - return -ENOMEM;
69 -
70 - ring->paddr_unaligned = dma_map_single(ab->dev,
71 - ring->vaddr_unaligned,
72 - ring->size,
73 - DMA_FROM_DEVICE);
74 - if (dma_mapping_error(ab->dev, ring->paddr_unaligned)) {
75 - kfree(ring->vaddr_unaligned);
76 - ring->vaddr_unaligned = NULL;
77 - return -ENOMEM;
78 - }
79 - }
80 }
81
82 - if (!cached)
83 + if (cached)
84 + ring->vaddr_unaligned = dma_alloc_noncoherent(ab->dev, ring->size,
85 + &ring->paddr_unaligned,
86 + DMA_FROM_DEVICE,
87 + GFP_KERNEL);
88 + else
89 ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size,
90 &ring->paddr_unaligned,
91 GFP_KERNEL);