aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/fs_enet/fs_enet-main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fs_enet/fs_enet-main.c')
-rw-r--r--drivers/net/fs_enet/fs_enet-main.c55
1 files changed, 24 insertions, 31 deletions
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index a4a2a0ea43d3..c509cb13222d 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -70,18 +70,16 @@ static void fs_set_multicast_list(struct net_device *dev)
70} 70}
71 71
72/* NAPI receive function */ 72/* NAPI receive function */
73static int fs_enet_rx_napi(struct net_device *dev, int *budget) 73static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
74{ 74{
75 struct fs_enet_private *fep = netdev_priv(dev); 75 struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
76 struct net_device *dev = to_net_dev(fep->dev);
76 const struct fs_platform_info *fpi = fep->fpi; 77 const struct fs_platform_info *fpi = fep->fpi;
77 cbd_t *bdp; 78 cbd_t *bdp;
78 struct sk_buff *skb, *skbn, *skbt; 79 struct sk_buff *skb, *skbn, *skbt;
79 int received = 0; 80 int received = 0;
80 u16 pkt_len, sc; 81 u16 pkt_len, sc;
81 int curidx; 82 int curidx;
82 int rx_work_limit = 0; /* pacify gcc */
83
84 rx_work_limit = min(dev->quota, *budget);
85 83
86 if (!netif_running(dev)) 84 if (!netif_running(dev))
87 return 0; 85 return 0;
@@ -96,7 +94,6 @@ static int fs_enet_rx_napi(struct net_device *dev, int *budget)
96 (*fep->ops->napi_clear_rx_event)(dev); 94 (*fep->ops->napi_clear_rx_event)(dev);
97 95
98 while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) { 96 while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
99
100 curidx = bdp - fep->rx_bd_base; 97 curidx = bdp - fep->rx_bd_base;
101 98
102 /* 99 /*
@@ -136,11 +133,6 @@ static int fs_enet_rx_napi(struct net_device *dev, int *budget)
136 skbn = skb; 133 skbn = skb;
137 134
138 } else { 135 } else {
139
140 /* napi, got packet but no quota */
141 if (--rx_work_limit < 0)
142 break;
143
144 skb = fep->rx_skbuff[curidx]; 136 skb = fep->rx_skbuff[curidx];
145 137
146 dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp), 138 dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
@@ -199,22 +191,19 @@ static int fs_enet_rx_napi(struct net_device *dev, int *budget)
199 bdp = fep->rx_bd_base; 191 bdp = fep->rx_bd_base;
200 192
201 (*fep->ops->rx_bd_done)(dev); 193 (*fep->ops->rx_bd_done)(dev);
194
195 if (received >= budget)
196 break;
202 } 197 }
203 198
204 fep->cur_rx = bdp; 199 fep->cur_rx = bdp;
205 200
206 dev->quota -= received; 201 if (received >= budget) {
207 *budget -= received; 202 /* done */
208 203 netif_rx_complete(dev, napi);
209 if (rx_work_limit < 0) 204 (*fep->ops->napi_enable_rx)(dev);
210 return 1; /* not done */ 205 }
211 206 return received;
212 /* done */
213 netif_rx_complete(dev);
214
215 (*fep->ops->napi_enable_rx)(dev);
216
217 return 0;
218} 207}
219 208
220/* non NAPI receive function */ 209/* non NAPI receive function */
@@ -470,7 +459,7 @@ fs_enet_interrupt(int irq, void *dev_id)
470 if (!fpi->use_napi) 459 if (!fpi->use_napi)
471 fs_enet_rx_non_napi(dev); 460 fs_enet_rx_non_napi(dev);
472 else { 461 else {
473 napi_ok = netif_rx_schedule_prep(dev); 462 napi_ok = napi_schedule_prep(&fep->napi);
474 463
475 (*fep->ops->napi_disable_rx)(dev); 464 (*fep->ops->napi_disable_rx)(dev);
476 (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx); 465 (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
@@ -478,7 +467,7 @@ fs_enet_interrupt(int irq, void *dev_id)
478 /* NOTE: it is possible for FCCs in NAPI mode */ 467 /* NOTE: it is possible for FCCs in NAPI mode */
479 /* to submit a spurious interrupt while in poll */ 468 /* to submit a spurious interrupt while in poll */
480 if (napi_ok) 469 if (napi_ok)
481 __netif_rx_schedule(dev); 470 __netif_rx_schedule(dev, &fep->napi);
482 } 471 }
483 } 472 }
484 473
@@ -799,18 +788,22 @@ static int fs_enet_open(struct net_device *dev)
799 int r; 788 int r;
800 int err; 789 int err;
801 790
791 napi_enable(&fep->napi);
792
802 /* Install our interrupt handler. */ 793 /* Install our interrupt handler. */
803 r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); 794 r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
804 if (r != 0) { 795 if (r != 0) {
805 printk(KERN_ERR DRV_MODULE_NAME 796 printk(KERN_ERR DRV_MODULE_NAME
806 ": %s Could not allocate FS_ENET IRQ!", dev->name); 797 ": %s Could not allocate FS_ENET IRQ!", dev->name);
798 napi_disable(&fep->napi);
807 return -EINVAL; 799 return -EINVAL;
808 } 800 }
809 801
810 err = fs_init_phy(dev); 802 err = fs_init_phy(dev);
811 if(err) 803 if(err) {
804 napi_disable(&fep->napi);
812 return err; 805 return err;
813 806 }
814 phy_start(fep->phydev); 807 phy_start(fep->phydev);
815 808
816 return 0; 809 return 0;
@@ -823,6 +816,7 @@ static int fs_enet_close(struct net_device *dev)
823 816
824 netif_stop_queue(dev); 817 netif_stop_queue(dev);
825 netif_carrier_off(dev); 818 netif_carrier_off(dev);
819 napi_disable(&fep->napi);
826 phy_stop(fep->phydev); 820 phy_stop(fep->phydev);
827 821
828 spin_lock_irqsave(&fep->lock, flags); 822 spin_lock_irqsave(&fep->lock, flags);
@@ -1047,10 +1041,9 @@ static struct net_device *fs_init_instance(struct device *dev,
1047 ndev->stop = fs_enet_close; 1041 ndev->stop = fs_enet_close;
1048 ndev->get_stats = fs_enet_get_stats; 1042 ndev->get_stats = fs_enet_get_stats;
1049 ndev->set_multicast_list = fs_set_multicast_list; 1043 ndev->set_multicast_list = fs_set_multicast_list;
1050 if (fpi->use_napi) { 1044 netif_napi_add(ndev, &fep->napi,
1051 ndev->poll = fs_enet_rx_napi; 1045 fs_enet_rx_napi, fpi->napi_weight);
1052 ndev->weight = fpi->napi_weight; 1046
1053 }
1054 ndev->ethtool_ops = &fs_ethtool_ops; 1047 ndev->ethtool_ops = &fs_ethtool_ops;
1055 ndev->do_ioctl = fs_ioctl; 1048 ndev->do_ioctl = fs_ioctl;
1056 1049