diff options
Diffstat (limited to 'drivers/net/natsemi.c')
-rw-r--r-- | drivers/net/natsemi.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index b47a12d684f9..43cfa4b3e294 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -560,6 +560,8 @@ struct netdev_private { | |||
560 | /* address of a sent-in-place packet/buffer, for later free() */ | 560 | /* address of a sent-in-place packet/buffer, for later free() */ |
561 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; | 561 | struct sk_buff *tx_skbuff[TX_RING_SIZE]; |
562 | dma_addr_t tx_dma[TX_RING_SIZE]; | 562 | dma_addr_t tx_dma[TX_RING_SIZE]; |
563 | struct net_device *dev; | ||
564 | struct napi_struct napi; | ||
563 | struct net_device_stats stats; | 565 | struct net_device_stats stats; |
564 | /* Media monitoring timer */ | 566 | /* Media monitoring timer */ |
565 | struct timer_list timer; | 567 | struct timer_list timer; |
@@ -636,7 +638,7 @@ static void init_registers(struct net_device *dev); | |||
636 | static int start_tx(struct sk_buff *skb, struct net_device *dev); | 638 | static int start_tx(struct sk_buff *skb, struct net_device *dev); |
637 | static irqreturn_t intr_handler(int irq, void *dev_instance); | 639 | static irqreturn_t intr_handler(int irq, void *dev_instance); |
638 | static void netdev_error(struct net_device *dev, int intr_status); | 640 | static void netdev_error(struct net_device *dev, int intr_status); |
639 | static int natsemi_poll(struct net_device *dev, int *budget); | 641 | static int natsemi_poll(struct napi_struct *napi, int budget); |
640 | static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do); | 642 | static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do); |
641 | static void netdev_tx_done(struct net_device *dev); | 643 | static void netdev_tx_done(struct net_device *dev); |
642 | static int natsemi_change_mtu(struct net_device *dev, int new_mtu); | 644 | static int natsemi_change_mtu(struct net_device *dev, int new_mtu); |
@@ -861,6 +863,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, | |||
861 | dev->irq = irq; | 863 | dev->irq = irq; |
862 | 864 | ||
863 | np = netdev_priv(dev); | 865 | np = netdev_priv(dev); |
866 | netif_napi_add(dev, &np->napi, natsemi_poll, 64); | ||
864 | 867 | ||
865 | np->pci_dev = pdev; | 868 | np->pci_dev = pdev; |
866 | pci_set_drvdata(pdev, dev); | 869 | pci_set_drvdata(pdev, dev); |
@@ -931,8 +934,6 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, | |||
931 | dev->do_ioctl = &netdev_ioctl; | 934 | dev->do_ioctl = &netdev_ioctl; |
932 | dev->tx_timeout = &tx_timeout; | 935 | dev->tx_timeout = &tx_timeout; |
933 | dev->watchdog_timeo = TX_TIMEOUT; | 936 | dev->watchdog_timeo = TX_TIMEOUT; |
934 | dev->poll = natsemi_poll; | ||
935 | dev->weight = 64; | ||
936 | 937 | ||
937 | #ifdef CONFIG_NET_POLL_CONTROLLER | 938 | #ifdef CONFIG_NET_POLL_CONTROLLER |
938 | dev->poll_controller = &natsemi_poll_controller; | 939 | dev->poll_controller = &natsemi_poll_controller; |
@@ -1554,6 +1555,8 @@ static int netdev_open(struct net_device *dev) | |||
1554 | free_irq(dev->irq, dev); | 1555 | free_irq(dev->irq, dev); |
1555 | return i; | 1556 | return i; |
1556 | } | 1557 | } |
1558 | napi_enable(&np->napi); | ||
1559 | |||
1557 | init_ring(dev); | 1560 | init_ring(dev); |
1558 | spin_lock_irq(&np->lock); | 1561 | spin_lock_irq(&np->lock); |
1559 | init_registers(dev); | 1562 | init_registers(dev); |
@@ -2200,10 +2203,10 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) | |||
2200 | 2203 | ||
2201 | prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); | 2204 | prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); |
2202 | 2205 | ||
2203 | if (netif_rx_schedule_prep(dev)) { | 2206 | if (netif_rx_schedule_prep(dev, &np->napi)) { |
2204 | /* Disable interrupts and register for poll */ | 2207 | /* Disable interrupts and register for poll */ |
2205 | natsemi_irq_disable(dev); | 2208 | natsemi_irq_disable(dev); |
2206 | __netif_rx_schedule(dev); | 2209 | __netif_rx_schedule(dev, &np->napi); |
2207 | } else | 2210 | } else |
2208 | printk(KERN_WARNING | 2211 | printk(KERN_WARNING |
2209 | "%s: Ignoring interrupt, status %#08x, mask %#08x.\n", | 2212 | "%s: Ignoring interrupt, status %#08x, mask %#08x.\n", |
@@ -2216,12 +2219,11 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) | |||
2216 | /* This is the NAPI poll routine. As well as the standard RX handling | 2219 | /* This is the NAPI poll routine. As well as the standard RX handling |
2217 | * it also handles all other interrupts that the chip might raise. | 2220 | * it also handles all other interrupts that the chip might raise. |
2218 | */ | 2221 | */ |
2219 | static int natsemi_poll(struct net_device *dev, int *budget) | 2222 | static int natsemi_poll(struct napi_struct *napi, int budget) |
2220 | { | 2223 | { |
2221 | struct netdev_private *np = netdev_priv(dev); | 2224 | struct netdev_private *np = container_of(napi, struct netdev_private, napi); |
2225 | struct net_device *dev = np->dev; | ||
2222 | void __iomem * ioaddr = ns_ioaddr(dev); | 2226 | void __iomem * ioaddr = ns_ioaddr(dev); |
2223 | |||
2224 | int work_to_do = min(*budget, dev->quota); | ||
2225 | int work_done = 0; | 2227 | int work_done = 0; |
2226 | 2228 | ||
2227 | do { | 2229 | do { |
@@ -2236,7 +2238,7 @@ static int natsemi_poll(struct net_device *dev, int *budget) | |||
2236 | if (np->intr_status & | 2238 | if (np->intr_status & |
2237 | (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | | 2239 | (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | |
2238 | IntrRxErr | IntrRxOverrun)) { | 2240 | IntrRxErr | IntrRxOverrun)) { |
2239 | netdev_rx(dev, &work_done, work_to_do); | 2241 | netdev_rx(dev, &work_done, budget); |
2240 | } | 2242 | } |
2241 | 2243 | ||
2242 | if (np->intr_status & | 2244 | if (np->intr_status & |
@@ -2250,16 +2252,13 @@ static int natsemi_poll(struct net_device *dev, int *budget) | |||
2250 | if (np->intr_status & IntrAbnormalSummary) | 2252 | if (np->intr_status & IntrAbnormalSummary) |
2251 | netdev_error(dev, np->intr_status); | 2253 | netdev_error(dev, np->intr_status); |
2252 | 2254 | ||
2253 | *budget -= work_done; | 2255 | if (work_done >= budget) |
2254 | dev->quota -= work_done; | 2256 | return work_done; |
2255 | |||
2256 | if (work_done >= work_to_do) | ||
2257 | return 1; | ||
2258 | 2257 | ||
2259 | np->intr_status = readl(ioaddr + IntrStatus); | 2258 | np->intr_status = readl(ioaddr + IntrStatus); |
2260 | } while (np->intr_status); | 2259 | } while (np->intr_status); |
2261 | 2260 | ||
2262 | netif_rx_complete(dev); | 2261 | netif_rx_complete(dev, napi); |
2263 | 2262 | ||
2264 | /* Reenable interrupts providing nothing is trying to shut | 2263 | /* Reenable interrupts providing nothing is trying to shut |
2265 | * the chip down. */ | 2264 | * the chip down. */ |
@@ -2268,7 +2267,7 @@ static int natsemi_poll(struct net_device *dev, int *budget) | |||
2268 | natsemi_irq_enable(dev); | 2267 | natsemi_irq_enable(dev); |
2269 | spin_unlock(&np->lock); | 2268 | spin_unlock(&np->lock); |
2270 | 2269 | ||
2271 | return 0; | 2270 | return work_done; |
2272 | } | 2271 | } |
2273 | 2272 | ||
2274 | /* This routine is logically part of the interrupt handler, but separated | 2273 | /* This routine is logically part of the interrupt handler, but separated |
@@ -3158,6 +3157,8 @@ static int netdev_close(struct net_device *dev) | |||
3158 | dev->name, np->cur_tx, np->dirty_tx, | 3157 | dev->name, np->cur_tx, np->dirty_tx, |
3159 | np->cur_rx, np->dirty_rx); | 3158 | np->cur_rx, np->dirty_rx); |
3160 | 3159 | ||
3160 | napi_disable(&np->napi); | ||
3161 | |||
3161 | /* | 3162 | /* |
3162 | * FIXME: what if someone tries to close a device | 3163 | * FIXME: what if someone tries to close a device |
3163 | * that is suspended? | 3164 | * that is suspended? |
@@ -3253,7 +3254,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev) | |||
3253 | * disable_irq() to enforce synchronization. | 3254 | * disable_irq() to enforce synchronization. |
3254 | * * natsemi_poll: checks before reenabling interrupts. suspend | 3255 | * * natsemi_poll: checks before reenabling interrupts. suspend |
3255 | * sets hands_off, disables interrupts and then waits with | 3256 | * sets hands_off, disables interrupts and then waits with |
3256 | * netif_poll_disable(). | 3257 | * napi_disable(). |
3257 | * | 3258 | * |
3258 | * Interrupts must be disabled, otherwise hands_off can cause irq storms. | 3259 | * Interrupts must be disabled, otherwise hands_off can cause irq storms. |
3259 | */ | 3260 | */ |
@@ -3279,7 +3280,7 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state) | |||
3279 | spin_unlock_irq(&np->lock); | 3280 | spin_unlock_irq(&np->lock); |
3280 | enable_irq(dev->irq); | 3281 | enable_irq(dev->irq); |
3281 | 3282 | ||
3282 | netif_poll_disable(dev); | 3283 | napi_disable(&np->napi); |
3283 | 3284 | ||
3284 | /* Update the error counts. */ | 3285 | /* Update the error counts. */ |
3285 | __get_stats(dev); | 3286 | __get_stats(dev); |
@@ -3320,6 +3321,8 @@ static int natsemi_resume (struct pci_dev *pdev) | |||
3320 | pci_enable_device(pdev); | 3321 | pci_enable_device(pdev); |
3321 | /* pci_power_on(pdev); */ | 3322 | /* pci_power_on(pdev); */ |
3322 | 3323 | ||
3324 | napi_enable(&np->napi); | ||
3325 | |||
3323 | natsemi_reset(dev); | 3326 | natsemi_reset(dev); |
3324 | init_ring(dev); | 3327 | init_ring(dev); |
3325 | disable_irq(dev->irq); | 3328 | disable_irq(dev->irq); |
@@ -3333,7 +3336,6 @@ static int natsemi_resume (struct pci_dev *pdev) | |||
3333 | mod_timer(&np->timer, jiffies + 1*HZ); | 3336 | mod_timer(&np->timer, jiffies + 1*HZ); |
3334 | } | 3337 | } |
3335 | netif_device_attach(dev); | 3338 | netif_device_attach(dev); |
3336 | netif_poll_enable(dev); | ||
3337 | out: | 3339 | out: |
3338 | rtnl_unlock(); | 3340 | rtnl_unlock(); |
3339 | return 0; | 3341 | return 0; |