vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / e100.c
index a98e843..3acb810 100644 (file)
@@ -87,9 +87,8 @@
  *     cb_to_use is the next CB to use for queuing a command; cb_to_clean
  *     is the next CB to check for completion; cb_to_send is the first
  *     CB to start on in case of a previous failure to resume.  CB clean
- *     up happens in interrupt context in response to a CU interrupt, or
- *     in dev->poll in the case where NAPI is enabled.  cbs_avail keeps
- *     track of number of free CB resources available.
+ *     up happens in interrupt context in response to a CU interrupt.
+ *     cbs_avail keeps track of number of free CB resources available.
  *
  *     Hardware padding of short packets to minimum packet size is
  *     enabled.  82557 pads with 7Eh, while the later controllers pad
  *     replacement RFDs cannot be allocated, or the RU goes non-active,
  *     the RU must be restarted.  Frame arrival generates an interrupt,
  *     and Rx indication and re-allocation happen in the same context,
- *     therefore no locking is required.  If NAPI is enabled, this work
- *     happens in dev->poll.  A software-generated interrupt is gen-
- *     erated from the watchdog to recover from a failed allocation
+ *     therefore no locking is required.  A software-generated interrupt
+ *     is generated from the watchdog to recover from a failed allocation
  *     senario where all Rx resources have been indicated and none re-
  *     placed.
  *
  *     supported.  Tx Scatter/Gather is not supported.  Jumbo Frames is
  *     not supported (hardware limitation).
  *
- *     NAPI support is enabled with CONFIG_E100_NAPI.
- *
  *     MagicPacket(tm) WoL support is enabled/disabled via ethtool.
  *
  *     Thanks to JC (jchapman@katalix.com) for helping with
 
 
 #define DRV_NAME               "e100"
-#define DRV_VERSION            "3.0.17"
+#define DRV_EXT                "-NAPI"
+#define DRV_VERSION            "3.3.6-k2"DRV_EXT
 #define DRV_DESCRIPTION                "Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT          "Copyright(c) 1999-2004 Intel Corporation"
 #define PFX                    DRV_NAME ": "
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
 
 static int debug = 3;
 module_param(debug, int, 0);
