patch-2.4.15 linux/drivers/net/eepro.c

Next file: linux/drivers/net/eepro100.c
Previous file: linux/drivers/net/dmfe.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.14/linux/drivers/net/eepro.c linux/drivers/net/eepro.c
@@ -8,7 +8,7 @@
 	according to the terms of the GNU General Public License,
 	incorporated herein by reference.
 
-	The author may be reached at bao.ha@srs.gov 
+	The author may be reached at bao.ha@srs.gov
 	or 418 Hastings Place, Martinez, GA 30907.
 
 	Things remaining to do:
@@ -23,26 +23,31 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.13    irq sharing, rewrote probe function, fixed a nasty bug in
+		hardware_send_packet and a major cleanup (aris, 11/08/2001)
+	0.12d	fixing a problem with single card detected as eight eth devices
+		fixing a problem with sudden drop in card performance
+		(chris (asdn@go2.pl), 10/29/2001)
 	0.12c	fixing some problems with old cards (aris, 01/08/2001)
 	0.12b	misc fixes (aris, 06/26/2000)
 	0.12a   port of version 0.12a of 2.2.x kernels to 2.3.x
 		(aris (aris@conectiva.com.br), 05/19/2000)
 	0.11e   some tweaks about multiple cards support (PdP, jul/aug 1999)
 	0.11d	added __initdata, __init stuff; call spin_lock_init
-	        in eepro_probe1. Replaced "eepro" by dev->name. Augmented 
-		the code protected by spin_lock in interrupt routine 
+	        in eepro_probe1. Replaced "eepro" by dev->name. Augmented
+		the code protected by spin_lock in interrupt routine
 		(PdP, 12/12/1998)
-	0.11c   minor cleanup (PdP, RMC, 09/12/1998)  
-	0.11b   Pascal Dupuis (dupuis@lei.ucl.ac.be): works as a module 
-	        under 2.1.xx. Debug messages are flagged as KERN_DEBUG to 
-		avoid console flooding. Added locking at critical parts. Now 
+	0.11c   minor cleanup (PdP, RMC, 09/12/1998)
+	0.11b   Pascal Dupuis (dupuis@lei.ucl.ac.be): works as a module
+	        under 2.1.xx. Debug messages are flagged as KERN_DEBUG to
+		avoid console flooding. Added locking at critical parts. Now
 		the dawn thing is SMP safe.
 	0.11a   Attempt to get 2.1.xx support up (RMC)
 	0.11	Brian Candler added support for multiple cards. Tested as
 		a module, no idea if it works when compiled into kernel.
 
 	0.10e	Rick Bressler notified me that ifconfig up;ifconfig down fails
-		because the irq is lost somewhere. Fixed that by moving 
+		because the irq is lost somewhere. Fixed that by moving
 		request_irq and free_irq to eepro_open and eepro_close respectively.
 	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
@@ -50,8 +55,8 @@
 		And, yes, this is not the only 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 
+	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)
 
@@ -75,7 +80,7 @@
 	0.07a	Fix a stat report which counts every packet as a
 		heart-beat failure. (BCH, 6/3/95)
 
-	0.07	Modified to support all other 82595-based lan cards.  
+	0.07	Modified to support all other 82595-based lan cards.
 		The IRQ vector of the EtherExpress Pro will be set
 		according to the value saved in the EEPROM.  For other
 		cards, I will do autoirq_request() to grab the next
@@ -85,37 +90,37 @@
 		print out format. (BCH, 3/9/95 and 3/14/95)
 
 	0.06	First stable release that I am comfortable with. (BCH,
-		3/2/95)	
+		3/2/95)
 
-	0.05	Complete testing of multicast. (BCH, 2/23/95)	
+	0.05	Complete testing of multicast. (BCH, 2/23/95)
 
-	0.04	Adding multicast support. (BCH, 2/14/95)	
+	0.04	Adding multicast support. (BCH, 2/14/95)
 
-	0.03	First widely alpha release for public testing. 
-		(BCH, 2/14/95)	
+	0.03	First widely alpha release for public testing.
+		(BCH, 2/14/95)
 
 */
 
 static const char version[] =
-	"eepro.c: v0.12c 01/08/2000 aris@conectiva.com.br\n";
+	"eepro.c: v0.13 11/08/2001 aris@cathedrallabs.org\n";
 
 #include <linux/module.h>
 
 /*
   Sources:
 
-	This driver wouldn't have been written without the availability 
-	of the Crynwr's Lan595 driver source code.  It helps me to 
-	familiarize with the 82595 chipset while waiting for the Intel 
-	documentation.  I also learned how to detect the 82595 using 
+	This driver wouldn't have been written without the availability
+	of the Crynwr's Lan595 driver source code.  It helps me to
+	familiarize with the 82595 chipset while waiting for the Intel
+	documentation.  I also learned how to detect the 82595 using
 	the packet driver's technique.
 
 	This driver is written by cutting and pasting the skeleton.c driver
 	provided by Donald Becker.  I also borrowed the EEPROM routine from
 	Donald Becker's 82586 driver.
 
-	Datasheet for the Intel 82595 (including the TX and FX version). It 
-	provides just enough info that the casual reader might think that it 
+	Datasheet for the Intel 82595 (including the TX and FX version). It
+	provides just enough info that the casual reader might think that it
 	documents the i82595.
 
 	The User Manual for the 82595.  It provides a lot of the missing
@@ -157,7 +162,7 @@
 /* A zero-terminated list of I/O addresses to be probed. */
 static unsigned int eepro_portlist[] compat_init_data =
    { 0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
-/* note: 0x300 is default, the 595FX supports ALL IO Ports 
+/* 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: */
@@ -189,12 +194,24 @@
 	unsigned tx_end;   /* end of the transmit chain (plus 1) */
 	int eepro;	/* 1 for the EtherExpress Pro/10,
 			   2 for the EtherExpress Pro/10+,
+			   3 for the EtherExpress 10 (blue cards),
 			   0 for other 82595-based lan cards. */
 	int version;	/* a flag to indicate if this is a TX or FX
 				   version of the 82595 chip. */
 	int stepping;
 
-	spinlock_t lock; /* Serializing lock  */ 
+	spinlock_t lock; /* Serializing lock  */
+
+	unsigned rcv_ram;	/* pre-calculated space for rx */
+	unsigned xmt_ram;	/* pre-calculated space for tx */
+	unsigned char xmt_bar;
+	unsigned char xmt_lower_limit_reg;
+	unsigned char xmt_upper_limit_reg;
+	short xmt_lower_limit;
+	short xmt_upper_limit;
+	short rcv_lower_limit;
+	short rcv_upper_limit;
+	unsigned char eeprom_reg;
 };
 
 /* The station (ethernet) address prefix, used for IDing the board. */
