summaryrefslogtreecommitdiffstats
path: root/sys/dev/bge
diff options
context:
space:
mode:
authoroleg <oleg@FreeBSD.org>2006-02-17 14:33:35 +0000
committeroleg <oleg@FreeBSD.org>2006-02-17 14:33:35 +0000
commita5703d86de636f3eebb188d17d008e20ee6f4867 (patch)
tree85d0a161ef41369843146a8b8ebb07a6dcaabd1f /sys/dev/bge
parent89afcfeaef726e1729a473a7d2464f708d710797 (diff)
downloadFreeBSD-src-a5703d86de636f3eebb188d17d008e20ee6f4867.zip
FreeBSD-src-a5703d86de636f3eebb188d17d008e20ee6f4867.tar.gz
1) Ignore link events for MII/GMII cards if MI auto-polling disabled. This
should fix strange link state behaviour reported for bcm5721 & bcm5704c 2) Clear bge_link flag in bge_stop() 3) Force link state check after bge_ifmedia_upd(). Otherwise we can miss link event if PHY changes it's state fast enough. Tested by: phk (bcm5704c) Approved by: glebius (mentor) MFC after: 1 week
Diffstat (limited to 'sys/dev/bge')
-rw-r--r--sys/dev/bge/if_bge.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 2fea254..bb0ffd0 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -3382,6 +3382,7 @@ bge_ifmedia_upd(ifp)
return(0);
}
+ sc->bge_link_evt++;
mii = device_get_softc(sc->bge_miibus);
if (mii->mii_instance) {
struct mii_softc *miisc;
@@ -3682,9 +3683,17 @@ bge_stop(sc)
sc->bge_tx_saved_considx = BGE_TXCONS_UNSET;
- ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ /*
+ * We can't just call bge_link_upd() cause chip is almost stopped so
+ * bge_link_upd -> bge_tick_locked -> bge_stats_update sequence may
+ * lead to hardware deadlock. So we just clearing MAC's link state
+ * (PHY may still have link UP).
+ */
+ if (bootverbose && sc->bge_link)
+ if_printf(sc->bge_ifp, "link DOWN\n");
+ sc->bge_link = 0;
- return;
+ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
}
/*
@@ -3817,7 +3826,8 @@ bge_link_upd(sc)
if_printf(sc->bge_ifp, "link DOWN\n");
if_link_state_change(sc->bge_ifp, LINK_STATE_DOWN);
}
- } else {
+ /* Discard link events for MII/GMII cards if MI auto-polling disabled */
+ } else if (CSR_READ_4(sc, BGE_MI_MODE) & BGE_MIMODE_AUTOPOLL) {
/*
* Some broken BCM chips have BGE_STATFLAG_LINKSTATE_CHANGED bit
* in status word always set. Workaround this bug by reading
@@ -3847,7 +3857,7 @@ bge_link_upd(sc)
}
}
- /* Clear the interrupt */
+ /* Clear the attention */
CSR_WRITE_4(sc, BGE_MAC_STS, BGE_MACSTAT_SYNC_CHANGED|
BGE_MACSTAT_CFG_CHANGED|BGE_MACSTAT_MI_COMPLETE|
BGE_MACSTAT_LINK_CHANGED);
OpenPOWER on IntegriCloud