[rtems-libbsd commit] if_dwc: Use explicit cache operations

Sebastian Huber sebh at rtems.org
Tue Jan 10 10:06:12 UTC 2017


Module:    rtems-libbsd
Branch:    master
Commit:    3ef41be02fc0e4d6df0a109f1f126b81eb517176
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=3ef41be02fc0e4d6df0a109f1f126b81eb517176

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jan 10 09:16:17 2017 +0100

if_dwc: Use explicit cache operations

---

 freebsd/sys/dev/dwc/if_dwc.c    | 74 +++++++++++++++++++++++++++++++++++++++++
 freebsd/sys/dev/dwc/if_dwcvar.h |  6 ++++
 2 files changed, 80 insertions(+)

diff --git a/freebsd/sys/dev/dwc/if_dwc.c b/freebsd/sys/dev/dwc/if_dwc.c
index ba1be1e..cd1f217 100644
--- a/freebsd/sys/dev/dwc/if_dwc.c
+++ b/freebsd/sys/dev/dwc/if_dwc.c
@@ -181,6 +181,7 @@ next_txidx(struct dwc_softc *sc, uint32_t curidx, int inc)
 	return ((curidx + (uint32_t)inc) % TX_DESC_COUNT);
 }
 
+#ifndef __rtems__
 static void
 dwc_get1paddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 {
@@ -189,6 +190,7 @@ dwc_get1paddr(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
 		return;
 	*(bus_addr_t *)arg = segs[0].ds_addr;
 }
+#endif /* __rtems__ */
 
 static void
 dwc_setup_txdesc(struct dwc_softc *sc, int csum_flags, int idx,
@@ -255,6 +257,33 @@ dwc_setup_txdesc(struct dwc_softc *sc, int csum_flags, int idx,
 	}
 }
 
+#ifdef __rtems__
+static int
+dwc_get_segs_for_tx(struct mbuf *m, bus_dma_segment_t segs[TX_MAX_DMA_SEGS],
+    int *nsegs)
+{
+	int i = 0;
+
+	do {
+		if (m->m_len > 0) {
+			segs[i].ds_addr = mtod(m, bus_addr_t);
+			segs[i].ds_len = m->m_len;
+			rtems_cache_flush_multiple_data_lines(m->m_data, m->m_len);
+			++i;
+		}
+
+		m = m->m_next;
+
+		if (m == NULL) {
+			*nsegs = i;
+
+			return (0);
+		}
+	} while (i < TX_MAX_DMA_SEGS);
+
+	return (EFBIG);
+}
+#endif /* __rtems__ */
 static void
 dwc_setup_txbuf(struct dwc_softc *sc, struct mbuf *m, int *start_tx)
 {
@@ -262,9 +291,13 @@ dwc_setup_txbuf(struct dwc_softc *sc, struct mbuf *m, int *start_tx)
 	int error, nsegs, idx;
 
 	idx = sc->tx_idx_head;
+#ifndef __rtems__
 	error = bus_dmamap_load_mbuf_sg(sc->txbuf_tag, sc->txbuf_map[idx].map,
 	    m, &seg, &nsegs, BUS_DMA_NOWAIT);
 
+#else /* __rtems__ */
+	error = dwc_get_segs_for_tx(m, segs, &nsegs);
+#endif /* __rtems__ */
 	if (error == EFBIG) {
 		/* Too many segments!  Defrag and try again. */
 		struct mbuf *m2 = m_defrag(m, M_NOWAIT);
@@ -274,8 +307,12 @@ dwc_setup_txbuf(struct dwc_softc *sc, struct mbuf *m, int *start_tx)
 			return;
 		}
 		m = m2;
+#ifndef __rtems__
 		error = bus_dmamap_load_mbuf_sg(sc->txbuf_tag,
 		    sc->txbuf_map[idx].map, m, &seg, &nsegs, BUS_DMA_NOWAIT);
+#else /* __rtems__ */
+		error = dwc_get_segs_for_tx(m, segs, &nsegs);
+#endif /* __rtems__ */
 	}
 	if (error != 0) {
 		/* Give up. */
@@ -285,8 +322,10 @@ dwc_setup_txbuf(struct dwc_softc *sc, struct mbuf *m, int *start_tx)
 
 	sc->txbuf_map[idx].mbuf = m;
 
+#ifndef __rtems__
 	bus_dmamap_sync(sc->txbuf_tag, sc->txbuf_map[idx].map,
 	    BUS_DMASYNC_PREWRITE);
+#endif /* __rtems__ */
 
 	dwc_setup_txdesc(sc, m->m_pkthdr.csum_flags, idx, segs, nsegs);
 
@@ -518,8 +557,12 @@ dwc_setup_rxdesc(struct dwc_softc *sc, int idx, bus_addr_t paddr)
 
 	sc->rxdesc_ring[idx].addr = (uint32_t)paddr;
 	nidx = next_rxidx(sc, idx);
+#ifndef __rtems__
 	sc->rxdesc_ring[idx].addr_next = sc->rxdesc_ring_paddr +	\
 	    (nidx * sizeof(struct dwc_hwdesc));
+#else /* __rtems__ */
+	sc->rxdesc_ring[idx].addr_next = (uint32_t)&sc->rxdesc_ring[nidx];
+#endif /* __rtems__ */
 	if (sc->mactype == DWC_GMAC_ALT_DESC)
 		sc->rxdesc_ring[idx].tdes1 = DDESC_CNTL_CHAINED | RX_MAX_PACKET;
 	else
@@ -536,10 +579,13 @@ static int
 dwc_setup_rxbuf(struct dwc_softc *sc, int idx, struct mbuf *m)
 {
 	bus_dma_segment_t seg;
+#ifndef __rtems__
 	int error, nsegs;
+#endif /* __rtems__ */
 
 	m_adj(m, ETHER_ALIGN);
 
+#ifndef __rtems__
 	error = bus_dmamap_load_mbuf_sg(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
 	    m, &seg, &nsegs, 0);
 	if (error != 0) {
@@ -550,6 +596,10 @@ dwc_setup_rxbuf(struct dwc_softc *sc, int idx, struct mbuf *m)
 
 	bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
 	    BUS_DMASYNC_PREREAD);
+#else /* __rtems__ */
+	rtems_cache_invalidate_multiple_data_lines(m->m_data, m->m_len);
+	seg.ds_addr = mtod(m, bus_addr_t);
+#endif /* __rtems__ */
 
 	sc->rxbuf_map[idx].mbuf = m;
 	dwc_setup_rxdesc(sc, idx, seg.ds_addr);
@@ -771,9 +821,11 @@ dwc_txfinish_locked(struct dwc_softc *sc)
 		if ((desc->tdes0 & DDESC_TDES0_OWN) != 0)
 			break;
 		bmap = &sc->txbuf_map[sc->tx_idx_tail];
+#ifndef __rtems__
 		bus_dmamap_sync(sc->txbuf_tag, bmap->map,
 		    BUS_DMASYNC_POSTWRITE);
 		bus_dmamap_unload(sc->txbuf_tag, bmap->map);
+#endif /* __rtems__ */
 		m_freem(bmap->mbuf);
 		bmap->mbuf = NULL;
 		--sc->txcount;
@@ -833,9 +885,11 @@ dwc_rxfinish_locked(struct dwc_softc *sc)
 			continue;
 		}
 
+#ifndef __rtems__
 		bus_dmamap_sync(sc->rxbuf_tag, sc->rxbuf_map[idx].map,
 		    BUS_DMASYNC_POSTREAD);
 		bus_dmamap_unload(sc->rxbuf_tag, sc->rxbuf_map[idx].map);
+#endif /* __rtems__ */
 
 		len = (rdes0 >> DDESC_RDES0_FL_SHIFT) & DDESC_RDES0_FL_MASK;
 		if (len != 0) {
@@ -951,6 +1005,7 @@ setup_dma(struct dwc_softc *sc)
 		goto out;
 	}
 
+#ifndef __rtems__
 	error = bus_dmamap_load(sc->txdesc_tag, sc->txdesc_map,
 	    sc->txdesc_ring, TX_DESC_SIZE, dwc_get1paddr,
 	    &sc->txdesc_ring_paddr, 0);
@@ -959,6 +1014,7 @@ setup_dma(struct dwc_softc *sc)
 		    "could not load TX descriptor ring map.\n");
 		goto out;
 	}
