X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fnet%2Ftc35815.c;h=370d329d15d91cb1b56955afe8888e89d1c1234d;hb=444ad82bc3eaa554be40d22dc248e58aeefd54d9;hp=7f94ca930988d08e63271469a3f3910494831259;hpb=e6f194d8f6f50da6837af637b2fd839c34185f7a;p=linux-2.6 diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index 7f94ca9309..370d329d15 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -414,6 +414,9 @@ enum tc35815_timer_state { struct tc35815_local { struct pci_dev *pci_dev; + struct net_device *dev; + struct napi_struct napi; + /* statistics */ struct net_device_stats stats; struct { @@ -566,7 +569,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev); 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 @@ -608,7 +611,7 @@ static int __devinit tc35815_mac_match(struct device *dev, void *data) { 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; } @@ -682,9 +685,9 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, 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); @@ -738,8 +741,7 @@ static int __devinit tc35815_init_one (struct pci_dev *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; @@ -748,8 +750,6 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, 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; @@ -1237,6 +1237,10 @@ tc35815_open(struct net_device *dev) 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); @@ -1436,6 +1440,7 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status) 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 @@ -1444,8 +1449,8 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id) 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); @@ -1456,7 +1461,6 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id) } return IRQ_NONE; #else - struct tc35815_local *lp = dev->priv; int handled; u32 status; @@ -1650,7 +1654,7 @@ tc35815_rx(struct net_device *dev) 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 = @@ -1690,7 +1694,7 @@ tc35815_rx(struct net_device *dev) } #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 @@ -1726,13 +1730,12 @@ tc35815_rx(struct net_device *dev) } #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; @@ -1744,23 +1747,19 @@ tc35815_poll(struct net_device *dev, int *budget) 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 @@ -1949,7 +1948,11 @@ static int 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. */ @@ -2158,10 +2161,16 @@ static void tc35815_set_msglevel(struct net_device *dev, u32 datum) 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) @@ -2196,9 +2205,8 @@ static const struct ethtool_ops tc35815_ethtool_ops = { .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, - .get_perm_addr = ethtool_op_get_perm_addr, }; static int tc35815_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)