bug-grub
[Top][All Lists]
Advanced

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

Re: Patch for EtherExpressPro100


From: Christoph Plattner
Subject: Re: Patch for EtherExpressPro100
Date: Thu, 01 Mar 2001 00:54:01 +0100

Hello GRUB people,

        now I have done the patch for the eepro100 stuff.
Two points changed:
(1)     Added support for i82559ER (not tested here @home, as I have
        no 559ER card, but I tested the modified chip ID in the company
        on a real 559ER
(2)     Changed access to EEPROM to avoid failures on modern 82559 cards.
        This feature is tested on a moder i82559 card (Compaq/Intel NIC).

Now the eepro100 driver is in sync with etherboot (release 4.7.18), but 
I used the "old" method of TIMEOUT (it is a tested merge of the two
versions).

Again, I think we should speek about the future strategy to be able to
really copy in the current etherboot-drivers only.

Here is the patch ...

Cheers
        Christoph P.




Christoph Plattner wrote:
> 
> Ok, I did the patch already using the old TIMEOUT method (used before in
> etherboot and GRUB) but the new routines handling the EEPROM access,
> etc.
> 
> At the moment my time is limited to do that in a "releasable" way, but I
> will try in the next few days.
> 
> Cheers
>         Christoph Plattner
> 
> OKUJI Yoshinori wrote:
> >
> > From: OKUJI Yoshinori <address@hidden>
> > Subject: Re: Patch for EtherExpressPro100
> > Date: Wed, 28 Feb 2001 18:44:00 +0900
> >
> > > Ok, then I'll update only the eepro100 driver, as I have too little
> > > time to update all the drivers.
> >
> > Ah, I reminded myself of that the most difficult part to update a
> > newer version of Etherboot was eepro100, because it used the
> > low-overhead timer routine. Because it is obvious that I cannot have
> > time to investigate the solution for porting the routine to GRUB for
> > now, I'd like to leave the work to one who is willing to do
> > that. Sorry.
> >
> > (I guess that I won't have spare time to work on really new things, at
> > least in two weeks.)
> >
> > Okuji
> >
> > _______________________________________________
> > Bug-grub mailing list
> > address@hidden
> > http://mail.gnu.org/mailman/listinfo/bug-grub
> 
> --
> -------------------------------------------------------------------------
> private:        address@hidden
> company:        address@hidden
> 
> _______________________________________________
> Bug-grub mailing list
> address@hidden
> http://mail.gnu.org/mailman/listinfo/bug-grub

-- 
-------------------------------------------------------------------------
private:        address@hidden
company:        address@hidden
Index: ChangeLog
===================================================================
RCS file: /cvs/grub/ChangeLog,v
retrieving revision 1.405
diff -u -r1.405 ChangeLog
--- ChangeLog   2001/02/28 11:19:39     1.405
+++ ChangeLog   2001/02/28 23:46:48
@@ -1,3 +1,19 @@
+2001-03-01    <address@hidden>
+
+       * netboot/eepro100.c: merged all changes on base of etherboot-
+       4.7.18 but with restrictions:
+          (1) changes in newlines and comments in untouched parts
+              are not changes (I want only change a minimum)
+          (2) I used the "olt" TIMEOUT method without timer control.
+
+2001-02-28    <address@hidden>
+
+       * netboot/config.c (PCI_NIC): added 82559ER with eepro100_probe
+       added 82559ER to PCI network device list
+
+       * netboot/pci.h (PCI_DEVICE_ID_INTEL_82559ER): added chip ID
+       for i82559ER version (subset chip of i82559).
+
 2001-02-28  OKUJI Yoshinori  <address@hidden>
 
        From HASEGAWA Tomoki <address@hidden>:
Index: netboot/config.c
===================================================================
RCS file: /cvs/grub/netboot/config.c,v
retrieving revision 1.10
diff -u -r1.10 config.c
--- netboot/config.c    2001/02/02 12:21:18     1.10
+++ netboot/config.c    2001/02/28 23:46:49
@@ -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_82559ER,
+               "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_82559ER,   eepro100_probe },
 # endif /* INCLUDE_EEPRO100 */
 # ifdef        INCLUDE_EPIC100
   { PCI_VENDOR_ID_SMC,      PCI_DEVICE_ID_SMC_EPIC100,     epic100_probe },
Index: netboot/eepro100.c
===================================================================
RCS file: /cvs/grub/netboot/eepro100.c,v
retrieving revision 1.3
diff -u -r1.3 eepro100.c
--- netboot/eepro100.c  2000/04/22 01:17:09     1.3
+++ netboot/eepro100.c  2001/02/28 23:46:49
@@ -125,8 +125,7 @@
 };
 
 
-static int read_eeprom(int location);
-static void udelay (int val);
+static int do_eeprom_cmd(int cmd, int cmd_len);
 void hd (void *where, int n);
 
 
@@ -140,22 +139,20 @@
 #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_WRITE_0      0x4802
+#define EE_WRITE_1      0x4806
 #define EE_ENB          (0x4800 | EE_CS)
 
 
 /* Delay between EEPROM clock transitions.
    This is a "nasty" timing loop, but PC compatible machines are defined
    to delay an ISA compatible period for the SLOW_DOWN_IO macro.  */
