patch-2.4.19 linux-2.4.19/drivers/net/sun3lance.c

Next file: linux-2.4.19/drivers/net/sunbmac.c
Previous file: linux-2.4.19/drivers/net/sun3_82586.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/net/sun3lance.c linux-2.4.19/drivers/net/sun3lance.c
@@ -21,7 +21,7 @@
   
 */
 
-static char *version = "sun3lance.c: v1.1 11/17/1999  Sam Creasey (sammy@oh.verio.com)\n";
+static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
 
 #include <linux/module.h>
 
@@ -35,16 +35,24 @@
 #include <linux/interrupt.h>
 #include <linux/init.h>
 #include <linux/ioport.h>
+#include <linux/delay.h>
 
 #include <asm/setup.h>
 #include <asm/irq.h>
 
 #include <asm/bitops.h>
 #include <asm/io.h>
-#include <asm/idprom.h>
 #include <asm/pgtable.h>
-#include <asm/sun3mmu.h>
+#include <asm/pgalloc.h>
 #include <asm/dvma.h>
+#include <asm/idprom.h>
+#include <asm/machines.h>
+
+#ifdef CONFIG_SUN3
+#include <asm/sun3mmu.h>
+#else
+#include <asm/sun3xprom.h>
+#endif
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
@@ -62,7 +70,7 @@
  *  3 = debug, print even more debug infos (packet data)
  */
 
-#define	LANCE_DEBUG	1
+#define	LANCE_DEBUG	0
 
 #ifdef LANCE_DEBUG
 static int lance_debug = LANCE_DEBUG;
@@ -139,7 +147,7 @@
 	struct lance_tx_head	tx_head[TX_RING_SIZE];
 	struct lance_rx_head	rx_head[RX_RING_SIZE];
 	char   rx_data[RX_RING_SIZE][PKT_BUF_SZ];
-	char   tx_data[RX_RING_SIZE][PKT_BUF_SZ];
+	char   tx_data[TX_RING_SIZE][PKT_BUF_SZ];
 };
 
 /* The driver's private device structure */
@@ -151,8 +159,8 @@
 	int old_tx, old_rx;     /* ring entry to be processed */
 	struct net_device_stats stats;
 /* These two must be longs for set_bit() */
-	long					tx_full;
-	long					lock;
+	long	    tx_full;
+	long	    lock;
 };
 
 /* I/O register access macros */
@@ -247,15 +255,27 @@
 {	
 	static int found;
 
+	/* check that this machine has an onboard lance */
+	switch(idprom->id_machtype) {
+	case SM_SUN3|SM_3_50:
+	case SM_SUN3|SM_3_60:
+	case SM_SUN3X|SM_3_80:
+		/* these machines have lance */
+		break;
+
+	default:
+		return(-ENODEV);
+	}
+
 	if(found)
-		return(ENODEV);
+		return(-ENODEV);
 
 	if (lance_probe(dev)) {
 			found = 1;
 			return( 0 );
 	}
 
-	return( ENODEV );
+	return( -ENODEV );
 }
 
 static int __init lance_probe( struct net_device *dev)
@@ -269,6 +289,7 @@
 	volatile unsigned short *ioaddr_probe;
 	unsigned short tmp1, tmp2;
 
+#ifdef CONFIG_SUN3
 	/* LANCE_OBIO can be found within the IO pmeg with some effort */
 	for(ioaddr = 0xfe00000; ioaddr < (0xfe00000 +
 	    SUN3_PMEG_SIZE); ioaddr += SUN3_PTE_SIZE) {
@@ -286,6 +307,9 @@
 	
 	if(!found)
 		return 0;
+#else
+	ioaddr = SUN3X_LANCE;
+#endif
 
 	/* test to see if there's really a lance here */
 	/* (CSRO_INIT shouldn't be readable) */
@@ -311,8 +335,9 @@
 			return 0;
 	}
 	lp = (struct lance_private *)dev->priv;
-	MEM = (struct lance_memory *)sun3_dvma_malloc(sizeof(struct
-							     lance_memory)); 
+
+	MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
+
 	lp->iobase = (volatile unsigned short *)ioaddr;
 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
 
@@ -331,7 +356,7 @@
 	/* copy in the ethernet address from the prom */
 	for(i = 0; i < 6 ; i++)
 	     dev->dev_addr[i] = idprom->id_ethaddr[i];
-	
+
 	/* tell the card it's ether address, bytes swapped */
 	MEM->init.hwaddr[0] = dev->dev_addr[1];
 	MEM->init.hwaddr[1] = dev->dev_addr[0];
@@ -346,20 +371,19 @@
 	MEM->init.mode = 0x0000;
 	MEM->init.filter[0] = 0x00000000;
 	MEM->init.filter[1] = 0x00000000;
-	MEM->init.rdra = sun3_dvma_vtop(MEM->rx_head);
+	MEM->init.rdra = dvma_vtob(MEM->rx_head);
 	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
-		(sun3_dvma_vtop(MEM->rx_head) >> 16);
-	MEM->init.tdra = sun3_dvma_vtop(MEM->tx_head);
+		(dvma_vtob(MEM->rx_head) >> 16);
+	MEM->init.tdra = dvma_vtob(MEM->tx_head);
 	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
-		(sun3_dvma_vtop(MEM->tx_head) >> 16);
+		(dvma_vtob(MEM->tx_head) >> 16);
 
 	DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
-	       sun3_dvma_vtop(&(MEM->init)), sun3_dvma_vtop(MEM->rx_head),
-	       (sun3_dvma_vtop(MEM->tx_head))));  
-
+	       dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
+	       (dvma_vtob(MEM->tx_head))));  
 
 	if (did_version++ == 0)
