fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / net / tulip / tulip_core.c
index c3b4d91..5a35354 100644 (file)
@@ -1,7 +1,7 @@
 /* tulip_core.c: A DEC 21x4x-family ethernet driver for Linux. */
 
 /*
-       Maintained by Jeff Garzik <jgarzik@pobox.com>
+       Maintained by Valerie Henson <val_henson@linux.intel.com>
        Copyright 2000,2001  The Linux Kernel Team
        Written/copyright 1994-2001 by Donald Becker.
 
 
 */
 
-#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.14-NAPI" /* Keep at least for test */
 #else
-#define DRV_VERSION    "1.1.13"
+#define DRV_VERSION    "1.1.14"
 #endif
 #define DRV_RELDATE    "May 11, 2002"
 
 
 #include <linux/module.h>
-#include "tulip.h"
 #include <linux/pci.h>
+#include "tulip.h"
 #include <linux/init.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
@@ -88,9 +87,9 @@ static int rx_copybreak = 100;
        ToDo: Non-Intel setting could be better.
 */
 
-#if defined(__alpha__) || defined(__ia64__) || defined(__x86_64__)
+#if defined(__alpha__) || defined(__ia64__)
 static int csr0 = 0x01A00000 | 0xE000;
-#elif defined(__i386__) || defined(__powerpc__)
+#elif defined(__i386__) || defined(__powerpc__) || defined(__x86_64__)
 static int csr0 = 0x01A00000 | 0x8000;
 #elif defined(__sparc__) || defined(__hppa__)
 /* The UltraSparc PCI controllers will disconnect at every 64-byte
@@ -115,12 +114,13 @@ static int csr0 = 0x00A00000 | 0x4800;
 MODULE_AUTHOR("The Linux Kernel Team");
 MODULE_DESCRIPTION("Digital 21*4* Tulip ethernet driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(tulip_debug, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(csr0, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_VERSION(DRV_VERSION);
+module_param(tulip_debug, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(csr0, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
 
 #define PFX DRV_NAME ": "
 
@@ -130,7 +130,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.
@@ -144,59 +151,61 @@ 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 */
   { "Davicom DM9102/DM9102A", 128, 0x0001ebef,
        HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | HAS_ACPI,
-       tulip_timer },
+       tulip_timer, tulip_media_task },
 
   /* RS7112 */
   { "Conexant LANfinity", 256, 0x0001ebef,
-       HAS_MII | HAS_ACPI, tulip_timer },
+       HAS_MII | HAS_ACPI, tulip_timer, tulip_media_task },
+
 };
 
 
