natsemi: fix MMIO for PPC 44x platforms
[safe/jmp/linux-2.6] / drivers / net / starfire.c
index ed1f599..7b7b171 100644 (file)
 
        Support and updates available at
        http://www.scyld.com/network/starfire.html
+       [link no longer provides useful info -jgarzik]
 
-       -----------------------------------------------------------
-
-       Linux kernel-specific changes:
-
-       LK1.1.1 (jgarzik):
-       - Use PCI driver interface
-       - Fix MOD_xxx races
-       - softnet fixups
-
-       LK1.1.2 (jgarzik):
-       - Merge Becker version 0.15
-
-       LK1.1.3 (Andrew Morton)
-       - Timer cleanups
-
-       LK1.1.4 (jgarzik):
-       - Merge Becker version 1.03
-
-       LK1.2.1 (Ion Badulescu <ionut@cs.columbia.edu>)
-       - Support hardware Rx/Tx checksumming
-       - Use the GFP firmware taken from Adaptec's Netware driver
-
-       LK1.2.2 (Ion Badulescu)
-       - Backported to 2.2.x
-
-       LK1.2.3 (Ion Badulescu)
-       - Fix the flaky mdio interface
-       - More compat clean-ups
-
-       LK1.2.4 (Ion Badulescu)
-       - More 2.2.x initialization fixes
-
-       LK1.2.5 (Ion Badulescu)
-       - Several fixes from Manfred Spraul
-
-       LK1.2.6 (Ion Badulescu)
-       - Fixed ifup/ifdown/ifup problem in 2.4.x
-
-       LK1.2.7 (Ion Badulescu)
-       - Removed unused code
-       - Made more functions static and __init
-
-       LK1.2.8 (Ion Badulescu)
-       - Quell bogus error messages, inform about the Tx threshold
-       - Removed #ifdef CONFIG_PCI, this driver is PCI only
-
-       LK1.2.9 (Ion Badulescu)
-       - Merged Jeff Garzik's changes from 2.4.4-pre5
-       - Added 2.2.x compatibility stuff required by the above changes
-
-       LK1.2.9a (Ion Badulescu)
-       - More updates from Jeff Garzik
-
-       LK1.3.0 (Ion Badulescu)
-       - Merged zerocopy support
-
-       LK1.3.1 (Ion Badulescu)
-       - Added ethtool support
-       - Added GPIO (media change) interrupt support
-
-       LK1.3.2 (Ion Badulescu)
-       - Fixed 2.2.x compatibility issues introduced in 1.3.1
-       - Fixed ethtool ioctl returning uninitialized memory
-
-       LK1.3.3 (Ion Badulescu)
-       - Initialize the TxMode register properly
-       - Don't dereference dev->priv after freeing it
-
-       LK1.3.4 (Ion Badulescu)
-       - Fixed initialization timing problems
-       - Fixed interrupt mask definitions
-
-       LK1.3.5 (jgarzik)
-       - ethtool NWAY_RST, GLINK, [GS]MSGLVL support
-
-       LK1.3.6:
-       - Sparc64 support and fixes (Ion Badulescu)
-       - Better stats and error handling (Ion Badulescu)
-       - Use new pci_set_mwi() PCI API function (jgarzik)
-
-       LK1.3.7 (Ion Badulescu)
-       - minimal implementation of tx_timeout()
-       - correctly shutdown the Rx/Tx engines in netdev_close()
-       - added calls to netif_carrier_on/off
-       (patch from Stefan Rompf <srompf@isg.de>)
-       - VLAN support
-
-       LK1.3.8 (Ion Badulescu)
-       - adjust DMA burst size on sparc64
-       - 64-bit support
-       - reworked zerocopy support for 64-bit buffers
-       - working and usable interrupt mitigation/latency
-       - reduced Tx interrupt frequency for lower interrupt overhead
-
-       LK1.3.9 (Ion Badulescu)
-       - bugfix for mcast filter
-       - enable the right kind of Tx interrupts (TxDMADone, not TxDone)
-
-       LK1.4.0 (Ion Badulescu)
-       - NAPI support
-
-       LK1.4.1 (Ion Badulescu)
-       - flush PCI posting buffers after disabling Rx interrupts
-       - put the chip to a D3 slumber on driver unload
-       - added config option to enable/disable NAPI
-
-       LK1.4.2 (Ion Badulescu)
-       - finally added firmware (GPL'ed by Adaptec)
-       - removed compatibility code for 2.2.x
-
-       LK1.4.2.1 (Ion Badulescu)
-       - fixed 32/64 bit issues on i386 + CONFIG_HIGHMEM
-       - added 32-bit padding to outgoing skb's, removed previous workaround
-
-TODO:  - fix forced speed/duplexing code (broken a long time ago, when
-       somebody converted the driver to use the generic MII code)
-       - fix VLAN support
 */
 
 #define DRV_NAME       "starfire"
-#define DRV_VERSION    "1.03+LK1.4.2.1"
-#define DRV_RELDATE    "October 3, 2005"
+#define DRV_VERSION    "2.0"
+#define DRV_RELDATE    "June 27, 2006"
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -157,6 +41,7 @@ TODO:        - fix forced speed/duplexing code (broken a long time ago, when
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/if_vlan.h>
+#include <linux/mm.h>
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -267,10 +152,10 @@ static int full_duplex[MAX_UNITS] = {0, };
  * This SUCKS.
  * We need a much better method to determine if dma_addr_t is 64-bit.
  */
-#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
+#if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR))
 /* 64-bit dma_addr_t */
 #define ADDR_64BITS    /* This chip uses 64 bit addresses. */
-#define netdrv_addr_t u64
+#define netdrv_addr_t __le64
 #define cpu_to_dma(x) cpu_to_le64(x)
 #define dma_to_cpu(x) le64_to_cpu(x)
 #define RX_DESC_Q_ADDR_SIZE RxDescQAddr64bit
@@ -279,7 +164,7 @@ static int full_duplex[MAX_UNITS] = {0, };
 #define TX_COMPL_Q_ADDR_SIZE TxComplQAddr64bit
 #define RX_DESC_ADDR_SIZE RxDescAddr64bit
 #else  /* 32-bit dma_addr_t */
-#define netdrv_addr_t u32
+#define netdrv_addr_t __le32
 #define cpu_to_dma(x) cpu_to_le32(x)
 #define dma_to_cpu(x) le32_to_cpu(x)
 #define RX_DESC_Q_ADDR_SIZE RxDescQAddr32bit
@@ -293,16 +178,13 @@ static int full_duplex[MAX_UNITS] = {0, };
 #define skb_num_frags(skb) (skb_shinfo(skb)->nr_frags + 1)
 
 #ifdef HAVE_NETDEV_POLL
-#define init_poll(dev) \
-do { \
-       dev->poll = &netdev_poll; \
-       dev->weight = max_interrupt_work; \
-} while (0)
-#define netdev_rx(dev, ioaddr) \
+#define init_poll(dev, np) \
+       netif_napi_add(dev, &np->napi, netdev_poll, max_interrupt_work)
+#define netdev_rx(dev, np, ioaddr) \
 do { \
        u32 intr_enable; \
-       if (netif_rx_schedule_prep(dev)) { \
-               __netif_rx_schedule(dev); \
+       if (netif_rx_schedule_prep(dev, &np->napi)) { \
+               __netif_rx_schedule(dev, &np->napi); \
                intr_enable = readl(ioaddr + IntrEnable); \
                intr_enable &= ~(IntrRxDone | IntrRxEmpty); \
                writel(intr_enable, ioaddr + IntrEnable); \
@@ -319,12 +201,12 @@ do { \
 } while (0)
 #define netdev_receive_skb(skb) netif_receive_skb(skb)
 #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_receive_skb(skb, vlgrp, vlid)
-static int     netdev_poll(struct net_device *dev, int *budget);
+static int     netdev_poll(struct napi_struct *napi, int budget);
 #else  /* not HAVE_NETDEV_POLL */
-#define init_poll(dev)
+#define init_poll(dev, np)
 #define netdev_receive_skb(skb) netif_rx(skb)
 #define vlan_netdev_receive_skb(skb, vlgrp, vlid) vlan_hwaccel_rx(skb, vlgrp, vlid)
-#define netdev_rx(dev, ioaddr) \
+#define netdev_rx(dev, np, ioaddr) \
 do { \
        int quota = np->dirty_rx + RX_RING_SIZE - np->cur_rx; \
        __netdev_rx(dev, &quota);\
@@ -334,7 +216,7 @@ do { \
 
 
 /* These identify the driver base version and may not be removed. */
-static const char version[] __devinitdata =
+static char version[] =
 KERN_INFO "starfire.c:v1.03 7/26/2000  Written by Donald Becker <becker@scyld.com>\n"
 KERN_INFO " (unofficial 2.2/2.4 kernel port, version " DRV_VERSION ", " DRV_RELDATE ")\n";
 
@@ -612,7 +494,7 @@ enum intr_ctrl_bits {
 
 /* The Rx and Tx buffer descriptors. */
 struct starfire_rx_desc {
-       dma_addr_t rxaddr;
+       netdrv_addr_t rxaddr;
 };
 enum rx_desc_bits {
        RxDescValid=1, RxDescEndRing=2,
@@ -620,25 +502,25 @@ enum rx_desc_bits {
 
 /* Completion queue entry. */
 struct short_rx_done_desc {
-       u32 status;                     /* Low 16 bits is length. */
+       __le32 status;                  /* Low 16 bits is length. */
 };
 struct basic_rx_done_desc {
-       u32 status;                     /* Low 16 bits is length. */
-       u16 vlanid;
-       u16 status2;
+       __le32 status;                  /* Low 16 bits is length. */
+       __le16 vlanid;
+       __le16 status2;
 };
 struct csum_rx_done_desc {
-       u32 status;                     /* Low 16 bits is length. */
-       u16 csum;                       /* Partial checksum */
-       u16 status2;
+       __le32 status;                  /* Low 16 bits is length. */
+       __le16 csum;                    /* Partial checksum */
+       __le16 status2;
 };
 struct full_rx_done_desc {
-       u32 status;                     /* Low 16 bits is length. */
-       u16 status3;
-       u16 status2;
-       u16 vlanid;
-       u16 csum;                       /* partial checksum */
-       u32 timestamp;
+       __le32 status;                  /* Low 16 bits is length. */
+       __le16 status3;
+       __le16 status2;
+       __le16 vlanid;
+       __le16 csum;                    /* partial checksum */
+       __le32 timestamp;
 };
 /* XXX: this is ugly and I'm not sure it's worth the trouble -Ion */
 #ifdef VLAN_SUPPORT
@@ -655,15 +537,15 @@ enum rx_done_bits {
 
 /* Type 1 Tx descriptor. */
 struct starfire_tx_desc_1 {
-       u32 status;                     /* Upper bits are status, lower 16 length. */
-       u32 addr;
+       __le32 status;                  /* Upper bits are status, lower 16 length. */
+       __le32 addr;
 };
 
 /* Type 2 Tx descriptor. */
 struct starfire_tx_desc_2 {
-       u32 status;                     /* Upper bits are status, lower 16 length. */
-       u32 reserved;
-       u64 addr;
+       __le32 status;                  /* Upper bits are status, lower 16 length. */
+       __le32 reserved;
+       __le64 addr;
 };
 
 #ifdef ADDR_64BITS
@@ -681,9 +563,9 @@ enum tx_desc_bits {
        TxRingWrap=0x04000000, TxCalTCP=0x02000000,
 };
 struct tx_done_desc {
-       u32 status;                     /* timestamp, index. */
+       __le32 status;                  /* timestamp, index. */
 #if 0
-       u32 intrstatus;                 /* interrupt status */
+       __le32 intrstatus;              /* interrupt status */
 #endif
 };
 
@@ -714,6 +596,8 @@ struct netdev_private {
        struct tx_done_desc *tx_done_q;
        dma_addr_t tx_done_q_dma;
        unsigned int tx_done;
+       struct napi_struct napi;
+       struct net_device *dev;
        struct net_device_stats stats;
        struct pci_dev *pci_dev;
 #ifdef VLAN_SUPPORT
@@ -748,7 +632,7 @@ static void check_duplex(struct net_device *dev);
 static void    tx_timeout(struct net_device *dev);
 static void    init_ring(struct net_device *dev);
 static int     start_tx(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static irqreturn_t intr_handler(int irq, void *dev_instance);
 static void    netdev_error(struct net_device *dev, int intr_status);
 static int     __netdev_rx(struct net_device *dev, int *quota);
 static void    refill_rx_ring(struct net_device *dev);
@@ -758,7 +642,7 @@ static struct net_device_stats *get_stats(struct net_device *dev);
 static int     netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int     netdev_close(struct net_device *dev);
 static void    netdev_media_change(struct net_device *dev);
-static struct ethtool_ops ethtool_ops;
+static const struct ethtool_ops ethtool_ops;
 
 
 #ifdef VLAN_SUPPORT
@@ -792,8 +676,7 @@ static void netdev_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        spin_lock(&np->lock);
        if (debug > 1)
                printk("%s: removing vlanid %d from vlan filter\n", dev->name, vid);
-       if (np->vlgrp)
-               np->vlgrp->vlan_devices[vid] = NULL;
+       vlan_group_set_device(np->vlgrp, vid, NULL);
        set_rx_mode(dev);
        spin_unlock(&np->lock);
 }
@@ -811,6 +694,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        void __iomem *base;
        int drv_flags, io_size;
        int boguscnt;
+       DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -836,7 +720,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
                printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx);
                return -ENOMEM;
        }
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        irq = pdev->irq;
@@ -846,7 +729,6 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
                goto err_out_free_netdev;
        }
 
-       /* ioremap is borken in Linux-2.2.x/sparc64 */
        base = ioremap(ioaddr, io_size);
        if (!base) {
                printk(KERN_ERR DRV_NAME " %d: cannot remap %#x @ %#lx, aborting\n",
@@ -857,7 +739,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        pci_set_master(pdev);
 
        /* enable MWI -- it vastly improves Rx performance on sparc64 */
-       pci_set_mwi(pdev);
+       pci_try_set_mwi(pdev);
 
 #ifdef ZEROCOPY
        /* Starfire can do TCP/UDP checksumming */
@@ -908,6 +790,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        dev->irq = irq;
 
        np = netdev_priv(dev);
+       np->dev = dev;
        np->base = base;
        spin_lock_init(&np->lock);
        pci_set_drvdata(pdev, dev);
@@ -968,7 +851,7 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        dev->hard_start_xmit = &start_tx;
        dev->tx_timeout = tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
-       init_poll(dev);
+       init_poll(dev, np);
        dev->stop = &netdev_close;
        dev->get_stats = &get_stats;
        dev->set_multicast_list = &set_rx_mode;
@@ -981,11 +864,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev,
        if (register_netdev(dev))
                goto err_out_cleardev;
 
-       printk(KERN_INFO "%s: %s at %p, ",
-                  dev->name, netdrv_tbl[chip_idx].name, base);
-       for (i = 0; i < 5; i++)
-               printk("%2.2x:", dev->dev_addr[i]);
-       printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+       printk(KERN_INFO "%s: %s at %p, %s, IRQ %d.\n",
+              dev->name, netdrv_tbl[chip_idx].name, base,
+              print_mac(mac, dev->dev_addr), irq);
 
        if (drv_flags & CanHaveMII) {
                int phy, phy_idx = 0;
@@ -1082,7 +963,7 @@ static int netdev_open(struct net_device *dev)
                       dev->name, dev->irq);
 
        /* Allocate the various queues. */
-       if (np->queue_mem == 0) {
+       if (!np->queue_mem) {
                tx_done_q_size = ((sizeof(struct tx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
                rx_done_q_size = ((sizeof(rx_done_desc) * DONE_Q_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
                tx_ring_size = ((sizeof(starfire_tx_desc) * TX_RING_SIZE + QUEUE_ALIGN - 1) / QUEUE_ALIGN) * QUEUE_ALIGN;
@@ -1155,11 +1036,11 @@ static int netdev_open(struct net_device *dev)
        writew(0, ioaddr + PerfFilterTable + 4);
        writew(0, ioaddr + PerfFilterTable + 8);
        for (i = 1; i < 16; i++) {
-               u16 *eaddrs = (u16 *)dev->dev_addr;
+               __be16 *eaddrs = (__be16 *)dev->dev_addr;
                void __iomem *setup_frm = ioaddr + PerfFilterTable + i * 16;
-               writew(cpu_to_be16(eaddrs[2]), setup_frm); setup_frm += 4;
-               writew(cpu_to_be16(eaddrs[1]), setup_frm); setup_frm += 4;
-               writew(cpu_to_be16(eaddrs[0]), setup_frm); setup_frm += 8;
+               writew(be16_to_cpu(eaddrs[2]), setup_frm); setup_frm += 4;
+               writew(be16_to_cpu(eaddrs[1]), setup_frm); setup_frm += 4;
+               writew(be16_to_cpu(eaddrs[0]), setup_frm); setup_frm += 8;
        }
 
        /* Initialize other registers. */
@@ -1173,6 +1054,9 @@ static int netdev_open(struct net_device *dev)
 
        writel(np->intr_timer_ctrl, ioaddr + IntrTimerCtrl);
 
+#ifdef HAVE_NETDEV_POLL
+       napi_enable(&np->napi);
+#endif
        netif_start_queue(dev);
 
        if (debug > 1)
@@ -1347,7 +1231,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
        }
 
 #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
-       if (skb->ip_summed == CHECKSUM_HW) {
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
                if (skb_padto(skb, (skb->len + PADDING_MASK) & ~PADDING_MASK))
                        return NETDEV_TX_OK;
        }
@@ -1369,7 +1253,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
                                status |= TxDescIntr;
                                np->reap_tx = 0;
                        }
-                       if (skb->ip_summed == CHECKSUM_HW) {
+                       if (skb->ip_summed == CHECKSUM_PARTIAL) {
                                status |= TxCalTCP;
                                np->stats.tx_compressed++;
                        }
@@ -1424,7 +1308,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
-static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+static irqreturn_t intr_handler(int irq, void *dev_instance)
 {
        struct net_device *dev = dev_instance;
        struct netdev_private *np = netdev_priv(dev);
@@ -1447,7 +1331,7 @@ static irqreturn_t intr_handler(int irq, void *dev_instance, struct pt_regs *rgs
                handled = 1;
 
                if (intr_status & (IntrRxDone | IntrRxEmpty))
-                       netdev_rx(dev, ioaddr);
+                       netdev_rx(dev, np, ioaddr);
 
                /* Scavenge the skbuff list based on the Tx-done queue.
                   There are redundant checks here that may be cleaned up
@@ -1569,12 +1453,11 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                   to a minimally-sized skbuff. */
                if (pkt_len < rx_copybreak
                    && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-                       skb->dev = dev;
                        skb_reserve(skb, 2);    /* 16 byte align the IP header */
                        pci_dma_sync_single_for_cpu(np->pci_dev,
                                                    np->rx_info[entry].mapping,
                                                    pkt_len, PCI_DMA_FROMDEVICE);
-                       eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0);
+                       skb_copy_to_linear_data(skb, np->rx_info[entry].skb->data, pkt_len);
                        pci_dma_sync_single_for_device(np->pci_dev,
                                                       np->rx_info[entry].mapping,
                                                       pkt_len, PCI_DMA_FROMDEVICE);
@@ -1588,13 +1471,15 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                }
 #ifndef final_version                  /* Remove after testing. */
                /* You will want this info for the initial debug. */
-               if (debug > 5)
-                       printk(KERN_DEBUG "  Rx data %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:"
-                              "%2.2x %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x %2.2x%2.2x.\n",
-                              skb->data[0], skb->data[1], skb->data[2], skb->data[3],
-                              skb->data[4], skb->data[5], skb->data[6], skb->data[7],
-                              skb->data[8], skb->data[9], skb->data[10],
-                              skb->data[11], skb->data[12], skb->data[13]);
+               if (debug > 5) {
+                       printk(KERN_DEBUG "  Rx data " MAC_FMT " " MAC_FMT
+                              " %2.2x%2.2x.\n",
+                              skb->data[0], skb->data[1], skb->data[2],
+                              skb->data[3], skb->data[4], skb->data[5],
+                              skb->data[6], skb->data[7], skb->data[8],
+                              skb->data[9], skb->data[10], skb->data[11],
+                              skb->data[12], skb->data[13]);
+               }
 #endif
 
                skb->protocol = eth_type_trans(skb, dev);
@@ -1616,7 +1501,7 @@ static int __netdev_rx(struct net_device *dev, int *quota)
                 * Until then, the printk stays. :-) -Ion
                 */
                else if (le16_to_cpu(desc->status2) & 0x0040) {
-                       skb->ip_summed = CHECKSUM_HW;
+                       skb->ip_summed = CHECKSUM_COMPLETE;
                        skb->csum = le16_to_cpu(desc->csum);
                        printk(KERN_DEBUG "%s: checksum_hw, status2 = %#x\n", dev->name, le16_to_cpu(desc->status2));
                }
@@ -1649,36 +1534,35 @@ static int __netdev_rx(struct net_device *dev, int *quota)
 
 
 #ifdef HAVE_NETDEV_POLL
-static int netdev_poll(struct net_device *dev, int *budget)
+static int netdev_poll(struct napi_struct *napi, int budget)
 {
+       struct netdev_private *np = container_of(napi, struct netdev_private, napi);
+       struct net_device *dev = np->dev;
        u32 intr_status;
-       struct netdev_private *np = netdev_priv(dev);
        void __iomem *ioaddr = np->base;
-       int retcode = 0, quota = dev->quota;
+       int quota = budget;
 
        do {
                writel(IntrRxDone | IntrRxEmpty, ioaddr + IntrClear);
 
-               retcode = __netdev_rx(dev, &quota);
-               *budget -= (dev->quota - quota);
-               dev->quota = quota;
-               if (retcode)
+               if (__netdev_rx(dev, &quota))
                        goto out;
 
                intr_status = readl(ioaddr + IntrStatus);
        } while (intr_status & (IntrRxDone | IntrRxEmpty));
 
-       netif_rx_complete(dev);
+       netif_rx_complete(dev, napi);
        intr_status = readl(ioaddr + IntrEnable);
        intr_status |= IntrRxDone | IntrRxEmpty;
        writel(intr_status, ioaddr + IntrEnable);
 
  out:
        if (debug > 5)
-               printk(KERN_DEBUG "  exiting netdev_poll(): %d.\n", retcode);
+               printk(KERN_DEBUG "  exiting netdev_poll(): %d.\n",
+                      budget - quota);
 
        /* Restart Rx engine if stopped. */
-       return retcode;
+       return budget - quota;
 }
 #endif /* HAVE_NETDEV_POLL */
 
@@ -1854,10 +1738,10 @@ static void set_rx_mode(struct net_device *dev)
                int vlan_count = 0;
                void __iomem *filter_addr = ioaddr + HashTable + 8;
                for (i = 0; i < VLAN_VID_MASK; i++) {
-                       if (np->vlgrp->vlan_devices[i]) {
+                       if (vlan_group_get_device(np->vlgrp, i)) {
                                if (vlan_count >= 32)
                                        break;
-                               writew(cpu_to_be16(i), filter_addr);
+                               writew(i, filter_addr);
                                filter_addr += 16;
                                vlan_count++;
                        }
@@ -1882,26 +1766,26 @@ static void set_rx_mode(struct net_device *dev)
        } else if (dev->mc_count <= 14) {
                /* Use the 16 element perfect filter, skip first two entries. */
                void __iomem *filter_addr = ioaddr + PerfFilterTable + 2 * 16;
-               u16 *eaddrs;
+               __be16 *eaddrs;
                for (i = 2, mclist = dev->mc_list; mclist && i < dev->mc_count + 2;
                     i++, mclist = mclist->next) {
-                       eaddrs = (u16 *)mclist->dmi_addr;
-                       writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 8;
+                       eaddrs = (__be16 *)mclist->dmi_addr;
+                       writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 8;
                }
-               eaddrs = (u16 *)dev->dev_addr;
+               eaddrs = (__be16 *)dev->dev_addr;
                while (i++ < 16) {
-                       writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8;
+                       writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 8;
                }
                rx_mode |= AcceptBroadcast|PerfectFilter;
        } else {
                /* Must use a multicast hash table. */
                void __iomem *filter_addr;
-               u16 *eaddrs;
-               u16 mc_filter[32] __attribute__ ((aligned(sizeof(long))));      /* Multicast hash filter */
+               __be16 *eaddrs;
+               __le16 mc_filter[32] __attribute__ ((aligned(sizeof(long))));   /* Multicast hash filter */
 
                memset(mc_filter, 0, sizeof(mc_filter));
                for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
@@ -1909,17 +1793,17 @@ static void set_rx_mode(struct net_device *dev)
                        /* The chip uses the upper 9 CRC bits
                           as index into the hash table */
                        int bit_nr = ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 23;
-                       __u32 *fptr = (__u32 *) &mc_filter[(bit_nr >> 4) & ~1];
+                       __le32 *fptr = (__le32 *) &mc_filter[(bit_nr >> 4) & ~1];
 
                        *fptr |= cpu_to_le32(1 << (bit_nr & 31));
                }
                /* Clear the perfect filter list, skip first two entries. */
                filter_addr = ioaddr + PerfFilterTable + 2 * 16;
-               eaddrs = (u16 *)dev->dev_addr;
+               eaddrs = (__be16 *)dev->dev_addr;
                for (i = 2; i < 16; i++) {
-                       writew(cpu_to_be16(eaddrs[0]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[1]), filter_addr); filter_addr += 4;
-                       writew(cpu_to_be16(eaddrs[2]), filter_addr); filter_addr += 8;
+                       writew(be16_to_cpu(eaddrs[0]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[1]), filter_addr); filter_addr += 4;
+                       writew(be16_to_cpu(eaddrs[2]), filter_addr); filter_addr += 8;
                }
                for (filter_addr = ioaddr + HashTable, i = 0; i < 32; filter_addr+= 16, i++)
                        writew(mc_filter[i], filter_addr);
@@ -1985,7 +1869,7 @@ static void set_msglevel(struct net_device *dev, u32 val)
        debug = val;
 }
 
-static struct ethtool_ops ethtool_ops = {
+static const struct ethtool_ops ethtool_ops = {
        .begin = check_if_running,
        .get_drvinfo = get_drvinfo,
        .get_settings = get_settings,
@@ -2022,6 +1906,9 @@ static int netdev_close(struct net_device *dev)
        int i;
 
        netif_stop_queue(dev);
+#ifdef HAVE_NETDEV_POLL
+       napi_disable(&np->napi);
+#endif
 
        if (debug > 1) {
                printk(KERN_DEBUG "%s: Shutting down ethercard, Intr status %#8.8x.\n",
@@ -2101,7 +1988,7 @@ static int starfire_suspend(struct pci_dev *pdev, pm_message_t state)
 static int starfire_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
-       
+
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
 
@@ -2170,7 +2057,7 @@ static int __init starfire_init (void)
                return -ENODEV;
        }
 
-       return pci_module_init (&starfire_driver);
+       return pci_register_driver(&starfire_driver);
 }