bug-grub
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Resumo release new patch and it's idea.


From: Takashi Ikebe
Subject: Resumo release new patch and it's idea.
Date: Fri, 22 Apr 2005 17:07:57 +0900
User-agent: Mozilla Thunderbird 1.0.2 (Windows/20050317)

Hello, okuji-san and all,
The resumo project which implements Carrier Grade Linux function
releases new version of patch.
The URL is http://resumo.sourceforge.net
The patch includes following functions;
o Boot image fallback
o Boot cycle detection
o Remote management notification

The above two functions are already implemented in Grub 0.96, so it's
duplicated.
We will fit out commands to grub 0.96 based fallback functions.

The last function is new one, which notify the system error to remote
management system by using netboot function.
We also add new gigabit network interface drivers(intel e1000 and
broadcom tg3) which commonly used on recent computers from netboot.
The remote management node's software and other tools are provided on
resumo project homepage, please take a look.

Thank you.

-- 
Takashi Ikebe
NTT Network Service Systems Laboratories
9-11, Midori-Cho 3-Chome Musashino-Shi,
Tokyo 180-8585 Japan
Tel : +81 422 59 4246, Fax : +81 422 60 4012
e-mail : address@hidden

diff -urpN grub-0.96/configure resumo-0.96/configure
--- grub-0.96/configure 2005-01-30 10:03:40.000000000 +0900
+++ resumo-0.96/configure       2005-04-19 20:34:49.000000000 +0900
@@ -5,6 +5,7 @@
 # Report bugs to <address@hidden>.
 #
 # Copyright (C) 2003 Free Software Foundation, Inc.
+# Copyright (C) 2004-2005 NTT Corporation
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
 ## --------------------- ##
@@ -903,6 +904,8 @@ Optional Features:
   --enable-tulip          enable Tulip driver
   --enable-via-rhine      enable Rhine-I/II driver
   --enable-w89c840        enable Winbond W89c840, Compex RL100-ATX driver
+  --enable-e1000          enable EtherExpressPro1000 driver
+  --enable-tg3            enable Broadcom Tigon3 ethernet driver
   --enable-3c503-shmem    use 3c503 shared memory mode
   --enable-3c503-aui      use AUI by default on 3c503 cards
   --enable-compex-rl2000-fix
@@ -5869,6 +5872,25 @@ if test "x$enable_w89c840" = xyes; then
   NETBOOT_DRIVERS="$NETBOOT_DRIVERS w89c840.o"
 fi
 
+# Check whether --enable-e1000 or --disable-e1000 was given.
+if test "${enable_e1000+set}" = set; then
+  enableval="$enable_e1000"
+
+fi;
+if test "x$enable_e1000" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_E1000=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS e1000.o"
+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=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
+fi
 
 
 if test "x$NET_CFLAGS" != x; then
diff -urpN grub-0.96/configure.ac resumo-0.96/configure.ac
--- grub-0.96/configure.ac      2005-01-30 10:02:32.000000000 +0900
+++ resumo-0.96/configure.ac    2005-04-19 20:38:34.000000000 +0900
@@ -1,5 +1,6 @@
 dnl Configure script for GRUB.
 dnl Copyright 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+dnl Copyright (C) 2004-2005 NTT Corporation
 
 dnl Permission to use, copy, modify and distribute this software and its
 dnl documentation is hereby granted, provided that both the copyright
@@ -544,6 +545,20 @@ if test "x$enable_w89c840" = xyes; then
   NETBOOT_DRIVERS="$NETBOOT_DRIVERS w89c840.o"
 fi
 
+AC_ARG_ENABLE(e1000,
+  [  --enable-e1000       enable EtherexpressPro1000 driver])
+if test "x$enable_e1000" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_E1000=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS e1000.o"
+fi
+
+AC_ARG_ENABLE(tg3,
+  [  --enable-tg3       enable Broadcom Tigon3 ethernet driver])
+if test "x$enable_tg3" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TG3=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tg3.o"
+fi
+
 dnl Check if the netboot support is turned on.
 AM_CONDITIONAL(NETBOOT_SUPPORT, test "x$NET_CFLAGS" != x)
 if test "x$NET_CFLAGS" != x; then
diff -urpN grub-0.96/grub/Makefile.in resumo-0.96/grub/Makefile.in
--- grub-0.96/grub/Makefile.in  2005-01-30 10:07:36.000000000 +0900
+++ resumo-0.96/grub/Makefile.in        2005-04-19 20:34:49.000000000 +0900
@@ -105,7 +105,7 @@ INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -static
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LTLIBOBJS = @LTLIBOBJS@
diff -urpN grub-0.96/netboot/Makefile.am resumo-0.96/netboot/Makefile.am
--- grub-0.96/netboot/Makefile.am       2003-07-09 20:45:37.000000000 +0900
+++ resumo-0.96/netboot/Makefile.am     2005-04-19 20:34:49.000000000 +0900
@@ -18,7 +18,8 @@ EXTRA_libdrivers_a_SOURCES = 3c509.c 3c5
        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 \
+       e1000.c e1000_hw.h tg3.c tg3.h
 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
        -DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
 # Filled by configure.
@@ -56,6 +57,8 @@ tiara_drivers = tiara.o
 tulip_drivers = tulip.o
 via_rhine_drivers = via_rhine.o
 w89c840_drivers = w89c840.o
+e1000_drivers = e1000.o
+tg3_drivers = tg3.o
 
 # Is it really necessary to specify dependecies explicitly?
 $(3c509_drivers): 3c509.c 3c509.h
@@ -183,6 +186,16 @@ $(w89c840_drivers): %.o: w89c840.c
        $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
          $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
 
+$(e1000_drivers): e1000.c e1000_hw.h
+$(e1000_drivers): %.o: e1000.c
+       $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+         $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tg3_drivers): tg3.c tg3.h
+$(tg3_drivers): %.o: tg3.c
+       $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+         $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
 # Per-object flags.
 3c509_o_CFLAGS = -DINCLUDE_3C509=1
 3c529_o_CFLAGS = -DINCLUDE_3C529=1
@@ -217,3 +230,5 @@ tiara_o_CFLAGS = -DINCLUDE_TIARA=1
 tulip_o_CFLAGS = -DINCLUDE_TULIP=1
 via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
 w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
+e1000_o_CFLAGS = -DINCLUDE_E1000=1
+tg3_o_CFLAGS = -DINCLUDE_TG3=1
diff -urpN grub-0.96/netboot/Makefile.in resumo-0.96/netboot/Makefile.in
--- grub-0.96/netboot/Makefile.in       2005-01-30 10:07:38.000000000 +0900
+++ resumo-0.96/netboot/Makefile.in     2005-04-19 20:34:49.000000000 +0900
@@ -89,7 +89,9 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@   ./$(DEPDIR)/libdrivers_a-tlan.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/libdrivers_a-tulip.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/libdrivers_a-via-rhine.Po \
address@hidden@ ./$(DEPDIR)/libdrivers_a-w89c840.Po
address@hidden@ ./$(DEPDIR)/libdrivers_a-w89c840.Po \
address@hidden@ ./$(DEPDIR)/libdrivers_a-e1000.Po \
address@hidden@ ./$(DEPDIR)/libdrivers_a-tg3.Po
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -223,7 +225,8 @@ EXTRA_libdrivers_a_SOURCES = 3c509.c 3c5
        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 \
+       e1000.c e1000_hw.h tg3.c tg3.h
 
 libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
        -DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
@@ -262,6 +265,8 @@ tiara_drivers = tiara.o
 tulip_drivers = tulip.o
 via_rhine_drivers = via_rhine.o
 w89c840_drivers = w89c840.o
+e1000_drivers = e1000.o
+tg3_drivers = tg3.o
 
 # Per-object flags.
 3c509_o_CFLAGS = -DINCLUDE_3C509=1
@@ -297,6 +302,8 @@ tiara_o_CFLAGS = -DINCLUDE_TIARA=1
 tulip_o_CFLAGS = -DINCLUDE_TULIP=1
 via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
 w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
+e1000_o_CFLAGS = -DINCLUDE_E1000=1
+tg3_o_CFLAGS = -DINCLUDE_TG3=1
 all: all-am
 
 .SUFFIXES:
@@ -375,6 +382,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 
 .c.o:
 @am__fastdepCC_TRUE@   if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c 
-o $@ $<; \
@@ -887,6 +896,39 @@ libdrivers_a-w89c840.obj: w89c840.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      
depfile='$(DEPDIR)/libdrivers_a-w89c840.Po' 
tmpdepfile='$(DEPDIR)/libdrivers_a-w89c840.TPo' @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o 
libdrivers_a-w89c840.obj `if test -f 'w89c840.c'; then $(CYGPATH_W) 
'w89c840.c'; else $(CYGPATH_W) '$(srcdir)/w89c840.c'; fi`
+
+libdrivers_a-e1000.o: e1000.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-e1000.o -MD -MP 
-MF "$(DEPDIR)/libdrivers_a-e1000.Tpo" -c -o libdrivers_a-e1000.o `test -f 
'e1000.c' || echo '$(srcdir)/'`e1000.c; \
address@hidden@ then mv -f "$(DEPDIR)/libdrivers_a-e1000.Tpo" 
"$(DEPDIR)/libdrivers_a-e1000.Po"; else rm -f 
"$(DEPDIR)/libdrivers_a-e1000.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='e1000.c' 
object='libdrivers_a-e1000.o' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/libdrivers_a-e1000.Po' 
tmpdepfile='$(DEPDIR)/libdrivers_a-e1000.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-e1000.o `test 
-f 'e1000.c' || echo '$(srcdir)/'`e1000.c
+
+libdrivers_a-e1000.obj: e1000.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-e1000.obj -MD -MP 
-MF "$(DEPDIR)/libdrivers_a-e1000.Tpo" -c -o libdrivers_a-e1000.obj `if test -f 
'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) '$(srcdir)/e1000.c'; 
fi`; \
address@hidden@ then mv -f "$(DEPDIR)/libdrivers_a-e1000.Tpo" 
"$(DEPDIR)/libdrivers_a-e1000.Po"; else rm -f 
"$(DEPDIR)/libdrivers_a-e1000.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='e1000.c' 
object='libdrivers_a-e1000.obj' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/libdrivers_a-e1000.Po' 
tmpdepfile='$(DEPDIR)/libdrivers_a-e1000.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-e1000.obj `if 
test -f 'e1000.c'; then $(CYGPATH_W) 'e1000.c'; else $(CYGPATH_W) 
'$(srcdir)/e1000.c'; fi`
+
+libdrivers_a-tg3.o: tg3.c
address@hidden@ 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; \
address@hidden@ then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" 
"$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; 
exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='tg3.c' 
object='libdrivers_a-tg3.o' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    depfile='$(DEPDIR)/libdrivers_a-tg3.Po' 
tmpdepfile='$(DEPDIR)/libdrivers_a-tg3.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(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
address@hidden@ 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`; \
address@hidden@ then mv -f "$(DEPDIR)/libdrivers_a-tg3.Tpo" 
"$(DEPDIR)/libdrivers_a-tg3.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tg3.Tpo"; 
exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='tg3.c' 
object='libdrivers_a-tg3.obj' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    depfile='$(DEPDIR)/libdrivers_a-tg3.Po' 
tmpdepfile='$(DEPDIR)/libdrivers_a-tg3.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(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`
+
 uninstall-info-am:
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -1178,6 +1220,17 @@ $(w89c840_drivers): w89c840.c
 $(w89c840_drivers): %.o: w89c840.c
        $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
          $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(e1000_drivers): e1000.c e1000_hw.h
+$(e1000_drivers): %.o: e1000.c
+       $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+         $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tg3_drivers): tg3.c tg3.h
+$(tg3_drivers): %.o: tg3.c
+       $(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+         $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff -urpN grub-0.96/netboot/cards.h resumo-0.96/netboot/cards.h
--- grub-0.96/netboot/cards.h   2003-07-09 20:45:37.000000000 +0900
+++ resumo-0.96/netboot/cards.h 2005-04-19 20:34:49.000000000 +0900
@@ -6,6 +6,7 @@
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2, or (at
  * your option) any later version.
+ * Copyright (C) 2004-2005 NTT Corporation
  */
 
 #include "nic.h"
@@ -180,4 +181,18 @@ extern struct nic  *tlan_probe(struct nic
         PCI_ARG(struct pci_device *));
 #endif
 
+/*!!!!!!!!!! START E1000 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_E1000
+extern struct nic      *e1000_probe(struct nic *, unsigned short *
+       PCI_ARG(struct pci_device *));
+#endif
+/*!!!!!!!!!!! END E1000 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_TG3
+extern struct nic      *tg3_probe(struct nic *, unsigned short *
+       PCI_ARG(struct pci_device *));
+#endif
+/*!!!!!!!!!!! END TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 #endif /* CARDS_H */
diff -urpN grub-0.96/netboot/config.c resumo-0.96/netboot/config.c
--- grub-0.96/netboot/config.c  2003-07-09 20:45:37.000000000 +0900
+++ resumo-0.96/netboot/config.c        2005-04-19 20:34:49.000000000 +0900
@@ -1,6 +1,7 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -31,7 +32,10 @@
 #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)
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Update !!!!!!!!!!*/
+//#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_E1000) 
|| defined(INCLUDE_TG3)
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Update !!!!!!!!!!!*/
        /* || others later */
 # define INCLUDE_PCI
 # include <pci.h>
@@ -218,6 +222,126 @@ static struct pci_device pci_nic_list[] 
     "OC2326", 0, 0, 0, 0},
 #endif
 
+/*!!!!!!!!!! START E1000 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_E1000
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82542,
+    "Intel EtherExpressPro1000", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82543GC_FIBER,
+    "Intel EtherExpressPro1000 82543GC Fiber", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82543GC_COPPER,
+    "Intel EtherExpressPro1000 82543GC Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82544EI_COPPER,
+    "Intel EtherExpressPro1000 82544EI Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82544EI_FIBER,
+    "Intel EtherExpressPro1000 82544EI Fiber", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82544GC_COPPER,
+    "Intel EtherExpressPro1000 82544GC Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82544GC_LOM,
+    "Intel EtherExpressPro1000 82544GC LOM", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82540EM,
+    "Intel EtherExpressPro1000 82540EM", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82540EM_LOM,
+    "Intel EtherExpressPro1000 82540EM LOM", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82540EP_LOM,
+    "Intel EtherExpressPro1000 82540EP LOM", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82540EP,
+    "Intel EtherExpressPro1000 82540EP", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82540EP_LP,
+    "Intel EtherExpressPro1000 82540EP LP", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82545EM_COPPER,
+    "Intel EtherExpressPro1000 82545EM Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82545EM_FIBER,
+    "Intel EtherExpressPro1000 82545EM Fiber", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82545GM_COPPER,
+    "Intel EtherExpressPro1000 82545GM Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82545GM_FIBER,
+    "Intel EtherExpressPro1000 82545GM Fiber", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82545GM_SERDES,
+    "Intel EtherExpressPro1000 82545GM SERDES", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546EB_COPPER,
+    "Intel EtherExpressPro1000 82546EB Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546EB_FIBER,
+    "Intel EtherExpressPro1000 82546EB Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546EB_QUAD_COPPER,
+    "Intel EtherExpressPro1000 82546EB Quad Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82541EI,
+    "Intel EtherExpressPro1000 82541EI", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82541EI_MOBILE,
+    "Intel EtherExpressPro1000 82541EP", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82541ER,
+    "Intel EtherExpressPro1000 82541ER", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82547GI,
+    "Intel EtherExpressPro1000 82547GI", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82541GI,
+    "Intel EtherExpressPro1000 82541GI", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82541GI_MOBILE,
+    "Intel EtherExpressPro1000 82541GI Mobile", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546GB_COPPER,
+    "Intel EtherExpressPro1000 82546GB Copper", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546GB_FIBER,
+    "Intel EtherExpressPro1000 82546GB Fiber", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82546GB_SERDES,
+    "Intel EtherExpressPro1000 82546GB SERDES", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,       E1000_DEV_ID_82547EI,
+    "Intel EtherExpressPro1000 82547EI", 0, 0, 0, 0},
+#endif
+/*!!!!!!!!!!! END E1000 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_TG3
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5700,
+    "Broadcom Tigon 3 5700", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5701,
+    "Broadcom Tigon 3 5701", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5702,
+    "Broadcom Tigon 3 5702", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5703,
+    "Broadcom Tigon 3 5703", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5704,
+    "Broadcom Tigon 3 5704", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5702FE,
+    "Broadcom Tigon 3 5702FE", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5705,
+    "Broadcom Tigon 3 5705", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5705_2,
+    "Broadcom Tigon 3 5705_2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5705M,
+    "Broadcom Tigon 3 5705M", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5705M_2,
+    "Broadcom Tigon 3 5705M_2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5782,
+    "Broadcom Tigon 3 5782", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5788,
+    "Broadcom Tigon 3 5788", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5702X,
+    "Broadcom Tigon 3 5702X", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5703X,
+    "Broadcom Tigon 3 5703X", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5704S,
+    "Broadcom Tigon 3 5704S", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5702A3,
+    "Broadcom Tigon 3 5702A3", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5703A3,
+    "Broadcom Tigon 3 5703A3", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5901,
+    "Broadcom Tigon 3 5901", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_BROADCOM,    PCI_DEVICE_ID_TIGON3_5901_2,
+    "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
+/*!!!!!!!!!!! END TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
   /* other PCI NICs go here */
   {0, 0, NULL, 0, 0, 0, 0}
 };
@@ -339,6 +463,69 @@ static struct pci_dispatch_table PCI_NIC
 # ifdef INCLUDE_TLAN
   { PCI_VENDOR_ID_OLICOM,   PCI_DEVICE_ID_OLICOM_OC2326,   tlan_probe },
 # endif /* INCLUDE_TLAN */
+/*!!!!!!!!!! START E1000 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_E1000
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82542,               e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82543GC_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82543GC_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82544EI_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82544EI_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82544GC_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82544GC_LOM,         e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82540EM,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82540EM_LOM,         e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82540EP_LOM,         e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82540EP,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82540EP_LP,          e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82545EM_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82545EM_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82545GM_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82545GM_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82545GM_SERDES,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546EB_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546EB_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546EB_QUAD_COPPER, e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82541EI,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82541EI_MOBILE,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82541ER,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82547GI,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82541GI,             e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82541GI_MOBILE,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546GB_COPPER,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546GB_FIBER,       e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82546GB_SERDES,      e1000_probe },
+  { PCI_VENDOR_ID_INTEL,    E1000_DEV_ID_82547EI,             e1000_probe },
+#endif /* INCLUDE_E1000 */
+/*!!!!!!!!!!! END E1000 (GRUB-CGL) Addition !!!!!!!!!!!*/
+/*!!!!!!!!!! START TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_TG3
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5700,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5701,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5702,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5703,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5704,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5702FE,  tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5705,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5705_2,  tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5705M,   tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5705M_2, tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5782,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5788,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5702X,   tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5703X,   tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5704S,   tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5702A3,  tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5703A3,  tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5901,    tg3_probe },
+  { PCI_VENDOR_ID_BROADCOM,   PCI_DEVICE_ID_TIGON3_5901_2,  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 /* INCLUDE_TG3 */
+/*!!!!!!!!!!! END TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
   { 0,                      0,                             0 }
 };
 #endif /* GRUB && INCLUDE_PCI */
@@ -458,6 +645,16 @@ static struct dispatch_table       NIC[] =
 #ifdef INCLUDE_TLAN
   { "Olicom 2326", tlan_probe, pci_ioaddrs },
 #endif
+/*!!!!!!!!!! START E1000 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_E1000
+  { "E1000", e1000_probe, pci_ioaddrs },
+#endif
+/*!!!!!!!!!!! END E1000 (GRUB-CGL) Addition !!!!!!!!!!!*/
+/*!!!!!!!!!! START TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef INCLUDE_TG3
+  { "TG3", tg3_probe, pci_ioaddrs },
+#endif
+/*!!!!!!!!!!! END TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
   /* this entry must always be last to mark the end of list */
   { 0, 0, 0 }
 };
diff -urpN grub-0.96/netboot/e1000.c resumo-0.96/netboot/e1000.c
--- grub-0.96/netboot/e1000.c   1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/netboot/e1000.c 2005-04-19 21:18:11.000000000 +0900
@@ -0,0 +1,3758 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+Inter Pro 1000 for Etherboot
+Drivers are port from Intel's Linux driver e1000-4.3.15
+
+***************************************************************************/
+/*******************************************************************************
+
+  
+  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+  
+  This program is free software; you can redistribute it and/or modify it 
+  under the terms of the GNU General Public License as published by the Free 
+  Software Foundation; either version 2 of the License, or (at your option) 
+  any later version.
+  
+  This program is distributed in the hope that it will be useful, but WITHOUT 
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  more details.
+  
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59 
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+  
+  Contact Information:
+  Linux NICS <address@hidden>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+/*
+ *  Copyright (C) Archway Digital Solutions.
+ *
+ *  written by Chrsitopher Li <cli at arcyway dot com> or <chrisl at gnuchina 
dot org>
+ *  2/9/2002
+ *
+ *  Copyright (C) Linux Networx.
+ *  Massive upgrade to work with the new intel gigabit NICs.
+ *  <ebiederman at lnxi dot com>
+ *
+ *  Support for 82541ei & 82547ei chips from Intel's Linux driver 5.1.13 added 
by
+ *  Georg Baum <address@hidden>, sponsored by PetaMem GmbH and linkLINE 
Communications, Inc.
+ *
+ *  01/2004: Updated to Linux driver 5.2.22 by Georg Baum <address@hidden>
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+/* to get the PCI support functions, if this is a PCI NIC */
+#include "pci.h"
+#include "timer.h"
+
+typedef unsigned char *dma_addr_t;
+
+typedef enum {
+       FALSE = 0,
+       TRUE = 1
+} boolean_t;
+
+#define DEBUG 0
+
+
+/* Some pieces of code are disabled with #if 0 ... #endif.
+ * They are not deleted to show where the etherboot driver differs
+ * from the linux driver below the function level.
+ * Some member variables of the hw struct have been eliminated
+ * and the corresponding inplace checks inserted instead.
+ * Pieces such as LED handling that we definitely don't need are deleted.
+ *
+ * The following defines should not be needed normally,
+ * but may be helpful for debugging purposes. */
+
+/* Define this if you want to program the transmission control register
+ * the way the Linux driver does it. */
+#undef LINUX_DRIVER_TCTL
+
+/* Define this to behave more like the Linux driver. */
+#undef LINUX_DRIVER
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+typedef unsigned short         uint16_t;
+typedef unsigned char          uint8_t;
+typedef unsigned int           uint32_t;
+typedef unsigned long long int uint64_t;
+typedef signed int             int32_t;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+#include "e1000_hw.h"
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+//#=#=#=#=#=#=#=#=#=# Start (osdep.h) #=#=#=#=#=#=#=#=#=#
+#define __unused __attribute__((unused))
+//#=#=#=#=#=#=#=#=#=# End (osdep.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (io.h) #=#=#=#=#=#=#=#=#=#
+#undef virt_to_bus
+#define virt_to_bus(vaddr)     ((unsigned long)vaddr)
+#define bus_to_virt(vaddr)     ((void *)vaddr)
+#define virt_to_phys(vaddr)    ((unsigned long) (vaddr))
+#define phys_to_virt(vaddr)    ((void *) (vaddr))
+#define iounmap(addr)          ((void)0)
+#define ioremap(physaddr, size)        bus_to_virt(physaddr)
+//#=#=#=#=#=#=#=#=#=# End (io.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (pci.h) #=#=#=#=#=#=#=#=#=#
+#define PCI_COMMAND_INVALIDATE         0x10    /* Use memory write and 
invalidate */
+//#=#=#=#=#=#=#=#=#=# End (pci.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (timer.h) #=#=#=#=#=#=#=#=#=#
+extern void mdelay(unsigned int msecs);
+//#=#=#=#=#=#=#=#=#=# End (timer.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (timer.c) #=#=#=#=#=#=#=#=#=#
+#define        poll_interruptions()
+#define        udelay(n)       waiton_timer2(((n)*TICKS_PER_MS)/1000)
+void mdelay(unsigned int msecs)
+{
+       unsigned int i;
+       for(i = 0; i < msecs; i++) {
+               udelay(1000);
+               poll_interruptions();
+       }
+}
+//#=#=#=#=#=#=#=#=#=# End (timer.c) #=#=#=#=#=#=#=#=#=#
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+/* NIC specific static variables go here */
+static struct e1000_hw hw;
+static char tx_pool[128 + 16];
+static char rx_pool[128 + 16];
+static char packet[2096];
+
+static struct e1000_tx_desc *tx_base;
+static struct e1000_rx_desc *rx_base;
+
+static int tx_tail;
+static int rx_tail, rx_last;
+
+/* Function forward declarations */
+static int e1000_setup_link(struct e1000_hw *hw);
+static int e1000_setup_fiber_serdes_link(struct e1000_hw *hw);
+static int e1000_setup_copper_link(struct e1000_hw *hw);
+static int e1000_phy_setup_autoneg(struct e1000_hw *hw);
+static void e1000_config_collision_dist(struct e1000_hw *hw);
+static int e1000_config_mac_to_phy(struct e1000_hw *hw);
+static int e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int e1000_check_for_link(struct e1000_hw *hw);
+static int e1000_wait_autoneg(struct e1000_hw *hw);
+static void e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t *speed, 
uint16_t *duplex);
+static int e1000_read_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t 
*phy_data);
+static int e1000_read_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr, 
uint16_t *phy_data);
+static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, 
uint16_t phy_data);
+static int e1000_write_phy_reg_ex(struct e1000_hw *hw, uint32_t reg_addr, 
uint16_t phy_data);
+static void e1000_phy_hw_reset(struct e1000_hw *hw);
+static int e1000_phy_reset(struct e1000_hw *hw);
+static int e1000_detect_gig_phy(struct e1000_hw *hw);
+
+/* Printing macros... */
+
+#define E1000_ERR(args...) printf("e1000: " args)
+
+#if DEBUG >= 3
+#define E1000_DBG(args...) printf("e1000: " args)
+#else
+#define E1000_DBG(args...)
+#endif
+
+#define MSGOUT(S, A, B)     printk(S "\n", A, B)
+#if DEBUG >= 2
+#define DEBUGFUNC(F)        DEBUGOUT(F "\n");
+#else
+#define DEBUGFUNC(F)
+#endif
+#if DEBUG >= 1
+#define DEBUGOUT(S) printf(S)
+#define DEBUGOUT1(S,A) printf(S,A)
+#define DEBUGOUT2(S,A,B) printf(S,A,B)
+#define DEBUGOUT3(S,A,B,C) printf(S,A,B,C)
+#define DEBUGOUT7(S,A,B,C,D,E,F,G) printf(S,A,B,C,D,E,F,G)
+#else
+#define DEBUGOUT(S)
+#define DEBUGOUT1(S,A)
+#define DEBUGOUT2(S,A,B)
+#define DEBUGOUT3(S,A,B,C)
+#define DEBUGOUT7(S,A,B,C,D,E,F,G)
+#endif
+
+#define E1000_WRITE_REG(a, reg, value) ( \
+    ((a)->mac_type >= e1000_82543) ? \
+        (writel((value), ((a)->hw_addr + E1000_##reg))) : \
+        (writel((value), ((a)->hw_addr + E1000_82542_##reg))))
+
+#define E1000_READ_REG(a, reg) ( \
+    ((a)->mac_type >= e1000_82543) ? \
+        readl((a)->hw_addr + E1000_##reg) : \
+        readl((a)->hw_addr + E1000_82542_##reg))
+
+#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) ( \
+    ((a)->mac_type >= e1000_82543) ? \
+        writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2))) : \
+        writel((value), ((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))))
+
+#define E1000_READ_REG_ARRAY(a, reg, offset) ( \
+    ((a)->mac_type >= e1000_82543) ? \
+        readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \
+        readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2)))
+
+#define E1000_WRITE_FLUSH(a) {uint32_t x; x = E1000_READ_REG(a, STATUS);}
+
+uint32_t
+e1000_io_read(struct e1000_hw *hw __unused, uint32_t port)
+{
+        return inl(port);
+}
+
+void
+e1000_io_write(struct e1000_hw *hw __unused, uint32_t port, uint32_t value)
+{
+        outl(value, port);
+}
+
+static inline void e1000_pci_set_mwi(struct e1000_hw *hw)
+{
+       pci_write_config_word(hw->pdev, PCI_COMMAND, hw->pci_cmd_word);
+}
+
+static inline void e1000_pci_clear_mwi(struct e1000_hw *hw)
+{
+       pci_write_config_word(hw->pdev, PCI_COMMAND,
+                             hw->pci_cmd_word & ~PCI_COMMAND_INVALIDATE);
+}
+
+/******************************************************************************
+ * Raises the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_raise_ee_clk(struct e1000_hw *hw,
+                   uint32_t *eecd)
+{
+       /* Raise the clock input to the EEPROM (by setting the SK bit), and then
+        * wait <delay> microseconds.
+        */
+       *eecd = *eecd | E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, *eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(hw->eeprom.delay_usec);
+}
+
+/******************************************************************************
+ * Lowers the EEPROM's clock input.
+ *
+ * hw - Struct containing variables accessed by shared code 
+ * eecd - EECD's current value
+ *****************************************************************************/
+static void
+e1000_lower_ee_clk(struct e1000_hw *hw,
+                   uint32_t *eecd)
+{
+       /* Lower the clock input to the EEPROM (by clearing the SK bit), and 
then 
+        * wait 50 microseconds. 
+        */
+       *eecd = *eecd & ~E1000_EECD_SK;
+       E1000_WRITE_REG(hw, EECD, *eecd);
+       E1000_WRITE_FLUSH(hw);
+       udelay(hw->eeprom.delay_usec);
+}
+
+/******************************************************************************
+ * Shift data bits out to the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * data - data to send to the EEPROM
+ * count - number of bits to shift out
+ *****************************************************************************/
+static void
+e1000_shift_out_ee_bits(struct e1000_hw *hw,
+                        uint16_t data,
+                        uint16_t count)
+{
+       struct e1000_eeprom_info *eeprom = &hw->eeprom;
+       uint32_t eecd;
+       uint32_t mask;
+       
+       /* We need to shift "count" bits out to the EEPROM. So, value in the
+        * "data" parameter will be shifted out to the EEPROM one bit at a time.
+        * In order to do this, "data" must be broken down into bits. 
+        */
+       mask = 0x01 << (count - 1);
+       eecd = E1000_READ_REG(hw, EECD);
+       if (eeprom->type == e1000_eeprom_microwire) {
+               eecd &= ~E1000_EECD_DO;
+       } else if (eeprom->type == e1000_eeprom_spi) {
+               eecd |= E1000_EECD_DO;
+       }
+       do {
+               /* A "1" is shifted out to the EEPROM by setting bit "DI" to a 
"1",
+                * and then raising and then lowering the clock (the SK bit 
controls
+                * the clock input to the EEPROM).  A "0" is shifted out to the 
EEPROM
+                * by setting "DI" to "0" and then raising and then lowering 
the clock.
+                */
+               eecd &= ~E1000_EECD_DI;
+               
+               if(data & mask)
+                       eecd |= E1000_EECD_DI;
+               
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               
+               udelay(eeprom->delay_usec);
+               
+               e1000_raise_ee_clk(hw, &eecd);
+               e1000_lower_ee_clk(hw, &eecd);
+               
+               mask = mask >> 1;
+               
+       } while(mask);
+
+       /* We leave the "DI" bit set to "0" when we leave this routine. */
+       eecd &= ~E1000_EECD_DI;
+       E1000_WRITE_REG(hw, EECD, eecd);
+}
+
+/******************************************************************************
+ * Shift data bits in from the EEPROM
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static uint16_t
+e1000_shift_in_ee_bits(struct e1000_hw *hw,
+                       uint16_t count)
+{
+       uint32_t eecd;
+       uint32_t i;
+       uint16_t data;
+       
+       /* In order to read a register from the EEPROM, we need to shift 
'count' 
+        * bits in from the EEPROM. Bits are "shifted in" by raising the clock
+        * input to the EEPROM (setting the SK bit), and then reading the value 
of
+        * the "DO" bit.  During this "shifting in" process the "DI" bit should
+        * always be clear.
+        */
+       
+       eecd = E1000_READ_REG(hw, EECD);
+       
+       eecd &= ~(E1000_EECD_DO | E1000_EECD_DI);
+       data = 0;
+       
+       for(i = 0; i < count; i++) {
+               data = data << 1;
+               e1000_raise_ee_clk(hw, &eecd);
+               
+               eecd = E1000_READ_REG(hw, EECD);
+               
+               eecd &= ~(E1000_EECD_DI);
+               if(eecd & E1000_EECD_DO)
+                       data |= 1;
+               
+               e1000_lower_ee_clk(hw, &eecd);
+       }
+       
+       return data;
+}
+
+/******************************************************************************
+ * Prepares EEPROM for access
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Lowers EEPROM clock. Clears input pin. Sets the chip select pin. This 
+ * function should be called before issuing a command to the EEPROM.
+ *****************************************************************************/
+static int32_t
+e1000_acquire_eeprom(struct e1000_hw *hw)
+{
+       struct e1000_eeprom_info *eeprom = &hw->eeprom;
+       uint32_t eecd, i=0;
+
+       eecd = E1000_READ_REG(hw, EECD);
+
+       /* Request EEPROM Access */
+       if(hw->mac_type > e1000_82544) {
+               eecd |= E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               eecd = E1000_READ_REG(hw, EECD);
+               while((!(eecd & E1000_EECD_GNT)) &&
+                     (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+                       i++;
+                       udelay(5);
+                       eecd = E1000_READ_REG(hw, EECD);
+               }
+               if(!(eecd & E1000_EECD_GNT)) {
+                       eecd &= ~E1000_EECD_REQ;
+                       E1000_WRITE_REG(hw, EECD, eecd);
+                       DEBUGOUT("Could not acquire EEPROM grant\n");
+                       return -E1000_ERR_EEPROM;
+               }
+       }
+
+       /* Setup EEPROM for Read/Write */
+
+       if (eeprom->type == e1000_eeprom_microwire) {
+               /* Clear SK and DI */
+               eecd &= ~(E1000_EECD_DI | E1000_EECD_SK);
+               E1000_WRITE_REG(hw, EECD, eecd);
+
+               /* Set CS */
+               eecd |= E1000_EECD_CS;
+               E1000_WRITE_REG(hw, EECD, eecd);
+       } else if (eeprom->type == e1000_eeprom_spi) {
+               /* Clear SK and CS */
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+               E1000_WRITE_REG(hw, EECD, eecd);
+               udelay(1);
+       }
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Returns EEPROM to a "standby" state
+ * 
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_standby_eeprom(struct e1000_hw *hw)
+{
+       struct e1000_eeprom_info *eeprom = &hw->eeprom;
+       uint32_t eecd;
+       
+       eecd = E1000_READ_REG(hw, EECD);
+
+       if(eeprom->type == e1000_eeprom_microwire) {
+
+               /* Deselect EEPROM */
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_SK);
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+       
+               /* Clock high */
+               eecd |= E1000_EECD_SK;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+       
+               /* Select EEPROM */
+               eecd |= E1000_EECD_CS;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+
+               /* Clock low */
+               eecd &= ~E1000_EECD_SK;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+       } else if(eeprom->type == e1000_eeprom_spi) {
+               /* Toggle CS to flush commands */
+               eecd |= E1000_EECD_CS;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+               eecd &= ~E1000_EECD_CS;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(eeprom->delay_usec);
+       }
+}
+
+/******************************************************************************
+ * Terminates a command by inverting the EEPROM's chip select pin
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_release_eeprom(struct e1000_hw *hw)
+{
+       uint32_t eecd;
+
+       eecd = E1000_READ_REG(hw, EECD);
+
+       if (hw->eeprom.type == e1000_eeprom_spi) {
+               eecd |= E1000_EECD_CS;  /* Pull CS high */
+               eecd &= ~E1000_EECD_SK; /* Lower SCK */
+
+               E1000_WRITE_REG(hw, EECD, eecd);
+
+               udelay(hw->eeprom.delay_usec);
+       } else if(hw->eeprom.type == e1000_eeprom_microwire) {
+               /* cleanup eeprom */
+
+               /* CS on Microwire is active-high */
+               eecd &= ~(E1000_EECD_CS | E1000_EECD_DI);
+
+               E1000_WRITE_REG(hw, EECD, eecd);
+
+               /* Rising edge of clock */
+               eecd |= E1000_EECD_SK;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(hw->eeprom.delay_usec);
+
+               /* Falling edge of clock */
+               eecd &= ~E1000_EECD_SK;
+               E1000_WRITE_REG(hw, EECD, eecd);
+               E1000_WRITE_FLUSH(hw);
+               udelay(hw->eeprom.delay_usec);
+       }
+
+       /* Stop requesting EEPROM access */
+       if(hw->mac_type > e1000_82544) {
+               eecd &= ~E1000_EECD_REQ;
+               E1000_WRITE_REG(hw, EECD, eecd);
+       }
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_spi_eeprom_ready(struct e1000_hw *hw)
+{
+       uint16_t retry_count = 0;
+       uint8_t spi_stat_reg;
+
+       /* Read "Status Register" repeatedly until the LSB is cleared.  The
+        * EEPROM will signal that the command has been completed by clearing
+        * bit 0 of the internal status register.  If it's not cleared within
+        * 5 milliseconds, then error out.
+        */
+       retry_count = 0;
+       do {
+               e1000_shift_out_ee_bits(hw, EEPROM_RDSR_OPCODE_SPI,
+               hw->eeprom.opcode_bits);
+               spi_stat_reg = (uint8_t)e1000_shift_in_ee_bits(hw, 8);
+               if (!(spi_stat_reg & EEPROM_STATUS_RDY_SPI))
+                       break;
+
+               udelay(5);
+               retry_count += 5;
+
+       } while(retry_count < EEPROM_MAX_RETRY_SPI);
+
+       /* ATMEL SPI write time could vary from 0-20mSec on 3.3V devices (and
+        * only 0-5mSec on 5V devices)
+        */
+       if(retry_count >= EEPROM_MAX_RETRY_SPI) {
+               DEBUGOUT("SPI EEPROM Status error\n");
+               return -E1000_ERR_EEPROM;
+       }
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Reads a 16 bit word from the EEPROM.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * offset - offset of  word in the EEPROM to read
+ * data - word read from the EEPROM
+ * words - number of words to read
+ *****************************************************************************/
+static int
+e1000_read_eeprom(struct e1000_hw *hw,
+                  uint16_t offset,
+                 uint16_t words,
+                  uint16_t *data)
+{
+       struct e1000_eeprom_info *eeprom = &hw->eeprom;
+       uint32_t i = 0;
+       
+       DEBUGFUNC("e1000_read_eeprom");
+
+       /* A check for invalid values:  offset too large, too many words, and 
not
+        * enough words.
+        */
+       if((offset > eeprom->word_size) || (words > eeprom->word_size - offset) 
||
+          (words == 0)) {
+               DEBUGOUT("\"words\" parameter out of bounds\n");
+               return -E1000_ERR_EEPROM;
+       }
+
+       /*  Prepare the EEPROM for reading  */
+       if(e1000_acquire_eeprom(hw) != E1000_SUCCESS)
+               return -E1000_ERR_EEPROM;
+
+       if(eeprom->type == e1000_eeprom_spi) {
+               uint16_t word_in;
+               uint8_t read_opcode = EEPROM_READ_OPCODE_SPI;
+
+               if(e1000_spi_eeprom_ready(hw)) {
+                       e1000_release_eeprom(hw);
+                       return -E1000_ERR_EEPROM;
+               }
+
+               e1000_standby_eeprom(hw);
+
+               /* Some SPI eeproms use the 8th address bit embedded in the 
opcode */
+               if((eeprom->address_bits == 8) && (offset >= 128))
+                       read_opcode |= EEPROM_A8_OPCODE_SPI;
+
+               /* Send the READ command (opcode + addr)  */
+               e1000_shift_out_ee_bits(hw, read_opcode, eeprom->opcode_bits);
+               e1000_shift_out_ee_bits(hw, (uint16_t)(offset*2), 
eeprom->address_bits);
+
+               /* Read the data.  The address of the eeprom internally 
increments with
+                * each byte (spi) being read, saving on the overhead of eeprom 
setup
+                * and tear-down.  The address counter will roll over if 
reading beyond
+                * the size of the eeprom, thus allowing the entire memory to 
be read
+                * starting from any offset. */
+               for (i = 0; i < words; i++) {
+                       word_in = e1000_shift_in_ee_bits(hw, 16);
+                       data[i] = (word_in >> 8) | (word_in << 8);
+               }
+       } else if(eeprom->type == e1000_eeprom_microwire) {
+               for (i = 0; i < words; i++) {
+                       /*  Send the READ command (opcode + addr)  */
+                       e1000_shift_out_ee_bits(hw, 
EEPROM_READ_OPCODE_MICROWIRE,
+                                               eeprom->opcode_bits);
+                       e1000_shift_out_ee_bits(hw, (uint16_t)(offset + i),
+                                               eeprom->address_bits);
+
+                       /* Read the data.  For microwire, each word requires 
the overhead
+                        * of eeprom setup and tear-down. */
+                       data[i] = e1000_shift_in_ee_bits(hw, 16);
+                       e1000_standby_eeprom(hw);
+               }
+       }
+
+       /* End this read operation */
+       e1000_release_eeprom(hw);
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Verifies that the EEPROM has a valid checksum
+ * 
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Reads the first 64 16 bit words of the EEPROM and sums the values read.
+ * If the the sum of the 64 16 bit words is 0xBABA, the EEPROM's checksum is
+ * valid.
+ *****************************************************************************/
+static int
+e1000_validate_eeprom_checksum(struct e1000_hw *hw)
+{
+       uint16_t checksum = 0;
+       uint16_t i, eeprom_data;
+
+       DEBUGFUNC("e1000_validate_eeprom_checksum");
+
+       for(i = 0; i < (EEPROM_CHECKSUM_REG + 1); i++) {
+               if(e1000_read_eeprom(hw, i, 1, &eeprom_data) < 0) {
+                       DEBUGOUT("EEPROM Read Error\n");
+                       return -E1000_ERR_EEPROM;
+               }
+               checksum += eeprom_data;
+       }
+       
+       if(checksum == (uint16_t) EEPROM_SUM)
+               return E1000_SUCCESS;
+       else {
+               DEBUGOUT("EEPROM Checksum Invalid\n");    
+               return -E1000_ERR_EEPROM;
+       }
+}
+
+/******************************************************************************
+ * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the
+ * second function of dual function devices
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int 
+e1000_read_mac_addr(struct e1000_hw *hw)
+{
+       uint16_t offset;
+       uint16_t eeprom_data;
+       int i;
+
+       DEBUGFUNC("e1000_read_mac_addr");
+
+       for(i = 0; i < NODE_ADDRESS_SIZE; i += 2) {
+               offset = i >> 1;
+               if(e1000_read_eeprom(hw, offset, 1, &eeprom_data) < 0) {
+                       DEBUGOUT("EEPROM Read Error\n");
+                       return -E1000_ERR_EEPROM;
+               }
+               hw->mac_addr[i] = eeprom_data & 0xff;
+               hw->mac_addr[i+1] = (eeprom_data >> 8) & 0xff;
+       }
+       if(((hw->mac_type == e1000_82546) || (hw->mac_type == 
e1000_82546_rev_3)) &&
+               (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+               /* Invert the last bit if this is the second device */
+               hw->mac_addr[5] ^= 1;
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Initializes receive address filters.
+ *
+ * hw - Struct containing variables accessed by shared code 
+ *
+ * Places the MAC address in receive address register 0 and clears the rest
+ * of the receive addresss registers. Clears the multicast table. Assumes
+ * the receiver is in reset when the routine is called.
+ *****************************************************************************/
+static void
+e1000_init_rx_addrs(struct e1000_hw *hw)
+{
+       uint32_t i;
+       uint32_t addr_low;
+       uint32_t addr_high;
+       
+       DEBUGFUNC("e1000_init_rx_addrs");
+       
+       /* Setup the receive address. */
+       DEBUGOUT("Programming MAC Address into RAR[0]\n");
+       addr_low = (hw->mac_addr[0] |
+               (hw->mac_addr[1] << 8) |
+               (hw->mac_addr[2] << 16) | (hw->mac_addr[3] << 24));
+       
+       addr_high = (hw->mac_addr[4] |
+               (hw->mac_addr[5] << 8) | E1000_RAH_AV);
+       
+       E1000_WRITE_REG_ARRAY(hw, RA, 0, addr_low);
+       E1000_WRITE_REG_ARRAY(hw, RA, 1, addr_high);
+       
+       /* Zero out the other 15 receive addresses. */
+       DEBUGOUT("Clearing RAR[1-15]\n");
+       for(i = 1; i < E1000_RAR_ENTRIES; i++) {
+               E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
+               E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
+       }
+}
+
+/******************************************************************************
+ * Clears the VLAN filer table
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_clear_vfta(struct e1000_hw *hw)
+{
+       uint32_t offset;
+    
+       for(offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++)
+               E1000_WRITE_REG_ARRAY(hw, VFTA, offset, 0);
+}
+
+/******************************************************************************
+* Writes a value to one of the devices registers using port I/O (as opposed to
+* memory mapped I/O). Only 82544 and newer devices support port I/O. *
+* hw - Struct containing variables accessed by shared code
+* offset - offset to write to * value - value to write
+*****************************************************************************/
+void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value){
+       uint32_t io_addr = hw->io_base;
+       uint32_t io_data = hw->io_base + 4;
+       e1000_io_write(hw, io_addr, offset);
+       e1000_io_write(hw, io_data, value);
+}
+
+/******************************************************************************
+ * Set the phy type member in the hw struct.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int32_t
+e1000_set_phy_type(struct e1000_hw *hw)
+{
+       DEBUGFUNC("e1000_set_phy_type");
+
+       switch(hw->phy_id) {
+       case M88E1000_E_PHY_ID:
+       case M88E1000_I_PHY_ID:
+       case M88E1011_I_PHY_ID:
+               hw->phy_type = e1000_phy_m88;
+               break;
+       case IGP01E1000_I_PHY_ID:
+               hw->phy_type = e1000_phy_igp;
+               break;
+       default:
+               /* Should never have loaded on this device */
+               hw->phy_type = e1000_phy_undefined;
+               return -E1000_ERR_PHY_TYPE;
+       }
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * IGP phy init script - initializes the GbE PHY
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_phy_init_script(struct e1000_hw *hw)
+{
+       DEBUGFUNC("e1000_phy_init_script");
+
+#if 0
+       /* See e1000_sw_init() of the Linux driver */
+       if(hw->phy_init_script) {
+#else
+       if((hw->mac_type == e1000_82541) ||
+          (hw->mac_type == e1000_82547) ||
+          (hw->mac_type == e1000_82541_rev_2) ||
+          (hw->mac_type == e1000_82547_rev_2)) {
+#endif
+               mdelay(20);
+
+               e1000_write_phy_reg(hw,0x0000,0x0140);
+
+               mdelay(5);
+
+               if(hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547) {
+                       e1000_write_phy_reg(hw, 0x1F95, 0x0001);
+
+                       e1000_write_phy_reg(hw, 0x1F71, 0xBD21);
+
+                       e1000_write_phy_reg(hw, 0x1F79, 0x0018);
+
+                       e1000_write_phy_reg(hw, 0x1F30, 0x1600);
+
+                       e1000_write_phy_reg(hw, 0x1F31, 0x0014);
+
+                       e1000_write_phy_reg(hw, 0x1F32, 0x161C);
+
+                       e1000_write_phy_reg(hw, 0x1F94, 0x0003);
+
+                       e1000_write_phy_reg(hw, 0x1F96, 0x003F);
+
+                       e1000_write_phy_reg(hw, 0x2010, 0x0008);
+               } else {
+                       e1000_write_phy_reg(hw, 0x1F73, 0x0099);
+               }
+
+               e1000_write_phy_reg(hw, 0x0000, 0x3300);
+
+
+               if(hw->mac_type == e1000_82547) {
+                       uint16_t fused, fine, coarse;
+
+                       /* Move to analog registers page */
+                       e1000_read_phy_reg(hw, 
IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused);
+
+                       if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) {
+                               e1000_read_phy_reg(hw, 
IGP01E1000_ANALOG_FUSE_STATUS, &fused);
+
+                               fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK;
+                               coarse = fused & 
IGP01E1000_ANALOG_FUSE_COARSE_MASK;
+
+                               if(coarse > 
IGP01E1000_ANALOG_FUSE_COARSE_THRESH) {
+                                       coarse -= 
IGP01E1000_ANALOG_FUSE_COARSE_10;
+                                       fine -= IGP01E1000_ANALOG_FUSE_FINE_1;
+                               } else if(coarse == 
IGP01E1000_ANALOG_FUSE_COARSE_THRESH)
+                                       fine -= IGP01E1000_ANALOG_FUSE_FINE_10;
+
+                               fused = (fused & 
IGP01E1000_ANALOG_FUSE_POLY_MASK) |
+                                       (fine & 
IGP01E1000_ANALOG_FUSE_FINE_MASK) |
+                                       (coarse & 
IGP01E1000_ANALOG_FUSE_COARSE_MASK);
+
+                               e1000_write_phy_reg(hw, 
IGP01E1000_ANALOG_FUSE_CONTROL, fused);
+                               e1000_write_phy_reg(hw, 
IGP01E1000_ANALOG_FUSE_BYPASS,
+                                               
IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL);
+                       }
+               }
+       }
+}
+
+/******************************************************************************
+ * Set the mac type member in the hw struct.
+ * 
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static int
+e1000_set_mac_type(struct e1000_hw *hw)
+{
+       DEBUGFUNC("e1000_set_mac_type");
+
+       switch (hw->device_id) {
+       case E1000_DEV_ID_82542:
+               switch (hw->revision_id) {
+               case E1000_82542_2_0_REV_ID:
+                       hw->mac_type = e1000_82542_rev2_0;
+                       break;
+               case E1000_82542_2_1_REV_ID:
+                       hw->mac_type = e1000_82542_rev2_1;
+                       break;
+               default:
+                       /* Invalid 82542 revision ID */
+                       return -E1000_ERR_MAC_TYPE;
+               }
+               break;
+       case E1000_DEV_ID_82543GC_FIBER:
+       case E1000_DEV_ID_82543GC_COPPER:
+               hw->mac_type = e1000_82543;
+               break;
+       case E1000_DEV_ID_82544EI_COPPER:
+       case E1000_DEV_ID_82544EI_FIBER:
+       case E1000_DEV_ID_82544GC_COPPER:
+       case E1000_DEV_ID_82544GC_LOM:
+               hw->mac_type = e1000_82544;
+               break;
+       case E1000_DEV_ID_82540EM:
+       case E1000_DEV_ID_82540EM_LOM:
+       case E1000_DEV_ID_82540EP:
+       case E1000_DEV_ID_82540EP_LOM:
+       case E1000_DEV_ID_82540EP_LP:
+               hw->mac_type = e1000_82540;
+               break;
+       case E1000_DEV_ID_82545EM_COPPER:
+       case E1000_DEV_ID_82545EM_FIBER:
+               hw->mac_type = e1000_82545;
+               break;
+       case E1000_DEV_ID_82545GM_COPPER:
+       case E1000_DEV_ID_82545GM_FIBER:
+       case E1000_DEV_ID_82545GM_SERDES:
+               hw->mac_type = e1000_82545_rev_3;
+               break;
+       case E1000_DEV_ID_82546EB_COPPER:
+       case E1000_DEV_ID_82546EB_FIBER:
+       case E1000_DEV_ID_82546EB_QUAD_COPPER:
+               hw->mac_type = e1000_82546;
+               break;
+       case E1000_DEV_ID_82546GB_COPPER:
+       case E1000_DEV_ID_82546GB_FIBER:
+       case E1000_DEV_ID_82546GB_SERDES:
+               hw->mac_type = e1000_82546_rev_3;
+               break;
+       case E1000_DEV_ID_82541EI:
+       case E1000_DEV_ID_82541EI_MOBILE:
+               hw->mac_type = e1000_82541;
+               break;
+       case E1000_DEV_ID_82541ER:
+       case E1000_DEV_ID_82541GI:
+       case E1000_DEV_ID_82541GI_MOBILE:
+               hw->mac_type = e1000_82541_rev_2;
+               break;
+       case E1000_DEV_ID_82547EI:
+               hw->mac_type = e1000_82547;
+               break;
+       case E1000_DEV_ID_82547GI:
+               hw->mac_type = e1000_82547_rev_2;
+               break;
+       default:
+               /* Should never have loaded on this device */
+               return -E1000_ERR_MAC_TYPE;
+       }
+
+       return E1000_SUCCESS;
+}
+
+/*****************************************************************************
+ * Set media type and TBI compatibility.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * **************************************************************************/
+static void
+e1000_set_media_type(struct e1000_hw *hw)
+{
+       uint32_t status;
+
+       DEBUGFUNC("e1000_set_media_type");
+       
+       if(hw->mac_type != e1000_82543) {
+               /* tbi_compatibility is only valid on 82543 */
+               hw->tbi_compatibility_en = FALSE;
+       }
+
+       switch (hw->device_id) {
+               case E1000_DEV_ID_82545GM_SERDES:
+               case E1000_DEV_ID_82546GB_SERDES:
+                       hw->media_type = e1000_media_type_internal_serdes;
+                       break;
+               default:
+                       if(hw->mac_type >= e1000_82543) {
+                               status = E1000_READ_REG(hw, STATUS);
+                               if(status & E1000_STATUS_TBIMODE) {
+                                       hw->media_type = e1000_media_type_fiber;
+                                       /* tbi_compatibility not valid on fiber 
*/
+                                       hw->tbi_compatibility_en = FALSE;
+                               } else {
+                                       hw->media_type = 
e1000_media_type_copper;
+                               }
+                       } else {
+                               /* This is an 82542 (fiber only) */
+                               hw->media_type = e1000_media_type_fiber;
+                       }
+       }
+}
+
+/******************************************************************************
+ * Reset the transmit and receive units; mask and clear all interrupts.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_reset_hw(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint32_t ctrl_ext;
+       uint32_t icr;
+       uint32_t manc;
+       
+       DEBUGFUNC("e1000_reset_hw");
+       
+       /* For 82542 (rev 2.0), disable MWI before issuing a device reset */
+       if(hw->mac_type == e1000_82542_rev2_0) {
+               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+               e1000_pci_clear_mwi(hw);
+       }
+
+       /* Clear interrupt mask to stop board from generating interrupts */
+       DEBUGOUT("Masking off all interrupts\n");
+       E1000_WRITE_REG(hw, IMC, 0xffffffff);
+       
+       /* Disable the Transmit and Receive units.  Then delay to allow
+        * any pending transactions to complete before we hit the MAC with
+        * the global reset.
+        */
+       E1000_WRITE_REG(hw, RCTL, 0);
+       E1000_WRITE_REG(hw, TCTL, E1000_TCTL_PSP);
+       E1000_WRITE_FLUSH(hw);
+
+       /* The tbi_compatibility_on Flag must be cleared when Rctl is cleared. 
*/
+       hw->tbi_compatibility_on = FALSE;
+
+       /* Delay to allow any outstanding PCI transactions to complete before
+        * resetting the device
+        */ 
+       mdelay(10);
+
+       ctrl = E1000_READ_REG(hw, CTRL);
+
+       /* Must reset the PHY before resetting the MAC */
+       if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+               E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_PHY_RST));
+               mdelay(5);
+       }
+
+       /* Issue a global reset to the MAC.  This will reset the chip's
+        * transmit, receive, DMA, and link units.  It will not effect
+        * the current PCI configuration.  The global reset bit is self-
+        * clearing, and should clear within a microsecond.
+        */
+       DEBUGOUT("Issuing a global reset to MAC\n");
+
+       switch(hw->mac_type) {
+               case e1000_82544:
+               case e1000_82540:
+               case e1000_82545:
+               case e1000_82546:
+               case e1000_82541:
+               case e1000_82541_rev_2:
+                       /* These controllers can't ack the 64-bit write when 
issuing the
+                        * reset, so use IO-mapping as a workaround to issue 
the reset */
+                       E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST));
+                       break;
+               case e1000_82545_rev_3:
+               case e1000_82546_rev_3:
+                       /* Reset is performed on a shadow of the control 
register */
+                       E1000_WRITE_REG(hw, CTRL_DUP, (ctrl | E1000_CTRL_RST));
+                       break;
+               default:
+                       E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST));
+                       break;
+       }
+
+       /* After MAC reset, force reload of EEPROM to restore power-on settings 
to
+        * device.  Later controllers reload the EEPROM automatically, so just 
wait
+        * for reload to complete.
+        */
+       switch(hw->mac_type) {
+               case e1000_82542_rev2_0:
+               case e1000_82542_rev2_1:
+               case e1000_82543:
+               case e1000_82544:
+                       /* Wait for reset to complete */
+                       udelay(10);
+                       ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+                       ctrl_ext |= E1000_CTRL_EXT_EE_RST;
+                       E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+                       E1000_WRITE_FLUSH(hw);
+                       /* Wait for EEPROM reload */
+                       mdelay(2);
+                       break;
+               case e1000_82541:
+               case e1000_82541_rev_2:
+               case e1000_82547:
+               case e1000_82547_rev_2:
+                       /* Wait for EEPROM reload */
+                       mdelay(20);
+                       break;
+               default:
+                       /* Wait for EEPROM reload (it happens automatically) */
+                       mdelay(5);
+                       break;
+       }
+
+       /* Disable HW ARPs on ASF enabled adapters */
+       if(hw->mac_type >= e1000_82540) {
+               manc = E1000_READ_REG(hw, MANC);
+               manc &= ~(E1000_MANC_ARP_EN);
+               E1000_WRITE_REG(hw, MANC, manc);
+       }
+
+       if((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) {
+               e1000_phy_init_script(hw);
+       }
+
+       /* Clear interrupt mask to stop board from generating interrupts */
+       DEBUGOUT("Masking off all interrupts\n");
+       E1000_WRITE_REG(hw, IMC, 0xffffffff);
+       
+       /* Clear any pending interrupt events. */
+       icr = E1000_READ_REG(hw, ICR);
+
+       /* If MWI was previously enabled, reenable it. */
+       if(hw->mac_type == e1000_82542_rev2_0) {
+#ifdef LINUX_DRIVER
+               if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+#endif
+                       e1000_pci_set_mwi(hw);
+       }
+}
+
+/******************************************************************************
+ * Performs basic configuration of the adapter.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * 
+ * Assumes that the controller has previously been reset and is in a 
+ * post-reset uninitialized state. Initializes the receive address registers,
+ * multicast table, and VLAN filter table. Calls routines to setup link
+ * configuration and flow control settings. Clears all on-chip counters. Leaves
+ * the transmit and receive units disabled and uninitialized.
+ *****************************************************************************/
+static int
+e1000_init_hw(struct e1000_hw *hw)
+{
+       uint32_t ctrl, status;
+       uint32_t i;
+       int32_t ret_val;
+       uint16_t pcix_cmd_word;
+       uint16_t pcix_stat_hi_word;
+       uint16_t cmd_mmrbc;
+       uint16_t stat_mmrbc;
+       e1000_bus_type bus_type = e1000_bus_type_unknown;
+
+       DEBUGFUNC("e1000_init_hw");
+
+       /* Set the media type and TBI compatibility */
+       e1000_set_media_type(hw);
+
+       /* Disabling VLAN filtering. */
+       DEBUGOUT("Initializing the IEEE VLAN\n");
+       E1000_WRITE_REG(hw, VET, 0);
+       
+       e1000_clear_vfta(hw);
+       
+       /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */
+       if(hw->mac_type == e1000_82542_rev2_0) {
+               DEBUGOUT("Disabling MWI on 82542 rev 2.0\n");
+               e1000_pci_clear_mwi(hw);
+               E1000_WRITE_REG(hw, RCTL, E1000_RCTL_RST);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(5);
+       }
+       
+       /* Setup the receive address. This involves initializing all of the 
Receive
+        * Address Registers (RARs 0 - 15).
+        */
+       e1000_init_rx_addrs(hw);
+       
+       /* For 82542 (rev 2.0), take the receiver out of reset and enable MWI */
+       if(hw->mac_type == e1000_82542_rev2_0) {
+               E1000_WRITE_REG(hw, RCTL, 0);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(1);
+#ifdef LINUX_DRIVER
+               if(hw->pci_cmd_word & CMD_MEM_WRT_INVALIDATE)
+#endif
+                       e1000_pci_set_mwi(hw);
+       }
+       
+       /* Zero out the Multicast HASH table */
+       DEBUGOUT("Zeroing the MTA\n");
+       for(i = 0; i < E1000_MC_TBL_SIZE; i++)
+               E1000_WRITE_REG_ARRAY(hw, MTA, i, 0);
+       
+#if 0
+       /* Set the PCI priority bit correctly in the CTRL register.  This
+        * determines if the adapter gives priority to receives, or if it
+        * gives equal priority to transmits and receives.
+        */
+       if(hw->dma_fairness) {
+               ctrl = E1000_READ_REG(hw, CTRL);
+               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
+       }
+#endif
+
+       switch(hw->mac_type) {
+               case e1000_82545_rev_3:
+               case e1000_82546_rev_3:
+                       break;
+               default:
+                       if (hw->mac_type >= e1000_82543) {
+                               /* See e1000_get_bus_info() of the Linux driver 
*/
+                               status = E1000_READ_REG(hw, STATUS);
+                               bus_type = (status & E1000_STATUS_PCIX_MODE) ?
+                                       e1000_bus_type_pcix : 
e1000_bus_type_pci;
+                       }
+
+                       /* Workaround for PCI-X problem when BIOS sets MMRBC 
incorrectly. */
+                       if(bus_type == e1000_bus_type_pcix) {
+                               pci_read_config_word(hw->pdev, 
PCIX_COMMAND_REGISTER, &pcix_cmd_word);
+                               pci_read_config_word(hw->pdev, 
PCIX_STATUS_REGISTER_HI, &pcix_stat_hi_word);
+                               cmd_mmrbc = (pcix_cmd_word & 
PCIX_COMMAND_MMRBC_MASK) >>
+                                       PCIX_COMMAND_MMRBC_SHIFT;
+                               stat_mmrbc = (pcix_stat_hi_word & 
PCIX_STATUS_HI_MMRBC_MASK) >>
+                                       PCIX_STATUS_HI_MMRBC_SHIFT;
+                               if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
+                                       stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
+                               if(cmd_mmrbc > stat_mmrbc) {
+                                       pcix_cmd_word &= 
~PCIX_COMMAND_MMRBC_MASK;
+                                       pcix_cmd_word |= stat_mmrbc << 
PCIX_COMMAND_MMRBC_SHIFT;
+                                       pci_write_config_word(hw->pdev, 
PCIX_COMMAND_REGISTER, pcix_cmd_word);
+                               }
+                       }
+                       break;
+       }
+
+       /* Call a subroutine to configure the link and setup flow control. */
+       ret_val = e1000_setup_link(hw);
+       
+       /* Set the transmit descriptor write-back policy */
+       if(hw->mac_type > e1000_82544) {
+               ctrl = E1000_READ_REG(hw, TXDCTL);
+               ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | 
E1000_TXDCTL_FULL_TX_DESC_WB;
+               E1000_WRITE_REG(hw, TXDCTL, ctrl);
+       }
+
+#if 0
+       /* Clear all of the statistics registers (clear on read).  It is
+        * important that we do this after we have tried to establish link
+        * because the symbol error count will increment wildly if there
+        * is no link.
+        */
+       e1000_clear_hw_cntrs(hw);
+#endif
+
+       return ret_val;
+}
+
+/******************************************************************************
+ * Adjust SERDES output amplitude based on EEPROM setting.
+ *
+ * hw - Struct containing variables accessed by shared code.
+ *****************************************************************************/
+static int32_t
+e1000_adjust_serdes_amplitude(struct e1000_hw *hw)
+{
+       uint16_t eeprom_data;
+       int32_t  ret_val;
+
+       DEBUGFUNC("e1000_adjust_serdes_amplitude");
+
+       if(hw->media_type != e1000_media_type_internal_serdes)
+               return E1000_SUCCESS;
+
+       switch(hw->mac_type) {
+               case e1000_82545_rev_3:
+               case e1000_82546_rev_3:
+                       break;
+               default:
+                       return E1000_SUCCESS;
+       }
+
+       if ((ret_val = e1000_read_eeprom(hw, EEPROM_SERDES_AMPLITUDE, 1,
+                                       &eeprom_data))) {
+               return ret_val;
+       }
+
+       if(eeprom_data != EEPROM_RESERVED_WORD) {
+               /* Adjust SERDES output amplitude only. */
+               eeprom_data &= EEPROM_SERDES_AMPLITUDE_MASK;
+               if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_EXT_CTRL,
+                                                 eeprom_data)))
+                       return ret_val;
+       }
+
+       return E1000_SUCCESS;
+}
+                                                                  
+/******************************************************************************
+ * Configures flow control and link settings.
+ * 
+ * hw - Struct containing variables accessed by shared code
+ * 
+ * Determines which flow control settings to use. Calls the apropriate media-
+ * specific link configuration function. Configures the flow control settings.
+ * Assuming the adapter has a valid link partner, a valid link should be
+ * established. Assumes the hardware has previously been reset and the 
+ * transmitter and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_link(struct e1000_hw *hw)
+{
+       uint32_t ctrl_ext;
+       int32_t ret_val;
+       uint16_t eeprom_data;
+
+       DEBUGFUNC("e1000_setup_link");
+       
+       /* Read and store word 0x0F of the EEPROM. This word contains bits
+        * that determine the hardware's default PAUSE (flow control) mode,
+        * a bit that determines whether the HW defaults to enabling or
+        * disabling auto-negotiation, and the direction of the
+        * SW defined pins. If there is no SW over-ride of the flow
+        * control setting, then the variable hw->fc will
+        * be initialized based on a value in the EEPROM.
+        */
+       if(e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data) < 
0) {
+               DEBUGOUT("EEPROM Read Error\n");
+               return -E1000_ERR_EEPROM;
+       }
+       
+       if(hw->fc == e1000_fc_default) {
+               if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 0)
+                       hw->fc = e1000_fc_none;
+               else if((eeprom_data & EEPROM_WORD0F_PAUSE_MASK) == 
+                       EEPROM_WORD0F_ASM_DIR)
+                       hw->fc = e1000_fc_tx_pause;
+               else
+                       hw->fc = e1000_fc_full;
+       }
+       
+       /* We want to save off the original Flow Control configuration just
+        * in case we get disconnected and then reconnected into a different
+        * hub or switch with different Flow Control capabilities.
+        */
+       if(hw->mac_type == e1000_82542_rev2_0)
+               hw->fc &= (~e1000_fc_tx_pause);
+
+#if 0
+       /* See e1000_sw_init() of the Linux driver */
+       if((hw->mac_type < e1000_82543) && (hw->report_tx_early == 1))
+#else
+       if((hw->mac_type < e1000_82543) && (hw->mac_type >= e1000_82543))
+#endif
+               hw->fc &= (~e1000_fc_rx_pause);
+       
+#if 0
+       hw->original_fc = hw->fc;
+#endif
+
+       DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc);
+       
+       /* Take the 4 bits from EEPROM word 0x0F that determine the initial
+        * polarity value for the SW controlled pins, and setup the
+        * Extended Device Control reg with that info.
+        * This is needed because one of the SW controlled pins is used for
+        * signal detection.  So this should be done before 
e1000_setup_pcs_link()
+        * or e1000_phy_setup() is called.
+        */
+       if(hw->mac_type == e1000_82543) {
+               ctrl_ext = ((eeprom_data & EEPROM_WORD0F_SWPDIO_EXT) << 
+                       SWDPIO__EXT_SHIFT);
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+       }
+       
+       /* Call the necessary subroutine to configure the link. */
+       ret_val = (hw->media_type == e1000_media_type_copper) ?
+               e1000_setup_copper_link(hw) :
+               e1000_setup_fiber_serdes_link(hw);
+       if (ret_val < 0) {
+               return ret_val;
+       }
+       
+       /* Initialize the flow control address, type, and PAUSE timer
+        * registers to their default values.  This is done even if flow
+        * control is disabled, because it does not hurt anything to
+        * initialize these registers.
+        */
+       DEBUGOUT("Initializing the Flow Control address, type and timer 
regs\n");
+       
+       E1000_WRITE_REG(hw, FCAL, FLOW_CONTROL_ADDRESS_LOW);
+       E1000_WRITE_REG(hw, FCAH, FLOW_CONTROL_ADDRESS_HIGH);
+       E1000_WRITE_REG(hw, FCT, FLOW_CONTROL_TYPE);
+#if 0
+       E1000_WRITE_REG(hw, FCTTV, hw->fc_pause_time);
+#else
+       E1000_WRITE_REG(hw, FCTTV, FC_DEFAULT_TX_TIMER);
+#endif
+       
+       /* Set the flow control receive threshold registers.  Normally,
+        * these registers will be set to a default threshold that may be
+        * adjusted later by the driver's runtime code.  However, if the
+        * ability to transmit pause frames in not enabled, then these
+        * registers will be set to 0. 
+        */
+       if(!(hw->fc & e1000_fc_tx_pause)) {
+               E1000_WRITE_REG(hw, FCRTL, 0);
+               E1000_WRITE_REG(hw, FCRTH, 0);
+       } else {
+               /* We need to set up the Receive Threshold high and low water 
marks
+                * as well as (optionally) enabling the transmission of XON 
frames.
+                */
+#if 0
+               if(hw->fc_send_xon) {
+                       E1000_WRITE_REG(hw, FCRTL, (hw->fc_low_water | 
E1000_FCRTL_XONE));
+                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+               } else {
+                       E1000_WRITE_REG(hw, FCRTL, hw->fc_low_water);
+                       E1000_WRITE_REG(hw, FCRTH, hw->fc_high_water);
+               }
+#else
+               E1000_WRITE_REG(hw, FCRTL, (FC_DEFAULT_LO_THRESH | 
E1000_FCRTL_XONE));
+               E1000_WRITE_REG(hw, FCRTH, FC_DEFAULT_HI_THRESH);
+#endif
+       }
+       return ret_val;
+}
+
+/******************************************************************************
+ * Sets up link for a fiber based or serdes based adapter
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Manipulates Physical Coding Sublayer functions in order to configure
+ * link. Assumes the hardware has been previously reset and the transmitter
+ * and receiver are not enabled.
+ *****************************************************************************/
+static int
+e1000_setup_fiber_serdes_link(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint32_t status;
+       uint32_t txcw = 0;
+       uint32_t i;
+       uint32_t signal = 0;
+       int32_t ret_val;
+
+       DEBUGFUNC("e1000_setup_fiber_serdes_link");
+
+       /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be 
+        * set when the optics detect a signal. On older adapters, it will be 
+        * cleared when there is a signal.  This applies to fiber media only.
+        * If we're on serdes media, adjust the output amplitude to value set in
+        * the EEPROM.
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       if(hw->media_type == e1000_media_type_fiber)
+               signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
+
+       if((ret_val = e1000_adjust_serdes_amplitude(hw)))
+               return ret_val;
+
+       /* Take the link out of reset */
+       ctrl &= ~(E1000_CTRL_LRST);
+
+#if 0
+       /* Adjust VCO speed to improve BER performance */
+       if((ret_val = e1000_set_vco_speed(hw)))
+               return ret_val;
+#endif
+
+       e1000_config_collision_dist(hw);
+       
+       /* Check for a software override of the flow control settings, and setup
+        * the device accordingly.  If auto-negotiation is enabled, then 
software
+        * will have to set the "PAUSE" bits to the correct value in the 
Tranmsit
+        * Config Word Register (TXCW) and re-start auto-negotiation.  However, 
if
+        * auto-negotiation is disabled, then software will have to manually 
+        * configure the two flow control enable bits in the CTRL register.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause frames, 
but 
+        *          not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames but we 
do
+        *          not support receiving pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) are enabled.
+        */
+       switch (hw->fc) {
+       case e1000_fc_none:
+               /* Flow control is completely disabled by a software over-ride. 
*/
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
+               break;
+       case e1000_fc_rx_pause:
+               /* RX Flow control is enabled and TX Flow control is disabled 
by a 
+                * software over-ride. Since there really isn't a way to 
advertise 
+                * that we are capable of RX Pause ONLY, we will advertise that 
we
+                * support both symmetric and asymmetric RX PAUSE. Later, we 
will
+                *  disable the adapter's ability to send PAUSE frames.
+                */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+               break;
+       case e1000_fc_tx_pause:
+               /* TX Flow control is enabled, and RX Flow control is disabled, 
by a 
+                * software over-ride.
+                */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
+               break;
+       case e1000_fc_full:
+               /* Flow control (both RX and TX) is enabled by a software 
over-ride. */
+               txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+               break;
+       }
+       
+       /* Since auto-negotiation is enabled, take the link out of reset (the 
link
+        * will be in reset, because we previously reset the chip). This will
+        * restart auto-negotiation.  If auto-neogtiation is successful then the
+        * link-up status bit will be set and the flow control enable bits (RFCE
+        * and TFCE) will be set according to their negotiated value.
+        */
+       DEBUGOUT("Auto-negotiation enabled\n");
+       
+       E1000_WRITE_REG(hw, TXCW, txcw);
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       E1000_WRITE_FLUSH(hw);
+       
+       hw->txcw = txcw;
+       mdelay(1);
+       
+       /* If we have a signal (the cable is plugged in) then poll for a 
"Link-Up"
+        * indication in the Device Status Register.  Time-out if a link isn't 
+        * seen in 500 milliseconds seconds (Auto-negotiation should complete 
in 
+        * less than 500 milliseconds even if the other end is doing it in SW).
+        * For internal serdes, we just assume a signal is present, then poll.
+        */
+       if(hw->media_type == e1000_media_type_internal_serdes ||
+          (E1000_READ_REG(hw, CTRL) & E1000_CTRL_SWDPIN1) == signal) {
+               DEBUGOUT("Looking for Link\n");
+               for(i = 0; i < (LINK_UP_TIMEOUT / 10); i++) {
+                       mdelay(10);
+                       status = E1000_READ_REG(hw, STATUS);
+                       if(status & E1000_STATUS_LU) break;
+               }
+               if(i == (LINK_UP_TIMEOUT / 10)) {
+                       DEBUGOUT("Never got a valid link from auto-neg!!!\n");
+                       hw->autoneg_failed = 1;
+                       /* AutoNeg failed to achieve a link, so we'll call 
+                        * e1000_check_for_link. This routine will force the 
link up if
+                        * we detect a signal. This will allow us to 
communicate with
+                        * non-autonegotiating link partners.
+                        */
+                       if((ret_val = e1000_check_for_link(hw))) {
+                               DEBUGOUT("Error while checking for link\n");
+                               return ret_val;
+                       }
+                       hw->autoneg_failed = 0;
+               } else {
+                       hw->autoneg_failed = 0;
+                       DEBUGOUT("Valid Link Found\n");
+               }
+       } else {
+               DEBUGOUT("No Signal Detected\n");
+       }
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Detects which PHY is present and the speed and duplex
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_setup_copper_link(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       int32_t ret_val;
+       uint16_t i;
+       uint16_t phy_data;
+       
+       DEBUGFUNC("e1000_setup_copper_link");
+       
+       ctrl = E1000_READ_REG(hw, CTRL);
+       /* With 82543, we need to force speed and duplex on the MAC equal to 
what
+        * the PHY speed and duplex configuration is. In addition, we need to
+        * perform a hardware reset on the PHY to take it out of reset.
+        */
+       if(hw->mac_type > e1000_82543) {
+               ctrl |= E1000_CTRL_SLU;
+               ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+       } else {
+               ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX | 
E1000_CTRL_SLU);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               e1000_phy_hw_reset(hw);
+       }
+       
+       /* Make sure we have a valid PHY */
+       if((ret_val = e1000_detect_gig_phy(hw))) {
+               DEBUGOUT("Error, did not detect valid phy.\n");
+               return ret_val;
+       }
+       DEBUGOUT1("Phy ID = %x \n", hw->phy_id);
+
+       if(hw->mac_type <= e1000_82543 ||
+          hw->mac_type == e1000_82541 || hw->mac_type == e1000_82547 ||
+#if 0
+          hw->mac_type == e1000_82541_rev_2 || hw->mac_type == 
e1000_82547_rev_2)
+               hw->phy_reset_disable = FALSE;
+
+       if(!hw->phy_reset_disable) {
+#else
+          hw->mac_type == e1000_82541_rev_2 || hw->mac_type == 
e1000_82547_rev_2) {
+#endif
+       if (hw->phy_type == e1000_phy_igp) {
+
+               if((ret_val = e1000_phy_reset(hw))) {
+                       DEBUGOUT("Error Resetting the PHY\n");
+                       return ret_val;
+               }
+
+               /* Wait 10ms for MAC to configure PHY from eeprom settings */
+               mdelay(15);
+
+#if 0
+               /* disable lplu d3 during driver init */
+               if((ret_val = e1000_set_d3_lplu_state(hw, FALSE))) {
+                       DEBUGOUT("Error Disabling LPLU D3\n");
+                       return ret_val;
+               }
+
+               /* Configure mdi-mdix settings */
+               if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                                &phy_data)))
+                       return ret_val;
+
+               if((hw->mac_type == e1000_82541) || (hw->mac_type == 
e1000_82547)) {
+                       hw->dsp_config_state = e1000_dsp_config_disabled;
+                       /* Force MDI for IGP B-0 PHY */
+                       phy_data &= ~(IGP01E1000_PSCR_AUTO_MDIX |
+                                     IGP01E1000_PSCR_FORCE_MDI_MDIX);
+                       hw->mdix = 1;
+
+               } else {
+                       hw->dsp_config_state = e1000_dsp_config_enabled;
+                       phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX;
+
+                       switch (hw->mdix) {
+                       case 1:
+                               phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX;
+                               break;
+                       case 2:
+                               phy_data |= IGP01E1000_PSCR_FORCE_MDI_MDIX;
+                               break;
+                       case 0:
+                       default:
+                               phy_data |= IGP01E1000_PSCR_AUTO_MDIX;
+                               break;
+                       }
+               }
+               if((ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL,
+                                                 phy_data)))
+                       return ret_val;
+
+               /* set auto-master slave resolution settings */
+               e1000_ms_type phy_ms_setting = hw->master_slave;
+
+               if(hw->ffe_config_state == e1000_ffe_config_active)
+                       hw->ffe_config_state = e1000_ffe_config_enabled;
+
+               if(hw->dsp_config_state == e1000_dsp_config_activated)
+                       hw->dsp_config_state = e1000_dsp_config_enabled;
+#endif
+
+               /* when autonegotiation advertisment is only 1000Mbps then we
+                * should disable SmartSpeed and enable Auto MasterSlave
+                * resolution as hardware default. */
+               if(hw->autoneg_advertised == ADVERTISE_1000_FULL) {
+                       /* Disable SmartSpeed */
+                       if((ret_val = e1000_read_phy_reg(hw,
+                                                        
IGP01E1000_PHY_PORT_CONFIG,
+                                                        &phy_data)))
+                               return ret_val;
+                       phy_data &= ~IGP01E1000_PSCFR_SMART_SPEED;
+                       if((ret_val = e1000_write_phy_reg(hw,
+                                                         
IGP01E1000_PHY_PORT_CONFIG,
+                                                         phy_data)))
+                               return ret_val;
+                       /* Set auto Master/Slave resolution process */
+                       if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+                                                        &phy_data)))
+                               return ret_val;
+                       phy_data &= ~CR_1000T_MS_ENABLE;
+                       if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+                                                         phy_data)))
+                               return ret_val;
+               }
+
+               if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL,
+                                                &phy_data)))
+                       return ret_val;
+
+#if 0
+               /* load defaults for future use */
+               hw->original_master_slave = (phy_data & CR_1000T_MS_ENABLE) ?
+                                           ((phy_data & CR_1000T_MS_VALUE) ?
+                                            e1000_ms_force_master :
+                                            e1000_ms_force_slave) :
+                                            e1000_ms_auto;
+
+               switch (phy_ms_setting) {
+               case e1000_ms_force_master:
+                       phy_data |= (CR_1000T_MS_ENABLE | CR_1000T_MS_VALUE);
+                       break;
+               case e1000_ms_force_slave:
+                       phy_data |= CR_1000T_MS_ENABLE;
+                       phy_data &= ~(CR_1000T_MS_VALUE);
+                       break;
+               case e1000_ms_auto:
+                       phy_data &= ~CR_1000T_MS_ENABLE;
+               default:
+                       break;
+               }
+#endif
+
+               if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL,
+                                                 phy_data)))
+                       return ret_val;
+       } else {
+               /* Enable CRS on TX. This must be set for half-duplex 
operation. */
+               if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                                &phy_data)))
+                       return ret_val;
+
+               phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+
+               /* Options:
+                *   MDI/MDI-X = 0 (default)
+                *   0 - Auto for all speeds
+                *   1 - MDI mode
+                *   2 - MDI-X mode
+                *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+                */
+#if 0
+               phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+               switch (hw->mdix) {
+               case 1:
+                       phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+                       break;
+               case 2:
+                       phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+                       break;
+               case 3:
+                       phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+                       break;
+               case 0:
+               default:
+#endif
+                       phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+#if 0
+                       break;
+               }
+#endif
+
+               /* Options:
+                *   disable_polarity_correction = 0 (default)
+                *       Automatic Correction for Reversed Cable Polarity
+                *   0 - Disabled
+                *   1 - Enabled
+                */
+               phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+               if((ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL,
+                                                 phy_data)))
+                       return ret_val;
+
+               /* Force TX_CLK in the Extended PHY Specific Control Register
+                * to 25MHz clock.
+                */
+               if((ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                                &phy_data)))
+                       return ret_val;
+
+               phy_data |= M88E1000_EPSCR_TX_CLK_25;
+
+#ifdef LINUX_DRIVER
+               if (hw->phy_revision < M88E1011_I_REV_4) {
+#endif
+                       /* Configure Master and Slave downshift values */
+                       phy_data &= ~(M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK |
+                               M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK);
+                       phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X |
+                               M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X);
+                       if((ret_val = e1000_write_phy_reg(hw,
+                                                         
M88E1000_EXT_PHY_SPEC_CTRL,
+                                                         phy_data)))
+                               return ret_val;
+               }
+       
+               /* SW Reset the PHY so all changes take effect */
+               if((ret_val = e1000_phy_reset(hw))) {
+                       DEBUGOUT("Error Resetting the PHY\n");
+                       return ret_val;
+#ifdef LINUX_DRIVER
+               }
+#endif
+       }
+       
+       /* Options:
+        *   autoneg = 1 (default)
+        *      PHY will advertise value(s) parsed from
+        *      autoneg_advertised and fc
+        *   autoneg = 0
+        *      PHY will be set to 10H, 10F, 100H, or 100F
+        *      depending on value parsed from forced_speed_duplex.
+        */
+       
+       /* Is autoneg enabled?  This is enabled by default or by software
+        * override.  If so, call e1000_phy_setup_autoneg routine to parse the
+        * autoneg_advertised and fc options. If autoneg is NOT enabled, then
+        * the user should have provided a speed/duplex override.  If so, then
+        * call e1000_phy_force_speed_duplex to parse and set this up.
+        */
+       /* Perform some bounds checking on the hw->autoneg_advertised
+        * parameter.  If this variable is zero, then set it to the default.
+        */
+       hw->autoneg_advertised &= AUTONEG_ADVERTISE_SPEED_DEFAULT;
+       
+       /* If autoneg_advertised is zero, we assume it was not defaulted
+        * by the calling code so we set to advertise full capability.
+        */
+       if(hw->autoneg_advertised == 0)
+               hw->autoneg_advertised = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+       
+       DEBUGOUT("Reconfiguring auto-neg advertisement params\n");
+       if((ret_val = e1000_phy_setup_autoneg(hw))) {
+               DEBUGOUT("Error Setting up Auto-Negotiation\n");
+               return ret_val;
+       }
+       DEBUGOUT("Restarting Auto-Neg\n");
+       
+       /* Restart auto-negotiation by setting the Auto Neg Enable bit and
+        * the Auto Neg Restart bit in the PHY control register.
+        */
+       if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+               return ret_val;
+
+       phy_data |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG);
+       if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
+               return ret_val;
+
+#if 0  
+       /* Does the user want to wait for Auto-Neg to complete here, or
+        * check at a later time (for example, callback routine).
+        */
+       if(hw->wait_autoneg_complete) {
+               if((ret_val = e1000_wait_autoneg(hw))) {
+                       DEBUGOUT("Error while waiting for autoneg to 
complete\n");
+                       return ret_val;
+               }
+       }
+#else
+       /* If we do not wait for autonegotiation to complete I 
+        * do not see a valid link status.
+        */
+       if((ret_val = e1000_wait_autoneg(hw))) {
+               DEBUGOUT("Error while waiting for autoneg to complete\n");
+               return ret_val;
+       }
+#endif
+       } /* !hw->phy_reset_disable */
+       
+       /* Check link status. Wait up to 100 microseconds for link to become
+        * valid.
+        */
+       for(i = 0; i < 10; i++) {
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+
+               if(phy_data & MII_SR_LINK_STATUS) {
+                       /* We have link, so we need to finish the config 
process:
+                        *   1) Set up the MAC to the current PHY speed/duplex
+                        *      if we are on 82543.  If we
+                        *      are on newer silicon, we only need to configure
+                        *      collision distance in the Transmit Control 
Register.
+                        *   2) Set up flow control on the MAC to that 
established with
+                        *      the link partner.
+                        */
+                       if(hw->mac_type >= e1000_82544) {
+                               e1000_config_collision_dist(hw);
+                       } else {
+                               if((ret_val = e1000_config_mac_to_phy(hw))) {
+                                       DEBUGOUT("Error configuring MAC to PHY 
settings\n");
+                                       return ret_val;
+                               }
+                       }
+                       if((ret_val = e1000_config_fc_after_link_up(hw))) {
+                               DEBUGOUT("Error Configuring Flow Control\n");
+                               return ret_val;
+                       }
+#if 0
+                       if(hw->phy_type == e1000_phy_igp) {
+                               if((ret_val = 
e1000_config_dsp_after_link_change(hw, TRUE))) {
+                                       DEBUGOUT("Error Configuring DSP after 
link up\n");
+                                       return ret_val;
+                               }
+                       }
+#endif
+                       DEBUGOUT("Valid link established!!!\n");
+                       return E1000_SUCCESS;
+               }
+               udelay(10);
+       }
+       
+       DEBUGOUT("Unable to establish link!!!\n");
+       return -E1000_ERR_NOLINK;
+}
+
+/******************************************************************************
+* Configures PHY autoneg and flow control advertisement settings
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_phy_setup_autoneg(struct e1000_hw *hw)
+{
+       int32_t ret_val;
+       uint16_t mii_autoneg_adv_reg;
+       uint16_t mii_1000t_ctrl_reg;
+
+       DEBUGFUNC("e1000_phy_setup_autoneg");
+       
+       /* Read the MII Auto-Neg Advertisement Register (Address 4). */
+       if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                        &mii_autoneg_adv_reg)))
+               return ret_val;
+
+       /* Read the MII 1000Base-T Control Register (Address 9). */
+       if((ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, 
&mii_1000t_ctrl_reg)))
+               return ret_val;
+
+       /* Need to parse both autoneg_advertised and fc and set up
+        * the appropriate PHY registers.  First we will parse for
+        * autoneg_advertised software override.  Since we can advertise
+        * a plethora of combinations, we need to check each bit
+        * individually.
+        */
+       
+       /* First we clear all the 10/100 mb speed bits in the Auto-Neg
+        * Advertisement Register (Address 4) and the 1000 mb speed bits in
+        * the  1000Base-T Control Register (Address 9).
+        */
+       mii_autoneg_adv_reg &= ~REG4_SPEED_MASK;
+       mii_1000t_ctrl_reg &= ~REG9_SPEED_MASK;
+
+       DEBUGOUT1("autoneg_advertised %x\n", hw->autoneg_advertised);
+
+       /* Do we want to advertise 10 Mb Half Duplex? */
+       if(hw->autoneg_advertised & ADVERTISE_10_HALF) {
+               DEBUGOUT("Advertise 10mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_HD_CAPS;
+       }
+
+       /* Do we want to advertise 10 Mb Full Duplex? */
+       if(hw->autoneg_advertised & ADVERTISE_10_FULL) {
+               DEBUGOUT("Advertise 10mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_10T_FD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Half Duplex? */
+       if(hw->autoneg_advertised & ADVERTISE_100_HALF) {
+               DEBUGOUT("Advertise 100mb Half duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_HD_CAPS;
+       }
+
+       /* Do we want to advertise 100 Mb Full Duplex? */
+       if(hw->autoneg_advertised & ADVERTISE_100_FULL) {
+               DEBUGOUT("Advertise 100mb Full duplex\n");
+               mii_autoneg_adv_reg |= NWAY_AR_100TX_FD_CAPS;
+       }
+
+       /* We do not allow the Phy to advertise 1000 Mb Half Duplex */
+       if(hw->autoneg_advertised & ADVERTISE_1000_HALF) {
+               DEBUGOUT("Advertise 1000mb Half duplex requested, request 
denied!\n");
+       }
+
+       /* Do we want to advertise 1000 Mb Full Duplex? */
+       if(hw->autoneg_advertised & ADVERTISE_1000_FULL) {
+               DEBUGOUT("Advertise 1000mb Full duplex\n");
+               mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
+       }
+
+       /* Check for a software override of the flow control settings, and
+        * setup the PHY advertisement registers accordingly.  If
+        * auto-negotiation is enabled, then software will have to set the
+        * "PAUSE" bits to the correct value in the Auto-Negotiation
+        * Advertisement Register (PHY_AUTONEG_ADV) and re-start 
auto-negotiation.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause frames
+        *          but not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames
+        *          but we do not support receiving pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) are enabled.
+        *  other:  No software override.  The flow control configuration
+        *          in the EEPROM is used.
+        */
+       switch (hw->fc) {
+       case e1000_fc_none: /* 0 */
+               /* Flow control (RX & TX) is completely disabled by a
+                * software over-ride.
+                */
+               mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_rx_pause: /* 1 */
+               /* RX Flow control is enabled, and TX Flow control is
+                * disabled, by a software over-ride.
+                */
+               /* Since there really isn't a way to advertise that we are
+                * capable of RX Pause ONLY, we will advertise that we
+                * support both symmetric and asymmetric RX PAUSE.  Later
+                * (in e1000_config_fc_after_link_up) we will disable the
+                *hw's ability to send PAUSE frames.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       case e1000_fc_tx_pause: /* 2 */
+               /* TX Flow control is enabled, and RX Flow control is
+                * disabled, by a software over-ride.
+                */
+               mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
+               mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
+               break;
+       case e1000_fc_full: /* 3 */
+               /* Flow control (both RX and TX) is enabled by a software
+                * over-ride.
+                */
+               mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+       }
+
+       if((ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV,
+                              mii_autoneg_adv_reg)))
+               return ret_val;
+
+       DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg);
+
+       if((ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, 
mii_1000t_ctrl_reg)))
+               return ret_val;
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Sets the collision distance in the Transmit Control register
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Link should have been established previously. Reads the speed and duplex
+* information from the Device Status register.
+******************************************************************************/
+static void
+e1000_config_collision_dist(struct e1000_hw *hw)
+{
+       uint32_t tctl;
+
+       tctl = E1000_READ_REG(hw, TCTL);
+       
+       tctl &= ~E1000_TCTL_COLD;
+       tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT;
+       
+       E1000_WRITE_REG(hw, TCTL, tctl);
+       E1000_WRITE_FLUSH(hw);
+}
+
+/******************************************************************************
+* Sets MAC speed and duplex settings to reflect the those in the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* mii_reg - data to write to the MII control register
+*
+* The contents of the PHY register containing the needed information need to
+* be passed in.
+******************************************************************************/
+static int
+e1000_config_mac_to_phy(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       int32_t ret_val;
+       uint16_t phy_data;
+
+       DEBUGFUNC("e1000_config_mac_to_phy");
+
+       /* Read the Device Control Register and set the bits to Force Speed
+        * and Duplex.
+        */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
+       ctrl &= ~(E1000_CTRL_SPD_SEL | E1000_CTRL_ILOS);
+
+       /* Set up duplex in the Device Control and Transmit Control
+        * registers depending on negotiated values.
+        */
+       if (hw->phy_type == e1000_phy_igp) {
+               if((ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS,
+                                                &phy_data)))
+                       return ret_val;
+
+               if(phy_data & IGP01E1000_PSSR_FULL_DUPLEX) ctrl |= 
E1000_CTRL_FD;
+               else ctrl &= ~E1000_CTRL_FD;
+
+               e1000_config_collision_dist(hw);
+
+               /* Set up speed in the Device Control register depending on
+                * negotiated values.
+                */
+               if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+                  IGP01E1000_PSSR_SPEED_1000MBPS)
+                       ctrl |= E1000_CTRL_SPD_1000;
+               else if((phy_data & IGP01E1000_PSSR_SPEED_MASK) ==
+                       IGP01E1000_PSSR_SPEED_100MBPS)
+                       ctrl |= E1000_CTRL_SPD_100;
+       } else {
+               if((ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS,
+                                                &phy_data)))
+                       return ret_val;
+               
+               if(phy_data & M88E1000_PSSR_DPLX) ctrl |= E1000_CTRL_FD;
+               else ctrl &= ~E1000_CTRL_FD;
+
+               e1000_config_collision_dist(hw);
+
+               /* Set up speed in the Device Control register depending on
+                * negotiated values.
+                */
+               if((phy_data & M88E1000_PSSR_SPEED) == M88E1000_PSSR_1000MBS)
+                       ctrl |= E1000_CTRL_SPD_1000;
+               else if((phy_data & M88E1000_PSSR_SPEED) == 
M88E1000_PSSR_100MBS)
+                       ctrl |= E1000_CTRL_SPD_100;
+       }
+       /* Write the configured values back to the Device Control Reg. */
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Forces the MAC's flow control settings.
+ * 
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Sets the TFCE and RFCE bits in the device control register to reflect
+ * the adapter settings. TFCE and RFCE need to be explicitly set by
+ * software when a Copper PHY is used because autonegotiation is managed
+ * by the PHY rather than the MAC. Software must also configure these
+ * bits when link is forced on a fiber connection.
+ *****************************************************************************/
+static int
+e1000_force_mac_fc(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       
+       DEBUGFUNC("e1000_force_mac_fc");
+       
+       /* Get the current configuration of the Device Control Register */
+       ctrl = E1000_READ_REG(hw, CTRL);
+       
+       /* Because we didn't get link via the internal auto-negotiation
+        * mechanism (we either forced link or we got link via PHY
+        * auto-neg), we have to manually enable/disable transmit an
+        * receive flow control.
+        *
+        * The "Case" statement below enables/disable flow control
+        * according to the "hw->fc" parameter.
+        *
+        * The possible values of the "fc" parameter are:
+        *      0:  Flow control is completely disabled
+        *      1:  Rx flow control is enabled (we can receive pause
+        *          frames but not send pause frames).
+        *      2:  Tx flow control is enabled (we can send pause frames
+        *          frames but we do not receive pause frames).
+        *      3:  Both Rx and TX flow control (symmetric) is enabled.
+        *  other:  No other values should be possible at this point.
+        */
+       
+       switch (hw->fc) {
+       case e1000_fc_none:
+               ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
+               break;
+       case e1000_fc_rx_pause:
+               ctrl &= (~E1000_CTRL_TFCE);
+               ctrl |= E1000_CTRL_RFCE;
+               break;
+       case e1000_fc_tx_pause:
+               ctrl &= (~E1000_CTRL_RFCE);
+               ctrl |= E1000_CTRL_TFCE;
+               break;
+       case e1000_fc_full:
+               ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE);
+               break;
+       default:
+               DEBUGOUT("Flow control param set incorrectly\n");
+               return -E1000_ERR_CONFIG;
+       }
+       
+       /* Disable TX Flow Control for 82542 (rev 2.0) */
+       if(hw->mac_type == e1000_82542_rev2_0)
+               ctrl &= (~E1000_CTRL_TFCE);
+       
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Configures flow control settings after link is established
+ * 
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Should be called immediately after a valid link has been established.
+ * Forces MAC flow control settings if link was forced. When in MII/GMII mode
+ * and autonegotiation is enabled, the MAC flow control settings will be set
+ * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
+ * and RFCE bits will be automaticaly set to the negotiated flow control mode.
+ *****************************************************************************/
+static int
+e1000_config_fc_after_link_up(struct e1000_hw *hw)
+{
+       int32_t ret_val;
+       uint16_t mii_status_reg;
+       uint16_t mii_nway_adv_reg;
+       uint16_t mii_nway_lp_ability_reg;
+       uint16_t speed;
+       uint16_t duplex;
+       
+       DEBUGFUNC("e1000_config_fc_after_link_up");
+       
+       /* Check for the case where we have fiber media and auto-neg failed
+        * so we had to force link.  In this case, we need to force the
+        * configuration of the MAC to match the "fc" parameter.
+        */
+       if(((hw->media_type == e1000_media_type_fiber) && (hw->autoneg_failed)) 
||
+          ((hw->media_type == e1000_media_type_internal_serdes) && 
(hw->autoneg_failed))) { 
+               if((ret_val = e1000_force_mac_fc(hw))) {
+                       DEBUGOUT("Error forcing flow control settings\n");
+                       return ret_val;
+               }
+       }
+       
+       /* Check for the case where we have copper media and auto-neg is
+        * enabled.  In this case, we need to check and see if Auto-Neg
+        * has completed, and if so, how the PHY and link partner has
+        * flow control configured.
+        */
+       if(hw->media_type == e1000_media_type_copper) {
+               /* Read the MII Status Register and check to see if AutoNeg
+                * has completed.  We read this twice because this reg has
+                * some "sticky" (latched) bits.
+                */
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, 
&mii_status_reg)))
+                       return ret_val;
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, 
&mii_status_reg)))
+                       return ret_val;
+               
+               if(mii_status_reg & MII_SR_AUTONEG_COMPLETE) {
+                       /* The AutoNeg process has completed, so we now need to
+                        * read both the Auto Negotiation Advertisement Register
+                        * (Address 4) and the Auto_Negotiation Base Page 
Ability
+                        * Register (Address 5) to determine how flow control 
was
+                        * negotiated.
+                        */
+                       if((ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV,
+                                                        &mii_nway_adv_reg)))
+                               return ret_val;
+                       if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
+                                                        
&mii_nway_lp_ability_reg)))
+                               return ret_val;
+
+                       /* Two bits in the Auto Negotiation Advertisement 
Register
+                        * (Address 4) and two bits in the Auto Negotiation Base
+                        * Page Ability Register (Address 5) determine flow 
control
+                        * for both the PHY and the link partner.  The following
+                        * table, taken out of the IEEE 802.3ab/D6.0 dated 
March 25,
+                        * 1999, describes these PAUSE resolution bits and how 
flow
+                        * control is determined based upon these settings.
+                        * NOTE:  DC = Don't Care
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution
+                        
*-------|---------|-------|---------|--------------------
+                        *   0   |    0    |  DC   |   DC    | e1000_fc_none
+                        *   0   |    1    |   0   |   DC    | e1000_fc_none
+                        *   0   |    1    |   1   |    0    | e1000_fc_none
+                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                        *   1   |    0    |   0   |   DC    | e1000_fc_none
+                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
+                        *   1   |    1    |   0   |    0    | e1000_fc_none
+                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                        *
+                        */
+                       /* Are both PAUSE bits set to 1?  If so, this implies
+                        * Symmetric Flow Control is enabled at both ends.  The
+                        * ASM_DIR bits are irrelevant per the spec.
+                        *
+                        * For Symmetric Flow Control:
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        
*-------|---------|-------|---------|--------------------
+                        *   1   |   DC    |   1   |   DC    | e1000_fc_full
+                        *
+                        */
+                       if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                               (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
+                               /* Now we need to check if the user selected RX 
ONLY
+                                * of pause frames.  In this case, we had to 
advertise
+                                * FULL flow control because we could not 
advertise RX
+                                * ONLY. Hence, we must now check to see if we 
need to
+                                * turn OFF  the TRANSMISSION of PAUSE frames.
+                                */
+#if 0
+                               if(hw->original_fc == e1000_fc_full) {
+                                       hw->fc = e1000_fc_full;
+#else
+                               if(hw->fc == e1000_fc_full) {
+#endif
+                                       DEBUGOUT("Flow Control = FULL.\r\n");
+                               } else {
+                                       hw->fc = e1000_fc_rx_pause;
+                                       DEBUGOUT("Flow Control = RX PAUSE 
frames only.\r\n");
+                               }
+                       }
+                       /* For receiving PAUSE frames ONLY.
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        
*-------|---------|-------|---------|--------------------
+                        *   0   |    1    |   1   |    1    | e1000_fc_tx_pause
+                        *
+                        */
+                       else if(!(mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                               (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                               (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                               (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+                               hw->fc = e1000_fc_tx_pause;
+                               DEBUGOUT("Flow Control = TX PAUSE frames 
only.\r\n");
+                       }
+                       /* For transmitting PAUSE frames ONLY.
+                        *
+                        *   LOCAL DEVICE  |   LINK PARTNER
+                        * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
+                        
*-------|---------|-------|---------|--------------------
+                        *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
+                        *
+                        */
+                       else if((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
+                               (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
+                               !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
+                               (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
+                               hw->fc = e1000_fc_rx_pause;
+                               DEBUGOUT("Flow Control = RX PAUSE frames 
only.\r\n");
+                       }
+                       /* Per the IEEE spec, at this point flow control should 
be
+                        * disabled.  However, we want to consider that we could
+                        * be connected to a legacy switch that doesn't 
advertise
+                        * desired flow control, but can be forced on the link
+                        * partner.  So if we advertised no flow control, that 
is
+                        * what we will resolve to.  If we advertised some kind 
of
+                        * receive capability (Rx Pause Only or Full Flow 
Control)
+                        * and the link partner advertised none, we will 
configure
+                        * ourselves to enable Rx Flow Control only.  We can do
+                        * this safely for two reasons:  If the link partner 
really
+                        * didn't want flow control enabled, and we enable Rx, 
no
+                        * harm done since we won't be receiving any PAUSE 
frames
+                        * anyway.  If the intent on the link partner was to 
have
+                        * flow control enabled, then by us enabling RX only, we
+                        * can at least receive pause frames and process them.
+                        * This is a good idea because in most cases, since we 
are
+                        * predominantly a server NIC, more times than not we 
will
+                        * be asked to delay transmission of packets than asking
+                        * our link partner to pause transmission of frames.
+                        */
+#if 0
+                       else if(hw->original_fc == e1000_fc_none ||
+                               hw->original_fc == e1000_fc_tx_pause) {
+#else
+                       else if(hw->fc == e1000_fc_none)
+                               DEBUGOUT("Flow Control = NONE.\r\n");
+                       else if(hw->fc == e1000_fc_tx_pause) {
+#endif
+                               hw->fc = e1000_fc_none;
+                               DEBUGOUT("Flow Control = NONE.\r\n");
+                       } else {
+                               hw->fc = e1000_fc_rx_pause;
+                               DEBUGOUT("Flow Control = RX PAUSE frames 
only.\r\n");
+                       }
+                       
+                       /* Now we need to do one last check...  If we auto-
+                        * negotiated to HALF DUPLEX, flow control should not be
+                        * enabled per IEEE 802.3 spec.
+                        */
+                       e1000_get_speed_and_duplex(hw, &speed, &duplex);
+                       
+                       if(duplex == HALF_DUPLEX)
+                               hw->fc = e1000_fc_none;
+                       
+                       /* Now we call a subroutine to actually force the MAC
+                        * controller to use the correct flow control settings.
+                        */
+                       if((ret_val = e1000_force_mac_fc(hw))) {
+                               DEBUGOUT("Error forcing flow control 
settings\n");
+                               return ret_val;
+                       }
+               } else {
+                       DEBUGOUT("Copper PHY and Auto Neg has not 
completed.\r\n");
+               }
+       }
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Checks to see if the link status of the hardware has changed.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *
+ * Called by any function that needs to check the link status of the adapter.
+ *****************************************************************************/
+static int
+e1000_check_for_link(struct e1000_hw *hw)
+{
+       uint32_t rxcw;
+       uint32_t ctrl;
+       uint32_t status;
+       uint32_t rctl;
+       uint32_t signal = 0;
+       int32_t ret_val;
+       uint16_t phy_data;
+       uint16_t lp_capability;
+       
+       DEBUGFUNC("e1000_check_for_link");
+       
+       /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be 
+        * set when the optics detect a signal. On older adapters, it will be 
+        * cleared when there is a signal.  This applies to fiber media only.
+        */
+       if(hw->media_type == e1000_media_type_fiber)
+               signal = (hw->mac_type > e1000_82544) ? E1000_CTRL_SWDPIN1 : 0;
+
+       ctrl = E1000_READ_REG(hw, CTRL);
+       status = E1000_READ_REG(hw, STATUS);
+       rxcw = E1000_READ_REG(hw, RXCW);
+       
+       /* If we have a copper PHY then we only want to go out to the PHY
+        * registers to see if Auto-Neg has completed and/or if our link
+        * status has changed.  The get_link_status flag will be set if we
+        * receive a Link Status Change interrupt or we have Rx Sequence
+        * Errors.
+        */
+#if 0
+       if((hw->media_type == e1000_media_type_copper) && hw->get_link_status) {
+#else
+       if(hw->media_type == e1000_media_type_copper) {
+#endif
+               /* First we want to see if the MII Status Register reports
+                * link.  If so, then we want to get the current speed/duplex
+                * of the PHY.
+                * Read the register twice since the link bit is sticky.
+                */
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+               
+               if(phy_data & MII_SR_LINK_STATUS) {
+#if 0
+                       hw->get_link_status = FALSE;
+#endif
+               } else {
+                       /* No link detected */
+                       return -E1000_ERR_NOLINK;
+               }
+
+               /* We have a M88E1000 PHY and Auto-Neg is enabled.  If we
+                * have Si on board that is 82544 or newer, Auto
+                * Speed Detection takes care of MAC speed/duplex
+                * configuration.  So we only need to configure Collision
+                * Distance in the MAC.  Otherwise, we need to force
+                * speed/duplex on the MAC to the current PHY speed/duplex
+                * settings.
+                */
+               if(hw->mac_type >= e1000_82544)
+                       e1000_config_collision_dist(hw);
+               else {
+                       if((ret_val = e1000_config_mac_to_phy(hw))) {
+                               DEBUGOUT("Error configuring MAC to PHY 
settings\n");
+                               return ret_val;
+                       }
+               }
+               
+               /* Configure Flow Control now that Auto-Neg has completed. 
First, we 
+                * need to restore the desired flow control settings because we 
may
+                * have had to re-autoneg with a different link partner.
+                */
+               if((ret_val = e1000_config_fc_after_link_up(hw))) {
+                       DEBUGOUT("Error configuring flow control\n");
+                       return ret_val;
+               }
+               
+               /* At this point we know that we are on copper and we have
+                * auto-negotiated link.  These are conditions for checking the 
link
+                * parter capability register.  We use the link partner 
capability to
+                * determine if TBI Compatibility needs to be turned on or off. 
 If
+                * the link partner advertises any speed in addition to 
Gigabit, then
+                * we assume that they are GMII-based, and TBI compatibility is 
not
+                * needed. If no other speeds are advertised, we assume the link
+                * partner is TBI-based, and we turn on TBI Compatibility.
+                */
+               if(hw->tbi_compatibility_en) {
+                       if((ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY,
+                                                        &lp_capability)))
+                               return ret_val;
+                       if(lp_capability & (NWAY_LPAR_10T_HD_CAPS |
+                                NWAY_LPAR_10T_FD_CAPS |
+                                NWAY_LPAR_100TX_HD_CAPS |
+                                NWAY_LPAR_100TX_FD_CAPS |
+                                NWAY_LPAR_100T4_CAPS)) {
+                               /* If our link partner advertises anything in 
addition to 
+                                * gigabit, we do not need to enable TBI 
compatibility.
+                                */
+                               if(hw->tbi_compatibility_on) {
+                                       /* If we previously were in the mode, 
turn it off. */
+                                       rctl = E1000_READ_REG(hw, RCTL);
+                                       rctl &= ~E1000_RCTL_SBP;
+                                       E1000_WRITE_REG(hw, RCTL, rctl);
+                                       hw->tbi_compatibility_on = FALSE;
+                               }
+                       } else {
+                               /* If TBI compatibility is was previously off, 
turn it on. For
+                                * compatibility with a TBI link partner, we 
will store bad
+                                * packets. Some frames have an additional byte 
on the end and
+                                * will look like CRC errors to to the hardware.
+                                */
+                               if(!hw->tbi_compatibility_on) {
+                                       hw->tbi_compatibility_on = TRUE;
+                                       rctl = E1000_READ_REG(hw, RCTL);
+                                       rctl |= E1000_RCTL_SBP;
+                                       E1000_WRITE_REG(hw, RCTL, rctl);
+                               }
+                       }
+               }
+       }
+       /* If we don't have link (auto-negotiation failed or link partner cannot
+        * auto-negotiate), the cable is plugged in (we have signal), and our
+        * link partner is not trying to auto-negotiate with us (we are 
receiving
+        * idles or data), we need to force link up. We also need to give
+        * auto-negotiation time to complete, in case the cable was just plugged
+        * in. The autoneg_failed flag does this.
+        */
+       else if((((hw->media_type == e1000_media_type_fiber) &&
+               ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
+               (hw->media_type == e1000_media_type_internal_serdes)) &&
+               (!(status & E1000_STATUS_LU)) &&
+               (!(rxcw & E1000_RXCW_C))) {
+               if(hw->autoneg_failed == 0) {
+                       hw->autoneg_failed = 1;
+                       return 0;
+               }
+               DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\r\n");
+               
+               /* Disable auto-negotiation in the TXCW register */
+               E1000_WRITE_REG(hw, TXCW, (hw->txcw & ~E1000_TXCW_ANE));
+               
+               /* Force link-up and also force full-duplex. */
+               ctrl = E1000_READ_REG(hw, CTRL);
+               ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               
+               /* Configure Flow Control after forcing link up. */
+               if((ret_val = e1000_config_fc_after_link_up(hw))) {
+                       DEBUGOUT("Error configuring flow control\n");
+                       return ret_val;
+               }
+       }
+       /* If we are forcing link and we are receiving /C/ ordered sets, 
re-enable
+        * auto-negotiation in the TXCW register and disable forced link in the
+        * Device Control register in an attempt to auto-negotiate with our link
+        * partner.
+        */
+       else if(((hw->media_type == e1000_media_type_fiber)  ||
+                (hw->media_type == e1000_media_type_internal_serdes)) &&
+               (ctrl & E1000_CTRL_SLU) &&
+               (rxcw & E1000_RXCW_C)) {
+               DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing 
link.\r\n");
+               E1000_WRITE_REG(hw, TXCW, hw->txcw);
+               E1000_WRITE_REG(hw, CTRL, (ctrl & ~E1000_CTRL_SLU));
+       }
+#if 0
+       /* If we force link for non-auto-negotiation switch, check link status
+        * based on MAC synchronization for internal serdes media type.
+        */
+       else if((hw->media_type == e1000_media_type_internal_serdes) &&
+                       !(E1000_TXCW_ANE & E1000_READ_REG(hw, TXCW))) {
+               /* SYNCH bit and IV bit are sticky. */
+               udelay(10);
+               if(E1000_RXCW_SYNCH & E1000_READ_REG(hw, RXCW)) {
+                       if(!(rxcw & E1000_RXCW_IV)) {
+                               hw->serdes_link_down = FALSE;
+                               DEBUGOUT("SERDES: Link is up.\n");
+                       }
+               } else {
+                       hw->serdes_link_down = TRUE;
+                       DEBUGOUT("SERDES: Link is down.\n");
+               }
+       }
+#endif
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+ * Detects the current speed and duplex settings of the hardware.
+ *
+ * hw - Struct containing variables accessed by shared code
+ * speed - Speed of the connection
+ * duplex - Duplex setting of the connection
+ *****************************************************************************/
+static void 
+e1000_get_speed_and_duplex(struct e1000_hw *hw,
+                           uint16_t *speed,
+                           uint16_t *duplex)
+{
+       uint32_t status;
+       
+       DEBUGFUNC("e1000_get_speed_and_duplex");
+       
+       if(hw->mac_type >= e1000_82543) {
+               status = E1000_READ_REG(hw, STATUS);
+               if(status & E1000_STATUS_SPEED_1000) {
+                       *speed = SPEED_1000;
+                       DEBUGOUT("1000 Mbs, ");
+               } else if(status & E1000_STATUS_SPEED_100) {
+                       *speed = SPEED_100;
+                       DEBUGOUT("100 Mbs, ");
+               } else {
+                       *speed = SPEED_10;
+                       DEBUGOUT("10 Mbs, ");
+               }
+               
+               if(status & E1000_STATUS_FD) {
+                       *duplex = FULL_DUPLEX;
+                       DEBUGOUT("Full Duplex\r\n");
+               } else {
+                       *duplex = HALF_DUPLEX;
+                       DEBUGOUT(" Half Duplex\r\n");
+               }
+       } else {
+               DEBUGOUT("1000 Mbs, Full Duplex\r\n");
+               *speed = SPEED_1000;
+               *duplex = FULL_DUPLEX;
+       }
+}
+
+/******************************************************************************
+* Blocks until autoneg completes or times out (~4.5 seconds)
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_wait_autoneg(struct e1000_hw *hw)
+{
+       int32_t ret_val;
+       uint16_t i;
+       uint16_t phy_data;
+       
+       DEBUGFUNC("e1000_wait_autoneg");
+       DEBUGOUT("Waiting for Auto-Neg to complete.\n");
+       
+       /* We will wait for autoneg to complete or 4.5 seconds to expire. */
+       for(i = PHY_AUTO_NEG_TIME; i > 0; i--) {
+               /* Read the MII Status Register and wait for Auto-Neg
+                * Complete bit to be set.
+                */
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+               if((ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_data)))
+                       return ret_val;
+               if(phy_data & MII_SR_AUTONEG_COMPLETE) {
+                       DEBUGOUT("Auto-Neg complete.\n");
+                       return E1000_SUCCESS;
+               }
+               mdelay(100);
+       }
+       DEBUGOUT("Auto-Neg timedout.\n");
+       return -E1000_ERR_TIMEOUT;
+}
+
+/******************************************************************************
+* Raises the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_raise_mdi_clk(struct e1000_hw *hw,
+                    uint32_t *ctrl)
+{
+       /* Raise the clock input to the Management Data Clock (by setting the 
MDC
+        * bit), and then delay 10 microseconds.
+        */
+       E1000_WRITE_REG(hw, CTRL, (*ctrl | E1000_CTRL_MDC));
+       E1000_WRITE_FLUSH(hw);
+       udelay(10);
+}
+
+/******************************************************************************
+* Lowers the Management Data Clock
+*
+* hw - Struct containing variables accessed by shared code
+* ctrl - Device control register's current value
+******************************************************************************/
+static void
+e1000_lower_mdi_clk(struct e1000_hw *hw,
+                    uint32_t *ctrl)
+{
+       /* Lower the clock input to the Management Data Clock (by clearing the 
MDC
+        * bit), and then delay 10 microseconds.
+        */
+       E1000_WRITE_REG(hw, CTRL, (*ctrl & ~E1000_CTRL_MDC));
+       E1000_WRITE_FLUSH(hw);
+       udelay(10);
+}
+
+/******************************************************************************
+* Shifts data bits out to the PHY
+*
+* hw - Struct containing variables accessed by shared code
+* data - Data to send out to the PHY
+* count - Number of bits to shift out
+*
+* Bits are shifted out in MSB to LSB order.
+******************************************************************************/
+static void
+e1000_shift_out_mdi_bits(struct e1000_hw *hw,
+                         uint32_t data,
+                         uint16_t count)
+{
+       uint32_t ctrl;
+       uint32_t mask;
+
+       /* We need to shift "count" number of bits out to the PHY. So, the value
+        * in the "data" parameter will be shifted out to the PHY one bit at a 
+        * time. In order to do this, "data" must be broken down into bits.
+        */
+       mask = 0x01;
+       mask <<= (count - 1);
+       
+       ctrl = E1000_READ_REG(hw, CTRL);
+       
+       /* Set MDIO_DIR and MDC_DIR direction bits to be used as output pins. */
+       ctrl |= (E1000_CTRL_MDIO_DIR | E1000_CTRL_MDC_DIR);
+       
+       while(mask) {
+               /* A "1" is shifted out to the PHY by setting the MDIO bit to 
"1" and
+                * then raising and lowering the Management Data Clock. A "0" is
+                * shifted out to the PHY by setting the MDIO bit to "0" and 
then
+                * raising and lowering the clock.
+                */
+               if(data & mask) ctrl |= E1000_CTRL_MDIO;
+               else ctrl &= ~E1000_CTRL_MDIO;
+               
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               E1000_WRITE_FLUSH(hw);
+               
+               udelay(10);
+
+               e1000_raise_mdi_clk(hw, &ctrl);
+               e1000_lower_mdi_clk(hw, &ctrl);
+
+               mask = mask >> 1;
+       }
+}
+
+/******************************************************************************
+* Shifts data bits in from the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Bits are shifted in in MSB to LSB order. 
+******************************************************************************/
+static uint16_t
+e1000_shift_in_mdi_bits(struct e1000_hw *hw)
+{
+       uint32_t ctrl;
+       uint16_t data = 0;
+       uint8_t i;
+
+       /* In order to read a register from the PHY, we need to shift in a total
+        * of 18 bits from the PHY. The first two bit (turnaround) times are 
used
+        * to avoid contention on the MDIO pin when a read operation is 
performed.
+        * These two bits are ignored by us and thrown away. Bits are "shifted 
in"
+        * by raising the input to the Management Data Clock (setting the MDC 
bit),
+        * and then reading the value of the MDIO bit.
+        */ 
+       ctrl = E1000_READ_REG(hw, CTRL);
+       
+       /* Clear MDIO_DIR (SWDPIO1) to indicate this bit is to be used as 
input. */
+       ctrl &= ~E1000_CTRL_MDIO_DIR;
+       ctrl &= ~E1000_CTRL_MDIO;
+       
+       E1000_WRITE_REG(hw, CTRL, ctrl);
+       E1000_WRITE_FLUSH(hw);
+       
+       /* Raise and Lower the clock before reading in the data. This accounts 
for
+        * the turnaround bits. The first clock occurred when we clocked out the
+        * last bit of the Register Address.
+        */
+       e1000_raise_mdi_clk(hw, &ctrl);
+       e1000_lower_mdi_clk(hw, &ctrl);
+       
+       for(data = 0, i = 0; i < 16; i++) {
+               data = data << 1;
+               e1000_raise_mdi_clk(hw, &ctrl);
+               ctrl = E1000_READ_REG(hw, CTRL);
+               /* Check to see if we shifted in a "1". */
+               if(ctrl & E1000_CTRL_MDIO) data |= 1;
+               e1000_lower_mdi_clk(hw, &ctrl);
+       }
+       
+       e1000_raise_mdi_clk(hw, &ctrl);
+       e1000_lower_mdi_clk(hw, &ctrl);
+       
+       return data;
+}
+
+/*****************************************************************************
+* Reads the value from a PHY register, if the value is on a specific non zero
+* page, sets the page first.
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to read
+******************************************************************************/
+static int
+e1000_read_phy_reg(struct e1000_hw *hw,
+                   uint32_t reg_addr,
+                   uint16_t *phy_data)
+{
+       uint32_t ret_val;
+
+       DEBUGFUNC("e1000_read_phy_reg");
+
+       if(hw->phy_type == e1000_phy_igp &&
+          (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+               if((ret_val = e1000_write_phy_reg_ex(hw, 
IGP01E1000_PHY_PAGE_SELECT,
+                                                    (uint16_t)reg_addr)))
+                       return ret_val;
+       }
+
+       ret_val = e1000_read_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & 
reg_addr,
+                                       phy_data);
+
+       return ret_val;
+}
+
+static int
+e1000_read_phy_reg_ex(struct e1000_hw *hw,
+                      uint32_t reg_addr,
+                      uint16_t *phy_data)
+{
+       uint32_t i;
+       uint32_t mdic = 0;
+       const uint32_t phy_addr = 1;
+
+       DEBUGFUNC("e1000_read_phy_reg_ex");
+       
+       if(reg_addr > MAX_PHY_REG_ADDRESS) {
+               DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+               return -E1000_ERR_PARAM;
+       }
+       
+       if(hw->mac_type > e1000_82543) {
+               /* Set up Op-code, Phy Address, and register address in the MDI
+                * Control register.  The MAC will take care of interfacing 
with the
+                * PHY to retrieve the desired data.
+                */
+               mdic = ((reg_addr << E1000_MDIC_REG_SHIFT) |
+                       (phy_addr << E1000_MDIC_PHY_SHIFT) | 
+                       (E1000_MDIC_OP_READ));
+               
+               E1000_WRITE_REG(hw, MDIC, mdic);
+
+               /* Poll the ready bit to see if the MDI read completed */
+               for(i = 0; i < 64; i++) {
+                       udelay(50);
+                       mdic = E1000_READ_REG(hw, MDIC);
+                       if(mdic & E1000_MDIC_READY) break;
+               }
+               if(!(mdic & E1000_MDIC_READY)) {
+                       DEBUGOUT("MDI Read did not complete\n");
+                       return -E1000_ERR_PHY;
+               }
+               if(mdic & E1000_MDIC_ERROR) {
+                       DEBUGOUT("MDI Error\n");
+                       return -E1000_ERR_PHY;
+               }
+               *phy_data = (uint16_t) mdic;
+       } else {
+               /* We must first send a preamble through the MDIO pin to signal 
the
+                * beginning of an MII instruction.  This is done by sending 32
+                * consecutive "1" bits.
+                */
+               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+               
+               /* Now combine the next few fields that are required for a read
+                * operation.  We use this method instead of calling the
+                * e1000_shift_out_mdi_bits routine five different times. The 
format of
+                * a MII read instruction consists of a shift out of 14 bits 
and is
+                * defined as follows:
+                *    <Preamble><SOF><Op Code><Phy Addr><Reg Addr>
+                * followed by a shift in of 18 bits.  This first two bits 
shifted in
+                * are TurnAround bits used to avoid contention on the MDIO pin 
when a
+                * READ operation is performed.  These two bits are thrown away
+                * followed by a shift in of 16 bits which contains the desired 
data.
+                */
+               mdic = ((reg_addr) | (phy_addr << 5) | 
+                       (PHY_OP_READ << 10) | (PHY_SOF << 12));
+               
+               e1000_shift_out_mdi_bits(hw, mdic, 14);
+               
+               /* Now that we've shifted out the read command to the MII, we 
need to
+                * "shift in" the 16-bit value (18 total bits) of the requested 
PHY
+                * register address.
+                */
+               *phy_data = e1000_shift_in_mdi_bits(hw);
+       }
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Writes a value to a PHY register
+*
+* hw - Struct containing variables accessed by shared code
+* reg_addr - address of the PHY register to write
+* data - data to write to the PHY
+******************************************************************************/
+static int 
+e1000_write_phy_reg(struct e1000_hw *hw,
+                    uint32_t reg_addr,
+                    uint16_t phy_data)
+{
+       uint32_t ret_val;
+
+       DEBUGFUNC("e1000_write_phy_reg");
+
+       if(hw->phy_type == e1000_phy_igp &&
+          (reg_addr > MAX_PHY_MULTI_PAGE_REG)) {
+               if((ret_val = e1000_write_phy_reg_ex(hw, 
IGP01E1000_PHY_PAGE_SELECT,
+                                                    (uint16_t)reg_addr)))
+                       return ret_val;
+       }
+
+       ret_val = e1000_write_phy_reg_ex(hw, IGP01E1000_PHY_PAGE_SELECT & 
reg_addr,
+                                        phy_data);
+
+       return ret_val;
+}
+
+static int
+e1000_write_phy_reg_ex(struct e1000_hw *hw,
+                       uint32_t reg_addr,
+                       uint16_t phy_data)
+{
+       uint32_t i;
+       uint32_t mdic = 0;
+       const uint32_t phy_addr = 1;
+       
+       DEBUGFUNC("e1000_write_phy_reg_ex");
+       
+       if(reg_addr > MAX_PHY_REG_ADDRESS) {
+               DEBUGOUT1("PHY Address %d is out of range\n", reg_addr);
+               return -E1000_ERR_PARAM;
+       }
+       
+       if(hw->mac_type > e1000_82543) {
+               /* Set up Op-code, Phy Address, register address, and data 
intended
+                * for the PHY register in the MDI Control register.  The MAC 
will take
+                * care of interfacing with the PHY to send the desired data.
+                */
+               mdic = (((uint32_t) phy_data) |
+                       (reg_addr << E1000_MDIC_REG_SHIFT) |
+                       (phy_addr << E1000_MDIC_PHY_SHIFT) | 
+                       (E1000_MDIC_OP_WRITE));
+               
+               E1000_WRITE_REG(hw, MDIC, mdic);
+               
+               /* Poll the ready bit to see if the MDI read completed */
+               for(i = 0; i < 640; i++) {
+                       udelay(5);
+                       mdic = E1000_READ_REG(hw, MDIC);
+                       if(mdic & E1000_MDIC_READY) break;
+               }
+               if(!(mdic & E1000_MDIC_READY)) {
+                       DEBUGOUT("MDI Write did not complete\n");
+                       return -E1000_ERR_PHY;
+               }
+       } else {
+               /* We'll need to use the SW defined pins to shift the write 
command
+                * out to the PHY. We first send a preamble to the PHY to 
signal the
+                * beginning of the MII instruction.  This is done by sending 
32 
+                * consecutive "1" bits.
+                */
+               e1000_shift_out_mdi_bits(hw, PHY_PREAMBLE, PHY_PREAMBLE_SIZE);
+               
+               /* Now combine the remaining required fields that will indicate 
a 
+                * write operation. We use this method instead of calling the
+                * e1000_shift_out_mdi_bits routine for each field in the 
command. The
+                * format of a MII write instruction is as follows:
+                * <Preamble><SOF><Op Code><Phy Addr><Reg 
Addr><Turnaround><Data>.
+                */
+               mdic = ((PHY_TURNAROUND) | (reg_addr << 2) | (phy_addr << 7) |
+                       (PHY_OP_WRITE << 12) | (PHY_SOF << 14));
+               mdic <<= 16;
+               mdic |= (uint32_t) phy_data;
+               
+               e1000_shift_out_mdi_bits(hw, mdic, 32);
+       }
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Returns the PHY to the power-on reset state
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static void
+e1000_phy_hw_reset(struct e1000_hw *hw)
+{
+       uint32_t ctrl, ctrl_ext;
+
+       DEBUGFUNC("e1000_phy_hw_reset");
+       
+       DEBUGOUT("Resetting Phy...\n");
+       
+       if(hw->mac_type > e1000_82543) {
+               /* Read the device control register and assert the 
E1000_CTRL_PHY_RST
+                * bit. Then, take it out of reset.
+                */
+               ctrl = E1000_READ_REG(hw, CTRL);
+               E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PHY_RST);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(10);
+               E1000_WRITE_REG(hw, CTRL, ctrl);
+               E1000_WRITE_FLUSH(hw);
+       } else {
+               /* Read the Extended Device Control Register, assert the 
PHY_RESET_DIR
+                * bit to put the PHY into reset. Then, take it out of reset.
+                */
+               ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+               ctrl_ext |= E1000_CTRL_EXT_SDP4_DIR;
+               ctrl_ext &= ~E1000_CTRL_EXT_SDP4_DATA;
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH(hw);
+               mdelay(10);
+               ctrl_ext |= E1000_CTRL_EXT_SDP4_DATA;
+               E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+               E1000_WRITE_FLUSH(hw);
+       }
+       udelay(150);
+}
+
+/******************************************************************************
+* Resets the PHY
+*
+* hw - Struct containing variables accessed by shared code
+*
+* Sets bit 15 of the MII Control regiser
+******************************************************************************/
+static int 
+e1000_phy_reset(struct e1000_hw *hw)
+{
+       int32_t ret_val;
+       uint16_t phy_data;
+
+       DEBUGFUNC("e1000_phy_reset");
+
+       if(hw->mac_type != e1000_82541_rev_2) {
+               if((ret_val = e1000_read_phy_reg(hw, PHY_CTRL, &phy_data)))
+                       return ret_val;
+               
+               phy_data |= MII_CR_RESET;
+               if((ret_val = e1000_write_phy_reg(hw, PHY_CTRL, phy_data)))
+                       return ret_val;
+               
+               udelay(1);
+       } else e1000_phy_hw_reset(hw);
+
+       if(hw->phy_type == e1000_phy_igp)
+               e1000_phy_init_script(hw);
+
+       return E1000_SUCCESS;
+}
+
+/******************************************************************************
+* Probes the expected PHY address for known PHY IDs
+*
+* hw - Struct containing variables accessed by shared code
+******************************************************************************/
+static int
+e1000_detect_gig_phy(struct e1000_hw *hw)
+{
+       int32_t phy_init_status, ret_val;
+       uint16_t phy_id_high, phy_id_low;
+       boolean_t match = FALSE;
+
+       DEBUGFUNC("e1000_detect_gig_phy");
+       
+       /* Read the PHY ID Registers to identify which PHY is onboard. */
+       if((ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high)))
+               return ret_val;
+
+       hw->phy_id = (uint32_t) (phy_id_high << 16);
+       udelay(20);
+       if((ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id_low)))
+               return ret_val;
+       
+       hw->phy_id |= (uint32_t) (phy_id_low & PHY_REVISION_MASK);
+#ifdef LINUX_DRIVER
+       hw->phy_revision = (uint32_t) phy_id_low & ~PHY_REVISION_MASK;
+#endif
+       
+       switch(hw->mac_type) {
+       case e1000_82543:
+               if(hw->phy_id == M88E1000_E_PHY_ID) match = TRUE;
+               break;
+       case e1000_82544:
+               if(hw->phy_id == M88E1000_I_PHY_ID) match = TRUE;
+               break;
+       case e1000_82540:
+       case e1000_82545:
+       case e1000_82545_rev_3:
+       case e1000_82546:
+       case e1000_82546_rev_3:
+               if(hw->phy_id == M88E1011_I_PHY_ID) match = TRUE;
+               break;
+       case e1000_82541:
+       case e1000_82541_rev_2:
+       case e1000_82547:
+       case e1000_82547_rev_2:
+               if(hw->phy_id == IGP01E1000_I_PHY_ID) match = TRUE;
+               break;
+       default:
+               DEBUGOUT1("Invalid MAC type %d\n", hw->mac_type);
+               return -E1000_ERR_CONFIG;
+       }
+       phy_init_status = e1000_set_phy_type(hw);
+
+       if ((match) && (phy_init_status == E1000_SUCCESS)) {
+               DEBUGOUT1("PHY ID 0x%X detected\n", hw->phy_id);
+               return E1000_SUCCESS;
+       }
+       DEBUGOUT1("Invalid PHY ID 0x%X\n", hw->phy_id);
+       return -E1000_ERR_PHY;
+}
+
+/******************************************************************************
+ * Sets up eeprom variables in the hw struct.  Must be called after mac_type
+ * is configured.
+ *
+ * hw - Struct containing variables accessed by shared code
+ *****************************************************************************/
+static void
+e1000_init_eeprom_params(struct e1000_hw *hw)
+{
+       struct e1000_eeprom_info *eeprom = &hw->eeprom;
+       uint32_t eecd = E1000_READ_REG(hw, EECD);
+       uint16_t eeprom_size;
+
+       DEBUGFUNC("e1000_init_eeprom_params");
+
+       switch (hw->mac_type) {
+       case e1000_82542_rev2_0:
+       case e1000_82542_rev2_1:
+       case e1000_82543:
+       case e1000_82544:
+               eeprom->type = e1000_eeprom_microwire;
+               eeprom->word_size = 64;
+               eeprom->opcode_bits = 3;
+               eeprom->address_bits = 6;
+               eeprom->delay_usec = 50;
+               break;
+       case e1000_82540:
+       case e1000_82545:
+       case e1000_82545_rev_3:
+       case e1000_82546:
+       case e1000_82546_rev_3:
+               eeprom->type = e1000_eeprom_microwire;
+               eeprom->opcode_bits = 3;
+               eeprom->delay_usec = 50;
+               if(eecd & E1000_EECD_SIZE) {
+                       eeprom->word_size = 256;
+                       eeprom->address_bits = 8;
+               } else {
+                       eeprom->word_size = 64;
+                       eeprom->address_bits = 6;
+               }
+               break;
+       case e1000_82541:
+       case e1000_82541_rev_2:
+       case e1000_82547:
+       case e1000_82547_rev_2:
+               if (eecd & E1000_EECD_TYPE) {
+                       eeprom->type = e1000_eeprom_spi;
+                       if (eecd & E1000_EECD_ADDR_BITS) {
+                               eeprom->page_size = 32;
+                               eeprom->address_bits = 16;
+                       } else {
+                               eeprom->page_size = 8;
+                               eeprom->address_bits = 8;
+                       }
+               } else {
+                       eeprom->type = e1000_eeprom_microwire;
+                       eeprom->opcode_bits = 3;
+                       eeprom->delay_usec = 50;
+                       if (eecd & E1000_EECD_ADDR_BITS) {
+                               eeprom->word_size = 256;
+                               eeprom->address_bits = 8;
+                       } else {
+                               eeprom->word_size = 64;
+                               eeprom->address_bits = 6;
+                       }
+               }
+               break;
+       default:
+               eeprom->type = e1000_eeprom_spi;
+               if (eecd & E1000_EECD_ADDR_BITS) {
+                       eeprom->page_size = 32;
+                       eeprom->address_bits = 16;
+               } else {
+                       eeprom->page_size = 8;
+                       eeprom->address_bits = 8;
+               }
+               break;
+       }
+
+       if (eeprom->type == e1000_eeprom_spi) {
+               eeprom->opcode_bits = 8;
+               eeprom->delay_usec = 1;
+               eeprom->word_size = 64;
+               if (e1000_read_eeprom(hw, EEPROM_CFG, 1, &eeprom_size) == 0) {
+                       eeprom_size &= EEPROM_SIZE_MASK;
+
+                       switch (eeprom_size) {
+                       case EEPROM_SIZE_16KB:
+                               eeprom->word_size = 8192;
+                               break;
+                       case EEPROM_SIZE_8KB:
+                               eeprom->word_size = 4096;
+                               break;
+                       case EEPROM_SIZE_4KB:
+                               eeprom->word_size = 2048;
+                               break;
+                       case EEPROM_SIZE_2KB:
+                               eeprom->word_size = 1024;
+                               break;
+                       case EEPROM_SIZE_1KB:
+                               eeprom->word_size = 512;
+                               break;
+                       case EEPROM_SIZE_512B:
+                               eeprom->word_size = 256;
+                               break;
+                       case EEPROM_SIZE_128B:
+                       default:
+                               break;
+                       }
+               }
+       }
+}
+
+/**
+ * e1000_reset - Reset the adapter
+ */
+
+static int
+e1000_reset(struct e1000_hw *hw)
+{
+       uint32_t pba;
+       /* Repartition Pba for greater than 9k mtu
+        * To take effect CTRL.RST is required.
+        */
+
+       if(hw->mac_type < e1000_82547) {
+               pba = E1000_PBA_48K;
+       } else {
+               pba = E1000_PBA_30K;
+       }
+       E1000_WRITE_REG(hw, PBA, pba);
+
+       /* flow control settings */
+#if 0
+       hw->fc_high_water = FC_DEFAULT_HI_THRESH;
+       hw->fc_low_water = FC_DEFAULT_LO_THRESH;
+       hw->fc_pause_time = FC_DEFAULT_TX_TIMER;
+       hw->fc_send_xon = 1;
+       hw->fc = hw->original_fc;
+#endif
+       
+       e1000_reset_hw(hw);
+       if(hw->mac_type >= e1000_82544)
+               E1000_WRITE_REG(hw, WUC, 0);
+       return e1000_init_hw(hw);
+}
+
+/**
+ * e1000_sw_init - Initialize general software structures (struct 
e1000_adapter)
+ * @adapter: board private structure to initialize
+ *
+ * e1000_sw_init initializes the Adapter private data structure.
+ * Fields are initialized based on PCI device information and
+ * OS network device settings (MTU size).
+ **/
+
+static int 
+e1000_sw_init(struct pci_device *pdev, struct e1000_hw *hw)
+{
+       int result;
+
+       /* PCI config space info */
+       pci_read_config_word(pdev, PCI_VENDOR_ID, &hw->vendor_id);
+       pci_read_config_word(pdev, PCI_DEVICE_ID, &hw->device_id);
+       pci_read_config_byte(pdev, PCI_REVISION, &hw->revision_id);
+#if 0
+       pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID,
+                             &hw->subsystem_vendor_id);
+       pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id);
+#endif
+
+       pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
+
+       /* identify the MAC */
+
+       result = e1000_set_mac_type(hw);
+       if (result) {
+               E1000_ERR("Unknown MAC Type\n");
+               return result;
+       }
+
+       /* initialize eeprom parameters */
+
+       e1000_init_eeprom_params(hw);
+
+#if 0
+       if((hw->mac_type == e1000_82541) ||
+          (hw->mac_type == e1000_82547) ||
+          (hw->mac_type == e1000_82541_rev_2) ||
+          (hw->mac_type == e1000_82547_rev_2))
+               hw->phy_init_script = 1;
+#endif
+
+       e1000_set_media_type(hw);
+
+#if 0
+       if(hw->mac_type < e1000_82543)
+               hw->report_tx_early = 0;
+       else
+               hw->report_tx_early = 1;
+
+       hw->wait_autoneg_complete = FALSE;
+#endif
+       hw->tbi_compatibility_en = TRUE;
+#if 0
+       hw->adaptive_ifs = TRUE;
+
+       /* Copper options */
+
+       if(hw->media_type == e1000_media_type_copper) {
+               hw->mdix = AUTO_ALL_MODES;
+               hw->disable_polarity_correction = FALSE;
+               hw->master_slave = E1000_MASTER_SLAVE;
+       }
+#endif
+       return E1000_SUCCESS;
+}
+
+static void fill_rx (void)
+{
+       struct e1000_rx_desc *rd;
+       rx_last = rx_tail;
+       rd = rx_base + rx_tail;
+       rx_tail = (rx_tail + 1) % 8;
+       memset (rd, 0, 16);
+       rd->buffer_addr = virt_to_bus(&packet);
+       E1000_WRITE_REG (&hw, RDT, rx_tail);
+}
+
+static void init_descriptor (void)
+{
+       unsigned long ptr;
+       unsigned long tctl;
+
+       ptr = virt_to_phys(tx_pool);
+       if (ptr & 0xf)
+               ptr = (ptr + 0x10) & (~0xf);
+
+       tx_base = phys_to_virt(ptr);
+
+       E1000_WRITE_REG (&hw, TDBAL, virt_to_bus(tx_base));
+       E1000_WRITE_REG (&hw, TDBAH, 0);
+       E1000_WRITE_REG (&hw, TDLEN, 128);
+
+       /* Setup the HW Tx Head and Tail descriptor pointers */
+
+       E1000_WRITE_REG (&hw, TDH, 0);
+       E1000_WRITE_REG (&hw, TDT, 0);
+       tx_tail = 0;
+
+       /* Program the Transmit Control Register */
+
+#ifdef LINUX_DRIVER_TCTL
+       tctl = E1000_READ_REG(&hw, TCTL);
+
+       tctl &= ~E1000_TCTL_CT;
+       tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+               (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
+#else
+       tctl = E1000_TCTL_PSP | E1000_TCTL_EN |
+               (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT) | 
+               (E1000_HDX_COLLISION_DISTANCE << E1000_COLD_SHIFT);
+#endif
+
+       E1000_WRITE_REG (&hw, TCTL, tctl);
+
+       e1000_config_collision_dist(&hw);
+
+
+       rx_tail = 0;
+       /* disable receive */
+       E1000_WRITE_REG (&hw, RCTL, 0);
+       ptr = virt_to_phys(rx_pool);
+       if (ptr & 0xf)
+               ptr = (ptr + 0x10) & (~0xf);
+       rx_base = phys_to_virt(ptr);
+
+       /* Setup the Base and Length of the Rx Descriptor Ring */
+
+       E1000_WRITE_REG (&hw, RDBAL, virt_to_bus(rx_base));
+       E1000_WRITE_REG (&hw, RDBAH, 0);
+
+       E1000_WRITE_REG (&hw, RDLEN, 128);
+
+       /* Setup the HW Rx Head and Tail Descriptor Pointers */
+       E1000_WRITE_REG (&hw, RDH, 0);
+       E1000_WRITE_REG (&hw, RDT, 0);
+
+       E1000_WRITE_REG (&hw, RCTL, 
+               E1000_RCTL_EN | 
+               E1000_RCTL_BAM | 
+               E1000_RCTL_SZ_2048 | 
+               E1000_RCTL_MPE);
+       fill_rx();
+}
+
+
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//e1000_poll (struct nic *nic, int retrieve)
+e1000_poll (struct nic *nic)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       /* 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 e1000_rx_desc *rd;
+
+       rd = rx_base + rx_last;
+       if (!rd->status & E1000_RXD_STAT_DD)
+               return 0;
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       if ( ! retrieve ) return 1;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+       //      printf("recv: packet %! -> %! len=%d \n", packet+6, 
packet,rd->Length);
+       memcpy (nic->packet, packet, rd->length);
+       nic->packetlen = rd->length;
+       fill_rx ();
+       return 1;
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void
+e1000_transmit (struct nic *nic, const char *d,        /* Destination */
+                   unsigned int type,  /* Type */
+                   unsigned int size,  /* size */
+                   const char *p)      /* Packet */
+{
+       /* send the packet to destination */
+       struct eth_hdr {
+               unsigned char dst_addr[ETH_ALEN];
+               unsigned char src_addr[ETH_ALEN];
+               unsigned short type;
+       } hdr;
+       struct e1000_tx_desc *txhd;     /* header */
+       struct e1000_tx_desc *txp;      /* payload */
+       DEBUGFUNC("send");
+
+       memcpy (&hdr.dst_addr, d, ETH_ALEN);
+       memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
+
+       hdr.type = htons (type);
+       txhd = tx_base + tx_tail;
+       tx_tail = (tx_tail + 1) % 8;
+       txp = tx_base + tx_tail;
+       tx_tail = (tx_tail + 1) % 8;
+
+       txhd->buffer_addr = virt_to_bus (&hdr);
+       txhd->lower.data = sizeof (hdr);
+       txhd->upper.data = 0;
+
+       txp->buffer_addr = virt_to_bus(p);
+       txp->lower.data = E1000_TXD_CMD_RPS | E1000_TXD_CMD_EOP | 
E1000_TXD_CMD_IFCS | size;
+       txp->upper.data = 0;
+
+       E1000_WRITE_REG (&hw, TDT, tx_tail);
+       while (!(txp->upper.data & E1000_TXD_STAT_DD)) {
+               udelay(10);     /* give the nic a chance to write to the 
register */
+               poll_interruptions();
+       }
+       DEBUGFUNC("send end");
+}
+
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//static void e1000_disable (struct dev *dev __unused)
+static void e1000_disable (struct nic *e1000_nic)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       /* Clear the transmit ring */
+       E1000_WRITE_REG (&hw, TDH, 0);
+       E1000_WRITE_REG (&hw, TDT, 0);
+
+       /* Clear the receive ring */
+       E1000_WRITE_REG (&hw, RDH, 0);
+       E1000_WRITE_REG (&hw, RDT, 0);
+
+       /* put the card in its initial state */
+       E1000_WRITE_REG (&hw, CTRL, E1000_CTRL_RST);
+
+       /* Turn off the ethernet interface */
+       E1000_WRITE_REG (&hw, RCTL, 0);
+       E1000_WRITE_REG (&hw, TCTL, 0);
+       mdelay (10);
+
+       /* Unmap my window to the device */
+       iounmap(hw.hw_addr);
+}
+
+/**************************************************************************
+IRQ - Enable, Disable, or Force interrupts
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+static void e1000_irq(struct nic *nic __unused, irq_action_t action __unused)
+{
+  switch ( action ) {
+  case DISABLE :
+    break;
+  case ENABLE :
+    break;
+  case FORCE :
+    break;
+  }
+}
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+static void e1000_reset_nic(struct nic *dev)
+{
+       e1000_reset(&hw);
+}
+/*!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!*/
+
+#define IORESOURCE_IO  0x00000100     /* Resource type */
+#define BAR_0          0
+#define BAR_1          1
+#define BAR_5          5
+
+/**************************************************************************
+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
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//static int e1000_probe(struct dev *dev, struct pci_device *p)
+struct nic *e1000_probe(struct nic *dev, unsigned short *probeaddrs, struct 
pci_device *p)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       struct nic *nic = (struct nic *)dev;
+       unsigned long mmio_start, mmio_len;
+       int ret_val, i;
+
+       if (p == 0)
+               return 0;
+       /* Initialize hw with default values */
+       memset(&hw, 0, sizeof(hw));
+       hw.pdev = p;
+
+#if 1
+       /* Are these variables needed? */
+       hw.fc                    = e1000_fc_none;
+#if 0
+       hw.original_fc           = e1000_fc_none;
+#endif
+       hw.autoneg_failed        = 0;
+#if 0
+       hw.get_link_status       = TRUE;
+#endif
+#endif
+
+       mmio_start = pci_bar_start(p, PCI_BASE_ADDRESS_0);
+       mmio_len   = pci_bar_size(p,  PCI_BASE_ADDRESS_0);
+       hw.hw_addr = ioremap(mmio_start, mmio_len);
+
+       for(i = BAR_1; i <= BAR_5; i++) {
+               if(pci_bar_size(p, i) == 0)
+                       continue;                
+               if(pci_find_capability(p, i) & IORESOURCE_IO) {
+                       hw.io_base = pci_bar_start(p, i);
+                       break;
+                }        
+       }
+
+       adjust_pci_device(p);
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       nic->ioaddr   = p->ioaddr & ~3;
+       nic->irqno    = 0;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+       /* From Matt Hortman <address@hidden> */
+       /* MAC and Phy settings */
+
+       /* setup the private structure */
+       if (e1000_sw_init(p, &hw) < 0) {
+               iounmap(hw.hw_addr);
+               return 0;
+       }
+
+       /* make sure the EEPROM is good */
+
+       if (e1000_validate_eeprom_checksum(&hw) < 0) {
+               printf ("The EEPROM Checksum Is Not Valid\n");
+               iounmap(hw.hw_addr);
+               return 0;
+       }
+
+       /* copy the MAC address out of the EEPROM */
+
+       e1000_read_mac_addr(&hw);
+       memcpy (nic->node_addr, hw.mac_addr, ETH_ALEN);
+       
+       printf("Ethernet addr: %!\n", nic->node_addr);
+
+       /* reset the hardware with the new settings */
+
+       ret_val = e1000_reset(&hw);
+       if (ret_val < 0) {
+               if ((ret_val == -E1000_ERR_NOLINK) ||
+                       (ret_val == -E1000_ERR_TIMEOUT)) {
+                       E1000_ERR("Valid Link not detected\n");
+               } else {
+                       E1000_ERR("Hardware Initialization Failed\n");
+               }
+               iounmap(hw.hw_addr);
+               return 0;
+       }
+       init_descriptor();
+
+       /* point to NIC specific routines */
+       dev->disable  = e1000_disable;
+       nic->poll     = e1000_poll;
+       nic->transmit = e1000_transmit;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+       nic->reset    = e1000_reset_nic;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       nic->irq      = e1000_irq;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//     return 1;
+       return dev;
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+}
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+static struct pci_id e1000_nics[] = {
+PCI_ROM(0x8086, 0x1000, "e1000-82542",               "Intel 
EtherExpressPro1000"),
+PCI_ROM(0x8086, 0x1001, "e1000-82543gc-fiber",       "Intel 
EtherExpressPro1000 82543GC Fiber"),
+PCI_ROM(0x8086, 0x1004, "e1000-82543gc-copper",             "Intel 
EtherExpressPro1000 82543GC Copper"),
+PCI_ROM(0x8086, 0x1008, "e1000-82544ei-copper",      "Intel 
EtherExpressPro1000 82544EI Copper"),
+PCI_ROM(0x8086, 0x1009, "e1000-82544ei-fiber",       "Intel 
EtherExpressPro1000 82544EI Fiber"),
+PCI_ROM(0x8086, 0x100C, "e1000-82544gc-copper",      "Intel 
EtherExpressPro1000 82544GC Copper"),
+PCI_ROM(0x8086, 0x100D, "e1000-82544gc-lom",         "Intel 
EtherExpressPro1000 82544GC LOM"),
+PCI_ROM(0x8086, 0x100E, "e1000-82540em",            "Intel EtherExpressPro1000 
82540EM"),
+PCI_ROM(0x8086, 0x100F, "e1000-82545em-copper",      "Intel 
EtherExpressPro1000 82545EM Copper"),
+PCI_ROM(0x8086, 0x1010, "e1000-82546eb-copper",      "Intel 
EtherExpressPro1000 82546EB Copper"),
+PCI_ROM(0x8086, 0x1011, "e1000-82545em-fiber",       "Intel 
EtherExpressPro1000 82545EM Fiber"),
+PCI_ROM(0x8086, 0x1012, "e1000-82546eb-fiber",              "Intel 
EtherExpressPro1000 82546EB Copper"),
+PCI_ROM(0x8086, 0x1013, "e1000-82541ei",            "Intel EtherExpressPro1000 
82541EI"),
+PCI_ROM(0x8086, 0x1015, "e1000-82540em-lom",        "Intel EtherExpressPro1000 
82540EM LOM"),
+PCI_ROM(0x8086, 0x1016, "e1000-82540ep-lom",        "Intel EtherExpressPro1000 
82540EP LOM"),
+PCI_ROM(0x8086, 0x1017, "e1000-82540ep",            "Intel EtherExpressPro1000 
82540EP"),
+PCI_ROM(0x8086, 0x1018, "e1000-82541ep",            "Intel EtherExpressPro1000 
82541EP"),
+PCI_ROM(0x8086, 0x1019, "e1000-82547ei",            "Intel EtherExpressPro1000 
82547EI"),
+PCI_ROM(0x8086, 0x101d, "e1000-82546eb-quad-copper", "Intel 
EtherExpressPro1000 82546EB Quad Copper"),
+PCI_ROM(0x8086, 0x101e, "e1000-82540ep-lp",         "Intel EtherExpressPro1000 
82540EP LP"),
+PCI_ROM(0x8086, 0x1026, "e1000-82545gm-copper",             "Intel 
EtherExpressPro1000 82545GM Copper"),
+PCI_ROM(0x8086, 0x1027, "e1000-82545gm-fiber",      "Intel EtherExpressPro1000 
82545GM Fiber"),
+PCI_ROM(0x8086, 0x1028, "e1000-82545gm-serdes",             "Intel 
EtherExpressPro1000 82545GM SERDES"),
+PCI_ROM(0x8086, 0x1075, "e1000-82547gi",            "Intel EtherExpressPro1000 
82547GI"),
+PCI_ROM(0x8086, 0x1076, "e1000-82541gi",            "Intel EtherExpressPro1000 
82541GI"),
+PCI_ROM(0x8086, 0x1077, "e1000-82541gi-mobile",             "Intel 
EtherExpressPro1000 82541GI Mobile"),
+PCI_ROM(0x8086, 0x1078, "e1000-82541er",            "Intel EtherExpressPro1000 
82541ER"),
+PCI_ROM(0x8086, 0x1079, "e1000-82546gb-copper",             "Intel 
EtherExpressPro1000 82546GB Copper"),
+PCI_ROM(0x8086, 0x107a, "e1000-82546gb-fiber",      "Intel EtherExpressPro1000 
82546GB Fiber"),
+PCI_ROM(0x8086, 0x107b, "e1000-82546gb-serdes",             "Intel 
EtherExpressPro1000 82546GB SERDES"),
+};
+
+static struct pci_driver e1000_driver __pci_driver = {
+       .type     = NIC_DRIVER,
+       .name     = "E1000",
+       .probe    = e1000_probe,
+       .ids      = e1000_nics,
+       .id_count = sizeof(e1000_nics)/sizeof(e1000_nics[0]),
+       .class    = 0,
+};
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
diff -urpN grub-0.96/netboot/e1000_hw.h resumo-0.96/netboot/e1000_hw.h
--- grub-0.96/netboot/e1000_hw.h        1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/netboot/e1000_hw.h      2005-04-19 20:34:49.000000000 +0900
@@ -0,0 +1,2058 @@
+/*******************************************************************************
+
+  
+  Copyright(c) 1999 - 2003 Intel Corporation. All rights reserved.
+  
+  This program is free software; you can redistribute it and/or modify it 
+  under the terms of the GNU General Public License as published by the Free 
+  Software Foundation; either version 2 of the License, or (at your option) 
+  any later version.
+  
+  This program is distributed in the hope that it will be useful, but WITHOUT 
+  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for 
+  more details.
+  
+  You should have received a copy of the GNU General Public License along with
+  this program; if not, write to the Free Software Foundation, Inc., 59 
+  Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+  
+  The full GNU General Public License is included in this distribution in the
+  file called LICENSE.
+  
+  Contact Information:
+  Linux NICS <address@hidden>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+/* e1000_hw.h
+ * Structures, enums, and macros for the MAC
+ */
+
+#ifndef _E1000_HW_H_
+#define _E1000_HW_H_
+
+/* Forward declarations of structures used by the shared code */
+struct e1000_hw;
+struct e1000_hw_stats;
+
+/* Enumerated types specific to the e1000 hardware */
+/* Media Access Controlers */
+typedef enum {
+    e1000_undefined = 0,
+    e1000_82542_rev2_0,
+    e1000_82542_rev2_1,
+    e1000_82543,
+    e1000_82544,
+    e1000_82540,
+    e1000_82545,
+    e1000_82545_rev_3,
+    e1000_82546,
+    e1000_82546_rev_3,
+    e1000_82541,
+    e1000_82541_rev_2,
+    e1000_82547,
+    e1000_82547_rev_2,
+    e1000_num_macs
+} e1000_mac_type;
+
+typedef enum {
+    e1000_eeprom_uninitialized = 0,
+    e1000_eeprom_spi,
+    e1000_eeprom_microwire,
+    e1000_num_eeprom_types
+} e1000_eeprom_type;
+
+/* Media Types */
+typedef enum {
+       e1000_media_type_copper = 0,
+       e1000_media_type_fiber = 1,
+       e1000_media_type_internal_serdes = 2,
+       e1000_num_media_types
+} e1000_media_type;
+
+typedef enum {
+    e1000_10_half = 0,
+    e1000_10_full = 1,
+    e1000_100_half = 2,
+    e1000_100_full = 3
+} e1000_speed_duplex_type;
+
+/* Flow Control Settings */
+typedef enum {
+       e1000_fc_none = 0,
+       e1000_fc_rx_pause = 1,
+       e1000_fc_tx_pause = 2,
+       e1000_fc_full = 3,
+       e1000_fc_default = 0xFF
+} e1000_fc_type;
+
+/* PCI bus types */
+typedef enum {
+       e1000_bus_type_unknown = 0,
+       e1000_bus_type_pci,
+       e1000_bus_type_pcix,
+       e1000_bus_type_reserved
+} e1000_bus_type;
+
+/* PCI bus speeds */
+typedef enum {
+       e1000_bus_speed_unknown = 0,
+       e1000_bus_speed_33,
+       e1000_bus_speed_66,
+       e1000_bus_speed_100,
+       e1000_bus_speed_120,
+       e1000_bus_speed_133,
+       e1000_bus_speed_reserved
+} e1000_bus_speed;
+
+/* PCI bus widths */
+typedef enum {
+       e1000_bus_width_unknown = 0,
+       e1000_bus_width_32,
+       e1000_bus_width_64,
+       e1000_bus_width_reserved
+} e1000_bus_width;
+
+/* PHY status info structure and supporting enums */
+typedef enum {
+       e1000_cable_length_50 = 0,
+       e1000_cable_length_50_80,
+       e1000_cable_length_80_110,
+       e1000_cable_length_110_140,
+       e1000_cable_length_140,
+       e1000_cable_length_undefined = 0xFF
+} e1000_cable_length;
+
+typedef enum {
+    e1000_igp_cable_length_10  = 10,
+    e1000_igp_cable_length_20  = 20,
+    e1000_igp_cable_length_30  = 30,
+    e1000_igp_cable_length_40  = 40,
+    e1000_igp_cable_length_50  = 50,
+    e1000_igp_cable_length_60  = 60,
+    e1000_igp_cable_length_70  = 70,
+    e1000_igp_cable_length_80  = 80,
+    e1000_igp_cable_length_90  = 90,
+    e1000_igp_cable_length_100 = 100,
+    e1000_igp_cable_length_110 = 110,
+    e1000_igp_cable_length_120 = 120,
+    e1000_igp_cable_length_130 = 130,
+    e1000_igp_cable_length_140 = 140,
+    e1000_igp_cable_length_150 = 150,
+    e1000_igp_cable_length_160 = 160,
+    e1000_igp_cable_length_170 = 170,
+    e1000_igp_cable_length_180 = 180
+} e1000_igp_cable_length;
+
+typedef enum {
+       e1000_10bt_ext_dist_enable_normal = 0,
+       e1000_10bt_ext_dist_enable_lower,
+       e1000_10bt_ext_dist_enable_undefined = 0xFF
+} e1000_10bt_ext_dist_enable;
+
+typedef enum {
+       e1000_rev_polarity_normal = 0,
+       e1000_rev_polarity_reversed,
+       e1000_rev_polarity_undefined = 0xFF
+} e1000_rev_polarity;
+
+typedef enum {
+    e1000_downshift_normal = 0,
+    e1000_downshift_activated,
+    e1000_downshift_undefined = 0xFF
+} e1000_downshift;
+
+typedef enum {
+       e1000_polarity_reversal_enabled = 0,
+       e1000_polarity_reversal_disabled,
+       e1000_polarity_reversal_undefined = 0xFF
+} e1000_polarity_reversal;
+
+typedef enum {
+       e1000_auto_x_mode_manual_mdi = 0,
+       e1000_auto_x_mode_manual_mdix,
+       e1000_auto_x_mode_auto1,
+       e1000_auto_x_mode_auto2,
+       e1000_auto_x_mode_undefined = 0xFF
+} e1000_auto_x_mode;
+
+typedef enum {
+       e1000_1000t_rx_status_not_ok = 0,
+       e1000_1000t_rx_status_ok,
+       e1000_1000t_rx_status_undefined = 0xFF
+} e1000_1000t_rx_status;
+
+typedef enum {
+    e1000_phy_m88 = 0,
+    e1000_phy_igp,
+    e1000_phy_undefined = 0xFF
+} e1000_phy_type;
+
+typedef enum {
+    e1000_ms_hw_default = 0,
+    e1000_ms_force_master,
+    e1000_ms_force_slave,
+    e1000_ms_auto
+} e1000_ms_type;
+
+typedef enum {
+    e1000_ffe_config_enabled = 0,
+    e1000_ffe_config_active,
+    e1000_ffe_config_blocked
+} e1000_ffe_config;
+
+typedef enum {
+    e1000_dsp_config_disabled = 0,
+    e1000_dsp_config_enabled,
+    e1000_dsp_config_activated,
+    e1000_dsp_config_undefined = 0xFF
+} e1000_dsp_config;
+
+struct e1000_phy_info {
+       e1000_cable_length cable_length;
+       e1000_10bt_ext_dist_enable extended_10bt_distance;
+       e1000_rev_polarity cable_polarity;
+       e1000_downshift downshift;
+       e1000_polarity_reversal polarity_correction;
+       e1000_auto_x_mode mdix_mode;
+       e1000_1000t_rx_status local_rx;
+       e1000_1000t_rx_status remote_rx;
+};
+
+struct e1000_phy_stats {
+       uint32_t idle_errors;
+       uint32_t receive_errors;
+};
+
+struct e1000_eeprom_info {
+    e1000_eeprom_type type;
+    uint16_t word_size;
+    uint16_t opcode_bits;
+    uint16_t address_bits;
+    uint16_t delay_usec;
+    uint16_t page_size;
+};
+
+
+
+/* Error Codes */
+#define E1000_SUCCESS      0
+#define E1000_ERR_EEPROM   1
+#define E1000_ERR_PHY      2
+#define E1000_ERR_CONFIG   3
+#define E1000_ERR_PARAM    4
+#define E1000_ERR_MAC_TYPE 5
+#define E1000_ERR_PHY_TYPE 6
+#define E1000_ERR_NOLINK   7
+#define E1000_ERR_TIMEOUT  8
+
+#define E1000_READ_REG_IO(a, reg) \
+       e1000_read_reg_io((a), E1000_##reg)
+#define E1000_WRITE_REG_IO(a, reg, val) \
+       e1000_write_reg_io((a), E1000_##reg, val)
+
+/* PCI Device IDs */
+#define E1000_DEV_ID_82542               0x1000
+#define E1000_DEV_ID_82543GC_FIBER       0x1001
+#define E1000_DEV_ID_82543GC_COPPER      0x1004
+#define E1000_DEV_ID_82544EI_COPPER      0x1008
+#define E1000_DEV_ID_82544EI_FIBER       0x1009
+#define E1000_DEV_ID_82544GC_COPPER      0x100C
+#define E1000_DEV_ID_82544GC_LOM         0x100D
+#define E1000_DEV_ID_82540EM             0x100E
+#define E1000_DEV_ID_82540EM_LOM         0x1015
+#define E1000_DEV_ID_82540EP_LOM         0x1016
+#define E1000_DEV_ID_82540EP             0x1017
+#define E1000_DEV_ID_82540EP_LP          0x101E
+#define E1000_DEV_ID_82545EM_COPPER      0x100F
+#define E1000_DEV_ID_82545EM_FIBER       0x1011
+#define E1000_DEV_ID_82545GM_COPPER      0x1026
+#define E1000_DEV_ID_82545GM_FIBER       0x1027
+#define E1000_DEV_ID_82545GM_SERDES      0x1028
+#define E1000_DEV_ID_82546EB_COPPER      0x1010
+#define E1000_DEV_ID_82546EB_FIBER       0x1012
+#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+#define E1000_DEV_ID_82541EI             0x1013
+#define E1000_DEV_ID_82541EI_MOBILE      0x1018
+#define E1000_DEV_ID_82541ER             0x1078
+#define E1000_DEV_ID_82547GI             0x1075
+#define E1000_DEV_ID_82541GI             0x1076
+#define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82546GB_COPPER      0x1079
+#define E1000_DEV_ID_82546GB_FIBER       0x107A
+#define E1000_DEV_ID_82546GB_SERDES      0x107B
+#define E1000_DEV_ID_82547EI             0x1019
+
+#define NODE_ADDRESS_SIZE 6
+#define ETH_LENGTH_OF_ADDRESS 6
+
+/* MAC decode size is 128K - This is the size of BAR0 */
+#define MAC_DECODE_SIZE (128 * 1024)
+
+#define E1000_82542_2_0_REV_ID 2
+#define E1000_82542_2_1_REV_ID 3
+
+#define SPEED_10    10
+#define SPEED_100   100
+#define SPEED_1000  1000
+#define HALF_DUPLEX 1
+#define FULL_DUPLEX 2
+
+/* The sizes (in bytes) of a ethernet packet */
+#define ENET_HEADER_SIZE             14
+#define MAXIMUM_ETHERNET_FRAME_SIZE  1518 /* With FCS */
+#define MINIMUM_ETHERNET_FRAME_SIZE  64   /* With FCS */
+#define ETHERNET_FCS_SIZE            4
+#define MAXIMUM_ETHERNET_PACKET_SIZE \
+    (MAXIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define MINIMUM_ETHERNET_PACKET_SIZE \
+    (MINIMUM_ETHERNET_FRAME_SIZE - ETHERNET_FCS_SIZE)
+#define CRC_LENGTH                   ETHERNET_FCS_SIZE
+#define MAX_JUMBO_FRAME_SIZE         0x3F00
+
+
+/* 802.1q VLAN Packet Sizes */
+#define VLAN_TAG_SIZE                     4     /* 802.3ac tag (not DMAed) */
+
+/* Ethertype field values */
+#define ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.3ac packet */
+#define ETHERNET_IP_TYPE        0x0800  /* IP packets */
+#define ETHERNET_ARP_TYPE       0x0806  /* Address Resolution Protocol (ARP) */
+
+/* Packet Header defines */
+#define IP_PROTOCOL_TCP    6
+#define IP_PROTOCOL_UDP    0x11
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error 
+ */
+#define POLL_IMS_ENABLE_MASK ( \
+    E1000_IMS_RXDMT0 |         \
+    E1000_IMS_RXSEQ)
+
+/* This defines the bits that are set in the Interrupt Mask
+ * Set/Read Register.  Each bit is documented below:
+ *   o RXT0   = Receiver Timer Interrupt (ring 0)
+ *   o TXDW   = Transmit Descriptor Written Back
+ *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
+ *   o RXSEQ  = Receive Sequence Error
+ *   o LSC    = Link Status Change
+ */
+#define IMS_ENABLE_MASK ( \
+    E1000_IMS_RXT0   |    \
+    E1000_IMS_TXDW   |    \
+    E1000_IMS_RXDMT0 |    \
+    E1000_IMS_RXSEQ  |    \
+    E1000_IMS_LSC)
+
+/* Number of high/low register pairs in the RAR. The RAR (Receive Address
+ * Registers) holds the directed and multicast addresses that we monitor. We
+ * reserve one of these spots for our directed address, allowing us room for
+ * E1000_RAR_ENTRIES - 1 multicast addresses. 
+ */
+#define E1000_RAR_ENTRIES 15
+
+#define MIN_NUMBER_OF_DESCRIPTORS 8
+#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8
+
+/* Receive Descriptor */
+struct e1000_rx_desc {
+    uint64_t buffer_addr; /* Address of the descriptor's data buffer */
+    uint16_t length;     /* Length of data DMAed into data buffer */
+    uint16_t csum;       /* Packet checksum */
+    uint8_t status;      /* Descriptor status */
+    uint8_t errors;      /* Descriptor Errors */
+    uint16_t special;
+};
+
+/* Receive Decriptor bit definitions */
+#define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
+#define E1000_RXD_STAT_EOP      0x02    /* End of Packet */
+#define E1000_RXD_STAT_IXSM     0x04    /* Ignore checksum */
+#define E1000_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
+#define E1000_RXD_STAT_TCPCS    0x20    /* TCP xsum calculated */
+#define E1000_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
+#define E1000_RXD_STAT_PIF      0x80    /* passed in-exact filter */
+#define E1000_RXD_ERR_CE        0x01    /* CRC Error */
+#define E1000_RXD_ERR_SE        0x02    /* Symbol Error */
+#define E1000_RXD_ERR_SEQ       0x04    /* Sequence Error */
+#define E1000_RXD_ERR_CXE       0x10    /* Carrier Extension Error */
+#define E1000_RXD_ERR_TCPE      0x20    /* TCP/UDP Checksum Error */
+#define E1000_RXD_ERR_IPE       0x40    /* IP Checksum Error */
+#define E1000_RXD_ERR_RXE       0x80    /* Rx Data Error */
+#define E1000_RXD_SPC_VLAN_MASK 0x0FFF  /* VLAN ID is in lower 12 bits */
+#define E1000_RXD_SPC_PRI_MASK  0xE000  /* Priority is in upper 3 bits */
+#define E1000_RXD_SPC_PRI_SHIFT 0x000D  /* Priority is in upper 3 of 16 */
+#define E1000_RXD_SPC_CFI_MASK  0x1000  /* CFI is bit 12 */
+#define E1000_RXD_SPC_CFI_SHIFT 0x000C  /* CFI is bit 12 */
+
+/* mask to determine if packets should be dropped due to frame errors */
+#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
+    E1000_RXD_ERR_CE  |                \
+    E1000_RXD_ERR_SE  |                \
+    E1000_RXD_ERR_SEQ |                \
+    E1000_RXD_ERR_CXE |                \
+    E1000_RXD_ERR_RXE)
+
+/* Transmit Descriptor */
+struct e1000_tx_desc {
+    uint64_t buffer_addr;       /* Address of the descriptor's data buffer */
+    union {
+        uint32_t data;
+        struct {
+            uint16_t length;    /* Data buffer length */
+            uint8_t cso;        /* Checksum offset */
+            uint8_t cmd;        /* Descriptor control */
+        } flags;
+    } lower;
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t css;        /* Checksum start */
+            uint16_t special;
+        } fields;
+    } upper;
+};
+
+/* Transmit Descriptor bit definitions */
+#define E1000_TXD_DTYP_D     0x00100000 /* Data Descriptor */
+#define E1000_TXD_DTYP_C     0x00000000 /* Context Descriptor */
+#define E1000_TXD_POPTS_IXSM 0x01       /* Insert IP checksum */
+#define E1000_TXD_POPTS_TXSM 0x02       /* Insert TCP/UDP checksum */
+#define E1000_TXD_CMD_EOP    0x01000000 /* End of Packet */
+#define E1000_TXD_CMD_IFCS   0x02000000 /* Insert FCS (Ethernet CRC) */
+#define E1000_TXD_CMD_IC     0x04000000 /* Insert Checksum */
+#define E1000_TXD_CMD_RS     0x08000000 /* Report Status */
+#define E1000_TXD_CMD_RPS    0x10000000 /* Report Packet Sent */
+#define E1000_TXD_CMD_DEXT   0x20000000 /* Descriptor extension (0 = legacy) */
+#define E1000_TXD_CMD_VLE    0x40000000 /* Add VLAN tag */
+#define E1000_TXD_CMD_IDE    0x80000000 /* Enable Tidv register */
+#define E1000_TXD_STAT_DD    0x00000001 /* Descriptor Done */
+#define E1000_TXD_STAT_EC    0x00000002 /* Excess Collisions */
+#define E1000_TXD_STAT_LC    0x00000004 /* Late Collisions */
+#define E1000_TXD_STAT_TU    0x00000008 /* Transmit underrun */
+#define E1000_TXD_CMD_TCP    0x01000000 /* TCP packet */
+#define E1000_TXD_CMD_IP     0x02000000 /* IP packet */
+#define E1000_TXD_CMD_TSE    0x04000000 /* TCP Seg enable */
+#define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */
+
+/* Offload Context Descriptor */
+struct e1000_context_desc {
+    union {
+        uint32_t ip_config;
+        struct {
+            uint8_t ipcss;      /* IP checksum start */
+            uint8_t ipcso;      /* IP checksum offset */
+            uint16_t ipcse;     /* IP checksum end */
+        } ip_fields;
+    } lower_setup;
+    union {
+        uint32_t tcp_config;
+        struct {
+            uint8_t tucss;      /* TCP checksum start */
+            uint8_t tucso;      /* TCP checksum offset */
+            uint16_t tucse;     /* TCP checksum end */
+        } tcp_fields;
+    } upper_setup;
+    uint32_t cmd_and_length;    /* */
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t hdr_len;    /* Header length */
+            uint16_t mss;       /* Maximum segment size */
+        } fields;
+    } tcp_seg_setup;
+};
+
+/* Offload data descriptor */
+struct e1000_data_desc {
+    uint64_t buffer_addr;       /* Address of the descriptor's buffer address 
*/
+    union {
+        uint32_t data;
+        struct {
+            uint16_t length;    /* Data buffer length */
+            uint8_t typ_len_ext;        /* */
+            uint8_t cmd;        /* */
+        } flags;
+    } lower;
+    union {
+        uint32_t data;
+        struct {
+            uint8_t status;     /* Descriptor status */
+            uint8_t popts;      /* Packet Options */
+            uint16_t special;   /* */
+        } fields;
+    } upper;
+};
+
+/* Filters */
+#define E1000_NUM_UNICAST          16   /* Unicast filter entries */
+#define E1000_MC_TBL_SIZE          128  /* Multicast Filter Table (4096 bits) 
*/
+#define E1000_VLAN_FILTER_TBL_SIZE 128  /* VLAN Filter Table (4096 bits) */
+
+
+/* Receive Address Register */
+struct e1000_rar {
+    volatile uint32_t low;      /* receive address low */
+    volatile uint32_t high;     /* receive address high */
+};
+
+/* Number of entries in the Multicast Table Array (MTA). */
+#define E1000_NUM_MTA_REGISTERS 128
+
+/* IPv4 Address Table Entry */
+struct e1000_ipv4_at_entry {
+    volatile uint32_t ipv4_addr;        /* IP Address (RW) */
+    volatile uint32_t reserved;
+};
+
+/* Four wakeup IP addresses are supported */
+#define E1000_WAKEUP_IP_ADDRESS_COUNT_MAX 4
+#define E1000_IP4AT_SIZE                  E1000_WAKEUP_IP_ADDRESS_COUNT_MAX
+#define E1000_IP6AT_SIZE                  1
+
+/* IPv6 Address Table Entry */
+struct e1000_ipv6_at_entry {
+    volatile uint8_t ipv6_addr[16];
+};
+
+/* Flexible Filter Length Table Entry */
+struct e1000_fflt_entry {
+    volatile uint32_t length;   /* Flexible Filter Length (RW) */
+    volatile uint32_t reserved;
+};
+
+/* Flexible Filter Mask Table Entry */
+struct e1000_ffmt_entry {
+    volatile uint32_t mask;     /* Flexible Filter Mask (RW) */
+    volatile uint32_t reserved;
+};
+
+/* Flexible Filter Value Table Entry */
+struct e1000_ffvt_entry {
+    volatile uint32_t value;    /* Flexible Filter Value (RW) */
+    volatile uint32_t reserved;
+};
+
+/* Four Flexible Filters are supported */
+#define E1000_FLEXIBLE_FILTER_COUNT_MAX 4
+
+/* Each Flexible Filter is at most 128 (0x80) bytes in length */
+#define E1000_FLEXIBLE_FILTER_SIZE_MAX  128
+
+#define E1000_FFLT_SIZE E1000_FLEXIBLE_FILTER_COUNT_MAX
+#define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+#define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
+
+/* Register Set. (82543, 82544)
+ *
+ * Registers are defined to be 32 bits and  should be accessed as 32 bit 
values.
+ * These registers are physically located on the NIC, but are mapped into the 
+ * host memory address space.
+ *
+ * RW - register is both readable and writable
+ * RO - register is read only
+ * WO - register is write only
+ * R/clr - register is read only and is cleared when read
+ * A - register array
+ */
+#define E1000_CTRL     0x00000  /* Device Control - RW */
+#define E1000_CTRL_DUP 0x00004  /* Device Control Duplicate (Shadow) - RW */
+#define E1000_STATUS   0x00008  /* Device Status - RO */
+#define E1000_EECD     0x00010  /* EEPROM/Flash Control - RW */
+#define E1000_EERD     0x00014  /* EEPROM Read - RW */
+#define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
+#define E1000_FLA      0x0001C  /* Flash Access - RW */
+#define E1000_MDIC     0x00020  /* MDI Control - RW */
+#define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
+#define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
+#define E1000_FCT      0x00030  /* Flow Control Type - RW */
+#define E1000_VET      0x00038  /* VLAN Ether Type - RW */
+#define E1000_ICR      0x000C0  /* Interrupt Cause Read - R/clr */
+#define E1000_ITR      0x000C4  /* Interrupt Throttling Rate - RW */
+#define E1000_ICS      0x000C8  /* Interrupt Cause Set - WO */
+#define E1000_IMS      0x000D0  /* Interrupt Mask Set - RW */
+#define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
+#define E1000_RCTL     0x00100  /* RX Control - RW */
+#define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
+#define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
+#define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
+#define E1000_TCTL     0x00400  /* TX Control - RW */
+#define E1000_TIPG     0x00410  /* TX Inter-packet gap -RW */
+#define E1000_TBT      0x00448  /* TX Burst Timer - RW */
+#define E1000_AIT      0x00458  /* Adaptive Interframe Spacing Throttle - RW */
+#define E1000_LEDCTL   0x00E00  /* LED Control - RW */
+#define E1000_PBA      0x01000  /* Packet Buffer Allocation - RW */
+#define E1000_FCRTL    0x02160  /* Flow Control Receive Threshold Low - RW */
+#define E1000_FCRTH    0x02168  /* Flow Control Receive Threshold High - RW */
+#define E1000_RDBAL    0x02800  /* RX Descriptor Base Address Low - RW */
+#define E1000_RDBAH    0x02804  /* RX Descriptor Base Address High - RW */
+#define E1000_RDLEN    0x02808  /* RX Descriptor Length - RW */
+#define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
+#define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
+#define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
+#define E1000_RXDCTL   0x02828  /* RX Descriptor Control - RW */
+#define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
+#define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
+#define E1000_TXDMAC   0x03000  /* TX DMA Control - RW */
+#define E1000_TDFH     0x03410  /* TX Data FIFO Head - RW */
+#define E1000_TDFT     0x03418  /* TX Data FIFO Tail - RW */
+#define E1000_TDFHS    0x03420  /* TX Data FIFO Head Saved - RW */
+#define E1000_TDFTS    0x03428  /* TX Data FIFO Tail Saved - RW */
+#define E1000_TDFPC    0x03430  /* TX Data FIFO Packet Count - RW */
+#define E1000_TDBAL    0x03800  /* TX Descriptor Base Address Low - RW */
+#define E1000_TDBAH    0x03804  /* TX Descriptor Base Address High - RW */
+#define E1000_TDLEN    0x03808  /* TX Descriptor Length - RW */
+#define E1000_TDH      0x03810  /* TX Descriptor Head - RW */
+#define E1000_TDT      0x03818  /* TX Descripotr Tail - RW */
+#define E1000_TIDV     0x03820  /* TX Interrupt Delay Value - RW */
+#define E1000_TXDCTL   0x03828  /* TX Descriptor Control - RW */
+#define E1000_TADV     0x0382C  /* TX Interrupt Absolute Delay Val - RW */
+#define E1000_TSPMT    0x03830  /* TCP Segmentation PAD & Min Threshold - RW */
+#define E1000_CRCERRS  0x04000  /* CRC Error Count - R/clr */
+#define E1000_ALGNERRC 0x04004  /* Alignment Error Count - R/clr */
+#define E1000_SYMERRS  0x04008  /* Symbol Error Count - R/clr */
+#define E1000_RXERRC   0x0400C  /* Receive Error Count - R/clr */
+#define E1000_MPC      0x04010  /* Missed Packet Count - R/clr */
+#define E1000_SCC      0x04014  /* Single Collision Count - R/clr */
+#define E1000_ECOL     0x04018  /* Excessive Collision Count - R/clr */
+#define E1000_MCC      0x0401C  /* Multiple Collision Count - R/clr */
+#define E1000_LATECOL  0x04020  /* Late Collision Count - R/clr */
+#define E1000_COLC     0x04028  /* Collision Count - R/clr */
+#define E1000_DC       0x04030  /* Defer Count - R/clr */
+#define E1000_TNCRS    0x04034  /* TX-No CRS - R/clr */
+#define E1000_SEC      0x04038  /* Sequence Error Count - R/clr */
+#define E1000_CEXTERR  0x0403C  /* Carrier Extension Error Count - R/clr */
+#define E1000_RLEC     0x04040  /* Receive Length Error Count - R/clr */
+#define E1000_XONRXC   0x04048  /* XON RX Count - R/clr */
+#define E1000_XONTXC   0x0404C  /* XON TX Count - R/clr */
+#define E1000_XOFFRXC  0x04050  /* XOFF RX Count - R/clr */
+#define E1000_XOFFTXC  0x04054  /* XOFF TX Count - R/clr */
+#define E1000_FCRUC    0x04058  /* Flow Control RX Unsupported Count- R/clr */
+#define E1000_PRC64    0x0405C  /* Packets RX (64 bytes) - R/clr */
+#define E1000_PRC127   0x04060  /* Packets RX (65-127 bytes) - R/clr */
+#define E1000_PRC255   0x04064  /* Packets RX (128-255 bytes) - R/clr */
+#define E1000_PRC511   0x04068  /* Packets RX (255-511 bytes) - R/clr */
+#define E1000_PRC1023  0x0406C  /* Packets RX (512-1023 bytes) - R/clr */
+#define E1000_PRC1522  0x04070  /* Packets RX (1024-1522 bytes) - R/clr */
+#define E1000_GPRC     0x04074  /* Good Packets RX Count - R/clr */
+#define E1000_BPRC     0x04078  /* Broadcast Packets RX Count - R/clr */
+#define E1000_MPRC     0x0407C  /* Multicast Packets RX Count - R/clr */
+#define E1000_GPTC     0x04080  /* Good Packets TX Count - R/clr */
+#define E1000_GORCL    0x04088  /* Good Octets RX Count Low - R/clr */
+#define E1000_GORCH    0x0408C  /* Good Octets RX Count High - R/clr */
+#define E1000_GOTCL    0x04090  /* Good Octets TX Count Low - R/clr */
+#define E1000_GOTCH    0x04094  /* Good Octets TX Count High - R/clr */
+#define E1000_RNBC     0x040A0  /* RX No Buffers Count - R/clr */
+#define E1000_RUC      0x040A4  /* RX Undersize Count - R/clr */
+#define E1000_RFC      0x040A8  /* RX Fragment Count - R/clr */
+#define E1000_ROC      0x040AC  /* RX Oversize Count - R/clr */
+#define E1000_RJC      0x040B0  /* RX Jabber Count - R/clr */
+#define E1000_MGTPRC   0x040B4  /* Management Packets RX Count - R/clr */
+#define E1000_MGTPDC   0x040B8  /* Management Packets Dropped Count - R/clr */
+#define E1000_MGTPTC   0x040BC  /* Management Packets TX Count - R/clr */
+#define E1000_TORL     0x040C0  /* Total Octets RX Low - R/clr */
+#define E1000_TORH     0x040C4  /* Total Octets RX High - R/clr */
+#define E1000_TOTL     0x040C8  /* Total Octets TX Low - R/clr */
+#define E1000_TOTH     0x040CC  /* Total Octets TX High - R/clr */
+#define E1000_TPR      0x040D0  /* Total Packets RX - R/clr */
+#define E1000_TPT      0x040D4  /* Total Packets TX - R/clr */
+#define E1000_PTC64    0x040D8  /* Packets TX (64 bytes) - R/clr */
+#define E1000_PTC127   0x040DC  /* Packets TX (65-127 bytes) - R/clr */
+#define E1000_PTC255   0x040E0  /* Packets TX (128-255 bytes) - R/clr */
+#define E1000_PTC511   0x040E4  /* Packets TX (256-511 bytes) - R/clr */
+#define E1000_PTC1023  0x040E8  /* Packets TX (512-1023 bytes) - R/clr */
+#define E1000_PTC1522  0x040EC  /* Packets TX (1024-1522 Bytes) - R/clr */
+#define E1000_MPTC     0x040F0  /* Multicast Packets TX Count - R/clr */
+#define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
+#define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
+#define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
+#define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
+#define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
+#define E1000_RA       0x05400  /* Receive Address - RW Array */
+#define E1000_VFTA     0x05600  /* VLAN Filter Table Array - RW Array */
+#define E1000_WUC      0x05800  /* Wakeup Control - RW */
+#define E1000_WUFC     0x05808  /* Wakeup Filter Control - RW */
+#define E1000_WUS      0x05810  /* Wakeup Status - RO */
+#define E1000_MANC     0x05820  /* Management Control - RW */
+#define E1000_IPAV     0x05838  /* IP Address Valid - RW */
+#define E1000_IP4AT    0x05840  /* IPv4 Address Table - RW Array */
+#define E1000_IP6AT    0x05880  /* IPv6 Address Table - RW Array */
+#define E1000_WUPL     0x05900  /* Wakeup Packet Length - RW */
+#define E1000_WUPM     0x05A00  /* Wakeup Packet Memory - RO A */
+#define E1000_FFLT     0x05F00  /* Flexible Filter Length Table - RW Array */
+#define E1000_FFMT     0x09000  /* Flexible Filter Mask Table - RW Array */
+#define E1000_FFVT     0x09800  /* Flexible Filter Value Table - RW Array */
+
+/* Register Set (82542)
+ *
+ * Some of the 82542 registers are located at different offsets than they are
+ * in more current versions of the 8254x. Despite the difference in location,
+ * the registers function in the same manner.
+ */
+#define E1000_82542_CTRL     E1000_CTRL
+#define E1000_82542_CTRL_DUP E1000_CTRL_DUP
+#define E1000_82542_STATUS   E1000_STATUS
+#define E1000_82542_EECD     E1000_EECD
+#define E1000_82542_EERD     E1000_EERD
+#define E1000_82542_CTRL_EXT E1000_CTRL_EXT
+#define E1000_82542_FLA      E1000_FLA
+#define E1000_82542_MDIC     E1000_MDIC
+#define E1000_82542_FCAL     E1000_FCAL
+#define E1000_82542_FCAH     E1000_FCAH
+#define E1000_82542_FCT      E1000_FCT
+#define E1000_82542_VET      E1000_VET
+#define E1000_82542_RA       0x00040
+#define E1000_82542_ICR      E1000_ICR
+#define E1000_82542_ITR      E1000_ITR
+#define E1000_82542_ICS      E1000_ICS
+#define E1000_82542_IMS      E1000_IMS
+#define E1000_82542_IMC      E1000_IMC
+#define E1000_82542_RCTL     E1000_RCTL
+#define E1000_82542_RDTR     0x00108
+#define E1000_82542_RDBAL    0x00110
+#define E1000_82542_RDBAH    0x00114
+#define E1000_82542_RDLEN    0x00118
+#define E1000_82542_RDH      0x00120
+#define E1000_82542_RDT      0x00128
+#define E1000_82542_FCRTH    0x00160
+#define E1000_82542_FCRTL    0x00168
+#define E1000_82542_FCTTV    E1000_FCTTV
+#define E1000_82542_TXCW     E1000_TXCW
+#define E1000_82542_RXCW     E1000_RXCW
+#define E1000_82542_MTA      0x00200
+#define E1000_82542_TCTL     E1000_TCTL
+#define E1000_82542_TIPG     E1000_TIPG
+#define E1000_82542_TDBAL    0x00420
+#define E1000_82542_TDBAH    0x00424
+#define E1000_82542_TDLEN    0x00428
+#define E1000_82542_TDH      0x00430
+#define E1000_82542_TDT      0x00438
+#define E1000_82542_TIDV     0x00440
+#define E1000_82542_TBT      E1000_TBT
+#define E1000_82542_AIT      E1000_AIT
+#define E1000_82542_VFTA     0x00600
+#define E1000_82542_LEDCTL   E1000_LEDCTL
+#define E1000_82542_PBA      E1000_PBA
+#define E1000_82542_RXDCTL   E1000_RXDCTL
+#define E1000_82542_RADV     E1000_RADV
+#define E1000_82542_RSRPD    E1000_RSRPD
+#define E1000_82542_TXDMAC   E1000_TXDMAC
+#define E1000_82542_TDFHS    E1000_TDFHS
+#define E1000_82542_TDFTS    E1000_TDFTS
+#define E1000_82542_TDFPC    E1000_TDFPC
+#define E1000_82542_TXDCTL   E1000_TXDCTL
+#define E1000_82542_TADV     E1000_TADV
+#define E1000_82542_TSPMT    E1000_TSPMT
+#define E1000_82542_CRCERRS  E1000_CRCERRS
+#define E1000_82542_ALGNERRC E1000_ALGNERRC
+#define E1000_82542_SYMERRS  E1000_SYMERRS
+#define E1000_82542_RXERRC   E1000_RXERRC
+#define E1000_82542_MPC      E1000_MPC
+#define E1000_82542_SCC      E1000_SCC
+#define E1000_82542_ECOL     E1000_ECOL
+#define E1000_82542_MCC      E1000_MCC
+#define E1000_82542_LATECOL  E1000_LATECOL
+#define E1000_82542_COLC     E1000_COLC
+#define E1000_82542_DC       E1000_DC
+#define E1000_82542_TNCRS    E1000_TNCRS
+#define E1000_82542_SEC      E1000_SEC
+#define E1000_82542_CEXTERR  E1000_CEXTERR
+#define E1000_82542_RLEC     E1000_RLEC
+#define E1000_82542_XONRXC   E1000_XONRXC
+#define E1000_82542_XONTXC   E1000_XONTXC
+#define E1000_82542_XOFFRXC  E1000_XOFFRXC
+#define E1000_82542_XOFFTXC  E1000_XOFFTXC
+#define E1000_82542_FCRUC    E1000_FCRUC
+#define E1000_82542_PRC64    E1000_PRC64
+#define E1000_82542_PRC127   E1000_PRC127
+#define E1000_82542_PRC255   E1000_PRC255
+#define E1000_82542_PRC511   E1000_PRC511
+#define E1000_82542_PRC1023  E1000_PRC1023
+#define E1000_82542_PRC1522  E1000_PRC1522
+#define E1000_82542_GPRC     E1000_GPRC
+#define E1000_82542_BPRC     E1000_BPRC
+#define E1000_82542_MPRC     E1000_MPRC
+#define E1000_82542_GPTC     E1000_GPTC
+#define E1000_82542_GORCL    E1000_GORCL
+#define E1000_82542_GORCH    E1000_GORCH
+#define E1000_82542_GOTCL    E1000_GOTCL
+#define E1000_82542_GOTCH    E1000_GOTCH
+#define E1000_82542_RNBC     E1000_RNBC
+#define E1000_82542_RUC      E1000_RUC
+#define E1000_82542_RFC      E1000_RFC
+#define E1000_82542_ROC      E1000_ROC
+#define E1000_82542_RJC      E1000_RJC
+#define E1000_82542_MGTPRC   E1000_MGTPRC
+#define E1000_82542_MGTPDC   E1000_MGTPDC
+#define E1000_82542_MGTPTC   E1000_MGTPTC
+#define E1000_82542_TORL     E1000_TORL
+#define E1000_82542_TORH     E1000_TORH
+#define E1000_82542_TOTL     E1000_TOTL
+#define E1000_82542_TOTH     E1000_TOTH
+#define E1000_82542_TPR      E1000_TPR
+#define E1000_82542_TPT      E1000_TPT
+#define E1000_82542_PTC64    E1000_PTC64
+#define E1000_82542_PTC127   E1000_PTC127
+#define E1000_82542_PTC255   E1000_PTC255
+#define E1000_82542_PTC511   E1000_PTC511
+#define E1000_82542_PTC1023  E1000_PTC1023
+#define E1000_82542_PTC1522  E1000_PTC1522
+#define E1000_82542_MPTC     E1000_MPTC
+#define E1000_82542_BPTC     E1000_BPTC
+#define E1000_82542_TSCTC    E1000_TSCTC
+#define E1000_82542_TSCTFC   E1000_TSCTFC
+#define E1000_82542_RXCSUM   E1000_RXCSUM
+#define E1000_82542_WUC      E1000_WUC
+#define E1000_82542_WUFC     E1000_WUFC
+#define E1000_82542_WUS      E1000_WUS
+#define E1000_82542_MANC     E1000_MANC
+#define E1000_82542_IPAV     E1000_IPAV
+#define E1000_82542_IP4AT    E1000_IP4AT
+#define E1000_82542_IP6AT    E1000_IP6AT
+#define E1000_82542_WUPL     E1000_WUPL
+#define E1000_82542_WUPM     E1000_WUPM
+#define E1000_82542_FFLT     E1000_FFLT
+#define E1000_82542_TDFH     0x08010
+#define E1000_82542_TDFT     0x08018
+#define E1000_82542_FFMT     E1000_FFMT
+#define E1000_82542_FFVT     E1000_FFVT
+
+/* Statistics counters collected by the MAC */
+struct e1000_hw_stats {
+    uint64_t crcerrs;
+    uint64_t algnerrc;
+    uint64_t symerrs;
+    uint64_t rxerrc;
+    uint64_t mpc;
+    uint64_t scc;
+    uint64_t ecol;
+    uint64_t mcc;
+    uint64_t latecol;
+    uint64_t colc;
+    uint64_t dc;
+    uint64_t tncrs;
+    uint64_t sec;
+    uint64_t cexterr;
+    uint64_t rlec;
+    uint64_t xonrxc;
+    uint64_t xontxc;
+    uint64_t xoffrxc;
+    uint64_t xofftxc;
+    uint64_t fcruc;
+    uint64_t prc64;
+    uint64_t prc127;
+    uint64_t prc255;
+    uint64_t prc511;
+    uint64_t prc1023;
+    uint64_t prc1522;
+    uint64_t gprc;
+    uint64_t bprc;
+    uint64_t mprc;
+    uint64_t gptc;
+    uint64_t gorcl;
+    uint64_t gorch;
+    uint64_t gotcl;
+    uint64_t gotch;
+    uint64_t rnbc;
+    uint64_t ruc;
+    uint64_t rfc;
+    uint64_t roc;
+    uint64_t rjc;
+    uint64_t mgprc;
+    uint64_t mgpdc;
+    uint64_t mgptc;
+    uint64_t torl;
+    uint64_t torh;
+    uint64_t totl;
+    uint64_t toth;
+    uint64_t tpr;
+    uint64_t tpt;
+    uint64_t ptc64;
+    uint64_t ptc127;
+    uint64_t ptc255;
+    uint64_t ptc511;
+    uint64_t ptc1023;
+    uint64_t ptc1522;
+    uint64_t mptc;
+    uint64_t bptc;
+    uint64_t tsctc;
+    uint64_t tsctfc;
+};
+
+/* Structure containing variables used by the shared code (e1000_hw.c) */
+struct e1000_hw {
+       struct pci_device *pdev;
+       uint8_t *hw_addr;
+       e1000_mac_type   mac_type;
+       e1000_phy_type phy_type;
+#if 0
+       uint32_t phy_init_script;
+#endif
+       e1000_media_type media_type;
+       e1000_fc_type    fc;
+#if 0
+       e1000_bus_speed bus_speed;
+       e1000_bus_width bus_width;
+       e1000_bus_type  bus_type;
+#endif
+       struct e1000_eeprom_info eeprom;
+#if 0
+       e1000_ms_type master_slave;
+       e1000_ms_type original_master_slave;
+       e1000_ffe_config ffe_config_state;
+#endif
+       uint32_t io_base;
+       uint32_t phy_id;
+#ifdef LINUX_DRIVER
+       uint32_t phy_revision;
+#endif
+       uint32_t phy_addr;
+#if 0
+       uint32_t original_fc;
+#endif
+       uint32_t txcw;
+       uint32_t autoneg_failed;
+#if 0
+       uint32_t max_frame_size;
+       uint32_t min_frame_size;
+       uint32_t mc_filter_type;
+       uint32_t num_mc_addrs;
+       uint32_t collision_delta;
+       uint32_t tx_packet_delta;
+       uint32_t ledctl_default;
+       uint32_t ledctl_mode1;
+       uint32_t ledctl_mode2;
+       uint16_t phy_spd_default;
+#endif
+       uint16_t autoneg_advertised;
+       uint16_t pci_cmd_word;
+#if 0
+       uint16_t fc_high_water;
+       uint16_t fc_low_water;
+       uint16_t fc_pause_time;
+       uint16_t current_ifs_val;
+       uint16_t ifs_min_val;
+       uint16_t ifs_max_val;
+       uint16_t ifs_step_size;
+       uint16_t ifs_ratio;
+#endif
+       uint16_t device_id;
+       uint16_t vendor_id;
+#if 0
+       uint16_t subsystem_id;
+       uint16_t subsystem_vendor_id;
+#endif
+       uint8_t revision_id;
+#if 0
+       uint8_t autoneg;
+       uint8_t mdix;
+       uint8_t forced_speed_duplex;
+       uint8_t wait_autoneg_complete;
+       uint8_t dma_fairness;
+#endif
+       uint8_t mac_addr[NODE_ADDRESS_SIZE];
+#if 0
+       uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
+       boolean_t disable_polarity_correction;
+       boolean_t speed_downgraded;
+       e1000_dsp_config dsp_config_state;
+       boolean_t get_link_status;
+       boolean_t serdes_link_down;
+#endif
+       boolean_t tbi_compatibility_en;
+       boolean_t tbi_compatibility_on;
+#if 0
+       boolean_t phy_reset_disable;
+       boolean_t fc_send_xon;
+       boolean_t fc_strict_ieee;
+       boolean_t report_tx_early;
+       boolean_t adaptive_ifs;
+       boolean_t ifs_params_forced;
+       boolean_t in_ifs_mode;
+#endif
+};
+
+
+#define E1000_EEPROM_SWDPIN0   0x0001   /* SWDPIN 0 EEPROM Value */
+#define E1000_EEPROM_LED_LOGIC 0x0020   /* Led Logic Word */
+
+/* Register Bit Masks */
+/* Device Control */
+#define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
+#define E1000_CTRL_BEM      0x00000002  /* Endian Mode.0=little,1=big */
+#define E1000_CTRL_PRIOR    0x00000004  /* Priority on PCI. 0=rx,1=fair */
+#define E1000_CTRL_LRST     0x00000008  /* Link reset. 0=normal,1=reset */
+#define E1000_CTRL_TME      0x00000010  /* Test mode. 0=normal,1=test */
+#define E1000_CTRL_SLE      0x00000020  /* Serial Link on 0=dis,1=en */
+#define E1000_CTRL_ASDE     0x00000020  /* Auto-speed detect enable */
+#define E1000_CTRL_SLU      0x00000040  /* Set link up (Force Link) */
+#define E1000_CTRL_ILOS     0x00000080  /* Invert Loss-Of Signal */
+#define E1000_CTRL_SPD_SEL  0x00000300  /* Speed Select Mask */
+#define E1000_CTRL_SPD_10   0x00000000  /* Force 10Mb */
+#define E1000_CTRL_SPD_100  0x00000100  /* Force 100Mb */
+#define E1000_CTRL_SPD_1000 0x00000200  /* Force 1Gb */
+#define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
+#define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
+#define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
+#define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
+#define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
+#define E1000_CTRL_SWDPIN2  0x00100000  /* SWDPIN 2 value */
+#define E1000_CTRL_SWDPIN3  0x00200000  /* SWDPIN 3 value */
+#define E1000_CTRL_SWDPIO0  0x00400000  /* SWDPIN 0 Input or output */
+#define E1000_CTRL_SWDPIO1  0x00800000  /* SWDPIN 1 input or output */
+#define E1000_CTRL_SWDPIO2  0x01000000  /* SWDPIN 2 input or output */
+#define E1000_CTRL_SWDPIO3  0x02000000  /* SWDPIN 3 input or output */
+#define E1000_CTRL_RST      0x04000000  /* Global reset */
+#define E1000_CTRL_RFCE     0x08000000  /* Receive Flow Control enable */
+#define E1000_CTRL_TFCE     0x10000000  /* Transmit flow control enable */
+#define E1000_CTRL_RTE      0x20000000  /* Routing tag enable */
+#define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
+#define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */
+
+/* Device Status */
+#define E1000_STATUS_FD         0x00000001      /* Full duplex.0=half,1=full */
+#define E1000_STATUS_LU         0x00000002      /* Link up.0=no,1=link */
+#define E1000_STATUS_FUNC_MASK  0x0000000C      /* PCI Function Mask */
+#define E1000_STATUS_FUNC_0     0x00000000      /* Function 0 */
+#define E1000_STATUS_FUNC_1     0x00000004      /* Function 1 */
+#define E1000_STATUS_TXOFF      0x00000010      /* transmission paused */
+#define E1000_STATUS_TBIMODE    0x00000020      /* TBI mode */
+#define E1000_STATUS_SPEED_MASK 0x000000C0
+#define E1000_STATUS_SPEED_10   0x00000000      /* Speed 10Mb/s */
+#define E1000_STATUS_SPEED_100  0x00000040      /* Speed 100Mb/s */
+#define E1000_STATUS_SPEED_1000 0x00000080      /* Speed 1000Mb/s */
+#define E1000_STATUS_ASDV       0x00000300      /* Auto speed detect value */
+#define E1000_STATUS_MTXCKOK    0x00000400      /* MTX clock running OK */
+#define E1000_STATUS_PCI66      0x00000800      /* In 66Mhz slot */
+#define E1000_STATUS_BUS64      0x00001000      /* In 64 bit slot */
+#define E1000_STATUS_PCIX_MODE  0x00002000      /* PCI-X mode */
+#define E1000_STATUS_PCIX_SPEED 0x0000C000      /* PCI-X bus speed */
+
+/* Constants used to intrepret the masked PCI-X bus speed. */
+#define E1000_STATUS_PCIX_SPEED_66  0x00000000 /* PCI-X bus speed  50-66 MHz */
+#define E1000_STATUS_PCIX_SPEED_100 0x00004000 /* PCI-X bus speed  66-100 MHz 
*/
+#define E1000_STATUS_PCIX_SPEED_133 0x00008000 /* PCI-X bus speed 100-133 MHz 
*/
+
+/* EEPROM/Flash Control */
+#define E1000_EECD_SK        0x00000001 /* EEPROM Clock */
+#define E1000_EECD_CS        0x00000002 /* EEPROM Chip Select */
+#define E1000_EECD_DI        0x00000004 /* EEPROM Data In */
+#define E1000_EECD_DO        0x00000008 /* EEPROM Data Out */
+#define E1000_EECD_FWE_MASK  0x00000030 
+#define E1000_EECD_FWE_DIS   0x00000010 /* Disable FLASH writes */
+#define E1000_EECD_FWE_EN    0x00000020 /* Enable FLASH writes */
+#define E1000_EECD_FWE_SHIFT 4
+#define E1000_EECD_REQ       0x00000040 /* EEPROM Access Request */
+#define E1000_EECD_GNT       0x00000080 /* EEPROM Access Grant */
+#define E1000_EECD_PRES      0x00000100 /* EEPROM Present */
+#define E1000_EECD_SIZE      0x00000200 /* EEPROM Size (0=64 word 1=256 word) 
*/
+#define E1000_EECD_ADDR_BITS 0x00000400 /* EEPROM Addressing bits based on type
+                                         * (0-small, 1-large) */
+#define E1000_EECD_TYPE      0x00002000 /* EEPROM Type (1-SPI, 0-Microwire) */
+#ifndef E1000_EEPROM_GRANT_ATTEMPTS
+#define E1000_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
+#endif
+
+/* EEPROM Read */
+#define E1000_EERD_START      0x00000001 /* Start Read */
+#define E1000_EERD_DONE       0x00000010 /* Read Done */
+#define E1000_EERD_ADDR_SHIFT 8
+#define E1000_EERD_ADDR_MASK  0x0000FF00 /* Read Address */
+#define E1000_EERD_DATA_SHIFT 16
+#define E1000_EERD_DATA_MASK  0xFFFF0000 /* Read Data */
+
+/* SPI EEPROM Status Register */
+#define EEPROM_STATUS_RDY_SPI  0x01
+#define EEPROM_STATUS_WEN_SPI  0x02
+#define EEPROM_STATUS_BP0_SPI  0x04
+#define EEPROM_STATUS_BP1_SPI  0x08
+#define EEPROM_STATUS_WPEN_SPI 0x80
+
+/* Extended Device Control */
+#define E1000_CTRL_EXT_GPI0_EN   0x00000001 /* Maps SDP4 to GPI0 */ 
+#define E1000_CTRL_EXT_GPI1_EN   0x00000002 /* Maps SDP5 to GPI1 */
+#define E1000_CTRL_EXT_PHYINT_EN E1000_CTRL_EXT_GPI1_EN
+#define E1000_CTRL_EXT_GPI2_EN   0x00000004 /* Maps SDP6 to GPI2 */
+#define E1000_CTRL_EXT_GPI3_EN   0x00000008 /* Maps SDP7 to GPI3 */
+#define E1000_CTRL_EXT_SDP4_DATA 0x00000010 /* Value of SW Defineable Pin 4 */
+#define E1000_CTRL_EXT_SDP5_DATA 0x00000020 /* Value of SW Defineable Pin 5 */
+#define E1000_CTRL_EXT_PHY_INT   E1000_CTRL_EXT_SDP5_DATA
+#define E1000_CTRL_EXT_SDP6_DATA 0x00000040 /* Value of SW Defineable Pin 6 */
+#define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Defineable Pin 7 */
+#define E1000_CTRL_EXT_SDP4_DIR  0x00000100 /* Direction of SDP4 0=in 1=out */
+#define E1000_CTRL_EXT_SDP5_DIR  0x00000200 /* Direction of SDP5 0=in 1=out */
+#define E1000_CTRL_EXT_SDP6_DIR  0x00000400 /* Direction of SDP6 0=in 1=out */
+#define E1000_CTRL_EXT_SDP7_DIR  0x00000800 /* Direction of SDP7 0=in 1=out */
+#define E1000_CTRL_EXT_ASDCHK    0x00001000 /* Initiate an ASD sequence */
+#define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
+#define E1000_CTRL_EXT_IPS       0x00004000 /* Invert Power State */
+#define E1000_CTRL_EXT_SPD_BYPS  0x00008000 /* Speed Select Bypass */
+#define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000
+#define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000
+#define E1000_CTRL_EXT_LINK_MODE_TBI  0x00C00000
+#define E1000_CTRL_EXT_WR_WMARK_MASK  0x03000000
+#define E1000_CTRL_EXT_WR_WMARK_256   0x00000000
+#define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
+#define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
+#define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
+
+/* MDI Control */
+#define E1000_MDIC_DATA_MASK 0x0000FFFF
+#define E1000_MDIC_REG_MASK  0x001F0000
+#define E1000_MDIC_REG_SHIFT 16
+#define E1000_MDIC_PHY_MASK  0x03E00000
+#define E1000_MDIC_PHY_SHIFT 21
+#define E1000_MDIC_OP_WRITE  0x04000000
+#define E1000_MDIC_OP_READ   0x08000000
+#define E1000_MDIC_READY     0x10000000
+#define E1000_MDIC_INT_EN    0x20000000
+#define E1000_MDIC_ERROR     0x40000000
+
+/* LED Control */
+#define E1000_LEDCTL_LED0_MODE_MASK  0x0000000F
+#define E1000_LEDCTL_LED0_MODE_SHIFT 0
+#define E1000_LEDCTL_LED0_IVRT       0x00000040
+#define E1000_LEDCTL_LED0_BLINK      0x00000080
+#define E1000_LEDCTL_LED1_MODE_MASK  0x00000F00
+#define E1000_LEDCTL_LED1_MODE_SHIFT 8
+#define E1000_LEDCTL_LED1_IVRT       0x00004000
+#define E1000_LEDCTL_LED1_BLINK      0x00008000
+#define E1000_LEDCTL_LED2_MODE_MASK  0x000F0000
+#define E1000_LEDCTL_LED2_MODE_SHIFT 16
+#define E1000_LEDCTL_LED2_IVRT       0x00400000
+#define E1000_LEDCTL_LED2_BLINK      0x00800000
+#define E1000_LEDCTL_LED3_MODE_MASK  0x0F000000
+#define E1000_LEDCTL_LED3_MODE_SHIFT 24
+#define E1000_LEDCTL_LED3_IVRT       0x40000000
+#define E1000_LEDCTL_LED3_BLINK      0x80000000
+
+#define E1000_LEDCTL_MODE_LINK_10_1000  0x0
+#define E1000_LEDCTL_MODE_LINK_100_1000 0x1
+#define E1000_LEDCTL_MODE_LINK_UP       0x2
+#define E1000_LEDCTL_MODE_ACTIVITY      0x3
+#define E1000_LEDCTL_MODE_LINK_ACTIVITY 0x4
+#define E1000_LEDCTL_MODE_LINK_10       0x5
+#define E1000_LEDCTL_MODE_LINK_100      0x6
+#define E1000_LEDCTL_MODE_LINK_1000     0x7
+#define E1000_LEDCTL_MODE_PCIX_MODE     0x8
+#define E1000_LEDCTL_MODE_FULL_DUPLEX   0x9
+#define E1000_LEDCTL_MODE_COLLISION     0xA
+#define E1000_LEDCTL_MODE_BUS_SPEED     0xB
+#define E1000_LEDCTL_MODE_BUS_SIZE      0xC
+#define E1000_LEDCTL_MODE_PAUSED        0xD
+#define E1000_LEDCTL_MODE_LED_ON        0xE
+#define E1000_LEDCTL_MODE_LED_OFF       0xF
+
+/* Receive Address */
+#define E1000_RAH_AV  0x80000000        /* Receive descriptor valid */
+
+/* Interrupt Cause Read */
+#define E1000_ICR_TXDW    0x00000001    /* Transmit desc written back */
+#define E1000_ICR_TXQE    0x00000002    /* Transmit Queue empty */
+#define E1000_ICR_LSC     0x00000004    /* Link Status Change */
+#define E1000_ICR_RXSEQ   0x00000008    /* rx sequence error */
+#define E1000_ICR_RXDMT0  0x00000010    /* rx desc min. threshold (0) */
+#define E1000_ICR_RXO     0x00000040    /* rx overrun */
+#define E1000_ICR_RXT0    0x00000080    /* rx timer intr (ring 0) */
+#define E1000_ICR_MDAC    0x00000200    /* MDIO access complete */
+#define E1000_ICR_RXCFG   0x00000400    /* RX /c/ ordered set */
+#define E1000_ICR_GPI_EN0 0x00000800    /* GP Int 0 */
+#define E1000_ICR_GPI_EN1 0x00001000    /* GP Int 1 */
+#define E1000_ICR_GPI_EN2 0x00002000    /* GP Int 2 */
+#define E1000_ICR_GPI_EN3 0x00004000    /* GP Int 3 */
+#define E1000_ICR_TXD_LOW 0x00008000
+#define E1000_ICR_SRPD    0x00010000
+
+/* Interrupt Cause Set */
+#define E1000_ICS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back 
*/
+#define E1000_ICS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+#define E1000_ICS_LSC     E1000_ICR_LSC         /* Link Status Change */
+#define E1000_ICS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+#define E1000_ICS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+#define E1000_ICS_RXO     E1000_ICR_RXO         /* rx overrun */
+#define E1000_ICS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+#define E1000_ICS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+#define E1000_ICS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+#define E1000_ICS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+#define E1000_ICS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+#define E1000_ICS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+#define E1000_ICS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+#define E1000_ICS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_ICS_SRPD    E1000_ICR_SRPD
+
+/* Interrupt Mask Set */
+#define E1000_IMS_TXDW    E1000_ICR_TXDW        /* Transmit desc written back 
*/
+#define E1000_IMS_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+#define E1000_IMS_LSC     E1000_ICR_LSC         /* Link Status Change */
+#define E1000_IMS_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+#define E1000_IMS_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+#define E1000_IMS_RXO     E1000_ICR_RXO         /* rx overrun */
+#define E1000_IMS_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+#define E1000_IMS_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+#define E1000_IMS_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+#define E1000_IMS_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+#define E1000_IMS_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+#define E1000_IMS_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+#define E1000_IMS_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+#define E1000_IMS_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMS_SRPD    E1000_ICR_SRPD
+
+/* Interrupt Mask Clear */
+#define E1000_IMC_TXDW    E1000_ICR_TXDW        /* Transmit desc written back 
*/
+#define E1000_IMC_TXQE    E1000_ICR_TXQE        /* Transmit Queue empty */
+#define E1000_IMC_LSC     E1000_ICR_LSC         /* Link Status Change */
+#define E1000_IMC_RXSEQ   E1000_ICR_RXSEQ       /* rx sequence error */
+#define E1000_IMC_RXDMT0  E1000_ICR_RXDMT0      /* rx desc min. threshold */
+#define E1000_IMC_RXO     E1000_ICR_RXO         /* rx overrun */
+#define E1000_IMC_RXT0    E1000_ICR_RXT0        /* rx timer intr */
+#define E1000_IMC_MDAC    E1000_ICR_MDAC        /* MDIO access complete */
+#define E1000_IMC_RXCFG   E1000_ICR_RXCFG       /* RX /c/ ordered set */
+#define E1000_IMC_GPI_EN0 E1000_ICR_GPI_EN0     /* GP Int 0 */
+#define E1000_IMC_GPI_EN1 E1000_ICR_GPI_EN1     /* GP Int 1 */
+#define E1000_IMC_GPI_EN2 E1000_ICR_GPI_EN2     /* GP Int 2 */
+#define E1000_IMC_GPI_EN3 E1000_ICR_GPI_EN3     /* GP Int 3 */
+#define E1000_IMC_TXD_LOW E1000_ICR_TXD_LOW
+#define E1000_IMC_SRPD    E1000_ICR_SRPD
+
+/* Receive Control */
+#define E1000_RCTL_RST          0x00000001      /* Software reset */
+#define E1000_RCTL_EN           0x00000002      /* enable */
+#define E1000_RCTL_SBP          0x00000004      /* store bad packet */
+#define E1000_RCTL_UPE          0x00000008      /* unicast promiscuous enable 
*/
+#define E1000_RCTL_MPE          0x00000010      /* multicast promiscuous enab 
*/
+#define E1000_RCTL_LPE          0x00000020      /* long packet enable */
+#define E1000_RCTL_LBM_NO       0x00000000      /* no loopback mode */
+#define E1000_RCTL_LBM_MAC      0x00000040      /* MAC loopback mode */
+#define E1000_RCTL_LBM_SLP      0x00000080      /* serial link loopback mode */
+#define E1000_RCTL_LBM_TCVR     0x000000C0      /* tcvr loopback mode */
+#define E1000_RCTL_RDMTS_HALF   0x00000000      /* rx desc min threshold size 
*/
+#define E1000_RCTL_RDMTS_QUAT   0x00000100      /* rx desc min threshold size 
*/
+#define E1000_RCTL_RDMTS_EIGTH  0x00000200      /* rx desc min threshold size 
*/
+#define E1000_RCTL_MO_SHIFT     12              /* multicast offset shift */
+#define E1000_RCTL_MO_0         0x00000000      /* multicast offset 11:0 */
+#define E1000_RCTL_MO_1         0x00001000      /* multicast offset 12:1 */
+#define E1000_RCTL_MO_2         0x00002000      /* multicast offset 13:2 */
+#define E1000_RCTL_MO_3         0x00003000      /* multicast offset 15:4 */
+#define E1000_RCTL_MDR          0x00004000      /* multicast desc ring 0 */
+#define E1000_RCTL_BAM          0x00008000      /* broadcast enable */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
+#define E1000_RCTL_SZ_2048      0x00000000      /* rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024      0x00010000      /* rx buffer size 1024 */
+#define E1000_RCTL_SZ_512       0x00020000      /* rx buffer size 512 */
+#define E1000_RCTL_SZ_256       0x00030000      /* rx buffer size 256 */
+/* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
+#define E1000_RCTL_SZ_16384     0x00010000      /* rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192      0x00020000      /* rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096      0x00030000      /* rx buffer size 4096 */
+#define E1000_RCTL_VFE          0x00040000      /* vlan filter enable */
+#define E1000_RCTL_CFIEN        0x00080000      /* canonical form enable */
+#define E1000_RCTL_CFI          0x00100000      /* canonical form indicator */
+#define E1000_RCTL_DPF          0x00400000      /* discard pause frames */
+#define E1000_RCTL_PMCF         0x00800000      /* pass MAC control frames */
+#define E1000_RCTL_BSEX         0x02000000      /* Buffer size extension */
+
+/* Receive Descriptor */
+#define E1000_RDT_DELAY 0x0000ffff      /* Delay timer (1=1024us) */
+#define E1000_RDT_FPDB  0x80000000      /* Flush descriptor block */
+#define E1000_RDLEN_LEN 0x0007ff80      /* descriptor length */
+#define E1000_RDH_RDH   0x0000ffff      /* receive descriptor head */
+#define E1000_RDT_RDT   0x0000ffff      /* receive descriptor tail */
+
+/* Flow Control */
+#define E1000_FCRTH_RTH  0x0000FFF8     /* Mask Bits[15:3] for RTH */
+#define E1000_FCRTH_XFCE 0x80000000     /* External Flow Control Enable */
+#define E1000_FCRTL_RTL  0x0000FFF8     /* Mask Bits[15:3] for RTL */
+#define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
+
+/* Receive Descriptor Control */
+#define E1000_RXDCTL_PTHRESH 0x0000003F /* RXDCTL Prefetch Threshold */
+#define E1000_RXDCTL_HTHRESH 0x00003F00 /* RXDCTL Host Threshold */
+#define E1000_RXDCTL_WTHRESH 0x003F0000 /* RXDCTL Writeback Threshold */
+#define E1000_RXDCTL_GRAN    0x01000000 /* RXDCTL Granularity */
+
+/* Transmit Descriptor Control */
+#define E1000_TXDCTL_PTHRESH 0x000000FF /* TXDCTL Prefetch Threshold */
+#define E1000_TXDCTL_HTHRESH 0x0000FF00 /* TXDCTL Host Threshold */
+#define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */
+#define E1000_TXDCTL_GRAN    0x01000000 /* TXDCTL Granularity */
+#define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */
+#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
+
+/* Transmit Configuration Word */
+#define E1000_TXCW_FD         0x00000020        /* TXCW full duplex */
+#define E1000_TXCW_HD         0x00000040        /* TXCW half duplex */
+#define E1000_TXCW_PAUSE      0x00000080        /* TXCW sym pause request */
+#define E1000_TXCW_ASM_DIR    0x00000100        /* TXCW astm pause direction */
+#define E1000_TXCW_PAUSE_MASK 0x00000180        /* TXCW pause request mask */
+#define E1000_TXCW_RF         0x00003000        /* TXCW remote fault */
+#define E1000_TXCW_NP         0x00008000        /* TXCW next page */
+#define E1000_TXCW_CW         0x0000ffff        /* TxConfigWord mask */
+#define E1000_TXCW_TXC        0x40000000        /* Transmit Config control */
+#define E1000_TXCW_ANE        0x80000000        /* Auto-neg enable */
+
+/* Receive Configuration Word */
+#define E1000_RXCW_CW    0x0000ffff     /* RxConfigWord mask */
+#define E1000_RXCW_NC    0x04000000     /* Receive config no carrier */
+#define E1000_RXCW_IV    0x08000000     /* Receive config invalid */
+#define E1000_RXCW_CC    0x10000000     /* Receive config change */
+#define E1000_RXCW_C     0x20000000     /* Receive config */
+#define E1000_RXCW_SYNCH 0x40000000     /* Receive config synch */
+#define E1000_RXCW_ANC   0x80000000     /* Auto-neg complete */
+
+/* Transmit Control */
+#define E1000_TCTL_RST    0x00000001    /* software reset */
+#define E1000_TCTL_EN     0x00000002    /* enable tx */
+#define E1000_TCTL_BCE    0x00000004    /* busy check enable */
+#define E1000_TCTL_PSP    0x00000008    /* pad short packets */
+#define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
+#define E1000_TCTL_COLD   0x003ff000    /* collision distance */
+#define E1000_TCTL_SWXOFF 0x00400000    /* SW Xoff transmission */
+#define E1000_TCTL_PBE    0x00800000    /* Packet Burst Enable */
+#define E1000_TCTL_RTLC   0x01000000    /* Re-transmit on late collision */
+#define E1000_TCTL_NRTU   0x02000000    /* No Re-transmit on underrun */
+
+/* Receive Checksum Control */
+#define E1000_RXCSUM_PCSS_MASK 0x000000FF   /* Packet Checksum Start */
+#define E1000_RXCSUM_IPOFL     0x00000100   /* IPv4 checksum offload */
+#define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
+#define E1000_RXCSUM_IPV6OFL   0x00000400   /* IPv6 checksum offload */
+
+/* Definitions for power management and wakeup registers */
+/* Wake Up Control */
+#define E1000_WUC_APME       0x00000001 /* APM Enable */
+#define E1000_WUC_PME_EN     0x00000002 /* PME Enable */
+#define E1000_WUC_PME_STATUS 0x00000004 /* PME Status */
+#define E1000_WUC_APMPME     0x00000008 /* Assert PME on APM Wakeup */
+#define E1000_WUC_SPM        0x80000000 /* Enable SPM */
+
+/* Wake Up Filter Control */
+#define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
+#define E1000_WUFC_MAG  0x00000002 /* Magic Packet Wakeup Enable */
+#define E1000_WUFC_EX   0x00000004 /* Directed Exact Wakeup Enable */
+#define E1000_WUFC_MC   0x00000008 /* Directed Multicast Wakeup Enable */
+#define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
+#define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
+#define E1000_WUFC_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Enable */
+#define E1000_WUFC_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Enable */
+#define E1000_WUFC_FLX0 0x00010000 /* Flexible Filter 0 Enable */
+#define E1000_WUFC_FLX1 0x00020000 /* Flexible Filter 1 Enable */
+#define E1000_WUFC_FLX2 0x00040000 /* Flexible Filter 2 Enable */
+#define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */
+#define E1000_WUFC_ALL_FILTERS 0x000F00FF /* Mask for all wakeup filters */
+#define E1000_WUFC_FLX_OFFSET 16       /* Offset to the Flexible Filters bits 
*/
+#define E1000_WUFC_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+
+/* Wake Up Status */
+#define E1000_WUS_LNKC 0x00000001 /* Link Status Changed */
+#define E1000_WUS_MAG  0x00000002 /* Magic Packet Received */
+#define E1000_WUS_EX   0x00000004 /* Directed Exact Received */
+#define E1000_WUS_MC   0x00000008 /* Directed Multicast Received */
+#define E1000_WUS_BC   0x00000010 /* Broadcast Received */
+#define E1000_WUS_ARP  0x00000020 /* ARP Request Packet Received */
+#define E1000_WUS_IPV4 0x00000040 /* Directed IPv4 Packet Wakeup Received */
+#define E1000_WUS_IPV6 0x00000080 /* Directed IPv6 Packet Wakeup Received */
+#define E1000_WUS_FLX0 0x00010000 /* Flexible Filter 0 Match */
+#define E1000_WUS_FLX1 0x00020000 /* Flexible Filter 1 Match */
+#define E1000_WUS_FLX2 0x00040000 /* Flexible Filter 2 Match */
+#define E1000_WUS_FLX3 0x00080000 /* Flexible Filter 3 Match */
+#define E1000_WUS_FLX_FILTERS 0x000F0000 /* Mask for the 4 flexible filters */
+
+/* Management Control */
+#define E1000_MANC_SMBUS_EN      0x00000001 /* SMBus Enabled - RO */
+#define E1000_MANC_ASF_EN        0x00000002 /* ASF Enabled - RO */
+#define E1000_MANC_R_ON_FORCE    0x00000004 /* Reset on Force TCO - RO */
+#define E1000_MANC_RMCP_EN       0x00000100 /* Enable RCMP 026Fh Filtering */
+#define E1000_MANC_0298_EN       0x00000200 /* Enable RCMP 0298h Filtering */
+#define E1000_MANC_IPV4_EN       0x00000400 /* Enable IPv4 */
+#define E1000_MANC_IPV6_EN       0x00000800 /* Enable IPv6 */
+#define E1000_MANC_SNAP_EN       0x00001000 /* Accept LLC/SNAP */
+#define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
+#define E1000_MANC_NEIGHBOR_EN   0x00004000 /* Enable Neighbor Discovery 
+                                             * Filtering */
+#define E1000_MANC_TCO_RESET     0x00010000 /* TCO Reset Occurred */
+#define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
+#define E1000_MANC_REPORT_STATUS 0x00040000 /* Status Reporting Enabled */
+#define E1000_MANC_SMB_REQ       0x01000000 /* SMBus Request */
+#define E1000_MANC_SMB_GNT       0x02000000 /* SMBus Grant */
+#define E1000_MANC_SMB_CLK_IN    0x04000000 /* SMBus Clock In */
+#define E1000_MANC_SMB_DATA_IN   0x08000000 /* SMBus Data In */
+#define E1000_MANC_SMB_DATA_OUT  0x10000000 /* SMBus Data Out */
+#define E1000_MANC_SMB_CLK_OUT   0x20000000 /* SMBus Clock Out */
+
+#define E1000_MANC_SMB_DATA_OUT_SHIFT  28 /* SMBus Data Out Shift */
+#define E1000_MANC_SMB_CLK_OUT_SHIFT   29 /* SMBus Clock Out Shift */
+
+/* Wake Up Packet Length */
+#define E1000_WUPL_LENGTH_MASK 0x0FFF   /* Only the lower 12 bits are valid */
+
+#define E1000_MDALIGN          4096
+
+/* EEPROM Commands - Microwire */
+#define EEPROM_READ_OPCODE_MICROWIRE  0x6  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_MICROWIRE 0x5  /* EEPROM write opcode */
+#define EEPROM_ERASE_OPCODE_MICROWIRE 0x7  /* EEPROM erase opcode */
+#define EEPROM_EWEN_OPCODE_MICROWIRE  0x13 /* EEPROM erase/write enable */
+#define EEPROM_EWDS_OPCODE_MICROWIRE  0x10 /* EEPROM erast/write disable */
+
+/* EEPROM Commands - SPI */
+#define EEPROM_MAX_RETRY_SPI    5000 /* Max wait of 5ms, for RDY signal */
+#define EEPROM_READ_OPCODE_SPI  0x3  /* EEPROM read opcode */
+#define EEPROM_WRITE_OPCODE_SPI 0x2  /* EEPROM write opcode */
+#define EEPROM_A8_OPCODE_SPI    0x8  /* opcode bit-3 = address bit-8 */
+#define EEPROM_WREN_OPCODE_SPI  0x6  /* EEPROM set Write Enable latch */
+#define EEPROM_WRDI_OPCODE_SPI  0x4  /* EEPROM reset Write Enable latch */
+#define EEPROM_RDSR_OPCODE_SPI  0x5  /* EEPROM read Status register */
+#define EEPROM_WRSR_OPCODE_SPI  0x1  /* EEPROM write Status register */
+
+/* EEPROM Size definitions */
+#define EEPROM_SIZE_16KB        0x1800
+#define EEPROM_SIZE_8KB         0x1400
+#define EEPROM_SIZE_4KB         0x1000
+#define EEPROM_SIZE_2KB         0x0C00
+#define EEPROM_SIZE_1KB         0x0800
+#define EEPROM_SIZE_512B        0x0400
+#define EEPROM_SIZE_128B        0x0000
+#define EEPROM_SIZE_MASK        0x1C00
+
+/* EEPROM Word Offsets */
+#define EEPROM_COMPAT              0x0003
+#define EEPROM_ID_LED_SETTINGS     0x0004
+#define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude 
adjustment. */
+#define EEPROM_INIT_CONTROL1_REG   0x000A
+#define EEPROM_INIT_CONTROL2_REG   0x000F
+#define EEPROM_INIT_CONTROL3_PORT_B   0x0014
+#define EEPROM_INIT_CONTROL3_PORT_A   0x0024
+#define EEPROM_CFG                 0x0012
+#define EEPROM_FLASH_VERSION       0x0032
+#define EEPROM_CHECKSUM_REG        0x003F
+
+/* Word definitions for ID LED Settings */
+#define ID_LED_RESERVED_0000 0x0000
+#define ID_LED_RESERVED_FFFF 0xFFFF
+#define ID_LED_DEFAULT       ((ID_LED_OFF1_ON2 << 12) | \
+                              (ID_LED_OFF1_OFF2 << 8) | \
+                              (ID_LED_DEF1_DEF2 << 4) | \
+                              (ID_LED_DEF1_DEF2))
+#define ID_LED_DEF1_DEF2     0x1
+#define ID_LED_DEF1_ON2      0x2
+#define ID_LED_DEF1_OFF2     0x3
+#define ID_LED_ON1_DEF2      0x4
+#define ID_LED_ON1_ON2       0x5
+#define ID_LED_ON1_OFF2      0x6
+#define ID_LED_OFF1_DEF2     0x7
+#define ID_LED_OFF1_ON2      0x8
+#define ID_LED_OFF1_OFF2     0x9
+
+#define IGP_ACTIVITY_LED_MASK   0xFFFFF0FF
+#define IGP_ACTIVITY_LED_ENABLE 0x0300
+#define IGP_LED3_MODE           0x07000000
+
+
+/* Mask bits for SERDES amplitude adjustment in Word 6 of the EEPROM */
+#define EEPROM_SERDES_AMPLITUDE_MASK  0x000F
+
+/* Mask bits for fields in Word 0x0a of the EEPROM */
+#define EEPROM_WORD0A_ILOS   0x0010
+#define EEPROM_WORD0A_SWDPIO 0x01E0
+#define EEPROM_WORD0A_LRST   0x0200
+#define EEPROM_WORD0A_FD     0x0400
+#define EEPROM_WORD0A_66MHZ  0x0800
+
+/* Mask bits for fields in Word 0x0f of the EEPROM */
+#define EEPROM_WORD0F_PAUSE_MASK 0x3000
+#define EEPROM_WORD0F_PAUSE      0x1000
+#define EEPROM_WORD0F_ASM_DIR    0x2000
+#define EEPROM_WORD0F_ANE        0x0800
+#define EEPROM_WORD0F_SWPDIO_EXT 0x00F0
+
+/* For checksumming, the sum of all words in the EEPROM should equal 0xBABA. */
+#define EEPROM_SUM 0xBABA
+
+/* EEPROM Map defines (WORD OFFSETS)*/
+#define EEPROM_NODE_ADDRESS_BYTE_0 0
+#define EEPROM_PBA_BYTE_1          8
+
+#define EEPROM_RESERVED_WORD          0xFFFF
+
+/* EEPROM Map Sizes (Byte Counts) */
+#define PBA_SIZE 4
+
+/* Collision related configuration parameters */
+#define E1000_COLLISION_THRESHOLD       16
+#define E1000_CT_SHIFT                  4
+#define E1000_COLLISION_DISTANCE        64
+#define E1000_FDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
+#define E1000_HDX_COLLISION_DISTANCE    E1000_COLLISION_DISTANCE
+#define E1000_COLD_SHIFT                12
+
+/* Number of Transmit and Receive Descriptors must be a multiple of 8 */
+#define REQ_TX_DESCRIPTOR_MULTIPLE  8
+#define REQ_RX_DESCRIPTOR_MULTIPLE  8
+
+/* Default values for the transmit IPG register */
+#define DEFAULT_82542_TIPG_IPGT        10
+#define DEFAULT_82543_TIPG_IPGT_FIBER  9
+#define DEFAULT_82543_TIPG_IPGT_COPPER 8
+
+#define E1000_TIPG_IPGT_MASK  0x000003FF
+#define E1000_TIPG_IPGR1_MASK 0x000FFC00
+#define E1000_TIPG_IPGR2_MASK 0x3FF00000
+
+#define DEFAULT_82542_TIPG_IPGR1 2
+#define DEFAULT_82543_TIPG_IPGR1 8
+#define E1000_TIPG_IPGR1_SHIFT  10
+
+#define DEFAULT_82542_TIPG_IPGR2 10
+#define DEFAULT_82543_TIPG_IPGR2 6
+#define E1000_TIPG_IPGR2_SHIFT  20
+
+#define E1000_TXDMAC_DPP 0x00000001
+
+/* Adaptive IFS defines */
+#define TX_THRESHOLD_START     8
+#define TX_THRESHOLD_INCREMENT 10
+#define TX_THRESHOLD_DECREMENT 1
+#define TX_THRESHOLD_STOP      190
+#define TX_THRESHOLD_DISABLE   0
+#define TX_THRESHOLD_TIMER_MS  10000
+#define MIN_NUM_XMITS          1000
+#define IFS_MAX                80
+#define IFS_STEP               10
+#define IFS_MIN                40
+#define IFS_RATIO              4
+
+/* PBA constants */
+#define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
+#define E1000_PBA_22K 0x0016
+#define E1000_PBA_24K 0x0018
+#define E1000_PBA_30K 0x001E
+#define E1000_PBA_40K 0x0028
+#define E1000_PBA_48K 0x0030    /* 48KB, default RX allocation */
+
+/* Flow Control Constants */
+#define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
+#define FLOW_CONTROL_ADDRESS_HIGH 0x00000100
+#define FLOW_CONTROL_TYPE         0x8808
+
+/* The historical defaults for the flow control values are given below. */
+#define FC_DEFAULT_HI_THRESH        (0x8000)    /* 32KB */
+#define FC_DEFAULT_LO_THRESH        (0x4000)    /* 16KB */
+#define FC_DEFAULT_TX_TIMER         (0x100)     /* ~130 us */
+
+/* PCIX Config space */
+#define PCIX_COMMAND_REGISTER    0xE6
+#define PCIX_STATUS_REGISTER_LO  0xE8
+#define PCIX_STATUS_REGISTER_HI  0xEA
+
+#define PCIX_COMMAND_MMRBC_MASK      0x000C
+#define PCIX_COMMAND_MMRBC_SHIFT     0x2
+#define PCIX_STATUS_HI_MMRBC_MASK    0x0060
+#define PCIX_STATUS_HI_MMRBC_SHIFT   0x5
+#define PCIX_STATUS_HI_MMRBC_4K      0x3
+#define PCIX_STATUS_HI_MMRBC_2K      0x2
+
+
+/* Number of bits required to shift right the "pause" bits from the
+ * EEPROM (bits 13:12) to the "pause" (bits 8:7) field in the TXCW register.
+ */
+#define PAUSE_SHIFT 5
+
+/* Number of bits required to shift left the "SWDPIO" bits from the
+ * EEPROM (bits 8:5) to the "SWDPIO" (bits 25:22) field in the CTRL register.
+ */
+#define SWDPIO_SHIFT 17
+
+/* Number of bits required to shift left the "SWDPIO_EXT" bits from the
+ * EEPROM word F (bits 7:4) to the bits 11:8 of The Extended CTRL register.
+ */
+#define SWDPIO__EXT_SHIFT 4
+
+/* Number of bits required to shift left the "ILOS" bit from the EEPROM
+ * (bit 4) to the "ILOS" (bit 7) field in the CTRL register.
+ */
+#define ILOS_SHIFT  3
+
+
+#define RECEIVE_BUFFER_ALIGN_SIZE  (256)
+
+/* Number of milliseconds we wait for auto-negotiation to complete */
+#define LINK_UP_TIMEOUT             500
+
+#define E1000_TX_BUFFER_SIZE ((uint32_t)1514)
+
+/* The carrier extension symbol, as received by the NIC. */
+#define CARRIER_EXTENSION   0x0F
+
+/* TBI_ACCEPT macro definition:
+ *
+ * This macro requires:
+ *      adapter = a pointer to struct e1000_hw 
+ *      status = the 8 bit status field of the RX descriptor with EOP set
+ *      error = the 8 bit error field of the RX descriptor with EOP set
+ *      length = the sum of all the length fields of the RX descriptors that
+ *               make up the current frame
+ *      last_byte = the last byte of the frame DMAed by the hardware
+ *      max_frame_length = the maximum frame length we want to accept.
+ *      min_frame_length = the minimum frame length we want to accept.
+ *
+ * This macro is a conditional that should be used in the interrupt 
+ * handler's Rx processing routine when RxErrors have been detected.
+ *
+ * Typical use:
+ *  ...
+ *  if (TBI_ACCEPT) {
+ *      accept_frame = TRUE;
+ *      e1000_tbi_adjust_stats(adapter, MacAddress);
+ *      frame_length--;
+ *  } else {
+ *      accept_frame = FALSE;
+ *  }
+ *  ...
+ */
+
+#define TBI_ACCEPT(adapter, status, errors, length, last_byte) \
+    ((adapter)->tbi_compatibility_on && \
+     (((errors) & E1000_RXD_ERR_FRAME_ERR_MASK) == E1000_RXD_ERR_CE) && \
+     ((last_byte) == CARRIER_EXTENSION) && \
+     (((status) & E1000_RXD_STAT_VP) ? \
+          (((length) > ((adapter)->min_frame_size - VLAN_TAG_SIZE)) && \
+           ((length) <= ((adapter)->max_frame_size + 1))) : \
+          (((length) > (adapter)->min_frame_size) && \
+           ((length) <= ((adapter)->max_frame_size + VLAN_TAG_SIZE + 1)))))
+
+
+/* Structures, enums, and macros for the PHY */
+
+/* Bit definitions for the Management Data IO (MDIO) and Management Data
+ * Clock (MDC) pins in the Device Control Register.
+ */
+#define E1000_CTRL_PHY_RESET_DIR  E1000_CTRL_SWDPIO0
+#define E1000_CTRL_PHY_RESET      E1000_CTRL_SWDPIN0
+#define E1000_CTRL_MDIO_DIR       E1000_CTRL_SWDPIO2
+#define E1000_CTRL_MDIO           E1000_CTRL_SWDPIN2
+#define E1000_CTRL_MDC_DIR        E1000_CTRL_SWDPIO3
+#define E1000_CTRL_MDC            E1000_CTRL_SWDPIN3
+#define E1000_CTRL_PHY_RESET_DIR4 E1000_CTRL_EXT_SDP4_DIR
+#define E1000_CTRL_PHY_RESET4     E1000_CTRL_EXT_SDP4_DATA
+
+/* PHY 1000 MII Register/Bit Definitions */
+/* PHY Registers defined by IEEE */
+#define PHY_CTRL         0x00 /* Control Register */
+#define PHY_STATUS       0x01 /* Status Regiser */
+#define PHY_ID1          0x02 /* Phy Id Reg (word 1) */
+#define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
+#define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
+#define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP  0x06 /* Autoneg Expansion Reg */
+#define PHY_NEXT_PAGE_TX 0x07 /* Next Page TX */
+#define PHY_LP_NEXT_PAGE 0x08 /* Link Partner Next Page */
+#define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
+#define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
+
+/* M88E1000 Specific Registers */
+#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
+#define M88E1000_PHY_SPEC_STATUS   0x11  /* PHY Specific Status Register */
+#define M88E1000_INT_ENABLE        0x12  /* Interrupt Enable Register */
+#define M88E1000_INT_STATUS        0x13  /* Interrupt Status Register */
+#define M88E1000_EXT_PHY_SPEC_CTRL 0x14  /* Extended PHY Specific Control */
+#define M88E1000_RX_ERR_CNTR       0x15  /* Receive Error Counter */
+
+#define M88E1000_PHY_EXT_CTRL      0x1A  /* PHY extend control register */
+#define M88E1000_PHY_PAGE_SELECT   0x1D  /* Reg 29 for page number setting */
+#define M88E1000_PHY_GEN_CONTROL   0x1E  /* Its meaning depends on reg 29 */
+#define M88E1000_PHY_VCO_REG_BIT8  0x100 /* Bits 8 & 11 are adjusted for */
+#define M88E1000_PHY_VCO_REG_BIT11 0x800    /* improved BER performance */
+
+#define IGP01E1000_IEEE_REGS_PAGE  0x0000
+#define IGP01E1000_IEEE_RESTART_AUTONEG 0x3300
+#define IGP01E1000_IEEE_FORCE_GIGA      0x0140
+
+/* IGP01E1000 Specific Registers */
+#define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */
+#define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */
+#define IGP01E1000_PHY_PORT_CTRL   0x12 /* PHY Specific Control Register */
+#define IGP01E1000_PHY_LINK_HEALTH 0x13 /* PHY Link Health Register */
+#define IGP01E1000_GMII_FIFO       0x14 /* GMII FIFO Register */
+#define IGP01E1000_PHY_CHANNEL_QUALITY 0x15 /* PHY Channel Quality Register */
+#define IGP01E1000_PHY_PAGE_SELECT     0x1F /* PHY Page Select Core Register */
+
+/* IGP01E1000 AGC Registers - stores the cable length values*/
+#define IGP01E1000_PHY_AGC_A        0x1172
+#define IGP01E1000_PHY_AGC_B        0x1272
+#define IGP01E1000_PHY_AGC_C        0x1472
+#define IGP01E1000_PHY_AGC_D        0x1872
+
+/* IGP01E1000 DSP Reset Register */
+#define IGP01E1000_PHY_DSP_RESET   0x1F33
+#define IGP01E1000_PHY_DSP_SET     0x1F71
+#define IGP01E1000_PHY_DSP_FFE     0x1F35
+
+#define IGP01E1000_PHY_CHANNEL_NUM    4
+#define IGP01E1000_PHY_AGC_PARAM_A    0x1171
+#define IGP01E1000_PHY_AGC_PARAM_B    0x1271
+#define IGP01E1000_PHY_AGC_PARAM_C    0x1471
+#define IGP01E1000_PHY_AGC_PARAM_D    0x1871
+
+#define IGP01E1000_PHY_EDAC_MU_INDEX        0xC000
+#define IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS 0x8000
+
+#define IGP01E1000_PHY_ANALOG_TX_STATE      0x2890
+#define IGP01E1000_PHY_ANALOG_CLASS_A       0x2000
+#define IGP01E1000_PHY_FORCE_ANALOG_ENABLE  0x0004
+#define IGP01E1000_PHY_DSP_FFE_CM_CP        0x0069
+
+#define IGP01E1000_PHY_DSP_FFE_DEFAULT      0x002A
+/* IGP01E1000 PCS Initialization register - stores the polarity status when
+ * speed = 1000 Mbps. */
+#define IGP01E1000_PHY_PCS_INIT_REG  0x00B4
+#define IGP01E1000_PHY_PCS_CTRL_REG  0x00B5
+
+#define IGP01E1000_ANALOG_REGS_PAGE  0x20C0
+  
+#define MAX_PHY_REG_ADDRESS 0x1F        /* 5 bit address bus (0-0x1F) */
+#define MAX_PHY_MULTI_PAGE_REG  0xF     /*Registers that are equal on all 
pages*/
+/* PHY Control Register */
+#define MII_CR_SPEED_SELECT_MSB 0x0040  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_COLL_TEST_ENABLE 0x0080  /* Collision test enable */
+#define MII_CR_FULL_DUPLEX      0x0100  /* FDX =1, half duplex =0 */
+#define MII_CR_RESTART_AUTO_NEG 0x0200  /* Restart auto negotiation */
+#define MII_CR_ISOLATE          0x0400  /* Isolate PHY from MII */
+#define MII_CR_POWER_DOWN       0x0800  /* Power down */
+#define MII_CR_AUTO_NEG_EN      0x1000  /* Auto Neg Enable */
+#define MII_CR_SPEED_SELECT_LSB 0x2000  /* bits 6,13: 10=1000, 01=100, 00=10 */
+#define MII_CR_LOOPBACK         0x4000  /* 0 = normal, 1 = loopback */
+#define MII_CR_RESET            0x8000  /* 0 = normal, 1 = PHY reset */
+
+/* PHY Status Register */
+#define MII_SR_EXTENDED_CAPS     0x0001 /* Extended register capabilities */
+#define MII_SR_JABBER_DETECT     0x0002 /* Jabber Detected */
+#define MII_SR_LINK_STATUS       0x0004 /* Link Status 1 = link */
+#define MII_SR_AUTONEG_CAPS      0x0008 /* Auto Neg Capable */
+#define MII_SR_REMOTE_FAULT      0x0010 /* Remote Fault Detect */
+#define MII_SR_AUTONEG_COMPLETE  0x0020 /* Auto Neg Complete */
+#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */
+#define MII_SR_EXTENDED_STATUS   0x0100 /* Ext. status info in Reg 0x0F */
+#define MII_SR_100T2_HD_CAPS     0x0200 /* 100T2 Half Duplex Capable */
+#define MII_SR_100T2_FD_CAPS     0x0400 /* 100T2 Full Duplex Capable */
+#define MII_SR_10T_HD_CAPS       0x0800 /* 10T   Half Duplex Capable */
+#define MII_SR_10T_FD_CAPS       0x1000 /* 10T   Full Duplex Capable */
+#define MII_SR_100X_HD_CAPS      0x2000 /* 100X  Half Duplex Capable */
+#define MII_SR_100X_FD_CAPS      0x4000 /* 100X  Full Duplex Capable */
+#define MII_SR_100T4_CAPS        0x8000 /* 100T4 Capable */
+
+/* Autoneg Advertisement Register */
+#define NWAY_AR_SELECTOR_FIELD 0x0001   /* indicates IEEE 802.3 CSMA/CD */
+#define NWAY_AR_10T_HD_CAPS    0x0020   /* 10T   Half Duplex Capable */
+#define NWAY_AR_10T_FD_CAPS    0x0040   /* 10T   Full Duplex Capable */
+#define NWAY_AR_100TX_HD_CAPS  0x0080   /* 100TX Half Duplex Capable */
+#define NWAY_AR_100TX_FD_CAPS  0x0100   /* 100TX Full Duplex Capable */
+#define NWAY_AR_100T4_CAPS     0x0200   /* 100T4 Capable */
+#define NWAY_AR_PAUSE          0x0400   /* Pause operation desired */
+#define NWAY_AR_ASM_DIR        0x0800   /* Asymmetric Pause Direction bit */
+#define NWAY_AR_REMOTE_FAULT   0x2000   /* Remote Fault detected */
+#define NWAY_AR_NEXT_PAGE      0x8000   /* Next Page ability supported */
+
+/* Link Partner Ability Register (Base Page) */
+#define NWAY_LPAR_SELECTOR_FIELD 0x0000 /* LP protocol selector field */
+#define NWAY_LPAR_10T_HD_CAPS    0x0020 /* LP is 10T   Half Duplex Capable */
+#define NWAY_LPAR_10T_FD_CAPS    0x0040 /* LP is 10T   Full Duplex Capable */
+#define NWAY_LPAR_100TX_HD_CAPS  0x0080 /* LP is 100TX Half Duplex Capable */
+#define NWAY_LPAR_100TX_FD_CAPS  0x0100 /* LP is 100TX Full Duplex Capable */
+#define NWAY_LPAR_100T4_CAPS     0x0200 /* LP is 100T4 Capable */
+#define NWAY_LPAR_PAUSE          0x0400 /* LP Pause operation desired */
+#define NWAY_LPAR_ASM_DIR        0x0800 /* LP Asymmetric Pause Direction bit */
+#define NWAY_LPAR_REMOTE_FAULT   0x2000 /* LP has detected Remote Fault */
+#define NWAY_LPAR_ACKNOWLEDGE    0x4000 /* LP has rx'd link code word */
+#define NWAY_LPAR_NEXT_PAGE      0x8000 /* Next Page ability supported */
+
+/* Autoneg Expansion Register */
+#define NWAY_ER_LP_NWAY_CAPS      0x0001 /* LP has Auto Neg Capability */
+#define NWAY_ER_PAGE_RXD          0x0002 /* LP is 10T   Half Duplex Capable */
+#define NWAY_ER_NEXT_PAGE_CAPS    0x0004 /* LP is 10T   Full Duplex Capable */
+#define NWAY_ER_LP_NEXT_PAGE_CAPS 0x0008 /* LP is 100TX Half Duplex Capable */
+#define NWAY_ER_PAR_DETECT_FAULT  0x0010 /* LP is 100TX Full Duplex Capable */
+
+/* Next Page TX Register */
+#define NPTX_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
+#define NPTX_TOGGLE         0x0800 /* Toggles between exchanges
+                                    * of different NP
+                                    */
+#define NPTX_ACKNOWLDGE2    0x1000 /* 1 = will comply with msg
+                                    * 0 = cannot comply with msg
+                                    */
+#define NPTX_MSG_PAGE       0x2000 /* formatted(1)/unformatted(0) pg */
+#define NPTX_NEXT_PAGE      0x8000 /* 1 = addition NP will follow 
+                                    * 0 = sending last NP
+                                    */
+
+/* Link Partner Next Page Register */
+#define LP_RNPR_MSG_CODE_FIELD 0x0001 /* NP msg code or unformatted data */
+#define LP_RNPR_TOGGLE         0x0800 /* Toggles between exchanges
+                                       * of different NP
+                                       */
+#define LP_RNPR_ACKNOWLDGE2    0x1000 /* 1 = will comply with msg 
+                                       * 0 = cannot comply with msg
+                                       */
+#define LP_RNPR_MSG_PAGE       0x2000  /* formatted(1)/unformatted(0) pg */
+#define LP_RNPR_ACKNOWLDGE     0x4000  /* 1 = ACK / 0 = NO ACK */
+#define LP_RNPR_NEXT_PAGE      0x8000  /* 1 = addition NP will follow
+                                        * 0 = sending last NP 
+                                        */
+
+/* 1000BASE-T Control Register */
+#define CR_1000T_ASYM_PAUSE      0x0080 /* Advertise asymmetric pause bit */
+#define CR_1000T_HD_CAPS         0x0100 /* Advertise 1000T HD capability */
+#define CR_1000T_FD_CAPS         0x0200 /* Advertise 1000T FD capability  */
+#define CR_1000T_REPEATER_DTE    0x0400 /* 1=Repeater/switch device port */
+                                        /* 0=DTE device */
+#define CR_1000T_MS_VALUE        0x0800 /* 1=Configure PHY as Master */
+                                        /* 0=Configure PHY as Slave */
+#define CR_1000T_MS_ENABLE       0x1000 /* 1=Master/Slave manual config value 
*/
+                                        /* 0=Automatic Master/Slave config */
+#define CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */
+#define CR_1000T_TEST_MODE_1     0x2000 /* Transmit Waveform test */
+#define CR_1000T_TEST_MODE_2     0x4000 /* Master Transmit Jitter test */
+#define CR_1000T_TEST_MODE_3     0x6000 /* Slave Transmit Jitter test */
+#define CR_1000T_TEST_MODE_4     0x8000 /* Transmitter Distortion test */
+
+/* 1000BASE-T Status Register */
+#define SR_1000T_IDLE_ERROR_CNT   0x00FF /* Num idle errors since last read */
+#define SR_1000T_ASYM_PAUSE_DIR   0x0100 /* LP asymmetric pause direction bit 
*/
+#define SR_1000T_LP_HD_CAPS       0x0400 /* LP is 1000T HD capable */
+#define SR_1000T_LP_FD_CAPS       0x0800 /* LP is 1000T FD capable */
+#define SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */
+#define SR_1000T_LOCAL_RX_STATUS  0x2000 /* Local receiver OK */
+#define SR_1000T_MS_CONFIG_RES    0x4000 /* 1=Local TX is Master, 0=Slave */
+#define SR_1000T_MS_CONFIG_FAULT  0x8000 /* Master/Slave config fault */
+#define SR_1000T_REMOTE_RX_STATUS_SHIFT 12
+#define SR_1000T_LOCAL_RX_STATUS_SHIFT  13
+#define SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT    5
+#define FFE_IDLE_ERR_COUNT_TIMEOUT_20            20
+#define FFE_IDLE_ERR_COUNT_TIMEOUT_100           100
+
+/* Extended Status Register */
+#define IEEE_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */
+#define IEEE_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */
+#define IEEE_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */
+#define IEEE_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */
+
+#define PHY_TX_POLARITY_MASK   0x0100 /* register 10h bit 8 (polarity bit) */
+#define PHY_TX_NORMAL_POLARITY 0      /* register 10h bit 8 (normal polarity) 
*/
+
+#define AUTO_POLARITY_DISABLE  0x0010 /* register 11h bit 4 */
+                                      /* (0=enable, 1=disable) */
+
+/* M88E1000 PHY Specific Control Register */
+#define M88E1000_PSCR_JABBER_DISABLE    0x0001 /* 1=Jabber Function disabled */
+#define M88E1000_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled 
*/
+#define M88E1000_PSCR_SQE_TEST          0x0004 /* 1=SQE Test enabled */
+#define M88E1000_PSCR_CLK125_DISABLE    0x0010 /* 1=CLK125 low, 
+                                                * 0=CLK125 toggling
+                                                */
+#define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 
*/
+                                               /* Manual MDI configuration */
+#define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
+#define M88E1000_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover,
+                                                *  100BASE-TX/10BASE-T: 
+                                                *  MDI Mode
+                                                */
+#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled 
+                                                * all speeds. 
+                                                */
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE 0x0080 
+                                        /* 1=Enable Extended 10BASE-T distance
+                                         * (Lower 10BASE-T RX Threshold)
+                                         * 0=Normal 10BASE-T RX Threshold */
+#define M88E1000_PSCR_MII_5BIT_ENABLE      0x0100
+                                        /* 1=5-Bit interface in 100BASE-TX
+                                         * 0=MII interface in 100BASE-TX */
+#define M88E1000_PSCR_SCRAMBLER_DISABLE    0x0200 /* 1=Scrambler disable */
+#define M88E1000_PSCR_FORCE_LINK_GOOD      0x0400 /* 1=Force link good */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800 /* 1=Assert CRS on Transmit 
*/
+
+#define M88E1000_PSCR_POLARITY_REVERSAL_SHIFT    1
+#define M88E1000_PSCR_AUTO_X_MODE_SHIFT          5
+#define M88E1000_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7
+
+/* M88E1000 PHY Specific Status Register */
+#define M88E1000_PSSR_JABBER             0x0001 /* 1=Jabber */
+#define M88E1000_PSSR_REV_POLARITY       0x0002 /* 1=Polarity reversed */
+#define M88E1000_PSSR_DOWNSHIFT          0x0020 /* 1=Downshifted */
+#define M88E1000_PSSR_MDIX               0x0040 /* 1=MDIX; 0=MDI */
+#define M88E1000_PSSR_CABLE_LENGTH       0x0380 /* 0=<50M;1=50-80M;2=80-110M;
+                                            * 3=110-140M;4=>140M */
+#define M88E1000_PSSR_LINK               0x0400 /* 1=Link up, 0=Link down */
+#define M88E1000_PSSR_SPD_DPLX_RESOLVED  0x0800 /* 1=Speed & Duplex resolved */
+#define M88E1000_PSSR_PAGE_RCVD          0x1000 /* 1=Page received */
+#define M88E1000_PSSR_DPLX               0x2000 /* 1=Duplex 0=Half Duplex */
+#define M88E1000_PSSR_SPEED              0xC000 /* Speed, bits 14:15 */
+#define M88E1000_PSSR_10MBS              0x0000 /* 00=10Mbs */
+#define M88E1000_PSSR_100MBS             0x4000 /* 01=100Mbs */
+#define M88E1000_PSSR_1000MBS            0x8000 /* 10=1000Mbs */
+
+#define M88E1000_PSSR_REV_POLARITY_SHIFT 1
+#define M88E1000_PSSR_DOWNSHIFT_SHIFT    5
+#define M88E1000_PSSR_MDIX_SHIFT         6
+#define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
+
+/* M88E1000 Extended PHY Specific Control Register */
+#define M88E1000_EPSCR_FIBER_LOOPBACK 0x4000 /* 1=Fiber loopback */
+#define M88E1000_EPSCR_DOWN_NO_IDLE   0x8000 /* 1=Lost lock detect enabled.
+                                              * Will assert lost lock and bring
+                                              * link down if idle not seen
+                                              * within 1ms in 1000BASE-T 
+                                              */
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master */
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000    
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_2X   0x0400
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_3X   0x0800
+#define M88E1000_EPSCR_MASTER_DOWNSHIFT_4X   0x0C00
+/* Number of times we will attempt to autonegotiate before downshifting if we
+ * are the slave */
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_DIS   0x0000
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_2X    0x0200
+#define M88E1000_EPSCR_SLAVE_DOWNSHIFT_3X    0x0300
+#define M88E1000_EPSCR_TX_CLK_2_5     0x0060 /* 2.5 MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
+#define M88E1000_EPSCR_TX_CLK_0       0x0000 /* NO  TX_CLK */
+
+/* IGP01E1000 Specific Port Config Register - R/W */
+#define IGP01E1000_PSCFR_AUTO_MDIX_PAR_DETECT  0x0010
+#define IGP01E1000_PSCFR_PRE_EN                0x0020
+#define IGP01E1000_PSCFR_SMART_SPEED           0x0080
+#define IGP01E1000_PSCFR_DISABLE_TPLOOPBACK    0x0100
+#define IGP01E1000_PSCFR_DISABLE_JABBER        0x0400
+#define IGP01E1000_PSCFR_DISABLE_TRANSMIT      0x2000
+
+/* IGP01E1000 Specific Port Status Register - R/O */
+#define IGP01E1000_PSSR_AUTONEG_FAILED         0x0001 /* RO LH SC */
+#define IGP01E1000_PSSR_POLARITY_REVERSED      0x0002
+#define IGP01E1000_PSSR_CABLE_LENGTH           0x007C
+#define IGP01E1000_PSSR_FULL_DUPLEX            0x0200
+#define IGP01E1000_PSSR_LINK_UP                0x0400
+#define IGP01E1000_PSSR_MDIX                   0x0800
+#define IGP01E1000_PSSR_SPEED_MASK             0xC000 /* speed bits mask */
+#define IGP01E1000_PSSR_SPEED_10MBPS           0x4000
+#define IGP01E1000_PSSR_SPEED_100MBPS          0x8000
+#define IGP01E1000_PSSR_SPEED_1000MBPS         0xC000
+#define IGP01E1000_PSSR_CABLE_LENGTH_SHIFT     0x0002 /* shift right 2 */
+#define IGP01E1000_PSSR_MDIX_SHIFT             0x000B /* shift right 11 */
+
+/* IGP01E1000 Specific Port Control Register - R/W */
+#define IGP01E1000_PSCR_TP_LOOPBACK            0x0001
+#define IGP01E1000_PSCR_CORRECT_NC_SCMBLR      0x0200
+#define IGP01E1000_PSCR_TEN_CRS_SELECT         0x0400
+#define IGP01E1000_PSCR_FLIP_CHIP              0x0800
+#define IGP01E1000_PSCR_AUTO_MDIX              0x1000
+#define IGP01E1000_PSCR_FORCE_MDI_MDIX         0x2000 /* 0-MDI, 1-MDIX */
+
+/* IGP01E1000 Specific Port Link Health Register */
+#define IGP01E1000_PLHR_SS_DOWNGRADE           0x8000
+#define IGP01E1000_PLHR_GIG_SCRAMBLER_ERROR    0x4000
+#define IGP01E1000_PLHR_GIG_REM_RCVR_NOK       0x0800 /* LH */
+#define IGP01E1000_PLHR_IDLE_ERROR_CNT_OFLOW   0x0400 /* LH */
+#define IGP01E1000_PLHR_DATA_ERR_1             0x0200 /* LH */
+#define IGP01E1000_PLHR_DATA_ERR_0             0x0100
+#define IGP01E1000_PLHR_AUTONEG_FAULT          0x0010
+#define IGP01E1000_PLHR_AUTONEG_ACTIVE         0x0008
+#define IGP01E1000_PLHR_VALID_CHANNEL_D        0x0004
+#define IGP01E1000_PLHR_VALID_CHANNEL_C        0x0002
+#define IGP01E1000_PLHR_VALID_CHANNEL_B        0x0001
+#define IGP01E1000_PLHR_VALID_CHANNEL_A        0x0000
+
+/* IGP01E1000 Channel Quality Register */
+#define IGP01E1000_MSE_CHANNEL_D        0x000F
+#define IGP01E1000_MSE_CHANNEL_C        0x00F0
+#define IGP01E1000_MSE_CHANNEL_B        0x0F00
+#define IGP01E1000_MSE_CHANNEL_A        0xF000
+
+/* IGP01E1000 DSP reset macros */
+#define DSP_RESET_ENABLE     0x0
+#define DSP_RESET_DISABLE    0x2
+#define E1000_MAX_DSP_RESETS 10
+
+/* IGP01E1000 AGC Registers */
+
+#define IGP01E1000_AGC_LENGTH_SHIFT 7         /* Coarse - 13:11, Fine - 10:7 */
+
+/* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
+#define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
+
+/* The precision of the length is +/- 10 meters */
+#define IGP01E1000_AGC_RANGE    10
+
+/* IGP01E1000 PCS Initialization register */
+/* bits 3:6 in the PCS registers stores the channels polarity */
+#define IGP01E1000_PHY_POLARITY_MASK    0x0078
+
+/* IGP01E1000 GMII FIFO Register */
+#define IGP01E1000_GMII_FLEX_SPD               0x10 /* Enable flexible speed
+                                                     * on Link-Up */
+#define IGP01E1000_GMII_SPD                    0x20 /* Enable SPD */
+
+/* IGP01E1000 Analog Register */
+#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS         0x20D1
+#define IGP01E1000_ANALOG_FUSE_STATUS               0x20D0
+#define IGP01E1000_ANALOG_FUSE_CONTROL              0x20DC
+#define IGP01E1000_ANALOG_FUSE_BYPASS               0x20DE
+
+#define IGP01E1000_ANALOG_FUSE_POLY_MASK            0xF000
+#define IGP01E1000_ANALOG_FUSE_FINE_MASK            0x0F80
+#define IGP01E1000_ANALOG_FUSE_COARSE_MASK          0x0070
+#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED        0x0100
+#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL    0x0002
+
+#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH        0x0040
+#define IGP01E1000_ANALOG_FUSE_COARSE_10            0x0010
+#define IGP01E1000_ANALOG_FUSE_FINE_1               0x0080
+#define IGP01E1000_ANALOG_FUSE_FINE_10              0x0500
+
+/* Bit definitions for valid PHY IDs. */
+#define M88E1000_E_PHY_ID  0x01410C50
+#define M88E1000_I_PHY_ID  0x01410C30
+#define M88E1011_I_PHY_ID  0x01410C20
+#define IGP01E1000_I_PHY_ID  0x02A80380
+#define M88E1000_12_PHY_ID M88E1000_E_PHY_ID
+#define M88E1000_14_PHY_ID M88E1000_E_PHY_ID
+#define M88E1011_I_REV_4   0x04
+
+/* Miscellaneous PHY bit definitions. */
+#define PHY_PREAMBLE        0xFFFFFFFF
+#define PHY_SOF             0x01
+#define PHY_OP_READ         0x02
+#define PHY_OP_WRITE        0x01
+#define PHY_TURNAROUND      0x02
+#define PHY_PREAMBLE_SIZE   32
+#define MII_CR_SPEED_1000   0x0040
+#define MII_CR_SPEED_100    0x2000
+#define MII_CR_SPEED_10     0x0000
+#define E1000_PHY_ADDRESS   0x01
+#define PHY_AUTO_NEG_TIME   45  /* 4.5 Seconds */
+#define PHY_FORCE_TIME      20  /* 2.0 Seconds */
+#define PHY_REVISION_MASK   0xFFFFFFF0
+#define DEVICE_SPEED_MASK   0x00000300  /* Device Ctrl Reg Speed Mask */
+#define REG4_SPEED_MASK     0x01E0
+#define REG9_SPEED_MASK     0x0300
+#define ADVERTISE_10_HALF   0x0001
+#define ADVERTISE_10_FULL   0x0002
+#define ADVERTISE_100_HALF  0x0004
+#define ADVERTISE_100_FULL  0x0008
+#define ADVERTISE_1000_HALF 0x0010
+#define ADVERTISE_1000_FULL 0x0020
+#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x002F  /* Everything but 1000-Half */
+#define AUTONEG_ADVERTISE_10_100_ALL    0x000F /* All 10/100 speeds*/
+#define AUTONEG_ADVERTISE_10_ALL        0x0003 /* 10Mbps Full & Half speeds*/
+
+#endif /* _E1000_HW_H_ */
diff -urpN grub-0.96/netboot/etherboot.h resumo-0.96/netboot/etherboot.h
--- grub-0.96/netboot/etherboot.h       2003-07-09 20:45:37.000000000 +0900
+++ resumo-0.96/netboot/etherboot.h     2005-04-19 20:34:49.000000000 +0900
@@ -1,6 +1,7 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -496,6 +497,11 @@ External prototypes
 /* main.c */
 extern void print_network_configuration (void);
 extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+extern int recover_transmit (unsigned long destip, unsigned int srcsock,
+                            unsigned int destsock, int len, const void *buf, 
int try, int timer);
+extern int recover_bootp (int try, int timer);
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
 extern int udp_transmit (unsigned long destip, unsigned int srcsock,
                         unsigned int destsock, int len, const void *buf);
 extern int await_reply (int type, int ival, void *ptr, int timeout);
diff -urpN grub-0.96/netboot/main.c resumo-0.96/netboot/main.c
--- grub-0.96/netboot/main.c    2004-05-21 07:19:33.000000000 +0900
+++ resumo-0.96/netboot/main.c  2005-04-19 20:34:49.000000000 +0900
@@ -1,6 +1,7 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -61,7 +62,7 @@ static unsigned char *end_of_rfc1533 = N
 #ifndef        NO_DHCP_SUPPORT
 #endif /* NO_DHCP_SUPPORT */
 
-/* äEth */
+/* ’ç¦th */
 static unsigned char vendorext_magic[] = {0xE4, 0x45, 0x74, 0x68};
 static const unsigned char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
@@ -191,6 +192,262 @@ ifconfig (char *ip, char *sm, char *gw, 
 }
 
 
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+/**********************************************************************
+ *  recover_transmit function
+ *********************************************************************/
+int 
+recover_transmit (unsigned long destip, unsigned int srcsock,
+                 unsigned int destsock, int len, const void *buf, int try, int 
timer)
+{
+  struct iphdr *ip;
+  struct udphdr *udp;
+  struct arprequest arpreq;
+  int arpentry, i;
+  int retry;
+
+  ip = (struct iphdr *) buf;
+  udp = (struct udphdr *) ((unsigned long) buf + sizeof (struct iphdr));
+  ip->verhdrlen = 0x45;
+  ip->service = 0;
+  ip->len = htons (len);
+  ip->ident = 0;
+  ip->frags = 0;
+  ip->ttl = 60;
+  ip->protocol = IP_UDP;
+  ip->chksum = 0;
+  ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
+  ip->dest.s_addr = destip;
+  ip->chksum = ipchksum ((unsigned short *) buf, sizeof (struct iphdr));
+  udp->src = htons (srcsock);
+  udp->dest = htons (destsock);
+  udp->len = htons (len - sizeof (struct iphdr));
+  udp->chksum = 0;
+  udp->chksum = htons (udpchksum (ip));
+
+  if (udp->chksum == 0)
+    udp->chksum = 0xffff;
+  
+  if (destip == IP_BROADCAST)
+    {
+      eth_transmit (broadcast, IP, len, buf);
+    }
+  else
+    {
+      if (((destip & netmask)
+          != (arptable[ARP_CLIENT].ipaddr.s_addr & netmask))
+         && arptable[ARP_GATEWAY].ipaddr.s_addr)
+       destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
+      
+      for (arpentry = 0; arpentry < MAX_ARP; arpentry++)
+       if (arptable[arpentry].ipaddr.s_addr == destip)
+         break;
+      
+      if (arpentry == MAX_ARP)
+       {
+         etherboot_printf ("%@ is not in my arp table!\n", destip);
+         return 0;
+       }
+      
+      for (i = 0; i < ETH_ALEN; i++)
+       if (arptable[arpentry].node[i])
+         break;
+      
+      if (i == ETH_ALEN)
+       {
+         /* Need to do arp request.  */
+         arpreq.hwtype = htons (1);
+         arpreq.protocol = htons (IP);
+         arpreq.hwlen = ETH_ALEN;
+         arpreq.protolen = 4;
+         arpreq.opcode = htons (ARP_REQUEST);
+         grub_memmove (arpreq.shwaddr, arptable[ARP_CLIENT].node,
+                       ETH_ALEN);
+         grub_memmove (arpreq.sipaddr, (char *) &arptable[ARP_CLIENT].ipaddr,
+                       sizeof (in_addr));
+         grub_memset (arpreq.thwaddr, 0, ETH_ALEN);
+         grub_memmove (arpreq.tipaddr, (char *) &destip, sizeof (in_addr));
+         
+         for (retry = 0; retry < try + 1; retry++)
+           {
+             long timeout;
+             
+             eth_transmit (broadcast, ARP, sizeof (arpreq), &arpreq);
+             timeout = rfc2131_sleep_interval (timer * TICKS_PER_SEC, retry);
+             
+             if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, timeout))
+               goto xxmit;
+
+             if (ip_abort)
+               return 0;
+           }
+         
+         return 0;
+       }
+      
+xxmit:
+      eth_transmit (arptable[arpentry].node, IP, len, buf);
+    }
+  
+  return 1;
+}
+/**********************************************************************
+ *  recover_bootp function
+ *********************************************************************/
+int 
+recover_bootp (int try, int timer)
+{
+  int retry;
+#ifndef        NO_DHCP_SUPPORT
+  int reqretry;
+#endif /* ! NO_DHCP_SUPPORT */
+  struct bootpip_t ip;
+  unsigned long starttime;
+
+  /* Make sure that an ethernet is probed.  */
+  if (! eth_probe ())
+    return 0;
+
+  /* Clear the ready flag.  */
+  network_ready = 0;
+
+#ifdef DEBUG
+  grub_printf ("network is ready.\n");
+#endif
+  
+  grub_memset (&ip, 0, sizeof (struct bootpip_t));
+  ip.bp.bp_op = BOOTP_REQUEST;
+  ip.bp.bp_htype = 1;
+  ip.bp.bp_hlen = ETH_ALEN;
+  starttime = currticks ();
+  /* Use lower 32 bits of node address, more likely to be
+     distinct than the time since booting */
+  grub_memmove (&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
+  ip.bp.bp_xid = xid += htonl (starttime);
+  grub_memmove (ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
+#ifdef DEBUG
+  etherboot_printf ("bp_op = %d\n", ip.bp.bp_op);
+  etherboot_printf ("bp_htype = %d\n", ip.bp.bp_htype);
+  etherboot_printf ("bp_hlen = %d\n", ip.bp.bp_hlen);
+  etherboot_printf ("bp_xid = %d\n", ip.bp.bp_xid);
+  etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
+  etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
+  etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
+#endif
+  
+#ifdef NO_DHCP_SUPPORT
+  /* Request RFC-style options.  */
+  grub_memmove (ip.bp.bp_vend, rfc1533_cookie, 5);
+#else
+  /* Request RFC-style options.  */
+  grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
+  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover,
+               sizeof dhcpdiscover);
+  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover,
+               rfc1533_end, sizeof rfc1533_end);
+#endif /* ! NO_DHCP_SUPPORT */
+
+  for (retry = 0; retry < try + 1;)
+    {
+      long timeout;
+
+#ifdef DEBUG
+      grub_printf ("retry = %d\n", retry);
+#endif
+      
+      /* Clear out the Rx queue first.  It contains nothing of
+       * interest, except possibly ARP requests from the DHCP/TFTP
+       * server.  We use polling throughout Etherboot, so some time
+       * may have passed since we last polled the receive queue,
+       * which may now be filled with broadcast packets.  This will
+       * cause the reply to the packets we are about to send to be
+       * lost immediately.  Not very clever.  */
+      await_reply (AWAIT_QDRAIN, 0, NULL, 0);
+
+      udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
+                   sizeof (struct bootpip_t), &ip);
+      timeout = rfc2131_sleep_interval (timer * TICKS_PER_SEC, retry++);
+#ifdef NO_DHCP_SUPPORT
+      if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+       {
+         network_ready = 1;
+         return 1;
+       }
+#else /* ! NO_DHCP_SUPPORT */
+      if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+       {
+         if (dhcp_reply != DHCPOFFER)
+           {
+             network_ready = 1;
+             return 1;
+           }
+
+         dhcp_reply = 0;
+#ifdef DEBUG
+  etherboot_printf ("bp_op = %d\n", (int) ip.bp.bp_op);
+  etherboot_printf ("bp_htype = %d\n", (int) ip.bp.bp_htype);
+  etherboot_printf ("bp_hlen = %d\n", (int) ip.bp.bp_hlen);
+  etherboot_printf ("bp_xid = %d\n", (int) ip.bp.bp_xid);
+  etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
+  etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
+  etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
+#endif
+         grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
+         grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie,
+                       dhcprequest, sizeof dhcprequest);
+         grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie
+                       + sizeof dhcprequest,
+                       rfc1533_end, sizeof rfc1533_end);
+         grub_memmove (ip.bp.bp_vend + 9, (char *) &dhcp_server,
+                       sizeof (in_addr));
+         grub_memmove (ip.bp.bp_vend + 15, (char *) &dhcp_addr,
+                       sizeof (in_addr));
+#ifdef DEBUG
+         grub_printf ("errnum = %d\n", errnum);
+#endif
+         for (reqretry = 0; reqretry < try + 1;)
+           {
+             int ret;
+#ifdef DEBUG
+             grub_printf ("reqretry = %d\n", reqretry);
+#endif
+             
+             ret = udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
+                                 sizeof (struct bootpip_t), &ip);
+             if (! ret)
+               grub_printf ("udp_transmit failed.\n");
+             
+             dhcp_reply = 0;
+             timeout = rfc2131_sleep_interval (timer * TICKS_PER_SEC, 
reqretry++);
+             if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+               if (dhcp_reply == DHCPACK)
+                 {
+                   network_ready = 1;
+                   return 1;
+                 }
+
+#ifdef DEBUG
+             grub_printf ("dhcp_reply = %d\n", dhcp_reply);
+#endif
+             
+             if (ip_abort)
+               return 0;
+           }
+       }
+#endif /* ! NO_DHCP_SUPPORT */
+      
+      if (ip_abort)
+       return 0;
+      
+      ip.bp.bp_secs = htons ((currticks () - starttime) / TICKS_PER_SEC);
+    }
+
+  /* Timeout.  */
+  return 0;
+}
+
+/*!!!|!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 /**************************************************************************
 UDP_TRANSMIT - Send a UDP datagram
 **************************************************************************/
diff -urpN grub-0.96/netboot/pci.c resumo-0.96/netboot/pci.c
--- grub-0.96/netboot/pci.c     2003-07-09 20:45:38.000000000 +0900
+++ resumo-0.96/netboot/pci.c   2005-04-19 20:34:49.000000000 +0900
@@ -1,6 +1,7 @@
 /*
 ** Support for NE2000 PCI clones added David Monro June 1997
 ** Generalised to other NICs by Ken Yap July 1997
+** Copyright (C) 2004-2005 NTT Corporation
 **
 ** Most of this is taken from:
 **
@@ -21,6 +22,10 @@
 #include "etherboot.h"
 #include "pci.h"
 
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+int nic_number = 0;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 /*#define      DEBUG   1*/
 #define DEBUG  0
 
@@ -404,6 +409,9 @@ static void scan_bus(struct pci_device *
        unsigned int membase, ioaddr, romaddr;
        int i, reg;
        unsigned int pci_ioaddr = 0;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+       int nic_count = 1 ;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
 
        /* Scan all PCI buses, until we find our card.
         * We could be smart only scan the required busses but that
@@ -435,13 +443,32 @@ static void scan_bus(struct pci_device *
                                if (vendor != pcidev[i].vendor
                                    || device != pcidev[i].dev_id)
                                        continue;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+                               if ((nic_number == 0) || (nic_count == 
nic_number))
+                                 {
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
                                pcidev[i].devfn = devfn;
                                pcidev[i].bus = bus;
                                for (reg = PCI_BASE_ADDRESS_0; reg <= 
PCI_BASE_ADDRESS_5; reg += 4) {
                                        pcibios_read_config_dword(bus, devfn, 
reg, &ioaddr);
 
                                        if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) 
== 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+                                         {
+                                       if ((PCI_VENDOR_ID_BROADCOM   == 
pcidev[i].vendor) ||
+                                           (PCI_VENDOR_ID_SYSKONNECT == 
pcidev[i].vendor) ||
+                                           (PCI_VENDOR_ID_ALTIMA     == 
pcidev[i].vendor))
+                                         {
+                                               ioaddr = 0xff;
+                                         }
+                                       else
+                                         {
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
                                                continue;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+                                         }
+                                         }
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
                                        /* Strip the I/O address out of the 
returned value */
                                        ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
                                        /* Get the memory base address */
@@ -459,6 +486,14 @@ static void scan_bus(struct pci_device *
                                                return;
                                        }
                                }
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+                               }
+                               nic_count++;
+                               if ((nic_number != 0) && (nic_count > 
nic_number))
+                                 {
+                                       return;
+                                 }
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
                        }
                }
        }
@@ -499,3 +534,116 @@ void adjust_pci_device(struct pci_device
                pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 
32);
        }
 }
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
+#define ULONG_MAX      4294967295UL
+
+#define pcibios_bus_base(bus)          ((unsigned long)0)
+unsigned long pci_bar_start(struct pci_device *dev, unsigned int index)
+{
+       unsigned int lo, hi;
+       unsigned int bar;
+       pci_read_config_dword(dev, 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) {
+                       pci_read_config_dword(dev, index + 4, &hi);
+                       if (hi) {
+#if ULONG_MAX > 0xffffffff
+                                       bar = hi;
+                                       bar <<=32;
+#else
+                                       printf("Unhandled 64bit BAR\n");
+                                       return -1UL;
+#endif
+                       }
+               }
+               bar |= lo & PCI_BASE_ADDRESS_MEM_MASK;
+       }
+       return bar + pcibios_bus_base(dev->bus);
+}
+
+/*
+ * Find the size of a pci resource.
+ */
+unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar)
+{
+       unsigned int start, size;
+       /* Save the original bar */
+       pci_read_config_dword(dev, bar, &start);
+       /* Compute which bits can be set */
+       pci_write_config_dword(dev, bar, ~0);
+       pci_read_config_dword(dev, bar, &size);
+       /* Restore the original size */
+       pci_write_config_dword(dev, 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;
+}
+
+/**
+ * pci_find_capability - query for devices' capabilities 
+ * @dev: PCI device to query
+ * @cap: capability code
+ *
+ * Tell if a device supports a given PCI capability.
+ * Returns the address of the requested capability structure within the
+ * device's PCI configuration space or 0 in case the device does not
+ * support it.  Possible values for @cap:
+ *
+ *  %PCI_CAP_ID_PM           Power Management 
+ *
+ *  %PCI_CAP_ID_AGP          Accelerated Graphics Port 
+ *
+ *  %PCI_CAP_ID_VPD          Vital Product Data 
+ *
+ *  %PCI_CAP_ID_SLOTID       Slot Identification 
+ *
+ *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
+ *
+ *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap 
+ */
+int pci_find_capability(struct pci_device *dev, int cap)
+{
+       unsigned short status;
+       unsigned char pos, id;
+       unsigned char hdr_type;
+       int ttl = 48;
+
+       pci_read_config_word(dev, PCI_STATUS, &status);
+       if (!(status & PCI_STATUS_CAP_LIST))
+               return 0;
+       pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
+       switch (hdr_type & 0x7F) {
+       case PCI_HEADER_TYPE_NORMAL:
+       case PCI_HEADER_TYPE_BRIDGE:
+       default:
+               pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
+               break;
+       case PCI_HEADER_TYPE_CARDBUS:
+               pci_read_config_byte(dev, PCI_CB_CAPABILITY_LIST, &pos);
+               break;
+       }
+       while (ttl-- && pos >= 0x40) {
+               pos &= ~3;
+               pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
+#if    DEBUG > 0
+               printf("Capability: %d\n", id);
+#endif
+               if (id == 0xff)
+                       break;
+               if (id == cap)
+                       return pos;
+               pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
+       }
+       return 0;
+}
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
diff -urpN grub-0.96/netboot/pci.h resumo-0.96/netboot/pci.h
--- grub-0.96/netboot/pci.h     2003-07-09 20:45:38.000000000 +0900
+++ resumo-0.96/netboot/pci.h   2005-04-19 21:18:49.000000000 +0900
@@ -130,6 +130,39 @@ __asm__ __volatile__("pushl %0 ; popfl":
 #define PCI_DEVICE_ID_INTEL_ID1029     0x1029
 #define PCI_DEVICE_ID_INTEL_ID1030     0x1030
 #define PCI_DEVICE_ID_INTEL_82562      0x2449
+/*!!!!!!!!!! START E1000 (GRUB-CGL) Addition !!!!!!!!!!*/
+#define E1000_DEV_ID_82542               0x1000
+#define E1000_DEV_ID_82543GC_FIBER       0x1001
+#define E1000_DEV_ID_82543GC_COPPER      0x1004
+#define E1000_DEV_ID_82544EI_COPPER      0x1008
+#define E1000_DEV_ID_82544EI_FIBER       0x1009
+#define E1000_DEV_ID_82544GC_COPPER      0x100C
+#define E1000_DEV_ID_82544GC_LOM         0x100D
+#define E1000_DEV_ID_82540EM             0x100E
+#define E1000_DEV_ID_82545EM_COPPER      0x100F
+#define E1000_DEV_ID_82546EB_COPPER      0x1010
+#define E1000_DEV_ID_82545EM_FIBER       0x1011
+#define E1000_DEV_ID_82546EB_FIBER       0x1012
+#define E1000_DEV_ID_82541EI             0x1013
+#define E1000_DEV_ID_82540EM_LOM         0x1015
+#define E1000_DEV_ID_82540EP_LOM         0x1016
+#define E1000_DEV_ID_82540EP             0x1017
+#define E1000_DEV_ID_82541EI_MOBILE      0x1018
+#define E1000_DEV_ID_82547EI             0x1019
+#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
+#define E1000_DEV_ID_82540EP_LP          0x101E
+#define E1000_DEV_ID_82545GM_COPPER      0x1026
+#define E1000_DEV_ID_82545GM_FIBER       0x1027
+#define E1000_DEV_ID_82545GM_SERDES      0x1028
+#define E1000_DEV_ID_82547GI             0x1075
+#define E1000_DEV_ID_82541GI             0x1076
+#define E1000_DEV_ID_82541GI_MOBILE      0x1077
+#define E1000_DEV_ID_82541ER             0x1078
+#define E1000_DEV_ID_82546GB_COPPER      0x1079
+#define E1000_DEV_ID_82546GB_FIBER       0x107A
+#define E1000_DEV_ID_82546GB_SERDES      0x107B
+#define E1000_DEV_ID_82541GI_LF          0x107C
+/*!!!!!!!!!!! END E1000 (GRUB-CGL) Addition !!!!!!!!!!!*/
 #define PCI_VENDOR_ID_AMD              0x1022
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_VENDOR_ID_AMD_HOMEPNA      0x1022
@@ -170,6 +203,30 @@ __asm__ __volatile__("pushl %0 ; popfl":
 #define PCI_DEVICE_ID_OLICOM_OC2183    0x0013
 #define PCI_DEVICE_ID_OLICOM_OC2326    0x0014
 #define PCI_DEVICE_ID_OLICOM_OC6151    0x0021
+/*!!!!!!!!!! START TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#define PCI_VENDOR_ID_BROADCOM         0x14e4
+#define PCI_DEVICE_ID_TIGON3_5700      0x1644
+#define PCI_DEVICE_ID_TIGON3_5701      0x1645
+#define PCI_DEVICE_ID_TIGON3_5702      0x1646
+#define PCI_DEVICE_ID_TIGON3_5703      0x1647
+#define PCI_DEVICE_ID_TIGON3_5704      0x1648
+#define PCI_DEVICE_ID_TIGON3_5702FE    0x164d
+#define PCI_DEVICE_ID_TIGON3_5705      0x1653
+#define PCI_DEVICE_ID_TIGON3_5705_2    0x1654
+#define PCI_DEVICE_ID_TIGON3_5705M     0x165d
+#define PCI_DEVICE_ID_TIGON3_5705M_2   0x165e
+#define PCI_DEVICE_ID_TIGON3_5782      0x1696
+#define PCI_DEVICE_ID_TIGON3_5788      0x169c
+#define PCI_DEVICE_ID_TIGON3_5702X     0x16a6
+#define PCI_DEVICE_ID_TIGON3_5703X     0x16a7
+#define PCI_DEVICE_ID_TIGON3_5704S     0x16a8
+#define PCI_DEVICE_ID_TIGON3_5702A3    0x16c6
+#define PCI_DEVICE_ID_TIGON3_5703A3    0x16c7
+#define PCI_DEVICE_ID_TIGON3_5901      0x170d
+#define PCI_DEVICE_ID_TIGON3_5901_2    0x170e
+#define PCI_VENDOR_ID_SYSKONNECT       0x1148
+#define PCI_VENDOR_ID_ALTIMA           0x173b
+/*!!!!!!!!!!! END TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
 
 struct pci_device {
        unsigned short  vendor, dev_id;
@@ -189,4 +246,36 @@ extern int pcibios_write_config_word (un
 extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, 
unsigned int where, unsigned int *value);
 extern int pcibios_write_config_dword(unsigned int bus, unsigned int 
device_fn, unsigned int where, unsigned int value);
 void adjust_pci_device(struct pci_device *p);
+
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#define PCI_STATUS             0x06    /* 16 bits */
+#define  PCI_STATUS_CAP_LIST   0x10    /* Support Capability List */
+#define PCI_CB_CAPABILITY_LIST 0x14
+#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_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_HEADER_TYPE_NORMAL        0
+#define  PCI_HEADER_TYPE_BRIDGE 1
+#define  PCI_HEADER_TYPE_CARDBUS 2
+
+#define pci_read_config_byte(a,b,c) 
pcibios_read_config_byte(a->bus,a->devfn,b,c)
+#define pci_write_config_byte(a,b,c) 
pcibios_write_config_byte(a->bus,a->devfn,b,c)
+#define pci_read_config_word(a,b,c) 
pcibios_read_config_word(a->bus,a->devfn,b,c)
+#define pci_write_config_word(a,b,c) 
pcibios_write_config_word(a->bus,a->devfn,b,c)
+#define pci_read_config_dword(a,b,c) 
pcibios_read_config_dword(a->bus,a->devfn,b,c)
+#define pci_write_config_dword(a,b,c) 
pcibios_write_config_dword(a->bus,a->devfn,b,c)
+
+/* Helper functions to find the size of a pci bar */
+extern unsigned long pci_bar_start(struct pci_device *dev, unsigned int bar);
+extern unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar);
+/* Helper function to find pci capabilities */
+extern int pci_find_capability(struct pci_device *dev, int cap);
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
 #endif /* PCI_H */
diff -urpN grub-0.96/netboot/sk_g16.c resumo-0.96/netboot/sk_g16.c
--- grub-0.96/netboot/sk_g16.c  2003-07-09 20:45:38.000000000 +0900
+++ resumo-0.96/netboot/sk_g16.c        2005-04-19 20:34:49.000000000 +0900
@@ -13,12 +13,12 @@ Changes to make it work with Etherboot b
  *
  * Module         : sk_g16.c
  *
- * Version        : $Revision: 1.4 $
+ * Version        : $Revision: 1.1.1.1 $
  *
  * Author         : Patrick J.D. Weichmann
  *
  * Date Created   : 94/05/26
- * Last Updated   : $Date: 2002/01/02 21:56:40 $
+ * Last Updated   : $Date: 2004/12/02 12:00:37 $
  *
  * Description    : Schneider & Koch G16 Ethernet Device Driver for
  *                  Linux Kernel >= 1.1.22
diff -urpN grub-0.96/netboot/tg3.c resumo-0.96/netboot/tg3.c
--- grub-0.96/netboot/tg3.c     1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/netboot/tg3.c   2005-04-19 21:15:30.000000000 +0900
@@ -0,0 +1,3465 @@
+/* 
+ * tg3.c: Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (address@hidden)
+ * Copyright (C) 2001, 2002 Jeff Garzik (address@hidden)
+ * Copyright (C) 2003 Eric Biederman (address@hidden)  [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.
+ */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "timer.h"
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+#include "string.h"
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+typedef unsigned short         uint16_t;
+typedef unsigned char          uint8_t;
+typedef unsigned int           uint32_t;
+typedef unsigned long long int uint64_t;
+typedef signed int             int32_t;
+//#=#=#=#=#=#=#=#=#=# Start (endian.h) #=#=#=#=#=#=#=#=#=#
+#undef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN    4321
+#define __BYTE_ORDER __LITTLE_ENDIAN
+//#=#=#=#=#=#=#=#=#=# End (endian.h) #=#=#=#=#=#=#=#=#=#
+#define TG3_VLAN_TAG_USED 0
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+#include "tg3.h"
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+//#=#=#=#=#=#=#=#=#=# Start (osdep.h) #=#=#=#=#=#=#=#=#=#
+#define __unused __attribute__((unused))
+//#=#=#=#=#=#=#=#=#=# End (osdep.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (etherboot.h) #=#=#=#=#=#=#=#=#=#
+#ifndef VALID_LINK_TIMEOUT
+#define VALID_LINK_TIMEOUT     100 /* 10.0 seconds */
+#endif
+//#=#=#=#=#=#=#=#=#=# End (etherboot.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (io.h) #=#=#=#=#=#=#=#=#=#
+#undef virt_to_bus
+#define virt_to_bus(x) ((unsigned long)x)
+#define bus_to_virt(x) ((void *)x)
+#define iounmap(addr)          ((void)0)
+#define ioremap(physaddr, size)        bus_to_virt(physaddr)
+//#=#=#=#=#=#=#=#=#=# End (io.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (pci_ids.h) #=#=#=#=#=#=#=#=#=#
+#define PCI_VENDOR_ID_DELL              0x1028
+#define PCI_VENDOR_ID_COMPAQ           0x0e11
+//#=#=#=#=#=#=#=#=#=# End (pci_ids.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (byteswap.h) #=#=#=#=#=#=#=#=#=#
+static inline uint32_t __i386_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;
+}
+#define __bswap_constant_32(x) \
+       ((uint32_t)((((uint32_t)(x) & 0x000000ffU) << 24) | \
+               (((uint32_t)(x) & 0x0000ff00U) <<  8) | \
+               (((uint32_t)(x) & 0x00ff0000U) >>  8) | \
+               (((uint32_t)(x) & 0xff000000U) >> 24)))
+#define __bswap_32(x) \
+       ((uint32_t)(__builtin_constant_p(x) ? \
+       __bswap_constant_32(x) : \
+       __i386_bswap_32(x)))
+#define bswap_32(x)    __bswap_32(x)
+//#=#=#=#=#=#=#=#=#=# End (byteswap.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (pci.h) #=#=#=#=#=#=#=#=#=#
+#define PCI_COMMAND_INVALIDATE         0x10    /* Use memory write and 
invalidate */
+#define  PCI_CAP_ID_PM         0x01    /* Power Management */
+
+#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_SUBSYSTEM_VENDOR_ID        0x2c
+#define PCI_SUBSYSTEM_ID       0x2e  
+#define  PCI_COMMAND_PARITY    0x40    /* Enable parity checking */
+#define  PCI_COMMAND_SERR      0x100   /* Enable SERR */
+//#=#=#=#=#=#=#=#=#=# End (pci.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (timer.h) #=#=#=#=#=#=#=#=#=#
+#define mdelay         mdelay1
+extern void mdelay(unsigned int msecs);
+//#=#=#=#=#=#=#=#=#=# End (timer.h) #=#=#=#=#=#=#=#=#=#
+
+//#=#=#=#=#=#=#=#=#=# Start (timer.c) #=#=#=#=#=#=#=#=#=#
+#define        poll_interruptions()
+#define        udelay(n)       waiton_timer2(((n)*TICKS_PER_MS)/1000)
+void mdelay(unsigned int msecs)
+{
+       unsigned int i;
+       for(i = 0; i < msecs; i++) {
+               udelay(1000);
+               poll_interruptions();
+       }
+}
+//#=#=#=#=#=#=#=#=#=# End (timer.c) #=#=#=#=#=#=#=#=#=#
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+#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++)
+               pci_read_config_dword(dev, 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++)
+               pci_write_config_dword(dev,i * 4, buffer[i]);
+       return 0;
+}
+
+static void tg3_write_indirect_reg32(uint32_t off, uint32_t val)
+{
+       pci_write_config_dword(tg3.pdev, TG3PCI_REG_BASE_ADDR, off);
+       pci_write_config_dword(tg3.pdev, 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)
+{
+       pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+       pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_DATA, val);
+
+       /* Always leave this as zero. */
+       pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
+}
+
+static void tg3_read_mem(uint32_t off, uint32_t *val)
+{
+       pci_write_config_dword(tg3.pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
+       pci_read_config_dword(tg3.pdev, TG3PCI_MEM_WIN_DATA, val);
+
+       /* Always leave this as zero. */
+       pci_write_config_dword(tg3.pdev, 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) &&
+               (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;
+       }
+       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.
+        */
+       pci_write_config_dword(tp->pdev,  TG3PCI_MISC_HOST_CTRL, 
tp->misc_host_ctrl);
+
+       pci_read_config_word(tp->pdev, pm + PCI_PM_CTRL, &power_control);
+
+       power_control |= PCI_PM_CTRL_PME_STATUS;
+       power_control &= ~(PCI_PM_CTRL_STATE_MASK);
+       power_control |= 0;
+       pci_write_config_word(tp->pdev, 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 __unused, 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));
+
+       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.
+        */
+
+       /* do the reset */
+       val = GRC_MISC_CFG_CORECLK_RESET;
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
+               val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
+       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.
+        */
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &val);
+
+       udelay(120);
+
+       /* Re-enable indirect register accesses. */
+       pci_write_config_dword(tp->pdev, 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;
+       pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, val);
+
+       pci_restore_state(tp->pdev, tp->pci_cfg_state);
+
+       /* Make sure PCI-X relaxed ordering bit is clear. */
+       pci_read_config_dword(tp->pdev, TG3PCI_X_CAPS, &val);
+       val &= ~PCIX_CAPS_RELAXED_ORDERING;
+       pci_write_config_dword(tp->pdev, 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;
+       }
+       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);
+
+
+       /* 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.
+        */
+       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)
+               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 __unused, 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 */
+
+       /* 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 address@hidden */
+       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;
+       int err;
+
+       /* Read the subsystem vendor and device ids */
+       pci_read_config_word(tp->pdev, PCI_SUBSYSTEM_VENDOR_ID, 
&tp->subsystem_vendor);
+       pci_read_config_word(tp->pdev, 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.
+        */
+       pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
+       pci_cmd &= ~PCI_COMMAND_INVALIDATE;
+       /* Also, force SERR#/PERR# in PCI command. */
+       pci_cmd |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR;
+       pci_write_config_word(tp->pdev, 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.
+        */
+       pci_read_config_dword(tp->pdev, 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);
+       pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL,
+                              tp->misc_host_ctrl);
+
+       pci_read_config_byte(tp->pdev, PCI_LATENCY_TIMER, &pci_latency);
+       if (pci_latency < 64) {
+               pci_write_config_byte(tp->pdev, PCI_LATENCY_TIMER, 64);
+       }
+
+       pci_read_config_dword(tp->pdev, 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;
+               pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, 
pci_state_reg);
+       }
+
+       /* 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 address@hidden phy feature */
+       if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
+               ((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;
+
+       /* 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);
+       }
+
+       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_BCM8002:    return "8002";
+       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;
+       }
+}
+
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//static int tg3_poll(struct nic *nic, int retrieve)
+static int tg3_poll(struct nic *nic)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       /* 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;
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       if ( (tp->hw_status->idx[0].rx_producer != tp->rx_rcb_ptr) && !retrieve 
) 
+         return 1;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+       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
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//static void tg3_disable(struct dev *dev __unused)
+static void tg3_disable(struct nic *tg3nic)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       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);
+}
+
+/**************************************************************************
+IRQ - Enable, Disable, or Force interrupts
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+static void tg3_irq(struct nic *nic __unused, irq_action_t action __unused)
+{
+  switch ( action ) {
+  case DISABLE :
+    break;
+  case ENABLE :
+    break;
+  case FORCE :
+    break;
+  }
+}
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+static void tg3_reset(struct nic *tg3nic)
+{
+}
+/*!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!*/
+
+/**************************************************************************
+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
+***************************************************************************/
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//static int tg3_probe(struct dev *dev, struct pci_device *pdev)
+struct nic *tg3_probe(struct nic *dev, unsigned short *probeaddrs, struct 
pci_device *pdev)
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+{
+       struct nic *nic = (struct nic *)dev;
+       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);
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       nic->irqno  = 0;
+       nic->ioaddr = pdev->ioaddr & ~3;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+       /* 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;
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+       int resumo_cnt = 0;
+ resumo_retry:
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+       /* 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){
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+       if (resumo_cnt++ >= 2)
+         {
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+               printf("Valid link not established\n");
+               goto err_out_disable;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+         }
+       else
+         {
+               tg3_halt(tp);
+               tg3_setup_hw(tp);
+               goto resumo_retry;
+         }
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+       }
+
+       dev->disable  = tg3_disable;
+       nic->poll     = tg3_poll;
+       nic->transmit = tg3_transmit;
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+       nic->reset    = tg3_reset;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+       nic->irq      = tg3_irq;
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//     return 1;
+       return nic;
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
+
+ err_out_iounmap:
+       iounmap((void *)tp->regs);
+       return 0;
+ err_out_disable:
+       tg3_disable(dev);
+       return 0;
+}
+
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+static struct pci_id tg3_nics[] = {
+PCI_ROM(0x14e4, 0x1644, "tg3-5700",        "Broadcom Tigon 3 5700"),
+PCI_ROM(0x14e4, 0x1645, "tg3-5701",        "Broadcom Tigon 3 5701"),
+PCI_ROM(0x14e4, 0x1646, "tg3-5702",        "Broadcom Tigon 3 5702"),
+PCI_ROM(0x14e4, 0x1647, "tg3-5703",        "Broadcom Tigon 3 5703"),
+PCI_ROM(0x14e4, 0x1648, "tg3-5704",        "Broadcom Tigon 3 5704"),
+PCI_ROM(0x14e4, 0x164d, "tg3-5702FE",      "Broadcom Tigon 3 5702FE"),
+PCI_ROM(0x14e4, 0x1653, "tg3-5705",        "Broadcom Tigon 3 5705"),
+PCI_ROM(0x14e4, 0x1654, "tg3-5705_2",      "Broadcom Tigon 3 5705_2"),
+PCI_ROM(0x14e4, 0x165d, "tg3-5705M",       "Broadcom Tigon 3 5705M"),
+PCI_ROM(0x14e4, 0x165e, "tg3-5705M_2",     "Broadcom Tigon 3 5705M_2"),
+PCI_ROM(0x14e4, 0x1696, "tg3-5782",        "Broadcom Tigon 3 5782"),
+PCI_ROM(0x14e4, 0x169c, "tg3-5788",        "Broadcom Tigon 3 5788"),
+PCI_ROM(0x14e4, 0x16a6, "tg3-5702X",       "Broadcom Tigon 3 5702X"),
+PCI_ROM(0x14e4, 0x16a7, "tg3-5703X",       "Broadcom Tigon 3 5703X"),
+PCI_ROM(0x14e4, 0x16a8, "tg3-5704S",       "Broadcom Tigon 3 5704S"),
+PCI_ROM(0x14e4, 0x16c6, "tg3-5702A3",      "Broadcom Tigon 3 5702A3"),
+PCI_ROM(0x14e4, 0x16c7, "tg3-5703A3",      "Broadcom Tigon 3 5703A3"),
+PCI_ROM(0x14e4, 0x170d, "tg3-5901",        "Broadcom Tigon 3 5901"),
+PCI_ROM(0x14e4, 0x170e, "tg3-5901_2",      "Broadcom Tigon 3 5901_2"),
+PCI_ROM(0x1148, 0x4400, "tg3-9DXX",        "Syskonnect 9DXX"),
+PCI_ROM(0x1148, 0x4500, "tg3-9MXX",        "Syskonnect 9MXX"),
+PCI_ROM(0x173b, 0x03e8, "tg3-ac1000",      "Altima AC1000"),
+PCI_ROM(0x173b, 0x03e9, "tg3-ac1001",      "Altima AC1001"),
+PCI_ROM(0x173b, 0x03ea, "tg3-ac9100",      "Altima AC9100"),
+PCI_ROM(0x173b, 0x03eb, "tg3-ac1003",      "Altima AC1003"),
+};
+
+static struct pci_driver tg3_driver __pci_driver = {
+       .type     = NIC_DRIVER,
+       .name     = "TG3",
+       .probe    = tg3_probe,
+       .ids      = tg3_nics,
+       .id_count = sizeof(tg3_nics)/sizeof(tg3_nics[0]),
+       .class    = 0,
+};
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
diff -urpN grub-0.96/netboot/tg3.h resumo-0.96/netboot/tg3.h
--- grub-0.96/netboot/tg3.h     1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/netboot/tg3.h   2005-04-19 21:16:05.000000000 +0900
@@ -0,0 +1,2202 @@
+/* 
+ * tg3.h: Definitions for Broadcom Tigon3 ethernet driver.
+ *
+ * Copyright (C) 2001, 2002 David S. Miller (address@hidden)
+ * Copyright (C) 2001 Jeff Garzik (address@hidden)
+ */
+
+#ifndef _T3_H
+#define _T3_H
+/*!!!!!!!!!! START (GRUB-CGL) Comment out !!!!!!!!!!
+#include "stdint.h"
+!!!!!!!!!!! END (GRUB-CGL) Comment out !!!!!!!!!!!*/
+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  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  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
+
+
+
+       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_BCM8002                 0x60010140
+#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_BCM8002 || (X) == PHY_ID_SERDES)
+
+       unsigned long                   regs;
+       struct pci_device               *pdev;
+       struct nic                      *nic;
+#if 0
+       struct net_device               *dev;
+#endif
+#if 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) */
diff -urpN grub-0.96/netboot/timer.c resumo-0.96/netboot/timer.c
--- grub-0.96/netboot/timer.c   2003-07-09 20:45:38.000000000 +0900
+++ resumo-0.96/netboot/timer.c 2005-04-19 20:34:49.000000000 +0900
@@ -123,5 +123,4 @@ unsigned long currticks(void)
 
        return currticks;
 }
-
 #endif /* RTC_CURRTICKS */
diff -urpN grub-0.96/netboot/timer.h resumo-0.96/netboot/timer.h
--- grub-0.96/netboot/timer.h   2003-07-09 20:45:38.000000000 +0900
+++ resumo-0.96/netboot/timer.h 2005-04-19 20:34:49.000000000 +0900
@@ -60,5 +60,4 @@ extern inline void waiton_timer2(unsigne
        while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
                ;
 }
-
 #endif /* TIMER_H */
diff -urpN grub-0.96/stage2/Makefile.am resumo-0.96/stage2/Makefile.am
--- grub-0.96/stage2/Makefile.am        2004-07-16 20:44:56.000000000 +0900
+++ resumo-0.96/stage2/Makefile.am      2005-04-19 20:34:49.000000000 +0900
@@ -91,7 +91,7 @@ pre_stage2_exec_SOURCES = asm.S bios.c b
        cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
        fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
        fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
-       hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+       hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c 
recovery.c
 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
diff -urpN grub-0.96/stage2/Makefile.in resumo-0.96/stage2/Makefile.in
--- grub-0.96/stage2/Makefile.in        2005-01-30 10:07:41.000000000 +0900
+++ resumo-0.96/stage2/Makefile.in      2005-04-19 20:34:49.000000000 +0900
@@ -124,7 +124,8 @@ am__objects_1 = diskless_exec-asm.$(OBJE
        diskless_exec-serial.$(OBJEXT) \
        diskless_exec-smp-imps.$(OBJEXT) \
        diskless_exec-stage2.$(OBJEXT) \
-       diskless_exec-terminfo.$(OBJEXT) diskless_exec-tparm.$(OBJEXT)
+       diskless_exec-terminfo.$(OBJEXT) diskless_exec-tparm.$(OBJEXT) \
+       diskless_exec-recovery.$(OBJEXT)
 am_diskless_exec_OBJECTS = $(am__objects_1)
 diskless_exec_OBJECTS = $(am_diskless_exec_OBJECTS)
 diskless_exec_DEPENDENCIES = ../netboot/libdrivers.a
@@ -216,7 +217,8 @@ am_pre_stage2_exec_OBJECTS = pre_stage2_
        pre_stage2_exec-smp-imps.$(OBJEXT) \
        pre_stage2_exec-stage2.$(OBJEXT) \
        pre_stage2_exec-terminfo.$(OBJEXT) \
-       pre_stage2_exec-tparm.$(OBJEXT)
+       pre_stage2_exec-tparm.$(OBJEXT) \
+       pre_stage2_exec-recovery.$(OBJEXT)
 pre_stage2_exec_OBJECTS = $(am_pre_stage2_exec_OBJECTS)
 @address@hidden =  \
 @NETBOOT_SUPPORT_TRUE@ ../netboot/libdrivers.a
@@ -297,6 +299,7 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-gunzip.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-hercules.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-md5.Po \
address@hidden@ ./$(DEPDIR)/diskless_exec-recovery.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-serial.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-smp-imps.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/diskless_exec-stage2.Po \
@@ -381,6 +384,7 @@ am__depfiles_maybe = depfiles
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-gunzip.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-hercules.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-md5.Po \
address@hidden@ ./$(DEPDIR)/pre_stage2_exec-recovery.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-serial.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-smp-imps.Po \
 @AMDEP_TRUE@   ./$(DEPDIR)/pre_stage2_exec-stage2.Po \
@@ -616,7 +620,7 @@ pre_stage2_exec_SOURCES = asm.S bios.c b
        cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
        fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
        fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
-       hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+       hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c 
recovery.c
 
 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
@@ -895,6 +899,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -979,6 +984,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
 @AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@@ -1955,6 +1961,22 @@ diskless_exec-tparm.obj: tparm.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o 
diskless_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; 
else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`
 
+diskless_exec-recovery.o: recovery.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-recovery.o -MD 
-MP -MF "$(DEPDIR)/diskless_exec-recovery.Tpo" -c -o diskless_exec-recovery.o 
`test -f 'recovery.c' || echo '$(srcdir)/'`recovery.c; \
address@hidden@ then mv -f "$(DEPDIR)/diskless_exec-recovery.Tpo" 
"$(DEPDIR)/diskless_exec-recovery.Po"; else rm -f 
"$(DEPDIR)/diskless_exec-recovery.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='recovery.c' 
object='diskless_exec-recovery.o' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/diskless_exec-recovery.Po' 
tmpdepfile='$(DEPDIR)/diskless_exec-recovery.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-recovery.o 
`test -f 'recovery.c' || echo '$(srcdir)/'`recovery.c
+
+diskless_exec-recovery.obj: recovery.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-recovery.obj 
-MD -MP -MF "$(DEPDIR)/diskless_exec-recovery.Tpo" -c -o 
diskless_exec-recovery.obj `if test -f 'recovery.c'; then $(CYGPATH_W) 
'recovery.c'; else $(CYGPATH_W) '$(srcdir)/recovery.c'; fi`; \
address@hidden@ then mv -f "$(DEPDIR)/diskless_exec-recovery.Tpo" 
"$(DEPDIR)/diskless_exec-recovery.Po"; else rm -f 
"$(DEPDIR)/diskless_exec-recovery.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='recovery.c' 
object='diskless_exec-recovery.obj' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/diskless_exec-recovery.Po' 
tmpdepfile='$(DEPDIR)/diskless_exec-recovery.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-recovery.obj 
`if test -f 'recovery.c'; then $(CYGPATH_W) 'recovery.c'; else $(CYGPATH_W) 
'$(srcdir)/recovery.c'; fi`
+
 e2fs_stage1_5_exec-common.o: common.c
 @am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT 
e2fs_stage1_5_exec-common.o -MD -MP -MF 
"$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" -c -o e2fs_stage1_5_exec-common.o 
`test -f 'common.c' || echo '$(srcdir)/'`common.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" 
"$(DEPDIR)/e2fs_stage1_5_exec-common.Po"; else rm -f 
"$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo"; exit 1; fi
@@ -2947,6 +2969,22 @@ pre_stage2_exec-tparm.obj: tparm.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o 
pre_stage2_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; 
else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`
 
+pre_stage2_exec-recovery.o: recovery.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-recovery.o 
-MD -MP -MF "$(DEPDIR)/pre_stage2_exec-recovery.Tpo" -c -o 
pre_stage2_exec-recovery.o `test -f 'recovery.c' || echo 
'$(srcdir)/'`recovery.c; \
address@hidden@ then mv -f "$(DEPDIR)/pre_stage2_exec-recovery.Tpo" 
"$(DEPDIR)/pre_stage2_exec-recovery.Po"; else rm -f 
"$(DEPDIR)/pre_stage2_exec-recovery.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='recovery.c' 
object='pre_stage2_exec-recovery.o' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/pre_stage2_exec-recovery.Po' 
tmpdepfile='$(DEPDIR)/pre_stage2_exec-recovery.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o 
pre_stage2_exec-recovery.o `test -f 'recovery.c' || echo '$(srcdir)/'`recovery.c
+
+pre_stage2_exec-recovery.obj: recovery.c
address@hidden@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT 
pre_stage2_exec-recovery.obj -MD -MP -MF 
"$(DEPDIR)/pre_stage2_exec-recovery.Tpo" -c -o pre_stage2_exec-recovery.obj `if 
test -f 'recovery.c'; then $(CYGPATH_W) 'recovery.c'; else $(CYGPATH_W) 
'$(srcdir)/recovery.c'; fi`; \
address@hidden@ then mv -f "$(DEPDIR)/pre_stage2_exec-recovery.Tpo" 
"$(DEPDIR)/pre_stage2_exec-recovery.Po"; else rm -f 
"$(DEPDIR)/pre_stage2_exec-recovery.Tpo"; exit 1; fi
address@hidden@@am__fastdepCC_FALSE@    source='recovery.c' 
object='pre_stage2_exec-recovery.obj' libtool=no @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    
depfile='$(DEPDIR)/pre_stage2_exec-recovery.Po' 
tmpdepfile='$(DEPDIR)/pre_stage2_exec-recovery.TPo' @AMDEPBACKSLASH@
address@hidden@@am__fastdepCC_FALSE@    $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
address@hidden@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) 
$(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o 
pre_stage2_exec-recovery.obj `if test -f 'recovery.c'; then $(CYGPATH_W) 
'recovery.c'; else $(CYGPATH_W) '$(srcdir)/recovery.c'; fi`
+
 reiserfs_stage1_5_exec-common.o: common.c
 @am__fastdepCC_TRUE@   if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) 
$(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT 
reiserfs_stage1_5_exec-common.o -MD -MP -MF 
"$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" -c -o 
reiserfs_stage1_5_exec-common.o `test -f 'common.c' || echo 
'$(srcdir)/'`common.c; \
 @am__fastdepCC_TRUE@   then mv -f 
"$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" 
"$(DEPDIR)/reiserfs_stage1_5_exec-common.Po"; else rm -f 
"$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo"; exit 1; fi
diff -urpN grub-0.96/stage2/asm.S resumo-0.96/stage2/asm.S
--- grub-0.96/stage2/asm.S      2004-06-20 01:55:22.000000000 +0900
+++ resumo-0.96/stage2/asm.S    2005-04-19 20:34:49.000000000 +0900
@@ -1,7 +1,8 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
- *
+ *  Copyright (C) 2004-2005 NTT Corporation
+ *     
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  the Free Software Foundation; either version 2 of the License, or
@@ -94,6 +95,12 @@ VARIABLE(stage2_id)
        .byte   STAGE2_ID
 VARIABLE(force_lba)
        .byte   0
+VARIABLE(recovery_counter)
+       .byte   0
+VARIABLE(loop_counter)
+       .byte   0
+VARIABLE(start_system)
+       .byte   0
 VARIABLE(version_string)
        .string VERSION
 VARIABLE(config_file)
@@ -2281,6 +2288,70 @@ ENTRY(currticks)
        popl    %ebp
        ret
 
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+/*
+ * getrtdate()
+ *
+ * INT 1Ah Function 04h = Return Current Date
+ * Input:  AH = 04h
+ * Output: CF = 0 Succesfull
+ *            = 1 Clock has stopped running
+ *         CH = Century (in BCD)
+ *         CL = Year (in BCD)
+ *         DH = Month (in BCD)
+ *         DL = Day (in BCD)
+ *
+ * INT 1Ah Function 02h = Return Current Time
+ * Input:  AH = 02h
+ * Output: CF = 0 Succesfull
+ *            = 1 Clock has stopped running
+ *         CH = Number of Hours (in BCD)
+ *         CL = Number of Minutes (in BCD)
+ *         DH = Number of Seconds (in BCD)
+ *         DL = 00h Standard time
+ *            = 01h Daylight savings time
+ */
+ENTRY(getrtdate)
+       pushl   %ebp
+       call    EXT_C(prot_to_real)     /* enter real mode */
+       .code16
+       movb    $0x4,   %ah
+       int     $0x1a
+       DATA32  jnc     gotdate
+       movl    $0x0,   %ecx
+       movl    $0x0,   %edx
+gotdate:
+       DATA32  call    EXT_C(real_to_prot)
+       .code32
+       movb    %ch,            %ah     /* Century */
+       movb    %cl,            %al     /* Year */
+       imul    $0x10000,       %eax    /* Shift */
+       movb    %dh,            %ah     /* Month */
+       movb    %dl,            %al     /* Day */
+       popl    %ebp
+       ret
+
+ENTRY(getrtclock)
+       pushl   %ebp
+       call    EXT_C(prot_to_real)     /* enter real mode */
+       .code16
+       movb    $0x2,   %ah
+       int     $0x1a
+       DATA32  jnc     gotclock
+       movl    $0x0,   %ecx
+       movl    $0x0,   %edx
+gotclock:
+       DATA32  call    EXT_C(real_to_prot)
+       .code32
+       movb    %ch,            %ah     /* Hours */
+       movb    %cl,            %al     /* Minutes */
+       imul    $0x10000,       %eax    /* Shift */
+       movb    %dh,            %ah     /* Seconds */
+       movb    %dl,            %al     /* Week */
+       popl    %ebp
+       ret
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 #endif /* STAGE1_5 */
 
 /*
diff -urpN grub-0.96/stage2/recovery.c resumo-0.96/stage2/recovery.c
--- grub-0.96/stage2/recovery.c 1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/stage2/recovery.c       2005-04-19 20:34:49.000000000 +0900
@@ -0,0 +1,949 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+ 
+#include <shared.h>
+#include <recovery.h>
+
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef SUPPORT_NETBOOT
+# define GRUB  1
+# include <etherboot.h>
+# include <nic.h>
+#endif
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+#define AREA_MAX 5                /* Area max value. */
+#define AREA_TYPE_COUNT 3         /* Area type count. */
+#define LOOP_COUNTER_MAX 100      /* Loop counter max value. */
+
+/* config define */
+#define SECTION_LOOP       "Loop"           /* Loop section name. */
+#define SECTION_AREA       "Area"           /* Area section name. */
+#define SECTION_IFCONFIG   "Ifconfig"       /* Ifconfig section name. */
+#define SECTION_MAINTE     "Mainte"         /* Mainte section name. */
+#define SECTION_NOTICE     "Notice"         /* Notification section name. */
+#define SECTION_ARP        "Arp"            /* Arp section name. */
+#define KEY_MAXCOUNT       "MaxCount"       /* Loop max count key name. */
+#define KEY_SYSTEMCOUNT    "SystemCount"    /* System count key name. */
+#define KEY_TEMPORARYCOUNT "TemporaryCount" /* Temporary count key name. */
+#define KEY_RESERVECOUNT   "ReserveCount"   /* Reserve count key name. */
+#define KEY_ENTRY          "Entry"          /* Entry number key name. */
+#define KEY_DISABLE        "Disable"        /* Disable flag key name. */
+#define KEY_AVAILABLE      "Available"      /* Available flag key name. */
+#define KEY_TIMEOUT        "Timeout"        /* Timeout key name. */
+#define KEY_RETRY          "Retry"          /* Retry key name. */
+
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+/* Request message format */
+#define CGL_REQUEST "POST RESUMO/1.0\r\n\
+Seq: %d\r\n\
+System: %d\r\n\
+Host: %s\r\n\
+Date: %s\r\n\
+Content-Length: %d\r\n\r\n"
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+struct entry_info_t
+{
+  int entry;
+  int disable;
+  int available;
+};
+
+/* config variable */
+static int loop_max_count = -1;
+static struct entry_info_t bootentry[AREA_TYPE_COUNT][AREA_MAX];
+static int area_count[AREA_TYPE_COUNT];
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef SUPPORT_NETBOOT
+extern int nic_number;
+static int sequence_no = 0;
+static int ack_timeout = 0;
+static int retry_count = 0;
+static int mainte_port = 0;
+static int notice_flg  = 0;
+static int arp_timeout = 0;
+static int arp_retry   = 0;
+static char hostname[256];
+
+/*----------------------------------------------------------------------
+ *  Structure declaration
+ *--------------------------------------------------------------------*/
+struct recover_t
+{
+  struct iphdr ip;
+  struct udphdr udp;
+  char body[256];
+};
+union m{
+    int m1 ;
+    unsigned char m2[sizeof(int)] ;
+    unsigned short m3[sizeof(short)] ;
+};
+#endif
+
+/*----------------------------------------------------------------------
+ *  Prototype declaration
+ *--------------------------------------------------------------------*/
+#ifdef SUPPORT_NETBOOT
+int getrtdate (void);
+int getrtclock (void);
+static int
+recover_protocol(int sequence, int device, int response);
+#endif
+
+static int
+recover_profile_string (char *Section, char *Key, char *Default, char *Buffer, 
int Size, char *FileName);
+
+static int
+recover_profile_int (char *Section, char *Key, int Default, char *FileName);
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+/* Read bootlist file. */
+static int
+read_boot_list(char* bootlist)
+{
+
+  char section[256];
+  int i,j;
+  const char *area_name[] = {
+    "System",
+    "Temporary",
+    "Reserve"
+  };
+
+  for(i = 0;i < AREA_TYPE_COUNT; i++)
+    {
+      for(j = 0;j < area_count[i]; j++)
+       {
+          grub_sprintf(section,"%s%d",area_name[i],j+1);
+          bootentry[i][j].entry = recover_profile_int (section, KEY_ENTRY, -1, 
bootlist);
+
+          if(0 > bootentry[i][j].entry)
+            return 0;
+
+          if(type_system == i)
+           {
+              char buf[256];
+              recover_profile_string (section, KEY_DISABLE, "", buf, 
sizeof(buf), bootlist);
+              if(!grub_strcmp(buf,"false"))
+               {
+                 bootentry[i][j].disable = 0;
+               }
+             else if(!grub_strcmp(buf,"true"))
+               {
+                  bootentry[i][j].disable = 1;
+               }
+             else
+               return 0;
+
+              recover_profile_string (section, KEY_AVAILABLE, "" , buf, 
sizeof(buf), bootlist);
+              if(!grub_strcmp(buf,"false"))
+               {
+                 bootentry[i][j].available = 0;
+               }
+             else if(!grub_strcmp(buf,"true"))
+               {
+                  bootentry[i][j].available = 1;
+               }
+             else
+               return 0;
+           }
+        }
+    }
+
+  return 1;
+
+}
+
+/* Return counter value corresponding to the entry.  */
+int
+get_counter_for_entry(int entry,enum area_type *type)
+{
+
+  int i,j;
+  for(i = 0;i < AREA_TYPE_COUNT; i++)
+    {
+      for(j = 0;j < area_count[i]; j++)
+       {
+          if (bootentry[i][j].entry == entry)
+            {
+              *type = i;
+              return (j + 1);
+           }
+        }
+    }
+  
+  return 0;
+}
+
+/* Read second sector data. */
+static int
+read_second_sector(char* buffer)
+{
+  /* Get the geometry of the boot drive (i.e. the disk which contains
+     this stage2).  */
+  if (get_diskinfo (boot_drive, &buf_geom))
+    {
+      errnum = ERR_NO_DISK;
+      return 0;
+    }
+
+  /* Load the second sector of this stage2.  */
+  if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
+    {
+      return 0;
+    }
+
+  /* Sanity check.  */
+  if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
+      || *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
+    {
+      errnum = ERR_BAD_VERSION;
+      return 0;
+    }
+    
+  return 1;
+
+}
+
+/* Write recovery counter to secound sector data. */
+static int 
+write_recovery_counter(unsigned char counter)
+{
+  char buffer[512];
+  if (! read_second_sector(buffer))
+    {
+      return 0;
+    }
+
+  int old_counter = buffer[STAGE2_RECOVERY_COUNTER];
+
+  if (old_counter != counter)
+  {
+    buffer[STAGE2_RECOVERY_COUNTER] = counter;
+    /* Save the image in the disk.  */
+    if (! rawwrite (boot_drive, install_second_sector, buffer))
+      return 0;
+  }
+
+  return 1;
+
+}
+
+/* Write loop counter to secound sector data. */
+static int
+write_loop_counter(unsigned char counter)
+{
+  char buffer[512];
+  if (! read_second_sector(buffer)) return 0;
+
+  int old_counter = buffer[STAGE2_LOOP_COUNTER];
+
+  if (old_counter != counter)
+  {
+    buffer[STAGE2_LOOP_COUNTER] = counter;
+    /* Save the image in the disk.  */
+    if (! rawwrite (boot_drive, install_second_sector, buffer))
+      {
+        return 0;
+      }
+  }
+
+  return 1;
+
+}
+
+/* Write start system entry to secound sector data. */
+static int 
+write_start_system(unsigned char entryno)
+{
+  char buffer[512];
+  if (! read_second_sector(buffer)) return 0;
+
+  int old_counter = buffer[STAGE2_START_SYSTEM];
+
+  if (old_counter != entryno)
+  {
+    buffer[STAGE2_START_SYSTEM] = entryno;
+    /* Save the image in the disk.  */
+    if (! rawwrite (boot_drive, install_second_sector, buffer))
+      return 0;
+  }
+
+  return 1;
+
+}
+
+int
+select_system(char* menulist, int num_entries)
+{
+  if (num_entries < 1)
+    {
+       return -1;
+    }
+  
+  int counter = recovery_counter; 
+
+  /* main escalation logic */
+  while (-1 < counter)
+    {
+    
+      if (counter >= area_count[type_system])
+        {
+          counter = 0;
+          loop_counter++;
+        }
+
+      if (loop_counter > loop_max_count)
+        {
+          printf("Escalation failure. Shutdown...\n");
+
+          /* initialize counter for next boot. */
+          write_recovery_counter(0);
+          write_loop_counter(0);
+              
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef SUPPORT_NETBOOT
+          if (notice_flg)
+            {
+             int retry;
+             for (retry = 0; retry < retry_count+1; retry++)
+               {
+                 if (recover_protocol (++sequence_no, 0, 1))
+                   {
+                     break;
+                   }
+//----- Start Debug -----
+//grub_printf ("!!!!!! await_reply !!!!!!!\n");
+//------ End Debug ------
+               }
+            }
+#endif
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+          /* power down.*/
+          grub_halt(0);
+
+          /* never reach here.*/
+          return -3;
+        }
+
+      counter++;
+      int cur_entry = bootentry[type_system][counter-1].entry;
+
+      if (bootentry[type_system][counter-1].available && 
!bootentry[type_system][counter-1].disable)
+       {
+          if ((-1 < cur_entry) && (cur_entry < num_entries))
+            {
+              /* replace default entry*/
+              default_entry = cur_entry;
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef SUPPORT_NETBOOT
+              if (notice_flg)
+                {
+                  recover_protocol (++sequence_no, counter, 0);
+                }
+#endif
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+              return 0;  
+            }
+/*---------- 2004/12/17 START Bug(Entry error) ----------*/
+         else
+           {
+              return -4;  
+           }
+/*----------- 2004/12/17 END Bug(Entry error) -----------*/
+       }
+    }
+  
+  return -2;
+  
+}
+
+void
+set_manual_flag(int entryno)
+{
+  if (-1 == entryno)
+    {
+      write_start_system(0);
+      return;
+    }
+
+  enum area_type type;
+  int counter = get_counter_for_entry(entryno,&type);
+
+  if ((counter == 0) || (type_system != type))
+    {
+      /* invalid system. */
+      write_start_system(0);
+      return;     
+    }
+  else
+    {
+      /* valid system.*/
+      write_start_system(entryno + 1);
+      
+      /* write counter values.*/
+      write_recovery_counter(counter);
+      write_loop_counter(loop_counter);
+
+    }
+
+}
+
+/*!!!!!!!!!! START E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!*/
+#ifdef SUPPORT_NETBOOT
+/**********************************************************************
+ *  recover_message function
+ *********************************************************************/
+static int
+recover_message(char *message)
+{
+  char *seq_str = 0;
+  char *length_str = 0;
+
+//----- Start Debug -----
+//grub_printf ("%s\n",message);
+//------ End Debug ------
+  /* Status header */
+  if (substring ("RESUMO/1.0 200 OK\r\n", message) > 0)
+    {
+      return 0;
+    }
+  message = grub_strstr (message, "\r\n") + 2;
+
+  /* Analyze header */
+  while (*message) 
+    {
+      /* Sequence number */
+      if (! grub_memcmp ("Seq:", message, sizeof ("Seq:") - 1))
+       {
+         seq_str = message + sizeof("Seq:") - 1;
+       }
+      /* Content length */
+      else if (! grub_memcmp ("Content-Length:", message, sizeof 
("Content-Length:") - 1))
+       {
+         length_str = message + sizeof("Content-Length:") - 1;
+       }
+      /* Delimiter */
+      else if (! grub_memcmp ("\r\n", message, sizeof ("\r\n") - 1))
+       {
+         break;
+       }
+      message = grub_strstr (message, "\r\n") + 2;
+    }
+
+  /* Analyze sequence */
+  if ( seq_str )
+    {
+      int val, flg;
+      for (val = flg = 0; *seq_str; seq_str++)
+       {
+         if (*seq_str >= '0' && *seq_str <= '9')
+           {
+             val = (val * 10) + *seq_str - 0x30;
+             flg = 1;
+           }
+         else if (*seq_str == ' ' || *seq_str == '\t' || *seq_str == '\r')
+           {
+             if (flg == 1 && sequence_no == val)
+               {
+                 return 1;
+               }
+           }
+         else
+           {
+             return 0;
+           }
+       }
+    }
+  return 0;
+}
+
+/**********************************************************************
+ *  recover_protocol function
+ *********************************************************************/
+static int
+recover_protocol(int sequence, int device, int response)
+{
+  struct recover_t resumo_request;
+  int length;
+  union m days;
+  union m clock;
+  char biostime[256];
+  char temp[12];
+
+  await_reply (AWAIT_QDRAIN, 0, NULL, 0);
+
+  /* Get Date And Clock */
+  days.m1 = getrtdate ();
+  clock.m1 = getrtclock ();
+  /* Year/Month */
+  if (days.m2[1] <= 9 )
+    {
+      grub_sprintf (biostime, "%x/0%x", days.m3[1], days.m2[1]);
+    }
+  else
+    {
+      grub_sprintf (biostime, "%x/%x", days.m3[1], days.m2[1]);
+    }
+  /* Day */
+  if (days.m2[0] <= 9 )
+    {
+      grub_sprintf (temp, "/0%x", days.m2[0]);
+    }
+  else
+    {
+      grub_sprintf (temp, "/%x", days.m2[0]);
+    }
+  grub_strncat(biostime, temp, sizeof(biostime));
+  /* Hours */
+  if (clock.m2[3] <= 9 )
+    {
+      grub_sprintf (temp, " 0%x", clock.m2[3]);
+    }
+  else
+    {
+      grub_sprintf (temp, " %x", clock.m2[3]);
+    }
+  grub_strncat(biostime, temp, sizeof(biostime));
+  /* Minutes */
+  if (clock.m2[2] <= 9 )
+    {
+      grub_sprintf (temp, ":0%x", clock.m2[2]);
+    }
+  else
+    {
+      grub_sprintf (temp, ":%x", clock.m2[2]);
+    }
+  grub_strncat(biostime, temp, sizeof(biostime));
+  /* Seconds */
+  if (clock.m2[1] <= 9 )
+    {
+      grub_sprintf (temp, ":0%x.000", clock.m2[1]);
+    }
+  else
+    {
+      grub_sprintf (temp, ":%x.000", clock.m2[1]);
+    }
+  grub_strncat(biostime, temp, sizeof(biostime));
+
+  /* Create send packet */
+  length = (grub_sprintf (resumo_request.body, CGL_REQUEST,
+                         sequence, device, hostname, biostime, 0)
+           + sizeof (resumo_request.ip) + sizeof (resumo_request.udp) + 1);
+//----- Start Debug -----
+//grub_printf ("%s\n",resumo_request.body);
+//------ End Debug ------
+  if (!recover_transmit (arptable[ARP_SERVER].ipaddr.s_addr, mainte_port,
+                        mainte_port, length, &resumo_request, arp_retry, 
arp_timeout))
+    {
+      return 0;
+    }
+
+  /* Response Kind */
+  if (!response) 
+    {
+      return 1;
+    }
+
+  /* Recieve timeout setting */
+  long timeout;
+  timeout = rfc2131_sleep_interval (ack_timeout, 0);
+  if (await_reply (AWAIT_TFTP, mainte_port, NULL, timeout))
+    {
+      struct recover_t *resumo_response;
+      resumo_response = (struct recover_t *) &nic.packet[ETH_HLEN];
+      return recover_message(resumo_response->body);
+    }
+  return 0;
+}
+#endif
+
+/**********************************************************************
+ *  recover_profile_int function
+ *  The recover_profile_int function retrieves an integer associated
+ *  with a key in the specified section of an initialization file.
+ *********************************************************************/
+static int
+recover_profile_int (char *Section, char *Key, int Default, char *FileName)
+{
+  /* Parameter check */
+  if (Section == 0 || Key == 0 || FileName == 0)
+    return Default;
+  /* Config file open */
+  if (! grub_open (FileName))
+    {
+/*---------- 2004/12/17 START Bug(Command mode) ----------*/
+      errnum = 0;
+/*----------- 2004/12/17 END Bug(Command mode) -----------*/
+      return Default;
+    }
+  char buf[256];
+  int eof = 1;
+  int flg = 0;
+  int val = Default;
+  while (eof)
+    {
+      int len = 0;
+      char c;
+      /* Line parsing */
+      while ( (eof = grub_read (&c , 1)) )
+       {
+         if (c == '\n') break;
+         if (c == ' '||c == '\t') continue;
+         buf[len++] = c;
+       }
+      buf[len] = 0;
+      if (len == 0) continue;
+      /* Section analyze */
+      if (buf[0] == '[' && buf[len-1] == ']')
+       {
+         buf[len-1] = 0;
+         if (! grub_strcmp(&buf[1], Section))
+           flg = 1;
+         else
+           flg = 0;
+         continue;
+       }
+      /* Key analyze */
+      if (flg == 1)
+       {
+         c = grub_strlen (Key);
+         for (len = 0; len < c; len++)
+           {
+             if ( buf[len] != Key[len] ) break;
+           }
+         if (c != len) continue;
+         if (buf[len++] != '=') continue;
+         c = grub_strlen (buf);
+         if (buf[len] == '-')
+           {
+             flg = -1;
+             len++;
+           }
+         else
+           flg = 1;
+         for (val = 0; len < c; len++)
+           {
+             if (buf[len] >= '0' && buf[len] <= '9')
+               {
+                 val = (val * 10) + ((buf[len] - 0x30) * flg);
+               }
+             else
+               {
+                 val = Default;
+                 break;
+               }
+           }
+         break ;
+       }
+    }
+  grub_close ();
+  return val;
+}
+
+/**********************************************************************
+ *  recover_profile_string
+ *  The recover_profile_string function retrieves a string from the 
+ *  specified section in an initialization file.
+ *********************************************************************/
+static int
+recover_profile_string (char *Section, char *Key, char *Default, char *Buffer, 
int Size, char *FileName)
+{
+  /* Buffer size check */
+  if (Size <= 0)
+    return 0;
+  grub_strcpy (Buffer, Default);
+  /* Parameter check */
+  if (Section == 0 || Key == 0 || FileName == 0)
+    return grub_strlen (Buffer);
+  /* Config file open */
+  if (! grub_open (FileName))
+    {
+/*---------- 2004/12/17 START Bug(Command mode) ----------*/
+      errnum = 0;
+/*----------- 2004/12/17 END Bug(Command mode) -----------*/
+      return grub_strlen (Default);
+    }
+  char buf[256];
+  int eof = 1;
+  int flg = 0;
+  while (eof)
+    {
+      int len = 0;
+      char c;
+      /* Line parsing */
+      while ( (eof = grub_read (&c , 1)) )
+       {
+         if (c == '\n') break;
+         if (c == ' '||c == '\t') continue;
+         buf[len++] = c;
+       }
+      buf[len] = 0;
+      if (len == 0) continue;
+      /* Section analyze */
+      if (buf[0] == '[' && buf[len-1] == ']')
+       {
+         buf[len-1] = 0;
+         if (! grub_strcmp(&buf[1], Section))
+           flg = 1;
+         else
+           flg = 0;
+         continue;
+       }
+      /* Key analyze */
+      if (flg == 1)
+       {
+         c = grub_strlen (Key);
+         for (len = 0; len < c; len++)
+           {
+             if (buf[len] != Key[len]) break;
+           }
+         if (c != len) continue;
+         if (buf[len++] != '=') continue;
+         grub_strcpy(Buffer, &buf[len]);
+         break ;
+       }
+    }
+  grub_close ();
+  return grub_strlen (Buffer);
+}
+
+/**********************************************************************
+ *  recover_initialization function
+ *********************************************************************/
+int
+recover_initialization ( void )
+{
+  /* Create config filename (system.conf) */
+  /* Create bootlist filename (boot.lst) */
+  char  SysConf[256];
+  char  BootList[256];
+  grub_strcpy(SysConf, config_file);
+  int i ;
+  for ( i = grub_strlen (SysConf); i > 0 ; i--)
+    {
+      if (SysConf[i] == '/' )
+        {
+          SysConf[i] = 0 ;
+          break ;
+        }
+    }
+
+  grub_strcpy(BootList, SysConf);
+  grub_strncat(BootList, "/boot.lst", sizeof(BootList));
+  grub_strncat (SysConf, "/conf/system.conf", sizeof (SysConf));
+
+  /* Area count*/
+  area_count[type_system] = recover_profile_int (SECTION_AREA, 
KEY_SYSTEMCOUNT, -1, SysConf);
+  area_count[type_temporary] = recover_profile_int (SECTION_AREA, 
KEY_TEMPORARYCOUNT, -1, SysConf);
+  area_count[type_reserve] = recover_profile_int (SECTION_AREA, 
KEY_RESERVECOUNT, -1, SysConf);
+ 
+  if ((2 > area_count[type_system]) ||
+      (0 > area_count[type_temporary])||
+      (0 > area_count[type_reserve]) ||
+      (AREA_MAX < area_count[type_system]) ||
+      (AREA_MAX < area_count[type_temporary]) ||
+      (AREA_MAX < area_count[type_reserve]))
+    {
+      return 1;
+    }
+
+  /* Loop counter */
+  loop_max_count = recover_profile_int (SECTION_LOOP, KEY_MAXCOUNT, -1, 
SysConf);
+  /*---------- 2004/12/14 START Bug(shutdown) ----------*/
+  //  if(-1 == loop_max_count)
+  if((0 >  loop_max_count) ||
+     (loop_max_count > LOOP_COUNTER_MAX))
+  /*---------- 2004/12/14 END Bug(shutdown) ----------*/
+    return 1;
+
+
+  /* read setting from file */
+  if (! read_boot_list(BootList))
+    {
+      return 1;
+    }
+
+  /* bootable check */
+  int counter;
+  int bootable = 0;
+  for ( counter = 0; counter < area_count[type_system] ; counter++)
+    {
+      if (bootentry[type_system][counter].available && 
+          !bootentry[type_system][counter].disable)
+        {
+          bootable = 1;
+          break;
+        }
+    }
+    
+  if (! bootable)
+    {
+      return 1;
+    }
+
+#ifdef SUPPORT_NETBOOT
+  char Value[8];
+  /* Meaage notification flag (true/false) */
+  recover_profile_string (SECTION_NOTICE, KEY_DISABLE, "true", Value,
+                         sizeof (Value), SysConf);
+  if ( grub_strcmp (Value, "false"))
+    {
+      return 0;
+    }
+
+  /* Select device(NIC) number (0-)*/
+  nic_number = recover_profile_int (SECTION_IFCONFIG, "Device", 1, SysConf);
+  if (nic_number < 0)
+    {
+      return 0;
+    }
+
+  /* Setup ethernet card */
+  if (! eth_probe ( ) )
+    {
+      grub_printf ("No ethernet card found.\n");
+/*---------- 2004/12/14 START Bug(Command mode) ----------
+      errnum = ERR_DEV_VALUES;
+----------- 2004/12/14 END Bug(Command mode) -----------*/
+      return 0;
+    }
+
+  /* Arp timeout */
+  arp_timeout = recover_profile_int (SECTION_ARP, KEY_TIMEOUT, 1, SysConf);
+  if (arp_timeout < 0)
+    {
+      arp_timeout = 0;
+    }
+
+  /* Arp retry count */
+  arp_retry = recover_profile_int (SECTION_ARP, KEY_RETRY, 1, SysConf);
+  if (arp_retry < 0)
+    {
+      arp_retry = 0;
+    }
+
+  /* DHCP Support (true/false) */
+  recover_profile_string (SECTION_IFCONFIG, "Dhcp", "false", Value,
+                         sizeof (Value), SysConf);
+  if (! grub_strcmp (Value, "true"))
+    {
+      if (! recover_bootp (arp_retry, arp_timeout))
+        {
+/*---------- 2004/12/14 START Bug(Command mode) ----------
+          errnum = ERR_DEV_VALUES;
+----------- 2004/12/14 END Bug(Command mode) -----------*/
+          return 0;
+        }
+    }
+  else
+    {
+      /* Local address */
+      char     IPAddr[16];
+      recover_profile_string (SECTION_IFCONFIG, "Address", "", IPAddr,
+                             sizeof (IPAddr), SysConf);
+
+      /* Subnet mask */
+      char     Mask[16];
+      recover_profile_string (SECTION_IFCONFIG, "Mask", "255.255.255.0", Mask,
+                             sizeof (Mask), SysConf);
+
+      /* Default gateway */
+      char     GateWay[16];
+      recover_profile_string (SECTION_IFCONFIG, "Gateway", "", GateWay,
+                             sizeof (GateWay), SysConf);
+      if (! grub_strcmp (GateWay, ""))
+       {
+         if (! ifconfig (IPAddr, Mask, 0, 0))
+           {
+/*---------- 2004/12/14 START Bug(Command mode) ----------
+              errnum = ERR_BAD_ARGUMENT;
+----------- 2004/12/14 END Bug(Command mode) -----------*/
+             return 0;
+           }
+       }
+      else
+       {
+         if (! ifconfig (IPAddr, Mask, GateWay, 0))
+           {
+/*---------- 2004/12/14 START Bug(Command mode) ----------
+              errnum = ERR_BAD_ARGUMENT;
+----------- 2004/12/14 END Bug(Command mode) -----------*/
+             return 0;
+           }
+       }
+    }
+
+  /* Maintenance server address */
+  char Server[16];
+  recover_profile_string (SECTION_MAINTE, "Server", "", Server,
+                         sizeof (Server), SysConf);
+
+  if (! ifconfig (0, 0, 0, Server))
+    {
+/*---------- 2004/12/14 START Bug(Command mode) ----------
+      errnum = ERR_BAD_ARGUMENT;
+----------- 2004/12/14 END Bug(Command mode) -----------*/
+      return 0;
+    }
+//----- Start Debug -----
+//print_network_configuration ();
+//------ End Debug ------
+  notice_flg = 1;
+  /* Local host name */
+  char Local[16];
+  union m m;
+  m.m1 = arptable[ARP_SERVER].ipaddr.s_addr ;
+  grub_sprintf (Local, "%d.%d.%d.%d", m.m2[0], m.m2[1], m.m2[2],m.m2[3]);
+  recover_profile_string (SECTION_IFCONFIG, "Hostname", Local, hostname,
+                         sizeof (hostname), SysConf);
+  /* Maintenance server port number */
+  mainte_port = recover_profile_int (SECTION_MAINTE, "Port", 10510, SysConf);
+  if (mainte_port <= 0 || mainte_port > 65535)
+    {
+      mainte_port = 10510;
+    }
+
+  /* Ack timeout */
+  ack_timeout = recover_profile_int (SECTION_MAINTE, KEY_TIMEOUT, 10, SysConf);
+  if (ack_timeout < 0)
+    {
+      ack_timeout = 0;
+    }
+  else
+    {
+      ack_timeout *= 18;
+    }
+
+  /* Send retry count */
+  retry_count = recover_profile_int (SECTION_MAINTE, KEY_RETRY, 1, SysConf);
+  if (retry_count < 0)
+    {
+      retry_count = 0;
+    }
+#endif
+
+  return 0;
+}
+/*!!!!!!!!!!! END E1000/TG3 (GRUB-CGL) Addition !!!!!!!!!!!*/
diff -urpN grub-0.96/stage2/recovery.h resumo-0.96/stage2/recovery.h
--- grub-0.96/stage2/recovery.h 1970-01-01 09:00:00.000000000 +0900
+++ resumo-0.96/stage2/recovery.h       2005-04-19 20:34:49.000000000 +0900
@@ -0,0 +1,44 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _GRUB_RECOVERY_H_
+#define _GRUB_RECOVERY_H_
+
+enum area_type
+  {
+    type_system = 0,
+    type_temporary,
+    type_reserve
+  };
+
+/* Select boot system entry. */
+int select_system(char* menulist,int num_entries);
+
+/* Write manual flag. */
+void set_manual_flag(int entryno);
+
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+int get_counter_for_entry(int entry,enum area_type *area);
+
+/* Get system config file. */
+int recover_initialization( void ) ;
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
+#endif /* _GRUB_RECOVERY_H_ */
diff -urpN grub-0.96/stage2/shared.h resumo-0.96/stage2/shared.h
--- grub-0.96/stage2/shared.h   2004-06-20 01:40:09.000000000 +0900
+++ resumo-0.96/stage2/shared.h 2005-04-19 20:34:49.000000000 +0900
@@ -2,6 +2,7 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 1999,2000,2001,2002,2003,2004  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -198,7 +199,10 @@ extern char *grub_scratch_mem;
 #define STAGE2_SAVED_ENTRYNO   0xc
 #define STAGE2_STAGE2_ID       0x10
 #define STAGE2_FORCE_LBA       0x11
-#define STAGE2_VER_STR_OFFS    0x12
+#define STAGE2_RECOVERY_COUNTER        0x12
+#define STAGE2_LOOP_COUNTER    0x13
+#define STAGE2_START_SYSTEM    0x14
+#define STAGE2_VER_STR_OFFS    0x15
 
 /* Stage 2 identifiers */
 #define STAGE2_ID_STAGE2               0
@@ -556,6 +560,8 @@ extern struct apm_info apm_bios_info;
 extern unsigned long boot_part_addr;
 extern int saved_entryno;
 extern unsigned char force_lba;
+extern unsigned char recovery_counter;
+extern unsigned char loop_counter;
 extern char version_string[];
 extern char config_file[];
 extern unsigned long linux_text_len;
diff -urpN grub-0.96/stage2/stage2.c resumo-0.96/stage2/stage2.c
--- grub-0.96/stage2/stage2.c   2004-07-25 03:53:47.000000000 +0900
+++ resumo-0.96/stage2/stage2.c 2005-04-19 20:37:07.000000000 +0900
@@ -1,6 +1,7 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
  *  Copyright (C) 2000,2001,2002,2004  Free Software Foundation, Inc.
+ *  Copyright (C) 2004-2005 NTT Corporation
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -22,6 +23,13 @@
 
 grub_jmp_buf restart_env;
 
+#ifndef GRUB_UTIL
+#include <recovery.h>
+#endif
+
+static int restart_flag;
+static int resumo_init;
+
 #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
 
 # if defined(PRESET_MENU_STRING)
@@ -125,6 +133,43 @@ print_entry (int y, int highlight, char 
     current_term->setcolorstate (COLOR_STATE_STANDARD);
 }
 
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+/* Print an entry in a line of the menu box.  */
+static void
+print_entry2 (int menu,int entryno, int y, int highlight, char *entry)
+{
+
+#ifndef GRUB_UTIL
+/*----------- 2004/12/17 START Bug(Entry error) -----------*/
+//  if(menu && resumo_init)
+  if(menu && resumo_init && ! restart_flag)
+/*------------ 2004/12/17 END Bug(Entry error) ------------*/
+    {
+      enum area_type type;
+      int cnt = get_counter_for_entry(entryno , &type);
+      char* labelname[] = {"SYS","TMP","RSV"};
+
+      if ((0 != cnt) && (0 != grub_strlen(entry)))
+        {
+          char entryname[256];
+          int len;
+
+          if(entryno == default_entry)
+            len = sprintf(entryname,"[%s%d]*",labelname[type],cnt);
+          else
+            len = sprintf(entryname,"[%s%d] ",labelname[type],cnt);
+
+          strcpy(entryname + len ,entry);
+          print_entry(y,highlight,entryname);
+          return;
+        }
+    }
+#endif
+
+  print_entry(y,highlight,entry);
+}
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 /* Print entries in the menu box.  */
 static void
 print_entries (int y, int size, int first, int entryno, char *menu_entries)
@@ -161,6 +206,50 @@ print_entries (int y, int size, int firs
   gotoxy (74, y + entryno + 1);
 }
 
+/*!!!!!!!!!! START (GRUB-CGL) Addition !!!!!!!!!!*/
+/* Print entries in the menu box.  */
+static void
+print_entries2 (int menu,int y, int size, int first, int entryno, char 
*menu_entries)
+{
+  if (!menu)
+    {
+      print_entries(y,size,first,entryno,menu_entries);
+      return;
+    }
+
+  int i;
+  
+  gotoxy (77, y + 1);
+
+  if (first)
+    grub_putchar (DISP_UP);
+  else
+    grub_putchar (' ');
+
+  menu_entries = get_entry (menu_entries, first, 0);
+
+  for (i = 0; i < size; i++)
+    {
+      print_entry2 (1,first + i,y + i + 1, entryno == i, menu_entries);
+
+      while (*menu_entries)
+       menu_entries++;
+
+      if (*(menu_entries - 1))
+       menu_entries++;
+    }
+
+  gotoxy (77, y + size);
+
+  if (*menu_entries)
+    grub_putchar (DISP_DOWN);
+  else
+    grub_putchar (' ');
+
+  gotoxy (74, y + entryno + 1);
+}
+/*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
+
 static void
 print_entries_raw (int size, int first, char *menu_entries)
 {
@@ -331,7 +420,10 @@ restart:
       if (current_term->flags & TERM_DUMB)
        grub_printf ("\n\nThe selected entry is %d ", entryno);
       else
-       print_entries (3, 12, first_entry, entryno, menu_entries);
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//     print_entries (3, 12, first_entry, entryno, menu_entries);
+       print_entries2 (NULL != config_entries, 3, 12, first_entry, entryno, 
menu_entries);
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
     }
 
   /* XX using RT clock now, need to initialize value */
@@ -408,12 +500,18 @@ restart:
                {
                  if (entryno > 0)
                    {
-                     print_entry (4 + entryno, 0,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                   print_entry (4 + entryno, 0,
+                     print_entry2 (config_entries != NULL,first_entry + 
entryno,4 + entryno, 0,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                   get_entry (menu_entries,
                                              first_entry + entryno,
                                              0));
                      entryno--;
-                     print_entry (4 + entryno, 1,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                   print_entry (4 + entryno, 1,
+                     print_entry2 (config_entries != NULL,first_entry + 
entryno,4 + entryno, 1,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                   get_entry (menu_entries,
                                              first_entry + entryno,
                                              0));
@@ -421,7 +519,10 @@ restart:
                  else if (first_entry > 0)
                    {
                      first_entry--;
-                     print_entries (3, 12, first_entry, entryno,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                   print_entries (3, 12, first_entry, entryno,
+                     print_entries2 (NULL != config_entries, 3, 12, 
first_entry, entryno,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                     menu_entries);
                    }
                }
@@ -435,12 +536,18 @@ restart:
                {
                  if (entryno < 11)
                    {
-                     print_entry (4 + entryno, 0,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                   print_entry (4 + entryno, 0,
+                     print_entry2 (config_entries != NULL,first_entry + 
entryno,4 + entryno, 0,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                   get_entry (menu_entries,
                                              first_entry + entryno,
                                              0));
                      entryno++;
-                     print_entry (4 + entryno, 1,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                   print_entry (4 + entryno, 1,
+                     print_entry2 (config_entries != NULL,first_entry + 
entryno,4 + entryno, 1,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                   get_entry (menu_entries,
                                              first_entry + entryno,
                                              0));
@@ -448,7 +555,10 @@ restart:
                else if (num_entries > 12 + first_entry)
                  {
                    first_entry++;
-                   print_entries (3, 12, first_entry, entryno, menu_entries);
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                 print_entries (3, 12, first_entry, entryno, menu_entries);
+                   print_entries2 (NULL != config_entries, 3, 12, first_entry, 
entryno, menu_entries);
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                  }
                }
            }
@@ -463,7 +573,10 @@ restart:
                  if (entryno < 0)
                    entryno = 0;
                }
-             print_entries (3, 12, first_entry, entryno, menu_entries);
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//           print_entries (3, 12, first_entry, entryno, menu_entries);
+             print_entries2 (NULL != config_entries, 3, 12, first_entry, 
entryno, menu_entries);
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
            }
          else if (c == 3)
            {
@@ -476,7 +589,10 @@ restart:
                    first_entry = 0;
                  entryno = num_entries - first_entry - 1;
                }
-             print_entries (3, 12, first_entry, entryno, menu_entries);
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//           print_entries (3, 12, first_entry, entryno, menu_entries);
+             print_entries2 (NULL != config_entries, 3, 12, first_entry, 
entryno, menu_entries);
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
            }
 
          if (config_entries)
@@ -489,7 +605,10 @@ restart:
              if ((c == 'd') || (c == 'o') || (c == 'O'))
                {
                  if (! (current_term->flags & TERM_DUMB))
-                   print_entry (4 + entryno, 0,
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                 print_entry (4 + entryno, 0,
+                   print_entry2 (config_entries != NULL,first_entry + entryno, 
4 + entryno, 0,
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                                 get_entry (menu_entries,
                                            first_entry + entryno,
                                            0));
@@ -549,7 +668,10 @@ restart:
                      grub_printf ("\n");
                    }
                  else
-                   print_entries (3, 12, first_entry, entryno, menu_entries);
+/*!!!!!!!!!! START (GRUB-CGL) Update !!!!!!!!!!*/
+//                 print_entries (3, 12, first_entry, entryno, menu_entries);
+                   print_entries2 (NULL != config_entries, 3, 12, first_entry, 
entryno, menu_entries);
+/*!!!!!!!!!!! END (GRUB-CGL) Update !!!!!!!!!!!*/
                }
 
              cur_entry = menu_entries;
@@ -729,6 +851,14 @@ restart:
       /* Set CURRENT_ENTRYNO for the command "savedefault".  */
       current_entryno = first_entry + entryno;
       
+#ifndef GRUB_UTIL
+      /* Add system recovery. */
+      if (! restart_flag && config_entries && resumo_init)
+       {
+          set_manual_flag (current_entryno);
+       }
+#endif /* GRUB_UTIL */
+
       if (run_script (cur_entry, heap))
        {
          if (fallback_entryno >= 0)
@@ -849,7 +979,17 @@ cmain (void)
     }
   
   /* Initialize the environment for restarting Stage 2.  */
-  grub_setjmp (restart_env);
+//  grub_setjmp (restart_env);
+   restart_flag = grub_setjmp (restart_env);
+
+ #ifndef GRUB_UTIL
+   if (! restart_flag)
+     {
+       resumo_init = !recover_initialization ();
+       set_manual_flag (-1);
+     }
+ #endif /* GRUB_UTIL */
+ /*!!!!!!!!!!! END (GRUB-CGL) Addition !!!!!!!!!!!*/
   
   /* Initialize the kill buffer.  */
   *kill_buf = 0;
@@ -1058,6 +1198,15 @@ cmain (void)
        }
       else
        {
+
+#ifndef GRUB_UTIL
+          /* Add system recovery. */
+         if (! restart_flag && resumo_init)
+            {
+              resumo_init = !select_system (config_file, num_entries);
+            }
+#endif
+       
          /* Run menu interface.  */
          run_menu (menu_entries, config_entries, num_entries,
                    menu_entries + menu_len, default_entry);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]