@@ -201,6 +199,9 @@ static struct pci_device_id e100_id_table[] = {
        INTEL_8255X_ETHERNET_DEVICE(0x1053, 5),
        INTEL_8255X_ETHERNET_DEVICE(0x1054, 5),
        INTEL_8255X_ETHERNET_DEVICE(0x1055, 5),
+       INTEL_8255X_ETHERNET_DEVICE(0x1056, 5),
+       INTEL_8255X_ETHERNET_DEVICE(0x1057, 5),
+       INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x1064, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x1065, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x1066, 6),
@@ -209,7 +210,6 @@ static struct pci_device_id e100_id_table[] = {
        INTEL_8255X_ETHERNET_DEVICE(0x1069, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x106A, 6),
        INTEL_8255X_ETHERNET_DEVICE(0x106B, 6),
-       INTEL_8255X_ETHERNET_DEVICE(0x1059, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x1209, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x1229, 0),
        INTEL_8255X_ETHERNET_DEVICE(0x2449, 2),
@@ -242,6 +242,7 @@ enum phy {
        phy_nsc_tx   = 0x5C002000,
        phy_82562_et = 0x033002A8,
        phy_82562_em = 0x032002A8,
+       phy_82562_ek = 0x031002A8,
        phy_82562_eh = 0x017002A8,
        phy_unknown  = 0xFFFFFFFF,
 };
@@ -330,11 +331,16 @@ enum eeprom_op {
 };
 
 enum eeprom_offsets {
+       eeprom_cnfg_mdix  = 0x03,
        eeprom_id         = 0x0A,
        eeprom_config_asf = 0x0D,
        eeprom_smbus_addr = 0x90,
 };
 
+enum eeprom_cnfg_mdix {
+       eeprom_mdix_enabled = 0x0080,
+};
+
 enum eeprom_id {
        eeprom_id_wol = 0x0020,
 };
@@ -350,10 +356,12 @@ enum cb_status {
 };
 
 enum cb_command {
+       cb_nop    = 0x0000,
        cb_iaaddr = 0x0001,
        cb_config = 0x0002,
        cb_multi  = 0x0003,
        cb_tx     = 0x0004,
+       cb_ucode  = 0x0005,
        cb_dump   = 0x0006,
        cb_tx_sf  = 0x0008,
        cb_cid    = 0x1f00,
@@ -428,12 +436,14 @@ struct multi {
 };
 
 /* Important: keep total struct u32-aligned */
+#define UCODE_SIZE                     134
 struct cb {
        u16 status;
        u16 command;
        u32 link;
        union {
                u8 iaaddr[ETH_ALEN];
+               u32 ucode[UCODE_SIZE];
                struct config config;
                struct multi multi;
                struct {
@@ -504,7 +514,7 @@ struct nic {
 
        spinlock_t cb_lock                      ____cacheline_aligned;
        spinlock_t cmd_lock;
-       struct csr *csr;
+       struct csr __iomem *csr;
        enum scb_cmd_lo cuc_cmd;
        unsigned int cbs_avail;
        struct cb *cbs;
@@ -548,12 +558,12 @@ struct nic {
        u32 rx_fc_pause;
        u32 rx_fc_unsupported;
        u32 rx_tco_frames;
+       u32 rx_over_length_errors;
 
        u8 rev_id;
        u16 leds;
        u16 eeprom_wc;
        u16 eeprom[256];
-       u32 pm_state[16];
 };
 
 static inline void e100_write_flush(struct nic *nic)
@@ -565,13 +575,21 @@ static inline void e100_write_flush(struct nic *nic)
 
 static inline void e100_enable_irq(struct nic *nic)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->cmd_lock, flags);
        writeb(irq_mask_none, &nic->csr->scb.cmd_hi);
+       spin_unlock_irqrestore(&nic->cmd_lock, flags);
        e100_write_flush(nic);
 }
 
 static inline void e100_disable_irq(struct nic *nic)
 {
+       unsigned long flags;
+
+       spin_lock_irqsave(&nic->cmd_lock, flags);
        writeb(irq_mask_all, &nic->csr->scb.cmd_hi);
+       spin_unlock_irqrestore(&nic->cmd_lock, flags);
        e100_write_flush(nic);
 }
 
@@ -586,16 +604,6 @@ static void e100_hw_reset(struct nic *nic)
        writel(software_reset, &nic->csr->port);
        e100_write_flush(nic); udelay(20);
 
-       /* TCO workaround - 82559 and greater */
-       if(nic->mac >= mac_82559_D101M) {
-               /* Issue a redundant CU load base without setting
-                * general pointer, and without waiting for scb to
-                * clear.  This gets us into post-driver.  Finally,
-                * wait 20 msec for reset to take effect. */
-               writeb(cuc_load_base, &nic->csr->scb.cmd_lo);
-               mdelay(20);
-       }
-
        /* Mask off our interrupt line - it's unmasked after reset */
        e100_disable_irq(nic);
 }
@@ -613,8 +621,7 @@ static int e100_self_test(struct nic *nic)
        writel(selftest | dma_addr, &nic->csr->port);
        e100_write_flush(nic);
        /* Wait 10 msec for self-test to complete */
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 100 + 1);
+       msleep(10);
 
        /* Interrupts are enabled after self-test */
        e100_disable_irq(nic);
@@ -641,7 +648,8 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
 
        /* Three cmds: write/erase enable, write data, write/erase disable */
        cmd_addr_data[0] = op_ewen << (addr_len - 2);
-       cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) | data;
+       cmd_addr_data[1] = (((op_write << addr_len) | addr) << 16) |
+               cpu_to_le16(data);
        cmd_addr_data[2] = op_ewds << (addr_len - 2);
 
        /* Bit-bang cmds to write word to eeprom */
@@ -661,14 +669,12 @@ static void e100_eeprom_write(struct nic *nic, u16 addr_len, u16 addr, u16 data)
                        e100_write_flush(nic); udelay(4);
                }
                /* Wait 10 msec for cmd to complete */
-               set_current_state(TASK_UNINTERRUPTIBLE);
-               schedule_timeout(HZ / 100 + 1);
+               msleep(10);
 
                /* Chip deselect */
                writeb(0, &nic->csr->eeprom_ctrl_lo);
                e100_write_flush(nic); udelay(4);
        }
-
 };
 
 /* General technique stolen from the eepro100 driver - very clever */
@@ -709,7 +715,7 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr)
        writeb(0, &nic->csr->eeprom_ctrl_lo);
        e100_write_flush(nic); udelay(4);
 
-       return data;
+       return le16_to_cpu(data);
 };
 
 /* Load entire EEPROM image into driver cache and validate checksum */
