patch for eepro.c :-[I had to fix it ]-:

Bruce Korb (korb@datadesign.com)
Wed, 26 May 1999 22:13:00 +0000


This is a multi-part message in MIME format.
--------------C78E5E3276BEA9C85C32EB1F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

For some inexplicable reason, not only was the P&P stuff
stripped out, but my card's io address was removed from
the list of addresses to check!! Yes, I could have booted
DOS, run the SOFTSET2 program and changed the io addr to
one of the ones I found in the linux/drivers/net/eepro.c
file, but good grief!! Even still, I did that to disable
P&P and that wound up making the card unidentifiable to
the driver. So, finally, I located the old floppy where
the 0.10e version was located. That version did not work,
of course, so I merged its stuff with the _alternate_
0.10c path. It was confusing, but I have it all working.

My card is:

Intel EtherExpress Pro/10+ ISA with P&P

It was waaaaaaaaaaaaaaaaay too much work!!
Some of the diffs are due to better formatting
in the "old" 0.10e version vs. the "new" 0.10c version.
--------------C78E5E3276BEA9C85C32EB1F
Content-Type: text/plain; charset=us-ascii; name="eepro.DIF"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="eepro.DIF"

--- eepro.c.orig Sun Nov 15 10:33:02 1998
+++ eepro.c.new Wed May 26 15:11:56 1999
@@ -23,13 +23,20 @@
This is a compatibility hardware problem.

