Add support the Korina (IDT RC32434) Ethernet MAC
[linux-2.6.git] / drivers / net / sungem.c
index 1f56556..4291458 100644 (file)
@@ -2,24 +2,24 @@
  * sungem.c: Sun GEM ethernet driver.
  *
  * Copyright (C) 2000, 2001, 2002, 2003 David S. Miller (davem@redhat.com)
- * 
+ *
  * Support for Apple GMAC and assorted PHYs, WOL, Power Management
  * (C) 2001,2002,2003 Benjamin Herrenscmidt (benh@kernel.crashing.org)
  * (C) 2004,2005 Benjamin Herrenscmidt, IBM Corp.
  *
  * NAPI and NETPOLL support
  * (C) 2004 by Eric Lemoine (eric.lemoine@gmail.com)
- * 
- * TODO: 
+ *
+ * TODO:
  *  - Now that the driver was significantly simplified, I need to rework
  *    the locking. I'm sure we don't need _2_ spinlocks, and we probably
  *    can avoid taking most of them for so long period of time (and schedule
  *    instead). The main issues at this point are caused by the netdev layer
  *    though:
- *    
+ *
  *    gem_change_mtu() and gem_set_multicast() are called with a read_lock()
  *    help by net/core/dev.c, thus they can't schedule. That means they can't
- *    call netif_poll_disable() neither, thus force gem_poll() to keep a spinlock
+ *    call napi_disable() neither, thus force gem_poll() to keep a spinlock
  *    where it could have been dropped. change_mtu especially would love also to
  *    be able to msleep instead of horrid locked delays when resetting the HW,
  *    but that read_lock() makes it impossible, unless I defer it's action to
@@ -55,6 +55,8 @@
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
 #include <linux/bitops.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 
-#ifdef __sparc__
+#ifdef CONFIG_SPARC
 #include <asm/idprom.h>
-#include <asm/openprom.h>
-#include <asm/oplib.h>
-#include <asm/pbm.h>
+#include <asm/prom.h>
 #endif
 
 #ifdef CONFIG_PPC_PMAC
@@ -88,7 +88,8 @@
 
 #define ADVERTISE_MASK (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
                         SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
-                        SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
+                        SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | \
+                        SUPPORTED_Pause | SUPPORTED_Autoneg)
 
 #define DRV_NAME       "sungem"
 #define DRV_VERSION    "0.98"
