diff options
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 315335671f0f..702eba549161 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -66,7 +66,7 @@ static int mv643xx_eth_change_mtu(struct net_device *, int); | |||
66 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); | 66 | static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); |
67 | static void eth_port_init_mac_tables(unsigned int eth_port_num); | 67 | static void eth_port_init_mac_tables(unsigned int eth_port_num); |
68 | #ifdef MV643XX_NAPI | 68 | #ifdef MV643XX_NAPI |
69 | static int mv643xx_poll(struct net_device *dev, int *budget); | 69 | static int mv643xx_poll(struct napi_struct *napi, int budget); |
70 | #endif | 70 | #endif |
71 | static int ethernet_phy_get(unsigned int eth_port_num); | 71 | static int ethernet_phy_get(unsigned int eth_port_num); |
72 | static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); | 72 | static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr); |
@@ -562,7 +562,7 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id) | |||
562 | /* wait for previous write to complete */ | 562 | /* wait for previous write to complete */ |
563 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); | 563 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); |
564 | 564 | ||
565 | netif_rx_schedule(dev); | 565 | netif_rx_schedule(dev, &mp->napi); |
566 | } | 566 | } |
567 | #else | 567 | #else |
568 | if (eth_int_cause & ETH_INT_CAUSE_RX) | 568 | if (eth_int_cause & ETH_INT_CAUSE_RX) |
@@ -880,6 +880,10 @@ static int mv643xx_eth_open(struct net_device *dev) | |||
880 | 880 | ||
881 | mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ | 881 | mv643xx_eth_rx_refill_descs(dev); /* Fill RX ring with skb's */ |
882 | 882 | ||
883 | #ifdef MV643XX_NAPI | ||
884 | napi_enable(&mp->napi); | ||
885 | #endif | ||
886 | |||
883 | eth_port_start(dev); | 887 | eth_port_start(dev); |
884 | 888 | ||
885 | /* Interrupt Coalescing */ | 889 | /* Interrupt Coalescing */ |
@@ -982,7 +986,7 @@ static int mv643xx_eth_stop(struct net_device *dev) | |||
982 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); | 986 | mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); |
983 | 987 | ||
984 | #ifdef MV643XX_NAPI | 988 | #ifdef MV643XX_NAPI |
985 | netif_poll_disable(dev); | 989 | napi_disable(&mp->napi); |
986 | #endif | 990 | #endif |
987 | netif_carrier_off(dev); | 991 | netif_carrier_off(dev); |
988 | netif_stop_queue(dev); | 992 | netif_stop_queue(dev); |
@@ -992,10 +996,6 @@ static int mv643xx_eth_stop(struct net_device *dev) | |||
992 | mv643xx_eth_free_tx_rings(dev); | 996 | mv643xx_eth_free_tx_rings(dev); |
993 | mv643xx_eth_free_rx_rings(dev); | 997 | mv643xx_eth_free_rx_rings(dev); |
994 | 998 | ||
995 | #ifdef MV643XX_NAPI | ||
996 | netif_poll_enable(dev); | ||
997 | #endif | ||
998 | |||
999 | free_irq(dev->irq, dev); | 999 | free_irq(dev->irq, dev); |
1000 | 1000 | ||
1001 | return 0; | 1001 | return 0; |
@@ -1007,11 +1007,12 @@ static int mv643xx_eth_stop(struct net_device *dev) | |||
1007 | * | 1007 | * |
1008 | * This function is used in case of NAPI | 1008 | * This function is used in case of NAPI |
1009 | */ | 1009 | */ |
1010 | static int mv643xx_poll(struct net_device *dev, int *budget) | 1010 | static int mv643xx_poll(struct napi_struct *napi, int budget) |
1011 | { | 1011 | { |
1012 | struct mv643xx_private *mp = netdev_priv(dev); | 1012 | struct mv643xx_private *mp = container_of(napi, struct mv643xx_private, napi); |
1013 | int done = 1, orig_budget, work_done; | 1013 | struct net_device *dev = mp->dev; |
1014 | unsigned int port_num = mp->port_num; | 1014 | unsigned int port_num = mp->port_num; |
1015 | int work_done; | ||
1015 | 1016 | ||
1016 | #ifdef MV643XX_TX_FAST_REFILL | 1017 | #ifdef MV643XX_TX_FAST_REFILL |
1017 | if (++mp->tx_clean_threshold > 5) { | 1018 | if (++mp->tx_clean_threshold > 5) { |
@@ -1020,27 +1021,20 @@ static int mv643xx_poll(struct net_device *dev, int *budget) | |||
1020 | } | 1021 | } |
1021 | #endif | 1022 | #endif |
1022 | 1023 | ||
1024 | work_done = 0; | ||
1023 | if ((mv_read(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num))) | 1025 | if ((mv_read(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num))) |
1024 | != (u32) mp->rx_used_desc_q) { | 1026 | != (u32) mp->rx_used_desc_q) |
1025 | orig_budget = *budget; | 1027 | work_done = mv643xx_eth_receive_queue(dev, budget); |
1026 | if (orig_budget > dev->quota) | ||
1027 | orig_budget = dev->quota; | ||
1028 | work_done = mv643xx_eth_receive_queue(dev, orig_budget); | ||
1029 | *budget -= work_done; | ||
1030 | dev->quota -= work_done; | ||
1031 | if (work_done >= orig_budget) | ||
1032 | done = 0; | ||
1033 | } | ||
1034 | 1028 | ||
1035 | if (done) { | 1029 | if (work_done < budget) { |
1036 | netif_rx_complete(dev); | 1030 | netif_rx_complete(dev, napi); |
1037 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); | 1031 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); |
1038 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); | 1032 | mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); |
1039 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), | 1033 | mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), |
1040 | ETH_INT_UNMASK_ALL); | 1034 | ETH_INT_UNMASK_ALL); |
1041 | } | 1035 | } |
1042 | 1036 | ||
1043 | return done ? 0 : 1; | 1037 | return work_done; |
1044 | } | 1038 | } |
1045 | #endif | 1039 | #endif |
1046 | 1040 | ||
@@ -1333,6 +1327,10 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1333 | platform_set_drvdata(pdev, dev); | 1327 | platform_set_drvdata(pdev, dev); |
1334 | 1328 | ||
1335 | mp = netdev_priv(dev); | 1329 | mp = netdev_priv(dev); |
1330 | mp->dev = dev; | ||
1331 | #ifdef MV643XX_NAPI | ||
1332 | netif_napi_add(dev, &mp->napi, mv643xx_poll, 64); | ||
1333 | #endif | ||
1336 | 1334 | ||
1337 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1335 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
1338 | BUG_ON(!res); | 1336 | BUG_ON(!res); |
@@ -1347,10 +1345,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) | |||
1347 | 1345 | ||
1348 | /* No need to Tx Timeout */ | 1346 | /* No need to Tx Timeout */ |
1349 | dev->tx_timeout = mv643xx_eth_tx_timeout; | 1347 | dev->tx_timeout = mv643xx_eth_tx_timeout; |
1350 | #ifdef MV643XX_NAPI | ||
1351 | dev->poll = mv643xx_poll; | ||
1352 | dev->weight = 64; | ||
1353 | #endif | ||
1354 | 1348 | ||
1355 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1349 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1356 | dev->poll_controller = mv643xx_netpoll; | 1350 | dev->poll_controller = mv643xx_netpoll; |