@@ -226,14 +235,17 @@ static struct pci_device_id tulip_pci_tbl[] = {
        { 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 },
-       { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
+       { 0x1186, 0x1541, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x1186, 0x1561, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x1186, 0x1591, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
+       { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT },
        { 0x1626, 0x8410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x1737, 0xAB09, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x1737, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
-       { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X },       /* ALi 1563 integrated ethernet */
        { 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, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET },
        { } /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, tulip_pci_tbl);
@@ -278,7 +290,7 @@ static void tulip_set_power_state (struct tulip_private *tp,
 static void tulip_up(struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = tp->base_addr;
        int next_tick = 3*HZ;
        int i;
 
@@ -287,23 +299,25 @@ static void tulip_up(struct net_device *dev)
 
        /* On some chip revs we must set the MII/SYM port before the reset!? */
        if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii))
-               outl(0x00040000, ioaddr + CSR6);
+               iowrite32(0x00040000, ioaddr + CSR6);
 
        /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
-       outl(0x00000001, ioaddr + CSR0);
+       iowrite32(0x00000001, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &i);  /* 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. */
-       outl(tp->csr0, ioaddr + CSR0);
+       iowrite32(tp->csr0, ioaddr + CSR0);
+       pci_read_config_dword(tp->pdev, PCI_COMMAND, &i);  /* flush write */
        udelay(100);
 
        if (tulip_debug > 1)
                printk(KERN_DEBUG "%s: tulip_up(), irq==%d.\n", dev->name, dev->irq);
 
-       outl(tp->rx_ring_dma, ioaddr + CSR3);
-       outl(tp->tx_ring_dma, ioaddr + CSR4);
+       iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
+       iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
        tp->cur_rx = tp->cur_tx = 0;
        tp->dirty_rx = tp->dirty_tx = 0;
 
@@ -311,15 +325,15 @@ static void tulip_up(struct net_device *dev)
                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)));
                if (tp->chip_id == AX88140) {
-                       outl(0, ioaddr + CSR13);
-                       outl(addr_low,  ioaddr + CSR14);
-                       outl(1, ioaddr + CSR13);
-                       outl(addr_high, ioaddr + CSR14);
+                       iowrite32(0, ioaddr + CSR13);
+                       iowrite32(addr_low,  ioaddr + CSR14);
+                       iowrite32(1, ioaddr + CSR13);
+                       iowrite32(addr_high, ioaddr + CSR14);
                } else if (tp->flags & COMET_MAC_ADDR) {
-                       outl(addr_low,  ioaddr + 0xA4);
-                       outl(addr_high, ioaddr + 0xA8);
-                       outl(0, ioaddr + 0xAC);
-                       outl(0, ioaddr + 0xB0);
+                       iowrite32(addr_low,  ioaddr + 0xA4);
+                       iowrite32(addr_high, ioaddr + 0xA8);
+                       iowrite32(0, ioaddr + 0xAC);
+                       iowrite32(0, ioaddr + 0xB0);
                }
        } else {
                /* This is set_rx_mode(), but without starting the transmitter. */
@@ -389,9 +403,9 @@ media_picked:
                if (tp->chip_id == DC21143  &&
                    (tulip_media_cap[dev->if_port] & MediaIsMII)) {
                        /* We must reset the media CSRs when we force-select MII mode. */
-                       outl(0x0000, ioaddr + CSR13);
-                       outl(0x0000, ioaddr + CSR14);
-                       outl(0x0008, ioaddr + CSR15);
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
+                       iowrite32(0x0008, ioaddr + CSR15);
                }
                tulip_select_media(dev, 1);
        } else if (tp->chip_id == DC21142) {
@@ -401,49 +415,49 @@ media_picked:
                                printk(KERN_INFO "%s: Using MII transceiver %d, status "
                                           "%4.4x.\n",
                                           dev->name, tp->phys[0], tulip_mdio_read(dev, tp->phys[0], 1));
-                       outl(csr6_mask_defstate, ioaddr + CSR6);
+                       iowrite32(csr6_mask_defstate, ioaddr + CSR6);
                        tp->csr6 = csr6_mask_hdcap;
                        dev->if_port = 11;
-                       outl(0x0000, ioaddr + CSR13);
-                       outl(0x0000, ioaddr + CSR14);
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
                } else
                        t21142_start_nway(dev);
        } else if (tp->chip_id == PNIC2) {
                /* for initial startup advertise 10/100 Full and Half */
                tp->sym_advertise = 0x01E0;
                 /* enable autonegotiate end interrupt */
-               outl(inl(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5);
-               outl(inl(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7);
+               iowrite32(ioread32(ioaddr+CSR5)| 0x00008010, ioaddr + CSR5);
+               iowrite32(ioread32(ioaddr+CSR7)| 0x00008010, ioaddr + CSR7);
                pnic2_start_nway(dev);
        } else if (tp->chip_id == LC82C168  &&  ! tp->medialock) {
                if (tp->mii_cnt) {
                        dev->if_port = 11;
                        tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
-                       outl(0x0001, ioaddr + CSR15);
-               } else if (inl(ioaddr + CSR5) & TPLnkPass)
+                       iowrite32(0x0001, ioaddr + CSR15);
+               } else if (ioread32(ioaddr + CSR5) & TPLnkPass)
                        pnic_do_nway(dev);
                else {
                        /* Start with 10mbps to do autonegotiation. */
-                       outl(0x32, ioaddr + CSR12);
+                       iowrite32(0x32, ioaddr + CSR12);
                        tp->csr6 = 0x00420000;
-                       outl(0x0001B078, ioaddr + 0xB8);
-                       outl(0x0201B078, ioaddr + 0xB8);
+                       iowrite32(0x0001B078, ioaddr + 0xB8);
+                       iowrite32(0x0201B078, ioaddr + 0xB8);
                        next_tick = 1*HZ;
                }
        } else if ((tp->chip_id == MX98713 || tp->chip_id == COMPEX9881)
                           && ! tp->medialock) {
                dev->if_port = 0;
                tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
-               outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
+               iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
        } else if (tp->chip_id == MX98715 || tp->chip_id == MX98725) {
                /* Provided by BOLO, Macronix - 12/10/1998. */
                dev->if_port = 0;
                tp->csr6 = 0x01a80200;
-               outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
-               outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
+               iowrite32(0x0f370000 | ioread16(ioaddr + 0x80), ioaddr + 0x80);
+               iowrite32(0x11000 | ioread16(ioaddr + 0xa0), ioaddr + 0xa0);
        } else if (tp->chip_id == COMET || tp->chip_id == CONEXANT) {
                /* Enable automatic Tx underrun recovery. */
-               outl(inl(ioaddr + 0x88) | 1, ioaddr + 0x88);
+               iowrite32(ioread32(ioaddr + 0x88) | 1, ioaddr + 0x88);
                dev->if_port = tp->mii_cnt ? 11 : 0;
                tp->csr6 = 0x00040000;
        } else if (tp->chip_id == AX88140) {
@@ -455,18 +469,18 @@ media_picked:
        tulip_stop_rxtx(tp);
        barrier();
        udelay(5);
-       outl(tp->csr6 | TxOn, ioaddr + CSR6);
+       iowrite32(tp->csr6 | TxOn, ioaddr + CSR6);
 
        /* Enable interrupts by setting the interrupt mask. */
-       outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
-       outl(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
+       iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR5);
+       iowrite32(tulip_tbl[tp->chip_id].valid_intrs, ioaddr + CSR7);
        tulip_start_rxtx(tp);
-       outl(0, ioaddr + CSR2);         /* Rx poll demand */
+       iowrite32(0, ioaddr + CSR2);            /* Rx poll demand */
 
        if (tulip_debug > 2) {
                printk(KERN_DEBUG "%s: Done tulip_up(), CSR0 %8.8x, CSR5 %8.8x CSR6 %8.8x.\n",
-                          dev->name, inl(ioaddr + CSR0), inl(ioaddr + CSR5),
-                          inl(ioaddr + CSR6));
+                          dev->name, ioread32(ioaddr + CSR0), ioread32(ioaddr + CSR5),
+                          ioread32(ioaddr + CSR6));
        }
 
        /* Set the timer to switch to check for link beat and perhaps switch
@@ -485,7 +499,7 @@ tulip_open(struct net_device *dev)
 {
        int 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)))
                return retval;
 
        tulip_init_ring (dev);
@@ -501,7 +515,7 @@ tulip_open(struct net_device *dev)
 static void tulip_tx_timeout(struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = tp->base_addr;
        unsigned long flags;
 
        spin_lock_irqsave (&tp->lock, flags);
@@ -516,31 +530,20 @@ static void tulip_tx_timeout(struct net_device *dev)
                           || 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, inl(ioaddr + CSR5), inl(ioaddr + CSR12),
-                          inl(ioaddr + CSR13), inl(ioaddr + CSR14), inl(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]);
-               }
+                          dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12),
+                          ioread32(ioaddr + CSR13), ioread32(ioaddr + CSR14), ioread32(ioaddr + CSR15));
+               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",
-                      dev->name, (int)inl(ioaddr + CSR5), (int)inl(ioaddr + CSR6),
-                      (int)inl(ioaddr + CSR7), (int)inl(ioaddr + CSR12));
+                      dev->name, (int)ioread32(ioaddr + CSR5), (int)ioread32(ioaddr + CSR6),
+                      (int)ioread32(ioaddr + CSR7), (int)ioread32(ioaddr + CSR12));
        } else {
                printk(KERN_WARNING "%s: Transmit timed out, status %8.8x, CSR12 "
                           "%8.8x, resetting...\n",
-                          dev->name, inl(ioaddr + CSR5), inl(ioaddr + CSR12));
+                          dev->name, ioread32(ioaddr + CSR5), ioread32(ioaddr + CSR12));
                dev->if_port = 0;
        }
 
@@ -571,14 +574,9 @@ static void tulip_tx_timeout(struct net_device *dev)
        }
 #endif
 
-       /* Stop and restart the chip's Tx processes . */
-
-       tulip_restart_rxtx(tp);
-       /* Trigger an immediate transmit demand. */
-       outl(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);
@@ -616,7 +614,7 @@ static void tulip_init_ring(struct net_device *dev)
                tp->rx_buffers[i].skb = skb;
                if (skb == NULL)
                        break;
-               mapping = pci_map_single(tp->pdev, skb->tail,
+               mapping = pci_map_single(tp->pdev, skb->data,
                                         PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
                tp->rx_buffers[i].mapping = mapping;
                skb->dev = dev;                 /* Mark as being used by this device. */
@@ -677,7 +675,7 @@ tulip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        tp->cur_tx++;
 
        /* Trigger an immediate transmit demand. */
-       outl(0, dev->base_addr + CSR1);
+       iowrite32(0, tp->base_addr + CSR1);
 
        spin_unlock_irq(&tp->lock);
 
@@ -724,10 +722,12 @@ static void tulip_clean_tx_ring(struct tulip_private *tp)
 
 static void tulip_down (struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
        struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
        unsigned long flags;
 
+       flush_scheduled_work();
+
        del_timer_sync (&tp->timer);
 #ifdef CONFIG_TULIP_NAPI
        del_timer_sync (&tp->oom_timer);
@@ -735,7 +735,7 @@ static void tulip_down (struct net_device *dev)
        spin_lock_irqsave (&tp->lock, flags);
 
        /* Disable interrupts by clearing the interrupt mask. */
-       outl (0x00000000, ioaddr + CSR7);
+       iowrite32 (0x00000000, ioaddr + CSR7);
 
        /* Stop the Tx and Rx processes. */
        tulip_stop_rxtx(tp);
@@ -746,8 +746,8 @@ static void tulip_down (struct net_device *dev)
        /* release any unconsumed transmit buffers */
        tulip_clean_tx_ring(tp);
 
-       if (inl (ioaddr + CSR6) != 0xffffffff)
-               tp->stats.rx_missed_errors += inl (ioaddr + CSR8) & 0xffff;
+       if (ioread32 (ioaddr + CSR6) != 0xffffffff)
+               tp->stats.rx_missed_errors += ioread32 (ioaddr + CSR8) & 0xffff;
 
        spin_unlock_irqrestore (&tp->lock, flags);
 
@@ -764,8 +764,8 @@ static void tulip_down (struct net_device *dev)
 
 static int tulip_close (struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
        struct tulip_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->base_addr;
        int i;
 
        netif_stop_queue (dev);
@@ -774,7 +774,7 @@ static int tulip_close (struct net_device *dev)
 
        if (tulip_debug > 1)
                printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
-                       dev->name, inl (ioaddr + CSR5));
+                       dev->name, ioread32 (ioaddr + CSR5));
 
        free_irq (dev->irq, dev);
 
@@ -813,14 +813,14 @@ static int tulip_close (struct net_device *dev)
 static struct net_device_stats *tulip_get_stats(struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = tp->base_addr;
 
        if (netif_running(dev)) {
                unsigned long flags;
 
                spin_lock_irqsave (&tp->lock, flags);
 
-               tp->stats.rx_missed_errors += inl(ioaddr + CSR8) & 0xffff;
+               tp->stats.rx_missed_errors += ioread32(ioaddr + CSR8) & 0xffff;
 
                spin_unlock_irqrestore(&tp->lock, flags);
        }
@@ -829,44 +829,29 @@ static struct net_device_stats *tulip_get_stats(struct net_device *dev)
 }
 
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static void tulip_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        struct tulip_private *np = netdev_priv(dev);
-       u32 ethcmd;
-
-       if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
-               return -EFAULT;
-
-        switch (ethcmd) {
-        case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strcpy(info.driver, DRV_NAME);
-               strcpy(info.version, DRV_VERSION);
-               strcpy(info.bus_info, pci_name(np->pdev));
-               if (copy_to_user(useraddr, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-
-        }
-
-       return -EOPNOTSUPP;
+       strcpy(info->driver, DRV_NAME);
+       strcpy(info->version, DRV_VERSION);
+       strcpy(info->bus_info, pci_name(np->pdev));
 }
 
+static const struct ethtool_ops ops = {
+       .get_drvinfo = tulip_get_drvinfo
+};
+
 /* Provide ioctl() calls to examine the MII xcvr state. */
 static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
-       struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+       void __iomem *ioaddr = tp->base_addr;
+       struct mii_ioctl_data *data = if_mii(rq);
        const unsigned int phy_idx = 0;
        int phy = tp->phys[phy_idx] & 0x1f;
        unsigned int regnum = data->reg_num;
 
        switch (cmd) {
-       case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
-
        case SIOCGMIIPHY:               /* Get address of MII PHY in use. */
                if (tp->mii_cnt)
                        data->phy_id = phy;
@@ -879,8 +864,8 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 
        case SIOCGMIIREG:               /* Read MII PHY register. */
                if (data->phy_id == 32 && (tp->flags & HAS_NWAY)) {
-                       int csr12 = inl (ioaddr + CSR12);
-                       int csr14 = inl (ioaddr + CSR14);
+                       int csr12 = ioread32 (ioaddr + CSR12);
+                       int csr14 = ioread32 (ioaddr + CSR14);
                        switch (regnum) {
                        case 0:
                                 if (((csr14<<5) & 0x1000) ||
@@ -900,7 +885,7 @@ static int private_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
                        case 4:
                                 /* Advertised value, bogus 10baseTx-FD value from CSR6. */
                                 data->val_out =
-                                       ((inl(ioaddr + CSR6) >> 3) & 0x0040) +
+                                       ((ioread32(ioaddr + CSR6) >> 3) & 0x0040) +
                                        ((csr14 >> 1) & 0x20) + 1;
                                 data->val_out |= ((csr14 >> 9) & 0x03C0);
                                break;
@@ -1025,17 +1010,15 @@ static void build_setup_frame_perfect(u16 *setup_frm, struct net_device *dev)
 static void set_rx_mode(struct net_device *dev)
 {
        struct tulip_private *tp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = tp->base_addr;
        int csr6;
 
-       csr6 = inl(ioaddr + CSR6) & ~0x00D5;
+       csr6 = ioread32(ioaddr + CSR6) & ~0x00D5;
 
        tp->csr6 &= ~0x00D5;
        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;
@@ -1058,7 +1041,7 @@ static void set_rx_mode(struct net_device *dev)
                                else
                                        filterbit = ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
                                filterbit &= 0x3f;
-                               mc_filter[filterbit >> 5] |= cpu_to_le32(1 << (filterbit & 31));
+                               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,
@@ -1072,13 +1055,13 @@ static void set_rx_mode(struct net_device *dev)
                                mc_filter[1] == tp->mc_filter[1])
                                ;                               /* No change. */
                        else if (tp->flags & IS_ASIX) {
-                               outl(2, ioaddr + CSR13);
-                               outl(mc_filter[0], ioaddr + CSR14);
-                               outl(3, ioaddr + CSR13);
-                               outl(mc_filter[1], ioaddr + CSR14);
+                               iowrite32(2, ioaddr + CSR13);
+                               iowrite32(mc_filter[0], ioaddr + CSR14);
+                               iowrite32(3, ioaddr + CSR13);
+                               iowrite32(mc_filter[1], ioaddr + CSR14);
                        } else if (tp->flags & COMET_MAC_ADDR) {
-                               outl(mc_filter[0], ioaddr + 0xAC);
-                               outl(mc_filter[1], ioaddr + 0xB0);
+                               iowrite32(mc_filter[0], ioaddr + 0xAC);
+                               iowrite32(mc_filter[1], ioaddr + 0xB0);
                        }
                        tp->mc_filter[0] = mc_filter[0];
                        tp->mc_filter[1] = mc_filter[1];
@@ -1118,6 +1101,7 @@ static void set_rx_mode(struct net_device *dev)
                                /* Must set DescOwned later to avoid race with chip */
                                dummy = entry;
                                entry = tp->cur_tx++ % TX_RING_SIZE;
+
                        }
 
                        tp->tx_buffers[entry].skb = NULL;
@@ -1138,13 +1122,13 @@ static void set_rx_mode(struct net_device *dev)
                                netif_stop_queue(dev);
 
                        /* Trigger an immediate transmit demand. */
-                       outl(0, ioaddr + CSR1);
+                       iowrite32(0, ioaddr + CSR1);
                }
 
                spin_unlock_irqrestore(&tp->lock, flags);
        }
 
-       outl(csr6, ioaddr + CSR6);
+       iowrite32(csr6, ioaddr + CSR6);
 }
 
 #ifdef CONFIG_TULIP_MWI
@@ -1229,12 +1213,29 @@ out:
 }
 #endif
 
+/*
+ *     Chips that have the MRM/reserved bit quirk and the burst quirk. That
+ *     is the DM910X and the on chip ULi devices
+ */
+
+static int tulip_uli_dm_quirk(struct pci_dev *pdev)
+{
+       if (pdev->vendor == 0x1282 && pdev->device == 0x9102)
+               return 1;
+       return 0;
+}
+
 static int __devinit tulip_init_one (struct pci_dev *pdev,
                                     const struct pci_device_id *ent)
 {
        struct tulip_private *tp;
        /* See note below on the multiport cards. */
        static unsigned char last_phys_addr[6] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+       static struct pci_device_id early_486_chipsets[] = {
+               { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424) },
+               { PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496) },
+               { },
+       };
        static int last_irq;
        static int multiport_cnt;       /* For four-port boards w/one EEPROM */
        u8 chip_rev;
@@ -1242,9 +1243,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        unsigned short sum;
        unsigned char *ee_data;
        struct net_device *dev;
-       long ioaddr;
+       void __iomem *ioaddr;
        static int board_idx = -1;
        int chip_idx = ent->driver_data;
+       const char *chip_name = tulip_tbl[chip_idx].chip_name;
        unsigned int eeprom_missing = 0;
        unsigned int force_csr0 = 0;
 
@@ -1287,17 +1289,15 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
         *      without the workarounds being on.
         */
 
-       /* Intel Saturn. Switch to 8 long words burst, 8 long word cache aligned
-          Aries might need this too. The Saturn errata are not pretty reading but
-          thankfully it's an old 486 chipset.
+       /* 1. Intel Saturn. Switch to 8 long words burst, 8 long word cache
+             aligned.  Aries might need this too. The Saturn errata are not
+             pretty reading but thankfully it's an old 486 chipset.
+
+          2. The dreaded SiS496 486 chipset. Same workaround as Intel
+             Saturn.
        */
 
-       if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, NULL)) {
-               csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift);
-               force_csr0 = 1;
-       }
-       /* The dreaded SiS496 486 chipset. Same workaround as above. */
-       if (pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_496, NULL)) {
+       if (pci_dev_present(early_486_chipsets)) {
                csr0 = MRL | MRM | (8 << BurstLenShift) | (1 << CALShift);
                force_csr0 = 1;
        }
@@ -1313,17 +1313,12 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                csr0 &= ~0xfff10000; /* zero reserved bits 31:20, 16 */
 
        /* DM9102A has troubles with MRM & clear reserved bits 24:22, 20, 16, 7:1 */
-       if ((pdev->vendor == 0x1282 && pdev->device == 0x9102)
-               || (pdev->vendor == 0x10b9 && pdev->device == 0x5261))
+       if (tulip_uli_dm_quirk(pdev)) {
                csr0 &= ~0x01f100ff;
-
 #if defined(__sparc__)
-        /* DM9102A needs 32-dword alignment/burst length on sparc - chip bug? */
-       if ((pdev->vendor == 0x1282 && pdev->device == 0x9102)
-               || (pdev->vendor == 0x10b9 && pdev->device == 0x5261))
                 csr0 = (csr0 & ~0xff00) | 0xe000;
 #endif
-
+       }
        /*
         *      And back to business
         */
@@ -1336,7 +1331,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                return i;
        }
 