Versions:
-
- 0.10c Some cosmetic changes. (9/28/98, BCH)
-
- 0.10b Should work now with (some) Pro/10+. At least for
- me (and my two cards) it does. _No_ guarantee for
- function with non-Pro/10+ cards! (don't have any)
- (RMC, 9/11/96)
+ 0.10f Some cosmetic changes. (9/28/98, BCH - reapplied 5/25/99, BK)
+ 0.10e Rick Bressler notified me that ifconfig up;ifconfig down fails
+ because the irq is lost somewhere. Fixed that by moving
+ request_irq and free_irq to eepro_open and eepro_close respectiveley.
+ 0.10d Ugh! Now Wakeup works. Was seriously broken in my first attempt.
+ I'll need to find a way to specify an ioport other than
+ the default one in the PnP case. PnP definitively sucks.
+ And, yes, this is not the noly reason.
+ 0.10c PnP Wakeup Test for 595FX. uncomment #define PnPWakeup;
+ to use.
+ 0.10b Should work now with (some) Pro/10+. At least for
+ me (and my two cards) it does. _No_ guarantee for
+ function with non-Pro/10+ cards! (don't have any)
+ (RMC, 9/11/96)

0.10 Added support for the Etherexpress Pro/10+. The
IRQ map was changed significantly from the old
@@ -72,8 +79,8 @@

*/

-static const char *version =
- "eepro.c: v0.10c 9/28/98 Bao C. Ha (bao@hacom.net)\n";
+static const char eepro_version[] =
+ "eepro.c: v0.10f 9/3/96 Bao C. Ha (bao.ha@srs.gov)\n";

#include <linux/module.h>

@@ -123,7 +130,13 @@

/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int eepro_portlist[] =
- { 0x300, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
+ { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
+/* note: 0x300 is default, the 595FX supports ALL IO Ports
+ from 0x000 to 0x3F0, some of which are reserved in PCs */
+
+/* To try the (not-really PnP Wakeup: */
+
+#define PnPWakeup

/* use 0 for production, 1 for verification, >2 for debug */

@@ -173,6 +186,86 @@
#define SA3_ADDR2 0x00
#define SA3_ADDR3 0xc9

+#define GetBit(x,y) ((x & (1<<y))>>y)
+
+/* EEPROM Word 0: */
+#define ee_PnP 0 /* Plug 'n Play enable bit */
+#define ee_Word1 1 /* Word 1? */
+#define ee_BusWidth 2 /* 8/16 bit */
+#define ee_FlashAddr 3 /* Flash Address */
+#define ee_FlashMask 0x7 /* Mask */
+#define ee_AutoIO 6 /* */
+#define ee_reserved0 7 /* =0! */
+#define ee_Flash 8 /* Flash there? */
+#define ee_AutoNeg 9 /* Auto Negotiation enabled? */
+#define ee_IO0 10 /* IO Address LSB */
+#define ee_IO0Mask 0x /*...*/
+#define ee_IO1 15 /* IO MSB */
+
+/* EEPROM Word 1: */
+#define ee_IntSel 0 /* Interrupt */
+#define ee_IntMask 0x7
+#define ee_LI 3 /* Link Integrity 0= enabled */
+#define ee_PC 4 /* Polarity Correction 0= enabled */
+#define ee_TPE_AUI 5 /* PortSelection 1=TPE */
+#define ee_Jabber 6 /* Jabber prevention 0= enabled */
+#define ee_AutoPort 7 /* Auto Port Selection 1= Disabled */
+#define ee_SMOUT 8 /* SMout Pin Control 0= Input */
+#define ee_PROM 9 /* Flash EPROM / PROM 0=Flash */
+#define ee_reserved1 10 /* .. 12 =0! */
+#define ee_AltReady 13 /* Alternate Ready, 0=normal */
+#define ee_reserved2 14 /* =0! */
+#define ee_Duplex 15
+
+/* Word2,3,4: */
+#define ee_IA5 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA4 8 /*bit start for individual Addr Byte 5 */
+#define ee_IA3 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA2 8 /*bit start for individual Addr Byte 5 */
+#define ee_IA1 0 /*bit start for individual Addr Byte 5 */
+#define ee_IA0 8 /*bit start for individual Addr Byte 5 */
+
+/* Word 5: */
+#define ee_BNC_TPE 0 /* 0=TPE */
+#define ee_BootType 1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
+#define ee_BootTypeMask 0x3
+#define ee_NumConn 3 /* Number of Connections 0= One or Two */
+#define ee_FlashSock 4 /* Presence of Flash Socket 0= Present */
+#define ee_PortTPE 5
+#define ee_PortBNC 6
+#define ee_PortAUI 7
+#define ee_PowerMgt 10 /* 0= disabled */
+#define ee_CP 13 /* Concurrent Processing */
+#define ee_CPMask 0x7
+
+/* Word 6: */
+#define ee_Stepping 0 /* Stepping info */
+#define ee_StepMask 0x0F
+#define ee_BoardID 4 /* Manucaturer Board ID, reserved */
+#define ee_BoardMask 0x0FFF
+
+/* Word 7: */
+#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping = 0x1EB8 for Pro/10+ */
+#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
+
+/*..*/
+#define ee_SIZE 0x40 /* total EEprom Size */
+#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
+
+
+/* Card identification via EEprom: */
+#define ee_addr_vendor 0x10 /* Word offset for EISA Vendor ID */
+#define ee_addr_id 0x11 /* Word offset for Card ID */
+#define ee_addr_SN 0x12 /* Serial Number */
+#define ee_addr_CRC_8 0x14 /* CRC over last thee Bytes */
+
+
+#define ee_vendor_intel0 0x25 /* Vendor ID Intel */
+#define ee_vendor_intel1 0xD4
+#define ee_id_eepro10p0 0x10 /* ID for eepro/10+ */
+#define ee_id_eepro10p1 0x31
+
+
/* Index to functions, as function prototypes. */

extern int eepro_probe(struct device *dev);
@@ -346,12 +439,39 @@

#else

-int
+int
eepro_probe(struct device *dev)
{
int i;
int base_addr = dev ? dev->base_addr : 0;

+#ifdef PnPWakeup
+
+ /* Wakeup: */
+ #define WakeupPort 0x279
+ #define WakeupSeq {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\
+ 0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,\
+ 0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,\
+ 0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x43}
+
+ {
+ unsigned short int WS[32]=WakeupSeq;
+
+ if (check_region(WakeupPort, 2)==0) {
+ if (net_debug>3)
+ printk("Waking UP\n");
+
+ outb_p(0,WakeupPort);
+ outb_p(0,WakeupPort);
+ for (i=0; i<32; i++) {
+ outb_p(WS[i],WakeupPort);
+ if (net_debug>3) printk(": %#x ",WS[i]);
+ }
+ if (net_debug>3) printk("\n");
+ } else printk("Checkregion Failed!\n");
+ }
+#endif
+
if (base_addr > 0x1ff) /* Check a single specified location. */
return eepro_probe1(dev, base_addr);
else if (base_addr != 0) /* Don't probe at all. */
@@ -370,11 +490,65 @@
}
#endif

+#if NET_DEBUG > 3
+void
+printEEPROMInfo(short ioaddr)
+{
+ unsigned short Word;
+ int i,j;
+
+ for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
+ j+=read_eeprom(ioaddr,i);
+ printk("Checksum: %#x\n",j&0xffff);
+
+ Word=read_eeprom(ioaddr, 0);
+ printk("Word0:\n");
+ printk(" Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
+ printk(" Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
+ printk(" AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg));
+ printk(" IO Address: %#x\n", (Word>>ee_IO0)<<4);
+
+ Word=read_eeprom(ioaddr, 1);
+ printk("Word1:\n");
+ printk(" INT: %d\n", Word & ee_IntMask);
+ printk(" LI: %d\n", GetBit(Word,ee_LI));
+ printk(" PC: %d\n", GetBit(Word,ee_PC));
+ printk(" TPE/AUI: %d\n", GetBit(Word,ee_TPE_AUI));
+ printk(" Jabber: %d\n", GetBit(Word,ee_Jabber));
+ printk(" AutoPort: %d\n", GetBit(!Word,ee_Jabber));
+ printk(" Duplex: %d\n", GetBit(Word,ee_Duplex));
+
+ Word=read_eeprom(ioaddr, 5);
+ printk(" Word5:\n");
+ printk(" BNC: %d\n",GetBit(Word,ee_BNC_TPE));
+ printk(" NumConnectors: %d\n",GetBit(Word,ee_NumConn));
+ printk("Has ");
+ if (GetBit(Word,ee_PortTPE)) printk("TPE ");
+ if (GetBit(Word,ee_PortBNC)) printk("BNC ");
+ if (GetBit(Word,ee_PortAUI)) printk("AUI ");
+ printk("port(s) \n");
+
+ Word=read_eeprom(ioaddr, 6);
+ printk("Word6:\n");
+ printk(" Stepping: %d\n",Word & ee_StepMask);
+ printk(" BoardID: %d\n",Word>>ee_BoardID);
+
+ Word=read_eeprom(ioaddr, 7);
+ printk("Word7:\n");
+ printk(" INT to IRQ:\n");
+
+ for (i=0, j=0; i<15; i++)
+ if (GetBit(Word,i)) printk("INT%d -> IRQ %d; ",j++,i);
+
+ printk("\n");
+}
+#endif
+
/* This is the real probe routine. Linux has a history of friendly device
probes on the ISA bus. A good device probes avoids doing writes, and
verifies that the correct device exists and functions. */

-int
+int
eepro_probe1(struct device *dev, short ioaddr)
{
unsigned short station_addr[6], id, counter;
@@ -405,22 +579,28 @@
station_addr[2] = read_eeprom(ioaddr, 4);

/* Check the station address for the manufacturer's code */
-
- if ((station_addr[2] == 0x00aa) && (station_addr[1]!= 0x00c9)) {
+#if NET_DEBUG > 3
+ if (net_debug>3)
+ printEEPROMInfo(ioaddr);
+#endif
+ if ((station_addr[2] == 0x00aa) && (station_addr[1] != 0x00c9)) {
eepro = 1;
printk("%s: Intel EtherExpress Pro/10 ISA at %#x,",
dev->name, ioaddr);
- } else
- if ( (station_addr[2] == 0x00a0)
- || ((station_addr[2] == 0x00aa) && (station_addr[1] == 0x00c9) )) {
+ }
+
+ else if ( (station_addr[2] == 0x00a0)
+ || ( (station_addr[2] == 0x00aa)
+ && (station_addr[1] == 0x00c9) )) {
eepro = 2;
printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
- dev->name, ioaddr);
+ dev->name, ioaddr);
}
+
else {
eepro = 0;
printk("%s: Intel 82595-based lan card at %#x,",
- dev->name, ioaddr);
+ dev->name, ioaddr);
}

/* Fill in the 'dev' fields. */
@@ -497,9 +677,6 @@
dev->name);
}

- if (net_debug)
- printk(version);
-
/* Grab the region so we can find another board if autoIRQ fails. */
request_region(ioaddr, EEPRO_IO_EXTENT, "eepro");

@@ -522,10 +699,13 @@

outb(RESET_CMD, ioaddr); /* RESET the 82595 */

+ if (net_debug)
+ printk("EEPRO Initialized\n%s", eepro_version);
+
return 0;
}
else return ENODEV;
- }
+ }
else if (net_debug > 3)
printk ("EtherExpress Pro probed failed!\n");
return ENODEV;
@@ -552,20 +732,20 @@