-		DPRINTK( 1, ( version ));
+		printk( version );
 
 	/* The LANCE-specific entries in the device structure. */
 	dev->open = &lance_open;
@@ -386,16 +410,8 @@
 
 	REGA(CSR0) = CSR0_STOP;
 
-	/* tell the lance the address of its init block */
-	REGA(CSR1) = sun3_dvma_vtop(&(MEM->init));
-	REGA(CSR2) = sun3_dvma_vtop(&(MEM->init)) >> 16;
-
 	lance_init_ring(dev);
 
-	/* Re-initialize the LANCE, and start it when done. */
-
-	REGA(CSR3) = CSR3_BSWP;
-
 	/* From now on, AREG is kept to point to CSR0 */
 	REGA(CSR0) = CSR0_INIT;
 
@@ -434,23 +450,52 @@
 	lp->old_rx = lp->old_tx = 0;
 
 	for( i = 0; i < TX_RING_SIZE; i++ ) {
-		MEM->tx_head[i].base = sun3_dvma_vtop(MEM->tx_data[i]);
+		MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
 		MEM->tx_head[i].flag = 0;
  		MEM->tx_head[i].base_hi = 
-			(sun3_dvma_vtop(MEM->tx_data[i])) >>16;
+			(dvma_vtob(MEM->tx_data[i])) >>16;
 		MEM->tx_head[i].length = 0;
 		MEM->tx_head[i].misc = 0;
 	}
 
 	for( i = 0; i < RX_RING_SIZE; i++ ) {
-		MEM->rx_head[i].base = sun3_dvma_vtop(MEM->rx_data[i]);
-		MEM->rx_head[i].flag = TMD1_OWN_CHIP;
+		MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
+		MEM->rx_head[i].flag = RMD1_OWN_CHIP;
 		MEM->rx_head[i].base_hi = 
-			(sun3_dvma_vtop(MEM->rx_data[i])) >> 16;
+			(dvma_vtob(MEM->rx_data[i])) >> 16;
 		MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
 		MEM->rx_head[i].msg_length = 0;
 	}
 
+	/* tell the card it's ether address, bytes swapped */
+	MEM->init.hwaddr[0] = dev->dev_addr[1];
+	MEM->init.hwaddr[1] = dev->dev_addr[0];
+	MEM->init.hwaddr[2] = dev->dev_addr[3];
+	MEM->init.hwaddr[3] = dev->dev_addr[2];
+	MEM->init.hwaddr[4] = dev->dev_addr[5];
+	MEM->init.hwaddr[5] = dev->dev_addr[4];
+
+	MEM->init.mode = 0x0000;
+	MEM->init.filter[0] = 0x00000000;
+	MEM->init.filter[1] = 0x00000000;
+	MEM->init.rdra = dvma_vtob(MEM->rx_head);
+	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
+		(dvma_vtob(MEM->rx_head) >> 16);
+	MEM->init.tdra = dvma_vtob(MEM->tx_head);
+	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
+		(dvma_vtob(MEM->tx_head) >> 16);
+
+
+	/* tell the lance the address of its init block */
+	REGA(CSR1) = dvma_vtob(&(MEM->init));
+	REGA(CSR2) = dvma_vtob(&(MEM->init)) >> 16;
+
+#ifdef CONFIG_SUN3X
+	REGA(CSR3) = CSR3_BSWP | CSR3_ACON | CSR3_BCON;
+#else
+	REGA(CSR3) = CSR3_BSWP;
+#endif
+
 }
 
 
@@ -512,7 +557,7 @@
 	   stopping the queue for a bit... */
      
 	netif_stop_queue(dev);
-
+	
 	if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
 		printk( "%s: tx queue lock!.\n", dev->name);
 		/* don't clear dev->tbusy flag. */
@@ -520,13 +565,22 @@
 	}
 
 	AREG = CSR0;
-//	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
-//				  dev->name, DREG ));
-	
+  	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
+  				  dev->name, DREG ));
+
+#ifdef CONFIG_SUN3X
+	/* this weirdness doesn't appear on sun3... */
+	if(!(DREG & CSR0_INIT)) {
+		DPRINTK( 1, ("INIT not set, reinitializing...\n"));
+		REGA( CSR0 ) = CSR0_STOP;
+		lance_init_ring(dev);
+		REGA( CSR0 ) = CSR0_INIT | CSR0_STRT;
+	}
+#endif
 
 	/* Fill in a Tx ring entry */
 #if 0
-	if (lance_debug >= 3) {
+	if (lance_debug >= 2) {
 		u_char *p;
 		int i;
 		printk( "%s: TX pkt %d type 0x%04x from ", dev->name,
@@ -566,7 +620,10 @@
 	lp->stats.tx_bytes += skb->len;
 
 	/* Trigger an immediate send poll. */
-	REGA(CSR0) = CSR0_INEA | CSR0_TDMD;
+	REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT;
+	AREG = CSR0;
+  	DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
+  				  dev->name, DREG ));
 	dev->trans_start = jiffies;
 	dev_kfree_skb( skb );
 
@@ -597,14 +654,15 @@
 	if (in_interrupt)
 		DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name ));
 	in_interrupt = 1;
-
+	
  still_more:
-
+	flush_cache_all();
+	
 	AREG = CSR0;
 	csr0 = DREG;
 
 	/* ack interrupts */
-	DREG = csr0 & (CSR0_TINT | CSR0_RINT);
+	DREG = csr0 & (CSR0_TINT | CSR0_RINT | CSR0_IDON);
 
 	/* clear errors */
 	if(csr0 & CSR0_ERR)

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