fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / 3c509.c
index 830528d..f791bf0 100644 (file)
@@ -28,7 +28,7 @@
        FIXES:
                Alan Cox:       Removed the 'Unexpected interrupt' bug.
                Michael Meskes: Upgraded to Donald Becker's version 1.07.
        FIXES:
                Alan Cox:       Removed the 'Unexpected interrupt' bug.
                Michael Meskes: Upgraded to Donald Becker's version 1.07.
-               Alan Cox:       Increased the eeprom delay. Regardless of 
+               Alan Cox:       Increased the eeprom delay. Regardless of
                                what the docs say some people definitely
                                get problems with lower (but in card spec)
                                delays
                                what the docs say some people definitely
                                get problems with lower (but in card spec)
                                delays
@@ -68,7 +68,6 @@
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 10;
 
 /* Maximum events (Rx packets, etc.) to handle at each interrupt. */
 static int max_interrupt_work = 10;
 
-#include <linux/config.h>
 #include <linux/module.h>
 #ifdef CONFIG_MCA
 #include <linux/mca.h>
 #include <linux/module.h>
 #ifdef CONFIG_MCA
 #include <linux/mca.h>
@@ -100,6 +99,10 @@ static int max_interrupt_work = 10;
 static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
 static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
 
 static char versionA[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
 static char versionB[] __initdata = "http://www.scyld.com/network/3c509.html\n";
 
+#if defined(CONFIG_PM) && (defined(CONFIG_MCA) || defined(CONFIG_EISA))
+#define EL3_SUSPEND
+#endif
+
 #ifdef EL3_DEBUG
 static int el3_debug = EL3_DEBUG;
 #else
 #ifdef EL3_DEBUG
 static int el3_debug = EL3_DEBUG;
 #else
@@ -159,7 +162,7 @@ enum RxFilter {
 #define WN4_MEDIA      0x0A            /* Window 4: Various transcvr/media bits. */
 #define        MEDIA_TP        0x00C0          /* Enable link beat and jabber for 10baseT. */
 #define WN4_NETDIAG    0x06            /* Window 4: Net diagnostic */
 #define WN4_MEDIA      0x0A            /* Window 4: Various transcvr/media bits. */
 #define        MEDIA_TP        0x00C0          /* Enable link beat and jabber for 10baseT. */
 #define WN4_NETDIAG    0x06            /* Window 4: Net diagnostic */
-#define FD_ENABLE      0x8000          /* Enable full-duplex ("external loopback") */  
+#define FD_ENABLE      0x8000          /* Enable full-duplex ("external loopback") */
 
 /*
  * Must be a power of two (we use a binary and in the
 
 /*
  * Must be a power of two (we use a binary and in the
@@ -174,9 +177,6 @@ struct el3_private {
        /* skb send-queue */
        int head, size;
        struct sk_buff *queue[SKB_QUEUE_SIZE];
        /* skb send-queue */
        int head, size;
        struct sk_buff *queue[SKB_QUEUE_SIZE];
-#ifdef CONFIG_PM_LEGACY
-       struct pm_dev *pmdev;
-#endif
        enum {
                EL3_MCA,
                EL3_PNP,
        enum {
                EL3_MCA,
                EL3_PNP,
@@ -191,7 +191,7 @@ static ushort id_read_eeprom(int index);
 static ushort read_eeprom(int ioaddr, int index);
 static int el3_open(struct net_device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static ushort read_eeprom(int ioaddr, int index);
 static int el3_open(struct net_device *dev);
 static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t el3_interrupt(int irq, void *dev_id);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
 static int el3_rx(struct net_device *dev);
 static void update_stats(struct net_device *dev);
 static struct net_device_stats *el3_get_stats(struct net_device *dev);
 static int el3_rx(struct net_device *dev);
@@ -200,12 +200,16 @@ static void set_multicast_list(struct net_device *dev);
 static void el3_tx_timeout (struct net_device *dev);
 static void el3_down(struct net_device *dev);
 static void el3_up(struct net_device *dev);
 static void el3_tx_timeout (struct net_device *dev);
 static void el3_down(struct net_device *dev);
 static void el3_up(struct net_device *dev);
-static struct ethtool_ops ethtool_ops;
-#ifdef CONFIG_PM_LEGACY
-static int el3_suspend(struct pm_dev *pdev);
-static int el3_resume(struct pm_dev *pdev);
-static int el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data);
+static const struct ethtool_ops ethtool_ops;
+#ifdef EL3_SUSPEND
+static int el3_suspend(struct device *, pm_message_t);
+static int el3_resume(struct device *);
+#else
+#define el3_suspend NULL
+#define el3_resume NULL
 #endif
 #endif
+
+
 /* generic device remove for all device types */
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 static int el3_device_remove (struct device *device);
 /* generic device remove for all device types */
 #if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 static int el3_device_remove (struct device *device);
@@ -221,6 +225,7 @@ static struct eisa_device_id el3_eisa_ids[] = {
                { "TCM5095" },
                { "" }
 };
                { "TCM5095" },
                { "" }
 };
+MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
 
 static int el3_eisa_probe (struct device *device);
 
 
 static int el3_eisa_probe (struct device *device);
 
@@ -229,7 +234,9 @@ static struct eisa_driver el3_eisa_driver = {
                .driver   = {
                                .name    = "3c509",
                                .probe   = el3_eisa_probe,
                .driver   = {
                                .name    = "3c509",
                                .probe   = el3_eisa_probe,
-                               .remove  = __devexit_p (el3_device_remove)
+                               .remove  = __devexit_p (el3_device_remove),
+                               .suspend = el3_suspend,
+                               .resume  = el3_resume,
                }
 };
 #endif
                }
 };
 #endif
@@ -262,6 +269,8 @@ static struct mca_driver el3_mca_driver = {
                                .bus = &mca_bus_type,
                                .probe = el3_mca_probe,
                                .remove = __devexit_p(el3_device_remove),
                                .bus = &mca_bus_type,
                                .probe = el3_mca_probe,
                                .remove = __devexit_p(el3_device_remove),
+                               .suspend = el3_suspend,
+                               .resume  = el3_resume,
                },
 };
 #endif /* CONFIG_MCA */
                },
 };
 #endif /* CONFIG_MCA */
