patch-2.2.17 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.2.16/drivers/net/eepro.c linux/drivers/net/eepro.c
@@ -23,6 +23,10 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.12b	added reset when the tx interrupt is called and TX isn't done
+		and other minor fixes. this may fix a problem found after
+		initialization that delays tx until a transmit timeout is 
+		reported and the board is reset.
 	0.12a	fixed bug that would make impossible have ee10 boards and
 		other previous supported boards. (aris, 05/19/2000)
 	0.12    added support to 82595FX etherexpress 10 based cards
@@ -97,7 +101,7 @@
 */
 
 static const char *version =
-	"eepro.c: v0.12a 04/26/2000 aris@conectiva.com.br\n";
+	"eepro.c: v0.12b 06/20/2000 aris@conectiva.com.br\n";
 
 #include <linux/module.h>
 
@@ -470,7 +474,7 @@
 #define EEDO 0x08
 
 /* do a full reset */
-#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr)
+#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
 
 /* do a nice reset */
 #define eepro_sel_reset(ioaddr) 	{ \
@@ -523,6 +527,20 @@
 /* ack for tx int */
 #define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)
 
+/* a complete sel reset */
+#define eepro_complete_selreset(ioaddr) { 	eepro_dis_int(ioaddr);\
+						lp->stats.tx_errors++;\
+						eepro_sel_reset(ioaddr);\
+						lp->tx_end = \
+							(XMT_LOWER_LIMIT << 8);\
+						lp->tx_start = lp->tx_end;\
+						lp->tx_last = 0;\
+						dev->tbusy=0;\
+						dev->trans_start = jiffies;\
+						eepro_en_int(ioaddr);\
+						eepro_en_rx(ioaddr);\
+					}
+
 /* Check for a network adaptor of this type, and return '0' if one exists.
    If dev->base_addr == 0, probe all likely locations.
    If dev->base_addr == 1, always return failure.
@@ -1064,10 +1082,6 @@
 		if (tickssofar < 40)
 			return 1;
 		
-		/* let's disable interrupts so we can avoid confusion on SMP
-		 */
-		eepro_dis_int(ioaddr);
-		
 		/* if (net_debug > 1) */
 		printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, 
 			"network cable problem");
@@ -1075,25 +1089,9 @@
 		   one for the the log file  */
 		printk(KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
 			"network cable problem");
-		lp->stats.tx_errors++;
-
-		/* Try to restart the adaptor. */
-		/* We are supposed to wait for 2 us after a SEL_RESET */
-		eepro_sel_reset(ioaddr);
-
-		/* Do I also need to flush the transmit buffers here? YES? */
-		lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); 
-		lp->tx_last = 0;
-	
-		dev->tbusy=0;
-		dev->trans_start = jiffies;
-
-
-		/* re-enabling all interrupts */
-		eepro_en_int(ioaddr);
-
-		/* enable rx */
-		eepro_en_rx(ioaddr);
+		
+		/* let's do a complete sel reset */
+		eepro_complete_selreset(ioaddr);
 	}
 	spin_lock_irqsave(&lp->lock, flags);
 
@@ -1379,8 +1377,7 @@
 		eepro_en_int(ioaddr);
 	
 	}
-	/* enabling rx */
-	eepro_en_rx(ioaddr);
+	eepro_complete_selreset(ioaddr);
 }
 
 /* The horrible routine to read a word from the serial EEPROM. */
@@ -1492,7 +1489,8 @@
 				last = (XMT_LOWER_LIMIT << 8);
 				end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 			}
-			else end = (XMT_LOWER_LIMIT << 8) + (end - XMT_RAM);
+			else end = (XMT_LOWER_LIMIT << 8) + (end - 
+						(XMT_UPPER_LIMIT << 8));
 		}
 
 		outw(last, ioaddr + HOST_ADDRESS_REG);
@@ -1554,7 +1552,6 @@
 		return;
 	}
 
-	eepro_en_int(ioaddr);
 	dev->tbusy = 1;
 
 	if (net_debug > 5)
@@ -1574,9 +1571,6 @@
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name);
 
-	/* clear all interrupts */
-	eepro_clear_int(ioaddr);
-	
 	/* Set the read pointer to the start of the RCV */
 	outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
 	
@@ -1655,9 +1649,6 @@
 
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name);
-
-	/* enable tx/rx interrupts */
-	eepro_en_int(ioaddr);
 }
 
 static void
@@ -1754,6 +1745,12 @@
 		}
 		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)
+		eepro_complete_selreset(ioaddr);
 }
 
 #ifdef MODULE

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