aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e100.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/e100.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/e100.c')
-rw-r--r--drivers/net/e100.c37
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 280313b9b069..e25f5ec2b279 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -539,6 +539,7 @@ struct nic {
539 struct csr __iomem *csr; 539 struct csr __iomem *csr;
540 enum scb_cmd_lo cuc_cmd; 540 enum scb_cmd_lo cuc_cmd;
541 unsigned int cbs_avail; 541 unsigned int cbs_avail;
542 struct napi_struct napi;
542 struct cb *cbs; 543 struct cb *cbs;
543 struct cb *cb_to_use; 544 struct cb *cb_to_use;
544 struct cb *cb_to_send; 545 struct cb *cb_to_send;
@@ -1974,35 +1975,31 @@ static irqreturn_t e100_intr(int irq, void *dev_id)
1974 if(stat_ack & stat_ack_rnr) 1975 if(stat_ack & stat_ack_rnr)
1975 nic->ru_running = RU_SUSPENDED; 1976 nic->ru_running = RU_SUSPENDED;
1976 1977
1977 if(likely(netif_rx_schedule_prep(netdev))) { 1978 if(likely(netif_rx_schedule_prep(netdev, &nic->napi))) {
1978 e100_disable_irq(nic); 1979 e100_disable_irq(nic);
1979 __netif_rx_schedule(netdev); 1980 __netif_rx_schedule(netdev, &nic->napi);
1980 } 1981 }
1981 1982
1982 return IRQ_HANDLED; 1983 return IRQ_HANDLED;
1983} 1984}
1984 1985
1985static int e100_poll(struct net_device *netdev, int *budget) 1986static int e100_poll(struct napi_struct *napi, int budget)
1986{ 1987{
1987 struct nic *nic = netdev_priv(netdev); 1988 struct nic *nic = container_of(napi, struct nic, napi);
1988 unsigned int work_to_do = min(netdev->quota, *budget); 1989 struct net_device *netdev = nic->netdev;
1989 unsigned int work_done = 0; 1990 int work_done = 0;
1990 int tx_cleaned; 1991 int tx_cleaned;
1991 1992
1992 e100_rx_clean(nic, &work_done, work_to_do); 1993 e100_rx_clean(nic, &work_done, budget);
1993 tx_cleaned = e100_tx_clean(nic); 1994 tx_cleaned = e100_tx_clean(nic);
1994 1995
1995 /* If no Rx and Tx cleanup work was done, exit polling mode. */ 1996 /* If no Rx and Tx cleanup work was done, exit polling mode. */
1996 if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) { 1997 if((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
1997 netif_rx_complete(netdev); 1998 netif_rx_complete(netdev, napi);
1998 e100_enable_irq(nic); 1999 e100_enable_irq(nic);
1999 return 0;
2000 } 2000 }
2001 2001
2002 *budget -= work_done; 2002 return work_done;
2003 netdev->quota -= work_done;
2004
2005 return 1;
2006} 2003}
2007 2004
2008#ifdef CONFIG_NET_POLL_CONTROLLER 2005#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2071,7 +2068,7 @@ static int e100_up(struct nic *nic)
2071 nic->netdev->name, nic->netdev))) 2068 nic->netdev->name, nic->netdev)))
2072 goto err_no_irq; 2069 goto err_no_irq;
2073 netif_wake_queue(nic->netdev); 2070 netif_wake_queue(nic->netdev);
2074 netif_poll_enable(nic->netdev); 2071 napi_enable(&nic->napi);
2075 /* enable ints _after_ enabling poll, preventing a race between 2072 /* enable ints _after_ enabling poll, preventing a race between
2076 * disable ints+schedule */ 2073 * disable ints+schedule */
2077 e100_enable_irq(nic); 2074 e100_enable_irq(nic);
@@ -2089,7 +2086,7 @@ err_rx_clean_list:
2089static void e100_down(struct nic *nic) 2086static void e100_down(struct nic *nic)
2090{ 2087{
2091 /* wait here for poll to complete */ 2088 /* wait here for poll to complete */
2092 netif_poll_disable(nic->netdev); 2089 napi_disable(&nic->napi);
2093 netif_stop_queue(nic->netdev); 2090 netif_stop_queue(nic->netdev);
2094 e100_hw_reset(nic); 2091 e100_hw_reset(nic);
2095 free_irq(nic->pdev->irq, nic->netdev); 2092 free_irq(nic->pdev->irq, nic->netdev);
@@ -2572,14 +2569,13 @@ static int __devinit e100_probe(struct pci_dev *pdev,
2572 SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops); 2569 SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops);
2573 netdev->tx_timeout = e100_tx_timeout; 2570 netdev->tx_timeout = e100_tx_timeout;
2574 netdev->watchdog_timeo = E100_WATCHDOG_PERIOD; 2571 netdev->watchdog_timeo = E100_WATCHDOG_PERIOD;
2575 netdev->poll = e100_poll;
2576 netdev->weight = E100_NAPI_WEIGHT;
2577#ifdef CONFIG_NET_POLL_CONTROLLER 2572#ifdef CONFIG_NET_POLL_CONTROLLER
2578 netdev->poll_controller = e100_netpoll; 2573 netdev->poll_controller = e100_netpoll;
2579#endif 2574#endif
2580 strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); 2575 strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
2581 2576
2582 nic = netdev_priv(netdev); 2577 nic = netdev_priv(netdev);
2578 netif_napi_add(netdev, &nic->napi, e100_poll, E100_NAPI_WEIGHT);
2583 nic->netdev = netdev; 2579 nic->netdev = netdev;
2584 nic->pdev = pdev; 2580 nic->pdev = pdev;
2585 nic->msg_enable = (1 << debug) - 1; 2581 nic->msg_enable = (1 << debug) - 1;
@@ -2733,7 +2729,7 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state)
2733 struct nic *nic = netdev_priv(netdev); 2729 struct nic *nic = netdev_priv(netdev);
2734 2730
2735 if (netif_running(netdev)) 2731 if (netif_running(netdev))
2736 netif_poll_disable(nic->netdev); 2732 napi_disable(&nic->napi);
2737 del_timer_sync(&nic->watchdog); 2733 del_timer_sync(&nic->watchdog);
2738 netif_carrier_off(nic->netdev); 2734 netif_carrier_off(nic->netdev);
2739 netif_device_detach(netdev); 2735 netif_device_detach(netdev);
@@ -2779,7 +2775,7 @@ static void e100_shutdown(struct pci_dev *pdev)
2779 struct nic *nic = netdev_priv(netdev); 2775 struct nic *nic = netdev_priv(netdev);
2780 2776
2781 if (netif_running(netdev)) 2777 if (netif_running(netdev))
2782 netif_poll_disable(nic->netdev); 2778 napi_disable(&nic->napi);
2783 del_timer_sync(&nic->watchdog); 2779 del_timer_sync(&nic->watchdog);
2784 netif_carrier_off(nic->netdev); 2780 netif_carrier_off(nic->netdev);
2785 2781
@@ -2804,12 +2800,13 @@ static void e100_shutdown(struct pci_dev *pdev)
2804static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) 2800static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
2805{ 2801{
2806 struct net_device *netdev = pci_get_drvdata(pdev); 2802 struct net_device *netdev = pci_get_drvdata(pdev);
2803 struct nic *nic = netdev_priv(netdev);
2807 2804
2808 /* Similar to calling e100_down(), but avoids adpater I/O. */ 2805 /* Similar to calling e100_down(), but avoids adpater I/O. */
2809 netdev->stop(netdev); 2806 netdev->stop(netdev);
2810 2807
2811 /* Detach; put netif into state similar to hotplug unplug. */ 2808 /* Detach; put netif into state similar to hotplug unplug. */
2812 netif_poll_enable(netdev); 2809 napi_enable(&nic->napi);
2813 netif_device_detach(netdev); 2810 netif_device_detach(netdev);
2814 pci_disable_device(pdev); 2811 pci_disable_device(pdev);
2815 2812