aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/e1000e
diff options
context:
space:
mode:
authorBenjamin Poirier <bpoirier@suse.com>2015-11-09 18:50:19 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2015-12-14 22:36:13 -0500
commit16ecba59bc333d6282ee057fb02339f77a880beb (patch)
treeb0a4368ef63eaaa823ce67d13e8c5bdc8fcd6e4a /drivers/net/ethernet/intel/e1000e
parent4d432f67ff004dc387ba307d418d0eae4fa9dc13 (diff)
e1000e: Do not read ICR in Other interrupt
Removes the ICR read in the other interrupt handler, uses EIAC to autoclear the Other bit from ICR and IMS. This allows us to avoid interference with Rx and Tx interrupts in the Other interrupt handler. The information read from ICR is not needed. IMS is configured such that the only interrupt cause that can trigger the Other interrupt is Link Status Change. Signed-off-by: Benjamin Poirier <bpoirier@suse.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/e1000e')
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c22
1 files changed, 7 insertions, 15 deletions
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index 26cf1833b86d..56bc422dc831 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -1905,24 +1905,15 @@ static irqreturn_t e1000_msix_other(int __always_unused irq, void *data)
1905 struct net_device *netdev = data; 1905 struct net_device *netdev = data;
1906 struct e1000_adapter *adapter = netdev_priv(netdev); 1906 struct e1000_adapter *adapter = netdev_priv(netdev);
1907 struct e1000_hw *hw = &adapter->hw; 1907 struct e1000_hw *hw = &adapter->hw;
1908 u32 icr = er32(ICR);
1909 1908
1910 if (icr & adapter->eiac_mask) 1909 hw->mac.get_link_status = true;
1911 ew32(ICS, (icr & adapter->eiac_mask));
1912 1910
1913 if (icr & E1000_ICR_OTHER) { 1911 /* guard against interrupt when we're going down */
1914 if (!(icr & E1000_ICR_LSC)) 1912 if (!test_bit(__E1000_DOWN, &adapter->state)) {
1915 goto no_link_interrupt; 1913 mod_timer(&adapter->watchdog_timer, jiffies + 1);
1916 hw->mac.get_link_status = true; 1914 ew32(IMS, E1000_IMS_OTHER);
1917 /* guard against interrupt when we're going down */
1918 if (!test_bit(__E1000_DOWN, &adapter->state))
1919 mod_timer(&adapter->watchdog_timer, jiffies + 1);
1920 } 1915 }
1921 1916
1922no_link_interrupt:
1923 if (!test_bit(__E1000_DOWN, &adapter->state))
1924 ew32(IMS, E1000_IMS_LSC | E1000_IMS_OTHER);
1925
1926 return IRQ_HANDLED; 1917 return IRQ_HANDLED;
1927} 1918}
1928 1919
@@ -2021,6 +2012,7 @@ static void e1000_configure_msix(struct e1000_adapter *adapter)
2021 hw->hw_addr + E1000_EITR_82574(vector)); 2012 hw->hw_addr + E1000_EITR_82574(vector));
2022 else 2013 else
2023 writel(1, hw->hw_addr + E1000_EITR_82574(vector)); 2014 writel(1, hw->hw_addr + E1000_EITR_82574(vector));
2015 adapter->eiac_mask |= E1000_IMS_OTHER;
2024 2016
2025 /* Cause Tx interrupts on every write back */ 2017 /* Cause Tx interrupts on every write back */
2026 ivar |= (1 << 31); 2018 ivar |= (1 << 31);
@@ -2249,7 +2241,7 @@ static void e1000_irq_enable(struct e1000_adapter *adapter)
2249 2241
2250 if (adapter->msix_entries) { 2242 if (adapter->msix_entries) {
2251 ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574); 2243 ew32(EIAC_82574, adapter->eiac_mask & E1000_EIAC_MASK_82574);
2252 ew32(IMS, adapter->eiac_mask | E1000_IMS_OTHER | E1000_IMS_LSC); 2244 ew32(IMS, adapter->eiac_mask | E1000_IMS_LSC);
2253 } else if ((hw->mac.type == e1000_pch_lpt) || 2245 } else if ((hw->mac.type == e1000_pch_lpt) ||
2254 (hw->mac.type == e1000_pch_spt)) { 2246 (hw->mac.type == e1000_pch_spt)) {
2255 ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER); 2247 ew32(IMS, IMS_ENABLE_MASK | E1000_IMS_ECCER);