X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fnet%2Fsk_mca.c;h=96e06c51b75d36790a989e4ce4f11794836f2af5;hb=refs%2Fheads%2Fvserver;hp=ef640f908297404e3b787959d256153d98f0be0f;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/drivers/net/sk_mca.c b/drivers/net/sk_mca.c index ef640f908..96e06c51b 100644 --- a/drivers/net/sk_mca.c +++ b/drivers/net/sk_mca.c @@ -1,4 +1,4 @@ -/* +/* net-3-driver for the SKNET MCA-based cards This is an extension to the Linux operating system, and is covered by the @@ -10,9 +10,9 @@ Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.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 @@ -24,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! @@ -34,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: @@ -57,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 @@ -93,7 +93,6 @@ History: #include #include #include -#include #include #include #include @@ -127,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"); } @@ -220,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) { @@ -250,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 */ @@ -263,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); @@ -288,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; @@ -302,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 */ @@ -329,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 @@ -344,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; } } @@ -364,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; } } @@ -425,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; @@ -478,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. @@ -492,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. */ @@ -572,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 */ @@ -588,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; @@ -597,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 */ @@ -629,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); @@ -647,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 */ @@ -669,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; @@ -679,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 */ @@ -736,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; @@ -798,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 */ @@ -825,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); @@ -868,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) { @@ -894,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; @@ -903,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) { @@ -911,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 = @@ -945,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 */ @@ -967,7 +959,7 @@ 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); } @@ -977,13 +969,14 @@ static struct net_device_stats *skmca_stats(struct net_device *dev) 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 @@ -1003,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); @@ -1017,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); } @@ -1104,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); @@ -1147,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, "