From 29aea9ec7ddbeac001c697bfc0a8b007a6b0aa11 Mon Sep 17 00:00:00 2001 From: Oleg Bulyzhin Date: Tue, 16 May 2006 12:26:00 +0000 Subject: [PATCH] 1) Fix mii_phy_tick(): Current code does not report link loss correctly - when link goes down, mii_phy_tick() will notice that with up to mii_anegticks delay. If link goes up during this delay then link flapping will be unnoticed by driver. 2) mii_phy_add_media(): initialize sc->mii_anegticks for 10/100 media 3) Use MII_ANEGTICKS/MII_ANEGTICKS_GIGE defines instead of hardcoded values. Approved by: glebius (mentor) MFC after: 1 month --- sys/dev/mii/mii_physubr.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/sys/dev/mii/mii_physubr.c b/sys/dev/mii/mii_physubr.c index 3d71061ac54..cc60966dacd 100644 --- a/sys/dev/mii/mii_physubr.c +++ b/sys/dev/mii/mii_physubr.c @@ -219,20 +219,21 @@ mii_phy_tick(struct mii_softc *sc) /* Read the status register twice; BMSR_LINK is latch-low. */ reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); if (reg & BMSR_LINK) { - /* - * See above. - */ + sc->mii_ticks = 0; /* reset autonegotiation timer. */ + /* See above. */ return (0); } - /* - * Only retry autonegotiation every N seconds. - */ - if (sc->mii_anegticks == 0) { - sc->mii_anegticks = 17; + /* Announce link loss right after it happens */ + if (sc->mii_ticks++ == 0) return (0); - } - if (++sc->mii_ticks <= sc->mii_anegticks) + + /* XXX: use default value if phy driver did not set mii_anegticks */ + if (sc->mii_anegticks == 0) + sc->mii_anegticks = MII_ANEGTICKS_GIGE; + + /* Only retry autonegotiation every mii_anegticks ticks. */ + if (sc->mii_ticks <= sc->mii_anegticks) return (EJUSTRETURN); sc->mii_ticks = 0; @@ -409,6 +410,9 @@ mii_phy_add_media(struct mii_softc *sc) struct mii_data *mii = sc->mii_pdata; const char *sep = ""; + /* Set aneg timer for 10/100 media. Gigabit media handled below. */ + sc->mii_anegticks = MII_ANEGTICKS; + #define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) #define PRINT(s) printf("%s%s", sep, s); sep = ", " @@ -461,20 +465,16 @@ mii_phy_add_media(struct mii_softc *sc) /* * XXX Right now only handle 1000SX and 1000TX. Need * XXX to handle 1000LX and 1000CX some how. - * - * Note since it can take 5 seconds to auto-negotiate - * a gigabit link, we make anegticks 10 seconds for - * all the gigabit media types. */ if (sc->mii_extcapabilities & EXTSR_1000XHDX) { - sc->mii_anegticks = 17; + sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_IS_1000X; ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, sc->mii_inst), MII_MEDIA_1000_X); PRINT("1000baseSX"); } if (sc->mii_extcapabilities & EXTSR_1000XFDX) { - sc->mii_anegticks = 17; + sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_IS_1000X; ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), MII_MEDIA_1000_X_FDX); @@ -490,7 +490,7 @@ mii_phy_add_media(struct mii_softc *sc) * All 1000baseT PHYs have a 1000baseT control register. */ if (sc->mii_extcapabilities & EXTSR_1000THDX) { - sc->mii_anegticks = 17; + sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_HAVE_GTCR; mii->mii_media.ifm_mask |= IFM_ETH_MASTER; ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, @@ -498,7 +498,7 @@ mii_phy_add_media(struct mii_softc *sc) PRINT("1000baseT"); } if (sc->mii_extcapabilities & EXTSR_1000TFDX) { - sc->mii_anegticks = 17; + sc->mii_anegticks = MII_ANEGTICKS_GIGE; sc->mii_flags |= MIIF_HAVE_GTCR; mii->mii_media.ifm_mask |= IFM_ETH_MASTER; ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX,