vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / eepro100.c
index 1132101..ab5146f 100644 (file)
@@ -102,8 +102,8 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/init.h>
 #include <linux/mii.h>
 #include <linux/delay.h>
+#include <linux/bitops.h>
 
-#include <asm/bitops.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
@@ -114,11 +114,7 @@ static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
 #include <linux/skbuff.h>
 #include <linux/ethtool.h>
 
-/* enable PIO instead of MMIO, if CONFIG_EEPRO100_PIO is selected */
-#ifdef CONFIG_EEPRO100_PIO
-#define USE_IO 1
-#endif
-
+static int use_io;
 static int debug = -1;
 #define DEBUG_DEFAULT          (NETIF_MSG_DRV          | \
                                 NETIF_MSG_HW           | \
@@ -130,17 +126,18 @@ static int debug = -1;
 MODULE_AUTHOR("Maintainer: Andrey V. Savochkin <saw@saw.sw.com.sg>");
 MODULE_DESCRIPTION("Intel i82557/i82558/i82559 PCI EtherExpressPro driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(congenb, "i");
-MODULE_PARM(txfifo, "i");
-MODULE_PARM(rxfifo, "i");
-MODULE_PARM(txdmacount, "i");
-MODULE_PARM(rxdmacount, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-MODULE_PARM(multicast_filter_limit, "i");
+module_param(use_io, int, 0);
+module_param(debug, int, 0);
+module_param_array(options, int, NULL, 0);
+module_param_array(full_duplex, int, NULL, 0);
+module_param(congenb, int, 0);
+module_param(txfifo, int, 0);
+module_param(rxfifo, int, 0);
+module_param(txdmacount, int, 0);
+module_param(rxdmacount, int, 0);
+module_param(rx_copybreak, int, 0);
+module_param(max_interrupt_work, int, 0);
+module_param(multicast_filter_limit, int, 0);
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(options, "Bits 0-3: transceiver type, bit 4: full duplex, bit 5: 100Mbps");
 MODULE_PARM_DESC(full_duplex, "full duplex setting(s) (1)");
@@ -289,39 +286,13 @@ having to sign an Intel NDA when I'm helping Intel sell their own product!
 
 */
 
-static int speedo_found1(struct pci_dev *pdev, long ioaddr, int fnd_cnt, int acpi_idle_state);
+static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state);
 
 enum pci_flags_bit {
        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
        PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
 };
 
-static inline unsigned int io_inw(unsigned long port)
-{
-       return inw(port);
-}
-static inline void io_outw(unsigned int val, unsigned long port)
-{
-       outw(val, port);
-}
-
-#ifndef USE_IO
-/* Currently alpha headers define in/out macros.
-   Undefine them.  2000/03/30  SAW */
-#undef inb
-#undef inw
-#undef inl
-#undef outb
-#undef outw
-#undef outl
-#define inb readb
-#define inw readw
-#define inl readl
-#define outb writeb
-#define outw writew
-#define outl writel
-#endif
-
 /* Offsets to the various registers.
    All accesses need not be longword aligned. */
 enum speedo_offsets {
@@ -453,6 +424,7 @@ enum Rx_ring_state_bits {
    Unfortunately, all the positions have been shifted since there.
    A new re-alignment is required.  2000/03/06  SAW */
 struct speedo_private {
+    void __iomem *regs;
        struct TxFD     *tx_ring;               /* Commands (usually CmdTxPacket). */
        struct RxFD *rx_ringp[RX_RING_SIZE];    /* Rx descriptor, used as ring. */
        /* The addresses of a Tx/Rx-in-place packets/buffers. */
@@ -490,9 +462,6 @@ struct speedo_private {
        unsigned short partner;                 /* Link partner caps. */
        struct mii_if_info mii_if;              /* MII API hooks, info */
        u32 msg_enable;                         /* debug message level */
-#ifdef CONFIG_PM
-       u32 pm_state[16];
-#endif
 };
 
 /* The parameters for a CmdConfigure operation.
@@ -523,7 +492,7 @@ static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
 static int eepro100_init_one(struct pci_dev *pdev,
                const struct pci_device_id *ent);
 
-static int do_eeprom_cmd(long ioaddr, int cmd, int cmd_len);
+static int do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int speedo_open(struct net_device *dev);
@@ -541,6 +510,7 @@ static struct net_device_stats *speedo_get_stats(struct net_device *dev);
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void set_rx_mode(struct net_device *dev);
 static void speedo_show_state(struct net_device *dev);
+static struct ethtool_ops ethtool_ops;
 
 \f
 
@@ -553,15 +523,16 @@ static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100,
 
 /* How to wait for the command unit to accept a command.
    Typically this takes 0 ticks. */
-static inline unsigned char wait_for_cmd_done(struct net_device *dev)
+static inline unsigned char wait_for_cmd_done(struct net_device *dev,
+                                                                                               struct speedo_private *sp)
 {
        int wait = 1000;
-       long cmd_ioaddr = dev->base_addr + SCBCmd;
+       void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
        unsigned char r;
 
        do  {
                udelay(1);
-               r = inb(cmd_ioaddr);
+               r = ioread8(cmd_ioaddr);
        } while(r && --wait >= 0);
 
        if (wait < 0)
@@ -572,10 +543,11 @@ static inline unsigned char wait_for_cmd_done(struct net_device *dev)
 static int __devinit eepro100_init_one (struct pci_dev *pdev,
                const struct pci_device_id *ent)
 {
-       unsigned long ioaddr;
-       int irq;
+       void __iomem *ioaddr;
+       int irq, pci_bar;
        int acpi_idle_state = 0, pm;
        static int cards_found /* = 0 */;
+       unsigned long pci_base;
 
 #ifndef MODULE
        /* when built-in, we only print version if device is found */
@@ -609,24 +581,17 @@ static int __devinit eepro100_init_one (struct pci_dev *pdev,
        }
 
        irq = pdev->irq;
-#ifdef USE_IO
-       ioaddr = pci_resource_start(pdev, 1);
+       pci_bar = use_io ? 1 : 0;
+       pci_base = pci_resource_start(pdev, pci_bar);
        if (DEBUG & NETIF_MSG_PROBE)
-               printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
-                          ioaddr, irq);
-#else
-       ioaddr = (unsigned long)ioremap(pci_resource_start(pdev, 0),
-                                                                       pci_resource_len(pdev, 0));
+               printk("Found Intel i82557 PCI Speedo at %#lx, IRQ %d.\n",
+                      pci_base, irq);
+
+       ioaddr = pci_iomap(pdev, pci_bar, 0);
        if (!ioaddr) {
-               printk (KERN_ERR "eepro100: cannot remap MMIO region %lx @ %lx\n",
-                               pci_resource_len(pdev, 0), pci_resource_start(pdev, 0));
+               printk (KERN_ERR "eepro100: cannot remap IO\n");
                goto err_out_free_mmio_region;
        }
-       if (DEBUG & NETIF_MSG_PROBE)
-               printk("Found Intel i82557 PCI Speedo, MMIO at %#lx, IRQ %d.\n",
-                          pci_resource_start(pdev, 0), irq);
-#endif
-
 
        if (speedo_found1(pdev, ioaddr, cards_found, acpi_idle_state) == 0)
                cards_found++;
@@ -636,9 +601,7 @@ static int __devinit eepro100_init_one (struct pci_dev *pdev,
        return 0;
 
 err_out_iounmap: ;
-#ifndef USE_IO
-       iounmap ((void *)ioaddr);
-#endif
+       pci_iounmap(pdev, ioaddr);
 err_out_free_mmio_region:
        release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 err_out_free_pio_region:
@@ -665,7 +628,7 @@ static void poll_speedo (struct net_device *dev)
 #endif
 
 static int __devinit speedo_found1(struct pci_dev *pdev,
-               long ioaddr, int card_idx, int acpi_idle_state)
+               void __iomem *ioaddr, int card_idx, int acpi_idle_state)
 {
        struct net_device *dev;
        struct speedo_private *sp;
@@ -708,14 +671,16 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
           The size test is for 6 bit vs. 8 bit address serial EEPROMs.
        */
        {
-               unsigned long iobase;
+               void __iomem *iobase;
                int read_cmd, ee_size;
                u16 sum;
                int j;
 
                /* Use IO only to avoid postponed writes and satisfy EEPROM timing
                   requirements. */
-               iobase = pci_resource_start(pdev, 1);
+               iobase = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
+               if (!iobase)
+                       goto err_free_unlock;
                if ((do_eeprom_cmd(iobase, EE_READ_CMD << 24, 27) & 0xffe0000)
                        == 0xffe0000) {
                        ee_size = 0x100;
@@ -741,13 +706,15 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
                /* Don't  unregister_netdev(dev);  as the EEPro may actually be
                   usable, especially if the MAC address is set later.
                   On the other hand, it may be unusable if MDI data is corrupted. */
+
+               pci_iounmap(pdev, iobase);
        }
 
        /* Reset the chip: stop Tx and Rx processes and clear counters.
           This takes less than 10usec and will easily finish before the next
           action. */
-       outl(PortReset, ioaddr + SCBPort);
-       inl(ioaddr + SCBPort);
+       iowrite32(PortReset, ioaddr + SCBPort);
+       ioread32(ioaddr + SCBPort);
        udelay(10);
 
        if (eeprom[3] & 0x0100)
@@ -760,13 +727,12 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
        for (i = 0; i < 5; i++)
                printk("%2.2X:", dev->dev_addr[i]);
        printk("%2.2X, ", dev->dev_addr[i]);
-#ifdef USE_IO
-       printk("I/O at %#3lx, ", ioaddr);
-#endif
        printk("IRQ %d.\n", pdev->irq);
 
-       /* we must initialize base_addr early, for mdio_{read,write} */
-       dev->base_addr = ioaddr;
+       sp = netdev_priv(dev);
+
+       /* we must initialize this early, for mdio_{read,write} */
+       sp->regs = ioaddr;
 
 #if 1 || defined(kernel_bloat)
        /* OK, this is pure kernel bloat.  I don't like it when other drivers
@@ -813,7 +779,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
                self_test_results = (s32*) ((((long) tx_ring_space) + 15) & ~0xf);
                self_test_results[0] = 0;
                self_test_results[1] = -1;
-               outl(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
+               iowrite32(tx_ring_dma | PortSelfTest, ioaddr + SCBPort);
                do {
                        udelay(10);
                } while (self_test_results[1] == -1  &&  --boguscnt >= 0);
@@ -837,8 +803,8 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
        }
 #endif  /* kernel_bloat */
 
-       outl(PortReset, ioaddr + SCBPort);
-       inl(ioaddr + SCBPort);
+       iowrite32(PortReset, ioaddr + SCBPort);
+       ioread32(ioaddr + SCBPort);
        udelay(10);
 
        /* Return the chip to its original power state. */
@@ -849,7 +815,6 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
 
        dev->irq = pdev->irq;
 
-       sp = netdev_priv(dev);
        sp->pdev = pdev;
        sp->msg_enable = DEBUG;
        sp->acpi_pwr = acpi_idle_state;
@@ -895,6 +860,7 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
        dev->get_stats = &speedo_get_stats;
        dev->set_multicast_list = &set_rx_mode;
        dev->do_ioctl = &speedo_ioctl;
+       SET_ETHTOOL_OPS(dev, &ethtool_ops);
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = &poll_speedo;
 #endif
@@ -911,27 +877,27 @@ static int __devinit speedo_found1(struct pci_dev *pdev,
        return -1;
 }
 
-static void do_slow_command(struct net_device *dev, int cmd)
+static void do_slow_command(struct net_device *dev, struct speedo_private *sp, int cmd)
 {
-       long cmd_ioaddr = dev->base_addr + SCBCmd;
+       void __iomem *cmd_ioaddr = sp->regs + SCBCmd;
        int wait = 0;
        do
-               if (inb(cmd_ioaddr) == 0) break;
+               if (ioread8(cmd_ioaddr) == 0) break;
        while(++wait <= 200);
        if (wait > 100)
                printk(KERN_ERR "Command %4.4x never accepted (%d polls)!\n",
-                      inb(cmd_ioaddr), wait);
+                      ioread8(cmd_ioaddr), wait);
 
-       outb(cmd, cmd_ioaddr);
+       iowrite8(cmd, cmd_ioaddr);
 
        for (wait = 0; wait <= 100; wait++)
-               if (inb(cmd_ioaddr) == 0) return;
+               if (ioread8(cmd_ioaddr) == 0) return;
        for (; wait <= 20000; wait++)
-               if (inb(cmd_ioaddr) == 0) return;
+               if (ioread8(cmd_ioaddr) == 0) return;
                else udelay(1);
        printk(KERN_ERR "Command %4.4x was not accepted after %d polls!"
               "  Current status %8.8x.\n",
-              cmd, wait, inl(dev->base_addr + SCBStatus));
+              cmd, wait, ioread32(sp->regs + SCBStatus));
 }
 
 /* Serial EEPROM section.
@@ -953,35 +919,36 @@ static void do_slow_command(struct net_device *dev, int cmd)
    interval for serial EEPROM.  However, it looks like that there is an
    additional requirement dictating larger udelay's in the code below.
    2000/05/24  SAW */
-static int __devinit do_eeprom_cmd(long ioaddr, int cmd, int cmd_len)
+static int __devinit do_eeprom_cmd(void __iomem *ioaddr, int cmd, int cmd_len)
 {
        unsigned retval = 0;
-       long ee_addr = ioaddr + SCBeeprom;
+       void __iomem *ee_addr = ioaddr + SCBeeprom;
 
-       io_outw(EE_ENB, ee_addr); udelay(2);
-       io_outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
+       iowrite16(EE_ENB, ee_addr); udelay(2);
+       iowrite16(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
 
        /* Shift the command bits out. */
        do {
                short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
-               io_outw(dataval, ee_addr); udelay(2);
-               io_outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
-               retval = (retval << 1) | ((io_inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
+               iowrite16(dataval, ee_addr); udelay(2);
+               iowrite16(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
+               retval = (retval << 1) | ((ioread16(ee_addr) & EE_DATA_READ) ? 1 : 0);
        } while (--cmd_len >= 0);
-       io_outw(EE_ENB, ee_addr); udelay(2);
+       iowrite16(EE_ENB, ee_addr); udelay(2);
 
        /* Terminate the EEPROM access. */
-       io_outw(EE_ENB & ~EE_CS, ee_addr);
+       iowrite16(EE_ENB & ~EE_CS, ee_addr);
        return retval;
 }
 
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
-       long ioaddr = dev->base_addr;
+       struct speedo_private *sp = netdev_priv(dev);
+       void __iomem *ioaddr = sp->regs;
        int val, boguscnt = 64*10;              /* <64 usec. to complete, typ 27 ticks */
-       outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
+       iowrite32(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
        do {
-               val = inl(ioaddr + SCBCtrlMDI);
+               val = ioread32(ioaddr + SCBCtrlMDI);
                if (--boguscnt < 0) {
                        printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
                        break;
@@ -992,12 +959,13 @@ static int mdio_read(struct net_device *dev, int phy_id, int location)
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-       long ioaddr = dev->base_addr;
+       struct speedo_private *sp = netdev_priv(dev);
+       void __iomem *ioaddr = sp->regs;
        int val, boguscnt = 64*10;              /* <64 usec. to complete, typ 27 ticks */
-       outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
+       iowrite32(0x04000000 | (location<<16) | (phy_id<<21) | value,
                 ioaddr + SCBCtrlMDI);
        do {
-               val = inl(ioaddr + SCBCtrlMDI);
+               val = ioread32(ioaddr + SCBCtrlMDI);
                if (--boguscnt < 0) {
                        printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
                        break;
@@ -1009,13 +977,13 @@ static int
 speedo_open(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
        int retval;
 
        if (netif_msg_ifup(sp))
                printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
 
-       pci_set_power_state(sp->pdev, 0);
+       pci_set_power_state(sp->pdev, PCI_D0);
 
        /* Set up the Tx queue early.. */
        sp->cur_tx = 0;
@@ -1053,7 +1021,7 @@ speedo_open(struct net_device *dev)
        speedo_init_rx_ring(dev);
 
        /* Fire up the hardware. */
-       outw(SCBMaskAll, ioaddr + SCBCmd);
+       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
        speedo_resume(dev);
 
        netdevice_start(dev);
@@ -1072,7 +1040,7 @@ speedo_open(struct net_device *dev)
 
        if (netif_msg_ifup(sp)) {
                printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
-                          dev->name, inw(ioaddr + SCBStatus));
+                          dev->name, ioread16(ioaddr + SCBStatus));
        }
 
        /* Set the timer.  The timer serves a dual purpose:
@@ -1096,46 +1064,46 @@ speedo_open(struct net_device *dev)
 static void speedo_resume(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
 
        /* Start with a Tx threshold of 256 (0x..20.... 8 byte units). */
        sp->tx_threshold = 0x01208000;
 
        /* Set the segment registers to '0'. */
-       if (wait_for_cmd_done(dev) != 0) {
-               outl(PortPartialReset, ioaddr + SCBPort);
+       if (wait_for_cmd_done(dev, sp) != 0) {
+               iowrite32(PortPartialReset, ioaddr + SCBPort);
                udelay(10);
        }
 
-        outl(0, ioaddr + SCBPointer);
-        inl(ioaddr + SCBPointer);                      /* Flush to PCI. */
+        iowrite32(0, ioaddr + SCBPointer);
+        ioread32(ioaddr + SCBPointer);                 /* Flush to PCI. */
         udelay(10);                    /* Bogus, but it avoids the bug. */
 
         /* Note: these next two operations can take a while. */
-        do_slow_command(dev, RxAddrLoad);
-        do_slow_command(dev, CUCmdBase);
+        do_slow_command(dev, sp, RxAddrLoad);
+        do_slow_command(dev, sp, CUCmdBase);
 
        /* Load the statistics block and rx ring addresses. */
-       outl(sp->lstats_dma, ioaddr + SCBPointer);
-       inl(ioaddr + SCBPointer);                       /* Flush to PCI */
+       iowrite32(sp->lstats_dma, ioaddr + SCBPointer);
+       ioread32(ioaddr + SCBPointer);                  /* Flush to PCI */
 
-       outb(CUStatsAddr, ioaddr + SCBCmd);
+       iowrite8(CUStatsAddr, ioaddr + SCBCmd);
        sp->lstats->done_marker = 0;
-       wait_for_cmd_done(dev);
+       wait_for_cmd_done(dev, sp);
 
        if (sp->rx_ringp[sp->cur_rx % RX_RING_SIZE] == NULL) {
                if (netif_msg_rx_err(sp))
                        printk(KERN_DEBUG "%s: NULL cur_rx in speedo_resume().\n",
                                        dev->name);
        } else {
-               outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
+               iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
                         ioaddr + SCBPointer);
-               inl(ioaddr + SCBPointer);               /* Flush to PCI */
+               ioread32(ioaddr + SCBPointer);          /* Flush to PCI */
        }
 
        /* Note: RxStart should complete instantly. */
-       do_slow_command(dev, RxStart);
-       do_slow_command(dev, CUDumpStats);
+       do_slow_command(dev, sp, RxStart);
+       do_slow_command(dev, sp, CUDumpStats);
 
        /* Fill the first command with our physical address. */
        {
@@ -1154,11 +1122,11 @@ static void speedo_resume(struct net_device *dev)
        }
 
        /* Start the chip's Tx process and unmask interrupts. */
-       outl(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
+       iowrite32(TX_RING_ELEM_DMA(sp, sp->dirty_tx % TX_RING_SIZE),
                 ioaddr + SCBPointer);
        /* We are not ACK-ing FCP and ER in the interrupt handler yet so they should
           remain masked --Dragan */
-       outw(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
+       iowrite16(CUStart | SCBMaskEarlyRx | SCBMaskFlowCtl, ioaddr + SCBCmd);
 }
 
 /*
@@ -1177,29 +1145,29 @@ speedo_rx_soft_reset(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
        struct RxFD *rfd;
-       long ioaddr;
+       void __iomem *ioaddr;
 
-       ioaddr = dev->base_addr;
-       if (wait_for_cmd_done(dev) != 0) {
+       ioaddr = sp->regs;
+       if (wait_for_cmd_done(dev, sp) != 0) {
                printk("%s: previous command stalled\n", dev->name);
                return;
        }
        /*
        * Put the hardware into a known state.
        */
-       outb(RxAbort, ioaddr + SCBCmd);
+       iowrite8(RxAbort, ioaddr + SCBCmd);
 
        rfd = sp->rx_ringp[sp->cur_rx % RX_RING_SIZE];
 
        rfd->rx_buf_addr = 0xffffffff;
 
-       if (wait_for_cmd_done(dev) != 0) {
+       if (wait_for_cmd_done(dev, sp) != 0) {
                printk("%s: RxAbort command stalled\n", dev->name);
                return;
        }
-       outl(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
+       iowrite32(sp->rx_ring_dma[sp->cur_rx % RX_RING_SIZE],
                ioaddr + SCBPointer);
-       outb(RxStart, ioaddr + SCBCmd);
+       iowrite8(RxStart, ioaddr + SCBCmd);
 }
 
 
@@ -1208,7 +1176,7 @@ static void speedo_timer(unsigned long data)
 {
        struct net_device *dev = (struct net_device *)data;
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
        int phy_num = sp->phy[0] & 0x1f;
 
        /* We have MII and lost link beat. */
@@ -1231,7 +1199,7 @@ static void speedo_timer(unsigned long data)
        mii_check_link(&sp->mii_if);
        if (netif_msg_timer(sp)) {
                printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
-                          dev->name, inw(ioaddr + SCBStatus));
+                          dev->name, ioread16(ioaddr + SCBStatus));
        }
        if (sp->rx_mode < 0  ||
                (sp->rx_bug  && jiffies - sp->last_rx_time > 2*HZ)) {
@@ -1278,7 +1246,7 @@ static void speedo_show_state(struct net_device *dev)
 
 #if 0
        {
-               long ioaddr = dev->base_addr;
+               void __iomem *ioaddr = sp->regs;
                int phy_num = sp->phy[0] & 0x1f;
                for (i = 0; i < 16; i++) {
                        /* FIXME: what does it mean?  --SAW */
@@ -1399,14 +1367,14 @@ static void reset_mii(struct net_device *dev)
 static void speedo_tx_timeout(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
-       int status = inw(ioaddr + SCBStatus);
+       void __iomem *ioaddr = sp->regs;
+       int status = ioread16(ioaddr + SCBStatus);
        unsigned long flags;
 
        if (netif_msg_tx_err(sp)) {
                printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
                   " %4.4x at %d/%d command %8.8x.\n",
-                  dev->name, status, inw(ioaddr + SCBCmd),
+                  dev->name, status, ioread16(ioaddr + SCBCmd),
                   sp->dirty_tx, sp->cur_tx,
                   sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
 
@@ -1418,9 +1386,9 @@ static void speedo_tx_timeout(struct net_device *dev)
                /* Only the command unit has stopped. */
                printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
                           dev->name);
-               outl(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
+               iowrite32(TX_RING_ELEM_DMA(sp, dirty_tx % TX_RING_SIZE]),
                         ioaddr + SCBPointer);
-               outw(CUStart, ioaddr + SCBCmd);
+               iowrite16(CUStart, ioaddr + SCBCmd);
                reset_mii(dev);
        } else {
 #else
@@ -1428,12 +1396,12 @@ static void speedo_tx_timeout(struct net_device *dev)
 #endif
                del_timer_sync(&sp->timer);
                /* Reset the Tx and Rx units. */
-               outl(PortReset, ioaddr + SCBPort);
+               iowrite32(PortReset, ioaddr + SCBPort);
                /* We may get spurious interrupts here.  But I don't think that they
                   may do much harm.  1999/12/09 SAW */
                udelay(10);
                /* Disable interrupts. */
-               outw(SCBMaskAll, ioaddr + SCBCmd);
+               iowrite16(SCBMaskAll, ioaddr + SCBCmd);
                synchronize_irq(dev->irq);
                speedo_tx_buffer_gc(dev);
                /* Free as much as possible.
@@ -1461,7 +1429,7 @@ static int
 speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
        int entry;
 
        /* Prevent interrupts from changing the Tx ring from underneath us. */
@@ -1500,18 +1468,18 @@ speedo_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* workaround for hardware bug on 10 mbit half duplex */
 
        if ((sp->partner == 0) && (sp->chip_id == 1)) {
-               wait_for_cmd_done(dev);
-               outb(0 , ioaddr + SCBCmd);
+               wait_for_cmd_done(dev, sp);
+               iowrite8(0 , ioaddr + SCBCmd);
                udelay(1);
        }
 
        /* Trigger the command unit resume. */
-       wait_for_cmd_done(dev);
+       wait_for_cmd_done(dev, sp);
        clear_suspend(sp->last_cmd);
        /* We want the time window between clearing suspend flag on the previous
           command and resuming CU to be as small as possible.
           Interrupts in between are very undesired.  --SAW */
-       outb(CUResume, ioaddr + SCBCmd);
+       iowrite8(CUResume, ioaddr + SCBCmd);
        sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
 
        /* Leave room for set_rx_mode(). If there is no more space than reserved
@@ -1593,12 +1561,13 @@ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs
 {
        struct net_device *dev = (struct net_device *)dev_instance;
        struct speedo_private *sp;
-       long ioaddr, boguscnt = max_interrupt_work;
+       void __iomem *ioaddr;
+       long boguscnt = max_interrupt_work;
        unsigned short status;
        unsigned int handled = 0;
 
-       ioaddr = dev->base_addr;
        sp = netdev_priv(dev);
+       ioaddr = sp->regs;
 
 #ifndef final_version
        /* A lock to prevent simultaneous entry on SMP machines. */
@@ -1611,11 +1580,11 @@ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs
 #endif
 
        do {
-               status = inw(ioaddr + SCBStatus);
+               status = ioread16(ioaddr + SCBStatus);
                /* Acknowledge all of the current interrupt sources ASAP. */
                /* Will change from 0xfc00 to 0xff00 when we start handling
                   FCP and ER interrupts --Dragan */
-               outw(status & 0xfc00, ioaddr + SCBStatus);
+               iowrite16(status & 0xfc00, ioaddr + SCBStatus);
 
                if (netif_msg_intr(sp))
                        printk(KERN_DEBUG "%s: interrupt  status=%#4.4x.\n",
@@ -1675,14 +1644,14 @@ static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs
                        /* Clear all interrupt sources. */
                        /* Will change from 0xfc00 to 0xff00 when we start handling
                           FCP and ER interrupts --Dragan */
-                       outw(0xfc00, ioaddr + SCBStatus);
+                       iowrite16(0xfc00, ioaddr + SCBStatus);
                        break;
                }
        } while (1);
 
        if (netif_msg_intr(sp))
                printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
-                          dev->name, inw(ioaddr + SCBStatus));
+                          dev->name, ioread16(ioaddr + SCBStatus));
 
        clear_bit(0, (void*)&sp->in_interrupt);
        return IRQ_RETVAL(handled);
@@ -1901,8 +1870,8 @@ speedo_rx(struct net_device *dev)
 static int
 speedo_close(struct net_device *dev)
 {
-       long ioaddr = dev->base_addr;
        struct speedo_private *sp = netdev_priv(dev);
+       void __iomem *ioaddr = sp->regs;
        int i;
 
        netdevice_stop(dev);
@@ -1910,16 +1879,16 @@ speedo_close(struct net_device *dev)
 
        if (netif_msg_ifdown(sp))
                printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
-                          dev->name, inw(ioaddr + SCBStatus));
+                          dev->name, ioread16(ioaddr + SCBStatus));
 
        /* Shut off the media monitoring timer. */
        del_timer_sync(&sp->timer);
 
-       outw(SCBMaskAll, ioaddr + SCBCmd);
+       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
 
        /* Shutting down the chip nicely fails to disable flow control. So.. */
-       outl(PortPartialReset, ioaddr + SCBPort);
-       inl(ioaddr + SCBPort); /* flush posted write */
+       iowrite32(PortPartialReset, ioaddr + SCBPort);
+       ioread32(ioaddr + SCBPort); /* flush posted write */
        /*
         * The chip requires a 10 microsecond quiet period.  Wait here!
         */
@@ -1964,7 +1933,7 @@ speedo_close(struct net_device *dev)
        if (netif_msg_ifdown(sp))
                printk(KERN_DEBUG "%s: %d multicast blocks dropped.\n", dev->name, i);
 
-       pci_set_power_state(sp->pdev, 2);
+       pci_set_power_state(sp->pdev, PCI_D2);
 
        return 0;
 }
@@ -1981,7 +1950,7 @@ static struct net_device_stats *
 speedo_get_stats(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
 
        /* Update only if the previous dump finished. */
        if (sp->lstats->done_marker == le32_to_cpu(0xA007)) {
@@ -2002,90 +1971,76 @@ speedo_get_stats(struct net_device *dev)
                        /* Take a spinlock to make wait_for_cmd_done and sending the
                           command atomic.  --SAW */
                        spin_lock_irqsave(&sp->lock, flags);
-                       wait_for_cmd_done(dev);
-                       outb(CUDumpStats, ioaddr + SCBCmd);
+                       wait_for_cmd_done(dev, sp);
+                       iowrite8(CUDumpStats, ioaddr + SCBCmd);
                        spin_unlock_irqrestore(&sp->lock, flags);
                }
        }
        return &sp->stats;
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
+static void speedo_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       u32 ethcmd;
        struct speedo_private *sp = netdev_priv(dev);
-               
-       if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
-               return -EFAULT;
-       
-        switch (ethcmd) {
-       /* get driver-specific version/etc. info */
-       case ETHTOOL_GDRVINFO: {
-               struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
-               strncpy(info.driver, "eepro100", sizeof(info.driver)-1);
-               strncpy(info.version, version, sizeof(info.version)-1);
-               if (sp && sp->pdev)
-                       strcpy(info.bus_info, pci_name(sp->pdev));
-               if (copy_to_user(useraddr, &info, sizeof(info)))
-                       return -EFAULT;
-               return 0;
-       }
-       
-       /* get settings */
-       case ETHTOOL_GSET: {
-               struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-               spin_lock_irq(&sp->lock);
-               mii_ethtool_gset(&sp->mii_if, &ecmd);
-               spin_unlock_irq(&sp->lock);
-               if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* set settings */
-       case ETHTOOL_SSET: {
-               int r;
-               struct ethtool_cmd ecmd;
-               if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-                       return -EFAULT;
-               spin_lock_irq(&sp->lock);
-               r = mii_ethtool_sset(&sp->mii_if, &ecmd);
-               spin_unlock_irq(&sp->lock);
-               return r;
-       }
-       /* restart autonegotiation */
-       case ETHTOOL_NWAY_RST: {
-               return mii_nway_restart(&sp->mii_if);
-       }
-       /* get link status */
-       case ETHTOOL_GLINK: {
-               struct ethtool_value edata = {ETHTOOL_GLINK};
-               edata.data = mii_link_ok(&sp->mii_if);
-               if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* get message-level */
-       case ETHTOOL_GMSGLVL: {
-               struct ethtool_value edata = {ETHTOOL_GMSGLVL};
-               edata.data = sp->msg_enable;
-               if (copy_to_user(useraddr, &edata, sizeof(edata)))
-                       return -EFAULT;
-               return 0;
-       }
-       /* set message-level */
-       case ETHTOOL_SMSGLVL: {
-               struct ethtool_value edata;
-               if (copy_from_user(&edata, useraddr, sizeof(edata)))
-                       return -EFAULT;
-               sp->msg_enable = edata.data;
-               return 0;
-       }
+       strncpy(info->driver, "eepro100", sizeof(info->driver)-1);
+       strncpy(info->version, version, sizeof(info->version)-1);
+       if (sp->pdev)
+               strcpy(info->bus_info, pci_name(sp->pdev));
+}
 
-        }
-       
-       return -EOPNOTSUPP;
+static int speedo_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       spin_lock_irq(&sp->lock);
+       mii_ethtool_gset(&sp->mii_if, ecmd);
+       spin_unlock_irq(&sp->lock);
+       return 0;
 }
 
+static int speedo_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       int res;
+       spin_lock_irq(&sp->lock);
+       res = mii_ethtool_sset(&sp->mii_if, ecmd);
+       spin_unlock_irq(&sp->lock);
+       return res;
+}
+
+static int speedo_nway_reset(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return mii_nway_restart(&sp->mii_if);
+}
+
+static u32 speedo_get_link(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return mii_link_ok(&sp->mii_if);
+}
+
+static u32 speedo_get_msglevel(struct net_device *dev)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       return sp->msg_enable;
+}
+
+static void speedo_set_msglevel(struct net_device *dev, u32 v)
+{
+       struct speedo_private *sp = netdev_priv(dev);
+       sp->msg_enable = v;
+}
+
+static struct ethtool_ops ethtool_ops = {
+       .get_drvinfo = speedo_get_drvinfo,
+       .get_settings = speedo_get_settings,
+       .set_settings = speedo_set_settings,
+       .nway_reset = speedo_nway_reset,
+       .get_link = speedo_get_link,
+       .get_msglevel = speedo_get_msglevel,
+       .set_msglevel = speedo_set_msglevel,
+};
+
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
        struct speedo_private *sp = netdev_priv(dev);
@@ -2103,7 +2058,7 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
                   access from the timeout handler.
                   They are currently serialized only with MDIO access from the
                   timer routine.  2000/05/09 SAW */
-               saved_acpi = pci_set_power_state(sp->pdev, 0);
+               saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
                t = del_timer_sync(&sp->timer);
                data->val_out = mdio_read(dev, data->phy_id & 0x1f, data->reg_num & 0x1f);
                if (t)
@@ -2114,15 +2069,13 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        case SIOCSMIIREG:               /* Write MII PHY register. */
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
-               saved_acpi = pci_set_power_state(sp->pdev, 0);
+               saved_acpi = pci_set_power_state(sp->pdev, PCI_D0);
                t = del_timer_sync(&sp->timer);
                mdio_write(dev, data->phy_id, data->reg_num, data->val_in);
                if (t)
                        add_timer(&sp->timer); /* may be set to the past  --SAW */
                pci_set_power_state(sp->pdev, saved_acpi);
                return 0;
-       case SIOCETHTOOL:
-               return netdev_ethtool_ioctl(dev, rq->ifr_data);
        default:
                return -EOPNOTSUPP;
        }
@@ -2140,7 +2093,7 @@ static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 static void set_rx_mode(struct net_device *dev)
 {
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
        struct descriptor *last_cmd;
        char new_rx_mode;
        unsigned long flags;
@@ -2195,9 +2148,9 @@ static void set_rx_mode(struct net_device *dev)
                        config_cmd_data[8] = 0;
                }
                /* Trigger the command unit resume. */
-               wait_for_cmd_done(dev);
+               wait_for_cmd_done(dev, sp);
                clear_suspend(last_cmd);
-               outb(CUResume, ioaddr + SCBCmd);
+               iowrite8(CUResume, ioaddr + SCBCmd);
                if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
                        netif_stop_queue(dev);
                        sp->tx_full = 1;
@@ -2232,10 +2185,10 @@ static void set_rx_mode(struct net_device *dev)
                        *setup_params++ = *eaddrs++;
                }
 
-               wait_for_cmd_done(dev);
+               wait_for_cmd_done(dev, sp);
                clear_suspend(last_cmd);
                /* Immediately trigger the command unit resume. */
-               outb(CUResume, ioaddr + SCBCmd);
+               iowrite8(CUResume, ioaddr + SCBCmd);
 
                if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
                        netif_stop_queue(dev);
@@ -2308,10 +2261,10 @@ static void set_rx_mode(struct net_device *dev)
                pci_dma_sync_single_for_device(sp->pdev, mc_blk->frame_dma,
                                                                           mc_blk->len, PCI_DMA_TODEVICE);
 
-               wait_for_cmd_done(dev);
+               wait_for_cmd_done(dev, sp);
                clear_suspend(last_cmd);
                /* Immediately trigger the command unit resume. */
-               outb(CUResume, ioaddr + SCBCmd);
+               iowrite8(CUResume, ioaddr + SCBCmd);
 
                if ((int)(sp->cur_tx - sp->dirty_tx) >= TX_QUEUE_LIMIT) {
                        netif_stop_queue(dev);
@@ -2332,9 +2285,9 @@ static int eepro100_suspend(struct pci_dev *pdev, u32 state)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
 
-       pci_save_state(pdev, sp->pm_state);
+       pci_save_state(pdev);
 
        if (!netif_running(dev))
                return 0;
@@ -2342,9 +2295,11 @@ static int eepro100_suspend(struct pci_dev *pdev, u32 state)
        del_timer_sync(&sp->timer);
 
        netif_device_detach(dev);
-       outl(PortPartialReset, ioaddr + SCBPort);
+       iowrite32(PortPartialReset, ioaddr + SCBPort);
        
        /* XXX call pci_set_power_state ()? */
+       pci_disable_device(pdev);
+       pci_set_power_state (pdev, 3);
        return 0;
 }
 
@@ -2352,9 +2307,12 @@ static int eepro100_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata (pdev);
        struct speedo_private *sp = netdev_priv(dev);
-       long ioaddr = dev->base_addr;
+       void __iomem *ioaddr = sp->regs;
 
-       pci_restore_state(pdev, sp->pm_state);
+       pci_set_power_state(pdev, 0);
+       pci_restore_state(pdev);
+       pci_enable_device(pdev);
+       pci_set_master(pdev);
 
        if (!netif_running(dev))
                return 0;
@@ -2366,7 +2324,7 @@ static int eepro100_resume(struct pci_dev *pdev)
                  reinitialization;
                - serialization with other driver calls.
           2000/03/08  SAW */
-       outw(SCBMaskAll, ioaddr + SCBCmd);
+       iowrite16(SCBMaskAll, ioaddr + SCBCmd);
        speedo_resume(dev);
        netif_device_attach(dev);
        sp->rx_mode = -1;
@@ -2388,10 +2346,7 @@ static void __devexit eepro100_remove_one (struct pci_dev *pdev)
        release_region(pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
        release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
 
-#ifndef USE_IO
-       iounmap((char *)dev->base_addr);
-#endif
-
+       pci_iounmap(pdev, sp->regs);
        pci_free_consistent(pdev, TX_RING_SIZE * sizeof(struct TxFD)
                                                                + sizeof(struct speedo_stats),
                                                sp->tx_ring, sp->tx_ring_dma);