Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Nov 2014 16:12:12 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r274967 - head/sys/dev/ffec
Message-ID:  <201411241612.sAOGCC4L028077@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Mon Nov 24 16:12:11 2014
New Revision: 274967
URL: https://svnweb.freebsd.org/changeset/base/274967

Log:
  Add busdma sync ops before reading and after modifying the descriptor rings.
  
  This was previously working by accident because BUSDMA_COHERENT_MEMORY has
  always been set to strongly-ordered on arm.  Now we're moving towards
  normal-uncacheable (what might be called write-combining on other platforms)
  and using the proper sync ops will be more important.  Of course, that
  opens the question of just what is the "proper" sync op for shared
  concurrent dma access as opposed to accesses where the handoff of control
  of the memory has well-defined sequence points that match the available
  busdma sync operations.

Modified:
  head/sys/dev/ffec/if_ffec.c

Modified: head/sys/dev/ffec/if_ffec.c
==============================================================================
--- head/sys/dev/ffec/if_ffec.c	Mon Nov 24 14:00:27 2014	(r274966)
+++ head/sys/dev/ffec/if_ffec.c	Mon Nov 24 16:12:11 2014	(r274967)
@@ -652,7 +652,9 @@ ffec_txstart_locked(struct ffec_softc *s
 	}
 
 	if (enqueued != 0) {
+		bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_PREWRITE);
 		WR4(sc, FEC_TDAR_REG, FEC_TDAR_TDAR);
+		bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_POSTWRITE);
 		sc->tx_watchdog_count = WATCHDOG_TIMEOUT_SECS;
 	}
 }
@@ -677,6 +679,9 @@ ffec_txfinish_locked(struct ffec_softc *
 
 	FFEC_ASSERT_LOCKED(sc);
 
+	/* XXX Can't set PRE|POST right now, but we need both. */
+	bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_PREREAD);
+	bus_dmamap_sync(sc->txdesc_tag, sc->txdesc_map, BUS_DMASYNC_POSTREAD);
 	ifp = sc->ifp;
 	retired_buffer = false;
 	while (sc->tx_idx_tail != sc->tx_idx_head) {
@@ -841,6 +846,9 @@ ffec_rxfinish_locked(struct ffec_softc *
 
 	FFEC_ASSERT_LOCKED(sc);
 
+	/* XXX Can't set PRE|POST right now, but we need both. */
+	bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_PREREAD);
+	bus_dmamap_sync(sc->rxdesc_tag, sc->rxdesc_map, BUS_DMASYNC_POSTREAD);
 	produced_empty_buffer = false;
 	for (;;) {
 		desc = &sc->rxdesc_ring[sc->rx_idx];
@@ -888,7 +896,9 @@ ffec_rxfinish_locked(struct ffec_softc *
 	}
 
 	if (produced_empty_buffer) {
+		bus_dmamap_sync(sc->rxdesc_tag, sc->txdesc_map, BUS_DMASYNC_PREWRITE);
 		WR4(sc, FEC_RDAR_REG, FEC_RDAR_RDAR);
+		bus_dmamap_sync(sc->rxdesc_tag, sc->txdesc_map, BUS_DMASYNC_POSTWRITE);
 	}
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201411241612.sAOGCC4L028077>