svn commit: r192027 - head/sys/arm/at91

Stanislav Sedov stas at FreeBSD.org
Tue May 12 21:14:36 UTC 2009


Author: stas
Date: Tue May 12 21:14:36 2009
New Revision: 192027
URL: http://svn.freebsd.org/changeset/base/192027

Log:
  - Eliminate extra register reads by using a variable to store
    registers contents.
  - Use memory barriers to preserve the order of buffer space operations.
    This might be needed if we'll ever use this driver on architectures
    where ordering is not guaranteed.

Modified:
  head/sys/arm/at91/if_ate.c

Modified: head/sys/arm/at91/if_ate.c
==============================================================================
--- head/sys/arm/at91/if_ate.c	Tue May 12 20:56:34 2009	(r192026)
+++ head/sys/arm/at91/if_ate.c	Tue May 12 21:14:36 2009	(r192027)
@@ -118,6 +118,13 @@ WR4(struct ate_softc *sc, bus_size_t off
 	bus_write_4(sc->mem_res, off, val);
 }
 
+static inline void
+BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags)
+{
+
+	bus_barrier(sc->mem_res, off, len, flags);
+}
+
 #define ATE_LOCK(_sc)		mtx_lock(&(_sc)->sc_mtx)
 #define	ATE_UNLOCK(_sc)		mtx_unlock(&(_sc)->sc_mtx)
 #define ATE_LOCK_INIT(_sc) \
@@ -586,18 +593,19 @@ ate_ifmedia_sts(struct ifnet *ifp, struc
 static void
 ate_stat_update(struct ate_softc *sc, int active)
 {
+	uint32_t reg;
+
 	/*
 	 * The speed and full/half-duplex state needs to be reflected
 	 * in the ETH_CFG register.
 	 */
-	if (IFM_SUBTYPE(active) == IFM_10_T)
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_SPD);
-	else
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_SPD);
+	reg = RD4(sc, ETH_CFG);
+	reg &= ~(ETH_CFG_SPD | ETH_CFG_FD);
+	if (IFM_SUBTYPE(active) != IFM_10_T)
+		reg |= ETH_CFG_SPD;
 	if (active & IFM_FDX)
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_FD);
-	else
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_FD);
+		reg |= ETH_CFG_FD;
+	WR4(sc, ETH_CFG, reg);
 }
 
 static void
@@ -709,11 +717,10 @@ ate_intr(void *xsc)
 {
 	struct ate_softc *sc = xsc;
 	struct ifnet *ifp = sc->ifp;
-	int status;
-	int i;
-	void *bp;
 	struct mbuf *mb;
-	uint32_t rx_stat;
+	void *bp;
+	uint32_t status, reg, rx_stat;
+	int i;
 
 	status = RD4(sc, ETH_ISR);
 	if (status == 0)
@@ -800,10 +807,11 @@ ate_intr(void *xsc)
 		ATE_UNLOCK(sc);
 	}
 	if (status & ETH_ISR_RBNA) {
-		printf("RBNA workaround\n");
 		/* Workaround Errata #11 */
-		WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) &~ ETH_CTL_RE);
-		WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_RE);
+		reg = RD4(sc, ETH_CTL);
+		WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE);
+		BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE);
+		WR4(sc, ETH_CTL, reg | ETH_CTL_RE);
 	}
 }
 
@@ -816,6 +824,7 @@ ateinit_locked(void *xsc)
 	struct ate_softc *sc = xsc;
 	struct ifnet *ifp = sc->ifp;
  	struct mii_data *mii;
+	uint32_t reg;
 
 	ATE_ASSERT_LOCKED(sc);
 
@@ -834,10 +843,12 @@ ateinit_locked(void *xsc)
 	 * to this chip.  Select the right one based on a compile-time
 	 * option.
 	 */
+	reg = RD4(sc, ETH_CFG);
 	if (sc->use_rmii)
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_RMII);
+		reg |= ETH_CFG_RMII;
 	else
-		WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII);
+		reg &= ~ETH_CFG_RMII;
+	WR4(sc, ETH_CFG, reg);
 
 	ate_rxfilter(sc);
 
@@ -926,6 +937,7 @@ atestart_locked(struct ifnet *ifp)
 		 * tell the hardware to xmit the packet.
 		 */
 		WR4(sc, ETH_TAR, segs[0].ds_addr);
+		BARRIER(sc, ETH_TAR, 8, BUS_SPACE_BARRIER_WRITE);
 		WR4(sc, ETH_TCR, segs[0].ds_len);
 	
 		/*


More information about the svn-src-all mailing list