struct tc35815_local {
struct pci_dev *pci_dev;
+ struct net_device *dev;
+ struct napi_struct napi;
+
/* statistics */
struct net_device_stats stats;
struct {
static irqreturn_t tc35815_interrupt(int irq, void *dev_id);
#ifdef TC35815_NAPI
static int tc35815_rx(struct net_device *dev, int limit);
-static int tc35815_poll(struct net_device *dev, int *budget);
+static int tc35815_poll(struct napi_struct *napi, int budget);
#else
static void tc35815_rx(struct net_device *dev);
#endif
{
struct platform_device *plat_dev = to_platform_device(dev);
struct pci_dev *pci_dev = data;
- unsigned int id = (pci_dev->bus->number << 8) | pci_dev->devfn;
+ unsigned int id = pci_dev->irq;
return !strcmp(plat_dev->name, "tc35815-mac") && plat_dev->id == id;
}
dev_err(&pdev->dev, "unable to alloc new ethernet\n");
return -ENOMEM;
}
- SET_MODULE_OWNER(dev);
SET_NETDEV_DEV(dev, &pdev->dev);
lp = dev->priv;
+ lp->dev = dev;
/* enable device (incl. PCI PM wakeup), and bus-mastering */
rc = pci_enable_device (pdev);
dev->tx_timeout = tc35815_tx_timeout;
dev->watchdog_timeo = TC35815_TX_TIMEOUT;
#ifdef TC35815_NAPI
- dev->poll = tc35815_poll;
- dev->weight = NAPI_WEIGHT;
+ netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT);
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = tc35815_poll_controller;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
- /* dev->priv/lp zeroed and aligned in alloc_etherdev */
- lp = dev->priv;
spin_lock_init(&lp->lock);
lp->pci_dev = pdev;
lp->boardtype = ent->driver_data;
return -EAGAIN;
}
+#ifdef TC35815_NAPI
+ napi_enable(&lp->napi);
+#endif
+
/* Reset the hardware here. Don't forget to set the station address. */
spin_lock_irq(&lp->lock);
tc35815_chip_init(dev);
static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
+ struct tc35815_local *lp = netdev_priv(dev);
struct tc35815_regs __iomem *tr =
(struct tc35815_regs __iomem *)dev->base_addr;
#ifdef TC35815_NAPI
if (!(dmactl & DMA_IntMask)) {
/* disable interrupts */
tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl);
- if (netif_rx_schedule_prep(dev))
- __netif_rx_schedule(dev);
+ if (netif_rx_schedule_prep(dev, &lp->napi))
+ __netif_rx_schedule(dev, &lp->napi);
else {
printk(KERN_ERR "%s: interrupt taken in poll\n",
dev->name);
}
return IRQ_NONE;
#else
- struct tc35815_local *lp = dev->priv;
int handled;
u32 status;
panic_queues(dev);
}
#endif
- /* pass BD to controler */
+ /* pass BD to controller */
#ifndef TC35815_USE_PACKEDBUFFER
if (!lp->rx_skbs[curid].skb) {
lp->rx_skbs[curid].skb =
}
#endif
for (i = 0; i < (bd_count + 1) / 2 + 1; i++) {
- /* pass FD to controler */
+ /* pass FD to controller */
#ifdef DEBUG
lp->rfd_cur->fd.FDNext = cpu_to_le32(0xdeaddead);
#else
}
#ifdef TC35815_NAPI
-static int
-tc35815_poll(struct net_device *dev, int *budget)
+static int tc35815_poll(struct napi_struct *napi, int budget)
{
- struct tc35815_local *lp = dev->priv;
+ struct tc35815_local *lp = container_of(napi, struct tc35815_local, napi);
+ struct net_device *dev = lp->dev;
struct tc35815_regs __iomem *tr =
(struct tc35815_regs __iomem *)dev->base_addr;
- int limit = min(*budget, dev->quota);
int received = 0, handled;
u32 status;
handled = tc35815_do_interrupt(dev, status, limit);
if (handled >= 0) {
received += handled;
- limit -= handled;
- if (limit <= 0)
+ if (received >= budget)
break;
}
status = tc_readl(&tr->Int_Src);
} while (status);
spin_unlock(&lp->lock);
- dev->quota -= received;
- *budget -= received;
- if (limit <= 0)
- return 1;
-
- netif_rx_complete(dev);
- /* enable interrupts */
- tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
- return 0;
+ if (received < budget) {
+ netif_rx_complete(dev, napi);
+ /* enable interrupts */
+ tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl);
+ }
+ return received;
}
#endif
tc35815_close(struct net_device *dev)
{
struct tc35815_local *lp = dev->priv;
+
netif_stop_queue(dev);
+#ifdef TC35815_NAPI
+ napi_disable(&lp->napi);
+#endif
/* Flush the Tx and disable Rx here. */
lp->msg_enable = datum;
}
-static int tc35815_get_stats_count(struct net_device *dev)
+static int tc35815_get_sset_count(struct net_device *dev, int sset)
{
struct tc35815_local *lp = dev->priv;
- return sizeof(lp->lstats) / sizeof(int);
+
+ switch (sset) {
+ case ETH_SS_STATS:
+ return sizeof(lp->lstats) / sizeof(int);
+ default:
+ return -EOPNOTSUPP;
+ }
}
static void tc35815_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
.get_msglevel = tc35815_get_msglevel,
.set_msglevel = tc35815_set_msglevel,
.get_strings = tc35815_get_strings,
- .get_stats_count = tc35815_get_stats_count,
+ .get_sset_count = tc35815_get_sset_count,
.get_ethtool_stats = tc35815_get_ethtool_stats,
};