fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / sun3lance.c
index 01bdb23..c62e85d 100644 (file)
@@ -1,24 +1,24 @@
 /* sun3lance.c: Ethernet driver for SUN3 Lance chip */
 /*
 
 /* sun3lance.c: Ethernet driver for SUN3 Lance chip */
 /*
 
-  Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net).  
+  Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net).
   This driver is a part of the linux kernel, and is thus distributed
   under the GNU General Public License.
   This driver is a part of the linux kernel, and is thus distributed
   under the GNU General Public License.
-  
+
   The values used in LANCE_OBIO and LANCE_IRQ seem to be empirically
   true for the correct IRQ and address of the lance registers.  They
   have not been widely tested, however.  What we probably need is a
   "proper" way to search for a device in the sun3's prom, but, alas,
   The values used in LANCE_OBIO and LANCE_IRQ seem to be empirically
   true for the correct IRQ and address of the lance registers.  They
   have not been widely tested, however.  What we probably need is a
   "proper" way to search for a device in the sun3's prom, but, alas,
-  linux has no such thing.  
+  linux has no such thing.
 
   This driver is largely based on atarilance.c, by Roman Hodek.  Other
   sources of inspiration were the NetBSD sun3 am7990 driver, and the
 
   This driver is largely based on atarilance.c, by Roman Hodek.  Other
   sources of inspiration were the NetBSD sun3 am7990 driver, and the
-  linux sparc lance driver (sunlance.c).  
+  linux sparc lance driver (sunlance.c).
 
   There are more assumptions made throughout this driver, it almost
   certainly still needs work, but it does work at least for RARP/BOOTP and
   mounting the root NFS filesystem.
 
   There are more assumptions made throughout this driver, it almost
   certainly still needs work, but it does work at least for RARP/BOOTP and
   mounting the root NFS filesystem.
-  
+
 */
 
 static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
 */
 
 static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
@@ -38,6 +38,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.ne
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 
 #include <linux/skbuff.h>
 #include <linux/bitops.h>
 
+#include <asm/cacheflush.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/setup.h>
 #include <asm/irq.h>
 #include <asm/io.h>
@@ -55,7 +56,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.ne
 /* sun3/60 addr/irq for the lance chip.  If your sun is different,
    change this. */
 #define LANCE_OBIO 0x120000
 /* sun3/60 addr/irq for the lance chip.  If your sun is different,
    change this. */
 #define LANCE_OBIO 0x120000
-#define LANCE_IRQ IRQ3
+#define LANCE_IRQ IRQ_AUTO_3
 
 /* Debug level:
  *  0 = silent, print only serious errors
 
 /* Debug level:
  *  0 = silent, print only serious errors
@@ -71,7 +72,7 @@ static int lance_debug = LANCE_DEBUG;
 #else
 static int lance_debug = 1;
 #endif
 #else
 static int lance_debug = 1;
 #endif
-MODULE_PARM(lance_debug, "i");
+module_param(lance_debug, int, 0);
 MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
 MODULE_LICENSE("GPL");
 
 MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
 MODULE_LICENSE("GPL");
 
@@ -237,7 +238,7 @@ static int lance_probe( struct net_device *dev);
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
 static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
 static int lance_open( struct net_device *dev );
 static void lance_init_ring( struct net_device *dev );
 static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev );
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );
+static irqreturn_t lance_interrupt( int irq, void *dev_id);
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
 static struct net_device_stats *lance_get_stats( struct net_device *dev );
 static int lance_rx( struct net_device *dev );
 static int lance_close( struct net_device *dev );
 static struct net_device_stats *lance_get_stats( struct net_device *dev );
@@ -286,7 +287,7 @@ struct net_device * __init sun3lance_probe(int unit)
 
 out1:
 #ifdef CONFIG_SUN3
 
 out1:
 #ifdef CONFIG_SUN3
-       iounmap((void *)dev->base_addr);
+       iounmap((void __iomem *)dev->base_addr);
 #endif
 out:
        free_netdev(dev);
 #endif
 out:
        free_netdev(dev);
@@ -294,9 +295,9 @@ out:
 }
 
 static int __init lance_probe( struct net_device *dev)
 }
 
 static int __init lance_probe( struct net_device *dev)
-{      
+{
        unsigned long ioaddr;
        unsigned long ioaddr;
-       
+
        struct lance_private    *lp;
        int                     i;
        static int              did_version;
        struct lance_private    *lp;
        int                     i;
        static int              did_version;
@@ -313,7 +314,7 @@ static int __init lance_probe( struct net_device *dev)
 
        /* test to see if there's really a lance here */
        /* (CSRO_INIT shouldn't be readable) */
 
        /* test to see if there's really a lance here */
        /* (CSRO_INIT shouldn't be readable) */
