diff options
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 21 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82599.c | 20 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_common.c | 47 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 4 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_x540.c | 20 |
5 files changed, 90 insertions, 22 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index d0f1d9d2c416..291b1e6f85c9 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -770,7 +770,6 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) | |||
770 | else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) | 770 | else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT) |
771 | goto no_phy_reset; | 771 | goto no_phy_reset; |
772 | 772 | ||
773 | |||
774 | hw->phy.ops.reset(hw); | 773 | hw->phy.ops.reset(hw); |
775 | } | 774 | } |
776 | 775 | ||
@@ -779,12 +778,9 @@ no_phy_reset: | |||
779 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 778 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master |
780 | * access and verify no pending requests before reset | 779 | * access and verify no pending requests before reset |
781 | */ | 780 | */ |
782 | status = ixgbe_disable_pcie_master(hw); | 781 | ixgbe_disable_pcie_master(hw); |
783 | if (status != 0) { | ||
784 | status = IXGBE_ERR_MASTER_REQUESTS_PENDING; | ||
785 | hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); | ||
786 | } | ||
787 | 782 | ||
783 | mac_reset_top: | ||
788 | /* | 784 | /* |
789 | * Issue global reset to the MAC. This needs to be a SW reset. | 785 | * Issue global reset to the MAC. This needs to be a SW reset. |
790 | * If link reset is used, it might reset the MAC when mng is using it | 786 | * If link reset is used, it might reset the MAC when mng is using it |
@@ -805,6 +801,19 @@ no_phy_reset: | |||
805 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 801 | hw_dbg(hw, "Reset polling failed to complete.\n"); |
806 | } | 802 | } |
807 | 803 | ||
804 | /* | ||
805 | * Double resets are required for recovery from certain error | ||
806 | * conditions. Between resets, it is necessary to stall to allow time | ||
807 | * for any pending HW events to complete. We use 1usec since that is | ||
808 | * what is needed for ixgbe_disable_pcie_master(). The second reset | ||
809 | * then clears out any effects of those events. | ||
810 | */ | ||
811 | if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { | ||
812 | hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | ||
813 | udelay(1); | ||
814 | goto mac_reset_top; | ||
815 | } | ||
816 | |||
808 | msleep(50); | 817 | msleep(50); |
809 | 818 | ||
810 | gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); | 819 | gheccr = IXGBE_READ_REG(hw, IXGBE_GHECCR); |
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index b45a491ac2e1..126a06fa2a12 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c | |||
@@ -904,12 +904,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) | |||
904 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 904 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master |
905 | * access and verify no pending requests before reset | 905 | * access and verify no pending requests before reset |
906 | */ | 906 | */ |
907 | status = ixgbe_disable_pcie_master(hw); | 907 | ixgbe_disable_pcie_master(hw); |
908 | if (status != 0) { | ||
909 | status = IXGBE_ERR_MASTER_REQUESTS_PENDING; | ||
910 | hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); | ||
911 | } | ||
912 | 908 | ||
909 | mac_reset_top: | ||
913 | /* | 910 | /* |
914 | * Issue global reset to the MAC. This needs to be a SW reset. | 911 | * Issue global reset to the MAC. This needs to be a SW reset. |
915 | * If link reset is used, it might reset the MAC when mng is using it | 912 | * If link reset is used, it might reset the MAC when mng is using it |
@@ -930,6 +927,19 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) | |||
930 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 927 | hw_dbg(hw, "Reset polling failed to complete.\n"); |
931 | } | 928 | } |
932 | 929 | ||
930 | /* | ||
931 | * Double resets are required for recovery from certain error | ||
932 | * conditions. Between resets, it is necessary to stall to allow time | ||
933 | * for any pending HW events to complete. We use 1usec since that is | ||
934 | * what is needed for ixgbe_disable_pcie_master(). The second reset | ||
935 | * then clears out any effects of those events. | ||
936 | */ | ||
937 | if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { | ||
938 | hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | ||
939 | udelay(1); | ||
940 | goto mac_reset_top; | ||
941 | } | ||
942 | |||
933 | msleep(50); | 943 | msleep(50); |
934 | 944 | ||
935 | /* | 945 | /* |
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 | **/ |
2162 | s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) | 2161 | s32 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 | */ | ||
2201 | check_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 | |||
2225 | out: | ||
2191 | return status; | 2226 | return status; |
2192 | } | 2227 | } |
2193 | 2228 | ||
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index af5ad406ef12..5ede03c84a5e 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h | |||
@@ -1614,6 +1614,8 @@ | |||
1614 | #define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */ | 1614 | #define IXGBE_ALT_SAN_MAC_ADDR_CAPS_ALTWWN 0x1 /* Alt. WWN base exists */ |
1615 | 1615 | ||
1616 | /* PCI Bus Info */ | 1616 | /* PCI Bus Info */ |
1617 | #define IXGBE_PCI_DEVICE_STATUS 0xAA | ||
1618 | #define IXGBE_PCI_DEVICE_STATUS_TRANSACTION_PENDING 0x0020 | ||
1617 | #define IXGBE_PCI_LINK_STATUS 0xB2 | 1619 | #define IXGBE_PCI_LINK_STATUS 0xB2 |
1618 | #define IXGBE_PCI_DEVICE_CONTROL2 0xC8 | 1620 | #define IXGBE_PCI_DEVICE_CONTROL2 0xC8 |
1619 | #define IXGBE_PCI_LINK_WIDTH 0x3F0 | 1621 | #define IXGBE_PCI_LINK_WIDTH 0x3F0 |
@@ -2557,6 +2559,7 @@ struct ixgbe_eeprom_info { | |||
2557 | u16 address_bits; | 2559 | u16 address_bits; |
2558 | }; | 2560 | }; |
2559 | 2561 | ||
2562 | #define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED 0x01 | ||
2560 | struct ixgbe_mac_info { | 2563 | struct ixgbe_mac_info { |
2561 | struct ixgbe_mac_operations ops; | 2564 | struct ixgbe_mac_operations ops; |
2562 | enum ixgbe_mac_type type; | 2565 | enum ixgbe_mac_type type; |
@@ -2579,6 +2582,7 @@ struct ixgbe_mac_info { | |||
2579 | u32 orig_autoc2; | 2582 | u32 orig_autoc2; |
2580 | bool orig_link_settings_stored; | 2583 | bool orig_link_settings_stored; |
2581 | bool autotry_restart; | 2584 | bool autotry_restart; |
2585 | u8 flags; | ||
2582 | }; | 2586 | }; |
2583 | 2587 | ||
2584 | struct ixgbe_phy_info { | 2588 | struct ixgbe_phy_info { |
diff --git a/drivers/net/ixgbe/ixgbe_x540.c b/drivers/net/ixgbe/ixgbe_x540.c index f2518b01067d..a6f06d59a64a 100644 --- a/drivers/net/ixgbe/ixgbe_x540.c +++ b/drivers/net/ixgbe/ixgbe_x540.c | |||
@@ -110,12 +110,9 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) | |||
110 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master | 110 | * Prevent the PCI-E bus from from hanging by disabling PCI-E master |
111 | * access and verify no pending requests before reset | 111 | * access and verify no pending requests before reset |
112 | */ | 112 | */ |
113 | status = ixgbe_disable_pcie_master(hw); | 113 | ixgbe_disable_pcie_master(hw); |
114 | if (status != 0) { | ||
115 | status = IXGBE_ERR_MASTER_REQUESTS_PENDING; | ||
116 | hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); | ||
117 | } | ||
118 | 114 | ||
115 | mac_reset_top: | ||
119 | /* | 116 | /* |
120 | * Issue global reset to the MAC. Needs to be SW reset if link is up. | 117 | * Issue global reset to the MAC. Needs to be SW reset if link is up. |
121 | * If link reset is used when link is up, it might reset the PHY when | 118 | * If link reset is used when link is up, it might reset the PHY when |
@@ -148,6 +145,19 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) | |||
148 | hw_dbg(hw, "Reset polling failed to complete.\n"); | 145 | hw_dbg(hw, "Reset polling failed to complete.\n"); |
149 | } | 146 | } |
150 | 147 | ||
148 | /* | ||
149 | * Double resets are required for recovery from certain error | ||
150 | * conditions. Between resets, it is necessary to stall to allow time | ||
151 | * for any pending HW events to complete. We use 1usec since that is | ||
152 | * what is needed for ixgbe_disable_pcie_master(). The second reset | ||
153 | * then clears out any effects of those events. | ||
154 | */ | ||
155 | if (hw->mac.flags & IXGBE_FLAGS_DOUBLE_RESET_REQUIRED) { | ||
156 | hw->mac.flags &= ~IXGBE_FLAGS_DOUBLE_RESET_REQUIRED; | ||
157 | udelay(1); | ||
158 | goto mac_reset_top; | ||
159 | } | ||
160 | |||
151 | /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ | 161 | /* Clear PF Reset Done bit so PF/VF Mail Ops can work */ |
152 | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); | 162 | ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); |
153 | ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; | 163 | ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; |