/* Enable the interrupt line. */
temp_reg = inb(ioaddr + REG1);
- outb(temp_reg | INT_ENABLE, ioaddr + REG1);
-
+ outb(temp_reg | INT_ENABLE, ioaddr + REG1);
+
outb(BANK0_SELECT, ioaddr); /* be CAREFUL, BANK 0 now */

/* clear all interrupts */
- outb(ALL_MASK, ioaddr + STATUS_REG);
+ outb(ALL_MASK, ioaddr + STATUS_REG);

/* Let EXEC event to interrupt */
- outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);
+ outb(ALL_MASK & ~(EXEC_MASK), ioaddr + INT_MASK_REG);

do {
outb(BANK1_SELECT, ioaddr); /* be CAREFUL, BANK 1 now */
temp_reg = inb(ioaddr + INT_NO_REG);
- outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
+ outb((temp_reg & 0xf8) | irqrmap[*irqp], ioaddr + INT_NO_REG);
outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
if (request_irq (*irqp, NULL, 0, "bogus", NULL) != EBUSY) {
/* Twinkle the interrupt, and check if it's seen */
@@ -573,8 +753,10 @@
outb(DIAGNOSE_CMD, ioaddr); /* RESET the 82595 */

if (*irqp == autoirq_report(2) && /* It's a good IRQ line */
- (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro", NULL) == 0))
+ (request_irq(dev->irq = *irqp, &eepro_interrupt, 0, "eepro",
+ NULL) == 0))
break;
+
/* clear all interrupts */
outb(ALL_MASK, ioaddr + STATUS_REG);
}
@@ -783,25 +965,25 @@
if (dev->tbusy) {
/* If we get here, some higher level has decided we are broken.
There should really be a "kick me" function call instead. */
-
+
int tickssofar = jiffies - dev->trans_start;
-
+
if (tickssofar < 40)
return 1;
-
+
if (net_debug > 1)
printk("%s: transmit timed out, %s?\n", dev->name,
"network cable problem");
-
+
lp->stats.tx_errors++;
-
+
/* Try to restart the adaptor. */
outb(SEL_RESET_CMD, ioaddr);
-
+
/* We are supposed to wait for 2 us after a SEL_RESET */
SLOW_DOWN_IO;
SLOW_DOWN_IO;
-
+
/* Do I also need to flush the transmit buffers here? YES? */
lp->tx_start = lp->tx_end = rcv_ram;
lp->tx_last = 0;
@@ -810,18 +992,18 @@
dev->trans_start = jiffies;
outb(RCV_ENABLE_CMD, ioaddr);
}
-
+
/* If some higher layer thinks we've missed an tx-done interrupt
we are passed NULL. Caution: dev_tint() handles the cli()/sti()
itself. */
-
+
if (skb == NULL) {
dev_tint(dev);
return 0;
}
-
+
/* Block a timer-based transmit from overlapping. */
-
+
if (set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
@@ -830,12 +1012,12 @@
hardware_send_packet(dev, buf, length);
dev->trans_start = jiffies;
}
-
+
dev_kfree_skb (skb, FREE_WRITE);
-
+
/* You might need to clean up and record Tx statistics here. */
/* lp->stats.tx_aborted_errors++; */
-
+
if (net_debug > 5)
printk("eepro: exiting eepro_send_packet routine.\n");

@@ -858,35 +1040,40 @@
printk ("eepro_interrupt(): irq %d for unknown device.\n", irq);
return;
}
-
+
dev->interrupt = 1;

ioaddr = dev->base_addr;
-
+
do {
status = inb(ioaddr + STATUS_REG);

if (status & RX_INT) {
if (net_debug > 4)
printk("eepro: packet received interrupt.\n");
+
/* Acknowledge the RX_INT */
outb(RX_INT, ioaddr + STATUS_REG);
+
/* Get the received packets */
eepro_rx(dev);
}
+
else if (status & TX_INT) {
if (net_debug > 4)
printk("eepro: packet transmit interrupt.\n");
+
/* Acknowledge the TX_INT */
outb(TX_INT, ioaddr + STATUS_REG);
+
/* Process the status of transmitted packets */
eepro_transmit_interrupt(dev);
}

} while ((boguscount-- > 0) && (status & 0x06));
-
+
dev->interrupt = 0;
-
+
if (net_debug > 5)
printk("eepro: exiting eepro_interrupt routine.\n");

@@ -903,39 +1090,39 @@

dev->tbusy = 1;
dev->start = 0;
-
+
outb(BANK1_SELECT, ioaddr); /* Switch back to Bank 1 */
-
+
/* Disable the physical interrupt line. */
temp_reg = inb(ioaddr + REG1);
outb(temp_reg & 0x7f, ioaddr + REG1);
outb(BANK0_SELECT, ioaddr); /* Switch back to Bank 0 */
-
+
/* Flush the Tx and disable Rx. */
outb(STOP_RCV_CMD, ioaddr);
-
+
lp->tx_start = lp->tx_end = rcv_ram ;
lp->tx_last = 0;
-
+
/* Mask all the interrupts. */
outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
+
/* clear all interrupts */
outb(ALL_MASK, ioaddr + STATUS_REG);
-
+
/* Reset the 82595 */
outb(RESET_CMD, ioaddr);
-
+
/* release the interrupt */
free_irq(dev->irq, NULL);
irq2dev_map[dev->irq] = 0;
-
+
/* Update the statistics here. What statistics? */
/* We are supposed to wait for 200 us after a RESET */
SLOW_DOWN_IO;
SLOW_DOWN_IO; /* May not be enough? */
MOD_DEC_USE_COUNT;
-
+
return 0;
}

