Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / tulip / tulip_core.c
index cabdf89..da4fc45 100644 (file)
@@ -1,7 +1,5 @@
-/* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */
+/*     tulip_core.c: A DEC 21x4x-family ethernet driver for Linux.
 
-/*
-       Maintained by Jeff Garzik <jgarzik@pobox.com>
        Copyright 2000,2001  The Linux Kernel Team
        Written/copyright 1994-2001 by Donald Becker.
 
@@ -9,20 +7,19 @@
        of the GNU General Public License, incorporated herein by reference.
 
        Please refer to Documentation/DocBook/tulip-user.{pdf,ps,html}
-       for more information on this driver, or visit the project
-       Web page at http://sourceforge.net/projects/tulip/
+       for more information on this driver.
 
+       Please submit bugs to http://bugzilla.kernel.org/ .
 */
 
-#include <linux/config.h>
 
 #define DRV_NAME       "tulip"
 #ifdef CONFIG_TULIP_NAPI
-#define DRV_VERSION    "1.1.13-NAPI" /* Keep at least for test */
+#define DRV_VERSION    "1.1.15-NAPI" /* Keep at least for test */
 #else
-#define DRV_VERSION    "1.1.13"
+#define DRV_VERSION    "1.1.15"
 #endif
-#define DRV_RELDATE    "May 11, 2002"
+#define DRV_RELDATE    "Feb 27, 2007"
 
 
 #include <linux/module.h>
@@ -37,8 +34,8 @@
 #include <asm/unaligned.h>
 #include <asm/uaccess.h>
 
-#ifdef __sparc__
-#include <asm/pbm.h>
+#ifdef CONFIG_SPARC
+#include <asm/prom.h>
 #endif
 
 static char version[] __devinitdata =
@@ -67,9 +64,9 @@ const char * const medianame[32] = {
 };
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx structure. */
-#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) \
-       || defined(__sparc_) || defined(__ia64__) \
-       || defined(__sh__) || defined(__mips__)
+#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
+       defined(CONFIG_SPARC) || defined(__ia64__) || \
+       defined(__sh__) || defined(__mips__)
 static int rx_copybreak = 1518;
 #else
 static int rx_copybreak = 100;
@@ -92,7 +89,7 @@ static int rx_copybreak = 100;
 static int csr0 = 0x01A00000 | 0xE000;
 #elif defined(__i386__) || defined(__powerpc__) || defined(__x86_64__)
 static int csr0 = 0x01A00000 | 0x8000;
-#elif defined(__sparc__) || defined(__hppa__)
+#elif defined(CONFIG_SPARC) || defined(__hppa__)
 /* The UltraSparc PCI controllers will disconnect at every 64-byte
  * crossing anyways so it makes no sense to tell Tulip to burst
  * any more than that.
@@ -131,7 +128,14 @@ int tulip_debug = TULIP_DEBUG;
 int tulip_debug = 1;
 #endif
 
+static void tulip_timer(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct tulip_private *tp = netdev_priv(dev);
 
+       if (netif_running(dev))
+               schedule_work(&tp->media_work);
+}
 
 /*
  * This table use during operation for capabilities and media timer.
@@ -145,64 +149,69 @@ struct tulip_chip_table tulip_tbl[] = {
 
   /* DC21140 */
   { "Digital DS21140 Tulip", 128, 0x0001ebef,
-       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer },
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_PCI_MWI, tulip_timer,
+       tulip_media_task },
 
   /* DC21142, DC21143 */
