Module Name: src
Committed By: skrll
Date: Sun Jul 14 09:31:55 UTC 2024
Modified Files:
src/sys/dev/ic: dwc_gmac.c
Log Message:
Fix some bus_dmamap_sync calls.
- ensure new descriptors are written before handing ownership of the
first in the list to the device.
- ensure descriptors are sync'ed before dumping them in
dwc_gmac_dump_[rt]x_desc
- don't sync the TX packet buffer twice (and not after we've passed
ownership of its TX descriptor)
Change some variable names to better reflect what they are while I'm here.
To generate a diff of this commit:
cvs rdiff -u -r1.88 -r1.89 src/sys/dev/ic/dwc_gmac.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/ic/dwc_gmac.c
diff -u src/sys/dev/ic/dwc_gmac.c:1.88 src/sys/dev/ic/dwc_gmac.c:1.89
--- src/sys/dev/ic/dwc_gmac.c:1.88 Fri Jul 5 04:31:51 2024
+++ src/sys/dev/ic/dwc_gmac.c Sun Jul 14 09:31:55 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: dwc_gmac.c,v 1.88 2024/07/05 04:31:51 rin Exp $ */
+/* $NetBSD: dwc_gmac.c,v 1.89 2024/07/14 09:31:55 skrll Exp $ */
/*-
* Copyright (c) 2013, 2014 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.88 2024/07/05 04:31:51 rin Exp $");
+__KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.89 2024/07/14 09:31:55 skrll Exp $");
/* #define DWC_GMAC_DEBUG 1 */
@@ -473,11 +473,11 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s
{
struct dwc_gmac_rx_data *data;
bus_addr_t physaddr;
- const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc);
+ const size_t rxringsz = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc);
int error, i, next;
ring->r_cur = ring->r_next = 0;
- memset(ring->r_desc, 0, descsize);
+ memset(ring->r_desc, 0, rxringsz);
/*
* Pre-allocate Rx buffers and populate Rx ring.
@@ -537,7 +537,8 @@ dwc_gmac_alloc_rx_ring(struct dwc_gmac_s
sc->sc_descm->rx_set_owned_by_dev(desc);
}
- bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0,
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
+ RX_DESC_OFFSET(0),
AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR,
@@ -581,12 +582,12 @@ dwc_gmac_reset_rx_ring(struct dwc_gmac_s
static int
dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc)
{
- const size_t descsize = AWGE_TOTAL_RING_COUNT *
+ const size_t ringsize = AWGE_TOTAL_RING_COUNT *
sizeof(struct dwc_gmac_dev_dmadesc);
int error, nsegs;
void *rings;
- error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0,
+ error = bus_dmamap_create(sc->sc_dmat, ringsize, 1, ringsize, 0,
BUS_DMA_NOWAIT, &sc->sc_dma_ring_map);
if (error != 0) {
aprint_error_dev(sc->sc_dev,
@@ -595,7 +596,7 @@ dwc_gmac_alloc_dma_rings(struct dwc_gmac
goto fail;
}
- error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0,
+ error = bus_dmamem_alloc(sc->sc_dmat, ringsize, PAGE_SIZE, 0,
&sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT);
if (error != 0) {
aprint_error_dev(sc->sc_dev,
@@ -604,7 +605,7 @@ dwc_gmac_alloc_dma_rings(struct dwc_gmac
}
error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs,
- descsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ ringsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
if (error != 0) {
aprint_error_dev(sc->sc_dev,
"could not allocate DMA memory\n");
@@ -612,7 +613,7 @@ dwc_gmac_alloc_dma_rings(struct dwc_gmac
}
error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings,
- descsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
+ ringsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT);
if (error != 0) {
aprint_error_dev(sc->sc_dev,
"could not load desc DMA map\n");
@@ -683,7 +684,7 @@ dwc_gmac_alloc_tx_ring(struct dwc_gmac_s
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
TX_DESC_OFFSET(0),
AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
- BUS_DMASYNC_POSTWRITE);
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
error = bus_dmamap_create(sc->sc_dmat, MCLBYTES,
@@ -700,6 +701,10 @@ dwc_gmac_alloc_tx_ring(struct dwc_gmac_s
ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc)
* TX_NEXT(i));
}
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
+ TX_DESC_OFFSET(0),
+ AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
return 0;
@@ -1088,15 +1093,17 @@ dwc_gmac_queue(struct dwc_gmac_softc *sc
data->td_m = m0;
data->td_active = map;
+ /* sync the packet buffer */
bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
BUS_DMASYNC_PREWRITE);
+ /* sync the new descriptors - ownership not transferred yet */
+ dwc_gmac_txdesc_sync(sc, first, sc->sc_txq.t_cur,
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
/* Pass first to device */
sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]);
- bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize,
- BUS_DMASYNC_PREWRITE);
-
return 0;
}
@@ -1330,6 +1337,11 @@ skip:
sc->sc_descm->rx_init_flags(desc);
sc->sc_descm->rx_set_len(desc, data->rd_m->m_len);
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
+ RX_DESC_OFFSET(i), sizeof(*desc),
+ BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
+
sc->sc_descm->rx_set_owned_by_dev(desc);
bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
@@ -1633,11 +1645,17 @@ dwc_gmac_dump_dma(struct dwc_gmac_softc
static void
dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc)
{
+ const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc);
int i;
aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n",
sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued);
aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n");
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
+ TX_DESC_OFFSET(0), AWGE_TX_RING_COUNT * descsz,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
for (i = 0; i < AWGE_TX_RING_COUNT; i++) {
struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i];
aprint_normal("#%d (%08lx): status: %08x cntl: %08x "
@@ -1652,11 +1670,17 @@ dwc_gmac_dump_tx_desc(struct dwc_gmac_so
static void
dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc)
{
+ const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc);
int i;
aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n",
sc->sc_rxq.r_cur, sc->sc_rxq.r_next);
aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n");
+
+ bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map,
+ RX_DESC_OFFSET(0), AWGE_RX_RING_COUNT * descsz,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
for (i = 0; i < AWGE_RX_RING_COUNT; i++) {
struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i];
aprint_normal("#%d (%08lx): status: %08x cntl: %08x "