summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/mii/Makefile8
-rw-r--r--sys/dev/mii/devlist2h.awk146
-rw-r--r--sys/dev/mii/exphy.c378
-rw-r--r--sys/dev/mii/files.mii24
-rw-r--r--sys/dev/mii/inphy.c397
-rw-r--r--sys/dev/mii/inphyreg.h101
-rw-r--r--sys/dev/mii/mii.c304
-rw-r--r--sys/dev/mii/mii.h127
-rw-r--r--sys/dev/mii/miidevs78
-rw-r--r--sys/dev/mii/miidevs.h94
-rw-r--r--sys/dev/mii/miivar.h147
-rw-r--r--sys/dev/mii/nsphy.c464
-rw-r--r--sys/dev/mii/nsphyreg.h114
-rw-r--r--sys/dev/mii/qsphy.c380
-rw-r--r--sys/dev/mii/qsphyreg.h85
-rw-r--r--sys/dev/mii/tlphy.c464
-rw-r--r--sys/dev/mii/tlphyreg.h58
-rw-r--r--sys/dev/mii/tlphyvar.h59
18 files changed, 3428 insertions, 0 deletions
diff --git a/sys/dev/mii/Makefile b/sys/dev/mii/Makefile
new file mode 100644
index 00000000000..93b6114a29f
--- /dev/null
+++ b/sys/dev/mii/Makefile
@@ -0,0 +1,8 @@
+# $OpenBSD: Makefile,v 1.1 1998/09/10 17:17:32 jason Exp $
+# $NetBSD: Makefile.miidevs,v 1.1 1998/08/10 23:55:17 thorpej Exp $
+
+AWK= awk
+
+miidevs.h: miidevs devlist2h.awk
+ /bin/rm -f miidevs.h
+ ${AWK} -f devlist2h.awk miidevs
diff --git a/sys/dev/mii/devlist2h.awk b/sys/dev/mii/devlist2h.awk
new file mode 100644
index 00000000000..ab12b82e80b
--- /dev/null
+++ b/sys/dev/mii/devlist2h.awk
@@ -0,0 +1,146 @@
+#! /usr/bin/awk -f
+# $OpenBSD: devlist2h.awk,v 1.1 1998/09/10 17:17:33 jason Exp $
+# $NetBSD: devlist2h.awk,v 1.2 1998/09/05 14:42:06 christos Exp $
+#
+# Copyright (c) 1998 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Christos Zoulas.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This product includes software developed by the NetBSD
+# Foundation, Inc. and its contributors.
+# 4. Neither the name of The NetBSD Foundation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Copyright (c) 1995, 1996 Christopher G. Demetriou
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. All advertising materials mentioning features or use of this software
+# must display the following acknowledgement:
+# This model includes software developed by Christopher G. Demetriou.
+# This model includes software developed by Christos Zoulas
+# 4. The name of the author(s) may not be used to endorse or promote models
+# derived from this software without specific prior written permission
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+function collectline(f, line) {
+ oparen = 0
+ line = ""
+ while (f <= NF) {
+ if ($f == "#") {
+ line = line "("
+ oparen = 1
+ f++
+ continue
+ }
+ if (oparen) {
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ continue
+ }
+ line = line $f
+ if (f < NF)
+ line = line " "
+ f++
+ }
+ if (oparen)
+ line = line ")"
+ return line
+}
+BEGIN {
+ nmodels = nouis = 0
+ hfile="miidevs.h"
+}
+NR == 1 {
+ VERSION = $0
+ gsub("\\$", "", VERSION)
+
+ printf("/*\t\$OpenBSD\$\t*/\n\n") > hfile
+ printf("/*\n") > hfile
+ printf(" * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.\n") \
+ > hfile
+ printf(" *\n") > hfile
+ printf(" * generated from:\n") > hfile
+ printf(" *\t%s\n", VERSION) > hfile
+ printf(" */\n") > hfile
+
+ next
+}
+$1 == "oui" {
+ nuios++
+
+ ouiindex[$2] = nouis; # record index for this name, for later.
+
+ ouis[nouis, 1] = $2; # name
+ ouis[nouis, 2] = $3; # id
+ printf("#define\tMII_OUI_%s\t%s\t", ouis[nouis, 1],
+ ouis[nouis, 2]) > hfile
+ ouis[nouis, 3] = collectline(4, line)
+ printf("/* %s */\n", ouis[nouis, 3]) > hfile
+ next
+}
+$1 == "model" {
+ nmodels++
+
+ models[nmodels, 1] = $2; # oui name
+ models[nmodels, 2] = $3; # model id
+ models[nmodels, 3] = $4; # id
+
+ printf("#define\tMII_MODEL_%s_%s\t%s\n", models[nmodels, 1],
+ models[nmodels, 2], models[nmodels, 3]) > hfile
+
+ models[nmodels, 4] = collectline(5, line)
+
+ printf("#define\tMII_STR_%s_%s\t\"%s\"\n",
+ models[nmodels, 1], models[nmodels, 2],
+ models[nmodels, 4]) > hfile
+
+ next
+}
+{
+ print $0 > hfile
+}
diff --git a/sys/dev/mii/exphy.c b/sys/dev/mii/exphy.c
new file mode 100644
index 00000000000..7c062f925ff
--- /dev/null
+++ b/sys/dev/mii/exphy.c
@@ -0,0 +1,378 @@
+/* $OpenBSD: exphy.c,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+/* $NetBSD: exphy.c,v 1.5 1998/08/28 12:50:36 fvdl Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center, and by Frank van der Linden.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * driver for 3Com internal PHYs
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/mii/miidevs.h>
+
+struct exphy_softc {
+ struct mii_softc sc_mii; /* generic PHY */
+ int sc_capabilities;
+ int sc_active;
+};
+
+#ifdef __NetBSD__
+int exphymatch __P((struct device *, struct cfdata *, void *));
+#else
+int exphymatch __P((struct device *, void *, void *));
+#endif
+void exphyattach __P((struct device *, struct device *, void *));
+
+struct cfattach exphy_ca = {
+ sizeof(struct exphy_softc), exphymatch, exphyattach
+};
+
+#ifdef __OpenBSD__
+struct cfdriver exphy_cd = {
+ NULL, "exphy", DV_DULL
+};
+#endif
+
+#define EXPHY_READ(sc, reg) \
+ (*(sc)->sc_mii.mii_pdata->mii_readreg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg))
+
+#define EXPHY_WRITE(sc, reg, val) \
+ (*(sc)->sc_mii.mii_pdata->mii_writereg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg), (val))
+
+int exphy_service __P((struct mii_softc *, struct mii_data *, int));
+void exphy_reset __P((struct exphy_softc *));
+void exphy_auto __P((struct exphy_softc *));
+void exphy_status __P((struct exphy_softc *));
+
+int
+exphymatch(parent, match, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *match;
+#else
+ void *match;
+#endif
+ void *aux;
+{
+ struct mii_attach_args *ma = aux;
+
+ /*
+ * Argh, 3Com PHY reports oui == 0 model == 0!
+ */
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == 0 &&
+ MII_MODEL(ma->mii_id2) == 0)
+ return (1);
+
+ return (0);
+}
+
+void
+exphyattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct exphy_softc *sc = (struct exphy_softc *)self;
+ struct mii_attach_args *ma = aux;
+ struct mii_data *mii = ma->mii_data;
+
+ printf(": 3Com internal media interface, rev. %d\n",
+ MII_REV(ma->mii_id2));
+
+ sc->sc_mii.mii_inst = mii->mii_instance;
+ sc->sc_mii.mii_phy = ma->mii_phyno;
+ sc->sc_mii.mii_service = exphy_service;
+ sc->sc_mii.mii_pdata = mii;
+
+ /*
+ * The 3Com PHY can never be isolated, so never allow non-zero
+ * instances!
+ */
+ if (mii->mii_instance != 0) {
+ printf("%s: ignoring this PHY, non-zero instance\n",
+ sc->sc_mii.mii_dev.dv_xname);
+ return;
+ }
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst),
+ BMCR_ISO);
+
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->sc_mii.mii_inst),
+ BMCR_LOOP|BMCR_S100);
+
+ exphy_reset(sc);
+
+ sc->sc_capabilities = EXPHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ printf("%s: ", sc->sc_mii.mii_dev.dv_xname);
+ if ((sc->sc_capabilities & BMSR_MEDIAMASK) == 0)
+ printf("no media present");
+ else
+ mii_add_media(mii, sc->sc_capabilities, sc->sc_mii.mii_inst);
+ printf("\n");
+#undef ADD
+}
+
+int
+exphy_service(self, mii, cmd)
+ struct mii_softc *self;
+ struct mii_data *mii;
+ int cmd;
+{
+ struct exphy_softc *sc = (struct exphy_softc *)self;
+
+ /*
+ * We can't isolate the 3Com PHY, so it has to be the only one!
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) != sc->sc_mii.mii_inst)
+ panic("exphy_service: can't isolate 3Com PHY");
+
+
+ switch (cmd) {
+ case MII_POLLSTAT:
+ break;
+
+ case MII_MEDIACHG:
+ /*
+ * If the interface is not up, don't do anything.
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ break;
+
+ switch (IFM_SUBTYPE(mii->mii_media.ifm_media)) {
+ case IFM_AUTO:
+ /*
+ * If we're already in auto mode, just return.
+ */
+ if (EXPHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
+ return (0);
+ exphy_auto(sc);
+ break;
+ case IFM_100_T4:
+ /*
+ * XXX Not supported as a manual setting right now.
+ */
+ return (EINVAL);
+ default:
+ /*
+ * BMCR data is stored in the ifmedia entry.
+ */
+ EXPHY_WRITE(sc, MII_ANAR,
+ mii_anar(mii->mii_media.ifm_media));
+ EXPHY_WRITE(sc, MII_BMCR,
+ mii->mii_media.ifm_cur->ifm_data);
+ }
+ break;
+
+ case MII_TICK:
+ /*
+ * Only used for autonegotiation.
+ */
+ if (IFM_SUBTYPE(mii->mii_media.ifm_media) != IFM_AUTO)
+ return (0);
+
+ /*
+ * Is the interface even up?
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ return (0);
+
+ /*
+ * The 3Com PHY's autonegotiation doesn't need to be
+ * kicked; it continues in the background.
+ */
+ break;
+ }
+
+ /* Update the media status. */
+ exphy_status(sc);
+
+ /* Callback if something changed. */
+ if (sc->sc_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
+ (*mii->mii_statchg)(sc->sc_mii.mii_dev.dv_parent);
+ sc->sc_active = mii->mii_media_active;
+ }
+ return (0);
+}
+
+void
+exphy_status(sc)
+ struct exphy_softc *sc;
+{
+ struct mii_data *mii = sc->sc_mii.mii_pdata;
+ int bmsr, bmcr, anlpar;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = EXPHY_READ(sc, MII_BMSR) | EXPHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = EXPHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BMCR_AUTOEN) {
+ /*
+ * The 3Com PHY uses the highest-order common bit of
+ * the ANAR and ANLPAR (i.e. best media advertised
+ * both by us and our link partner).
+ */
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+
+ anlpar = EXPHY_READ(sc, MII_ANAR) & EXPHY_READ(sc, MII_ANLPAR);
+ if (anlpar & ANLPAR_T4)
+ mii->mii_media_active |= IFM_100_T4;
+ else if (anlpar & ANLPAR_TX_FD)
+ mii->mii_media_active |= IFM_100_TX|IFM_FDX;
+ else if (anlpar & ANLPAR_TX)
+ mii->mii_media_active |= IFM_100_TX;
+ else if (anlpar & ANLPAR_10_FD)
+ mii->mii_media_active |= IFM_10_T|IFM_FDX;
+ else if (anlpar & ANLPAR_10)
+ mii->mii_media_active |= IFM_10_T;
+ else
+ mii->mii_media_active |= IFM_NONE;
+ } else {
+ if (bmcr & BMCR_S100)
+ mii->mii_media_active |= IFM_100_TX;
+ else
+ mii->mii_media_active |= IFM_10_T;
+ if (bmcr & BMCR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ }
+}
+
+void
+exphy_auto(sc)
+ struct exphy_softc *sc;
+{
+ int bmsr, i;
+
+ EXPHY_WRITE(sc, MII_ANAR,
+ BMSR_MEDIA_TO_ANAR(sc->sc_capabilities) | ANAR_CSMA);
+ EXPHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ /* Wait 500ms for it to complete. */
+ for (i = 0; i < 500; i++) {
+ if ((bmsr = EXPHY_READ(sc, MII_BMSR)) & BMSR_ACOMP)
+ return;
+ delay(1000);
+ }
+#if 0
+ if ((bmsr & BMSR_ACOMP) == 0)
+ printf("%s: autonegotiation failed to complete\n",
+ sc->sc_mii.mii_dev.dv_xname);
+#endif
+}
+
+void
+exphy_reset(sc)
+ struct exphy_softc *sc;
+{
+ int reg, i;
+
+ EXPHY_WRITE(sc, MII_BMCR, BMCR_RESET);
+
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = EXPHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ /*
+ * XXX 3Com PHY doesn't set the BMCR properly after
+ * XXX reset, which breaks autonegotiation.
+ */
+ EXPHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_AUTOEN|BMCR_FDX);
+}
diff --git a/sys/dev/mii/files.mii b/sys/dev/mii/files.mii
new file mode 100644
index 00000000000..c8d7e79b420
--- /dev/null
+++ b/sys/dev/mii/files.mii
@@ -0,0 +1,24 @@
+# $OpenBSD: files.mii,v 1.1 1998/09/10 17:17:33 jason Exp $
+# $NetBSD: files.mii,v 1.7 1998/08/12 08:46:20 thorpej Exp $
+
+file dev/mii/mii.c mii
+
+device tlphy
+attach tlphy at mii
+file dev/mii/tlphy.c tlphy
+
+device nsphy
+attach nsphy at mii
+file dev/mii/nsphy.c nsphy
+
+device qsphy
+attach qsphy at mii
+file dev/mii/qsphy.c qsphy
+
+device inphy
+attach inphy at mii
+file dev/mii/inphy.c inphy
+
+device exphy
+attach exphy at mii
+file dev/mii/exphy.c exphy
diff --git a/sys/dev/mii/inphy.c b/sys/dev/mii/inphy.c
new file mode 100644
index 00000000000..70cedb54345
--- /dev/null
+++ b/sys/dev/mii/inphy.c
@@ -0,0 +1,397 @@
+/* $OpenBSD: inphy.c,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+/* $NetBSD: inphy.c,v 1.3 1998/08/12 20:56:35 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * driver for Intel's i82555 ethernet 10/100 PHY
+ * Data Sheet available from www.intel.com
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/mii/miidevs.h>
+
+#include <dev/mii/inphyreg.h>
+
+struct inphy_softc {
+ struct mii_softc sc_mii; /* generic PHY */
+ int sc_capabilities;
+ int sc_ticks;
+ int sc_active;
+};
+
+#ifdef __NetBSD__
+int inphymatch __P((struct device *, struct cfdata *, void *));
+#else
+int inphymatch __P((struct device *, void *, void *));
+#endif
+void inphyattach __P((struct device *, struct device *, void *));
+
+struct cfattach inphy_ca = {
+ sizeof(struct inphy_softc), inphymatch, inphyattach
+};
+
+#ifdef __OpenBSD__
+struct cfdriver inphy_cd = {
+ NULL, "inphy", DV_DULL
+};
+#endif
+
+#define INPHY_READ(sc, reg) \
+ (*(sc)->sc_mii.mii_pdata->mii_readreg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg))
+
+#define INPHY_WRITE(sc, reg, val) \
+ (*(sc)->sc_mii.mii_pdata->mii_writereg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg), (val))
+
+int inphy_service __P((struct mii_softc *, struct mii_data *, int));
+void inphy_reset __P((struct inphy_softc *));
+void inphy_auto __P((struct inphy_softc *));
+void inphy_status __P((struct inphy_softc *));
+
+int
+inphymatch(parent, match, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *match;
+#else
+ void *match;
+#endif
+ void *aux;
+{
+ struct mii_attach_args *ma = aux;
+
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_INTEL &&
+ MII_MODEL(ma->mii_id2) == MII_MODEL_INTEL_I82555)
+ return (1);
+
+ return (0);
+}
+
+void
+inphyattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct inphy_softc *sc = (struct inphy_softc *)self;
+ struct mii_attach_args *ma = aux;
+ struct mii_data *mii = ma->mii_data;
+
+ printf(": %s, rev. %d\n", MII_STR_INTEL_I82555,
+ MII_REV(ma->mii_id2));
+
+ sc->sc_mii.mii_inst = mii->mii_instance;
+ sc->sc_mii.mii_phy = ma->mii_phyno;
+ sc->sc_mii.mii_service = inphy_service;
+ sc->sc_mii.mii_pdata = mii;
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+#if 0
+ /* Can't do this on the i82557! */
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst),
+ BMCR_ISO);
+#endif
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->sc_mii.mii_inst),
+ BMCR_LOOP|BMCR_S100);
+
+ inphy_reset(sc);
+
+ sc->sc_capabilities = INPHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ printf("%s: ", sc->sc_mii.mii_dev.dv_xname);
+ if ((sc->sc_capabilities & BMSR_MEDIAMASK) == 0)
+ printf("no media present");
+ else
+ mii_add_media(mii, sc->sc_capabilities, sc->sc_mii.mii_inst);
+ printf("\n");
+#undef ADD
+}
+
+int
+inphy_service(self, mii, cmd)
+ struct mii_softc *self;
+ struct mii_data *mii;
+ int cmd;
+{
+ struct inphy_softc *sc = (struct inphy_softc *)self;
+ int reg;
+
+ switch (cmd) {
+ case MII_POLLSTAT:
+ /*
+ * If we're not polling our PHY instance, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+ break;
+
+ case MII_MEDIACHG:
+ /*
+ * If the media indicates a different PHY instance,
+ * isolate ourselves.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst) {
+ reg = INPHY_READ(sc, MII_BMCR);
+ INPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+ return (0);
+ }
+
+ /*
+ * If the interface is not up, don't do anything.
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ break;
+
+ switch (IFM_SUBTYPE(mii->mii_media.ifm_media)) {
+ case IFM_AUTO:
+ /*
+ * If we're already in auto mode, just return.
+ */
+ if (INPHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
+ return (0);
+ inphy_auto(sc);
+ break;
+ case IFM_100_T4:
+ /*
+ * XXX Not supported as a manual setting right now.
+ */
+ return (EINVAL);
+ default:
+ /*
+ * BMCR data is stored in the ifmedia entry.
+ */
+ INPHY_WRITE(sc, MII_ANAR,
+ mii_anar(mii->mii_media.ifm_media));
+ INPHY_WRITE(sc, MII_BMCR,
+ mii->mii_media.ifm_cur->ifm_data);
+ }
+ break;
+
+ case MII_TICK:
+ /*
+ * If we're not currently selected, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+
+ /*
+ * Only used for autonegotiation.
+ */
+ if (IFM_SUBTYPE(mii->mii_media.ifm_media) != IFM_AUTO)
+ return (0);
+
+ /*
+ * Is the interface even up?
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ return (0);
+
+ /*
+ * Check to see if we have link. If we do, we don't
+ * need to restart the autonegotiation process. Read
+ * the BMSR twice in case it's latched.
+ */
+ reg = INPHY_READ(sc, MII_BMSR) | INPHY_READ(sc, MII_BMSR);
+ if (reg & BMSR_LINK)
+ return (0);
+
+ /*
+ * Only retry autonegotiation every 5 seconds.
+ */
+ if (++sc->sc_ticks != 5)
+ return (0);
+
+ sc->sc_ticks = 0;
+ inphy_reset(sc);
+ inphy_auto(sc);
+ break;
+ }
+
+ /* Update the media status. */
+ inphy_status(sc);
+
+ /* Callback if something changed. */
+ if (sc->sc_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
+ (*mii->mii_statchg)(sc->sc_mii.mii_dev.dv_parent);
+ sc->sc_active = mii->mii_media_active;
+ }
+ return (0);
+}
+
+void
+inphy_status(sc)
+ struct inphy_softc *sc;
+{
+ struct mii_data *mii = sc->sc_mii.mii_pdata;
+ int bmsr, bmcr, scr;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = INPHY_READ(sc, MII_BMSR) | INPHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = INPHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BMCR_AUTOEN) {
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+ scr = INPHY_READ(sc, MII_INPHY_SCR);
+ if (scr & SCR_T4)
+ mii->mii_media_active |= IFM_100_T4;
+ else if (scr & SCR_S100)
+ mii->mii_media_active |= IFM_100_TX;
+ else
+ mii->mii_media_active |= IFM_10_T;
+ if (scr & SCR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ } else {
+ if (bmcr & BMCR_S100)
+ mii->mii_media_active |= IFM_100_TX;
+ else
+ mii->mii_media_active |= IFM_10_T;
+ if (bmcr & BMCR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ }
+}
+
+void
+inphy_auto(sc)
+ struct inphy_softc *sc;
+{
+ int bmsr, i;
+
+ INPHY_WRITE(sc, MII_ANAR,
+ BMSR_MEDIA_TO_ANAR(sc->sc_capabilities) | ANAR_CSMA);
+ INPHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ /* Wait 500ms for it to complete. */
+ for (i = 0; i < 500; i++) {
+ if ((bmsr = INPHY_READ(sc, MII_BMSR)) & BMSR_ACOMP)
+ return;
+ delay(1000);
+ }
+#if 0
+ if ((bmsr & BMSR_ACOMP) == 0)
+ printf("%s: autonegotiation failed to complete\n",
+ sc->sc_mii.mii_dev.dv_xname);
+#endif
+}
+
+void
+inphy_reset(sc)
+ struct inphy_softc *sc;
+{
+ int reg, i;
+
+ /*
+ * The i82557 wedges if we isolate all of its PHYs!
+ */
+ if (sc->sc_mii.mii_inst == 0)
+ INPHY_WRITE(sc, MII_BMCR, BMCR_RESET);
+ else
+ INPHY_WRITE(sc, MII_BMCR, BMCR_RESET|BMCR_ISO);
+
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = INPHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ /* Make sure the PHY is isolated. */
+ if (sc->sc_mii.mii_inst != 0)
+ INPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+}
diff --git a/sys/dev/mii/inphyreg.h b/sys/dev/mii/inphyreg.h
new file mode 100644
index 00000000000..c637a83ec06
--- /dev/null
+++ b/sys/dev/mii/inphyreg.h
@@ -0,0 +1,101 @@
+/* $OpenBSD: inphyreg.h,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+/* $NetBSD: inphyreg.h,v 1.1 1998/08/11 00:00:28 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_INPHYREG_H_
+#define _DEV_MII_INPHYREG_H_
+
+/*
+ * Intel 82555 registers.
+ */
+
+#define MII_INPHY_SCR 0x10 /* Status and Control */
+#define SCR_FLOWCTL 0x8000 /* PHY Base flow control enabled */
+#define SCR_CSDC 0x2000 /* Carrier sense disconnect control */
+#define SCR_TFCD 0x1000 /* Transmit flow control disable */
+#define SCR_RDSI 0x0800 /* Receive deserializer in-sync */
+#define SCR_100TXPD 0x0400 /* 100baseTX is powered down */
+#define SCR_10TPD 0x0200 /* 10baseT is powered down */
+#define SCR_POLARITY 0x0100 /* reverse 10baseT polarity */
+#define SCR_T4 0x0004 /* autoneg resulted in 100baseT4 */
+#define SCR_S100 0x0002 /* autoneg resulted in 100baseTX */
+#define SCR_FDX 0x0001 /* autoneg resulted in full-duplex */
+
+#define MII_INPHY_SCTRL 0x11 /* Special Control Bit */
+#define SCTRL_SCRBYPASS 0x8000 /* scrambler bypass */
+#define SCTRL_4B5BNYPASS 0x4000 /* 4bit to 5bit bypass */
+#define SCTRL_FTHP 0x2000 /* force transmit H-pattern */
+#define SCTRL_F34TP 0x1000 /* force 34 transmit patter */
+#define SCTRL_GOODLINK 0x0800 /* 100baseTX link good */
+#define SCTRL_TCSD 0x0200 /* transmit carrier sense disable */
+#define SCTRL_DDPD 0x0100 /* disable dynamic power-down */
+#define SCTRL_ANEGLOOP 0x0080 /* autonegotiaion loopback */
+#define SCTRL_MDITRISTATE 0x0040 /* MDI Tri-state */
+#define SCTRL_FILTERBYPASS 0x0020 /* Filter bypass */
+#define SCTRL_AUTOPOLDIS 0x0010 /* auto-polarity disable */
+#define SCTRL_SQUELCHDIS 0x0008 /* squlch test disable */
+#define SCTRL_EXTSQUELCH 0x0004 /* extended sequelch enable */
+#define SCTRL_LINKINTDIS 0x0002 /* link integrity disable */
+#define SCTRL_JABBERDIS 0x0001 /* jabber disabled */
+
+#define MII_INPHY_100TXRDC 0x14 /* 100baseTX Receive Disconnect Cntr */
+
+#define MII_INPHY_100TXREFC 0x15 /* 100baseTX Receive Error Frame Ctr */
+
+#define MII_INPHY_RSEC 0x16 /* Receive Symbol Error Counter */
+
+#define MII_INPHY_100TXRPEOFC 0x17 /* 100baseTX Rcv Premature EOF Ctr */
+
+#define MII_INPHY_10TREOFC 0x18 /* 10baseT Rcv EOF Ctr */
+
+#define MII_INPHY_10TTJDC 0x19 /* 10baseT Tx Jabber Detect Ctr */
+
+#define MII_INPHY_SCTRL2 0x21 /* 82555 Special Control */
+#define SCTRL2_LEDMASK 0x0007 /* mask of LEDs control: see below */
+
+#define LEDMASK_ACTLINK 0x0000 /* A = Activity, L = Link */
+#define LEDMASK_SPDCOLL 0x0001 /* A = Speed, L = Collision */
+#define LEDMASK_SPDLINK 0x0002 /* A = Speed, L = Link */
+#define LEDMASK_ACTCOLL 0x0003 /* A = Activity, L = Collision */
+#define LEDMASK_OFFOFF 0x0004 /* A = off, L = off */
+#define LEDMASK_OFFON 0x0005 /* A = off, L = on */
+#define LEDMASK_ONOFF 0x0006 /* A = on, L = off */
+#define LESMASK_ONON 0x0007 /* A = on, L = on */
+
+#endif /* _DEV_MII_INPHYREG_H_ */
diff --git a/sys/dev/mii/mii.c b/sys/dev/mii/mii.c
new file mode 100644
index 00000000000..40cc6e12194
--- /dev/null
+++ b/sys/dev/mii/mii.c
@@ -0,0 +1,304 @@
+/* $OpenBSD: mii.c,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+/* $NetBSD: mii.c,v 1.7 1998/08/11 00:41:44 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * MII bus layer, glues MII-capable network interface drivers to sharable
+ * PHY drivers. This exports an interface compatible with BSD/OS 3.0's,
+ * plus some NetBSD extensions.
+ */
+
+#include <sys/param.h>
+#include <sys/device.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+int mii_print __P((void *, const char *));
+#ifdef __NetBSD__
+int mii_submatch __P((struct device *, struct cfdata *, void *));
+#else
+int mii_submatch __P((struct device *, void *, void *));
+#endif
+
+#ifdef __OpenBSD__
+#define MIICF_PHY 0 /* cf_loc index */
+#define MIICF_PHY_DEFAULT (-1) /* default phy device */
+#endif
+
+/*
+ * Helper function used by network interface drivers, attaches PHYs
+ * to the network interface driver parent.
+ */
+void
+mii_phy_probe(parent, mii, capmask)
+ struct device *parent;
+ struct mii_data *mii;
+ int capmask;
+{
+ struct mii_attach_args ma;
+ struct mii_softc *child;
+
+ LIST_INIT(&mii->mii_phys);
+
+ for (ma.mii_phyno = 0; ma.mii_phyno < MII_NPHY; ma.mii_phyno++) {
+ /*
+ * Check to see if there is a PHY at this address. If
+ * the register contains garbage, assume no.
+ */
+ ma.mii_id1 = (*mii->mii_readreg)(parent, ma.mii_phyno,
+ MII_PHYIDR1);
+ ma.mii_id2 = (*mii->mii_readreg)(parent, ma.mii_phyno,
+ MII_PHYIDR2);
+ if (ma.mii_id1 == 0 || ma.mii_id1 == 0xffff ||
+ ma.mii_id2 == 0 || ma.mii_id2 == 0xffff) {
+ /*
+ * ARGH!! 3Com internal PHYs report 0/0 in their
+ * ID registers! If we spot this, check to see
+ * if the BMSR has reasonable data in it.
+ */
+ if (MII_OUI(ma.mii_id1, ma.mii_id2) == 0 &&
+ MII_MODEL(ma.mii_id2) == 0) {
+ int bmsr = (*mii->mii_readreg)(parent,
+ ma.mii_phyno, MII_BMSR);
+ if (bmsr == 0 || bmsr == 0xffff ||
+ (bmsr & BMSR_MEDIAMASK) == 0)
+ continue;
+ } else
+ continue;
+ }
+
+ ma.mii_data = mii;
+ ma.mii_capmask = capmask;
+
+ if ((child = (struct mii_softc *)config_found_sm(parent, &ma,
+ mii_print, mii_submatch)) != NULL) {
+ /*
+ * Link it up in the parent's MII data.
+ */
+ LIST_INSERT_HEAD(&mii->mii_phys, child, mii_list);
+ mii->mii_instance++;
+ }
+ }
+}
+
+int
+mii_print(aux, pnp)
+ void *aux;
+ const char *pnp;
+{
+ struct mii_attach_args *ma = aux;
+
+ if (pnp != NULL)
+ printf("PHY oui 0x%x model 0x%x rev 0x%x at %s",
+ MII_OUI(ma->mii_id1, ma->mii_id2), MII_MODEL(ma->mii_id2),
+ MII_REV(ma->mii_id2), pnp);
+
+ printf(" phy %d", ma->mii_phyno);
+ return (UNCONF);
+}
+
+#ifdef __NetBSD__
+int
+mii_submatch(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+#else
+int
+mii_submatch(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct cfdata *cf = match;
+#endif
+ struct mii_attach_args *ma = aux;
+
+ if (ma->mii_phyno != cf->cf_loc[MIICF_PHY] &&
+ cf->cf_loc[MIICF_PHY] != MIICF_PHY_DEFAULT)
+ return (0);
+
+ return ((*cf->cf_attach->ca_match)(parent, cf, aux));
+}
+
+/*
+ * Given an ifmedia word, return the corresponding ANAR value.
+ */
+int
+mii_anar(media)
+ int media;
+{
+ int rv;
+
+ switch (media & (IFM_TMASK|IFM_NMASK|IFM_FDX)) {
+ case IFM_ETHER|IFM_10_T:
+ rv = ANAR_10|ANAR_CSMA;
+ break;
+ case IFM_ETHER|IFM_10_T|IFM_FDX:
+ rv = ANAR_10_FD|ANAR_CSMA;
+ break;
+ case IFM_ETHER|IFM_100_TX:
+ rv = ANAR_TX|ANAR_CSMA;
+ break;
+ case IFM_ETHER|IFM_100_TX|IFM_FDX:
+ rv = ANAR_TX_FD|ANAR_CSMA;
+ break;
+ case IFM_ETHER|IFM_100_T4:
+ rv = ANAR_T4|ANAR_CSMA;
+ break;
+ default:
+ rv = 0;
+ break;
+ }
+
+ return (rv);
+}
+
+/*
+ * Media changed; notify all PHYs.
+ */
+int
+mii_mediachg(mii)
+ struct mii_data *mii;
+{
+ struct mii_softc *child;
+ int rv;
+
+ mii->mii_media_status = 0;
+ mii->mii_media_active = IFM_NONE;
+
+ for (child = LIST_FIRST(&mii->mii_phys); child != NULL;
+ child = LIST_NEXT(child, mii_list)) {
+ rv = (*child->mii_service)(child, mii, MII_MEDIACHG);
+ if (rv)
+ return (rv);
+ }
+ return (0);
+}
+
+/*
+ * Call the PHY tick routines, used during autonegotiation.
+ */
+void
+mii_tick(mii)
+ struct mii_data *mii;
+{
+ struct mii_softc *child;
+
+ for (child = LIST_FIRST(&mii->mii_phys); child != NULL;
+ child = LIST_NEXT(child, mii_list))
+ (void) (*child->mii_service)(child, mii, MII_TICK);
+}
+
+/*
+ * Get media status from PHYs.
+ */
+void
+mii_pollstat(mii)
+ struct mii_data *mii;
+{
+ struct mii_softc *child;
+
+ mii->mii_media_status = 0;
+ mii->mii_media_active = IFM_NONE;
+
+ for (child = LIST_FIRST(&mii->mii_phys); child != NULL;
+ child = LIST_NEXT(child, mii_list))
+ (void) (*child->mii_service)(child, mii, MII_POLLSTAT);
+}
+
+/*
+ * Initialize generic PHY media based on BMSR, called when a PHY is
+ * attached. We expect to be set up to print a comma-separated list
+ * of media names. Does not print a newline.
+ */
+void
+mii_add_media(mii, bmsr, instance)
+ struct mii_data *mii;
+ int bmsr, instance;
+{
+ const char *sep = "";
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+#define PRINT(s) printf("%s%s", sep, s); sep = ", "
+
+ if (bmsr & BMSR_10THDX) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, instance), 0);
+ PRINT("10baseT");
+ }
+ if (bmsr & BMSR_10TFDX) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, instance),
+ BMCR_FDX);
+ PRINT("10baseT-FDX");
+ }
+ if (bmsr & BMSR_100TXHDX) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, instance),
+ BMCR_S100);
+ PRINT("100baseTX");
+ }
+ if (bmsr & BMSR_100TXFDX) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, instance),
+ BMCR_S100|BMCR_FDX);
+ PRINT("100baseTX-FDX");
+ }
+ if (bmsr & BMSR_100T4) {
+ /*
+ * XXX How do you enable 100baseT4? I assume we set
+ * XXX BMCR_S100 and then assume the PHYs will take
+ * XXX watever action is necessary to switch themselves
+ * XXX into T4 mode.
+ */
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_T4, 0, instance),
+ BMCR_S100);
+ PRINT("100baseT4");
+ }
+ if (bmsr & BMSR_ANEG) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance),
+ BMCR_AUTOEN);
+ PRINT("auto");
+ }
+#undef ADD
+#undef PRINT
+}
diff --git a/sys/dev/mii/mii.h b/sys/dev/mii/mii.h
new file mode 100644
index 00000000000..798bd488e6d
--- /dev/null
+++ b/sys/dev/mii/mii.h
@@ -0,0 +1,127 @@
+/* $OpenBSD: mii.h,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+/* $NetBSD: mii.h,v 1.1 1998/08/10 23:55:17 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Modification to match BSD/OS 3.0 MII interface by Jason R. Thorpe,
+ * Numerical Aerospace Simulation Facility, NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_MII_H_
+#define _DEV_MII_MII_H_
+
+/*
+ * Registers common to all PHYs.
+ */
+
+#define MII_NPHY 32 /* max # of PHYs per MII */
+
+/*
+ * MII commands, used if a device must drive the MII lines
+ * manually.
+ */
+#define MII_COMMAND_START 0x01
+#define MII_COMMAND_READ 0x02
+#define MII_COMMAND_WRITE 0x01
+#define MII_COMMAND_ACK 0x02
+
+#define MII_BMCR 0x00 /* Basic mode control register (rw) */
+#define BMCR_RESET 0x8000 /* reset */
+#define BMCR_LOOP 0x4000 /* loopback */
+#define BMCR_S100 0x2000 /* speed (10/100) select */
+#define BMCR_AUTOEN 0x1000 /* autonegotiation enable */
+#define BMCR_PDOWN 0x0800 /* power down */
+#define BMCR_ISO 0x0400 /* isolate */
+#define BMCR_STARTNEG 0x0200 /* restart autonegotiation */
+#define BMCR_FDX 0x0100 /* Set duplex mode */
+#define BMCR_CTEST 0x0080 /* collision test */
+
+#define MII_BMSR 0x01 /* Basic mode status register (ro) */
+#define BMSR_100T4 0x8000 /* 100 base T4 capable */
+#define BMSR_100TXFDX 0x4000 /* 100 base Tx full duplex capable */
+#define BMSR_100TXHDX 0x2000 /* 100 base Tx half duplex capable */
+#define BMSR_10TFDX 0x1000 /* 10 base T full duplex capable */
+#define BMSR_10THDX 0x0800 /* 10 base T half duplex capable */
+#define BMSR_ACOMP 0x0020 /* Autonegotiation complete */
+#define BMSR_RFAULT 0x0010 /* Link partner fault */
+#define BMSR_ANEG 0x0008 /* Autonegotiation capable */
+#define BMSR_LINK 0x0004 /* Link status */
+#define BMSR_JABBER 0x0002 /* Jabber detected */
+#define BMSR_EXT 0x0001 /* Extended capability */
+
+#define BMSR_MEDIAMASK (BMSR_100T4|BMSR_100TXFDX|BMSR_100TXHDX|BMSR_10TFDX| \
+ BMSR_10THDX|BMSR_ANEG)
+
+/*
+ * Convert BMSR media capabilities to ANAR bits for autonegotiation.
+ * Note the shift chopps off the BMSR_ANEG bit.
+ */
+#define BMSR_MEDIA_TO_ANAR(x) (((x) & BMSR_MEDIAMASK) >> 6)
+
+#define MII_PHYIDR1 0x02 /* ID register 1 (ro) */
+
+#define MII_PHYIDR2 0x03 /* ID register 2 (ro) */
+#define IDR2_OUILSB 0xfc00 /* OUI LSB */
+#define IDR2_MODEL 0x03f0 /* vendor model */
+#define IDR2_REV 0x000f /* vendor revision */
+
+#define MII_OUI(id1, id2) (((id1) << 6) | ((id2) >> 10))
+#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
+#define MII_REV(id2) ((id2) & IDR2_REV)
+
+#define MII_ANAR 0x04 /* Autonegotiation advertisement (rw) */
+#define ANAR_NP 0x8000 /* Next page (ro) */
+#define ANAR_ACK 0x4000 /* link partner abilities acknowledged (ro) */
+#define ANAR_RF 0x2000 /* remote fault (ro) */
+#define ANAR_T4 0x0200 /* local device supports 100bT4 */
+#define ANAR_TX_FD 0x0100 /* local device supports 100bTx FD */
+#define ANAR_TX 0x0080 /* local device supports 100bTx */
+#define ANAR_10_FD 0x0040 /* local device supports 10bT FD */
+#define ANAR_10 0x0020 /* local device supports 10bT */
+#define ANAR_CSMA 0x0001 /* protocol selector CSMA/CD */
+
+#define MII_ANLPAR 0x05 /* Autonegotiation lnk partner abilities (rw) */
+#define ANLPAR_NP 0x8000 /* Next page (ro) */
+#define ANLPAR_ACK 0x4000 /* link partner accepted ACK (ro) */
+#define ANLPAR_RF 0x2000 /* remote fault (ro) */
+#define ANLPAR_T4 0x0200 /* link partner supports 100bT4 */
+#define ANLPAR_TX_FD 0x0100 /* link partner supports 100bTx FD */
+#define ANLPAR_TX 0x0080 /* link partner supports 100bTx */
+#define ANLPAR_10_FD 0x0040 /* link partner supports 10bT FD */
+#define ANLPAR_10 0x0020 /* link partner supports 10bT */
+#define ANLPAR_CSMA 0x0001 /* protocol selector CSMA/CD */
+
+#define MII_ANER 0x06 /* Autonegotiation expansion (ro) */
+#define ANER_MLF 0x0010 /* multiple link detection fault */
+#define ANER_LPNP 0x0008 /* link parter next page-able */
+#define ANER_NP 0x0004 /* next page-able */
+#define ANER_PAGE_RX 0x0002 /* Page received */
+#define ANER_LPAN 0x0001 /* link parter autoneg-able */
+
+#endif /* _DEV_MII_MII_H_ */
diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs
new file mode 100644
index 00000000000..efb94e62f44
--- /dev/null
+++ b/sys/dev/mii/miidevs
@@ -0,0 +1,78 @@
+$OpenBSD: miidevs,v 1.1 1998/09/10 17:17:33 jason Exp $
+/* $NetBSD: miidevs,v 1.1 1998/08/10 23:55:17 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * List of known MII OUIs
+ */
+
+oui ICS 0x00057d Integrated Circuit Systems
+oui INTEL 0x00aa00 Intel
+oui LEVEL1 0x1e0400 Level 1
+oui NATSEMI 0x080017 National Semiconductor
+oui QUALSEMI 0x006051 Quality Semiconductor
+oui SEEQ 0x0005be Seeq
+oui TI 0x100014 Texas Instruments
+
+/*
+ * List of known models. Grouped by oui.
+ */
+
+/* Integrated Circuit Systems PHYs */
+model ICS 1890 0x0002 ICS1890 10/100 media interface
+
+/* Intel PHYs */
+model INTEL I82555 0x0015 i82555 10/100 media interface
+
+/* Level 1 PHYs */
+model LEVEL1 LXT970 0x0000 LXT970 10/100 media interface
+
+/* National Semiconductor PHYs */
+model NATSEMI DP83840 0x0000 DP83840 10/100 media interface
+model NATSEMI DP83843 0x0001 DP83843 10/100 media interface
+
+/* Quality Semiconductor PHYs */
+model QUALSEMI QS6612 0x0000 QS6612 10/100 media interface
+
+/* Seeq PHYs */
+model SEEQ 80220 0x0003 Seeq 80220 10/100 media interface
+
+/* Texas Instruments PHYs */
+model TI TLAN10T 0x0001 ThunderLAN 10baseT media interface
+model TI 100VGPMI 0x0002 ThunderLAN 100VG-AnyLan media interface
diff --git a/sys/dev/mii/miidevs.h b/sys/dev/mii/miidevs.h
new file mode 100644
index 00000000000..8b5fcc68613
--- /dev/null
+++ b/sys/dev/mii/miidevs.h
@@ -0,0 +1,94 @@
+/* $OpenBSD: miidevs.h,v 1.1 1998/09/10 17:17:33 jason Exp $ */
+
+/*
+ * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT.
+ *
+ * generated from:
+ * OpenBSD
+ */
+/* $NetBSD: miidevs,v 1.1 1998/08/10 23:55:17 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * List of known MII OUIs
+ */
+
+#define MII_OUI_ICS 0x00057d /* Integrated Circuit Systems */
+#define MII_OUI_INTEL 0x00aa00 /* Intel */
+#define MII_OUI_LEVEL1 0x1e0400 /* Level 1 */
+#define MII_OUI_NATSEMI 0x080017 /* National Semiconductor */
+#define MII_OUI_QUALSEMI 0x006051 /* Quality Semiconductor */
+#define MII_OUI_SEEQ 0x0005be /* Seeq */
+#define MII_OUI_TI 0x100014 /* Texas Instruments */
+
+/*
+ * List of known models. Grouped by oui.
+ */
+
+/* Integrated Circuit Systems PHYs */
+#define MII_MODEL_ICS_1890 0x0002
+#define MII_STR_ICS_1890 "ICS1890 10/100 media interface"
+
+/* Intel PHYs */
+#define MII_MODEL_INTEL_I82555 0x0015
+#define MII_STR_INTEL_I82555 "i82555 10/100 media interface"
+
+/* Level 1 PHYs */
+#define MII_MODEL_LEVEL1_LXT970 0x0000
+#define MII_STR_LEVEL1_LXT970 "LXT970 10/100 media interface"
+
+/* National Semiconductor PHYs */
+#define MII_MODEL_NATSEMI_DP83840 0x0000
+#define MII_STR_NATSEMI_DP83840 "DP83840 10/100 media interface"
+#define MII_MODEL_NATSEMI_DP83843 0x0001
+#define MII_STR_NATSEMI_DP83843 "DP83843 10/100 media interface"
+
+/* Quality Semiconductor PHYs */
+#define MII_MODEL_QUALSEMI_QS6612 0x0000
+#define MII_STR_QUALSEMI_QS6612 "QS6612 10/100 media interface"
+
+/* Seeq PHYs */
+#define MII_MODEL_SEEQ_80220 0x0003
+#define MII_STR_SEEQ_80220 "Seeq 80220 10/100 media interface"
+
+/* Texas Instruments PHYs */
+#define MII_MODEL_TI_TLAN10T 0x0001
+#define MII_STR_TI_TLAN10T "ThunderLAN 10baseT media interface"
+#define MII_MODEL_TI_100VGPMI 0x0002
+#define MII_STR_TI_100VGPMI "ThunderLAN 100VG-AnyLan media interface"
diff --git a/sys/dev/mii/miivar.h b/sys/dev/mii/miivar.h
new file mode 100644
index 00000000000..e25a1d354f8
--- /dev/null
+++ b/sys/dev/mii/miivar.h
@@ -0,0 +1,147 @@
+/* $OpenBSD: miivar.h,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: miivar.h,v 1.1 1998/08/10 23:55:18 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_MIIVAR_H_
+#define _DEV_MII_MIIVAR_H_
+
+#include <sys/queue.h>
+
+/*
+ * Media Independent Interface autoconfiguration defintions.
+ *
+ * This file exports an interface which attempts to be compatible
+ * with the BSD/OS 3.0 interface.
+ */
+
+struct mii_softc;
+
+/*
+ * Callbacks from MII layer into network interface device driver.
+ */
+typedef int (*mii_readreg_t) __P((struct device *, int, int));
+typedef void (*mii_writereg_t) __P((struct device *, int, int, int));
+typedef void (*mii_statchg_t) __P((struct device *));
+
+/*
+ * A network interface driver has one of these structures in its softc.
+ * It is the interface from the network interface driver to the MII
+ * layer.
+ */
+struct mii_data {
+ struct ifmedia mii_media; /* media information */
+ struct ifnet *mii_ifp; /* pointer back to network interface */
+
+ /*
+ * For network interfaces with multiple PHYs, a list of all
+ * PHYs is required so they can all be notified when a media
+ * request is made.
+ */
+ LIST_HEAD(mii_listhead, mii_softc) mii_phys;
+ int mii_instance;
+
+ /*
+ * PHY driver fills this in with active media status.
+ */
+ int mii_media_status;
+ int mii_media_active;
+
+ /*
+ * Calls from MII layer into network interface driver.
+ */
+ mii_readreg_t mii_readreg;
+ mii_writereg_t mii_writereg;
+ mii_statchg_t mii_statchg;
+};
+typedef struct mii_data mii_data_t;
+
+/*
+ * This call is used by the MII layer to call into the PHY driver
+ * to perform a `service request'.
+ */
+typedef int (*mii_downcall_t) __P((struct mii_softc *, struct mii_data *, int));
+
+/*
+ * Requests that can be made to the downcall.
+ */
+#define MII_TICK 1
+#define MII_MEDIACHG 2 /* user changed media; perform the switch */
+#define MII_POLLSTAT 3 /* user requested media status; fill it in */
+
+/*
+ * Each PHY driver's softc has one of these as the first member.
+ * XXX This would be better named "phy_softc", but this is the name
+ * XXX BSDI used, and we would like to have the same interface.
+ */
+struct mii_softc {
+ struct device mii_dev; /* generic device glue */
+
+ LIST_ENTRY(mii_softc) mii_list; /* entry on parent's PHY list */
+
+ int mii_phy; /* our MII address */
+ int mii_inst; /* instance for ifmedia */
+
+ mii_downcall_t mii_service; /* our downcall */
+ struct mii_data *mii_pdata; /* pointer to parent's mii_data */
+};
+typedef struct mii_softc mii_softc_t;
+
+/*
+ * Used to attach a PHY to a parent.
+ */
+struct mii_attach_args {
+ struct mii_data *mii_data; /* pointer to parent data */
+ int mii_phyno; /* MII address */
+ int mii_id1; /* PHY ID register 1 */
+ int mii_id2; /* PHY ID register 2 */
+ int mii_capmask; /* capability mask from BMSR */
+};
+typedef struct mii_attach_args mii_attach_args_t;
+
+#ifdef _KERNEL
+
+int mii_anar __P((int));
+int mii_mediachg __P((struct mii_data *));
+void mii_tick __P((struct mii_data *));
+void mii_pollstat __P((struct mii_data *));
+void mii_phy_probe __P((struct device *, struct mii_data *, int));
+void mii_add_media __P((struct mii_data *, int, int));
+#endif /* _KERNEL */
+
+#endif /* _DEV_MII_MIIVAR_H_ */
diff --git a/sys/dev/mii/nsphy.c b/sys/dev/mii/nsphy.c
new file mode 100644
index 00000000000..ee9430df8ae
--- /dev/null
+++ b/sys/dev/mii/nsphy.c
@@ -0,0 +1,464 @@
+/* $OpenBSD: nsphy.c,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: nsphy.c,v 1.9 1998/08/14 00:23:26 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * driver for National Semiconductor's DP83840A ethernet 10/100 PHY
+ * Data Sheet available from www.national.com
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/mii/miidevs.h>
+
+#include <dev/mii/nsphyreg.h>
+
+struct nsphy_softc {
+ struct mii_softc sc_mii; /* generic PHY */
+ int sc_capabilities;
+ int sc_ticks;
+ int sc_active;
+};
+
+#ifdef __NetBSD__
+int nsphymatch __P((struct device *, struct cfdata *, void *));
+#else
+int nsphymatch __P((struct device *, void *, void *));
+#endif
+void nsphyattach __P((struct device *, struct device *, void *));
+
+struct cfattach nsphy_ca = {
+ sizeof(struct nsphy_softc), nsphymatch, nsphyattach
+};
+
+#ifdef __OpenBSD__
+struct cfdriver nsphy_cd = {
+ NULL, "nsphy", DV_DULL
+};
+#endif
+
+#define NSPHY_READ(sc, reg) \
+ (*(sc)->sc_mii.mii_pdata->mii_readreg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg))
+
+#define NSPHY_WRITE(sc, reg, val) \
+ (*(sc)->sc_mii.mii_pdata->mii_writereg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg), (val))
+
+int nsphy_service __P((struct mii_softc *, struct mii_data *, int));
+void nsphy_reset __P((struct nsphy_softc *));
+void nsphy_auto __P((struct nsphy_softc *));
+void nsphy_status __P((struct nsphy_softc *));
+
+int
+nsphymatch(parent, match, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *match;
+#else
+ void *match;
+#endif
+ void *aux;
+{
+ struct mii_attach_args *ma = aux;
+
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_NATSEMI &&
+ MII_MODEL(ma->mii_id2) == MII_MODEL_NATSEMI_DP83840)
+ return (1);
+
+ return (0);
+}
+
+void
+nsphyattach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct nsphy_softc *sc = (struct nsphy_softc *)self;
+ struct mii_attach_args *ma = aux;
+ struct mii_data *mii = ma->mii_data;
+
+ printf(": %s, rev. %d\n", MII_STR_NATSEMI_DP83840,
+ MII_REV(ma->mii_id2));
+
+ sc->sc_mii.mii_inst = mii->mii_instance;
+ sc->sc_mii.mii_phy = ma->mii_phyno;
+ sc->sc_mii.mii_service = nsphy_service;
+ sc->sc_mii.mii_pdata = mii;
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+#if 0
+ /* Can't do this on the i82557! */
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst),
+ BMCR_ISO);
+#endif
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->sc_mii.mii_inst),
+ BMCR_LOOP|BMCR_S100);
+
+ nsphy_reset(sc);
+
+ sc->sc_capabilities = NSPHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ printf("%s: ", sc->sc_mii.mii_dev.dv_xname);
+ if ((sc->sc_capabilities & BMSR_MEDIAMASK) == 0)
+ printf("no media present");
+ else
+ mii_add_media(mii, sc->sc_capabilities, sc->sc_mii.mii_inst);
+ printf("\n");
+#undef ADD
+}
+
+int
+nsphy_service(self, mii, cmd)
+ struct mii_softc *self;
+ struct mii_data *mii;
+ int cmd;
+{
+ struct nsphy_softc *sc = (struct nsphy_softc *)self;
+ int reg;
+
+ switch (cmd) {
+ case MII_POLLSTAT:
+ /*
+ * If we're not polling our PHY instance, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+ break;
+
+ case MII_MEDIACHG:
+ /*
+ * If the media indicates a different PHY instance,
+ * isolate ourselves.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst) {
+ reg = NSPHY_READ(sc, MII_BMCR);
+ NSPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+ return (0);
+ }
+
+ /*
+ * If the interface is not up, don't do anything.
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ break;
+
+ reg = NSPHY_READ(sc, MII_NSPHY_PCR);
+
+ /*
+ * Set up the PCR to use LED4 to indicate full-duplex
+ * in both 10baseT and 100baseTX modes.
+ */
+ reg |= PCR_LED4MODE;
+
+ /*
+ * Make sure Carrier Intgrity Monitor function is
+ * disabled (normal for Node operation, but sometimes
+ * it's not set?!)
+ */
+ reg |= PCR_CIMDIS;
+
+ /*
+ * Make sure "force link good" is not set. It's only
+ * intended for debugging, but sometimes it's set
+ * after a reset.
+ */
+ reg &= ~PCR_FLINK100;
+
+#if 0
+ /*
+ * Mystery bits which are supposedly `reserved',
+ * but we seem to need to set them when the PHY
+ * is connected to some interfaces!
+ */
+ reg |= 0x0100 | 0x0400;
+#endif
+
+ NSPHY_WRITE(sc, MII_NSPHY_PCR, reg);
+
+ switch (IFM_SUBTYPE(mii->mii_media.ifm_media)) {
+ case IFM_AUTO:
+ /*
+ * If we're already in auto mode, just return.
+ */
+ if (NSPHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
+ return (0);
+ nsphy_auto(sc);
+ break;
+ case IFM_100_T4:
+ /*
+ * XXX Not supported as a manual setting right now.
+ */
+ return (EINVAL);
+ default:
+ /*
+ * BMCR data is stored in the ifmedia entry.
+ */
+ NSPHY_WRITE(sc, MII_ANAR,
+ mii_anar(mii->mii_media.ifm_media));
+ NSPHY_WRITE(sc, MII_BMCR,
+ mii->mii_media.ifm_cur->ifm_data);
+ }
+ break;
+
+ case MII_TICK:
+ /*
+ * If we're not currently selected, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+
+ /*
+ * Only used for autonegotiation.
+ */
+ if (IFM_SUBTYPE(mii->mii_media.ifm_media) != IFM_AUTO)
+ return (0);
+
+ /*
+ * Is the interface even up?
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ return (0);
+
+ /*
+ * Check to see if we have link. If we do, we don't
+ * need to restart the autonegotiation process. Read
+ * the BMSR twice in case it's latched.
+ */
+ reg = NSPHY_READ(sc, MII_BMSR) | NSPHY_READ(sc, MII_BMSR);
+ if (reg & BMSR_LINK)
+ return (0);
+
+ /*
+ * Only retry autonegotiation every 5 seconds.
+ */
+ if (++sc->sc_ticks != 5)
+ return (0);
+
+ sc->sc_ticks = 0;
+ nsphy_reset(sc);
+ nsphy_auto(sc);
+ break;
+ }
+
+ /* Update the media status. */
+ nsphy_status(sc);
+
+ /* Callback if something changed. */
+ if (sc->sc_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
+ (*mii->mii_statchg)(sc->sc_mii.mii_dev.dv_parent);
+ sc->sc_active = mii->mii_media_active;
+ }
+ return (0);
+}
+
+void
+nsphy_status(sc)
+ struct nsphy_softc *sc;
+{
+ struct mii_data *mii = sc->sc_mii.mii_pdata;
+ int bmsr, bmcr, par, anlpar;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = NSPHY_READ(sc, MII_BMSR) | NSPHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = NSPHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if (bmcr & BMCR_AUTOEN) {
+ /*
+ * The PAR status bits are only valid of autonegotiation
+ * has completed (or it's disabled).
+ */
+ if ((bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+
+ /*
+ * Argh. The PAR doesn't seem to indicate duplex mode
+ * properly! Determine media based on link partner's
+ * advertised capabilities.
+ */
+ if (NSPHY_READ(sc, MII_ANER) & ANER_LPAN) {
+ anlpar = NSPHY_READ(sc, MII_ANAR) &
+ NSPHY_READ(sc, MII_ANLPAR);
+ if (anlpar & ANLPAR_T4)
+ mii->mii_media_active |= IFM_100_T4;
+ else if (anlpar & ANLPAR_TX_FD)
+ mii->mii_media_active |= IFM_100_TX|IFM_FDX;
+ else if (anlpar & ANLPAR_TX)
+ mii->mii_media_active |= IFM_100_TX;
+ else if (anlpar & ANLPAR_10_FD)
+ mii->mii_media_active |= IFM_10_T|IFM_FDX;
+ else if (anlpar & ANLPAR_10)
+ mii->mii_media_active |= IFM_10_T;
+ else
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+
+ /*
+ * Link partner is not capable of autonegotiation.
+ * We will never be in full-duplex mode if this is
+ * the case, so reading the PAR is OK.
+ */
+ par = NSPHY_READ(sc, MII_NSPHY_PAR);
+ if (par & PAR_10)
+ mii->mii_media_active |= IFM_10_T;
+ else
+ mii->mii_media_active |= IFM_100_TX;
+#if 0
+ if (par & PAR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+#endif
+ } else {
+ if (bmcr & BMCR_S100)
+ mii->mii_media_active |= IFM_100_TX;
+ else
+ mii->mii_media_active |= IFM_10_T;
+ if (bmcr & BMCR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ }
+}
+
+void
+nsphy_auto(sc)
+ struct nsphy_softc *sc;
+{
+ int bmsr, i;
+
+ NSPHY_WRITE(sc, MII_ANAR,
+ BMSR_MEDIA_TO_ANAR(sc->sc_capabilities) | ANAR_CSMA);
+ NSPHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ /* Wait 500ms for it to complete. */
+ for (i = 0; i < 500; i++) {
+ if ((bmsr = NSPHY_READ(sc, MII_BMSR)) & BMSR_ACOMP)
+ return;
+ delay(1000);
+ }
+#if 0
+ if ((bmsr & BMSR_ACOMP) == 0)
+ printf("%s: autonegotiation failed to complete\n",
+ sc->sc_mii.mii_dev.dv_xname);
+#endif
+}
+
+void
+nsphy_reset(sc)
+ struct nsphy_softc *sc;
+{
+ int reg, i;
+
+ /*
+ * The i82557 wedges if we isolate all of its PHYs!
+ */
+ if (sc->sc_mii.mii_inst == 0)
+ NSPHY_WRITE(sc, MII_BMCR, BMCR_RESET);
+ else
+ NSPHY_WRITE(sc, MII_BMCR, BMCR_RESET|BMCR_ISO);
+
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = NSPHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ /* Make sure the PHY is isolated. */
+ if (sc->sc_mii.mii_inst != 0)
+ NSPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+}
diff --git a/sys/dev/mii/nsphyreg.h b/sys/dev/mii/nsphyreg.h
new file mode 100644
index 00000000000..5fe0328fb70
--- /dev/null
+++ b/sys/dev/mii/nsphyreg.h
@@ -0,0 +1,114 @@
+/* $OpenBSD: nsphyreg.h,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: nsphyreg.h,v 1.1 1998/08/10 23:58:39 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_NSPHYREG_H_
+#define _DEV_MII_NSPHYREG_H_
+
+/*
+ * DP83840 registers.
+ */
+
+#define MII_NSPHY_DCR 0x12 /* Disconnect counter */
+
+#define MII_NSPHY_FCSCR 0x13 /* False carrier sense counter */
+
+#define MII_NSPHY_RECR 0x15 /* Receive error counter */
+
+#define MII_NSPHY_SRR 0x16 /* Silicon revision */
+
+#define MII_NSPHY_PCR 0x17 /* PCS sub-layer configuration */
+#define PCR_NRZI 0x8000 /* NRZI encoding enabled for 100TX */
+#define PCR_DESCRTOSEL 0x4000 /* descrambler t/o select (2ms) */
+#define PCR_DESCRTODIS 0x2000 /* descrambler t/o disable */
+#define PCR_REPEATER 0x1000 /* repeater mode */
+#define PCR_ENCSEL 0x0800 /* encoder mode select */
+#define PCR_CLK25MDIS 0x0080 /* CLK25M disable */
+#define PCR_FLINK100 0x0040 /* force good link in 100mbps */
+#define PCR_CIMDIS 0x0020 /* carrier integrity monitor disable */
+#define PCR_TXOFF 0x0010 /* force transmit off */
+#define PCR_LED1MODE 0x0004 /* LED1 mode: see below */
+#define PCR_LED4MODE 0x0002 /* LED4 mode: see below */
+
+/*
+ * LED1 Mode:
+ *
+ * 1 LED1 output configured to PAR's CON_STATUS, useful for
+ * network management in 100baseTX mode.
+ *
+ * 0 Normal LED1 operation - 10baseTX and 100baseTX transmission
+ * activity.
+ *
+ * LED4 Mode:
+ *
+ * 1 LED4 output configured to indicate full-duplex in both
+ * 10baseT and 100baseTX modes.
+ *
+ * 0 LED4 output configured to indicate polarity in 10baseT
+ * mode and full-duplex in 100baseTX mode.
+ */
+
+#define MII_NSPHY_LBREMR 0x18 /* Loopback, bypass, error mask */
+#define LBREMR_BADSSDEN 0x8000 /* enable bad SSD detection */
+#define LBREMR_BP4B5B 0x4000 /* bypass 4b/5b encoding */
+#define LBREMR_BPSCR 0x2000 /* bypass scrambler */
+#define LBREMR_BPALIGN 0x1000 /* bypass alignment function */
+#define LBREMR_10LOOP 0x0800 /* 10baseT loopback */
+#define LBREMR_LB1 0x0200 /* loopback ctl 1 */
+#define LBREMR_LB0 0x0100 /* loopback ctl 0 */
+#define LBREMR_ALTCRS 0x0040 /* alt crs operation */
+#define LBREMR_LOOPXMTDIS 0x0020 /* disable transmit in 100TX loopbk */
+#define LBREMR_CODEERR 0x0010 /* code errors */
+#define LBREMR_PEERR 0x0008 /* premature end errors */
+#define LBREMR_LINKERR 0x0004 /* link errors */
+#define LBREMR_PKTERR 0x0002 /* packet errors */
+
+#define MII_NSPHY_PAR 0x19 /* Physical address and status */
+#define PAR_DISCRSJAB 0x0800 /* disable car sense during jab */
+#define PAR_ANENSTAT 0x0400 /* autoneg mode status */
+#define PAR_FEFIEN 0x0100 /* far end fault enable */
+#define PAR_FDX 0x0080 /* full duplex status */
+#define PAR_10 0x0040 /* 10mbps mode */
+#define PAR_CON 0x0020 /* connect status */
+#define PAR_AMASK 0x001f /* PHY address bits */
+
+#define MII_NSPHY_10BTSR 0x1b /* 10baseT status */
+#define MII_NSPHY_10BTCR 0x1c /* 10baseT configuration */
+
+#endif /* _DEV_MII_NSPHYREG_H_ */
diff --git a/sys/dev/mii/qsphy.c b/sys/dev/mii/qsphy.c
new file mode 100644
index 00000000000..d199bd46256
--- /dev/null
+++ b/sys/dev/mii/qsphy.c
@@ -0,0 +1,380 @@
+/* $OpenBSD: qsphy.c,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: qsphy.c,v 1.3 1998/08/12 20:56:37 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * driver for Quality Semiconductor's QS6612 ethernet 10/100 PHY
+ * datasheet from www.qualitysemi.com
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/mii/miidevs.h>
+
+#include <dev/mii/qsphyreg.h>
+
+struct qsphy_softc {
+ struct mii_softc sc_mii; /* generic PHY */
+ int sc_capabilities;
+ int sc_active;
+};
+
+#ifdef __NetBSD__
+int qsphymatch __P((struct device *, struct cfdata *, void *));
+#else
+int qsphymatch __P((struct device *, void *, void *));
+#endif
+void qsphyattach __P((struct device *, struct device *, void *));
+
+struct cfattach qsphy_ca = {
+ sizeof(struct qsphy_softc), qsphymatch, qsphyattach
+};
+
+#ifdef __OpenBSD__
+struct cfdriver qsphy_cd = {
+ NULL, "qsphy", DV_DULL
+};
+#endif
+
+#define QSPHY_READ(sc, reg) \
+ (*(sc)->sc_mii.mii_pdata->mii_readreg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg))
+
+#define QSPHY_WRITE(sc, reg, val) \
+ (*(sc)->sc_mii.mii_pdata->mii_writereg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg), (val))
+
+int qsphy_service __P((struct mii_softc *, struct mii_data *, int));
+void qsphy_reset __P((struct qsphy_softc *));
+void qsphy_auto __P((struct qsphy_softc *));
+void qsphy_status __P((struct qsphy_softc *));
+
+int
+qsphymatch(parent, match, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *match;
+#else
+ void *match;
+#endif
+ void *aux;
+{
+ struct mii_attach_args *ma = aux;
+
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_QUALSEMI &&
+ MII_MODEL(ma->mii_id2) == MII_MODEL_QUALSEMI_QS6612)
+ return (1);
+
+ return (0);
+}
+
+void
+qsphyattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct qsphy_softc *sc = (struct qsphy_softc *)self;
+ struct mii_attach_args *ma = aux;
+ struct mii_data *mii = ma->mii_data;
+
+ printf(": %s, rev. %d\n", MII_STR_QUALSEMI_QS6612,
+ MII_REV(ma->mii_id2));
+
+ sc->sc_mii.mii_inst = mii->mii_instance;
+ sc->sc_mii.mii_phy = ma->mii_phyno;
+ sc->sc_mii.mii_service = qsphy_service;
+ sc->sc_mii.mii_pdata = mii;
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst),
+ BMCR_ISO);
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_LOOP, sc->sc_mii.mii_inst),
+ BMCR_LOOP|BMCR_S100);
+
+ qsphy_reset(sc);
+
+ sc->sc_capabilities = QSPHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ printf("%s: ", sc->sc_mii.mii_dev.dv_xname);
+ if ((sc->sc_capabilities & BMSR_MEDIAMASK) == 0)
+ printf("no media present");
+ else
+ mii_add_media(mii, sc->sc_capabilities, sc->sc_mii.mii_inst);
+ printf("\n");
+#undef ADD
+}
+
+int
+qsphy_service(self, mii, cmd)
+ struct mii_softc *self;
+ struct mii_data *mii;
+ int cmd;
+{
+ struct qsphy_softc *sc = (struct qsphy_softc *)self;
+ int reg;
+
+ switch (cmd) {
+ case MII_POLLSTAT:
+ /*
+ * If we're not polling our PHY instance, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+ break;
+
+ case MII_MEDIACHG:
+ /*
+ * If the media indicates a different PHY instance,
+ * isolate ourselves.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst) {
+ reg = QSPHY_READ(sc, MII_BMCR);
+ QSPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+ return (0);
+ }
+
+ /*
+ * If the interface is not up, don't do anything.
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ break;
+
+ switch (IFM_SUBTYPE(mii->mii_media.ifm_media)) {
+ case IFM_AUTO:
+ /*
+ * If we're already in auto mode, just return.
+ */
+ if (QSPHY_READ(sc, MII_BMCR) & BMCR_AUTOEN)
+ return (0);
+ qsphy_auto(sc);
+ break;
+ case IFM_100_T4:
+ /*
+ * XXX Not supported as a manual setting right now.
+ */
+ return (EINVAL);
+ default:
+ /*
+ * BMCR data is stored in the ifmedia entry.
+ */
+ QSPHY_WRITE(sc, MII_ANAR,
+ mii_anar(mii->mii_media.ifm_media));
+ QSPHY_WRITE(sc, MII_BMCR,
+ mii->mii_media.ifm_cur->ifm_data);
+ }
+ break;
+
+ case MII_TICK:
+ /*
+ * If we're not currently selected, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+
+ /*
+ * Only used for autonegotiation.
+ */
+ if (IFM_SUBTYPE(mii->mii_media.ifm_media) != IFM_AUTO)
+ return (0);
+
+ /*
+ * Is the interface even up?
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ return (0);
+
+ /*
+ * The QS6612's autonegotiation doesn't need to be
+ * kicked; it continues in the background.
+ */
+ break;
+ }
+
+ /* Update the media status. */
+ qsphy_status(sc);
+
+ /* Callback if something changed. */
+ if (sc->sc_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
+ (*mii->mii_statchg)(sc->sc_mii.mii_dev.dv_parent);
+ sc->sc_active = mii->mii_media_active;
+ }
+ return (0);
+}
+
+void
+qsphy_status(sc)
+ struct qsphy_softc *sc;
+{
+ struct mii_data *mii = sc->sc_mii.mii_pdata;
+ int bmsr, bmcr, pctl;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmsr = QSPHY_READ(sc, MII_BMSR) | QSPHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ bmcr = QSPHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ if ((bmcr & BMCR_AUTOEN) && (bmsr & BMSR_ACOMP) == 0) {
+ /* Erg, still trying, I guess... */
+ mii->mii_media_active |= IFM_NONE;
+ return;
+ }
+
+ pctl = QSPHY_READ(sc, MII_QSPHY_PCTL) | QSPHY_READ(sc, MII_QSPHY_PCTL);
+ switch (pctl & PCTL_OPMASK) {
+ case PCTL_10_T:
+ mii->mii_media_active |= IFM_10_T;
+ break;
+ case PCTL_10_T_FDX:
+ mii->mii_media_active |= IFM_10_T|IFM_FDX;
+ break;
+ case PCTL_100_TX:
+ mii->mii_media_active |= IFM_100_TX;
+ break;
+ case PCTL_100_TX_FDX:
+ mii->mii_media_active |= IFM_100_TX|IFM_FDX;
+ break;
+ case PCTL_100_T4:
+ mii->mii_media_active |= IFM_100_T4;
+ break;
+ default:
+ /* Erg... this shouldn't happen. */
+ mii->mii_media_active |= IFM_NONE;
+ break;
+ }
+}
+
+void
+qsphy_auto(sc)
+ struct qsphy_softc *sc;
+{
+ int bmsr, i;
+
+ QSPHY_WRITE(sc, MII_ANAR,
+ BMSR_MEDIA_TO_ANAR(sc->sc_capabilities) | ANAR_CSMA);
+ QSPHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ /* Wait 500ms for it to complete. */
+ for (i = 0; i < 500; i++) {
+ if ((bmsr = QSPHY_READ(sc, MII_BMSR)) & BMSR_ACOMP)
+ return;
+ delay(1000);
+ }
+#if 0
+ if ((bmsr & BMSR_ACOMP) == 0)
+ printf("%s: autonegotiation failed to complete\n",
+ sc->sc_mii.mii_dev.dv_xname);
+#endif
+}
+
+void
+qsphy_reset(sc)
+ struct qsphy_softc *sc;
+{
+ int reg, i;
+
+ QSPHY_WRITE(sc, MII_BMCR, BMCR_RESET|BMCR_ISO);
+
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = QSPHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ /* Make sure the PHY is isolated. */
+ if (sc->sc_mii.mii_inst != 0)
+ QSPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+
+ QSPHY_WRITE(sc, MII_QSPHY_IMASK, 0);
+}
diff --git a/sys/dev/mii/qsphyreg.h b/sys/dev/mii/qsphyreg.h
new file mode 100644
index 00000000000..5194ccd180a
--- /dev/null
+++ b/sys/dev/mii/qsphyreg.h
@@ -0,0 +1,85 @@
+/* $OpenBSD: qsphyreg.h,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: qsphyreg.h,v 1.1 1998/08/11 00:01:03 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_QSPHYREG_H_
+#define _DEV_MII_QSPHYREG_H_
+
+/*
+ * QS6612 registers.
+ */
+
+#define MII_QSPHY_MCTL 0x11 /* Mode control */
+#define MCTL_T4PRE 0x1000 /* 100baseT4 interface present */
+#define MCTL_BTEXT 0x0800 /* reduce 10baseT squelch level */
+#define MCTL_FACTTEST 0x0100 /* factory test mode */
+#define MCTL_PHYADDRMASK 0x00f8 /* PHY address */
+#define MCTL_FACTTEST2 0x0004 /* another factory test mode */
+#define MCTL_NLPDIS 0x0002 /* disable link pulse tx */
+#define MCTL_SQEDIS 0x0001 /* disable SQE */
+
+#define MII_QSPHY_ISRC 0x1d /* Interrupt source */
+#define MII_QSPHY_IMASK 0x1e /* Interrupt mask */
+#define IMASK_TLINTR 0x8000 /* ThunderLAN interrupt mode */
+#define IMASK_ANCPL 0x0040 /* autonegotiation complete */
+#define IMASK_RFD 0x0020 /* remote fault detected */
+#define IMASK_LD 0x0010 /* link down */
+#define IMASK_ANLPA 0x0008 /* autonegotiation LP ACK */
+#define IMASK_PDT 0x0004 /* parallel detection fault */
+#define IMASK_ANPR 0x0002 /* autonegotiation page received */
+#define IMASK_REF 0x0001 /* receive error counter full */
+
+#define MII_QSPHY_PCTL 0x1f /* PHY control */
+#define PCTL_RXERDIS 0x2000 /* receive error counter disable */
+#define PCTL_ANC 0x1000 /* autonegotiation complete */
+#define PCTL_RLBEN 0x0200 /* remote coopback enable */
+#define PCTL_DCREN 0x0100 /* DC restoration enable */
+#define PCTL_4B5BEN 0x0040 /* 4b/5b encoding */
+#define PCTL_PHYISO 0x0020 /* isolate PHY */
+#define PCTL_OPMASK 0x001c /* operation mode mask */
+#define PCTL_AN 0x0000 /* autonegotiation in-progress */
+#define PCTL_10_T 0x0004 /* 10baseT */
+#define PCTL_100_TX 0x0008 /* 100baseTX */
+#define PCTL_100_T4 0x0010 /* 100baseT4 */
+#define PCTL_10_T_FDX 0x0014 /* 10baseT-FDX */
+#define PCTL_100_TX_FDX 0x0018 /* 100baseTX-FDX */
+#define PCTL_MLT3DIS 0x0002 /* disable MLT3 */
+#define PCTL_SRCDIS 0x0001 /* disable scrambling */
+
+#endif /* _DEV_MII_QSPHYREG_H_ */
diff --git a/sys/dev/mii/tlphy.c b/sys/dev/mii/tlphy.c
new file mode 100644
index 00000000000..6ef3c6b5d80
--- /dev/null
+++ b/sys/dev/mii/tlphy.c
@@ -0,0 +1,464 @@
+/* $OpenBSD: tlphy.c,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: tlphy.c,v 1.10 1998/08/17 16:41:45 bouyer Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Driver for Texas Instruments's ThunderLAN PHYs
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/socket.h>
+
+#ifdef __NetBSD__
+#include <machine/bus.h>
+#endif
+
+#include <net/if.h>
+#include <net/if_media.h>
+
+#ifdef __NetBSD__
+#include <net/if_ether.h>
+#endif
+
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+#include <dev/mii/miidevs.h>
+
+#ifdef __NetBSD__
+#include <dev/i2c/i2c_bus.h>
+#endif
+
+#include <dev/mii/tlphyreg.h>
+#include <dev/mii/tlphyvar.h>
+
+/* ThunderLAN PHY can only be on a ThunderLAN */
+#include <dev/pci/if_tlvar.h>
+
+struct tlphy_softc {
+ struct mii_softc sc_mii; /* generic PHY */
+ int sc_capabilities;
+ int sc_ticks;
+ int sc_tlphycap;
+ int sc_active;
+};
+
+#ifdef __NetBSD__
+int tlphymatch __P((struct device *, struct cfdata *, void *));
+#else
+int tlphymatch __P((struct device *, void *, void *));
+#endif
+void tlphyattach __P((struct device *, struct device *, void *));
+
+#ifdef __OpenBSD__
+struct cfdriver tlphy_cd = {
+ NULL, "tlphy", DV_DULL
+};
+#endif
+
+struct cfattach tlphy_ca = {
+ sizeof(struct tlphy_softc), tlphymatch, tlphyattach
+};
+
+#define TLPHY_READ(sc, reg) \
+ (*(sc)->sc_mii.mii_pdata->mii_readreg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg))
+
+#define TLPHY_WRITE(sc, reg, val) \
+ (*(sc)->sc_mii.mii_pdata->mii_writereg)((sc)->sc_mii.mii_dev.dv_parent, \
+ (sc)->sc_mii.mii_phy, (reg), (val))
+
+int tlphy_service __P((struct mii_softc *, struct mii_data *, int));
+void tlphy_reset __P((struct tlphy_softc *));
+void tlphy_auto __P((struct tlphy_softc *));
+void tlphy_status __P((struct tlphy_softc *));
+
+int
+tlphymatch(parent, match, aux)
+ struct device *parent;
+#ifdef __NetBSD__
+ struct cfdata *match;
+#else
+ void *match;
+#endif
+ void *aux;
+{
+ struct mii_attach_args *ma = aux;
+
+ if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_TI &&
+ MII_MODEL(ma->mii_id2) == MII_MODEL_TI_TLAN10T)
+ return (1);
+
+ return (0);
+}
+
+void
+tlphyattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct tlphy_softc *sc = (struct tlphy_softc *)self;
+ struct tl_softc *tlsc = (struct tl_softc *)self->dv_parent;
+ struct mii_attach_args *ma = aux;
+ struct mii_data *mii = ma->mii_data;
+ const char *sep = "";
+
+ printf(": %s, rev. %d\n", MII_STR_TI_TLAN10T,
+ MII_REV(ma->mii_id2));
+
+ sc->sc_mii.mii_inst = mii->mii_instance;
+ sc->sc_mii.mii_phy = ma->mii_phyno;
+ sc->sc_mii.mii_service = tlphy_service;
+ sc->sc_mii.mii_pdata = mii;
+
+ tlphy_reset(sc);
+
+ /*
+ * Note that if we're on a device that also supports 100baseTX,
+ * we are not going to want to use the built-in 10baseT port,
+ * since there will be another PHY on the MII wired up to the
+ * UTP connector. The parent indicates this to us by specifying
+ * the TLPHY_MEDIA_NO_10_T bit.
+ */
+ sc->sc_tlphycap = tlsc->tl_product->tp_tlphymedia;
+ if ((sc->sc_tlphycap & TLPHY_MEDIA_NO_10_T) == 0)
+ sc->sc_capabilities =
+ TLPHY_READ(sc, MII_BMSR) & ma->mii_capmask;
+ else
+ sc->sc_capabilities = 0;
+
+#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL)
+
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->sc_mii.mii_inst),
+ BMCR_ISO);
+
+ if ((sc->sc_tlphycap & TLPHY_MEDIA_NO_10_T) == 0)
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_LOOP,
+ sc->sc_mii.mii_inst), BMCR_LOOP);
+
+#define PRINT(s) printf("%s%s", sep, s); sep = ", "
+
+ printf("%s: ", sc->sc_mii.mii_dev.dv_xname);
+ if (sc->sc_tlphycap) {
+ if (sc->sc_tlphycap & TLPHY_MEDIA_10_2) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_2, 0,
+ sc->sc_mii.mii_inst), 0);
+ PRINT("10base2/BNC");
+ } else if (sc->sc_tlphycap & TLPHY_MEDIA_10_5) {
+ ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_5, 0,
+ sc->sc_mii.mii_inst), 0);
+ PRINT("10base5/AUI");
+ }
+ }
+ if (sc->sc_capabilities & BMSR_MEDIAMASK) {
+ printf(sep);
+ mii_add_media(mii, sc->sc_capabilities, sc->sc_mii.mii_inst);
+ } else if ((sc->sc_tlphycap & (TLPHY_MEDIA_10_2 | TLPHY_MEDIA_10_5))
+ == 0)
+ printf("no media present");
+ printf("\n");
+#undef ADD
+#undef PRINT
+}
+
+int
+tlphy_service(self, mii, cmd)
+ struct mii_softc *self;
+ struct mii_data *mii;
+ int cmd;
+{
+ struct tlphy_softc *sc = (struct tlphy_softc *)self;
+ int reg;
+
+ switch (cmd) {
+ case MII_POLLSTAT:
+ /*
+ * If we're not polling our PHY instance, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+ break;
+
+ case MII_MEDIACHG:
+ /*
+ * If the media indicates a different PHY instance,
+ * isolate ourselves.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst) {
+ reg = TLPHY_READ(sc, MII_BMCR);
+ TLPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+ return (0);
+ }
+
+ /*
+ * If the interface is not up, don't do anything.
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ break;
+
+ switch (IFM_SUBTYPE(mii->mii_media.ifm_media)) {
+ case IFM_AUTO:
+ /*
+ * The ThunderLAN PHY doesn't self-configure after
+ * an autonegotiation cycle, so there's no such
+ * thing as "already in auto mode".
+ */
+ tlphy_auto(sc);
+ break;
+ case IFM_10_2:
+ case IFM_10_5:
+ TLPHY_WRITE(sc, MII_BMCR, 0);
+ TLPHY_WRITE(sc, MII_TLPHY_CTRL, CTRL_AUISEL);
+ delay(100000);
+ break;
+ default:
+ TLPHY_WRITE(sc, MII_TLPHY_CTRL, 0);
+ delay(100000);
+ TLPHY_WRITE(sc, MII_ANAR,
+ mii_anar(mii->mii_media.ifm_media));
+ TLPHY_WRITE(sc, MII_BMCR,
+ mii->mii_media.ifm_cur->ifm_data);
+ }
+ break;
+
+ case MII_TICK:
+ /*
+ * If we're not currently selected, just return.
+ */
+ if (IFM_INST(mii->mii_media.ifm_media) !=
+ sc->sc_mii.mii_inst)
+ return (0);
+
+ /*
+ * Only used for autonegotiation.
+ */
+ if (IFM_SUBTYPE(mii->mii_media.ifm_media) != IFM_AUTO)
+ return (0);
+
+ /*
+ * Is the interface even up?
+ */
+ if ((mii->mii_ifp->if_flags & IFF_UP) == 0)
+ return (0);
+
+ /*
+ * Check to see if we have link. If we do, we don't
+ * need to restart the autonegotiation process. Read
+ * the BMSR twice in case it's latched.
+ *
+ * XXX WHAT ABOUT CHECKING LINK ON THE BNC/AUI?!
+ */
+ reg = TLPHY_READ(sc, MII_BMSR) | TLPHY_READ(sc, MII_BMSR);
+ if (reg & BMSR_LINK)
+ return (0);
+
+ /*
+ * Only retry autonegotiation every 5 seconds.
+ */
+ if (++sc->sc_ticks != 5)
+ return (0);
+
+ sc->sc_ticks = 0;
+ tlphy_reset(sc);
+ tlphy_auto(sc);
+ break;
+ }
+
+ /* Update the media status. */
+ tlphy_status(sc);
+
+ /* Callback if something changed. */
+ if (sc->sc_active != mii->mii_media_active || cmd == MII_MEDIACHG) {
+ (*mii->mii_statchg)(sc->sc_mii.mii_dev.dv_parent);
+ sc->sc_active = mii->mii_media_active;
+ }
+ return (0);
+}
+
+void
+tlphy_status(sc)
+ struct tlphy_softc *sc;
+{
+ struct mii_data *mii = sc->sc_mii.mii_pdata;
+ struct tl_softc *tlsc = (struct tl_softc *)sc->sc_mii.mii_dev.dv_parent;
+ int bmsr, bmcr, tlctrl;
+
+ mii->mii_media_status = IFM_AVALID;
+ mii->mii_media_active = IFM_ETHER;
+
+ bmcr = TLPHY_READ(sc, MII_BMCR);
+ if (bmcr & BMCR_ISO) {
+ mii->mii_media_active |= IFM_NONE;
+ mii->mii_media_status = 0;
+ return;
+ }
+
+ tlctrl = TLPHY_READ(sc, MII_TLPHY_CTRL);
+ if (tlctrl & CTRL_AUISEL) {
+ if (sc->sc_tlphycap & TLPHY_MEDIA_10_2)
+ mii->mii_media_active |= IFM_10_2;
+ else if (sc->sc_tlphycap & TLPHY_MEDIA_10_5)
+ mii->mii_media_active |= IFM_10_5;
+ else
+ printf("%s: AUI selected with no matching media !\n",
+ sc->sc_mii.mii_dev.dv_xname);
+ if (tlsc->tl_flags & TL_IFACT)
+ mii->mii_media_status |= IFM_ACTIVE;
+ return;
+ }
+
+ bmsr = TLPHY_READ(sc, MII_BMSR) | TLPHY_READ(sc, MII_BMSR);
+ if (bmsr & BMSR_LINK)
+ mii->mii_media_status |= IFM_ACTIVE;
+
+ if (bmcr & BMCR_LOOP)
+ mii->mii_media_active |= IFM_LOOP;
+
+ /*
+ * Grr, braindead ThunderLAN PHY doesn't have any way to
+ * tell which media is actually active. (Note it also
+ * doesn't self-configure after autonegotiation.) We
+ * just have to report what's in the BMCR.
+ */
+ if (bmcr & BMCR_FDX)
+ mii->mii_media_active |= IFM_FDX;
+ mii->mii_media_active |= IFM_10_T;
+}
+
+void
+tlphy_auto(sc)
+ struct tlphy_softc *sc;
+{
+ int aner, anlpar, bmsr, i;
+
+ TLPHY_WRITE(sc, MII_ANAR,
+ BMSR_MEDIA_TO_ANAR(sc->sc_capabilities) | ANAR_CSMA);
+ TLPHY_WRITE(sc, MII_BMCR, BMCR_AUTOEN | BMCR_STARTNEG);
+
+ /* Wait 500ms for it to complete. */
+ for (i = 0; i < 500; i++) {
+ if ((bmsr = TLPHY_READ(sc, MII_BMSR)) & BMSR_ACOMP)
+ return;
+ delay(1000);
+ }
+ if ((bmsr & BMSR_ACOMP) == 0) {
+#if 0
+ printf("%s: autonegotiation failed to complete\n",
+ sc->sc_mii.mii_dev.dv_xname);
+#endif
+ goto dflt;
+ }
+
+ /*
+ * Grr, braindead ThunderLAN PHY doesn't self-configure
+ * after autonegotiation. We have to do it ourselves
+ * based on the link partner status.
+ */
+
+ aner = TLPHY_READ(sc, MII_ANER);
+ if (aner & ANER_LPAN) {
+ anlpar = TLPHY_READ(sc, MII_ANLPAR) &
+ TLPHY_READ(sc, MII_ANAR);
+ if (anlpar & ANAR_10_FD) {
+ TLPHY_WRITE(sc, MII_BMCR, BMCR_FDX);
+ return;
+ }
+ }
+
+ dflt:
+ /*
+ * Just assume we're not in full-duplex mode.
+ * XXX Check link and try AUI/BNC?
+ */
+ TLPHY_WRITE(sc, MII_BMCR, 0);
+}
+
+void
+tlphy_reset(sc)
+ struct tlphy_softc *sc;
+{
+ int reg, i;
+
+ TLPHY_WRITE(sc, MII_BMCR, BMCR_RESET|BMCR_ISO);
+
+ /* Wait 100ms for it to complete. */
+ for (i = 0; i < 100; i++) {
+ reg = TLPHY_READ(sc, MII_BMCR);
+ if ((reg & BMCR_RESET) == 0)
+ break;
+ delay(1000);
+ }
+
+ /* Make sure the PHY is isolated. */
+ if (sc->sc_mii.mii_inst != 0)
+ TLPHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO);
+}
diff --git a/sys/dev/mii/tlphyreg.h b/sys/dev/mii/tlphyreg.h
new file mode 100644
index 00000000000..8c9d3593aa0
--- /dev/null
+++ b/sys/dev/mii/tlphyreg.h
@@ -0,0 +1,58 @@
+/* $OpenBSD: tlphyreg.h,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: tlphyreg.h,v 1.1 1998/08/10 23:59:58 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 Manuel Bouyer. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Manuel Bouyer.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_TLPHYREG_H_
+#define _DEV_MII_TLPHYREG_H_
+
+/*
+ * Registers for the TI ThunderLAN internal PHY.
+ */
+
+#define MII_TLPHY_ID 0x10 /* ThunderLAN PHY ID */
+#define ID_10BASETAUI 0x0001 /* 10baseT/AUI PHY */
+
+#define MII_TLPHY_CTRL 0x11 /* Control regiseter */
+#define CTRL_ILINK 0x8000 /* Ignore link */
+#define CTRL_SWPOL 0x4000 /* swap polarity */
+#define CTRL_AUISEL 0x2000 /* Select AUI */
+#define CTRL_SQEEN 0x1000 /* Enable SQE */
+#define CTRL_NFEW 0x0004 /* Not far end wrap */
+#define CTRL_INTEN 0x0002 /* Interrupts enable */
+#define CTRL_TINT 0x0001 /* Test Interrupts */
+
+#define MII_TLPHY_ST 0x12 /* Status register */
+#define ST_MII_INT 0x8000 /* MII interrupt */
+#define ST_PHOK 0x4000 /* Power high OK */
+#define ST_POLOK 0x2000 /* Polarity OK */
+#define ST_TPE 0x1000 /* Twisted pair energy */
+
+#endif /* _DEV_MII_TLPHYREG_H_ */
diff --git a/sys/dev/mii/tlphyvar.h b/sys/dev/mii/tlphyvar.h
new file mode 100644
index 00000000000..81a2b72e0d4
--- /dev/null
+++ b/sys/dev/mii/tlphyvar.h
@@ -0,0 +1,59 @@
+/* $OpenBSD: tlphyvar.h,v 1.1 1998/09/10 17:17:34 jason Exp $ */
+/* $NetBSD: tlphyvar.h,v 1.1 1998/08/10 23:59:58 thorpej Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _DEV_MII_TLPHYVAR_H_
+#define _DEV_MII_TLPHYVAR_H_
+
+/*
+ * Constants used by the ThunderLAN driver to notify the PHY
+ * layer which media this particular interface supports on the PHY.
+ * There can be only one of BNC or AUI (since the same line driver
+ * is used).
+ *
+ * For cards using the ThunderLAN PHY that also support 100baseTX,
+ * they often want to bypass the 10baseT support on the ThunderLAN
+ * PHY (because the UTP is wired up to another PHY). That is what
+ * the NO_10_T bit is for.
+ */
+#define TLPHY_MEDIA_10_2 0x01 /* 10base2 (BNC) */
+#define TLPHY_MEDIA_10_5 0x02 /* 10base5 (AUI) */
+#define TLPHY_MEDIA_NO_10_T 0x04 /* don't use the 10baseT (UTP) */
+
+#endif /* _DEV_MII_TLPHYVAR_H_ */