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 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
struct ixgbe_ring *tx_ring,
|
||||
unsigned int eop)
|
||||
|
@ -237,7 +287,7 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
|
|||
adapter->detect_tx_hung = false;
|
||||
if (tx_ring->tx_buffer_info[eop].time_stamp &&
|
||||
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 */
|
||||
union ixgbe_adv_tx_desc *tx_desc;
|
||||
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
|
||||
|
|
Loading…
Reference in a new issue