[Top][All Lists]
[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
Re: Patch for EtherExpressPro100, Christoph Plattner, 2001/02/27