diff options
author | Emil Tantilov <emil.s.tantilov@intel.com> | 2010-09-29 17:35:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-09-30 20:59:30 -0400 |
commit | 6af3b9ebfea38d0a057fbd7bdcecc61ac5662f02 (patch) | |
tree | 0a5e19d0bc41dc9402c44b397d03c9397051d2cc /drivers | |
parent | dd28d1a0b5ecc0f5512f658b1a8fd38bc4f4c98c (diff) |
ixgbe: fix link issues and panic with shared interrupts for 82598
Fix possible panic/hang with shared Legacy interrupts by not enabling
interrupts when interface is down.
Also fixes an intermittent link by enabling LSC upon exit from ixgbe_intr()
This patch adds flags to ixgbe_irq_enable() to allow for some flexibility
when enabling interrupts.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index c35185cb27fe..c35e13c01dbe 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -2233,7 +2233,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) | |||
2233 | * ixgbe_irq_enable - Enable default interrupt generation settings | 2233 | * ixgbe_irq_enable - Enable default interrupt generation settings |
2234 | * @adapter: board private structure | 2234 | * @adapter: board private structure |
2235 | **/ | 2235 | **/ |
2236 | static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) | 2236 | static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter, bool queues, |
2237 | bool flush) | ||
2237 | { | 2238 | { |
2238 | u32 mask; | 2239 | u32 mask; |
2239 | 2240 | ||
@@ -2254,8 +2255,10 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter) | |||
2254 | mask |= IXGBE_EIMS_FLOW_DIR; | 2255 | mask |= IXGBE_EIMS_FLOW_DIR; |
2255 | 2256 | ||
2256 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); | 2257 | IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); |
2257 | ixgbe_irq_enable_queues(adapter, ~0); | 2258 | if (queues) |
2258 | IXGBE_WRITE_FLUSH(&adapter->hw); | 2259 | ixgbe_irq_enable_queues(adapter, ~0); |
2260 | if (flush) | ||
2261 | IXGBE_WRITE_FLUSH(&adapter->hw); | ||
2259 | 2262 | ||
2260 | if (adapter->num_vfs > 32) { | 2263 | if (adapter->num_vfs > 32) { |
2261 | u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1; | 2264 | u32 eitrsel = (1 << (adapter->num_vfs - 32)) - 1; |
@@ -2277,7 +2280,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
2277 | u32 eicr; | 2280 | u32 eicr; |
2278 | 2281 | ||
2279 | /* | 2282 | /* |
2280 | * Workaround for silicon errata. Mask the interrupts | 2283 | * Workaround for silicon errata on 82598. Mask the interrupts |
2281 | * before the read of EICR. | 2284 | * before the read of EICR. |
2282 | */ | 2285 | */ |
2283 | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); | 2286 | IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK); |
@@ -2286,10 +2289,15 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
2286 | * therefore no explict interrupt disable is necessary */ | 2289 | * therefore no explict interrupt disable is necessary */ |
2287 | eicr = IXGBE_READ_REG(hw, IXGBE_EICR); | 2290 | eicr = IXGBE_READ_REG(hw, IXGBE_EICR); |
2288 | if (!eicr) { | 2291 | if (!eicr) { |
2289 | /* shared interrupt alert! | 2292 | /* |
2293 | * shared interrupt alert! | ||
2290 | * make sure interrupts are enabled because the read will | 2294 | * make sure interrupts are enabled because the read will |
2291 | * have disabled interrupts due to EIAM */ | 2295 | * have disabled interrupts due to EIAM |
2292 | ixgbe_irq_enable(adapter); | 2296 | * finish the workaround of silicon errata on 82598. Unmask |
2297 | * the interrupt that we masked before the EICR read. | ||
2298 | */ | ||
2299 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
2300 | ixgbe_irq_enable(adapter, true, true); | ||
2293 | return IRQ_NONE; /* Not our interrupt */ | 2301 | return IRQ_NONE; /* Not our interrupt */ |
2294 | } | 2302 | } |
2295 | 2303 | ||
@@ -2313,6 +2321,14 @@ static irqreturn_t ixgbe_intr(int irq, void *data) | |||
2313 | __napi_schedule(&(q_vector->napi)); | 2321 | __napi_schedule(&(q_vector->napi)); |
2314 | } | 2322 | } |
2315 | 2323 | ||
2324 | /* | ||
2325 | * re-enable link(maybe) and non-queue interrupts, no flush. | ||
2326 | * ixgbe_poll will re-enable the queue interrupts | ||
2327 | */ | ||
2328 | |||
2329 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | ||
2330 | ixgbe_irq_enable(adapter, false, false); | ||
2331 | |||
2316 | return IRQ_HANDLED; | 2332 | return IRQ_HANDLED; |
2317 | } | 2333 | } |
2318 | 2334 | ||
@@ -3048,7 +3064,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
3048 | vlan_group_set_device(adapter->vlgrp, vid, NULL); | 3064 | vlan_group_set_device(adapter->vlgrp, vid, NULL); |
3049 | 3065 | ||
3050 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 3066 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
3051 | ixgbe_irq_enable(adapter); | 3067 | ixgbe_irq_enable(adapter, true, true); |
3052 | 3068 | ||
3053 | /* remove VID from filter table */ | 3069 | /* remove VID from filter table */ |
3054 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); | 3070 | hw->mac.ops.set_vfta(&adapter->hw, vid, pool_ndx, false); |
@@ -3145,7 +3161,7 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, | |||
3145 | ixgbe_vlan_rx_add_vid(netdev, 0); | 3161 | ixgbe_vlan_rx_add_vid(netdev, 0); |
3146 | 3162 | ||
3147 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) | 3163 | if (!test_bit(__IXGBE_DOWN, &adapter->state)) |
3148 | ixgbe_irq_enable(adapter); | 3164 | ixgbe_irq_enable(adapter, true, true); |
3149 | } | 3165 | } |
3150 | 3166 | ||
3151 | static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) | 3167 | static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) |
@@ -3546,7 +3562,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) | |||
3546 | 3562 | ||
3547 | /* clear any pending interrupts, may auto mask */ | 3563 | /* clear any pending interrupts, may auto mask */ |
3548 | IXGBE_READ_REG(hw, IXGBE_EICR); | 3564 | IXGBE_READ_REG(hw, IXGBE_EICR); |
3549 | ixgbe_irq_enable(adapter); | 3565 | ixgbe_irq_enable(adapter, true, true); |
3550 | 3566 | ||
3551 | /* | 3567 | /* |
3552 | * If this adapter has a fan, check to see if we had a failure | 3568 | * If this adapter has a fan, check to see if we had a failure |