@@ -724,12 +730,12 @@ static int e100_eeprom_load(struct nic *nic)
        for(addr = 0; addr < nic->eeprom_wc; addr++) {
                nic->eeprom[addr] = e100_eeprom_read(nic, &addr_len, addr);
                if(addr < nic->eeprom_wc - 1)
-                       checksum += nic->eeprom[addr];
+                       checksum += cpu_to_le16(nic->eeprom[addr]);
        }
 
        /* The checksum, stored in the last word, is calculated such that
         * the sum of words should be 0xBABA */
-       checksum = 0xBABA - checksum;
+       checksum = le16_to_cpu(0xBABA - checksum);
        if(checksum != nic->eeprom[nic->eeprom_wc - 1]) {
                DPRINTK(PROBE, ERR, "EEPROM corrupted\n");
                return -EAGAIN;
@@ -756,9 +762,10 @@ static int e100_eeprom_save(struct nic *nic, u16 start, u16 count)
        /* The checksum, stored in the last word, is calculated such that
         * the sum of words should be 0xBABA */
        for(addr = 0; addr < nic->eeprom_wc - 1; addr++)
-               checksum += nic->eeprom[addr];
-       nic->eeprom[nic->eeprom_wc - 1] = 0xBABA - checksum;
-       e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1, 0xBABA - checksum);
+               checksum += cpu_to_le16(nic->eeprom[addr]);
+       nic->eeprom[nic->eeprom_wc - 1] = le16_to_cpu(0xBABA - checksum);
+       e100_eeprom_write(nic, addr_len, nic->eeprom_wc - 1,
+               nic->eeprom[nic->eeprom_wc - 1]);
 
        return 0;
 }
@@ -826,8 +833,8 @@ static inline int e100_exec_cb(struct nic *nic, struct sk_buff *skb,
        cb->prev->command &= cpu_to_le16(~cb_s);
 
        while(nic->cb_to_send != nic->cb_to_use) {
-               if(unlikely((err = e100_exec_cmd(nic, nic->cuc_cmd,
-                       nic->cb_to_send->dma_addr)))) {
+               if(unlikely(e100_exec_cmd(nic, nic->cuc_cmd,
+                       nic->cb_to_send->dma_addr))) {
                        /* Ok, here's where things get sticky.  It's
                         * possible that we can't schedule the command
                         * because the controller is too busy, so
@@ -867,12 +874,12 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
 
 static int mdio_read(struct net_device *netdev, int addr, int reg)
 {
-       return mdio_ctrl(netdev->priv, addr, mdi_read, reg, 0);
+       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
 }
 
 static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
 {
-       mdio_ctrl(netdev->priv, addr, mdi_write, reg, data);
+       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
 }
 
 static void e100_get_defaults(struct nic *nic)
@@ -979,6 +986,27 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
                c[16], c[17], c[18], c[19], c[20], c[21], c[22], c[23]);
 }
 
+static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb)
+{
+       int i;
+       static const u32 ucode[UCODE_SIZE] = {
+               /* NFS packets are misinterpreted as TCO packets and
+                * incorrectly routed to the BMC over SMBus.  This
+                * microcode patch checks the fragmented IP bit in the
+                * NFS/UDP header to distinguish between NFS and TCO. */
+               0x0EF70E36, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF, 0x1FFF1FFF,
+               0x1FFF1FFF, 0x00906E41, 0x00800E3C, 0x00E00E39, 0x00000000,
+               0x00906EFD, 0x00900EFD, 0x00E00EF8,
+       };
+
+       if(nic->mac == mac_82551_F || nic->mac == mac_82551_10) {
+               for(i = 0; i < UCODE_SIZE; i++)
+                       cb->u.ucode[i] = cpu_to_le32(ucode[i]);
+               cb->command = cpu_to_le16(cb_ucode);
+       } else
+               cb->command = cpu_to_le16(cb_nop);
+}
+
 static void e100_setup_iaaddr(struct nic *nic, struct cb *cb,
        struct sk_buff *skb)
 {
@@ -1044,7 +1072,9 @@ static int e100_phy_init(struct nic *nic)
                mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong);
        }
 
-       if(nic->mac >= mac_82550_D102)
+       if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && 
+               (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000) && 
+               (nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)))
                /* enable/disable MDI/MDI-X auto-switching */
                mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG,
                        nic->mii.force_media ? 0 : NCONFIG_AUTO_SWITCH);
@@ -1068,6 +1098,8 @@ static int e100_hw_init(struct nic *nic)
                return err;
        if((err = e100_exec_cmd(nic, ruc_load_base, 0)))
                return err;
+       if((err = e100_exec_cb(nic, NULL, e100_load_ucode)))
+               return err;
        if((err = e100_exec_cb(nic, NULL, e100_configure)))
                return err;
        if((err = e100_exec_cb(nic, NULL, e100_setup_iaaddr)))