-       
+
        ioaddr_probe = (volatile unsigned short *)ioaddr;
        tmp1 = ioaddr_probe[0];
        tmp2 = ioaddr_probe[1];
        ioaddr_probe = (volatile unsigned short *)ioaddr;
        tmp1 = ioaddr_probe[0];
        tmp2 = ioaddr_probe[1];
@@ -326,7 +327,7 @@ static int __init lance_probe( struct net_device *dev)
                ioaddr_probe[1] = tmp2;
 
 #ifdef CONFIG_SUN3
                ioaddr_probe[1] = tmp2;
 
 #ifdef CONFIG_SUN3
-               iounmap((void *)ioaddr);
+               iounmap((void __iomem *)ioaddr);
 #endif
                return 0;
        }
 #endif
                return 0;
        }
@@ -339,9 +340,9 @@ static int __init lance_probe( struct net_device *dev)
        lp->iobase = (volatile unsigned short *)ioaddr;
        dev->base_addr = (unsigned long)ioaddr; /* informational only */
 
        lp->iobase = (volatile unsigned short *)ioaddr;
        dev->base_addr = (unsigned long)ioaddr; /* informational only */
 
-       REGA(CSR0) = CSR0_STOP; 
+       REGA(CSR0) = CSR0_STOP;
 
 
-       request_irq(LANCE_IRQ, lance_interrupt, SA_INTERRUPT, "SUN3 Lance", dev);
+       request_irq(LANCE_IRQ, lance_interrupt, IRQF_DISABLED, "SUN3 Lance", dev);
        dev->irq = (unsigned short)LANCE_IRQ;
 
 
        dev->irq = (unsigned short)LANCE_IRQ;
 
 
@@ -378,7 +379,7 @@ static int __init lance_probe( struct net_device *dev)
 
        DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
               dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
 
        DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
               dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
-              (dvma_vtob(MEM->tx_head))));  
+              (dvma_vtob(MEM->tx_head))));
 
        if (did_version++ == 0)
                printk( version );
 
        if (did_version++ == 0)
                printk( version );
@@ -427,7 +428,7 @@ static int lance_open( struct net_device *dev )
        DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
 
        netif_start_queue(dev);
        DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
 
        netif_start_queue(dev);
-       
+
        DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
 
        return( 0 );
        DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
 
        return( 0 );
@@ -449,7 +450,7 @@ static void lance_init_ring( struct net_device *dev )
        for( i = 0; i < TX_RING_SIZE; i++ ) {
                MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
                MEM->tx_head[i].flag = 0;
        for( i = 0; i < TX_RING_SIZE; i++ ) {
                MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
                MEM->tx_head[i].flag = 0;
-               MEM->tx_head[i].base_hi = 
+               MEM->tx_head[i].base_hi =
                        (dvma_vtob(MEM->tx_data[i])) >>16;
                MEM->tx_head[i].length = 0;
                MEM->tx_head[i].misc = 0;
                        (dvma_vtob(MEM->tx_data[i])) >>16;
                MEM->tx_head[i].length = 0;
                MEM->tx_head[i].misc = 0;
@@ -458,7 +459,7 @@ static void lance_init_ring( struct net_device *dev )
        for( i = 0; i < RX_RING_SIZE; i++ ) {
                MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
                MEM->rx_head[i].flag = RMD1_OWN_CHIP;
        for( i = 0; i < RX_RING_SIZE; i++ ) {
                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 = 
+               MEM->rx_head[i].base_hi =
                        (dvma_vtob(MEM->rx_data[i])) >> 16;
                MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
                MEM->rx_head[i].msg_length = 0;
                        (dvma_vtob(MEM->rx_data[i])) >> 16;
                MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
                MEM->rx_head[i].msg_length = 0;
@@ -542,22 +543,22 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
                lance_init_ring(dev);
                REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
 
                lance_init_ring(dev);
                REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
-               
+
                netif_start_queue(dev);
                dev->trans_start = jiffies;
                netif_start_queue(dev);
                dev->trans_start = jiffies;
-               
+
                return 0;
        }
 
                return 0;
        }
 
-       
+
        /* Block a timer-based transmit from overlapping.  This could better be
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 
        /* Block a timer-based transmit from overlapping with us by
           stopping the queue for a bit... */
        /* Block a timer-based transmit from overlapping.  This could better be
           done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
 
        /* Block a timer-based transmit from overlapping with us by
           stopping the queue for a bit... */
-     
+
        netif_stop_queue(dev);
        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. */
        if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
                printk( "%s: tx queue lock!.\n", dev->name);
                /* don't clear dev->tbusy flag. */
@@ -593,7 +594,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
                printk(" data at 0x%08x len %d\n", (int)skb->data,
                       (int)skb->len );
        }
                printk(" data at 0x%08x len %d\n", (int)skb->data,
                       (int)skb->len );
        }