@@ -958,7 +1145,7 @@
short ioaddr = dev->base_addr;
unsigned short mode;
struct dev_mc_list *dmi=dev->mc_list;
-
+
if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
{
/*
@@ -976,7 +1163,7 @@
outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
printk("%s: promiscuous mode enabled.\n", dev->name);
}
-
+
else if (dev->mc_count==0 )
{
outb(BANK2_SELECT, ioaddr); /* be CAREFUL, BANK 2 now */
@@ -986,7 +1173,7 @@
outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
outb(BANK0_SELECT, ioaddr); /* Return to BANK 0 now */
}
-
+
else
{
unsigned short status, *eaddrs;
@@ -1007,7 +1194,7 @@
outw(0, ioaddr + IO_PORT);
outw(0, ioaddr + IO_PORT);
outw(6*(dev->mc_count + 1), ioaddr + IO_PORT);
-
+
for (i = 0; i < dev->mc_count; i++)
{
eaddrs=(unsigned short *)dmi->dmi_addr;
@@ -1016,17 +1203,17 @@
outw(*eaddrs++, ioaddr + IO_PORT);
outw(*eaddrs++, ioaddr + IO_PORT);
}
-
+
eaddrs = (unsigned short *) dev->dev_addr;
outw(eaddrs[0], ioaddr + IO_PORT);
outw(eaddrs[1], ioaddr + IO_PORT);
outw(eaddrs[2], ioaddr + IO_PORT);
outw(lp->tx_end, ioaddr + XMT_BAR);
outb(MC_SETUP, ioaddr);
-
+
/* Update the transmit queue */
i = lp->tx_end + XMT_HEADER + 6*(dev->mc_count + 1);
-
+
if (lp->tx_start != lp->tx_end)
{
/* update the next address and the chain bit in the
@@ -1041,17 +1228,17 @@
else {
lp->tx_start = lp->tx_end = i ;
}
-
+
/* Acknowledge that the MC setup is done */
do { /* We should be doing this in the eepro_interrupt()! */
SLOW_DOWN_IO;
SLOW_DOWN_IO;
-
+
if (inb(ioaddr + STATUS_REG) & 0x08)
{
i = inb(ioaddr);
outb(0x08, ioaddr + STATUS_REG);
-
+
if (i & 0x20) { /* command ABORTed */
printk("%s: multicast setup failed.\n",
dev->name);
@@ -1063,7 +1250,7 @@
}
}
} while (++boguscount < 100);
-
+
/* Re-enable RX and TX interrupts */
outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);

@@ -1127,47 +1314,48 @@

if (net_debug > 5)
printk("eepro: entering hardware_send_packet routine.\n");
-
+
while (boguscount-- > 0) {
-
+
/* Disable RX and TX interrupts. Necessary to avoid
corruption of the HOST_ADDRESS_REG by interrupt
service routines. */
outb(ALL_MASK, ioaddr + INT_MASK_REG);
-
+
if (dev->interrupt == 1) {
/* Enable RX and TX interrupts */
outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
continue;
}
-
+
/* determine how much of the transmit buffer space is available */
if (lp->tx_end > lp->tx_start)
tx_available = XMT_RAM - (lp->tx_end - lp->tx_start);
else if (lp->tx_end < lp->tx_start)
tx_available = lp->tx_start - lp->tx_end;
else tx_available = XMT_RAM;
-
+
if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER)
>= tx_available) /* No space available ??? */
{
eepro_transmit_interrupt(dev); /* Clean up the transmiting queue */
+
/* Enable RX and TX interrupts */
outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);
continue;
}
-
+
last = lp->tx_end;
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+
if (end >= RAM_SIZE) { /* the transmit buffer is wrapped around */
-
+
if ((RAM_SIZE - last) <= XMT_HEADER) {
/* Arrrr!!!, must keep the xmt header together,
several days were lost to chase this one down. */
last = rcv_ram;
end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
}
-
else end = rcv_ram + (end - RAM_SIZE);
}

