realtime problem

Mike Silbersack silby at silby.com
Wed Apr 9 17:07:38 PDT 2003


On Wed, 9 Apr 2003, Harti Brandt wrote:

> I first discovered this with the xl driver. Mike Silbersack commited a

Hmmm, someone has summoned me?

Here's the patch I started and stopped working on a few months back.  As
you can see, it's small, but it reduces the amount of time spent in
mii_tick _greatly_.  Most specifically, it doesn't waste time reading the
BMSR register twice, because even reading it twice doesn't mean that we
don't lose the race!  In addition, it takes advantage of the fact that
since the link status bit is latch low, we do not need to proceed any
further if it's still high, thereby saving another few register accesses.

Harti, you're more than welcome to investigate and see if those changes
reduce delay for you. :)

Mike "Silby" Silbersack
-------------- next part --------------
diff -u -r /usr/src/sys.old/dev/mii/exphy.c /usr/src/sys/dev/mii/exphy.c
--- /usr/src/sys.old/dev/mii/exphy.c	Sat Dec 21 01:55:08 2002
+++ /usr/src/sys/dev/mii/exphy.c	Tue Dec 24 11:44:43 2002
@@ -195,6 +195,7 @@
 
 	sc->mii_capabilities =
 	    PHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+	printf("mii capabilities: %x\n", sc->mii_capabilities);
 	device_printf(dev, " ");
 	mii_phy_add_media(sc);
 	printf("\n");
diff -u -r /usr/src/sys.old/dev/mii/mii_physubr.c /usr/src/sys/dev/mii/mii_physubr.c
--- /usr/src/sys.old/dev/mii/mii_physubr.c	Sat Dec 21 01:55:08 2002
+++ /usr/src/sys/dev/mii/mii_physubr.c	Tue Dec 24 22:00:28 2002
@@ -203,6 +203,7 @@
 {
 	struct ifmedia_entry *ife = sc->mii_pdata->mii_media.ifm_cur;
 	struct ifnet *ifp = sc->mii_pdata->mii_ifp;
+	struct mii_data *mii = sc->mii_pdata;
 	int reg;
 
 	/* Just bail now if the interface is down. */
@@ -218,11 +219,24 @@
 	if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO)
 		return (0);
 
-	/* Read the status register twice; BMSR_LINK is latch-low. */
-	reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR);
+	reg = PHY_READ(sc, MII_BMSR);
+
+	/*
+	 * BMSR_LINK is latch low.  If we had an established link and
+	 * its status has not changed, no need to poll.
+	 */
+	if ((reg & BMSR_LINK) && (reg & BMSR_ACOMP) &&
+	    (mii->mii_media_status & IFM_ACTIVE))
+		return (EJUSTRETURN);
+
+	printf("Link status had gone low recently.\n");
+
+	/* Read the status register again to clear BMSR_LINK latch. */
+	reg = PHY_READ(sc, MII_BMSR);
+
 	if (reg & BMSR_LINK) {
 		/*
-		 * See above.
+		 * Link status might have changed, but link is up.
 		 */
 		return (0);
 	}
diff -u -r /usr/src/sys.old/dev/mii/ukphy_subr.c /usr/src/sys/dev/mii/ukphy_subr.c
--- /usr/src/sys.old/dev/mii/ukphy_subr.c	Sat Dec 21 01:55:08 2002
+++ /usr/src/sys/dev/mii/ukphy_subr.c	Tue Dec 24 16:09:03 2002
@@ -74,7 +74,20 @@
 	mii->mii_media_status = IFM_AVALID;
 	mii->mii_media_active = IFM_ETHER;
 
-	bmsr = PHY_READ(phy, MII_BMSR) | PHY_READ(phy, MII_BMSR);
+	bmsr = PHY_READ(phy, MII_BMSR);
+
+
+	/* Link status is latched, so if we read a 1, nothing has changed. */
+	if ((bmsr & BMSR_LINK) && (bmsr & BMSR_ACOMP) &&
+		(mii->mii_media_status & IFM_ACTIVE))
+		return;
+
+	if (!(bmsr & BMSR_LINK))
+		printf("Link had failed recently.\n");
+
+	bmsr = PHY_READ(phy, MII_BMSR);
+	
+
 	if (bmsr & BMSR_LINK)
 		mii->mii_media_status |= IFM_ACTIVE;
 


More information about the freebsd-hackers mailing list