diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2010-08-02 14:27:23 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-02 21:20:21 -0700 |
commit | 8e86acd7d5968e08b3e1604e685a8c45f6fd7f40 (patch) | |
tree | f870dc8370e6b23022c0914e4899dfd345b42ee9 | |
parent | c128ec29208d410568469bd8bb373b4cdc10912a (diff) | |
download | kernel_samsung_smdk4412-8e86acd7d5968e08b3e1604e685a8c45f6fd7f40.zip kernel_samsung_smdk4412-8e86acd7d5968e08b3e1604e685a8c45f6fd7f40.tar.gz kernel_samsung_smdk4412-8e86acd7d5968e08b3e1604e685a8c45f6fd7f40.tar.bz2 |
e1000e: Fix irq_synchronize in MSI-X case
Based on original patch/work from Jean Delvare <jdelvare@suse.de>
Synchronize all IRQs when in MSI-X IRQ mode.
Jean's original patch hard coded the sync with the 3 possible vectors,
this patch incorporates more flexibility for the future and aligns
with how igb stores the number of vectors into the adapter structure.
CC: Jean Delvare <jdelvare@suse.de>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Acked-by: Bruce Allan <bruce.w.allan@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/e1000e/e1000.h | 1 | ||||
-rw-r--r-- | drivers/net/e1000e/netdev.c | 26 |
2 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 9ee133f..f9a31c8 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h @@ -348,6 +348,7 @@ struct e1000_adapter { u32 test_icr; u32 msg_enable; + unsigned int num_vectors; struct msix_entry *msix_entries; int int_mode; u32 eiac_mask; diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 464c9a2..9e9164a 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -1785,25 +1785,25 @@ void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter) void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) { int err; - int numvecs, i; - + int i; switch (adapter->int_mode) { case E1000E_INT_MODE_MSIX: if (adapter->flags & FLAG_HAS_MSIX) { - numvecs = 3; /* RxQ0, TxQ0 and other */ - adapter->msix_entries = kcalloc(numvecs, + adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */ + adapter->msix_entries = kcalloc(adapter->num_vectors, sizeof(struct msix_entry), GFP_KERNEL); if (adapter->msix_entries) { - for (i = 0; i < numvecs; i++) + for (i = 0; i < adapter->num_vectors; i++) adapter->msix_entries[i].entry = i; err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - numvecs); - if (err == 0) + adapter->num_vectors); + if (err == 0) { return; + } } /* MSI-X failed, so fall through and try MSI */ e_err("Failed to initialize MSI-X interrupts. " @@ -1825,6 +1825,9 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) /* Don't do anything; this is the system default */ break; } + + /* store the number of vectors being used */ + adapter->num_vectors = 1; } /** @@ -1946,7 +1949,14 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) if (adapter->msix_entries) ew32(EIAC_82574, 0); e1e_flush(); - synchronize_irq(adapter->pdev->irq); + + if (adapter->msix_entries) { + int i; + for (i = 0; i < adapter->num_vectors; i++) + synchronize_irq(adapter->msix_entries[i].vector); + } else { + synchronize_irq(adapter->pdev->irq); + } } /** |