diff options
Diffstat (limited to 'drivers/net/tsi108_eth.c')
-rw-r--r-- | drivers/net/tsi108_eth.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 1aabc91f6458..b3069ee34bd2 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c | |||
@@ -79,6 +79,9 @@ struct tsi108_prv_data { | |||
79 | void __iomem *regs; /* Base of normal regs */ | 79 | void __iomem *regs; /* Base of normal regs */ |
80 | void __iomem *phyregs; /* Base of register bank used for PHY access */ | 80 | void __iomem *phyregs; /* Base of register bank used for PHY access */ |
81 | 81 | ||
82 | struct net_device *dev; | ||
83 | struct napi_struct napi; | ||
84 | |||
82 | unsigned int phy; /* Index of PHY for this interface */ | 85 | unsigned int phy; /* Index of PHY for this interface */ |
83 | unsigned int irq_num; | 86 | unsigned int irq_num; |
84 | unsigned int id; | 87 | unsigned int id; |
@@ -837,13 +840,13 @@ static int tsi108_refill_rx(struct net_device *dev, int budget) | |||
837 | return done; | 840 | return done; |
838 | } | 841 | } |
839 | 842 | ||
840 | static int tsi108_poll(struct net_device *dev, int *budget) | 843 | static int tsi108_poll(struct napi_struct *napi, int budget) |
841 | { | 844 | { |
842 | struct tsi108_prv_data *data = netdev_priv(dev); | 845 | struct tsi108_prv_data *data = container_of(napi, struct tsi108_prv_data, napi); |
846 | struct net_device *dev = data->dev; | ||
843 | u32 estat = TSI_READ(TSI108_EC_RXESTAT); | 847 | u32 estat = TSI_READ(TSI108_EC_RXESTAT); |
844 | u32 intstat = TSI_READ(TSI108_EC_INTSTAT); | 848 | u32 intstat = TSI_READ(TSI108_EC_INTSTAT); |
845 | int total_budget = min(*budget, dev->quota); | 849 | int num_received = 0, num_filled = 0; |
846 | int num_received = 0, num_filled = 0, budget_used; | ||
847 | 850 | ||
848 | intstat &= TSI108_INT_RXQUEUE0 | TSI108_INT_RXTHRESH | | 851 | intstat &= TSI108_INT_RXQUEUE0 | TSI108_INT_RXTHRESH | |
849 | TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR | TSI108_INT_RXWAIT; | 852 | TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR | TSI108_INT_RXWAIT; |
@@ -852,7 +855,7 @@ static int tsi108_poll(struct net_device *dev, int *budget) | |||
852 | TSI_WRITE(TSI108_EC_INTSTAT, intstat); | 855 | TSI_WRITE(TSI108_EC_INTSTAT, intstat); |
853 | 856 | ||
854 | if (data->rxpending || (estat & TSI108_EC_RXESTAT_Q0_DESCINT)) | 857 | if (data->rxpending || (estat & TSI108_EC_RXESTAT_Q0_DESCINT)) |
855 | num_received = tsi108_complete_rx(dev, total_budget); | 858 | num_received = tsi108_complete_rx(dev, budget); |
856 | 859 | ||
857 | /* This should normally fill no more slots than the number of | 860 | /* This should normally fill no more slots than the number of |
858 | * packets received in tsi108_complete_rx(). The exception | 861 | * packets received in tsi108_complete_rx(). The exception |
@@ -867,7 +870,7 @@ static int tsi108_poll(struct net_device *dev, int *budget) | |||
867 | */ | 870 | */ |
868 | 871 | ||
869 | if (data->rxfree < TSI108_RXRING_LEN) | 872 | if (data->rxfree < TSI108_RXRING_LEN) |
870 | num_filled = tsi108_refill_rx(dev, total_budget * 2); | 873 | num_filled = tsi108_refill_rx(dev, budget * 2); |
871 | 874 | ||
872 | if (intstat & TSI108_INT_RXERROR) { | 875 | if (intstat & TSI108_INT_RXERROR) { |
873 | u32 err = TSI_READ(TSI108_EC_RXERR); | 876 | u32 err = TSI_READ(TSI108_EC_RXERR); |
@@ -890,14 +893,9 @@ static int tsi108_poll(struct net_device *dev, int *budget) | |||
890 | spin_unlock_irq(&data->misclock); | 893 | spin_unlock_irq(&data->misclock); |
891 | } | 894 | } |
892 | 895 | ||
893 | budget_used = max(num_received, num_filled / 2); | 896 | if (num_received < budget) { |
894 | |||
895 | *budget -= budget_used; | ||
896 | dev->quota -= budget_used; | ||
897 | |||
898 | if (budget_used != total_budget) { | ||
899 | data->rxpending = 0; | 897 | data->rxpending = 0; |
900 | netif_rx_complete(dev); | 898 | netif_rx_complete(dev, napi); |
901 | 899 | ||
902 | TSI_WRITE(TSI108_EC_INTMASK, | 900 | TSI_WRITE(TSI108_EC_INTMASK, |
903 | TSI_READ(TSI108_EC_INTMASK) | 901 | TSI_READ(TSI108_EC_INTMASK) |
@@ -906,14 +904,11 @@ static int tsi108_poll(struct net_device *dev, int *budget) | |||
906 | TSI108_INT_RXOVERRUN | | 904 | TSI108_INT_RXOVERRUN | |
907 | TSI108_INT_RXERROR | | 905 | TSI108_INT_RXERROR | |
908 | TSI108_INT_RXWAIT)); | 906 | TSI108_INT_RXWAIT)); |
909 | |||
910 | /* IRQs are level-triggered, so no need to re-check */ | ||
911 | return 0; | ||
912 | } else { | 907 | } else { |
913 | data->rxpending = 1; | 908 | data->rxpending = 1; |
914 | } | 909 | } |
915 | 910 | ||
916 | return 1; | 911 | return num_received; |
917 | } | 912 | } |
918 | 913 | ||
919 | static void tsi108_rx_int(struct net_device *dev) | 914 | static void tsi108_rx_int(struct net_device *dev) |
@@ -931,7 +926,7 @@ static void tsi108_rx_int(struct net_device *dev) | |||
931 | * from tsi108_check_rxring(). | 926 | * from tsi108_check_rxring(). |
932 | */ | 927 | */ |
933 | 928 | ||
934 | if (netif_rx_schedule_prep(dev)) { | 929 | if (netif_rx_schedule_prep(dev, &data->napi)) { |
935 | /* Mask, rather than ack, the receive interrupts. The ack | 930 | /* Mask, rather than ack, the receive interrupts. The ack |
936 | * will happen in tsi108_poll(). | 931 | * will happen in tsi108_poll(). |
937 | */ | 932 | */ |
@@ -942,7 +937,7 @@ static void tsi108_rx_int(struct net_device *dev) | |||
942 | | TSI108_INT_RXTHRESH | | 937 | | TSI108_INT_RXTHRESH | |
943 | TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR | | 938 | TSI108_INT_RXOVERRUN | TSI108_INT_RXERROR | |
944 | TSI108_INT_RXWAIT); | 939 | TSI108_INT_RXWAIT); |
945 | __netif_rx_schedule(dev); | 940 | __netif_rx_schedule(dev, &data->napi); |
946 | } else { | 941 | } else { |
947 | if (!netif_running(dev)) { | 942 | if (!netif_running(dev)) { |
948 | /* This can happen if an interrupt occurs while the | 943 | /* This can happen if an interrupt occurs while the |
@@ -1401,6 +1396,8 @@ static int tsi108_open(struct net_device *dev) | |||
1401 | TSI_WRITE(TSI108_EC_TXQ_PTRLOW, data->txdma); | 1396 | TSI_WRITE(TSI108_EC_TXQ_PTRLOW, data->txdma); |
1402 | tsi108_init_phy(dev); | 1397 | tsi108_init_phy(dev); |
1403 | 1398 | ||
1399 | napi_enable(&data->napi); | ||
1400 | |||
1404 | setup_timer(&data->timer, tsi108_timed_checker, (unsigned long)dev); | 1401 | setup_timer(&data->timer, tsi108_timed_checker, (unsigned long)dev); |
1405 | mod_timer(&data->timer, jiffies + 1); | 1402 | mod_timer(&data->timer, jiffies + 1); |
1406 | 1403 | ||
@@ -1425,6 +1422,7 @@ static int tsi108_close(struct net_device *dev) | |||
1425 | struct tsi108_prv_data *data = netdev_priv(dev); | 1422 | struct tsi108_prv_data *data = netdev_priv(dev); |
1426 | 1423 | ||
1427 | netif_stop_queue(dev); | 1424 | netif_stop_queue(dev); |
1425 | napi_disable(&data->napi); | ||
1428 | 1426 | ||
1429 | del_timer_sync(&data->timer); | 1427 | del_timer_sync(&data->timer); |
1430 | 1428 | ||
@@ -1562,6 +1560,7 @@ tsi108_init_one(struct platform_device *pdev) | |||
1562 | 1560 | ||
1563 | printk("tsi108_eth%d: probe...\n", pdev->id); | 1561 | printk("tsi108_eth%d: probe...\n", pdev->id); |
1564 | data = netdev_priv(dev); | 1562 | data = netdev_priv(dev); |
1563 | data->dev = dev; | ||
1565 | 1564 | ||
1566 | pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n", | 1565 | pr_debug("tsi108_eth%d:regs:phyresgs:phy:irq_num=0x%x:0x%x:0x%x:0x%x\n", |
1567 | pdev->id, einfo->regs, einfo->phyregs, | 1566 | pdev->id, einfo->regs, einfo->phyregs, |
@@ -1597,9 +1596,8 @@ tsi108_init_one(struct platform_device *pdev) | |||
1597 | dev->set_mac_address = tsi108_set_mac; | 1596 | dev->set_mac_address = tsi108_set_mac; |
1598 | dev->set_multicast_list = tsi108_set_rx_mode; | 1597 | dev->set_multicast_list = tsi108_set_rx_mode; |
1599 | dev->get_stats = tsi108_get_stats; | 1598 | dev->get_stats = tsi108_get_stats; |
1600 | dev->poll = tsi108_poll; | 1599 | netif_napi_add(dev, &data->napi, tsi108_poll, 64); |
1601 | dev->do_ioctl = tsi108_do_ioctl; | 1600 | dev->do_ioctl = tsi108_do_ioctl; |
1602 | dev->weight = 64; /* 64 is more suitable for GigE interface - klai */ | ||
1603 | 1601 | ||
1604 | /* Apparently, the Linux networking code won't use scatter-gather | 1602 | /* Apparently, the Linux networking code won't use scatter-gather |
1605 | * if the hardware doesn't do checksums. However, it's faster | 1603 | * if the hardware doesn't do checksums. However, it's faster |