diff -urN grub-0.97.old/configure grub-0.97/configure
--- grub-0.97.old/configure	2005-05-08 11:48:12.000000000 +0900
+++ grub-0.97/configure	2006-03-14 12:03:32.000000000 +0900
@@ -872,6 +872,7 @@
   --disable-packet-retransmission
                           turn off packet retransmission
   --enable-pci-direct     access PCI directly instead of using BIOS
+  --enable-tg3            enable Broadcom tg3 driver
   --enable-3c509          enable 3Com509 driver
   --enable-3c529          enable 3Com529 driver
   --enable-3c595          enable 3Com595 driver
@@ -5571,6 +5572,16 @@
   NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONFIG_PCI_DIRECT=1"
 fi
 
+# Check whether --enable-tg3 or --disable-tg3 was given.
+if test "${enable_tg3+set}" = set; then
+  enableval="$enable_tg3"
+
+fi;
+if test "x$enable_tg3" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TG3"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
+fi
+
 # Check whether --enable-3c509 or --disable-3c509 was given.
 if test "${enable_3c509+set}" = set; then
   enableval="$enable_3c509"
diff -urN grub-0.97.old/configure.ac grub-0.97/configure.ac
--- grub-0.97.old/configure.ac	2005-05-08 11:36:03.000000000 +0900
+++ grub-0.97/configure.ac	2006-03-14 12:03:32.000000000 +0900
@@ -327,6 +327,13 @@
 fi
 
 dnl Device drivers.
+AC_ARG_ENABLE(tg3,
+  [  --enable-tg3          enable Broadcom tg3 driver])
+if test "x$enable_tg3" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TG3"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
+fi
+
 AC_ARG_ENABLE(3c509,
   [  --enable-3c509          enable 3Com509 driver])
 if test "x$enable_3c509" = xyes; then
diff -urN grub-0.97.old/netboot/Makefile.am grub-0.97/netboot/Makefile.am
--- grub-0.97.old/netboot/Makefile.am	2003-07-09 20:45:37.000000000 +0900
+++ grub-0.97/netboot/Makefile.am	2006-03-14 12:03:32.000000000 +0900
@@ -18,7 +18,7 @@
 	epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
 	ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
 	sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
-	tiara.c tlan.c tulip.c via-rhine.c w89c840.c
+	tiara.c tlan.c tulip.c via-rhine.c w89c840.c tg3.c tg3.h
 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
 	-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
 # Filled by configure.
@@ -31,6 +31,7 @@
 # We cannot use a simple rule for them...
 
 # What objects are derived from a driver?
+tg3_drivers = tg3.o
 3c509_drivers = 3c509.o 3c529.o
 3c595_drivers = 3c595.o
 3c90x_drivers = 3c90x.o
@@ -58,6 +59,10 @@
 w89c840_drivers = w89c840.o
 
 # Is it really necessary to specify dependecies explicitly?
+$(tg3_drivers): tg3.c tg3.h
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
 $(3c509_drivers): 3c509.c 3c509.h
 $(3c509_drivers): %.o: 3c509.c
 	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
@@ -184,6 +189,7 @@
 	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
 
 # Per-object flags.
+tg3_o_CFLAGS = -DINCLUDE_TG3=1
 3c509_o_CFLAGS = -DINCLUDE_3C509=1
 3c529_o_CFLAGS = -DINCLUDE_3C529=1
 3c595_o_CFLAGS = -DINCLUDE_3C595=1
diff -urN grub-0.97.old/netboot/Makefile.in grub-0.97/netboot/Makefile.in
--- grub-0.97.old/netboot/Makefile.in	2005-05-08 11:42:35.000000000 +0900
+++ grub-0.97/netboot/Makefile.in	2006-03-14 12:03:32.000000000 +0900
@@ -195,7 +195,7 @@
 	epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
 	ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
 	sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
-	tiara.c tlan.c tulip.c via-rhine.c w89c840.c
+	tiara.c tlan.c tulip.c via-rhine.c w89c840.c tg3.c tg3.h
 
 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
 	-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
@@ -209,6 +209,7 @@
 # We cannot use a simple rule for them...
 
 # What objects are derived from a driver?
+tg3_drivers = tg3.o
 3c509_drivers = 3c509.o 3c529.o
 3c595_drivers = 3c595.o
 3c90x_drivers = 3c90x.o
@@ -236,6 +237,7 @@
 w89c840_drivers = w89c840.o
 
 # Per-object flags.
+tg3_o_CFLAGS = -DINCLUDE_TG3=1
 3c509_o_CFLAGS = -DINCLUDE_3C509=1
 3c529_o_CFLAGS = -DINCLUDE_3C529=1
 3c595_o_CFLAGS = -DINCLUDE_3C595=1
@@ -316,6 +318,7 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tg3.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c509.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c595.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c90x.Po@am__quote@
@@ -446,6 +449,20 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
 
+libdrivers_a-tg3.o: tg3.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tg3.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tg3.Tpo" -c -o libdrivers_a-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" "$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tg3.c' object='libdrivers_a-tg3.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tg3.o `test -f 'tg3.c' || echo '$(srcdir)/'`tg3.c
+
+libdrivers_a-tg3.obj: tg3.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tg3.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tg3.Tpo" -c -o libdrivers_a-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" "$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tg3.c' object='libdrivers_a-tg3.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tg3.obj `if test -f 'tg3.c'; then $(CYGPATH_W) 'tg3.c'; else $(CYGPATH_W) '$(srcdir)/tg3.c'; fi`
+
 libdrivers_a-3c509.o: 3c509.c
 @am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c509.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c509.Tpo" -c -o libdrivers_a-3c509.o `test -f '3c509.c' || echo '$(srcdir)/'`3c509.c; \
 @am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c509.Tpo" "$(DEPDIR)/libdrivers_a-3c509.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c509.Tpo"; exit 1; fi
@@ -962,6 +979,11 @@
 
 
 # Is it really necessary to specify dependecies explicitly?
+$(tg3_drivers): tg3.c tg3.h
+$(tg3_drivers): %.o: tg3.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
 $(3c509_drivers): 3c509.c 3c509.h
 $(3c509_drivers): %.o: 3c509.c
 	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
diff -urN grub-0.97.old/netboot/cards.h grub-0.97/netboot/cards.h
--- grub-0.97.old/netboot/cards.h	2003-07-09 20:45:37.000000000 +0900
+++ grub-0.97/netboot/cards.h	2006-03-14 12:03:32.000000000 +0900
@@ -20,6 +20,11 @@
 #define PCI_ARG(x)
 #endif
 
+#ifdef INCLUDE_TG3
+extern struct nic	*tg3_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
 #ifdef	INCLUDE_WD
 extern struct nic	*wd_probe(struct nic *, unsigned short *
 	PCI_ARG(struct pci_device *));
diff -urN grub-0.97.old/netboot/config.c grub-0.97/netboot/config.c
--- grub-0.97.old/netboot/config.c	2003-07-09 20:45:37.000000000 +0900
+++ grub-0.97/netboot/config.c	2006-03-14 12:09:42.000000000 +0900
@@ -31,7 +31,7 @@
 #include <nic.h>
 
 #undef	INCLUDE_PCI
-#if	defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) ||  defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN)
+#if	defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) ||  defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN) || defined(INCLUDE_TG3)
 	/* || others later */
 # define INCLUDE_PCI
 # include <pci.h>
@@ -217,6 +217,34 @@
   { PCI_VENDOR_ID_OLICOM,	PCI_DEVICE_ID_OLICOM_OC2326,
     "OC2326", 0, 0, 0, 0},
 #endif
+#ifdef INCLUDE_TG3
+  { PCI_VENDOR_ID_BROADCOM, 0x1644, "Broadcom Tigon 3 5700", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1645, "Broadcom Tigon 3 5701", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1646, "Broadcom Tigon 3 5702", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1647, "Broadcom Tigon 3 5703", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1648, "Broadcom Tigon 3 5704", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x164d, "Broadcom Tigon 3 5702FE", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1653, "Broadcom Tigon 3 5705", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1654, "Broadcom Tigon 3 5705_2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x165d, "Broadcom Tigon 3 5705M", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x165e, "Broadcom Tigon 3 5705M_2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1677, "Broadcom Tigon 3 5751", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x1696, "Broadcom Tigon 3 5782", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x169c, "Broadcom Tigon 3 5788", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a6, "Broadcom Tigon 3 5702X", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a7, "Broadcom Tigon 3 5703X", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a8, "Broadcom Tigon 3 5704S", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x16c6, "Broadcom Tigon 3 5702A3", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x16c7, "Broadcom Tigon 3 5703A3", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x170d, "Broadcom Tigon 3 5901", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM, 0x170e, "Broadcom Tigon 3 5901_2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_SYSKONNECT, 0x4400, "Syskonnect 9DXX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_SYSKONNECT, 0x4500, "Syskonnect 9MXX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ALTIMA, 0x03e8, "Altima AC1000", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ALTIMA, 0x03e9, "Altima AC1001", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ALTIMA, 0x03ea, "Altima AC9100", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ALTIMA, 0x03eb, "Altima AC1003", 0, 0, 0, 0},
+#endif
 
   /* other PCI NICs go here */
   {0, 0, NULL, 0, 0, 0, 0}
@@ -339,6 +367,34 @@
 # ifdef INCLUDE_TLAN
   { PCI_VENDOR_ID_OLICOM,   PCI_DEVICE_ID_OLICOM_OC2326,   tlan_probe },
 # endif /* INCLUDE_TLAN */
+#ifdef INCLUDE_TG3
+  { PCI_VENDOR_ID_BROADCOM, 0x1644, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1645, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1646, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1647, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1648, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x164d, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1653, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1654, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x165d, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x165e, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1677, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x1696, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x169c, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a6, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a7, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x16a8, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x16c6, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x16c7, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x170d, tg3_probe},
+  { PCI_VENDOR_ID_BROADCOM, 0x170e, tg3_probe},
+  { PCI_VENDOR_ID_SYSKONNECT, 0x4400, tg3_probe},
+  { PCI_VENDOR_ID_SYSKONNECT, 0x4500, tg3_probe},
+  { PCI_VENDOR_ID_ALTIMA, 0x03e8, tg3_probe},
+  { PCI_VENDOR_ID_ALTIMA, 0x03e9, tg3_probe},
+  { PCI_VENDOR_ID_ALTIMA, 0x03ea, tg3_probe},
+  { PCI_VENDOR_ID_ALTIMA, 0x03eb, tg3_probe},
+#endif
   { 0,                      0,                             0 }
 };
 #endif /* GRUB && INCLUDE_PCI */
@@ -458,6 +514,9 @@
 #ifdef	INCLUDE_TLAN
   { "Olicom 2326", tlan_probe, pci_ioaddrs },
 #endif
+#ifdef	INCLUDE_TG3
+  { "TG3", tg3_probe, pci_ioaddrs },
+#endif
   /* this entry must always be last to mark the end of list */
   { 0, 0, 0 }
 };
diff -urN grub-0.97.old/netboot/pci.c grub-0.97/netboot/pci.c
--- grub-0.97.old/netboot/pci.c	2003-07-09 20:45:38.000000000 +0900
+++ grub-0.97/netboot/pci.c	2006-03-14 12:12:34.000000000 +0900
@@ -441,7 +441,12 @@
 					pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
 
 					if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
-						continue;
+						if( (vendor == PCI_VENDOR_ID_BROADCOM) ||
+						    (vendor == PCI_VENDOR_ID_SYSKONNECT) ||
+						    (vendor == PCI_VENDOR_ID_ALTIMA)) {
+						    ioaddr = 0xff; /* only for probed mark. */
+						}
+						else continue;
 					/* Strip the I/O address out of the returned value */
 					ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
 					/* Get the memory base address */
diff -urN grub-0.97.old/netboot/pci.h grub-0.97/netboot/pci.h
--- grub-0.97.old/netboot/pci.h	2003-07-09 20:45:38.000000000 +0900
+++ grub-0.97/netboot/pci.h	2006-03-14 12:06:51.000000000 +0900
@@ -170,6 +170,12 @@
 #define PCI_DEVICE_ID_OLICOM_OC2183	0x0013
 #define PCI_DEVICE_ID_OLICOM_OC2326	0x0014
 #define PCI_DEVICE_ID_OLICOM_OC6151	0x0021