@@ -342,7 +351,7 @@ static int __init el3_common_init(struct net_device *dev)
        {
                const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
                printk("%s: 3c5x9 found at %#3.3lx, %s port, address ",
        {
                const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
                printk("%s: 3c5x9 found at %#3.3lx, %s port, address ",
-                       dev->name, dev->base_addr, 
+                       dev->name, dev->base_addr,
                        if_names[(dev->if_port & 0x03)]);
        }
 
                        if_names[(dev->if_port & 0x03)]);
        }
 
@@ -362,10 +371,6 @@ static void el3_common_remove (struct net_device *dev)
        struct el3_private *lp = netdev_priv(dev);
 
        (void) lp;                              /* Keep gcc quiet... */
        struct el3_private *lp = netdev_priv(dev);
 
        (void) lp;                              /* Keep gcc quiet... */
-#ifdef CONFIG_PM_LEGACY
-       if (lp->pmdev)
-               pm_unregister(lp->pmdev);
-#endif
 #if defined(__ISAPNP__)
        if (lp->type == EL3_PNP)
                pnp_device_detach(to_pnp_dev(lp->dev));
 #if defined(__ISAPNP__)
        if (lp->type == EL3_PNP)
                pnp_device_detach(to_pnp_dev(lp->dev));
@@ -524,7 +529,7 @@ no_pnp:
        SET_MODULE_OWNER(dev);
 
        netdev_boot_setup_check(dev);
        SET_MODULE_OWNER(dev);
 
        netdev_boot_setup_check(dev);
-       
+
        /* Set passed-in IRQ or I/O Addr. */
        if (dev->irq > 1  &&  dev->irq < 16)
                        irq = dev->irq;
        /* Set passed-in IRQ or I/O Addr. */
        if (dev->irq > 1  &&  dev->irq < 16)
                        irq = dev->irq;
@@ -572,16 +577,6 @@ no_pnp:
        if (err)
                goto out1;
 
        if (err)
                goto out1;
 