-#endif 
+#endif
        /* We're not prepared for the int until the last flags are set/reset.
         * And the int may happen already after setting the OWN_CHIP... */
        local_irq_save(flags);
        /* We're not prepared for the int until the last flags are set/reset.
         * And the int may happen already after setting the OWN_CHIP... */
        local_irq_save(flags);
@@ -632,7 +633,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
        lp->lock = 0;
        if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
 
        lp->lock = 0;
        if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
-           TMD1_OWN_HOST) 
+           TMD1_OWN_HOST)
                netif_start_queue(dev);
 
        local_irq_restore(flags);
                netif_start_queue(dev);
 
        local_irq_restore(flags);
@@ -642,7 +643,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
 
 /* The LANCE interrupt handler. */
 
 
 /* The LANCE interrupt handler. */
 
-static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
+static irqreturn_t lance_interrupt( int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp = netdev_priv(dev);
@@ -657,10 +658,10 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
        if (in_interrupt)
                DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name ));
        in_interrupt = 1;
        if (in_interrupt)
                DPRINTK( 2, ( "%s: Re-entering the interrupt handler.\n", dev->name ));
        in_interrupt = 1;
-       
+
  still_more:
        flush_cache_all();
  still_more:
        flush_cache_all();
-       
+
        AREG = CSR0;
        csr0 = DREG;
 
        AREG = CSR0;
        csr0 = DREG;
 
@@ -680,22 +681,22 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
 
 //             if(lance_debug >= 3) {
 //                     int i;
 
 //             if(lance_debug >= 3) {
 //                     int i;
-//                     
+//
 //                     printk("%s: tx int\n", dev->name);
 //                     printk("%s: tx int\n", dev->name);
-//                     
+//
 //                     for(i = 0; i < TX_RING_SIZE; i++)
 //                             printk("ring %d flag=%04x\n", i,
 //                                    MEM->tx_head[i].flag);
 //             }
 //                     for(i = 0; i < TX_RING_SIZE; i++)
 //                             printk("ring %d flag=%04x\n", i,
 //                                    MEM->tx_head[i].flag);
 //             }
