patch-2.1.101 linux/drivers/net/sgiseeq.c

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

diff -u --recursive --new-file v2.1.100/linux/drivers/net/sgiseeq.c linux/drivers/net/sgiseeq.c
@@ -1,7 +1,9 @@
-/* $Id: sgiseeq.c,v 1.3 1997/11/16 13:57:45 alan Exp $
+/*
  * sgiseeq.c: Seeq8003 ethernet driver for SGI machines.
  *
  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ *
+ * $Id: sgiseeq.c,v 1.5 1998/05/01 01:35:40 ralf Exp $
  */
 
 #include <linux/kernel.h>
@@ -15,6 +17,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 
+#include <asm/io.h>
 #include <asm/segment.h>
 #include <asm/system.h>
 #include <asm/bitops.h>
@@ -173,7 +176,7 @@
 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
 			ib->tx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
 			ib->tx_desc[i].tdma.pbuf = PHYSADDR(buffer);
-			flush_cache_all();
+//			flush_cache_all();
 		}
 		ib->tx_desc[i].tdma.cntinfo = (TCNTINFO_INIT);
 	}
@@ -186,7 +189,7 @@
 			buffer = (unsigned long) kmalloc(PKT_BUF_SZ, GFP_KERNEL);
 			ib->rx_desc[i].buf_vaddr = KSEG1ADDR(buffer);
 			ib->rx_desc[i].rdma.pbuf = PHYSADDR(buffer);
-			flush_cache_all();
+//			flush_cache_all();
 		}
 		ib->rx_desc[i].rdma.cntinfo = (RCNTINFO_INIT);
 	}
@@ -351,6 +354,25 @@
 	}
 }
 
