aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_common.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c47
1 files changed, 41 insertions, 6 deletions
diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c
index 345c32eab4a5..6d87c7491d10 100644
--- a/drivers/net/ixgbe/ixgbe_common.c
+++ b/drivers/net/ixgbe/ixgbe_common.c
@@ -454,8 +454,7 @@ s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
454 * Prevent the PCI-E bus from from hanging by disabling PCI-E master 454 * Prevent the PCI-E bus from from hanging by disabling PCI-E master
455 * access and verify no pending requests 455 * access and verify no pending requests
456 */ 456 */
457 if (ixgbe_disable_pcie_master(hw) != 0) 457 ixgbe_disable_pcie_master(hw);
458 hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
459 458
460 return 0; 459 return 0;
461} 460}
@@ -2161,10 +2160,16 @@ out:
2161 **/ 2160 **/
2162s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) 2161s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
2163{ 2162{
2163 struct ixgbe_adapter *adapter = hw->back;
2164 u32 i; 2164 u32 i;
2165 u32 reg_val; 2165 u32 reg_val;
2166 u32 number_of_queues; 2166 u32 number_of_queues;
2167 s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING; 2167 s32 status = 0;
2168 u16 dev_status = 0;
2169
2170 /* Just jump out if bus mastering is already disabled */
2171 if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
2172 goto out;
2168 2173
2169 /* Disable the receive unit by stopping each queue */ 2174 /* Disable the receive unit by stopping each queue */
2170 number_of_queues = hw->mac.max_rx_queues; 2175 number_of_queues = hw->mac.max_rx_queues;
@@ -2181,13 +2186,43 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
2181 IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); 2186 IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
2182 2187
2183 for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { 2188 for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
2184 if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) { 2189 if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO))
2185 status = 0; 2190 goto check_device_status;
2191 udelay(100);
2192 }
2193
2194 hw_dbg(hw, "GIO Master Disable bit didn't clear - requesting resets\n");
2195 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
2196
2197 /*
2198 * Before proceeding, make sure that the PCIe block does not have
2199 * transactions pending.
2200 */
2201check_device_status:
2202 for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
2203 pci_read_config_word(adapter->pdev, IXGBE_PCI_DEVICE_STATUS,
2204 &dev_status);
2205 if (!(dev_status & IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING))
2186 break; 2206 break;
2187 }
2188 udelay(100); 2207 udelay(100);
2189 } 2208 }
2190 2209
2210 if (i == IXGBE_PCI_MASTER_DISABLE_TIMEOUT)
2211 hw_dbg(hw, "PCIe transaction pending bit also did not clear.\n");
2212 else
2213 goto out;
2214
2215 /*
2216 * Two consecutive resets are required via CTRL.RST per datasheet
2217 * 5.2.5.3.2 Master Disable. We set a flag to inform the reset routine
2218 * of this need. The first reset prevents new master requests from
2219 * being issued by our device. We then must wait 1usec for any
2220 * remaining completions from the PCIe bus to trickle in, and then reset
2221 * again to clear out any effects they may have had on our device.
2222 */
2223 hw->mac.flags |= IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
2224
2225out:
2191 return status; 2226 return status;
2192} 2227}
2193 2228