1*112a855dSMarius Strobl /* $NetBSD: exphy.c,v 1.16 1999/04/23 04:24:32 thorpej Exp $ */ 2*112a855dSMarius Strobl 3*112a855dSMarius Strobl /*- 4*112a855dSMarius Strobl * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 5*112a855dSMarius Strobl * All rights reserved. 6*112a855dSMarius Strobl * 7*112a855dSMarius Strobl * This code is derived from software contributed to The NetBSD Foundation 8*112a855dSMarius Strobl * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9*112a855dSMarius Strobl * NASA Ames Research Center, and by Frank van der Linden. 10*112a855dSMarius Strobl * 11*112a855dSMarius Strobl * Redistribution and use in source and binary forms, with or without 12*112a855dSMarius Strobl * modification, are permitted provided that the following conditions 13*112a855dSMarius Strobl * are met: 14*112a855dSMarius Strobl * 1. Redistributions of source code must retain the above copyright 15*112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer. 16*112a855dSMarius Strobl * 2. Redistributions in binary form must reproduce the above copyright 17*112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer in the 18*112a855dSMarius Strobl * documentation and/or other materials provided with the distribution. 19*112a855dSMarius Strobl * 20*112a855dSMarius Strobl * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21*112a855dSMarius Strobl * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22*112a855dSMarius Strobl * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23*112a855dSMarius Strobl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24*112a855dSMarius Strobl * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25*112a855dSMarius Strobl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26*112a855dSMarius Strobl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27*112a855dSMarius Strobl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28*112a855dSMarius Strobl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29*112a855dSMarius Strobl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30*112a855dSMarius Strobl * POSSIBILITY OF SUCH DAMAGE. 31*112a855dSMarius Strobl */ 32*112a855dSMarius Strobl 33*112a855dSMarius Strobl /*- 34*112a855dSMarius Strobl * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 35*112a855dSMarius Strobl * 36*112a855dSMarius Strobl * Redistribution and use in source and binary forms, with or without 37*112a855dSMarius Strobl * modification, are permitted provided that the following conditions 38*112a855dSMarius Strobl * are met: 39*112a855dSMarius Strobl * 1. Redistributions of source code must retain the above copyright 40*112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer. 41*112a855dSMarius Strobl * 2. Redistributions in binary form must reproduce the above copyright 42*112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer in the 43*112a855dSMarius Strobl * documentation and/or other materials provided with the distribution. 44*112a855dSMarius Strobl * 45*112a855dSMarius Strobl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46*112a855dSMarius Strobl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47*112a855dSMarius Strobl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48*112a855dSMarius Strobl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49*112a855dSMarius Strobl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50*112a855dSMarius Strobl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51*112a855dSMarius Strobl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52*112a855dSMarius Strobl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53*112a855dSMarius Strobl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54*112a855dSMarius Strobl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55*112a855dSMarius Strobl */ 56*112a855dSMarius Strobl 57*112a855dSMarius Strobl #include <sys/cdefs.h> 58*112a855dSMarius Strobl __FBSDID("$FreeBSD$"); 59*112a855dSMarius Strobl 60*112a855dSMarius Strobl /* 61*112a855dSMarius Strobl * driver for 3Com internal PHYs 62*112a855dSMarius Strobl */ 63*112a855dSMarius Strobl 64*112a855dSMarius Strobl #include <sys/param.h> 65*112a855dSMarius Strobl #include <sys/systm.h> 66*112a855dSMarius Strobl #include <sys/kernel.h> 67*112a855dSMarius Strobl #include <sys/socket.h> 68*112a855dSMarius Strobl #include <sys/module.h> 69*112a855dSMarius Strobl #include <sys/bus.h> 70*112a855dSMarius Strobl 71*112a855dSMarius Strobl #include <net/if.h> 72*112a855dSMarius Strobl #include <net/if_media.h> 73*112a855dSMarius Strobl 74*112a855dSMarius Strobl #include <dev/mii/mii.h> 75*112a855dSMarius Strobl #include <dev/mii/miivar.h> 76*112a855dSMarius Strobl #include "miidevs.h" 77*112a855dSMarius Strobl 78*112a855dSMarius Strobl #include "miibus_if.h" 79*112a855dSMarius Strobl 80*112a855dSMarius Strobl static int xlphy_probe(device_t); 81*112a855dSMarius Strobl static int xlphy_attach(device_t); 82*112a855dSMarius Strobl 83*112a855dSMarius Strobl static device_method_t xlphy_methods[] = { 84*112a855dSMarius Strobl /* device interface */ 85*112a855dSMarius Strobl DEVMETHOD(device_probe, xlphy_probe), 86*112a855dSMarius Strobl DEVMETHOD(device_attach, xlphy_attach), 87*112a855dSMarius Strobl DEVMETHOD(device_detach, mii_phy_detach), 88*112a855dSMarius Strobl DEVMETHOD(device_shutdown, bus_generic_shutdown), 89*112a855dSMarius Strobl { 0, 0 } 90*112a855dSMarius Strobl }; 91*112a855dSMarius Strobl 92*112a855dSMarius Strobl static devclass_t xlphy_devclass; 93*112a855dSMarius Strobl 94*112a855dSMarius Strobl static driver_t xlphy_driver = { 95*112a855dSMarius Strobl "xlphy", 96*112a855dSMarius Strobl xlphy_methods, 97*112a855dSMarius Strobl sizeof(struct mii_softc) 98*112a855dSMarius Strobl }; 99*112a855dSMarius Strobl 100*112a855dSMarius Strobl DRIVER_MODULE(xlphy, miibus, xlphy_driver, xlphy_devclass, 0, 0); 101*112a855dSMarius Strobl 102*112a855dSMarius Strobl static int xlphy_service(struct mii_softc *, struct mii_data *, int); 103*112a855dSMarius Strobl static void xlphy_reset(struct mii_softc *); 104*112a855dSMarius Strobl 105*112a855dSMarius Strobl /* 106*112a855dSMarius Strobl * Some 3Com internal PHYs report zero for OUI and model, others use 107*112a855dSMarius Strobl * actual values. 108*112a855dSMarius Strobl * Note that the 3Com internal PHYs having OUI 0x105a and model 0 are 109*112a855dSMarius Strobl * handled fine by ukphy(4); they can be isolated and don't require 110*112a855dSMarius Strobl * special treatment after reset. 111*112a855dSMarius Strobl */ 112*112a855dSMarius Strobl static const struct mii_phydesc xlphys[] = { 113*112a855dSMarius Strobl { 0, 0, "3Com internal media interface" }, 114*112a855dSMarius Strobl MII_PHY_DESC(xxBROADCOM, 3C905C), 115*112a855dSMarius Strobl MII_PHY_END 116*112a855dSMarius Strobl }; 117*112a855dSMarius Strobl 118*112a855dSMarius Strobl static const struct mii_phy_funcs xlphy_funcs = { 119*112a855dSMarius Strobl xlphy_service, 120*112a855dSMarius Strobl ukphy_status, 121*112a855dSMarius Strobl xlphy_reset 122*112a855dSMarius Strobl }; 123*112a855dSMarius Strobl 124*112a855dSMarius Strobl static int 125*112a855dSMarius Strobl xlphy_probe(device_t dev) 126*112a855dSMarius Strobl { 127*112a855dSMarius Strobl 128*112a855dSMarius Strobl if (strcmp(device_get_name(device_get_parent(device_get_parent(dev))), 129*112a855dSMarius Strobl "xl") == 0) 130*112a855dSMarius Strobl return (mii_phy_dev_probe(dev, xlphys, BUS_PROBE_DEFAULT)); 131*112a855dSMarius Strobl return (ENXIO); 132*112a855dSMarius Strobl } 133*112a855dSMarius Strobl 134*112a855dSMarius Strobl static int 135*112a855dSMarius Strobl xlphy_attach(device_t dev) 136*112a855dSMarius Strobl { 137*112a855dSMarius Strobl 138*112a855dSMarius Strobl /* 139*112a855dSMarius Strobl * The 3Com PHY can never be isolated. 140*112a855dSMarius Strobl */ 141*112a855dSMarius Strobl mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, 142*112a855dSMarius Strobl &xlphy_funcs, 1); 143*112a855dSMarius Strobl return (0); 144*112a855dSMarius Strobl } 145*112a855dSMarius Strobl 146*112a855dSMarius Strobl static int 147*112a855dSMarius Strobl xlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 148*112a855dSMarius Strobl { 149*112a855dSMarius Strobl 150*112a855dSMarius Strobl switch (cmd) { 151*112a855dSMarius Strobl case MII_POLLSTAT: 152*112a855dSMarius Strobl break; 153*112a855dSMarius Strobl 154*112a855dSMarius Strobl case MII_MEDIACHG: 155*112a855dSMarius Strobl /* 156*112a855dSMarius Strobl * If the interface is not up, don't do anything. 157*112a855dSMarius Strobl */ 158*112a855dSMarius Strobl if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 159*112a855dSMarius Strobl break; 160*112a855dSMarius Strobl 161*112a855dSMarius Strobl mii_phy_setmedia(sc); 162*112a855dSMarius Strobl break; 163*112a855dSMarius Strobl 164*112a855dSMarius Strobl case MII_TICK: 165*112a855dSMarius Strobl /* 166*112a855dSMarius Strobl * Is the interface even up? 167*112a855dSMarius Strobl */ 168*112a855dSMarius Strobl if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 169*112a855dSMarius Strobl return (0); 170*112a855dSMarius Strobl 171*112a855dSMarius Strobl /* 172*112a855dSMarius Strobl * The 3Com PHY's autonegotiation doesn't need to be 173*112a855dSMarius Strobl * kicked; it continues in the background. 174*112a855dSMarius Strobl */ 175*112a855dSMarius Strobl break; 176*112a855dSMarius Strobl } 177*112a855dSMarius Strobl 178*112a855dSMarius Strobl /* Update the media status. */ 179*112a855dSMarius Strobl PHY_STATUS(sc); 180*112a855dSMarius Strobl 181*112a855dSMarius Strobl /* Callback if something changed. */ 182*112a855dSMarius Strobl mii_phy_update(sc, cmd); 183*112a855dSMarius Strobl return (0); 184*112a855dSMarius Strobl } 185*112a855dSMarius Strobl 186*112a855dSMarius Strobl static void 187*112a855dSMarius Strobl xlphy_reset(struct mii_softc *sc) 188*112a855dSMarius Strobl { 189*112a855dSMarius Strobl 190*112a855dSMarius Strobl mii_phy_reset(sc); 191*112a855dSMarius Strobl 192*112a855dSMarius Strobl /* 193*112a855dSMarius Strobl * XXX 3Com PHY doesn't set the BMCR properly after 194*112a855dSMarius Strobl * XXX reset, which breaks autonegotiation. 195*112a855dSMarius Strobl */ 196*112a855dSMarius Strobl PHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_AUTOEN|BMCR_FDX); 197*112a855dSMarius Strobl } 198