diff options
Diffstat (limited to 'drivers/net/fec_8xx/fec_main.c')
-rw-r--r-- | drivers/net/fec_8xx/fec_main.c | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index e5502af5b8e2..6348fb93ca9c 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c | |||
@@ -465,9 +465,9 @@ void fec_stop(struct net_device *dev) | |||
465 | } | 465 | } |
466 | 466 | ||
467 | /* common receive function */ | 467 | /* common receive function */ |
468 | static int fec_enet_rx_common(struct net_device *dev, int *budget) | 468 | static int fec_enet_rx_common(struct fec_enet_private *ep, |
469 | struct net_device *dev, int budget) | ||
469 | { | 470 | { |
470 | struct fec_enet_private *fep = netdev_priv(dev); | ||
471 | fec_t *fecp = fep->fecp; | 471 | fec_t *fecp = fep->fecp; |
472 | const struct fec_platform_info *fpi = fep->fpi; | 472 | const struct fec_platform_info *fpi = fep->fpi; |
473 | cbd_t *bdp; | 473 | cbd_t *bdp; |
@@ -475,11 +475,8 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget) | |||
475 | int received = 0; | 475 | int received = 0; |
476 | __u16 pkt_len, sc; | 476 | __u16 pkt_len, sc; |
477 | int curidx; | 477 | int curidx; |
478 | int rx_work_limit; | ||
479 | 478 | ||
480 | if (fpi->use_napi) { | 479 | if (fpi->use_napi) { |
481 | rx_work_limit = min(dev->quota, *budget); | ||
482 | |||
483 | if (!netif_running(dev)) | 480 | if (!netif_running(dev)) |
484 | return 0; | 481 | return 0; |
485 | } | 482 | } |
@@ -530,11 +527,6 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget) | |||
530 | BUG_ON(skbn == NULL); | 527 | BUG_ON(skbn == NULL); |
531 | 528 | ||
532 | } else { | 529 | } else { |
533 | |||
534 | /* napi, got packet but no quota */ | ||
535 | if (fpi->use_napi && --rx_work_limit < 0) | ||
536 | break; | ||
537 | |||
538 | skb = fep->rx_skbuff[curidx]; | 530 | skb = fep->rx_skbuff[curidx]; |
539 | BUG_ON(skb == NULL); | 531 | BUG_ON(skb == NULL); |
540 | 532 | ||
@@ -599,25 +591,24 @@ static int fec_enet_rx_common(struct net_device *dev, int *budget) | |||
599 | * able to keep up at the expense of system resources. | 591 | * able to keep up at the expense of system resources. |
600 | */ | 592 | */ |
601 | FW(fecp, r_des_active, 0x01000000); | 593 | FW(fecp, r_des_active, 0x01000000); |
594 | |||
595 | if (received >= budget) | ||
596 | break; | ||
597 | |||
602 | } | 598 | } |
603 | 599 | ||
604 | fep->cur_rx = bdp; | 600 | fep->cur_rx = bdp; |
605 | 601 | ||
606 | if (fpi->use_napi) { | 602 | if (fpi->use_napi) { |
607 | dev->quota -= received; | 603 | if (received < budget) { |
608 | *budget -= received; | 604 | netif_rx_complete(dev, &fep->napi); |
609 | |||
610 | if (rx_work_limit < 0) | ||
611 | return 1; /* not done */ | ||
612 | 605 | ||
613 | /* done */ | 606 | /* enable RX interrupt bits */ |
614 | netif_rx_complete(dev); | 607 | FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); |
615 | 608 | } | |
616 | /* enable RX interrupt bits */ | ||
617 | FS(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); | ||
618 | } | 609 | } |
619 | 610 | ||
620 | return 0; | 611 | return received; |
621 | } | 612 | } |
622 | 613 | ||
623 | static void fec_enet_tx(struct net_device *dev) | 614 | static void fec_enet_tx(struct net_device *dev) |
@@ -743,12 +734,12 @@ fec_enet_interrupt(int irq, void *dev_id) | |||
743 | 734 | ||
744 | if ((int_events & FEC_ENET_RXF) != 0) { | 735 | if ((int_events & FEC_ENET_RXF) != 0) { |
745 | if (!fpi->use_napi) | 736 | if (!fpi->use_napi) |
746 | fec_enet_rx_common(dev, NULL); | 737 | fec_enet_rx_common(fep, dev, ~0); |
747 | else { | 738 | else { |
748 | if (netif_rx_schedule_prep(dev)) { | 739 | if (netif_rx_schedule_prep(dev, &fep->napi)) { |
749 | /* disable rx interrupts */ | 740 | /* disable rx interrupts */ |
750 | FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); | 741 | FC(fecp, imask, FEC_ENET_RXF | FEC_ENET_RXB); |
751 | __netif_rx_schedule(dev); | 742 | __netif_rx_schedule(dev, &fep->napi); |
752 | } else { | 743 | } else { |
753 | printk(KERN_ERR DRV_MODULE_NAME | 744 | printk(KERN_ERR DRV_MODULE_NAME |
754 | ": %s driver bug! interrupt while in poll!\n", | 745 | ": %s driver bug! interrupt while in poll!\n", |
@@ -893,10 +884,13 @@ static int fec_enet_open(struct net_device *dev) | |||
893 | const struct fec_platform_info *fpi = fep->fpi; | 884 | const struct fec_platform_info *fpi = fep->fpi; |
894 | unsigned long flags; | 885 | unsigned long flags; |
895 | 886 | ||
887 | napi_enable(&fep->napi); | ||
888 | |||
896 | /* Install our interrupt handler. */ | 889 | /* Install our interrupt handler. */ |
897 | if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) { | 890 | if (request_irq(fpi->fec_irq, fec_enet_interrupt, 0, "fec", dev) != 0) { |
898 | printk(KERN_ERR DRV_MODULE_NAME | 891 | printk(KERN_ERR DRV_MODULE_NAME |
899 | ": %s Could not allocate FEC IRQ!", dev->name); | 892 | ": %s Could not allocate FEC IRQ!", dev->name); |
893 | napi_disable(&fep->napi); | ||
900 | return -EINVAL; | 894 | return -EINVAL; |
901 | } | 895 | } |
902 | 896 | ||
@@ -907,6 +901,7 @@ static int fec_enet_open(struct net_device *dev) | |||
907 | printk(KERN_ERR DRV_MODULE_NAME | 901 | printk(KERN_ERR DRV_MODULE_NAME |
908 | ": %s Could not allocate PHY IRQ!", dev->name); | 902 | ": %s Could not allocate PHY IRQ!", dev->name); |
909 | free_irq(fpi->fec_irq, dev); | 903 | free_irq(fpi->fec_irq, dev); |
904 | napi_disable(&fep->napi); | ||
910 | return -EINVAL; | 905 | return -EINVAL; |
911 | } | 906 | } |
912 | 907 | ||
@@ -932,6 +927,7 @@ static int fec_enet_close(struct net_device *dev) | |||
932 | unsigned long flags; | 927 | unsigned long flags; |
933 | 928 | ||
934 | netif_stop_queue(dev); | 929 | netif_stop_queue(dev); |
930 | napi_disable(&fep->napi); | ||
935 | netif_carrier_off(dev); | 931 | netif_carrier_off(dev); |
936 | 932 | ||
937 | if (fpi->use_mdio) | 933 | if (fpi->use_mdio) |
@@ -955,9 +951,12 @@ static struct net_device_stats *fec_enet_get_stats(struct net_device *dev) | |||
955 | return &fep->stats; | 951 | return &fep->stats; |
956 | } | 952 | } |
957 | 953 | ||
958 | static int fec_enet_poll(struct net_device *dev, int *budget) | 954 | static int fec_enet_poll(struct napi_struct *napi, int budget) |
959 | { | 955 | { |
960 | return fec_enet_rx_common(dev, budget); | 956 | struct fec_enet_private *fep = container_of(napi, struct fec_enet_private, napi); |
957 | struct net_device *dev = fep->dev; | ||
958 | |||
959 | return fec_enet_rx_common(fep, dev, budget); | ||
961 | } | 960 | } |
962 | 961 | ||
963 | /*************************************************************************/ | 962 | /*************************************************************************/ |
@@ -1107,6 +1106,7 @@ int fec_8xx_init_one(const struct fec_platform_info *fpi, | |||
1107 | SET_MODULE_OWNER(dev); | 1106 | SET_MODULE_OWNER(dev); |
1108 | 1107 | ||
1109 | fep = netdev_priv(dev); | 1108 | fep = netdev_priv(dev); |
1109 | fep->dev = dev; | ||
1110 | 1110 | ||
1111 | /* partial reset of FEC */ | 1111 | /* partial reset of FEC */ |
1112 | fec_whack_reset(fecp); | 1112 | fec_whack_reset(fecp); |
@@ -1172,10 +1172,9 @@ int fec_8xx_init_one(const struct fec_platform_info *fpi, | |||
1172 | dev->get_stats = fec_enet_get_stats; | 1172 | dev->get_stats = fec_enet_get_stats; |
1173 | dev->set_multicast_list = fec_set_multicast_list; | 1173 | dev->set_multicast_list = fec_set_multicast_list; |
1174 | dev->set_mac_address = fec_set_mac_address; | 1174 | dev->set_mac_address = fec_set_mac_address; |
1175 | if (fpi->use_napi) { | 1175 | netif_napi_add(dev, &fec->napi, |
1176 | dev->poll = fec_enet_poll; | 1176 | fec_enet_poll, fpi->napi_weight); |
1177 | dev->weight = fpi->napi_weight; | 1177 | |
1178 | } | ||
1179 | dev->ethtool_ops = &fec_ethtool_ops; | 1178 | dev->ethtool_ops = &fec_ethtool_ops; |
1180 | dev->do_ioctl = fec_ioctl; | 1179 | dev->do_ioctl = fec_ioctl; |
1181 | 1180 | ||