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
- Lines: 171
- Date:
Fri May 8 00:20:47 1998
- Orig file:
v2.1.100/linux/drivers/net/sgiseeq.c
- Orig date:
Thu Feb 12 20:56:09 1998
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