summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2003-07-11 08:19:52 +0000
committerwpaul <wpaul@FreeBSD.org>2003-07-11 08:19:52 +0000
commit4d41e2d69fdd3612c75d5889cc640a08728bfad8 (patch)
treec210d9f040a926c7e906b9da69c7b5577b9a32c5 /sys/dev
parentfd945a32e8edfd0780990850ebe8b4c598275529 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/dev/bge/if_bge.c23
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);
OpenPOWER on IntegriCloud