+#endif /* __rtems__ */
 
 	for (idx = 0; idx < TX_DESC_COUNT; idx++) {
 		sc->txdesc_ring[idx].addr = 0;
@@ -970,10 +1026,16 @@ setup_dma(struct dwc_softc *sc)
 			sc->txdesc_ring[idx].tdes1 = 0;
 		}
 		nidx = next_txidx(sc, idx, 1);
+#ifndef __rtems__
 		sc->txdesc_ring[idx].addr_next = sc->txdesc_ring_paddr +
 		    (nidx * sizeof(struct dwc_hwdesc));
+#else /* __rtems__ */
+		sc->txdesc_ring[idx].addr_next =
+		    (uint32_t)&sc->txdesc_ring[nidx];
+#endif /* __rtems__ */
 	}
 
+#ifndef __rtems__
 	error = bus_dma_tag_create(
 	    bus_get_dma_tag(sc->dev),	/* Parent tag. */
 	    1, 0,			/* alignment, boundary */
@@ -990,8 +1052,10 @@ setup_dma(struct dwc_softc *sc)
 		    "could not create TX ring DMA tag.\n");
 		goto out;
 	}
+#endif /* __rtems__ */
 
 	for (idx = 0; idx < TX_DESC_COUNT; idx++) {
+#ifndef __rtems__
 		error = bus_dmamap_create(sc->txbuf_tag, BUS_DMA_COHERENT,
 		    &sc->txbuf_map[idx].map);
 		if (error != 0) {
@@ -999,6 +1063,7 @@ setup_dma(struct dwc_softc *sc)
 			    "could not create TX buffer DMA map.\n");
 			goto out;
 		}
