|
@@ -3583,7 +3583,8 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
|
|
**/
|
|
**/
|
|
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
|
|
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
|
|
{
|
|
{
|
|
- u32 gcr_ext, hlreg0;
|
|
|
|
|
|
+ u32 gcr_ext, hlreg0, i, poll;
|
|
|
|
+ u16 value;
|
|
|
|
|
|
/*
|
|
/*
|
|
* If double reset is not requested then all transactions should
|
|
* If double reset is not requested then all transactions should
|
|
@@ -3600,6 +3601,23 @@ void ixgbe_clear_tx_pending(struct ixgbe_hw *hw)
|
|
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
|
|
hlreg0 = IXGBE_READ_REG(hw, IXGBE_HLREG0);
|
|
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK);
|
|
IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0 | IXGBE_HLREG0_LPBK);
|
|
|
|
|
|
|
|
+ /* wait for a last completion before clearing buffers */
|
|
|
|
+ IXGBE_WRITE_FLUSH(hw);
|
|
|
|
+ usleep_range(3000, 6000);
|
|
|
|
+
|
|
|
|
+ /* Before proceeding, make sure that the PCIe block does not have
|
|
|
|
+ * transactions pending.
|
|
|
|
+ */
|
|
|
|
+ poll = ixgbe_pcie_timeout_poll(hw);
|
|
|
|
+ for (i = 0; i < poll; i++) {
|
|
|
|
+ usleep_range(100, 200);
|
|
|
|
+ value = ixgbe_read_pci_cfg_word(hw, IXGBE_PCI_DEVICE_STATUS);
|
|
|
|
+ if (ixgbe_removed(hw->hw_addr))
|
|
|
|
+ break;
|
|
|
|
+ if (!(value & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* initiate cleaning flow for buffers in the PCIe transaction layer */
|
|
/* initiate cleaning flow for buffers in the PCIe transaction layer */
|
|
gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
|
|
gcr_ext = IXGBE_READ_REG(hw, IXGBE_GCR_EXT);
|
|
IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
|
|
IXGBE_WRITE_REG(hw, IXGBE_GCR_EXT,
|