@@ -112,7 +113,7 @@ static struct pci_device_id gem_pci_tbl[] = {
        /* These models only differ from the original GEM in
         * that their tx/rx fifos are of a different size and
         * they only support 10/100 speeds. -DaveM
-        * 
+        *
         * Apple's GMAC does support gigabit on machines with
         * the BCM54xx PHYs. -BenH
         */
@@ -128,6 +129,8 @@ static struct pci_device_id gem_pci_tbl[] = {
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_SUNGEM,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+       { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID2_GMAC,
+         PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
        {0, }
 };
 
@@ -755,6 +758,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
 {
        int entry, drops, work_done = 0;
        u32 done;
+       __sum16 csum;
 
        if (netif_msg_rx_status(gp))
                printk(KERN_DEBUG "%s: rx interrupt, done: %d, rx_new: %d\n",
@@ -766,7 +770,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
        for (;;) {
                struct gem_rxd *rxd = &gp->init_block->rxd[entry];
                struct sk_buff *skb;
-               u64 status = cpu_to_le64(rxd->status_word);
+               u64 status = le64_to_cpu(rxd->status_word);
                dma_addr_t dma_addr;
                int len;
 
@@ -808,7 +812,7 @@ static int gem_rx(struct gem *gp, int work_to_do)
                        goto next;
                }
 
-               dma_addr = cpu_to_le64(rxd->buffer);
+               dma_addr = le64_to_cpu(rxd->buffer);
                if (len > RX_COPY_THRESHOLD) {
                        struct sk_buff *new_skb;
 
@@ -840,19 +844,19 @@ static int gem_rx(struct gem *gp, int work_to_do)
                                goto drop_it;
                        }
 
-                       copy_skb->dev = gp->dev;
                        skb_reserve(copy_skb, 2);
                        skb_put(copy_skb, len);
                        pci_dma_sync_single_for_cpu(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
-                       memcpy(copy_skb->data, skb->data, len);
+                       skb_copy_from_linear_data(skb, copy_skb->data, len);
                        pci_dma_sync_single_for_device(gp->pdev, dma_addr, len, PCI_DMA_FROMDEVICE);
 
                        /* We'll reuse the original ring buffer. */
                        skb = copy_skb;
                }
 
-               skb->csum = ntohs((status & RXDCTRL_TCPCSUM) ^ 0xffff);
-               skb->ip_summed = CHECKSUM_HW;
+               csum = (__force __sum16)htons((status & RXDCTRL_TCPCSUM) ^ 0xffff);
+               skb->csum = csum_unfold(csum);
+               skb->ip_summed = CHECKSUM_COMPLETE;
                skb->protocol = eth_type_trans(skb, gp->dev);
 
                netif_receive_skb(skb);
@@ -876,19 +880,20 @@ static int gem_rx(struct gem *gp, int work_to_do)
        return work_done;
 }
 
-static int gem_poll(struct net_device *dev, int *budget)
+static int gem_poll(struct napi_struct *napi, int budget)
 {
-       struct gem *gp = dev->priv;
+       struct gem *gp = container_of(napi, struct gem, napi);
+       struct net_device *dev = gp->dev;
        unsigned long flags;
+       int work_done;
 
        /*
-        * NAPI locking nightmare: See comment at head of driver 
+        * NAPI locking nightmare: See comment at head of driver
         */
        spin_lock_irqsave(&gp->lock, flags);
 
+       work_done = 0;
        do {
-               int work_to_do, work_done;
-
                /* Handle anomalies */
                if (gp->status & GREG_STAT_ABNORMAL) {
                        if (gem_abnormal_irq(dev, gp, gp->status))
@@ -902,34 +907,30 @@ static int gem_poll(struct net_device *dev, int *budget)
 
                spin_unlock_irqrestore(&gp->lock, flags);
 
-               /* Run RX thread. We don't use any locking here, 
-                * code willing to do bad things - like cleaning the 
-                * rx ring - must call netif_poll_disable(), which
+               /* Run RX thread. We don't use any locking here,
+                * code willing to do bad things - like cleaning the
+                * rx ring - must call napi_disable(), which
                 * schedule_timeout()'s if polling is already disabled.
                 */
-               work_to_do = min(*budget, dev->quota);
-
-               work_done = gem_rx(gp, work_to_do);
-
-               *budget -= work_done;
-               dev->quota -= work_done;
+               work_done += gem_rx(gp, budget - work_done);
 
-               if (work_done >= work_to_do)
-                       return 1;
+               if (work_done >= budget)
+                       return work_done;
 
                spin_lock_irqsave(&gp->lock, flags);
-               
+
                gp->status = readl(gp->regs + GREG_STAT);
        } while (gp->status & GREG_STAT_NAPI);
 
-       __netif_rx_complete(dev);
+       __netif_rx_complete(dev, napi);
        gem_enable_ints(gp);
 
        spin_unlock_irqrestore(&gp->lock, flags);
-       return 0;
+
+       return work_done;
 }
 
-static irqreturn_t gem_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t gem_interrupt(int irq, void *dev_id)
 {
        struct net_device *dev = dev_id;
        struct gem *gp = dev->priv;
@@ -943,23 +944,24 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                return IRQ_HANDLED;
 
        spin_lock_irqsave(&gp->lock, flags);
-       
-       if (netif_rx_schedule_prep(dev)) {
+
+       if (netif_rx_schedule_prep(dev, &gp->napi)) {
                u32 gem_status = readl(gp->regs + GREG_STAT);
 
                if (gem_status == 0) {
+                       napi_enable(&gp->napi);
                        spin_unlock_irqrestore(&gp->lock, flags);
                        return IRQ_NONE;
                }
                gp->status = gem_status;
                gem_disable_ints(gp);
-               __netif_rx_schedule(dev);
+               __netif_rx_schedule(dev, &gp->napi);
        }
 
        spin_unlock_irqrestore(&gp->lock, flags);
-  
+
        /* If polling was disabled at the time we received that
-        * interrupt, we may return IRQ_HANDLED here while we 
+        * interrupt, we may return IRQ_HANDLED here while we
         * should return IRQ_NONE. No big deal...
         */
        return IRQ_HANDLED;
@@ -971,7 +973,7 @@ static void gem_poll_controller(struct net_device *dev)
        /* gem_interrupt is safe to reentrance so no need
         * to disable_irq here.
         */
-       gem_interrupt(dev->irq, dev, NULL);
+       gem_interrupt(dev->irq, dev);
 }
 #endif
 
@@ -1022,11 +1024,9 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
 
        ctrl = 0;
-       if (skb->ip_summed == CHECKSUM_HW) {
-               u64 csum_start_off, csum_stuff_off;
-
-               csum_start_off = (u64) (skb->h.raw - skb->data);
-               csum_stuff_off = (u64) ((skb->h.raw + skb->csum) - skb->data);
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               const u64 csum_start_off = skb_transport_offset(skb);
+               const u64 csum_stuff_off = csum_start_off + skb->csum_offset;
 
                ctrl = (TXDCTRL_CENAB |
                        (csum_start_off << 15) |
@@ -1108,7 +1108,7 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        this_ctrl = ctrl;
                        if (frag == skb_shinfo(skb)->nr_frags - 1)
                                this_ctrl |= TXDCTRL_EOF;
-                       
+
                        txd = &gp->init_block->txd[entry];
                        txd->buffer = cpu_to_le64(mapping);
                        wmb();
@@ -1174,7 +1174,7 @@ static void gem_reset(struct gem *gp)
 static void gem_start_dma(struct gem *gp)
 {
        u32 val;
-       
+
        /* We are ready to rock, turn everything on. */
        val = readl(gp->regs + TXDMA_CFG);
        writel(val | TXDMA_CFG_ENABLE, gp->regs + TXDMA_CFG);
@@ -1242,7 +1242,7 @@ static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
        autoneg = gp->want_autoneg;
        speed = gp->phy_mii.speed;
        duplex = gp->phy_mii.duplex;
-       
+
        /* Setup link parameters */
        if (!ep)
                goto start_aneg;
@@ -1272,7 +1272,7 @@ start_aneg:
                duplex = DUPLEX_HALF;
        if (speed == 0)
                speed = SPEED_10;
-       
+
        /* If we are asleep, we don't try to actually setup the PHY, we
         * just store the settings
         */
@@ -1341,7 +1341,7 @@ static int gem_set_link_modes(struct gem *gp)
                val |= (MAC_TXCFG_ICS | MAC_TXCFG_ICOLL);
        } else {
                /* MAC_TXCFG_NBO must be zero. */
-       }       
+       }
        writel(val, gp->regs + MAC_TXCFG);
 
        val = (MAC_XIFCFG_OE | MAC_XIFCFG_LLED);
@@ -1466,7 +1466,7 @@ static void gem_link_timer(unsigned long data)
 {
        struct gem *gp = (struct gem *) data;
        int restart_aneg = 0;
-               
+
        if (gp->asleep)
                return;
 
@@ -1479,7 +1479,7 @@ static void gem_link_timer(unsigned long data)
         */
        if (gp->reset_task_pending)
                goto restart;
-               
+
        if (gp->phy_type == phy_serialink ||
            gp->phy_type == phy_serdes) {
                u32 val = readl(gp->regs + PCS_MIISTAT);
@@ -1656,7 +1656,7 @@ static void gem_init_phy(struct gem *gp)
        mifcfg = readl(gp->regs + MIF_CFG);
        mifcfg &= ~MIF_CFG_BBMODE;
        writel(mifcfg, gp->regs + MIF_CFG);
-       
+
        if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
                int i;
 
@@ -1819,7 +1819,7 @@ static u32 gem_setup_multicast(struct gem *gp)
 {
        u32 rxcfg = 0;
        int i;
-       
+
        if ((gp->dev->flags & IFF_ALLMULTI) ||
            (gp->dev->mc_count > 256)) {
                for (i=0; i<16; i++)
@@ -1981,7 +1981,7 @@ static void gem_init_pause_thresholds(struct gem *gp)
                cfg = ((2 << 1) & GREG_CFG_TXDMALIM);
                cfg |= ((8 << 6) & GREG_CFG_RXDMALIM);
                writel(cfg, gp->regs + GREG_CFG);
-       }       
+       }
 }
 
 static int gem_check_invariants(struct gem *gp)
@@ -2035,7 +2035,7 @@ static int gem_check_invariants(struct gem *gp)
        /* Determine initial PHY interface type guess.  MDIO1 is the
         * external PHY and thus takes precedence over MDIO0.
         */
-       
+
        if (mif_cfg & MIF_CFG_MDI1) {
                gp->phy_type = phy_mii_mdio1;
                mif_cfg |= MIF_CFG_PSELECT;
@@ -2137,7 +2137,7 @@ static void gem_stop_phy(struct gem *gp, int wol)
 
                /* Setup wake-on-lan for MAGIC packet */
                writel(MAC_RXCFG_HFE | MAC_RXCFG_SFCS | MAC_RXCFG_ENAB,
-                      gp->regs + MAC_RXCFG);   
+                      gp->regs + MAC_RXCFG);
                writel((e[4] << 8) | e[5], gp->regs + WOL_MATCH0);
                writel((e[2] << 8) | e[3], gp->regs + WOL_MATCH1);
                writel((e[0] << 8) | e[1], gp->regs + WOL_MATCH2);
@@ -2216,7 +2216,7 @@ static int gem_do_start(struct net_device *dev)
        spin_unlock_irqrestore(&gp->lock, flags);
 
        if (request_irq(gp->pdev->irq, gem_interrupt,
-                                  SA_SHIRQ, dev->name, (void *)dev)) {
+                                  IRQF_SHARED, dev->name, (void *)dev)) {
                printk(KERN_ERR "%s: failed to request irq !\n", gp->dev->name);
 
                spin_lock_irqsave(&gp->lock, flags);
@@ -2226,7 +2226,7 @@ static int gem_do_start(struct net_device *dev)
                gem_reset(gp);
                gem_clean_rings(gp);
                gem_put_cell(gp);
-               
+
                spin_unlock(&gp->tx_lock);
                spin_unlock_irqrestore(&gp->lock, flags);
 
@@ -2277,20 +2277,18 @@ static void gem_do_stop(struct net_device *dev, int wol)
        }
 }
 
-static void gem_reset_task(void *data)
+static void gem_reset_task(struct work_struct *work)
 {
-       struct gem *gp = (struct gem *) data;
+       struct gem *gp = container_of(work, struct gem, reset_task);
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
-       netif_poll_disable(gp->dev);
+       if (gp->opened)
+               napi_disable(&gp->napi);
 
        spin_lock_irq(&gp->lock);
        spin_lock(&gp->tx_lock);
 
-       if (gp->running == 0)
-               goto not_running;
-
        if (gp->running) {
                netif_stop_queue(gp->dev);
 
@@ -2300,15 +2298,16 @@ static void gem_reset_task(void *data)
                        gem_set_link_modes(gp);
                netif_wake_queue(gp->dev);
        }
- not_running:
+
        gp->reset_task_pending = 0;
 
        spin_unlock(&gp->tx_lock);
        spin_unlock_irq(&gp->lock);
 
-       netif_poll_enable(gp->dev);
+       if (gp->opened)
+               napi_enable(&gp->napi);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 }
 
 
@@ -2317,14 +2316,16 @@ static int gem_open(struct net_device *dev)
        struct gem *gp = dev->priv;
        int rc = 0;
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        /* We need the cell enabled */
        if (!gp->asleep)
                rc = gem_do_start(dev);
        gp->opened = (rc == 0);
+       if (gp->opened)
+               napi_enable(&gp->napi);
 
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return rc;
 }
@@ -2333,18 +2334,16 @@ static int gem_close(struct net_device *dev)
 {
        struct gem *gp = dev->priv;
 
-       /* Note: we don't need to call netif_poll_disable() here because
-        * our caller (dev_close) already did it for us
-        */
+       mutex_lock(&gp->pm_mutex);
 
-       down(&gp->pm_sem);
+       napi_disable(&gp->napi);
 
-       gp->opened = 0; 
+       gp->opened = 0;
        if (!gp->asleep)
                gem_do_stop(dev, 0);
 
-       up(&gp->pm_sem);
-       
+       mutex_unlock(&gp->pm_mutex);
+
        return 0;
 }
 
@@ -2355,14 +2354,12 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        struct gem *gp = dev->priv;
        unsigned long flags;
 
-       down(&gp->pm_sem);
-
-       netif_poll_disable(dev);
+       mutex_lock(&gp->pm_mutex);
 
        printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
               dev->name,
               (gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
-       
+
        /* Keep the cell enabled during the entire operation */
        spin_lock_irqsave(&gp->lock, flags);
        spin_lock(&gp->tx_lock);
@@ -2372,6 +2369,8 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 
        /* If the driver is opened, we stop the MAC */
        if (gp->opened) {
+               napi_disable(&gp->napi);
+
                /* Stop traffic, mark us closed */
                netif_device_detach(dev);
 
@@ -2388,11 +2387,11 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
        /* Stop the link timer */
        del_timer_sync(&gp->link_timer);
 
-       /* Now we release the semaphore to not block the reset task who
+       /* Now we release the mutex to not block the reset task who
         * can take it too. We are marked asleep, so there will be no
         * conflict here
         */
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        /* Wait for a pending reset task to complete */
        while (gp->reset_task_pending)
@@ -2421,7 +2420,7 @@ static int gem_resume(struct pci_dev *pdev)
 
        printk(KERN_INFO "%s: resuming\n", dev->name);
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
 
        /* Keep the cell enabled during the entire operation, no need to
         * take a lock here tho since nothing else can happen while we are
@@ -2437,7 +2436,7 @@ static int gem_resume(struct pci_dev *pdev)
                 * still asleep, a new sleep cycle may bring it back
                 */
                gem_put_cell(gp);
-               up(&gp->pm_sem);
+               mutex_unlock(&gp->pm_mutex);
                return 0;
        }
        pci_set_master(gp->pdev);
@@ -2462,6 +2461,7 @@ static int gem_resume(struct pci_dev *pdev)
                /* Re-attach net device */
                netif_device_attach(dev);
 
+               napi_enable(&gp->napi);
        }
 
        spin_lock_irqsave(&gp->lock, flags);
@@ -2481,9 +2481,7 @@ static int gem_resume(struct pci_dev *pdev)
        spin_unlock(&gp->tx_lock);
        spin_unlock_irqrestore(&gp->lock, flags);
 
-       netif_poll_enable(dev);
-       
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return 0;
 }
@@ -2524,12 +2522,41 @@ static struct net_device_stats *gem_get_stats(struct net_device *dev)
        return &gp->net_stats;
 }
 
+static int gem_set_mac_address(struct net_device *dev, void *addr)
+{
+       struct sockaddr *macaddr = (struct sockaddr *) addr;
+       struct gem *gp = dev->priv;
+       unsigned char *e = &dev->dev_addr[0];
+
+       if (!is_valid_ether_addr(macaddr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       if (!netif_running(dev) || !netif_device_present(dev)) {
+               /* We'll just catch it later when the
+                * device is up'd or resumed.
+                */
+               memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+               return 0;
+       }
+
+       mutex_lock(&gp->pm_mutex);
+       memcpy(dev->dev_addr, macaddr->sa_data, dev->addr_len);
+       if (gp->running) {
+               writel((e[4] << 8) | e[5], gp->regs + MAC_ADDR0);
+               writel((e[2] << 8) | e[3], gp->regs + MAC_ADDR1);
+               writel((e[0] << 8) | e[1], gp->regs + MAC_ADDR2);
+       }
+       mutex_unlock(&gp->pm_mutex);
+
+       return 0;
+}
+
 static void gem_set_multicast(struct net_device *dev)
 {
        struct gem *gp = dev->priv;
        u32 rxcfg, rxcfg_new;
        int limit = 10000;
-       
+
 
        spin_lock_irq(&gp->lock);
        spin_lock(&gp->tx_lock);
@@ -2545,7 +2572,7 @@ static void gem_set_multicast(struct net_device *dev)
        rxcfg_new |= MAC_RXCFG_SFCS;
 #endif
        gp->mac_rx_cfg = rxcfg_new;
-       
+
        writel(rxcfg & ~MAC_RXCFG_ENAB, gp->regs + MAC_RXCFG);
        while (readl(gp->regs + MAC_RXCFG) & MAC_RXCFG_ENAB) {
                if (!limit--)
@@ -2588,7 +2615,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
                return 0;
        }
 
-       down(&gp->pm_sem);
+       mutex_lock(&gp->pm_mutex);
        spin_lock_irq(&gp->lock);
        spin_lock(&gp->tx_lock);
        dev->mtu = new_mtu;
@@ -2599,7 +2626,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
        }
        spin_unlock(&gp->tx_lock);
        spin_unlock_irq(&gp->lock);
-       up(&gp->pm_sem);
+       mutex_unlock(&gp->pm_mutex);
 
        return 0;
 }
@@ -2607,12 +2634,12 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
 static void gem_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
        struct gem *gp = dev->priv;
-  
+
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
        strcpy(info->bus_info, pci_name(gp->pdev));
 }
-  
+
 static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct gem *gp = dev->priv;
@@ -2634,7 +2661,7 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
                spin_lock_irq(&gp->lock);
                cmd->autoneg = gp->want_autoneg;
                cmd->speed = gp->phy_mii.speed;
-               cmd->duplex = gp->phy_mii.duplex;                       
+               cmd->duplex = gp->phy_mii.duplex;
                cmd->advertising = gp->phy_mii.advertising;
 
                /* If we started with a forced mode, we don't have a default
@@ -2679,7 +2706,7 @@ static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
             (cmd->duplex != DUPLEX_HALF &&
              cmd->duplex != DUPLEX_FULL)))
                return -EINVAL;
-             
+
        /* Apply settings and restart link process. */
        spin_lock_irq(&gp->lock);
        gem_get_cell(gp);
@@ -2712,7 +2739,7 @@ static u32 gem_get_msglevel(struct net_device *dev)
        struct gem *gp = dev->priv;
        return gp->msg_enable;
 }
-  
+
 static void gem_set_msglevel(struct net_device *dev, u32 value)
 {
        struct gem *gp = dev->priv;
@@ -2749,7 +2776,7 @@ static int gem_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        return 0;
 }
 
-static struct ethtool_ops gem_ethtool_ops = {
+static const struct ethtool_ops gem_ethtool_ops = {
        .get_drvinfo            = gem_get_drvinfo,
        .get_link               = ethtool_op_get_link,
        .get_settings           = gem_get_settings,
@@ -2768,11 +2795,11 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        int rc = -EOPNOTSUPP;
        unsigned long flags;
 
-       /* Hold the PM semaphore while doing ioctl's or we may collide
+       /* Hold the PM mutex while doing ioctl's or we may collide
         * with power management.
         */
-       down(&gp->pm_sem);
-               
+       mutex_lock(&gp->pm_mutex);
+
        spin_lock_irqsave(&gp->lock, flags);
        gem_get_cell(gp);
        spin_unlock_irqrestore(&gp->lock, flags);
@@ -2804,19 +2831,19 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                }
                break;
        };
-       
+
        spin_lock_irqsave(&gp->lock, flags);
        gem_put_cell(gp);
        spin_unlock_irqrestore(&gp->lock, flags);
 
-       up(&gp->pm_sem);
-       
+       mutex_unlock(&gp->pm_mutex);
+
        return rc;
 }
 
