diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-07-11 08:19:52 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-07-11 08:19:52 +0000 |
commit | 4d41e2d69fdd3612c75d5889cc640a08728bfad8 (patch) | |
tree | c210d9f040a926c7e906b9da69c7b5577b9a32c5 /sys/dev/bge | |
parent | fd945a32e8edfd0780990850ebe8b4c598275529 (diff) | |
download | FreeBSD-src-4d41e2d69fdd3612c75d5889cc640a08728bfad8.zip FreeBSD-src-4d41e2d69fdd3612c75d5889cc640a08728bfad8.tar.gz |
Squelch spurious "gigabit link up" messages generated on some fiber NICs
(mainly the 3Com 3c996B/BCM5701).
For some reason that I don't fully understand, the 5701 signals PCS
encoding errors as though they were link change events, i.e. the 'link
state changed' bit in the status word of the status block is updated
and an interrupt is generated. This would cause the bge_tick() function
to be invoked and a "gigabit link up" message to be printed on the console.
To avoid this, the interrupt handler now checks the MAC status register
when a link change interrupt is triggered, and it will only call the
bge_tick() function if the 'PCS encoding error detected' bit is clear.
(This change should have no effect on copper NICs since this bit can
only ever be set in TBI mode. I do not know how it affects 5704 NICs
with a BCM8002 SERDES PHY.)
Special thanks to: Sherry Rogers at UCB for allowing me access to one
of their traffic monitor boxes so I could diagnose this problem.
Diffstat (limited to 'sys/dev/bge')
-rw-r--r-- | sys/dev/bge/if_bge.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 24bc04f..7012cdf 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2045,6 +2045,7 @@ bge_intr(xsc) struct bge_softc *sc; struct ifnet *ifp; u_int32_t statusword; + u_int32_t status; sc = xsc; ifp = &sc->arpcom.ac_if; @@ -2073,7 +2074,6 @@ bge_intr(xsc) */ if (sc->bge_asicrev == BGE_ASICREV_BCM5700) { - u_int32_t status; status = CSR_READ_4(sc, BGE_MAC_STS); if (status & BGE_MACSTAT_MI_INTERRUPT) { @@ -2089,9 +2089,24 @@ bge_intr(xsc) } } else { if (statusword & BGE_STATFLAG_LINKSTATE_CHANGED) { - sc->bge_link = 0; - untimeout(bge_tick, sc, sc->bge_stat_ch); - bge_tick(sc); + /* + * Sometimes PCS encoding errors are detected in + * TBI mode (on fiber NICs), and for some reason + * the chip will signal them as link changes. + * If we get a link change event, but the 'PCS + * encoding error' bit in the MAC status register + * is set, don't bother doing a link check. + * This avoids spurious "gigabit link up" messages + * that sometimes appear on fiber NICs during + * periods of heavy traffic. (There should be no + * effect on copper NICs.) + */ + status = CSR_READ_4(sc, BGE_MAC_STS); + if (!(status & BGE_MACSTAT_PORT_DECODE_ERROR)) { + sc->bge_link = 0; + untimeout(bge_tick, sc, sc->bge_stat_ch); + bge_tick(sc); + } /* Clear the interrupt */ CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED| BGE_MACSTAT_CFG_CHANGED); |