@@ -244,7 +261,7 @@
 /* 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_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
@@ -299,7 +316,7 @@
 static void     eepro_tx_timeout (struct net_device *dev);
 
 static int read_eeprom(int ioaddr, int location, struct net_device *dev);
-static void hardware_send_packet(struct net_device *dev, void *buf, short length);
+static int	hardware_send_packet(struct net_device *dev, void *buf, short length);
 static int	eepro_grab_irq(struct net_device *dev);
 
 /*
@@ -323,55 +340,42 @@
 network traffics, the ring linked list should improve performance by
 allowing up to 8K worth of packets to be queued.
 
-The sizes of the receive and transmit buffers can now be changed via lilo 
+The sizes of the receive and transmit buffers can now be changed via lilo
 or insmod.  Lilo uses the appended line "ether=io,irq,debug,rx-buffer,eth0"
 where rx-buffer is in KB unit.  Modules uses the parameter mem which is
-also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."  
+also in KB unit, for example "insmod io=io-address irq=0 mem=rx-buffer."
 The receive buffer has to be more than 3K or less than 29K.  Otherwise,
 it is reset to the default of 24K, and, hence, 8K for the trasnmit
 buffer (transmit-buffer = 32K - receive-buffer).
 
 */
-/* now this section could be used by both boards: the oldies and the ee10:
- * ee10 uses tx buffer before of rx buffer and the oldies the inverse.
- * (aris)
- */
 #define RAM_SIZE        0x8000
 
 #define RCV_HEADER      8
 #define RCV_DEFAULT_RAM 0x6000
-#define RCV_RAM         rcv_ram
-
-static unsigned rcv_ram = RCV_DEFAULT_RAM;
 
 #define XMT_HEADER      8
-#define XMT_RAM         (RAM_SIZE - RCV_RAM)
-
-#define XMT_START       ((rcv_start + RCV_RAM) % RAM_SIZE)
+#define XMT_DEFAULT_RAM	(RAM_SIZE - RCV_DEFAULT_RAM)
 
-#define RCV_LOWER_LIMIT (rcv_start >> 8)
-#define RCV_UPPER_LIMIT (((rcv_start + RCV_RAM) - 2) >> 8)
-#define XMT_LOWER_LIMIT (XMT_START >> 8)
-#define XMT_UPPER_LIMIT (((XMT_START + XMT_RAM) - 2) >> 8)
-
-#define RCV_START_PRO   0x00
-#define RCV_START_10    XMT_RAM
-				/* by default the old driver */
-static unsigned rcv_start = RCV_START_PRO;
+#define XMT_START_PRO	RCV_DEFAULT_RAM
+#define XMT_START_10	0x0000
+#define RCV_START_PRO	0x0000
+#define RCV_START_10	XMT_DEFAULT_RAM
 
 #define	RCV_DONE	0x0008
 #define	RX_OK		0x2000
 #define	RX_ERROR	0x0d81
 
 #define	TX_DONE_BIT	0x0080
+#define	TX_OK		0x2000
 #define	CHAIN_BIT	0x8000
 #define	XMT_STATUS	0x02
 #define	XMT_CHAIN	0x04
 #define	XMT_COUNT	0x06
 
-#define	BANK0_SELECT	0x00		
-#define	BANK1_SELECT	0x40		
-#define	BANK2_SELECT	0x80		
+#define	BANK0_SELECT	0x00
+#define	BANK1_SELECT	0x40
+#define	BANK2_SELECT	0x80
 
 /* Bank 0 registers */
 #define	COMMAND_REG	0x00	/* Register 0 */
@@ -406,7 +410,6 @@
 
 #define	XMT_BAR_PRO	0x0a
 #define	XMT_BAR_10	0x0b
-static unsigned xmt_bar = XMT_BAR_PRO;
 
 #define	HOST_ADDRESS_REG	0x0c
 #define	IO_PORT		0x0e
@@ -424,8 +427,6 @@
 #define	XMT_UPPER_LIMIT_REG_PRO 0x0b
 #define	XMT_LOWER_LIMIT_REG_10  0x0b
 #define	XMT_UPPER_LIMIT_REG_10  0x0a
-static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
-static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
 
 /* Bank 2 registers */
 #define	XMT_Chain_Int	0x20	/* Interrupt at the end of the transmit chain */
@@ -440,7 +441,7 @@
 #define	REG13		0x0d
 #define	FDX		0x00
 #define	A_N_ENABLE	0x02
-	
+
 #define	I_ADD_REG0	0x04
 #define	I_ADD_REG1	0x05
 #define	I_ADD_REG2	0x06
@@ -450,7 +451,6 @@
 
 #define	EEPROM_REG_PRO 0x0a
 #define	EEPROM_REG_10  0x0b
-static unsigned eeprom_reg = EEPROM_REG_PRO;
 
 #define EESK 0x01
 #define EECS 0x02
@@ -502,11 +502,6 @@
 /* set diagnose flag */
 #define eepro_diag(ioaddr) outb(DIAGNOSE_CMD, ioaddr)
 
-#ifdef ANSWER_TX_AND_RX		/* experimental way of handling interrupts */
-/* ack for rx/tx int */
-#define eepro_ack_rxtx(ioaddr) outb (RX_INT | TX_INT, ioaddr + STATUS_REG)
-#endif
-
 /* ack for rx int */
 #define eepro_ack_rx(ioaddr) outb (RX_INT, ioaddr + STATUS_REG)
 
@@ -514,16 +509,15 @@
 #define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)
 
 /* a complete sel reset */
-#define eepro_complete_selreset(ioaddr) { 	eepro_dis_int(ioaddr);\
+#define eepro_complete_selreset(ioaddr) { \
 						lp->stats.tx_errors++;\
 						eepro_sel_reset(ioaddr);\
 						lp->tx_end = \
-							(XMT_LOWER_LIMIT << 8);\
+							lp->xmt_lower_limit;\
 						lp->tx_start = lp->tx_end;\
 						lp->tx_last = 0;\
 						dev->trans_start = jiffies;\
 						netif_wake_queue(dev);\
-						eepro_en_int(ioaddr);\
 						eepro_en_rx(ioaddr);\
 					}
 
@@ -542,7 +536,7 @@
 
 #ifdef PnPWakeup
 	/* XXXX for multiple cards should this only be run once? */
-	
+
 	/* Wakeup: */
 	#define WakeupPort 0x279
 	#define WakeupSeq    {0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,\
@@ -568,7 +562,6 @@
 	}
 #endif
 
-
 	if (base_addr > 0x1ff)		/* Check a single specified location. */
 		return eepro_probe1(dev, base_addr);
 
@@ -595,13 +588,13 @@
 
 	for (i=0, j=ee_Checksum; i<ee_SIZE; i++)
 		j+=read_eeprom(ioaddr,i,dev);
-	printk("Checksum: %#x\n",j&0xffff);
+	printk(KERN_DEBUG "Checksum: %#x\n",j&0xffff);
 
 	Word=read_eeprom(ioaddr, 0, dev);
 	printk(KERN_DEBUG "Word0:\n");
 	printk(KERN_DEBUG " Plug 'n Pray: %d\n",GetBit(Word,ee_PnP));
 	printk(KERN_DEBUG " Buswidth: %d\n",(GetBit(Word,ee_BusWidth)+1)*8 );