-#if (!defined(__sparc__) && !defined(CONFIG_PPC_PMAC))
+#if (!defined(CONFIG_SPARC) && !defined(CONFIG_PPC_PMAC))
 /* Fetch MAC address from vital product data of PCI ROM. */
-static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr)
+static int find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr)
 {
        int this_offset;
 
@@ -2837,35 +2864,27 @@ static void find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char
 
                for (i = 0; i < 6; i++)
                        dev_addr[i] = readb(p + i);
-               break;
+               return 1;
        }
+       return 0;
 }
 
 static void get_gem_mac_nonobp(struct pci_dev *pdev, unsigned char *dev_addr)
 {
-       u32 rom_reg_orig;
-       void __iomem *p;
-
-       if (pdev->resource[PCI_ROM_RESOURCE].parent == NULL) {
-               if (pci_assign_resource(pdev, PCI_ROM_RESOURCE) < 0)
-                       goto use_random;
-       }
-
-       pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_reg_orig);
-       pci_write_config_dword(pdev, pdev->rom_base_reg,
-                              rom_reg_orig | PCI_ROM_ADDRESS_ENABLE);
-
-       p = ioremap(pci_resource_start(pdev, PCI_ROM_RESOURCE), (64 * 1024));
-       if (p != NULL && readb(p) == 0x55 && readb(p + 1) == 0xaa)
-               find_eth_addr_in_vpd(p, (64 * 1024), dev_addr);
+       size_t size;
+       void __iomem *p = pci_map_rom(pdev, &size);
 
