From 1fb1e4cd2460414b718d23b6f614d6b34eb63397 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 7 Nov 2003 05:57:23 +0000 Subject: [PATCH] Add 3c940 ethernet driver support ('sk' driver) for ASUS K8V (AMD64) motherboards. Attributes: This driver was ported from Nathan L. Binkert's OpenBSD driver by Jung-uk Kim to FreeBSD-4.x. Jung-uk's port is independant from Stuart Walsh's work. --- sys/dev/netif/mii_layer/e1000phy.c | 136 ++++-- sys/dev/netif/mii_layer/e1000phyreg.h | 30 +- sys/dev/netif/mii_layer/miidevs | 3 +- sys/dev/netif/mii_layer/miidevs.h | 4 +- sys/dev/netif/mii_layer/miivar.h | 17 +- sys/dev/netif/sk/if_sk.c | 679 ++++++++++++++++++++------ sys/dev/netif/sk/if_skreg.h | 284 +++++++++-- sys/dev/netif/sk/yukonreg.h | 174 +++++++ 8 files changed, 1098 insertions(+), 229 deletions(-) create mode 100644 sys/dev/netif/sk/yukonreg.h diff --git a/sys/dev/netif/mii_layer/e1000phy.c b/sys/dev/netif/mii_layer/e1000phy.c index a7ab9ab15a..588eb64b97 100644 --- a/sys/dev/netif/mii_layer/e1000phy.c +++ b/sys/dev/netif/mii_layer/e1000phy.c @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/mii/e1000phy.c,v 1.1.2.2 2002/11/08 21:53:49 semenu Exp $ */ -/* $DragonFly: src/sys/dev/netif/mii_layer/e1000phy.c,v 1.3 2003/08/07 21:17:03 dillon Exp $ */ +/* $DragonFly: src/sys/dev/netif/mii_layer/e1000phy.c,v 1.4 2003/11/07 05:57:21 dillon Exp $ */ /* * Principal Author: Parag Patel * Copyright (c) 2001 @@ -35,6 +35,13 @@ * driver for the Marvell 88E1000 series external 1000/100/10-BT PHY. */ +/* + * Support added for the Marvell 88E1011 (Alaska) 1000/100/10baseTX and + * 1000baseSX PHY. + * Nathan Binkert + * Jung-uk Kim + */ + #include #include #include @@ -78,7 +85,7 @@ void e1000phy_status(struct mii_softc *); static int e1000phy_mii_phy_auto(struct mii_softc *, int); extern void mii_phy_auto_timeout(void *); -static void e1000phy_reset(struct mii_softc *); +static void e1000phy_reset(struct mii_softc *); static int e1000phy_debug = 0; @@ -90,8 +97,9 @@ e1000phy_probe(device_t dev) ma = device_get_ivars(dev); id = ((ma->mii_id1 << 16) | ma->mii_id2) & E1000_ID_MASK; - - if (id != E1000_ID_88E1000 && id != E1000_ID_88E1000S) { + if (id != E1000_ID_88E1000 + && id != E1000_ID_88E1000S + && id != E1000_ID_88E1011) { return ENXIO; } @@ -106,6 +114,7 @@ e1000phy_attach(device_t dev) struct mii_attach_args *ma; struct mii_data *mii; const char *sep = ""; + u_int32_t id; getenv_int("e1000phy_debug", &e1000phy_debug); @@ -119,8 +128,12 @@ e1000phy_attach(device_t dev) sc->mii_phy = ma->mii_phyno; sc->mii_service = e1000phy_service; sc->mii_pdata = mii; - sc->mii_flags |= MIIF_NOISOLATE; + + id = ((ma->mii_id1 << 16) | ma->mii_id2) & E1000_ID_MASK; + if (id == E1000_ID_88E1011 + && (PHY_READ(sc, E1000_ESSR) & E1000_ESSR_FIBER_LINK)) + sc->mii_flags |= MIIF_HAVEFIBER; mii->mii_instance++; e1000phy_reset(sc); @@ -133,27 +146,33 @@ e1000phy_attach(device_t dev) #endif device_printf(dev, " "); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); - PRINT("1000baseTX-FDX"); - /* - TODO - apparently 1000BT-simplex not supported? - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, 0, sc->mii_inst), - E1000_CR_SPEED_1000); - PRINT("1000baseTX"); - */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX); - PRINT("100baseTX-FDX"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), - E1000_CR_SPEED_100); - PRINT("100baseTX"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX); - PRINT("10baseTX-FDX"); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), - E1000_CR_SPEED_10); - PRINT("10baseTX"); + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, IFM_FDX, sc->mii_inst), + E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); + PRINT("1000baseTX-FDX"); + /* + TODO - apparently 1000BT-simplex not supported? + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_TX, 0, sc->mii_inst), + E1000_CR_SPEED_1000); + PRINT("1000baseTX"); + */ + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), + E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX); + PRINT("100baseTX-FDX"); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), + E1000_CR_SPEED_100); + PRINT("100baseTX"); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), + E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX); + PRINT("10baseTX-FDX"); + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), + E1000_CR_SPEED_10); + PRINT("10baseTX"); + } else { + ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), + E1000_CR_SPEED_1000); + PRINT("1000baseSX-FDX"); + } ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); PRINT("auto"); @@ -267,6 +286,14 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) (void)e1000phy_mii_phy_auto(sc, 1); break; + case IFM_1000_SX: + e1000phy_reset(sc); + + PHY_WRITE(sc, E1000_CR, + E1000_CR_FULL_DUPLEX | E1000_CR_SPEED_1000); + PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD); + break; + case IFM_1000_TX: if (sc->mii_flags & MIIF_DOINGAUTO) return (0); @@ -402,27 +429,34 @@ e1000phy_status(struct mii_softc *sc) return; } - if (ssr & E1000_SSR_1000MBS) - mii->mii_media_active |= IFM_1000_TX; - else if (ssr & E1000_SSR_100MBS) - mii->mii_media_active |= IFM_100_TX; - else - mii->mii_media_active |= IFM_10_T; + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + if (ssr & E1000_SSR_1000MBS) + mii->mii_media_active |= IFM_1000_TX; + else if (ssr & E1000_SSR_100MBS) + mii->mii_media_active |= IFM_100_TX; + else + mii->mii_media_active |= IFM_10_T; + } else { + if (ssr & E1000_SSR_1000MBS) + mii->mii_media_active |= IFM_1000_SX; + } if (ssr & E1000_SSR_DUPLEX) mii->mii_media_active |= IFM_FDX; else mii->mii_media_active |= IFM_HDX; - /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ - if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { - mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; - } else if (!(ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && - (lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { - mii->mii_media_active |= IFM_FLAG1; - } else if ((ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && - !(lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { - mii->mii_media_active |= IFM_FLAG0; + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ + if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { + mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; + } else if (!(ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && + (lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { + mii->mii_media_active |= IFM_FLAG1; + } else if ((ar & E1000_AR_PAUSE) && (ar & E1000_AR_ASM_DIR) && + !(lpar & E1000_LPAR_PAUSE) && (lpar & E1000_LPAR_ASM_DIR)) { + mii->mii_media_active |= IFM_FLAG0; + } } } @@ -432,17 +466,19 @@ e1000phy_mii_phy_auto(struct mii_softc *mii, int waitfor) int bmsr, i; if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { - PHY_WRITE(mii, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD | - E1000_AR_100TX | E1000_AR_100TX_FD | - E1000_AR_PAUSE | E1000_AR_ASM_DIR); - PHY_WRITE(mii, E1000_1GCR, E1000_1GCR_1000T_FD); - PHY_WRITE(mii, E1000_CR, - E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG); + if ((mii->mii_flags & MIIF_HAVEFIBER) == 0) { + PHY_WRITE(mii, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD | + E1000_AR_100TX | E1000_AR_100TX_FD | + E1000_AR_PAUSE | E1000_AR_ASM_DIR); + PHY_WRITE(mii, E1000_1GCR, E1000_1GCR_1000T_FD); + PHY_WRITE(mii, E1000_CR, + E1000_CR_AUTO_NEG_ENABLE | E1000_CR_RESTART_AUTO_NEG); + } } if (waitfor) { - /* Wait 500ms for it to complete. */ - for (i = 0; i < 500; i++) { + /* Wait 5 seconds for it to complete. */ + for (i = 0; i < 5000; i++) { bmsr = PHY_READ(mii, E1000_SR) | PHY_READ(mii, E1000_SR); @@ -467,7 +503,7 @@ e1000phy_mii_phy_auto(struct mii_softc *mii, int waitfor) if ((mii->mii_flags & MIIF_DOINGAUTO) == 0) { mii->mii_flags |= MIIF_DOINGAUTO; mii->mii_ticks = 0; - mii->mii_auto_ch = timeout(mii_phy_auto_timeout, mii, hz >> 1); + mii->mii_auto_ch = timeout(mii_phy_auto_timeout, mii, 5 * hz); } return (EJUSTRETURN); } diff --git a/sys/dev/netif/mii_layer/e1000phyreg.h b/sys/dev/netif/mii_layer/e1000phyreg.h index 34059c4fea..8c5b9eea34 100644 --- a/sys/dev/netif/mii_layer/e1000phyreg.h +++ b/sys/dev/netif/mii_layer/e1000phyreg.h @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/mii/e1000phyreg.h,v 1.1.2.1 2001/04/21 16:13:09 mjacob Exp $ */ -/* $DragonFly: src/sys/dev/netif/mii_layer/e1000phyreg.h,v 1.2 2003/06/17 04:28:28 dillon Exp $ */ +/* $DragonFly: src/sys/dev/netif/mii_layer/e1000phyreg.h,v 1.3 2003/11/07 05:57:21 dillon Exp $ */ /* * Principal Author: Parag Patel * Copyright (c) 2001 @@ -74,6 +74,7 @@ #define E1000_ID2 0x03 /* ID register 2 */ #define E1000_ID_88E1000 0x01410C50 #define E1000_ID_88E1000S 0x01410C40 +#define E1000_ID_88E1011 0x01410c20 #define E1000_ID_MASK 0xFFFFFFF0 #define E1000_AR 0x04 /* autonegotiation advertise reg */ @@ -89,6 +90,15 @@ #define E1000_AR_NEXT_PAGE 0x8000 #define E1000_AR_SPEED_MASK 0x01E0 +/* Autonegotiation register bits for fiber cards (Alaska Only!) */ +#define E1000_FA_1000X_FD 0x0020 +#define E1000_FA_1000X 0x0040 +#define E1000_FA_SYM_PAUSE 0x0080 +#define E1000_FA_ASYM_PAUSE 0x0100 +#define E1000_FA_FAULT1 0x1000 +#define E1000_FA_FAULT2 0x2000 +#define E1000_FA_NEXT_PAGE 0x8000 + #define E1000_LPAR 0x05 /* autoneg link partner abilities reg */ #define E1000_LPAR_SELECTOR_FIELD 0x0001 #define E1000_LPAR_10T 0x0020 @@ -102,6 +112,16 @@ #define E1000_LPAR_ACKNOWLEDGE 0x4000 #define E1000_LPAR_NEXT_PAGE 0x8000 +/* autoneg link partner ability register bits for fiber cards (Alaska Only!) */ +#define E1000_FPAR_1000X_FD 0x0020 +#define E1000_FPAR_1000X 0x0040 +#define E1000_FPAR_SYM_PAUSE 0x0080 +#define E1000_FPAR_ASYM_PAUSE 0x0100 +#define E1000_FPAR_FAULT1 0x1000 +#define E1000_FPAR_FAULT2 0x2000 +#define E1000_FPAR_ACK 0x4000 +#define E1000_FPAR_NEXT_PAGE 0x8000 + #define E1000_ER 0x06 /* autoneg expansion reg */ #define E1000_ER_LP_NWAY 0x0001 #define E1000_ER_PAGE_RXD 0x0002 @@ -251,3 +271,11 @@ #define E1000_LCR_PULSE_340_670MS 0x5000 #define E1000_LCR_PULSE_670_13S 0x6000 #define E1000_LCR_PULSE_13_26S 0x7000 + +/* The following register is found only on the 88E1011 Alaska PHY */ +#define E1000_ESSR 0x1B /* Extended PHY specific sts */ +#define E1000_ESSR_FIBER_LINK 0x2000 +#define E1000_ESSR_GMII_COPPER 0x000f +#define E1000_ESSR_GMII_FIBER 0x0007 +#define E1000_ESSR_TBI_COPPER 0x000d +#define E1000_ESSR_TBI_FIBER 0x0005 diff --git a/sys/dev/netif/mii_layer/miidevs b/sys/dev/netif/mii_layer/miidevs index 414365a038..0ab6cc404b 100644 --- a/sys/dev/netif/mii_layer/miidevs +++ b/sys/dev/netif/mii_layer/miidevs @@ -1,5 +1,5 @@ $FreeBSD: src/sys/dev/mii/miidevs,v 1.4.2.12 2003/05/13 21:21:33 ps Exp $ -$DragonFly: src/sys/dev/netif/mii_layer/miidevs,v 1.2 2003/06/17 04:28:28 dillon Exp $ +$DragonFly: src/sys/dev/netif/mii_layer/miidevs,v 1.3 2003/11/07 05:57:21 dillon Exp $ /*$NetBSD: miidevs,v 1.6 1999/05/14 11:37:30 drochner Exp $*/ /*- @@ -163,3 +163,4 @@ model XAQTI XMACII 0x0000 XaQti Corp. XMAC II gigabit interface /* Marvell Semiconductor PHYs */ model MARVELL E1000 0x0000 Marvell Semiconductor 88E1000* gigabit PHY +model MARVELL E1011 0x0002 Marvell Semiconductor 88E1011 Gigabit PHY diff --git a/sys/dev/netif/mii_layer/miidevs.h b/sys/dev/netif/mii_layer/miidevs.h index 715189a736..cf799cb71b 100644 --- a/sys/dev/netif/mii_layer/miidevs.h +++ b/sys/dev/netif/mii_layer/miidevs.h @@ -1,5 +1,5 @@ /* $FreeBSD: src/sys/dev/mii/miidevs.h,v 1.4.2.12 2003/05/13 21:21:33 ps Exp $ */ -/* $DragonFly: src/sys/dev/netif/mii_layer/miidevs.h,v 1.2 2003/06/17 04:28:28 dillon Exp $ */ +/* $DragonFly: src/sys/dev/netif/mii_layer/miidevs.h,v 1.3 2003/11/07 05:57:21 dillon Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -204,3 +204,5 @@ /* Marvell Semiconductor PHYs */ #define MII_MODEL_MARVELL_E1000 0x0000 #define MII_STR_MARVELL_E1000 "Marvell Semiconductor 88E1000* gigabit PHY" +#define MII_MODEL_MARVELL_E1011 0x0002 +#define MII_STR_MARVELL_E1011 "Marvell Semiconductor 88E1011 Gigabit PHY" diff --git a/sys/dev/netif/mii_layer/miivar.h b/sys/dev/netif/mii_layer/miivar.h index ad455917b8..a0d5a05751 100644 --- a/sys/dev/netif/mii_layer/miivar.h +++ b/sys/dev/netif/mii_layer/miivar.h @@ -37,7 +37,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/dev/mii/miivar.h,v 1.3.2.1 2000/12/12 19:29:14 wpaul Exp $ - * $DragonFly: src/sys/dev/netif/mii_layer/miivar.h,v 1.3 2003/08/27 09:38:31 rob Exp $ + * $DragonFly: src/sys/dev/netif/mii_layer/miivar.h,v 1.4 2003/11/07 05:57:21 dillon Exp $ */ #ifndef _DEV_MII_MIIVAR_H_ @@ -131,8 +131,19 @@ struct mii_softc { typedef struct mii_softc mii_softc_t; /* mii_flags */ -#define MIIF_NOISOLATE 0x0001 /* do not isolate the PHY */ -#define MIIF_DOINGAUTO 0x0002 /* doing autonegotiation */ +#define MIIF_INITDONE 0x0001 /* has been initialized (mii_data) */ +#define MIIF_NOISOLATE 0x0002 /* do not isolate the PHY */ +#define MIIF_NOLOOP 0x0004 /* no loopback capability */ +#define MIIF_DOINGAUTO 0x0008 /* doing autonegotiation (mii_softc) */ +#define MIIF_AUTOTSLEEP 0x0010 /* use tsleep(), not callout() */ +#define MIIF_HAVEFIBER 0x0020 /* from parent: has fiber interface */ +#define MIIF_HAVE_GTCR 0x0040 /* has 100base-T2/1000base-T CR */ +#define MIIF_IS_1000X 0x0080 /* is a 1000BASE-X device */ +#define MIIF_DOPAUSE 0x0100 /* advertise PAUSE capability */ +#define MIIF_IS_HPNA 0x0200 /* is a HomePNA device */ +#define MIIF_FORCEANEG 0x0400 /* is a HomePNA device */ + +#define MIIF_INHERIT_MASK (MIIF_NOISOLATE|MIIF_NOLOOP|MIIF_AUTOTSLEEP) /* * Used to attach a PHY to a parent. diff --git a/sys/dev/netif/sk/if_sk.c b/sys/dev/netif/sk/if_sk.c index 8e106a0090..d55548f763 100644 --- a/sys/dev/netif/sk/if_sk.c +++ b/sys/dev/netif/sk/if_sk.c @@ -1,3 +1,5 @@ +/* $OpenBSD: if_sk.c,v 1.33 2003/08/12 05:23:06 nate Exp $ */ + /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. @@ -30,11 +32,27 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/if_sk.c,v 1.19.2.9 2003/03/05 18:42:34 njl Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.5 2003/08/27 09:38:32 rob Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.6 2003/11/07 05:57:23 dillon Exp $ * * $FreeBSD: src/sys/pci/if_sk.c,v 1.19.2.9 2003/03/05 18:42:34 njl Exp $ */ +/* + * Copyright (c) 2003 Nathan L. Binkert + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + /* * SysKonnect SK-NET gigabit ethernet driver for FreeBSD. Supports * the SK-984x series adapters, both single port and dual port. @@ -105,29 +123,48 @@ #include #include +#if 0 #define SK_USEIOSPACE +#endif #include "if_skreg.h" #include "xmaciireg.h" +#include "yukonreg.h" /* "controller miibus0" required. See GENERIC if you get errors here. */ #include "miibus_if.h" static struct sk_type sk_devs[] = { - { SK_VENDORID, SK_DEVICEID_GE, "SysKonnect Gigabit Ethernet" }, + { + VENDORID_SK, + DEVICEID_SK_V1, + "SysKonnect Gigabit Ethernet (V1.0)" + }, + { + VENDORID_SK, + DEVICEID_SK_V2, + "SysKonnect Gigabit Ethernet (V2.0)" + }, + { + VENDORID_3COM, + DEVICEID_3COM_3C940, + "3Com 3C940 Gigabit Ethernet" + }, { 0, 0, NULL } }; +static int skc_probe (device_t); +static int skc_attach (device_t); +static int skc_detach (device_t); +static void skc_shutdown (device_t); static int sk_probe (device_t); static int sk_attach (device_t); static int sk_detach (device_t); -static int sk_detach_xmac (device_t); -static int sk_probe_xmac (device_t); -static int sk_attach_xmac (device_t); static void sk_tick (void *); static void sk_intr (void *); -static void sk_intr_xmac (struct sk_if_softc *); static void sk_intr_bcom (struct sk_if_softc *); +static void sk_intr_xmac (struct sk_if_softc *); +static void sk_intr_yukon (struct sk_if_softc *); static void sk_rxeof (struct sk_if_softc *); static void sk_txeof (struct sk_if_softc *); static int sk_encap (struct sk_if_softc *, struct mbuf *, @@ -136,9 +173,9 @@ static void sk_start (struct ifnet *); static int sk_ioctl (struct ifnet *, u_long, caddr_t); static void sk_init (void *); static void sk_init_xmac (struct sk_if_softc *); +static void sk_init_yukon (struct sk_if_softc *); static void sk_stop (struct sk_if_softc *); static void sk_watchdog (struct ifnet *); -static void sk_shutdown (device_t); static int sk_ifmedia_upd (struct ifnet *); static void sk_ifmedia_sts (struct ifnet *, struct ifmediareq *); static void sk_reset (struct sk_softc *); @@ -165,6 +202,14 @@ static int sk_miibus_readreg (device_t, int, int); static int sk_miibus_writereg (device_t, int, int, int); static void sk_miibus_statchg (device_t); +static int sk_xmac_miibus_readreg (struct sk_if_softc *, int, int); +static int sk_xmac_miibus_writereg (struct sk_if_softc *, int, int, int); +static void sk_xmac_miibus_statchg (struct sk_if_softc *); + +static int sk_marv_miibus_readreg (struct sk_if_softc *, int, int); +static int sk_marv_miibus_writereg (struct sk_if_softc *, int, int, int); +static void sk_marv_miibus_statchg (struct sk_if_softc *); + static u_int32_t sk_calchash (caddr_t); static void sk_setfilt (struct sk_if_softc *, caddr_t, int); static void sk_setmulti (struct sk_if_softc *); @@ -187,10 +232,10 @@ static void sk_setmulti (struct sk_if_softc *); */ static device_method_t skc_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, sk_probe), - DEVMETHOD(device_attach, sk_attach), - DEVMETHOD(device_detach, sk_detach), - DEVMETHOD(device_shutdown, sk_shutdown), + DEVMETHOD(device_probe, skc_probe), + DEVMETHOD(device_attach, skc_attach), + DEVMETHOD(device_detach, skc_detach), + DEVMETHOD(device_shutdown, skc_shutdown), /* bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), @@ -209,9 +254,9 @@ static devclass_t skc_devclass; static device_method_t sk_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, sk_probe_xmac), - DEVMETHOD(device_attach, sk_attach_xmac), - DEVMETHOD(device_detach, sk_detach_xmac), + DEVMETHOD(device_probe, sk_probe), + DEVMETHOD(device_attach, sk_attach), + DEVMETHOD(device_detach, sk_detach), DEVMETHOD(device_shutdown, bus_generic_shutdown), /* bus interface */ @@ -260,24 +305,36 @@ static u_int32_t sk_win_read_4(sc, reg) struct sk_softc *sc; int reg; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_4(sc, SK_WIN_BASE + SK_REG(reg))); +#else + return(CSR_READ_4(sc, reg)); +#endif } static u_int16_t sk_win_read_2(sc, reg) struct sk_softc *sc; int reg; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_2(sc, SK_WIN_BASE + SK_REG(reg))); +#else + return(CSR_READ_2(sc, reg)); +#endif } static u_int8_t sk_win_read_1(sc, reg) struct sk_softc *sc; int reg; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); return(CSR_READ_1(sc, SK_WIN_BASE + SK_REG(reg))); +#else + return(CSR_READ_1(sc, reg)); +#endif } static void sk_win_write_4(sc, reg, val) @@ -285,8 +342,12 @@ static void sk_win_write_4(sc, reg, val) int reg; u_int32_t val; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); CSR_WRITE_4(sc, SK_WIN_BASE + SK_REG(reg), val); +#else + CSR_WRITE_4(sc, reg, val); +#endif return; } @@ -295,8 +356,12 @@ static void sk_win_write_2(sc, reg, val) int reg; u_int32_t val; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); - CSR_WRITE_2(sc, SK_WIN_BASE + SK_REG(reg), (u_int32_t)val); + CSR_WRITE_2(sc, SK_WIN_BASE + SK_REG(reg), val); +#else + CSR_WRITE_2(sc, reg, val); +#endif return; } @@ -305,8 +370,12 @@ static void sk_win_write_1(sc, reg, val) int reg; u_int32_t val; { +#ifdef SK_USEIOSPACE CSR_WRITE_4(sc, SK_RAP, SK_WIN(reg)); CSR_WRITE_1(sc, SK_WIN_BASE + SK_REG(reg), val); +#else + CSR_WRITE_1(sc, reg, val); +#endif return; } @@ -405,10 +474,62 @@ static int sk_miibus_readreg(dev, phy, reg) int phy, reg; { struct sk_if_softc *sc_if; - int i; sc_if = device_get_softc(dev); + switch(sc_if->sk_softc->sk_type) { + case SK_GENESIS: + return(sk_xmac_miibus_readreg(sc_if, phy, reg)); + case SK_YUKON: + return(sk_marv_miibus_readreg(sc_if, phy, reg)); + } + + return(0); +} + +static int sk_miibus_writereg(dev, phy, reg, val) + device_t dev; + int phy, reg, val; +{ + struct sk_if_softc *sc_if; + + sc_if = device_get_softc(dev); + + switch(sc_if->sk_softc->sk_type) { + case SK_GENESIS: + return(sk_xmac_miibus_writereg(sc_if, phy, reg, val)); + case SK_YUKON: + return(sk_marv_miibus_writereg(sc_if, phy, reg, val)); + } + + return(0); +} + +static void sk_miibus_statchg(dev) + device_t dev; +{ + struct sk_if_softc *sc_if; + + sc_if = device_get_softc(dev); + + switch(sc_if->sk_softc->sk_type) { + case SK_GENESIS: + sk_xmac_miibus_statchg(sc_if); + break; + case SK_YUKON: + sk_marv_miibus_statchg(sc_if); + break; + } + + return; +} + +static int sk_xmac_miibus_readreg(sc_if, phy, reg) + struct sk_if_softc *sc_if; + int phy, reg; +{ + int i; + if (sc_if->sk_phytype == SK_PHYTYPE_XMAC && phy != 0) return(0); @@ -432,15 +553,12 @@ static int sk_miibus_readreg(dev, phy, reg) return(SK_XM_READ_2(sc_if, XM_PHY_DATA)); } -static int sk_miibus_writereg(dev, phy, reg, val) - device_t dev; +static int sk_xmac_miibus_writereg(sc_if, phy, reg, val) + struct sk_if_softc *sc_if; int phy, reg, val; { - struct sk_if_softc *sc_if; int i; - sc_if = device_get_softc(dev); - SK_XM_WRITE_2(sc_if, XM_PHY_ADDR, reg|(phy << 8)); for (i = 0; i < SK_TIMEOUT; i++) { if (!(SK_XM_READ_2(sc_if, XM_MMUCMD) & XM_MMUCMD_PHYBUSY)) @@ -465,13 +583,11 @@ static int sk_miibus_writereg(dev, phy, reg, val) return(0); } -static void sk_miibus_statchg(dev) - device_t dev; -{ +static void sk_xmac_miibus_statchg(sc_if) struct sk_if_softc *sc_if; +{ struct mii_data *mii; - sc_if = device_get_softc(dev); mii = device_get_softc(sc_if->sk_miibus); /* @@ -489,6 +605,65 @@ static void sk_miibus_statchg(dev) return; } +static int sk_marv_miibus_readreg(sc_if, phy, reg) + struct sk_if_softc *sc_if; + int phy, reg; +{ + u_int16_t val; + int i; + + if (phy != 0 || + (sc_if->sk_phytype != SK_PHYTYPE_MARV_COPPER && + sc_if->sk_phytype != SK_PHYTYPE_MARV_FIBER)) { + return(0); + } + + SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) | + YU_SMICR_REGAD(reg) | YU_SMICR_OP_READ); + + for (i = 0; i < SK_TIMEOUT; i++) { + DELAY(1); + val = SK_YU_READ_2(sc_if, YUKON_SMICR); + if (val & YU_SMICR_READ_VALID) + break; + } + + if (i == SK_TIMEOUT) { + printf("sk%d: phy failed to come ready\n", + sc_if->sk_unit); + return(0); + } + + val = SK_YU_READ_2(sc_if, YUKON_SMIDR); + + return(val); +} + +static int sk_marv_miibus_writereg(sc_if, phy, reg, val) + struct sk_if_softc *sc_if; + int phy, reg, val; +{ + int i; + + SK_YU_WRITE_2(sc_if, YUKON_SMIDR, val); + SK_YU_WRITE_2(sc_if, YUKON_SMICR, YU_SMICR_PHYAD(phy) | + YU_SMICR_REGAD(reg) | YU_SMICR_OP_WRITE); + + for (i = 0; i < SK_TIMEOUT; i++) { + DELAY(1); + if (SK_YU_READ_2(sc_if, YUKON_SMICR) & YU_SMICR_BUSY) + break; + } + + return(0); +} + +static void sk_marv_miibus_statchg(sc_if) + struct sk_if_softc *sc_if; +{ + return; +} + #define SK_POLY 0xEDB88320 #define SK_BITS 6 @@ -527,19 +702,30 @@ static void sk_setfilt(sc_if, addr, slot) static void sk_setmulti(sc_if) struct sk_if_softc *sc_if; { - struct ifnet *ifp; + struct sk_softc *sc = sc_if->sk_softc; + struct ifnet *ifp = &sc_if->arpcom.ac_if; u_int32_t hashes[2] = { 0, 0 }; int h, i; struct ifmultiaddr *ifma; u_int8_t dummy[] = { 0, 0, 0, 0, 0 ,0 }; - ifp = &sc_if->arpcom.ac_if; /* First, zot all the existing filters. */ - for (i = 1; i < XM_RXFILT_MAX; i++) - sk_setfilt(sc_if, (caddr_t)&dummy, i); - SK_XM_WRITE_4(sc_if, XM_MAR0, 0); - SK_XM_WRITE_4(sc_if, XM_MAR2, 0); + switch(sc->sk_type) { + case SK_GENESIS: + for (i = 1; i < XM_RXFILT_MAX; i++) + sk_setfilt(sc_if, (caddr_t)&dummy, i); + + SK_XM_WRITE_4(sc_if, XM_MAR0, 0); + SK_XM_WRITE_4(sc_if, XM_MAR2, 0); + break; + case SK_YUKON: + SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0); + break; + } /* Now program new ones. */ if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { @@ -563,7 +749,7 @@ static void sk_setmulti(sc_if) * into the perfect filter. For all others, * use the hash table. */ - if (i < XM_RXFILT_MAX) { + if (sc->sk_type == SK_GENESIS && i < XM_RXFILT_MAX) { sk_setfilt(sc_if, LLADDR((struct sockaddr_dl *)ifma->ifma_addr), i); i++; @@ -579,10 +765,20 @@ static void sk_setmulti(sc_if) } } - SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH| - XM_MODE_RX_USE_PERFECT); - SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]); - SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]); + switch(sc->sk_type) { + case SK_GENESIS: + SK_XM_SETBIT_4(sc_if, XM_MODE, XM_MODE_RX_USE_HASH| + XM_MODE_RX_USE_PERFECT); + SK_XM_WRITE_4(sc_if, XM_MAR0, hashes[0]); + SK_XM_WRITE_4(sc_if, XM_MAR2, hashes[1]); + break; + case SK_YUKON: + SK_YU_WRITE_2(sc_if, YUKON_MCAH1, hashes[0] & 0xffff); + SK_YU_WRITE_2(sc_if, YUKON_MCAH2, (hashes[0] >> 16) & 0xffff); + SK_YU_WRITE_2(sc_if, YUKON_MCAH3, hashes[1] & 0xffff); + SK_YU_WRITE_2(sc_if, YUKON_MCAH4, (hashes[1] >> 16) & 0xffff); + break; + } return; } @@ -590,13 +786,10 @@ static void sk_setmulti(sc_if) static int sk_init_rx_ring(sc_if) struct sk_if_softc *sc_if; { - struct sk_chain_data *cd; - struct sk_ring_data *rd; + struct sk_chain_data *cd = &sc_if->sk_cdata; + struct sk_ring_data *rd = sc_if->sk_rdata; int i; - cd = &sc_if->sk_cdata; - rd = sc_if->sk_rdata; - bzero((char *)rd->sk_rx_ring, sizeof(struct sk_rx_desc) * SK_RX_RING_CNT); @@ -626,13 +819,10 @@ static int sk_init_rx_ring(sc_if) static void sk_init_tx_ring(sc_if) struct sk_if_softc *sc_if; { - struct sk_chain_data *cd; - struct sk_ring_data *rd; + struct sk_chain_data *cd = &sc_if->sk_cdata; + struct sk_ring_data *rd = sc_if->sk_rdata; int i; - cd = &sc_if->sk_cdata; - rd = sc_if->sk_rdata; - bzero((char *)sc_if->sk_rdata->sk_tx_ring, sizeof(struct sk_tx_desc) * SK_TX_RING_CNT); @@ -895,10 +1085,9 @@ static void sk_jfree(buf, size) static int sk_ifmedia_upd(ifp) struct ifnet *ifp; { - struct sk_if_softc *sc_if; + struct sk_if_softc *sc_if = ifp->if_softc; struct mii_data *mii; - sc_if = ifp->if_softc; mii = device_get_softc(sc_if->sk_miibus); sk_init(sc_if); mii_mediachg(mii); @@ -932,6 +1121,7 @@ static int sk_ioctl(ifp, command, data) caddr_t data; { struct sk_if_softc *sc_if = ifp->if_softc; + struct sk_softc *sc = sc_if->sk_softc; struct ifreq *ifr = (struct ifreq *) data; int s, error = 0; struct mii_data *mii; @@ -956,14 +1146,30 @@ static int sk_ioctl(ifp, command, data) if (ifp->if_flags & IFF_RUNNING && ifp->if_flags & IFF_PROMISC && !(sc_if->sk_if_flags & IFF_PROMISC)) { - SK_XM_SETBIT_4(sc_if, XM_MODE, - XM_MODE_RX_PROMISC); + switch(sc->sk_type) { + case SK_GENESIS: + SK_XM_SETBIT_4(sc_if, XM_MODE, + XM_MODE_RX_PROMISC); + break; + case SK_YUKON: + SK_YU_CLRBIT_2(sc_if, YUKON_RCR, + YU_RCR_UFLEN | YU_RCR_MUFLEN); + break; + } sk_setmulti(sc_if); } else if (ifp->if_flags & IFF_RUNNING && !(ifp->if_flags & IFF_PROMISC) && sc_if->sk_if_flags & IFF_PROMISC) { - SK_XM_CLRBIT_4(sc_if, XM_MODE, - XM_MODE_RX_PROMISC); + switch(sc->sk_type) { + case SK_GENESIS: + SK_XM_CLRBIT_4(sc_if, XM_MODE, + XM_MODE_RX_PROMISC); + break; + case SK_YUKON: + SK_YU_SETBIT_2(sc_if, YUKON_RCR, + YU_RCR_UFLEN | YU_RCR_MUFLEN); + break; + } sk_setmulti(sc_if); } else sk_init(sc_if); @@ -998,12 +1204,13 @@ static int sk_ioctl(ifp, command, data) * Probe for a SysKonnect GEnesis chip. Check the PCI vendor and device * IDs against our list and return a device name if we find a match. */ -static int sk_probe(dev) +static int skc_probe(dev) device_t dev; { - struct sk_type *t; + struct sk_softc *sc; + struct sk_type *t = sk_devs; - t = sk_devs; + sc = device_get_softc(dev); while(t->sk_name != NULL) { if ((pci_get_vendor(dev) == t->sk_vid) && @@ -1023,18 +1230,26 @@ static int sk_probe(dev) static void sk_reset(sc) struct sk_softc *sc; { - CSR_WRITE_4(sc, SK_CSR, SK_CSR_SW_RESET); - CSR_WRITE_4(sc, SK_CSR, SK_CSR_MASTER_RESET); - DELAY(1000); - CSR_WRITE_4(sc, SK_CSR, SK_CSR_SW_UNRESET); - CSR_WRITE_4(sc, SK_CSR, SK_CSR_MASTER_UNRESET); + CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET); + CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_RESET); + if (sc->sk_type == SK_YUKON) + CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_SET); - /* Configure packet arbiter */ - sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET); - sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT); - sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT); - sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT); - sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT); + DELAY(1000); + CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_UNRESET); + DELAY(2); + CSR_WRITE_2(sc, SK_CSR, SK_CSR_MASTER_UNRESET); + if (sc->sk_type == SK_YUKON) + CSR_WRITE_2(sc, SK_LINK_CTRL, SK_LINK_RESET_CLEAR); + + if (sc->sk_type == SK_GENESIS) { + /* Configure packet arbiter */ + sk_win_write_2(sc, SK_PKTARB_CTL, SK_PKTARBCTL_UNRESET); + sk_win_write_2(sc, SK_RXPA1_TINIT, SK_PKTARB_TIMEOUT); + sk_win_write_2(sc, SK_TXPA1_TINIT, SK_PKTARB_TIMEOUT); + sk_win_write_2(sc, SK_RXPA2_TINIT, SK_PKTARB_TIMEOUT); + sk_win_write_2(sc, SK_TXPA2_TINIT, SK_PKTARB_TIMEOUT); + } /* Enable RAM interface */ sk_win_write_4(sc, SK_RAMCTL, SK_RAMCTL_UNRESET); @@ -1055,16 +1270,27 @@ static void sk_reset(sc) return; } -static int sk_probe_xmac(dev) +static int sk_probe(dev) device_t dev; { + struct sk_softc *sc; + + sc = device_get_softc(device_get_parent(dev)); + /* * Not much to do here. We always know there will be * at least one XMAC present, and if there are two, - * sk_attach() will create a second device instance + * skc_attach() will create a second device instance * for us. */ - device_set_desc(dev, "XaQti Corp. XMAC II"); + switch (sc->sk_type) { + case SK_GENESIS: + device_set_desc(dev, "XaQti Corp. XMAC II"); + break; + case SK_YUKON: + device_set_desc(dev, "Marvell Semiconductor, Inc. Yukon"); + break; + } return(0); } @@ -1073,7 +1299,7 @@ static int sk_probe_xmac(dev) * Each XMAC chip is attached as a separate logical IP interface. * Single port cards will have only one logical interface of course. */ -static int sk_attach_xmac(dev) +static int sk_attach(dev) device_t dev; { struct sk_softc *sc; @@ -1102,7 +1328,7 @@ static int sk_attach_xmac(dev) sc_if->sk_tx_bmu = SK_BMU_TXS_CSR0; if (port == SK_PORT_B) sc_if->sk_tx_bmu = SK_BMU_TXS_CSR1; - + /* * Get station address for this interface. Note that * dual port cards actually come with three station @@ -1161,6 +1387,9 @@ static int sk_attach_xmac(dev) case SK_PHYTYPE_BCOM: sc_if->sk_phyaddr = SK_PHYADDR_BCOM; break; + case SK_PHYTYPE_MARV_COPPER: + sc_if->sk_phyaddr = SK_PHYADDR_MARV; + break; default: printf("skc%d: unsupported PHY type: %d\n", sc->sk_unit, sc_if->sk_phytype); @@ -1206,7 +1435,15 @@ static int sk_attach_xmac(dev) /* * Do miibus setup. */ - sk_init_xmac(sc_if); + switch (sc->sk_type) { + case SK_GENESIS: + sk_init_xmac(sc_if); + break; + case SK_YUKON: + sk_init_yukon(sc_if); + break; + } + if (mii_phy_probe(dev, &sc_if->sk_miibus, sk_ifmedia_upd, sk_ifmedia_sts)) { printf("skc%d: no PHY found!\n", sc_if->sk_unit); @@ -1230,7 +1467,7 @@ static int sk_attach_xmac(dev) * Attach the interface. Allocate softc structures, do ifmedia * setup and ethernet/BPF attach. */ -static int sk_attach(dev) +static int skc_attach(dev) device_t dev; { int s; @@ -1243,13 +1480,21 @@ static int sk_attach(dev) sc = device_get_softc(dev); unit = device_get_unit(dev); bzero(sc, sizeof(struct sk_softc)); + switch (pci_get_device(dev)) { + case DEVICEID_SK_V1: + sc->sk_type = SK_GENESIS; + break; + case DEVICEID_SK_V2: + case DEVICEID_3COM_3C940: + sc->sk_type = SK_YUKON; + break; + } /* * Handle power management nonsense. */ command = pci_read_config(dev, SK_PCI_CAPID, 4) & 0x000000FF; if (command == 0x01) { - command = pci_read_config(dev, SK_PCI_PWRMGMTCTRL, 4); if (command & SK_PSTATE_MASK) { u_int32_t iobase, membase, irq; @@ -1337,33 +1582,38 @@ static int sk_attach(dev) /* Read and save vital product data from EEPROM. */ sk_vpd_read(sc); - /* Read and save RAM size and RAMbuffer offset */ - switch(sk_win_read_1(sc, SK_EPROM0)) { - case SK_RAMSIZE_512K_64: - sc->sk_ramsize = 0x80000; - sc->sk_rboff = SK_RBOFF_0; - break; - case SK_RAMSIZE_1024K_64: - sc->sk_ramsize = 0x100000; - sc->sk_rboff = SK_RBOFF_80000; - break; - case SK_RAMSIZE_1024K_128: - sc->sk_ramsize = 0x100000; - sc->sk_rboff = SK_RBOFF_0; - break; - case SK_RAMSIZE_2048K_128: - sc->sk_ramsize = 0x200000; + if (sc->sk_type == SK_GENESIS) { + /* Read and save RAM size and RAMbuffer offset */ + switch(sk_win_read_1(sc, SK_EPROM0)) { + case SK_RAMSIZE_512K_64: + sc->sk_ramsize = 0x80000; + sc->sk_rboff = SK_RBOFF_0; + break; + case SK_RAMSIZE_1024K_64: + sc->sk_ramsize = 0x100000; + sc->sk_rboff = SK_RBOFF_80000; + break; + case SK_RAMSIZE_1024K_128: + sc->sk_ramsize = 0x100000; + sc->sk_rboff = SK_RBOFF_0; + break; + case SK_RAMSIZE_2048K_128: + sc->sk_ramsize = 0x200000; + sc->sk_rboff = SK_RBOFF_0; + break; + default: + printf("skc%d: unknown ram size: %d\n", + sc->sk_unit, sk_win_read_1(sc, SK_EPROM0)); + bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); + bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); + error = ENXIO; + goto fail; + break; + } + } else { + sc->sk_ramsize = 0x20000; sc->sk_rboff = SK_RBOFF_0; - break; - default: - printf("skc%d: unknown ram size: %d\n", - sc->sk_unit, sk_win_read_1(sc, SK_EPROM0)); - bus_teardown_intr(dev, sc->sk_irq, sc->sk_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sk_irq); - bus_release_resource(dev, SK_RES, SK_RID, sc->sk_res); - error = ENXIO; - goto fail; - break; } /* Read and save physical media type */ @@ -1414,7 +1664,7 @@ fail: return(error); } -static int sk_detach_xmac(dev) +static int sk_detach(dev) device_t dev; { struct sk_softc *sc; @@ -1438,7 +1688,7 @@ static int sk_detach_xmac(dev) return(0); } -static int sk_detach(dev) +static int skc_detach(dev) device_t dev; { struct sk_softc *sc; @@ -1573,7 +1823,7 @@ static void sk_watchdog(ifp) return; } -static void sk_shutdown(dev) +static void skc_shutdown(dev) device_t dev; { struct sk_softc *sc; @@ -1763,8 +2013,7 @@ static void sk_intr_bcom(sc_if) * Read the PHY interrupt register to make sure * we clear any pending interrupts. */ - status = sk_miibus_readreg(sc_if->sk_dev, - SK_PHYADDR_BCOM, BRGPHY_MII_ISR); + status = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_ISR); if (!(ifp->if_flags & IFF_RUNNING)) { sk_init_xmac(sc_if); @@ -1773,8 +2022,8 @@ static void sk_intr_bcom(sc_if) if (status & (BRGPHY_ISR_LNK_CHG|BRGPHY_ISR_AN_PR)) { int lstat; - lstat = sk_miibus_readreg(sc_if->sk_dev, - SK_PHYADDR_BCOM, BRGPHY_MII_AUXSTS); + lstat = sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, + BRGPHY_MII_AUXSTS); if (!(lstat & BRGPHY_AUXSTS_LINK) && sc_if->sk_link) { mii_mediachg(mii); @@ -1783,7 +2032,7 @@ static void sk_intr_bcom(sc_if) SK_LINKLED1_CTL, SK_LINKLED_OFF); sc_if->sk_link = 0; } else if (status & BRGPHY_ISR_LNK_CHG) { - sk_miibus_writereg(sc_if->sk_dev, SK_PHYADDR_BCOM, + sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFF00); mii_tick(mii); sc_if->sk_link = 1; @@ -1840,6 +2089,16 @@ static void sk_intr_xmac(sc_if) return; } +static void sk_intr_yukon(sc_if) + struct sk_if_softc *sc_if; +{ + int status; + + status = SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR); + + return; +} + static void sk_intr(xsc) void *xsc; { @@ -1886,18 +2145,26 @@ static void sk_intr(xsc) } /* Then MAC interrupts. */ - if (status & SK_ISR_MAC1 && - ifp0->if_flags & IFF_RUNNING) - sk_intr_xmac(sc_if0); + if (status & SK_ISR_MAC1 && ifp0->if_flags & IFF_RUNNING) { + if (sc->sk_type == SK_GENESIS) + sk_intr_xmac(sc_if0); + else + sk_intr_yukon(sc_if0); + } - if (status & SK_ISR_MAC2 && - ifp1->if_flags & IFF_RUNNING) - sk_intr_xmac(sc_if1); + if (status & SK_ISR_MAC2 && ifp1->if_flags & IFF_RUNNING) { + if (sc->sk_type == SK_GENESIS) + sk_intr_xmac(sc_if1); + else + sk_intr_yukon(sc_if0); + } if (status & SK_ISR_EXTERNAL_REG) { - if (ifp0 != NULL) + if (ifp0 != NULL && + sc_if0->sk_phytype == SK_PHYTYPE_BCOM) sk_intr_bcom(sc_if0); - if (ifp1 != NULL) + if (ifp1 != NULL && + sc_if1->sk_phytype == SK_PHYTYPE_BCOM) sk_intr_bcom(sc_if1); } } @@ -1956,10 +2223,10 @@ static void sk_init_xmac(sc_if) /* Enable GMII mode on the XMAC. */ SK_XM_SETBIT_2(sc_if, XM_HWCFG, XM_HWCFG_GMIIMODE); - sk_miibus_writereg(sc_if->sk_dev, SK_PHYADDR_BCOM, + sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_BMCR, BRGPHY_BMCR_RESET); DELAY(10000); - sk_miibus_writereg(sc_if->sk_dev, SK_PHYADDR_BCOM, + sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, BRGPHY_MII_IMR, 0xFFF0); /* @@ -1968,12 +2235,11 @@ static void sk_init_xmac(sc_if) * registers initialized to some magic values. I don't * know what the numbers do, I'm just the messenger. */ - if (sk_miibus_readreg(sc_if->sk_dev, - SK_PHYADDR_BCOM, 0x03) == 0x6041) { + if (sk_xmac_miibus_readreg(sc_if, SK_PHYADDR_BCOM, 0x03) + == 0x6041) { while(bhack[i].reg) { - sk_miibus_writereg(sc_if->sk_dev, - SK_PHYADDR_BCOM, bhack[i].reg, - bhack[i].val); + sk_xmac_miibus_writereg(sc_if, SK_PHYADDR_BCOM, + bhack[i].reg, bhack[i].val); i++; } } @@ -2080,6 +2346,101 @@ static void sk_init_xmac(sc_if) return; } +static void sk_init_yukon(sc_if) + struct sk_if_softc *sc_if; +{ + u_int32_t phy; + u_int16_t reg; + int i; + + /* GMAC and GPHY Reset */ + SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, SK_GPHY_RESET_SET); + SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET); + DELAY(1000); + SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_CLEAR); + SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_RESET_SET); + DELAY(1000); + + phy = SK_GPHY_INT_POL_HI | SK_GPHY_DIS_FC | SK_GPHY_DIS_SLEEP | + SK_GPHY_ENA_XC | SK_GPHY_ANEG_ALL | SK_GPHY_ENA_PAUSE; + + switch(sc_if->sk_softc->sk_pmd) { + case IFM_1000_SX: + case IFM_1000_LX: + phy |= SK_GPHY_FIBER; + break; + + case IFM_1000_CX: + case IFM_1000_TX: + phy |= SK_GPHY_COPPER; + break; + } + + SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_SET); + DELAY(1000); + SK_IF_WRITE_4(sc_if, 0, SK_GPHY_CTRL, phy | SK_GPHY_RESET_CLEAR); + SK_IF_WRITE_4(sc_if, 0, SK_GMAC_CTRL, SK_GMAC_LOOP_OFF | + SK_GMAC_PAUSE_ON | SK_GMAC_RESET_CLEAR); + + /* unused read of the interrupt source register */ + SK_IF_READ_2(sc_if, 0, SK_GMAC_ISR); + + reg = SK_YU_READ_2(sc_if, YUKON_PAR); + + /* MIB Counter Clear Mode set */ + reg |= YU_PAR_MIB_CLR; + SK_YU_WRITE_2(sc_if, YUKON_PAR, reg); + + /* MIB Counter Clear Mode clear */ + reg &= ~YU_PAR_MIB_CLR; + SK_YU_WRITE_2(sc_if, YUKON_PAR, reg); + + /* receive control reg */ + SK_YU_WRITE_2(sc_if, YUKON_RCR, YU_RCR_UFLEN | YU_RCR_MUFLEN | + YU_RCR_CRCR); + + /* transmit parameter register */ + SK_YU_WRITE_2(sc_if, YUKON_TPR, YU_TPR_JAM_LEN(0x3) | + YU_TPR_JAM_IPG(0xb) | YU_TPR_JAM2DATA_IPG(0x1a) ); + + /* serial mode register */ + SK_YU_WRITE_2(sc_if, YUKON_SMR, YU_SMR_DATA_BLIND(0x1c) | + YU_SMR_MFL_VLAN | YU_SMR_IPG_DATA(0x1e)); + + /* Setup Yukon's address */ + for (i = 0; i < 3; i++) { + /* Write Source Address 1 (unicast filter) */ + SK_YU_WRITE_2(sc_if, YUKON_SAL1 + i * 4, + sc_if->arpcom.ac_enaddr[i * 2] | + sc_if->arpcom.ac_enaddr[i * 2 + 1] << 8); + } + + for (i = 0; i < 3; i++) { + reg = sk_win_read_2(sc_if->sk_softc, + SK_MAC1_0 + i * 2 + sc_if->sk_port * 8); + SK_YU_WRITE_2(sc_if, YUKON_SAL2 + i * 4, reg); + } + + /* clear all Multicast filter hash registers */ + SK_YU_WRITE_2(sc_if, YUKON_MCAH1, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH2, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH3, 0); + SK_YU_WRITE_2(sc_if, YUKON_MCAH4, 0); + + /* enable interrupt mask for counter overflows */ + SK_YU_WRITE_2(sc_if, YUKON_TIMR, 0); + SK_YU_WRITE_2(sc_if, YUKON_RIMR, 0); + SK_YU_WRITE_2(sc_if, YUKON_TRIMR, 0); + + /* Configure RX MAC FIFO */ + SK_IF_WRITE_1(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_CLEAR); + SK_IF_WRITE_4(sc_if, 0, SK_RXMF1_CTRL_TEST, SK_RFCTL_OPERATION_ON); + + /* Configure TX MAC FIFO */ + SK_IF_WRITE_1(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_CLEAR); + SK_IF_WRITE_4(sc_if, 0, SK_TXMF1_CTRL_TEST, SK_TFCTL_OPERATION_ON); +} + /* * Note that to properly initialize any part of the GEnesis chip, * you first have to take it out of reset mode. @@ -2092,6 +2453,7 @@ static void sk_init(xsc) struct ifnet *ifp; struct mii_data *mii; int s; + u_int16_t reg; s = splimp(); @@ -2102,30 +2464,44 @@ static void sk_init(xsc) /* Cancel pending I/O and free all RX/TX buffers. */ sk_stop(sc_if); - /* Configure LINK_SYNC LED */ - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON); - SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_LINKSYNC_ON); + if (sc->sk_type == SK_GENESIS) { + /* Configure LINK_SYNC LED */ + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, SK_LINKLED_ON); + SK_IF_WRITE_1(sc_if, 0, SK_LINKLED1_CTL, + SK_LINKLED_LINKSYNC_ON); - /* Configure RX LED */ - SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, SK_RXLEDCTL_COUNTER_START); + /* Configure RX LED */ + SK_IF_WRITE_1(sc_if, 0, SK_RXLED1_CTL, + SK_RXLEDCTL_COUNTER_START); - /* Configure TX LED */ - SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, SK_TXLEDCTL_COUNTER_START); + /* Configure TX LED */ + SK_IF_WRITE_1(sc_if, 0, SK_TXLED1_CTL, + SK_TXLEDCTL_COUNTER_START); + } /* Configure I2C registers */ /* Configure XMAC(s) */ - sk_init_xmac(sc_if); + switch (sc->sk_type) { + case SK_GENESIS: + sk_init_xmac(sc_if); + break; + case SK_YUKON: + sk_init_yukon(sc_if); + break; + } mii_mediachg(mii); - /* Configure MAC FIFOs */ - SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET); - SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END); - SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON); + if (sc->sk_type == SK_GENESIS) { + /* Configure MAC FIFOs */ + SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_UNRESET); + SK_IF_WRITE_4(sc_if, 0, SK_RXF1_END, SK_FIFO_END); + SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_ON); - SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET); - SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END); - SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON); + SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_UNRESET); + SK_IF_WRITE_4(sc_if, 0, SK_TXF1_END, SK_FIFO_END); + SK_IF_WRITE_4(sc_if, 0, SK_TXF1_CTL, SK_FIFO_ON); + } /* Configure transmit arbiter(s) */ SK_IF_WRITE_1(sc_if, 0, SK_TXAR1_COUNTERCTL, @@ -2182,9 +2558,18 @@ static void sk_init(xsc) /* Start BMUs. */ SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_RX_START); - /* Enable XMACs TX and RX state machines */ - SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE); - SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); + switch(sc->sk_type) { + case SK_GENESIS: + /* Enable XMACs TX and RX state machines */ + SK_XM_CLRBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_IGNPAUSE); + SK_XM_SETBIT_2(sc_if, XM_MMUCMD, XM_MMUCMD_TX_ENB|XM_MMUCMD_RX_ENB); + break; + case SK_YUKON: + reg = SK_YU_READ_2(sc_if, YUKON_GPCR); + reg |= YU_GPCR_TXEN | YU_GPCR_RXEN; + reg &= ~(YU_GPCR_SPEED_EN | YU_GPCR_DPLX_EN); + SK_YU_WRITE_2(sc_if, YUKON_GPCR, reg); + } ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -2223,8 +2608,16 @@ static void sk_stop(sc_if) /* Turn off various components of this interface. */ SK_XM_SETBIT_2(sc_if, XM_GPIO, XM_GPIO_RESETMAC); - SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_RESET); - SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); + switch (sc->sk_type) { + case SK_GENESIS: + SK_IF_WRITE_2(sc_if, 0, SK_TXF1_MACCTL, SK_TXMACCTL_XMAC_RESET); + SK_IF_WRITE_4(sc_if, 0, SK_RXF1_CTL, SK_FIFO_RESET); + break; + case SK_YUKON: + SK_IF_WRITE_1(sc_if,0, SK_RXMF1_CTRL_TEST, SK_RFCTL_RESET_SET); + SK_IF_WRITE_1(sc_if,0, SK_TXMF1_CTRL_TEST, SK_TFCTL_RESET_SET); + break; + } SK_IF_WRITE_4(sc_if, 0, SK_RXQ1_BMU_CSR, SK_RXBMU_OFFLINE); SK_IF_WRITE_4(sc_if, 0, SK_RXRB1_CTLTST, SK_RBCTL_RESET|SK_RBCTL_OFF); SK_IF_WRITE_4(sc_if, 1, SK_TXQS1_BMU_CSR, SK_TXBMU_OFFLINE); diff --git a/sys/dev/netif/sk/if_skreg.h b/sys/dev/netif/sk/if_skreg.h index e2bc57ef9b..1235e531d4 100644 --- a/sys/dev/netif/sk/if_skreg.h +++ b/sys/dev/netif/sk/if_skreg.h @@ -1,3 +1,5 @@ +/* $OpenBSD: if_skreg.h,v 1.10 2003/08/12 05:23:06 nate Exp $ */ + /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul . All rights reserved. @@ -30,18 +32,49 @@ * THE POSSIBILITY OF SUCH DAMAGE. * * $FreeBSD: src/sys/pci/if_skreg.h,v 1.8.2.1 2000/04/27 14:48:07 wpaul Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_skreg.h,v 1.2 2003/06/17 04:28:57 dillon Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_skreg.h,v 1.3 2003/11/07 05:57:23 dillon Exp $ + */ + +/* + * Copyright (c) 2003 Nathan L. Binkert + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +/* Values to keep the different chip revisions apart */ +#define SK_GENESIS 0 +#define SK_YUKON 1 + /* * SysKonnect PCI vendor ID */ -#define SK_VENDORID 0x1148 +#define VENDORID_SK 0x1148 /* - * SK-NET gigabit ethernet device ID + * SK-NET gigabit ethernet device IDs */ -#define SK_DEVICEID_GE 0x4300 +#define DEVICEID_SK_V1 0x4300 +#define DEVICEID_SK_V2 0x4320 + +/* + * 3Com PCI vendor ID + */ +#define VENDORID_3COM 0x10b7 + +/* + * 3Com gigabit ethernet device ID + */ +#define DEVICEID_3COM_3C940 0x1700 /* * GEnesis registers. The GEnesis chip has a 256-byte I/O window @@ -329,6 +362,8 @@ #define SK_PHYTYPE_BCOM 1 /* Broadcom BCM5400 */ #define SK_PHYTYPE_LONE 2 /* Level One LXT1000 */ #define SK_PHYTYPE_NAT 3 /* National DP83891 */ +#define SK_PHYTYPE_MARV_COPPER 4 /* Marvell 88E1011S */ +#define SK_PHYTYPE_MARV_FIBER 5 /* Marvell 88E1011S (fiber) */ /* * PHY addresses. @@ -337,6 +372,7 @@ #define SK_PHYADDR_BCOM 0x1 #define SK_PHYADDR_LONE 0x3 #define SK_PHYADDR_NAT 0x0 +#define SK_PHYADDR_MARV 0x0 #define SK_CONFIG_SINGLEMAC 0x01 #define SK_CONFIG_DIS_DSL_CLK 0x02 @@ -806,6 +842,28 @@ #define SK_FIFO_END 0x3F +/* Receive MAC FIFO 1 (Yukon Only) */ +#define SK_RXMF1_END 0x0C40 +#define SK_RXMF1_THRESHOLD 0x0C44 +#define SK_RXMF1_CTRL_TEST 0x0C48 +#define SK_RXMF1_WRITE_PTR 0x0C60 +#define SK_RXMF1_WRITE_LEVEL 0x0C68 +#define SK_RXMF1_READ_PTR 0x0C70 +#define SK_RXMF1_READ_LEVEL 0x0C78 + +#define SK_RFCTL_WR_PTR_TST_ON 0x00004000 /* Write pointer test on*/ +#define SK_RFCTL_WR_PTR_TST_OFF 0x00002000 /* Write pointer test off */ +#define SK_RFCTL_WR_PTR_STEP 0x00001000 /* Write pointer increment */ +#define SK_RFCTL_RD_PTR_TST_ON 0x00000400 /* Read pointer test on */ +#define SK_RFCTL_RD_PTR_TST_OFF 0x00000200 /* Read pointer test off */ +#define SK_RFCTL_RD_PTR_STEP 0x00000100 /* Read pointer increment */ +#define SK_RFCTL_RX_FIFO_OVER 0x00000040 /* Clear IRQ RX FIFO Overrun */ +#define SK_RFCTL_FRAME_RX_DONE 0x00000010 /* Clear IRQ Frame RX Done */ +#define SK_RFCTL_OPERATION_ON 0x00000008 /* Operational mode on */ +#define SK_RFCTL_OPERATION_OFF 0x00000004 /* Operational mode off */ +#define SK_RFCTL_RESET_CLEAR 0x00000002 /* MAC FIFO Reset Clear */ +#define SK_RFCTL_RESET_SET 0x00000001 /* MAC FIFO Reset Set */ + /* Block 25 -- RX MAC FIFO 2 regisrers and LINK_SYNC counter */ #define SK_RXF2_END 0x0C80 #define SK_RXF2_WPTR 0x0C84 @@ -865,6 +923,31 @@ #define SK_TXLED1_CTL 0x0D28 #define SK_TXLED1_TST 0x0D29 +/* Receive MAC FIFO 1 (Yukon Only) */ +#define SK_TXMF1_END 0x0D40 +#define SK_TXMF1_THRESHOLD 0x0D44 +#define SK_TXMF1_CTRL_TEST 0x0D48 +#define SK_TXMF1_WRITE_PTR 0x0D60 +#define SK_TXMF1_WRITE_SHADOW 0x0D64 +#define SK_TXMF1_WRITE_LEVEL 0x0D68 +#define SK_TXMF1_READ_PTR 0x0D70 +#define SK_TXMF1_RESTART_PTR 0x0D74 +#define SK_TXMF1_READ_LEVEL 0x0D78 + +#define SK_TFCTL_WR_PTR_TST_ON 0x00004000 /* Write pointer test on*/ +#define SK_TFCTL_WR_PTR_TST_OFF 0x00002000 /* Write pointer test off */ +#define SK_TFCTL_WR_PTR_STEP 0x00001000 /* Write pointer increment */ +#define SK_TFCTL_RD_PTR_TST_ON 0x00000400 /* Read pointer test on */ +#define SK_TFCTL_RD_PTR_TST_OFF 0x00000200 /* Read pointer test off */ +#define SK_TFCTL_RD_PTR_STEP 0x00000100 /* Read pointer increment */ +#define SK_TFCTL_TX_FIFO_UNDER 0x00000040 /* Clear IRQ TX FIFO Under */ +#define SK_TFCTL_FRAME_TX_DONE 0x00000020 /* Clear IRQ Frame TX Done */ +#define SK_TFCTL_IRQ_PARITY_ER 0x00000010 /* Clear IRQ Parity Error */ +#define SK_TFCTL_OPERATION_ON 0x00000008 /* Operational mode on */ +#define SK_TFCTL_OPERATION_OFF 0x00000004 /* Operational mode off */ +#define SK_TFCTL_RESET_CLEAR 0x00000002 /* MAC FIFO Reset Clear */ +#define SK_TFCTL_RESET_SET 0x00000001 /* MAC FIFO Reset Set */ + /* Block 27 -- TX MAC FIFO 2 regisrers */ #define SK_TXF2_END 0x0D80 #define SK_TXF2_WPTR 0x0D84 @@ -904,35 +987,148 @@ #define SK_FIFO_OFF 0x00000004 #define SK_FIFO_ON 0x00000008 +/* Block 28 -- Descriptor Poll Timer */ +#define SK_DPT_INIT 0x0e00 /* Initial value 24 bits */ +#define SK_DPT_TIMER 0x0e04 /* Mul of 78.12MHz clk (24b) */ + +#define SK_DPT_TIMER_CTRL 0x0e08 /* Timer Control 16 bits */ +#define SK_DPT_TCTL_STOP 0x0001 /* Stop Timer */ +#define SK_DPT_TCTL_START 0x0002 /* Start Timer */ + +#define SK_DPT_TIMER_TEST 0x0e0a /* Timer Test 16 bits */ +#define SK_DPT_TTEST_STEP 0x0001 /* Timer Decrement */ +#define SK_DPT_TTEST_OFF 0x0002 /* Test Mode Off */ +#define SK_DPT_TTEST_ON 0x0004 /* Test Mode On */ + +/* Block 29 -- reserved */ + +/* Block 30 -- GMAC/GPHY Control Registers (Yukon Only)*/ +#define SK_GMAC_CTRL 0x0f00 /* GMAC Control Register */ +#define SK_GPHY_CTRL 0x0f04 /* GPHY Control Register */ +#define SK_GMAC_ISR 0x0f08 /* GMAC Interrupt Source Register */ +#define SK_GMAC_IMR 0x0f08 /* GMAC Interrupt Mask Register */ +#define SK_LINK_CTRL 0x0f10 /* Link Control Register (LCR) */ +#define SK_WOL_CTRL 0x0f20 /* Wake on LAN Control Register */ +#define SK_MAC_ADDR_LOW 0x0f24 /* Mack Address Registers LOW */ +#define SK_MAC_ADDR_HIGH 0x0f28 /* Mack Address Registers HIGH */ +#define SK_PAT_READ_PTR 0x0f2c /* Pattern Read Pointer Register */ +#define SK_PAT_LEN_REG0 0x0f30 /* Pattern Length Register 0 */ +#define SK_PAT_LEN0 0x0f30 /* Pattern Length 0 */ +#define SK_PAT_LEN1 0x0f31 /* Pattern Length 1 */ +#define SK_PAT_LEN2 0x0f32 /* Pattern Length 2 */ +#define SK_PAT_LEN3 0x0f33 /* Pattern Length 3 */ +#define SK_PAT_LEN_REG1 0x0f34 /* Pattern Length Register 1 */ +#define SK_PAT_LEN4 0x0f34 /* Pattern Length 4 */ +#define SK_PAT_LEN5 0x0f35 /* Pattern Length 5 */ +#define SK_PAT_LEN6 0x0f36 /* Pattern Length 6 */ +#define SK_PAT_LEN7 0x0f37 /* Pattern Length 7 */ +#define SK_PAT_CTR_REG0 0x0f38 /* Pattern Counter Register 0 */ +#define SK_PAT_CTR0 0x0f38 /* Pattern Counter 0 */ +#define SK_PAT_CTR1 0x0f39 /* Pattern Counter 1 */ +#define SK_PAT_CTR2 0x0f3a /* Pattern Counter 2 */ +#define SK_PAT_CTR3 0x0f3b /* Pattern Counter 3 */ +#define SK_PAT_CTR_REG1 0x0f3c /* Pattern Counter Register 1 */ +#define SK_PAT_CTR4 0x0f3c /* Pattern Counter 4 */ +#define SK_PAT_CTR5 0x0f3d /* Pattern Counter 5 */ +#define SK_PAT_CTR6 0x0f3e /* Pattern Counter 6 */ +#define SK_PAT_CTR7 0x0f3f /* Pattern Counter 7 */ + +#define SK_GMAC_LOOP_ON 0x00000020 /* Loopback mode for testing */ +#define SK_GMAC_LOOP_OFF 0x00000010 /* purposes */ +#define SK_GMAC_PAUSE_ON 0x00000008 /* enable forward of pause */ +#define SK_GMAC_PAUSE_OFF 0x00000004 /* signal to GMAC */ +#define SK_GMAC_RESET_CLEAR 0x00000002 /* Clear GMAC Reset */ +#define SK_GMAC_RESET_SET 0x00000001 /* Set GMAC Reset */ + +#define SK_GPHY_SEL_BDT 0x10000000 /* Select Bidirectional xfer */ +#define SK_GPHY_INT_POL_HI 0x08000000 /* IRQ Polarity Active */ +#define SK_GPHY_75_OHM 0x04000000 /* Use 75 Ohm Termination */ +#define SK_GPHY_DIS_FC 0x02000000 /* Disable Auto Fiber/Copper */ +#define SK_GPHY_DIS_SLEEP 0x01000000 /* Disable Energy Detect */ +#define SK_GPHY_HWCFG_M_3 0x00800000 /* HWCFG_MODE[3] */ +#define SK_GPHY_HWCFG_M_2 0x00400000 /* HWCFG_MODE[2] */ +#define SK_GPHY_HWCFG_M_1 0x00200000 /* HWCFG_MODE[1] */ +#define SK_GPHY_HWCFG_M_0 0x00100000 /* HWCFG_MODE[0] */ +#define SK_GPHY_ANEG_0 0x00080000 /* ANEG[0] */ +#define SK_GPHY_ENA_XC 0x00040000 /* Enable MDI Crossover */ +#define SK_GPHY_DIS_125 0x00020000 /* Disable 125MHz Clock */ +#define SK_GPHY_ANEG_3 0x00010000 /* ANEG[3] */ +#define SK_GPHY_ANEG_2 0x00008000 /* ANEG[2] */ +#define SK_GPHY_ANEG_1 0x00004000 /* ANEG[1] */ +#define SK_GPHY_ENA_PAUSE 0x00002000 /* Enable Pause */ +#define SK_GPHY_PHYADDR_4 0x00001000 /* Bit 4 of Phy Addr */ +#define SK_GPHY_PHYADDR_3 0x00000800 /* Bit 3 of Phy Addr */ +#define SK_GPHY_PHYADDR_2 0x00000400 /* Bit 2 of Phy Addr */ +#define SK_GPHY_PHYADDR_1 0x00000200 /* Bit 1 of Phy Addr */ +#define SK_GPHY_PHYADDR_0 0x00000100 /* Bit 0 of Phy Addr */ +#define SK_GPHY_RESET_CLEAR 0x00000002 /* Clear GPHY Reset */ +#define SK_GPHY_RESET_SET 0x00000001 /* Set GPHY Reset */ + +#define SK_GPHY_COPPER (SK_GPHY_HWCFG_M_0 | SK_GPHY_HWCFG_M_1 | \ + SK_GPHY_HWCFG_M_2 | SK_GPHY_HWCFG_M_3 ) +#define SK_GPHY_FIBER (SK_GPHY_HWCFG_M_0 | SK_GPHY_HWCFG_M_1 | \ + SK_GPHY_HWCFG_M_2 ) +#define SK_GPHY_ANEG_ALL (SK_GPHY_ANEG_0 | SK_GPHY_ANEG_1 | \ + SK_GPHY_ANEG_2 | SK_GPHY_ANEG_3 ) + +#define SK_GMAC_INT_TX_OFLOW 0x20 /* Transmit Counter Overflow */ +#define SK_GMAC_INT_RX_OFLOW 0x10 /* Receiver Overflow */ +#define SK_GMAC_INT_TX_UNDER 0x08 /* Transmit FIFO Underrun */ +#define SK_GMAC_INT_TX_DONE 0x04 /* Transmit Complete */ +#define SK_GMAC_INT_RX_OVER 0x02 /* Receive FIFO Overrun */ +#define SK_GMAC_INT_RX_DONE 0x01 /* Receive Complete */ + +#define SK_LINK_RESET_CLEAR 0x0002 /* Link Reset Clear */ +#define SK_LINK_RESET_SET 0x0001 /* Link Reset Set */ + +/* Block 31 -- reserved */ + +/* Block 32-33 -- Pattern Ram */ +#define SK_WOL_PRAM 0x1000 + +/* Block 0x22 - 0x3f -- reserved */ + /* Block 0x40 to 0x4F -- XMAC 1 registers */ #define SK_XMAC1_BASE 0x2000 -#define SK_XMAC1_END 0x23FF + +/* Block 0x50 to 0x5F -- MARV 1 registers */ +#define SK_MARV1_BASE 0x2800 /* Block 0x60 to 0x6F -- XMAC 2 registers */ #define SK_XMAC2_BASE 0x3000 -#define SK_XMAC2_END 0x33FF - -/* Compute relative offset of an XMAC register in the XMAC window(s). */ -#define SK_XMAC_REG(reg, mac) (((reg) * 2) + SK_XMAC1_BASE + \ - (mac * (SK_XMAC2_BASE - SK_XMAC1_BASE))) -#define SK_XM_READ_4(sc, reg) \ - (sk_win_read_2(sc->sk_softc, \ - SK_XMAC_REG(reg, sc->sk_port)) & 0xFFFF) | \ - ((sk_win_read_2(sc->sk_softc, \ - SK_XMAC_REG(reg + 2, sc->sk_port)) << 16) & 0xFFFF0000) +/* Block 0x70 to 0x7F -- MARV 2 registers */ +#define SK_MARV2_BASE 0x3800 -#define SK_XM_WRITE_4(sc, reg, val) \ - sk_win_write_2(sc->sk_softc, \ - SK_XMAC_REG(reg, sc->sk_port), ((val) & 0xFFFF)); \ - sk_win_write_2(sc->sk_softc, \ - SK_XMAC_REG(reg + 2, sc->sk_port), ((val) >> 16) & 0xFFFF); +/* Compute relative offset of an XMAC register in the XMAC window(s). */ +#define SK_XMAC_REG(sc, reg) (((reg) * 2) + SK_XMAC1_BASE + \ + (((sc)->sk_port) * (SK_XMAC2_BASE - SK_XMAC1_BASE))) + +#if 0 +#define SK_XM_READ_4(sc, reg) \ + ((sk_win_read_2(sc->sk_softc, \ + SK_XMAC_REG(sc, reg)) & 0xFFFF) | \ + ((sk_win_read_2(sc->sk_softc, \ + SK_XMAC_REG(sc, reg + 2)) & 0xFFFF) << 16)) + +#define SK_XM_WRITE_4(sc, reg, val) \ + sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg), \ + ((val) & 0xFFFF)); \ + sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg + 2), \ + ((val) >> 16) & 0xFFFF) +#else +#define SK_XM_READ_4(sc, reg) \ + sk_win_read_4(sc->sk_softc, SK_XMAC_REG(sc, reg)) + +#define SK_XM_WRITE_4(sc, reg, val) \ + sk_win_write_4(sc->sk_softc, SK_XMAC_REG(sc, reg), (val)) +#endif -#define SK_XM_READ_2(sc, reg) \ - sk_win_read_2(sc->sk_softc, SK_XMAC_REG(reg, sc->sk_port)) +#define SK_XM_READ_2(sc, reg) \ + sk_win_read_2(sc->sk_softc, SK_XMAC_REG(sc, reg)) -#define SK_XM_WRITE_2(sc, reg, val) \ - sk_win_write_2(sc->sk_softc, SK_XMAC_REG(reg, sc->sk_port), val) +#define SK_XM_WRITE_2(sc, reg, val) \ + sk_win_write_2(sc->sk_softc, SK_XMAC_REG(sc, reg), val) #define SK_XM_SETBIT_4(sc, reg, x) \ SK_XM_WRITE_4(sc, reg, (SK_XM_READ_4(sc, reg)) | (x)) @@ -946,6 +1142,34 @@ #define SK_XM_CLRBIT_2(sc, reg, x) \ SK_XM_WRITE_2(sc, reg, (SK_XM_READ_2(sc, reg)) & ~(x)) +/* Compute relative offset of an MARV register in the MARV window(s). */ +#define SK_YU_REG(sc, reg) \ + ((reg) + SK_MARV1_BASE + \ + (((sc)->sk_port) * (SK_MARV2_BASE - SK_MARV1_BASE))) + +#define SK_YU_READ_4(sc, reg) \ + sk_win_read_4((sc)->sk_softc, SK_YU_REG((sc), (reg))) + +#define SK_YU_READ_2(sc, reg) \ + sk_win_read_2((sc)->sk_softc, SK_YU_REG((sc), (reg))) + +#define SK_YU_WRITE_4(sc, reg, val) \ + sk_win_write_4((sc)->sk_softc, SK_YU_REG((sc), (reg)), (val)) + +#define SK_YU_WRITE_2(sc, reg, val) \ + sk_win_write_2((sc)->sk_softc, SK_YU_REG((sc), (reg)), (val)) + +#define SK_YU_SETBIT_4(sc, reg, x) \ + SK_YU_WRITE_4(sc, reg, (SK_YU_READ_4(sc, reg)) | (x)) + +#define SK_YU_CLRBIT_4(sc, reg, x) \ + SK_YU_WRITE_4(sc, reg, (SK_YU_READ_4(sc, reg)) & ~(x)) + +#define SK_YU_SETBIT_2(sc, reg, x) \ + SK_YU_WRITE_2(sc, reg, (SK_YU_READ_2(sc, reg)) | (x)) + +#define SK_YU_CLRBIT_2(sc, reg, x) \ + SK_YU_WRITE_2(sc, reg, (SK_YU_READ_2(sc, reg)) & ~(x)) /* * The default FIFO threshold on the XMAC II is 4 bytes. On @@ -1019,18 +1243,18 @@ struct vpd_key { #define VPD_RES_END 0x78 /* end tag */ #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->sk_btag, sc->sk_bhandle, reg, val) + bus_space_write_4((sc)->sk_btag, (sc)->sk_bhandle, (reg), (val)) #define CSR_WRITE_2(sc, reg, val) \ - bus_space_write_2(sc->sk_btag, sc->sk_bhandle, reg, val) + bus_space_write_2((sc)->sk_btag, (sc)->sk_bhandle, (reg), (val)) #define CSR_WRITE_1(sc, reg, val) \ - bus_space_write_1(sc->sk_btag, sc->sk_bhandle, reg, val) + bus_space_write_1((sc)->sk_btag, (sc)->sk_bhandle, (reg), (val)) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->sk_btag, sc->sk_bhandle, reg) + bus_space_read_4((sc)->sk_btag, (sc)->sk_bhandle, (reg)) #define CSR_READ_2(sc, reg) \ - bus_space_read_2(sc->sk_btag, sc->sk_bhandle, reg) + bus_space_read_2((sc)->sk_btag, (sc)->sk_bhandle, (reg)) #define CSR_READ_1(sc, reg) \ - bus_space_read_1(sc->sk_btag, sc->sk_bhandle, reg) + bus_space_read_1((sc)->sk_btag, (sc)->sk_bhandle, (reg)) struct sk_type { u_int16_t sk_vid; diff --git a/sys/dev/netif/sk/yukonreg.h b/sys/dev/netif/sk/yukonreg.h new file mode 100644 index 0000000000..324b07d199 --- /dev/null +++ b/sys/dev/netif/sk/yukonreg.h @@ -0,0 +1,174 @@ +/* + * $OpenBSD: yukonreg.h,v 1.2 2003/08/12 05:23:06 nate Exp $ + * $DragonFly: src/sys/dev/netif/sk/yukonreg.h,v 1.1 2003/11/07 05:57:23 dillon Exp $ + */ +/* + * Copyright (c) 2003 Nathan L. Binkert + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * $FreeBSD$ + */ + +/* General Purpose Status Register (GPSR) */ +#define YUKON_GPSR 0x0000 + +#define YU_GPSR_SPEED 0x8000 /* speed 0 - 10Mbps, 1 - 100Mbps */ +#define YU_GPSR_DUPLEX 0x4000 /* 0 - half duplex, 1 - full duplex */ +#define YU_GPSR_FCTL_TX 0x2000 /* flow control */ +#define YU_GPSR_LINK 0x1000 /* link status (down/up) */ +#define YU_GPSR_PAUSE 0x0800 /* flow control enable/disable */ +#define YU_GPSR_TX_IN_PROG 0x0400 /* transmit in progress */ +#define YU_GPSR_EXCESS_COL 0x0200 /* excessive collisions occurred */ +#define YU_GPSR_LATE_COL 0x0100 /* late collision occurred */ +#define YU_GPSR_MII_PHY_STC 0x0020 /* MII PHY status change */ +#define YU_GPSR_GIG_SPEED 0x0010 /* Gigabit Speed (0 - use speed bit) */ +#define YU_GPSR_PARTITION 0x0008 /* partition mode */ +#define YU_GPSR_FCTL_RX 0x0004 /* flow control enable/disable */ +#define YU_GPSR_PROMS_EN 0x0002 /* promiscuous mode enable/disable */ + +/* General Purpose Control Register (GPCR) */ +#define YUKON_GPCR 0x0004 + +#define YU_GPCR_FCTL_TX 0x2000 /* Transmit flow control 802.3x */ +#define YU_GPCR_TXEN 0x1000 /* Transmit Enable */ +#define YU_GPCR_RXEN 0x0800 /* Receive Enable */ +#define YU_GPCR_LPBK 0x0200 /* Loopback Enable */ +#define YU_GPCR_PAR 0x0100 /* Partition Enable */ +#define YU_GPCR_GIG 0x0080 /* Gigabit Speed */ +#define YU_GPCR_FLP 0x0040 /* Force Link Pass */ +#define YU_GPCR_DUPLEX 0x0020 /* Duplex Enable */ +#define YU_GPCR_FCTL_RX 0x0010 /* Receive flow control 802.3x */ +#define YU_GPCR_SPEED 0x0008 /* Port Speed */ +#define YU_GPCR_DPLX_EN 0x0004 /* Enable Auto-Update for duplex */ +#define YU_GPCR_FCTL_EN 0x0002 /* Enabel Auto-Update for 802.3x */ +#define YU_GPCR_SPEED_EN 0x0001 /* Enable Auto-Update for speed */ + +/* Transmit Control Register (TCR) */ +#define YUKON_TCR 0x0008 + +#define YU_TCR_FJ 0x8000 /* force jam / flow control */ +#define YU_TCR_CRCD 0x4000 /* insert CRC (0 - enable) */ +#define YU_TCR_PADD 0x2000 /* pad packets to 64b (0 - enable) */ +#define YU_TCR_COLTH 0x1c00 /* collision threshold */ + +/* Receive Control Register (RCR) */ +#define YUKON_RCR 0x000c + +#define YU_RCR_UFLEN 0x8000 /* unicast filter enable */ +#define YU_RCR_MUFLEN 0x4000 /* multicast filter enable */ +#define YU_RCR_CRCR 0x2000 /* remove CRC */ +#define YU_RCR_PASSFC 0x1000 /* pass flow control packets */ + +/* Transmit Flow Control Register (TFCR) */ +#define YUKON_TFCR 0x0010 /* Pause Time */ + +/* Transmit Parameter Register (TPR) */ +#define YUKON_TPR 0x0014 + +#define YU_TPR_JAM_LEN(x) (((x) & 0x3) << 14) +#define YU_TPR_JAM_IPG(x) (((x) & 0x1f) << 9) +#define YU_TPR_JAM2DATA_IPG(x) (((x) & 0x1f) << 4) + +/* Serial Mode Register (SMR) */ +#define YUKON_SMR 0x0018 + +#define YU_SMR_DATA_BLIND(x) (((x) & 0x1f) << 11) +#define YU_SMR_LIMIT4 0x0400 /* reset after 16 / 4 collisions */ +#define YU_SMR_MFL_JUMBO 0x0100 /* max frame length for jumbo frames */ +#define YU_SMR_MFL_VLAN 0x0200 /* max frame length + vlan tag */ +#define YU_SMR_IPG_DATA(x) ((x) & 0x1f) + +/* Source Address Low #1 (SAL1) */ +#define YUKON_SAL1 0x001c /* SA1[15:0] */ + +/* Source Address Middle #1 (SAM1) */ +#define YUKON_SAM1 0x0020 /* SA1[31:16] */ + +/* Source Address High #1 (SAH1) */ +#define YUKON_SAH1 0x0024 /* SA1[47:32] */ + +/* Source Address Low #2 (SAL2) */ +#define YUKON_SAL2 0x0028 /* SA2[15:0] */ + +/* Source Address Middle #2 (SAM2) */ +#define YUKON_SAM2 0x002c /* SA2[31:16] */ + +/* Source Address High #2 (SAH2) */ +#define YUKON_SAH2 0x0030 /* SA2[47:32] */ + +/* Multicatst Address Hash Register 1 (MCAH1) */ +#define YUKON_MCAH1 0x0034 + +/* Multicatst Address Hash Register 2 (MCAH2) */ +#define YUKON_MCAH2 0x0038 + +/* Multicatst Address Hash Register 3 (MCAH3) */ +#define YUKON_MCAH3 0x003c + +/* Multicatst Address Hash Register 4 (MCAH4) */ +#define YUKON_MCAH4 0x0040 + +/* Transmit Interrupt Register (TIR) */ +#define YUKON_TIR 0x0044 + +#define YU_TIR_OUT_UNICAST 0x0001 /* Num Unicast Packets Transmitted */ +#define YU_TIR_OUT_BROADCAST 0x0002 /* Num Broadcast Packets Transmitted */ +#define YU_TIR_OUT_PAUSE 0x0004 /* Num Pause Packets Transmitted */ +#define YU_TIR_OUT_MULTICAST 0x0008 /* Num Multicast Packets Transmitted */ +#define YU_TIR_OUT_OCTETS 0x0030 /* Num Bytes Transmitted */ +#define YU_TIR_OUT_64_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_127_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_255_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_511_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_1023_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_1518_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_MAX_OCTETS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_SPARE 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_COLLISIONS 0x0000 /* Num Packets Transmitted */ +#define YU_TIR_OUT_LATE 0x0000 /* Num Packets Transmitted */ + +/* Receive Interrupt Register (RIR) */ +#define YUKON_RIR 0x0048 + +/* Transmit and Receive Interrupt Register (TRIR) */ +#define YUKON_TRIR 0x004c + +/* Transmit Interrupt Mask Register (TIMR) */ +#define YUKON_TIMR 0x0050 + +/* Receive Interrupt Mask Register (RIMR) */ +#define YUKON_RIMR 0x0054 + +/* Transmit and Receive Interrupt Mask Register (TRIMR) */ +#define YUKON_TRIMR 0x0058 + +/* SMI Control Register (SMICR) */ +#define YUKON_SMICR 0x0080 + +#define YU_SMICR_PHYAD(x) (((x) & 0x1f) << 11) +#define YU_SMICR_REGAD(x) (((x) & 0x1f) << 6) +#define YU_SMICR_OPCODE 0x0020 /* opcode (0 - write, 1 - read) */ +#define YU_SMICR_OP_READ 0x0020 /* opcode read */ +#define YU_SMICR_OP_WRITE 0x0000 /* opcode write */ +#define YU_SMICR_READ_VALID 0x0010 /* read valid */ +#define YU_SMICR_BUSY 0x0008 /* busy (writing) */ + +/* SMI Data Register (SMIDR) */ +#define YUKON_SMIDR 0x0084 + +/* PHY Addres Register (PAR) */ +#define YUKON_PAR 0x0088 + +#define YU_PAR_MIB_CLR 0x0020 /* MIB Counters Clear Mode */ +#define YU_PAR_LOAD_TSTCNT 0x0010 /* Load count 0xfffffff0 into cntr */ -- 2.41.0