-	printk(KERN_DEBUG " AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg)); 
+	printk(KERN_DEBUG " AutoNegotiation: %d\n",GetBit(Word,ee_AutoNeg));
 	printk(KERN_DEBUG " IO Address: %#x\n", (Word>>ee_IO0)<<4);
 
 	if (net_debug>4)  {
@@ -621,10 +614,10 @@
 	printk(KERN_DEBUG " BNC: %d\n",GetBit(Word,ee_BNC_TPE));
 	printk(KERN_DEBUG " NumConnectors: %d\n",GetBit(Word,ee_NumConn));
 	printk(KERN_DEBUG " 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");
+	if (GetBit(Word,ee_PortTPE)) printk(KERN_DEBUG "TPE ");
+	if (GetBit(Word,ee_PortBNC)) printk(KERN_DEBUG "BNC ");
+	if (GetBit(Word,ee_PortAUI)) printk(KERN_DEBUG "AUI ");
+	printk(KERN_DEBUG "port(s) \n");
 
 	Word=read_eeprom(ioaddr, 6, dev);
 	printk(KERN_DEBUG "Word6:\n");
@@ -635,12 +628,85 @@
 	printk(KERN_DEBUG "Word7:\n");
 	printk(KERN_DEBUG " INT to IRQ:\n");
 
-	printk(KERN_DEBUG);
-
 	for (i=0, j=0; i<15; i++)
-		if (GetBit(Word,i)) printk(" INT%d -> IRQ %d;",j++,i);
+		if (GetBit(Word,i)) printk(KERN_DEBUG " INT%d -> IRQ %d;",j++,i);
+
+	printk(KERN_DEBUG "\n");
+}
+
+/* function to recalculate the limits of buffer based on rcv_ram */
+static void eepro_recalc (struct net_device *dev)
+{
+	struct eepro_local *	lp;
+
+	lp = dev->priv;
+	lp->xmt_ram = RAM_SIZE - lp->rcv_ram;
+
+	if (lp->eepro == LAN595FX_10ISA) {
+		lp->xmt_lower_limit = XMT_START_10;
+		lp->xmt_upper_limit = (lp->xmt_ram - 2);
+		lp->rcv_lower_limit = lp->xmt_ram;
+		lp->rcv_upper_limit = (RAM_SIZE - 2);
+	}
+	else {
+		lp->rcv_lower_limit = RCV_START_PRO;
+		lp->rcv_upper_limit = (lp->rcv_ram - 2);
+		lp->xmt_lower_limit = lp->rcv_ram;
+		lp->xmt_upper_limit = (RAM_SIZE - 2);
+	}
+}
+
+/* prints boot-time info */
+static void eepro_print_info (struct net_device *dev)
+{
+	struct eepro_local *	lp = dev->priv;
+	int			i;
+	const char *		ifmap[] = {"AUI", "10Base2", "10BaseT"};
+
+	i = inb(dev->base_addr + ID_REG);
+	printk(KERN_DEBUG " id: %#x ",i);
+	printk(KERN_DEBUG " io: %#x ", (unsigned)dev->base_addr);
+
+	switch (lp->eepro) {
+		case LAN595FX_10ISA:
+			printk(KERN_INFO "%s: Intel EtherExpress 10 ISA\n at %#x,",
+					dev->name, (unsigned)dev->base_addr);
+			break;
+		case LAN595FX:
+			printk(KERN_INFO "%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
+					dev->name, (unsigned)dev->base_addr);
+			break;
+		case LAN595TX:
+			printk(KERN_INFO "%s: Intel EtherExpress Pro/10 ISA at %#x,",
+					dev->name, (unsigned)dev->base_addr);
+			break;
+		case LAN595:
+			printk(KERN_INFO "%s: Intel 82595-based lan card at %#x,", 
+					dev->name, (unsigned)dev->base_addr);
+	}
+
+	for (i=0; i < 6; i++)
+		printk(KERN_INFO "%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
+
+	if (net_debug > 3)
+		printk(KERN_DEBUG ", %dK RCV buffer",
+				(int)(lp->rcv_ram)/1024);
+
+	if (dev->irq > 2)
+		printk(KERN_INFO ", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
+	else 
+		printk(KERN_INFO ", %s.\n", ifmap[dev->if_port]);
 
-	printk("\n");
+	if (net_debug > 3) {
+		i = read_eeprom(dev->base_addr, 5, dev);
+		if (i & 0x2000) /* bit 13 of EEPROM word 5 */
+			printk(KERN_DEBUG "%s: Concurrent Processing is "
+				"enabled but not used!\n", dev->name);
+	}
+
+	/* Check the station address for the manufacturer's code */
+	if (net_debug>3)
+		printEEPROMInfo(dev->base_addr, dev);
 }
 
 /* This is the real probe routine.  Linux has a history of friendly device
@@ -650,42 +716,51 @@
 static int __init eepro_probe1(struct net_device *dev, short ioaddr)
 {
 	unsigned short station_addr[6], id, counter;
-	int i,j, irqMask;
-	int eepro = 0;
+	int i, j, irqMask, retval = 0;
 	struct eepro_local *lp;
-	const char *ifmap[] = {"AUI", "10Base2", "10BaseT"};
 	enum iftype { AUI=0, BNC=1, TPE=2 };
 
 	/* Now, we are going to check for the signature of the
 	   ID_REG (register 2 of bank 0) */
 
 	id=inb(ioaddr + ID_REG);
- 
-	if (((id) & ID_REG_MASK) == ID_REG_SIG) {
+
+	if (((id) & ID_REG_MASK) != ID_REG_SIG) {
+		retval = -ENODEV;
+		goto exit;
+	}
 
 		/* We seem to have the 82595 signature, let's
 		   play with its counter (last 2 bits of
 		   register 2 of bank 0) to be sure. */
-	
-		counter = (id & R_ROBIN_BITS);	
-		if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS) == 
-			(counter + 0x40)) {
-
-			/* Yes, the 82595 has been found */
-			printk(KERN_DEBUG " id: %#x ",id);
-			printk(" io: %#x ",ioaddr);
+
+		counter = (id & R_ROBIN_BITS);
+
+	if (((id=inb(ioaddr+ID_REG)) & R_ROBIN_BITS)!=(counter + 0x40)) {
+		retval = -ENODEV;
+		goto exit;
+	}
 
 			/* Initialize the device structure */
 			dev->priv = kmalloc(sizeof(struct eepro_local), GFP_KERNEL);
-			if (dev->priv == NULL)
-				return -ENOMEM;
+	if (!dev->priv) {
+		retval = -ENOMEM;
+		goto exit;
+	}
+
 			memset(dev->priv, 0, sizeof(struct eepro_local));
 
 			lp = (struct eepro_local *)dev->priv;
 
+	/* default values */
+	lp->eepro = 0;
+	lp->xmt_bar = XMT_BAR_PRO;
+	lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
+	lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
+	lp->eeprom_reg = EEPROM_REG_PRO;
+
 			/* Now, get the ethernet hardware address from
 			   the EEPROM */
-
 			station_addr[0] = read_eeprom(ioaddr, 2, dev);
 
 			/* FIXME - find another way to know that we've found
@@ -693,81 +768,47 @@
 			 */
 			if (station_addr[0] == 0x0000 ||
 			    station_addr[0] == 0xffff) {
-				eepro = 3;
 				lp->eepro = LAN595FX_10ISA;
-				eeprom_reg = EEPROM_REG_10;
-				rcv_start = RCV_START_10;
-				xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
-				xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
-
+		lp->eeprom_reg = EEPROM_REG_10;
+		lp->xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
+		lp->xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
+		lp->xmt_bar = XMT_BAR_10;
 				station_addr[0] = read_eeprom(ioaddr, 2, dev);
 			}
-			
 			station_addr[1] = read_eeprom(ioaddr, 3, dev);
 			station_addr[2] = read_eeprom(ioaddr, 4, dev);
 
-			if (eepro) {
-				printk("%s: Intel EtherExpress 10 ISA\n at %#x,",
-					dev->name, ioaddr);
-			} else if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ) { 
-							/* int to IRQ Mask */
-				eepro = 2;
-				printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
-					dev->name, ioaddr);
-			} else
-			if (station_addr[2] == 0x00aa)  {
-				eepro = 1;
-				printk("%s: Intel EtherExpress Pro/10 ISA at %#x,", 
-					dev->name, ioaddr);
-			}
-			else {
-				eepro = 0;
-				printk("%s: Intel 82595-based lan card at %#x,", 
-					dev->name, ioaddr);
+	if (!lp->eepro) {
+		if (read_eeprom(ioaddr,7,dev)== ee_FX_INT2IRQ)
+			lp->eepro = 2;
+		else if (station_addr[2] == SA_ADDR1)
+			lp->eepro = 1;
 			}
 
 			/* Fill in the 'dev' fields. */
 			dev->base_addr = ioaddr;
-			
-			for (i=0; i < 6; i++) {
+
+	for (i=0; i < 6; i++)
 				dev->dev_addr[i] = ((unsigned char *) station_addr)[5-i];
-				printk("%c%02x", i ? ':' : ' ', dev->dev_addr[i]);
-			}
-	
-			dev->mem_start = (RCV_LOWER_LIMIT << 8);
-			
-			if ((dev->mem_end & 0x3f) < 3 ||	/* RX buffer must be more than 3K */
-				(dev->mem_end & 0x3f) > 29)	/* and less than 29K */
-				dev->mem_end = (RCV_UPPER_LIMIT << 8);
-			else {
-				dev->mem_end = (dev->mem_end * 1024) +
-							(RCV_LOWER_LIMIT << 8);
-				rcv_ram = dev->mem_end - (RCV_LOWER_LIMIT << 8);
-			}
 
-			/* From now on, dev->mem_end - dev->mem_start contains 
-			 * the actual size of rx buffer 
-			 */
-			
-			if (net_debug > 3)
-				printk(", %dK RCV buffer", (int)(dev->mem_end -
-							 dev->mem_start)/1024);
-				
-				
-			/* ............... */
+	/* RX buffer must be more than 3K and less than 29K */
+	if (dev->mem_end < 3072 || dev->mem_end > 29696)
+		lp->rcv_ram = RCV_DEFAULT_RAM;
 
-			if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
-				dev->if_port = BNC;
-			else dev->if_port = TPE;
+	/* calculate {xmt,rcv}_{lower,upper}_limit */
+	eepro_recalc(dev);
 
-			/* ............... */
 
+			if (GetBit( read_eeprom(ioaddr, 5, dev),ee_BNC_TPE))
+				dev->if_port = BNC;
+	else
+		dev->if_port = TPE;
 
-			if ((dev->irq < 2) && (eepro!=0)) {
+	if ((dev->irq < 2) && (lp->eepro!=0)) {
 				i = read_eeprom(ioaddr, 1, dev);
 				irqMask = read_eeprom(ioaddr, 7, dev);
 				i &= 0x07; /* Mask off INT number */
-				
+
 				for (j=0; ((j<16) && (i>=0)); j++) {
 					if ((irqMask & (1<<j))!=0) {
 						if (i==0) {
@@ -778,34 +819,14 @@
 					}
 				}
 				if (dev->irq < 2) {
-					printk(" Duh! illegal interrupt vector stored in EEPROM.\n");
+			printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
 					kfree(dev->priv);
-					return -ENODEV;
-				} else 
-				
-				if (dev->irq==2)
-					dev->irq = 9;
-			}
-			
-			if (dev->irq > 2) {
-				printk(", IRQ %d, %s.\n", dev->irq,
-						ifmap[dev->if_port]);
-			}
-			else printk(", %s.\n", ifmap[dev->if_port]);
-			
-			if ((dev->mem_start & 0xf) > 0)	/* I don't know if this is */
-				net_debug = dev->mem_start & 7; /* still useful or not */
-
-			if (net_debug > 3) {
-				i = read_eeprom(ioaddr, 5, dev);
-				if (i & 0x2000) /* bit 13 of EEPROM word 5 */
-					printk(KERN_DEBUG "%s: Concurrent Processing is enabled but not used!\n",
-						dev->name);
+			retval = -ENODEV;
+			goto freeall;
+				} else
+			if (dev->irq==2) dev->irq = 9;
 			}
 
-			if (net_debug) 
-				printk(version);
-
 			/* Grab the region so we can find another board if autoIRQ fails. */
 			request_region(ioaddr, EEPRO_IO_EXTENT, dev->name);
 
@@ -821,23 +842,20 @@
 
 			/* Fill in the fields of the device structure with
 			   ethernet generic values */
-
 			ether_setup(dev);
 
-			/* Check the station address for the manufacturer's code */
-			if (net_debug>3)
-				printEEPROMInfo(ioaddr, dev);
+	/* print boot time info */
+	eepro_print_info(dev);
 
-			/* RESET the 82595 */
+	/* reset 82595 */
 			eepro_reset(ioaddr);
 
-			return 0;
-			}
-		else return -ENODEV;
-		}
-	else if (net_debug > 3)
-		printk ("EtherExpress Pro probed failed!\n");
-	return -ENODEV;
+exit:
+	return retval;
+freeall:
+	kfree(dev->priv);
+	goto exit;
+
 }
 
 /* Open/initialize the board.  This is called (in the current kernel)
@@ -854,15 +872,15 @@
 {
 	int irqlist[] = { 3, 4, 5, 7, 9, 10, 11, 12, 0 };
 	int *irqp = irqlist, temp_reg, ioaddr = dev->base_addr;
-	
+
 	eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
 
 	/* Enable the interrupt line. */
 	eepro_en_intline(ioaddr);
