Date: Thu, 2 Nov 2006 23:33:25 GMT From: Warner Losh <imp@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 109081 for review Message-ID: <200611022333.kA2NXPnk092483@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=109081 Change 109081 by imp@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200611022333.kA2NXPnk092483>