@@ -1098,7 +1130,7 @@ static void e100_multi(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 
 static void e100_set_multicast_list(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        DPRINTK(HW, DEBUG, "mc_count=%d, flags=0x%04X\n",
                netdev->mc_count, netdev->flags);
@@ -1142,9 +1174,11 @@ static void e100_update_stats(struct nic *nic)
                ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
                        le32_to_cpu(s->tx_lost_crs);
                ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
-               ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors);
+               ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
+                       nic->rx_over_length_errors;
                ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
                ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
+               ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
                ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
                ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
                        le32_to_cpu(s->rx_alignment_errors) +
@@ -1216,8 +1250,13 @@ static void e100_watchdog(unsigned long data)
        mii_check_link(&nic->mii);
 
        /* Software generated interrupt to recover from (rare) Rx
-        * allocation failure */
-       writeb(irq_sw_gen, &nic->csr->scb.cmd_hi);
+       * allocation failure.
+       * Unfortunately have to use a spinlock to not re-enable interrupts
+       * accidentally, due to hardware that shares a register between the
+       * interrupt mask bit and the SW Interrupt generation bit */
+       spin_lock_irq(&nic->cmd_lock);
+       writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi);
+       spin_unlock_irq(&nic->cmd_lock);
        e100_write_flush(nic);
 
        e100_update_stats(nic);
