aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tsi108_eth.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-10-03 19:41:36 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:47:45 -0400
commitbea3348eef27e6044b6161fd04c3152215f96411 (patch)
treef0990b263e5ce42505d290a4c346fe990bcd4c33 /drivers/net/tsi108_eth.c
parentdde4e47e8fe333a5649a3fa0e7db1fa7c08d6158 (diff)
[NET]: Make NAPI polling independent of struct net_device objects.
Several devices have multiple independant RX queues per net device, and some have a single interrupt doorbell for several queues. In either case, it's easier to support layouts like that if the structure representing the poll is independant from the net device itself. The signature of the ->poll() call back goes from: int foo_poll(struct net_device *dev, int *budget) to int foo_poll(struct napi_struct *napi, int budget) The caller is returned the number of RX packets processed (or the number of "NAPI credits" consumed if you want to get abstract). The callee no longer messes around bumping dev->quota, *budget, etc. because that is all handled in the caller upon return. The napi_struct is to be embedded in the device driver private data structures. Furthermore, it is the driver's responsibility to disable all NAPI instances in it's ->stop() device close handler. Since the napi_struct is privatized into the driver's private data structures, only the driver knows how to get at all of the napi_struct instances it may have per-device. With lots of help and suggestions from Rusty Russell, Roland Dreier, Michael Chan, Jeff Garzik, and Jamal Hadi Salim. Bug fixes from Thomas Graf, Roland Dreier, Peter Zijlstra, Joseph Fannin, Scott Wood, Hans J. Koch, and Michael Chan. [ Ported to current tree and all drivers converted. Integrated Stephen's follow-on kerneldoc additions, and restored poll_list handling to the old style to fix mutual exclusion issues. -DaveM ] Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tsi108_eth.c')
-rw-r--r--drivers/net/tsi108_eth.c40
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
840static int tsi108_poll(struct net_device *dev, int *budget) 843static 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
919static void tsi108_rx_int(struct net_device *dev) 914static 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