-  { "Digital DS21143 Tulip", 128, 0x0801fbff,
+  { "Digital DS21142/43 Tulip", 128, 0x0801fbff,
        HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI | HAS_NWAY
-       | HAS_INTR_MITIGATION | HAS_PCI_MWI, t21142_timer },
+       | HAS_INTR_MITIGATION | HAS_PCI_MWI, tulip_timer, t21142_media_task },
 
   /* LC82C168 */
   { "Lite-On 82c168 PNIC", 256, 0x0001fbef,
-       HAS_MII | HAS_PNICNWAY, pnic_timer },
+       HAS_MII | HAS_PNICNWAY, pnic_timer, },
 
   /* MX98713 */
   { "Macronix 98713 PMAC", 128, 0x0001ebef,
-       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
 
   /* MX98715 */
   { "Macronix 98715 PMAC", 256, 0x0001ebef,
-       HAS_MEDIA_TABLE, mxic_timer },
+       HAS_MEDIA_TABLE, mxic_timer, },
 
   /* MX98725 */
   { "Macronix 98725 PMAC", 256, 0x0001ebef,
-       HAS_MEDIA_TABLE, mxic_timer },
+       HAS_MEDIA_TABLE, mxic_timer, },
 
   /* AX88140 */
   { "ASIX AX88140", 128, 0x0001fbff,
        HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY
-       | IS_ASIX, tulip_timer },
+       | IS_ASIX, tulip_timer, tulip_media_task },
 
   /* PNIC2 */
   { "Lite-On PNIC-II", 256, 0x0801fbff,
-       HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer },
+       HAS_MII | HAS_NWAY | HAS_8023X | HAS_PCI_MWI, pnic2_timer, },
 
   /* COMET */
   { "ADMtek Comet", 256, 0x0001abef,
-       HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer },
+       HAS_MII | MC_HASH_ONLY | COMET_MAC_ADDR, comet_timer, },
 
   /* COMPEX9881 */
   { "Compex 9881 PMAC", 128, 0x0001ebef,
-       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer },
+       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM, mxic_timer, },
 
   /* I21145 */
   { "Intel DS21145 Tulip", 128, 0x0801fbff,
        HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII | HAS_ACPI
-       | HAS_NWAY | HAS_PCI_MWI, t21142_timer },
+       | HAS_NWAY | HAS_PCI_MWI, tulip_timer, tulip_media_task },
 
   /* DM910X */
+#ifdef CONFIG_TULIP_DM910X
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
        HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
-       tulip_timer },
+       tulip_timer, tulip_media_task },
+#else
+  { NULL },
+#endif
 
   /* RS7112 */
   { "Conexant LANfinity", 256, 0x0001ebef,
-       HAS_MII | HAS_ACPI, tulip_timer },
+       HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
 
 };
 
 
