Add 3c940 ethernet driver support ('sk' driver) for ASUS K8V (AMD64)
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 7 Nov 2003 05:57:23 +0000 (05:57 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 7 Nov 2003 05:57:23 +0000 (05:57 +0000)
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
sys/dev/netif/mii_layer/e1000phyreg.h
sys/dev/netif/mii_layer/miidevs
sys/dev/netif/mii_layer/miidevs.h
sys/dev/netif/mii_layer/miivar.h
sys/dev/netif/sk/if_sk.c
sys/dev/netif/sk/if_skreg.h
sys/dev/netif/sk/yukonreg.h [new file with mode: 0644]

index a7ab9ab..588eb64 100644 (file)
@@ -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
  * 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 <nate@openbsd.org>
+ * Jung-uk Kim <jkim@niksun.com>
+ */
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -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);
 }
index 34059c4..8c5b9ee 100644 (file)
@@ -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 */
 #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
 #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
 #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
index 414365a..0ab6cc4 100644 (file)
@@ -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
index 715189a..cf799cb 100644 (file)
@@ -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.
 /* 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"
index ad45591..a0d5a05 100644 (file)
@@ -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.
index 8e106a0..d55548f 100644 (file)
@@ -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 <wpaul@ctr.columbia.edu>.  All rights reserved.
  * 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 <binkertn@umich.edu>
+ *
+ * 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.
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
+#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);
index e2bc57e..1235e53 100644 (file)
@@ -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 <wpaul@ctr.columbia.edu>.  All rights reserved.
  * 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 <binkertn@umich.edu>
+ *
+ * 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
 #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.
 #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
 
 #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
 #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
 #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))
 #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 (file)
index 0000000..324b07d
--- /dev/null
@@ -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 <binkertn@umich.edu>
+ *
+ * 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 */