[401] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Sleeping 3c503 cards -- fix

daemon@ATHENA.MIT.EDU (Paul Gortmaker)
Thu Jun 1 13:51:21 1995

From: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
To: linux-net@vger.rutgers.edu
Date: Fri, 2 Jun 1995 01:41:54 +1000 (EST)
Cc: becker@cesdis1.gsfc.nasa.gov (Donald Becker)


	Okay, those of you with 3c503 cards that fall asleep and require
a ping from the console to wake up, here is the fix I promised earlier.
This is against stock/oem 1.2.8. I haven't had any time to test it
but that is what you net-channel readers are for...   :-)

[ NB: this does *not* contain the dev.c locking that I implemented in
a previous patch that is vital for ne2k cards. This is just a minimal 
patch to try and fix the 3c503 cards. The dev.c locking will probably
appear in 1.2.x but in the form of blocking the net_bh() instead of
implementing a dev->in_xmit -- stay tuned. ]

For those that care (perhaps one of you?)  I believe that the problem
was that a valid overrun condition was ignored. Note that because of the
segmented memory on the 3c503/16  the driver treats it as an 8kB 3c503,
regardless of what card you have. (Eventually I guess the driver should
be updated to switch to the other 8kB window on the 16 bit cards for 
the Tx packets...) Hence the 16 bit cards suffer from small Rx space
(and hence overruns) just like the 8 bit card.

If an overrun was posted by the 8390 after reading the ISR in the
interrupt handler, it would be silently ack'ed in the Rx routine,
(but not serviced) which would leave the card in a stopped state 
(because of the o'run) and hence a deaf card. Once a Tx comes along,
it will time out, and reset the card, and everything works again.
The fix is to not have the Rx routine ack the overrun interrupts.
Don's original comments indicated that some cards posted bogus
o'run interrupts and that is why the ack was there in the 1st place,
but we can't afford to ignore real o'run interrupts either.

There is another problem, that being that the o'run code ack's all
8390 interrupts, including perfectly valid Tx-done interrupts. This
shows up as having a Tx-timeout immediately after an o'run. This
happens because the o'run is serviced before the Tx-done in the
interrupt handler. The fix here is to not have the o'run code ack
all 8390 interrupts.

Please let me know if this stops your 3c503 cards from going deaf.
If you have a slow 8bit 8390 based card, (ne1000, wd8003-old, etc.)
you may wish to try this as well. Also note that an o'run will show
up in the Rx "frame" errors of /proc/net/dev but will not emit any
printk's (unless you do a "#define EI_DEBUG 3" at the top of 8390.c).

Paul.

diff -ur linux-oem/drivers/net/8390.c linux/drivers/net/8390.c
--- linux-oem/drivers/net/8390.c	Sat Apr 29 16:49:58 1995
+++ linux/drivers/net/8390.c	Fri Jun  2 00:11:05 1995
@@ -500,7 +500,7 @@
 		ei_local->current_page = next_frame;
 		outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
     }
-    /* If any worth-while packets have been received, dev_rint()
+    /* If any worth-while packets have been received, netif_rx()
        has done a mark_bh(NET_BH) for us and will work on them
        when we get to the bottom-half routine. */
 
@@ -508,8 +508,7 @@
 	if (rx_pkt_count > high_water_mark)
 		high_water_mark = rx_pkt_count;
 
-    /* Bug alert!  Reset ENISR_OVER to avoid spurious overruns! */
-    outb_p(ENISR_RX+ENISR_RX_ERR+ENISR_OVER, e8390_base+EN0_ISR);
+    outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
     return;
 }
 
@@ -546,7 +545,7 @@
     /* Remove packets right away. */
     ei_receive(dev);
     
-    outb_p(0xff, e8390_base+EN0_ISR);
+    outb_p(ENISR_OVER, e8390_base+EN0_ISR);
     /* Generic 8390 insns to start up again, same as in open_8390(). */
     outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
     outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR); /* xmit on. */

home help back first fref pref prev next nref lref last post