diff options
-rw-r--r-- | sys/dev/mii/Makefile | 8 | ||||
-rw-r--r-- | sys/dev/mii/devlist2h.awk | 146 | ||||
-rw-r--r-- | sys/dev/mii/exphy.c | 378 | ||||
-rw-r--r-- | sys/dev/mii/files.mii | 24 | ||||
-rw-r--r-- | sys/dev/mii/inphy.c | 397 | ||||
-rw-r--r-- | sys/dev/mii/inphyreg.h | 101 | ||||
-rw-r--r-- | sys/dev/mii/mii.c | 304 | ||||
-rw-r--r-- | sys/dev/mii/mii.h | 127 | ||||
-rw-r--r-- | sys/dev/mii/miidevs | 78 | ||||
-rw-r--r-- | sys/dev/mii/miidevs.h | 94 | ||||
-rw-r--r-- | sys/dev/mii/miivar.h | 147 | ||||
-rw-r--r-- | sys/dev/mii/nsphy.c | 464 | ||||
-rw-r--r-- | sys/dev/mii/nsphyreg.h | 114 | ||||
-rw-r--r-- | sys/dev/mii/qsphy.c | 380 | ||||
-rw-r--r-- | sys/dev/mii/qsphyreg.h | 85 | ||||
-rw-r--r-- | sys/dev/mii/tlphy.c | 464 | ||||
-rw-r--r-- | sys/dev/mii/tlphyreg.h | 58 | ||||
-rw-r--r-- | sys/dev/mii/tlphyvar.h | 59 |
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_ */ |