ixgbe: Fix checking TFCS register for TXOFF status when DCB is enabled
When DCB is enabled, the ixgbe_check_tx_hang() should check the corresponding TC's TXOFF in TFCS based on the TC that the tx ring belongs to. Adds a function to map from the tx_ring hw reg_idx to the correspodning TC and read TFCS accordingly. Signed-off-by: Yi Zou <yi.zou@intel.com> Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b352e40da8
commit
26f23d82dd
|
@ -226,6 +226,56 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
|
||||||
/* tx_buffer_info must be completely set up in the transmit path */
|
/* tx_buffer_info must be completely set up in the transmit path */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ixgbe_tx_is_paused - check if the tx ring is paused
|
||||||
|
* @adapter: the ixgbe adapter
|
||||||
|
* @tx_ring: the corresponding tx_ring
|
||||||
|
*
|
||||||
|
* If not in DCB mode, checks TFCS.TXOFF, otherwise, find out the
|
||||||
|
* corresponding TC of this tx_ring when checking TFCS.
|
||||||
|
*
|
||||||
|
* Returns : true if paused
|
||||||
|
*/
|
||||||
|
static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter,
|
||||||
|
struct ixgbe_ring *tx_ring)
|
||||||
|
{
|
||||||
|
int tc;
|
||||||
|
u32 txoff = IXGBE_TFCS_TXOFF;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IXGBE_DCB
|
||||||
|
if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
|
||||||
|
int reg_idx = tx_ring->reg_idx;
|
||||||
|
int dcb_i = adapter->ring_feature[RING_F_DCB].indices;
|
||||||
|
|
||||||
|
if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
|
||||||
|
tc = reg_idx >> 2;
|
||||||
|
txoff = IXGBE_TFCS_TXOFF0;
|
||||||
|
} else if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
|
||||||
|
tc = 0;
|
||||||
|
txoff = IXGBE_TFCS_TXOFF;
|
||||||
|
if (dcb_i == 8) {
|
||||||
|
/* TC0, TC1 */
|
||||||
|
tc = reg_idx >> 5;
|
||||||
|
if (tc == 2) /* TC2, TC3 */
|
||||||
|
tc += (reg_idx - 64) >> 4;
|
||||||
|
else if (tc == 3) /* TC4, TC5, TC6, TC7 */
|
||||||
|
tc += 1 + ((reg_idx - 96) >> 3);
|
||||||
|
} else if (dcb_i == 4) {
|
||||||
|
/* TC0, TC1 */
|
||||||
|
tc = reg_idx >> 6;
|
||||||
|
if (tc == 1) {
|
||||||
|
tc += (reg_idx - 64) >> 5;
|
||||||
|
if (tc == 2) /* TC2, TC3 */
|
||||||
|
tc += (reg_idx - 96) >> 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
txoff <<= tc;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & txoff;
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
||||||
struct ixgbe_ring *tx_ring,
|
struct ixgbe_ring *tx_ring,
|
||||||
unsigned int eop)
|
unsigned int eop)
|
||||||
|
@ -237,7 +287,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
||||||
adapter->detect_tx_hung = false;
|
adapter->detect_tx_hung = false;
|
||||||
if (tx_ring->tx_buffer_info[eop].time_stamp &&
|
if (tx_ring->tx_buffer_info[eop].time_stamp &&
|
||||||
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
|
time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
|
||||||
!(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
|
!ixgbe_tx_is_paused(adapter, tx_ring)) {
|
||||||
/* detected Tx unit hang */
|
/* detected Tx unit hang */
|
||||||
union ixgbe_adv_tx_desc *tx_desc;
|
union ixgbe_adv_tx_desc *tx_desc;
|
||||||
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
|
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
|
||||||
|
|
Loading…
Reference in New Issue