summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2007-04-20 01:38:33 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2007-04-20 01:38:33 +0000
commit61258c6611dd734617851906e722a53e39f3e533 (patch)
tree2d86ccaf3b56725102b3cf86cd3aa689cc894a07 /sys
parentc632e6a3796ed8a2a089a1853581f80e04b5445b (diff)
implement checking of the link status according to the firmware, and teach
ifmedia about it. im not sure what the point of the ifmedia goo is if the only link type we support is "autoselect". using it to show the link state seems to be easier than implementing that ioctl ourselves.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_tht.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/sys/dev/pci/if_tht.c b/sys/dev/pci/if_tht.c
index 890006a6967..a18e4f8f422 100644
--- a/sys/dev/pci/if_tht.c
+++ b/sys/dev/pci/if_tht.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_tht.c,v 1.29 2007/04/20 00:41:32 dlg Exp $ */
+/* $OpenBSD: if_tht.c,v 1.30 2007/04/20 01:38:32 dlg Exp $ */
/*
* Copyright (c) 2007 David Gwynne <dlg@openbsd.org>
@@ -378,6 +378,7 @@ void tht_fifo_post(struct tht_softc *,
void tht_read_lladdr(struct tht_softc *);
int tht_sw_reset(struct tht_softc *);
int tht_fw_load(struct tht_softc *);
+void tht_link_state(struct tht_softc *);
/* interface operations */
int tht_ioctl(struct ifnet *, u_long, caddr_t);
@@ -617,7 +618,6 @@ tht_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
case SIOCSIFMEDIA:
error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd);
break;
-
default:
error = ENOTTY;
break;
@@ -650,10 +650,15 @@ tht_media_change(struct ifnet *ifp)
void
tht_media_status(struct ifnet *ifp, struct ifmediareq *imr)
{
+ struct tht_softc *sc = ifp->if_softc;
+
imr->ifm_active = IFM_ETHER | IFM_AUTO;
imr->ifm_status = IFM_AVALID;
- /* TODO: check link state */
+ tht_link_state(sc);
+
+ if (LINK_STATE_IS_UP(ifp->if_link_state) && ifp->if_flags & IFF_UP)
+ imr->ifm_status |= IFM_ACTIVE;
}
int
@@ -875,6 +880,21 @@ err:
return (error);
}
+void
+tht_link_state(struct tht_softc *sc)
+{
+ struct ifnet *ifp = &sc->sc_ac.ac_if;
+ int link_state = LINK_STATE_DOWN;
+
+ if (tht_read(sc, THT_REG_MAC_LNK_STAT) & THT_REG_MAC_LNK_STAT_LINK)
+ link_state = LINK_STATE_UP;
+
+ if (ifp->if_link_state != link_state) {
+ ifp->if_link_state = link_state;
+ if_link_state_change(ifp);
+ }
+}
+
u_int32_t
tht_read(struct tht_softc *sc, bus_size_t r)
{