-static struct pci_device_id tulip_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(tulip_pci_tbl) = {
        { 0x1011, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21140 },
        { 0x1011, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DC21143 },
        { 0x11AD, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, LC82C168 },
@@ -223,8 +232,10 @@ static struct pci_device_id tulip_pci_tbl[] = {
        { 0x1259, 0xa120, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x11F6, 0x9881, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMPEX9881 },
        { 0x8086, 0x0039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, I21145 },
+#ifdef CONFIG_TULIP_DM910X
        { 0x1282, 0x9100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
        { 0x1282, 0x9102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },
+#endif
        { 0x1113, 0x1216, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x1113, 0x1217, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MX98715 },
        { 0x1113, 0x9511, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
@@ -238,6 +249,7 @@ static struct pci_device_id tulip_pci_tbl[] = {
        { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */
        { 0x14ea, 0xab08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Planex FNW-3602-TX */
+       { 0x1414, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* Microsoft MN-120 */
        { 0x1414, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { } /* terminate list */
 };
@@ -250,7 +262,9 @@ const char tulip_media_cap[32] =
 
 static void tulip_tx_timeout(struct net_device *dev);
 static void tulip_init_ring(struct net_device *dev);
-static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static void tulip_free_ring(struct net_device *dev);
+static netdev_tx_t tulip_start_xmit(struct sk_buff *skb,
+                                         struct net_device *dev);
 static int tulip_open(struct net_device *dev);
 static int tulip_close(struct net_device *dev);
 static void tulip_up(struct net_device *dev);
@@ -285,8 +299,13 @@ static void tulip_up(struct net_device *dev)
        struct tulip_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->base_addr;
        int next_tick = 3*HZ;
+       u32 reg;
        int i;
 
+#ifdef CONFIG_TULIP_NAPI
+       napi_enable(&tp->napi);
+#endif
+
        /* Wake the chip from sleep/snooze mode. */
        tulip_set_power_state (tp, 0, 0);
 
@@ -296,12 +315,14 @@ static void tulip_up(struct net_device *dev)
 
        /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
        iowrite32(0x00000001, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &reg);  /* flush write */
        udelay(100);
 
        /* Deassert reset.
           Wait the specified 50 PCI cycles after a reset by initializing
           Tx and Rx queues and the address filter list. */
        iowrite32(tp->csr0, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &reg);  /* flush write */
        udelay(100);
 
        if (tulip_debug > 1)
@@ -313,8 +334,8 @@ static void tulip_up(struct net_device *dev)
        tp->dirty_rx = tp->dirty_tx = 0;
 
        if (tp->flags & MC_HASH_ONLY) {
-               u32 addr_low = le32_to_cpu(get_unaligned((u32 *)dev->dev_addr));
-               u32 addr_high = le16_to_cpu(get_unaligned((u16 *)(dev->dev_addr+4)));
+               u32 addr_low = get_unaligned_le32(dev->dev_addr);
+               u32 addr_high = get_unaligned_le16(dev->dev_addr + 4);
                if (tp->chip_id == AX88140) {
                        iowrite32(0, ioaddr + CSR13);
                        iowrite32(addr_low,  ioaddr + CSR14);
@@ -435,8 +456,8 @@ media_picked:
                        iowrite32(0x0201B078, ioaddr + 0xB8);
                        next_tick = 1*HZ;
                }
-       } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
-                          && ! tp->medialock) {
+       } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881) &&
+                  ! tp->medialock) {
                dev->if_port = 0;
                tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
                iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
@@ -490,16 +511,21 @@ tulip_open(struct net_device *dev)
 {
        int retval;
 
-       if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev)))
-               return retval;
-
        tulip_init_ring (dev);
 
+       retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev);
+       if (retval)
+               goto free_ring;
+
        tulip_up (dev);
 
        netif_start_queue (dev);
 
        return 0;
+
+free_ring:
+       tulip_free_ring (dev);
+       return retval;
 }
 
 
@@ -516,27 +542,16 @@ static void tulip_tx_timeout(struct net_device *dev)
                if (tulip_debug > 1)
                        printk(KERN_WARNING "%s: Transmit timeout using MII device.\n",
                                   dev->name);
-       } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142
-                          || tp->chip_id == MX98713 || tp->chip_id == COMPEX9881
-                          || tp->chip_id == DM910X) {
+       } else if (tp->chip_id == DC21140 || tp->chip_id == DC21142 ||
+                  tp->chip_id == MX98713 || tp->chip_id == COMPEX9881 ||
+                  tp->chip_id == DM910X) {
                printk(KERN_WARNING "%s: 21140 transmit timed out, status %8.8x, "
                           "SIA %8.8x %8.8x %8.8x %8.8x, resetting...\n",
                           dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
                           ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
-               if ( ! tp->medialock  &&  tp->mtable) {
-                       do
-                               --tp->cur_index;
-                       while (tp->cur_index >= 0
-                                  && (tulip_media_cap[tp->mtable->mleaf[tp->cur_index].media]
-                                          & MediaIsFD));
-                       if (--tp->cur_index < 0) {
-                               /* We start again, but should instead look for default. */
-                               tp->cur_index = tp->mtable->leafcount - 1;
-                       }
-                       tulip_select_media(dev, 0);
-                       printk(KERN_WARNING "%s: transmit timed out, switching to %s "
-                                  "media.\n", dev->name, medianame[dev->if_port]);
-               }
+               tp->timeout_recovery = 1;
+               schedule_work(&tp->media_work);
+               goto out_unlock;
        } else if (tp->chip_id == PNIC2) {
                printk(KERN_WARNING "%s: PNIC2 transmit timed out, status %8.8x, "
                       "CSR6/7 %8.8x / %8.8x CSR12 %8.8x, resetting...\n",
@@ -563,27 +578,24 @@ static void tulip_tx_timeout(struct net_device *dev)
                                   (unsigned int)tp->rx_ring[i].buffer2,
                                   buf[0], buf[1], buf[2]);
                        for (j = 0; buf[j] != 0xee && j < 1600; j++)
-                               if (j < 100) printk(" %2.2x", buf[j]);
-                       printk(" j=%d.\n", j);
+                               if (j < 100)
+                                       printk(KERN_CONT " %2.2x", buf[j]);
+                       printk(KERN_CONT " j=%d.\n", j);
                }
                printk(KERN_DEBUG "  Rx ring %8.8x: ", (int)tp->rx_ring);
                for (i = 0; i < RX_RING_SIZE; i++)
-                       printk(" %8.8x", (unsigned int)tp->rx_ring[i].status);
-               printk("\n" KERN_DEBUG "  Tx ring %8.8x: ", (int)tp->tx_ring);
+                       printk(KERN_CONT " %8.8x",
+                              (unsigned int)tp->rx_ring[i].status);
+               printk(KERN_DEBUG "  Tx ring %8.8x: ", (int)tp->tx_ring);
                for (i = 0; i < TX_RING_SIZE; i++)
-                       printk(" %8.8x", (unsigned int)tp->tx_ring[i].status);
-               printk("\n");
+                       printk(KERN_CONT " %8.8x", (unsigned int)tp->tx_ring[i].status);
+               printk(KERN_CONT "\n");
        }
 #endif
 
