Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / drivers / net / 3c515.c
index fc86a35..91d1c4c 100644 (file)
@@ -34,7 +34,7 @@ DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n";
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
    Setting to > 1512 effectively disables this feature. */
-static const int rx_copybreak = 200;
+static int rx_copybreak = 200;
 
 /* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
 static const int mtu = 1500;
@@ -72,9 +72,9 @@ static int max_interrupt_work = 20;
 #include <linux/interrupt.h>
 #include <linux/timer.h>
 #include <linux/ethtool.h>
+#include <linux/bitops.h>
 
 #include <asm/uaccess.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/dma.h>
 
@@ -86,15 +86,7 @@ static int max_interrupt_work = 20;
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
 MODULE_LICENSE("GPL");
-
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
-MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
-MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
+MODULE_VERSION(DRV_VERSION);
 
 /* "Knobs" for adjusting internal parameters. */
 /* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
@@ -373,7 +365,7 @@ static int nopnp;
 #endif /* __ISAPNP__ */
 
 static struct net_device *corkscrew_scan(int unit);
-static void corkscrew_setup(struct net_device *dev, int ioaddr,
+static int corkscrew_setup(struct net_device *dev, int ioaddr,
                            struct pnp_dev *idev, int card_number);
 static int corkscrew_open(struct net_device *dev);
 static void corkscrew_timer(unsigned long arg);
@@ -409,6 +401,16 @@ static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
 
 #ifdef MODULE
 static int debug = -1;
+
+module_param(debug, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param(rx_copybreak, int, 0);
+module_param(max_interrupt_work, int, 0);
+MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
+MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
+MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
+
 /* A list of all installed Vortex devices, for removing the driver module. */
 /* we will need locking (and refcounting) if we ever use it for more */
 static LIST_HEAD(root_corkscrew_dev);
@@ -471,7 +473,7 @@ static int check_device(unsigned ioaddr)
 
 static void cleanup_card(struct net_device *dev)
 {
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        list_del_init(&vp->list);
        if (dev->dma)
                free_dma(dev->dma);
@@ -537,10 +539,9 @@ static struct net_device *corkscrew_scan(int unit)
                        printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                                inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
                        /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
-                       corkscrew_setup(dev, ioaddr, idev, cards_found++);
                        SET_NETDEV_DEV(dev, &idev->dev);
                        pnp_cards++;
-                       err = register_netdev(dev);
+                       err = corkscrew_setup(dev, ioaddr, idev, cards_found++);
                        if (!err)
                                return dev;
                        cleanup_card(dev);
@@ -556,8 +557,7 @@ no_pnp:
 
                printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
-               corkscrew_setup(dev, ioaddr, NULL, cards_found++);
-               err = register_netdev(dev);
+               err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
                if (!err)
                        return dev;
                cleanup_card(dev);
@@ -566,10 +566,10 @@ no_pnp:
        return NULL;
 }
 
-static void corkscrew_setup(struct net_device *dev, int ioaddr,
+static int corkscrew_setup(struct net_device *dev, int ioaddr,
                            struct pnp_dev *idev, int card_number)
 {
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        unsigned int eeprom[0x40], checksum = 0;        /* EEPROM contents */
        int i;
        int irq;
@@ -689,14 +689,15 @@ static void corkscrew_setup(struct net_device *dev, int ioaddr,
        dev->get_stats = &corkscrew_get_stats;
        dev->set_multicast_list = &set_rx_mode;
        dev->ethtool_ops = &netdev_ethtool_ops;
+
+       return register_netdev(dev);
 }
 \f
 
 static int corkscrew_open(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        union wn3_config config;
        int i;
 
@@ -821,7 +822,7 @@ static int corkscrew_open(struct net_device *dev)
                                break;  /* Bad news!  */
                        skb->dev = dev; /* Mark as being used by this device. */
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                       vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail);
+                       vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
                }
                vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]);     /* Wrap the ring. */
                outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
@@ -831,7 +832,7 @@ static int corkscrew_open(struct net_device *dev)
                outb(PKT_BUF_SZ >> 8, ioaddr + TxFreeThreshold);        /* Room for a packet. */
                /* Clear the Tx ring. */
                for (i = 0; i < TX_RING_SIZE; i++)
-                       vp->tx_skbuff[i] = 0;
+                       vp->tx_skbuff[i] = NULL;
                outl(0, ioaddr + DownListPtr);
        }
        /* Set receiver mode: presumably accept b-case and phys addr only. */
