[PATCH 4/4] b43: align DMA64 descriptor ring to 64K on AC cores
Alessio Ferri <[email protected]> Wed, 17 Jun 2026 23:42:11 +0200
| Newsgroups | org.infradead.lists.b43-dev,org.kernel.vger.linux-kernel,org.kernel.vger.linux-wireless |
|---|---|
| Message-ID | <[email protected]> |
From: Alessio Ferri <[email protected]> The AC d11 core (core_rev 40/42, BCM4352) exposes a 16-bit DMA descriptor pointer (wrap mask 0xffff, not the 0x1fff b43 assumes). With an 8K-aligned ring the engine wraps the pointer outside the ring and raises I_DE on RX. Allocate the 64-bit ring with 64K size on these cores so the base is 64K-aligned and (base & 0xffff) == 0; dma_alloc_coherent() aligns to the allocation size. ring_mem_size widens to u32 to hold 0x10000. N-PHY cores report 0x1fff and keep the 8K allocation. Assisted-by: claude:claude-Opus-4.8 Signed-off-by: Alessio Ferri <[email protected]> --- drivers/net/wireless/broadcom/b43/dma.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/broadcom/b43/dma.c b/drivers/net/wireless/broadcom/b43/dma.c index 05da6987a845..cb308080312b 100644 --- a/drivers/net/wireless/broadcom/b43/dma.c +++ b/drivers/net/wireless/broadcom/b43/dma.c @@ -404,6 +404,18 @@ static inline } } +static u32 b43_dma64_ringmem_size(struct b43_dmaring *ring) +{ + /* AC d11 cores (core_rev 40/42) expose a 16-bit descriptor pointer + * (mask 0xffff) and need a 64K-aligned ring; dma_alloc_coherent() + * aligns to the (power-of-2) allocation size. Smaller cores use the + * 0x1fff mask and are fine with 8K. + */ + if (ring->dev->dev->core_rev == 40 || ring->dev->dev->core_rev == 42) + return 0x10000; + return B43_DMA64_RINGMEMSIZE; +} + static int alloc_ringmemory(struct b43_dmaring *ring) { /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K @@ -415,8 +427,8 @@ static int alloc_ringmemory(struct b43_dmaring *ring) * B43_DMA64_RXSTATDPTR. Let's just use 8K buffers even if we don't use * more than 256 slots for ring. */ - u16 ring_mem_size = (ring->type == B43_DMA_64BIT) ? - B43_DMA64_RINGMEMSIZE : B43_DMA32_RINGMEMSIZE; + u32 ring_mem_size = (ring->type == B43_DMA_64BIT) ? + b43_dma64_ringmem_size(ring) : B43_DMA32_RINGMEMSIZE; ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, ring_mem_size, &(ring->dmabase), @@ -429,8 +441,8 @@ static int alloc_ringmemory(struct b43_dmaring *ring) static void free_ringmemory(struct b43_dmaring *ring) { - u16 ring_mem_size = (ring->type == B43_DMA_64BIT) ? - B43_DMA64_RINGMEMSIZE : B43_DMA32_RINGMEMSIZE; + u32 ring_mem_size = (ring->type == B43_DMA_64BIT) ? + b43_dma64_ringmem_size(ring) : B43_DMA32_RINGMEMSIZE; dma_free_coherent(ring->dev->dev->dma_dev, ring_mem_size, ring->descbase, ring->dmabase); } -- 2.54.0 _______________________________________________ b43-dev mailing list [email protected] http://lists.infradead.org/mailman/listinfo/b43-dev