+#define PCI_VENDOR_ID_BROADCOM          0x14e4
+#define PCI_VENDOR_ID_SYSKONNECT        0x1148
+#define PCI_VENDOR_ID_ALTIMA            0x173b
+#define PCI_VENDOR_ID_DELL              0x1028
+#define PCI_VENDOR_ID_COMPAQ            0x0e11
+#define PCI_VENDOR_ID_FSC               0x1734
 
 struct pci_device {
 	unsigned short	vendor, dev_id;
diff -urN grub-0.97.old/netboot/tg3.c grub-0.97/netboot/tg3.c
--- grub-0.97.old/netboot/tg3.c	1970-01-01 09:00:00.000000000 +0900
+++ grub-0.97/netboot/tg3.c	2006-03-14 12:03:32.000000000 +0900
@@ -0,0 +1,3447 @@
+/* $Id: tg3.c,v 1.5 2003/03/19 21:26:20 gbaum Exp $
+ * tg3.c: Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001, 2002 Jeff Garzik (jgarzik@mandrakesoft.com)
+ * Copyright (C) 2003 Eric Biederman (ebiederman@lnxi.com)  [etherboot port]
+ */
+
+/* 11-13-2003	timlegge	Fix Issue with NetGear GA302T 
+ * 11-18-2003   ebiederm        Generalize NetGear Fix to what the code was supposed to be.
+ * 01-06-2005   Alf (Frederic Olivie) Add Dell bcm 5751 (0x1677) support
+ * 04-15-2005   Martin Vogt Add Fujitsu Siemens Computer (FSC) 0x1734 bcm 5751 0x105d support
+ */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "timer.h"
+/* #include "string.h" */
+#include "tg3.h"
+
+#define udelay(n) waiton_timer2(((n)*TICKS_PER_MS)/1000)
+#define mdelay(n) do{ unsigned int iii; for(iii = 0; iii < n; iii++) udelay(1000);}while(0)
+#define poll_interruptions() 0
+#define virt_to_bus(x) ((unsigned long)x)
+#define bus_to_virt(x) ((void *)x)
+#define ULONG_MAX  4294967295UL
+#define DEBUG 0
+static inline uint32_t bswap_32(uint32_t x)
+{
+        __asm__("xchgb %b0,%h0\n\t"
+                "rorl $16,%0\n\t"
+                "xchgb %b0,%h0"
+                : "=q" (x)
+                : "0" (x));
+        return x;
+}
+static inline void iounmap(void *virt_addr)
+{
+        return;
+}
+static inline void *ioremap(unsigned long bus_addr, unsigned long length)
+{
+	        return bus_to_virt(bus_addr);
+}
+static unsigned long pcibios_bus_base(unsigned int bus)
+{
+	        /* architecturally this must be 0 */
+	        return 0;
+}
+static unsigned long pci_bar_start(struct pci_device *dev, unsigned int index)
+{
+        uint32_t lo, hi;
+        unsigned long bar;
+        pcibios_read_config_dword(dev->bus, dev->devfn, index, &lo);
+        if (lo & PCI_BASE_ADDRESS_SPACE_IO) {
+                bar = lo & PCI_BASE_ADDRESS_IO_MASK;
+        } else {
+                bar = 0;
+                if ((lo & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
+                        pcibios_read_config_dword(dev->bus, dev->devfn, index + 4, &hi);
+                        if (hi) {
+#if ULONG_MAX > 0xffffffff
+                                bar = hi;
+                                bar <<=32;
+#else
+                                printf ( "Unhandled 64bit BAR %08x:%08x\n",
+                                         hi, lo );
+                                return -1UL;
+#endif
+                        }
+                }
+                bar |= lo & PCI_BASE_ADDRESS_MEM_MASK;
+        }
+        return bar + pcibios_bus_base(dev->bus);
+}
+static unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar)
+{
+        uint32_t start, size;
+        /* Save the original bar */
+        pcibios_read_config_dword(dev->bus, dev->devfn, bar, &start);
+        /* Compute which bits can be set */
+        pcibios_write_config_dword(dev->bus, dev->devfn, bar, ~0);
+        pcibios_read_config_dword(dev->bus, dev->devfn, bar, &size);
+        /* Restore the original size */
+        pcibios_write_config_dword(dev->bus, dev->devfn, bar, start);
+        /* Find the significant bits */
+        if (start & PCI_BASE_ADDRESS_SPACE_IO) {
+                size &= PCI_BASE_ADDRESS_IO_MASK;
+        } else {
+                size &= PCI_BASE_ADDRESS_MEM_MASK;
+        }
+        /* Find the lowest bit set */
+        size = size & ~(size - 1);
+        return size;
+}
+static int pci_find_capability(struct pci_device *dev, int cap)
+{
+        uint16_t status;
+        uint8_t pos, id;
+        uint8_t hdr_type;
+        int ttl = 48;
+
+        pcibios_read_config_word(dev->bus, dev->devfn, PCI_STATUS, &status);
+        if (!(status & PCI_STATUS_CAP_LIST))
+                return 0;
+        pcibios_read_config_byte(dev->bus, dev->devfn, PCI_HEADER_TYPE, &hdr_type);
+        switch (hdr_type & 0x7F) {
+        case PCI_HEADER_TYPE_NORMAL:
+        case PCI_HEADER_TYPE_BRIDGE:
+        default:
+                pcibios_read_config_byte(dev->bus, dev->devfn, PCI_CAPABILITY_LIST, &pos);
+                break;
+        case PCI_HEADER_TYPE_CARDBUS:
+                pcibios_read_config_byte(dev->bus, dev->devfn, PCI_CB_CAPABILITY_LIST, &pos);
+                break;
+        }
+        while (ttl-- && pos >= 0x40) {
+                pos &= ~3;
+                pcibios_read_config_byte(dev->bus, dev->devfn, pos + PCI_CAP_LIST_ID, &id);
+#if     DEBUG > 0
+                printf("Capability: %d\n", id);
+#endif
+                if (id == 0xff)
+                        break;
+                if (id == cap)
+                        return pos;
+                pcibios_read_config_byte(dev->bus, dev->devfn, pos + PCI_CAP_LIST_NEXT, &pos);
+        }
+        return 0;
+}
+
+
+#define SUPPORT_COPPER_PHY  1
+#define SUPPORT_FIBER_PHY   1
+#define SUPPORT_LINK_REPORT 1
+#define SUPPORT_PARTNO_STR  1
+#define SUPPORT_PHY_STR     1
+
+struct tg3 tg3;
+
+/* Dummy defines for error handling */
+#define EBUSY  1
+#define ENODEV 2
+#define EINVAL 3
+#define ENOMEM 4
+
+
+/* These numbers seem to be hard coded in the NIC firmware somehow.
+ * You can't change the ring sizes, but you can change where you place
+ * them in the NIC onboard memory.
+ */
+#define TG3_RX_RING_SIZE		512
+#define TG3_DEF_RX_RING_PENDING		20	/* RX_RING_PENDING seems to be o.k. at 20 and 200 */
+#define TG3_RX_RCB_RING_SIZE	1024
+
+/*	(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ? \
+	 512 : 1024) */
+#define TG3_TX_RING_SIZE		512
+#define TG3_DEF_TX_RING_PENDING		(TG3_TX_RING_SIZE - 1)
+
+#define TG3_RX_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RING_SIZE)
+#define TG3_RX_RCB_RING_BYTES	(sizeof(struct tg3_rx_buffer_desc) * TG3_RX_RCB_RING_SIZE)
+
+#define TG3_TX_RING_BYTES	(sizeof(struct tg3_tx_buffer_desc) * TG3_TX_RING_SIZE)
+#define NEXT_TX(N)		(((N) + 1) & (TG3_TX_RING_SIZE - 1))
+#define PREV_TX(N)		(((N) - 1) & (TG3_TX_RING_SIZE - 1))
+
+#define RX_PKT_BUF_SZ		(1536 + 2 + 64)
+
+
+static struct bss {
+	struct tg3_rx_buffer_desc rx_std[TG3_RX_RING_SIZE];
+	struct tg3_rx_buffer_desc rx_rcb[TG3_RX_RCB_RING_SIZE];
+	struct tg3_tx_buffer_desc tx_ring[TG3_TX_RING_SIZE];
+	struct tg3_hw_status      hw_status;
+	struct tg3_hw_stats       hw_stats;
+	unsigned char             rx_bufs[TG3_DEF_RX_RING_PENDING][RX_PKT_BUF_SZ];
+} tg3_bss;
+
+/**
+ * pci_save_state - save the PCI configuration space of a device before suspending
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - buffer to hold config space context
+ *
+ * @buffer must be large enough to hold the entire PCI 2.2 config space 
+ * (>= 64 bytes).
+ */
+static int pci_save_state(struct pci_device *dev, uint32_t *buffer)
+{
+	int i;
+	for (i = 0; i < 16; i++)
+		pcibios_read_config_dword(dev->bus, dev->devfn, i * 4,&buffer[i]);
+	return 0;
+}
+
+/** 
+ * pci_restore_state - Restore the saved state of a PCI device
+ * @dev: - PCI device that we're dealing with
+ * @buffer: - saved PCI config space
+ *
+ */
+static int pci_restore_state(struct pci_device *dev, uint32_t *buffer)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		pcibios_write_config_dword(dev->bus, dev->devfn, i * 4, buffer[i]);
+	return 0;
+}
+
+static void tg3_write_indirect_reg32(uint32_t off, uint32_t val)
+{
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_REG_BASE_ADDR, off);
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_REG_DATA, val);
+}
+
+#define tw32(reg,val)		tg3_write_indirect_reg32((reg),(val))
+#define tw32_mailbox(reg, val)	writel(((val) & 0xffffffff), tg3.regs + (reg))
+#define tw16(reg,val)		writew(((val) & 0xffff), tg3.regs + (reg))
+#define tw8(reg,val)		writeb(((val) & 0xff), tg3.regs + (reg))
+#define tr32(reg)		readl(tg3.regs + (reg))
+#define tr16(reg)		readw(tg3.regs + (reg))
+#define tr8(reg)		readb(tg3.regs + (reg))
+
+static void tw32_carefully(uint32_t reg, uint32_t val)
+{
+	tw32(reg, val);
+	tr32(reg);
+	udelay(100);
+}
+
+static void tw32_mailbox2(uint32_t reg, uint32_t val)
+{
+	tw32_mailbox(reg, val);
+	tr32(reg);
+}
+
+static void tg3_write_mem(uint32_t off, uint32_t val)
+{
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_BASE_ADDR, off);
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_DATA, val);
+
+	/* Always leave this as zero. */
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+}
+
+static void tg3_read_mem(uint32_t off, uint32_t *val)
+{
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_BASE_ADDR, off);
+	pcibios_read_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_DATA, val);
+
+	/* Always leave this as zero. */
+	pcibios_write_config_dword(tg3.pdev->bus, tg3.pdev->devfn, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+}
+
+static void tg3_disable_ints(struct tg3 *tp)
+{
+	tw32(TG3PCI_MISC_HOST_CTRL,
+	     (tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
+	tw32_mailbox2(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+}
+
+static void tg3_switch_clocks(struct tg3 *tp)
+{
+	uint32_t orig_clock_ctrl, clock_ctrl;
+
+	clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
+
+	orig_clock_ctrl = clock_ctrl;
+	clock_ctrl &= (CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE | 0x1f);
+	tp->pci_clock_ctrl = clock_ctrl;
+	
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) &&
+	    (!((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
+	       && (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) &&
+		(orig_clock_ctrl & CLOCK_CTRL_44MHZ_CORE)!=0) {
+		tw32_carefully(TG3PCI_CLOCK_CTRL, 
+			clock_ctrl | (CLOCK_CTRL_44MHZ_CORE | CLOCK_CTRL_ALTCLK));
+		tw32_carefully(TG3PCI_CLOCK_CTRL, 
+			clock_ctrl | (CLOCK_CTRL_ALTCLK));
+	}
+	tw32_carefully(TG3PCI_CLOCK_CTRL, clock_ctrl);
+}
+
+#define PHY_BUSY_LOOPS	5000
+
+static int tg3_readphy(struct tg3 *tp, int reg, uint32_t *val)
+{
+	uint32_t frame_val;
+	int loops, ret;
+
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL);
+
+	*val = 0xffffffff;
+
+	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+		      MI_COM_PHY_ADDR_MASK);
+	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
+		      MI_COM_REG_ADDR_MASK);
+	frame_val |= (MI_COM_CMD_READ | MI_COM_START);
+	
+	tw32_carefully(MAC_MI_COM, frame_val);
+
+	loops = PHY_BUSY_LOOPS;
+	while (loops-- > 0) {
+		udelay(10);
+		frame_val = tr32(MAC_MI_COM);
+
+		if ((frame_val & MI_COM_BUSY) == 0) {
+			udelay(5);
+			frame_val = tr32(MAC_MI_COM);
+			break;
+		}
+	}
+
+	ret = -EBUSY;
+	if (loops > 0) {
+		*val = frame_val & MI_COM_DATA_MASK;
+		ret = 0;
+	}
+
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+
+	return ret;
+}
+
+static int tg3_writephy(struct tg3 *tp, int reg, uint32_t val)
+{
+	uint32_t frame_val;
+	int loops, ret;
+
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode & ~MAC_MI_MODE_AUTO_POLL);
+
+	frame_val  = ((PHY_ADDR << MI_COM_PHY_ADDR_SHIFT) &
+		      MI_COM_PHY_ADDR_MASK);
+	frame_val |= ((reg << MI_COM_REG_ADDR_SHIFT) &
+		      MI_COM_REG_ADDR_MASK);
+	frame_val |= (val & MI_COM_DATA_MASK);
+	frame_val |= (MI_COM_CMD_WRITE | MI_COM_START);
+	
+	tw32_carefully(MAC_MI_COM, frame_val);
+
+	loops = PHY_BUSY_LOOPS;
+	while (loops-- > 0) {
+		udelay(10);
+		frame_val = tr32(MAC_MI_COM);
+		if ((frame_val & MI_COM_BUSY) == 0) {
+			udelay(5);
+			frame_val = tr32(MAC_MI_COM);
+			break;
+		}
+	}
+
+	ret = -EBUSY;
+	if (loops > 0)
+		ret = 0;
+
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+
+	return ret;
+}
+
+static int tg3_writedsp(struct tg3 *tp, uint16_t addr, uint16_t val)
+{
+	int err;
+	err  = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, addr);
+	err |= tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+	return err;
+}
+
+
+static void tg3_phy_set_wirespeed(struct tg3 *tp)
+{
+	uint32_t val;
+
+	if (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED)
+		return;
+
+	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007);
+	tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
+	tg3_writephy(tp, MII_TG3_AUX_CTRL, (val | (1 << 15) | (1 << 4)));
+}
+
+static int tg3_bmcr_reset(struct tg3 *tp)
+{
+	uint32_t phy_control;
+	int limit, err;
+
+	/* OK, reset it, and poll the BMCR_RESET bit until it
+	 * clears or we time out.
+	 */
+	phy_control = BMCR_RESET;
+	err = tg3_writephy(tp, MII_BMCR, phy_control);
+	if (err != 0)
+		return -EBUSY;
+
+	limit = 5000;
+	while (limit--) {
+		err = tg3_readphy(tp, MII_BMCR, &phy_control);
+		if (err != 0)
+			return -EBUSY;
+
+		if ((phy_control & BMCR_RESET) == 0) {
+			udelay(40);
+			break;
+		}
+		udelay(10);
+	}
+	if (limit <= 0)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int tg3_wait_macro_done(struct tg3 *tp)
+{
+	int limit = 100;
+
+	while (limit--) {
+		uint32_t tmp32;
+
+		tg3_readphy(tp, 0x16, &tmp32);
+		if ((tmp32 & 0x1000) == 0)
+			break;
+	}
+	if (limit <= 0)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int tg3_phy_write_and_check_testpat(struct tg3 *tp, int *resetp)
+{
+	static const uint32_t test_pat[4][6] = {
+	{ 0x00005555, 0x00000005, 0x00002aaa, 0x0000000a, 0x00003456, 0x00000003 },
+	{ 0x00002aaa, 0x0000000a, 0x00003333, 0x00000003, 0x0000789a, 0x00000005 },
+	{ 0x00005a5a, 0x00000005, 0x00002a6a, 0x0000000a, 0x00001bcd, 0x00000003 },
+	{ 0x00002a5a, 0x0000000a, 0x000033c3, 0x00000003, 0x00002ef1, 0x00000005 }
+	};
+	int chan;
+
+	for (chan = 0; chan < 4; chan++) {
+		int i;
+
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+			(chan * 0x2000) | 0x0200);
+		tg3_writephy(tp, 0x16, 0x0002);
+
+		for (i = 0; i < 6; i++)
+			tg3_writephy(tp, MII_TG3_DSP_RW_PORT,
+				test_pat[chan][i]);
+
+		tg3_writephy(tp, 0x16, 0x0202);
+		if (tg3_wait_macro_done(tp)) {
+			*resetp = 1;
+			return -EBUSY;
+		}
+
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+			     (chan * 0x2000) | 0x0200);
+		tg3_writephy(tp, 0x16, 0x0082);
+		if (tg3_wait_macro_done(tp)) {
+			*resetp = 1;
+			return -EBUSY;
+		}
+
+		tg3_writephy(tp, 0x16, 0x0802);
+		if (tg3_wait_macro_done(tp)) {
+			*resetp = 1;
+			return -EBUSY;
+		}
+
+		for (i = 0; i < 6; i += 2) {
+			uint32_t low, high;
+
+			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &low);
+			tg3_readphy(tp, MII_TG3_DSP_RW_PORT, &high);
+			if (tg3_wait_macro_done(tp)) {
+				*resetp = 1;
+				return -EBUSY;
+			}
+			low &= 0x7fff;
+			high &= 0x000f;
+			if (low != test_pat[chan][i] ||
+			    high != test_pat[chan][i+1]) {
+				tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000b);
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4001);
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x4005);
+
+				return -EBUSY;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int tg3_phy_reset_chanpat(struct tg3 *tp)
+{
+	int chan;
+
+	for (chan = 0; chan < 4; chan++) {
+		int i;
+
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS,
+			     (chan * 0x2000) | 0x0200);
+		tg3_writephy(tp, 0x16, 0x0002);
+		for (i = 0; i < 6; i++)
+			tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x000);
+		tg3_writephy(tp, 0x16, 0x0202);
+		if (tg3_wait_macro_done(tp))
+			return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int tg3_phy_reset_5703_4_5(struct tg3 *tp)
+{
+	uint32_t reg32, phy9_orig;
+	int retries, do_phy_reset, err;
+
+	retries = 10;
+	do_phy_reset = 1;
+	do {
+		if (do_phy_reset) {
+			err = tg3_bmcr_reset(tp);
+			if (err)
+				return err;
+			do_phy_reset = 0;
+		}
+		
+		/* Disable transmitter and interrupt.  */
+		tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
+		reg32 |= 0x3000;
+		tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
+
+		/* Set full-duplex, 1000 mbps.  */
+		tg3_writephy(tp, MII_BMCR,
+			BMCR_FULLDPLX | TG3_BMCR_SPEED1000);
+
+		/* Set to master mode.  */
+		tg3_readphy(tp, MII_TG3_CTRL, &phy9_orig);
+		tg3_writephy(tp, MII_TG3_CTRL,
+			(MII_TG3_CTRL_AS_MASTER |
+				MII_TG3_CTRL_ENABLE_AS_MASTER));
+
+		/* Enable SM_DSP_CLOCK and 6dB.  */
+		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+
+		/* Block the PHY control access.  */
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
+		tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0800);
+
+		err = tg3_phy_write_and_check_testpat(tp, &do_phy_reset);
+		if (!err)
+			break;
+	} while (--retries);
+
+	err = tg3_phy_reset_chanpat(tp);
+	if (err)
+		return err;
+
+	tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8005);
+	tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x0000);
+
+	tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
+	tg3_writephy(tp, 0x16, 0x0000);
+
+	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+
+	tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
+
+	tg3_readphy(tp, MII_TG3_EXT_CTRL, &reg32);
+	reg32 &= ~0x3000;
+	tg3_writephy(tp, MII_TG3_EXT_CTRL, reg32);
+
+	return err;
+}
+
+/* This will reset the tigon3 PHY if there is no valid
+ * link.
+ */
+static int tg3_phy_reset(struct tg3 *tp)
+{
+	uint32_t phy_status;
+	int err;
+
+	err  = tg3_readphy(tp, MII_BMSR, &phy_status);
+	err |= tg3_readphy(tp, MII_BMSR, &phy_status);
+	if (err != 0)
+		return -EBUSY;
+
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
+		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
+		err = tg3_phy_reset_5703_4_5(tp);
+		if (err)
+			return err;
+		goto out;
+	}
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+	  // Taken from Broadcom's source code
+	  tg3_writephy(tp, 0x18, 0x0c00);
+	  tg3_writephy(tp, 0x17, 0x000a);
+	  tg3_writephy(tp, 0x15, 0x310b);
+	  tg3_writephy(tp, 0x17, 0x201f);
+	  tg3_writephy(tp, 0x15, 0x9506);
+	  tg3_writephy(tp, 0x17, 0x401f);
+	  tg3_writephy(tp, 0x15, 0x14e2);
+	  tg3_writephy(tp, 0x18, 0x0400);
+	}
+	err = tg3_bmcr_reset(tp);
+	if (err)
+		return err;
+ out:
+	tg3_phy_set_wirespeed(tp);
+	return 0;
+}
+
+static void tg3_set_power_state_0(struct tg3 *tp)
+{
+	uint16_t power_control;
+	int pm = tp->pm_cap;
+
+	/* Make sure register accesses (indirect or otherwise)
+	 * will function correctly.
+	 */
+	pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn,  TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+
+	pcibios_read_config_word(tp->pdev->bus, tp->pdev->devfn, pm + PCI_PM_CTRL, &power_control);
+
+	power_control |= PCI_PM_CTRL_PME_STATUS;
+	power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+	power_control |= 0;
+	pcibios_write_config_word(tp->pdev->bus, tp->pdev->devfn, pm + PCI_PM_CTRL, power_control);
+
+	tw32_carefully(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+
+	return;
+}
+
+
+#if SUPPORT_LINK_REPORT
+static void tg3_link_report(struct tg3 *tp)
+{
+	if (!tp->carrier_ok) {
+		printf("Link is down.\n");
+	} else {
+		printf("Link is up at %d Mbps, %s duplex. %s %s %s\n",
+			(tp->link_config.active_speed == SPEED_1000 ?
+			       1000 :
+			(tp->link_config.active_speed == SPEED_100 ?
+				100 : 10)),
+			(tp->link_config.active_duplex == DUPLEX_FULL ?  
+				"full" : "half"),
+			(tp->tg3_flags & TG3_FLAG_TX_PAUSE) ? "TX" : "",
+			(tp->tg3_flags & TG3_FLAG_RX_PAUSE) ? "RX" : "",
+			(tp->tg3_flags & (TG3_FLAG_TX_PAUSE |TG3_FLAG_RX_PAUSE)) ? "flow control" : "");
+	}
+}
+#else
+#define tg3_link_report(tp)
+#endif
+
+static void tg3_setup_flow_control(struct tg3 *tp, uint32_t local_adv, uint32_t remote_adv)
+{
+	uint32_t new_tg3_flags = 0;
+
+	if (local_adv & ADVERTISE_PAUSE_CAP) {
+		if (local_adv & ADVERTISE_PAUSE_ASYM) {
+			if (remote_adv & LPA_PAUSE_CAP)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+			else if (remote_adv & LPA_PAUSE_ASYM)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE);
+		} else {
+			if (remote_adv & LPA_PAUSE_CAP)
+				new_tg3_flags |=
+					(TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+		}
+	} else if (local_adv & ADVERTISE_PAUSE_ASYM) {
+		if ((remote_adv & LPA_PAUSE_CAP) &&
+		    (remote_adv & LPA_PAUSE_ASYM))
+			new_tg3_flags |= TG3_FLAG_TX_PAUSE;
+	}
+
+	tp->tg3_flags &= ~(TG3_FLAG_RX_PAUSE | TG3_FLAG_TX_PAUSE);
+	tp->tg3_flags |= new_tg3_flags;
+
+	if (new_tg3_flags & TG3_FLAG_RX_PAUSE)
+		tp->rx_mode |= RX_MODE_FLOW_CTRL_ENABLE;
+	else
+		tp->rx_mode &= ~RX_MODE_FLOW_CTRL_ENABLE;
+
+	if (new_tg3_flags & TG3_FLAG_TX_PAUSE)
+		tp->tx_mode |= TX_MODE_FLOW_CTRL_ENABLE;
+	else
+		tp->tx_mode &= ~TX_MODE_FLOW_CTRL_ENABLE;
+}
+
+#if SUPPORT_COPPER_PHY
+static void tg3_aux_stat_to_speed_duplex(
+	struct tg3 *tp, uint32_t val, uint8_t *speed, uint8_t *duplex)
+{
+	static const uint8_t map[] = {
+		[0] = (SPEED_INVALID << 2) | DUPLEX_INVALID,
+		[MII_TG3_AUX_STAT_10HALF >> 8]   = (SPEED_10 << 2) | DUPLEX_HALF,
+		[MII_TG3_AUX_STAT_10FULL >> 8]   = (SPEED_10 << 2) | DUPLEX_FULL,
+		[MII_TG3_AUX_STAT_100HALF >> 8]  = (SPEED_100 << 2) | DUPLEX_HALF,
+		[MII_TG3_AUX_STAT_100_4 >> 8] = (SPEED_INVALID << 2) | DUPLEX_INVALID,
+		[MII_TG3_AUX_STAT_100FULL >> 8]  = (SPEED_100 << 2) | DUPLEX_FULL,
+		[MII_TG3_AUX_STAT_1000HALF >> 8] = (SPEED_1000 << 2) | DUPLEX_HALF,
+		[MII_TG3_AUX_STAT_1000FULL >> 8] = (SPEED_1000 << 2) | DUPLEX_FULL,
+	};
+	uint8_t result;
+	result = map[(val & MII_TG3_AUX_STAT_SPDMASK) >> 8];
+	*speed = result >> 2;
+	*duplex = result & 3;
+}
+
+static int tg3_phy_copper_begin(struct tg3 *tp)
+{
+	uint32_t new_adv;
+
+	tp->link_config.advertising =
+		(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+			ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+			ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
+			ADVERTISED_Autoneg | ADVERTISED_MII);
+	
+	if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) {
+		tp->link_config.advertising &=
+			~(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
+	}
+	
+	new_adv = (ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
+	if (tp->link_config.advertising & ADVERTISED_10baseT_Half) {
+		new_adv |= ADVERTISE_10HALF;
+	}
+	if (tp->link_config.advertising & ADVERTISED_10baseT_Full) {
+		new_adv |= ADVERTISE_10FULL;
+	}
+	if (tp->link_config.advertising & ADVERTISED_100baseT_Half) {
+		new_adv |= ADVERTISE_100HALF;
+	}
+	if (tp->link_config.advertising & ADVERTISED_100baseT_Full) {
+		new_adv |= ADVERTISE_100FULL;
+	}
+	tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	
+	if (tp->link_config.advertising &
+		(ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {
+		new_adv = 0;
+		if (tp->link_config.advertising & ADVERTISED_1000baseT_Half) {
+			new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
+		}
+		if (tp->link_config.advertising & ADVERTISED_1000baseT_Full) {
+			new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
+		}
+		if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY) &&
+			(tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+				tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)) {
+			new_adv |= (MII_TG3_CTRL_AS_MASTER |
+				MII_TG3_CTRL_ENABLE_AS_MASTER);
+		}
+		tg3_writephy(tp, MII_TG3_CTRL, new_adv);
+	} else {
+		tg3_writephy(tp, MII_TG3_CTRL, 0);
+	}
+
+	tg3_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+
+	return 0;
+}
+
+static int tg3_init_5401phy_dsp(struct tg3 *tp)
+{
+	int err;
+
+	/* Turn off tap power management. */
+	err  = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c20);
+	
+	err |= tg3_writedsp(tp, 0x0012, 0x1804);
+	err |= tg3_writedsp(tp, 0x0013, 0x1204);
+	err |= tg3_writedsp(tp, 0x8006, 0x0132);
+	err |= tg3_writedsp(tp, 0x8006, 0x0232);
+	err |= tg3_writedsp(tp, 0x201f, 0x0a20);
+
+	udelay(40);
+
+	return err;
+}
+
+static int tg3_setup_copper_phy(struct tg3 *tp)
+{
+	int current_link_up;
+	uint32_t bmsr, dummy;
+	int i, err;
+
+	tw32_carefully(MAC_STATUS,
+		(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED
+		 | MAC_STATUS_LNKSTATE_CHANGED));
+
+	tp->mi_mode = MAC_MI_MODE_BASE;
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+
+	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+
+	/* Some third-party PHYs need to be reset on link going
+	 * down.
+	 */
+	if (	(	(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
+			(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+			(tp->pci_chip_rev_id == CHIPREV_ID_5705_A0)) &&
+		(tp->carrier_ok)) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		if (!(bmsr & BMSR_LSTATUS))
+			tg3_phy_reset(tp);
+	}
+
+	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) {
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+		tg3_readphy(tp, MII_BMSR, &bmsr);
+
+		if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE))
+			bmsr = 0;
+
+		if (!(bmsr & BMSR_LSTATUS)) {
+			err = tg3_init_5401phy_dsp(tp);
+			if (err)
+				return err;
+
+			tg3_readphy(tp, MII_BMSR, &bmsr);
+			for (i = 0; i < 1000; i++) {
+				udelay(10);
+				tg3_readphy(tp, MII_BMSR, &bmsr);
+				if (bmsr & BMSR_LSTATUS) {
+					udelay(40);
+					break;
+				}
+			}
+
+			if ((tp->phy_id & PHY_ID_REV_MASK) == PHY_REV_BCM5401_B0 &&
+			    !(bmsr & BMSR_LSTATUS) &&
+			    tp->link_config.active_speed == SPEED_1000) {
+				err = tg3_phy_reset(tp);
+				if (!err)
+					err = tg3_init_5401phy_dsp(tp);
+				if (err)
+					return err;
+			}
+		}
+	} else if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+		   tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
+		/* 5701 {A0,B0} CRC bug workaround */
+		tg3_writephy(tp, 0x15, 0x0a75);
+		tg3_writephy(tp, 0x1c, 0x8c68);
+		tg3_writephy(tp, 0x1c, 0x8d68);
+		tg3_writephy(tp, 0x1c, 0x8c68);
+	}
+
+	/* Clear pending interrupts... */
+	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+	tg3_readphy(tp, MII_TG3_ISTAT, &dummy);
+
+	tg3_writephy(tp, MII_TG3_IMASK, ~0);
+
+	if (tp->led_mode == led_mode_three_link)
+		tg3_writephy(tp, MII_TG3_EXT_CTRL,
+			     MII_TG3_EXT_CTRL_LNK3_LED_MODE);
+	else
+		tg3_writephy(tp, MII_TG3_EXT_CTRL, 0);
+
+	current_link_up = 0;
+
+	tg3_readphy(tp, MII_BMSR, &bmsr);
+	tg3_readphy(tp, MII_BMSR, &bmsr);
+
+	if (bmsr & BMSR_LSTATUS) {
+		uint32_t aux_stat, bmcr;
+
+		tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
+		for (i = 0; i < 2000; i++) {
+			udelay(10);
+			tg3_readphy(tp, MII_TG3_AUX_STAT, &aux_stat);
+			if (aux_stat)
+				break;
+		}
+
+		tg3_aux_stat_to_speed_duplex(tp, aux_stat,
+			&tp->link_config.active_speed,
+			&tp->link_config.active_duplex);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		tg3_readphy(tp, MII_BMCR, &bmcr);
+		if (bmcr & BMCR_ANENABLE) {
+			uint32_t gig_ctrl;
+			
+			current_link_up = 1;
+			
+			/* Force autoneg restart if we are exiting
+			 * low power mode.
+			 */
+			tg3_readphy(tp, MII_TG3_CTRL, &gig_ctrl);
+			if (!(gig_ctrl & (MII_TG3_CTRL_ADV_1000_HALF |
+				      MII_TG3_CTRL_ADV_1000_FULL))) {
+				current_link_up = 0;
+			}
+		} else {
+			current_link_up = 0;
+		}
+	}
+
+	if (current_link_up == 1 &&
+		(tp->link_config.active_duplex == DUPLEX_FULL)) {
+		uint32_t local_adv, remote_adv;
+
+		tg3_readphy(tp, MII_ADVERTISE, &local_adv);
+		local_adv &= (ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+
+		tg3_readphy(tp, MII_LPA, &remote_adv);
+		remote_adv &= (LPA_PAUSE_CAP | LPA_PAUSE_ASYM);
+
+		/* If we are not advertising full pause capability,
+		 * something is wrong.  Bring the link down and reconfigure.
+		 */
+		if (local_adv != ADVERTISE_PAUSE_CAP) {
+			current_link_up = 0;
+		} else {
+			tg3_setup_flow_control(tp, local_adv, remote_adv);
+		}
+	}
+
+	if (current_link_up == 0) {
+		uint32_t tmp;
+
+		tg3_phy_copper_begin(tp);
+
+		tg3_readphy(tp, MII_BMSR, &tmp);
+		tg3_readphy(tp, MII_BMSR, &tmp);
+		if (tmp & BMSR_LSTATUS)
+			current_link_up = 1;
+	}
+
+	tp->mac_mode &= ~MAC_MODE_PORT_MODE_MASK;
+	if (current_link_up == 1) {
+		if (tp->link_config.active_speed == SPEED_100 ||
+		    tp->link_config.active_speed == SPEED_10)
+			tp->mac_mode |= MAC_MODE_PORT_MODE_MII;
+		else
+			tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+	} else
+		tp->mac_mode |= MAC_MODE_PORT_MODE_GMII;
+
+	tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+	if (tp->link_config.active_duplex == DUPLEX_HALF)
+		tp->mac_mode |= MAC_MODE_HALF_DUPLEX;
+
+	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) {
+		if ((tp->led_mode == led_mode_link10) ||
+		    (current_link_up == 1 &&
+		     tp->link_config.active_speed == SPEED_10))
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+	} else {
+		if (current_link_up == 1)
+			tp->mac_mode |= MAC_MODE_LINK_POLARITY;
+		tw32(MAC_LED_CTRL, LED_CTRL_PHY_MODE_1);
+	}
+
+	/* ??? Without this setting Netgear GA302T PHY does not
+	 * ??? send/receive packets...
+	 * With this other PHYs cannot bring up the link
+	 */
+	if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5411 &&
+		tp->pci_chip_rev_id == CHIPREV_ID_5700_ALTIMA) {
+		tp->mi_mode |= MAC_MI_MODE_AUTO_POLL;
+		tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+	}
+
+	tw32_carefully(MAC_MODE, tp->mac_mode);
+
+	/* Link change polled. */
+	tw32_carefully(MAC_EVENT, 0);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
+	    current_link_up == 1 &&
+	    tp->link_config.active_speed == SPEED_1000 &&
+	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||
+	     (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {
+		udelay(120);
+		tw32_carefully(MAC_STATUS,
+			(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
+		tg3_write_mem(
+			      NIC_SRAM_FIRMWARE_MBOX,
+			      NIC_SRAM_FIRMWARE_MBOX_MAGIC2);
+	}
+
+	if (current_link_up != tp->carrier_ok) {
+		tp->carrier_ok = current_link_up;
+		tg3_link_report(tp);
+	}
+
+	return 0;
+}
+#else
+#define tg3_setup_copper_phy(TP) (-EINVAL)
+#endif /* SUPPORT_COPPER_PHY */
+
+#if SUPPORT_FIBER_PHY
+struct tg3_fiber_aneginfo {
+	int state;
+#define ANEG_STATE_UNKNOWN		0
+#define ANEG_STATE_AN_ENABLE		1
+#define ANEG_STATE_RESTART_INIT		2
+#define ANEG_STATE_RESTART		3
+#define ANEG_STATE_DISABLE_LINK_OK	4
+#define ANEG_STATE_ABILITY_DETECT_INIT	5
+#define ANEG_STATE_ABILITY_DETECT	6
+#define ANEG_STATE_ACK_DETECT_INIT	7
+#define ANEG_STATE_ACK_DETECT		8
+#define ANEG_STATE_COMPLETE_ACK_INIT	9
+#define ANEG_STATE_COMPLETE_ACK		10
+#define ANEG_STATE_IDLE_DETECT_INIT	11
+#define ANEG_STATE_IDLE_DETECT		12
+#define ANEG_STATE_LINK_OK		13
+#define ANEG_STATE_NEXT_PAGE_WAIT_INIT	14
+#define ANEG_STATE_NEXT_PAGE_WAIT	15
+
+	uint32_t flags;
+#define MR_AN_ENABLE		0x00000001
+#define MR_RESTART_AN		0x00000002
+#define MR_AN_COMPLETE		0x00000004
+#define MR_PAGE_RX		0x00000008
+#define MR_NP_LOADED		0x00000010
+#define MR_TOGGLE_TX		0x00000020
+#define MR_LP_ADV_FULL_DUPLEX	0x00000040
+#define MR_LP_ADV_HALF_DUPLEX	0x00000080
+#define MR_LP_ADV_SYM_PAUSE	0x00000100
+#define MR_LP_ADV_ASYM_PAUSE	0x00000200
+#define MR_LP_ADV_REMOTE_FAULT1	0x00000400
+#define MR_LP_ADV_REMOTE_FAULT2	0x00000800
+#define MR_LP_ADV_NEXT_PAGE	0x00001000
+#define MR_TOGGLE_RX		0x00002000
+#define MR_NP_RX		0x00004000
+
+#define MR_LINK_OK		0x80000000
+
+	unsigned long link_time, cur_time;
+
+	uint32_t ability_match_cfg;
+	int ability_match_count;
+
+	char ability_match, idle_match, ack_match;
+
+	uint32_t txconfig, rxconfig;
+#define ANEG_CFG_NP		0x00000080
+#define ANEG_CFG_ACK		0x00000040
+#define ANEG_CFG_RF2		0x00000020
+#define ANEG_CFG_RF1		0x00000010
+#define ANEG_CFG_PS2		0x00000001
+#define ANEG_CFG_PS1		0x00008000
+#define ANEG_CFG_HD		0x00004000
+#define ANEG_CFG_FD		0x00002000
+#define ANEG_CFG_INVAL		0x00001f06
+
+};
+#define ANEG_OK		0
+#define ANEG_DONE	1
+#define ANEG_TIMER_ENAB	2
+#define ANEG_FAILED	-1
+
+#define ANEG_STATE_SETTLE_TIME	10000
+
+static int tg3_fiber_aneg_smachine(struct tg3 *tp,
+				   struct tg3_fiber_aneginfo *ap)
+{
+	unsigned long delta;
+	uint32_t rx_cfg_reg;
+	int ret;
+
+	if (ap->state == ANEG_STATE_UNKNOWN) {
+		ap->rxconfig = 0;
+		ap->link_time = 0;
+		ap->cur_time = 0;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->idle_match = 0;
+		ap->ack_match = 0;
+	}
+	ap->cur_time++;
+
+	if (tr32(MAC_STATUS) & MAC_STATUS_RCVD_CFG) {
+		rx_cfg_reg = tr32(MAC_RX_AUTO_NEG);
+
+		if (rx_cfg_reg != ap->ability_match_cfg) {
+			ap->ability_match_cfg = rx_cfg_reg;
+			ap->ability_match = 0;
+			ap->ability_match_count = 0;
+		} else {
+			if (++ap->ability_match_count > 1) {
+				ap->ability_match = 1;
+				ap->ability_match_cfg = rx_cfg_reg;
+			}
+		}
+		if (rx_cfg_reg & ANEG_CFG_ACK)
+			ap->ack_match = 1;
+		else
+			ap->ack_match = 0;
+
+		ap->idle_match = 0;
+	} else {
+		ap->idle_match = 1;
+		ap->ability_match_cfg = 0;
+		ap->ability_match_count = 0;
+		ap->ability_match = 0;
+		ap->ack_match = 0;
+
+		rx_cfg_reg = 0;
+	}
+
+	ap->rxconfig = rx_cfg_reg;
+	ret = ANEG_OK;
+
+	switch(ap->state) {
+	case ANEG_STATE_UNKNOWN:
+		if (ap->flags & (MR_AN_ENABLE | MR_RESTART_AN))
+			ap->state = ANEG_STATE_AN_ENABLE;
+
+		/* fallthru */
+	case ANEG_STATE_AN_ENABLE:
+		ap->flags &= ~(MR_AN_COMPLETE | MR_PAGE_RX);
+		if (ap->flags & MR_AN_ENABLE) {
+			ap->link_time = 0;
+			ap->cur_time = 0;
+			ap->ability_match_cfg = 0;
+			ap->ability_match_count = 0;
+			ap->ability_match = 0;
+			ap->idle_match = 0;
+			ap->ack_match = 0;
+
+			ap->state = ANEG_STATE_RESTART_INIT;
+		} else {
+			ap->state = ANEG_STATE_DISABLE_LINK_OK;
+		}
+		break;
+
+	case ANEG_STATE_RESTART_INIT:
+		ap->link_time = ap->cur_time;
+		ap->flags &= ~(MR_NP_LOADED);
+		ap->txconfig = 0;
+		tw32(MAC_TX_AUTO_NEG, 0);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32_carefully(MAC_MODE, tp->mac_mode);
+
+		ret = ANEG_TIMER_ENAB;
+		ap->state = ANEG_STATE_RESTART;
+
+		/* fallthru */
+	case ANEG_STATE_RESTART:
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			ap->state = ANEG_STATE_ABILITY_DETECT_INIT;
+		} else {
+			ret = ANEG_TIMER_ENAB;
+		}
+		break;
+
+	case ANEG_STATE_DISABLE_LINK_OK:
+		ret = ANEG_DONE;
+		break;
+
+	case ANEG_STATE_ABILITY_DETECT_INIT:
+		ap->flags &= ~(MR_TOGGLE_TX);
+		ap->txconfig = (ANEG_CFG_FD | ANEG_CFG_PS1);
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32_carefully(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_ABILITY_DETECT;
+		break;
+
+	case ANEG_STATE_ABILITY_DETECT:
+		if (ap->ability_match != 0 && ap->rxconfig != 0) {
+			ap->state = ANEG_STATE_ACK_DETECT_INIT;
+		}
+		break;
+
+	case ANEG_STATE_ACK_DETECT_INIT:
+		ap->txconfig |= ANEG_CFG_ACK;
+		tw32(MAC_TX_AUTO_NEG, ap->txconfig);
+		tp->mac_mode |= MAC_MODE_SEND_CONFIGS;
+		tw32_carefully(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_ACK_DETECT;
+
+		/* fallthru */
+	case ANEG_STATE_ACK_DETECT:
+		if (ap->ack_match != 0) {
+			if ((ap->rxconfig & ~ANEG_CFG_ACK) ==
+			    (ap->ability_match_cfg & ~ANEG_CFG_ACK)) {
+				ap->state = ANEG_STATE_COMPLETE_ACK_INIT;
+			} else {
+				ap->state = ANEG_STATE_AN_ENABLE;
+			}
+		} else if (ap->ability_match != 0 &&
+			   ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+		}
+		break;
+
+	case ANEG_STATE_COMPLETE_ACK_INIT:
+		if (ap->rxconfig & ANEG_CFG_INVAL) {
+			ret = ANEG_FAILED;
+			break;
+		}
+		ap->flags &= ~(MR_LP_ADV_FULL_DUPLEX |
+			       MR_LP_ADV_HALF_DUPLEX |
+			       MR_LP_ADV_SYM_PAUSE |
+			       MR_LP_ADV_ASYM_PAUSE |
+			       MR_LP_ADV_REMOTE_FAULT1 |
+			       MR_LP_ADV_REMOTE_FAULT2 |
+			       MR_LP_ADV_NEXT_PAGE |
+			       MR_TOGGLE_RX |
+			       MR_NP_RX);
+		if (ap->rxconfig & ANEG_CFG_FD)
+			ap->flags |= MR_LP_ADV_FULL_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_HD)
+			ap->flags |= MR_LP_ADV_HALF_DUPLEX;
+		if (ap->rxconfig & ANEG_CFG_PS1)
+			ap->flags |= MR_LP_ADV_SYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_PS2)
+			ap->flags |= MR_LP_ADV_ASYM_PAUSE;
+		if (ap->rxconfig & ANEG_CFG_RF1)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT1;
+		if (ap->rxconfig & ANEG_CFG_RF2)
+			ap->flags |= MR_LP_ADV_REMOTE_FAULT2;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_LP_ADV_NEXT_PAGE;
+
+		ap->link_time = ap->cur_time;
+
+		ap->flags ^= (MR_TOGGLE_TX);
+		if (ap->rxconfig & 0x0008)
+			ap->flags |= MR_TOGGLE_RX;
+		if (ap->rxconfig & ANEG_CFG_NP)
+			ap->flags |= MR_NP_RX;
+		ap->flags |= MR_PAGE_RX;
+
+		ap->state = ANEG_STATE_COMPLETE_ACK;
+		ret = ANEG_TIMER_ENAB;
+		break;
+
+	case ANEG_STATE_COMPLETE_ACK:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+			break;
+		}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			if (!(ap->flags & (MR_LP_ADV_NEXT_PAGE))) {
+				ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+			} else {
+				if ((ap->txconfig & ANEG_CFG_NP) == 0 &&
+				    !(ap->flags & MR_NP_RX)) {
+					ap->state = ANEG_STATE_IDLE_DETECT_INIT;
+				} else {
+					ret = ANEG_FAILED;
+				}
+			}
+		}
+		break;
+
+	case ANEG_STATE_IDLE_DETECT_INIT:
+		ap->link_time = ap->cur_time;
+		tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+		tw32_carefully(MAC_MODE, tp->mac_mode);
+
+		ap->state = ANEG_STATE_IDLE_DETECT;
+		ret = ANEG_TIMER_ENAB;
+		break;
+
+	case ANEG_STATE_IDLE_DETECT:
+		if (ap->ability_match != 0 &&
+		    ap->rxconfig == 0) {
+			ap->state = ANEG_STATE_AN_ENABLE;
+			break;
+		}
+		delta = ap->cur_time - ap->link_time;
+		if (delta > ANEG_STATE_SETTLE_TIME) {
+			/* XXX another gem from the Broadcom driver :( */
+			ap->state = ANEG_STATE_LINK_OK;
+		}
+		break;
+
+	case ANEG_STATE_LINK_OK:
+		ap->flags |= (MR_AN_COMPLETE | MR_LINK_OK);
+		ret = ANEG_DONE;
+		break;
+
+	case ANEG_STATE_NEXT_PAGE_WAIT_INIT:
+		/* ??? unimplemented */
+		break;
+
+	case ANEG_STATE_NEXT_PAGE_WAIT:
+		/* ??? unimplemented */
+		break;
+
+	default:
+		ret = ANEG_FAILED;
+		break;
+	};
+
+	return ret;
+}
+
+static int tg3_setup_fiber_phy(struct tg3 *tp)
+{
+	uint32_t orig_pause_cfg;
+	uint16_t orig_active_speed;
+	uint8_t orig_active_duplex;
+	int current_link_up;
+	int i;
+
+	orig_pause_cfg =
+		(tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
+				  TG3_FLAG_TX_PAUSE));
+	orig_active_speed = tp->link_config.active_speed;
+	orig_active_duplex = tp->link_config.active_duplex;
+
+	tp->mac_mode &= ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
+	tp->mac_mode |= MAC_MODE_PORT_MODE_TBI;
+	tw32_carefully(MAC_MODE, tp->mac_mode);
+
+	/* Reset when initting first time or we have a link. */
+	if (!(tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) ||
+	    (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
+		/* Set PLL lock range. */
+		tg3_writephy(tp, 0x16, 0x8007);
+
+		/* SW reset */
+		tg3_writephy(tp, MII_BMCR, BMCR_RESET);
+
+		/* Wait for reset to complete. */
+		mdelay(5);
+
+		/* Config mode; select PMA/Ch 1 regs. */
+		tg3_writephy(tp, 0x10, 0x8411);
+
+		/* Enable auto-lock and comdet, select txclk for tx. */
+		tg3_writephy(tp, 0x11, 0x0a10);
+
+		tg3_writephy(tp, 0x18, 0x00a0);
+		tg3_writephy(tp, 0x16, 0x41ff);
+
+		/* Assert and deassert POR. */
+		tg3_writephy(tp, 0x13, 0x0400);
+		udelay(40);
+		tg3_writephy(tp, 0x13, 0x0000);
+
+		tg3_writephy(tp, 0x11, 0x0a50);
+		udelay(40);
+		tg3_writephy(tp, 0x11, 0x0a10);
+
+		/* Wait for signal to stabilize */
+		mdelay(150);
+
+		/* Deselect the channel register so we can read the PHYID
+		 * later.
+		 */
+		tg3_writephy(tp, 0x10, 0x8011);
+	}
+
+	/* Disable link change interrupt.  */
+	tw32_carefully(MAC_EVENT, 0);
+
+	current_link_up = 0;
+	if (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) {
+		if (!(tp->tg3_flags & TG3_FLAG_GOT_SERDES_FLOWCTL)) {
+			struct tg3_fiber_aneginfo aninfo;
+			int status = ANEG_FAILED;
+			unsigned int tick;
+			uint32_t tmp;
+
+			memset(&aninfo, 0, sizeof(aninfo));
+			aninfo.flags |= (MR_AN_ENABLE);
+
+			tw32(MAC_TX_AUTO_NEG, 0);
+
+			tmp = tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK;
+			tw32_carefully(MAC_MODE, tmp | MAC_MODE_PORT_MODE_GMII);
+
+			tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_SEND_CONFIGS);
+
+			aninfo.state = ANEG_STATE_UNKNOWN;
+			aninfo.cur_time = 0;
+			tick = 0;
+			while (++tick < 195000) {
+				status = tg3_fiber_aneg_smachine(tp, &aninfo);
+				if (status == ANEG_DONE ||
+				    status == ANEG_FAILED)
+					break;
+
+				udelay(1);
+			}
+
+			tp->mac_mode &= ~MAC_MODE_SEND_CONFIGS;
+			tw32_carefully(MAC_MODE, tp->mac_mode);
+
+			if (status == ANEG_DONE &&
+			    (aninfo.flags &
+			     (MR_AN_COMPLETE | MR_LINK_OK |
+			      MR_LP_ADV_FULL_DUPLEX))) {
+				uint32_t local_adv, remote_adv;
+
+				local_adv = ADVERTISE_PAUSE_CAP;
+				remote_adv = 0;
+				if (aninfo.flags & MR_LP_ADV_SYM_PAUSE)
+					remote_adv |= LPA_PAUSE_CAP;
+				if (aninfo.flags & MR_LP_ADV_ASYM_PAUSE)
+					remote_adv |= LPA_PAUSE_ASYM;
+
+				tg3_setup_flow_control(tp, local_adv, remote_adv);
+
+				tp->tg3_flags |=
+					TG3_FLAG_GOT_SERDES_FLOWCTL;
+				current_link_up = 1;
+			}
+			for (i = 0; i < 60; i++) {
+				udelay(20);
+				tw32_carefully(MAC_STATUS,
+					(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
+				if ((tr32(MAC_STATUS) &
+				     (MAC_STATUS_SYNC_CHANGED |
+				      MAC_STATUS_CFG_CHANGED)) == 0)
+					break;
+			}
+			if (current_link_up == 0 &&
+			    (tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED)) {
+				current_link_up = 1;
+			}
+		} else {
+			/* Forcing 1000FD link up. */
+			current_link_up = 1;
+		}
+	}
+
+	tp->mac_mode &= ~MAC_MODE_LINK_POLARITY;
+	tw32_carefully(MAC_MODE, tp->mac_mode);
+
+	tp->hw_status->status =
+		(SD_STATUS_UPDATED |
+		 (tp->hw_status->status & ~SD_STATUS_LINK_CHG));
+
+	for (i = 0; i < 100; i++) {
+		udelay(20);
+		tw32_carefully(MAC_STATUS,
+			(MAC_STATUS_SYNC_CHANGED | MAC_STATUS_CFG_CHANGED));
+		if ((tr32(MAC_STATUS) &
+		     (MAC_STATUS_SYNC_CHANGED |
+		      MAC_STATUS_CFG_CHANGED)) == 0)
+			break;
+	}
+
+	if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0)
+		current_link_up = 0;
+
+	if (current_link_up == 1) {
+		tp->link_config.active_speed = SPEED_1000;
+		tp->link_config.active_duplex = DUPLEX_FULL;
+	} else {
+		tp->link_config.active_speed = SPEED_INVALID;
+		tp->link_config.active_duplex = DUPLEX_INVALID;
+	}
+
+	if (current_link_up != tp->carrier_ok) {
+		tp->carrier_ok = current_link_up;
+		tg3_link_report(tp);
+	} else {
+		uint32_t now_pause_cfg =
+			tp->tg3_flags & (TG3_FLAG_RX_PAUSE |
+					 TG3_FLAG_TX_PAUSE);
+		if (orig_pause_cfg != now_pause_cfg ||
+		    orig_active_speed != tp->link_config.active_speed ||
+		    orig_active_duplex != tp->link_config.active_duplex)
+			tg3_link_report(tp);
+	}
+
+	if ((tr32(MAC_STATUS) & MAC_STATUS_PCS_SYNCED) == 0) {
+		tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_LINK_POLARITY);
+		if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) {
+			tw32_carefully(MAC_MODE, tp->mac_mode);
+		}
+	}
+
+	return 0;
+}
+#else
+#define tg3_setup_fiber_phy(TP) (-EINVAL)
+#endif /* SUPPORT_FIBER_PHY */
+
+static int tg3_setup_phy(struct tg3 *tp)
+{
+	int err;
+
+	if (tp->phy_id == PHY_ID_SERDES) {
+		err = tg3_setup_fiber_phy(tp);
+	} else {
+		err = tg3_setup_copper_phy(tp);
+	}
+
+	if (tp->link_config.active_speed == SPEED_1000 &&
+	    tp->link_config.active_duplex == DUPLEX_HALF)
+		tw32(MAC_TX_LENGTHS,
+		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+		      (6 << TX_LENGTHS_IPG_SHIFT) |
+		      (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
+	else
+		tw32(MAC_TX_LENGTHS,
+		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+		      (6 << TX_LENGTHS_IPG_SHIFT) |
+		      (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+
+	return err;
+}
+
+
+#define MAX_WAIT_CNT 1000
+
+/* To stop a block, clear the enable bit and poll till it
+ * clears.  
+ */
+static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, uint32_t enable_bit)
+{
+	unsigned int i;
+	uint32_t val;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+		switch(ofs) {
+		case RCVLSC_MODE:
+		case DMAC_MODE:
+		case MBFREE_MODE:
+		case BUFMGR_MODE:
+		case MEMARB_MODE:
+			/* We can't enable/disable these bits of the
+			 * 5705, just say success.
+			 */
+			return 0;
+		default:
+			break;
+		}
+	}
+	val = tr32(ofs);
+	val &= ~enable_bit;
+	tw32(ofs, val);
+	tr32(ofs);
+
+	for (i = 0; i < MAX_WAIT_CNT; i++) {
+		udelay(100);
+		val = tr32(ofs);
+		if ((val & enable_bit) == 0)
+			break;
+	}
+
+	if (i == MAX_WAIT_CNT) {
+		printf("tg3_stop_block timed out, ofs=%lx enable_bit=%x\n",
+		       ofs, enable_bit);
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int tg3_abort_hw(struct tg3 *tp)
+{
+	int i, err;
+
+	tg3_disable_ints(tp);
+
+	tp->rx_mode &= ~RX_MODE_ENABLE;
+	tw32_carefully(MAC_RX_MODE, tp->rx_mode);
+
+	err  = tg3_stop_block(tp, RCVBDI_MODE,   RCVBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVLPC_MODE,   RCVLPC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVLSC_MODE,   RCVLSC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVDBDI_MODE,  RCVDBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVDCC_MODE,   RCVDCC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RCVCC_MODE,    RCVCC_MODE_ENABLE);
+
+	err |= tg3_stop_block(tp, SNDBDS_MODE,   SNDBDS_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDBDI_MODE,   SNDBDI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
+	err |= tg3_stop_block(tp, RDMAC_MODE,    RDMAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, SNDBDC_MODE,   SNDBDC_MODE_ENABLE);
+	if (err)
+		goto out;
+
+	tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
+	tw32_carefully(MAC_MODE, tp->mac_mode);
+
+	tp->tx_mode &= ~TX_MODE_ENABLE;
+	tw32_carefully(MAC_TX_MODE, tp->tx_mode);
+
+	for (i = 0; i < MAX_WAIT_CNT; i++) {
+		udelay(100);
+		if (!(tr32(MAC_TX_MODE) & TX_MODE_ENABLE))
+			break;
+	}
+	if (i >= MAX_WAIT_CNT) {
+		printf("tg3_abort_hw timed out TX_MODE_ENABLE will not clear MAC_TX_MODE=%x\n",
+			tr32(MAC_TX_MODE));
+		return -ENODEV;
+	}
+
+	err  = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, WDMAC_MODE,  WDMAC_MODE_ENABLE);
+	err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE);
+
+	tw32(FTQ_RESET, 0xffffffff);
+	tw32(FTQ_RESET, 0x00000000);
+
+	err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE);
+	err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE);
+	if (err)
+		goto out;
+
+	memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE);
+
+out:
+	return err;
+}
+
+static void tg3_chip_reset(struct tg3 *tp)
+{
+	uint32_t val;
+
+	if (!(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
+		/* Force NVRAM to settle.
+		 * This deals with a chip bug which can result in EEPROM
+		 * corruption.
+		 */
+		if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+			int i;
+	
+			tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+			for (i = 0; i < 100000; i++) {
+				if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+					break;
+				udelay(10);
+			}
+		}
+	}
+	/* In Etherboot we don't need to worry about the 5701
+	 * REG_WRITE_BUG because we do all register writes indirectly.
+	 */
+
+	// Alf: here patched
+	/* do the reset */
+	val = GRC_MISC_CFG_CORECLK_RESET;
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+	    || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)) {
+		val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
+	}
+
+	// Alf : Please VALIDATE THIS.
+	// It is necessary in my case (5751) to prevent a reboot, but
+	// I have no idea about a side effect on any other version.
+	// It appears to be what's done in tigon3.c from Broadcom
+	if (tp->pci_chip_rev_id != CHIPREV_ID_5750_A0) {
+	  tw32(GRC_MISC_CFG, 0x20000000) ;
+	  val |= 0x20000000 ;
+	}
+
+	tw32(GRC_MISC_CFG, val);
+
+	/* Flush PCI posted writes.  The normal MMIO registers
+	 * are inaccessible at this time so this is the only
+	 * way to make this reliably.  I tried to use indirect
+	 * register read/write but this upset some 5701 variants.
+	 */
+	pcibios_read_config_dword(tp->pdev->bus, tp->pdev->devfn, PCI_COMMAND, &val);
+
+	udelay(120);
+
+	/* Re-enable indirect register accesses. */
+	pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	/* Set MAX PCI retry to zero. */
+	val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
+		val |= PCISTATE_RETRY_SAME_DMA;
+	pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_PCISTATE, val);
+
+	pci_restore_state(tp->pdev, tp->pci_cfg_state);
+
+	/* Make sure PCI-X relaxed ordering bit is clear. */
+	pcibios_read_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_X_CAPS, &val);
+	val &= ~PCIX_CAPS_RELAXED_ORDERING;
+	pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_X_CAPS, val);
+
+	tw32(MEMARB_MODE, MEMARB_MODE_ENABLE);
+
+	if (((tp->nic_sram_data_cfg & NIC_SRAM_DATA_CFG_MINI_PCI) != 0) &&
+		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) {
+		tp->pci_clock_ctrl |=
+			(CLOCK_CTRL_FORCE_CLKRUN | CLOCK_CTRL_CLKRUN_OENABLE);
+		tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
+	}
+
+	tw32(TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl);
+}
+
+static void tg3_stop_fw(struct tg3 *tp)
+{
+	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+		uint32_t val;
+		int i;
+
+		tg3_write_mem(NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
+		val = tr32(GRC_RX_CPU_EVENT);
+		val |= (1 << 14);
+		tw32(GRC_RX_CPU_EVENT, val);
+
+		/* Wait for RX cpu to ACK the event.  */
+		for (i = 0; i < 100; i++) {
+			if (!(tr32(GRC_RX_CPU_EVENT) & (1 << 14)))
+				break;
+			udelay(1);
+		}
+	}
+}
+
+static int tg3_restart_fw(struct tg3 *tp, uint32_t state)
+{
+	uint32_t val;
+	int i;
+	
+	tg3_write_mem(NIC_SRAM_FIRMWARE_MBOX, 
+		NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
+	/* Wait for firmware initialization to complete. */
+	for (i = 0; i < 100000; i++) {
+		tg3_read_mem(NIC_SRAM_FIRMWARE_MBOX, &val);
+		if (val == (uint32_t) ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
+			break;
+		udelay(10);
+	}
+	if (i >= 100000 &&
+		    !(tp->tg3_flags2 & TG3_FLG2_SUN_5704)) {
+		printf("Firmware will not restart magic=%x\n",
+			val);
+		return -ENODEV;
+	}
+	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+	  state = DRV_STATE_SUSPEND;
+	}
+
+	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+	    (tp->pci_chip_rev_id != CHIPREV_ID_5750_A0)) {
+	  // Enable PCIE bug fix
+	  tg3_read_mem(0x7c00, &val);
+	  tg3_write_mem(0x7c00, val | 0x02000000);
+	}
+	tg3_write_mem(NIC_SRAM_FW_DRV_STATE_MBOX, state);
+	return 0;
+}
+
+static int tg3_halt(struct tg3 *tp)
+{
+	tg3_stop_fw(tp);
+	tg3_abort_hw(tp);
+	tg3_chip_reset(tp);
+	return tg3_restart_fw(tp, DRV_STATE_UNLOAD);
+}
+
+static void __tg3_set_mac_addr(struct tg3 *tp)
+{
+	uint32_t addr_high, addr_low;
+	int i;
+
+	addr_high = ((tp->nic->node_addr[0] << 8) |
+		     tp->nic->node_addr[1]);
+	addr_low = ((tp->nic->node_addr[2] << 24) |
+		    (tp->nic->node_addr[3] << 16) |
+		    (tp->nic->node_addr[4] <<  8) |
+		    (tp->nic->node_addr[5] <<  0));
+	for (i = 0; i < 4; i++) {
+		tw32(MAC_ADDR_0_HIGH + (i * 8), addr_high);
+		tw32(MAC_ADDR_0_LOW + (i * 8), addr_low);
+	}
+
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
+		(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
+		(GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705)) {
+		for(i = 0; i < 12; i++) {
+			tw32(MAC_EXTADDR_0_HIGH + (i * 8), addr_high);
+			tw32(MAC_EXTADDR_0_LOW + (i * 8), addr_low);
+		}
+	}
+	addr_high = (tp->nic->node_addr[0] +
+		     tp->nic->node_addr[1] +
+		     tp->nic->node_addr[2] +
+		     tp->nic->node_addr[3] +
+		     tp->nic->node_addr[4] +
+		     tp->nic->node_addr[5]) &
+		TX_BACKOFF_SEED_MASK;
+	tw32(MAC_TX_BACKOFF_SEED, addr_high);
+}
+
+static void tg3_set_bdinfo(struct tg3 *tp, uint32_t bdinfo_addr,
+			   dma_addr_t mapping, uint32_t maxlen_flags,
+			   uint32_t nic_addr)
+{
+	tg3_write_mem((bdinfo_addr +
+		       TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH),
+		      ((uint64_t) mapping >> 32));
+	tg3_write_mem((bdinfo_addr +
+		       TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW),
+		      ((uint64_t) mapping & 0xffffffff));
+	tg3_write_mem((bdinfo_addr +
+		       TG3_BDINFO_MAXLEN_FLAGS),
+		       maxlen_flags);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		tg3_write_mem((bdinfo_addr + TG3_BDINFO_NIC_ADDR), nic_addr);
+	}
+}
+
+
+static void tg3_init_rings(struct tg3 *tp)
+{
+	unsigned i;
+
+	/* Zero out the tg3 variables */
+	memset(&tg3_bss, 0, sizeof(tg3_bss));
+	tp->rx_std    = &tg3_bss.rx_std[0];
+	tp->rx_rcb    = &tg3_bss.rx_rcb[0];
+	tp->tx_ring   = &tg3_bss.tx_ring[0];
+	tp->hw_status = &tg3_bss.hw_status;
+	tp->hw_stats  = &tg3_bss.hw_stats;
+	tp->mac_mode  = 0;
+
+
+	/* Initialize tx/rx rings for packet processing.
+	 *
+	 * The chip has been shut down and the driver detached from
+	 * the networking, so no interrupts or new tx packets will
+	 * end up in the driver.
+	 */
+
+	/* Initialize invariants of the rings, we only set this
+	 * stuff once.  This works because the card does not
+	 * write into the rx buffer posting rings.
+	 */
+	for (i = 0; i < TG3_RX_RING_SIZE; i++) {
+		struct tg3_rx_buffer_desc *rxd;
+
+		rxd = &tp->rx_std[i];
+		rxd->idx_len = (RX_PKT_BUF_SZ - 2 - 64)	<< RXD_LEN_SHIFT;
+		rxd->type_flags = (RXD_FLAG_END << RXD_FLAGS_SHIFT);
+		rxd->opaque = (RXD_OPAQUE_RING_STD | (i << RXD_OPAQUE_INDEX_SHIFT));
+
+		/* Note where the receive buffer for the ring is placed */
+		rxd->addr_hi = 0;
+		rxd->addr_lo = virt_to_bus(
+			&tg3_bss.rx_bufs[i%TG3_DEF_RX_RING_PENDING][2]);
+	}
+}
+
+#define TG3_WRITE_SETTINGS(TABLE) \
+do { \
+	const uint32_t *_table, *_end; \
+	_table = TABLE; \
+	_end = _table + sizeof(TABLE)/sizeof(TABLE[0]);  \
+	for(; _table < _end; _table += 2) { \
+		tw32(_table[0], _table[1]); \
+	} \
+} while(0)
+
+
+/* initialize/reset the tg3 */
+static int tg3_setup_hw(struct tg3 *tp)
+{
+	uint32_t val, rdmac_mode;
+	int i, err, limit;
+
+	/* Simply don't support setups with extremly buggy firmware in etherboot */
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) {
+		printf("Error 5701_A0 firmware bug detected\n");
+		return -EINVAL;
+	}
+
+	tg3_disable_ints(tp);
+
+	/* Originally this was all in tg3_init_hw */
+
+	/* Force the chip into D0. */
+	tg3_set_power_state_0(tp);
+
+	tg3_switch_clocks(tp);
+
+	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+
+	// This should go somewhere else
+#define T3_PCIE_CAPABILITY_ID_REG           0xD0
+#define T3_PCIE_CAPABILITY_ID               0x10
+#define T3_PCIE_CAPABILITY_REG              0xD2
+
+	/* Originally this was all in tg3_reset_hw */
+
+	tg3_stop_fw(tp);
+
+	/* No need to call tg3_abort_hw here, it is called before tg3_setup_hw. */
+
+	tg3_chip_reset(tp);
+
+	tw32(GRC_MODE, tp->grc_mode);  /* Redundant? */
+
+	err = tg3_restart_fw(tp, DRV_STATE_START);
+	if (err)
+		return err;
+
+	if (tp->phy_id == PHY_ID_SERDES) {
+		tp->mac_mode = MAC_MODE_PORT_MODE_TBI;
+	}
+	tw32_carefully(MAC_MODE, tp->mac_mode);
+
+
+	/* This works around an issue with Athlon chipsets on
+	 * B3 tigon3 silicon.  This bit has no effect on any
+	 * other revision.
+	 * Alf: Except 5750 ! (which reboots)
+	 */
+
+        if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+	  tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;
+	tw32_carefully(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
+	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+		val = tr32(TG3PCI_PCISTATE);
+		val |= PCISTATE_RETRY_SAME_DMA;
+		tw32(TG3PCI_PCISTATE, val);
+	}
+
+	/* Descriptor ring init may make accesses to the
+	 * NIC SRAM area to setup the TX descriptors, so we
+	 * can only do this after the hardware has been
+	 * successfully reset.
+	 */
+	tg3_init_rings(tp);
+
+	/* Clear statistics/status block in chip */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		for (i = NIC_SRAM_STATS_BLK;
+		     i < NIC_SRAM_STATUS_BLK + TG3_HW_STATUS_SIZE;
+		     i += sizeof(uint32_t)) {
+			tg3_write_mem(i, 0);
+			udelay(40);
+		}
+	}
+
+	/* This value is determined during the probe time DMA
+	 * engine test, tg3_setup_dma.
+	 */
+	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+
+	tp->grc_mode &= ~(GRC_MODE_HOST_SENDBDS |
+			  GRC_MODE_4X_NIC_SEND_RINGS |
+			  GRC_MODE_NO_TX_PHDR_CSUM |
+			  GRC_MODE_NO_RX_PHDR_CSUM);
+	tp->grc_mode |= GRC_MODE_HOST_SENDBDS;
+	tp->grc_mode |= GRC_MODE_NO_TX_PHDR_CSUM;
+	tp->grc_mode |= GRC_MODE_NO_RX_PHDR_CSUM;
+
+	tw32(GRC_MODE,
+		tp->grc_mode | 
+		(GRC_MODE_IRQ_ON_MAC_ATTN | GRC_MODE_HOST_STACKUP));
+
+	/* Setup the timer prescalar register.  Clock is always 66Mhz. */
+	tw32(GRC_MISC_CFG,
+	     (65 << GRC_MISC_CFG_PRESCALAR_SHIFT));
+
+	/* Initialize MBUF/DESC pool. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+			tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE64);
+		else
+			tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
+		tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
+		tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
+	}
+	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_ENABLE)) {
+		tw32(BUFMGR_MB_RDMA_LOW_WATER,
+		     tp->bufmgr_config.mbuf_read_dma_low_water);
+		tw32(BUFMGR_MB_MACRX_LOW_WATER,
+		     tp->bufmgr_config.mbuf_mac_rx_low_water);
+		tw32(BUFMGR_MB_HIGH_WATER,
+		     tp->bufmgr_config.mbuf_high_water);
+	} else {
+		tw32(BUFMGR_MB_RDMA_LOW_WATER,
+		     tp->bufmgr_config.mbuf_read_dma_low_water_jumbo);
+		tw32(BUFMGR_MB_MACRX_LOW_WATER,
+		     tp->bufmgr_config.mbuf_mac_rx_low_water_jumbo);
+		tw32(BUFMGR_MB_HIGH_WATER,
+		     tp->bufmgr_config.mbuf_high_water_jumbo);
+	}
+	tw32(BUFMGR_DMA_LOW_WATER,
+	     tp->bufmgr_config.dma_low_water);
+	tw32(BUFMGR_DMA_HIGH_WATER,
+	     tp->bufmgr_config.dma_high_water);
+
+	tw32(BUFMGR_MODE, BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE);
+	for (i = 0; i < 2000; i++) {
+		if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
+			break;
+		udelay(10);
+	}
+	if (i >= 2000) {
+		printf("tg3_setup_hw cannot enable BUFMGR\n");
+		return -ENODEV;
+	}
+
+	tw32(FTQ_RESET, 0xffffffff);
+	tw32(FTQ_RESET, 0x00000000);
+	for (i = 0; i < 2000; i++) {
+		if (tr32(FTQ_RESET) == 0x00000000)
+			break;
+		udelay(10);
+	}
+	if (i >= 2000) {
+		printf("tg3_setup_hw cannot reset FTQ\n");
+		return -ENODEV;
+	}
+
+	/* Initialize TG3_BDINFO's at:
+	 *  RCVDBDI_STD_BD:	standard eth size rx ring
+	 *  RCVDBDI_JUMBO_BD:	jumbo frame rx ring
+	 *  RCVDBDI_MINI_BD:	small frame rx ring (??? does not work)
+	 *
+	 * like so:
+	 *  TG3_BDINFO_HOST_ADDR:	high/low parts of DMA address of ring
+	 *  TG3_BDINFO_MAXLEN_FLAGS:	(rx max buffer size << 16) |
+	 *                              ring attribute flags
+	 *  TG3_BDINFO_NIC_ADDR:	location of descriptors in nic SRAM
+	 *
+	 * Standard receive ring @ NIC_SRAM_RX_BUFFER_DESC, 512 entries.
+	 * Jumbo receive ring @ NIC_SRAM_RX_JUMBO_BUFFER_DESC, 256 entries.
+	 *
+	 * ??? No space allocated for mini receive ring? :(
+	 *
+	 * The size of each ring is fixed in the firmware, but the location is
+	 * configurable.
+	 */
+	{
+		static const uint32_t table_all[] = {
+			/* Setup replenish thresholds. */
+			RCVBDI_STD_THRESH, TG3_DEF_RX_RING_PENDING / 8,
+
+			/* Etherboot lives below 4GB */
+			RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
+			RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR, NIC_SRAM_RX_BUFFER_DESC,
+		};
+		static const uint32_t table_not_5705[] = {
+			/* Buffer maximum length */
+			RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, RX_STD_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT,
+			
+			/* Disable the mini frame rx ring */
+			RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,	BDINFO_FLAGS_DISABLED,
+			
+			/* Disable the jumbo frame rx ring */
+			RCVBDI_JUMBO_THRESH, 0,
+			RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED,
+			
+			
+		};
+		TG3_WRITE_SETTINGS(table_all);
+		tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW, 
+			virt_to_bus(tp->rx_std));
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+			tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS,
+				RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT);
+		} else {
+			TG3_WRITE_SETTINGS(table_not_5705);
+		}
+	}
+
+	
+	/* There is only one send ring on 5705, no need to explicitly
+	 * disable the others.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		/* Clear out send RCB ring in SRAM. */
+		for (i = NIC_SRAM_SEND_RCB; i < NIC_SRAM_RCV_RET_RCB; i += TG3_BDINFO_SIZE)
+			tg3_write_mem(i + TG3_BDINFO_MAXLEN_FLAGS, BDINFO_FLAGS_DISABLED);
+	}
+
+	tp->tx_prod = 0;
+	tw32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+	tw32_mailbox2(MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW, 0);
+
+	tg3_set_bdinfo(tp,
+		NIC_SRAM_SEND_RCB,
+		virt_to_bus(tp->tx_ring),
+		(TG3_TX_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT),
+		NIC_SRAM_TX_BUFFER_DESC);
+
+	/* There is only one receive return ring on 5705, no need to explicitly
+	 * disable the others.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		for (i = NIC_SRAM_RCV_RET_RCB; i < NIC_SRAM_STATS_BLK; i += TG3_BDINFO_SIZE) {
+			tg3_write_mem(i + TG3_BDINFO_MAXLEN_FLAGS,
+				BDINFO_FLAGS_DISABLED);
+		}
+	}
+
+	tp->rx_rcb_ptr = 0;
+	tw32_mailbox2(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, 0);
+
+	tg3_set_bdinfo(tp,
+		NIC_SRAM_RCV_RET_RCB,
+		virt_to_bus(tp->rx_rcb),
+		(TG3_RX_RCB_RING_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT),
+		0);
+
+	tp->rx_std_ptr = TG3_DEF_RX_RING_PENDING;
+	tw32_mailbox2(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW,
+		     tp->rx_std_ptr);
+
+	tw32_mailbox2(MAILBOX_RCV_JUMBO_PROD_IDX + TG3_64BIT_REG_LOW, 0);
+
+	/* Initialize MAC address and backoff seed. */
+	__tg3_set_mac_addr(tp);
+
+	/* Calculate RDMAC_MODE setting early, we need it to determine
+	 * the RCVLPC_STATE_ENABLE mask.
+	 */
+	rdmac_mode = (RDMAC_MODE_ENABLE | RDMAC_MODE_TGTABORT_ENAB |
+		RDMAC_MODE_MSTABORT_ENAB | RDMAC_MODE_PARITYERR_ENAB |
+		RDMAC_MODE_ADDROFLOW_ENAB | RDMAC_MODE_FIFOOFLOW_ENAB |
+		RDMAC_MODE_FIFOURUN_ENAB | RDMAC_MODE_FIFOOREAD_ENAB |
+		RDMAC_MODE_LNGREAD_ENAB);
+	if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+		rdmac_mode |= RDMAC_MODE_SPLIT_ENABLE;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+		if (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
+			if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
+				!(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+				rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
+			}
+		}
+	}
+
+	/* Setup host coalescing engine. */
+	tw32(HOSTCC_MODE, 0);
+	for (i = 0; i < 2000; i++) {
+		if (!(tr32(HOSTCC_MODE) & HOSTCC_MODE_ENABLE))
+			break;
+		udelay(10);
+	}
+
+	tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
+		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
+	tw32_carefully(MAC_MODE, tp->mac_mode | MAC_MODE_RXSTAT_CLEAR | MAC_MODE_TXSTAT_CLEAR);
+
+	tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
+		tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
+				       GRC_LCLCTRL_GPIO_OUTPUT1);
+	tw32_carefully(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
+
+	tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
+	tr32(MAILBOX_INTERRUPT_0);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+		tw32_carefully(DMAC_MODE, DMAC_MODE_ENABLE);
+	}
+
+	val = (	WDMAC_MODE_ENABLE | WDMAC_MODE_TGTABORT_ENAB |
+		WDMAC_MODE_MSTABORT_ENAB | WDMAC_MODE_PARITYERR_ENAB |
+		WDMAC_MODE_ADDROFLOW_ENAB | WDMAC_MODE_FIFOOFLOW_ENAB |
+		WDMAC_MODE_FIFOURUN_ENAB | WDMAC_MODE_FIFOOREAD_ENAB |
+		WDMAC_MODE_LNGREAD_ENAB);
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) &&
+		((tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) != 0) &&
+		!(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+		val |= WDMAC_MODE_RX_ACCEL;
+	}
+	tw32_carefully(WDMAC_MODE, val);
+
+	if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
+		val = tr32(TG3PCI_X_CAPS);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
+			val &= PCIX_CAPS_BURST_MASK;
+			val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
+		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+			val &= ~(PCIX_CAPS_SPLIT_MASK | PCIX_CAPS_BURST_MASK);
+			val |= (PCIX_CAPS_MAX_BURST_CPIOB << PCIX_CAPS_BURST_SHIFT);
+			if (tp->tg3_flags & TG3_FLAG_SPLIT_MODE)
+				val |= (tp->split_mode_max_reqs <<
+					PCIX_CAPS_SPLIT_SHIFT);
+		}
+		tw32(TG3PCI_X_CAPS, val);
+	}
+
+	tw32_carefully(RDMAC_MODE, rdmac_mode);
+	{
+		static const uint32_t table_all[] = {
+			/* MTU + ethernet header + FCS + optional VLAN tag */
+			MAC_RX_MTU_SIZE, ETH_MAX_MTU + ETH_HLEN + 8,
+			
+			/* The slot time is changed by tg3_setup_phy if we
+			 * run at gigabit with half duplex.
+			 */
+			MAC_TX_LENGTHS,	
+			(2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+			(6 << TX_LENGTHS_IPG_SHIFT) |
+			(32 << TX_LENGTHS_SLOT_TIME_SHIFT),
+			
+			/* Receive rules. */
+			MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS,
+			RCVLPC_CONFIG, 0x0181,
+			
+			/* Receive/send statistics. */
+			RCVLPC_STATS_ENABLE, 0xffffff,
+			RCVLPC_STATSCTRL, RCVLPC_STATSCTRL_ENABLE,
+			SNDDATAI_STATSENAB, 0xffffff,
+			SNDDATAI_STATSCTRL, (SNDDATAI_SCTRL_ENABLE |SNDDATAI_SCTRL_FASTUPD),
+			
+			/* Host coalescing engine */
+			HOSTCC_RXCOL_TICKS, 0,
+			HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS,
+			HOSTCC_RXMAX_FRAMES, 1,
+			HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES,
+			HOSTCC_RXCOAL_MAXF_INT, 1,
+			HOSTCC_TXCOAL_MAXF_INT, 0,
+			
+			/* Status/statistics block address. */
+			/* Etherboot lives below 4GB, so HIGH == 0 */
+			HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
+
+			/* No need to enable 32byte coalesce mode. */
+			HOSTCC_MODE, HOSTCC_MODE_ENABLE | 0,
+			
+			RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE,
+			RCVLPC_MODE, RCVLPC_MODE_ENABLE,
+			
+			RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE,
+
+			SNDDATAC_MODE, SNDDATAC_MODE_ENABLE,
+			SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE,
+			RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB,
+			RCVDBDI_MODE, RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ,
+			SNDDATAI_MODE, SNDDATAI_MODE_ENABLE,
+			SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE,
+			SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE,
+			
+			/* Accept all multicast frames. */
+			MAC_HASH_REG_0, 0xffffffff,
+			MAC_HASH_REG_1, 0xffffffff,
+			MAC_HASH_REG_2, 0xffffffff,
+			MAC_HASH_REG_3, 0xffffffff,
+		};
+		static const uint32_t table_not_5705[] = {
+			/* Host coalescing engine */
+			HOSTCC_RXCOAL_TICK_INT, 0,
+			HOSTCC_TXCOAL_TICK_INT, 0,
+
+			/* Status/statistics block address. */
+			/* Etherboot lives below 4GB, so HIGH == 0 */
+			HOSTCC_STAT_COAL_TICKS, DEFAULT_STAT_COAL_TICKS,
+			HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, 0,
+			HOSTCC_STATS_BLK_NIC_ADDR, NIC_SRAM_STATS_BLK,
+			HOSTCC_STATUS_BLK_NIC_ADDR, NIC_SRAM_STATUS_BLK,
+
+			RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE,
+
+			MBFREE_MODE, MBFREE_MODE_ENABLE,
+		};
+		TG3_WRITE_SETTINGS(table_all);
+		tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+			virt_to_bus(tp->hw_stats));
+		tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
+			virt_to_bus(tp->hw_status));
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
+			TG3_WRITE_SETTINGS(table_not_5705);
+		}
+	}
+
+	tp->tx_mode = TX_MODE_ENABLE;
+	tw32_carefully(MAC_TX_MODE, tp->tx_mode);
+
+	tp->rx_mode = RX_MODE_ENABLE;
+	tw32_carefully(MAC_RX_MODE, tp->rx_mode);
+
+	tp->mi_mode = MAC_MI_MODE_BASE;
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+
+	tw32(MAC_LED_CTRL, 0);
+	tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB);
+	if (tp->phy_id == PHY_ID_SERDES) {
+		tw32_carefully(MAC_RX_MODE, RX_MODE_RESET);
+	}
+	tp->rx_mode |= RX_MODE_KEEP_VLAN_TAG; /* drop tagged vlan packets */
+	tw32_carefully(MAC_RX_MODE, tp->rx_mode);
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5703_A1)
+		tw32(MAC_SERDES_CFG, 0x616000);
+
+	/* Prevent chip from dropping frames when flow control
+	 * is enabled.
+	 */
+	tw32(MAC_LOW_WMARK_MAX_RX_FRAME, 2);
+	tr32(MAC_LOW_WMARK_MAX_RX_FRAME);
+
+	err = tg3_setup_phy(tp);
+
+	/* Ignore CRC stats */
+
+	/* Initialize receive rules. */
+	tw32(MAC_RCV_RULE_0,  0xc2000000 & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_VALUE_0, 0xffffffff & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_RULE_1,  0x86000004 & RCV_RULE_DISABLE_MASK);
+	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
+
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+	    || (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750))
+		limit = 8;
+	else
+		limit = 16;
+	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+		limit -= 4;
+	switch (limit) {
+	case 16:	tw32(MAC_RCV_RULE_15,  0); tw32(MAC_RCV_VALUE_15,  0);
+	case 15:	tw32(MAC_RCV_RULE_14,  0); tw32(MAC_RCV_VALUE_14,  0);
+	case 14:	tw32(MAC_RCV_RULE_13,  0); tw32(MAC_RCV_VALUE_13,  0);
+	case 13:	tw32(MAC_RCV_RULE_12,  0); tw32(MAC_RCV_VALUE_12,  0);
+	case 12:	tw32(MAC_RCV_RULE_11,  0); tw32(MAC_RCV_VALUE_11,  0);
+	case 11:	tw32(MAC_RCV_RULE_10,  0); tw32(MAC_RCV_VALUE_10,  0);
+	case 10:	tw32(MAC_RCV_RULE_9,  0);  tw32(MAC_RCV_VALUE_9,  0);
+	case 9:		tw32(MAC_RCV_RULE_8,  0);  tw32(MAC_RCV_VALUE_8,  0);
+	case 8:		tw32(MAC_RCV_RULE_7,  0);  tw32(MAC_RCV_VALUE_7,  0);
+	case 7:		tw32(MAC_RCV_RULE_6,  0);  tw32(MAC_RCV_VALUE_6,  0);
+	case 6:		tw32(MAC_RCV_RULE_5,  0);  tw32(MAC_RCV_VALUE_5,  0);
+	case 5:		tw32(MAC_RCV_RULE_4,  0);  tw32(MAC_RCV_VALUE_4,  0);
+	case 4:		/* tw32(MAC_RCV_RULE_3,  0); tw32(MAC_RCV_VALUE_3,  0); */
+	case 3:		/* tw32(MAC_RCV_RULE_2,  0); tw32(MAC_RCV_VALUE_2,  0); */
+	case 2:
+	case 1:
+	default:
+		break;
+	};
+
+	return err;
+}
+
+
+
+/* Chips other than 5700/5701 use the NVRAM for fetching info. */
+static void tg3_nvram_init(struct tg3 *tp)
+{
+	tw32(GRC_EEPROM_ADDR,
+	     (EEPROM_ADDR_FSM_RESET |
+	      (EEPROM_DEFAULT_CLOCK_PERIOD <<
+	       EEPROM_ADDR_CLKPERD_SHIFT)));
+
+	mdelay(1);
+
+	/* Enable seeprom accesses. */
+	tw32_carefully(GRC_LOCAL_CTRL,
+		tr32(GRC_LOCAL_CTRL) | GRC_LCLCTRL_AUTO_SEEPROM);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
+		uint32_t nvcfg1 = tr32(NVRAM_CFG1);
+
+		tp->tg3_flags |= TG3_FLAG_NVRAM;
+		if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
+			if (nvcfg1 & NVRAM_CFG1_BUFFERED_MODE)
+				tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		} else {
+			nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+			tw32(NVRAM_CFG1, nvcfg1);
+		}
+
+	} else {
+		tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
+	}
+}
+
+
+static int tg3_nvram_read_using_eeprom(
+	struct tg3 *tp, uint32_t offset, uint32_t *val)
+{
+	uint32_t tmp;
+	int i;
+
+	if (offset > EEPROM_ADDR_ADDR_MASK ||
+		(offset % 4) != 0) {
+		return -EINVAL;
+	}
+
+	tmp = tr32(GRC_EEPROM_ADDR) & ~(EEPROM_ADDR_ADDR_MASK |
+					EEPROM_ADDR_DEVID_MASK |
+					EEPROM_ADDR_READ);
+	tw32(GRC_EEPROM_ADDR,
+	     tmp |
+	     (0 << EEPROM_ADDR_DEVID_SHIFT) |
+	     ((offset << EEPROM_ADDR_ADDR_SHIFT) &
+	      EEPROM_ADDR_ADDR_MASK) |
+	     EEPROM_ADDR_READ | EEPROM_ADDR_START);
+
+	for (i = 0; i < 10000; i++) {
+		tmp = tr32(GRC_EEPROM_ADDR);
+
+		if (tmp & EEPROM_ADDR_COMPLETE)
+			break;
+		udelay(100);
+	}
+	if (!(tmp & EEPROM_ADDR_COMPLETE)) {
+		return -EBUSY;
+	}
+
+	*val = tr32(GRC_EEPROM_DATA);
+	return 0;
+}
+
+static int tg3_nvram_read(struct tg3 *tp, uint32_t offset, uint32_t *val)
+{
+	int i, saw_done_clear;
+
+	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+		return tg3_nvram_read_using_eeprom(tp, offset, val);
+
+	if (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED)
+		offset = ((offset / NVRAM_BUFFERED_PAGE_SIZE) <<
+			  NVRAM_BUFFERED_PAGE_POS) +
+			(offset % NVRAM_BUFFERED_PAGE_SIZE);
+
+	if (offset > NVRAM_ADDR_MSK)
+		return -EINVAL;
+
+	tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+	for (i = 0; i < 1000; i++) {
+		if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+			break;
+		udelay(20);
+	}
+
+	tw32(NVRAM_ADDR, offset);
+	tw32(NVRAM_CMD,
+	     NVRAM_CMD_RD | NVRAM_CMD_GO |
+	     NVRAM_CMD_FIRST | NVRAM_CMD_LAST | NVRAM_CMD_DONE);
+
+	/* Wait for done bit to clear then set again. */
+	saw_done_clear = 0;
+	for (i = 0; i < 1000; i++) {
+		udelay(10);
+		if (!saw_done_clear &&
+		    !(tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
+			saw_done_clear = 1;
+		else if (saw_done_clear &&
+			 (tr32(NVRAM_CMD) & NVRAM_CMD_DONE))
+			break;
+	}
+	if (i >= 1000) {
+		tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+		return -EBUSY;
+	}
+
+	*val = bswap_32(tr32(NVRAM_RDDATA));
+	tw32(NVRAM_SWARB, 0x20);
+
+	return 0;
+}
+
+struct subsys_tbl_ent {
+	uint16_t subsys_vendor, subsys_devid;
+	uint32_t phy_id;
+};
+
+static struct subsys_tbl_ent subsys_id_to_phy_id[] = {
+	/* Broadcom boards. */
+	{ 0x14e4, 0x1644, PHY_ID_BCM5401 }, /* BCM95700A6 */
+	{ 0x14e4, 0x0001, PHY_ID_BCM5701 }, /* BCM95701A5 */
+	{ 0x14e4, 0x0002, PHY_ID_BCM8002 }, /* BCM95700T6 */
+	{ 0x14e4, 0x0003, PHY_ID_SERDES  }, /* BCM95700A9 */
+	{ 0x14e4, 0x0005, PHY_ID_BCM5701 }, /* BCM95701T1 */
+	{ 0x14e4, 0x0006, PHY_ID_BCM5701 }, /* BCM95701T8 */
+	{ 0x14e4, 0x0007, PHY_ID_SERDES  }, /* BCM95701A7 */
+	{ 0x14e4, 0x0008, PHY_ID_BCM5701 }, /* BCM95701A10 */
+	{ 0x14e4, 0x8008, PHY_ID_BCM5701 }, /* BCM95701A12 */
+	{ 0x14e4, 0x0009, PHY_ID_BCM5701 }, /* BCM95703Ax1 */
+	{ 0x14e4, 0x8009, PHY_ID_BCM5701 }, /* BCM95703Ax2 */
+
+	/* 3com boards. */
+	{ PCI_VENDOR_ID_3COM, 0x1000, PHY_ID_BCM5401 }, /* 3C996T */
+	{ PCI_VENDOR_ID_3COM, 0x1006, PHY_ID_BCM5701 }, /* 3C996BT */
+	/* { PCI_VENDOR_ID_3COM, 0x1002, PHY_ID_XXX },     3C996CT */
+	/* { PCI_VENDOR_ID_3COM, 0x1003, PHY_ID_XXX },     3C997T */
+	{ PCI_VENDOR_ID_3COM, 0x1004, PHY_ID_SERDES  }, /* 3C996SX */
+	/* { PCI_VENDOR_ID_3COM, 0x1005, PHY_ID_XXX },     3C997SZ */
+	{ PCI_VENDOR_ID_3COM, 0x1007, PHY_ID_BCM5701 }, /* 3C1000T */
+	{ PCI_VENDOR_ID_3COM, 0x1008, PHY_ID_BCM5701 }, /* 3C940BR01 */
+
+	/* DELL boards. */
+	{ PCI_VENDOR_ID_DELL, 0x00d1, PHY_ID_BCM5401 }, /* VIPER */
+	{ PCI_VENDOR_ID_DELL, 0x0106, PHY_ID_BCM5401 }, /* JAGUAR */
+	{ PCI_VENDOR_ID_DELL, 0x0109, PHY_ID_BCM5411 }, /* MERLOT */
+	{ PCI_VENDOR_ID_DELL, 0x010a, PHY_ID_BCM5411 }, /* SLIM_MERLOT */
+	{ PCI_VENDOR_ID_DELL, 0x0179, PHY_ID_BCM5751 }, /* EtherXpress */
+	
+	/* Compaq boards. */
+	{ PCI_VENDOR_ID_COMPAQ, 0x007c, PHY_ID_BCM5701 }, /* BANSHEE */
+	{ PCI_VENDOR_ID_COMPAQ, 0x009a, PHY_ID_BCM5701 }, /* BANSHEE_2 */
+	{ PCI_VENDOR_ID_COMPAQ, 0x007d, PHY_ID_SERDES  }, /* CHANGELING */
+	{ PCI_VENDOR_ID_COMPAQ, 0x0085, PHY_ID_BCM5701 }, /* NC7780 */
+	{ PCI_VENDOR_ID_COMPAQ, 0x0099, PHY_ID_BCM5701 }  /* NC7780_2 */
+};
+
+static int tg3_phy_probe(struct tg3 *tp)
+{
+	uint32_t eeprom_phy_id, hw_phy_id_1, hw_phy_id_2;
+	uint32_t hw_phy_id, hw_phy_id_masked;
+	enum phy_led_mode eeprom_led_mode;
+	uint32_t val;
+	unsigned i;
+	int eeprom_signature_found, err;
+
+	tp->phy_id = PHY_ID_INVALID;
+
+	for (i = 0; i < sizeof(subsys_id_to_phy_id)/sizeof(subsys_id_to_phy_id[0]); i++) {
+		if ((subsys_id_to_phy_id[i].subsys_vendor == tp->subsystem_vendor) &&
+			(subsys_id_to_phy_id[i].subsys_devid == tp->subsystem_device)) {
+			tp->phy_id = subsys_id_to_phy_id[i].phy_id;
+			break;
+		}
+	}
+
+	eeprom_phy_id = PHY_ID_INVALID;
+	eeprom_led_mode = led_mode_auto;
+	eeprom_signature_found = 0;
+	tg3_read_mem(NIC_SRAM_DATA_SIG, &val);
+	if (val == NIC_SRAM_DATA_SIG_MAGIC) {
+		uint32_t nic_cfg;
+
+		tg3_read_mem(NIC_SRAM_DATA_CFG, &nic_cfg);
+		tp->nic_sram_data_cfg = nic_cfg;
+
+		eeprom_signature_found = 1;
+
+		if ((nic_cfg & NIC_SRAM_DATA_CFG_PHY_TYPE_MASK) ==
+		    NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER) {
+			eeprom_phy_id = PHY_ID_SERDES;
+		} else {
+			uint32_t nic_phy_id;
+
+			tg3_read_mem(NIC_SRAM_DATA_PHY_ID, &nic_phy_id);
+			if (nic_phy_id != 0) {
+				uint32_t id1 = nic_phy_id & NIC_SRAM_DATA_PHY_ID1_MASK;
+				uint32_t id2 = nic_phy_id & NIC_SRAM_DATA_PHY_ID2_MASK;
+
+				eeprom_phy_id  = (id1 >> 16) << 10;
+				eeprom_phy_id |= (id2 & 0xfc00) << 16;
+				eeprom_phy_id |= (id2 & 0x03ff) <<  0;
+			}
+		}
+
+		switch (nic_cfg & NIC_SRAM_DATA_CFG_LED_MODE_MASK) {
+		case NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD:
+			eeprom_led_mode = led_mode_three_link;
+			break;
+
+		case NIC_SRAM_DATA_CFG_LED_LINK_SPD:
+			eeprom_led_mode = led_mode_link10;
+			break;
+
+		default:
+			eeprom_led_mode = led_mode_auto;
+			break;
+		};
+		if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
+			(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
+			(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)) &&
+			(nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP)) {
+			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+		}
+
+		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE)
+			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+		if (nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL)
+			tp->tg3_flags |= TG3_FLAG_SERDES_WOL_CAP;
+	}
+
+	/* Now read the physical PHY_ID from the chip and verify
+	 * that it is sane.  If it doesn't look good, we fall back
+	 * to either the hard-coded table based PHY_ID and failing
+	 * that the value found in the eeprom area.
+	 */
+	err  = tg3_readphy(tp, MII_PHYSID1, &hw_phy_id_1);
+	err |= tg3_readphy(tp, MII_PHYSID2, &hw_phy_id_2);
+
+	hw_phy_id  = (hw_phy_id_1 & 0xffff) << 10;
+	hw_phy_id |= (hw_phy_id_2 & 0xfc00) << 16;
+	hw_phy_id |= (hw_phy_id_2 & 0x03ff) <<  0;
+
+	hw_phy_id_masked = hw_phy_id & PHY_ID_MASK;
+
+	if (!err && KNOWN_PHY_ID(hw_phy_id_masked)) {
+		tp->phy_id = hw_phy_id;
+	} else {
+		/* phy_id currently holds the value found in the
+		 * subsys_id_to_phy_id[] table or PHY_ID_INVALID
+		 * if a match was not found there.
+		 */
+		if (tp->phy_id == PHY_ID_INVALID) {
+			if (!eeprom_signature_found ||
+			    !KNOWN_PHY_ID(eeprom_phy_id & PHY_ID_MASK))
+				return -ENODEV;
+			tp->phy_id = eeprom_phy_id;
+		}
+	}
+
+	err = tg3_phy_reset(tp);
+	if (err)
+		return err;
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0) {
+		uint32_t mii_tg3_ctrl;
+		
+		/* These chips, when reset, only advertise 10Mb
+		 * capabilities.  Fix that.
+		 */
+		err  = tg3_writephy(tp, MII_ADVERTISE,
+				    (ADVERTISE_CSMA |
+				     ADVERTISE_PAUSE_CAP |
+				     ADVERTISE_10HALF |
+				     ADVERTISE_10FULL |
+				     ADVERTISE_100HALF |
+				     ADVERTISE_100FULL));
+		mii_tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
+				MII_TG3_CTRL_ADV_1000_FULL |
+				MII_TG3_CTRL_AS_MASTER |
+				MII_TG3_CTRL_ENABLE_AS_MASTER);
+		if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+			mii_tg3_ctrl = 0;
+
+		err |= tg3_writephy(tp, MII_TG3_CTRL, mii_tg3_ctrl);
+		err |= tg3_writephy(tp, MII_BMCR,
+				    (BMCR_ANRESTART | BMCR_ANENABLE));
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) {
+		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+		tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x201f);
+		tg3_writedsp(tp, MII_TG3_DSP_RW_PORT, 0x2aaa);
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
+		tg3_writephy(tp, 0x1c, 0x8d68);
+		tg3_writephy(tp, 0x1c, 0x8d68);
+	}
+
+	/* Enable Ethernet@WireSpeed */
+	tg3_phy_set_wirespeed(tp);
+
+	if (!err && ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401)) {
+		err = tg3_init_5401phy_dsp(tp);
+	}
+
+	/* Determine the PHY led mode. 
+	 * Be careful if this gets set wrong it can result in an inability to 
+	 * establish a link.
+	 */
+	if (tp->phy_id == PHY_ID_SERDES) {
+		tp->led_mode = led_mode_three_link;
+	}
+	else if (tp->subsystem_vendor == PCI_VENDOR_ID_DELL) {
+		tp->led_mode = led_mode_link10;
+	} else {
+		tp->led_mode = led_mode_three_link;
+		if (eeprom_signature_found &&
+		    eeprom_led_mode != led_mode_auto)
+			tp->led_mode = eeprom_led_mode;
+	}
+
+	if (tp->phy_id == PHY_ID_SERDES)
+		tp->link_config.advertising =
+			(ADVERTISED_1000baseT_Half |
+			 ADVERTISED_1000baseT_Full |
+			 ADVERTISED_Autoneg |
+			 ADVERTISED_FIBRE);
+	if (tp->tg3_flags & TG3_FLAG_10_100_ONLY)
+		tp->link_config.advertising &=
+			~(ADVERTISED_1000baseT_Half |
+			  ADVERTISED_1000baseT_Full);
+
+	return err;
+}
+
+#if SUPPORT_PARTNO_STR
+static void tg3_read_partno(struct tg3 *tp)
+{
+	unsigned char vpd_data[256];
+	int i;
+
+	for (i = 0; i < 256; i += 4) {
+		uint32_t tmp;
+
+		if (tg3_nvram_read(tp, 0x100 + i, &tmp))
+			goto out_not_found;
+
+		vpd_data[i + 0] = ((tmp >>  0) & 0xff);
+		vpd_data[i + 1] = ((tmp >>  8) & 0xff);
+		vpd_data[i + 2] = ((tmp >> 16) & 0xff);
+		vpd_data[i + 3] = ((tmp >> 24) & 0xff);
+	}
+
+	/* Now parse and find the part number. */
+	for (i = 0; i < 256; ) {
+		unsigned char val = vpd_data[i];
+		int block_end;
+
+		if (val == 0x82 || val == 0x91) {
+			i = (i + 3 +
+			     (vpd_data[i + 1] +
+			      (vpd_data[i + 2] << 8)));
+			continue;
+		}
+
+		if (val != 0x90)
+			goto out_not_found;
+
+		block_end = (i + 3 +
+			     (vpd_data[i + 1] +
+			      (vpd_data[i + 2] << 8)));
+		i += 3;
+		while (i < block_end) {
+			if (vpd_data[i + 0] == 'P' &&
+			    vpd_data[i + 1] == 'N') {
+				int partno_len = vpd_data[i + 2];
+
+				if (partno_len > 24)
+					goto out_not_found;
+
+				memcpy(tp->board_part_number,
+				       &vpd_data[i + 3],
+				       partno_len);
+
+				/* Success. */
+				return;
+			}
+		}
+
+		/* Part number not found. */
+		goto out_not_found;
+	}
+
+out_not_found:
+	memcpy(tp->board_part_number, "none", sizeof("none"));
+}
+#else
+#define tg3_read_partno(TP) ((TP)->board_part_number[0] = '\0')
+#endif
+
+static int tg3_get_invariants(struct tg3 *tp)
+{
+	uint32_t misc_ctrl_reg;
+	uint32_t pci_state_reg, grc_misc_cfg;
+	uint16_t pci_cmd;
+	uint8_t  pci_latency;
+	uint32_t val ;
+	int err;
+
+	/* Read the subsystem vendor and device ids */
+	pcibios_read_config_word(tp->pdev->bus, tp->pdev->devfn, PCI_SUBSYSTEM_VENDOR_ID, &tp->subsystem_vendor);
+	pcibios_read_config_word(tp->pdev->bus, tp->pdev->devfn, PCI_SUBSYSTEM_ID, &tp->subsystem_device);
+
+	/* The sun_5704 code needs infrastructure etherboot does have
+	 * ignore it for now.
+	 */
+
+	/* If we have an AMD 762 or Intel ICH/ICH0 chipset, write
+	 * reordering to the mailbox registers done by the host
+	 * controller can cause major troubles.  We read back from
+	 * every mailbox register write to force the writes to be
+	 * posted to the chip in order.
+	 *
+	 * TG3_FLAG_MBOX_WRITE_REORDER has been forced on.
+	 */
+
+	/* Force memory write invalidate off.  If we leave it on,
+	 * then on 5700_BX chips we have to enable a workaround.
+	 * The workaround is to set the TG3PCI_DMA_RW_CTRL boundry
+	 * to match the cacheline size.  The Broadcom driver have this
+	 * workaround but turns MWI off all the times so never uses
+	 * it.  This seems to suggest that the workaround is insufficient.
+	 */
+	pcibios_read_config_word(tp->pdev->bus, tp->pdev->devfn, PCI_COMMAND, &pci_cmd);
+	pci_cmd &= ~PCI_COMMAND_INVALIDATE;
+	/* Also, force SERR#/PERR# in PCI command. */
+	pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+	pcibios_write_config_word(tp->pdev->bus, tp->pdev->devfn, PCI_COMMAND, pci_cmd);
+
+	/* It is absolutely critical that TG3PCI_MISC_HOST_CTRL
+	 * has the register indirect write enable bit set before
+	 * we try to access any of the MMIO registers.  It is also
+	 * critical that the PCI-X hw workaround situation is decided
+	 * before that as well.
+	 */
+	pcibios_read_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_MISC_HOST_CTRL, &misc_ctrl_reg);
+
+	tp->pci_chip_rev_id = (misc_ctrl_reg >> MISC_HOST_CTRL_CHIPREV_SHIFT);
+
+	/* Initialize misc host control in PCI block. */
+	tp->misc_host_ctrl |= (misc_ctrl_reg &
+			       MISC_HOST_CTRL_CHIPREV);
+	pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_MISC_HOST_CTRL,
+			       tp->misc_host_ctrl);
+
+	pcibios_read_config_byte(tp->pdev->bus, tp->pdev->devfn, PCI_LATENCY_TIMER, &pci_latency);
+	if (pci_latency < 64) {
+		pcibios_write_config_byte(tp->pdev->bus, tp->pdev->devfn, PCI_LATENCY_TIMER, 64);
+	}
+
+	pcibios_read_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_PCISTATE, &pci_state_reg);
+
+	/* If this is a 5700 BX chipset, and we are in PCI-X
+	 * mode, enable register write workaround.
+	 *
+	 * The workaround is to use indirect register accesses
+	 * for all chip writes not to mailbox registers.
+	 *
+	 * In etherboot to simplify things we just always use this work around.
+	 */
+	if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0) {
+		tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
+	}
+	/* Back to back register writes can cause problems on the 5701,
+	 * the workaround is to read back all reg writes except those to
+	 * mailbox regs.
+	 * In etherboot we always use indirect register accesses so
+	 * we don't see this.
+	 */
+
+	if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
+		tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
+	if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
+		tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
+
+	/* Chip-specific fixup from Broadcom driver */
+	if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
+	    (!(pci_state_reg & PCISTATE_RETRY_SAME_DMA))) {
+		pci_state_reg |= PCISTATE_RETRY_SAME_DMA;
+		pcibios_write_config_dword(tp->pdev->bus, tp->pdev->devfn, TG3PCI_PCISTATE, pci_state_reg);
+	}
+
+	/* determine if it is PCIE system */
+	// Alf : I have no idea what this is about...
+	// But it's definitely usefull
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) {
+	  val = tr32(TG3PCI_MSI_CAP_ID) ;
+	  if (((val >> 8) & 0xff) == T3_PCIE_CAPABILITY_ID_REG) {
+	    val = tr32(T3_PCIE_CAPABILITY_ID_REG) ;
+	    if ((val & 0xff) == T3_PCIE_CAPABILITY_ID) {
+	      tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS ;
+	    }
+	  }
+	}
+
+	/* Force the chip into D0. */
+	tg3_set_power_state_0(tp);
+
+	/* Etherboot does not ask the tg3 to do checksums */
+	/* Etherboot does not ask the tg3 to do jumbo frames */
+	/* Ehterboot does not ask the tg3 to use WakeOnLan. */
+
+	/* A few boards don't want Ethernet@WireSpeed phy feature */
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
+		((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
+			(tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
+			(tp->pci_chip_rev_id != CHIPREV_ID_5705_A1))) {
+		tp->tg3_flags2 |= TG3_FLG2_NO_ETH_WIRE_SPEED;
+	}
+
+	/* Avoid tagged irq status etherboot does not use irqs */
+
+	/* Only 5701 and later support tagged irq status mode.
+	 * Also, 5788 chips cannot use tagged irq status.
+	 *
+	 * However, since etherboot does not use irqs avoid tagged irqs
+	 * status  because the interrupt condition is more difficult to
+	 * fully clear in that mode.
+	 */
+	
+	/* Since some 5700_AX && 5700_BX have problems with 32BYTE
+	 * coalesce_mode, and the rest work fine anything set.
+	 * Don't enable HOST_CC_MODE_32BYTE in etherboot.
+	 */
+
+	/* Initialize MAC MI mode, polling disabled. */
+	tw32_carefully(MAC_MI_MODE, tp->mi_mode);
+
+	/* Initialize data/descriptor byte/word swapping. */
+	tw32(GRC_MODE, tp->grc_mode);
+
+	tg3_switch_clocks(tp);
+
+	/* Clear this out for sanity. */
+	tw32(TG3PCI_MEM_WIN_BASE_ADDR, 0);
+
+	/* Etherboot does not need to check if the PCIX_TARGET_HWBUG
+	 * is needed.  It always uses it.
+	 */
+	
+	udelay(50);
+	tg3_nvram_init(tp);
+
+	/* The TX descriptors will reside in main memory.
+	 */
+
+	/* See which board we are using.
+	 */
+	grc_misc_cfg = tr32(GRC_MISC_CFG);
+	grc_misc_cfg &= GRC_MISC_CFG_BOARD_ID_MASK;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
+	    grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5704CIOBE) {
+		tp->tg3_flags |= TG3_FLAG_SPLIT_MODE;
+		tp->split_mode_max_reqs = SPLIT_MODE_5704_MAX_REQ;
+	}
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
+	    (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
+	     grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
+		tp->tg3_flags2 |= TG3_FLG2_IS_5788;
+
+#define PCI_DEVICE_ID_TIGON3_5901	0x170d
+#define PCI_DEVICE_ID_TIGON3_5901_2	0x170e
+
+	/* these are limited to 10/100 only */
+	if (((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) &&
+		    ((grc_misc_cfg == 0x8000) || (grc_misc_cfg == 0x4000))) ||
+		((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
+			(tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM) &&
+			((tp->pdev->dev_id == PCI_DEVICE_ID_TIGON3_5901) ||
+				(tp->pdev->dev_id == PCI_DEVICE_ID_TIGON3_5901_2)))) {
+		tp->tg3_flags |= TG3_FLAG_10_100_ONLY;
+	}
+
+	err = tg3_phy_probe(tp);
+	if (err) {
+		printf("phy probe failed, err %d\n", err);
+	}
+
+	tg3_read_partno(tp);
+
+
+	/* 5700 BX chips need to have their TX producer index mailboxes
+	 * written twice to workaround a bug.
+	 * In etherboot we do this unconditionally to simplify things.
+	 */
+
+	/* 5700 chips can get confused if TX buffers straddle the
+	 * 4GB address boundary in some cases.
+	 * 
+	 * In etherboot we can ignore the problem as etherboot lives below 4GB.
+	 */
+
+	/* In etherboot wake-on-lan is unconditionally disabled */
+	return err;
+}
+
+static int  tg3_get_device_address(struct tg3 *tp)
+{
+	struct nic *nic = tp->nic;
+	uint32_t hi, lo, mac_offset;
+
+	if (PCI_FUNC(tp->pdev->devfn) == 0)
+		mac_offset = 0x7c;
+	else
+		mac_offset = 0xcc;
+
+	/* First try to get it from MAC address mailbox. */
+	tg3_read_mem(NIC_SRAM_MAC_ADDR_HIGH_MBOX, &hi);
+	if ((hi >> 16) == 0x484b) {
+		nic->node_addr[0] = (hi >>  8) & 0xff;
+		nic->node_addr[1] = (hi >>  0) & 0xff;
+
+		tg3_read_mem(NIC_SRAM_MAC_ADDR_LOW_MBOX, &lo);
+		nic->node_addr[2] = (lo >> 24) & 0xff;
+		nic->node_addr[3] = (lo >> 16) & 0xff;
+		nic->node_addr[4] = (lo >>  8) & 0xff;
+		nic->node_addr[5] = (lo >>  0) & 0xff;
+	}
+	/* Next, try NVRAM. */
+	else if (!tg3_nvram_read(tp, mac_offset + 0, &hi) &&
+		 !tg3_nvram_read(tp, mac_offset + 4, &lo)) {
+		nic->node_addr[0] = ((hi >> 16) & 0xff);
+		nic->node_addr[1] = ((hi >> 24) & 0xff);
+		nic->node_addr[2] = ((lo >>  0) & 0xff);
+		nic->node_addr[3] = ((lo >>  8) & 0xff);
+		nic->node_addr[4] = ((lo >> 16) & 0xff);
+		nic->node_addr[5] = ((lo >> 24) & 0xff);
+	}
+	/* Finally just fetch it out of the MAC control regs. */
+	else {
+		hi = tr32(MAC_ADDR_0_HIGH);
+		lo = tr32(MAC_ADDR_0_LOW);
+
+		nic->node_addr[5] = lo & 0xff;
+		nic->node_addr[4] = (lo >> 8) & 0xff;
+		nic->node_addr[3] = (lo >> 16) & 0xff;
+		nic->node_addr[2] = (lo >> 24) & 0xff;
+		nic->node_addr[1] = hi & 0xff;
+		nic->node_addr[0] = (hi >> 8) & 0xff;
+	}
+
+	return 0;
+}
+
+
+static int tg3_setup_dma(struct tg3 *tp)
+{
+	tw32(TG3PCI_CLOCK_CTRL, 0);
+
+	if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) == 0) {
+		tp->dma_rwctrl =
+			(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+			(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+			(0x7 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+			(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
+			(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+			tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA << DMA_RWCTRL_MIN_DMA_SHIFT);
+		}
+	} else {
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
+			tp->dma_rwctrl =
+				(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+				(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+				(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+				(0x7 << DMA_RWCTRL_READ_WATER_SHIFT) |
+				(0x00 << DMA_RWCTRL_MIN_DMA_SHIFT);
+		else
+			tp->dma_rwctrl =
+				(0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) |
+				(0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT) |
+				(0x3 << DMA_RWCTRL_WRITE_WATER_SHIFT) |
+				(0x3 << DMA_RWCTRL_READ_WATER_SHIFT) |
+				(0x0f << DMA_RWCTRL_MIN_DMA_SHIFT);
+
+		/* Wheee, some more chip bugs... */
+		if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
+			(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)) {
+			uint32_t ccval = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
+
+			if ((ccval == 0x6) || (ccval == 0x7)) {
+				tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA;
+			}
+		}
+	}
+
+	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703) ||
+		(GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)) {
+		tp->dma_rwctrl &= ~(DMA_RWCTRL_MIN_DMA << DMA_RWCTRL_MIN_DMA_SHIFT);
+	}
+
+	/*
+	  Alf : Tried that, but it does not work. Should be this way though :-(
+	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+    	  tp->dma_rwctrl |= 0x001f0000;
+	}
+	*/
+	tp->dma_rwctrl |= DMA_RWCTRL_ASSERT_ALL_BE;
+
+	tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl);
+
+	return 0;
+}
+
+static void tg3_init_link_config(struct tg3 *tp)
+{
+	tp->link_config.advertising =
+		(ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+		 ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+		 ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full |
+		 ADVERTISED_Autoneg | ADVERTISED_MII);
+	tp->carrier_ok = 0;
+	tp->link_config.active_speed = SPEED_INVALID;
+	tp->link_config.active_duplex = DUPLEX_INVALID;
+}
+
+
+#if SUPPORT_PHY_STR
+static const char * tg3_phy_string(struct tg3 *tp)
+{
+	switch (tp->phy_id & PHY_ID_MASK) {
+	case PHY_ID_BCM5400:	return "5400";
+	case PHY_ID_BCM5401:	return "5401";
+	case PHY_ID_BCM5411:	return "5411";
+	case PHY_ID_BCM5701:	return "5701";
+	case PHY_ID_BCM5703:	return "5703";
+	case PHY_ID_BCM5704:	return "5704";
+        case PHY_ID_BCM5705:    return "5705";
+        case PHY_ID_BCM5750:    return "5750";
+	case PHY_ID_BCM5751:	return "5751"; 
+	case PHY_ID_BCM8002:	return "8002/serdes";
+	case PHY_ID_SERDES:	return "serdes";
+	default:		return "unknown";
+	};
+}
+#else
+#define tg3_phy_string(TP) "?"
+#endif
+
+
+static void tg3_poll_link(struct tg3 *tp)
+{
+	uint32_t mac_stat;
+
+	mac_stat = tr32(MAC_STATUS);
+	if (tp->phy_id == PHY_ID_SERDES) {
+		if (tp->carrier_ok?
+			(mac_stat & MAC_STATUS_LNKSTATE_CHANGED):
+			(mac_stat & MAC_STATUS_PCS_SYNCED)) {
+			tw32_carefully(MAC_MODE, tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK);
+			tw32_carefully(MAC_MODE, tp->mac_mode);
+
+			tg3_setup_phy(tp);
+		}
+	}
+	else {
+		if (mac_stat & MAC_STATUS_LNKSTATE_CHANGED) {
+			tg3_setup_phy(tp);
+		}
+	}
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static void tg3_ack_irqs(struct tg3 *tp)
+{
+	if (tp->hw_status->status & SD_STATUS_UPDATED) {
+		/*
+		 * writing any value to intr-mbox-0 clears PCI INTA# and
+		 * chip-internal interrupt pending events.
+		 * writing non-zero to intr-mbox-0 additional tells the
+		 * NIC to stop sending us irqs, engaging "in-intr-handler"
+		 * event coalescing.
+		 */
+		tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 
+			0x00000001);
+		/*
+		 * Flush PCI write.  This also guarantees that our
+		 * status block has been flushed to host memory.
+		 */
+		tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
+		tp->hw_status->status &= ~SD_STATUS_UPDATED;
+	}
+}
+
+static int tg3_poll(struct nic *nic)
+{
+	/* return true if there's an ethernet packet ready to read */
+	/* nic->packet should contain data on return */
+	/* nic->packetlen should contain length of data */
+
+	struct tg3 *tp = &tg3;
+	int result;
+
+	result = 0;
+
+	tg3_ack_irqs(tp);
+
+	if (tp->hw_status->idx[0].rx_producer != tp->rx_rcb_ptr) {
+		struct tg3_rx_buffer_desc *desc;
+		unsigned int len;
+		desc = &tp->rx_rcb[tp->rx_rcb_ptr];
+		if ((desc->opaque & RXD_OPAQUE_RING_MASK) == RXD_OPAQUE_RING_STD) {
+			len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; /* omit crc */
+			
+			nic->packetlen = len;
+			memcpy(nic->packet, bus_to_virt(desc->addr_lo), len);
+			result = 1;
+		}
+		tp->rx_rcb_ptr = (tp->rx_rcb_ptr + 1) % TG3_RX_RCB_RING_SIZE;
+		
+		/* ACK the status ring */
+		tw32_mailbox2(MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW, tp->rx_rcb_ptr);
+
+		/* Refill RX ring. */
+		if (result) {
+			tp->rx_std_ptr = (tp->rx_std_ptr + 1) % TG3_RX_RING_SIZE;
+			tw32_mailbox2(MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW, tp->rx_std_ptr);
+		}
+	}
+	tg3_poll_link(tp);
+	return result;
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+#if 0
+static void tg3_set_txd(struct tg3 *tp, int entry,
+	dma_addr_t mapping, int len, uint32_t flags,
+	uint32_t mss_and_is_end)
+{
+	struct tg3_tx_buffer_desc *txd =  &tp->tx_ring[entry];
+	int is_end = (mss_and_is_end & 0x1);
+	if (is_end) {
+		flags |= TXD_FLAG_END;
+	}
+
+	txd->addr_hi   = 0;
+	txd->addr_lo   = mapping & 0xffffffff;
+	txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
+	txd->vlan_tag  = 0 << TXD_VLAN_TAG_SHIFT;
+}
+#endif
+
+static void tg3_transmit(struct nic *nic, const char *dst_addr,
+	unsigned int type, unsigned int size, const char *packet)
+{
+	static struct eth_frame {
+		uint8_t  dst_addr[ETH_ALEN];
+		uint8_t  src_addr[ETH_ALEN];
+		uint16_t type;
+		uint8_t  data [ETH_FRAME_LEN - ETH_HLEN];
+	} frame[2];
+	static int frame_idx;
+	
+	/* send the packet to destination */
+	struct tg3_tx_buffer_desc *txd;
+	struct tg3 *tp;
+	uint32_t entry;
+	int i;
+
+	/* Wait until there is a free packet frame */
+	tp = &tg3;
+	i = 0;
+	entry = tp->tx_prod;
+	while((tp->hw_status->idx[0].tx_consumer != entry) &&
+		(tp->hw_status->idx[0].tx_consumer != PREV_TX(entry))) {
+		mdelay(10);	/* give the nick a chance */
+		poll_interruptions();
+		if (++i > 500) { /* timeout 5s for transmit */
+			printf("transmit timed out\n");
+			tg3_halt(tp);
+			tg3_setup_hw(tp);
+			return;
+		}
+	}
+	if (i != 0) {
+		printf("#");
+	}
+	
+	/* Copy the packet to the our local buffer */
+	memcpy(&frame[frame_idx].dst_addr, dst_addr, ETH_ALEN);
+	memcpy(&frame[frame_idx].src_addr, nic->node_addr, ETH_ALEN);
+	frame[frame_idx].type = htons(type);
+	memset(&frame[frame_idx].data, 0, sizeof(frame[frame_idx].data));
+	memcpy(&frame[frame_idx].data, packet, size);
+
+	/* Setup the ring buffer entry to transmit */
+	txd            = &tp->tx_ring[entry];
+	txd->addr_hi   = 0; /* Etherboot runs under 4GB */
+	txd->addr_lo   = virt_to_bus(&frame[frame_idx]);
+	txd->len_flags = ((size + ETH_HLEN) << TXD_LEN_SHIFT) | TXD_FLAG_END;
+	txd->vlan_tag  = 0 << TXD_VLAN_TAG_SHIFT;
+
+	/* Advance to the next entry */
+	entry = NEXT_TX(entry);
+	frame_idx ^= 1;
+
+	/* Packets are ready, update Tx producer idx local and on card */
+	tw32_mailbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+	tw32_mailbox2((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry);
+	tp->tx_prod = entry;
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void tg3_disable(struct nic *nic)
+{
+	struct tg3 *tp = &tg3;
+	/* put the card in its initial state */
+	/* This function serves 3 purposes.
+	 * This disables DMA and interrupts so we don't receive
+	 *  unexpected packets or interrupts from the card after
+	 *  etherboot has finished. 
+	 * This frees resources so etherboot may use
+	 *  this driver on another interface
+	 * This allows etherboot to reinitialize the interface
+	 *  if something is something goes wrong.
+	 */
+	tg3_halt(tp);
+	tp->tg3_flags &= ~(TG3_FLAG_INIT_COMPLETE|TG3_FLAG_GOT_SERDES_FLOWCTL);
+	tp->carrier_ok = 0;
+	iounmap((void *)tp->regs);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+You should omit the last argument struct pci_device * for a non-PCI NIC
+***************************************************************************/
+struct nic *tg3_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pdev)
+{
+	struct tg3 *tp = &tg3;
+	unsigned long tg3reg_base, tg3reg_len;
+	int i, err, pm_cap;
+
+	if (pdev == 0)
+		return 0;
+
+	memset(tp, 0, sizeof(*tp));
+
+	adjust_pci_device(pdev);
+
+	/* Find power-management capability. */
+	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
+	if (pm_cap == 0) {
+		printf("Cannot find PowerManagement capability, aborting.\n");
+		return 0;
+	}
+	tg3reg_base = pci_bar_start(pdev, PCI_BASE_ADDRESS_0);
+	if (tg3reg_base == -1UL) {
+		printf("Unuseable bar\n");
+		return 0;
+	}
+	tg3reg_len  = pci_bar_size(pdev,  PCI_BASE_ADDRESS_0);
+
+	tp->pdev       = pdev;
+	tp->nic        = nic;
+	tp->pm_cap     = pm_cap;
+	tp->rx_mode    = 0;
+	tp->tx_mode    = 0;
+	tp->mi_mode    = MAC_MI_MODE_BASE;
+	tp->tg3_flags  = 0 & ~TG3_FLAG_INIT_COMPLETE; 
+	
+	/* The word/byte swap controls here control register access byte
+	 * swapping.  DMA data byte swapping is controlled in the GRC_MODE
+	 * setting below.
+	 */
+	tp->misc_host_ctrl =
+		MISC_HOST_CTRL_MASK_PCI_INT |
+		MISC_HOST_CTRL_WORD_SWAP |
+		MISC_HOST_CTRL_INDIR_ACCESS |
+		MISC_HOST_CTRL_PCISTATE_RW;
+
+	/* The NONFRM (non-frame) byte/word swap controls take effect
+	 * on descriptor entries, anything which isn't packet data.
+	 *
+	 * The StrongARM chips on the board (one for tx, one for rx)
+	 * are running in big-endian mode.
+	 */
+	tp->grc_mode = (GRC_MODE_WSWAP_DATA | GRC_MODE_BSWAP_DATA |
+			GRC_MODE_WSWAP_NONFRM_DATA);
+#if __BYTE_ORDER == __BIG_ENDIAN
+	tp->grc_mode |= GRC_MODE_BSWAP_NONFRM_DATA;
+#endif
+	tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
+	if (tp->regs == 0UL) {
+		printf("Cannot map device registers, aborting\n");
+		return 0;
+	}
+
+	tg3_init_link_config(tp);
+
+	err = tg3_get_invariants(tp);
+	if (err) {
+		printf("Problem fetching invariants of chip, aborting.\n");
+		goto err_out_iounmap;
+	}
+
+	err = tg3_get_device_address(tp);
+	if (err) {
+		printf("Could not obtain valid ethernet address, aborting.\n");
+		goto err_out_iounmap;
+	}
+	printf("Ethernet addr: %!\n", nic->node_addr);
+
+	tg3_setup_dma(tp);
+
+	/* Now that we have fully setup the chip, save away a snapshot
+	 * of the PCI config space.  We need to restore this after
+	 * GRC_MISC_CFG core clock resets and some resume events.
+	 */
+	pci_save_state(tp->pdev, tp->pci_cfg_state);
+
+	printf("Tigon3 [partno(%s) rev %hx PHY(%s)] (PCI%s:%s:%s)\n",
+		tp->board_part_number,
+		tp->pci_chip_rev_id,
+		tg3_phy_string(tp),
+		((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "X" : ""),
+		((tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) ?
+			((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "133MHz" : "66MHz") :
+			((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ? "100MHz" : "33MHz")),
+		((tp->tg3_flags & TG3_FLAG_PCI_32BIT) ? "32-bit" : "64-bit"));
+
+
+	err = tg3_setup_hw(tp); 
+	if (err) {
+		goto err_out_disable;
+	} 
+	tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+
+	/* Wait for a reasonable time for the link to come up */
+	tg3_poll_link(tp);
+	for(i = 0; !tp->carrier_ok && (i < VALID_LINK_TIMEOUT*100); i++) {
+		mdelay(1);
+		tg3_poll_link(tp);
+	}
+	if (!tp->carrier_ok){
+		printf("Valid link not established\n");
+		goto err_out_disable;
+	}
+
+	nic->poll     = tg3_poll;
+	nic->transmit = tg3_transmit;
+	nic->disable  = tg3_disable;
+
+	return nic;
+
+ err_out_iounmap:
+	iounmap((void *)tp->regs);
+	return 0;
+ err_out_disable:
+	tg3_disable(nic);
+	return 0;
+}
+
diff -urN grub-0.97.old/netboot/tg3.h grub-0.97/netboot/tg3.h
--- grub-0.97.old/netboot/tg3.h	1970-01-01 09:00:00.000000000 +0900
+++ grub-0.97/netboot/tg3.h	2006-03-14 12:03:32.000000000 +0900
@@ -0,0 +1,2252 @@
+/* $Id: tg3.h,v 1.3 2003/02/25 06:02:58 ebiederm Exp $
+ * tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2001 Jeff Garzik (jgarzik@mandrakesoft.com)
+ */
+
+#ifndef _T3_H
+#define _T3_H
+
+#if defined(__LITTLE_ENDIAN)
+#define __BIG_ENDIAN 1
+#define __BYTE_ORDER 0
+#endif
+#ifndef VALID_LINK_TIMEOUT
+#define VALID_LINK_TIMEOUT      100 /* 10.0 seconds */
+#endif
+
+#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
+#define PCI_BASE_ADDRESS_MEM_TYPE_64    0x04    /* 64 bit address */
+#ifndef PCI_BASE_ADDRESS_MEM_MASK
+#define PCI_BASE_ADDRESS_MEM_MASK       (~0x0f)
+#endif
+
+#define PCI_STATUS              0x06    /* 16 bits */
+#define  PCI_STATUS_CAP_LIST    0x10    /* Support Capability List */
+#define  PCI_HEADER_TYPE_NORMAL 0
+#define  PCI_HEADER_TYPE_BRIDGE 1
+#define  PCI_HEADER_TYPE_CARDBUS 2
+#define PCI_CAP_LIST_ID         0       /* Capability ID */
+#define PCI_CAP_LIST_NEXT       1       /* Next capability in the list */
+#define PCI_CAPABILITY_LIST     0x34    /* Offset of first capability list entry */
+#define PCI_CB_CAPABILITY_LIST  0x14
+
+#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
+#define PCI_SUBSYSTEM_ID        0x2e
+#define  PCI_COMMAND_PARITY     0x40    /* Enable parity checking */
+#define  PCI_COMMAND_SERR       0x100   /* Enable SERR */
+#define PCI_COMMAND_INVALIDATE          0x10    /* Use memory write and invalidate */
+
+#define PCI_PM_CTRL             4       /* PM control and status register */
+#define  PCI_PM_CTRL_STATE_MASK 0x0003  /* Current power state (D0 to D3) */
+#define  PCI_PM_CTRL_PME_STATUS 0x8000  /* PME pin status */
+
+#define  PCI_CAP_ID_PM          0x01    /* Power Management */
+
+
+typedef unsigned short         uint16_t;
+typedef unsigned char          uint8_t;
+typedef unsigned int           uint32_t;
+typedef unsigned long long int uint64_t;
+
+
+typedef unsigned long dma_addr_t;
+
+/* From mii.h */
+
+/* Indicates what features are advertised by the interface. */
+#define ADVERTISED_10baseT_Half		(1 << 0)
+#define ADVERTISED_10baseT_Full		(1 << 1)
+#define ADVERTISED_100baseT_Half	(1 << 2)
+#define ADVERTISED_100baseT_Full	(1 << 3)
+#define ADVERTISED_1000baseT_Half	(1 << 4)
+#define ADVERTISED_1000baseT_Full	(1 << 5)
+#define ADVERTISED_Autoneg		(1 << 6)
+#define ADVERTISED_TP			(1 << 7)
+#define ADVERTISED_AUI			(1 << 8)
+#define ADVERTISED_MII			(1 << 9)
+#define ADVERTISED_FIBRE		(1 << 10)
+#define ADVERTISED_BNC			(1 << 11)
+
+/* The following are all involved in forcing a particular link
+ * mode for the device for setting things.  When getting the
+ * devices settings, these indicate the current mode and whether
+ * it was foced up into this mode or autonegotiated.
+ */
+
+/* The forced speed, 10Mb, 100Mb, gigabit. */
+#define SPEED_10		0
+#define SPEED_100		1
+#define SPEED_1000		2
+#define SPEED_INVALID           3
+
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF		0x00
+#define DUPLEX_FULL		0x01
+#define DUPLEX_INVALID          0x02
+
+/* Which connector port. */
+#define PORT_TP			0x00
+#define PORT_AUI		0x01
+#define PORT_MII		0x02
+#define PORT_FIBRE		0x03
+#define PORT_BNC		0x04
+
+/* Which tranceiver to use. */
+#define XCVR_INTERNAL		0x00
+#define XCVR_EXTERNAL		0x01
+#define XCVR_DUMMY1		0x02
+#define XCVR_DUMMY2		0x03
+#define XCVR_DUMMY3		0x04
+
+/* Enable or disable autonegotiation.  If this is set to enable,
+ * the forced link modes above are completely ignored.
+ */
+#define AUTONEG_DISABLE		0x00
+#define AUTONEG_ENABLE		0x01
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY		(1 << 0)
+#define WAKE_UCAST		(1 << 1)
+#define WAKE_MCAST		(1 << 2)
+#define WAKE_BCAST		(1 << 3)
+#define WAKE_ARP		(1 << 4)
+#define WAKE_MAGIC		(1 << 5)
+#define WAKE_MAGICSECURE	(1 << 6) /* only meaningful if WAKE_MAGIC */
+
+/* Generic MII registers. */
+
+#define MII_BMCR            0x00        /* Basic mode control register */
+#define MII_BMSR            0x01        /* Basic mode status register  */
+#define MII_PHYSID1         0x02        /* PHYS ID 1                   */
+#define MII_PHYSID2         0x03        /* PHYS ID 2                   */
+#define MII_ADVERTISE       0x04        /* Advertisement control reg   */
+#define MII_LPA             0x05        /* Link partner ability reg    */
+#define MII_EXPANSION       0x06        /* Expansion register          */
+#define MII_DCOUNTER        0x12        /* Disconnect counter          */
+#define MII_FCSCOUNTER      0x13        /* False carrier counter       */
+#define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15        /* Receive error counter       */
+#define MII_SREVISION       0x16        /* Silicon revision            */
+#define MII_RESV1           0x17        /* Reserved...                 */
+#define MII_LBRERROR        0x18        /* Lpback, rx, bypass error    */
+#define MII_PHYADDR         0x19        /* PHY address                 */
+#define MII_RESV2           0x1a        /* Reserved...                 */
+#define MII_TPISTATUS       0x1b        /* TPI status for 10mbps       */
+#define MII_NCONFIG         0x1c        /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV               0x007f  /* Unused...                   */
+#define BMCR_CTST               0x0080  /* Collision test              */
+#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */
+#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */
+#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */
+#define BMCR_RESET              0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP              0x0001  /* Ext-reg capability          */
+#define BMSR_JCD                0x0002  /* Jabber detected             */
+#define BMSR_LSTATUS            0x0004  /* Link status                 */
+#define BMSR_ANEGCAPABLE        0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT             0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE       0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV               0x07c0  /* Unused...                   */
+#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4           0x8000  /* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT          0x001f  /* Selector bits               */
+#define ADVERTISE_CSMA          0x0001  /* Only selector supported     */
+#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */
+#define ADVERTISE_RESV          0x1c00  /* Unused...                   */
+#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */
+#define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */
+#define ADVERTISE_NPAGE         0x8000  /* Next page bit               */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+			ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+                       ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT                0x001f  /* Same as advertise selector  */
+#define LPA_10HALF              0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_10FULL              0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_100HALF             0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_100FULL             0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_100BASE4            0x0200  /* Can do 100mbps 4k packets   */
+#define LPA_RESV                0x1c00  /* Unused...                   */
+#define LPA_RFAULT              0x2000  /* Link partner faulted        */
+#define LPA_LPACK               0x4000  /* Link partner acked us       */
+#define LPA_NPAGE               0x8000  /* Next page bit               */
+
+#define LPA_DUPLEX		(LPA_10FULL | LPA_100FULL)
+#define LPA_100			(LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY          0x0001  /* Can do N-way auto-nego      */
+#define EXPANSION_LCWP          0x0002  /* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words    */
+#define EXPANSION_NPCAPABLE     0x0008  /* Link partner supports npage */
+#define EXPANSION_MFAULTS       0x0010  /* Multiple faults detected    */
+#define EXPANSION_RESV          0xffe0  /* Unused...                   */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1          0x00ff  /* Unused...                   */
+#define NWAYTEST_LOOPBACK       0x0100  /* Enable loopback for N-way   */
+#define NWAYTEST_RESV2          0xfe00  /* Unused...                   */
+
+
+/* From tg3.h */
+
+#define TG3_64BIT_REG_HIGH		0x00UL
+#define TG3_64BIT_REG_LOW		0x04UL
+
+/* Descriptor block info. */
+#define TG3_BDINFO_HOST_ADDR		0x0UL /* 64-bit */
+#define TG3_BDINFO_MAXLEN_FLAGS		0x8UL /* 32-bit */
+#define  BDINFO_FLAGS_USE_EXT_RECV	 0x00000001 /* ext rx_buffer_desc */
+#define  BDINFO_FLAGS_DISABLED		 0x00000002
+#define  BDINFO_FLAGS_MAXLEN_MASK	 0xffff0000
+#define  BDINFO_FLAGS_MAXLEN_SHIFT	 16
+#define TG3_BDINFO_NIC_ADDR		0xcUL /* 32-bit */
+#define TG3_BDINFO_SIZE			0x10UL
+
+#define RX_COPY_THRESHOLD  		256
+
+#define RX_STD_MAX_SIZE			1536
+#define RX_STD_MAX_SIZE_5705		512
+#define RX_JUMBO_MAX_SIZE		0xdeadbeef /* XXX */
+
+/* First 256 bytes are a mirror of PCI config space. */
+#define TG3PCI_VENDOR			0x00000000
+#define  TG3PCI_VENDOR_BROADCOM		 0x14e4
+#define TG3PCI_DEVICE			0x00000002
+#define  TG3PCI_DEVICE_TIGON3_1		 0x1644 /* BCM5700 */
+#define  TG3PCI_DEVICE_TIGON3_2		 0x1645 /* BCM5701 */
+#define  TG3PCI_DEVICE_TIGON3_3		 0x1646 /* BCM5702 */
+#define  TG3PCI_DEVICE_TIGON3_4		 0x1647 /* BCM5703 */
+#define TG3PCI_COMMAND			0x00000004
+#define TG3PCI_STATUS			0x00000006
+#define TG3PCI_CCREVID			0x00000008
+#define TG3PCI_CACHELINESZ		0x0000000c
+#define TG3PCI_LATTIMER			0x0000000d
+#define TG3PCI_HEADERTYPE		0x0000000e
+#define TG3PCI_BIST			0x0000000f
+#define TG3PCI_BASE0_LOW		0x00000010
+#define TG3PCI_BASE0_HIGH		0x00000014
+/* 0x18 --> 0x2c unused */
+#define TG3PCI_SUBSYSVENID		0x0000002c
+#define TG3PCI_SUBSYSID			0x0000002e
+#define TG3PCI_ROMADDR			0x00000030
+#define TG3PCI_CAPLIST			0x00000034
+/* 0x35 --> 0x3c unused */
+#define TG3PCI_IRQ_LINE			0x0000003c
+#define TG3PCI_IRQ_PIN			0x0000003d
+#define TG3PCI_MIN_GNT			0x0000003e
+#define TG3PCI_MAX_LAT			0x0000003f
+#define TG3PCI_X_CAPS			0x00000040
+#define  PCIX_CAPS_RELAXED_ORDERING	 0x00020000
+#define  PCIX_CAPS_SPLIT_MASK		 0x00700000
+#define  PCIX_CAPS_SPLIT_SHIFT		 20
+#define  PCIX_CAPS_BURST_MASK		 0x000c0000
+#define  PCIX_CAPS_BURST_SHIFT		 18
+#define  PCIX_CAPS_MAX_BURST_CPIOB	 2
+#define TG3PCI_PM_CAP_PTR		0x00000041
+#define TG3PCI_X_COMMAND		0x00000042
+#define TG3PCI_X_STATUS			0x00000044
+#define TG3PCI_PM_CAP_ID		0x00000048
+#define TG3PCI_VPD_CAP_PTR		0x00000049
+#define TG3PCI_PM_CAPS			0x0000004a
+#define TG3PCI_PM_CTRL_STAT		0x0000004c
+#define TG3PCI_BR_SUPP_EXT		0x0000004e
+#define TG3PCI_PM_DATA			0x0000004f
+#define TG3PCI_VPD_CAP_ID		0x00000050
+#define TG3PCI_MSI_CAP_PTR		0x00000051
+#define TG3PCI_VPD_ADDR_FLAG		0x00000052
+#define  VPD_ADDR_FLAG_WRITE		0x00008000
+#define TG3PCI_VPD_DATA			0x00000054
+#define TG3PCI_MSI_CAP_ID		0x00000058
+#define TG3PCI_NXT_CAP_PTR		0x00000059
+#define TG3PCI_MSI_CTRL			0x0000005a
+#define TG3PCI_MSI_ADDR_LOW		0x0000005c
+#define TG3PCI_MSI_ADDR_HIGH		0x00000060
+#define TG3PCI_MSI_DATA			0x00000064
+/* 0x66 --> 0x68 unused */
+#define TG3PCI_MISC_HOST_CTRL		0x00000068
+#define  MISC_HOST_CTRL_CLEAR_INT	 0x00000001
+#define  MISC_HOST_CTRL_MASK_PCI_INT	 0x00000002
+#define  MISC_HOST_CTRL_BYTE_SWAP	 0x00000004
+#define  MISC_HOST_CTRL_WORD_SWAP	 0x00000008
+#define  MISC_HOST_CTRL_PCISTATE_RW	 0x00000010
+#define  MISC_HOST_CTRL_CLKREG_RW	 0x00000020
+#define  MISC_HOST_CTRL_REGWORD_SWAP	 0x00000040
+#define  MISC_HOST_CTRL_INDIR_ACCESS	 0x00000080
+#define  MISC_HOST_CTRL_IRQ_MASK_MODE	 0x00000100
+#define  MISC_HOST_CTRL_TAGGED_STATUS	 0x00000200
+#define  MISC_HOST_CTRL_CHIPREV		 0xffff0000
+#define  MISC_HOST_CTRL_CHIPREV_SHIFT	 16
+#define  GET_CHIP_REV_ID(MISC_HOST_CTRL) \
+	 (((MISC_HOST_CTRL) & MISC_HOST_CTRL_CHIPREV) >> \
+	  MISC_HOST_CTRL_CHIPREV_SHIFT)
+#define  CHIPREV_ID_5700_A0		 0x7000
+#define  CHIPREV_ID_5700_A1		 0x7001
+#define  CHIPREV_ID_5700_B0		 0x7100
+#define  CHIPREV_ID_5700_B1		 0x7101
+#define  CHIPREV_ID_5700_B3		 0x7102
+#define  CHIPREV_ID_5700_ALTIMA		 0x7104
+#define  CHIPREV_ID_5700_C0		 0x7200
+#define  CHIPREV_ID_5701_A0		 0x0000
+#define  CHIPREV_ID_5701_B0		 0x0100
+#define  CHIPREV_ID_5701_B2		 0x0102
+#define  CHIPREV_ID_5701_B5		 0x0105
+#define  CHIPREV_ID_5703_A0		 0x1000
+#define  CHIPREV_ID_5703_A1		 0x1001
+#define  CHIPREV_ID_5703_A2		 0x1002
+#define  CHIPREV_ID_5703_A3		 0x1003
+#define  CHIPREV_ID_5704_A0		 0x2000
+#define  CHIPREV_ID_5704_A1		 0x2001
+#define  CHIPREV_ID_5704_A2		 0x2002
+#define  CHIPREV_ID_5705_A0		 0x3000
+#define  CHIPREV_ID_5705_A1		 0x3001
+#define	 CHIPREV_ID_5705_A2              0x3002
+#define  CHIPREV_ID_5705_A3              0x3003
+#define  CHIPREV_ID_5750_A0              0x4000
+#define  CHIPREV_ID_5750_A1              0x4001
+#define  CHIPREV_ID_5750_A3              0x4003
+#define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
+#define   ASIC_REV_5700			 0x07
+#define   ASIC_REV_5701			 0x00
+#define   ASIC_REV_5703			 0x01
+#define   ASIC_REV_5704			 0x02
+#define   ASIC_REV_5705			 0x03
+#define   ASIC_REV_5750			 0x04
+#define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
+#define   CHIPREV_5700_AX		 0x70
+#define   CHIPREV_5700_BX		 0x71
+#define   CHIPREV_5700_CX		 0x72
+#define   CHIPREV_5701_AX		 0x00
+#define  GET_METAL_REV(CHIP_REV_ID)	((CHIP_REV_ID) & 0xff)
+#define   METAL_REV_A0			 0x00
+#define   METAL_REV_A1			 0x01
+#define   METAL_REV_B0			 0x00
+#define   METAL_REV_B1			 0x01
+#define   METAL_REV_B2			 0x02
+#define TG3PCI_DMA_RW_CTRL		0x0000006c
+#define  DMA_RWCTRL_MIN_DMA		 0x000000ff
+#define  DMA_RWCTRL_MIN_DMA_SHIFT	 0
+#define  DMA_RWCTRL_READ_BNDRY_MASK	 0x00000700
+#define  DMA_RWCTRL_READ_BNDRY_DISAB	 0x00000000
+#define  DMA_RWCTRL_READ_BNDRY_16	 0x00000100
+#define  DMA_RWCTRL_READ_BNDRY_32	 0x00000200
+#define  DMA_RWCTRL_READ_BNDRY_64	 0x00000300
+#define  DMA_RWCTRL_READ_BNDRY_128	 0x00000400
+#define  DMA_RWCTRL_READ_BNDRY_256	 0x00000500
+#define  DMA_RWCTRL_READ_BNDRY_512	 0x00000600
+#define  DMA_RWCTRL_READ_BNDRY_1024	 0x00000700
+#define  DMA_RWCTRL_WRITE_BNDRY_MASK	 0x00003800
+#define  DMA_RWCTRL_WRITE_BNDRY_DISAB	 0x00000000
+#define  DMA_RWCTRL_WRITE_BNDRY_16	 0x00000800
+#define  DMA_RWCTRL_WRITE_BNDRY_32	 0x00001000
+#define  DMA_RWCTRL_WRITE_BNDRY_64	 0x00001800
+#define  DMA_RWCTRL_WRITE_BNDRY_128	 0x00002000
+#define  DMA_RWCTRL_WRITE_BNDRY_256	 0x00002800
+#define  DMA_RWCTRL_WRITE_BNDRY_512	 0x00003000
+#define  DMA_RWCTRL_WRITE_BNDRY_1024	 0x00003800
+#define  DMA_RWCTRL_ONE_DMA		 0x00004000
+#define  DMA_RWCTRL_READ_WATER		 0x00070000
+#define  DMA_RWCTRL_READ_WATER_SHIFT	 16
+#define  DMA_RWCTRL_WRITE_WATER		 0x00380000
+#define  DMA_RWCTRL_WRITE_WATER_SHIFT	 19
+#define  DMA_RWCTRL_USE_MEM_READ_MULT	 0x00400000
+#define  DMA_RWCTRL_ASSERT_ALL_BE	 0x00800000
+#define  DMA_RWCTRL_PCI_READ_CMD	 0x0f000000
+#define  DMA_RWCTRL_PCI_READ_CMD_SHIFT	 24
+#define  DMA_RWCTRL_PCI_WRITE_CMD	 0xf0000000
+#define  DMA_RWCTRL_PCI_WRITE_CMD_SHIFT	 28
+#define TG3PCI_PCISTATE			0x00000070
+#define  PCISTATE_FORCE_RESET		 0x00000001
+#define  PCISTATE_INT_NOT_ACTIVE	 0x00000002
+#define  PCISTATE_CONV_PCI_MODE		 0x00000004
+#define  PCISTATE_BUS_SPEED_HIGH	 0x00000008
+#define  PCISTATE_BUS_32BIT		 0x00000010
+#define  PCISTATE_ROM_ENABLE		 0x00000020
+#define  PCISTATE_ROM_RETRY_ENABLE	 0x00000040
+#define  PCISTATE_FLAT_VIEW		 0x00000100
+#define  PCISTATE_RETRY_SAME_DMA	 0x00002000
+#define TG3PCI_CLOCK_CTRL		0x00000074
+#define  CLOCK_CTRL_CORECLK_DISABLE	 0x00000200
+#define  CLOCK_CTRL_RXCLK_DISABLE	 0x00000400
+#define  CLOCK_CTRL_TXCLK_DISABLE	 0x00000800
+#define  CLOCK_CTRL_ALTCLK		 0x00001000
+#define  CLOCK_CTRL_PWRDOWN_PLL133	 0x00008000
+#define  CLOCK_CTRL_44MHZ_CORE		 0x00040000
+#define  CLOCK_CTRL_625_CORE		 0x00100000
+#define  CLOCK_CTRL_FORCE_CLKRUN	 0x00200000
+#define  CLOCK_CTRL_CLKRUN_OENABLE	 0x00400000
+#define  CLOCK_CTRL_DELAY_PCI_GRANT	 0x80000000
+#define TG3PCI_REG_BASE_ADDR		0x00000078
+#define TG3PCI_MEM_WIN_BASE_ADDR	0x0000007c
+#define TG3PCI_REG_DATA			0x00000080
+#define TG3PCI_MEM_WIN_DATA		0x00000084
+#define TG3PCI_MODE_CTRL		0x00000088
+#define TG3PCI_MISC_CFG			0x0000008c
+#define TG3PCI_MISC_LOCAL_CTRL		0x00000090
+/* 0x94 --> 0x98 unused */
+#define TG3PCI_STD_RING_PROD_IDX	0x00000098 /* 64-bit */
+#define TG3PCI_RCV_RET_RING_CON_IDX	0x000000a0 /* 64-bit */
+#define TG3PCI_SND_PROD_IDX		0x000000a8 /* 64-bit */
+/* 0xb0 --> 0x100 unused */
+
+/* 0x100 --> 0x200 unused */
+
+/* Mailbox registers */
+#define MAILBOX_INTERRUPT_0		0x00000200 /* 64-bit */
+#define MAILBOX_INTERRUPT_1		0x00000208 /* 64-bit */
+#define MAILBOX_INTERRUPT_2		0x00000210 /* 64-bit */
+#define MAILBOX_INTERRUPT_3		0x00000218 /* 64-bit */
+#define MAILBOX_GENERAL_0		0x00000220 /* 64-bit */
+#define MAILBOX_GENERAL_1		0x00000228 /* 64-bit */
+#define MAILBOX_GENERAL_2		0x00000230 /* 64-bit */
+#define MAILBOX_GENERAL_3		0x00000238 /* 64-bit */
+#define MAILBOX_GENERAL_4		0x00000240 /* 64-bit */
+#define MAILBOX_GENERAL_5		0x00000248 /* 64-bit */
+#define MAILBOX_GENERAL_6		0x00000250 /* 64-bit */
+#define MAILBOX_GENERAL_7		0x00000258 /* 64-bit */
+#define MAILBOX_RELOAD_STAT		0x00000260 /* 64-bit */
+#define MAILBOX_RCV_STD_PROD_IDX	0x00000268 /* 64-bit */
+#define MAILBOX_RCV_JUMBO_PROD_IDX	0x00000270 /* 64-bit */
+#define MAILBOX_RCV_MINI_PROD_IDX	0x00000278 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_0	0x00000280 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_1	0x00000288 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_2	0x00000290 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_3	0x00000298 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_4	0x000002a0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_5	0x000002a8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_6	0x000002b0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_7	0x000002b8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_8	0x000002c0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_9	0x000002c8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_10	0x000002d0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_11	0x000002d8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_12	0x000002e0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_13	0x000002e8 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_14	0x000002f0 /* 64-bit */
+#define MAILBOX_RCVRET_CON_IDX_15	0x000002f8 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_0	0x00000300 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_1	0x00000308 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_2	0x00000310 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_3	0x00000318 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_4	0x00000320 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_5	0x00000328 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_6	0x00000330 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_7	0x00000338 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_8	0x00000340 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_9	0x00000348 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_10	0x00000350 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_11	0x00000358 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_12	0x00000360 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_13	0x00000368 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_14	0x00000370 /* 64-bit */
+#define MAILBOX_SNDHOST_PROD_IDX_15	0x00000378 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_0	0x00000380 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_1	0x00000388 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_2	0x00000390 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_3	0x00000398 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_4	0x000003a0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_5	0x000003a8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_6	0x000003b0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_7	0x000003b8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_8	0x000003c0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_9	0x000003c8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_10	0x000003d0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_11	0x000003d8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_12	0x000003e0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_13	0x000003e8 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_14	0x000003f0 /* 64-bit */
+#define MAILBOX_SNDNIC_PROD_IDX_15	0x000003f8 /* 64-bit */
+
+/* MAC control registers */
+#define MAC_MODE			0x00000400
+#define  MAC_MODE_RESET			 0x00000001
+#define  MAC_MODE_HALF_DUPLEX		 0x00000002
+#define  MAC_MODE_PORT_MODE_MASK	 0x0000000c
+#define  MAC_MODE_PORT_MODE_TBI		 0x0000000c
+#define  MAC_MODE_PORT_MODE_GMII	 0x00000008
+#define  MAC_MODE_PORT_MODE_MII		 0x00000004
+#define  MAC_MODE_PORT_MODE_NONE	 0x00000000
+#define  MAC_MODE_PORT_INT_LPBACK	 0x00000010
+#define  MAC_MODE_TAGGED_MAC_CTRL	 0x00000080
+#define  MAC_MODE_TX_BURSTING		 0x00000100
+#define  MAC_MODE_MAX_DEFER		 0x00000200
+#define  MAC_MODE_LINK_POLARITY		 0x00000400
+#define  MAC_MODE_RXSTAT_ENABLE		 0x00000800
+#define  MAC_MODE_RXSTAT_CLEAR		 0x00001000
+#define  MAC_MODE_RXSTAT_FLUSH		 0x00002000
+#define  MAC_MODE_TXSTAT_ENABLE		 0x00004000
+#define  MAC_MODE_TXSTAT_CLEAR		 0x00008000
+#define  MAC_MODE_TXSTAT_FLUSH		 0x00010000
+#define  MAC_MODE_SEND_CONFIGS		 0x00020000
+#define  MAC_MODE_MAGIC_PKT_ENABLE	 0x00040000
+#define  MAC_MODE_ACPI_ENABLE		 0x00080000
+#define  MAC_MODE_MIP_ENABLE		 0x00100000
+#define  MAC_MODE_TDE_ENABLE		 0x00200000
+#define  MAC_MODE_RDE_ENABLE		 0x00400000
+#define  MAC_MODE_FHDE_ENABLE		 0x00800000
+#define MAC_STATUS			0x00000404
+#define  MAC_STATUS_PCS_SYNCED		 0x00000001
+#define  MAC_STATUS_SIGNAL_DET		 0x00000002
+#define  MAC_STATUS_RCVD_CFG		 0x00000004
+#define  MAC_STATUS_CFG_CHANGED		 0x00000008
+#define  MAC_STATUS_SYNC_CHANGED	 0x00000010
+#define  MAC_STATUS_PORT_DEC_ERR	 0x00000400
+#define  MAC_STATUS_LNKSTATE_CHANGED	 0x00001000
+#define  MAC_STATUS_MI_COMPLETION	 0x00400000
+#define  MAC_STATUS_MI_INTERRUPT	 0x00800000
+#define  MAC_STATUS_AP_ERROR		 0x01000000
+#define  MAC_STATUS_ODI_ERROR		 0x02000000
+#define  MAC_STATUS_RXSTAT_OVERRUN	 0x04000000
+#define  MAC_STATUS_TXSTAT_OVERRUN	 0x08000000
+#define MAC_EVENT			0x00000408
+#define  MAC_EVENT_PORT_DECODE_ERR	 0x00000400
+#define  MAC_EVENT_LNKSTATE_CHANGED	 0x00001000
+#define  MAC_EVENT_MI_COMPLETION	 0x00400000
+#define  MAC_EVENT_MI_INTERRUPT		 0x00800000
+#define  MAC_EVENT_AP_ERROR		 0x01000000
+#define  MAC_EVENT_ODI_ERROR		 0x02000000
+#define  MAC_EVENT_RXSTAT_OVERRUN	 0x04000000
+#define  MAC_EVENT_TXSTAT_OVERRUN	 0x08000000
+#define MAC_LED_CTRL			0x0000040c
+#define  LED_CTRL_LNKLED_OVERRIDE	 0x00000001
+#define  LED_CTRL_1000MBPS_ON		 0x00000002
+#define  LED_CTRL_100MBPS_ON		 0x00000004
+#define  LED_CTRL_10MBPS_ON		 0x00000008
+#define  LED_CTRL_TRAFFIC_OVERRIDE	 0x00000010
+#define  LED_CTRL_TRAFFIC_BLINK		 0x00000020
+#define  LED_CTRL_TRAFFIC_LED		 0x00000040
+#define  LED_CTRL_1000MBPS_STATUS	 0x00000080
+#define  LED_CTRL_100MBPS_STATUS	 0x00000100
+#define  LED_CTRL_10MBPS_STATUS		 0x00000200
+#define  LED_CTRL_TRAFFIC_STATUS	 0x00000400
+#define  LED_CTRL_MAC_MODE		 0x00000000
+#define  LED_CTRL_PHY_MODE_1		 0x00000800
+#define  LED_CTRL_PHY_MODE_2		 0x00001000
+#define  LED_CTRL_BLINK_RATE_MASK	 0x7ff80000
+#define  LED_CTRL_BLINK_RATE_SHIFT	 19
+#define  LED_CTRL_BLINK_PER_OVERRIDE	 0x00080000
+#define  LED_CTRL_BLINK_RATE_OVERRIDE	 0x80000000
+#define MAC_ADDR_0_HIGH			0x00000410 /* upper 2 bytes */
+#define MAC_ADDR_0_LOW			0x00000414 /* lower 4 bytes */
+#define MAC_ADDR_1_HIGH			0x00000418 /* upper 2 bytes */
+#define MAC_ADDR_1_LOW			0x0000041c /* lower 4 bytes */
+#define MAC_ADDR_2_HIGH			0x00000420 /* upper 2 bytes */
+#define MAC_ADDR_2_LOW			0x00000424 /* lower 4 bytes */
+#define MAC_ADDR_3_HIGH			0x00000428 /* upper 2 bytes */
+#define MAC_ADDR_3_LOW			0x0000042c /* lower 4 bytes */
+#define MAC_ACPI_MBUF_PTR		0x00000430
+#define MAC_ACPI_LEN_OFFSET		0x00000434
+#define  ACPI_LENOFF_LEN_MASK		 0x0000ffff
+#define  ACPI_LENOFF_LEN_SHIFT		 0
+#define  ACPI_LENOFF_OFF_MASK		 0x0fff0000
+#define  ACPI_LENOFF_OFF_SHIFT		 16
+#define MAC_TX_BACKOFF_SEED		0x00000438
+#define  TX_BACKOFF_SEED_MASK		 0x000003ff
+#define MAC_RX_MTU_SIZE			0x0000043c
+#define  RX_MTU_SIZE_MASK		 0x0000ffff
+#define MAC_PCS_TEST			0x00000440
+#define  PCS_TEST_PATTERN_MASK		 0x000fffff
+#define  PCS_TEST_PATTERN_SHIFT		 0
+#define  PCS_TEST_ENABLE		 0x00100000
+#define MAC_TX_AUTO_NEG			0x00000444
+#define  TX_AUTO_NEG_MASK		 0x0000ffff
+#define  TX_AUTO_NEG_SHIFT		 0
+#define MAC_RX_AUTO_NEG			0x00000448
+#define  RX_AUTO_NEG_MASK		 0x0000ffff
+#define  RX_AUTO_NEG_SHIFT		 0
+#define MAC_MI_COM			0x0000044c
+#define  MI_COM_CMD_MASK		 0x0c000000
+#define  MI_COM_CMD_WRITE		 0x04000000
+#define  MI_COM_CMD_READ		 0x08000000
+#define  MI_COM_READ_FAILED		 0x10000000
+#define  MI_COM_START			 0x20000000
+#define  MI_COM_BUSY			 0x20000000
+#define  MI_COM_PHY_ADDR_MASK		 0x03e00000
+#define  MI_COM_PHY_ADDR_SHIFT		 21
+#define  MI_COM_REG_ADDR_MASK		 0x001f0000
+#define  MI_COM_REG_ADDR_SHIFT		 16
+#define  MI_COM_DATA_MASK		 0x0000ffff
+#define MAC_MI_STAT			0x00000450
+#define  MAC_MI_STAT_LNKSTAT_ATTN_ENAB	 0x00000001
+#define MAC_MI_MODE			0x00000454
+#define  MAC_MI_MODE_CLK_10MHZ		 0x00000001
+#define  MAC_MI_MODE_SHORT_PREAMBLE	 0x00000002
+#define  MAC_MI_MODE_AUTO_POLL		 0x00000010
+#define  MAC_MI_MODE_CORE_CLK_62MHZ	 0x00008000
+#define  MAC_MI_MODE_BASE		 0x000c0000 /* XXX magic values XXX */
+#define MAC_AUTO_POLL_STATUS		0x00000458
+#define  MAC_AUTO_POLL_ERROR		 0x00000001
+#define MAC_TX_MODE			0x0000045c
+#define  TX_MODE_RESET			 0x00000001
+#define  TX_MODE_ENABLE			 0x00000002
+#define  TX_MODE_FLOW_CTRL_ENABLE	 0x00000010
+#define  TX_MODE_BIG_BCKOFF_ENABLE	 0x00000020
+#define  TX_MODE_LONG_PAUSE_ENABLE	 0x00000040
+#define MAC_TX_STATUS			0x00000460
+#define  TX_STATUS_XOFFED		 0x00000001
+#define  TX_STATUS_SENT_XOFF		 0x00000002
+#define  TX_STATUS_SENT_XON		 0x00000004
+#define  TX_STATUS_LINK_UP		 0x00000008
+#define  TX_STATUS_ODI_UNDERRUN		 0x00000010
+#define  TX_STATUS_ODI_OVERRUN		 0x00000020
+#define MAC_TX_LENGTHS			0x00000464
+#define  TX_LENGTHS_SLOT_TIME_MASK	 0x000000ff
+#define  TX_LENGTHS_SLOT_TIME_SHIFT	 0
+#define  TX_LENGTHS_IPG_MASK		 0x00000f00
+#define  TX_LENGTHS_IPG_SHIFT		 8
+#define  TX_LENGTHS_IPG_CRS_MASK	 0x00003000
+#define  TX_LENGTHS_IPG_CRS_SHIFT	 12
+#define MAC_RX_MODE			0x00000468
+#define  RX_MODE_RESET			 0x00000001
+#define  RX_MODE_ENABLE			 0x00000002
+#define  RX_MODE_FLOW_CTRL_ENABLE	 0x00000004
+#define  RX_MODE_KEEP_MAC_CTRL		 0x00000008
+#define  RX_MODE_KEEP_PAUSE		 0x00000010
+#define  RX_MODE_ACCEPT_OVERSIZED	 0x00000020
+#define  RX_MODE_ACCEPT_RUNTS		 0x00000040
+#define  RX_MODE_LEN_CHECK		 0x00000080
+#define  RX_MODE_PROMISC		 0x00000100
+#define  RX_MODE_NO_CRC_CHECK		 0x00000200
+#define  RX_MODE_KEEP_VLAN_TAG		 0x00000400
+#define MAC_RX_STATUS			0x0000046c
+#define  RX_STATUS_REMOTE_TX_XOFFED	 0x00000001
+#define  RX_STATUS_XOFF_RCVD		 0x00000002
+#define  RX_STATUS_XON_RCVD		 0x00000004
+#define MAC_HASH_REG_0			0x00000470
+#define MAC_HASH_REG_1			0x00000474
+#define MAC_HASH_REG_2			0x00000478
+#define MAC_HASH_REG_3			0x0000047c
+#define MAC_RCV_RULE_0			0x00000480
+#define MAC_RCV_VALUE_0			0x00000484
+#define MAC_RCV_RULE_1			0x00000488
+#define MAC_RCV_VALUE_1			0x0000048c
+#define MAC_RCV_RULE_2			0x00000490
+#define MAC_RCV_VALUE_2			0x00000494
+#define MAC_RCV_RULE_3			0x00000498
+#define MAC_RCV_VALUE_3			0x0000049c
+#define MAC_RCV_RULE_4			0x000004a0
+#define MAC_RCV_VALUE_4			0x000004a4
+#define MAC_RCV_RULE_5			0x000004a8
+#define MAC_RCV_VALUE_5			0x000004ac
+#define MAC_RCV_RULE_6			0x000004b0
+#define MAC_RCV_VALUE_6			0x000004b4
+#define MAC_RCV_RULE_7			0x000004b8
+#define MAC_RCV_VALUE_7			0x000004bc
+#define MAC_RCV_RULE_8			0x000004c0
+#define MAC_RCV_VALUE_8			0x000004c4
+#define MAC_RCV_RULE_9			0x000004c8
+#define MAC_RCV_VALUE_9			0x000004cc
+#define MAC_RCV_RULE_10			0x000004d0
+#define MAC_RCV_VALUE_10		0x000004d4
+#define MAC_RCV_RULE_11			0x000004d8
+#define MAC_RCV_VALUE_11		0x000004dc
+#define MAC_RCV_RULE_12			0x000004e0
+#define MAC_RCV_VALUE_12		0x000004e4
+#define MAC_RCV_RULE_13			0x000004e8
+#define MAC_RCV_VALUE_13		0x000004ec
+#define MAC_RCV_RULE_14			0x000004f0
+#define MAC_RCV_VALUE_14		0x000004f4
+#define MAC_RCV_RULE_15			0x000004f8
+#define MAC_RCV_VALUE_15		0x000004fc
+#define  RCV_RULE_DISABLE_MASK		 0x7fffffff
+#define MAC_RCV_RULE_CFG		0x00000500
+#define  RCV_RULE_CFG_DEFAULT_CLASS	0x00000008
+#define MAC_LOW_WMARK_MAX_RX_FRAME	0x00000504
+/* 0x508 --> 0x520 unused */
+#define MAC_HASHREGU_0			0x00000520
+#define MAC_HASHREGU_1			0x00000524
+#define MAC_HASHREGU_2			0x00000528
+#define MAC_HASHREGU_3			0x0000052c
+#define MAC_EXTADDR_0_HIGH		0x00000530
+#define MAC_EXTADDR_0_LOW		0x00000534
+#define MAC_EXTADDR_1_HIGH		0x00000538
+#define MAC_EXTADDR_1_LOW		0x0000053c
+#define MAC_EXTADDR_2_HIGH		0x00000540
+#define MAC_EXTADDR_2_LOW		0x00000544
+#define MAC_EXTADDR_3_HIGH		0x00000548
+#define MAC_EXTADDR_3_LOW		0x0000054c
+#define MAC_EXTADDR_4_HIGH		0x00000550
+#define MAC_EXTADDR_4_LOW		0x00000554
+#define MAC_EXTADDR_5_HIGH		0x00000558
+#define MAC_EXTADDR_5_LOW		0x0000055c
+#define MAC_EXTADDR_6_HIGH		0x00000560
+#define MAC_EXTADDR_6_LOW		0x00000564
+#define MAC_EXTADDR_7_HIGH		0x00000568
+#define MAC_EXTADDR_7_LOW		0x0000056c
+#define MAC_EXTADDR_8_HIGH		0x00000570
+#define MAC_EXTADDR_8_LOW		0x00000574
+#define MAC_EXTADDR_9_HIGH		0x00000578
+#define MAC_EXTADDR_9_LOW		0x0000057c
+#define MAC_EXTADDR_10_HIGH		0x00000580
+#define MAC_EXTADDR_10_LOW		0x00000584
+#define MAC_EXTADDR_11_HIGH		0x00000588
+#define MAC_EXTADDR_11_LOW		0x0000058c
+#define MAC_SERDES_CFG			0x00000590
+#define MAC_SERDES_STAT			0x00000594
+/* 0x598 --> 0x600 unused */
+#define MAC_TX_MAC_STATE_BASE		0x00000600 /* 16 bytes */
+#define MAC_RX_MAC_STATE_BASE		0x00000610 /* 20 bytes */
+/* 0x624 --> 0x800 unused */
+#define MAC_TX_STATS_OCTETS		0x00000800
+#define MAC_TX_STATS_RESV1		0x00000804
+#define MAC_TX_STATS_COLLISIONS		0x00000808
+#define MAC_TX_STATS_XON_SENT		0x0000080c
+#define MAC_TX_STATS_XOFF_SENT		0x00000810
+#define MAC_TX_STATS_RESV2		0x00000814
+#define MAC_TX_STATS_MAC_ERRORS		0x00000818
+#define MAC_TX_STATS_SINGLE_COLLISIONS	0x0000081c
+#define MAC_TX_STATS_MULT_COLLISIONS	0x00000820
+#define MAC_TX_STATS_DEFERRED		0x00000824
+#define MAC_TX_STATS_RESV3		0x00000828
+#define MAC_TX_STATS_EXCESSIVE_COL	0x0000082c
+#define MAC_TX_STATS_LATE_COL		0x00000830
+#define MAC_TX_STATS_RESV4_1		0x00000834
+#define MAC_TX_STATS_RESV4_2		0x00000838
+#define MAC_TX_STATS_RESV4_3		0x0000083c
+#define MAC_TX_STATS_RESV4_4		0x00000840
+#define MAC_TX_STATS_RESV4_5		0x00000844
+#define MAC_TX_STATS_RESV4_6		0x00000848
+#define MAC_TX_STATS_RESV4_7		0x0000084c
+#define MAC_TX_STATS_RESV4_8		0x00000850
+#define MAC_TX_STATS_RESV4_9		0x00000854
+#define MAC_TX_STATS_RESV4_10		0x00000858
+#define MAC_TX_STATS_RESV4_11		0x0000085c
+#define MAC_TX_STATS_RESV4_12		0x00000860
+#define MAC_TX_STATS_RESV4_13		0x00000864
+#define MAC_TX_STATS_RESV4_14		0x00000868
+#define MAC_TX_STATS_UCAST		0x0000086c
+#define MAC_TX_STATS_MCAST		0x00000870
+#define MAC_TX_STATS_BCAST		0x00000874
+#define MAC_TX_STATS_RESV5_1		0x00000878
+#define MAC_TX_STATS_RESV5_2		0x0000087c
+#define MAC_RX_STATS_OCTETS		0x00000880
+#define MAC_RX_STATS_RESV1		0x00000884
+#define MAC_RX_STATS_FRAGMENTS		0x00000888
+#define MAC_RX_STATS_UCAST		0x0000088c
+#define MAC_RX_STATS_MCAST		0x00000890
+#define MAC_RX_STATS_BCAST		0x00000894
+#define MAC_RX_STATS_FCS_ERRORS		0x00000898
+#define MAC_RX_STATS_ALIGN_ERRORS	0x0000089c
+#define MAC_RX_STATS_XON_PAUSE_RECVD	0x000008a0
+#define MAC_RX_STATS_XOFF_PAUSE_RECVD	0x000008a4
+#define MAC_RX_STATS_MAC_CTRL_RECVD	0x000008a8
+#define MAC_RX_STATS_XOFF_ENTERED	0x000008ac
+#define MAC_RX_STATS_FRAME_TOO_LONG	0x000008b0
+#define MAC_RX_STATS_JABBERS		0x000008b4
+#define MAC_RX_STATS_UNDERSIZE		0x000008b8
+/* 0x8bc --> 0xc00 unused */
+
+/* Send data initiator control registers */
+#define SNDDATAI_MODE			0x00000c00
+#define  SNDDATAI_MODE_RESET		 0x00000001
+#define  SNDDATAI_MODE_ENABLE		 0x00000002
+#define  SNDDATAI_MODE_STAT_OFLOW_ENAB	 0x00000004
+#define SNDDATAI_STATUS			0x00000c04
+#define  SNDDATAI_STATUS_STAT_OFLOW	 0x00000004
+#define SNDDATAI_STATSCTRL		0x00000c08
+#define  SNDDATAI_SCTRL_ENABLE		 0x00000001
+#define  SNDDATAI_SCTRL_FASTUPD		 0x00000002
+#define  SNDDATAI_SCTRL_CLEAR		 0x00000004
+#define  SNDDATAI_SCTRL_FLUSH		 0x00000008
+#define  SNDDATAI_SCTRL_FORCE_ZERO	 0x00000010
+#define SNDDATAI_STATSENAB		0x00000c0c
+#define SNDDATAI_STATSINCMASK		0x00000c10
+/* 0xc14 --> 0xc80 unused */
+#define SNDDATAI_COS_CNT_0		0x00000c80
+#define SNDDATAI_COS_CNT_1		0x00000c84
+#define SNDDATAI_COS_CNT_2		0x00000c88
+#define SNDDATAI_COS_CNT_3		0x00000c8c
+#define SNDDATAI_COS_CNT_4		0x00000c90
+#define SNDDATAI_COS_CNT_5		0x00000c94
+#define SNDDATAI_COS_CNT_6		0x00000c98
+#define SNDDATAI_COS_CNT_7		0x00000c9c
+#define SNDDATAI_COS_CNT_8		0x00000ca0
+#define SNDDATAI_COS_CNT_9		0x00000ca4
+#define SNDDATAI_COS_CNT_10		0x00000ca8
+#define SNDDATAI_COS_CNT_11		0x00000cac
+#define SNDDATAI_COS_CNT_12		0x00000cb0
+#define SNDDATAI_COS_CNT_13		0x00000cb4
+#define SNDDATAI_COS_CNT_14		0x00000cb8
+#define SNDDATAI_COS_CNT_15		0x00000cbc
+#define SNDDATAI_DMA_RDQ_FULL_CNT	0x00000cc0
+#define SNDDATAI_DMA_PRIO_RDQ_FULL_CNT	0x00000cc4
+#define SNDDATAI_SDCQ_FULL_CNT		0x00000cc8
+#define SNDDATAI_NICRNG_SSND_PIDX_CNT	0x00000ccc
+#define SNDDATAI_STATS_UPDATED_CNT	0x00000cd0
+#define SNDDATAI_INTERRUPTS_CNT		0x00000cd4
+#define SNDDATAI_AVOID_INTERRUPTS_CNT	0x00000cd8
+#define SNDDATAI_SND_THRESH_HIT_CNT	0x00000cdc
+/* 0xce0 --> 0x1000 unused */
+
+/* Send data completion control registers */
+#define SNDDATAC_MODE			0x00001000
+#define  SNDDATAC_MODE_RESET		 0x00000001
+#define  SNDDATAC_MODE_ENABLE		 0x00000002
+/* 0x1004 --> 0x1400 unused */
+
+/* Send BD ring selector */
+#define SNDBDS_MODE			0x00001400
+#define  SNDBDS_MODE_RESET		 0x00000001
+#define  SNDBDS_MODE_ENABLE		 0x00000002
+#define  SNDBDS_MODE_ATTN_ENABLE	 0x00000004
+#define SNDBDS_STATUS			0x00001404
+#define  SNDBDS_STATUS_ERROR_ATTN	 0x00000004
+#define SNDBDS_HWDIAG			0x00001408
+/* 0x140c --> 0x1440 */
+#define SNDBDS_SEL_CON_IDX_0		0x00001440
+#define SNDBDS_SEL_CON_IDX_1		0x00001444
+#define SNDBDS_SEL_CON_IDX_2		0x00001448
+#define SNDBDS_SEL_CON_IDX_3		0x0000144c
+#define SNDBDS_SEL_CON_IDX_4		0x00001450
+#define SNDBDS_SEL_CON_IDX_5		0x00001454
+#define SNDBDS_SEL_CON_IDX_6		0x00001458
+#define SNDBDS_SEL_CON_IDX_7		0x0000145c
+#define SNDBDS_SEL_CON_IDX_8		0x00001460
+#define SNDBDS_SEL_CON_IDX_9		0x00001464
+#define SNDBDS_SEL_CON_IDX_10		0x00001468
+#define SNDBDS_SEL_CON_IDX_11		0x0000146c
+#define SNDBDS_SEL_CON_IDX_12		0x00001470
+#define SNDBDS_SEL_CON_IDX_13		0x00001474
+#define SNDBDS_SEL_CON_IDX_14		0x00001478
+#define SNDBDS_SEL_CON_IDX_15		0x0000147c
+/* 0x1480 --> 0x1800 unused */
+
+/* Send BD initiator control registers */
+#define SNDBDI_MODE			0x00001800
+#define  SNDBDI_MODE_RESET		 0x00000001
+#define  SNDBDI_MODE_ENABLE		 0x00000002
+#define  SNDBDI_MODE_ATTN_ENABLE	 0x00000004
+#define SNDBDI_STATUS			0x00001804
+#define  SNDBDI_STATUS_ERROR_ATTN	 0x00000004
+#define SNDBDI_IN_PROD_IDX_0		0x00001808
+#define SNDBDI_IN_PROD_IDX_1		0x0000180c
+#define SNDBDI_IN_PROD_IDX_2		0x00001810
+#define SNDBDI_IN_PROD_IDX_3		0x00001814
+#define SNDBDI_IN_PROD_IDX_4		0x00001818
+#define SNDBDI_IN_PROD_IDX_5		0x0000181c
+#define SNDBDI_IN_PROD_IDX_6		0x00001820
+#define SNDBDI_IN_PROD_IDX_7		0x00001824
+#define SNDBDI_IN_PROD_IDX_8		0x00001828
+#define SNDBDI_IN_PROD_IDX_9		0x0000182c
+#define SNDBDI_IN_PROD_IDX_10		0x00001830
+#define SNDBDI_IN_PROD_IDX_11		0x00001834
+#define SNDBDI_IN_PROD_IDX_12		0x00001838
+#define SNDBDI_IN_PROD_IDX_13		0x0000183c
+#define SNDBDI_IN_PROD_IDX_14		0x00001840
+#define SNDBDI_IN_PROD_IDX_15		0x00001844
+/* 0x1848 --> 0x1c00 unused */
+
+/* Send BD completion control registers */
+#define SNDBDC_MODE			0x00001c00
+#define SNDBDC_MODE_RESET		 0x00000001
+#define SNDBDC_MODE_ENABLE		 0x00000002
+#define SNDBDC_MODE_ATTN_ENABLE		 0x00000004
+/* 0x1c04 --> 0x2000 unused */
+
+/* Receive list placement control registers */
+#define RCVLPC_MODE			0x00002000
+#define  RCVLPC_MODE_RESET		 0x00000001
+#define  RCVLPC_MODE_ENABLE		 0x00000002
+#define  RCVLPC_MODE_CLASS0_ATTN_ENAB	 0x00000004
+#define  RCVLPC_MODE_MAPOOR_AATTN_ENAB	 0x00000008
+#define  RCVLPC_MODE_STAT_OFLOW_ENAB	 0x00000010
+#define RCVLPC_STATUS			0x00002004
+#define  RCVLPC_STATUS_CLASS0		 0x00000004
+#define  RCVLPC_STATUS_MAPOOR		 0x00000008
+#define  RCVLPC_STATUS_STAT_OFLOW	 0x00000010
+#define RCVLPC_LOCK			0x00002008
+#define  RCVLPC_LOCK_REQ_MASK		 0x0000ffff
+#define  RCVLPC_LOCK_REQ_SHIFT		 0
+#define  RCVLPC_LOCK_GRANT_MASK		 0xffff0000
+#define  RCVLPC_LOCK_GRANT_SHIFT	 16
+#define RCVLPC_NON_EMPTY_BITS		0x0000200c
+#define  RCVLPC_NON_EMPTY_BITS_MASK	 0x0000ffff
+#define RCVLPC_CONFIG			0x00002010
+#define RCVLPC_STATSCTRL		0x00002014
+#define  RCVLPC_STATSCTRL_ENABLE	 0x00000001
+#define  RCVLPC_STATSCTRL_FASTUPD	 0x00000002
+#define RCVLPC_STATS_ENABLE		0x00002018
+#define  RCVLPC_STATSENAB_LNGBRST_RFIX	 0x00400000
+#define RCVLPC_STATS_INCMASK		0x0000201c
+/* 0x2020 --> 0x2100 unused */
+#define RCVLPC_SELLST_BASE		0x00002100 /* 16 16-byte entries */
+#define  SELLST_TAIL			0x00000004
+#define  SELLST_CONT			0x00000008
+#define  SELLST_UNUSED			0x0000000c
+#define RCVLPC_COS_CNTL_BASE		0x00002200 /* 16 4-byte entries */
+#define RCVLPC_DROP_FILTER_CNT		0x00002240
+#define RCVLPC_DMA_WQ_FULL_CNT		0x00002244
+#define RCVLPC_DMA_HIPRIO_WQ_FULL_CNT	0x00002248
+#define RCVLPC_NO_RCV_BD_CNT		0x0000224c
+#define RCVLPC_IN_DISCARDS_CNT		0x00002250
+#define RCVLPC_IN_ERRORS_CNT		0x00002254
+#define RCVLPC_RCV_THRESH_HIT_CNT	0x00002258
+/* 0x225c --> 0x2400 unused */
+
+/* Receive Data and Receive BD Initiator Control */
+#define RCVDBDI_MODE			0x00002400
+#define  RCVDBDI_MODE_RESET		 0x00000001
+#define  RCVDBDI_MODE_ENABLE		 0x00000002
+#define  RCVDBDI_MODE_JUMBOBD_NEEDED	 0x00000004
+#define  RCVDBDI_MODE_FRM_TOO_BIG	 0x00000008
+#define  RCVDBDI_MODE_INV_RING_SZ	 0x00000010
+#define RCVDBDI_STATUS			0x00002404
+#define  RCVDBDI_STATUS_JUMBOBD_NEEDED	 0x00000004
+#define  RCVDBDI_STATUS_FRM_TOO_BIG	 0x00000008
+#define  RCVDBDI_STATUS_INV_RING_SZ	 0x00000010
+#define RCVDBDI_SPLIT_FRAME_MINSZ	0x00002408
+/* 0x240c --> 0x2440 unused */
+#define RCVDBDI_JUMBO_BD		0x00002440 /* TG3_BDINFO_... */
+#define RCVDBDI_STD_BD			0x00002450 /* TG3_BDINFO_... */
+#define RCVDBDI_MINI_BD			0x00002460 /* TG3_BDINFO_... */
+#define RCVDBDI_JUMBO_CON_IDX		0x00002470
+#define RCVDBDI_STD_CON_IDX		0x00002474
+#define RCVDBDI_MINI_CON_IDX		0x00002478
+/* 0x247c --> 0x2480 unused */
+#define RCVDBDI_BD_PROD_IDX_0		0x00002480
+#define RCVDBDI_BD_PROD_IDX_1		0x00002484
+#define RCVDBDI_BD_PROD_IDX_2		0x00002488
+#define RCVDBDI_BD_PROD_IDX_3		0x0000248c
+#define RCVDBDI_BD_PROD_IDX_4		0x00002490
+#define RCVDBDI_BD_PROD_IDX_5		0x00002494
+#define RCVDBDI_BD_PROD_IDX_6		0x00002498
+#define RCVDBDI_BD_PROD_IDX_7		0x0000249c
+#define RCVDBDI_BD_PROD_IDX_8		0x000024a0
+#define RCVDBDI_BD_PROD_IDX_9		0x000024a4
+#define RCVDBDI_BD_PROD_IDX_10		0x000024a8
+#define RCVDBDI_BD_PROD_IDX_11		0x000024ac
+#define RCVDBDI_BD_PROD_IDX_12		0x000024b0
+#define RCVDBDI_BD_PROD_IDX_13		0x000024b4
+#define RCVDBDI_BD_PROD_IDX_14		0x000024b8
+#define RCVDBDI_BD_PROD_IDX_15		0x000024bc
+#define RCVDBDI_HWDIAG			0x000024c0
+/* 0x24c4 --> 0x2800 unused */
+
+/* Receive Data Completion Control */
+#define RCVDCC_MODE			0x00002800
+#define  RCVDCC_MODE_RESET		 0x00000001
+#define  RCVDCC_MODE_ENABLE		 0x00000002
+#define  RCVDCC_MODE_ATTN_ENABLE	 0x00000004
+/* 0x2804 --> 0x2c00 unused */
+
+/* Receive BD Initiator Control Registers */
+#define RCVBDI_MODE			0x00002c00
+#define  RCVBDI_MODE_RESET		 0x00000001
+#define  RCVBDI_MODE_ENABLE		 0x00000002
+#define  RCVBDI_MODE_RCB_ATTN_ENAB	 0x00000004
+#define RCVBDI_STATUS			0x00002c04
+#define  RCVBDI_STATUS_RCB_ATTN		 0x00000004
+#define RCVBDI_JUMBO_PROD_IDX		0x00002c08
+#define RCVBDI_STD_PROD_IDX		0x00002c0c
+#define RCVBDI_MINI_PROD_IDX		0x00002c10
+#define RCVBDI_MINI_THRESH		0x00002c14
+#define RCVBDI_STD_THRESH		0x00002c18
+#define RCVBDI_JUMBO_THRESH		0x00002c1c
+/* 0x2c20 --> 0x3000 unused */
+
+/* Receive BD Completion Control Registers */
+#define RCVCC_MODE			0x00003000
+#define  RCVCC_MODE_RESET		 0x00000001
+#define  RCVCC_MODE_ENABLE		 0x00000002
+#define  RCVCC_MODE_ATTN_ENABLE		 0x00000004
+#define RCVCC_STATUS			0x00003004
+#define  RCVCC_STATUS_ERROR_ATTN	 0x00000004
+#define RCVCC_JUMP_PROD_IDX		0x00003008
+#define RCVCC_STD_PROD_IDX		0x0000300c
+#define RCVCC_MINI_PROD_IDX		0x00003010
+/* 0x3014 --> 0x3400 unused */
+
+/* Receive list selector control registers */
+#define RCVLSC_MODE			0x00003400
+#define  RCVLSC_MODE_RESET		 0x00000001
+#define  RCVLSC_MODE_ENABLE		 0x00000002
+#define  RCVLSC_MODE_ATTN_ENABLE	 0x00000004
+#define RCVLSC_STATUS			0x00003404
+#define  RCVLSC_STATUS_ERROR_ATTN	 0x00000004
+/* 0x3408 --> 0x3800 unused */
+
+/* Mbuf cluster free registers */
+#define MBFREE_MODE			0x00003800
+#define  MBFREE_MODE_RESET		 0x00000001
+#define  MBFREE_MODE_ENABLE		 0x00000002
+#define MBFREE_STATUS			0x00003804
+/* 0x3808 --> 0x3c00 unused */
+
+/* Host coalescing control registers */
+#define HOSTCC_MODE			0x00003c00
+#define  HOSTCC_MODE_RESET		 0x00000001
+#define  HOSTCC_MODE_ENABLE		 0x00000002
+#define  HOSTCC_MODE_ATTN		 0x00000004
+#define  HOSTCC_MODE_NOW		 0x00000008
+#define  HOSTCC_MODE_FULL_STATUS	 0x00000000
+#define  HOSTCC_MODE_64BYTE		 0x00000080
+#define  HOSTCC_MODE_32BYTE		 0x00000100
+#define  HOSTCC_MODE_CLRTICK_RXBD	 0x00000200
+#define  HOSTCC_MODE_CLRTICK_TXBD	 0x00000400
+#define  HOSTCC_MODE_NOINT_ON_NOW	 0x00000800
+#define  HOSTCC_MODE_NOINT_ON_FORCE	 0x00001000
+#define HOSTCC_STATUS			0x00003c04
+#define  HOSTCC_STATUS_ERROR_ATTN	 0x00000004
+#define HOSTCC_RXCOL_TICKS		0x00003c08
+#define  LOW_RXCOL_TICKS		 0x00000032
+#define  DEFAULT_RXCOL_TICKS		 0x00000048
+#define  HIGH_RXCOL_TICKS		 0x00000096
+#define HOSTCC_TXCOL_TICKS		0x00003c0c
+#define  LOW_TXCOL_TICKS		 0x00000096
+#define  DEFAULT_TXCOL_TICKS		 0x0000012c
+#define  HIGH_TXCOL_TICKS		 0x00000145
+#define HOSTCC_RXMAX_FRAMES		0x00003c10
+#define  LOW_RXMAX_FRAMES		 0x00000005
+#define  DEFAULT_RXMAX_FRAMES		 0x00000008
+#define  HIGH_RXMAX_FRAMES		 0x00000012
+#define HOSTCC_TXMAX_FRAMES		0x00003c14
+#define  LOW_TXMAX_FRAMES		 0x00000035
+#define  DEFAULT_TXMAX_FRAMES		 0x0000004b
+#define  HIGH_TXMAX_FRAMES		 0x00000052
+#define HOSTCC_RXCOAL_TICK_INT		0x00003c18
+#define  DEFAULT_RXCOAL_TICK_INT	 0x00000019
+#define HOSTCC_TXCOAL_TICK_INT		0x00003c1c
+#define  DEFAULT_TXCOAL_TICK_INT	 0x00000019
+#define HOSTCC_RXCOAL_MAXF_INT		0x00003c20
+#define  DEFAULT_RXCOAL_MAXF_INT	 0x00000005
+#define HOSTCC_TXCOAL_MAXF_INT		0x00003c24
+#define  DEFAULT_TXCOAL_MAXF_INT	 0x00000005
+#define HOSTCC_STAT_COAL_TICKS		0x00003c28
+#define  DEFAULT_STAT_COAL_TICKS	 0x000f4240
+/* 0x3c2c --> 0x3c30 unused */
+#define HOSTCC_STATS_BLK_HOST_ADDR	0x00003c30 /* 64-bit */
+#define HOSTCC_STATUS_BLK_HOST_ADDR	0x00003c38 /* 64-bit */
+#define HOSTCC_STATS_BLK_NIC_ADDR	0x00003c40
+#define HOSTCC_STATUS_BLK_NIC_ADDR	0x00003c44
+#define HOSTCC_FLOW_ATTN		0x00003c48
+/* 0x3c4c --> 0x3c50 unused */
+#define HOSTCC_JUMBO_CON_IDX		0x00003c50
+#define HOSTCC_STD_CON_IDX		0x00003c54
+#define HOSTCC_MINI_CON_IDX		0x00003c58
+/* 0x3c5c --> 0x3c80 unused */
+#define HOSTCC_RET_PROD_IDX_0		0x00003c80
+#define HOSTCC_RET_PROD_IDX_1		0x00003c84
+#define HOSTCC_RET_PROD_IDX_2		0x00003c88
+#define HOSTCC_RET_PROD_IDX_3		0x00003c8c
+#define HOSTCC_RET_PROD_IDX_4		0x00003c90
+#define HOSTCC_RET_PROD_IDX_5		0x00003c94
+#define HOSTCC_RET_PROD_IDX_6		0x00003c98
+#define HOSTCC_RET_PROD_IDX_7		0x00003c9c
+#define HOSTCC_RET_PROD_IDX_8		0x00003ca0
+#define HOSTCC_RET_PROD_IDX_9		0x00003ca4
+#define HOSTCC_RET_PROD_IDX_10		0x00003ca8
+#define HOSTCC_RET_PROD_IDX_11		0x00003cac
+#define HOSTCC_RET_PROD_IDX_12		0x00003cb0
+#define HOSTCC_RET_PROD_IDX_13		0x00003cb4
+#define HOSTCC_RET_PROD_IDX_14		0x00003cb8
+#define HOSTCC_RET_PROD_IDX_15		0x00003cbc
+#define HOSTCC_SND_CON_IDX_0		0x00003cc0
+#define HOSTCC_SND_CON_IDX_1		0x00003cc4
+#define HOSTCC_SND_CON_IDX_2		0x00003cc8
+#define HOSTCC_SND_CON_IDX_3		0x00003ccc
+#define HOSTCC_SND_CON_IDX_4		0x00003cd0
+#define HOSTCC_SND_CON_IDX_5		0x00003cd4
+#define HOSTCC_SND_CON_IDX_6		0x00003cd8
+#define HOSTCC_SND_CON_IDX_7		0x00003cdc
+#define HOSTCC_SND_CON_IDX_8		0x00003ce0
+#define HOSTCC_SND_CON_IDX_9		0x00003ce4
+#define HOSTCC_SND_CON_IDX_10		0x00003ce8
+#define HOSTCC_SND_CON_IDX_11		0x00003cec
+#define HOSTCC_SND_CON_IDX_12		0x00003cf0
+#define HOSTCC_SND_CON_IDX_13		0x00003cf4
+#define HOSTCC_SND_CON_IDX_14		0x00003cf8
+#define HOSTCC_SND_CON_IDX_15		0x00003cfc
+/* 0x3d00 --> 0x4000 unused */
+
+/* Memory arbiter control registers */
+#define MEMARB_MODE			0x00004000
+#define  MEMARB_MODE_RESET		 0x00000001
+#define  MEMARB_MODE_ENABLE		 0x00000002
+#define MEMARB_STATUS			0x00004004
+#define MEMARB_TRAP_ADDR_LOW		0x00004008
+#define MEMARB_TRAP_ADDR_HIGH		0x0000400c
+/* 0x4010 --> 0x4400 unused */
+
+/* Buffer manager control registers */
+#define BUFMGR_MODE			0x00004400
+#define  BUFMGR_MODE_RESET		 0x00000001
+#define  BUFMGR_MODE_ENABLE		 0x00000002
+#define  BUFMGR_MODE_ATTN_ENABLE	 0x00000004
+#define  BUFMGR_MODE_BM_TEST		 0x00000008
+#define  BUFMGR_MODE_MBLOW_ATTN_ENAB	 0x00000010
+#define BUFMGR_STATUS			0x00004404
+#define  BUFMGR_STATUS_ERROR		 0x00000004
+#define  BUFMGR_STATUS_MBLOW		 0x00000010
+#define BUFMGR_MB_POOL_ADDR		0x00004408
+#define BUFMGR_MB_POOL_SIZE		0x0000440c
+#define BUFMGR_MB_RDMA_LOW_WATER	0x00004410
+#define  DEFAULT_MB_RDMA_LOW_WATER	 0x00000050
+#define  DEFAULT_MB_RDMA_LOW_WATER_5705	 0x00000000
+#define  DEFAULT_MB_RDMA_LOW_WATER_JUMBO 0x00000130
+#define BUFMGR_MB_MACRX_LOW_WATER	0x00004414
+#define  DEFAULT_MB_MACRX_LOW_WATER	  0x00000020
+#define  DEFAULT_MB_MACRX_LOW_WATER_5705  0x00000010
+#define  DEFAULT_MB_MACRX_LOW_WATER_JUMBO 0x00000098
+#define BUFMGR_MB_HIGH_WATER		0x00004418
+#define  DEFAULT_MB_HIGH_WATER		 0x00000060
+#define  DEFAULT_MB_HIGH_WATER_5705	 0x00000060
+#define  DEFAULT_MB_HIGH_WATER_JUMBO	 0x0000017c
+#define BUFMGR_RX_MB_ALLOC_REQ		0x0000441c
+#define  BUFMGR_MB_ALLOC_BIT		 0x10000000
+#define BUFMGR_RX_MB_ALLOC_RESP		0x00004420
+#define BUFMGR_TX_MB_ALLOC_REQ		0x00004424
+#define BUFMGR_TX_MB_ALLOC_RESP		0x00004428
+#define BUFMGR_DMA_DESC_POOL_ADDR	0x0000442c
+#define BUFMGR_DMA_DESC_POOL_SIZE	0x00004430
+#define BUFMGR_DMA_LOW_WATER		0x00004434
+#define  DEFAULT_DMA_LOW_WATER		 0x00000005
+#define BUFMGR_DMA_HIGH_WATER		0x00004438
+#define  DEFAULT_DMA_HIGH_WATER		 0x0000000a
+#define BUFMGR_RX_DMA_ALLOC_REQ		0x0000443c
+#define BUFMGR_RX_DMA_ALLOC_RESP	0x00004440
+#define BUFMGR_TX_DMA_ALLOC_REQ		0x00004444
+#define BUFMGR_TX_DMA_ALLOC_RESP	0x00004448
+#define BUFMGR_HWDIAG_0			0x0000444c
+#define BUFMGR_HWDIAG_1			0x00004450
+#define BUFMGR_HWDIAG_2			0x00004454
+/* 0x4458 --> 0x4800 unused */
+
+/* Read DMA control registers */
+#define RDMAC_MODE			0x00004800
+#define  RDMAC_MODE_RESET		 0x00000001
+#define  RDMAC_MODE_ENABLE		 0x00000002
+#define  RDMAC_MODE_TGTABORT_ENAB	 0x00000004
+#define  RDMAC_MODE_MSTABORT_ENAB	 0x00000008
+#define  RDMAC_MODE_PARITYERR_ENAB	 0x00000010
+#define  RDMAC_MODE_ADDROFLOW_ENAB	 0x00000020
+#define  RDMAC_MODE_FIFOOFLOW_ENAB	 0x00000040
+#define  RDMAC_MODE_FIFOURUN_ENAB	 0x00000080
+#define  RDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
+#define  RDMAC_MODE_LNGREAD_ENAB	 0x00000200
+#define  RDMAC_MODE_SPLIT_ENABLE	 0x00000800
+#define  RDMAC_MODE_SPLIT_RESET		 0x00001000
+#define  RDMAC_MODE_FIFO_SIZE_128	 0x00020000
+#define  RDMAC_MODE_FIFO_LONG_BURST	 0x00030000
+#define RDMAC_STATUS			0x00004804
+#define  RDMAC_STATUS_TGTABORT		 0x00000004
+#define  RDMAC_STATUS_MSTABORT		 0x00000008
+#define  RDMAC_STATUS_PARITYERR		 0x00000010
+#define  RDMAC_STATUS_ADDROFLOW		 0x00000020
+#define  RDMAC_STATUS_FIFOOFLOW		 0x00000040
+#define  RDMAC_STATUS_FIFOURUN		 0x00000080
+#define  RDMAC_STATUS_FIFOOREAD		 0x00000100
+#define  RDMAC_STATUS_LNGREAD		 0x00000200
+/* 0x4808 --> 0x4c00 unused */
+
+/* Write DMA control registers */
+#define WDMAC_MODE			0x00004c00
+#define  WDMAC_MODE_RESET		 0x00000001
+#define  WDMAC_MODE_ENABLE		 0x00000002
+#define  WDMAC_MODE_TGTABORT_ENAB	 0x00000004
+#define  WDMAC_MODE_MSTABORT_ENAB	 0x00000008
+#define  WDMAC_MODE_PARITYERR_ENAB	 0x00000010
+#define  WDMAC_MODE_ADDROFLOW_ENAB	 0x00000020
+#define  WDMAC_MODE_FIFOOFLOW_ENAB	 0x00000040
+#define  WDMAC_MODE_FIFOURUN_ENAB	 0x00000080
+#define  WDMAC_MODE_FIFOOREAD_ENAB	 0x00000100
+#define  WDMAC_MODE_LNGREAD_ENAB	 0x00000200
+#define  WDMAC_MODE_RX_ACCEL	 	 0x00000400
+#define WDMAC_STATUS			0x00004c04
+#define  WDMAC_STATUS_TGTABORT		 0x00000004
+#define  WDMAC_STATUS_MSTABORT		 0x00000008
+#define  WDMAC_STATUS_PARITYERR		 0x00000010
+#define  WDMAC_STATUS_ADDROFLOW		 0x00000020
+#define  WDMAC_STATUS_FIFOOFLOW		 0x00000040
+#define  WDMAC_STATUS_FIFOURUN		 0x00000080
+#define  WDMAC_STATUS_FIFOOREAD		 0x00000100
+#define  WDMAC_STATUS_LNGREAD		 0x00000200
+/* 0x4c08 --> 0x5000 unused */
+
+/* Per-cpu register offsets (arm9) */
+#define CPU_MODE			0x00000000
+#define  CPU_MODE_RESET			 0x00000001
+#define  CPU_MODE_HALT			 0x00000400
+#define CPU_STATE			0x00000004
+#define CPU_EVTMASK			0x00000008
+/* 0xc --> 0x1c reserved */
+#define CPU_PC				0x0000001c
+#define CPU_INSN			0x00000020
+#define CPU_SPAD_UFLOW			0x00000024
+#define CPU_WDOG_CLEAR			0x00000028
+#define CPU_WDOG_VECTOR			0x0000002c
+#define CPU_WDOG_PC			0x00000030
+#define CPU_HW_BP			0x00000034
+/* 0x38 --> 0x44 unused */
+#define CPU_WDOG_SAVED_STATE		0x00000044
+#define CPU_LAST_BRANCH_ADDR		0x00000048
+#define CPU_SPAD_UFLOW_SET		0x0000004c
+/* 0x50 --> 0x200 unused */
+#define CPU_R0				0x00000200
+#define CPU_R1				0x00000204
+#define CPU_R2				0x00000208
+#define CPU_R3				0x0000020c
+#define CPU_R4				0x00000210
+#define CPU_R5				0x00000214
+#define CPU_R6				0x00000218
+#define CPU_R7				0x0000021c
+#define CPU_R8				0x00000220
+#define CPU_R9				0x00000224
+#define CPU_R10				0x00000228
+#define CPU_R11				0x0000022c
+#define CPU_R12				0x00000230
+#define CPU_R13				0x00000234
+#define CPU_R14				0x00000238
+#define CPU_R15				0x0000023c
+#define CPU_R16				0x00000240
+#define CPU_R17				0x00000244
+#define CPU_R18				0x00000248
+#define CPU_R19				0x0000024c
+#define CPU_R20				0x00000250
+#define CPU_R21				0x00000254
+#define CPU_R22				0x00000258
+#define CPU_R23				0x0000025c
+#define CPU_R24				0x00000260
+#define CPU_R25				0x00000264
+#define CPU_R26				0x00000268
+#define CPU_R27				0x0000026c
+#define CPU_R28				0x00000270
+#define CPU_R29				0x00000274
+#define CPU_R30				0x00000278
+#define CPU_R31				0x0000027c
+/* 0x280 --> 0x400 unused */
+
+#define RX_CPU_BASE			0x00005000
+#define TX_CPU_BASE			0x00005400
+
+/* Mailboxes */
+#define GRCMBOX_INTERRUPT_0		0x00005800 /* 64-bit */
+#define GRCMBOX_INTERRUPT_1		0x00005808 /* 64-bit */
+#define GRCMBOX_INTERRUPT_2		0x00005810 /* 64-bit */
+#define GRCMBOX_INTERRUPT_3		0x00005818 /* 64-bit */
+#define GRCMBOX_GENERAL_0		0x00005820 /* 64-bit */
+#define GRCMBOX_GENERAL_1		0x00005828 /* 64-bit */
+#define GRCMBOX_GENERAL_2		0x00005830 /* 64-bit */
+#define GRCMBOX_GENERAL_3		0x00005838 /* 64-bit */
+#define GRCMBOX_GENERAL_4		0x00005840 /* 64-bit */
+#define GRCMBOX_GENERAL_5		0x00005848 /* 64-bit */
+#define GRCMBOX_GENERAL_6		0x00005850 /* 64-bit */
+#define GRCMBOX_GENERAL_7		0x00005858 /* 64-bit */
+#define GRCMBOX_RELOAD_STAT		0x00005860 /* 64-bit */
+#define GRCMBOX_RCVSTD_PROD_IDX		0x00005868 /* 64-bit */
+#define GRCMBOX_RCVJUMBO_PROD_IDX	0x00005870 /* 64-bit */
+#define GRCMBOX_RCVMINI_PROD_IDX	0x00005878 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_0	0x00005880 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_1	0x00005888 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_2	0x00005890 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_3	0x00005898 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_4	0x000058a0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_5	0x000058a8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_6	0x000058b0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_7	0x000058b8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_8	0x000058c0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_9	0x000058c8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_10	0x000058d0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_11	0x000058d8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_12	0x000058e0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_13	0x000058e8 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_14	0x000058f0 /* 64-bit */
+#define GRCMBOX_RCVRET_CON_IDX_15	0x000058f8 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_0	0x00005900 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_1	0x00005908 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_2	0x00005910 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_3	0x00005918 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_4	0x00005920 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_5	0x00005928 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_6	0x00005930 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_7	0x00005938 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_8	0x00005940 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_9	0x00005948 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_10	0x00005950 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_11	0x00005958 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_12	0x00005960 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_13	0x00005968 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_14	0x00005970 /* 64-bit */
+#define GRCMBOX_SNDHOST_PROD_IDX_15	0x00005978 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_0	0x00005980 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_1	0x00005988 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_2	0x00005990 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_3	0x00005998 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_4	0x000059a0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_5	0x000059a8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_6	0x000059b0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_7	0x000059b8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_8	0x000059c0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_9	0x000059c8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_10	0x000059d0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_11	0x000059d8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_12	0x000059e0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_13	0x000059e8 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_14	0x000059f0 /* 64-bit */
+#define GRCMBOX_SNDNIC_PROD_IDX_15	0x000059f8 /* 64-bit */
+#define GRCMBOX_HIGH_PRIO_EV_VECTOR	0x00005a00
+#define GRCMBOX_HIGH_PRIO_EV_MASK	0x00005a04
+#define GRCMBOX_LOW_PRIO_EV_VEC		0x00005a08
+#define GRCMBOX_LOW_PRIO_EV_MASK	0x00005a0c
+/* 0x5a10 --> 0x5c00 */
+
+/* Flow Through queues */
+#define FTQ_RESET			0x00005c00
+/* 0x5c04 --> 0x5c10 unused */
+#define FTQ_DMA_NORM_READ_CTL		0x00005c10
+#define FTQ_DMA_NORM_READ_FULL_CNT	0x00005c14
+#define FTQ_DMA_NORM_READ_FIFO_ENQDEQ	0x00005c18
+#define FTQ_DMA_NORM_READ_WRITE_PEEK	0x00005c1c
+#define FTQ_DMA_HIGH_READ_CTL		0x00005c20
+#define FTQ_DMA_HIGH_READ_FULL_CNT	0x00005c24
+#define FTQ_DMA_HIGH_READ_FIFO_ENQDEQ	0x00005c28
+#define FTQ_DMA_HIGH_READ_WRITE_PEEK	0x00005c2c
+#define FTQ_DMA_COMP_DISC_CTL		0x00005c30
+#define FTQ_DMA_COMP_DISC_FULL_CNT	0x00005c34
+#define FTQ_DMA_COMP_DISC_FIFO_ENQDEQ	0x00005c38
+#define FTQ_DMA_COMP_DISC_WRITE_PEEK	0x00005c3c
+#define FTQ_SEND_BD_COMP_CTL		0x00005c40
+#define FTQ_SEND_BD_COMP_FULL_CNT	0x00005c44
+#define FTQ_SEND_BD_COMP_FIFO_ENQDEQ	0x00005c48
+#define FTQ_SEND_BD_COMP_WRITE_PEEK	0x00005c4c
+#define FTQ_SEND_DATA_INIT_CTL		0x00005c50
+#define FTQ_SEND_DATA_INIT_FULL_CNT	0x00005c54
+#define FTQ_SEND_DATA_INIT_FIFO_ENQDEQ	0x00005c58
+#define FTQ_SEND_DATA_INIT_WRITE_PEEK	0x00005c5c
+#define FTQ_DMA_NORM_WRITE_CTL		0x00005c60
+#define FTQ_DMA_NORM_WRITE_FULL_CNT	0x00005c64
+#define FTQ_DMA_NORM_WRITE_FIFO_ENQDEQ	0x00005c68
+#define FTQ_DMA_NORM_WRITE_WRITE_PEEK	0x00005c6c
+#define FTQ_DMA_HIGH_WRITE_CTL		0x00005c70
+#define FTQ_DMA_HIGH_WRITE_FULL_CNT	0x00005c74
+#define FTQ_DMA_HIGH_WRITE_FIFO_ENQDEQ	0x00005c78
+#define FTQ_DMA_HIGH_WRITE_WRITE_PEEK	0x00005c7c
+#define FTQ_SWTYPE1_CTL			0x00005c80
+#define FTQ_SWTYPE1_FULL_CNT		0x00005c84
+#define FTQ_SWTYPE1_FIFO_ENQDEQ		0x00005c88
+#define FTQ_SWTYPE1_WRITE_PEEK		0x00005c8c
+#define FTQ_SEND_DATA_COMP_CTL		0x00005c90
+#define FTQ_SEND_DATA_COMP_FULL_CNT	0x00005c94
+#define FTQ_SEND_DATA_COMP_FIFO_ENQDEQ	0x00005c98
+#define FTQ_SEND_DATA_COMP_WRITE_PEEK	0x00005c9c
+#define FTQ_HOST_COAL_CTL		0x00005ca0
+#define FTQ_HOST_COAL_FULL_CNT		0x00005ca4
+#define FTQ_HOST_COAL_FIFO_ENQDEQ	0x00005ca8
+#define FTQ_HOST_COAL_WRITE_PEEK	0x00005cac
+#define FTQ_MAC_TX_CTL			0x00005cb0
+#define FTQ_MAC_TX_FULL_CNT		0x00005cb4
+#define FTQ_MAC_TX_FIFO_ENQDEQ		0x00005cb8
+#define FTQ_MAC_TX_WRITE_PEEK		0x00005cbc
+#define FTQ_MB_FREE_CTL			0x00005cc0
+#define FTQ_MB_FREE_FULL_CNT		0x00005cc4
+#define FTQ_MB_FREE_FIFO_ENQDEQ		0x00005cc8
+#define FTQ_MB_FREE_WRITE_PEEK		0x00005ccc
+#define FTQ_RCVBD_COMP_CTL		0x00005cd0
+#define FTQ_RCVBD_COMP_FULL_CNT		0x00005cd4
+#define FTQ_RCVBD_COMP_FIFO_ENQDEQ	0x00005cd8
+#define FTQ_RCVBD_COMP_WRITE_PEEK	0x00005cdc
+#define FTQ_RCVLST_PLMT_CTL		0x00005ce0
+#define FTQ_RCVLST_PLMT_FULL_CNT	0x00005ce4
+#define FTQ_RCVLST_PLMT_FIFO_ENQDEQ	0x00005ce8
+#define FTQ_RCVLST_PLMT_WRITE_PEEK	0x00005cec
+#define FTQ_RCVDATA_INI_CTL		0x00005cf0
+#define FTQ_RCVDATA_INI_FULL_CNT	0x00005cf4
+#define FTQ_RCVDATA_INI_FIFO_ENQDEQ	0x00005cf8
+#define FTQ_RCVDATA_INI_WRITE_PEEK	0x00005cfc
+#define FTQ_RCVDATA_COMP_CTL		0x00005d00
+#define FTQ_RCVDATA_COMP_FULL_CNT	0x00005d04
+#define FTQ_RCVDATA_COMP_FIFO_ENQDEQ	0x00005d08
+#define FTQ_RCVDATA_COMP_WRITE_PEEK	0x00005d0c
+#define FTQ_SWTYPE2_CTL			0x00005d10
+#define FTQ_SWTYPE2_FULL_CNT		0x00005d14
+#define FTQ_SWTYPE2_FIFO_ENQDEQ		0x00005d18
+#define FTQ_SWTYPE2_WRITE_PEEK		0x00005d1c
+/* 0x5d20 --> 0x6000 unused */
+
+/* Message signaled interrupt registers */
+#define MSGINT_MODE			0x00006000
+#define  MSGINT_MODE_RESET		 0x00000001
+#define  MSGINT_MODE_ENABLE		 0x00000002
+#define MSGINT_STATUS			0x00006004
+#define MSGINT_FIFO			0x00006008
+/* 0x600c --> 0x6400 unused */
+
+/* DMA completion registers */
+#define DMAC_MODE			0x00006400
+#define  DMAC_MODE_RESET		 0x00000001
+#define  DMAC_MODE_ENABLE		 0x00000002
+/* 0x6404 --> 0x6800 unused */
+
+/* GRC registers */
+#define GRC_MODE			0x00006800
+#define  GRC_MODE_UPD_ON_COAL		0x00000001
+#define  GRC_MODE_BSWAP_NONFRM_DATA	0x00000002
+#define  GRC_MODE_WSWAP_NONFRM_DATA	0x00000004
+#define  GRC_MODE_BSWAP_DATA		0x00000010
+#define  GRC_MODE_WSWAP_DATA		0x00000020
+#define  GRC_MODE_SPLITHDR		0x00000100
+#define  GRC_MODE_NOFRM_CRACKING	0x00000200
+#define  GRC_MODE_INCL_CRC		0x00000400
+#define  GRC_MODE_ALLOW_BAD_FRMS	0x00000800
+#define  GRC_MODE_NOIRQ_ON_SENDS	0x00002000
+#define  GRC_MODE_NOIRQ_ON_RCV		0x00004000
+#define  GRC_MODE_FORCE_PCI32BIT	0x00008000
+#define  GRC_MODE_HOST_STACKUP		0x00010000
+#define  GRC_MODE_HOST_SENDBDS		0x00020000
+#define  GRC_MODE_NO_TX_PHDR_CSUM	0x00100000
+#define  GRC_MODE_NO_RX_PHDR_CSUM	0x00800000
+#define  GRC_MODE_IRQ_ON_TX_CPU_ATTN	0x01000000
+#define  GRC_MODE_IRQ_ON_RX_CPU_ATTN	0x02000000
+#define  GRC_MODE_IRQ_ON_MAC_ATTN	0x04000000
+#define  GRC_MODE_IRQ_ON_DMA_ATTN	0x08000000
+#define  GRC_MODE_IRQ_ON_FLOW_ATTN	0x10000000
+#define  GRC_MODE_4X_NIC_SEND_RINGS	0x20000000
+#define  GRC_MODE_MCAST_FRM_ENABLE	0x40000000
+#define GRC_MISC_CFG			0x00006804
+#define  GRC_MISC_CFG_CORECLK_RESET	0x00000001
+#define  GRC_MISC_CFG_PRESCALAR_MASK	0x000000fe
+#define  GRC_MISC_CFG_PRESCALAR_SHIFT	1
+#define  GRC_MISC_CFG_BOARD_ID_MASK	0x0001e000
+#define  GRC_MISC_CFG_BOARD_ID_5700	0x0001e000
+#define  GRC_MISC_CFG_BOARD_ID_5701	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5702FE	0x00004000
+#define  GRC_MISC_CFG_BOARD_ID_5703	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5703S	0x00002000
+#define  GRC_MISC_CFG_BOARD_ID_5704	0x00000000
+#define  GRC_MISC_CFG_BOARD_ID_5704CIOBE 0x00004000
+#define  GRC_MISC_CFG_BOARD_ID_5704_A2	0x00008000
+#define  GRC_MISC_CFG_BOARD_ID_5788	0x00010000
+#define  GRC_MISC_CFG_BOARD_ID_5788M	0x00018000
+#define  GRC_MISC_CFG_BOARD_ID_AC91002A1 0x00018000
+#define  GRC_MISC_CFG_KEEP_GPHY_POWER	0x04000000
+#define GRC_LOCAL_CTRL			0x00006808
+#define  GRC_LCLCTRL_INT_ACTIVE		0x00000001
+#define  GRC_LCLCTRL_CLEARINT		0x00000002
+#define  GRC_LCLCTRL_SETINT		0x00000004
+#define  GRC_LCLCTRL_INT_ON_ATTN	0x00000008
+#define  GRC_LCLCTRL_GPIO_INPUT0	0x00000100
+#define  GRC_LCLCTRL_GPIO_INPUT1	0x00000200
+#define  GRC_LCLCTRL_GPIO_INPUT2	0x00000400
+#define  GRC_LCLCTRL_GPIO_OE0		0x00000800
+#define  GRC_LCLCTRL_GPIO_OE1		0x00001000
+#define  GRC_LCLCTRL_GPIO_OE2		0x00002000
+#define  GRC_LCLCTRL_GPIO_OUTPUT0	0x00004000
+#define  GRC_LCLCTRL_GPIO_OUTPUT1	0x00008000
+#define  GRC_LCLCTRL_GPIO_OUTPUT2	0x00010000
+#define  GRC_LCLCTRL_EXTMEM_ENABLE	0x00020000
+#define  GRC_LCLCTRL_MEMSZ_MASK		0x001c0000
+#define  GRC_LCLCTRL_MEMSZ_256K		0x00000000
+#define  GRC_LCLCTRL_MEMSZ_512K		0x00040000
+#define  GRC_LCLCTRL_MEMSZ_1M		0x00080000
+#define  GRC_LCLCTRL_MEMSZ_2M		0x000c0000
+#define  GRC_LCLCTRL_MEMSZ_4M		0x00100000
+#define  GRC_LCLCTRL_MEMSZ_8M		0x00140000
+#define  GRC_LCLCTRL_MEMSZ_16M		0x00180000
+#define  GRC_LCLCTRL_BANK_SELECT	0x00200000
+#define  GRC_LCLCTRL_SSRAM_TYPE		0x00400000
+#define  GRC_LCLCTRL_AUTO_SEEPROM	0x01000000
+#define GRC_TIMER			0x0000680c
+#define GRC_RX_CPU_EVENT		0x00006810
+#define GRC_RX_TIMER_REF		0x00006814
+#define GRC_RX_CPU_SEM			0x00006818
+#define GRC_REMOTE_RX_CPU_ATTN		0x0000681c
+#define GRC_TX_CPU_EVENT		0x00006820
+#define GRC_TX_TIMER_REF		0x00006824
+#define GRC_TX_CPU_SEM			0x00006828
+#define GRC_REMOTE_TX_CPU_ATTN		0x0000682c
+#define GRC_MEM_POWER_UP		0x00006830 /* 64-bit */
+#define GRC_EEPROM_ADDR			0x00006838
+#define  EEPROM_ADDR_WRITE		0x00000000
+#define  EEPROM_ADDR_READ		0x80000000
+#define  EEPROM_ADDR_COMPLETE		0x40000000
+#define  EEPROM_ADDR_FSM_RESET		0x20000000
+#define  EEPROM_ADDR_DEVID_MASK		0x1c000000
+#define  EEPROM_ADDR_DEVID_SHIFT	26
+#define  EEPROM_ADDR_START		0x02000000
+#define  EEPROM_ADDR_CLKPERD_SHIFT	16
+#define  EEPROM_ADDR_ADDR_MASK		0x0000ffff
+#define  EEPROM_ADDR_ADDR_SHIFT		0
+#define  EEPROM_DEFAULT_CLOCK_PERIOD	0x60
+#define  EEPROM_CHIP_SIZE		(64 * 1024)
+#define GRC_EEPROM_DATA			0x0000683c
+#define GRC_EEPROM_CTRL			0x00006840
+#define GRC_MDI_CTRL			0x00006844
+#define GRC_SEEPROM_DELAY		0x00006848
+/* 0x684c --> 0x6c00 unused */
+
+/* 0x6c00 --> 0x7000 unused */
+
+/* NVRAM Control registers */
+#define NVRAM_CMD			0x00007000
+#define  NVRAM_CMD_RESET		 0x00000001
+#define  NVRAM_CMD_DONE			 0x00000008
+#define  NVRAM_CMD_GO			 0x00000010
+#define  NVRAM_CMD_WR			 0x00000020
+#define  NVRAM_CMD_RD			 0x00000000
+#define  NVRAM_CMD_ERASE		 0x00000040
+#define  NVRAM_CMD_FIRST		 0x00000080
+#define  NVRAM_CMD_LAST			 0x00000100
+#define NVRAM_STAT			0x00007004
+#define NVRAM_WRDATA			0x00007008
+#define NVRAM_ADDR			0x0000700c
+#define  NVRAM_ADDR_MSK			0x00ffffff
+#define NVRAM_RDDATA			0x00007010
+#define NVRAM_CFG1			0x00007014
+#define  NVRAM_CFG1_FLASHIF_ENAB	 0x00000001
+#define  NVRAM_CFG1_BUFFERED_MODE	 0x00000002
+#define  NVRAM_CFG1_PASS_THRU		 0x00000004
+#define  NVRAM_CFG1_BIT_BANG		 0x00000008
+#define  NVRAM_CFG1_COMPAT_BYPASS	 0x80000000
+#define NVRAM_CFG2			0x00007018
+#define NVRAM_CFG3			0x0000701c
+#define NVRAM_SWARB			0x00007020
+#define  SWARB_REQ_SET0			 0x00000001
+#define  SWARB_REQ_SET1			 0x00000002
+#define  SWARB_REQ_SET2			 0x00000004
+#define  SWARB_REQ_SET3			 0x00000008
+#define  SWARB_REQ_CLR0			 0x00000010
+#define  SWARB_REQ_CLR1			 0x00000020
+#define  SWARB_REQ_CLR2			 0x00000040
+#define  SWARB_REQ_CLR3			 0x00000080
+#define  SWARB_GNT0			 0x00000100
+#define  SWARB_GNT1			 0x00000200
+#define  SWARB_GNT2			 0x00000400
+#define  SWARB_GNT3			 0x00000800
+#define  SWARB_REQ0			 0x00001000
+#define  SWARB_REQ1			 0x00002000
+#define  SWARB_REQ2			 0x00004000
+#define  SWARB_REQ3			 0x00008000
+#define    NVRAM_BUFFERED_PAGE_SIZE	   264
+#define    NVRAM_BUFFERED_PAGE_POS	   9
+/* 0x7024 --> 0x7400 unused */
+
+/* 0x7400 --> 0x8000 unused */
+
+/* 32K Window into NIC internal memory */
+#define NIC_SRAM_WIN_BASE		0x00008000
+
+/* Offsets into first 32k of NIC internal memory. */
+#define NIC_SRAM_PAGE_ZERO		0x00000000
+#define NIC_SRAM_SEND_RCB		0x00000100 /* 16 * TG3_BDINFO_... */
+#define NIC_SRAM_RCV_RET_RCB		0x00000200 /* 16 * TG3_BDINFO_... */
+#define NIC_SRAM_STATS_BLK		0x00000300
+#define NIC_SRAM_STATUS_BLK		0x00000b00
+
+#define NIC_SRAM_FIRMWARE_MBOX		0x00000b50
+#define  NIC_SRAM_FIRMWARE_MBOX_MAGIC1	 0x4B657654
+#define  NIC_SRAM_FIRMWARE_MBOX_MAGIC2	 0x4861764b /* !dma on linkchg */
+
+#define NIC_SRAM_DATA_SIG		0x00000b54
+#define  NIC_SRAM_DATA_SIG_MAGIC	 0x4b657654 /* ascii for 'KevT' */
+
+#define NIC_SRAM_DATA_CFG			0x00000b58
+#define  NIC_SRAM_DATA_CFG_LED_MODE_MASK	 0x0000000c
+#define  NIC_SRAM_DATA_CFG_LED_MODE_UNKNOWN	 0x00000000
+#define  NIC_SRAM_DATA_CFG_LED_TRIPLE_SPD	 0x00000004
+#define  NIC_SRAM_DATA_CFG_LED_OPEN_DRAIN	 0x00000004
+#define  NIC_SRAM_DATA_CFG_LED_LINK_SPD		 0x00000008
+#define  NIC_SRAM_DATA_CFG_LED_OUTPUT		 0x00000008
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_MASK	 0x00000030
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_UNKNOWN	 0x00000000
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_COPPER	 0x00000010
+#define  NIC_SRAM_DATA_CFG_PHY_TYPE_FIBER	 0x00000020
+#define  NIC_SRAM_DATA_CFG_WOL_ENABLE		 0x00000040
+#define  NIC_SRAM_DATA_CFG_ASF_ENABLE		 0x00000080
+#define  NIC_SRAM_DATA_CFG_EEPROM_WP		 0x00000100
+#define  NIC_SRAM_DATA_CFG_MINI_PCI		 0x00001000
+#define  NIC_SRAM_DATA_CFG_FIBER_WOL		 0x00004000
+
+#define NIC_SRAM_DATA_PHY_ID		0x00000b74
+#define  NIC_SRAM_DATA_PHY_ID1_MASK	 0xffff0000
+#define  NIC_SRAM_DATA_PHY_ID2_MASK	 0x0000ffff
+
+#define NIC_SRAM_FW_CMD_MBOX		0x00000b78
+#define  FWCMD_NICDRV_ALIVE		 0x00000001
+#define  FWCMD_NICDRV_PAUSE_FW		 0x00000002
+#define  FWCMD_NICDRV_IPV4ADDR_CHG	 0x00000003
+#define  FWCMD_NICDRV_IPV6ADDR_CHG	 0x00000004
+#define  FWCMD_NICDRV_FIX_DMAR		 0x00000005
+#define  FWCMD_NICDRV_FIX_DMAW		 0x00000006
+#define NIC_SRAM_FW_CMD_LEN_MBOX	0x00000b7c
+#define NIC_SRAM_FW_CMD_DATA_MBOX	0x00000b80
+#define NIC_SRAM_FW_ASF_STATUS_MBOX	0x00000c00
+#define NIC_SRAM_FW_DRV_STATE_MBOX	0x00000c04
+#define  DRV_STATE_START		 0x00000001
+#define  DRV_STATE_UNLOAD		 0x00000002
+#define  DRV_STATE_WOL			 0x00000003
+#define  DRV_STATE_SUSPEND		 0x00000004
+
+#define NIC_SRAM_FW_RESET_TYPE_MBOX	0x00000c08
+
+#define NIC_SRAM_MAC_ADDR_HIGH_MBOX	0x00000c14
+#define NIC_SRAM_MAC_ADDR_LOW_MBOX	0x00000c18
+
+#define NIC_SRAM_RX_MINI_BUFFER_DESC	0x00001000
+
+#define NIC_SRAM_DMA_DESC_POOL_BASE	0x00002000
+#define  NIC_SRAM_DMA_DESC_POOL_SIZE	 0x00002000
+#define NIC_SRAM_TX_BUFFER_DESC		0x00004000 /* 512 entries */
+#define NIC_SRAM_RX_BUFFER_DESC		0x00006000 /* 256 entries */
+#define NIC_SRAM_RX_JUMBO_BUFFER_DESC	0x00007000 /* 256 entries */
+#define NIC_SRAM_MBUF_POOL_BASE		0x00008000
+#define  NIC_SRAM_MBUF_POOL_SIZE96	 0x00018000
+#define  NIC_SRAM_MBUF_POOL_SIZE64	 0x00010000
+#define  NIC_SRAM_MBUF_POOL_BASE5705	0x00010000
+#define  NIC_SRAM_MBUF_POOL_SIZE5705	0x0000e000
+
+/* Currently this is fixed. */
+#define PHY_ADDR		0x01
+
+/* Tigon3 specific PHY MII registers. */
+#define  TG3_BMCR_SPEED1000		0x0040
+
+#define MII_TG3_CTRL			0x09 /* 1000-baseT control register */
+#define  MII_TG3_CTRL_ADV_1000_HALF	0x0100
+#define  MII_TG3_CTRL_ADV_1000_FULL	0x0200
+#define  MII_TG3_CTRL_AS_MASTER		0x0800
+#define  MII_TG3_CTRL_ENABLE_AS_MASTER	0x1000
+
+#define MII_TG3_EXT_CTRL		0x10 /* Extended control register */
+#define  MII_TG3_EXT_CTRL_LNK3_LED_MODE	0x0002
+#define  MII_TG3_EXT_CTRL_TBI		0x8000
+
+#define MII_TG3_EXT_STAT		0x11 /* Extended status register */
+#define  MII_TG3_EXT_STAT_LPASS		0x0100
+
+#define MII_TG3_DSP_RW_PORT		0x15 /* DSP coefficient read/write port */
+
+#define MII_TG3_DSP_ADDRESS		0x17 /* DSP address register */
+
+#define MII_TG3_AUX_CTRL		0x18 /* auxilliary control register */
+
+#define MII_TG3_AUX_STAT		0x19 /* auxilliary status register */
+#define MII_TG3_AUX_STAT_LPASS		0x0004
+#define MII_TG3_AUX_STAT_SPDMASK	0x0700
+#define MII_TG3_AUX_STAT_10HALF		0x0100
+#define MII_TG3_AUX_STAT_10FULL		0x0200
+#define MII_TG3_AUX_STAT_100HALF	0x0300
+#define MII_TG3_AUX_STAT_100_4		0x0400
+#define MII_TG3_AUX_STAT_100FULL	0x0500
+#define MII_TG3_AUX_STAT_1000HALF	0x0600
+#define MII_TG3_AUX_STAT_1000FULL	0x0700
+
+#define MII_TG3_ISTAT			0x1a /* IRQ status register */
+#define MII_TG3_IMASK			0x1b /* IRQ mask register */
+
+/* ISTAT/IMASK event bits */
+#define MII_TG3_INT_LINKCHG		0x0002
+#define MII_TG3_INT_SPEEDCHG		0x0004
+#define MII_TG3_INT_DUPLEXCHG		0x0008
+#define MII_TG3_INT_ANEG_PAGE_RX	0x0400
+
+/* XXX Add this to mii.h */
+#ifndef ADVERTISE_PAUSE
+#define ADVERTISE_PAUSE_CAP		0x0400
+#endif
+#ifndef ADVERTISE_PAUSE_ASYM
+#define ADVERTISE_PAUSE_ASYM		0x0800
+#endif
+#ifndef LPA_PAUSE
+#define LPA_PAUSE_CAP			0x0400
+#endif
+#ifndef LPA_PAUSE_ASYM
+#define LPA_PAUSE_ASYM			0x0800
+#endif
+
+/* There are two ways to manage the TX descriptors on the tigon3.
+ * Either the descriptors are in host DMA'able memory, or they
+ * exist only in the cards on-chip SRAM.  All 16 send bds are under
+ * the same mode, they may not be configured individually.
+ *
+ * The mode we use is controlled by TG3_FLAG_HOST_TXDS in tp->tg3_flags.
+ *
+ * To use host memory TX descriptors:
+ *	1) Set GRC_MODE_HOST_SENDBDS in GRC_MODE register.
+ *	   Make sure GRC_MODE_4X_NIC_SEND_RINGS is clear.
+ *	2) Allocate DMA'able memory.
+ *	3) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
+ *	   a) Set TG3_BDINFO_HOST_ADDR to DMA address of memory
+ *	      obtained in step 2
+ *	   b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC.
+ *	   c) Set len field of TG3_BDINFO_MAXLEN_FLAGS to number
+ *            of TX descriptors.  Leave flags field clear.
+ *	4) Access TX descriptors via host memory.  The chip
+ *	   will refetch into local SRAM as needed when producer
+ *	   index mailboxes are updated.
+ *
+ * To use on-chip TX descriptors:
+ *	1) Set GRC_MODE_4X_NIC_SEND_RINGS in GRC_MODE register.
+ *	   Make sure GRC_MODE_HOST_SENDBDS is clear.
+ *	2) In NIC_SRAM_SEND_RCB (of desired index) of on-chip SRAM:
+ *	   a) Set TG3_BDINFO_HOST_ADDR to zero.
+ *	   b) Set TG3_BDINFO_NIC_ADDR to NIC_SRAM_TX_BUFFER_DESC
+ *	   c) TG3_BDINFO_MAXLEN_FLAGS is don't care.
+ *	3) Access TX descriptors directly in on-chip SRAM
+ *	   using normal {read,write}l().  (and not using
+ *         pointer dereferencing of ioremap()'d memory like
+ *	   the broken Broadcom driver does)
+ *
+ * Note that BDINFO_FLAGS_DISABLED should be set in the flags field of
+ * TG3_BDINFO_MAXLEN_FLAGS of all unused SEND_RCB indices.
+ */
+struct tg3_tx_buffer_desc {
+	uint32_t			addr_hi;
+	uint32_t			addr_lo;
+
+	uint32_t			len_flags;
+#define TXD_FLAG_TCPUDP_CSUM		0x0001
+#define TXD_FLAG_IP_CSUM		0x0002
+#define TXD_FLAG_END			0x0004
+#define TXD_FLAG_IP_FRAG		0x0008
+#define TXD_FLAG_IP_FRAG_END		0x0010
+#define TXD_FLAG_VLAN			0x0040
+#define TXD_FLAG_COAL_NOW		0x0080
+#define TXD_FLAG_CPU_PRE_DMA		0x0100
+#define TXD_FLAG_CPU_POST_DMA		0x0200
+#define TXD_FLAG_ADD_SRC_ADDR		0x1000
+#define TXD_FLAG_CHOOSE_SRC_ADDR	0x6000
+#define TXD_FLAG_NO_CRC			0x8000
+#define TXD_LEN_SHIFT			16
+
+	uint32_t			vlan_tag;
+#define TXD_VLAN_TAG_SHIFT		0
+#define TXD_MSS_SHIFT			16
+};
+
+#define TXD_ADDR			0x00UL /* 64-bit */
+#define TXD_LEN_FLAGS			0x08UL /* 32-bit (upper 16-bits are len) */
+#define TXD_VLAN_TAG			0x0cUL /* 32-bit (upper 16-bits are tag) */
+#define TXD_SIZE			0x10UL
+
+struct tg3_rx_buffer_desc {
+	uint32_t			addr_hi;
+	uint32_t			addr_lo;
+
+	uint32_t			idx_len;
+#define RXD_IDX_MASK	0xffff0000
+#define RXD_IDX_SHIFT	16
+#define RXD_LEN_MASK	0x0000ffff
+#define RXD_LEN_SHIFT	0
+
+	uint32_t			type_flags;
+#define RXD_TYPE_SHIFT	16
+#define RXD_FLAGS_SHIFT	0
+
+#define RXD_FLAG_END			0x0004
+#define RXD_FLAG_MINI			0x0800
+#define RXD_FLAG_JUMBO			0x0020
+#define RXD_FLAG_VLAN			0x0040
+#define RXD_FLAG_ERROR			0x0400
+#define RXD_FLAG_IP_CSUM		0x1000
+#define RXD_FLAG_TCPUDP_CSUM		0x2000
+#define RXD_FLAG_IS_TCP			0x4000
+
+	uint32_t			ip_tcp_csum;
+#define RXD_IPCSUM_MASK		0xffff0000
+#define RXD_IPCSUM_SHIFT	16
+#define RXD_TCPCSUM_MASK	0x0000ffff
+#define RXD_TCPCSUM_SHIFT	0
+
+	uint32_t			err_vlan;
+
+#define RXD_VLAN_MASK			0x0000ffff
+
+#define RXD_ERR_BAD_CRC			0x00010000
+#define RXD_ERR_COLLISION		0x00020000
+#define RXD_ERR_LINK_LOST		0x00040000
+#define RXD_ERR_PHY_DECODE		0x00080000
+#define RXD_ERR_ODD_NIBBLE_RCVD_MII	0x00100000
+#define RXD_ERR_MAC_ABRT		0x00200000
+#define RXD_ERR_TOO_SMALL		0x00400000
+#define RXD_ERR_NO_RESOURCES		0x00800000
+#define RXD_ERR_HUGE_FRAME		0x01000000
+#define RXD_ERR_MASK			0xffff0000
+
+	uint32_t			reserved;
+	uint32_t			opaque;
+#define RXD_OPAQUE_INDEX_MASK		0x0000ffff
+#define RXD_OPAQUE_INDEX_SHIFT		0
+#define RXD_OPAQUE_RING_STD		0x00010000
+#define RXD_OPAQUE_RING_JUMBO		0x00020000
+#define RXD_OPAQUE_RING_MINI		0x00040000
+#define RXD_OPAQUE_RING_MASK		0x00070000
+};
+
+struct tg3_ext_rx_buffer_desc {
+	struct {
+		uint32_t		addr_hi;
+		uint32_t		addr_lo;
+	}				addrlist[3];
+	uint32_t			len2_len1;
+	uint32_t			resv_len3;
+	struct tg3_rx_buffer_desc	std;
+};
+
+/* We only use this when testing out the DMA engine
+ * at probe time.  This is the internal format of buffer
+ * descriptors used by the chip at NIC_SRAM_DMA_DESCS.
+ */
+struct tg3_internal_buffer_desc {
+	uint32_t			addr_hi;
+	uint32_t			addr_lo;
+	uint32_t			nic_mbuf;
+	/* XXX FIX THIS */
+#if __BYTE_ORDER == __BIG_ENDIAN
+	uint16_t			cqid_sqid;
+	uint16_t			len;
+#else
+	uint16_t			len;
+	uint16_t			cqid_sqid;
+#endif
+	uint32_t			flags;
+	uint32_t			__cookie1;
+	uint32_t			__cookie2;
+	uint32_t			__cookie3;
+};
+
+#define TG3_HW_STATUS_SIZE		0x50
+struct tg3_hw_status {
+	uint32_t			status;
+#define SD_STATUS_UPDATED		0x00000001
+#define SD_STATUS_LINK_CHG		0x00000002
+#define SD_STATUS_ERROR			0x00000004
+
+	uint32_t			status_tag;
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+	uint16_t			rx_consumer;
+	uint16_t			rx_jumbo_consumer;
+#else
+	uint16_t			rx_jumbo_consumer;
+	uint16_t			rx_consumer;
+#endif
+
+#if __BYTE_ORDER ==  __BIG_ENDIAN
+	uint16_t			reserved;
+	uint16_t			rx_mini_consumer;
+#else
+	uint16_t			rx_mini_consumer;
+	uint16_t			reserved;
+#endif
+	struct {
+#if __BYTE_ORDER ==  __BIG_ENDIAN
+		uint16_t		tx_consumer;
+		uint16_t		rx_producer;
+#else
+		uint16_t		rx_producer;
+		uint16_t		tx_consumer;
+#endif
+	}				idx[16];
+};
+
+typedef struct {
+	uint32_t high, low;
+} tg3_stat64_t;
+
+struct tg3_hw_stats {
+	uint8_t				__reserved0[0x400-0x300];
+
+	/* Statistics maintained by Receive MAC. */
+	tg3_stat64_t			rx_octets;
+	uint64_t			__reserved1;
+	tg3_stat64_t			rx_fragments;
+	tg3_stat64_t			rx_ucast_packets;
+	tg3_stat64_t			rx_mcast_packets;
+	tg3_stat64_t			rx_bcast_packets;
+	tg3_stat64_t			rx_fcs_errors;
+	tg3_stat64_t			rx_align_errors;
+	tg3_stat64_t			rx_xon_pause_rcvd;
+	tg3_stat64_t			rx_xoff_pause_rcvd;
+	tg3_stat64_t			rx_mac_ctrl_rcvd;
+	tg3_stat64_t			rx_xoff_entered;
+	tg3_stat64_t			rx_frame_too_long_errors;
+	tg3_stat64_t			rx_jabbers;
+	tg3_stat64_t			rx_undersize_packets;
+	tg3_stat64_t			rx_in_length_errors;
+	tg3_stat64_t			rx_out_length_errors;
+	tg3_stat64_t			rx_64_or_less_octet_packets;
+	tg3_stat64_t			rx_65_to_127_octet_packets;
+	tg3_stat64_t			rx_128_to_255_octet_packets;
+	tg3_stat64_t			rx_256_to_511_octet_packets;
+	tg3_stat64_t			rx_512_to_1023_octet_packets;
+	tg3_stat64_t			rx_1024_to_1522_octet_packets;
+	tg3_stat64_t			rx_1523_to_2047_octet_packets;
+	tg3_stat64_t			rx_2048_to_4095_octet_packets;
+	tg3_stat64_t			rx_4096_to_8191_octet_packets;
+	tg3_stat64_t			rx_8192_to_9022_octet_packets;
+
+	uint64_t			__unused0[37];
+
+	/* Statistics maintained by Transmit MAC. */
+	tg3_stat64_t			tx_octets;
+	uint64_t			__reserved2;
+	tg3_stat64_t			tx_collisions;
+	tg3_stat64_t			tx_xon_sent;
+	tg3_stat64_t			tx_xoff_sent;
+	tg3_stat64_t			tx_flow_control;
+	tg3_stat64_t			tx_mac_errors;
+	tg3_stat64_t			tx_single_collisions;
+	tg3_stat64_t			tx_mult_collisions;
+	tg3_stat64_t			tx_deferred;
+	uint64_t			__reserved3;
+	tg3_stat64_t			tx_excessive_collisions;
+	tg3_stat64_t			tx_late_collisions;
+	tg3_stat64_t			tx_collide_2times;
+	tg3_stat64_t			tx_collide_3times;
+	tg3_stat64_t			tx_collide_4times;
+	tg3_stat64_t			tx_collide_5times;
+	tg3_stat64_t			tx_collide_6times;
+	tg3_stat64_t			tx_collide_7times;
+	tg3_stat64_t			tx_collide_8times;
+	tg3_stat64_t			tx_collide_9times;
+	tg3_stat64_t			tx_collide_10times;
+	tg3_stat64_t			tx_collide_11times;
+	tg3_stat64_t			tx_collide_12times;
+	tg3_stat64_t			tx_collide_13times;
+	tg3_stat64_t			tx_collide_14times;
+	tg3_stat64_t			tx_collide_15times;
+	tg3_stat64_t			tx_ucast_packets;
+	tg3_stat64_t			tx_mcast_packets;
+	tg3_stat64_t			tx_bcast_packets;
+	tg3_stat64_t			tx_carrier_sense_errors;
+	tg3_stat64_t			tx_discards;
+	tg3_stat64_t			tx_errors;
+
+	uint64_t			__unused1[31];
+
+	/* Statistics maintained by Receive List Placement. */
+	tg3_stat64_t			COS_rx_packets[16];
+	tg3_stat64_t			COS_rx_filter_dropped;
+	tg3_stat64_t			dma_writeq_full;
+	tg3_stat64_t			dma_write_prioq_full;
+	tg3_stat64_t			rxbds_empty;
+	tg3_stat64_t			rx_discards;
+	tg3_stat64_t			rx_errors;
+	tg3_stat64_t			rx_threshold_hit;
+
+	uint64_t			__unused2[9];
+
+	/* Statistics maintained by Send Data Initiator. */
+	tg3_stat64_t			COS_out_packets[16];
+	tg3_stat64_t			dma_readq_full;
+	tg3_stat64_t			dma_read_prioq_full;
+	tg3_stat64_t			tx_comp_queue_full;
+
+	/* Statistics maintained by Host Coalescing. */
+	tg3_stat64_t			ring_set_send_prod_index;
+	tg3_stat64_t			ring_status_update;
+	tg3_stat64_t			nic_irqs;
+	tg3_stat64_t			nic_avoided_irqs;
+	tg3_stat64_t			nic_tx_threshold_hit;
+
+	uint8_t				__reserved4[0xb00-0x9c0];
+};
+
+enum phy_led_mode {
+	led_mode_auto,
+	led_mode_three_link,
+	led_mode_link10
+};
+
+#if 0
+/* 'mapping' is superfluous as the chip does not write into
+ * the tx/rx post rings so we could just fetch it from there.
+ * But the cache behavior is better how we are doing it now.
+ */
+struct ring_info {
+	struct sk_buff			*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+};
+
+struct tx_ring_info {
+	struct sk_buff			*skb;
+	DECLARE_PCI_UNMAP_ADDR(mapping)
+	uint32_t			prev_vlan_tag;
+};
+#endif
+
+struct tg3_config_info {
+	uint32_t			flags;
+};
+
+struct tg3_link_config {
+	/* Describes what we're trying to get. */
+	uint32_t			advertising;
+#if 0
+	uint16_t			speed;
+	uint8_t				duplex;
+	uint8_t				autoneg;
+#define SPEED_INVALID		0xffff
+#define DUPLEX_INVALID		0xff
+#define AUTONEG_INVALID		0xff
+#endif
+
+	/* Describes what we actually have. */
+	uint8_t				active_speed;
+	uint8_t				active_duplex;
+
+	/* When we go in and out of low power mode we need
+	 * to swap with this state.
+	 */
+#if 0
+	int				phy_is_low_power;
+	uint16_t			orig_speed;
+	uint8_t				orig_duplex;
+	uint8_t				orig_autoneg;
+#endif
+};
+
+struct tg3_bufmgr_config {
+	uint32_t		mbuf_read_dma_low_water;
+	uint32_t		mbuf_mac_rx_low_water;
+	uint32_t		mbuf_high_water;
+
+	uint32_t		mbuf_read_dma_low_water_jumbo;
+	uint32_t		mbuf_mac_rx_low_water_jumbo;
+	uint32_t		mbuf_high_water_jumbo;
+
+	uint32_t		dma_low_water;
+	uint32_t		dma_high_water;
+};
+
+struct tg3 {
+#if 0
+	/* SMP locking strategy:
+	 *
+	 * lock: Held during all operations except TX packet
+	 *       processing.
+	 *
+	 * tx_lock: Held during tg3_start_xmit{,_4gbug} and tg3_tx
+	 *
+	 * If you want to shut up all asynchronous processing you must
+	 * acquire both locks, 'lock' taken before 'tx_lock'.  IRQs must
+	 * be disabled to take 'lock' but only softirq disabling is
+	 * necessary for acquisition of 'tx_lock'.
+	 */
+	spinlock_t			lock;
+	spinlock_t			tx_lock;
+#endif
+
+	uint32_t			tx_prod;
+#if 0
+	uint32_t			tx_cons;
+#endif
+	uint32_t			rx_rcb_ptr;
+	uint32_t			rx_std_ptr;
+#if 0
+	uint32_t			rx_jumbo_ptr;
+	spinlock_t			indirect_lock;
+
+	struct net_device_stats		net_stats;
+	struct net_device_stats		net_stats_prev;
+#endif
+	unsigned long			phy_crc_errors;
+
+#if 0
+	uint32_t			rx_offset;
+#endif
+	uint32_t			tg3_flags;
+#if 0
+#define TG3_FLAG_HOST_TXDS		0x00000001
+#endif
+#define TG3_FLAG_TXD_MBOX_HWBUG		0x00000002
+#define TG3_FLAG_RX_CHECKSUMS		0x00000004
+#define TG3_FLAG_USE_LINKCHG_REG	0x00000008
+#define TG3_FLAG_USE_MI_INTERRUPT	0x00000010
+#define TG3_FLAG_ENABLE_ASF		0x00000020
+#define TG3_FLAG_5701_REG_WRITE_BUG	0x00000040
+#define TG3_FLAG_POLL_SERDES		0x00000080
+#define TG3_FLAG_MBOX_WRITE_REORDER	0x00000100
+#define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
+#define TG3_FLAG_WOL_SPEED_100MB	0x00000400
+#define TG3_FLAG_WOL_ENABLE		0x00000800
+#define TG3_FLAG_EEPROM_WRITE_PROT	0x00001000
+#define TG3_FLAG_NVRAM			0x00002000
+#define TG3_FLAG_NVRAM_BUFFERED		0x00004000
+#define TG3_FLAG_RX_PAUSE		0x00008000
+#define TG3_FLAG_TX_PAUSE		0x00010000
+#define TG3_FLAG_PCIX_MODE		0x00020000
+#define TG3_FLAG_PCI_HIGH_SPEED		0x00040000
+#define TG3_FLAG_PCI_32BIT		0x00080000
+#define TG3_FLAG_NO_TX_PSEUDO_CSUM	0x00100000
+#define TG3_FLAG_NO_RX_PSEUDO_CSUM	0x00200000
+#define TG3_FLAG_SERDES_WOL_CAP		0x00400000
+#define TG3_FLAG_JUMBO_ENABLE		0x00800000
+#define TG3_FLAG_10_100_ONLY		0x01000000
+#define TG3_FLAG_PAUSE_AUTONEG		0x02000000
+#define TG3_FLAG_PAUSE_RX		0x04000000
+#define TG3_FLAG_PAUSE_TX		0x08000000
+#define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
+#define TG3_FLAG_GOT_SERDES_FLOWCTL	0x20000000
+#define TG3_FLAG_SPLIT_MODE		0x40000000
+#define TG3_FLAG_INIT_COMPLETE		0x80000000
+
+	uint32_t			tg3_flags2;
+#define TG3_FLG2_RESTART_TIMER		0x00000001
+#define TG3_FLG2_SUN_5704		0x00000002
+#define TG3_FLG2_NO_ETH_WIRE_SPEED	0x00000004
+#define TG3_FLG2_IS_5788		0x00000008
+#define TG3_FLG2_MAX_RXPEND_64		0x00000010
+#define TG3_FLG2_TSO_CAPABLE		0x00000020
+  // Alf: Hope I'm not breaking anything here !
+#define TG3_FLG2_PCI_EXPRESS            0x00000040
+
+
+
+	uint32_t			split_mode_max_reqs;
+#define SPLIT_MODE_5704_MAX_REQ		3
+
+#if 0
+	struct timer_list		timer;
+	uint16_t			timer_counter;
+	uint16_t			timer_multiplier;
+	uint32_t			timer_offset;
+	uint16_t			asf_counter;
+	uint16_t			asf_multiplier;
+#endif
+
+	struct tg3_link_config		link_config;
+	struct tg3_bufmgr_config	bufmgr_config;
+
+#if 0
+	uint32_t			rx_pending;
+	uint32_t			rx_jumbo_pending;
+	uint32_t			tx_pending;
+#endif
+
+	/* cache h/w values, often passed straight to h/w */
+	uint32_t			rx_mode;
+	uint32_t			tx_mode;
+	uint32_t			mac_mode;
+	uint32_t			mi_mode;
+	uint32_t			misc_host_ctrl;
+	uint32_t			grc_mode;
+	uint32_t			grc_local_ctrl;
+	uint32_t			dma_rwctrl;
+#if 0
+	uint32_t			coalesce_mode;
+#endif
+
+	/* PCI block */
+	uint16_t			pci_chip_rev_id;
+#if 0
+	uint8_t				pci_cacheline_sz;
+	uint8_t				pci_lat_timer;
+	uint8_t				pci_hdr_type;
+	uint8_t				pci_bist;
+#endif
+	uint32_t			pci_cfg_state[64 / sizeof(uint32_t)];
+
+	int				pm_cap;
+
+	/* PHY info */
+	uint32_t			phy_id;
+#define PHY_ID_MASK			0xfffffff0
+#define PHY_ID_BCM5400			0x60008040
+#define PHY_ID_BCM5401			0x60008050
+#define PHY_ID_BCM5411			0x60008070
+#define PHY_ID_BCM5701			0x60008110
+#define PHY_ID_BCM5703			0x60008160
+#define PHY_ID_BCM5704			0x60008190
+#define PHY_ID_BCM5705			0x600081a0
+#define PHY_ID_BCM5750                  0x60008180
+#define PHY_ID_BCM8002			0x60010140
+#define PHY_ID_BCM5751			0x00206180
+#define PHY_ID_SERDES			0xfeedbee0
+#define PHY_ID_INVALID			0xffffffff
+#define PHY_ID_REV_MASK			0x0000000f
+#define PHY_REV_BCM5401_B0		0x1
+#define PHY_REV_BCM5401_B2		0x3
+#define PHY_REV_BCM5401_C0		0x6
+#define PHY_REV_BCM5411_X0		0x1 /* Found on Netgear GA302T */
+
+	enum phy_led_mode		led_mode;
+
+	char				board_part_number[24];
+	uint32_t			nic_sram_data_cfg;
+	uint32_t			pci_clock_ctrl;
+#if 0
+	struct pci_device		*pdev_peer;
+#endif
+
+	/* This macro assumes the passed PHY ID is already masked
+	 * with PHY_ID_MASK.
+	 */
+#define KNOWN_PHY_ID(X)		\
+	((X) == PHY_ID_BCM5400 || (X) == PHY_ID_BCM5401 || \
+	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
+	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
+	 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || (X) == PHY_ID_BCM5751 || \
+	 (X) == PHY_ID_BCM8002 || (X) == PHY_ID_SERDES)
+
+	unsigned long			regs;
+	struct pci_device		*pdev;
+	struct nic			*nic;
+#if 0
+	struct net_device		*dev;
+#endif
+#if defined(TG3_VLAN_TAG_USED)
+	struct vlan_group		*vlgrp;
+#endif
+
+	struct tg3_rx_buffer_desc	*rx_std;
+#if 0
+	struct ring_info		*rx_std_buffers;
+	dma_addr_t			rx_std_mapping;
+	struct tg3_rx_buffer_desc	*rx_jumbo;
+	struct ring_info		*rx_jumbo_buffers;
+	dma_addr_t			rx_jumbo_mapping;
+#endif
+
+	struct tg3_rx_buffer_desc	*rx_rcb;
+#if 0
+	dma_addr_t			rx_rcb_mapping;
+#endif
+
+	/* TX descs are only used if TG3_FLAG_HOST_TXDS is set. */
+	struct tg3_tx_buffer_desc	*tx_ring;
+#if 0
+	struct tx_ring_info		*tx_buffers;
+	dma_addr_t			tx_desc_mapping;
+#endif
+
+	struct tg3_hw_status		*hw_status;
+#if 0
+	dma_addr_t			status_mapping;
+#endif
+#if 0
+	uint32_t			msg_enable;
+#endif
+
+	struct tg3_hw_stats		*hw_stats;
+#if 0
+	dma_addr_t			stats_mapping;
+#endif
+
+	int				carrier_ok;
+	uint16_t			subsystem_vendor;
+	uint16_t			subsystem_device;
+};
+
+#endif /* !(_T3_H) */
