1112a855dSMarius Strobl /* $NetBSD: exphy.c,v 1.16 1999/04/23 04:24:32 thorpej Exp $ */ 2112a855dSMarius Strobl 3112a855dSMarius Strobl /*- 4112a855dSMarius Strobl * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 5112a855dSMarius Strobl * All rights reserved. 6112a855dSMarius Strobl * 7112a855dSMarius Strobl * This code is derived from software contributed to The NetBSD Foundation 8112a855dSMarius Strobl * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9112a855dSMarius Strobl * NASA Ames Research Center, and by Frank van der Linden. 10112a855dSMarius Strobl * 11112a855dSMarius Strobl * Redistribution and use in source and binary forms, with or without 12112a855dSMarius Strobl * modification, are permitted provided that the following conditions 13112a855dSMarius Strobl * are met: 14112a855dSMarius Strobl * 1. Redistributions of source code must retain the above copyright 15112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer. 16112a855dSMarius Strobl * 2. Redistributions in binary form must reproduce the above copyright 17112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer in the 18112a855dSMarius Strobl * documentation and/or other materials provided with the distribution. 19112a855dSMarius Strobl * 20112a855dSMarius Strobl * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21112a855dSMarius Strobl * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22112a855dSMarius Strobl * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23112a855dSMarius Strobl * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24112a855dSMarius Strobl * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25112a855dSMarius Strobl * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26112a855dSMarius Strobl * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27112a855dSMarius Strobl * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28112a855dSMarius Strobl * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29112a855dSMarius Strobl * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30112a855dSMarius Strobl * POSSIBILITY OF SUCH DAMAGE. 31112a855dSMarius Strobl */ 32112a855dSMarius Strobl 33112a855dSMarius Strobl /*- 34112a855dSMarius Strobl * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 35112a855dSMarius Strobl * 36112a855dSMarius Strobl * Redistribution and use in source and binary forms, with or without 37112a855dSMarius Strobl * modification, are permitted provided that the following conditions 38112a855dSMarius Strobl * are met: 39112a855dSMarius Strobl * 1. Redistributions of source code must retain the above copyright 40112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer. 41112a855dSMarius Strobl * 2. Redistributions in binary form must reproduce the above copyright 42112a855dSMarius Strobl * notice, this list of conditions and the following disclaimer in the 43112a855dSMarius Strobl * documentation and/or other materials provided with the distribution. 44112a855dSMarius Strobl * 45112a855dSMarius Strobl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46112a855dSMarius Strobl * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47112a855dSMarius Strobl * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48112a855dSMarius Strobl * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49112a855dSMarius Strobl * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50112a855dSMarius Strobl * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51112a855dSMarius Strobl * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52112a855dSMarius Strobl * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53112a855dSMarius Strobl * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54112a855dSMarius Strobl * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55112a855dSMarius Strobl */ 56112a855dSMarius Strobl 57112a855dSMarius Strobl #include <sys/cdefs.h> 58112a855dSMarius Strobl __FBSDID("$FreeBSD$"); 59112a855dSMarius Strobl 60112a855dSMarius Strobl /* 61112a855dSMarius Strobl * driver for 3Com internal PHYs 62112a855dSMarius Strobl */ 63112a855dSMarius Strobl 64112a855dSMarius Strobl #include <sys/param.h> 65112a855dSMarius Strobl #include <sys/systm.h> 66112a855dSMarius Strobl #include <sys/kernel.h> 67112a855dSMarius Strobl #include <sys/socket.h> 68112a855dSMarius Strobl #include <sys/module.h> 69112a855dSMarius Strobl #include <sys/bus.h> 70112a855dSMarius Strobl 71112a855dSMarius Strobl #include <net/if.h> 72112a855dSMarius Strobl #include <net/if_media.h> 73112a855dSMarius Strobl 74112a855dSMarius Strobl #include <dev/mii/mii.h> 75112a855dSMarius Strobl #include <dev/mii/miivar.h> 76112a855dSMarius Strobl #include "miidevs.h" 77112a855dSMarius Strobl 78112a855dSMarius Strobl #include "miibus_if.h" 79112a855dSMarius Strobl 80112a855dSMarius Strobl static int xlphy_probe(device_t); 81112a855dSMarius Strobl static int xlphy_attach(device_t); 82112a855dSMarius Strobl 83112a855dSMarius Strobl static device_method_t xlphy_methods[] = { 84112a855dSMarius Strobl /* device interface */ 85112a855dSMarius Strobl DEVMETHOD(device_probe, xlphy_probe), 86112a855dSMarius Strobl DEVMETHOD(device_attach, xlphy_attach), 87112a855dSMarius Strobl DEVMETHOD(device_detach, mii_phy_detach), 88112a855dSMarius Strobl DEVMETHOD(device_shutdown, bus_generic_shutdown), 89*604f5f1fSMarius Strobl DEVMETHOD_END 90112a855dSMarius Strobl }; 91112a855dSMarius Strobl 92112a855dSMarius Strobl static devclass_t xlphy_devclass; 93112a855dSMarius Strobl 94112a855dSMarius Strobl static driver_t xlphy_driver = { 95112a855dSMarius Strobl "xlphy", 96112a855dSMarius Strobl xlphy_methods, 97112a855dSMarius Strobl sizeof(struct mii_softc) 98112a855dSMarius Strobl }; 99112a855dSMarius Strobl 100112a855dSMarius Strobl DRIVER_MODULE(xlphy, miibus, xlphy_driver, xlphy_devclass, 0, 0); 101112a855dSMarius Strobl 102112a855dSMarius Strobl static int xlphy_service(struct mii_softc *, struct mii_data *, int); 103112a855dSMarius Strobl static void xlphy_reset(struct mii_softc *); 104112a855dSMarius Strobl 105112a855dSMarius Strobl /* 106112a855dSMarius Strobl * Some 3Com internal PHYs report zero for OUI and model, others use 107112a855dSMarius Strobl * actual values. 108112a855dSMarius Strobl * Note that the 3Com internal PHYs having OUI 0x105a and model 0 are 109112a855dSMarius Strobl * handled fine by ukphy(4); they can be isolated and don't require 110112a855dSMarius Strobl * special treatment after reset. 111112a855dSMarius Strobl */ 112112a855dSMarius Strobl static const struct mii_phydesc xlphys[] = { 113112a855dSMarius Strobl { 0, 0, "3Com internal media interface" }, 114112a855dSMarius Strobl MII_PHY_DESC(xxBROADCOM, 3C905C), 115112a855dSMarius Strobl MII_PHY_END 116112a855dSMarius Strobl }; 117112a855dSMarius Strobl 118112a855dSMarius Strobl static const struct mii_phy_funcs xlphy_funcs = { 119112a855dSMarius Strobl xlphy_service, 120112a855dSMarius Strobl ukphy_status, 121112a855dSMarius Strobl xlphy_reset 122112a855dSMarius Strobl }; 123112a855dSMarius Strobl 124112a855dSMarius Strobl static int 125112a855dSMarius Strobl xlphy_probe(device_t dev) 126112a855dSMarius Strobl { 127112a855dSMarius Strobl 128112a855dSMarius Strobl if (strcmp(device_get_name(device_get_parent(device_get_parent(dev))), 129112a855dSMarius Strobl "xl") == 0) 130112a855dSMarius Strobl return (mii_phy_dev_probe(dev, xlphys, BUS_PROBE_DEFAULT)); 131112a855dSMarius Strobl return (ENXIO); 132112a855dSMarius Strobl } 133112a855dSMarius Strobl 134112a855dSMarius Strobl static int 135112a855dSMarius Strobl xlphy_attach(device_t dev) 136112a855dSMarius Strobl { 137112a855dSMarius Strobl 138112a855dSMarius Strobl /* 139112a855dSMarius Strobl * The 3Com PHY can never be isolated. 140112a855dSMarius Strobl */ 141112a855dSMarius Strobl mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, 142112a855dSMarius Strobl &xlphy_funcs, 1); 143112a855dSMarius Strobl return (0); 144112a855dSMarius Strobl } 145112a855dSMarius Strobl 146112a855dSMarius Strobl static int 147112a855dSMarius Strobl xlphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 148112a855dSMarius Strobl { 149112a855dSMarius Strobl 150112a855dSMarius Strobl switch (cmd) { 151112a855dSMarius Strobl case MII_POLLSTAT: 152112a855dSMarius Strobl break; 153112a855dSMarius Strobl 154112a855dSMarius Strobl case MII_MEDIACHG: 155112a855dSMarius Strobl /* 156112a855dSMarius Strobl * If the interface is not up, don't do anything. 157112a855dSMarius Strobl */ 158112a855dSMarius Strobl if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 159112a855dSMarius Strobl break; 160112a855dSMarius Strobl 161112a855dSMarius Strobl mii_phy_setmedia(sc); 162112a855dSMarius Strobl break; 163112a855dSMarius Strobl 164112a855dSMarius Strobl case MII_TICK: 165112a855dSMarius Strobl /* 166112a855dSMarius Strobl * Is the interface even up? 167112a855dSMarius Strobl */ 168112a855dSMarius Strobl if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 169112a855dSMarius Strobl return (0); 170112a855dSMarius Strobl 171112a855dSMarius Strobl /* 172112a855dSMarius Strobl * The 3Com PHY's autonegotiation doesn't need to be 173112a855dSMarius Strobl * kicked; it continues in the background. 174112a855dSMarius Strobl */ 175112a855dSMarius Strobl break; 176112a855dSMarius Strobl } 177112a855dSMarius Strobl 178112a855dSMarius Strobl /* Update the media status. */ 179112a855dSMarius Strobl PHY_STATUS(sc); 180112a855dSMarius Strobl 181112a855dSMarius Strobl /* Callback if something changed. */ 182112a855dSMarius Strobl mii_phy_update(sc, cmd); 183112a855dSMarius Strobl return (0); 184112a855dSMarius Strobl } 185112a855dSMarius Strobl 186112a855dSMarius Strobl static void 187112a855dSMarius Strobl xlphy_reset(struct mii_softc *sc) 188112a855dSMarius Strobl { 189112a855dSMarius Strobl 190112a855dSMarius Strobl mii_phy_reset(sc); 191112a855dSMarius Strobl 192112a855dSMarius Strobl /* 193112a855dSMarius Strobl * XXX 3Com PHY doesn't set the BMCR properly after 194112a855dSMarius Strobl * XXX reset, which breaks autonegotiation. 195112a855dSMarius Strobl */ 196112a855dSMarius Strobl PHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_AUTOEN|BMCR_FDX); 197112a855dSMarius Strobl } 198