here's a small patch to make tulip.c (coming with 2.0.0) work with a
Cogent 964 4-port ethernet card.
The patch is only tested on one machine, so be careful using it.
My Cogent 964 is equipped with 21040-chips, so I don't know if it's
working on Cogent cards with the 21041, 21141 or multiports from other
manufacturers.
Basically I have corrected the IRQ-detection of my PCI-BIOS. The 964
is using one shared IRQ, but the BIOS assigns 4 separate IRQ's.
That's probably a problem of the PCI-specification, because there
is no way for the BIOS to detect this (I think).
In a final solution this should probably be moved to the PCI-code
of the kernel (reprogram PCI_INTERRUPT_LINE during initialization),
but I don't have enough knowledge to implement it there (is there a
kernel "knowledge base" for special cards?).
Ciao,
Franz.
PS:
The 964 and tulip.c don't work well after a softreset, if there is
traffic on the net. So for the moment ALWAYS hardreset your PC,
I'm trying to find a solution for this, but hey, Linux 2.0.0 gives
me no reason to reboot ;-).
The patch:
--- tulip.c.2.0.0 Sun Jun 9 20:15:22 1996
+++ tulip.c Mon Jun 10 00:26:27 1996
@@ -394,6 +394,8 @@
0x0000c000, PCI_DEVICE_ID_DEC_TULIP, "old smc8432", 0},
{auto21140_select, generic21140_fail,
0x0000f400, PCI_DEVICE_ID_DEC_TULIP_FAST, "LA100PCI", 0},
+ {generic21040_select, generic21040_fail,
+ 0x00009200, PCI_DEVICE_ID_DEC_TULIP, "Cogent EM96x", 1},
{cogent21140_select, generic21140_fail,
0x00009200, PCI_DEVICE_ID_DEC_TULIP_FAST, "cogent_em110", 0},
{generic21140_select, generic21140_fail,
@@ -1177,6 +1179,7 @@
{
/* See note below on the Znyx 315 etherarray. */
static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u',
'x'};
+ static int last_irq = 0;
char detect_mesg[80], *mesgp=detect_mesg;
struct tulip_private *tp = (struct tulip_private *)dev->priv;
int i;
@@ -1246,6 +1251,7 @@
for (i = 0; i < ETH_ALEN - 1; i++)
dev->dev_addr[i] = last_phys_addr[i];
dev->dev_addr[i] = last_phys_addr[i] + 1;
+ irq = last_irq;
}
for (i = 0; i < ETH_ALEN - 1; i++)
mesgp += sprintf(mesgp, "%2.2x:", dev->dev_addr[i]);
@@ -1255,8 +1261,10 @@
/* copy ethernet address */
if (card_type(tp, device_id,
htonl((*(int*)dev->dev_addr) & 0xFFFFFF)))
- for (i = 0; i < ETH_ALEN - 1; i++)
+ for (i = 0; i < ETH_ALEN - 1; i++) {
last_phys_addr[i] = dev->dev_addr[i];
+ last_irq = irq;
+ }
/* We do a request_region() only to register /proc/ioports info. */
request_region(ioaddr, TULIP_TOTAL_SIZE, tp->signature);