@@ -1251,7 +1290,7 @@ static inline void e100_xmit_prepare(struct nic *nic, struct cb *cb,
 
 static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        int err;
 
        if(nic->flags & ich_10h_workaround) {
@@ -1267,6 +1306,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        switch(err) {
        case -ENOSPC:
                /* We queued the skb, but now we're out of space. */
+               DPRINTK(TX_ERR, DEBUG, "No space for CB\n");
                netif_stop_queue(netdev);
                break;
        case -ENOMEM:
@@ -1322,7 +1362,7 @@ static inline int e100_tx_clean(struct nic *nic)
 static void e100_clean_cbs(struct nic *nic)
 {
        if(nic->cbs) {
-               while(nic->cb_to_clean != nic->cb_to_use) {
+               while(nic->cbs_avail != nic->params.cbs.count) {
                        struct cb *cb = nic->cb_to_clean;
                        if(cb->skb) {
                                pci_unmap_single(nic->pdev,
@@ -1332,8 +1372,8 @@ static void e100_clean_cbs(struct nic *nic)
                                dev_kfree_skb(cb->skb);
                        }
                        nic->cb_to_clean = nic->cb_to_clean->next;
+                       nic->cbs_avail++;
                }
-               nic->cbs_avail = nic->params.cbs.count;
                pci_free_consistent(nic->pdev,
                        sizeof(struct cb) * nic->params.cbs.count,
                        nic->cbs, nic->cbs_dma_addr);
@@ -1387,17 +1427,15 @@ static inline void e100_start_receiver(struct nic *nic)
 #define RFD_BUF_LEN (sizeof(struct rfd) + VLAN_ETH_FRAME_LEN)
 static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
 {
-       unsigned int rx_offset = 2; /* u32 align protocol headers */
-
-       if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + rx_offset)))
+       if(!(rx->skb = dev_alloc_skb(RFD_BUF_LEN + NET_IP_ALIGN)))
                return -ENOMEM;
 
-       /* Align, init, and map the RFA. */
+       /* Align, init, and map the RFD. */
        rx->skb->dev = nic->netdev;
-       skb_reserve(rx->skb, rx_offset);
+       skb_reserve(rx->skb, NET_IP_ALIGN);
        memcpy(rx->skb->data, &nic->blank_rfd, sizeof(struct rfd));
        rx->dma_addr = pci_map_single(nic->pdev, rx->skb->data,
-               RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
+               RFD_BUF_LEN, PCI_DMA_BIDIRECTIONAL);
 
        /* Link the RFD to end of RFA by linking previous RFD to
         * this one, and clearing EL bit of previous.  */
@@ -1408,7 +1446,7 @@ static inline int e100_rx_alloc_skb(struct nic *nic, struct rx *rx)
                wmb();
                prev_rfd->command &= ~cpu_to_le16(cb_el);
                pci_dma_sync_single_for_device(nic->pdev, rx->prev->dma_addr,
-                                              sizeof(struct rfd), PCI_DMA_TODEVICE);
+                       sizeof(struct rfd), PCI_DMA_TODEVICE);
        }
 
        return 0;
@@ -1426,14 +1464,14 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
 
        /* Need to sync before taking a peek at cb_complete bit */
        pci_dma_sync_single_for_cpu(nic->pdev, rx->dma_addr,
-                                   sizeof(struct rfd), PCI_DMA_FROMDEVICE);
+               sizeof(struct rfd), PCI_DMA_FROMDEVICE);
        rfd_status = le16_to_cpu(rfd->status);
 
        DPRINTK(RX_STATUS, DEBUG, "status=0x%04X\n", rfd_status);
 
        /* If data isn't ready, nothing to indicate */
        if(unlikely(!(rfd_status & cb_complete)))
-                       return -EAGAIN;
+               return -EAGAIN;
 
        /* Get actual data size */
        actual_size = le16_to_cpu(rfd->actual_size) & 0x3FFF;
@@ -1442,7 +1480,7 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
 
        /* Get data */
        pci_unmap_single(nic->pdev, rx->dma_addr,
-                        RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
+               RFD_BUF_LEN, PCI_DMA_FROMDEVICE);
 
        /* Pull off the RFD and put the actual data (minus eth hdr) */
        skb_reserve(skb, sizeof(struct rfd));
@@ -1455,18 +1493,14 @@ static inline int e100_rx_indicate(struct nic *nic, struct rx *rx,
                dev_kfree_skb_any(skb);
        } else if(actual_size > nic->netdev->mtu + VLAN_ETH_HLEN) {
                /* Don't indicate oversized frames */
-               nic->net_stats.rx_over_errors++;
+               nic->rx_over_length_errors++;
                nic->net_stats.rx_dropped++;
                dev_kfree_skb_any(skb);
        } else {
                nic->net_stats.rx_packets++;
                nic->net_stats.rx_bytes += actual_size;
                nic->netdev->last_rx = jiffies;
-#ifdef CONFIG_E100_NAPI
                netif_receive_skb(skb);
-#else
-               netif_rx(skb);
-#endif
                if(work_done)
                        (*work_done)++;
        }
@@ -1545,7 +1579,7 @@ static int e100_rx_alloc_list(struct nic *nic)
 static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
        struct net_device *netdev = dev_id;
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        u8 stat_ack = readb(&nic->csr->scb.stat_ack);
 
        DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack);
@@ -1561,23 +1595,15 @@ static irqreturn_t e100_intr(int irq, void *dev_id, struct pt_regs *regs)
        if(stat_ack & stat_ack_rnr)
                nic->ru_running = 0;
 
-#ifdef CONFIG_E100_NAPI
        e100_disable_irq(nic);
        netif_rx_schedule(netdev);
-#else
-       if(stat_ack & stat_ack_rx)
-               e100_rx_clean(nic, NULL, 0);
-       if(stat_ack & stat_ack_tx)
-               e100_tx_clean(nic);
-#endif
 
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_E100_NAPI
 static int e100_poll(struct net_device *netdev, int *budget)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        unsigned int work_to_do = min(netdev->quota, *budget);
        unsigned int work_done = 0;
        int tx_cleaned;
@@ -1597,27 +1623,27 @@ static int e100_poll(struct net_device *netdev, int *budget)
 
        return 1;
 }
-#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void e100_netpoll(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        e100_disable_irq(nic);
        e100_intr(nic->pdev->irq, netdev, NULL);
+       e100_tx_clean(nic);
        e100_enable_irq(nic);
 }
 #endif
 
 static struct net_device_stats *e100_get_stats(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return &nic->net_stats;
 }
 
 static int e100_set_mac_address(struct net_device *netdev, void *p)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        struct sockaddr *addr = p;
 
        if (!is_valid_ether_addr(addr->sa_data))
@@ -1640,7 +1666,7 @@ static int e100_change_mtu(struct net_device *netdev, int new_mtu)
 static int e100_asf(struct nic *nic)
 {
        /* ASF can be enabled from eeprom */
-       return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1055) &&
+       return((nic->pdev->device >= 0x1050) && (nic->pdev->device <= 0x1057) &&
           (nic->eeprom[eeprom_config_asf] & eeprom_asf) &&
           !(nic->eeprom[eeprom_config_asf] & eeprom_gcl) &&
           ((nic->eeprom[eeprom_smbus_addr] & 0xFF) != 0xFE));
@@ -1658,17 +1684,16 @@ static int e100_up(struct nic *nic)
                goto err_clean_cbs;
        e100_set_multicast_list(nic->netdev);
        e100_start_receiver(nic);