-#ifdef CONFIG_PM_LEGACY
-       /* register power management */
-       lp->pmdev = pm_register(PM_ISA_DEV, card_idx, el3_pm_callback);
-       if (lp->pmdev) {
-               struct pm_dev *p;
-               p = lp->pmdev;
-               p->data = (struct net_device *)dev;
-       }
-#endif
-
        el3_cards++;
        lp->next_dev = el3_root_dev;
        el3_root_dev = dev;
        el3_cards++;
        lp->next_dev = el3_root_dev;
        el3_root_dev = dev;
@@ -636,7 +631,7 @@ static int __init el3_mca_probe(struct device *device)
        if_port = pos4 & 0x03;
 
        irq = mca_device_transform_irq(mdev, irq);
        if_port = pos4 & 0x03;
 
        irq = mca_device_transform_irq(mdev, irq);
-       ioaddr = mca_device_transform_ioport(mdev, ioaddr); 
+       ioaddr = mca_device_transform_ioport(mdev, ioaddr);
        if (el3_debug > 2) {
                        printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
        }
        if (el3_debug > 2) {
                        printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
        }
@@ -673,7 +668,7 @@ static int __init el3_mca_probe(struct device *device)
        el3_cards++;
        return 0;
 }
        el3_cards++;
        return 0;
 }
-               
+
 #endif /* CONFIG_MCA */
 
 #ifdef CONFIG_EISA
 #endif /* CONFIG_MCA */
 
 #ifdef CONFIG_EISA
@@ -690,7 +685,7 @@ static int __init el3_eisa_probe (struct device *device)
        /* Yeepee, The driver framework is calling us ! */
        edev = to_eisa_device (device);
        ioaddr = edev->base_addr;
        /* Yeepee, The driver framework is calling us ! */
        edev = to_eisa_device (device);
        ioaddr = edev->base_addr;
-       
+
        if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
                return -EBUSY;
 
        if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
                return -EBUSY;
 
