fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / sk_mca.c
index 2d0d929..96e06c5 100644 (file)
@@ -1,17 +1,18 @@
-/* 
+/*
 net-3-driver for the SKNET MCA-based cards
 
 This is an extension to the Linux operating system, and is covered by the
 same GNU General Public License that covers that work.
 
-Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de, aarnold@elsa.de)
+Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de,
+                                 alfred.arnold@lancom.de)
 
 This driver is based both on the 3C523 driver and the SK_G16 driver.
 
 paper sources:
-  'PC Hardware: Aufbau, Funktionsweise, Programmierung' by 
+  'PC Hardware: Aufbau, Funktionsweise, Programmierung' by
   Hans-Peter Messmer for the basic Microchannel stuff
-  
+
   'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer
   for help on Ethernet driver programming
 
@@ -23,7 +24,7 @@ paper sources:
 
   'SK-NET MC2+ Technical Manual", Version 1.1 by Schneider&Koch for
   documentation on the MC2 bord
-  
+
   A big thank you to the S&K support for providing me so quickly with
   documentation!
 
@@ -33,7 +34,7 @@ paper sources:
 
   -> set debug level via ioctl instead of compile-time switches
   -> I didn't follow the development of the 2.1.x kernels, so my
-     assumptions about which things changed with which kernel version 
+     assumptions about which things changed with which kernel version
      are probably nonsense
 
 History:
@@ -56,7 +57,7 @@ History:
        fixed problem in GetLANCE leaving interrupts turned off
         increase TX queue to 4 packets to improve send performance
   May 29th, 1999
-       a few corrections in statistics, caught rcvr overruns 
+       a few corrections in statistics, caught rcvr overruns
         reinitialization of LANCE/board in critical situations
         MCA info implemented
        implemented LANCE multicast filter
@@ -92,13 +93,12 @@ History:
 #include <linux/mca-legacy.h>
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/skbuff.h>
+#include <linux/bitops.h>
 
 #include <asm/processor.h>
-#include <asm/bitops.h>
 #include <asm/io.h>
 
 #define _SK_MCA_DRIVER_
@@ -126,12 +126,13 @@ static unsigned char poly[] =
 #ifdef DEBUG
 static void dumpmem(struct net_device *dev, u32 start, u32 len)
 {
+       skmca_priv *priv = netdev_priv(dev);
        int z;
 
        for (z = 0; z < len; z++) {
                if ((z & 15) == 0)
                        printk("%04x:", z);
-               printk(" %02x", SKMCA_READB(dev->mem_start + start + z));
+               printk(" %02x", readb(priv->base + start + z));
                if ((z & 15) == 15)
                        printk("\n");
        }
@@ -219,21 +220,21 @@ static int __init dofind(int *junior, int firstslot)
 
 static void ResetBoard(struct net_device *dev)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
 
-       SKMCA_WRITEB(CTRL_RESET_ON, priv->ctrladdr);
+       writeb(CTRL_RESET_ON, priv->ctrladdr);
        udelay(10);
-       SKMCA_WRITEB(CTRL_RESET_OFF, priv->ctrladdr);
+       writeb(CTRL_RESET_OFF, priv->ctrladdr);
 }
 
 /* wait for LANCE interface to become not busy */
 
 static int WaitLANCE(struct net_device *dev)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        int t = 0;
 
-       while ((SKMCA_READB(priv->ctrladdr) & STAT_IO_BUSY) ==
+       while ((readb(priv->ctrladdr) & STAT_IO_BUSY) ==
               STAT_IO_BUSY) {
                udelay(1);
                if (++t > 1000) {
@@ -249,7 +250,7 @@ static int WaitLANCE(struct net_device *dev)
 
 static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        unsigned long flags;
 
        /* disable interrupts */
@@ -262,19 +263,17 @@ static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
 
        /* transfer register address to RAP */
 
-       SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
-                    priv->ctrladdr);
-       SKMCA_WRITEW(addr, priv->ioregaddr);
-       SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+       writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+       writew(addr, priv->ioregaddr);
+       writeb(IOCMD_GO, priv->cmdaddr);
        udelay(1);
        WaitLANCE(dev);
 
        /* transfer data to register */
 
-       SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA,
-                    priv->ctrladdr);
-       SKMCA_WRITEW(value, priv->ioregaddr);
-       SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+       writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr);
+       writew(value, priv->ioregaddr);
+       writeb(IOCMD_GO, priv->cmdaddr);
        udelay(1);
        WaitLANCE(dev);
 