-	
+
 	/* be CAREFUL, BANK 0 now */
 	eepro_sw2bank0(ioaddr);
-	
+
 	/* clear all interrupts */
 	eepro_clear_int(ioaddr);
 
@@ -877,12 +895,12 @@
 
 		eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
 
-		if (request_irq (*irqp, NULL, 0, "bogus", dev) != EBUSY) {
+		if (request_irq (*irqp, NULL, SA_SHIRQ, "bogus", dev) != EBUSY) {
 			/* Twinkle the interrupt, and check if it's seen */
 			autoirq_setup(0);
 
 			eepro_diag(ioaddr); /* RESET the 82595 */
-				
+
 			if (*irqp == autoirq_report(2))  /* It's a good IRQ line */
 				break;
 
@@ -920,38 +938,38 @@
 	irqMask = read_eeprom(ioaddr,7,dev);
 
 	if (lp->eepro == LAN595FX_10ISA) {
-		if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n"); 
+		if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 3;\n");
 	}
 	else if (irqMask == ee_FX_INT2IRQ) /* INT to IRQ Mask */
 		{
 			lp->eepro = 2; /* Yes, an Intel EtherExpress Pro/10+ */
-			if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n"); 
+			if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 2;\n");
 		}
 
 	else if ((dev->dev_addr[0] == SA_ADDR0 &&
 			dev->dev_addr[1] == SA_ADDR1 &&
 			dev->dev_addr[2] == SA_ADDR2))
-		{ 
+		{
 			lp->eepro = 1;
-			if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 1;\n"); 
+			if (net_debug > 3) printk(KERN_DEBUG "p->eepro = 1;\n");
 		}  /* Yes, an Intel EtherExpress Pro/10 */
 
 	else lp->eepro = 0; /* No, it is a generic 82585 lan card */
 
-	/* Get the interrupt vector for the 82595 */	
+	/* Get the interrupt vector for the 82595 */
 	if (dev->irq < 2 && eepro_grab_irq(dev) == 0) {
-		printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+		printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
-		
+
 	if (request_irq(dev->irq , &eepro_interrupt, 0, dev->name, dev)) {
-		printk("%s: unable to get IRQ %d.\n", dev->name, dev->irq);
+		printk(KERN_ERR "%s: unable to get IRQ %d.\n", dev->name, dev->irq);
 		return -EAGAIN;
 	}
-	
+
 #ifdef irq2dev_map
 	if  (((irq2dev_map[dev->irq] != 0)
-		|| (irq2dev_map[dev->irq] = dev) == 0) && 
+		|| (irq2dev_map[dev->irq] = dev) == 0) &&
 		(irq2dev_map[dev->irq]!=dev)) {
 		/* printk("%s: IRQ map wrong\n", dev->name); */
 	        free_irq(dev->irq, dev);
@@ -962,21 +980,21 @@
 	/* Initialize the 82595. */
 
 	eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
-	temp_reg = inb(ioaddr + eeprom_reg);
+	temp_reg = inb(ioaddr + lp->eeprom_reg);
 
 	lp->stepping = temp_reg >> 5;	/* Get the stepping number of the 595 */
-	
+
 	if (net_debug > 3)
 		printk(KERN_DEBUG "The stepping of the 82595 is %d\n", lp->stepping);
 
 	if (temp_reg & 0x10) /* Check the TurnOff Enable bit */
-		outb(temp_reg & 0xef, ioaddr + eeprom_reg);
-	for (i=0; i < 6; i++) 
-		outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i); 
-			
+		outb(temp_reg & 0xef, ioaddr + lp->eeprom_reg);
+	for (i=0; i < 6; i++)
+		outb(dev->dev_addr[i] , ioaddr + I_ADD_REG0 + i);
+
 	temp_reg = inb(ioaddr + REG1);    /* Setup Transmit Chaining */
 	outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop /* and discard bad RCV frames */
-		| RCV_Discard_BadFrame, ioaddr + REG1);  
+		| RCV_Discard_BadFrame, ioaddr + REG1);
 
 	temp_reg = inb(ioaddr + REG2); /* Match broadcast */
 	outb(temp_reg | 0x14, ioaddr + REG2);
@@ -987,15 +1005,15 @@
 	/* Set the receiving mode */
 	eepro_sw2bank1(ioaddr); /* be CAREFUL, BANK 1 now */
 
-	/* Set the interrupt vector */	
+	/* Set the interrupt vector */
 	temp_reg = inb(ioaddr + INT_NO_REG);
-	if (lp->eepro == 2 || lp->eepro == LAN595FX_10ISA)
+	if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
 		outb((temp_reg & 0xf8) | irqrmap2[dev->irq], ioaddr + INT_NO_REG);
-	else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG); 
+	else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
 
 
 	temp_reg = inb(ioaddr + INT_NO_REG);