-               
+
                while( old_tx != lp->new_tx) {
                while( old_tx != lp->new_tx) {
-                       struct lance_tx_head *head = &(MEM->tx_head[old_tx]); 
-                       
+                       struct lance_tx_head *head = &(MEM->tx_head[old_tx]);
+
                        DPRINTK(3, ("on tx_ring %d\n", old_tx));
 
                        if (head->flag & TMD1_OWN_CHIP)
                                break; /* It still hasn't been Txed */
                        DPRINTK(3, ("on tx_ring %d\n", old_tx));
 
                        if (head->flag & TMD1_OWN_CHIP)
                                break; /* It still hasn't been Txed */
-                               
+
                        if (head->flag & TMD1_ERR) {
                                int status = head->misc;
                                lp->stats.tx_errors++;
                        if (head->flag & TMD1_ERR) {
                                int status = head->misc;
                                lp->stats.tx_errors++;
@@ -705,7 +706,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
                                if (status & (TMD3_UFLO | TMD3_BUFF)) {
                                        lp->stats.tx_fifo_errors++;
                                        printk("%s: Tx FIFO error\n",
                                if (status & (TMD3_UFLO | TMD3_BUFF)) {
                                        lp->stats.tx_fifo_errors++;
                                        printk("%s: Tx FIFO error\n",
-                                              dev->name); 
+                                              dev->name);
                                        REGA(CSR0) = CSR0_STOP;
                                        REGA(CSR3) = CSR3_BSWP;
                                        lance_init_ring(dev);
                                        REGA(CSR0) = CSR0_STOP;
                                        REGA(CSR3) = CSR3_BSWP;
                                        lance_init_ring(dev);
@@ -713,11 +714,11 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
                                        return IRQ_HANDLED;
                                }
                        } else if(head->flag & (TMD1_ENP | TMD1_STP)) {
                                        return IRQ_HANDLED;
                                }
                        } else if(head->flag & (TMD1_ENP | TMD1_STP)) {
-                               
+
                                head->flag &= ~(TMD1_ENP | TMD1_STP);
                                if(head->flag & (TMD1_ONE | TMD1_MORE))
                                        lp->stats.collisions++;
                                head->flag &= ~(TMD1_ENP | TMD1_STP);
                                if(head->flag & (TMD1_ONE | TMD1_MORE))
                                        lp->stats.collisions++;
-                               
+
                                lp->stats.tx_packets++;
                                DPRINTK(3, ("cleared tx ring %d\n", old_tx));
                        }
                                lp->stats.tx_packets++;
                                DPRINTK(3, ("cleared tx ring %d\n", old_tx));
                        }
@@ -736,7 +737,7 @@ static irqreturn_t lance_interrupt( int irq, void *dev_id, struct pt_regs *fp)
 
        if (csr0 & CSR0_RINT)                   /* Rx interrupt */
                lance_rx( dev );
 
        if (csr0 & CSR0_RINT)                   /* Rx interrupt */
                lance_rx( dev );
-       
+
        /* Log misc errors. */
        if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */
        if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */
        /* Log misc errors. */
        if (csr0 & CSR0_BABL) lp->stats.tx_errors++; /* Tx babble. */
        if (csr0 & CSR0_MISS) lp->stats.rx_errors++; /* Missed a Rx frame. */
@@ -778,10 +779,10 @@ static int lance_rx( struct net_device *dev )
        while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
                struct lance_rx_head *head = &(MEM->rx_head[entry]);
                int status = head->flag;
        while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
                struct lance_rx_head *head = &(MEM->rx_head[entry]);
                int status = head->flag;
-               
+
                if (status != (RMD1_ENP|RMD1_STP)) {  /* There was an error. */
                        /* There is a tricky error noted by John Murphy,
                if (status != (RMD1_ENP|RMD1_STP)) {  /* There was an error. */
                        /* There is a tricky error noted by John Murphy,
-                          <murf@perftech.com> to Russ Nelson: Even with 
+                          <murf@perftech.com> to Russ Nelson: Even with
                           full-sized buffers it's possible for a jabber packet to use two
                           buffers, with only the last correctly noting the error. */
                        if (status & RMD1_ENP)  /* Only count a general error at the */
                           full-sized buffers it's possible for a jabber packet to use two
                           buffers, with only the last correctly noting the error. */
                        if (status & RMD1_ENP)  /* Only count a general error at the */
@@ -806,7 +807,7 @@ static int lance_rx( struct net_device *dev )
                                if (skb == NULL) {
                                        DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
                                                      dev->name ));
                                if (skb == NULL) {
                                        DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
                                                      dev->name ));
-                                       
+
                                        lp->stats.rx_dropped++;
                                        head->msg_length = 0;
                                        head->flag |= RMD1_OWN_CHIP;
                                        lp->stats.rx_dropped++;
                                        head->msg_length = 0;
                                        head->flag |= RMD1_OWN_CHIP;
@@ -833,7 +834,7 @@ static int lance_rx( struct net_device *dev )
                                if (lance_debug >= 3) {
                                        u_char *data = PKTBUF_ADDR(head);
                                        printk( "%s: RX pkt %d type 0x%04x len %d\n ", dev->name, entry, ((u_short *)data)[6], pkt_len);
                                if (lance_debug >= 3) {
                                        u_char *data = PKTBUF_ADDR(head);
                                        printk( "%s: RX pkt %d type 0x%04x len %d\n ", dev->name, entry, ((u_short *)data)[6], pkt_len);
-                               }                               
+                               }
 
 
                                skb->dev = dev;
 
 
                                skb->dev = dev;
@@ -914,7 +915,7 @@ static void set_multicast_list( struct net_device *dev )
 
        if (dev->flags & IFF_PROMISC) {
                /* Log any net taps. */
 
        if (dev->flags & IFF_PROMISC) {
                /* Log any net taps. */
-               DPRINTK( 1, ( "%s: Promiscuous mode enabled.\n", dev->name ));
+               DPRINTK( 3, ( "%s: Promiscuous mode enabled.\n", dev->name ));
                REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
        } else {
                short multicast_table[4];
                REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
        } else {
                short multicast_table[4];
@@ -944,7 +945,7 @@ static void set_multicast_list( struct net_device *dev )
 
 static struct net_device *sun3lance_dev;
 
 
 static struct net_device *sun3lance_dev;
 
-int init_module(void)
+int __init init_module(void)
 {
        sun3lance_dev = sun3lance_probe(-1);
        if (IS_ERR(sun3lance_dev))
 {
        sun3lance_dev = sun3lance_probe(-1);
        if (IS_ERR(sun3lance_dev))
@@ -952,11 +953,11 @@ int init_module(void)
        return 0;
 }
 
        return 0;
 }
 
-void cleanup_module(void)
+void __exit cleanup_module(void)
 {
        unregister_netdev(sun3lance_dev);
 #ifdef CONFIG_SUN3
 {
        unregister_netdev(sun3lance_dev);
 #ifdef CONFIG_SUN3
-       iounmap((void *)sun3lance_dev->base_addr);
+       iounmap((void __iomem *)sun3lance_dev->base_addr);
 #endif
        free_netdev(sun3lance_dev);
 }
 #endif
        free_netdev(sun3lance_dev);
 }