diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 26fc1df2b2e0..2d0f618b4a9d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -226,6 +226,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, | |||
226 | /* tx_buffer_info must be completely set up in the transmit path */ | 226 | /* tx_buffer_info must be completely set up in the transmit path */ |
227 | } | 227 | } |
228 | 228 | ||
229 | /** | ||
230 | * ixgbe_tx_is_paused - check if the tx ring is paused | ||
231 | * @adapter: the ixgbe adapter | ||
232 | * @tx_ring: the corresponding tx_ring | ||
233 | * | ||
234 | * If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the | ||
235 | * corresponding TC of this tx_ring when checking TFCS. | ||
236 | * | ||
237 | * Returns : true if paused | ||
238 | */ | ||
239 | static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, | ||
240 | struct ixgbe_ring *tx_ring) | ||
241 | { | ||
242 | int tc; | ||
243 | u32 txoff = IXGBE_TFCS_TXOFF; | ||
244 | |||
245 | #ifdef CONFIG_IXGBE_DCB | ||
246 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | ||
247 | int reg_idx = tx_ring->reg_idx; | ||
248 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; | ||
249 | |||
250 | if (adapter->hw.mac.type == ixgbe_mac_82598EB) { | ||
251 | tc = reg_idx >> 2; | ||
252 | txoff = IXGBE_TFCS_TXOFF0; | ||
253 | } else if (adapter->hw.mac.type == ixgbe_mac_82599EB) { | ||
254 | tc = 0; | ||
255 | txoff = IXGBE_TFCS_TXOFF; | ||
256 | if (dcb_i == 8) { | ||
257 | /* TC0, TC1 */ | ||
258 | tc = reg_idx >> 5; | ||
259 | if (tc == 2) /* TC2, TC3 */ | ||
260 | tc += (reg_idx - 64) >> 4; | ||
261 | else if (tc == 3) /* TC4, TC5, TC6, TC7 */ | ||
262 | tc += 1 + ((reg_idx - 96) >> 3); | ||
263 | } else if (dcb_i == 4) { | ||
264 | /* TC0, TC1 */ | ||
265 | tc = reg_idx >> 6; | ||
266 | if (tc == 1) { | ||
267 | tc += (reg_idx - 64) >> 5; | ||
268 | if (tc == 2) /* TC2, TC3 */ | ||
269 | tc += (reg_idx - 96) >> 4; | ||
270 | } | ||
271 | } | ||
272 | } | ||
273 | txoff <<= tc; | ||
274 | } | ||
275 | #endif | ||
276 | return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff; | ||
277 | } | ||
278 | |||
229 | static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, | 279 | static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, |
230 | struct ixgbe_ring *tx_ring, | 280 | struct ixgbe_ring *tx_ring, |
231 | unsigned int eop) | 281 | unsigned int eop) |
@@ -237,7 +287,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, | |||
237 | adapter->detect_tx_hung = false; | 287 | adapter->detect_tx_hung = false; |
238 | if (tx_ring->tx_buffer_info[eop].time_stamp && | 288 | if (tx_ring->tx_buffer_info[eop].time_stamp && |
239 | time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && | 289 | time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) && |
240 | !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) { | 290 | !ixgbe_tx_is_paused(adapter, tx_ring)) { |
241 | /* detected Tx unit hang */ | 291 | /* detected Tx unit hang */ |
242 | union ixgbe_adv_tx_desc *tx_desc; | 292 | union ixgbe_adv_tx_desc *tx_desc; |
243 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); | 293 | tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop); |