diff options
Diffstat (limited to 'drivers/net/tc35815.c')
-rw-r--r-- | drivers/net/tc35815.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index ec41469eee82..b5e0dff67230 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c | |||
@@ -414,6 +414,9 @@ enum tc35815_timer_state { | |||
414 | struct tc35815_local { | 414 | struct tc35815_local { |
415 | struct pci_dev *pci_dev; | 415 | struct pci_dev *pci_dev; |
416 | 416 | ||
417 | struct net_device *dev; | ||
418 | struct napi_struct napi; | ||
419 | |||
417 | /* statistics */ | 420 | /* statistics */ |
418 | struct net_device_stats stats; | 421 | struct net_device_stats stats; |
419 | struct { | 422 | struct { |
@@ -566,7 +569,7 @@ static int tc35815_send_packet(struct sk_buff *skb, struct net_device *dev); | |||
566 | static irqreturn_t tc35815_interrupt(int irq, void *dev_id); | 569 | static irqreturn_t tc35815_interrupt(int irq, void *dev_id); |
567 | #ifdef TC35815_NAPI | 570 | #ifdef TC35815_NAPI |
568 | static int tc35815_rx(struct net_device *dev, int limit); | 571 | static int tc35815_rx(struct net_device *dev, int limit); |
569 | static int tc35815_poll(struct net_device *dev, int *budget); | 572 | static int tc35815_poll(struct napi_struct *napi, int budget); |
570 | #else | 573 | #else |
571 | static void tc35815_rx(struct net_device *dev); | 574 | static void tc35815_rx(struct net_device *dev); |
572 | #endif | 575 | #endif |
@@ -685,6 +688,7 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
685 | SET_MODULE_OWNER(dev); | 688 | SET_MODULE_OWNER(dev); |
686 | SET_NETDEV_DEV(dev, &pdev->dev); | 689 | SET_NETDEV_DEV(dev, &pdev->dev); |
687 | lp = dev->priv; | 690 | lp = dev->priv; |
691 | lp->dev = dev; | ||
688 | 692 | ||
689 | /* enable device (incl. PCI PM wakeup), and bus-mastering */ | 693 | /* enable device (incl. PCI PM wakeup), and bus-mastering */ |
690 | rc = pci_enable_device (pdev); | 694 | rc = pci_enable_device (pdev); |
@@ -738,8 +742,7 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
738 | dev->tx_timeout = tc35815_tx_timeout; | 742 | dev->tx_timeout = tc35815_tx_timeout; |
739 | dev->watchdog_timeo = TC35815_TX_TIMEOUT; | 743 | dev->watchdog_timeo = TC35815_TX_TIMEOUT; |
740 | #ifdef TC35815_NAPI | 744 | #ifdef TC35815_NAPI |
741 | dev->poll = tc35815_poll; | 745 | netif_napi_add(dev, &lp->napi, tc35815_poll, NAPI_WEIGHT); |
742 | dev->weight = NAPI_WEIGHT; | ||
743 | #endif | 746 | #endif |
744 | #ifdef CONFIG_NET_POLL_CONTROLLER | 747 | #ifdef CONFIG_NET_POLL_CONTROLLER |
745 | dev->poll_controller = tc35815_poll_controller; | 748 | dev->poll_controller = tc35815_poll_controller; |
@@ -748,8 +751,6 @@ static int __devinit tc35815_init_one (struct pci_dev *pdev, | |||
748 | dev->irq = pdev->irq; | 751 | dev->irq = pdev->irq; |
749 | dev->base_addr = (unsigned long) ioaddr; | 752 | dev->base_addr = (unsigned long) ioaddr; |
750 | 753 | ||
751 | /* dev->priv/lp zeroed and aligned in alloc_etherdev */ | ||
752 | lp = dev->priv; | ||
753 | spin_lock_init(&lp->lock); | 754 | spin_lock_init(&lp->lock); |
754 | lp->pci_dev = pdev; | 755 | lp->pci_dev = pdev; |
755 | lp->boardtype = ent->driver_data; | 756 | lp->boardtype = ent->driver_data; |
@@ -1237,6 +1238,10 @@ tc35815_open(struct net_device *dev) | |||
1237 | return -EAGAIN; | 1238 | return -EAGAIN; |
1238 | } | 1239 | } |
1239 | 1240 | ||
1241 | #ifdef TC35815_NAPI | ||
1242 | napi_enable(&lp->napi); | ||
1243 | #endif | ||
1244 | |||
1240 | /* Reset the hardware here. Don't forget to set the station address. */ | 1245 | /* Reset the hardware here. Don't forget to set the station address. */ |
1241 | spin_lock_irq(&lp->lock); | 1246 | spin_lock_irq(&lp->lock); |
1242 | tc35815_chip_init(dev); | 1247 | tc35815_chip_init(dev); |
@@ -1436,6 +1441,7 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status) | |||
1436 | static irqreturn_t tc35815_interrupt(int irq, void *dev_id) | 1441 | static irqreturn_t tc35815_interrupt(int irq, void *dev_id) |
1437 | { | 1442 | { |
1438 | struct net_device *dev = dev_id; | 1443 | struct net_device *dev = dev_id; |
1444 | struct tc35815_local *lp = netdev_priv(dev); | ||
1439 | struct tc35815_regs __iomem *tr = | 1445 | struct tc35815_regs __iomem *tr = |
1440 | (struct tc35815_regs __iomem *)dev->base_addr; | 1446 | (struct tc35815_regs __iomem *)dev->base_addr; |
1441 | #ifdef TC35815_NAPI | 1447 | #ifdef TC35815_NAPI |
@@ -1444,8 +1450,8 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id) | |||
1444 | if (!(dmactl & DMA_IntMask)) { | 1450 | if (!(dmactl & DMA_IntMask)) { |
1445 | /* disable interrupts */ | 1451 | /* disable interrupts */ |
1446 | tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl); | 1452 | tc_writel(dmactl | DMA_IntMask, &tr->DMA_Ctl); |
1447 | if (netif_rx_schedule_prep(dev)) | 1453 | if (netif_rx_schedule_prep(dev, &lp->napi)) |
1448 | __netif_rx_schedule(dev); | 1454 | __netif_rx_schedule(dev, &lp->napi); |
1449 | else { | 1455 | else { |
1450 | printk(KERN_ERR "%s: interrupt taken in poll\n", | 1456 | printk(KERN_ERR "%s: interrupt taken in poll\n", |
1451 | dev->name); | 1457 | dev->name); |
@@ -1726,13 +1732,12 @@ tc35815_rx(struct net_device *dev) | |||
1726 | } | 1732 | } |
1727 | 1733 | ||
1728 | #ifdef TC35815_NAPI | 1734 | #ifdef TC35815_NAPI |
1729 | static int | 1735 | static int tc35815_poll(struct napi_struct *napi, int budget) |
1730 | tc35815_poll(struct net_device *dev, int *budget) | ||
1731 | { | 1736 | { |
1732 | struct tc35815_local *lp = dev->priv; | 1737 | struct tc35815_local *lp = container_of(napi, struct tc35815_local, napi); |
1738 | struct net_device *dev = lp->dev; | ||
1733 | struct tc35815_regs __iomem *tr = | 1739 | struct tc35815_regs __iomem *tr = |
1734 | (struct tc35815_regs __iomem *)dev->base_addr; | 1740 | (struct tc35815_regs __iomem *)dev->base_addr; |
1735 | int limit = min(*budget, dev->quota); | ||
1736 | int received = 0, handled; | 1741 | int received = 0, handled; |
1737 | u32 status; | 1742 | u32 status; |
1738 | 1743 | ||
@@ -1744,23 +1749,19 @@ tc35815_poll(struct net_device *dev, int *budget) | |||
1744 | handled = tc35815_do_interrupt(dev, status, limit); | 1749 | handled = tc35815_do_interrupt(dev, status, limit); |
1745 | if (handled >= 0) { | 1750 | if (handled >= 0) { |
1746 | received += handled; | 1751 | received += handled; |
1747 | limit -= handled; | 1752 | if (received >= budget) |
1748 | if (limit <= 0) | ||
1749 | break; | 1753 | break; |
1750 | } | 1754 | } |
1751 | status = tc_readl(&tr->Int_Src); | 1755 | status = tc_readl(&tr->Int_Src); |
1752 | } while (status); | 1756 | } while (status); |
1753 | spin_unlock(&lp->lock); | 1757 | spin_unlock(&lp->lock); |
1754 | 1758 | ||
1755 | dev->quota -= received; | 1759 | if (received < budget) { |
1756 | *budget -= received; | 1760 | netif_rx_complete(dev, napi); |
1757 | if (limit <= 0) | 1761 | /* enable interrupts */ |
1758 | return 1; | 1762 | tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl); |
1759 | 1763 | } | |
1760 | netif_rx_complete(dev); | 1764 | return received; |
1761 | /* enable interrupts */ | ||
1762 | tc_writel(tc_readl(&tr->DMA_Ctl) & ~DMA_IntMask, &tr->DMA_Ctl); | ||
1763 | return 0; | ||
1764 | } | 1765 | } |
1765 | #endif | 1766 | #endif |
1766 | 1767 | ||
@@ -1949,7 +1950,11 @@ static int | |||
1949 | tc35815_close(struct net_device *dev) | 1950 | tc35815_close(struct net_device *dev) |
1950 | { | 1951 | { |
1951 | struct tc35815_local *lp = dev->priv; | 1952 | struct tc35815_local *lp = dev->priv; |
1953 | |||
1952 | netif_stop_queue(dev); | 1954 | netif_stop_queue(dev); |
1955 | #ifdef TC35815_NAPI | ||
1956 | napi_disable(&lp->napi); | ||
1957 | #endif | ||
1953 | 1958 | ||
1954 | /* Flush the Tx and disable Rx here. */ | 1959 | /* Flush the Tx and disable Rx here. */ |
1955 | 1960 | ||