diff options
author | Kevin Lo <kevlo@cvs.openbsd.org> | 2011-08-21 15:25:21 +0000 |
---|---|---|
committer | Kevin Lo <kevlo@cvs.openbsd.org> | 2011-08-21 15:25:21 +0000 |
commit | 7212d06c0e5938a8c576561b6e540e019bad36bb (patch) | |
tree | 124a6764cdede17d9370ad4f1222591d39077ed1 /sys/dev/pci | |
parent | 680e42a8a8eeff4b57ed079a67b9111107daa9bd (diff) |
Help with the watchdog timeouts seen when unplugging the cable from
the alc(4) NIC while running or the NIC not working if the cable is
not plugged in upon boot up.
From Brad; tested by matteo filippetto, Gabriel Linder and edd@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_alc.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/sys/dev/pci/if_alc.c b/sys/dev/pci/if_alc.c index 75447886762..b1c03400458 100644 --- a/sys/dev/pci/if_alc.c +++ b/sys/dev/pci/if_alc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_alc.c,v 1.15 2011/06/17 07:16:42 kevlo Exp $ */ +/* $OpenBSD: if_alc.c,v 1.16 2011/08/21 15:25:20 kevlo Exp $ */ /*- * Copyright (c) 2009, Pyun YongHyeon <yongari@FreeBSD.org> * All rights reserved. @@ -214,14 +214,12 @@ alc_miibus_statchg(struct device *dev) { struct alc_softc *sc = (struct alc_softc *)dev; struct ifnet *ifp = &sc->sc_arpcom.ac_if; - struct mii_data *mii; + struct mii_data *mii = &sc->sc_miibus; uint32_t reg; if ((ifp->if_flags & IFF_RUNNING) == 0) return; - mii = &sc->sc_miibus; - sc->alc_flags &= ~ALC_FLAG_LINK; if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) == (IFM_ACTIVE | IFM_AVALID)) { @@ -260,6 +258,9 @@ alc_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) struct alc_softc *sc = ifp->if_softc; struct mii_data *mii = &sc->sc_miibus; + if ((ifp->if_flags & IFF_UP) == 0) + return; + mii_pollstat(mii); ifmr->ifm_status = mii->mii_media_status; ifmr->ifm_active = mii->mii_media_active; @@ -1381,6 +1382,10 @@ alc_start(struct ifnet *ifp) if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) return; + if ((sc->alc_flags & ALC_FLAG_LINK) == 0) + return; + if (IFQ_IS_EMPTY(&ifp->if_snd)) + return; for (;;) { IFQ_DEQUEUE(&ifp->if_snd, m_head); @@ -1441,9 +1446,7 @@ alc_watchdog(struct ifnet *ifp) printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname); ifp->if_oerrors++; alc_init(ifp); - - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - alc_start(ifp); + alc_start(ifp); } int @@ -1726,12 +1729,12 @@ alc_intr(void *arg) return (0); } - if (status & INTR_TX_PKT) { + if (status & INTR_TX_PKT) alc_txeof(sc); - if (!IFQ_IS_EMPTY(&ifp->if_snd)) - alc_start(ifp); - } + + alc_start(ifp); } + claimed = 1; back: /* Re-enable interrupts. */ |