@@ -1176,20 +1364,20 @@
outw(0, ioaddr + IO_PORT);
outw(end, ioaddr + IO_PORT);
outw(length, ioaddr + IO_PORT);
-
+
if (lp->version == LAN595)
outsw(ioaddr + IO_PORT, buf, (length + 3) >> 1);
-
+
else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
unsigned short temp = inb(ioaddr + INT_MASK_REG);
outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
outsl(ioaddr + IO_PORT_32_BIT, buf, (length + 3) >> 2);
outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
}
-
+
/* A dummy read to flush the DRAM write pipeline */
status = inw(ioaddr + IO_PORT);
-
+
if (lp->tx_start == lp->tx_end) {
outw(last, ioaddr + XMT_BAR);
outb(XMT_CMD, ioaddr);
@@ -1203,31 +1391,32 @@
outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
outw(last, ioaddr + IO_PORT);
}
-
+
outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
status = inw(ioaddr + IO_PORT);
outw(status | CHAIN_BIT, ioaddr + IO_PORT);
-
+
/* Continue the transmit command */
outb(RESUME_XMT_CMD, ioaddr);
}
lp->tx_last = last;
lp->tx_end = end;
-
+
/* Enable RX and TX interrupts */
outb(ALL_MASK & ~(RX_MASK | TX_MASK), ioaddr + INT_MASK_REG);

