diff options
Diffstat (limited to 'drivers/net/fs_enet/fs_enet-main.c')
-rw-r--r-- | drivers/net/fs_enet/fs_enet-main.c | 55 |
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 */ |
73 | static int fs_enet_rx_napi(struct net_device *dev, int *budget) | 73 | static 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 | ||