-       /* Stop and restart the chip's Tx processes . */
-
-       tulip_restart_rxtx(tp);
-       /* Trigger an immediate transmit demand. */
-       iowrite32(0, ioaddr + CSR1);
-
-       tp->stats.tx_errors++;
+       tulip_tx_timeout_complete(tp, ioaddr);
 
+out_unlock:
        spin_unlock_irqrestore (&tp->lock, flags);
        dev->trans_start = jiffies;
        netif_wake_queue (dev);
@@ -641,15 +653,16 @@ static void tulip_init_ring(struct net_device *dev)
        tp->tx_ring[i-1].buffer2 = cpu_to_le32(tp->tx_ring_dma);
 }
 
-static int
+static netdev_tx_t
 tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
        int entry;
        u32 flag;
        dma_addr_t mapping;
+       unsigned long flags;
 
-       spin_lock_irq(&tp->lock);
+       spin_lock_irqsave(&tp->lock, flags);
 
        /* Calculate the next Tx descriptor entry. */
        entry = tp->cur_tx % TX_RING_SIZE;
@@ -684,11 +697,11 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Trigger an immediate transmit demand. */
        iowrite32(0, tp->base_addr + CSR1);
 
-       spin_unlock_irq(&tp->lock);
+       spin_unlock_irqrestore(&tp->lock, flags);
 
        dev->trans_start = jiffies;
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static void tulip_clean_tx_ring(struct tulip_private *tp)
@@ -733,6 +746,12 @@ static void tulip_down (struct net_device *dev)
        void __iomem *ioaddr = tp->base_addr;
        unsigned long flags;
 
+       cancel_work_sync(&tp->media_work);
+
+#ifdef CONFIG_TULIP_NAPI
+       napi_disable(&tp->napi);
+#endif
+
        del_timer_sync (&tp->timer);
 #ifdef CONFIG_TULIP_NAPI
        del_timer_sync (&tp->oom_timer);
@@ -766,23 +785,11 @@ static void tulip_down (struct net_device *dev)
        tulip_set_power_state (tp, 0, 1);
 }
 
-
-static int tulip_close (struct net_device *dev)
+static void tulip_free_ring (struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       void __iomem *ioaddr = tp->base_addr;
        int i;
 
-       netif_stop_queue (dev);
-
-       tulip_down (dev);
-
-       if (tulip_debug > 1)
-               printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
-                       dev->name, ioread32 (ioaddr + CSR5));
-
-       free_irq (dev->irq, dev);
-
        /* Free all the skbuffs in the Rx queue. */
        for (i = 0; i < RX_RING_SIZE; i++) {
                struct sk_buff *skb = tp->rx_buffers[i].skb;
@@ -793,13 +800,15 @@ static int tulip_close (struct net_device *dev)
 
                tp->rx_ring[i].status = 0;      /* Not owned by Tulip chip. */
                tp->rx_ring[i].length = 0;
-               tp->rx_ring[i].buffer1 = 0xBADF00D0;    /* An invalid address. */
+               /* An invalid address. */
+               tp->rx_ring[i].buffer1 = cpu_to_le32(0xBADF00D0);
                if (skb) {
                        pci_unmap_single(tp->pdev, mapping, PKT_BUF_SZ,
                                         PCI_DMA_FROMDEVICE);
                        dev_kfree_skb (skb);
                }
        }
+
        for (i = 0; i < TX_RING_SIZE; i++) {
                struct sk_buff *skb = tp->tx_buffers[i].skb;
 
@@ -811,6 +820,24 @@ static int tulip_close (struct net_device *dev)
                tp->tx_buffers[i].skb = NULL;
                tp->tx_buffers[i].mapping = 0;
        }
