summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2011-09-26 21:44:05 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2011-09-26 21:44:05 +0000
commit14ac8e5a2de099f9a575de176af3f64d46a7c06e (patch)
treebf3ffa1a22c3700218b36bf4bffab8da2f5e099b /sys/arch
parentcc95d1129d0eafeb7202eb0fb5362ccd319924f1 (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.c21
-rw-r--r--sys/arch/vax/if/sgecreg.h4
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 */