if (dev->tbusy) {
dev->tbusy = 0;
}
-
+
if (net_debug > 5)
printk("eepro: exiting hardware_send_packet routine.\n");
-
+
return;
}
+
dev->tbusy = 1;
-
+
if (net_debug > 5)
printk("eepro: exiting hardware_send_packet routine.\n");
}
@@ -1246,68 +1435,68 @@

/* Set the read pointer to the start of the RCV */
outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
-
+
rcv_event = inw(ioaddr + IO_PORT);
while (rcv_event == RCV_DONE) {

rcv_status = inw(ioaddr + IO_PORT);
rcv_next_frame = inw(ioaddr + IO_PORT);
rcv_size = inw(ioaddr + IO_PORT);
-
+
if ((rcv_status & (RX_OK | RX_ERROR)) == RX_OK) {
-
+
/* Malloc up new buffer. */
struct sk_buff *skb;
rcv_size &= 0x3fff;
skb = dev_alloc_skb(rcv_size+5);
-
+
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
lp->stats.rx_dropped++;
break;
}
-
+
skb->dev = dev;
skb_reserve(skb,2);
-
+
if (lp->version == LAN595)
insw(ioaddr+IO_PORT, skb_put(skb,rcv_size), (rcv_size + 3) >> 1);
-
+
else { /* LAN595TX or LAN595FX, capable of 32-bit I/O processing */
unsigned short temp = inb(ioaddr + INT_MASK_REG);
outb(temp | IO_32_BIT, ioaddr + INT_MASK_REG);
insl(ioaddr+IO_PORT_32_BIT, skb_put(skb,rcv_size), (rcv_size + 3) >> 2);
outb(temp & ~(IO_32_BIT), ioaddr + INT_MASK_REG);
}
-
+
skb->protocol = eth_type_trans(skb,dev);
netif_rx(skb);
lp->stats.rx_packets++;
}
-
+
else { /* Not sure will ever reach here,
I set the 595 to discard bad received frames */
lp->stats.rx_errors++;
-
+
if (rcv_status & 0x0100)
lp->stats.rx_over_errors++;
-
+
else if (rcv_status & 0x0400)
lp->stats.rx_frame_errors++;
-
+
else if (rcv_status & 0x0800)
lp->stats.rx_crc_errors++;
-
+
printk("%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
}
-
+
if (rcv_status & 0x1000)
lp->stats.rx_length_errors++;
-
+
if (--boguscount == 0)
break;
-
+
rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
lp->rx_start = rcv_next_frame;
outw(rcv_next_frame, ioaddr + HOST_ADDRESS_REG);
@@ -1315,9 +1504,9 @@
}
if (rcv_car == 0)
rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
-
+
outw(rcv_car - 1, ioaddr + RCV_STOP);
-
+
if (net_debug > 5)
printk("eepro: exiting eepro_rx routine.\n");
}
@@ -1331,17 +1520,17 @@
short xmt_status;

