Bug report for epic100 v1.04 + fix

Joachim Geiler achim@HTWM.De
Mon Jan 11 08:29:33 1999


Under high traffic, when lots of packets arrive, it is possible that the
entire receive ring is filled. If all packets have length < rx_copybreak 
there is no chance to leave the rx-loop of the interrupt routine,
because 
all descriptors are owned  by the driver and no descriptor has a null 
pointer (i.e. all packets are copied). In this case, the machine
freezes. 
The fix is simple, we can use the code of  the tulip - driver and force
to
leave the loop when RX_RING_SIZE entrys are processed. But in this case 
there is just another problem. When the whole ring is filled and the
chip
owns no more packet descriptors it stops receiving with RxFull
interrupt. 
The driver ignores this case. The machine doesn't freeze anymore, but
all
received packets are dropped. So we must start receiving again by
setting 
the RXQUEUED bit in the COMMAND register.
 
The following diff fixes the problem (at least for us). 

----------------------------------------------------------------------

--- epic100.c.ori	Thu Jan  7 17:17:13 1999
+++ epic100.c	Mon Jan 11 14:55:24 1999
@@ -956,6 +956,10 @@
 		if (status & (RxDone | RxStarted | RxEarlyWarn))
 			epic_rx(dev);
 
+	/*  start receive DMA again */
+                if (status & RxFull) 
+                	outl(0x0008, ioaddr + COMMAND);
+
 		if (status & (TxEmpty | TxDone)) {
 			int dirty_tx;
 
@@ -1068,13 +1072,17 @@
 	struct epic_private *ep = (struct epic_private *)dev->priv;
 	int entry = ep->cur_rx % RX_RING_SIZE;
 	int work_done = 0;
-
+/* make sure to process no more then RX_RING_SIZE entrys */ 	
+	int rx_work_limit=RX_RING_SIZE;
+	
 	if (epic_debug > 4)
 		printk(KERN_DEBUG " In epic_rx(), entry %d %8.8x.\n", entry,
 			   ep->rx_ring[entry].status);
 	/* If we own the next entry, it's a new packet. Send it up. */
-	while (ep->rx_ring[entry].status >= 0  &&  ep->rx_skbuff[entry]) {
+	while (ep->rx_ring[entry].status >= 0 ) {
 		int status = ep->rx_ring[entry].status;
+	        
+	        if (--rx_work_limit < 0) break; 
 
 		if (epic_debug > 4)
 			printk(KERN_DEBUG "  epic_rx() status was %8.8x.\n", status);

------------------------------------------------------------------

In the critical cases we now only get the message
      " Too much work at interrupt, IntrStatus=0x00258401 ",
which can be avoided by setting max_interrupt_work to a higher value.


Joachim Geiler, Juergen Seifert

achim@htwm.de	seifert@htwm.de
 | To unsubscribe, send mail to Majordomo@cesdis.gsfc.nasa.gov, and within the
 |  body of the mail, include only the text:
 |   unsubscribe this-list-name youraddress@wherever.org
 | You will be unsubscribed as speedily as possible.