On Sun, Jan 19, 2025 at 8:42 AM P Praneesh <quic_ppranees@xxxxxxxxxxx> wrote: > > Currently, the driver allocates cacheable DMA buffers for rings like > HAL_REO_DST and HAL_WBM2SW_RELEASE. The buffers for HAL_WBM2SW_RELEASE > are large (1024 KiB), exceeding the SWIOTLB slot size of 256 KiB. This > leads to "swiotlb buffer is full" error messages on systems without an > IOMMU that use SWIOTLB, causing driver initialization failures. The driver > calls dma_map_single() with these large buffers obtained from kzalloc(), > resulting in ring initialization errors on systems without an IOMMU that > use SWIOTLB. > > To address these issues, replace the flawed buffer allocation mechanism > with the appropriate DMA API. Specifically, use dma_alloc_noncoherent() > for cacheable DMA buffers, ensuring proper freeing of buffers with > dma_free_noncoherent(). > > Error log: > [ 10.194343] ath11k_pci 0000:04:00.0: swiotlb buffer is full (sz:1048583 bytes), total 32768 (slots), used 2529 (slots) > [ 10.194406] ath11k_pci 0000:04:00.0: failed to set up tcl_comp ring (0) :-12 > [ 10.194781] ath11k_pci 0000:04:00.0: failed to init DP: -12 > > Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1 > Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3 > > Reported-by: Tim Harvey <tharvey@xxxxxxxxxxxxx> > Closes: https://lore.kernel.org/all/20241210041133.GA17116@xxxxxx/ > Signed-off-by: P Praneesh <quic_ppranees@xxxxxxxxxxx> > --- > drivers/net/wireless/ath/ath11k/dp.c | 35 +++++++++------------------- > 1 file changed, 11 insertions(+), 24 deletions(-) > > diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c > index fbf666d0ecf1..f124b7329e1a 100644 > --- a/drivers/net/wireless/ath/ath11k/dp.c > +++ b/drivers/net/wireless/ath/ath11k/dp.c > @@ -1,7 +1,7 @@ > // SPDX-License-Identifier: BSD-3-Clause-Clear > /* > * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. > - * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. > */ > > #include <crypto/hash.h> > @@ -104,14 +104,12 @@ void ath11k_dp_srng_cleanup(struct ath11k_base *ab, struct dp_srng *ring) > if (!ring->vaddr_unaligned) > return; > > - if (ring->cached) { > - dma_unmap_single(ab->dev, ring->paddr_unaligned, ring->size, > - DMA_FROM_DEVICE); > - kfree(ring->vaddr_unaligned); > - } else { > + if (ring->cached) > + dma_free_noncoherent(ab->dev, ring->size, ring->vaddr_unaligned, > + ring->paddr_unaligned, DMA_FROM_DEVICE); > + else > dma_free_coherent(ab->dev, ring->size, ring->vaddr_unaligned, > ring->paddr_unaligned); > - } > > ring->vaddr_unaligned = NULL; > } > @@ -249,25 +247,14 @@ int ath11k_dp_srng_setup(struct ath11k_base *ab, struct dp_srng *ring, > default: > cached = false; > } > - > - if (cached) { > - ring->vaddr_unaligned = kzalloc(ring->size, GFP_KERNEL); > - if (!ring->vaddr_unaligned) > - return -ENOMEM; > - > - ring->paddr_unaligned = dma_map_single(ab->dev, > - ring->vaddr_unaligned, > - ring->size, > - DMA_FROM_DEVICE); > - if (dma_mapping_error(ab->dev, ring->paddr_unaligned)) { > - kfree(ring->vaddr_unaligned); > - ring->vaddr_unaligned = NULL; > - return -ENOMEM; > - } > - } > } > > - if (!cached) > + if (cached) > + ring->vaddr_unaligned = dma_alloc_noncoherent(ab->dev, ring->size, > + &ring->paddr_unaligned, > + DMA_FROM_DEVICE, > + GFP_KERNEL); > + else > ring->vaddr_unaligned = dma_alloc_coherent(ab->dev, ring->size, > &ring->paddr_unaligned, > GFP_KERNEL); > -- > 2.34.1 > Thanks, this resolves the issue I reported. I tested this with qcn9074 on an imx8mm (no iommu) with 4GiB DRAM and verified swiotlb was not being used and infrastructure mode worked fine. Tested-By: Tim Harvey <tharvey@xxxxxxxxxxxxx> Best regards, Tim