diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2011-09-26 21:44:05 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2011-09-26 21:44:05 +0000 |
commit | 14ac8e5a2de099f9a575de176af3f64d46a7c06e (patch) | |
tree | bf3ffa1a22c3700218b36bf4bffab8da2f5e099b /sys/arch | |
parent | cc95d1129d0eafeb7202eb0fb5362ccd319924f1 (diff) |
Notify ifmedia layer of loss of link on SGEC interfaces (which only gets
detected upon failure to transmit if it is indeed lost), so that `ifconfig ze0'
reports the correct state of the link instead of always pretending it is up.
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/vax/if/sgec.c | 21 | ||||
-rw-r--r-- | sys/arch/vax/if/sgecreg.h | 4 |
2 files changed, 21 insertions, 4 deletions
diff --git a/sys/arch/vax/if/sgec.c b/sys/arch/vax/if/sgec.c index db60b04e24f..11abaa67089 100644 --- a/sys/arch/vax/if/sgec.c +++ b/sys/arch/vax/if/sgec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sgec.c,v 1.19 2008/11/28 02:44:17 brad Exp $ */ +/* $OpenBSD: sgec.c,v 1.20 2011/09/26 21:44:04 miod Exp $ */ /* $NetBSD: sgec.c,v 1.5 2000/06/04 02:14:14 matt Exp $ */ /* * Copyright (c) 1999 Ludd, University of Lule}, Sweden. All rights reserved. @@ -223,6 +223,7 @@ sgec_attach(sc) ze_ifmedia_status); ifmedia_add(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5, 0, 0); ifmedia_set(&sc->sc_ifmedia, IFM_ETHER | IFM_10_5); + /* supposedly connected, and the first Tx attempt will let us know */ sc->sc_flags |= SGECF_LINKUP; return; @@ -527,9 +528,9 @@ sgec_txintr(struct ze_softc *sc) { struct ze_cdata *zc = sc->sc_zedata; struct ifnet *ifp = &sc->sc_if; + int oldlink = sc->sc_flags & SGECF_LINKUP; u_short tdes0; - sc->sc_flags |= SGECF_LINKUP; while ((zc->zc_xmit[sc->sc_lastack].ze_tdr & ZE_TDR_OW) == 0) { int idx = sc->sc_lastack; @@ -551,6 +552,8 @@ sgec_txintr(struct ze_softc *sc) sc->sc_dev.dv_xname); if (tdes0 & (ZE_TDES0_LO | ZE_TDES0_NC)) sc->sc_flags &= ~SGECF_LINKUP; + else + sc->sc_flags |= SGECF_LINKUP; if (tdes0 & ZE_TDES0_EC) { printf("%s: excessive collisions, tdr %d\n", sc->sc_dev.dv_xname, @@ -565,6 +568,7 @@ sgec_txintr(struct ze_softc *sc) if (tdes0 & (ZE_TDES0_TO | ZE_TDES0_UF)) zeinit(sc); } else { + sc->sc_flags |= SGECF_LINKUP; if (zc->zc_xmit[idx].ze_tdes1 & ZE_TDES1_LS) ifp->if_opackets++; bus_dmamap_unload(sc->sc_dmat, sc->sc_xmtmap[idx]); @@ -574,6 +578,19 @@ sgec_txintr(struct ze_softc *sc) } } } + + /* Notify link status change */ + if ((sc->sc_flags & SGECF_LINKUP) != oldlink) { + if (oldlink != 0) { + ifp->if_link_state = LINK_STATE_DOWN; + ifp->if_baudrate = 0; + } else { + ifp->if_link_state = LINK_STATE_UP; + ifp->if_baudrate = IF_Mbps(10); + } + if_link_state_change(ifp); + } + if (sc->sc_inq == 0) ifp->if_timer = 0; ifp->if_flags &= ~IFF_OACTIVE; diff --git a/sys/arch/vax/if/sgecreg.h b/sys/arch/vax/if/sgecreg.h index eafae2d9a52..75eb248d6f3 100644 --- a/sys/arch/vax/if/sgecreg.h +++ b/sys/arch/vax/if/sgecreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sgecreg.h,v 1.3 2007/04/10 18:10:31 miod Exp $ */ +/* $OpenBSD: sgecreg.h,v 1.4 2011/09/26 21:44:04 miod Exp $ */ /* $NetBSD: sgecreg.h,v 1.1 1999/08/08 11:41:29 ragge Exp $ */ /* * Copyright (c) 1988 Regents of the University of California. @@ -210,7 +210,7 @@ struct ze_tdes { u_char *ze_bufaddr; /* address of data buffer */ }; -/* Receive descriptor bits */ +/* Transmit descriptor bits */ #define ZE_TDR_OW 0x8000 /* SGEC owns this descriptor */ #define ZE_TDES0_ES 0x8000 /* an error has occurred */ #define ZE_TDES0_TO 0x4000 /* transmit watchdog timeout */ |