-       ioaddr = pci_resource_start (pdev, 0);
        irq = pdev->irq;
 
        /* alloc_etherdev ensures aligned and zeroed private structures */
@@ -1349,10 +1343,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        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;
        }
 
@@ -1361,12 +1355,10 @@ 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 = (unsigned long) ioremap (pci_resource_start (pdev, 1),
-                                         tulip_tbl[chip_idx].io_size);
+       ioaddr =  pci_iomap(pdev, TULIP_BAR, tulip_tbl[chip_idx].io_size);
+
        if (!ioaddr)
                goto err_out_free_res;
-#endif
 
        pci_read_config_byte (pdev, PCI_REVISION_ID, &chip_rev);
 
@@ -1375,6 +1367,7 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
         * 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 +
@@ -1397,7 +1390,9 @@ 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;
 
-       dev->base_addr = ioaddr;
+       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))
@@ -1413,8 +1408,25 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 
        pci_set_master(pdev);
 
+#ifdef CONFIG_GSC
+       if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP) {
+               switch (pdev->subsystem_device) {
+               default:
+                       break;
+               case 0x1061:
+               case 0x1062:
+               case 0x1063:
+               case 0x1098:
+               case 0x1099:
+               case 0x10EE:
+                       tp->flags |= HAS_SWAPPED_SEEPROM | NEEDS_FAKE_MEDIA_TABLE;
+                       chip_name = "GSC DS21140 Tulip";
+               }
+       }
+#endif
+
        /* Clear the missed-packet counter. */
