1160636Syongari/* $NetBSD: gentbi.c,v 1.15 2006/03/29 07:05:24 thorpej Exp $ */ 2160636Syongari 3160636Syongari/*- 4160636Syongari * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. 5160636Syongari * All rights reserved. 6160636Syongari * 7160636Syongari * This code is derived from software contributed to The NetBSD Foundation 8160636Syongari * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9160636Syongari * NASA Ames Research Center. 10160636Syongari * 11160636Syongari * Redistribution and use in source and binary forms, with or without 12160636Syongari * modification, are permitted provided that the following conditions 13160636Syongari * are met: 14160636Syongari * 1. Redistributions of source code must retain the above copyright 15160636Syongari * notice, this list of conditions and the following disclaimer. 16160636Syongari * 2. Redistributions in binary form must reproduce the above copyright 17160636Syongari * notice, this list of conditions and the following disclaimer in the 18160636Syongari * documentation and/or other materials provided with the distribution. 19160636Syongari * 20160636Syongari * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21160636Syongari * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22160636Syongari * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23160636Syongari * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24160636Syongari * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25160636Syongari * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26160636Syongari * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27160636Syongari * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28160636Syongari * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29160636Syongari * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30160636Syongari * POSSIBILITY OF SUCH DAMAGE. 31160636Syongari */ 32160636Syongari 33160636Syongari/* 34160636Syongari * Copyright (c) 1997 Manuel Bouyer. All rights reserved. 35160636Syongari * 36160636Syongari * Redistribution and use in source and binary forms, with or without 37160636Syongari * modification, are permitted provided that the following conditions 38160636Syongari * are met: 39160636Syongari * 1. Redistributions of source code must retain the above copyright 40160636Syongari * notice, this list of conditions and the following disclaimer. 41160636Syongari * 2. Redistributions in binary form must reproduce the above copyright 42160636Syongari * notice, this list of conditions and the following disclaimer in the 43160636Syongari * documentation and/or other materials provided with the distribution. 44160636Syongari * 45160636Syongari * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 46160636Syongari * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 47160636Syongari * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 48160636Syongari * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 49160636Syongari * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 50160636Syongari * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 51160636Syongari * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 52160636Syongari * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 53160636Syongari * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 54160636Syongari * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 55160636Syongari */ 56160636Syongari 57160636Syongari/* 58213364Smarius * Driver for generic ten-bit (1000BASE-SX) interfaces, built into 59160636Syongari * many Gigabit Ethernet chips. 60160636Syongari * 61160636Syongari * All we have to do here is correctly report speed and duplex. 62160636Syongari */ 63160636Syongari 64160636Syongari#include <sys/cdefs.h> 65160636Syongari__FBSDID("$FreeBSD$"); 66160636Syongari 67160636Syongari/* 68160636Syongari * Driver for generic unknown ten-bit interfaces(1000BASE-{LX,SX} 69160636Syongari * fiber interfaces). 70160636Syongari */ 71160636Syongari 72160636Syongari#include <sys/param.h> 73160636Syongari#include <sys/systm.h> 74160636Syongari#include <sys/kernel.h> 75160636Syongari#include <sys/module.h> 76160636Syongari#include <sys/socket.h> 77160636Syongari#include <sys/errno.h> 78160636Syongari#include <sys/bus.h> 79160636Syongari 80160636Syongari#include <net/if.h> 81160636Syongari#include <net/if_media.h> 82160636Syongari 83160636Syongari#include <dev/mii/mii.h> 84160636Syongari#include <dev/mii/miivar.h> 85160636Syongari#include "miidevs.h" 86160636Syongari 87160636Syongari#include "miibus_if.h" 88160636Syongari 89160636Syongaristatic int gentbi_probe(device_t); 90160636Syongaristatic int gentbi_attach(device_t); 91160636Syongari 92160636Syongaristatic device_method_t gentbi_methods[] = { 93160636Syongari /* device interface */ 94160636Syongari DEVMETHOD(device_probe, gentbi_probe), 95160636Syongari DEVMETHOD(device_attach, gentbi_attach), 96160636Syongari DEVMETHOD(device_detach, mii_phy_detach), 97160636Syongari DEVMETHOD(device_shutdown, bus_generic_shutdown), 98229093Shselasky DEVMETHOD_END 99160636Syongari}; 100160636Syongari 101160636Syongaristatic devclass_t gentbi_devclass; 102160636Syongari 103160636Syongaristatic driver_t gentbi_driver = { 104160636Syongari "gentbi", 105160636Syongari gentbi_methods, 106160636Syongari sizeof(struct mii_softc) 107160636Syongari}; 108160636Syongari 109160636SyongariDRIVER_MODULE(gentbi, miibus, gentbi_driver, gentbi_devclass, 0, 0); 110160636Syongari 111160636Syongaristatic int gentbi_service(struct mii_softc *, struct mii_data *, int); 112160636Syongaristatic void gentbi_status(struct mii_softc *); 113160636Syongari 114221407Smariusstatic const struct mii_phy_funcs gentbi_funcs = { 115221407Smarius gentbi_service, 116221407Smarius gentbi_status, 117221407Smarius mii_phy_reset 118221407Smarius}; 119221407Smarius 120160636Syongaristatic int 121160636Syongarigentbi_probe(device_t dev) 122160636Syongari{ 123160636Syongari device_t parent; 124160636Syongari struct mii_attach_args *ma; 125160636Syongari int bmsr, extsr; 126160636Syongari 127160636Syongari parent = device_get_parent(dev); 128160636Syongari ma = device_get_ivars(dev); 129160636Syongari 130160636Syongari /* 131160636Syongari * We match as a generic TBI if: 132160636Syongari * 133160636Syongari * - There is no media in the BMSR. 134160636Syongari * - EXTSR has only 1000X. 135160636Syongari */ 136160636Syongari bmsr = MIIBUS_READREG(parent, ma->mii_phyno, MII_BMSR); 137160636Syongari if ((bmsr & BMSR_EXTSTAT) == 0 || (bmsr & BMSR_MEDIAMASK) != 0) 138160636Syongari return (ENXIO); 139160636Syongari 140160636Syongari extsr = MIIBUS_READREG(parent, ma->mii_phyno, MII_EXTSR); 141160636Syongari if (extsr & (EXTSR_1000TFDX|EXTSR_1000THDX)) 142160636Syongari return (ENXIO); 143160636Syongari 144160636Syongari if (extsr & (EXTSR_1000XFDX|EXTSR_1000XHDX)) { 145160636Syongari /* 146160636Syongari * We think this is a generic TBI. Return a match 147160636Syongari * priority higher than ukphy, but lower than what 148160636Syongari * specific drivers will return. 149160636Syongari */ 150160636Syongari device_set_desc(dev, "Generic ten-bit interface"); 151160636Syongari return (BUS_PROBE_LOW_PRIORITY); 152160636Syongari } 153160636Syongari 154160636Syongari return (ENXIO); 155160636Syongari} 156160636Syongari 157160636Syongaristatic int 158160636Syongarigentbi_attach(device_t dev) 159160636Syongari{ 160160636Syongari struct mii_softc *sc; 161160636Syongari 162160636Syongari sc = device_get_softc(dev); 163160636Syongari 164221407Smarius mii_phy_dev_attach(dev, MIIF_NOMANPAUSE, &gentbi_funcs, 0); 165160636Syongari 166221407Smarius PHY_RESET(sc); 167160636Syongari 168160636Syongari /* 169160636Syongari * Mask out all media in the BMSR. We only are really interested 170160636Syongari * in "auto". 171160636Syongari */ 172160636Syongari sc->mii_capabilities = 173221407Smarius PHY_READ(sc, MII_BMSR) & sc->mii_capmask & ~BMSR_MEDIAMASK; 174160636Syongari if (sc->mii_capabilities & BMSR_EXTSTAT) 175160636Syongari sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); 176160636Syongari 177160636Syongari device_printf(dev, " "); 178164703Smarius mii_phy_add_media(sc); 179160636Syongari printf("\n"); 180160636Syongari 181166263Sdwhite MIIBUS_MEDIAINIT(sc->mii_dev); 182160636Syongari return (0); 183160636Syongari} 184160636Syongari 185160636Syongaristatic int 186160636Syongarigentbi_service(struct mii_softc *sc, struct mii_data *mii, int cmd) 187160636Syongari{ 188160636Syongari 189160636Syongari switch (cmd) { 190160636Syongari case MII_POLLSTAT: 191160636Syongari break; 192160636Syongari 193160636Syongari case MII_MEDIACHG: 194160636Syongari /* 195160636Syongari * If the interface is not up, don't do anything. 196160636Syongari */ 197160636Syongari if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 198160636Syongari break; 199160636Syongari 200160636Syongari mii_phy_setmedia(sc); 201160636Syongari break; 202160636Syongari 203160636Syongari case MII_TICK: 204160636Syongari if (mii_phy_tick(sc) == EJUSTRETURN) 205160636Syongari return (0); 206160636Syongari break; 207160636Syongari } 208160636Syongari 209160636Syongari /* Update the media status. */ 210221407Smarius PHY_STATUS(sc); 211160636Syongari 212160636Syongari /* Callback if something changed. */ 213160636Syongari mii_phy_update(sc, cmd); 214160636Syongari return (0); 215160636Syongari} 216160636Syongari 217160636Syongaristatic void 218160636Syongarigentbi_status(struct mii_softc *sc) 219160636Syongari{ 220160636Syongari struct mii_data *mii = sc->mii_pdata; 221160636Syongari struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 222160636Syongari int bmsr, bmcr, anlpar; 223160636Syongari 224160636Syongari mii->mii_media_status = IFM_AVALID; 225160636Syongari mii->mii_media_active = IFM_ETHER; 226160636Syongari 227160636Syongari bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); 228160636Syongari 229160636Syongari if (bmsr & BMSR_LINK) 230160636Syongari mii->mii_media_status |= IFM_ACTIVE; 231160636Syongari 232160636Syongari bmcr = PHY_READ(sc, MII_BMCR); 233160636Syongari if (bmcr & BMCR_ISO) { 234160636Syongari mii->mii_media_active |= IFM_NONE; 235160636Syongari mii->mii_media_status = 0; 236160636Syongari return; 237160636Syongari } 238160636Syongari 239160636Syongari if (bmcr & BMCR_LOOP) 240160636Syongari mii->mii_media_active |= IFM_LOOP; 241160636Syongari 242160636Syongari if (bmcr & BMCR_AUTOEN) { 243160636Syongari /* 244173157Smarius * The media status bits are only valid if autonegotiation 245160636Syongari * has completed (or it's disabled). 246160636Syongari */ 247160636Syongari if ((bmsr & BMSR_ACOMP) == 0) { 248160636Syongari /* Erg, still trying, I guess... */ 249160636Syongari mii->mii_media_active |= IFM_NONE; 250160636Syongari return; 251160636Syongari } 252160636Syongari 253160636Syongari /* 254160636Syongari * The media is always 1000baseSX. Check the ANLPAR to 255160636Syongari * see if we're doing full-duplex. 256160636Syongari */ 257160636Syongari mii->mii_media_active |= IFM_1000_SX; 258160636Syongari anlpar = PHY_READ(sc, MII_ANLPAR); 259160636Syongari if ((sc->mii_extcapabilities & EXTSR_1000XFDX) != 0 && 260160636Syongari (anlpar & ANLPAR_X_FD) != 0) 261215298Smarius mii->mii_media_active |= 262215298Smarius IFM_FDX | mii_phy_flowstatus(sc); 263213384Smarius else 264213384Smarius mii->mii_media_active |= IFM_HDX; 265160636Syongari } else 266160636Syongari mii->mii_media_active = ife->ifm_media; 267160636Syongari} 268