diff options
author | 2011-06-23 03:36:06 +0000 | |
---|---|---|
committer | 2011-06-23 03:36:06 +0000 | |
commit | c0b1774c78ae1a9cbdaa5c9b47776adda5a161ee (patch) | |
tree | 51422314ccf15548749c19ed9f9d569ac3cfdc31 | |
parent | delete unused stupid code; Daniel Dickman (diff) | |
download | wireguard-openbsd-c0b1774c78ae1a9cbdaa5c9b47776adda5a161ee.tar.xz wireguard-openbsd-c0b1774c78ae1a9cbdaa5c9b47776adda5a161ee.zip |
this chip has an annoying "feature" where it cannot report the link
state unless the chip is up and handling packets. while its down
it does not report the link state, so it is unknown.
this tweaks the link state handling, in particular it adds code to
myx_down so it moves the link state to unknown, ie, it correctly
reflects reality.
stupidity pointed out by deraadt
-rw-r--r-- | sys/dev/pci/if_myx.c | 42 |
1 files changed, 14 insertions, 28 deletions
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c index 206a8a51e95..e0bc692db86 100644 --- a/sys/dev/pci/if_myx.c +++ b/sys/dev/pci/if_myx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_myx.c,v 1.26 2011/06/22 21:04:31 deraadt Exp $ */ +/* $OpenBSD: if_myx.c,v 1.27 2011/06/23 03:36:06 dlg Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -146,8 +146,6 @@ struct myx_softc { u_int sc_hwflags; #define MYXFLAG_FLOW_CONTROL (1<<0) /* Rx/Tx pause is enabled */ volatile u_int8_t sc_linkdown; - - struct timeout sc_tick; }; int myx_match(struct device *, void *, void *); @@ -172,7 +170,6 @@ int myx_media_change(struct ifnet *); void myx_media_status(struct ifnet *, struct ifmediareq *); void myx_link_state(struct myx_softc *); void myx_watchdog(struct ifnet *); -void myx_tick(void *); int myx_ioctl(struct ifnet *, u_long, caddr_t); void myx_up(struct myx_softc *); void myx_iff(struct myx_softc *); @@ -474,8 +471,6 @@ myx_attachhook(void *arg) if_attach(ifp); ether_ifattach(ifp); - timeout_set(&sc->sc_tick, myx_tick, sc); - return; freecmd: @@ -813,19 +808,20 @@ myx_media_status(struct ifnet *ifp, struct ifmediareq *imr) struct myx_softc *sc = (struct myx_softc *)ifp->if_softc; imr->ifm_active = IFM_ETHER | IFM_AUTO; - imr->ifm_status = IFM_AVALID; + if (!ISSET(ifp->if_flags, IFF_RUNNING)) { + imr->ifm_status = 0; + return; + } myx_link_state(sc); + imr->ifm_status = IFM_AVALID; if (!LINK_STATE_IS_UP(ifp->if_link_state)) return; - imr->ifm_active |= IFM_FDX; + imr->ifm_active |= IFM_FDX | IFM_FLOW | + IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE; imr->ifm_status |= IFM_ACTIVE; - - /* Flow control */ - if (sc->sc_hwflags & MYXFLAG_FLOW_CONTROL) - imr->ifm_active |= IFM_FLOW | IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE; } void @@ -834,9 +830,6 @@ myx_link_state(struct myx_softc *sc) struct ifnet *ifp = &sc->sc_ac.ac_if; int link_state = LINK_STATE_DOWN; - if (!ISSET(ifp->if_flags, IFF_RUNNING)) - return; - if (betoh32(sc->sc_sts->ms_linkstate) == MYXSTS_LINKUP) link_state = LINK_STATE_FULL_DUPLEX; if (ifp->if_link_state != link_state) { @@ -853,19 +846,6 @@ myx_watchdog(struct ifnet *ifp) return; } -void -myx_tick(void *arg) -{ - struct myx_softc *sc = (struct myx_softc *)arg; - struct ifnet *ifp = &sc->sc_ac.ac_if; - - if (!ISSET(ifp->if_flags, IFF_RUNNING)) - return; - - myx_link_state(sc); - timeout_add_sec(&sc->sc_tick, 1); -} - int myx_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { @@ -1319,6 +1299,12 @@ myx_down(struct myx_softc *sc) } CLR(ifp->if_flags, IFF_RUNNING); + + if (ifp->if_link_state != LINK_STATE_UNKNOWN) { + ifp->if_link_state = LINK_STATE_UNKNOWN; + ifp->if_baudrate = 0; + if_link_state_change(ifp); + } splx(s); bzero(&mc, sizeof(mc)); |