fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / lance.c
index a39f7a7..a384332 100644 (file)
@@ -19,7 +19,7 @@
        - alignment problem with 1.3.* kernel and some minor changes.
        Thomas Bogendoerfer (tsbogend@bigbug.franken.de):
        - added support for Linux/Alpha, but removed most of it, because
-        it worked only for the PCI chip. 
+        it worked only for the PCI chip.
       - added hook for the 32bit lance driver
       - added PCnetPCI II (79C970A) to chip table
        Paul Gortmaker (gpg109@rsphy1.anu.edu.au):
@@ -31,7 +31,7 @@
                   before unregister_netdev() which caused NULL pointer
                   reference later in the chain (in rtnetlink_fill_ifinfo())
                   -- Mika Kuoppala <miku@iki.fi>
-    
+
     Forward ported v1.14 to 2.1.129, merged the PCI and misc changes from
     the 2.1 version of the old driver - Alan Cox
 
        Vesselin Kostadinov <vesok at yahoo dot com > - 22/4/2004
 */
 
-static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
+static const char version[] = "lance.c:v1.16 2006/11/09 dplatt@3do.com, becker@cesdis.gsfc.nasa.gov\n";
 
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
@@ -56,8 +57,9 @@ static const char version[] = "lance.c:v1.15ac 1999/11/13 dplatt@3do.com, becker
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
@@ -297,27 +299,16 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_ISAP=2, PCNET_PCI=3, PCNET_VLB=4, PCNET_
 static unsigned char lance_need_isa_bounce_buffers = 1;
 
 static int lance_open(struct net_device *dev);
-static void lance_init_ring(struct net_device *dev, int mode);
+static void lance_init_ring(struct net_device *dev, gfp_t mode);
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lance_rx(struct net_device *dev);
-static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t lance_interrupt(int irq, void *dev_id);
 static int lance_close(struct net_device *dev);
 static struct net_device_stats *lance_get_stats(struct net_device *dev);
 static void set_multicast_list(struct net_device *dev);
 static void lance_tx_timeout (struct net_device *dev);
 
-\f
 
-static void cleanup_card(struct net_device *dev)
-{
-       struct lance_private *lp = dev->priv;
-       if (dev->dma != 4)
-               free_dma(dev->dma);
-       release_region(dev->base_addr, LANCE_TOTAL_SIZE);
-       kfree(lp->tx_bounce_buffs);
-       kfree((void*)lp->rx_buffs);
-       kfree(lp);
-}
 
 #ifdef MODULE
 #define MAX_CARDS              8       /* Max number of interfaces (cards) per module */
@@ -327,16 +318,16 @@ static int io[MAX_CARDS];
 static int dma[MAX_CARDS];
 static int irq[MAX_CARDS];
 