-       netif_start_queue(nic->netdev);
        mod_timer(&nic->watchdog, jiffies);
        if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
                nic->netdev->name, nic->netdev)))
                goto err_no_irq;
        e100_enable_irq(nic);
+       netif_wake_queue(nic->netdev);
        return 0;
 
 err_no_irq:
        del_timer_sync(&nic->watchdog);
-       netif_stop_queue(nic->netdev);
 err_clean_cbs:
        e100_clean_cbs(nic);
 err_rx_clean_list:
@@ -1689,12 +1714,12 @@ static void e100_down(struct nic *nic)
 
 static void e100_tx_timeout(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        DPRINTK(TX_ERR, DEBUG, "scb.status=0x%02X\n",
                readb(&nic->csr->scb.status));
-       e100_down(netdev->priv);
-       e100_up(netdev->priv);
+       e100_down(netdev_priv(netdev));
+       e100_up(netdev_priv(netdev));
 }
 
 static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
@@ -1734,12 +1759,11 @@ static int e100_loopback_test(struct nic *nic, enum loopback loopback_mode)
        memset(skb->data, 0xFF, ETH_DATA_LEN);
        e100_xmit_frame(skb, nic->netdev);
 
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 100 + 1);
+       msleep(10);
 
        if(memcmp(nic->rx_to_clean->skb->data + sizeof(struct rfd),
           skb->data, ETH_DATA_LEN))
-                       err = -EAGAIN;
+               err = -EAGAIN;
 
 err_loopback_none:
        mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR, 0);
@@ -1770,13 +1794,13 @@ static void e100_blink_led(unsigned long data)
 
 static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return mii_ethtool_gset(&nic->mii, cmd);
 }
 
 static int e100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        int err;
 
        mdio_write(netdev, nic->mii.phy_id, MII_BMCR, BMCR_RESET);
@@ -1789,7 +1813,7 @@ static int e100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 static void e100_get_drvinfo(struct net_device *netdev,
        struct ethtool_drvinfo *info)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
        strcpy(info->fw_version, "N/A");
@@ -1798,7 +1822,7 @@ static void e100_get_drvinfo(struct net_device *netdev,
 
 static int e100_get_regs_len(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 #define E100_PHY_REGS          0x1C
 #define E100_REGS_LEN          1 + E100_PHY_REGS + \
        sizeof(nic->mem->dump_buf) / sizeof(u32)
@@ -1808,7 +1832,7 @@ static int e100_get_regs_len(struct net_device *netdev)
 static void e100_get_regs(struct net_device *netdev,
        struct ethtool_regs *regs, void *p)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        u32 *buff = p;
        int i;
 
@@ -1821,22 +1845,21 @@ static void e100_get_regs(struct net_device *netdev,
                        mdio_read(netdev, nic->mii.phy_id, i);
        memset(nic->mem->dump_buf, 0, sizeof(nic->mem->dump_buf));
        e100_exec_cb(nic, NULL, e100_dump);
-       set_current_state(TASK_UNINTERRUPTIBLE);
-       schedule_timeout(HZ / 100 + 1);
+       msleep(10);
        memcpy(&buff[2 + E100_PHY_REGS], nic->mem->dump_buf,
                sizeof(nic->mem->dump_buf));
 }
 
 static void e100_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        wol->supported = (nic->mac >= mac_82558_D101_A4) ?  WAKE_MAGIC : 0;
        wol->wolopts = (nic->flags & wol_magic) ? WAKE_MAGIC : 0;
 }
 
 static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0)
                return -EOPNOTSUPP;
@@ -1854,31 +1877,31 @@ static int e100_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 
 static u32 e100_get_msglevel(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return nic->msg_enable;
 }
 
 static void e100_set_msglevel(struct net_device *netdev, u32 value)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        nic->msg_enable = value;
 }
 
 static int e100_nway_reset(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return mii_nway_restart(&nic->mii);
 }
 
 static u32 e100_get_link(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return mii_link_ok(&nic->mii);
 }
 
 static int e100_get_eeprom_len(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        return nic->eeprom_wc << 1;
 }
 
@@ -1886,7 +1909,7 @@ static int e100_get_eeprom_len(struct net_device *netdev)
 static int e100_get_eeprom(struct net_device *netdev,
        struct ethtool_eeprom *eeprom, u8 *bytes)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        eeprom->magic = E100_EEPROM_MAGIC;
        memcpy(bytes, &((u8 *)nic->eeprom)[eeprom->offset], eeprom->len);