@@ -287,7 +286,7 @@ static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
 
 static u16 GetLANCE(struct net_device *dev, u16 addr)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        unsigned long flags;
        unsigned int res;
 
@@ -301,21 +300,19 @@ static u16 GetLANCE(struct net_device *dev, u16 addr)
 
        /* transfer register address to RAP */
 
-       SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP,
-                    priv->ctrladdr);
-       SKMCA_WRITEW(addr, priv->ioregaddr);
-       SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+       writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
+       writew(addr, priv->ioregaddr);
+       writeb(IOCMD_GO, priv->cmdaddr);
        udelay(1);
        WaitLANCE(dev);
 
        /* transfer data from register */
 
-       SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA,
-                    priv->ctrladdr);
-       SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
+       writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr);
+       writeb(IOCMD_GO, priv->cmdaddr);
        udelay(1);
        WaitLANCE(dev);
-       res = SKMCA_READW(priv->ioregaddr);
+       res = readw(priv->ioregaddr);
 
        /* reenable interrupts */
 
@@ -328,6 +325,7 @@ static u16 GetLANCE(struct net_device *dev, u16 addr)
 
 static void InitDscrs(struct net_device *dev)
 {
+       skmca_priv *priv = netdev_priv(dev);
        u32 bufaddr;
 
        /* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
@@ -343,11 +341,10 @@ static void InitDscrs(struct net_device *dev)
                        descr.Flags = 0;
                        descr.Len = 0xf000;
                        descr.Status = 0;
-                       SKMCA_TOIO(dev->mem_start + RAM_TXBASE +
+                       memcpy_toio(priv->base + RAM_TXBASE +
                                   (z * sizeof(LANCE_TxDescr)), &descr,
                                   sizeof(LANCE_TxDescr));
-                       SKMCA_SETIO(dev->mem_start + bufaddr, 0,
-                                   RAM_BUFSIZE);
+                       memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
                        bufaddr += RAM_BUFSIZE;
                }
        }
@@ -363,11 +360,10 @@ static void InitDscrs(struct net_device *dev)
                        descr.Flags = RXDSCR_FLAGS_OWN;
                        descr.MaxLen = -RAM_BUFSIZE;
                        descr.Len = 0;
-                       SKMCA_TOIO(dev->mem_start + RAM_RXBASE +
+                       memcpy_toio(priv->base + RAM_RXBASE +
                                   (z * sizeof(LANCE_RxDescr)), &descr,
                                   sizeof(LANCE_RxDescr));
-                       SKMCA_SETIO(dev->mem_start + bufaddr, 0,
-                                   RAM_BUFSIZE);
+                       memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
                        bufaddr += RAM_BUFSIZE;
                }
        }
@@ -424,14 +420,14 @@ static unsigned int GetHash(char *address)
 
 static void InitLANCE(struct net_device *dev)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
 
        /* build up descriptors. */
 
        InitDscrs(dev);
 
        /* next RX descriptor to be read is the first one.  Since the LANCE
-          will start from the beginning after initialization, we have to 
+          will start from the beginning after initialization, we have to
           reset out pointers too. */
 
        priv->nextrx = 0;
@@ -477,6 +473,7 @@ static void StopLANCE(struct net_device *dev)
 
 static void InitBoard(struct net_device *dev)
 {
+       skmca_priv *priv = netdev_priv(dev);
        LANCE_InitBlock block;
 
        /* Lay out the shared RAM - first we create the init block for the LANCE.
@@ -491,7 +488,7 @@ static void InitBoard(struct net_device *dev)
        block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
        block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);
 
-       SKMCA_TOIO(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+       memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));
 
        /* initialize LANCE. Implicitly sets up other structures in RAM. */
 
@@ -571,7 +568,7 @@ static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0)
 
 static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
 
        /* update statistics */
 
@@ -587,7 +584,7 @@ static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0)
 
 static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        LANCE_RxDescr descr;
        unsigned int descraddr;
 
