[PATCH 4/4] b43: align DMA64 descriptor ring to 64K on AC cores

Alessio Ferri alessio.ferri at mythread.it
Wed Jun 17 14:42:11 PDT 2026


From: Alessio Ferri <alessio.ferri.3012 at gmail.com>

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 <alessio.ferri at mythread.it>
---
 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




More information about the b43-dev mailing list