From cafbf72df7fc4da1511f8e0c9b1a58b7b235a0a0 Mon Sep 17 00:00:00 2001 From: Siarzhuk Zharski Date: Wed, 9 Dec 2009 20:10:39 +0000 Subject: [PATCH] VIA VT6122 Gigabit Ethernet driver. Based on FreeBSD vge driver. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34608 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/drivers/network/Jamfile | 1 + .../kernel/drivers/network/vt612x/Jamfile | 3 + .../kernel/drivers/network/vt612x/dev/Jamfile | 4 + .../drivers/network/vt612x/dev/mii/Jamfile | 21 + .../drivers/network/vt612x/dev/mii/ciphy.c | 435 ++++++++++++++++++ .../drivers/network/vt612x/dev/mii/ciphyreg.h | 351 ++++++++++++++ .../drivers/network/vt612x/dev/mii/ukphy.c | 220 +++++++++ .../network/vt612x/dev/mii/ukphy_subr.c | 129 ++++++ .../drivers/network/vt612x/dev/vge/Jamfile | 18 + .../drivers/network/vt612x/dev/vge/glue.c | 29 ++ .../drivers/network/vt612x/dev/vge/if_vge.c | 23 + 11 files changed, 1234 insertions(+) create mode 100644 src/add-ons/kernel/drivers/network/vt612x/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/mii/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphyreg.h create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/vge/Jamfile create mode 100644 src/add-ons/kernel/drivers/network/vt612x/dev/vge/glue.c diff --git a/src/add-ons/kernel/drivers/network/Jamfile b/src/add-ons/kernel/drivers/network/Jamfile index aae1721d23..0946a37101 100644 --- a/src/add-ons/kernel/drivers/network/Jamfile +++ b/src/add-ons/kernel/drivers/network/Jamfile @@ -27,6 +27,7 @@ SubInclude HAIKU_TOP src add-ons kernel drivers network attansic_l1 ; SubInclude HAIKU_TOP src add-ons kernel drivers network attansic_l2 ; SubInclude HAIKU_TOP src add-ons kernel drivers network ar81xx ; SubInclude HAIKU_TOP src add-ons kernel drivers network rtl81xx ; +SubInclude HAIKU_TOP src add-ons kernel drivers network vt612x ; SubIncludeGPL HAIKU_TOP src add-ons kernel drivers network bcm440x ; SubIncludeGPL HAIKU_TOP src add-ons kernel drivers network bcm570x ; diff --git a/src/add-ons/kernel/drivers/network/vt612x/Jamfile b/src/add-ons/kernel/drivers/network/vt612x/Jamfile new file mode 100644 index 0000000000..9490443d85 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network vt612x ; + +SubInclude HAIKU_TOP src add-ons kernel drivers network vt612x dev ; diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/Jamfile b/src/add-ons/kernel/drivers/network/vt612x/dev/Jamfile new file mode 100644 index 0000000000..3d84a77d4a --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/Jamfile @@ -0,0 +1,4 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network vt612x dev ; + +SubInclude HAIKU_TOP src add-ons kernel drivers network vt612x dev mii ; +SubInclude HAIKU_TOP src add-ons kernel drivers network vt612x dev vge ; diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/Jamfile b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/Jamfile new file mode 100644 index 0000000000..10df624495 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/Jamfile @@ -0,0 +1,21 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network vt612x dev mii ; + +UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; + +UsePrivateHeaders net system ; +UsePrivateKernelHeaders ; + +SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ; + +KernelStaticLibrary vt612x_mii.a + : + ciphy.c + ukphy.c + ukphy_subr.c + ; + +ObjectHdrs [ FGristFiles ciphy$(SUFOBJ) ukphy$(SUFOBJ) ] + : [ FDirName $(TARGET_COMMON_DEBUG_OBJECT_DIR) libs compat freebsd_network ] ; +Includes [ FGristFiles ciphy.c ukphy.c ] : miidevs.h ; + diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c new file mode 100644 index 0000000000..e437af27d0 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphy.c @@ -0,0 +1,435 @@ +/*- + * Copyright (c) 2004 + * Bill Paul . 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD + * 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. + * + * $FreeBSD: src/sys/dev/mii/ciphy.c,v 1.2 2005/01/06 01:42:55 imp Exp $ + */ + +#include +__FBSDID("$FreeBSD: src/sys/dev/mii/ciphy.c,v 1.2 2005/01/06 01:42:55 imp Exp $"); + +/* + * Driver for the Cicada CS8201 10/100/1000 copper PHY. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include "miidevs.h" + +#include + +#include "miibus_if.h" + +#include +/* +#include +*/ +static int ciphy_probe(device_t); +static int ciphy_attach(device_t); + +static device_method_t ciphy_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, ciphy_probe), + DEVMETHOD(device_attach, ciphy_attach), + DEVMETHOD(device_detach, mii_phy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + { 0, 0 } +}; + +static devclass_t ciphy_devclass; + +static driver_t ciphy_driver = { + "ciphy", + ciphy_methods, + sizeof(struct mii_softc) +}; + +DRIVER_MODULE(ciphy, miibus, ciphy_driver, ciphy_devclass, 0, 0); + +static int ciphy_service(struct mii_softc *, struct mii_data *, int); +static void ciphy_status(struct mii_softc *); +static void ciphy_reset(struct mii_softc *); +static void ciphy_fixup(struct mii_softc *); + +static int +ciphy_probe(dev) + device_t dev; +{ + struct mii_attach_args *ma; + + ma = device_get_ivars(dev); + +device_printf(dev, "OUI: %x\n", MII_OUI(ma->mii_id1, ma->mii_id2)); +device_printf(dev, "MODEL: %x\n", MII_MODEL(ma->mii_id2)); + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_CICADA && + MII_MODEL(ma->mii_id2) == MII_MODEL_CICADA_CS8201) { + device_set_desc(dev, MII_STR_CICADA_CS8201); + return(0); + } + + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_CICADA && + MII_MODEL(ma->mii_id2) == MII_MODEL_CICADA_CS8201A) { + device_set_desc(dev, MII_STR_CICADA_CS8201A); + return(0); + } + + if (MII_OUI(ma->mii_id1, ma->mii_id2) == MII_OUI_CICADA && + MII_MODEL(ma->mii_id2) == MII_MODEL_CICADA_CS8201B) { + device_set_desc(dev, MII_STR_CICADA_CS8201B); + return(0); + } + + return(ENXIO); +} + +static int +ciphy_attach(dev) + device_t dev; +{ + struct mii_softc *sc; + struct mii_attach_args *ma; + struct mii_data *mii; + + sc = device_get_softc(dev); + ma = device_get_ivars(dev); + sc->mii_dev = device_get_parent(dev); + mii = device_get_softc(sc->mii_dev); + LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); + + sc->mii_inst = mii->mii_instance; + sc->mii_phy = ma->mii_phyno; + sc->mii_service = ciphy_service; + sc->mii_pdata = mii; + + sc->mii_flags |= MIIF_NOISOLATE; + mii->mii_instance++; + + ciphy_reset(sc); + + sc->mii_capabilities = + PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + if (sc->mii_capabilities & BMSR_EXTSTAT) + sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); + device_printf(dev, " "); + mii_phy_add_media(sc); + printf("\n"); + + MIIBUS_MEDIAINIT(sc->mii_dev); + return(0); +} + +static int +ciphy_service(sc, mii, cmd) + struct mii_softc *sc; + struct mii_data *mii; + int cmd; +{ + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int reg, speed, gig; + + switch (cmd) { + case MII_POLLSTAT: + /* + * If we're not polling our PHY instance, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + break; + + case MII_MEDIACHG: + /* + * If the media indicates a different PHY instance, + * isolate ourselves. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + reg = PHY_READ(sc, MII_BMCR); + PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); + return (0); + } + + /* + * If the interface is not up, don't do anything. + */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + break; + + ciphy_fixup(sc); /* XXX hardware bug work-around */ + + switch (IFM_SUBTYPE(ife->ifm_media)) { + case IFM_AUTO: +#ifdef foo + /* + * If we're already in auto mode, just return. + */ + if (PHY_READ(sc, CIPHY_MII_BMCR) & CIPHY_BMCR_AUTOEN) + return (0); +#endif + (void) mii_phy_auto(sc); + break; + case IFM_1000_T: + speed = CIPHY_S1000; + goto setit; + case IFM_100_TX: + speed = CIPHY_S100; + goto setit; + case IFM_10_T: + speed = CIPHY_S10; +setit: + if ((ife->ifm_media & IFM_GMASK) == IFM_FDX) { + speed |= CIPHY_BMCR_FDX; + gig = CIPHY_1000CTL_AFD; + } else { + gig = CIPHY_1000CTL_AHD; + } + + PHY_WRITE(sc, CIPHY_MII_1000CTL, 0); + PHY_WRITE(sc, CIPHY_MII_BMCR, speed); + PHY_WRITE(sc, CIPHY_MII_ANAR, CIPHY_SEL_TYPE); + + if (IFM_SUBTYPE(ife->ifm_media) != IFM_1000_T) + break; + + PHY_WRITE(sc, CIPHY_MII_1000CTL, gig); + PHY_WRITE(sc, CIPHY_MII_BMCR, + speed|CIPHY_BMCR_AUTOEN|CIPHY_BMCR_STARTNEG); + + /* + * When setting the link manually, one side must + * be the master and the other the slave. However + * ifmedia doesn't give us a good way to specify + * this, so we fake it by using one of the LINK + * flags. If LINK0 is set, we program the PHY to + * be a master, otherwise it's a slave. + */ + if ((mii->mii_ifp->if_flags & IFF_LINK0)) { + PHY_WRITE(sc, CIPHY_MII_1000CTL, + gig|CIPHY_1000CTL_MSE|CIPHY_1000CTL_MSC); + } else { + PHY_WRITE(sc, CIPHY_MII_1000CTL, + gig|CIPHY_1000CTL_MSE); + } + break; + case IFM_NONE: + PHY_WRITE(sc, MII_BMCR, BMCR_ISO|BMCR_PDOWN); + break; + case IFM_100_T4: + default: + return (EINVAL); + } + break; + + case MII_TICK: + /* + * If we're not currently selected, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + + /* + * Is the interface even up? + */ + if ((mii->mii_ifp->if_flags & IFF_UP) == 0) + return (0); + + /* + * Only used for autonegotiation. + */ + if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) + break; + + /* + * Check to see if we have link. If we do, we don't + * need to restart the autonegotiation process. Read + * the BMSR twice in case it's latched. + */ + reg = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); + if (reg & BMSR_LINK) + break; + + /* + * Only retry autonegotiation every 5 seconds. + */ + if (++sc->mii_ticks <= 5/*10*/) + break; + + sc->mii_ticks = 0; + mii_phy_auto(sc); + return (0); + } + + /* Update the media status. */ + ciphy_status(sc); + + /* + * Callback if something changed. Note that we need to poke + * apply fixups for certain PHY revs. + */ + if (sc->mii_media_active != mii->mii_media_active || + sc->mii_media_status != mii->mii_media_status || + cmd == MII_MEDIACHG) { + ciphy_fixup(sc); + } + mii_phy_update(sc, cmd); + return (0); +} + +static void +ciphy_status(sc) + struct mii_softc *sc; +{ + struct mii_data *mii = sc->mii_pdata; + int bmsr, bmcr; + + mii->mii_media_status = IFM_AVALID; + mii->mii_media_active = IFM_ETHER; + + bmsr = PHY_READ(sc, MII_BMSR) | PHY_READ(sc, MII_BMSR); + + if (bmsr & BMSR_LINK) + mii->mii_media_status |= IFM_ACTIVE; + + bmcr = PHY_READ(sc, CIPHY_MII_BMCR); + + if (bmcr & CIPHY_BMCR_LOOP) + mii->mii_media_active |= IFM_LOOP; + + if (bmcr & CIPHY_BMCR_AUTOEN) { + if ((bmsr & CIPHY_BMSR_ACOMP) == 0) { + /* Erg, still trying, I guess... */ + mii->mii_media_active |= IFM_NONE; + return; + } + } + + bmsr = PHY_READ(sc, CIPHY_MII_AUXCSR); + switch (bmsr & CIPHY_AUXCSR_SPEED) { + case CIPHY_SPEED10: + mii->mii_media_active |= IFM_10_T; + break; + case CIPHY_SPEED100: + mii->mii_media_active |= IFM_100_TX; + break; + case CIPHY_SPEED1000: + mii->mii_media_active |= IFM_1000_T; + break; + default: + device_printf(sc->mii_dev, "unknown PHY speed %x\n", + bmsr & CIPHY_AUXCSR_SPEED); + break; + } + + if (bmsr & CIPHY_AUXCSR_FDX) + mii->mii_media_active |= IFM_FDX; + + return; +} + +static void +ciphy_reset(struct mii_softc *sc) +{ + mii_phy_reset(sc); + DELAY(1000); + + return; +} + +#define PHY_SETBIT(x, y, z) \ + PHY_WRITE(x, y, (PHY_READ(x, y) | (z))) +#define PHY_CLRBIT(x, y, z) \ + PHY_WRITE(x, y, (PHY_READ(x, y) & ~(z))) + +static void +ciphy_fixup(struct mii_softc *sc) +{ + uint16_t model; + uint16_t status, speed; + + model = MII_MODEL(PHY_READ(sc, CIPHY_MII_PHYIDR2)); + status = PHY_READ(sc, CIPHY_MII_AUXCSR); + speed = status & CIPHY_AUXCSR_SPEED; + + switch (model) { + case MII_MODEL_CICADA_CS8201: + + /* Turn off "aux mode" (whatever that means) */ + PHY_SETBIT(sc, CIPHY_MII_AUXCSR, CIPHY_AUXCSR_MDPPS); + + /* + * Work around speed polling bug in VT3119/VT3216 + * when using MII in full duplex mode. + */ + if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && + (status & CIPHY_AUXCSR_FDX)) { + PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); + } else { + PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); + } + + /* Enable link/activity LED blink. */ + PHY_SETBIT(sc, CIPHY_MII_LED, CIPHY_LED_LINKACTBLINK); + + break; + + case MII_MODEL_CICADA_CS8201A: + case MII_MODEL_CICADA_CS8201B: + + /* + * Work around speed polling bug in VT3119/VT3216 + * when using MII in full duplex mode. + */ + if ((speed == CIPHY_SPEED10 || speed == CIPHY_SPEED100) && + (status & CIPHY_AUXCSR_FDX)) { + PHY_SETBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); + } else { + PHY_CLRBIT(sc, CIPHY_MII_10BTCSR, CIPHY_10BTCSR_ECHO); + } + + break; + default: + device_printf(sc->mii_dev, "unknown CICADA PHY model %x\n", + model); + break; + } + + return; +} diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphyreg.h b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphyreg.h new file mode 100644 index 0000000000..727441ab1b --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ciphyreg.h @@ -0,0 +1,351 @@ +/*- + * Copyright (c) 2004 + * Bill Paul . 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD + * 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. + * + * $FreeBSD: src/sys/dev/mii/ciphyreg.h,v 1.2 2005/01/06 01:42:55 imp Exp $ + */ + +#ifndef _DEV_MII_CIPHYREG_H_ +#define _DEV_MII_CIPHYREG_H_ + +/* + * Register definitions for the Cicada CS8201 10/100/1000 gigE copper + * PHY, embedded within the VIA Networks VT6122 controller. + */ + +/* Command register */ +#define CIPHY_MII_BMCR 0x00 +#define CIPHY_BMCR_RESET 0x8000 +#define CIPHY_BMCR_LOOP 0x4000 +#define CIPHY_BMCR_SPD0 0x2000 /* speed select, lower bit */ +#define CIPHY_BMCR_AUTOEN 0x1000 /* Autoneg enabled */ +#define CIPHY_BMCR_PDOWN 0x0800 /* Power down */ +#define CIPHY_BMCR_STARTNEG 0x0200 /* Restart autoneg */ +#define CIPHY_BMCR_FDX 0x0100 /* Duplex mode */ +#define CIPHY_BMCR_CTEST 0x0080 /* Collision test enable */ +#define CIPHY_BMCR_SPD1 0x0040 /* Speed select, upper bit */ + +#define CIPHY_S1000 CIPHY_BMCR_SPD1 /* 1000mbps */ +#define CIPHY_S100 CIPHY_BMCR_SPD0 /* 100mpbs */ +#define CIPHY_S10 0 /* 10mbps */ + +/* Status register */ +#define CIPHY_MII_BMSR 0x01 +#define CIPHY_BMSR_100T4 0x8000 /* 100 base T4 capable */ +#define CIPHY_BMSR_100TXFDX 0x4000 /* 100 base Tx full duplex capable */ +#define CIPHY_BMSR_100TXHDX 0x2000 /* 100 base Tx half duplex capable */ +#define CIPHY_BMSR_10TFDX 0x1000 /* 10 base T full duplex capable */ +#define CIPHY_BMSR_10THDX 0x0800 /* 10 base T half duplex capable */ +#define CIPHY_BMSR_100T2FDX 0x0400 /* 100 base T2 full duplex capable */ +#define CIPHY_BMSR_100T2HDX 0x0200 /* 100 base T2 half duplex capable */ +#define CIPHY_BMSR_EXTSTS 0x0100 /* Extended status present */ +#define CIPHY_BMSR_PRESUB 0x0040 /* Preamble surpression */ +#define CIPHY_BMSR_ACOMP 0x0020 /* Autoneg complete */ +#define CIPHY_BMSR_RFAULT 0x0010 /* Remote fault condition occured */ +#define CIPHY_BMSR_ANEG 0x0008 /* Autoneg capable */ +#define CIPHY_BMSR_LINK 0x0004 /* Link status */ +#define CIPHY_BMSR_JABBER 0x0002 /* Jabber detected */ +#define CIPHY_BMSR_EXT 0x0001 /* Extended capability */ + +/* PHY ID registers */ +#define CIPHY_MII_PHYIDR1 0x02 +#define CIPHY_MII_PHYIDR2 0x03 + +/* Autoneg advertisement */ +#define CIPHY_MII_ANAR 0x04 +#define CIPHY_ANAR_NP 0x8000 /* Next page */ +#define CIPHY_ANAR_RF 0x2000 /* Remote fault */ +#define CIPHY_ANAR_ASP 0x0800 /* Asymmetric Pause */ +#define CIPHY_ANAR_PC 0x0400 /* Pause capable */ +#define CIPHY_ANAR_T4 0x0200 /* local device supports 100bT4 */ +#define CIPHY_ANAR_TX_FD 0x0100 /* local device supports 100bTx FD */ +#define CIPHY_ANAR_TX 0x0080 /* local device supports 100bTx */ +#define CIPHY_ANAR_10_FD 0x0040 /* local device supports 10bT FD */ +#define CIPHY_ANAR_10 0x0020 /* local device supports 10bT */ +#define CIPHY_ANAR_SEL 0x001F /* selector field, 00001=Ethernet */ + +/* Autoneg link partner ability */ +#define CIPHY_MII_ANLPAR 0x05 +#define CIPHY_ANLPAR_NP 0x8000 /* Next page */ +#define CIPHY_ANLPAR_ACK 0x4000 /* link partner acknowledge */ +#define CIPHY_ANLPAR_RF 0x2000 /* Remote fault */ +#define CIPHY_ANLPAR_ASP 0x0800 /* Asymmetric Pause */ +#define CIPHY_ANLPAR_PC 0x0400 /* Pause capable */ +#define CIPHY_ANLPAR_T4 0x0200 /* link partner supports 100bT4 */ +#define CIPHY_ANLPAR_TX_FD 0x0100 /* link partner supports 100bTx FD */ +#define CIPHY_ANLPAR_TX 0x0080 /* link partner supports 100bTx */ +#define CIPHY_ANLPAR_10_FD 0x0040 /* link partner supports 10bT FD */ +#define CIPHY_ANLPAR_10 0x0020 /* link partner supports 10bT */ +#define CIPHY_ANLPAR_SEL 0x001F /* selector field, 00001=Ethernet */ + +#define CIPHY_SEL_TYPE 0x0001 /* ethernet */ + +/* Antoneg expansion register */ +#define CIPHY_MII_ANER 0x06 +#define CIPHY_ANER_PDF 0x0010 /* Parallel detection fault */ +#define CIPHY_ANER_LPNP 0x0008 /* Link partner can next page */ +#define CIPHY_ANER_NP 0x0004 /* Local PHY can next page */ +#define CIPHY_ANER_RX 0x0002 /* Next page received */ +#define CIPHY_ANER_LPAN 0x0001 /* Link partner autoneg capable */ + +/* Autoneg next page transmit regisyer */ +#define CIPHY_MII_NEXTP 0x07 +#define CIPHY_NEXTP_MOREP 0x8000 /* More pages to follow */ +#define CIPHY_NEXTP_MESS 0x2000 /* 1 = message page, 0 = unformatted */ +#define CIPHY_NEXTP_ACK2 0x1000 /* MAC acknowledge */ +#define CIPHY_NEXTP_TOGGLE 0x0800 /* Toggle */ +#define CIPHY_NEXTP_CODE 0x07FF /* Code bits */ + +/* Autoneg link partner next page receive register */ +#define CIPHY_MII_NEXTP_LP 0x08 +#define CIPHY_NEXTPLP_MOREP 0x8000 /* More pages to follow */ +#define CIPHY_NEXTPLP_MESS 0x2000 /* 1 = message page, 0 = unformatted */ +#define CIPHY_NEXTPLP_ACK2 0x1000 /* MAC acknowledge */ +#define CIPHY_NEXTPLP_TOGGLE 0x0800 /* Toggle */ +#define CIPHY_NEXTPLP_CODE 0x07FF /* Code bits */ + +/* 1000BT control register */ +#define CIPHY_MII_1000CTL 0x09 +#define CIPHY_1000CTL_TST 0xE000 /* test modes */ +#define CIPHY_1000CTL_MSE 0x1000 /* Master/Slave manual enable */ +#define CIPHY_1000CTL_MSC 0x0800 /* Master/Slave select */ +#define CIPHY_1000CTL_RD 0x0400 /* Repeater/DTE */ +#define CIPHY_1000CTL_AFD 0x0200 /* Advertise full duplex */ +#define CIPHY_1000CTL_AHD 0x0100 /* Advertise half duplex */ + +#define CIPHY_TEST_TX_JITTER 0x2000 +#define CIPHY_TEST_TX_JITTER_MASTER_MODE 0x4000 +#define CIPHY_TEST_TX_JITTER_SLAVE_MODE 0x6000 +#define CIPHY_TEST_TX_DISTORTION 0x8000 + +/* 1000BT status register */ +#define CIPHY_MII_1000STS 0x0A +#define CIPHY_1000STS_MSF 0x8000 /* Master/slave fault */ +#define CIPHY_1000STS_MSR 0x4000 /* Master/slave result */ +#define CIPHY_1000STS_LRS 0x2000 /* Local receiver status */ +#define CIPHY_1000STS_RRS 0x1000 /* Remote receiver status */ +#define CIPHY_1000STS_LPFD 0x0800 /* Link partner can FD */ +#define CIPHY_1000STS_LPHD 0x0400 /* Link partner can HD */ +#define CIPHY_1000STS_IEC 0x00FF /* Idle error count */ + +#define CIPHY_MII_EXTSTS 0x0F /* Extended status */ +#define CIPHY_EXTSTS_X_FD_CAP 0x8000 /* 1000base-X FD capable */ +#define CIPHY_EXTSTS_X_HD_CAP 0x4000 /* 1000base-X HD capable */ +#define CIPHY_EXTSTS_T_FD_CAP 0x2000 /* 1000base-T FD capable */ +#define CIPHY_EXTSTS_T_HD_CAP 0x1000 /* 1000base-T HD capable */ + +/* 1000BT status extension register #1 */ +#define CIPHY_MII_1000STS1 0x0F +#define CIPHY_1000STS1_1000XFDX 0x8000 /* 1000baseX FDX capable */ +#define CIPHY_1000STS1_1000XHDX 0x4000 /* 1000baseX HDX capable */ +#define CIPHY_1000STS1_1000TFDX 0x2000 /* 1000baseT FDX capable */ +#define CIPHY_1000STS1_1000THDX 0x1000 /* 1000baseT HDX capable */ + +/* Vendor-specific PHY registers */ + +/* 100baseTX status extention register */ +#define CIPHY_MII_100STS 0x10 +#define CIPHY_100STS_DESLCK 0x8000 /* descrambler locked */ +#define CIPHY_100STS_LKCERR 0x4000 /* lock error detected/lock lost */ +#define CIPHY_100STS_DISC 0x2000 /* disconnect state */ +#define CIPHY_100STS_LINK 0x1000 /* current link state */ +#define CIPHY_100STS_RXERR 0x0800 /* receive error detected */ +#define CIPHY_100STS_TXERR 0x0400 /* transmit error detected */ +#define CIPHY_100STS_SSDERR 0x0200 /* false carrier error detected */ +#define CIPHY_100STS_ESDERR 0x0100 /* premature end of stream error */ + +/* 1000BT status extention register #2 */ +#define CIPHY_MII_1000STS2 0x11 +#define CIPHY_1000STS2_DESLCK 0x8000 /* descrambler locked */ +#define CIPHY_1000STS2_LKCERR 0x4000 /* lock error detected/lock lost */ +#define CIPHY_1000STS2_DISC 0x2000 /* disconnect state */ +#define CIPHY_1000STS2_LINK 0x1000 /* current link state */ +#define CIPHY_1000STS2_RXERR 0x0800 /* receive error detected */ +#define CIPHY_1000STS2_TXERR 0x0400 /* transmit error detected */ +#define CIPHY_1000STS2_SSDERR 0x0200 /* false carrier error detected */ +#define CIPHY_1000STS2_ESDERR 0x0100 /* premature end of stream error */ +#define CIPHY_1000STS2_CARREXT 0x0080 /* carrier extention err detected */ +#define CIPHY_1000STS2_BCM5400 0x0040 /* non-complient BCM5400 detected */ + +/* Bypass control register */ +#define CIPHY_MII_BYPASS 0x12 +#define CIPHY_BYPASS_TX 0x8000 /* transmit disable */ +#define CIPHY_BYPASS_4B5B 0x4000 /* bypass the 4B5B encoder */ +#define CIPHY_BYPASS_SCRAM 0x2000 /* bypass scrambler */ +#define CIPHY_BYPASS_DSCAM 0x1000 /* bypass descrambler */ +#define CIPHY_BYPASS_PCSRX 0x0800 /* bypass PCS receive */ +#define CIPHY_BYPASS_PCSTX 0x0400 /* bypass PCS transmit */ +#define CIPHY_BYPASS_LFI 0x0200 /* bypass LFI timer */ +#define CIPHY_BYPASS_TXCLK 0x0100 /* enable transmit clock on LED4 pin */ +#define CIPHY_BYPASS_BCM5400_F 0x0080 /* force BCM5400 detect */ +#define CIPHY_BYPASS_BCM5400 0x0040 /* bypass BCM5400 detect */ +#define CIPHY_BYPASS_PAIRSWAP 0x0020 /* disable automatic pair swap */ +#define CIPHY_BYPASS_POLARITY 0x0010 /* disable polarity correction */ +#define CIPHY_BYPASS_PARALLEL 0x0008 /* parallel detect enable */ +#define CIPHY_BYPASS_PULSE 0x0004 /* disable pulse shaping filter */ +#define CIPHY_BYPASS_1000BNP 0x0002 /* disable 1000BT next page exchange */ + +/* RX error count register */ +#define CIPHY_MII_RXERR 0x13 + +/* False carrier sense count register */ +#define CIPHY_MII_FCSERR 0x14 + +/* Ddisconnect error counter */ +#define CIPHY_MII_DISCERR 0x15 + +/* 10baseT control/status register */ +#define CIPHY_MII_10BTCSR 0x16 +#define CIPHY_10BTCSR_DLIT 0x8000 /* Disable data link integrity test */ +#define CIPHY_10BTCSR_JABBER 0x4000 /* Disable jabber detect */ +#define CIPHY_10BTCSR_ECHO 0x2000 /* Disable echo mode */ +#define CIPHY_10BTCSR_SQE 0x1000 /* Disable signal quality error */ +#define CIPHY_10BTCSR_SQUENCH 0x0C00 /* Squelch control */ +#define CIPHY_10BTCSR_EOFERR 0x0100 /* End of Frame error */ +#define CIPHY_10BTCSR_DISC 0x0080 /* Disconnect status */ +#define CIPHY_10BTCSR_LINK 0x0040 /* current link state */ +#define CIPHY_10BTCSR_ITRIM 0x0038 /* current reference trim */ +#define CIPHY_10BTCSR_CSR 0x0006 /* CSR behavior control */ + +#define CIPHY_SQUELCH_300MV 0x0000 +#define CIPHY_SQUELCH_197MV 0x0400 +#define CIPHY_SQUELCH_450MV 0x0800 +#define CIPHY_SQUELCH_RSVD 0x0C00 + +#define CIPHY_ITRIM_PLUS2 0x0000 +#define CIPHY_ITRIM_PLUS4 0x0008 +#define CIPHY_ITRIM_PLUS6 0x0010 +#define CIPHY_ITRIM_PLUS6_ 0x0018 +#define CIPHY_ITRIM_MINUS4 0x0020 +#define CIPHY_ITRIM_MINUS4_ 0x0028 +#define CIPHY_ITRIM_MINUS2 0x0030 +#define CIPHY_ITRIM_ZERO 0x0038 + +/* Extended PHY control register #1 */ +#define CIPHY_MII_ECTL1 0x17 +#define CIPHY_ECTL1_ACTIPHY 0x0020 /* Enable ActiPHY power saving */ + +/* Extended PHY control register #2 */ +#define CIPHY_MII_ECTL2 0x18 +#define CIPHY_ECTL2_ERATE 0xE000 /* 10/1000 edge rate control */ +#define CIPHY_ECTL2_VTRIM 0x1C00 /* voltage reference trim */ +#define CIPHY_ECTL2_CABLELEN 0x000E /* Cable quality/length */ +#define CIPHY_ECTL2_ANALOGLOOP 0x0001 /* 1000BT analog loopback */ + +#define CIPHY_CABLELEN_0TO10M 0x0000 +#define CIPHY_CABLELEN_10TO20M 0x0002 +#define CIPHY_CABLELEN_20TO40M 0x0004 +#define CIPHY_CABLELEN_40TO80M 0x0006 +#define CIPHY_CABLELEN_80TO100M 0x0008 +#define CIPHY_CABLELEN_100TO140M 0x000A +#define CIPHY_CABLELEN_140TO180M 0x000C +#define CIPHY_CABLELEN_OVER180M 0x000E + +/* Interrupt mask register */ +#define CIPHY_MII_IMR 0x19 +#define CIPHY_IMR_PINENABLE 0x8000 /* Interrupt pin enable */ +#define CIPHY_IMR_SPEED 0x4000 /* speed changed event */ +#define CIPHY_IMR_LINK 0x2000 /* link change/ActiPHY event */ +#define CIPHY_IMR_DPX 0x1000 /* duplex change event */ +#define CIPHY_IMR_ANEGERR 0x0800 /* autoneg error event */ +#define CIPHY_IMR_ANEGDONE 0x0400 /* autoneg done event */ +#define CIPHY_IMR_NPRX 0x0200 /* page received event */ +#define CIPHY_IMR_SYMERR 0x0100 /* symbol error event */ +#define CIPHY_IMR_LOCKERR 0x0080 /* descrambler lock lost event */ +#define CIPHY_IMR_XOVER 0x0040 /* MDI crossover change event */ +#define CIPHY_IMR_POLARITY 0x0020 /* polarity change event */ +#define CIPHY_IMR_JABBER 0x0010 /* jabber detect event */ +#define CIPHY_IMR_SSDERR 0x0008 /* false carrier detect event */ +#define CIPHY_IMR_ESDERR 0x0004 /* parallel detect error event */ +#define CIPHY_IMR_MASTERSLAVE 0x0002 /* master/slave resolve done event */ +#define CIPHY_IMR_RXERR 0x0001 /* RX error event */ + +/* Interrupt status register */ +#define CIPHY_MII_ISR 0x1A +#define CIPHY_ISR_IPENDING 0x8000 /* Interrupt is pending */ +#define CIPHY_ISR_SPEED 0x4000 /* speed changed event */ +#define CIPHY_ISR_LINK 0x2000 /* link change/ActiPHY event */ +#define CIPHY_ISR_DPX 0x1000 /* duplex change event */ +#define CIPHY_ISR_ANEGERR 0x0800 /* autoneg error event */ +#define CIPHY_ISR_ANEGDONE 0x0400 /* autoneg done event */ +#define CIPHY_ISR_NPRX 0x0200 /* page received event */ +#define CIPHY_ISR_SYMERR 0x0100 /* symbol error event */ +#define CIPHY_ISR_LOCKERR 0x0080 /* descrambler lock lost event */ +#define CIPHY_ISR_XOVER 0x0040 /* MDI crossover change event */ +#define CIPHY_ISR_POLARITY 0x0020 /* polarity change event */ +#define CIPHY_ISR_JABBER 0x0010 /* jabber detect event */ +#define CIPHY_ISR_SSDERR 0x0008 /* false carrier detect event */ +#define CIPHY_ISR_ESDERR 0x0004 /* parallel detect error event */ +#define CIPHY_ISR_MASTERSLAVE 0x0002 /* master/slave resolve done event */ +#define CIPHY_ISR_RXERR 0x0001 /* RX error event */ + +/* LED control register */ +#define CIPHY_MII_LED 0x1B +#define CIPHY_LED_LINK10FORCE 0x8000 /* Force on link10 LED */ +#define CIPHY_LED_LINK10DIS 0x4000 /* Disable link10 LED */ +#define CIPHY_LED_LINK100FORCE 0x2000 /* Force on link10 LED */ +#define CIPHY_LED_LINK100DIS 0x1000 /* Disable link100 LED */ +#define CIPHY_LED_LINK1000FORCE 0x0800 /* Force on link1000 LED */ +#define CIPHY_LED_LINK1000DIS 0x0400 /* Disable link1000 LED */ +#define CIPHY_LED_FDXFORCE 0x0200 /* Force on duplex LED */ +#define CIPHY_LED_FDXDIS 0x0100 /* Disable duplex LED */ +#define CIPHY_LED_ACTFORCE 0x0080 /* Force on activity LED */ +#define CIPHY_LED_ACTDIS 0x0040 /* Disable activity LED */ +#define CIPHY_LED_PULSE 0x0008 /* LED pulse enable */ +#define CIPHY_LED_LINKACTBLINK 0x0004 /* enable link/activity LED blink */ +#define CIPHY_LED_BLINKRATE 0x0002 /* blink rate 0=10hz, 1=5hz */ + +/* Auxilliary control and status register */ +#define CIPHY_MII_AUXCSR 0x1C +#define CIPHY_AUXCSR_ANEGDONE 0x8000 /* Autoneg complete */ +#define CIPHY_AUXCSR_ANEGOFF 0x4000 /* Autoneg disabled */ +#define CIPHY_AUXCSR_XOVER 0x2000 /* MDI/MDI-X crossover indication */ +#define CIPHY_AUXCSR_PAIRSWAP 0x1000 /* pair swap indication */ +#define CIPHY_AUXCSR_APOLARITY 0x0800 /* polarity inversion pair A */ +#define CIPHY_AUXCSR_BPOLARITY 0x0400 /* polarity inversion pair B */ +#define CIPHY_AUXCSR_CPOLARITY 0x0200 /* polarity inversion pair C */ +#define CIPHY_AUXCSR_DPOLARITY 0x0100 /* polarity inversion pair D */ +#define CIPHY_AUXCSR_FDX 0x0020 /* duplex 1=full, 0=half */ +#define CIPHY_AUXCSR_SPEED 0x0018 /* speed */ +#define CIPHY_AUXCSR_MDPPS 0x0004 /* No idea, not documented */ +#define CIPHY_AUXCSR_STICKYREST 0x0002 /* reset clears sticky bits */ + +#define CIPHY_SPEED10 0x0000 +#define CIPHY_SPEED100 0x0008 +#define CIPHY_SPEED1000 0x0010 + +/* Delay skew status register */ +#define CIPHY_MII_DSKEW 0x1D +#define CIPHY_DSKEW_PAIRA 0x7000 /* Pair A skew in symbol times */ +#define CIPHY_DSKEW_PAIRB 0x0700 /* Pair B skew in symbol times */ +#define CIPHY_DSKEW_PAIRC 0x0070 /* Pair C skew in symbol times */ +#define CIPHY_DSKEW_PAIRD 0x0007 /* Pair D skew in symbol times */ + +#endif /* _DEV_CIPHY_MIIREG_H_ */ diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c new file mode 100644 index 0000000000..10347825bf --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy.c @@ -0,0 +1,220 @@ +/* $NetBSD: ukphy.c,v 1.2 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Manuel Bouyer. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * 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: src/sys/dev/mii/ukphy.c,v 1.20 2007/01/20 00:52:29 marius Exp $"); + +/* + * driver for generic unknown PHYs + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "miibus_if.h" + +static int ukphy_probe(device_t); +static int ukphy_attach(device_t); + +static device_method_t ukphy_methods[] = { + /* device interface */ + DEVMETHOD(device_probe, ukphy_probe), + DEVMETHOD(device_attach, ukphy_attach), + DEVMETHOD(device_detach, mii_phy_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + { 0, 0 } +}; + +static devclass_t ukphy_devclass; + +static driver_t ukphy_driver = { + "ukphy", + ukphy_methods, + sizeof(struct mii_softc) +}; + +DRIVER_MODULE(ukphy, miibus, ukphy_driver, ukphy_devclass, 0, 0); + +static int ukphy_service(struct mii_softc *, struct mii_data *, int); + +static int +ukphy_probe(device_t dev) +{ + + /* + * We know something is here, so always match at a low priority. + */ + device_set_desc(dev, "Generic IEEE 802.3u media interface"); + return (BUS_PROBE_GENERIC); +} + +static int +ukphy_attach(device_t dev) +{ + struct mii_softc *sc; + struct mii_attach_args *ma; + struct mii_data *mii; + + sc = device_get_softc(dev); + ma = device_get_ivars(dev); + sc->mii_dev = device_get_parent(dev); + mii = device_get_softc(sc->mii_dev); + LIST_INSERT_HEAD(&mii->mii_phys, sc, mii_list); + + if (bootverbose) + device_printf(dev, "OUI 0x%06x, model 0x%04x, rev. %d\n", + MII_OUI(ma->mii_id1, ma->mii_id2), + MII_MODEL(ma->mii_id2), MII_REV(ma->mii_id2)); + + sc->mii_inst = mii->mii_instance; + sc->mii_phy = ma->mii_phyno; + sc->mii_service = ukphy_service; + sc->mii_pdata = mii; + + mii->mii_instance++; + + mii_phy_reset(sc); + + sc->mii_capabilities = + PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + if (sc->mii_capabilities & BMSR_EXTSTAT) + sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); + device_printf(dev, " "); + mii_phy_add_media(sc); + printf("\n"); + + MIIBUS_MEDIAINIT(sc->mii_dev); + mii_phy_setmedia(sc); + + return (0); +} + +static int +ukphy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) +{ + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int reg; + + switch (cmd) { + case MII_POLLSTAT: + /* + * If we're not polling our PHY instance, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + break; + + case MII_MEDIACHG: + /* + * If the media indicates a different PHY instance, + * isolate ourselves. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) { + reg = PHY_READ(sc, MII_BMCR); + PHY_WRITE(sc, MII_BMCR, reg | BMCR_ISO); + return (0); + } + + /* + * 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: + /* + * If we're not currently selected, just return. + */ + if (IFM_INST(ife->ifm_media) != sc->mii_inst) + return (0); + if (mii_phy_tick(sc) == EJUSTRETURN) + return (0); + break; + } + + /* Update the media status. */ + ukphy_status(sc); + + /* Callback if something changed. */ + mii_phy_update(sc, cmd); + return (0); +} diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c new file mode 100644 index 0000000000..fb40b75c1d --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/mii/ukphy_subr.c @@ -0,0 +1,129 @@ +/* $NetBSD: ukphy_subr.c,v 1.2 1998/11/05 04:08:02 thorpej Exp $ */ + +/*- + * Copyright (c) 1998 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 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. + */ + +#include +__FBSDID("$FreeBSD: src/sys/dev/mii/ukphy_subr.c,v 1.8.8.1 2006/07/19 04:40:26 yongari Exp $"); + +/* + * Subroutines shared by the ukphy driver and other PHY drivers. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "miibus_if.h" + +/* + * Media status subroutine. If a PHY driver does media detection simply + * by decoding the NWay autonegotiation, use this routine. + */ +void +ukphy_status(struct mii_softc *phy) +{ + struct mii_data *mii = phy->mii_pdata; + struct ifmedia_entry *ife = mii->mii_media.ifm_cur; + int bmsr, bmcr, anlpar, gtcr, gtsr; + + mii->mii_media_status = IFM_AVALID; + mii->mii_media_active = IFM_ETHER; + + bmsr = PHY_READ(phy, MII_BMSR) | PHY_READ(phy, MII_BMSR); + if (bmsr & BMSR_LINK) + mii->mii_media_status |= IFM_ACTIVE; + + bmcr = PHY_READ(phy, MII_BMCR); + if (bmcr & BMCR_ISO) { + mii->mii_media_active |= IFM_NONE; + mii->mii_media_status = 0; + return; + } + + if (bmcr & BMCR_LOOP) + mii->mii_media_active |= IFM_LOOP; + + if (bmcr & BMCR_AUTOEN) { + /* + * NWay autonegotiation takes the highest-order common + * bit of the ANAR and ANLPAR (i.e. best media advertised + * both by us and our link partner). + */ + if ((bmsr & BMSR_ACOMP) == 0) { + /* Erg, still trying, I guess... */ + mii->mii_media_active |= IFM_NONE; + return; + } + + anlpar = PHY_READ(phy, MII_ANAR) & PHY_READ(phy, MII_ANLPAR); + if ((phy->mii_flags & MIIF_HAVE_GTCR) != 0 && + (phy->mii_extcapabilities & + (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) { + gtcr = PHY_READ(phy, MII_100T2CR); + gtsr = PHY_READ(phy, MII_100T2SR); + } else + gtcr = gtsr = 0; + + if ((gtcr & GTCR_ADV_1000TFDX) && (gtsr & GTSR_LP_1000TFDX)) + mii->mii_media_active |= IFM_1000_T|IFM_FDX; + else if ((gtcr & GTCR_ADV_1000THDX) && + (gtsr & GTSR_LP_1000THDX)) + mii->mii_media_active |= IFM_1000_T; + else if (anlpar & ANLPAR_T4) + mii->mii_media_active |= IFM_100_T4; + else if (anlpar & ANLPAR_TX_FD) + mii->mii_media_active |= IFM_100_TX|IFM_FDX; + else if (anlpar & ANLPAR_TX) + mii->mii_media_active |= IFM_100_TX; + else if (anlpar & ANLPAR_10_FD) + mii->mii_media_active |= IFM_10_T|IFM_FDX; + else if (anlpar & ANLPAR_10) + mii->mii_media_active |= IFM_10_T; + else + mii->mii_media_active |= IFM_NONE; + } else + mii->mii_media_active = ife->ifm_media; +} diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/Jamfile b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/Jamfile new file mode 100644 index 0000000000..f8b85176da --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/Jamfile @@ -0,0 +1,18 @@ +SubDir HAIKU_TOP src add-ons kernel drivers network vt612x dev vge ; + +SubDirCcFlags -Wall ; + +UseHeaders [ FDirName $(SUBDIR) .. .. ] : true ; +UseHeaders [ FDirName $(HAIKU_TOP) src libs compat freebsd_network compat ] : true ; + +UsePrivateHeaders net system ; +UsePrivateKernelHeaders ; + +SubDirCcFlags [ FDefines _KERNEL=1 FBSD_DRIVER=1 ] ; + +KernelAddon vt612x : + if_vge.c + glue.c + : libfreebsd_network.a vt612x_mii.a + ; + diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/glue.c b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/glue.c new file mode 100644 index 0000000000..5ca0397e86 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/glue.c @@ -0,0 +1,29 @@ +/* + * Copyright 2007, Axel Dörfler, axeld@pinc-software.de. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ + + +#include + + +HAIKU_FBSD_DRIVER_GLUE(vt612x, vge, pci); +HAIKU_DRIVER_REQUIREMENTS(FBSD_TASKQUEUES | FBSD_SWI_TASKQUEUE); + + +extern driver_t *DRIVER_MODULE_NAME(ciphy, miibus); +extern driver_t *DRIVER_MODULE_NAME(ukphy, miibus); + + +driver_t * +__haiku_select_miibus_driver(device_t dev) +{ + driver_t *drivers[] = { + DRIVER_MODULE_NAME(ciphy, miibus), + DRIVER_MODULE_NAME(ukphy, miibus), + NULL + }; + + return __haiku_probe_miibus(dev, drivers); +} + diff --git a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c index f08f8a267f..686dcded97 100644 --- a/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c +++ b/src/add-ons/kernel/drivers/network/vt612x/dev/vge/if_vge.c @@ -223,6 +223,29 @@ static devclass_t vge_devclass; DRIVER_MODULE(vge, pci, vge_driver, vge_devclass, 0, 0); DRIVER_MODULE(miibus, vge, miibus_driver, miibus_devclass, 0, 0); +#ifdef __HAIKU__ +int +__haiku_disable_interrupts(device_t dev) +{ + struct vge_softc *sc = device_get_softc(dev); + + if (CSR_READ_4(sc, VGE_ISR) == 0) + return 0; + + CSR_WRITE_4(sc, VGE_IMR, 0x00000000); + return 1; +} + + +void +__haiku_reenable_interrupts(device_t dev) +{ + struct vge_softc *sc = device_get_softc(dev); + + CSR_WRITE_4(sc, VGE_IMR, VGE_INTRS); +} +#endif /* __HAIKU__ */ + #ifdef VGE_EEPROM /* * Read a word of data stored in the EEPROM at address 'addr.'