-MODULE_PARM(io, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(dma, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_CARDS) "i");
-MODULE_PARM(lance_debug, "i");
+module_param_array(io, int, NULL, 0);
+module_param_array(dma, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param(lance_debug, int, 0);
 MODULE_PARM_DESC(io, "LANCE/PCnet I/O base address(es),required");
 MODULE_PARM_DESC(dma, "LANCE/PCnet ISA DMA channel (ignored for some devices)");
 MODULE_PARM_DESC(irq, "LANCE/PCnet IRQ number (ignored for some devices)");
 MODULE_PARM_DESC(lance_debug, "LANCE/PCnet debug level (0-7)");
 
-int init_module(void)
+int __init init_module(void)
 {
        struct net_device *dev;
        int this_dev, found = 0;
@@ -355,11 +346,8 @@ int init_module(void)
                dev->base_addr = io[this_dev];
                dev->dma = dma[this_dev];
                if (do_lance_probe(dev) == 0) {
-                       if (register_netdev(dev) == 0) {
-                               dev_lance[found++] = dev;
-                               continue;
-                       }
-                       cleanup_card(dev);
+                       dev_lance[found++] = dev;
+                       continue;
                }
                free_netdev(dev);
                break;
@@ -369,14 +357,25 @@ int init_module(void)
        return -ENXIO;
 }
 
-void cleanup_module(void)
+static void cleanup_card(struct net_device *dev)
+{
+       struct lance_private *lp = dev->priv;
+       if (dev->dma != 4)
+               free_dma(dev->dma);
+       release_region(dev->base_addr, LANCE_TOTAL_SIZE);
+       kfree(lp->tx_bounce_buffs);
+       kfree((void*)lp->rx_buffs);
+       kfree(lp);
+}
+
+void __exit cleanup_module(void)
 {
        int this_dev;
 
        for (this_dev = 0; this_dev < MAX_CARDS; this_dev++) {
                struct net_device *dev = dev_lance[this_dev];
                if (dev) {
-                       unregister_netdev(dev); 
+                       unregister_netdev(dev);
                        cleanup_card(dev);
                        free_netdev(dev);
                }
@@ -432,6 +431,7 @@ static int __init do_lance_probe(struct net_device *dev)
        return -ENODEV;
 }
 
+#ifndef MODULE
 struct net_device * __init lance_probe(int unit)
 {
        struct net_device *dev = alloc_etherdev(0);
@@ -446,16 +446,12 @@ struct net_device * __init lance_probe(int unit)
        err = do_lance_probe(dev);
        if (err)
                goto out;
-       err = register_netdev(dev);
-       if (err)
-               goto out1;
        return dev;
-out1:
-       cleanup_card(dev);
 out:
        free_netdev(dev);
        return ERR_PTR(err);
 }
+#endif
 
 static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int options)
 {
@@ -469,20 +465,25 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        static int did_version;                 /* Already printed version info. */
        unsigned long flags;
        int err = -ENOMEM;
+       void __iomem *bios;
 
        /* First we look for special cases.
           Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
           There are two HP versions, check the BIOS for the configuration port.
           This method provided by L. Julliard, Laurent_Julliard@grenoble.hp.com.
           */
-       if (isa_readw(0x000f0102) == 0x5048)  {
+       bios = ioremap(0xf00f0, 0x14);
+       if (!bios)
+               return -ENOMEM;
+       if (readw(bios + 0x12) == 0x5048)  {
                static const short ioaddr_table[] = { 0x300, 0x320, 0x340, 0x360};
-               int hp_port = (isa_readl(0x000f00f1) & 1)  ? 0x499 : 0x99;
+               int hp_port = (readl(bios + 1) & 1)  ? 0x499 : 0x99;
                /* We can have boards other than the built-in!  Verify this is on-board. */
                if ((inb(hp_port) & 0xc0) == 0x80
                        && ioaddr_table[inb(hp_port) & 3] == ioaddr)
                        hp_builtin = hp_port;
        }
+       iounmap(bios);
        /* We also recognize the HP Vectra on-board here, but check below. */
        hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
                                && inb(ioaddr+2) == 0x09);
@@ -531,7 +532,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
 
        dev->base_addr = ioaddr;
        /* Make certain the data structures used by the LANCE are aligned and DMAble. */
-               
+
        lp = kmalloc(sizeof(*lp), GFP_DMA | GFP_KERNEL);
        if(lp==NULL)
                return -ENODEV;
@@ -656,7 +657,7 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
                        outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */
                        if (request_dma(dma, chipname))
                                continue;
-                               
+
                        flags=claim_dma_lock();
                        set_dma_mode(dma, DMA_MODE_CASCADE);
                        enable_dma(dma);
@@ -721,6 +722,9 @@ static int __init lance_probe1(struct net_device *dev, int ioaddr, int irq, int
        dev->tx_timeout = lance_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
 
+       err = register_netdev(dev);
+       if (err)
+               goto out_dma;
        return 0;
 out_dma:
        if (dev->dma != 4)
@@ -734,7 +738,7 @@ out_lp:
        return err;
 }
 
-\f
+
 static int
 lance_open(struct net_device *dev)
 {
@@ -798,7 +802,7 @@ lance_open(struct net_device *dev)
        while (i++ < 100)
                if (inw(ioaddr+LANCE_DATA) & 0x0100)
                        break;
-       /* 
+       /*
         * We used to clear the InitDone bit, 0x0100, here but Mark Stockton
         * reports that doing so triggers a bug in the '974.
         */
@@ -823,7 +827,7 @@ lance_open(struct net_device *dev)
    restarting the chip, but I'm too lazy to do so right now.  dplatt@3do.com
 */
 
-static void 
+static void
 lance_purge_ring(struct net_device *dev)
 {
        struct lance_private *lp = dev->priv;
@@ -832,7 +836,7 @@ lance_purge_ring(struct net_device *dev)
        /* Free all the skbuffs in the Rx and Tx queues. */
        for (i = 0; i < RX_RING_SIZE; i++) {
                struct sk_buff *skb = lp->rx_skbuff[i];
-               lp->rx_skbuff[i] = 0;
+               lp->rx_skbuff[i] = NULL;
                lp->rx_ring[i].base = 0;                /* Not owned by LANCE chip. */
                if (skb)
                        dev_kfree_skb_any(skb);
@@ -848,7 +852,7 @@ lance_purge_ring(struct net_device *dev)
 
 /* Initialize the LANCE Rx and Tx rings. */
 static void
-lance_init_ring(struct net_device *dev, int gfp)
+lance_init_ring(struct net_device *dev, gfp_t gfp)
 {
        struct lance_private *lp = dev->priv;
        int i;
@@ -864,7 +868,7 @@ lance_init_ring(struct net_device *dev, int gfp)
                lp->rx_skbuff[i] = skb;
                if (skb) {
                        skb->dev = dev;
-                       rx_buff = skb->tail;
+                       rx_buff = skb->data;
                } else
                        rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp);
                if (rx_buff == NULL)
@@ -876,7 +880,7 @@ lance_init_ring(struct net_device *dev, int gfp)
        /* The Tx buffer address is filled in as needed, but we do need to clear
           the upper ownership bit. */
        for (i = 0; i < TX_RING_SIZE; i++) {
-               lp->tx_skbuff[i] = 0;
+               lp->tx_skbuff[i] = NULL;
                lp->tx_ring[i].base = 0;
        }
 
@@ -965,12 +969,11 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* The old LANCE chips doesn't automatically pad buffers to min. size. */
        if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) {
                if (skb->len < ETH_ZLEN) {
-                       skb = skb_padto(skb, ETH_ZLEN);
-                       if (skb == NULL)
+                       if (skb_padto(skb, ETH_ZLEN))
                                goto out;
                        lp->tx_ring[entry].length = -ETH_ZLEN;
                }
-               else 
+               else
                        lp->tx_ring[entry].length = -skb->len;
        } else
                lp->tx_ring[entry].length = -skb->len;
@@ -1010,22 +1013,16 @@ out:
 }
 
 /* The LANCE interrupt handler. */
-static irqreturn_t
-lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+static irqreturn_t lance_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct lance_private *lp;
        int csr0, ioaddr, boguscnt=10;
        int must_restart;
 
-       if (dev == NULL) {
-               printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        ioaddr = dev->base_addr;
        lp = dev->priv;
-       
+
        spin_lock (&lp->devlock);
 
        outw(0x00, dev->base_addr + LANCE_ADDR);
@@ -1049,7 +1046,7 @@ lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                        while (dirty_tx < lp->cur_tx) {
                                int entry = dirty_tx & TX_RING_MOD_MASK;
                                int status = lp->tx_ring[entry].base;
-                       
+
                                if (status < 0)
                                        break;                  /* It still hasn't been Txed */
 
@@ -1081,7 +1078,7 @@ lance_interrupt(int irq, void *dev_id, struct pt_regs * regs)
                                   in the bounce buffer. */
                                if (lp->tx_skbuff[entry]) {
                                        dev_kfree_skb_irq(lp->tx_skbuff[entry]);
-                                       lp->tx_skbuff[entry] = 0;
+                                       lp->tx_skbuff[entry] = NULL;
                                }
                                dirty_tx++;
                        }
@@ -1140,7 +1137,7 @@ lance_rx(struct net_device *dev)
        struct lance_private *lp = dev->priv;
        int entry = lp->cur_rx & RX_RING_MOD_MASK;
        int i;
-               
+
        /* If we own the next entry, it's a new packet. Send it up. */
        while (lp->rx_ring[entry].base >= 0) {
                int status = lp->rx_ring[entry].base >> 24;
@@ -1158,12 +1155,12 @@ lance_rx(struct net_device *dev)
                        if (status & 0x04) lp->stats.rx_fifo_errors++;
                        lp->rx_ring[entry].base &= 0x03ffffff;
                }
-               else 
+               else
                {
                        /* Malloc up new buffer, compatible with net3. */
                        short pkt_len = (lp->rx_ring[entry].msg_length & 0xfff)-4;
                        struct sk_buff *skb;
-                       
+
                        if(pkt_len<60)
                        {
                                printk("%s: Runt packet!\n",dev->name);
@@ -1172,14 +1169,14 @@ lance_rx(struct net_device *dev)
                        else
                        {
                                skb = dev_alloc_skb(pkt_len+2);
-                               if (skb == NULL) 
+                               if (skb == NULL)
                                {
                                        printk("%s: Memory squeeze, deferring packet.\n", dev->name);
                                        for (i=0; i < RX_RING_SIZE; i++)
                                                if (lp->rx_ring[(entry+i) & RX_RING_MOD_MASK].base < 0)
                                                        break;
 
-                                       if (i > RX_RING_SIZE -2) 
+                                       if (i > RX_RING_SIZE -2)
                                        {
                                                lp->stats.rx_dropped++;
                                                lp->rx_ring[entry].base |= 0x80000000;
@@ -1279,8 +1276,6 @@ static void set_multicast_list(struct net_device *dev)
        outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance.  */
 
        if (dev->flags&IFF_PROMISC) {
-               /* Log any net taps. */
-               printk("%s: Promiscuous mode enabled.\n", dev->name);
                outw(15, ioaddr+LANCE_ADDR);
                outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
        } else {