diff -u -r grub-0.5.97/netboot/config.c grub-0.5.97.new/netboot/config.c
--- grub-0.5.97/netboot/config.c	Fri Feb  2 21:21:18 2001
+++ grub-0.5.97.new/netboot/config.c	Mon Feb 26 14:20:28 2001
@@ -91,6 +91,8 @@
 #ifdef	INCLUDE_EEPRO100
 	{ PCI_VENDOR_ID_INTEL,		PCI_DEVICE_ID_INTEL_82557,
 		"Intel EtherExpressPro100", 0, 0, 0},
+	{ PCI_VENDOR_ID_INTEL,		PCI_DEVICE_ID_INTEL_82820FW_4,
+		"Intel EtherExpressPro100", 0, 0, 0},
 #endif
 #ifdef	INCLUDE_EPIC100
 	{ PCI_VENDOR_ID_SMC,		PCI_DEVICE_ID_SMC_EPIC100,
@@ -190,6 +192,7 @@
 # endif /* INCLUDE_3C595 */
 # ifdef	INCLUDE_EEPRO100
   { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82557,     eepro100_probe },
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82820FW_4, eepro100_probe },
 # endif /* INCLUDE_EEPRO100 */
 # ifdef	INCLUDE_EPIC100
   { PCI_VENDOR_ID_SMC,      PCI_DEVICE_ID_SMC_EPIC100,     epic100_probe },
diff -u -r grub-0.5.97/netboot/eepro100.c grub-0.5.97.new/netboot/eepro100.c
--- grub-0.5.97/netboot/eepro100.c	Sat Apr 22 10:17:09 2000
+++ grub-0.5.97.new/netboot/eepro100.c	Mon Feb 26 21:20:42 2001
@@ -125,7 +125,7 @@
 };
 
 
-static int read_eeprom(int location);
+static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
 static void udelay (int val);
 void hd (void *where, int n);
 
@@ -140,10 +140,11 @@
 #define EE_SHIFT_CLK    0x01    /* EEPROM shift clock. */
 #define EE_CS           0x02    /* EEPROM chip select. */
 #define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
-#define EE_WRITE_0      0x01
-#define EE_WRITE_1      0x05
 #define EE_DATA_READ    0x08    /* EEPROM chip data out. */
 #define EE_ENB          (0x4800 | EE_CS)
+#define EE_WRITE_0      0x4802
+#define EE_WRITE_1      0x4806
+#define EE_OFFSET       SCBeeprom
 
 
 /* Delay between EEPROM clock transitions.
@@ -153,9 +154,7 @@
                                      { __SLOW_DOWN_IO; }} while (0)
 
 /* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD    (5 << 6)
-#define EE_READ_CMD     (6 << 6)
-#define EE_ERASE_CMD    (7 << 6)
+#define EE_READ_CMD     (6)
 
 /* The SCB accepts the following controls for the Tx and Rx units: */
 #define  CU_START       0x0010
@@ -291,7 +290,7 @@
 
 #define TIME_OUT 1000000
 
-static unsigned short eeprom [0x40];
+static unsigned short eeprom [0x100];
 
 
 /***********************************************************************/
@@ -345,44 +344,33 @@
 }
 
 
-/* Support function: read_eeprom
- * reads a value from the eeprom at a specified location.
- * Arguments: location:  address of the location to read from the eeprom.
- * returns:   value read from eeprom at location.
- */
-static int read_eeprom(int location)
+/* The fixes for the code were kindly provided by Dragan Stancevic
+   <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
+   access timing.
+   The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
+   interval for serial EEPROM.  However, it looks like that there is an
+   additional requirement dictating larger udelay's in the code below.
+   2000/05/24  SAW */
+static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
 {
-        int i;
-        unsigned short retval = 0;
-        int ee_addr = ioaddr + SCBeeprom;
-        int read_cmd = location | EE_READ_CMD;
-
-        outw(EE_ENB & ~EE_CS, ee_addr);
-        outw(EE_ENB, ee_addr);
-
-        /* Shift the read command bits out. */
-        for (i = 10; i >= 0; i--) {
-                short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-                outw(EE_ENB | dataval, ee_addr);
-                eeprom_delay(100);
-                outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-                eeprom_delay(150);
-                outw(EE_ENB | dataval, ee_addr);        /* Finish EEPROM a clock tick. */
-                eeprom_delay(250);
-        }
-        outw(EE_ENB, ee_addr);
-
-        for (i = 15; i >= 0; i--) {
-                outw(EE_ENB | EE_SHIFT_CLK, ee_addr);
-                eeprom_delay(100);
-                retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
-                outw(EE_ENB, ee_addr);
-                eeprom_delay(100);
-        }
-
-        /* Terminate the EEPROM access. */
-        outw(EE_ENB & ~EE_CS, ee_addr);
-        return retval;
+  unsigned retval = 0;
+  long ee_addr = ioaddr + SCBeeprom;
+
+  outw(EE_ENB, ee_addr); udelay(2);
+  outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
+
+  /* Shift the command bits out. */
+  do {
+	short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+	outw(dataval, ee_addr); udelay(2);
+	outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
+	retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
+  } while (--cmd_len >= 0);
+  outw(EE_ENB, ee_addr); udelay(2);
+
+  /* Terminate the EEPROM access. */
+  outw(EE_ENB & ~EE_CS, ee_addr);
+  return retval;
 }
 
 
@@ -557,11 +545,25 @@
 
   ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
 
-  /* Ok. Got one. Read the eeprom. */
-  for (j = 0, i = 0; i < 0x40; i++) {
-	value = read_eeprom(i);
-	eeprom[i] = value;
-	sum += value;
+  {
+	int read_cmd, ee_size;
+
+	/* Use IO only to avoid postponed writes and satisfy EEPROM timing
+	   requirements. */
+	if ((do_eeprom_cmd(ioaddr, EE_READ_CMD << 24, 27) & 0xffe0000)
+		== 0xffe0000) {
+	  ee_size = 0x100;
+	  read_cmd = EE_READ_CMD << 24;
+	} else {
+	  ee_size = 0x40;
+	  read_cmd = EE_READ_CMD << 22;
+	}
+
+	for (i = 0; i < ee_size; i++) {
+	  u16 value = do_eeprom_cmd(ioaddr, read_cmd | (i << 16), 27);
+	  eeprom[i] = value;
+	  sum += value;
+	}
   }
 
 	/* From Matt Hortman <mbhortman@acpthinclient.com> */
diff -u -r grub-0.5.97/netboot/pci.h grub-0.5.97.new/netboot/pci.h
--- grub-0.5.97/netboot/pci.h	Sun Jul 30 04:22:54 2000
+++ grub-0.5.97.new/netboot/pci.h	Mon Feb 26 21:13:35 2001
@@ -120,6 +120,7 @@
 #define PCI_DEVICE_ID_3COM_3C905C_TXM	0x9200
 #define PCI_VENDOR_ID_INTEL		0x8086
 #define PCI_DEVICE_ID_INTEL_82557	0x1229
+#define PCI_DEVICE_ID_INTEL_82820FW_4	0x2449
 #define PCI_VENDOR_ID_AMD		0x1022
 #define PCI_DEVICE_ID_AMD_LANCE		0x2000
 #define PCI_VENDOR_ID_SMC_1211          0x1113