@@ -596,7 +593,7 @@ static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
        descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
        while (1) {
                /* read descriptor */
-               SKMCA_FROMIO(&descr, dev->mem_start + descraddr,
+               memcpy_fromio(&descr, priv->base + descraddr,
                             sizeof(LANCE_RxDescr));
 
                /* if we reach a descriptor we do not own, we're done */
@@ -628,8 +625,8 @@ static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
                        if (skb == NULL)
                                priv->stat.rx_dropped++;
                        else {
-                               SKMCA_FROMIO(skb_put(skb, descr.Len),
-                                            dev->mem_start +
+                               memcpy_fromio(skb_put(skb, descr.Len),
+                                            priv->base +
                                             descr.LowAddr, descr.Len);
                                skb->dev = dev;
                                skb->protocol = eth_type_trans(skb, dev);
@@ -646,7 +643,7 @@ static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
                descr.Flags |= RXDSCR_FLAGS_OWN;
 
                /* update descriptor in shared RAM */
-               SKMCA_TOIO(dev->mem_start + descraddr, &descr,
+               memcpy_toio(priv->base + descraddr, &descr,
                           sizeof(LANCE_RxDescr));
 
                /* go to next descriptor */
@@ -668,7 +665,7 @@ static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
 
 static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        LANCE_TxDescr descr;
        unsigned int descraddr;
 
@@ -678,7 +675,7 @@ static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
            RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
        while (priv->txbusy > 0) {
                /* read descriptor */
-               SKMCA_FROMIO(&descr, dev->mem_start + descraddr,
+               memcpy_fromio(&descr, priv->base + descraddr,
                             sizeof(LANCE_TxDescr));
 
                /* if the LANCE still owns this one, we've worked out all sent packets */
@@ -735,7 +732,7 @@ static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
 
 /* general interrupt entry */
 
-static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs)
+static irqreturn_t irq_handler(int irq, void *device)
 {
        struct net_device *dev = (struct net_device *) device;
        u16 csr0val;
@@ -797,9 +794,7 @@ static int skmca_getinfo(char *buf, int slot, void *d)
 
        if (dev == NULL)
                return len;
-       if (dev->priv == NULL)
-               return len;
-       priv = (skmca_priv *) dev->priv;
+       priv = netdev_priv(dev);
 
        /* print info */
 
@@ -824,12 +819,12 @@ static int skmca_getinfo(char *buf, int slot, void *d)
 static int skmca_open(struct net_device *dev)
 {
        int result;
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
 
        /* register resources - only necessary for IRQ */
        result =
            request_irq(priv->realirq, irq_handler,
-                       SA_SHIRQ | SA_SAMPLE_RANDOM, "sk_mca", dev);
+                       IRQF_SHARED | IRQF_SAMPLE_RANDOM, "sk_mca", dev);
        if (result != 0) {
                printk("%s: failed to register irq %d\n", dev->name,
                       dev->irq);
@@ -867,13 +862,13 @@ static int skmca_close(struct net_device *dev)
 
 static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        LANCE_TxDescr descr;
        unsigned int address;
        int tmplen, retval = 0;
        unsigned long flags;
 
-       /* if we get called with a NULL descriptor, the Ethernet layer thinks 
+       /* if we get called with a NULL descriptor, the Ethernet layer thinks
           our card is stuck an we should reset it.  We'll do this completely: */
 
        if (skb == NULL) {
@@ -893,8 +888,7 @@ static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
 
        /* get TX descriptor */
        address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
-       SKMCA_FROMIO(&descr, dev->mem_start + address,
-                    sizeof(LANCE_TxDescr));
+       memcpy_fromio(&descr, priv->base + address, sizeof(LANCE_TxDescr));
 
        /* enter packet length as 2s complement - assure minimum length */
        tmplen = skb->len;
@@ -902,7 +896,7 @@ static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
                tmplen = 60;
        descr.Len = 65536 - tmplen;
 
-       /* copy filler into RAM - in case we're filling up... 
+       /* copy filler into RAM - in case we're filling up...
           we're filling a bit more than necessary, but that doesn't harm
           since the buffer is far larger... */
        if (tmplen > skb->len) {
@@ -910,14 +904,14 @@ static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
                unsigned int destoffs = 0, l = strlen(fill);
 
                while (destoffs < tmplen) {
-                       SKMCA_TOIO(dev->mem_start + descr.LowAddr +
+                       memcpy_toio(priv->base + descr.LowAddr +
                                   destoffs, fill, l);
                        destoffs += l;
                }
        }
 
        /* do the real data copying */
-       SKMCA_TOIO(dev->mem_start + descr.LowAddr, skb->data, skb->len);
+       memcpy_toio(priv->base + descr.LowAddr, skb->data, skb->len);
 
        /* hand descriptor over to LANCE - this is the first and last chunk */
        descr.Flags =
@@ -944,8 +938,7 @@ static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
 
        /* write descriptor back to RAM */
-       SKMCA_TOIO(dev->mem_start + address, &descr,
-                  sizeof(LANCE_TxDescr));
+       memcpy_toio(priv->base + address, &descr, sizeof(LANCE_TxDescr));
 
        /* if no descriptors were active, give the LANCE a hint to read it
           immediately */
@@ -966,31 +959,24 @@ static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
 
 static struct net_device_stats *skmca_stats(struct net_device *dev)
 {
-       skmca_priv *priv = (skmca_priv *) dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
 
        return &(priv->stat);
 }
 
-/* we don't support runtime reconfiguration, since an MCA card can
-   be unambigously identified by its POS registers. */
-
-static int skmca_config(struct net_device *dev, struct ifmap *map)
-{
-       return 0;
-}
-
 /* switch receiver mode.  We use the LANCE's multicast filter to prefilter
    multicast addresses. */
 
 static void skmca_set_multicast_list(struct net_device *dev)
 {
+       skmca_priv *priv = netdev_priv(dev);
        LANCE_InitBlock block;
 
        /* first stop the LANCE... */
        StopLANCE(dev);
 
        /* ...then modify the initialization block... */
-       SKMCA_FROMIO(&block, dev->mem_start + RAM_INITBASE, sizeof(block));
+       memcpy_fromio(&block, priv->base + RAM_INITBASE, sizeof(block));
        if (dev->flags & IFF_PROMISC)
                block.Mode |= LANCE_INIT_PROM;
        else
@@ -1010,7 +996,7 @@ static void skmca_set_multicast_list(struct net_device *dev)
                }
        }
 
-       SKMCA_TOIO(dev->mem_start + RAM_INITBASE, &block, sizeof(block));
+       memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));
 
        /* ...then reinit LANCE with the correct flags */
        InitLANCE(dev);
@@ -1024,10 +1010,11 @@ static int startslot;           /* counts through slots when probing multiple devices */
 
 static void cleanup_card(struct net_device *dev)
 {
-       skmca_priv *priv = dev->priv;
+       skmca_priv *priv = netdev_priv(dev);
        DeinitBoard(dev);
        if (dev->irq != 0)
                free_irq(dev->irq, dev);
+       iounmap(priv->base);
        mca_mark_as_unused(priv->slot);
        mca_set_adapter_procfn(priv->slot, NULL, NULL);
 }
@@ -1111,13 +1098,20 @@ struct net_device * __init skmca_probe(int unit)
        printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
               junior ? "Junior MC2" : "MC2+", slot + 1);
 
-       /* allocate structure */
-       priv = dev->priv;
+       priv = netdev_priv(dev);
+       priv->base = ioremap(base, 0x4000);
+       if (!priv->base) {
+               mca_set_adapter_procfn(slot, NULL, NULL);
+               mca_mark_as_unused(slot);
+               free_netdev(dev);
+               return ERR_PTR(-ENOMEM);
+       }
+
        priv->slot = slot;
-       priv->macbase = base + 0x3fc0;
-       priv->ioregaddr = base + 0x3ff0;
-       priv->ctrladdr = base + 0x3ff2;
-       priv->cmdaddr = base + 0x3ff3;
+       priv->macbase = priv->base + 0x3fc0;
+       priv->ioregaddr = priv->base + 0x3ff0;
+       priv->ctrladdr = priv->base + 0x3ff2;
+       priv->cmdaddr = priv->base + 0x3ff3;
        priv->medium = medium;
        memset(&priv->stat, 0, sizeof(struct net_device_stats));
        spin_lock_init(&priv->lock);
@@ -1146,7 +1140,6 @@ struct net_device * __init skmca_probe(int unit)
        /* set methods */
        dev->open = skmca_open;
        dev->stop = skmca_close;
-       dev->set_config = skmca_config;
        dev->hard_start_xmit = skmca_tx;
        dev->do_ioctl = NULL;
        dev->get_stats = skmca_stats;
@@ -1155,7 +1148,7 @@ struct net_device * __init skmca_probe(int unit)
 
        /* copy out MAC address */
        for (i = 0; i < 6; i++)
-               dev->dev_addr[i] = SKMCA_READB(priv->macbase + (i << 1));
+               dev->dev_addr[i] = readb(priv->macbase + (i << 1));
 
        /* print config */
        printk("%s: IRQ %d, memory %#lx-%#lx, "