aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c52
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 */
239static 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
229static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, 279static 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);