aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fec_8xx/fec_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fec_8xx/fec_main.c')
-rw-r--r--drivers/net/fec_8xx/fec_main.c59
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 */
468static int fec_enet_rx_common(struct net_device *dev, int *budget) 468static 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
623static void fec_enet_tx(struct net_device *dev) 614static 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
958static int fec_enet_poll(struct net_device *dev, int *budget) 954static 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