Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 237559
b: refs/heads/master
c: a4297dc
h: refs/heads/master
i:
  237557: 55e174a
  237555: 7307ae0
  237551: 5e211e5
v: v3
  • Loading branch information
Emil Tantilov authored and Jeff Kirsher committed Mar 3, 2011
1 parent ed9df22 commit 6d0c5b7
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 21cc5b4f7eb7b6de90588331b7d0edb246502f46
refs/heads/master: a4297dc2f49d46d5452a948210be44442236e685
21 changes: 15 additions & 6 deletions trunk/drivers/net/ixgbe/ixgbe_82598.c
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,6 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
goto no_phy_reset;


hw->phy.ops.reset(hw);
}

Expand All @@ -779,12 +778,9 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
status = ixgbe_disable_pcie_master(hw);
if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
ixgbe_disable_pcie_master(hw);

mac_reset_top:
/*
* Issue global reset to the MAC. This needs to be a SW reset.
* If link reset is used, it might reset the MAC when mng is using it
Expand All @@ -805,6 +801,19 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
hw_dbg(hw, "Reset polling failed to complete.\n");
}

/*
* Double resets are required for recovery from certain error
* conditions. Between resets, it is necessary to stall to allow time
* for any pending HW events to complete. We use 1usec since that is
* what is needed for ixgbe_disable_pcie_master(). The second reset
* then clears out any effects of those events.
*/
if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
udelay(1);
goto mac_reset_top;
}

msleep(50);

gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR);
Expand Down
20 changes: 15 additions & 5 deletions trunk/drivers/net/ixgbe/ixgbe_82599.c
Original file line number Diff line number Diff line change
Expand Up @@ -904,12 +904,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
status = ixgbe_disable_pcie_master(hw);
if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
ixgbe_disable_pcie_master(hw);

mac_reset_top:
/*
* Issue global reset to the MAC. This needs to be a SW reset.
* If link reset is used, it might reset the MAC when mng is using it
Expand All @@ -930,6 +927,19 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
hw_dbg(hw, "Reset polling failed to complete.\n");
}

/*
* Double resets are required for recovery from certain error
* conditions. Between resets, it is necessary to stall to allow time
* for any pending HW events to complete. We use 1usec since that is
* what is needed for ixgbe_disable_pcie_master(). The second reset
* then clears out any effects of those events.
*/
if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
udelay(1);
goto mac_reset_top;
}

msleep(50);

/*
Expand Down
47 changes: 41 additions & 6 deletions trunk/drivers/net/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -2161,10 +2160,16 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
**/
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;
Expand All @@ -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;
}

Expand Down
4 changes: 4 additions & 0 deletions trunk/drivers/net/ixgbe/ixgbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -1614,6 +1614,8 @@
#define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */

/* PCI Bus Info */
#define IXGBE_PCI_DEVICE_STATUS 0xAA
#define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020
#define IXGBE_PCI_LINK_STATUS 0xB2
#define IXGBE_PCI_DEVICE_CONTROL2 0xC8
#define IXGBE_PCI_LINK_WIDTH 0x3F0
Expand Down Expand Up @@ -2557,6 +2559,7 @@ struct ixgbe_eeprom_info {
u16 address_bits;
};

#define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01
struct ixgbe_mac_info {
struct ixgbe_mac_operations ops;
enum ixgbe_mac_type type;
Expand All @@ -2579,6 +2582,7 @@ struct ixgbe_mac_info {
u32 orig_autoc2;
bool orig_link_settings_stored;
bool autotry_restart;
u8 flags;
};

struct ixgbe_phy_info {
Expand Down
20 changes: 15 additions & 5 deletions trunk/drivers/net/ixgbe/ixgbe_x540.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,9 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
* Prevent the PCI-E bus from from hanging by disabling PCI-E master
* access and verify no pending requests before reset
*/
status = ixgbe_disable_pcie_master(hw);
if (status != 0) {
status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
}
ixgbe_disable_pcie_master(hw);

mac_reset_top:
/*
* Issue global reset to the MAC. Needs to be SW reset if link is up.
* If link reset is used when link is up, it might reset the PHY when
Expand Down Expand Up @@ -148,6 +145,19 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw)
hw_dbg(hw, "Reset polling failed to complete.\n");
}

/*
* Double resets are required for recovery from certain error
* conditions. Between resets, it is necessary to stall to allow time
* for any pending HW events to complete. We use 1usec since that is
* what is needed for ixgbe_disable_pcie_master(). The second reset
* then clears out any effects of those events.
*/
if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) {
hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED;
udelay(1);
goto mac_reset_top;
}

/* Clear PF Reset Done bit so PF/VF Mail Ops can work */
ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD;
Expand Down

0 comments on commit 6d0c5b7

Please sign in to comment.