+}
+
+static int tulip_close (struct net_device *dev)
+{
+       struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
+
+       netif_stop_queue (dev);
+
+       tulip_down (dev);
+
+       if (tulip_debug > 1)
+               printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+                       dev->name, ioread32 (ioaddr + CSR5));
+
+       free_irq (dev->irq, dev);
+
+       tulip_free_ring (dev);
 
        return 0;
 }
@@ -842,7 +869,7 @@ static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *in
        strcpy(info->bus_info, pci_name(np->pdev));
 }
 
-static struct ethtool_ops ops = {
+static const struct ethtool_ops ops = {
        .get_drvinfo = tulip_get_drvinfo
 };
 
@@ -903,8 +930,6 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
                return 0;
 
        case SIOCSMIIREG:               /* Write MII PHY register. */
-               if (!capable (CAP_NET_ADMIN))
-                       return -EPERM;
                if (regnum & ~0x1f)
                        return -EINVAL;
                if (data->phy_id == phy) {
@@ -1024,8 +1049,6 @@ static void set_rx_mode(struct net_device *dev)
        if (dev->flags & IFF_PROMISC) {                 /* Set promiscuous. */
                tp->csr6 |= AcceptAllMulticast | AcceptAllPhys;
                csr6 |= AcceptAllMulticast | AcceptAllPhys;
-               /* Unconditionally log net taps. */
-               printk(KERN_INFO "%s: Promiscuous mode enabled.\n", dev->name);
        } else if ((dev->mc_count > 1000)  ||  (dev->flags & IFF_ALLMULTI)) {
                /* Too many to filter well -- accept all multicasts. */
                tp->csr6 |= AcceptAllMulticast;
@@ -1049,14 +1072,11 @@ static void set_rx_mode(struct net_device *dev)
                                        filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
                                filterbit &= 0x3f;
                                mc_filter[filterbit >> 5] |= 1 << (filterbit & 31);
-                               if (tulip_debug > 2) {
-                                       printk(KERN_INFO "%s: Added filter for %2.2x:%2.2x:%2.2x:"
-                                                  "%2.2x:%2.2x:%2.2x  %8.8x bit %d.\n", dev->name,
-                                                  mclist->dmi_addr[0], mclist->dmi_addr[1],
-                                                  mclist->dmi_addr[2], mclist->dmi_addr[3],
-                                                  mclist->dmi_addr[4], mclist->dmi_addr[5],
-                                                  ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
-                               }
+                               if (tulip_debug > 2)
+                                       printk(KERN_INFO "%s: Added filter for %pM"
+                                              "  %8.8x bit %d.\n",
+                                              dev->name, mclist->dmi_addr,
+                                              ether_crc(ETH_ALEN, mclist->dmi_addr), filterbit);
                        }
                        if (mc_filter[0] == tp->mc_filter[0]  &&
                                mc_filter[1] == tp->mc_filter[1])
@@ -1152,18 +1172,13 @@ static void __devinit tulip_mwi_config (struct pci_dev *pdev,
 
        tp->csr0 = csr0 = 0;
 
-       /* if we have any cache line size at all, we can do MRM */
-       csr0 |= MRM;
-
-       /* ...and barring hardware bugs, MWI */
-       if (!(tp->chip_id == DC21143 && tp->revision == 65))
-               csr0 |= MWI;
+       /* if we have any cache line size at all, we can do MRM and MWI */
+       csr0 |= MRM | MWI;
 
-       /* set or disable MWI in the standard PCI command bit.
-        * Check for the case where  mwi is desired but not available
+       /* Enable MWI in the standard PCI command bit.
+        * Check for the case where MWI is desired but not available
         */
-       if (csr0 & MWI) pci_set_mwi(pdev);
-       else            pci_clear_mwi(pdev);
+       pci_try_set_mwi(pdev);
 
        /* read result from hardware (in case bit refused to enable) */
        pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
@@ -1232,6 +1247,22 @@ static int tulip_uli_dm_quirk(struct pci_dev *pdev)
        return 0;
 }
 
+static const struct net_device_ops tulip_netdev_ops = {
+       .ndo_open               = tulip_open,
+       .ndo_start_xmit         = tulip_start_xmit,
+       .ndo_tx_timeout         = tulip_tx_timeout,
+       .ndo_stop               = tulip_close,
+       .ndo_get_stats          = tulip_get_stats,
+       .ndo_do_ioctl           = private_ioctl,
+       .ndo_set_multicast_list = set_rx_mode,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller     = poll_tulip,
+#endif
+};
+
 static int __devinit tulip_init_one (struct pci_dev *pdev,
                                     const struct pci_device_id *ent)
 {
@@ -1245,7 +1276,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        };
        static int last_irq;
        static int multiport_cnt;       /* For four-port boards w/one EEPROM */
-       u8 chip_rev;
        int i, irq;
        unsigned short sum;
        unsigned char *ee_data;
@@ -1276,20 +1306,30 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        }
 
        /*
-        *      Early DM9100's need software CRC and the DMFE driver
+        *      DM910x chips should be handled by the dmfe driver, except
+        *      on-board chips on SPARC systems.  Also, early DM9100s need
+        *      software CRC which only the dmfe driver supports.
         */
 
-       if (pdev->vendor == 0x1282 && pdev->device == 0x9100)
-       {
-               u32 dev_rev;
-               /* Read Chip revision */
-               pci_read_config_dword(pdev, PCI_REVISION_ID, &dev_rev);
-               if(dev_rev < 0x02000030)
-               {
-                       printk(KERN_ERR PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
+#ifdef CONFIG_TULIP_DM910X
+       if (chip_idx == DM910X) {
+               struct device_node *dp;
+
+               if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
+                   pdev->revision < 0x30) {
+                       printk(KERN_INFO PFX
+                              "skipping early DM9100 with Crc bug (use dmfe)\n");
+                       return -ENODEV;
+               }
+
+               dp = pci_device_to_OF_node(pdev);
+               if (!(dp && of_get_property(dp, "local-mac-address", NULL))) {
+                       printk(KERN_INFO PFX
+                              "skipping DM910x expansion card (use dmfe)\n");
                        return -ENODEV;
                }
        }
+#endif
 
        /*
         *      Looks for early PCI chipsets where people report hangs
@@ -1322,7 +1362,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        /* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */
        if (tulip_uli_dm_quirk(pdev)) {
                csr0 &= ~0x01f100ff;
-#if defined(__sparc__)
+#if defined(CONFIG_SPARC)
                 csr0 = (csr0 & ~0xff00) | 0xe000;
 #endif
        }
@@ -1347,13 +1387,12 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                return -ENOMEM;
        }
 
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
        if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) {
-               printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, "
+               printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, "
                        "aborting\n", pci_name(pdev),
-                       pci_resource_len (pdev, 0),
-                       pci_resource_start (pdev, 0));
+                       (unsigned long long)pci_resource_len (pdev, 0),
+                       (unsigned long long)pci_resource_start (pdev, 0));
                goto err_out_free_netdev;
        }
 