while (lp->tx_start != lp->tx_end) {
-
+
outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
xmt_status = inw(ioaddr+IO_PORT);
-
+
if ((xmt_status & TX_DONE_BIT) == 0) break;
-
+
xmt_status = inw(ioaddr+IO_PORT);
lp->tx_start = inw(ioaddr+IO_PORT);
dev->tbusy = 0;
mark_bh(NET_BH);
-
+
if (xmt_status & 0x2000)
lp->stats.tx_packets++;
else {
@@ -1351,15 +1540,15 @@
printk("%s: XMT status = %#x\n",
dev->name, xmt_status);
}
-
+
if (xmt_status & 0x000f) {
lp->stats.collisions += (xmt_status & 0x000f);
}
-
+
if ((xmt_status & 0x0040) == 0x0) {
lp->stats.tx_heartbeat_errors++;
}
-
+
if (--boguscount == 0)
break;
}
@@ -1373,11 +1562,17 @@
0, 0, 0, 0,
0, 0,
0, 0, 0, NULL, eepro_probe };
-static int io = 0x200;
+
+#ifdef PnPWakeup
+static int io = 0x210; /*: default for PnP enabled FX chips */
+/* static int SetIO = 0x210; */
+#else
+static int io = 0x200; /* Why? */
+#endif
static int irq = 0;
static int mem = (RCV_RAM/1024); /* Size of the rx buffer in KB */

-int
+int
init_module(void)
{
if (io == 0)

--------------C78E5E3276BEA9C85C32EB1F--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/