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 */