@@ -861,7 +862,7 @@ static void corkscrew_timer(unsigned long data)
 {
 #ifdef AUTOMEDIA
        struct net_device *dev = (struct net_device *) data;
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        unsigned long flags;
        int ok = 0;
@@ -953,8 +954,7 @@ static void corkscrew_timer(unsigned long data)
 static void corkscrew_timeout(struct net_device *dev)
 {
        int i;
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
        printk(KERN_WARNING
@@ -993,8 +993,7 @@ static void corkscrew_timeout(struct net_device *dev)
 static int corkscrew_start_xmit(struct sk_buff *skb,
                                struct net_device *dev)
 {
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
        /* Block a timer-based transmit from overlapping. */
@@ -1122,14 +1121,13 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
 {
        /* Use the now-standard shared IRQ implementation. */
        struct net_device *dev = dev_id;
-       struct corkscrew_private *lp;
+       struct corkscrew_private *lp = netdev_priv(dev);
        int ioaddr, status;
        int latency;
        int i = max_interrupt_work;
 
        ioaddr = dev->base_addr;
        latency = inb(ioaddr + Timer);
-       lp = (struct corkscrew_private *) dev->priv;
 
        spin_lock(&lp->lock);
        
@@ -1174,7 +1172,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
                                        break;  /* It still hasn't been processed. */
                                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++;
                        }
@@ -1261,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id,
 
 static int corkscrew_rx(struct net_device *dev)
 {
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        int i;
        short rx_status;
@@ -1328,8 +1326,7 @@ static int corkscrew_rx(struct net_device *dev)
 
 static int boomerang_rx(struct net_device *dev)
 {
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int entry = vp->cur_rx % RX_RING_SIZE;
        int ioaddr = dev->base_addr;
        int rx_status;
@@ -1409,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev)
                                break;  /* Bad news!  */
                        skb->dev = dev; /* Mark as being used by this device. */
                        skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
-                       vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail);
+                       vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
                        vp->rx_skbuff[entry] = skb;
                }
                vp->rx_ring[entry].status = 0;  /* Clear complete bit. */
@@ -1419,8 +1416,7 @@ static int boomerang_rx(struct net_device *dev)
 
 static int corkscrew_close(struct net_device *dev)
 {
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
        int i;
 
@@ -1458,7 +1454,7 @@ static int corkscrew_close(struct net_device *dev)
                for (i = 0; i < RX_RING_SIZE; i++)
                        if (vp->rx_skbuff[i]) {
                                dev_kfree_skb(vp->rx_skbuff[i]);
-                               vp->rx_skbuff[i] = 0;
+                               vp->rx_skbuff[i] = NULL;
                        }
        }
        if (vp->full_bus_master_tx) {   /* Free Boomerang bus master Tx buffers. */
@@ -1466,7 +1462,7 @@ static int corkscrew_close(struct net_device *dev)
                for (i = 0; i < TX_RING_SIZE; i++)
                        if (vp->tx_skbuff[i]) {
                                dev_kfree_skb(vp->tx_skbuff[i]);
-                               vp->tx_skbuff[i] = 0;
+                               vp->tx_skbuff[i] = NULL;
                        }
        }
 
@@ -1475,7 +1471,7 @@ static int corkscrew_close(struct net_device *dev)
 
 static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
 {
-       struct corkscrew_private *vp = (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
        unsigned long flags;
 
        if (netif_running(dev)) {
@@ -1495,8 +1491,7 @@ static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
        */
 static void update_stats(int ioaddr, struct net_device *dev)
 {
-       struct corkscrew_private *vp =
-           (struct corkscrew_private *) dev->priv;
+       struct corkscrew_private *vp = netdev_priv(dev);
 
        /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
        /* Switch to the stats window, and read everything. */