-	if (lp->eepro == 2 || lp->eepro == LAN595FX_10ISA)
+	if (lp->eepro == LAN595FX || lp->eepro == LAN595FX_10ISA)
 		outb((temp_reg & 0xf0) | irqrmap2[dev->irq] | 0x08,ioaddr+INT_NO_REG);
 	else outb((temp_reg & 0xf8) | irqrmap[dev->irq], ioaddr + INT_NO_REG);
 
@@ -1004,10 +1022,10 @@
 
 
 	/* Initialize the RCV and XMT upper and lower limits */
-	outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG); 
-	outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG); 
-	outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
-	outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
+	outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG); 
+	outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG); 
+	outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
+	outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
 
 	/* Enable the interrupt line. */
 	eepro_en_intline(ioaddr);
@@ -1022,12 +1040,14 @@
 	eepro_clear_int(ioaddr);
 
 	/* Initialize RCV */
-	outw(RCV_LOWER_LIMIT << 8, ioaddr + RCV_BAR); 
-	lp->rx_start = (RCV_LOWER_LIMIT << 8) ;
-	outw((RCV_UPPER_LIMIT << 8) | 0xfe, ioaddr + RCV_STOP); 
+	outw(lp->rcv_lower_limit, ioaddr + RCV_BAR); 
+	lp->rx_start = lp->rcv_lower_limit;
+	outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP); 
 
 	/* Initialize XMT */
-	outw(XMT_LOWER_LIMIT << 8, ioaddr + xmt_bar); 
+	outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar); 
+	lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
+	lp->tx_last = 0;
 
 	/* Check for the i82595TX and i82595FX */
 	old8 = inb(ioaddr + 8);
@@ -1042,9 +1062,7 @@
 		lp->version = LAN595TX;
 		outb(old8, ioaddr + 8);
 		old9 = inb(ioaddr + 9);
-		/*outb(~old9, ioaddr + 9);
-		if (((temp_reg = inb(ioaddr + 9)) == ( (~old9)&0xff) )) {*/
-		
+
 		if (irqMask==ee_FX_INT2IRQ) {
 			enum iftype { AUI=0, BNC=1, TPE=2 };
 
@@ -1070,15 +1088,10 @@
 			printk(KERN_DEBUG "i82595TX detected!\n");
 		}
 	}
-	
-	eepro_sel_reset(ioaddr);
-	SLOW_DOWN;
-	SLOW_DOWN;
 
-	lp->tx_start = lp->tx_end = XMT_LOWER_LIMIT << 8;
-	lp->tx_last = 0;
+	eepro_sel_reset(ioaddr);
 
