Skip site navigation (1)Skip section navigation (2)
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>