-       if (p != NULL)
-               iounmap(p);
+       if (p) {
+                       int found;
 
-       pci_write_config_dword(pdev, pdev->rom_base_reg, rom_reg_orig);
-       return;
+               found = readb(p) == 0x55 &&
+                       readb(p + 1) == 0xaa &&
+                       find_eth_addr_in_vpd(p, (64 * 1024), dev_addr);
+               pci_unmap_rom(pdev, p);
+               if (found)
+                       return;
+       }
 
-use_random:
        /* Sun MAC prefix then 3 random bytes. */
        dev_addr[0] = 0x08;
        dev_addr[1] = 0x00;
@@ -2877,33 +2896,19 @@ use_random:
 
 static int __devinit gem_get_device_address(struct gem *gp)
 {
-#if defined(__sparc__) || defined(CONFIG_PPC_PMAC)
+#if defined(CONFIG_SPARC) || defined(CONFIG_PPC_PMAC)
        struct net_device *dev = gp->dev;
-#endif
+       const unsigned char *addr;
 
-#if defined(__sparc__)
-       struct pci_dev *pdev = gp->pdev;
-       struct pcidev_cookie *pcp = pdev->sysdata;
-       int node = -1;
-
-       if (pcp != NULL) {
-               node = pcp->prom_node;
-               if (prom_getproplen(node, "local-mac-address") == 6)
-                       prom_getproperty(node, "local-mac-address",
-                                        dev->dev_addr, 6);
-               else
-                       node = -1;
-       }
-       if (node == -1)
-               memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
-#elif defined(CONFIG_PPC_PMAC)
-       unsigned char *addr;
-
-       addr = get_property(gp->of_node, "local-mac-address", NULL);
+       addr = of_get_property(gp->of_node, "local-mac-address", NULL);
        if (addr == NULL) {
+#ifdef CONFIG_SPARC
+               addr = idprom->id_ethaddr;
+#else
                printk("\n");
                printk(KERN_ERR "%s: can't get mac-address\n", dev->name);
                return -1;
+#endif
        }
        memcpy(dev->dev_addr, addr, 6);
 #else
@@ -2912,7 +2917,7 @@ static int __devinit gem_get_device_address(struct gem *gp)
        return 0;
 }
 