-	netif_start_queue(dev);	
+	netif_start_queue(dev);
 
 	if (net_debug > 3)
 		printk(KERN_DEBUG "%s: exiting eepro_open routine.\n", dev->name);
@@ -1086,6 +1099,8 @@
 	/* enabling rx */
 	eepro_en_rx(ioaddr);
 
+	MOD_INC_USE_COUNT;
+
 	return 0;
 }
 
@@ -1097,7 +1112,7 @@
 	/* if (net_debug > 1) */
 	printk (KERN_ERR "%s: transmit timed out, %s?\n", dev->name,
 		"network cable problem");
-	/* This is not a duplicate. One message for the console, 
+	/* This is not a duplicate. One message for the console,
 	   one for the the log file  */
 	printk (KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
 		"network cable problem");
@@ -1109,23 +1124,28 @@
 {
 	struct eepro_local *lp = (struct eepro_local *)dev->priv;
 	unsigned long flags;
-	
+	int ioaddr = dev->base_addr;
+
 	if (net_debug > 5)
 		printk(KERN_DEBUG  "%s: entering eepro_send_packet routine.\n", dev->name);
-	
+
 	netif_stop_queue (dev);
 
+	eepro_dis_int(ioaddr);
 	spin_lock_irqsave(&lp->lock, flags);
 
 	{
 		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
 		unsigned char *buf = skb->data;
 
+		if (hardware_send_packet(dev, buf, length))
+			/* we won't wake queue here because we're out of space */
+			lp->stats.tx_dropped++;
+		else {
 		lp->stats.tx_bytes+=skb->len;
-
-		hardware_send_packet(dev, buf, length);
-
 		dev->trans_start = jiffies;
+			netif_wake_queue(dev);
+		}
 
 	}
 
@@ -1137,8 +1157,9 @@
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: exiting eepro_send_packet routine.\n", dev->name);
 
+	eepro_en_int(ioaddr);
 	spin_unlock_irqrestore(&lp->lock, flags);
-	
+
 	return 0;
 }
 
@@ -1151,7 +1172,7 @@
 {
 	struct net_device *dev =  (struct net_device *)dev_id;
 	                      /* (struct net_device *)(irq2dev_map[irq]);*/
-	struct eepro_local *lp = (struct eepro_local *)dev->priv;
+	struct eepro_local *lp;
 	int ioaddr, status, boguscount = 20;
 
 	if (dev == NULL) {
@@ -1159,44 +1180,41 @@
                 return;
         }
 
+	lp = (struct eepro_local *)dev->priv;
+
         spin_lock(&lp->lock);
 
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: entering eepro_interrupt routine.\n", dev->name);
-	
+
 	ioaddr = dev->base_addr;
 
-	while (((status = inb(ioaddr + STATUS_REG)) & 0x06) && (boguscount--))
+	while (((status = inb(ioaddr + STATUS_REG)) & (RX_INT|TX_INT)) && (boguscount--))
 	{
-		switch (status & (RX_INT | TX_INT)) {
-#ifdef ANSWER_TX_AND_RX
-			case (RX_INT | TX_INT):
-				eepro_ack_rxtx(ioaddr);
-				break;
-#endif
-			case RX_INT:
-				eepro_ack_rx(ioaddr);
-				break;
-			case TX_INT:
-				eepro_ack_tx(ioaddr);
-				break;
-		}
 		if (status & RX_INT) {
 			if (net_debug > 4)
 				printk(KERN_DEBUG "%s: packet received interrupt.\n", dev->name);
 
+			eepro_dis_int(ioaddr);
+
 			/* Get the received packets */
+			eepro_ack_rx(ioaddr);
 			eepro_rx(dev);
-#ifndef ANSWER_TX_AND_RX
-			continue;
-#endif
+
+			eepro_en_int(ioaddr);
 		}
 		if (status & TX_INT) {
 			if (net_debug > 4)
  				printk(KERN_DEBUG "%s: packet transmit interrupt.\n", dev->name);
 
+
+			eepro_dis_int(ioaddr);
+
 			/* Process the status of transmitted packets */
+			eepro_ack_tx(ioaddr);
 			eepro_transmit_interrupt(dev);
+
+			eepro_en_int(ioaddr);
 		}
 	}
 
@@ -1219,13 +1237,13 @@
 
 	/* Disable the physical interrupt line. */
 	temp_reg = inb(ioaddr + REG1);
-	outb(temp_reg & 0x7f, ioaddr + REG1); 
+	outb(temp_reg & 0x7f, ioaddr + REG1);
 
 	eepro_sw2bank0(ioaddr); /* Switch back to Bank 0 */
 
 	/* Flush the Tx and disable Rx. */
-	outb(STOP_RCV_CMD, ioaddr); 
-	lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8);
+	outb(STOP_RCV_CMD, ioaddr);
+	lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
 	lp->tx_last = 0;
 
 	/* Mask all the interrupts. */
@@ -1246,6 +1264,8 @@
 
 	/* Update the statistics here. What statistics? */
 
+	MOD_DEC_USE_COUNT;
+
 	return 0;
 }
 
@@ -1269,7 +1289,7 @@
 	unsigned short mode;
 	struct dev_mc_list *dmi=dev->mc_list;
 
-	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63) 
+	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
 	{
 		/*
 		 *	We must make the kernel realise we had to move
@@ -1277,18 +1297,18 @@
 		 *	the cable. If it was a promisc request the
 		 *	flag is already set. If not we assert it.
 		 */
-		dev->flags|=IFF_PROMISC;		
+		dev->flags|=IFF_PROMISC;
 
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
-		outb(mode | PRMSC_Mode, ioaddr + REG2);	
+		outb(mode | PRMSC_Mode, ioaddr + REG2);
 		mode = inb(ioaddr + REG3);
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
-		printk("%s: promiscuous mode enabled.\n", dev->name);
+		printk(KERN_INFO "%s: promiscuous mode enabled.\n", dev->name);
 	}
-	
-	else if (dev->mc_count==0 ) 
+
+	else if (dev->mc_count==0 )
 	{
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
@@ -1297,12 +1317,12 @@
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
 	}
-	
-	else 
+
+	else
 	{
 		unsigned short status, *eaddrs;
 		int i, boguscount = 0;
-		
+
 		/* Disable RX and TX interrupts.  Necessary to avoid
 		   corruption of the HOST_ADDRESS_REG by interrupt
 		   service routines. */
@@ -1310,7 +1330,7 @@
 
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
-		outb(mode | Multi_IA, ioaddr + REG2);	
+		outb(mode | Multi_IA, ioaddr + REG2);
 		mode = inb(ioaddr + REG3);
 		outb(mode, ioaddr + REG3); /* writing reg. 3 to complete the update */
 		eepro_sw2bank0(ioaddr); /* Return to BANK 0 now */
@@ -1319,8 +1339,8 @@
 		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++) 
+
+		for (i = 0; i < dev->mc_count; i++)
 		{
 			eaddrs=(unsigned short *)dmi->dmi_addr;
 			dmi=dmi->next;
@@ -1328,20 +1348,20 @@
 			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);