+#endif /* __rtems__ */
 	}
 
 	/*
@@ -1030,6 +1095,7 @@ setup_dma(struct dwc_softc *sc)
 		goto out;
 	}
 
+#ifndef __rtems__
 	error = bus_dmamap_load(sc->rxdesc_tag, sc->rxdesc_map,
 	    sc->rxdesc_ring, RX_DESC_SIZE, dwc_get1paddr,
 	    &sc->rxdesc_ring_paddr, 0);
@@ -1055,8 +1121,10 @@ setup_dma(struct dwc_softc *sc)
 		    "could not create RX buf DMA tag.\n");
 		goto out;
 	}
+#endif /* __rtems__ */
 
 	for (idx = 0; idx < RX_DESC_COUNT; idx++) {
+#ifndef __rtems__
 		error = bus_dmamap_create(sc->rxbuf_tag, BUS_DMA_COHERENT,
 		    &sc->rxbuf_map[idx].map);
 		if (error != 0) {
@@ -1064,6 +1132,7 @@ setup_dma(struct dwc_softc *sc)
 			    "could not create RX buffer DMA map.\n");
 			goto out;
 		}
+#endif /* __rtems__ */
 		if ((m = dwc_alloc_mbufcl(sc)) == NULL) {
 			device_printf(sc->dev, "Could not alloc mbuf\n");
 			error = ENOMEM;
@@ -1313,8 +1382,13 @@ dwc_attach(device_t dev)
 	        return (ENXIO);
 
 	/* Setup addresses */
+#ifndef __rtems__
 	WRITE4(sc, RX_DESCR_LIST_ADDR, sc->rxdesc_ring_paddr);
 	WRITE4(sc, TX_DESCR_LIST_ADDR, sc->txdesc_ring_paddr);
+#else /* __rtems__ */
+	WRITE4(sc, RX_DESCR_LIST_ADDR, (uint32_t)&sc->rxdesc_ring[0]);
+	WRITE4(sc, TX_DESCR_LIST_ADDR, (uint32_t)&sc->txdesc_ring[0]);
+#endif /* __rtems__ */
 
 	mtx_init(&sc->mtx, device_get_nameunit(sc->dev),
 	    MTX_NETWORK_LOCK, MTX_DEF);
diff --git a/freebsd/sys/dev/dwc/if_dwcvar.h b/freebsd/sys/dev/dwc/if_dwcvar.h
index 2c485dc..b33fe2b 100644
--- a/freebsd/sys/dev/dwc/if_dwcvar.h
+++ b/freebsd/sys/dev/dwc/if_dwcvar.h
@@ -60,7 +60,9 @@
 #define	TX_MAX_DMA_SEGS	8	/* maximum segs in a tx mbuf dma */
 
 struct dwc_bufmap {
+#ifndef __rtems__
 	bus_dmamap_t		map;
+#endif /* __rtems__ */
 	struct mbuf		*mbuf;
 };
 
@@ -88,8 +90,10 @@ struct dwc_softc {
 	bus_dma_tag_t		rxdesc_tag;
 	bus_dmamap_t		rxdesc_map;
 	struct dwc_hwdesc	*rxdesc_ring;
+#ifndef __rtems__
 	bus_addr_t		rxdesc_ring_paddr;
 	bus_dma_tag_t		rxbuf_tag;
+#endif /* __rtems__ */
 	struct dwc_bufmap	rxbuf_map[RX_DESC_COUNT];
 	uint32_t		rx_idx;
 
@@ -97,8 +101,10 @@ struct dwc_softc {
 	bus_dma_tag_t		txdesc_tag;
 	bus_dmamap_t		txdesc_map;
 	struct dwc_hwdesc	*txdesc_ring;
+#ifndef __rtems__
 	bus_addr_t		txdesc_ring_paddr;
 	bus_dma_tag_t		txbuf_tag;
+#endif /* __rtems__ */
 	struct dwc_bufmap	txbuf_map[TX_DESC_COUNT];
 	uint32_t		tx_idx_head;
 	uint32_t		tx_idx_tail;



More information about the vc mailing list