*
* 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
#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
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. */
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
*/
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))
/* 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
+ * 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, budget);
- work_done = gem_rx(gp, work_to_do);
-
- *budget -= work_done;
- dev->quota -= 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)
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) {
- netif_poll_enable(dev);
+ 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);
ctrl = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) {
- u64 csum_start_off, csum_stuff_off;
-
- csum_start_off = (u64) (skb->h.raw - skb->data);
- csum_stuff_off = csum_start_off + skb->csum_offset;
+ 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) |
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);
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);
mutex_unlock(&gp->pm_mutex);
}
if (!gp->asleep)
rc = gem_do_start(dev);
gp->opened = (rc == 0);
+ if (gp->opened)
+ napi_enable(&gp->napi);
mutex_unlock(&gp->pm_mutex);
{
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);
+ napi_disable(&gp->napi);
+
gp->opened = 0;
if (!gp->asleep)
gem_do_stop(dev, 0);
mutex_lock(&gp->pm_mutex);
- netif_poll_disable(dev);
-
printk(KERN_INFO "%s: suspending, WakeOnLan %s\n",
dev->name,
(gp->wake_on_lan && gp->opened) ? "enabled" : "disabled");
/* 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);
/* Re-attach net device */
netif_device_attach(dev);
+ napi_enable(&gp->napi);
}
spin_lock_irqsave(&gp->lock, flags);
spin_unlock(&gp->tx_lock);
spin_unlock_irqrestore(&gp->lock, flags);
- netif_poll_enable(dev);
-
mutex_unlock(&gp->pm_mutex);
return 0;
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 int find_eth_addr_in_vpd(void __iomem *rom_base, int len, unsigned char *dev_addr)
{
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
-
-#if defined(__sparc__)
- struct pci_dev *pdev = gp->pdev;
- struct pcidev_cookie *pcp = pdev->sysdata;
- int use_idprom = 1;
-
- if (pcp != NULL) {
- const unsigned char *addr;
- int len;
-
- addr = of_get_property(pcp->prom_node, "local-mac-address",
- &len);
- if (addr && len == 6) {
- use_idprom = 0;
- memcpy(dev->dev_addr, addr, 6);
- }
- }
- if (use_idprom)
- memcpy(dev->dev_addr, idprom->id_ethaddr, 6);
-#elif defined(CONFIG_PPC_PMAC)
const 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
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);
err = -ENOMEM;
goto err_disable_device;
}
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
gp = dev->priv;
/* 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
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;
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)