-       inl(ioaddr + CSR8);
+       ioread32(ioaddr + CSR8);
 
        /* The station address ROM is read byte serially.  The register must
           be polled, waiting for the value to be read bit serially from the
@@ -1425,27 +1437,29 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        if (chip_idx == LC82C168) {
                for (i = 0; i < 3; i++) {
                        int value, boguscnt = 100000;
-                       outl(0x600 | i, ioaddr + 0x98);
+                       iowrite32(0x600 | i, ioaddr + 0x98);
                        do
-                               value = inl(ioaddr + CSR9);
+                               value = ioread32(ioaddr + CSR9);
                        while (value < 0  && --boguscnt > 0);
                        put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i);
                        sum += value & 0xffff;
                }
        } else if (chip_idx == COMET) {
                /* No need to read the EEPROM. */
-               put_unaligned(cpu_to_le32(inl(ioaddr + 0xA4)), (u32 *)dev->dev_addr);
-               put_unaligned(cpu_to_le16(inl(ioaddr + 0xA8)), (u16 *)(dev->dev_addr + 4));
+               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));
                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(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+               int ee_addr_size = tulip_read_eeprom(dev, 0xff, 8) & 0x40000 ? 8 : 6;
 
-               for (i = 0; i < sizeof(tp->eeprom)/2; i++)
-                       ((u16 *)ee_data)[i] =
-                               le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size));
+               for (i = 0; i < sizeof(tp->eeprom); i+=2) {
+                       u16 data = tulip_read_eeprom(dev, i/2, ee_addr_size);
+                       ee_data[i] = data & 0xff;
+                       ee_data[i + 1] = data >> 8;
+               }
 
                /* DEC now has a specification (see Notes) but early board makers
                   just put the address in the first EEPROM locations. */