@@ -1897,10 +1920,11 @@ static int e100_get_eeprom(struct net_device *netdev,
 static int e100_set_eeprom(struct net_device *netdev,
        struct ethtool_eeprom *eeprom, u8 *bytes)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        if(eeprom->magic != E100_EEPROM_MAGIC)
                return -EINVAL;
+
        memcpy(&((u8 *)nic->eeprom)[eeprom->offset], bytes, eeprom->len);
 
        return e100_eeprom_save(nic, eeprom->offset >> 1,
@@ -1910,7 +1934,7 @@ static int e100_set_eeprom(struct net_device *netdev,
 static void e100_get_ringparam(struct net_device *netdev,
        struct ethtool_ringparam *ring)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        struct param_range *rfds = &nic->params.rfds;
        struct param_range *cbs = &nic->params.cbs;
 
@@ -1927,16 +1951,21 @@ static void e100_get_ringparam(struct net_device *netdev,
 static int e100_set_ringparam(struct net_device *netdev,
        struct ethtool_ringparam *ring)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        struct param_range *rfds = &nic->params.rfds;
        struct param_range *cbs = &nic->params.cbs;
 
+       if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 
+               return -EINVAL;
+
        if(netif_running(netdev))
                e100_down(nic);
        rfds->count = max(ring->rx_pending, rfds->min);
        rfds->count = min(rfds->count, rfds->max);
        cbs->count = max(ring->tx_pending, cbs->min);
        cbs->count = min(cbs->count, cbs->max);
+       DPRINTK(DRV, INFO, "Ring Param settings: rx: %d, tx %d\n",
+               rfds->count, cbs->count);
        if(netif_running(netdev))
                e100_up(nic);
 
@@ -1960,18 +1989,27 @@ static int e100_diag_test_count(struct net_device *netdev)
 static void e100_diag_test(struct net_device *netdev,
        struct ethtool_test *test, u64 *data)
 {
-       struct nic *nic = netdev->priv;
-       int i;
+       struct ethtool_cmd cmd;
+       struct nic *nic = netdev_priv(netdev);
+       int i, err;
 
        memset(data, 0, E100_TEST_LEN * sizeof(u64));
        data[0] = !mii_link_ok(&nic->mii);
        data[1] = e100_eeprom_load(nic);
        if(test->flags & ETH_TEST_FL_OFFLINE) {
+
+               /* save speed, duplex & autoneg settings */
+               err = mii_ethtool_gset(&nic->mii, &cmd);
+
                if(netif_running(netdev))
                        e100_down(nic);
                data[2] = e100_self_test(nic);
                data[3] = e100_loopback_test(nic, lb_mac);
                data[4] = e100_loopback_test(nic, lb_phy);
+
+               /* restore speed, duplex & autoneg settings */
+               err = mii_ethtool_sset(&nic->mii, &cmd);
+
                if(netif_running(netdev))
                        e100_up(nic);
        }
@@ -1981,13 +2019,12 @@ static void e100_diag_test(struct net_device *netdev,
 
 static int e100_phys_id(struct net_device *netdev, u32 data)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
                data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
        mod_timer(&nic->blink_timer, jiffies);
-       set_current_state(TASK_INTERRUPTIBLE);
-       schedule_timeout(data * HZ);
+       msleep_interruptible(data * 1000);
        del_timer_sync(&nic->blink_timer);
        mdio_write(netdev, nic->mii.phy_id, MII_LED_CONTROL, 0);
 
@@ -2017,7 +2054,7 @@ static int e100_get_stats_count(struct net_device *netdev)
 static void e100_get_ethtool_stats(struct net_device *netdev,
        struct ethtool_stats *stats, u64 *data)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        int i;
 
        for(i = 0; i < E100_NET_STATS_LEN; i++)
@@ -2072,10 +2109,9 @@ static struct ethtool_ops e100_ethtool_ops = {
 
 static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
 {
-       struct nic *nic = netdev->priv;
-       struct mii_ioctl_data *mii = (struct mii_ioctl_data *)&ifr->ifr_data;
+       struct nic *nic = netdev_priv(netdev);
 
-       return generic_mii_ioctl(&nic->mii, mii, cmd, NULL);
+       return generic_mii_ioctl(&nic->mii, if_mii(ifr), cmd, NULL);
 }
 
 static int e100_alloc(struct nic *nic)
@@ -2096,7 +2132,7 @@ static void e100_free(struct nic *nic)
 
 static int e100_open(struct net_device *netdev)
 {
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
        int err = 0;
 
        netif_carrier_off(netdev);
@@ -2107,7 +2143,7 @@ static int e100_open(struct net_device *netdev)
 
 static int e100_close(struct net_device *netdev)
 {
-       e100_down(netdev->priv);
+       e100_down(netdev_priv(netdev));
        return 0;
 }
 
@@ -2135,15 +2171,14 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
        netdev->tx_timeout = e100_tx_timeout;
        netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
-#ifdef CONFIG_E100_NAPI
        netdev->poll = e100_poll;
        netdev->weight = E100_NAPI_WEIGHT;
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
        netdev->poll_controller = e100_netpoll;
 #endif
+       strcpy(netdev->name, pci_name(pdev));
 
-       nic = netdev->priv;
+       nic = netdev_priv(netdev);
        nic->netdev = netdev;
        nic->pdev = pdev;
        nic->msg_enable = (1 << debug) - 1;
@@ -2166,8 +2201,6 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                goto err_out_disable_pdev;
        }
 
-       pci_set_master(pdev);
-
        if((err = pci_set_dma_mask(pdev, 0xFFFFFFFFULL))) {
                DPRINTK(PROBE, ERR, "No usable DMA configuration, aborting.\n");
                goto err_out_free_res;
@@ -2188,9 +2221,18 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        else
                nic->flags &= ~ich;
 
+       e100_get_defaults(nic);
+
        spin_lock_init(&nic->cb_lock);
        spin_lock_init(&nic->cmd_lock);
 
+       /* Reset the device before pci_set_master() in case device is in some
+        * funky state and has an interrupt pending - hint: we don't have the
+        * interrupt handler registered yet. */
+       e100_hw_reset(nic);
+
+       pci_set_master(pdev);
+
        init_timer(&nic->watchdog);
        nic->watchdog.function = e100_watchdog;
        nic->watchdog.data = (unsigned long)nic;
@@ -2203,15 +2245,12 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                goto err_out_iounmap;
        }
 
-       e100_get_defaults(nic);
-       e100_hw_reset(nic);
        e100_phy_init(nic);
 
        if((err = e100_eeprom_load(nic)))
                goto err_out_free;
-       ((u16 *)netdev->dev_addr)[0] = le16_to_cpu(nic->eeprom[0]);
-       ((u16 *)netdev->dev_addr)[1] = le16_to_cpu(nic->eeprom[1]);
-       ((u16 *)netdev->dev_addr)[2] = le16_to_cpu(nic->eeprom[2]);
+
+       memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
        if(!is_valid_ether_addr(netdev->dev_addr)) {
                DPRINTK(PROBE, ERR, "Invalid MAC address from "
                        "EEPROM, aborting.\n");
@@ -2226,6 +2265,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
 
        pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic)));
 
+       strcpy(netdev->name, "eth%d");
        if((err = register_netdev(netdev))) {
                DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
                goto err_out_free;
@@ -2258,7 +2298,7 @@ static void __devexit e100_remove(struct pci_dev *pdev)
        struct net_device *netdev = pci_get_drvdata(pdev);
 
        if(netdev) {
-               struct nic *nic = netdev->priv;
+               struct nic *nic = netdev_priv(netdev);
                unregister_netdev(netdev);
                e100_free(nic);
                iounmap(nic->csr);
@@ -2273,17 +2313,17 @@ static void __devexit e100_remove(struct pci_dev *pdev)
 static int e100_suspend(struct pci_dev *pdev, u32 state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
        if(netif_running(netdev))
                e100_down(nic);
        e100_hw_reset(nic);
        netif_device_detach(netdev);
 
-       pci_save_state(pdev, nic->pm_state);
+       pci_save_state(pdev);
        pci_enable_wake(pdev, state, nic->flags & (wol_magic | e100_asf(nic)));
        pci_disable_device(pdev);
-       pci_set_power_state(pdev, state);
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
        return 0;
 }
@@ -2291,10 +2331,10 @@ static int e100_suspend(struct pci_dev *pdev, u32 state)
 static int e100_resume(struct pci_dev *pdev)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
-       struct nic *nic = netdev->priv;
+       struct nic *nic = netdev_priv(netdev);
 
-       pci_set_power_state(pdev, 0);
-       pci_restore_state(pdev, nic->pm_state);
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
        e100_hw_init(nic);
 
        netif_device_attach(netdev);
@@ -2322,7 +2362,7 @@ static int __init e100_init_module(void)
                printk(KERN_INFO PFX "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
                printk(KERN_INFO PFX "%s\n", DRV_COPYRIGHT);
        }
-        return pci_module_init(&e100_driver);
+       return pci_module_init(&e100_driver);
 }
 
 static void __exit e100_cleanup_module(void)