-static void __devexit gem_remove_one(struct pci_dev *pdev)
+static void gem_remove_one(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
 
@@ -2960,7 +2965,8 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        unsigned long gemreg_base, gemreg_len;
        struct net_device *dev;
        struct gem *gp;
-       int i, err, pci_using_dac;
+       int err, pci_using_dac;
+       DECLARE_MAC_BUF(mac);
 
        if (gem_version_printed++ == 0)
                printk(KERN_INFO "%s", version);
@@ -3001,7 +3007,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
                }
                pci_using_dac = 0;
        }
-       
+
        gemreg_base = pci_resource_start(pdev, 0);
        gemreg_len = pci_resource_len(pdev, 0);
 
@@ -3018,7 +3024,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
                err = -ENOMEM;
                goto err_disable_device;
        }
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        gp = dev->priv;
@@ -3038,20 +3043,20 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
        spin_lock_init(&gp->lock);
        spin_lock_init(&gp->tx_lock);
-       init_MUTEX(&gp->pm_sem);
+       mutex_init(&gp->pm_mutex);
 
        init_timer(&gp->link_timer);
        gp->link_timer.function = gem_link_timer;
        gp->link_timer.data = (unsigned long) gp;
 
-       INIT_WORK(&gp->reset_task, gem_reset_task, gp);
-       
+       INIT_WORK(&gp->reset_task, gem_reset_task);
+
        gp->lstate = link_down;
        gp->timer_ticks = 0;
        netif_carrier_off(dev);
 
        gp->regs = ioremap(gemreg_base, gemreg_len);
