aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-05-08 18:02:28 -0400
committerDavid S. Miller <davem@davemloft.net>2009-05-09 16:13:36 -0400
commitbe339aee634d5cb98a8df8d6febe04002ec497f3 (patch)
treeafca65306a28220adb2e24d0f0cbdfe19501b4af /drivers/net/netxen/netxen_nic_main.c
parent7a2469ce4d8984722d65628969ad6f8b09da136f (diff)
netxen: fix irq tear down and msix leak.
o Fix the order of irq and hardware context teardown. Also synchronize the interrupt in dev close() before releasing tx buffers. o Fix possible msi-x vector leak if available vectors are less than requested. o Request multiple msix vectors only if hardware supports multiple rx queues. Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c74
1 files changed, 43 insertions, 31 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index edb4bcda71ea..c61c1d187a9e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -175,12 +175,6 @@ netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
175 struct nx_host_sds_ring *sds_ring; 175 struct nx_host_sds_ring *sds_ring;
176 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx; 176 struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
177 177
178 if ((adapter->flags & NETXEN_NIC_MSIX_ENABLED) &&
179 adapter->rss_supported)
180 adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
181 else
182 adapter->max_sds_rings = 1;
183
184 if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings)) 178 if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
185 return 1; 179 return 1;
186 180
@@ -216,8 +210,9 @@ netxen_napi_disable(struct netxen_adapter *adapter)
216 210
217 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 211 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
218 sds_ring = &recv_ctx->sds_rings[ring]; 212 sds_ring = &recv_ctx->sds_rings[ring];
219 netxen_nic_disable_int(sds_ring);
220 napi_disable(&sds_ring->napi); 213 napi_disable(&sds_ring->napi);
214 netxen_nic_disable_int(sds_ring);
215 synchronize_irq(sds_ring->irq);
221 } 216 }
222} 217}
223 218
@@ -407,11 +402,11 @@ static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
407 } 402 }
408} 403}
409 404
410static void netxen_init_msix_entries(struct netxen_adapter *adapter) 405static void netxen_init_msix_entries(struct netxen_adapter *adapter, int count)
411{ 406{
412 int i; 407 int i;
413 408
414 for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++) 409 for (i = 0; i < count; i++)
415 adapter->msix_entries[i].entry = i; 410 adapter->msix_entries[i].entry = i;
416} 411}
417 412
@@ -496,6 +491,15 @@ netxen_setup_intr(struct netxen_adapter *adapter)
496{ 491{
497 struct netxen_legacy_intr_set *legacy_intrp; 492 struct netxen_legacy_intr_set *legacy_intrp;
498 struct pci_dev *pdev = adapter->pdev; 493 struct pci_dev *pdev = adapter->pdev;
494 int err, num_msix;
495
496 if (adapter->rss_supported) {
497 num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
498 MSIX_ENTRIES_PER_ADAPTER : 2;
499 } else
500 num_msix = 1;
501
502 adapter->max_sds_rings = 1;
499 503
500 adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED); 504 adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
501 505
@@ -512,26 +516,35 @@ netxen_setup_intr(struct netxen_adapter *adapter)
512 516
513 if (adapter->msix_supported) { 517 if (adapter->msix_supported) {
514 518
515 netxen_init_msix_entries(adapter); 519 netxen_init_msix_entries(adapter, num_msix);
516 if (pci_enable_msix(pdev, adapter->msix_entries, 520 err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
517 MSIX_ENTRIES_PER_ADAPTER)) 521 if (err == 0) {
518 goto request_msi; 522 adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
523 netxen_set_msix_bit(pdev, 1);
519 524
520 adapter->flags |= NETXEN_NIC_MSIX_ENABLED; 525 if (adapter->rss_supported)
521 netxen_set_msix_bit(pdev, 1); 526 adapter->max_sds_rings = num_msix;
522 dev_info(&pdev->dev, "using msi-x interrupts\n");
523 527
524 } else { 528 dev_info(&pdev->dev, "using msi-x interrupts\n");
525request_msi: 529 return;
526 if (use_msi && !pci_enable_msi(pdev)) { 530 }
527 adapter->flags |= NETXEN_NIC_MSI_ENABLED; 531
528 adapter->msi_tgt_status = 532 if (err > 0)
529 msi_tgt_status[adapter->ahw.pci_func]; 533 pci_disable_msix(pdev);
530 dev_info(&pdev->dev, "using msi interrupts\n"); 534
531 } else 535 /* fall through for msi */
532 dev_info(&pdev->dev, "using legacy interrupts\n");
533 adapter->msix_entries[0].vector = pdev->irq;
534 } 536 }
537
538 if (use_msi && !pci_enable_msi(pdev)) {
539 adapter->flags |= NETXEN_NIC_MSI_ENABLED;
540 adapter->msi_tgt_status =
541 msi_tgt_status[adapter->ahw.pci_func];
542 dev_info(&pdev->dev, "using msi interrupts\n");
543 return;
544 }
545
546 dev_info(&pdev->dev, "using legacy interrupts\n");
547 adapter->msix_entries[0].vector = pdev->irq;
535} 548}
536 549
537static void 550static void
@@ -767,7 +780,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
767 780
768 for (ring = 0; ring < adapter->max_sds_rings; ring++) { 781 for (ring = 0; ring < adapter->max_sds_rings; ring++) {
769 sds_ring = &recv_ctx->sds_rings[ring]; 782 sds_ring = &recv_ctx->sds_rings[ring];
770 sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring); 783 sprintf(sds_ring->name, "%s[%d]", netdev->name, ring);
771 err = request_irq(sds_ring->irq, handler, 784 err = request_irq(sds_ring->irq, handler,
772 flags, sds_ring->name, sds_ring); 785 flags, sds_ring->name, sds_ring);
773 if (err) 786 if (err)
@@ -830,8 +843,6 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
830{ 843{
831 netif_carrier_off(netdev); 844 netif_carrier_off(netdev);
832 netif_stop_queue(netdev); 845 netif_stop_queue(netdev);
833 smp_mb();
834 netxen_napi_disable(adapter);
835 846
836 if (adapter->stop_port) 847 if (adapter->stop_port)
837 adapter->stop_port(adapter); 848 adapter->stop_port(adapter);
@@ -839,6 +850,8 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
839 if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) 850 if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
840 netxen_p3_free_mac_list(adapter); 851 netxen_p3_free_mac_list(adapter);
841 852
853 netxen_napi_disable(adapter);
854
842 netxen_release_tx_buffers(adapter); 855 netxen_release_tx_buffers(adapter);
843 856
844 FLUSH_SCHEDULED_WORK(); 857 FLUSH_SCHEDULED_WORK();
@@ -917,10 +930,9 @@ err_out_free_sw:
917static void 930static void
918netxen_nic_detach(struct netxen_adapter *adapter) 931netxen_nic_detach(struct netxen_adapter *adapter)
919{ 932{
920 netxen_nic_free_irq(adapter);
921
922 netxen_release_rx_buffers(adapter); 933 netxen_release_rx_buffers(adapter);
923 netxen_free_hw_resources(adapter); 934 netxen_free_hw_resources(adapter);
935 netxen_nic_free_irq(adapter);
924 netxen_free_sw_resources(adapter); 936 netxen_free_sw_resources(adapter);
925 937
926 adapter->is_up = 0; 938 adapter->is_up = 0;