summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
diff options
context:
space:
mode:
authorJacob Keller <jacob.e.keller@intel.com>2016-06-07 16:08:47 -0700
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2016-07-20 15:22:11 -0700
commitce33624f37f43267e5fa0810a058807d268142fb (patch)
tree1382fc9c3ec31070a38890550d10a41574e3773a /drivers/net/ethernet/intel/fm10k/fm10k_pf.c
parent5e93cbadd3e9db342e48582178b7d241097f51c4 (diff)
downloadlinux-ce33624f37f43267e5fa0810a058807d268142fb.tar.gz
linux-ce33624f37f43267e5fa0810a058807d268142fb.tar.bz2
linux-ce33624f37f43267e5fa0810a058807d268142fb.zip
fm10k: don't stop reset due to FM10K_ERR_REQUESTS_PENDING
Don't report FM10K_ERR_REQUESTS_PENDING when we fail to disable queues within the timeout. This can occur due to a hardware Tx hang, or when the switch ethernet fabric is resetting while we are transmitting traffic. It can sometimes take up to 500ms before the Tx DMA engine gives up. Instead, just skip the DMA engine check and perform a data-path reset anyways. Add a statistic counter to keep track of the number of resets occurring while we have pending DMA on the rings. In order to prevent having to re-assign err to 0, re-order the last few items of the reset_hw_pf function so that we don't perform "return err" at the end. Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Tested-by: Krishneil Singh <Krishneil.k.singh@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/fm10k/fm10k_pf.c')
-rw-r--r--drivers/net/ethernet/intel/fm10k/fm10k_pf.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
index 69e2c822db00..7fbd94ba6745 100644
--- a/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
+++ b/drivers/net/ethernet/intel/fm10k/fm10k_pf.c
@@ -51,8 +51,12 @@ static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
/* shut down all rings */
err = fm10k_disable_queues_generic(hw, FM10K_MAX_QUEUES);
- if (err)
+ if (err == FM10K_ERR_REQUESTS_PENDING) {
+ hw->mac.reset_while_pending++;
+ goto force_reset;
+ } else if (err) {
return err;
+ }
/* Verify that DMA is no longer active */
reg = fm10k_read_reg(hw, FM10K_DMA_CTRL);
@@ -62,27 +66,27 @@ static s32 fm10k_reset_hw_pf(struct fm10k_hw *hw)
/* verify the switch is ready for reset */
reg = fm10k_read_reg(hw, FM10K_DMA_CTRL2);
if (!(reg & FM10K_DMA_CTRL2_SWITCH_READY))
- goto out;
+ return FM10K_ERR_DMA_PENDING;
+force_reset:
/* Inititate data path reset */
- reg |= FM10K_DMA_CTRL_DATAPATH_RESET;
+ reg = FM10K_DMA_CTRL_DATAPATH_RESET;
fm10k_write_reg(hw, FM10K_DMA_CTRL, reg);
/* Flush write and allow 100us for reset to complete */
fm10k_write_flush(hw);
udelay(FM10K_RESET_TIMEOUT);
- /* Verify we made it out of reset */
- reg = fm10k_read_reg(hw, FM10K_IP);
- if (!(reg & FM10K_IP_NOTINRESET))
- err = FM10K_ERR_RESET_FAILED;
-
/* Reset mailbox global interrupts */
reg = FM10K_MBX_GLOBAL_REQ_INTERRUPT | FM10K_MBX_GLOBAL_ACK_INTERRUPT;
fm10k_write_reg(hw, FM10K_GMBX, reg);
-out:
- return err;
+ /* Verify we made it out of reset */
+ reg = fm10k_read_reg(hw, FM10K_IP);
+ if (!(reg & FM10K_IP_NOTINRESET))
+ return FM10K_ERR_RESET_FAILED;
+
+ return 0;
}
/**