-#define eeprom_delay(nanosec)   do { int _i = 3; while (--_i > 0) \
+#define udelay(nanosec)   do { int _i = 3; while (--_i > 0) \
                                      { __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,9 +288,7 @@
 
 #define TIME_OUT 1000000
 
-static unsigned short eeprom [0x40];
 
-
 /***********************************************************************/
 /*                       Locally used functions                        */
 /***********************************************************************/
@@ -343,46 +338,34 @@
   } while (! (val & 0x10000000));
   return val & 0xffff;
 }
-
 
-/* 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)
-{
-        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;
+/* The fixes for the code were kindly provided by Dragan Stancevic
+   <address@hidden> 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(int cmd, int cmd_len)
+{
+       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;
 }
 
 
@@ -500,11 +483,8 @@
 
 static int eepro100_poll(struct nic *nic)
 {
-  int to;
-
-  to = TIME_OUT;
-  while (!ACCESS(rxfd)status && --to)
-    /* Wait */;
+  if (!ACCESS(rxfd)status)
+    return 0;
 
   /* Ok. We got a packet. Now restart the reciever.... */
   ACCESS(rxfd)status = 0;
@@ -513,7 +493,6 @@
   outw(INT_MASK | RX_START, ioaddr + SCBCmd);
   wait_for_cmd_done(ioaddr + SCBCmd);
 
-  if (to) {
 #ifdef DEBUG
     printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
 #endif
@@ -522,13 +501,14 @@
 #ifdef DEBUG
     hd (nic->packet, 0x30);
 #endif
-    return 1;
-  } else
-    return 0;
+  return 1;
 }
 
 static void eepro100_disable(struct nic *nic)
 {
+    /* See if this PartialReset solves the problem with interfering with
+       kernel operation after Etherboot hands over. - Ken 20001102 */
+    outl(2, ioaddr + SCBPort);
 }
 
 /* exported function: eepro100_probe / eth_probe
@@ -542,7 +522,8 @@
 struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct 
pci_device *p)
 {
   u16 sum = 0;
-  int i, j, to;
+  int i, to;
+  int read_cmd, ee_size;
   unsigned short value;
   int options;
   int promisc;
@@ -551,21 +532,19 @@
   unsigned short pci_command;
   unsigned short new_command;
   unsigned char pci_latency;
+  /* we cache only the first few words of the EEPROM data
+     be careful not to access beyond this array */
+  unsigned short eeprom[16];
 
   if (probeaddrs == 0 || probeaddrs[0] == 0)
           return 0;
 
   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;
-  }
 
        /* From Matt Hortman <address@hidden> */
-       if (p->dev_id == PCI_DEVICE_ID_INTEL_82557 ){
+       if ((p->dev_id == PCI_DEVICE_ID_INTEL_82557 ) || 
+           (p->dev_id == PCI_DEVICE_ID_INTEL_82559ER) ) {
                /*
                * check to make sure the bios properly set the
                * 82557 (or 82558) to be bus master
@@ -587,7 +566,23 @@
                        printf("\nPCI latency timer (CFLT) is unreasonably low 
at %d. Setting to 32 clocks.\n", pci_latency);
                        pcibios_write_config_byte(pci_bus, p->devfn, 
PCI_LATENCY_TIMER, 32);
                        }
-               }
+       }
+
+       if ((do_eeprom_cmd(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, sum = 0; i < ee_size; i++) {
+               unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27);
+               if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
+                       eeprom[i] = value;
+               sum += value;
+       }
 
   printf ("Ethernet addr: ");
   for (i=0;i<6;i++) {
@@ -597,7 +592,7 @@
   printf ("\n");
 
   if (sum != 0xBABA)
-       printf("eepro100: Invalid EEPROM checksum %#4.4x, "
+       printf("eepro100: Invalid EEPROM checksum %#x, "
               "check settings before activating this device!\n", sum);
   outl(0, ioaddr + SCBPort);
   udelay (10);
@@ -667,7 +662,6 @@
 
   promisc = 0;
 
-  printf ("eeprom[6] = %x \n", eeprom[6]);
   if (   ((eeprom[6]>>8) & 0x3f) == DP83840
          || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
        int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
@@ -713,17 +707,6 @@
   nic->transmit = eepro100_transmit;
   nic->disable = eepro100_disable;
   return nic;
-}
-
-static int loops_per_usec = 300; /* totally bogus value */
-
-static void udelay (int val)
-{
-  int c;
-
-  for(c=0; c<val*loops_per_usec; c++) {
-    /* Nothing */;
-  }
 }
 
 /*********************************************************************/
Index: netboot/pci.h
===================================================================
RCS file: /cvs/grub/netboot/pci.h,v
retrieving revision 1.7
diff -u -r1.7 pci.h
--- netboot/pci.h       2000/07/29 19:22:54     1.7
+++ netboot/pci.h       2001/02/28 23:46:49
@@ -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_82559ER     0x1209
 #define PCI_VENDOR_ID_AMD              0x1022
 #define PCI_DEVICE_ID_AMD_LANCE                0x2000
 #define PCI_VENDOR_ID_SMC_1211          0x1113

reply via email to

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