@@ -1462,14 +1476,6 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                        sa_offset = 2;          /* Grrr, damn Matrox boards. */
                        multiport_cnt = 4;
                }
-#ifdef CONFIG_DDB5476
-               if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 6)) {
-                       /* DDB5476 MAC address in first EEPROM locations. */
-                       sa_offset = 0;
-                       /* No media table either */
-                       tp->flags &= ~HAS_MEDIA_TABLE;
-               }
-#endif
 #ifdef CONFIG_DDB5477
                if ((pdev->bus->number == 0) && (PCI_SLOT(pdev->devfn) == 4)) {
                        /* DDB5477 MAC address in first EEPROM locations. */
@@ -1479,41 +1485,42 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                }
 #endif
 #ifdef CONFIG_MIPS_COBALT
-               if ((pdev->bus->number == 0) && 
+               if ((pdev->bus->number == 0) &&
                    ((PCI_SLOT(pdev->devfn) == 7) ||
                     (PCI_SLOT(pdev->devfn) == 12))) {
                        /* Cobalt MAC address in first EEPROM locations. */
                        sa_offset = 0;
-                       /* No media table either */
-                       tp->flags &= ~HAS_MEDIA_TABLE;
+                      /* Ensure our media table fixup get's applied */
+                      memcpy(ee_data + 16, ee_data, 8);
                }
 #endif
-#ifdef __hppa__
-               /* 3x5 HSC (J3514A) has a broken srom */
-               if(ee_data[0] == 0x61 && ee_data[1] == 0x10) {
+#ifdef CONFIG_GSC
+               /* Check to see if we have a broken srom */
+               if (ee_data[0] == 0x61 && ee_data[1] == 0x10) {
                        /* pci_vendor_id and subsystem_id are swapped */
                        ee_data[0] = ee_data[2];
                        ee_data[1] = ee_data[3];
                        ee_data[2] = 0x61;
                        ee_data[3] = 0x10;
 
-                       /* srom need to be byte-swaped and shifted up 1 word.  
-                        * This shift needs to happen at the end of the MAC
-                        * first because of the 2 byte overlap.
+                       /* HSC-PCI boards need to be byte-swaped and shifted
+                        * up 1 word.  This shift needs to happen at the end
+                        * of the MAC first because of the 2 byte overlap.
                         */
-                       for(i = 4; i >= 0; i -= 2) {
+                       for (i = 4; i >= 0; i -= 2) {
                                ee_data[17 + i + 3] = ee_data[17 + i];
                                ee_data[16 + i + 5] = ee_data[16 + i];
                        }
                }
 #endif
+
                for (i = 0; i < 6; i ++) {
                        dev->dev_addr[i] = ee_data[i + sa_offset];
                        sum += ee_data[i + sa_offset];
                }
        }
        /* Lite-On boards have the address byte-swapped. */
-       if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0)
+       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];
@@ -1536,13 +1543,17 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
                        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 (pcp) {
+                       unsigned char *addr;
+                       int len;
+
+                       addr = of_get_property(pcp->prom_node,
+                                              "local-mac-address", &len);
+                       if (addr && len == 6)
+                               memcpy(dev->dev_addr, addr, 6);
                }
 #endif
