/* $NetBSD: exphy.c,v 1.16 1999/04/23 04:24:32 thorpej Exp $ */ /*- * Copyright (c) 1998, 1999 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. * * 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. * * 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. */ #include __FBSDID("$FreeBSD$"); /* * driver for 3Com internal PHYs */ #include #include #include #include #include #include #include #include #include #include #include "miidevs.h" #include "miibus_if.h" static int exphy_probe(device_t); static int exphy_attach(device_t); static device_method_t exphy_methods[] = { /* device interface */ DEVMETHOD(device_probe, exphy_probe), DEVMETHOD(device_attach, exphy_attach), DEVMETHOD(device_detach, mii_phy_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), { 0, 0 } }; static devclass_t exphy_devclass; static driver_t exphy_driver = { "xlphy", exphy_methods, sizeof(struct mii_softc) }; DRIVER_MODULE(xlphy, miibus, exphy_driver, exphy_devclass, 0, 0); static int exphy_service(struct mii_softc *, struct mii_data *, int); static void exphy_reset(struct mii_softc *); /* * Some 3Com internal PHYs report zero for OUI and model, others use * actual values. * Note that the 3Com internal PHYs having OUI 0x105a and model 0 are * handled fine by ukphy(4); they can be isolated and don't require * special treatment after reset. */ static const struct mii_phydesc exphys[] = { { 0, 0, "3Com internal media interface" }, MII_PHY_DESC(xxBROADCOM, 3C905C), MII_PHY_END }; static const struct mii_phy_funcs exphy_funcs = { exphy_service, ukphy_status, exphy_reset }; static int exphy_probe(device_t dev) { if (strcmp(device_get_name(device_get_parent(device_get_parent(dev))), "xl") == 0) return (mii_phy_dev_probe(dev, exphys, BUS_PROBE_DEFAULT)); return (ENXIO); } static int exphy_attach(device_t dev) { /* * The 3Com PHY can never be isolated. */ mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE, &exphy_funcs, 1); return (0); } static int exphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) { 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; mii_phy_setmedia(sc); break; case MII_TICK: /* * 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. */ PHY_STATUS(sc); /* Callback if something changed. */ mii_phy_update(sc, cmd); return (0); } static void exphy_reset(struct mii_softc *sc) { mii_phy_reset(sc); /* * XXX 3Com PHY doesn't set the BMCR properly after * XXX reset, which breaks autonegotiation. */ PHY_WRITE(sc, MII_BMCR, BMCR_S100|BMCR_AUTOEN|BMCR_FDX); }