178679427SPyun YongHyeon /* $NetBSD: icsphy.c,v 1.41 2006/11/16 21:24:07 christos Exp $ */ 278679427SPyun YongHyeon 378679427SPyun YongHyeon /*- 4718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-NetBSD 5718cf2ccSPedro F. Giffuni * 678679427SPyun YongHyeon * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 778679427SPyun YongHyeon * All rights reserved. 878679427SPyun YongHyeon * 978679427SPyun YongHyeon * This code is derived from software contributed to The NetBSD Foundation 1078679427SPyun YongHyeon * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 1178679427SPyun YongHyeon * NASA Ames Research Center. 1278679427SPyun YongHyeon * 1378679427SPyun YongHyeon * Redistribution and use in source and binary forms, with or without 1478679427SPyun YongHyeon * modification, are permitted provided that the following conditions 1578679427SPyun YongHyeon * are met: 1678679427SPyun YongHyeon * 1. Redistributions of source code must retain the above copyright 1778679427SPyun YongHyeon * notice, this list of conditions and the following disclaimer. 1878679427SPyun YongHyeon * 2. Redistributions in binary form must reproduce the above copyright 1978679427SPyun YongHyeon * notice, this list of conditions and the following disclaimer in the 2078679427SPyun YongHyeon * documentation and/or other materials provided with the distribution. 2178679427SPyun YongHyeon * 2278679427SPyun YongHyeon * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2378679427SPyun YongHyeon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2478679427SPyun YongHyeon * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2578679427SPyun YongHyeon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2678679427SPyun YongHyeon * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2778679427SPyun YongHyeon * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2878679427SPyun YongHyeon * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2978679427SPyun YongHyeon * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 3078679427SPyun YongHyeon * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3178679427SPyun YongHyeon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3278679427SPyun YongHyeon * POSSIBILITY OF SUCH DAMAGE. 3378679427SPyun YongHyeon */ 3478679427SPyun YongHyeon 3578679427SPyun YongHyeon /* 3678679427SPyun YongHyeon * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 3778679427SPyun YongHyeon * 3878679427SPyun YongHyeon * Redistribution and use in source and binary forms, with or without 3978679427SPyun YongHyeon * modification, are permitted provided that the following conditions 4078679427SPyun YongHyeon * are met: 4178679427SPyun YongHyeon * 1. Redistributions of source code must retain the above copyright 4278679427SPyun YongHyeon * notice, this list of conditions and the following disclaimer. 4378679427SPyun YongHyeon * 2. Redistributions in binary form must reproduce the above copyright 4478679427SPyun YongHyeon * notice, this list of conditions and the following disclaimer in the 4578679427SPyun YongHyeon * documentation and/or other materials provided with the distribution. 4678679427SPyun YongHyeon * 4778679427SPyun YongHyeon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 4878679427SPyun YongHyeon * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 4978679427SPyun YongHyeon * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 5078679427SPyun YongHyeon * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 5178679427SPyun YongHyeon * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 5278679427SPyun YongHyeon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 5378679427SPyun YongHyeon * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 5478679427SPyun YongHyeon * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 5578679427SPyun YongHyeon * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 5678679427SPyun YongHyeon * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 5778679427SPyun YongHyeon */ 5878679427SPyun YongHyeon 5978679427SPyun YongHyeon #include <sys/cdefs.h> 6078679427SPyun YongHyeon __FBSDID("$FreeBSD$"); 6178679427SPyun YongHyeon 6278679427SPyun YongHyeon /* 6378679427SPyun YongHyeon * driver for Integrated Circuit Systems' ICS1889-1893 ethernet 10/100 PHY 6478679427SPyun YongHyeon * datasheet from www.icst.com 6578679427SPyun YongHyeon */ 6678679427SPyun YongHyeon 6778679427SPyun YongHyeon #include <sys/param.h> 6878679427SPyun YongHyeon #include <sys/systm.h> 6978679427SPyun YongHyeon #include <sys/kernel.h> 7078679427SPyun YongHyeon #include <sys/module.h> 7178679427SPyun YongHyeon #include <sys/socket.h> 7278679427SPyun YongHyeon #include <sys/bus.h> 7378679427SPyun YongHyeon 7478679427SPyun YongHyeon #include <net/if.h> 7578679427SPyun YongHyeon #include <net/if_media.h> 7678679427SPyun YongHyeon 7778679427SPyun YongHyeon #include <dev/mii/mii.h> 7878679427SPyun YongHyeon #include <dev/mii/miivar.h> 7978679427SPyun YongHyeon #include "miidevs.h" 8078679427SPyun YongHyeon 8178679427SPyun YongHyeon #include <dev/mii/icsphyreg.h> 8278679427SPyun YongHyeon 8378679427SPyun YongHyeon #include "miibus_if.h" 8478679427SPyun YongHyeon 8578679427SPyun YongHyeon static int icsphy_probe(device_t dev); 8678679427SPyun YongHyeon static int icsphy_attach(device_t dev); 8778679427SPyun YongHyeon 8878679427SPyun YongHyeon static device_method_t icsphy_methods[] = { 8978679427SPyun YongHyeon /* device interface */ 9078679427SPyun YongHyeon DEVMETHOD(device_probe, icsphy_probe), 9178679427SPyun YongHyeon DEVMETHOD(device_attach, icsphy_attach), 9278679427SPyun YongHyeon DEVMETHOD(device_detach, mii_phy_detach), 9378679427SPyun YongHyeon DEVMETHOD(device_shutdown, bus_generic_shutdown), 94604f5f1fSMarius Strobl DEVMETHOD_END 9578679427SPyun YongHyeon }; 9678679427SPyun YongHyeon 9778679427SPyun YongHyeon static driver_t icsphy_driver = { 9878679427SPyun YongHyeon "icsphy", 9978679427SPyun YongHyeon icsphy_methods, 1003fcb7a53SMarius Strobl sizeof(struct mii_softc) 10178679427SPyun YongHyeon }; 10278679427SPyun YongHyeon 103*f438c2ffSJohn Baldwin DRIVER_MODULE(icsphy, miibus, icsphy_driver, 0, 0); 10478679427SPyun YongHyeon 10578679427SPyun YongHyeon static int icsphy_service(struct mii_softc *, struct mii_data *, int); 10678679427SPyun YongHyeon static void icsphy_status(struct mii_softc *); 10778679427SPyun YongHyeon static void icsphy_reset(struct mii_softc *); 10878679427SPyun YongHyeon 10978679427SPyun YongHyeon static const struct mii_phydesc icsphys[] = { 1103fcb7a53SMarius Strobl MII_PHY_DESC(ICS, 1889), 1113fcb7a53SMarius Strobl MII_PHY_DESC(ICS, 1890), 1123fcb7a53SMarius Strobl MII_PHY_DESC(ICS, 1892), 1133fcb7a53SMarius Strobl MII_PHY_DESC(ICS, 1893), 114159f344bSMark Johnston MII_PHY_DESC(ICS, 1893C), 11578679427SPyun YongHyeon MII_PHY_END 11678679427SPyun YongHyeon }; 11778679427SPyun YongHyeon 1183fcb7a53SMarius Strobl static const struct mii_phy_funcs icsphy_funcs = { 1193fcb7a53SMarius Strobl icsphy_service, 1203fcb7a53SMarius Strobl icsphy_status, 1213fcb7a53SMarius Strobl icsphy_reset 1223fcb7a53SMarius Strobl }; 1233fcb7a53SMarius Strobl 12478679427SPyun YongHyeon static int 12578679427SPyun YongHyeon icsphy_probe(device_t dev) 12678679427SPyun YongHyeon { 12778679427SPyun YongHyeon 12878679427SPyun YongHyeon return (mii_phy_dev_probe(dev, icsphys, BUS_PROBE_DEFAULT)); 12978679427SPyun YongHyeon } 13078679427SPyun YongHyeon 13178679427SPyun YongHyeon static int 13278679427SPyun YongHyeon icsphy_attach(device_t dev) 13378679427SPyun YongHyeon { 13478679427SPyun YongHyeon 1353fcb7a53SMarius Strobl mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, 1363fcb7a53SMarius Strobl &icsphy_funcs, 1); 13778679427SPyun YongHyeon return (0); 13878679427SPyun YongHyeon } 13978679427SPyun YongHyeon 14078679427SPyun YongHyeon static int 14178679427SPyun YongHyeon icsphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 14278679427SPyun YongHyeon { 14378679427SPyun YongHyeon 14478679427SPyun YongHyeon switch (cmd) { 14578679427SPyun YongHyeon case MII_POLLSTAT: 14678679427SPyun YongHyeon break; 14778679427SPyun YongHyeon 14878679427SPyun YongHyeon case MII_MEDIACHG: 14978679427SPyun YongHyeon mii_phy_setmedia(sc); 15078679427SPyun YongHyeon break; 15178679427SPyun YongHyeon 15278679427SPyun YongHyeon case MII_TICK: 15378679427SPyun YongHyeon if (mii_phy_tick(sc) == EJUSTRETURN) 15478679427SPyun YongHyeon return (0); 15578679427SPyun YongHyeon break; 15678679427SPyun YongHyeon } 15778679427SPyun YongHyeon 15878679427SPyun YongHyeon /* Update the media status. */ 1593fcb7a53SMarius Strobl PHY_STATUS(sc); 16078679427SPyun YongHyeon 16178679427SPyun YongHyeon /* Callback if something changed. */ 16278679427SPyun YongHyeon mii_phy_update(sc, cmd); 16378679427SPyun YongHyeon return (0); 16478679427SPyun YongHyeon } 16578679427SPyun YongHyeon 16678679427SPyun YongHyeon static void 16778679427SPyun YongHyeon icsphy_status(struct mii_softc *sc) 16878679427SPyun YongHyeon { 16978679427SPyun YongHyeon struct mii_data *mii = sc->mii_pdata; 17078679427SPyun YongHyeon struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 17178679427SPyun YongHyeon int bmcr, qpr; 17278679427SPyun YongHyeon 17378679427SPyun YongHyeon mii->mii_media_status = IFM_AVALID; 17478679427SPyun YongHyeon mii->mii_media_active = IFM_ETHER; 17578679427SPyun YongHyeon 17678679427SPyun YongHyeon /* 17778679427SPyun YongHyeon * Don't get link from the BMSR. It's available in the QPR, 17878679427SPyun YongHyeon * and we have to read it twice to unlatch it anyhow. This 17978679427SPyun YongHyeon * gives us fewer register reads. 18078679427SPyun YongHyeon */ 18178679427SPyun YongHyeon qpr = PHY_READ(sc, MII_ICSPHY_QPR); /* unlatch */ 18278679427SPyun YongHyeon qpr = PHY_READ(sc, MII_ICSPHY_QPR); /* real value */ 18378679427SPyun YongHyeon 18478679427SPyun YongHyeon if (qpr & QPR_LINK) 18578679427SPyun YongHyeon mii->mii_media_status |= IFM_ACTIVE; 18678679427SPyun YongHyeon 18778679427SPyun YongHyeon bmcr = PHY_READ(sc, MII_BMCR); 18878679427SPyun YongHyeon if (bmcr & BMCR_ISO) { 18978679427SPyun YongHyeon mii->mii_media_active |= IFM_NONE; 19078679427SPyun YongHyeon mii->mii_media_status = 0; 19178679427SPyun YongHyeon return; 19278679427SPyun YongHyeon } 19378679427SPyun YongHyeon 19478679427SPyun YongHyeon if (bmcr & BMCR_LOOP) 19578679427SPyun YongHyeon mii->mii_media_active |= IFM_LOOP; 19678679427SPyun YongHyeon 19778679427SPyun YongHyeon if (bmcr & BMCR_AUTOEN) { 19878679427SPyun YongHyeon if ((qpr & QPR_ACOMP) == 0) { 19978679427SPyun YongHyeon /* Erg, still trying, I guess... */ 20078679427SPyun YongHyeon mii->mii_media_active |= IFM_NONE; 20178679427SPyun YongHyeon return; 20278679427SPyun YongHyeon } 20378679427SPyun YongHyeon if (qpr & QPR_SPEED) 20478679427SPyun YongHyeon mii->mii_media_active |= IFM_100_TX; 20578679427SPyun YongHyeon else 20678679427SPyun YongHyeon mii->mii_media_active |= IFM_10_T; 20778679427SPyun YongHyeon if (qpr & QPR_FDX) 2083fcb7a53SMarius Strobl mii->mii_media_active |= 2093fcb7a53SMarius Strobl IFM_FDX | mii_phy_flowstatus(sc); 21078679427SPyun YongHyeon else 21178679427SPyun YongHyeon mii->mii_media_active |= IFM_HDX; 21278679427SPyun YongHyeon } else 21378679427SPyun YongHyeon mii->mii_media_active = ife->ifm_media; 21478679427SPyun YongHyeon } 21578679427SPyun YongHyeon 21678679427SPyun YongHyeon static void 21778679427SPyun YongHyeon icsphy_reset(struct mii_softc *sc) 21878679427SPyun YongHyeon { 21978679427SPyun YongHyeon 22078679427SPyun YongHyeon mii_phy_reset(sc); 22178679427SPyun YongHyeon /* set powerdown feature */ 2223fcb7a53SMarius Strobl switch (sc->mii_mpd_model) { 2233fcb7a53SMarius Strobl case MII_MODEL_ICS_1890: 2243fcb7a53SMarius Strobl case MII_MODEL_ICS_1893: 22578679427SPyun YongHyeon PHY_WRITE(sc, MII_ICSPHY_ECR2, ECR2_100AUTOPWRDN); 22678679427SPyun YongHyeon break; 2273fcb7a53SMarius Strobl case MII_MODEL_ICS_1892: 22878679427SPyun YongHyeon PHY_WRITE(sc, MII_ICSPHY_ECR2, 22978679427SPyun YongHyeon ECR2_10AUTOPWRDN|ECR2_100AUTOPWRDN); 23078679427SPyun YongHyeon break; 23178679427SPyun YongHyeon default: 23278679427SPyun YongHyeon /* 1889 have no ECR2 */ 23378679427SPyun YongHyeon break; 23478679427SPyun YongHyeon } 23578679427SPyun YongHyeon /* 23678679427SPyun YongHyeon * There is no description that the reset do auto-negotiation in the 23778679427SPyun YongHyeon * data sheet. 23878679427SPyun YongHyeon */ 23978679427SPyun YongHyeon PHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_STARTNEG|BMCR_FDX); 24078679427SPyun YongHyeon } 241