@@ -757,7 +752,7 @@ static int __devexit el3_device_remove (struct device *device)
 static ushort read_eeprom(int ioaddr, int index)
 {
        outw(EEPROM_READ + index, ioaddr + 10);
 static ushort read_eeprom(int ioaddr, int index)
 {
        outw(EEPROM_READ + index, ioaddr + 10);
-       /* Pause for at least 162 us. for the read to take place. 
+       /* Pause for at least 162 us. for the read to take place.
           Some chips seem to require much longer */
        mdelay(2);
        return inw(ioaddr + 12);
           Some chips seem to require much longer */
        mdelay(2);
        return inw(ioaddr + 12);
@@ -775,7 +770,7 @@ static ushort __init id_read_eeprom(int index)
        /* Pause for at least 162 us. for the read to take place. */
        /* Some chips seem to require much longer */
        mdelay(4);
        /* Pause for at least 162 us. for the read to take place. */
        /* Some chips seem to require much longer */
        mdelay(4);
-       
+
        for (bit = 15; bit >= 0; bit--)
                word = (word << 1) + (inb(id_port) & 0x01);
 
        for (bit = 15; bit >= 0; bit--)
                word = (word << 1) + (inb(id_port) & 0x01);
 
@@ -844,7 +839,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        netif_stop_queue (dev);
 
        lp->stats.tx_bytes += skb->len;
        netif_stop_queue (dev);
 
        lp->stats.tx_bytes += skb->len;
-       
+
        if (el3_debug > 4) {
                printk("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
        if (el3_debug > 4) {
                printk("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
@@ -885,11 +880,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        outw(skb->len, ioaddr + TX_FIFO);
        outw(0x00, ioaddr + TX_FIFO);
        /* ... and the packet rounded to a doubleword. */
        outw(skb->len, ioaddr + TX_FIFO);
        outw(0x00, ioaddr + TX_FIFO);
        /* ... and the packet rounded to a doubleword. */
-#ifdef  __powerpc__
-       outsl_ns(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-#else
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
        outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-#endif
 
        dev->trans_start = jiffies;
        if (inw(ioaddr + TX_FREE) > 1536)
 
        dev->trans_start = jiffies;
        if (inw(ioaddr + TX_FREE) > 1536)
@@ -919,18 +910,13 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 /* The EL3 interrupt handler. */
 static irqreturn_t
 
 /* The EL3 interrupt handler. */
 static irqreturn_t
-el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+el3_interrupt(int irq, void *dev_id)
 {
 {
-       struct net_device *dev = (struct net_device *)dev_id;
+       struct net_device *dev = dev_id;
        struct el3_private *lp;
        int ioaddr, status;
        int i = max_interrupt_work;
 
        struct el3_private *lp;
        int ioaddr, status;
        int i = max_interrupt_work;
 
-       if (dev == NULL) {
-               printk ("el3_interrupt(): irq %d for unknown device.\n", irq);
-               return IRQ_NONE;
-       }
-
        lp = netdev_priv(dev);
        spin_lock(&lp->lock);
 
        lp = netdev_priv(dev);
        spin_lock(&lp->lock);
 
@@ -1015,7 +1001,7 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 static void el3_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
 static void el3_poll_controller(struct net_device *dev)
 {
        disable_irq(dev->irq);
-       el3_interrupt(dev->irq, dev, NULL);
+       el3_interrupt(dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
        enable_irq(dev->irq);
 }
 #endif
@@ -1030,7 +1016,7 @@ el3_get_stats(struct net_device *dev)
         *      This is fast enough not to bother with disable IRQ
         *      stuff.
         */
         *      This is fast enough not to bother with disable IRQ
         *      stuff.
         */
-        
+
        spin_lock_irqsave(&lp->lock, flags);
        update_stats(dev);
        spin_unlock_irqrestore(&lp->lock, flags);
        spin_lock_irqsave(&lp->lock, flags);
        update_stats(dev);
        spin_unlock_irqrestore(&lp->lock, flags);
@@ -1109,13 +1095,8 @@ el3_rx(struct net_device *dev)
                                skb_reserve(skb, 2);     /* Align IP on 16 byte */
 
                                /* 'skb->data' points to the start of sk_buff data area. */
                                skb_reserve(skb, 2);     /* Align IP on 16 byte */
 
                                /* 'skb->data' points to the start of sk_buff data area. */
-#ifdef  __powerpc__
-                               insl_ns(ioaddr+RX_FIFO, skb_put(skb,pkt_len),
-                                                          (pkt_len + 3) >> 2);
-#else
                                insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
                                         (pkt_len + 3) >> 2);
                                insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
                                         (pkt_len + 3) >> 2);
-#endif
 
                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb,dev);
 
                                outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
                                skb->protocol = eth_type_trans(skb,dev);
@@ -1174,7 +1155,7 @@ el3_close(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
        struct el3_private *lp = netdev_priv(dev);
 {
        int ioaddr = dev->base_addr;
        struct el3_private *lp = netdev_priv(dev);
-       
+
        if (el3_debug > 2)
                printk("%s: Shutting down ethercard.\n", dev->name);
 
        if (el3_debug > 2)
                printk("%s: Shutting down ethercard.\n", dev->name);
 
@@ -1193,7 +1174,7 @@ el3_close(struct net_device *dev)
        return 0;
 }
 
        return 0;
 }
 
-static int 
+static int
 el3_link_ok(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
 el3_link_ok(struct net_device *dev)
 {
        int ioaddr = dev->base_addr;
@@ -1210,9 +1191,9 @@ el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        u16 tmp;
        int ioaddr = dev->base_addr;
 {
        u16 tmp;
        int ioaddr = dev->base_addr;
-       
+
        EL3WINDOW(0);
        EL3WINDOW(0);
-       /* obtain current transceiver via WN4_MEDIA? */ 
+       /* obtain current transceiver via WN4_MEDIA? */
        tmp = inw(ioaddr + WN0_ADDR_CONF);
        ecmd->transceiver = XCVR_INTERNAL;
        switch (tmp >> 14) {
        tmp = inw(ioaddr + WN0_ADDR_CONF);
        ecmd->transceiver = XCVR_INTERNAL;
        switch (tmp >> 14) {
@@ -1355,7 +1336,7 @@ static void el3_set_msglevel(struct net_device *dev, u32 v)
        el3_debug = v;
 }
 
        el3_debug = v;
 }
 
-static struct ethtool_ops ethtool_ops = {
+static const struct ethtool_ops ethtool_ops = {
        .get_drvinfo = el3_get_drvinfo,
        .get_settings = el3_get_settings,
        .set_settings = el3_set_settings,
        .get_drvinfo = el3_get_drvinfo,
        .get_settings = el3_get_settings,
        .set_settings = el3_set_settings,
@@ -1397,7 +1378,7 @@ el3_up(struct net_device *dev)
 {
        int i, sw_info, net_diag;
        int ioaddr = dev->base_addr;
 {
        int i, sw_info, net_diag;
        int ioaddr = dev->base_addr;
-       
+
        /* Activating the board required and does no harm otherwise */
        outw(0x0001, ioaddr + 4);
 
        /* Activating the board required and does no harm otherwise */
        outw(0x0001, ioaddr + 4);
 
@@ -1417,7 +1398,7 @@ el3_up(struct net_device *dev)
                /* Combine secondary sw_info word (the adapter level) and primary
                        sw_info word (duplex setting plus other useless bits) */
                EL3WINDOW(0);
                /* Combine secondary sw_info word (the adapter level) and primary
                        sw_info word (duplex setting plus other useless bits) */
                EL3WINDOW(0);
-               sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) | 
+               sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) |
                        (read_eeprom(ioaddr, 0x0d) & 0xBff0);
 
                EL3WINDOW(4);
                        (read_eeprom(ioaddr, 0x0d) & 0xBff0);
 
                EL3WINDOW(4);
@@ -1480,20 +1461,17 @@ el3_up(struct net_device *dev)
 }
 
 /* Power Management support functions */
 }
 
 /* Power Management support functions */
-#ifdef CONFIG_PM_LEGACY
+#ifdef EL3_SUSPEND
 
 static int
 
 static int
-el3_suspend(struct pm_dev *pdev)
+el3_suspend(struct device *pdev, pm_message_t state)
 {
        unsigned long flags;
        struct net_device *dev;
        struct el3_private *lp;
        int ioaddr;
 {
        unsigned long flags;
        struct net_device *dev;
        struct el3_private *lp;
        int ioaddr;
-       
-       if (!pdev && !pdev->data)
-               return -EINVAL;
 
 
-       dev = (struct net_device *)pdev->data;
+       dev = pdev->driver_data;
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
@@ -1510,17 +1488,14 @@ el3_suspend(struct pm_dev *pdev)
 }
 
 static int
 }
 
 static int
-el3_resume(struct pm_dev *pdev)
+el3_resume(struct device *pdev)
 {
        unsigned long flags;
        struct net_device *dev;
        struct el3_private *lp;
        int ioaddr;
 {
        unsigned long flags;
        struct net_device *dev;
        struct el3_private *lp;
        int ioaddr;
-       
-       if (!pdev && !pdev->data)
-               return -EINVAL;
 
 
-       dev = (struct net_device *)pdev->data;
+       dev = pdev->driver_data;
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
@@ -1531,25 +1506,12 @@ el3_resume(struct pm_dev *pdev)
 
        if (netif_running(dev))
                netif_device_attach(dev);
 
        if (netif_running(dev))
                netif_device_attach(dev);
-               
-       spin_unlock_irqrestore(&lp->lock, flags);
-       return 0;
-}
 
 
-static int
-el3_pm_callback(struct pm_dev *pdev, pm_request_t rqst, void *data)
-{
-       switch (rqst) {
-               case PM_SUSPEND:
-                       return el3_suspend(pdev);
-
-               case PM_RESUME:
-                       return el3_resume(pdev);
-       }
+       spin_unlock_irqrestore(&lp->lock, flags);
        return 0;
 }
 
        return 0;
 }
 
-#endif /* CONFIG_PM_LEGACY */
+#endif /* EL3_SUSPEND */
 
 /* Parameters that may be passed into the module. */
 static int debug = -1;
 
 /* Parameters that may be passed into the module. */
 static int debug = -1;