19526a692SSemen Ustimenko /*- 2*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-NetBSD 3*718cf2ccSPedro F. Giffuni * 49526a692SSemen Ustimenko * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 59526a692SSemen Ustimenko * All rights reserved. 69526a692SSemen Ustimenko * 79526a692SSemen Ustimenko * This code is derived from software contributed to The NetBSD Foundation 89526a692SSemen Ustimenko * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 99526a692SSemen Ustimenko * NASA Ames Research Center. 109526a692SSemen Ustimenko * 119526a692SSemen Ustimenko * Redistribution and use in source and binary forms, with or without 129526a692SSemen Ustimenko * modification, are permitted provided that the following conditions 139526a692SSemen Ustimenko * are met: 149526a692SSemen Ustimenko * 1. Redistributions of source code must retain the above copyright 159526a692SSemen Ustimenko * notice, this list of conditions and the following disclaimer. 169526a692SSemen Ustimenko * 2. Redistributions in binary form must reproduce the above copyright 179526a692SSemen Ustimenko * notice, this list of conditions and the following disclaimer in the 189526a692SSemen Ustimenko * documentation and/or other materials provided with the distribution. 199526a692SSemen Ustimenko * 209526a692SSemen Ustimenko * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 219526a692SSemen Ustimenko * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 229526a692SSemen Ustimenko * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 239526a692SSemen Ustimenko * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 249526a692SSemen Ustimenko * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 259526a692SSemen Ustimenko * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 269526a692SSemen Ustimenko * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 279526a692SSemen Ustimenko * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 289526a692SSemen Ustimenko * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 299526a692SSemen Ustimenko * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 309526a692SSemen Ustimenko * POSSIBILITY OF SUCH DAMAGE. 319526a692SSemen Ustimenko */ 32aad970f1SDavid E. O'Brien 33098ca2bdSWarner Losh /*- 349526a692SSemen Ustimenko * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 359526a692SSemen Ustimenko * 369526a692SSemen Ustimenko * Redistribution and use in source and binary forms, with or without 379526a692SSemen Ustimenko * modification, are permitted provided that the following conditions 389526a692SSemen Ustimenko * are met: 399526a692SSemen Ustimenko * 1. Redistributions of source code must retain the above copyright 409526a692SSemen Ustimenko * notice, this list of conditions and the following disclaimer. 419526a692SSemen Ustimenko * 2. Redistributions in binary form must reproduce the above copyright 429526a692SSemen Ustimenko * notice, this list of conditions and the following disclaimer in the 439526a692SSemen Ustimenko * documentation and/or other materials provided with the distribution. 449526a692SSemen Ustimenko * 459526a692SSemen Ustimenko * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 469526a692SSemen Ustimenko * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 479526a692SSemen Ustimenko * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 489526a692SSemen Ustimenko * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 499526a692SSemen Ustimenko * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 509526a692SSemen Ustimenko * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 519526a692SSemen Ustimenko * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 529526a692SSemen Ustimenko * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 539526a692SSemen Ustimenko * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 549526a692SSemen Ustimenko * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 559526a692SSemen Ustimenko */ 569526a692SSemen Ustimenko 5750aa1061SMarius Strobl #include <sys/cdefs.h> 5850aa1061SMarius Strobl __FBSDID("$FreeBSD$"); 5950aa1061SMarius Strobl 609526a692SSemen Ustimenko /* 619526a692SSemen Ustimenko * Driver for Altima AC101 10/100 PHY 629526a692SSemen Ustimenko */ 639526a692SSemen Ustimenko 649526a692SSemen Ustimenko #include <sys/param.h> 659526a692SSemen Ustimenko #include <sys/systm.h> 669526a692SSemen Ustimenko #include <sys/kernel.h> 679526a692SSemen Ustimenko #include <sys/socket.h> 689526a692SSemen Ustimenko #include <sys/errno.h> 699526a692SSemen Ustimenko #include <sys/module.h> 709526a692SSemen Ustimenko #include <sys/bus.h> 719526a692SSemen Ustimenko 729526a692SSemen Ustimenko #include <net/if.h> 739526a692SSemen Ustimenko #include <net/if_media.h> 749526a692SSemen Ustimenko 759526a692SSemen Ustimenko #include <dev/mii/mii.h> 769526a692SSemen Ustimenko #include <dev/mii/miivar.h> 772d3ce713SDavid E. O'Brien #include "miidevs.h" 789526a692SSemen Ustimenko 799526a692SSemen Ustimenko #include <dev/mii/acphyreg.h> 809526a692SSemen Ustimenko 819526a692SSemen Ustimenko #include "miibus_if.h" 829526a692SSemen Ustimenko 83e51a25f8SAlfred Perlstein static int acphy_probe(device_t); 84e51a25f8SAlfred Perlstein static int acphy_attach(device_t); 859526a692SSemen Ustimenko 869526a692SSemen Ustimenko static device_method_t acphy_methods[] = { 879526a692SSemen Ustimenko /* device interface */ 889526a692SSemen Ustimenko DEVMETHOD(device_probe, acphy_probe), 899526a692SSemen Ustimenko DEVMETHOD(device_attach, acphy_attach), 90279fe8d1SPoul-Henning Kamp DEVMETHOD(device_detach, mii_phy_detach), 919526a692SSemen Ustimenko DEVMETHOD(device_shutdown, bus_generic_shutdown), 92604f5f1fSMarius Strobl DEVMETHOD_END 939526a692SSemen Ustimenko }; 949526a692SSemen Ustimenko 959526a692SSemen Ustimenko static devclass_t acphy_devclass; 969526a692SSemen Ustimenko 979526a692SSemen Ustimenko static driver_t acphy_driver = { 989526a692SSemen Ustimenko "acphy", 999526a692SSemen Ustimenko acphy_methods, 1009526a692SSemen Ustimenko sizeof(struct mii_softc) 1019526a692SSemen Ustimenko }; 1029526a692SSemen Ustimenko 1039526a692SSemen Ustimenko DRIVER_MODULE(acphy, miibus, acphy_driver, acphy_devclass, 0, 0); 1049526a692SSemen Ustimenko 105e51a25f8SAlfred Perlstein static int acphy_service(struct mii_softc *, struct mii_data *, int); 106e51a25f8SAlfred Perlstein static void acphy_reset(struct mii_softc *); 107e51a25f8SAlfred Perlstein static void acphy_status(struct mii_softc *); 1089526a692SSemen Ustimenko 109a35b9333SMarius Strobl static const struct mii_phydesc acphys[] = { 1103fcb7a53SMarius Strobl MII_PHY_DESC(ALTIMA, AC101), 1113fcb7a53SMarius Strobl MII_PHY_DESC(ALTIMA, AC101L), 11265169ee9SMarius Strobl /* XXX This is reported to work, but it's not from any data sheet. */ 1133fcb7a53SMarius Strobl MII_PHY_DESC(ALTIMA, ACXXX), 114a35b9333SMarius Strobl MII_PHY_END 115a35b9333SMarius Strobl }; 116a35b9333SMarius Strobl 1173fcb7a53SMarius Strobl static const struct mii_phy_funcs acphy_funcs = { 1183fcb7a53SMarius Strobl acphy_service, 1193fcb7a53SMarius Strobl acphy_status, 1203fcb7a53SMarius Strobl acphy_reset 1213fcb7a53SMarius Strobl }; 1223fcb7a53SMarius Strobl 1239c1c2e99SAlfred Perlstein static int 1247d830ac9SWarner Losh acphy_probe(device_t dev) 1259526a692SSemen Ustimenko { 1269526a692SSemen Ustimenko 127a35b9333SMarius Strobl return (mii_phy_dev_probe(dev, acphys, BUS_PROBE_DEFAULT)); 1289526a692SSemen Ustimenko } 1299526a692SSemen Ustimenko 1309c1c2e99SAlfred Perlstein static int 1317d830ac9SWarner Losh acphy_attach(device_t dev) 1329526a692SSemen Ustimenko { 1339526a692SSemen Ustimenko struct mii_softc *sc; 1349526a692SSemen Ustimenko 1359526a692SSemen Ustimenko sc = device_get_softc(dev); 1369526a692SSemen Ustimenko 1373fcb7a53SMarius Strobl mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &acphy_funcs, 0); 1389526a692SSemen Ustimenko 1393fcb7a53SMarius Strobl PHY_RESET(sc); 14065169ee9SMarius Strobl 1413fcb7a53SMarius Strobl sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & sc->mii_capmask; 1429526a692SSemen Ustimenko device_printf(dev, " "); 143a9ddce98SMarius Strobl 14427e1f92dSGleb Smirnoff #define ADD(m) ifmedia_add(&sc->mii_pdata->mii_media, (m), 0, NULL) 145a9ddce98SMarius Strobl if ((PHY_READ(sc, MII_ACPHY_MCTL) & AC_MCTL_FX_SEL) != 0) { 146a9ddce98SMarius Strobl sc->mii_flags |= MIIF_HAVEFIBER; 14727e1f92dSGleb Smirnoff ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, 0, sc->mii_inst)); 148a9ddce98SMarius Strobl printf("100baseFX, "); 14927e1f92dSGleb Smirnoff ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_FX, IFM_FDX, sc->mii_inst)); 150a9ddce98SMarius Strobl printf("100baseFX-FDX, "); 151a9ddce98SMarius Strobl } 152a9ddce98SMarius Strobl #undef ADD 153a9ddce98SMarius Strobl 15465169ee9SMarius Strobl mii_phy_add_media(sc); 1559526a692SSemen Ustimenko printf("\n"); 1569526a692SSemen Ustimenko 1579526a692SSemen Ustimenko MIIBUS_MEDIAINIT(sc->mii_dev); 1589526a692SSemen Ustimenko return (0); 1599526a692SSemen Ustimenko } 1609526a692SSemen Ustimenko 161d9730b8bSJonathan Lemon static int 1627d830ac9SWarner Losh acphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 1639526a692SSemen Ustimenko { 1649526a692SSemen Ustimenko int reg; 1659526a692SSemen Ustimenko 1664592db46SSemen Ustimenko switch (cmd) { 1674592db46SSemen Ustimenko case MII_POLLSTAT: 1684592db46SSemen Ustimenko break; 1694592db46SSemen Ustimenko 1704592db46SSemen Ustimenko case MII_MEDIACHG: 1714592db46SSemen Ustimenko /* Wake & deisolate up if necessary */ 1729526a692SSemen Ustimenko reg = PHY_READ(sc, MII_BMCR); 1739526a692SSemen Ustimenko if (reg & (BMCR_ISO | BMCR_PDOWN)) 1749526a692SSemen Ustimenko PHY_WRITE(sc, MII_BMCR, reg & ~(BMCR_ISO | BMCR_PDOWN)); 1759526a692SSemen Ustimenko 17665169ee9SMarius Strobl mii_phy_setmedia(sc); 1779526a692SSemen Ustimenko break; 1789526a692SSemen Ustimenko 1799526a692SSemen Ustimenko case MII_TICK: 1809526a692SSemen Ustimenko /* 1814592db46SSemen Ustimenko * This PHY's autonegotiation doesn't need to be kicked. 182d9730b8bSJonathan Lemon */ 1839526a692SSemen Ustimenko break; 1849526a692SSemen Ustimenko } 1859526a692SSemen Ustimenko 1869526a692SSemen Ustimenko /* Update the media status. */ 1873fcb7a53SMarius Strobl PHY_STATUS(sc); 1889526a692SSemen Ustimenko 1899526a692SSemen Ustimenko /* Callback if something changed. */ 190d9730b8bSJonathan Lemon mii_phy_update(sc, cmd); 1919526a692SSemen Ustimenko return (0); 1929526a692SSemen Ustimenko } 1939526a692SSemen Ustimenko 194d9730b8bSJonathan Lemon static void 1957d830ac9SWarner Losh acphy_status(struct mii_softc *sc) 1969526a692SSemen Ustimenko { 1979526a692SSemen Ustimenko struct mii_data *mii = sc->mii_pdata; 1989526a692SSemen Ustimenko struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 1999526a692SSemen Ustimenko int bmsr, bmcr, diag; 2009526a692SSemen Ustimenko 2019526a692SSemen Ustimenko mii->mii_media_status = IFM_AVALID; 2029526a692SSemen Ustimenko mii->mii_media_active = IFM_ETHER; 2039526a692SSemen Ustimenko 2049526a692SSemen Ustimenko bmsr = PHY_READ(sc, MII_BMSR) | 2059526a692SSemen Ustimenko PHY_READ(sc, MII_BMSR); 2069526a692SSemen Ustimenko if (bmsr & BMSR_LINK) 2079526a692SSemen Ustimenko mii->mii_media_status |= IFM_ACTIVE; 2089526a692SSemen Ustimenko 2099526a692SSemen Ustimenko bmcr = PHY_READ(sc, MII_BMCR); 2109526a692SSemen Ustimenko if (bmcr & BMCR_ISO) { 2119526a692SSemen Ustimenko mii->mii_media_active |= IFM_NONE; 2129526a692SSemen Ustimenko mii->mii_media_status = 0; 2139526a692SSemen Ustimenko return; 2149526a692SSemen Ustimenko } 2159526a692SSemen Ustimenko 2169526a692SSemen Ustimenko if (bmcr & BMCR_LOOP) 2179526a692SSemen Ustimenko mii->mii_media_active |= IFM_LOOP; 2189526a692SSemen Ustimenko 2199526a692SSemen Ustimenko if (bmcr & BMCR_AUTOEN) { 2209526a692SSemen Ustimenko if ((bmsr & BMSR_ACOMP) == 0) { 2219526a692SSemen Ustimenko /* Erg, still trying, I guess... */ 2229526a692SSemen Ustimenko mii->mii_media_active |= IFM_NONE; 2239526a692SSemen Ustimenko return; 2249526a692SSemen Ustimenko } 2254592db46SSemen Ustimenko diag = PHY_READ(sc, MII_ACPHY_DIAG); 2269526a692SSemen Ustimenko if (diag & AC_DIAG_SPEED) 2279526a692SSemen Ustimenko mii->mii_media_active |= IFM_100_TX; 2289526a692SSemen Ustimenko else 2299526a692SSemen Ustimenko mii->mii_media_active |= IFM_10_T; 2309526a692SSemen Ustimenko 2319526a692SSemen Ustimenko if (diag & AC_DIAG_DUPLEX) 2323fcb7a53SMarius Strobl mii->mii_media_active |= 2333fcb7a53SMarius Strobl IFM_FDX | mii_phy_flowstatus(sc); 234d7a9ad56SMarius Strobl else 235d7a9ad56SMarius Strobl mii->mii_media_active |= IFM_HDX; 2369526a692SSemen Ustimenko } else 2379526a692SSemen Ustimenko mii->mii_media_active = ife->ifm_media; 2389526a692SSemen Ustimenko } 2399526a692SSemen Ustimenko 240d9730b8bSJonathan Lemon static void 2417d830ac9SWarner Losh acphy_reset(struct mii_softc *sc) 2429526a692SSemen Ustimenko { 2439526a692SSemen Ustimenko 2449526a692SSemen Ustimenko mii_phy_reset(sc); 2459526a692SSemen Ustimenko PHY_WRITE(sc, MII_ACPHY_INT, 0); 2469526a692SSemen Ustimenko } 247