summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-09-17 04:58:17 +0000
committerwpaul <wpaul@FreeBSD.org>2004-09-17 04:58:17 +0000
commit5230412aea7618a1025952f2b502fb7bd28ccd8d (patch)
treeef8d2020be9c7840c1c292c15b64d49d09e099ff /sys/dev/bge
parente572c5e1cf5110dca2131bb7ba2d1c7d7814ee76 (diff)
downloadFreeBSD-src-5230412aea7618a1025952f2b502fb7bd28ccd8d.zip
FreeBSD-src-5230412aea7618a1025952f2b502fb7bd28ccd8d.tar.gz
Commit patch to supress spurious link change events. Apparently, with
copper NICs, a link change event is posted whenever MII autopolling is toggled off and on, which happens whenever someone calls bge_miibus_readreg() or bge_miibus_writereg() to access the PHY registers. This means anytime someone called the SIOCGIFMEDIA ioctl on a bge interface, the link would reset. Even a simple "ifconfig bge0" would do it, though other apps like dhclient or the PPPoE daemon could trigger it as well. An obvious symptom of this problem is lots of "bgeX: gigabit link up" messages appearing on the console for no apparent reason. Through experimentation, I determined that when a real link change event occurs, the BGE_MIMODE_AUTOPOLL in the BGE_MI_MODE register is always set, so now if we have a copper NIC and an link change event occurs and the BGE_MIMODE_AUTOPOLL bit is clear, we ignore the event. Note that this does not apply to the original BCM5700 chip since we use a different method for sensing link changes with that chip (the status block method was broken), nor to fiber optic NICs since they don't use the GMII PHY access registers.
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 5468423..71ad6ab 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -2802,7 +2802,7 @@ bge_intr(xsc)
struct bge_softc *sc;
struct ifnet *ifp;
u_int32_t statusword;
- u_int32_t status;
+ u_int32_t status, mimode;
sc = xsc;
ifp = &sc->arpcom.ac_if;
@@ -2863,10 +2863,19 @@ bge_intr(xsc)
* that sometimes appear on fiber NICs during
* periods of heavy traffic. (There should be no
* effect on copper NICs.)
+ *
+ * If we do have a copper NIC (bge_tbi == 0) then
+ * check that the AUTOPOLL bit is set before
+ * processing the event as a real link change.
+ * Turning AUTOPOLL on and off in the MII read/write
+ * functions will often trigger a link status
+ * interrupt for no reason.
*/
status = CSR_READ_4(sc, BGE_MAC_STS);
+ mimode = CSR_READ_4(sc, BGE_MI_MODE);
if (!(status & (BGE_MACSTAT_PORT_DECODE_ERROR|
- BGE_MACSTAT_MI_COMPLETE))) {
+ BGE_MACSTAT_MI_COMPLETE)) && (!sc->bge_tbi &&
+ (mimode & BGE_MIMODE_AUTOPOLL))) {
sc->bge_link = 0;
callout_stop(&sc->bge_stat_ch);
bge_tick_locked(sc);
OpenPOWER on IntegriCloud