|
@@ -454,8 +454,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
|
|
|
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
|
|
|
* access and verify no pending requests
|
|
|
*/
|
|
|
- if (ixgbe_disable_pcie_master(hw) != 0)
|
|
|
- hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
|
|
|
+ ixgbe_disable_pcie_master(hw);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2161,10 +2160,16 @@ out:
|
|
|
**/
|
|
|
s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
|
|
|
{
|
|
|
+ struct ixgbe_adapter *adapter = hw->back;
|
|
|
u32 i;
|
|
|
u32 reg_val;
|
|
|
u32 number_of_queues;
|
|
|
- s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
|
|
+ s32 status = 0;
|
|
|
+ u16 dev_status = 0;
|
|
|
+
|
|
|
+ /* Just jump out if bus mastering is already disabled */
|
|
|
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
|
|
|
+ goto out;
|
|
|
|
|
|
/* Disable the receive unit by stopping each queue */
|
|
|
number_of_queues = hw->mac.max_rx_queues;
|
|
@@ -2181,13 +2186,43 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
|
|
|
IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
|
|
|
|
|
|
for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
|
|
|
- if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
|
|
|
- status = 0;
|
|
|
+ if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
|
|
|
+ goto check_device_status;
|
|
|
+ udelay(100);
|
|
|
+ }
|
|
|
+
|
|
|
+ hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
|
|
|
+ status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Before proceeding, make sure that the PCIe block does not have
|
|
|
+ * transactions pending.
|
|
|
+ */
|
|
|
+check_device_status:
|
|
|
+ for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
|
|
|
+ pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS,
|
|
|
+ &dev_status);
|
|
|
+ if (!(dev_status & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
|
|
|
break;
|
|
|
- }
|
|
|
udelay(100);
|
|
|
}
|
|
|
|
|
|
+ if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT)
|
|
|
+ hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n");
|
|
|
+ else
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Two consecutive resets are required via CTRL.RST per datasheet
|
|
|
+ * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine
|
|
|
+ * of this need. The first reset prevents new master requests from
|
|
|
+ * being issued by our device. We then must wait 1usec for any
|
|
|
+ * remaining completions from the PCIe bus to trickle in, and then reset
|
|
|
+ * again to clear out any effects they may have had on our device.
|
|
|
+ */
|
|
|
+ hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
|
|
|
+
|
|
|
+out:
|
|
|
return status;
|
|
|
}
|
|
|
|