Module Name:    src
Committed By:   msaitoh
Date:           Fri Jul  5 07:08:26 UTC 2013

Modified Files:
        src/sys/dev/pci: if_bge.c

Log Message:
 Fix a link detect bug on non-autopoll systems. Same as OpenBSD
(rev.1.329 and 1.336) and FreeBSD (r213710).


To generate a diff of this commit:
cvs rdiff -u -r1.255 -r1.256 src/sys/dev/pci/if_bge.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/pci/if_bge.c
diff -u src/sys/dev/pci/if_bge.c:1.255 src/sys/dev/pci/if_bge.c:1.256
--- src/sys/dev/pci/if_bge.c:1.255	Wed Jul  3 15:21:35 2013
+++ src/sys/dev/pci/if_bge.c	Fri Jul  5 07:08:26 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_bge.c,v 1.255 2013/07/03 15:21:35 msaitoh Exp $	*/
+/*	$NetBSD: if_bge.c,v 1.256 2013/07/05 07:08:26 msaitoh Exp $	*/
 
 /*
  * Copyright (c) 2001 Wind River Systems
@@ -79,7 +79,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.255 2013/07/03 15:21:35 msaitoh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_bge.c,v 1.256 2013/07/05 07:08:26 msaitoh Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1446,10 +1446,20 @@ bge_miibus_statchg(struct ifnet *ifp)
 	 * Get flow control negotiation result.
 	 */
 	if (IFM_SUBTYPE(mii->mii_media.ifm_cur->ifm_media) == IFM_AUTO &&
-	    (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags) {
+	    (mii->mii_media_active & IFM_ETH_FMASK) != sc->bge_flowflags)
 		sc->bge_flowflags = mii->mii_media_active & IFM_ETH_FMASK;
-		mii->mii_media_active &= ~IFM_ETH_FMASK;
-	}
+
+	if (!BGE_STS_BIT(sc, BGE_STS_LINK) &&
+	    mii->mii_media_status & IFM_ACTIVE &&
+	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)
+		BGE_STS_SETBIT(sc, BGE_STS_LINK);
+	else if (BGE_STS_BIT(sc, BGE_STS_LINK) &&
+	    (!(mii->mii_media_status & IFM_ACTIVE) ||
+	    IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
+		BGE_STS_CLRBIT(sc, BGE_STS_LINK);
+
+	if (!BGE_STS_BIT(sc, BGE_STS_LINK))
+		return;
 
 	/* Set the port mode (MII/GMII) to match the link speed. */
 	mac_mode = CSR_READ_4(sc, BGE_MAC_MODE) &
@@ -1464,7 +1474,7 @@ bge_miibus_statchg(struct ifnet *ifp)
 
 	tx_mode &= ~BGE_TXMODE_FLOWCTL_ENABLE;
 	rx_mode &= ~BGE_RXMODE_FLOWCTL_ENABLE;
-	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
+	if ((mii->mii_media_active & IFM_FDX) != 0) {
 		if (sc->bge_flowflags & IFM_ETH_TXPAUSE)
 			tx_mode |= BGE_TXMODE_FLOWCTL_ENABLE;
 		if (sc->bge_flowflags & IFM_ETH_RXPAUSE)
@@ -5767,11 +5777,6 @@ bge_link_upd(struct bge_softc *sc)
 			BGE_STS_CLRBIT(sc, BGE_STS_LINK);
 			if_link_state_change(ifp, LINK_STATE_DOWN);
 		}
-	/*
-	 * Discard link events for MII/GMII cards if MI auto-polling disabled.
-	 * This should not happen since mii callouts are locked now, but
-	 * we keep this check for debug.
-	 */
 	} else if (BGE_STS_BIT(sc, BGE_STS_AUTOPOLL)) {
 		/*
 		 * Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED
@@ -5793,6 +5798,12 @@ bge_link_upd(struct bge_softc *sc)
 			    IFM_SUBTYPE(mii->mii_media_active) == IFM_NONE))
 				BGE_STS_CLRBIT(sc, BGE_STS_LINK);
 		}
+	} else {
+		/*
+		 * For controllers that call mii_tick, we have to poll
+		 * link status.
+		 */
+		mii_pollstat(mii);
 	}
 
 	/* Clear the attention */

Reply via email to