-       if (gp->regs == 0UL) {
+       if (!gp->regs) {
                printk(KERN_ERR PFX "Cannot map device registers, "
                       "aborting.\n");
                err = -EIO;
@@ -3061,7 +3066,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        /* On Apple, we want a reference to the Open Firmware device-tree
         * node. We use it for clock control.
         */
-#ifdef CONFIG_PPC_PMAC
+#if defined(CONFIG_PPC_PMAC) || defined(CONFIG_SPARC)
        gp->of_node = pci_device_to_OF_node(pdev);
 #endif
 
@@ -3079,7 +3084,9 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        gp->phy_mii.dev = dev;
        gp->phy_mii.mdio_read = _phy_read;
        gp->phy_mii.mdio_write = _phy_write;
-
+#ifdef CONFIG_PPC_PMAC
+       gp->phy_mii.platform_data = gp->of_node;
+#endif
        /* By default, we start with autoneg */
        gp->want_autoneg = 1;
 
@@ -3111,14 +3118,14 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
        dev->get_stats = gem_get_stats;
        dev->set_multicast_list = gem_set_multicast;
        dev->do_ioctl = gem_ioctl;
-       dev->poll = gem_poll;
-       dev->weight = 64;
+       netif_napi_add(dev, &gp->napi, gem_poll, 64);
        dev->ethtool_ops = &gem_ethtool_ops;
        dev->tx_timeout = gem_tx_timeout;
        dev->watchdog_timeo = 5 * HZ;
        dev->change_mtu = gem_change_mtu;
        dev->irq = pdev->irq;
        dev->dma = 0;
+       dev->set_mac_address = gem_set_mac_address;
 #ifdef CONFIG_NET_POLL_CONTROLLER
        dev->poll_controller = gem_poll_controller;
 #endif
@@ -3143,16 +3150,13 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
                goto err_out_free_consistent;
        }
 
-       printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ",
-              dev->name);
-       for (i = 0; i < 6; i++)
-               printk("%2.2x%c", dev->dev_addr[i],
-                      i == 5 ? ' ' : ':');
-       printk("\n");
+       printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet "
+              "%s\n",
+              dev->name, print_mac(mac, dev->dev_addr));
 
        if (gp->phy_type == phy_mii_mdio0 ||
            gp->phy_type == phy_mii_mdio1)
-               printk(KERN_INFO "%s: Found %s PHY\n", dev->name, 
+               printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
                        gp->phy_mii.def ? gp->phy_mii.def->name : "no");
 
        /* GEM can do it all... */
@@ -3184,7 +3188,7 @@ static struct pci_driver gem_driver = {
        .name           = GEM_MODULE_NAME,
        .id_table       = gem_pci_tbl,
        .probe          = gem_init_one,
-       .remove         = __devexit_p(gem_remove_one),
+       .remove         = gem_remove_one,
 #ifdef CONFIG_PM
        .suspend        = gem_suspend,
        .resume         = gem_resume,
@@ -3193,7 +3197,7 @@ static struct pci_driver gem_driver = {
 
 static int __init gem_init(void)
 {
-       return pci_module_init(&gem_driver);
+       return pci_register_driver(&gem_driver);
 }
 
 static void __exit gem_cleanup(void)