-#if defined(__i386__)          /* Patch up x86 BIOS bug. */
+#if defined(__i386__) || defined(__x86_64__)   /* Patch up x86 BIOS bug. */
                if (last_irq)
                        irq = last_irq;
 #endif
@@ -1622,12 +1633,19 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = &poll_tulip;
 #endif
+       SET_ETHTOOL_OPS(dev, &ops);
 
        if (register_netdev(dev))
                goto err_out_free_ring;
 
-       printk(KERN_INFO "%s: %s rev %d at %#3lx,",
-              dev->name, tulip_tbl[chip_idx].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, chip_rev,
+               (unsigned long long) pci_resource_start(pdev, TULIP_BAR));
        pci_set_drvdata(pdev, dev);
 
        if (eeprom_missing)
@@ -1649,43 +1667,43 @@ static int __devinit tulip_init_one (struct pci_dev *pdev,
        case DM910X:
        default:
                if (tp->mtable)
-                       outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
+                       iowrite32(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
                break;
        case DC21142:
                if (tp->mii_cnt  ||  tulip_media_cap[dev->if_port] & MediaIsMII) {
-                       outl(csr6_mask_defstate, ioaddr + CSR6);
-                       outl(0x0000, ioaddr + CSR13);
-                       outl(0x0000, ioaddr + CSR14);
-                       outl(csr6_mask_hdcap, ioaddr + CSR6);
+                       iowrite32(csr6_mask_defstate, ioaddr + CSR6);
+                       iowrite32(0x0000, ioaddr + CSR13);
+                       iowrite32(0x0000, ioaddr + CSR14);
+                       iowrite32(csr6_mask_hdcap, ioaddr + CSR6);
                } else
                        t21142_start_nway(dev);
                break;
        case PNIC2:
                /* just do a reset for sanity sake */
-               outl(0x0000, ioaddr + CSR13);
-               outl(0x0000, ioaddr + CSR14);
+               iowrite32(0x0000, ioaddr + CSR13);
+               iowrite32(0x0000, ioaddr + CSR14);
                break;
        case LC82C168:
                if ( ! tp->mii_cnt) {
                        tp->nway = 1;
                        tp->nwayset = 0;
-                       outl(csr6_ttm | csr6_ca, ioaddr + CSR6);
-                       outl(0x30, ioaddr + CSR12);
-                       outl(0x0001F078, ioaddr + CSR6);
-                       outl(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
+                       iowrite32(csr6_ttm | csr6_ca, ioaddr + CSR6);
+                       iowrite32(0x30, ioaddr + CSR12);
+                       iowrite32(0x0001F078, ioaddr + CSR6);
+                       iowrite32(0x0201F078, ioaddr + CSR6); /* Turn on autonegotiation. */
                }
                break;
        case MX98713:
        case COMPEX9881:
-               outl(0x00000000, ioaddr + CSR6);
-               outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
-               outl(0x00000001, ioaddr + CSR13);
+               iowrite32(0x00000000, ioaddr + CSR6);
+               iowrite32(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
+               iowrite32(0x00000001, ioaddr + CSR13);
                break;
        case MX98715:
        case MX98725:
-               outl(0x01a80000, ioaddr + CSR6);
-               outl(0xFFFFFFFF, ioaddr + CSR14);
-               outl(0x00001000, ioaddr + CSR12);
+               iowrite32(0x01a80000, ioaddr + CSR6);
+               iowrite32(0xFFFFFFFF, ioaddr + CSR14);
+               iowrite32(0x00001000, ioaddr + CSR12);
                break;
        case COMET:
                /* No initialization necessary. */
@@ -1704,13 +1722,10 @@ err_out_free_ring:
                             tp->rx_ring, tp->rx_ring_dma);
 
 err_out_mtable:
-       if (tp->mtable)
-               kfree (tp->mtable);
-#ifndef USE_IO_OPS
-       iounmap((void *)ioaddr);
+       kfree (tp->mtable);
+       pci_iounmap(pdev, ioaddr);
 
 err_out_free_res:
-#endif
        pci_release_regions (pdev);
 
 err_out_free_netdev:
@@ -1721,15 +1736,23 @@ err_out_free_netdev:
 
 #ifdef CONFIG_PM
 
-static int tulip_suspend (struct pci_dev *pdev, u32 state)
+static int tulip_suspend (struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
 
-       if (dev && netif_running (dev) && netif_device_present (dev)) {
-               netif_device_detach (dev);
-               tulip_down (dev);
-               /* pci_power_off(pdev, -1); */
-       }
+       if (!dev)
+               return -EINVAL;
+
+       if (netif_running(dev))
+               tulip_down(dev);
+
+       netif_device_detach(dev);
+       free_irq(dev->irq, dev);
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
        return 0;
 }
 
@@ -1737,15 +1760,29 @@ static int tulip_suspend (struct pci_dev *pdev, u32 state)
 static int tulip_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
+       int retval;
 
-       if (dev && netif_running (dev) && !netif_device_present (dev)) {
-#if 1
-               pci_enable_device (pdev);
-#endif
-               /* pci_power_on(pdev); */
-               tulip_up (dev);
-               netif_device_attach (dev);
+       if (!dev)
+               return -EINVAL;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+
+       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, IRQF_SHARED, dev->name, dev))) {
+               printk (KERN_ERR "tulip: request_irq failed in resume\n");
+               return retval;
        }
+
+       netif_device_attach(dev);
+
+       if (netif_running(dev))
+               tulip_up(dev);
+
        return 0;
 }
 
@@ -1766,11 +1803,8 @@ static void __devexit tulip_remove_one (struct pci_dev *pdev)
                             sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
                             sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
                             tp->rx_ring, tp->rx_ring_dma);
-       if (tp->mtable)
-               kfree (tp->mtable);
-#ifndef USE_IO_OPS
-       iounmap((void *)dev->base_addr);
-#endif
+       kfree (tp->mtable);
+       pci_iounmap(pdev, tp->base_addr);
        free_netdev (dev);
        pci_release_regions (pdev);
        pci_set_drvdata (pdev, NULL);
@@ -1790,7 +1824,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
@@ -1818,7 +1852,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);
 }