+static inline void kick_tx(struct sgiseeq_tx_desc *td,
+			   volatile struct hpc3_ethregs *hregs)
+{
+	/* If the HPC aint doin nothin, and there are more packets
+	 * with ETXD cleared and XIU set we must make very certain
+	 * that we restart the HPC else we risk locking up the
+	 * adapter.  The following code is only safe iff the HPCDMA
+	 * is not active!
+	 */
+	while((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
+	      (HPCDMA_XIU | HPCDMA_ETXD))
+		td = (struct sgiseeq_tx_desc *)
+			KSEG1ADDR(td->tdma.pnext);
+	if(td->tdma.cntinfo & HPCDMA_XIU) {
+		hregs->tx_ndptr = PHYSADDR(td);
+		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
+	}
+}
+
 static inline void sgiseeq_tx(struct device *dev, struct sgiseeq_private *sp,
 			      volatile struct hpc3_ethregs *hregs,
 			      volatile struct sgiseeq_regs *sregs)
@@ -361,32 +383,14 @@
 
 	tx_maybe_reset_collisions(sp, sregs);
 
-	if(!(status & HPC3_ETXCTRL_ACTIVE)) {
-		if(!(status & SEEQ_TSTAT_PTRANS)) {
-			/* Oops, HPC detected some sort of error. */
-			if(status & SEEQ_TSTAT_R16)
-				sp->stats.tx_aborted_errors++;
-			if(status & SEEQ_TSTAT_UFLOW)
-				sp->stats.tx_fifo_errors++;
-			if(status & SEEQ_TSTAT_LCLS)
-				sp->stats.collisions++;
-		}
-		/* If the HPC aint doin nothin, and there are more packets
-		 * with ETXD cleared and XIU set we must make very certain
-		 * that we restart the HPC else we risk locking up the
-		 * adapter.  The following read of tx_ndptr is only safe
-		 * iff the HPCDMA is not active!
-		 */
-		td = (struct sgiseeq_tx_desc *)
-			KSEG1ADDR(((hregs->tx_ndptr) & ~0xf));
-		while((td->tdma.cntinfo & (HPCDMA_XIU | HPCDMA_ETXD)) ==
-		      (HPCDMA_XIU | HPCDMA_ETXD))
-			td = (struct sgiseeq_tx_desc *)
-				KSEG1ADDR(td->tdma.pnext);
-		if(td->tdma.cntinfo & HPCDMA_XIU) {
-			hregs->tx_ndptr = PHYSADDR(td);
-			hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
-		}
+	if(!(status & (HPC3_ETXCTRL_ACTIVE | SEEQ_TSTAT_PTRANS))) {
+		/* Oops, HPC detected some sort of error. */
+		if(status & SEEQ_TSTAT_R16)
+			sp->stats.tx_aborted_errors++;
+		if(status & SEEQ_TSTAT_UFLOW)
+			sp->stats.tx_fifo_errors++;
+		if(status & SEEQ_TSTAT_LCLS)
+			sp->stats.collisions++;
 	}
 
 	/* Ack 'em... */
@@ -395,8 +399,13 @@
 
 		if(!(td->tdma.cntinfo & (HPCDMA_XIU)))
 			break;
-		if(!(td->tdma.cntinfo & (HPCDMA_ETXD)))
+		if(!(td->tdma.cntinfo & (HPCDMA_ETXD))) {
+			if(!(status & HPC3_ETXCTRL_ACTIVE)) {
+				hregs->tx_ndptr = PHYSADDR(td);
+				hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
+			}
 			break;
+		}
 		sp->stats.tx_packets++;
 		sp->tx_old = NEXT_TX(sp->tx_old);
 		td->tdma.cntinfo &= ~(HPCDMA_XIU | HPCDMA_XIE);
@@ -501,13 +510,14 @@
 	/* Are we bolixed? */
 	if(dev->tbusy) {
 		int tickssofar = jiffies - dev->trans_start;
+		if (tickssofar < 20)
+			return 1;
 
 		printk("%s: transmit timed out, ticks=%d resetting\n",
 		       dev->name, tickssofar);
 		sgiseeq_reset(dev);
 		return 0;
 	}
-
 	/* Are we getting in someone else's way? */
 	if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
 		printk("%s: Transmitter access conflict.\n", dev->name);
@@ -565,10 +575,9 @@
 	sp->tx_new = NEXT_TX(sp->tx_new); /* Advance. */
 
 	/* Maybe kick the HPC back into motion. */
-	if(!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE)) {
-		hregs->tx_ndptr = PHYSADDR(&sp->srings.tx_desc[sp->tx_old]);
-		hregs->tx_ctrl = HPC3_ETXCTRL_ACTIVE;
-	}
+	if(!(hregs->tx_ctrl & HPC3_ETXCTRL_ACTIVE))
+		kick_tx(&sp->srings.tx_desc[sp->tx_old], hregs);
+
 	dev->trans_start = jiffies;
 	dev_kfree_skb(skb);
 
@@ -656,15 +665,17 @@
 	sp->name = sgiseeqstr;
 
 	sp->srings.rx_desc = (struct sgiseeq_rx_desc *)
-		(KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])));
+	                     (KSEG1ADDR(ALIGNED(&sp->srings.rxvector[0])));
+	dma_cache_wback_inv((unsigned long)&sp->srings.rxvector,
+	                    sizeof(sp->srings.rxvector));
 	sp->srings.tx_desc = (struct sgiseeq_tx_desc *)
-		(KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])));
-	flush_cache_all();
+	                     (KSEG1ADDR(ALIGNED(&sp->srings.txvector[0])));
+	dma_cache_wback_inv((unsigned long)&sp->srings.txvector,
+	                    sizeof(sp->srings.txvector));
 
 	/* A couple calculations now, saves many cycles later. */
 	setup_rx_ring(sp->srings.rx_desc, SEEQ_RX_BUFFERS);
 	setup_tx_ring(sp->srings.tx_desc, SEEQ_TX_BUFFERS);
-	flush_cache_all();
 
 	/* Reset the chip. */
 	hpc3_eth_reset((volatile struct hpc3_ethregs *) hregs);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov