summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoroleg <oleg@FreeBSD.org>2006-12-19 08:57:46 +0000
committeroleg <oleg@FreeBSD.org>2006-12-19 08:57:46 +0000
commit5ce6905b904d4519790b59520e6592e4eaa3910d (patch)
tree95935e77876c58271573b075203c49e1b3425544 /sys/dev
parent967a981a72e6c247291631c0ba88111fd72dd0bb (diff)
downloadFreeBSD-src-5ce6905b904d4519790b59520e6592e4eaa3910d.zip
FreeBSD-src-5ce6905b904d4519790b59520e6592e4eaa3910d.tar.gz
- Add missing callout_drain() call.
- Synchronize bge_tick() with callout_reset/callout_stop() calls. - Avoid using bge_tick() inside bge_link_upd(), use mii_pollstat() instead. MFC after: 2 month
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/bge/if_bge.c22
1 files changed, 10 insertions, 12 deletions
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index 2bae618..1035083 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -2482,6 +2482,8 @@ bge_detach(device_t dev)
bge_reset(sc);
BGE_UNLOCK(sc);
+ callout_drain(&sc->bge_stat_ch);
+
ether_ifdetach(ifp);
if (sc->bge_flags & BGE_FLAG_TBI) {
@@ -3045,6 +3047,11 @@ bge_tick(void *xsc)
BGE_LOCK_ASSERT(sc);
+ /* Synchronize with possible callout reset/stop. */
+ if (callout_pending(&sc->bge_stat_ch) ||
+ !callout_active(&sc->bge_stat_ch))
+ return;
+
if (BGE_IS_5705_PLUS(sc))
bge_stats_update_regs(sc);
else
@@ -3870,12 +3877,7 @@ bge_stop(struct bge_softc *sc)
sc->bge_tx_saved_considx = BGE_TXCONS_UNSET;
- /*
- * 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).
- */
+ /* Clear 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;
@@ -3962,10 +3964,8 @@ bge_link_upd(struct bge_softc *sc)
sc->bge_chipid != BGE_CHIPID_BCM5700_B2) {
status = CSR_READ_4(sc, BGE_MAC_STS);
if (status & BGE_MACSTAT_MI_INTERRUPT) {
- callout_stop(&sc->bge_stat_ch);
- bge_tick(sc);
-
mii = device_get_softc(sc->bge_miibus);
+ mii_pollstat(mii);
if (!sc->bge_link &&
mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
@@ -4021,10 +4021,8 @@ bge_link_upd(struct bge_softc *sc)
if (link != sc->bge_link ||
sc->bge_asicrev == BGE_ASICREV_BCM5700) {
- callout_stop(&sc->bge_stat_ch);
- bge_tick(sc);
-
mii = device_get_softc(sc->bge_miibus);
+ mii_pollstat(mii);
if (!sc->bge_link &&
mii->mii_media_status & IFM_ACTIVE &&
IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
OpenPOWER on IntegriCloud