aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pasemi_mac.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/pasemi_mac.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/pasemi_mac.c')
-rw-r--r--drivers/net/pasemi_mac.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 0b3066a6fe40..e63cc335a4ba 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -584,7 +584,7 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
584 if (*mac->rx_status & PAS_STATUS_TIMER) 584 if (*mac->rx_status & PAS_STATUS_TIMER)
585 reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; 585 reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
586 586
587 netif_rx_schedule(dev); 587 netif_rx_schedule(dev, &mac->napi);
588 588
589 pci_write_config_dword(mac->iob_pdev, 589 pci_write_config_dword(mac->iob_pdev,
590 PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); 590 PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
@@ -808,7 +808,7 @@ static int pasemi_mac_open(struct net_device *dev)
808 dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret); 808 dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
809 809
810 netif_start_queue(dev); 810 netif_start_queue(dev);
811 netif_poll_enable(dev); 811 napi_enable(&mac->napi);
812 812
813 /* Interrupts are a bit different for our DMA controller: While 813 /* Interrupts are a bit different for our DMA controller: While
814 * it's got one a regular PCI device header, the interrupt there 814 * it's got one a regular PCI device header, the interrupt there
@@ -845,7 +845,7 @@ static int pasemi_mac_open(struct net_device *dev)
845out_rx_int: 845out_rx_int:
846 free_irq(mac->tx_irq, dev); 846 free_irq(mac->tx_irq, dev);
847out_tx_int: 847out_tx_int:
848 netif_poll_disable(dev); 848 napi_disable(&mac->napi);
849 netif_stop_queue(dev); 849 netif_stop_queue(dev);
850 pasemi_mac_free_tx_resources(dev); 850 pasemi_mac_free_tx_resources(dev);
851out_tx_resources: 851out_tx_resources:
@@ -869,6 +869,7 @@ static int pasemi_mac_close(struct net_device *dev)
869 } 869 }
870 870
871 netif_stop_queue(dev); 871 netif_stop_queue(dev);
872 napi_disable(&mac->napi);
872 873
873 /* Clean out any pending buffers */ 874 /* Clean out any pending buffers */
874 pasemi_mac_clean_tx(mac); 875 pasemi_mac_clean_tx(mac);
@@ -1047,26 +1048,20 @@ static void pasemi_mac_set_rx_mode(struct net_device *dev)
1047} 1048}
1048 1049
1049 1050
1050static int pasemi_mac_poll(struct net_device *dev, int *budget) 1051static int pasemi_mac_poll(struct napi_struct *napi, int budget)
1051{ 1052{
1052 int pkts, limit = min(*budget, dev->quota); 1053 struct pasemi_mac *mac = container_of(napi, struct pasemi_mac, napi);
1053 struct pasemi_mac *mac = netdev_priv(dev); 1054 struct net_device *dev = mac->netdev;
1054 1055 int pkts;
1055 pkts = pasemi_mac_clean_rx(mac, limit);
1056 1056
1057 dev->quota -= pkts; 1057 pkts = pasemi_mac_clean_rx(mac, budget);
1058 *budget -= pkts; 1058 if (pkts < budget) {
1059
1060 if (pkts < limit) {
1061 /* all done, no more packets present */ 1059 /* all done, no more packets present */
1062 netif_rx_complete(dev); 1060 netif_rx_complete(dev, napi);
1063 1061
1064 pasemi_mac_restart_rx_intr(mac); 1062 pasemi_mac_restart_rx_intr(mac);
1065 return 0;
1066 } else {
1067 /* used up our quantum, so reschedule */
1068 return 1;
1069 } 1063 }
1064 return pkts;
1070} 1065}
1071 1066
1072static int __devinit 1067static int __devinit
@@ -1099,6 +1094,10 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1099 mac->netdev = dev; 1094 mac->netdev = dev;
1100 mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL); 1095 mac->dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
1101 1096
1097 netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
1098
1099 dev->features = NETIF_F_HW_CSUM;
1100
1102 if (!mac->dma_pdev) { 1101 if (!mac->dma_pdev) {
1103 dev_err(&pdev->dev, "Can't find DMA Controller\n"); 1102 dev_err(&pdev->dev, "Can't find DMA Controller\n");
1104 err = -ENODEV; 1103 err = -ENODEV;
@@ -1150,9 +1149,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1150 dev->hard_start_xmit = pasemi_mac_start_tx; 1149 dev->hard_start_xmit = pasemi_mac_start_tx;
1151 dev->get_stats = pasemi_mac_get_stats; 1150 dev->get_stats = pasemi_mac_get_stats;
1152 dev->set_multicast_list = pasemi_mac_set_rx_mode; 1151 dev->set_multicast_list = pasemi_mac_set_rx_mode;
1153 dev->weight = 64;
1154 dev->poll = pasemi_mac_poll;
1155 dev->features = NETIF_F_HW_CSUM;
1156 1152
1157 /* The dma status structure is located in the I/O bridge, and 1153 /* The dma status structure is located in the I/O bridge, and
1158 * is cache coherent. 1154 * is cache coherent.