@@ -1362,21 +1401,17 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        if (pci_request_regions (pdev, "tulip"))
                goto err_out_free_netdev;
 
-#ifndef USE_IO_OPS
-       ioaddr =  pci_iomap(pdev, 1, tulip_tbl[chip_idx].io_size);
-#else
-       ioaddr =  pci_iomap(pdev, 0, tulip_tbl[chip_idx].io_size);
-#endif
+       ioaddr =  pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size);
+
        if (!ioaddr)
                goto err_out_free_res;
 
-       pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
-
        /*
         * initialize private data structure 'tp'
         * it is zeroed and aligned in alloc_etherdev
         */
        tp = netdev_priv(dev);
+       tp->dev = dev;
 
        tp->rx_ring = pci_alloc_consistent(pdev,
                                           sizeof(struct tulip_rx_desc) * RX_RING_SIZE +
@@ -1391,7 +1426,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        tp->flags = tulip_tbl[chip_idx].flags;
        tp->pdev = pdev;
        tp->base_addr = ioaddr;
-       tp->revision = chip_rev;
+       tp->revision = pdev->revision;
        tp->csr0 = csr0;
        spin_lock_init(&tp->lock);
        spin_lock_init(&tp->mii_lock);
@@ -1399,15 +1434,13 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        tp->timer.data = (unsigned long)dev;
        tp->timer.function = tulip_tbl[tp->chip_id].media_timer;
 
+       INIT_WORK(&tp->media_work, tulip_tbl[tp->chip_id].media_task);
+
        dev->base_addr = (unsigned long)ioaddr;
 
 #ifdef CONFIG_TULIP_MWI
        if (!force_csr0 && (tp->flags & HAS_PCI_MWI))
                tulip_mwi_config (pdev, dev);
-#else
-       /* MWI is broken for DC21143 rev 65... */
-       if (chip_idx == DC21143 && chip_rev == 65)
-               tp->csr0 &= ~MWI;
 #endif
 
        /* Stop the chip's Tx and Rx processes. */
@@ -1440,29 +1473,34 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
           EEPROM.
           */
        ee_data = tp->eeprom;
+       memset(ee_data, 0, sizeof(tp->eeprom));
        sum = 0;
        if (chip_idx == LC82C168) {
                for (i = 0; i < 3; i++) {
                        int value, boguscnt = 100000;
                        iowrite32(0x600 | i, ioaddr + 0x98);
-                       do
+                       do {
                                value = ioread32(ioaddr + CSR9);
-                       while (value < 0  && --boguscnt > 0);
-                       put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i);
+                       while (value < 0  && --boguscnt > 0);
+                       put_unaligned_le16(value, ((__le16 *)dev->dev_addr) + i);
                        sum += value & 0xffff;
                }
        } else if (chip_idx == COMET) {
                /* No need to read the EEPROM. */
-               put_unaligned(cpu_to_le32(ioread32(ioaddr + 0xA4)), (u32 *)dev->dev_addr);
-               put_unaligned(cpu_to_le16(ioread32(ioaddr + 0xA8)), (u16 *)(dev->dev_addr + 4));
+               put_unaligned_le32(ioread32(ioaddr + 0xA4), dev->dev_addr);
+               put_unaligned_le16(ioread32(ioaddr + 0xA8), dev->dev_addr + 4);
                for (i = 0; i < 6; i ++)
                        sum += dev->dev_addr[i];
        } else {
                /* A serial EEPROM interface, we read now and sort it out later. */
                int sa_offset = 0;
                int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
+               int ee_max_addr = ((1 << ee_addr_size) - 1) * sizeof(u16);
 
-               for (i = 0; i < sizeof(tp->eeprom); i+=2) {
+               if (ee_max_addr > sizeof(tp->eeprom))
+                       ee_max_addr = sizeof(tp->eeprom);
+
+               for (i = 0; i < ee_max_addr ; i += sizeof(u16)) {
                        u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
                        ee_data[i] = data & 0xff;
                        ee_data[i + 1] = data >> 8;
@@ -1483,14 +1521,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                        sa_offset = 2;          /* Grrr, damn Matrox boards. */
                        multiport_cnt = 4;
                }
-#ifdef CONFIG_DDB5477
-               if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) {
-                       /* DDB5477 MAC address in first EEPROM locations. */
-                       sa_offset = 0;
-                       /* No media table either */
-                       tp->flags &= ~HAS_MEDIA_TABLE;
-               }
-#endif
 #ifdef CONFIG_MIPS_COBALT
                if ((pdev->bus->number == 0) &&
                    ((PCI_SLOT(pdev->devfn) == 7) ||
@@ -1527,8 +1557,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                }
        }
        /* Lite-On boards have the address byte-swapped. */
-       if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0 || dev->dev_addr[0] == 0x02)
-               &&  dev->dev_addr[1] == 0x00)
+       if ((dev->dev_addr[0] == 0xA0 ||
+            dev->dev_addr[0] == 0xC0 ||
+            dev->dev_addr[0] == 0x02) &&
+           dev->dev_addr[1] == 0x00)
                for (i = 0; i < 6; i+=2) {
                        char tmp = dev->dev_addr[i];
                        dev->dev_addr[i] = dev->dev_addr[i+1];
@@ -1542,19 +1574,19 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
           Many PCI BIOSes also incorrectly report the IRQ line, so we correct
           that here as well. */
        if (sum == 0  || sum == 6*0xff) {
-#if defined(__sparc__)
-               struct pcidev_cookie *pcp = pdev->sysdata;
+#if defined(CONFIG_SPARC)
+               struct device_node *dp = pci_device_to_OF_node(pdev);
+               const unsigned char *addr;
+               int len;
 #endif
                eeprom_missing = 1;
                for (i = 0; i < 5; i++)
                        dev->dev_addr[i] = last_phys_addr[i];
                dev->dev_addr[i] = last_phys_addr[i] + 1;
-#if defined(__sparc__)
-               if ((pcp != NULL) && prom_getproplen(pcp->prom_node,
-                       "local-mac-address") == 6) {
-                       prom_getproperty(pcp->prom_node, "local-mac-address",
-                           dev->dev_addr, 6);
-               }
+#if defined(CONFIG_SPARC)
+               addr = of_get_property(dp, "local-mac-address", &len);
+               if (addr && len == 6)
+                       memcpy(dev->dev_addr, addr, 6);
 #endif
 #if defined(__i386__) || defined(__x86_64__)   /* Patch up x86 BIOS bug. */
                if (last_irq)
@@ -1621,34 +1653,29 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        }
 
        /* The Tulip-specific entries in the device structure. */
-       dev->open = tulip_open;
-       dev->hard_start_xmit = tulip_start_xmit;
-       dev->tx_timeout = tulip_tx_timeout;
+       dev->netdev_ops = &tulip_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
 #ifdef CONFIG_TULIP_NAPI
-       dev->poll = tulip_poll;
-       dev->weight = 16;
-#endif
-       dev->stop = tulip_close;
-       dev->get_stats = tulip_get_stats;
-       dev->do_ioctl = private_ioctl;
-       dev->set_multicast_list = set_rx_mode;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = &poll_tulip;
+       netif_napi_add(dev, &tp->napi, tulip_poll, 16);
 #endif
        SET_ETHTOOL_OPS(dev, &ops);
 
        if (register_netdev(dev))
                goto err_out_free_ring;
 
-       printk(KERN_INFO "%s: %s rev %d at %p,",
-              dev->name, chip_name, chip_rev, ioaddr);
+       printk(KERN_INFO "%s: %s rev %d at "
+#ifdef CONFIG_TULIP_MMIO
+               "MMIO"
+#else
+               "Port"
+#endif
+               " %#llx,", dev->name, chip_name, pdev->revision,
+               (unsigned long long) pci_resource_start(pdev, TULIP_BAR));
        pci_set_drvdata(pdev, dev);
 
        if (eeprom_missing)
                printk(" EEPROM not present,");
-       for (i = 0; i < 6; i++)
-               printk("%c%2.2X", i ? ':' : ' ', dev->dev_addr[i]);
+       printk(" %pM", dev->dev_addr);
        printk(", IRQ %d.\n", irq);
 
         if (tp->chip_id == PNIC2)
@@ -1740,12 +1767,15 @@ static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
        if (!dev)
                return -EINVAL;
 
-       if (netif_running(dev))
-               tulip_down(dev);
+       if (!netif_running(dev))
+               goto save_state;
+
+       tulip_down(dev);
 
        netif_device_detach(dev);
        free_irq(dev->irq, dev);
 
+save_state:
        pci_save_state(pdev);
        pci_disable_device(pdev);
        pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1765,9 +1795,15 @@ static int tulip_resume(struct pci_dev *pdev)
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
 
-       pci_enable_device(pdev);
+       if (!netif_running(dev))
+               return 0;
+
+       if ((retval = pci_enable_device(pdev))) {
+               printk (KERN_ERR "tulip: pci_enable_device failed in resume\n");
+               return retval;
+       }
 
-       if ((retval = request_irq(dev->irq, &tulip_interrupt, SA_SHIRQ, dev->name, dev))) {
+       if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
                printk (KERN_ERR "tulip: request_irq failed in resume\n");
                return retval;
        }
@@ -1818,7 +1854,7 @@ static void poll_tulip (struct net_device *dev)
        /* disable_irq here is not very nice, but with the lockless
           interrupt handler we have no other choice. */
        disable_irq(dev->irq);
-       tulip_interrupt (dev->irq, dev, NULL);
+       tulip_interrupt (dev->irq, dev);
        enable_irq(dev->irq);
 }
 #endif
@@ -1846,7 +1882,7 @@ static int __init tulip_init (void)
        tulip_max_interrupt_work = max_interrupt_work;
 
        /* probe for and init boards */
-       return pci_module_init (&tulip_driver);
+       return pci_register_driver(&tulip_driver);
 }