1*5c7e8fc0Sjason /* $OpenBSD: ukphy.c,v 1.6 1999/12/07 22:01:33 jason Exp $ */ 2b2e83a74Sjason /* $NetBSD: ukphy.c,v 1.1.6.1 1999/04/23 15:39:00 perry Exp $ */ 3bf11b014Sjason 4bf11b014Sjason /*- 5b2e83a74Sjason * Copyright (c) 1998, 1999 The NetBSD Foundation, Inc. 6bf11b014Sjason * All rights reserved. 7bf11b014Sjason * 8bf11b014Sjason * This code is derived from software contributed to The NetBSD Foundation 9bf11b014Sjason * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10bf11b014Sjason * NASA Ames Research Center, and by Frank van der Linden. 11bf11b014Sjason * 12bf11b014Sjason * Redistribution and use in source and binary forms, with or without 13bf11b014Sjason * modification, are permitted provided that the following conditions 14bf11b014Sjason * are met: 15bf11b014Sjason * 1. Redistributions of source code must retain the above copyright 16bf11b014Sjason * notice, this list of conditions and the following disclaimer. 17bf11b014Sjason * 2. Redistributions in binary form must reproduce the above copyright 18bf11b014Sjason * notice, this list of conditions and the following disclaimer in the 19bf11b014Sjason * documentation and/or other materials provided with the distribution. 20bf11b014Sjason * 3. All advertising materials mentioning features or use of this software 21bf11b014Sjason * must display the following acknowledgement: 22bf11b014Sjason * This product includes software developed by the NetBSD 23bf11b014Sjason * Foundation, Inc. and its contributors. 24bf11b014Sjason * 4. Neither the name of The NetBSD Foundation nor the names of its 25bf11b014Sjason * contributors may be used to endorse or promote products derived 26bf11b014Sjason * from this software without specific prior written permission. 27bf11b014Sjason * 28bf11b014Sjason * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 29bf11b014Sjason * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 30bf11b014Sjason * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 31bf11b014Sjason * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 32bf11b014Sjason * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 33bf11b014Sjason * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 34bf11b014Sjason * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 35bf11b014Sjason * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 36bf11b014Sjason * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 37bf11b014Sjason * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38bf11b014Sjason * POSSIBILITY OF SUCH DAMAGE. 39bf11b014Sjason */ 40bf11b014Sjason 41bf11b014Sjason /* 42bf11b014Sjason * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 43bf11b014Sjason * 44bf11b014Sjason * Redistribution and use in source and binary forms, with or without 45bf11b014Sjason * modification, are permitted provided that the following conditions 46bf11b014Sjason * are met: 47bf11b014Sjason * 1. Redistributions of source code must retain the above copyright 48bf11b014Sjason * notice, this list of conditions and the following disclaimer. 49bf11b014Sjason * 2. Redistributions in binary form must reproduce the above copyright 50bf11b014Sjason * notice, this list of conditions and the following disclaimer in the 51bf11b014Sjason * documentation and/or other materials provided with the distribution. 52bf11b014Sjason * 3. All advertising materials mentioning features or use of this software 53bf11b014Sjason * must display the following acknowledgement: 54bf11b014Sjason * This product includes software developed by Manuel Bouyer. 55bf11b014Sjason * 4. The name of the author may not be used to endorse or promote products 56bf11b014Sjason * derived from this software without specific prior written permission. 57bf11b014Sjason * 58bf11b014Sjason * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 59bf11b014Sjason * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60bf11b014Sjason * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61bf11b014Sjason * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 62bf11b014Sjason * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63bf11b014Sjason * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64bf11b014Sjason * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65bf11b014Sjason * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66bf11b014Sjason * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 67bf11b014Sjason * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68bf11b014Sjason */ 69bf11b014Sjason 70bf11b014Sjason /* 71bf11b014Sjason * driver for generic unknown PHYs 72bf11b014Sjason */ 73bf11b014Sjason 74bf11b014Sjason #include <sys/param.h> 75bf11b014Sjason #include <sys/systm.h> 76bf11b014Sjason #include <sys/kernel.h> 77bf11b014Sjason #include <sys/device.h> 78bf11b014Sjason #include <sys/malloc.h> 79bf11b014Sjason #include <sys/socket.h> 80b2e83a74Sjason #include <sys/errno.h> 81bf11b014Sjason 82bf11b014Sjason #include <net/if.h> 83bf11b014Sjason #include <net/if_media.h> 84bf11b014Sjason 85bf11b014Sjason #include <dev/mii/mii.h> 86bf11b014Sjason #include <dev/mii/miivar.h> 87bf11b014Sjason 88bf11b014Sjason int ukphymatch __P((struct device *, void *, void *)); 89bf11b014Sjason void ukphyattach __P((struct device *, struct device *, void *)); 90bf11b014Sjason 91bf11b014Sjason struct cfattach ukphy_ca = { 92bf11b014Sjason sizeof(struct mii_softc), ukphymatch, ukphyattach 93bf11b014Sjason }; 94bf11b014Sjason 95bf11b014Sjason struct cfdriver ukphy_cd = { 96bf11b014Sjason NULL, "ukphy", DV_DULL 97bf11b014Sjason }; 98bf11b014Sjason 99bf11b014Sjason int ukphy_service __P((struct mii_softc *, struct mii_data *, int)); 100bf11b014Sjason 101bf11b014Sjason int 102bf11b014Sjason ukphymatch(parent, match, aux) 103bf11b014Sjason struct device *parent; 104bf11b014Sjason void *match; 105bf11b014Sjason void *aux; 106bf11b014Sjason { 107bf11b014Sjason 108bf11b014Sjason /* 109bf11b014Sjason * We know something is here, so always match at a low priority. 110bf11b014Sjason */ 111bf11b014Sjason return (1); 112bf11b014Sjason } 113bf11b014Sjason 114bf11b014Sjason void 115bf11b014Sjason ukphyattach(parent, self, aux) 116bf11b014Sjason struct device *parent, *self; 117bf11b014Sjason void *aux; 118bf11b014Sjason { 119bf11b014Sjason struct mii_softc *sc = (struct mii_softc *)self; 120bf11b014Sjason struct mii_attach_args *ma = aux; 121bf11b014Sjason struct mii_data *mii = ma->mii_data; 122bf11b014Sjason 123bf11b014Sjason printf(": Generic IEEE 802.3u media interface\n"); 124bf11b014Sjason printf("%s: OUI 0x%06x, model 0x%04x, rev. %d\n", 125bf11b014Sjason sc->mii_dev.dv_xname, MII_OUI(ma->mii_id1, ma->mii_id2), 126bf11b014Sjason MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); 127bf11b014Sjason 128bf11b014Sjason sc->mii_inst = mii->mii_instance; 129bf11b014Sjason sc->mii_phy = ma->mii_phyno; 130bf11b014Sjason sc->mii_service = ukphy_service; 131bf11b014Sjason sc->mii_pdata = mii; 132bf11b014Sjason 133bf11b014Sjason mii_phy_reset(sc); 134bf11b014Sjason 135bf11b014Sjason sc->mii_capabilities = 136bf11b014Sjason PHY_READ(sc, MII_BMSR) & ma->mii_capmask; 137eb1f77c0Sderaadt if (sc->mii_capabilities & BMSR_MEDIAMASK) 138*5c7e8fc0Sjason mii_add_media(sc); 139bf11b014Sjason } 140bf11b014Sjason 141bf11b014Sjason int 142bf11b014Sjason ukphy_service(sc, mii, cmd) 143bf11b014Sjason struct mii_softc *sc; 144bf11b014Sjason struct mii_data *mii; 145bf11b014Sjason int cmd; 146bf11b014Sjason { 147bf11b014Sjason struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 148bf11b014Sjason int reg; 149bf11b014Sjason 150bf11b014Sjason switch (cmd) { 151bf11b014Sjason case MII_POLLSTAT: 152bf11b014Sjason /* 153bf11b014Sjason * If we're not polling our PHY instance, just return. 154bf11b014Sjason */ 155bf11b014Sjason if (IFM_INST(ife->ifm_media) != sc->mii_inst) 156bf11b014Sjason return (0); 157bf11b014Sjason break; 158bf11b014Sjason 159bf11b014Sjason case MII_MEDIACHG: 160bf11b014Sjason /* 161bf11b014Sjason * If the media indicates a different PHY instance, 162bf11b014Sjason * isolate ourselves. 163bf11b014Sjason */ 164bf11b014Sjason if (IFM_INST(ife->ifm_media) != sc->mii_inst) { 165bf11b014Sjason reg = PHY_READ(sc, MII_BMCR); 166bf11b014Sjason PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); 167bf11b014Sjason return (0); 168bf11b014Sjason } 169bf11b014Sjason 170bf11b014Sjason /* 171bf11b014Sjason * If the interface is not up, don't do anything. 172bf11b014Sjason */ 173bf11b014Sjason if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 174bf11b014Sjason break; 175bf11b014Sjason 176bf11b014Sjason switch (IFM_SUBTYPE(ife->ifm_media)) { 177bf11b014Sjason case IFM_AUTO: 178bf11b014Sjason /* 179bf11b014Sjason * If we're already in auto mode, just return. 180bf11b014Sjason */ 181bf11b014Sjason if (PHY_READ(sc, MII_BMCR) & BMCR_AUTOEN) 182bf11b014Sjason return (0); 183b2e83a74Sjason (void) mii_phy_auto(sc, 1); 184bf11b014Sjason break; 185bf11b014Sjason default: 186*5c7e8fc0Sjason mii_phy_setmedia(sc); 187bf11b014Sjason } 188bf11b014Sjason break; 189bf11b014Sjason 190bf11b014Sjason case MII_TICK: 191bf11b014Sjason /* 192bf11b014Sjason * If we're not currently selected, just return. 193bf11b014Sjason */ 194bf11b014Sjason if (IFM_INST(ife->ifm_media) != sc->mii_inst) 195bf11b014Sjason return (0); 196bf11b014Sjason 197bf11b014Sjason /* 198bf11b014Sjason * Only used for autonegotiation. 199bf11b014Sjason */ 200bf11b014Sjason if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 201bf11b014Sjason return (0); 202bf11b014Sjason 203bf11b014Sjason /* 204bf11b014Sjason * Is the interface even up? 205bf11b014Sjason */ 206bf11b014Sjason if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 207bf11b014Sjason return (0); 208bf11b014Sjason 209bf11b014Sjason /* 210bf11b014Sjason * Check to see if we have link. If we do, we don't 211bf11b014Sjason * need to restart the autonegotiation process. Read 212bf11b014Sjason * the BMSR twice in case it's latched. 213bf11b014Sjason */ 214bf11b014Sjason reg = PHY_READ(sc, MII_BMSR) | 215bf11b014Sjason PHY_READ(sc, MII_BMSR); 216bf11b014Sjason if (reg & BMSR_LINK) 217bf11b014Sjason return (0); 218bf11b014Sjason 219bf11b014Sjason /* 220bf11b014Sjason * Only retry autonegotiation every 5 seconds. 221bf11b014Sjason */ 222bf11b014Sjason if (++sc->mii_ticks != 5) 223bf11b014Sjason return (0); 224bf11b014Sjason 225bf11b014Sjason sc->mii_ticks = 0; 226bf11b014Sjason mii_phy_reset(sc); 227b2e83a74Sjason if (mii_phy_auto(sc, 0) == EJUSTRETURN) 228b2e83a74Sjason return (0); 229bf11b014Sjason break; 230*5c7e8fc0Sjason 231*5c7e8fc0Sjason case MII_DOWN: 232*5c7e8fc0Sjason mii_phy_down(sc); 233*5c7e8fc0Sjason return (0); 234bf11b014Sjason } 235bf11b014Sjason 236bf11b014Sjason /* Update the media status. */ 237bf11b014Sjason ukphy_status(sc); 238bf11b014Sjason 239bf11b014Sjason /* Callback if something changed. */ 240bf11b014Sjason if (sc->mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) { 241bf11b014Sjason (*mii->mii_statchg)(sc->mii_dev.dv_parent); 242bf11b014Sjason sc->mii_active = mii->mii_media_active; 243bf11b014Sjason } 244bf11b014Sjason return (0); 245bf11b014Sjason } 246