+		outw(lp->tx_end, ioaddr + lp->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) 
+
+		if (lp->tx_start != lp->tx_end)
 		{
-			/* update the next address and the chain bit in the 
+			/* update the next address and the chain bit in the
 			   last packet */
 			outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
 			outw(i, ioaddr + IO_PORT);
@@ -1358,17 +1378,17 @@
 		do { /* We should be doing this in the eepro_interrupt()! */
 			SLOW_DOWN;
 			SLOW_DOWN;
-			if (inb(ioaddr + STATUS_REG) & 0x08) 
+			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", 
+					printk(KERN_NOTICE "%s: multicast setup failed.\n", 
 						dev->name);
 					break;
 				} else if ((i & 0x0f) == 0x03)	{ /* MC-Done */
-					printk("%s: set Rx mode to %d address%s.\n",
+					printk(KERN_DEBUG "%s: set Rx mode to %d address%s.\n",
 						dev->name, dev->mc_count,
 						dev->mc_count > 1 ? "es":"");
 					break;
@@ -1398,23 +1418,19 @@
 {
 	int i;
 	unsigned short retval = 0;
-	short ee_addr = ioaddr + eeprom_reg;
-	struct eepro_local *lp = (struct eepro_local *)dev->priv;
+	struct eepro_local *lp = dev->priv;
+	short ee_addr = ioaddr + lp->eeprom_reg;
 	int read_cmd = location | EE_READ_CMD;
 	short ctrl_val = EECS ;
 
-	/* XXXX - this is not the final version. We must test this on other
-	 *	  boards other than eepro10. I think that it won't let other
-	 *	  boards to fail. (aris)
-	 */
-	if (lp->eepro == LAN595FX_10ISA) {
+	/* XXXX - black magic */
 		eepro_sw2bank1(ioaddr);
 		outb(0x00, ioaddr + STATUS_REG);
-	}
-	
+	/* XXXX - black magic */
+
 	eepro_sw2bank2(ioaddr);
 	outb(ctrl_val, ee_addr);
-	
+
 	/* Shift the read command bits out. */
 	for (i = 8; i >= 0; i--) {
 		short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI
@@ -1426,7 +1442,7 @@
 		eeprom_delay();
 	}
 	outb(ctrl_val, ee_addr);
-	
+
 	for (i = 16; i > 0; i--) {
 		outb(ctrl_val | EESK, ee_addr);	 eeprom_delay();
 		retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
@@ -1443,57 +1459,44 @@
 	return retval;
 }
 
-static void
+static int
 hardware_send_packet(struct net_device *dev, void *buf, short length)
 {
 	struct eepro_local *lp = (struct eepro_local *)dev->priv;
 	short ioaddr = dev->base_addr;
-	unsigned status, tx_available, last, end, boguscount = 100;
+	unsigned status, tx_available, last, end;
 
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: entering hardware_send_packet routine.\n", dev->name);
 
-	while (boguscount-- > 0) {
-
-		/* Disable RX and TX interrupts.  Necessary to avoid
-		corruption of the HOST_ADDRESS_REG by interrupt
-		service routines. */
-		eepro_dis_int(ioaddr);
-
 		/* 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);
+		tx_available = lp->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 */
+	else tx_available = lp->xmt_ram;
 
-			/* Enable RX and TX interrupts */
-			eepro_en_int(ioaddr);
-			continue;
+	if (((((length + 3) >> 1) << 1) + 2*XMT_HEADER) >= tx_available) {
+		/* No space available ??? */
+		return 1;
 		}
 
 		last = lp->tx_end;
 		end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
-		if (end >= (XMT_UPPER_LIMIT << 8)) { /* the transmit buffer is wrapped around */
-			if (((XMT_UPPER_LIMIT << 8) - last) <= XMT_HEADER) {	
+	if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
+		if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {	
 				/* Arrrr!!!, must keep the xmt header together,
 				several days were lost to chase this one down. */
-				
-				last = (XMT_LOWER_LIMIT << 8);
+			last = lp->xmt_lower_limit;
 				end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 			}
-			
-			else end = (XMT_LOWER_LIMIT << 8) + (end -
-						(XMT_UPPER_LIMIT <<8));
+		else end = lp->xmt_lower_limit + (end -
+						lp->xmt_upper_limit + 2);
 		}
+
 		outw(last, ioaddr + HOST_ADDRESS_REG);
-		outw(XMT_CMD, ioaddr + IO_PORT); 
+		outw(XMT_CMD, ioaddr + IO_PORT);
 		outw(0, ioaddr + IO_PORT);
 		outw(end, ioaddr + IO_PORT);
 		outw(length, ioaddr + IO_PORT);
@@ -1508,24 +1511,24 @@
 		}
 
 		/* A dummy read to flush the DRAM write pipeline */
-		status = inw(ioaddr + IO_PORT); 
+		status = inw(ioaddr + IO_PORT);
 
-		if (lp->tx_start == lp->tx_end) {	
-			outw(last, ioaddr + xmt_bar);
+		if (lp->tx_start == lp->tx_end) {
+		outw(last, ioaddr + lp->xmt_bar);
 			outb(XMT_CMD, ioaddr);
 			lp->tx_start = last;   /* I don't like to change tx_start here */
 		}
 		else {
-			/* update the next address and the chain bit in the 
+			/* update the next address and the chain bit in the
 			last packet */
-			
+
 			if (lp->tx_end != last) {
 				outw(lp->tx_last + XMT_CHAIN, ioaddr + HOST_ADDRESS_REG);
-				outw(last, ioaddr + IO_PORT); 
+				outw(last, ioaddr + IO_PORT);
 			}
-			
+
 			outw(lp->tx_last + XMT_COUNT, ioaddr + HOST_ADDRESS_REG);
-			status = inw(ioaddr + IO_PORT); 
+			status = inw(ioaddr + IO_PORT);
 			outw(status | CHAIN_BIT, ioaddr + IO_PORT);
 
 			/* Continue the transmit command */
@@ -1535,27 +1538,10 @@
 		lp->tx_last = last;
 		lp->tx_end = end;
 
-		if (netif_queue_stopped(dev))
-			netif_wake_queue(dev);
-
-		/* now we are serializing tx. queue won't come back until
-		 * the tx interrupt
-		 */
-		if (lp->eepro == LAN595FX_10ISA)
-			netif_stop_queue(dev);
-		
-		/* Enable RX and TX interrupts */
-		eepro_en_int(ioaddr);
-
 		if (net_debug > 5)
 			printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
-		return;
-	}
-	if (lp->eepro == LAN595FX_10ISA)
-		netif_stop_queue(dev);
 
-	if (net_debug > 5)
-		printk(KERN_DEBUG "%s: exiting hardware_send_packet routine.\n", dev->name);
+	return 0;
 }
 
 static void
@@ -1564,7 +1550,7 @@
 	struct eepro_local *lp = (struct eepro_local *)dev->priv;
 	short ioaddr = dev->base_addr;
 	short boguscount = 20;
-	unsigned rcv_car = lp->rx_start;
+	short rcv_car = lp->rx_start;
 	unsigned rcv_event, rcv_status, rcv_next_frame, rcv_size;
 
 	if (net_debug > 5)
@@ -1572,17 +1558,17 @@
 
 	/* 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_status = inw(ioaddr + IO_PORT);
 		rcv_next_frame = inw(ioaddr + IO_PORT);
-		rcv_size = 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;
 
@@ -1602,49 +1588,50 @@
 			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), 
+				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);	
+
+			skb->protocol = eth_type_trans(skb,dev);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
 			lp->stats.rx_packets++;
 		}
-		
-		else { /* Not sure will ever reach here, 
+
+		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", 
+
+			printk(KERN_DEBUG "%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++;
 
+		rcv_car = lp->rx_start + RCV_HEADER + rcv_size;
+		lp->rx_start = rcv_next_frame;
+
 		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);
 		rcv_event = inw(ioaddr + IO_PORT);
 
-	} 
+	}
 	if (rcv_car == 0)
-		rcv_car = (RCV_UPPER_LIMIT << 8) | 0xff;
-		
+		rcv_car = lp->rcv_upper_limit | 0xff;
+
 	outw(rcv_car - 1, ioaddr + RCV_STOP);
 
 	if (net_debug > 5)
@@ -1656,54 +1643,24 @@
 {
 	struct eepro_local *lp = (struct eepro_local *)dev->priv;
 	short ioaddr = dev->base_addr;
-	short boguscount = 20; 
-	unsigned xmt_status;
-	
-	/*
-	if (dev->tbusy == 0) {
-		printk("%s: transmit_interrupt called with tbusy = 0 ??\n",
-			dev->name);
-		printk(KERN_DEBUG "%s: transmit_interrupt called with tbusy = 0 ??\n",
-			dev->name);
-	}
-	*/
-	while (lp->tx_start != lp->tx_end && boguscount) { 
+	short boguscount = 25; 
+	short xmt_status;
+
+	while ((lp->tx_start != lp->tx_end) && boguscount--) { 
 
-		outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG); 
+		outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
 		xmt_status = inw(ioaddr+IO_PORT);
-		
-		if ((xmt_status & TX_DONE_BIT) == 0) {
-			if (lp->eepro == LAN595FX_10ISA) {
-				udelay(40);
-				boguscount--;
-				continue;
-			}
-			else
+
+		if (!(xmt_status & TX_DONE_BIT))
 				break;
-		}
 
-		xmt_status = inw(ioaddr+IO_PORT); 
+		xmt_status = inw(ioaddr+IO_PORT);
 		lp->tx_start = inw(ioaddr+IO_PORT);
 
-		if (lp->eepro == LAN595FX_10ISA) {
-			lp->tx_start = (XMT_LOWER_LIMIT << 8);
-			lp->tx_end = lp->tx_start;
-	
-			/* yeah, black magic :( */
-			eepro_sw2bank0(ioaddr);
-			eepro_en_int(ioaddr);
-
-			/* disabling rx */
-			eepro_dis_rx(ioaddr);
-			
-			/* enabling rx */
-			eepro_en_rx(ioaddr);
-		}
-
 		netif_wake_queue (dev);
 
-		if (xmt_status & 0x2000)
-			lp->stats.tx_packets++; 
+		if (xmt_status & TX_OK)
+			lp->stats.tx_packets++;
 		else {
 			lp->stats.tx_errors++;
 			if (xmt_status & 0x0400) {
@@ -1719,35 +1676,15 @@
 				printk(KERN_DEBUG "%s: XMT status = %#x\n",
 					dev->name, xmt_status);
 			}
-			if (lp->eepro == LAN595FX_10ISA) {			
-				/* Try to restart the adaptor. */
-				/* We are supposed to wait for 2 us after a SEL_RESET */
-				eepro_sel_reset(ioaddr);
-
-				/* first enable interrupts */
-				eepro_sw2bank0(ioaddr);
-				outb(ALL_MASK & ~(RX_INT | TX_INT), ioaddr + STATUS_REG);
-			
-				/* enabling rx */
-				eepro_en_rx(ioaddr);
-			}
 		}
 		if (xmt_status & 0x000f) {
 			lp->stats.collisions += (xmt_status & 0x000f);
 		}
-		
+
 		if ((xmt_status & 0x0040) == 0x0) {
 			lp->stats.tx_heartbeat_errors++;
 		}
-
-		boguscount--;
 	}
-	/* if it reached here then it's probable that the adapter won't
-	 * interrupt again for tx. in other words: tx timeout what will take
-	 * a lot of time to happen, so we'll do a complete selreset.
-	 */
-	if (!boguscount && lp->eepro == LAN595FX_10ISA)
-		eepro_complete_selreset(ioaddr);
 }
 
 #ifdef MODULE
@@ -1778,35 +1715,38 @@
 MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)");
 MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)");
 
-int 
+int
 init_module(void)
 {
 	int i;
 	if (io[0] == 0 && autodetect == 0) {
-		printk("eepro_init_module: Probe is very dangerous in ISA boards!\n");
-		printk("eepro_init_module: Please add \"autodetect=1\" to force probe\n");
+		printk(KERN_WARNING "eepro_init_module: Probe is very dangerous in ISA boards!\n");
+		printk(KERN_WARNING "eepro_init_module: Please add \"autodetect=1\" to force probe\n");
 		return 1;
 	}
 	else if (autodetect) {
 		/* if autodetect is set then we must force detection */
 		io[0] = 0;
-		
-		printk("eepro_init_module: Auto-detecting boards (May God protect us...)\n");
-	}	
+
+		printk(KERN_INFO "eepro_init_module: Auto-detecting boards (May God protect us...)\n");
+	}
 
 	for (i = 0; i < MAX_EEPRO; i++) {
 		struct net_device *d = &dev_eepro[n_eepro];
-		d->mem_end	= mem[n_eepro];
-		d->base_addr	= io[0];
-		d->irq		= irq[n_eepro];
+		d->mem_end	= mem[i];
+		d->base_addr	= io[i];
+		d->irq		= irq[i];
 		d->init		= eepro_probe;
 
-		if (register_netdev(d) == 0)
-			n_eepro++;
-		else
-			break;
-	}
-	
+			if (register_netdev(d) == 0)
+				n_eepro++;
+			else
+				break;
+		}
+
+	if (n_eepro)
+		printk(KERN_INFO "%s", version);
+
 	return n_eepro ? 0 : -ENODEV;
 }
 
@@ -1814,7 +1754,7 @@
 cleanup_module(void)
 {
 	int i;
-	
+
 	for (i=0; i<n_eepro; i++) {
 		struct net_device *d = &dev_eepro[i];
 		unregister_netdev(d);
@@ -1824,7 +1764,7 @@
 
 		/* If we don't do this, we can't re-insmod it later. */
 		release_region(d->base_addr, EEPRO_IO_EXTENT);
-		
+
 	}
 }
 #endif /* MODULE */

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)