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