diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2010-08-02 10:27:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-03 00:20:21 -0400 |
commit | 8e86acd7d5968e08b3e1604e685a8c45f6fd7f40 (patch) | |
tree | f870dc8370e6b23022c0914e4899dfd345b42ee9 /drivers/net/e1000e | |
parent | c128ec29208d410568469bd8bb373b4cdc10912a (diff) |
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>
Diffstat (limited to 'drivers/net/e1000e')
-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 9ee133f5034e..f9a31c82f871 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -348,6 +348,7 @@ struct e1000_adapter { | |||
348 | u32 test_icr; | 348 | u32 test_icr; |
349 | 349 | ||
350 | u32 msg_enable; | 350 | u32 msg_enable; |
351 | unsigned int num_vectors; | ||
351 | struct msix_entry *msix_entries; | 352 | struct msix_entry *msix_entries; |
352 | int int_mode; | 353 | int int_mode; |
353 | u32 eiac_mask; | 354 | u32 eiac_mask; |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 464c9a28f1ba..9e9164a9d489 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) | |||
1785 | void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) | 1785 | void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) |
1786 | { | 1786 | { |
1787 | int err; | 1787 | int err; |
1788 | int numvecs, i; | 1788 | int i; |
1789 | |||
1790 | 1789 | ||
1791 | switch (adapter->int_mode) { | 1790 | switch (adapter->int_mode) { |
1792 | case E1000E_INT_MODE_MSIX: | 1791 | case E1000E_INT_MODE_MSIX: |
1793 | if (adapter->flags & FLAG_HAS_MSIX) { | 1792 | if (adapter->flags & FLAG_HAS_MSIX) { |
1794 | numvecs = 3; /* RxQ0, TxQ0 and other */ | 1793 | adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */ |
1795 | adapter->msix_entries = kcalloc(numvecs, | 1794 | adapter->msix_entries = kcalloc(adapter->num_vectors, |
1796 | sizeof(struct msix_entry), | 1795 | sizeof(struct msix_entry), |
1797 | GFP_KERNEL); | 1796 | GFP_KERNEL); |
1798 | if (adapter->msix_entries) { | 1797 | if (adapter->msix_entries) { |
1799 | for (i = 0; i < numvecs; i++) | 1798 | for (i = 0; i < adapter->num_vectors; i++) |
1800 | adapter->msix_entries[i].entry = i; | 1799 | adapter->msix_entries[i].entry = i; |
1801 | 1800 | ||
1802 | err = pci_enable_msix(adapter->pdev, | 1801 | err = pci_enable_msix(adapter->pdev, |
1803 | adapter->msix_entries, | 1802 | adapter->msix_entries, |
1804 | numvecs); | 1803 | adapter->num_vectors); |
1805 | if (err == 0) | 1804 | if (err == 0) { |
1806 | return; | 1805 | return; |
1806 | } | ||
1807 | } | 1807 | } |
1808 | /* MSI-X failed, so fall through and try MSI */ | 1808 | /* MSI-X failed, so fall through and try MSI */ |
1809 | e_err("Failed to initialize MSI-X interrupts. " | 1809 | e_err("Failed to initialize MSI-X interrupts. " |
@@ -1825,6 +1825,9 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter) | |||
1825 | /* Don't do anything; this is the system default */ | 1825 | /* Don't do anything; this is the system default */ |
1826 | break; | 1826 | break; |
1827 | } | 1827 | } |
1828 | |||
1829 | /* store the number of vectors being used */ | ||
1830 | adapter->num_vectors = 1; | ||
1828 | } | 1831 | } |
1829 | 1832 | ||
1830 | /** | 1833 | /** |
@@ -1946,7 +1949,14 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) | |||
1946 | if (adapter->msix_entries) | 1949 | if (adapter->msix_entries) |
1947 | ew32(EIAC_82574, 0); | 1950 | ew32(EIAC_82574, 0); |
1948 | e1e_flush(); | 1951 | e1e_flush(); |
1949 | synchronize_irq(adapter->pdev->irq); | 1952 | |
1953 | if (adapter->msix_entries) { | ||
1954 | int i; | ||
1955 | for (i = 0; i < adapter->num_vectors; i++) | ||
1956 | synchronize_irq(adapter->msix_entries[i].vector); | ||
1957 | } else { | ||
1958 | synchronize_irq(adapter->pdev->irq); | ||
1959 | } | ||
1950 | } | 1960 | } |
1951 | 1961 | ||
1952 | /** | 1962 | /** |