diff options
Diffstat (limited to 'drivers/net/epic100.c')
-rw-r--r-- | drivers/net/epic100.c | 48 |
1 files changed, 22 insertions, 26 deletions
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 119778401e48..ecdd3fc8d70c 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c | |||
@@ -262,6 +262,7 @@ struct epic_private { | |||
262 | /* Ring pointers. */ | 262 | /* Ring pointers. */ |
263 | spinlock_t lock; /* Group with Tx control cache line. */ | 263 | spinlock_t lock; /* Group with Tx control cache line. */ |
264 | spinlock_t napi_lock; | 264 | spinlock_t napi_lock; |
265 | struct napi_struct napi; | ||
265 | unsigned int reschedule_in_poll; | 266 | unsigned int reschedule_in_poll; |
266 | unsigned int cur_tx, dirty_tx; | 267 | unsigned int cur_tx, dirty_tx; |
267 | 268 | ||
@@ -294,7 +295,7 @@ static void epic_tx_timeout(struct net_device *dev); | |||
294 | static void epic_init_ring(struct net_device *dev); | 295 | static void epic_init_ring(struct net_device *dev); |
295 | static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); | 296 | static int epic_start_xmit(struct sk_buff *skb, struct net_device *dev); |
296 | static int epic_rx(struct net_device *dev, int budget); | 297 | static int epic_rx(struct net_device *dev, int budget); |
297 | static int epic_poll(struct net_device *dev, int *budget); | 298 | static int epic_poll(struct napi_struct *napi, int budget); |
298 | static irqreturn_t epic_interrupt(int irq, void *dev_instance); | 299 | static irqreturn_t epic_interrupt(int irq, void *dev_instance); |
299 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 300 | static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
300 | static const struct ethtool_ops netdev_ethtool_ops; | 301 | static const struct ethtool_ops netdev_ethtool_ops; |
@@ -316,6 +317,7 @@ static int __devinit epic_init_one (struct pci_dev *pdev, | |||
316 | int i, ret, option = 0, duplex = 0; | 317 | int i, ret, option = 0, duplex = 0; |
317 | void *ring_space; | 318 | void *ring_space; |
318 | dma_addr_t ring_dma; | 319 | dma_addr_t ring_dma; |
320 | DECLARE_MAC_BUF(mac); | ||
319 | 321 | ||
320 | /* when built into the kernel, we only print version if device is found */ | 322 | /* when built into the kernel, we only print version if device is found */ |
321 | #ifndef MODULE | 323 | #ifndef MODULE |
@@ -351,7 +353,6 @@ static int __devinit epic_init_one (struct pci_dev *pdev, | |||
351 | dev_err(&pdev->dev, "no memory for eth device\n"); | 353 | dev_err(&pdev->dev, "no memory for eth device\n"); |
352 | goto err_out_free_res; | 354 | goto err_out_free_res; |
353 | } | 355 | } |
354 | SET_MODULE_OWNER(dev); | ||
355 | SET_NETDEV_DEV(dev, &pdev->dev); | 356 | SET_NETDEV_DEV(dev, &pdev->dev); |
356 | 357 | ||
357 | #ifdef USE_IO_OPS | 358 | #ifdef USE_IO_OPS |
@@ -487,18 +488,15 @@ static int __devinit epic_init_one (struct pci_dev *pdev, | |||
487 | dev->ethtool_ops = &netdev_ethtool_ops; | 488 | dev->ethtool_ops = &netdev_ethtool_ops; |
488 | dev->watchdog_timeo = TX_TIMEOUT; | 489 | dev->watchdog_timeo = TX_TIMEOUT; |
489 | dev->tx_timeout = &epic_tx_timeout; | 490 | dev->tx_timeout = &epic_tx_timeout; |
490 | dev->poll = epic_poll; | 491 | netif_napi_add(dev, &ep->napi, epic_poll, 64); |
491 | dev->weight = 64; | ||
492 | 492 | ||
493 | ret = register_netdev(dev); | 493 | ret = register_netdev(dev); |
494 | if (ret < 0) | 494 | if (ret < 0) |
495 | goto err_out_unmap_rx; | 495 | goto err_out_unmap_rx; |
496 | 496 | ||
497 | printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ", | 497 | printk(KERN_INFO "%s: %s at %#lx, IRQ %d, %s\n", |
498 | dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq); | 498 | dev->name, pci_id_tbl[chip_idx].name, ioaddr, dev->irq, |
499 | for (i = 0; i < 5; i++) | 499 | print_mac(mac, dev->dev_addr)); |
500 | printk("%2.2x:", dev->dev_addr[i]); | ||
501 | printk("%2.2x.\n", dev->dev_addr[i]); | ||
502 | 500 | ||
503 | out: | 501 | out: |
504 | return ret; | 502 | return ret; |
@@ -660,8 +658,11 @@ static int epic_open(struct net_device *dev) | |||
660 | /* Soft reset the chip. */ | 658 | /* Soft reset the chip. */ |
661 | outl(0x4001, ioaddr + GENCTL); | 659 | outl(0x4001, ioaddr + GENCTL); |
662 | 660 | ||
663 | if ((retval = request_irq(dev->irq, &epic_interrupt, IRQF_SHARED, dev->name, dev))) | 661 | napi_enable(&ep->napi); |
662 | if ((retval = request_irq(dev->irq, &epic_interrupt, IRQF_SHARED, dev->name, dev))) { | ||
663 | napi_disable(&ep->napi); | ||
664 | return retval; | 664 | return retval; |
665 | } | ||
665 | 666 | ||
666 | epic_init_ring(dev); | 667 | epic_init_ring(dev); |
667 | 668 | ||
@@ -1103,9 +1104,9 @@ static irqreturn_t epic_interrupt(int irq, void *dev_instance) | |||
1103 | 1104 | ||
1104 | if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) { | 1105 | if ((status & EpicNapiEvent) && !ep->reschedule_in_poll) { |
1105 | spin_lock(&ep->napi_lock); | 1106 | spin_lock(&ep->napi_lock); |
1106 | if (netif_rx_schedule_prep(dev)) { | 1107 | if (netif_rx_schedule_prep(dev, &ep->napi)) { |
1107 | epic_napi_irq_off(dev, ep); | 1108 | epic_napi_irq_off(dev, ep); |
1108 | __netif_rx_schedule(dev); | 1109 | __netif_rx_schedule(dev, &ep->napi); |
1109 | } else | 1110 | } else |
1110 | ep->reschedule_in_poll++; | 1111 | ep->reschedule_in_poll++; |
1111 | spin_unlock(&ep->napi_lock); | 1112 | spin_unlock(&ep->napi_lock); |
@@ -1257,26 +1258,22 @@ static void epic_rx_err(struct net_device *dev, struct epic_private *ep) | |||
1257 | outw(RxQueued, ioaddr + COMMAND); | 1258 | outw(RxQueued, ioaddr + COMMAND); |
1258 | } | 1259 | } |
1259 | 1260 | ||
1260 | static int epic_poll(struct net_device *dev, int *budget) | 1261 | static int epic_poll(struct napi_struct *napi, int budget) |
1261 | { | 1262 | { |
1262 | struct epic_private *ep = dev->priv; | 1263 | struct epic_private *ep = container_of(napi, struct epic_private, napi); |
1263 | int work_done = 0, orig_budget; | 1264 | struct net_device *dev = ep->mii.dev; |
1265 | int work_done = 0; | ||
1264 | long ioaddr = dev->base_addr; | 1266 | long ioaddr = dev->base_addr; |
1265 | 1267 | ||
1266 | orig_budget = (*budget > dev->quota) ? dev->quota : *budget; | ||
1267 | |||
1268 | rx_action: | 1268 | rx_action: |
1269 | 1269 | ||
1270 | epic_tx(dev, ep); | 1270 | epic_tx(dev, ep); |
1271 | 1271 | ||
1272 | work_done += epic_rx(dev, *budget); | 1272 | work_done += epic_rx(dev, budget); |
1273 | 1273 | ||
1274 | epic_rx_err(dev, ep); | 1274 | epic_rx_err(dev, ep); |
1275 | 1275 | ||
1276 | *budget -= work_done; | 1276 | if (netif_running(dev) && (work_done < budget)) { |
1277 | dev->quota -= work_done; | ||
1278 | |||
1279 | if (netif_running(dev) && (work_done < orig_budget)) { | ||
1280 | unsigned long flags; | 1277 | unsigned long flags; |
1281 | int more; | 1278 | int more; |
1282 | 1279 | ||
@@ -1286,7 +1283,7 @@ rx_action: | |||
1286 | 1283 | ||
1287 | more = ep->reschedule_in_poll; | 1284 | more = ep->reschedule_in_poll; |
1288 | if (!more) { | 1285 | if (!more) { |
1289 | __netif_rx_complete(dev); | 1286 | __netif_rx_complete(dev, napi); |
1290 | outl(EpicNapiEvent, ioaddr + INTSTAT); | 1287 | outl(EpicNapiEvent, ioaddr + INTSTAT); |
1291 | epic_napi_irq_on(dev, ep); | 1288 | epic_napi_irq_on(dev, ep); |
1292 | } else | 1289 | } else |
@@ -1298,7 +1295,7 @@ rx_action: | |||
1298 | goto rx_action; | 1295 | goto rx_action; |
1299 | } | 1296 | } |
1300 | 1297 | ||
1301 | return (work_done >= orig_budget); | 1298 | return work_done; |
1302 | } | 1299 | } |
1303 | 1300 | ||
1304 | static int epic_close(struct net_device *dev) | 1301 | static int epic_close(struct net_device *dev) |
@@ -1309,6 +1306,7 @@ static int epic_close(struct net_device *dev) | |||
1309 | int i; | 1306 | int i; |
1310 | 1307 | ||
1311 | netif_stop_queue(dev); | 1308 | netif_stop_queue(dev); |
1309 | napi_disable(&ep->napi); | ||
1312 | 1310 | ||
1313 | if (debug > 1) | 1311 | if (debug > 1) |
1314 | printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", | 1312 | printk(KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n", |
@@ -1495,8 +1493,6 @@ static const struct ethtool_ops netdev_ethtool_ops = { | |||
1495 | .get_link = netdev_get_link, | 1493 | .get_link = netdev_get_link, |
1496 | .get_msglevel = netdev_get_msglevel, | 1494 | .get_msglevel = netdev_get_msglevel, |
1497 | .set_msglevel = netdev_set_msglevel, | 1495 | .set_msglevel = netdev_set_msglevel, |
1498 | .get_sg = ethtool_op_get_sg, | ||
1499 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
1500 | .begin = ethtool_begin, | 1496 | .begin = ethtool_begin, |
1501 | .complete = ethtool_complete | 1497 | .complete = ethtool_complete |
1502 | }; | 1498 | }; |