summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/pci/if_art.c75
-rw-r--r--sys/dev/pci/if_art.h4
-rw-r--r--sys/dev/pci/musycc.c17
-rw-r--r--sys/dev/pci/musyccvar.h4
4 files changed, 55 insertions, 45 deletions
diff --git a/sys/dev/pci/if_art.c b/sys/dev/pci/if_art.c
index 775046421b5..f4ef7a112b3 100644
--- a/sys/dev/pci/if_art.c
+++ b/sys/dev/pci/if_art.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_art.c,v 1.8 2005/09/22 12:45:07 claudio Exp $ */
+/* $OpenBSD: if_art.c,v 1.9 2005/10/26 09:26:56 claudio Exp $ */
/*
* Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland
@@ -46,6 +46,7 @@ int art_ifm_change(struct ifnet *);
void art_ifm_status(struct ifnet *, struct ifmediareq *);
int art_ifm_options(struct ifnet *, struct channel_softc *, u_int);
void art_onesec(void *);
+void art_linkstate(void *);
struct cfattach art_ca = {
sizeof(struct art_softc), art_match, art_softc_attach
@@ -160,9 +161,7 @@ art_softc_attach(struct device *parent, struct device *self, void *aux)
if (bt8370_reset(sc) != 0)
return;
- /*
- * Initialize timeout for statistics update.
- */
+ /* Initialize timeout for statistics update. */
timeout_set(&sc->art_onesec, art_onesec, sc);
ifmedia_set(&sc->art_ifm, IFM_TDM|IFM_TDM_E1_G704_CRC4);
@@ -171,9 +170,11 @@ art_softc_attach(struct device *parent, struct device *self, void *aux)
bt8370_set_frame_mode(sc, sc->art_type, IFM_TDM_E1_G704_CRC4, 0);
musycc_attach_sppp(sc->art_channel, art_ioctl);
- /*
- * Schedule the timeout one second from now.
- */
+ /* Set linkstate hook to track link state changes done by sppp. */
+ sc->art_linkstatehook = hook_establish(
+ sc->art_channel->cc_ifp->if_linkstatehooks, 0, art_linkstate, sc);
+
+ /* Schedule the timeout one second from now. */
timeout_add(&sc->art_onesec, hz);
}
@@ -242,7 +243,7 @@ art_ifm_change(struct ifnet *ifp)
struct channel_softc *cc = ifp->if_softc;
struct art_softc *ac = (struct art_softc *)cc->cc_parent;
struct ifmedia *ifm = &ac->art_ifm;
- int rv;
+ int rv, s, baudrate;
ACCOOM_PRINTF(2, ("%s: art_ifm_change %08x\n", ifp->if_xname,
ifm->ifm_media));
@@ -265,6 +266,15 @@ art_ifm_change(struct ifnet *ifp)
IFM_SUBTYPE(ifm->ifm_media), IFM_MODE(ifm->ifm_media));
/* adjust timeslot map on media change */
}
+
+ baudrate = ifmedia_baudrate(ac->art_media);
+ if (baudrate != ifp->if_baudrate) {
+ ifp->if_baudrate = baudrate;
+ s = splsoftnet();
+ if_link_state_change(ifp), baudrate;
+ splx(s);
+ }
+
ac->art_media = ifm->ifm_media;
return (0);
@@ -277,7 +287,9 @@ art_ifm_status(struct ifnet *ifp, struct ifmediareq *ifmreq)
ac = (struct art_softc *)
((struct channel_softc *)ifp->if_softc)->cc_parent;
- ifmreq->ifm_status = ac->art_status;
+ ifmreq->ifm_status = IFM_AVALID;
+ if (ifp->if_link_state == LINK_STATE_UP)
+ ifmreq->ifm_status |= IFM_ACTIVE;
ifmreq->ifm_active = ac->art_media;
return;
@@ -317,52 +329,35 @@ art_onesec(void *arg)
struct art_softc *ac = arg;
struct ifnet *ifp = ac->art_channel->cc_ifp;
struct sppp *ppp = &ac->art_channel->cc_ppp;
- int s, rv, link_state, baudrate, announce = 0;
+ int s, rv, link_state;
- ac->art_status = IFM_AVALID;
rv = bt8370_link_status(ac);
switch (rv) {
case 1:
link_state = LINK_STATE_UP;
- /* set led green but ask sppp if red is needed */
- ebus_set_led(ac->art_channel, MUSYCC_LED_GREEN);
- ac->art_status |= IFM_ACTIVE;
+ /* set green led */
+ ebus_set_led(ac->art_channel, 1, MUSYCC_LED_GREEN);
break;
case 0:
link_state = LINK_STATE_DOWN;
- /* set led green & red */
- ebus_set_led(ac->art_channel,
+ /* set green led and red let as well */
+ ebus_set_led(ac->art_channel, 1,
MUSYCC_LED_GREEN | MUSYCC_LED_RED);
break;
default:
link_state = LINK_STATE_DOWN;
- /* set led red */
- ebus_set_led(ac->art_channel, MUSYCC_LED_RED);
+ /* turn green led off */
+ ebus_set_led(ac->art_channel, 0, MUSYCC_LED_GREEN);
break;
}
if (link_state != ifp->if_link_state) {
- ifp->if_link_state = link_state;
s = splsoftnet();
if (link_state == LINK_STATE_UP)
ppp->pp_up(ppp);
else
ppp->pp_down(ppp);
splx(s);
- announce = 1;
- }
-
- baudrate = ifmedia_baudrate(ac->art_media);
-
- if (baudrate != ifp->if_baudrate) {
- ifp->if_baudrate = baudrate;
- announce = 1;
- }
-
- if (announce) {
- s = splnet();
- if_link_state_change(ifp);
- splx(s);
}
/*
@@ -376,3 +371,17 @@ art_onesec(void *arg)
timeout_add(&ac->art_onesec, hz);
}
+void
+art_linkstate(void *arg)
+{
+ struct art_softc *ac = arg;
+ struct ifnet *ifp = ac->art_channel->cc_ifp;
+
+ if (ifp->if_link_state == LINK_STATE_UP)
+ /* turn red led off */
+ ebus_set_led(ac->art_channel, 0, MUSYCC_LED_RED);
+ else
+ /* turn red led on */
+ ebus_set_led(ac->art_channel, 1, MUSYCC_LED_RED);
+}
+
diff --git a/sys/dev/pci/if_art.h b/sys/dev/pci/if_art.h
index 46b15aa105b..880ff22754a 100644
--- a/sys/dev/pci/if_art.h
+++ b/sys/dev/pci/if_art.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_art.h,v 1.4 2005/08/27 13:32:01 claudio Exp $ */
+/* $OpenBSD: if_art.h,v 1.5 2005/10/26 09:26:56 claudio Exp $ */
/*
* Copyright (c) 2005 Internet Business Solutions AG, Zurich, Switzerland
@@ -35,8 +35,8 @@ struct art_softc {
struct timeout art_onesec; /* onesec timeout */
struct musycc_softc *art_parent; /* parent hdlc controller */
struct channel_softc *art_channel; /* channel config */
+ void *art_linkstatehook;
- int art_status; /* if_media status */
u_int art_media; /* if_media media */
enum art_sbi_type art_type; /* System Bus Type */
u_int8_t art_gnum; /* group number */
diff --git a/sys/dev/pci/musycc.c b/sys/dev/pci/musycc.c
index 806e21e9016..175e711a21b 100644
--- a/sys/dev/pci/musycc.c
+++ b/sys/dev/pci/musycc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: musycc.c,v 1.8 2005/09/22 12:47:14 claudio Exp $ */
+/* $OpenBSD: musycc.c,v 1.9 2005/10/26 09:26:56 claudio Exp $ */
/*
* Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland
@@ -1596,21 +1596,22 @@ ebus_read_buf(struct ebus_dev *rom, bus_size_t offset, void *buf, size_t size)
}
void
-ebus_set_led(struct channel_softc *cc, u_int8_t value)
+ebus_set_led(struct channel_softc *cc, int on, u_int8_t value)
{
struct musycc_softc *sc = cc->cc_group->mg_hdlc->mc_other;
- u_int8_t mask;
+ value &= MUSYCC_LED_MASK; /* don't write to other ports led */
value <<= cc->cc_group->mg_gnum * 2;
- mask = MUSYCC_LED_MASK << (cc->cc_group->mg_gnum * 2);
- value = (value & mask) | (sc->mc_ledstate & ~mask);
+ if (on)
+ sc->mc_ledstate |= value;
+ else
+ sc->mc_ledstate &= ~value;
- bus_space_write_1(sc->mc_st, sc->mc_sh, sc->mc_ledbase, value);
+ bus_space_write_1(sc->mc_st, sc->mc_sh, sc->mc_ledbase,
+ sc->mc_ledstate);
bus_space_barrier(sc->mc_st, sc->mc_sh, sc->mc_ledbase, 1,
BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
-
- sc->mc_ledstate = value;
}
/*
diff --git a/sys/dev/pci/musyccvar.h b/sys/dev/pci/musyccvar.h
index 7f23a96d3db..8325bedaa95 100644
--- a/sys/dev/pci/musyccvar.h
+++ b/sys/dev/pci/musyccvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: musyccvar.h,v 1.7 2005/09/22 12:47:14 claudio Exp $ */
+/* $OpenBSD: musyccvar.h,v 1.8 2005/10/26 09:26:56 claudio Exp $ */
/*
* Copyright (c) 2004,2005 Internet Business Solutions AG, Zurich, Switzerland
@@ -201,7 +201,7 @@ int ebus_attach_device(struct ebus_dev *, struct musycc_softc *,
u_int8_t ebus_read(struct ebus_dev *, bus_size_t);
void ebus_write(struct ebus_dev *, bus_size_t, u_int8_t);
void ebus_read_buf(struct ebus_dev *, bus_size_t, void *, size_t);
-void ebus_set_led(struct channel_softc *, u_int8_t);
+void ebus_set_led(struct channel_softc *, int, u_int8_t);
#define MUSYCC_LED_GREEN 0x1
#define MUSYCC_LED_RED 0x2