PERFORCE change 109081 for review
Warner Losh
imp at FreeBSD.org
Thu Nov 2 23:33:26 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=109081
Change 109081 by imp at imp_lighthouse on 2006/11/02 23:33:14
Fix SD booting issue.
o Poll the PHY status in ateinit_locked and update the ETH_CFG
register to match.
o Fix some comments to be more generic.
o Remove comment XXX when writing to RSR. I grok that now.
o Add comment about TSR register needing to be more completely
decoded. Mostly for stats.
o Be more pedantic about busdma sync operations (this isn't
strictly necessary to fix this issue).
o remove a few stray blank lines.
Affected files ...
.. //depot/projects/arm/src/sys/arm/at91/if_ate.c#59 edit
Differences ...
==== //depot/projects/arm/src/sys/arm/at91/if_ate.c#59 (text+ko) ====
@@ -195,7 +195,6 @@
ate_get_mac(sc, eaddr);
ate_set_mac(sc, eaddr);
-
sc->ifp = ifp = if_alloc(IFT_ETHER);
if (mii_phy_probe(dev, &sc->miibus, ate_ifmedia_upd, ate_ifmedia_sts)) {
device_printf(dev, "Cannot find my PHY.\n");
@@ -271,10 +270,12 @@
* For the last buffer, set the wrap bit so the controller
* restarts from the first descriptor.
*/
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE);
if (i == ATE_MAX_RX_BUFFERS - 1)
sc->rx_descs[i].addr = segs[0].ds_addr | ETH_WRAP_BIT;
else
sc->rx_descs[i].addr = segs[0].ds_addr;
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_POSTWRITE);
sc->rx_descs[i].status = 0;
/* Flush the memory in the mbuf */
bus_dmamap_sync(sc->rxtag, sc->rx_map[i], BUS_DMASYNC_PREREAD);
@@ -489,6 +490,23 @@
}
static void
+ate_stat_update(struct ate_softc *sc, int active)
+{
+ /*
+ * 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);
+ 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);
+}
+
+static void
ate_tick(void *xsc)
{
struct ate_softc *sc = xsc;
@@ -508,25 +526,8 @@
active = mii->mii_media_active;
mii_tick(mii);
if (mii->mii_media_status & IFM_ACTIVE &&
- active != mii->mii_media_active) {
- /*
- * The speed and full/half-duplex state needs
- * to be reflected in the ETH_CFG register, it
- * seems.
- */
- if (IFM_SUBTYPE(mii->mii_media_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);
- if (mii->mii_media_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);
- }
+ active != mii->mii_media_active)
+ ate_stat_update(sc, mii->mii_media_active);
}
/*
@@ -588,9 +589,9 @@
uint32_t low, high;
/*
- * The KB920x loaders will setup the MAC with an address, if one
- * is set in the loader. The TSC loader will also set the MAC address
- * in a similar way. Grab the MAC address from the SA1[HL] registers.
+ * The boot loader setup the MAC with an address, if one is set in
+ * the loader. The TSC loader will also set the MAC address in a
+ * similar way. Grab the MAC address from the SA1[HL] registers.
*/
low = RD4(sc, ETH_SA1L);
high = RD4(sc, ETH_SA1H);
@@ -626,15 +627,18 @@
rx_stat = sc->rx_descs[i].status;
if ((rx_stat & ETH_LEN_MASK) == 0) {
printf("ignoring bogus 0 len packet\n");
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+ BUS_DMASYNC_PREWRITE);
sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_PREWRITE);
+ BUS_DMASYNC_POSTWRITE);
continue;
}
/* Flush memory for mbuf so we don't get stale bytes */
bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
BUS_DMASYNC_POSTREAD);
- WR4(sc, ETH_RSR, RD4(sc, ETH_RSR)); // XXX WHY? XXX imp
+ WR4(sc, ETH_RSR, RD4(sc, ETH_RSR));
+
/*
* The length returned by the device includes the
* ethernet CRC calculation for the packet, but
@@ -643,9 +647,11 @@
mb = m_devget(sc->rx_buf[i],
(rx_stat & ETH_LEN_MASK) - ETHER_CRC_LEN,
ETHER_ALIGN, ifp, NULL);
+ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
+ BUS_DMASYNC_PREWRITE);
sc->rx_descs[i].addr &= ~ETH_CPU_OWNER;
bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map,
- BUS_DMASYNC_PREWRITE);
+ BUS_DMASYNC_POSTWRITE);
bus_dmamap_sync(sc->rxtag, sc->rx_map[i],
BUS_DMASYNC_PREREAD);
if (mb != NULL) {
@@ -657,13 +663,18 @@
}
if (status & ETH_ISR_TCOM) {
ATE_LOCK(sc);
+ /* XXX TSR register should be cleared */
if (sc->sent_mbuf[0]) {
+ bus_dmamap_sync(sc->rxtag, sc->tx_map[0],
+ BUS_DMASYNC_POSTWRITE);
m_freem(sc->sent_mbuf[0]);
ifp->if_opackets++;
sc->sent_mbuf[0] = NULL;
}
if (sc->sent_mbuf[1]) {
if (RD4(sc, ETH_TSR) & ETH_TSR_IDLE) {
+ bus_dmamap_sync(sc->rxtag, sc->tx_map[1],
+ BUS_DMASYNC_POSTWRITE);
m_freem(sc->sent_mbuf[1]);
ifp->if_opackets++;
sc->txcur = 0;
@@ -701,6 +712,7 @@
{
struct ate_softc *sc = xsc;
struct ifnet *ifp = sc->ifp;
+ struct mii_data *mii;
ATE_ASSERT_LOCKED(sc);
@@ -748,6 +760,10 @@
*/
ifp->if_drv_flags |= IFF_DRV_RUNNING;
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+
+ mii = device_get_softc(sc->miibus);
+ mii_pollstat(mii);
+ ate_stat_update(sc, mii->mii_media_active);
atestart_locked(ifp);
callout_reset(&sc->tick_ch, hz, ate_tick, sc);
More information about the p4-projects
mailing list