aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorEmil Tantilov <emil.s.tantilov@intel.com>2011-02-14 03:45:13 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-03 06:00:09 -0500
commita4297dc2f49d46d5452a948210be44442236e685 (patch)
treebd1e121b13480179db21d5adc79b800dd0efe409 /drivers/net/ixgbe
parent21cc5b4f7eb7b6de90588331b7d0edb246502f46 (diff)
ixgbe: Add ability to double reset on failure to clear master enable
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. Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com> Tested-by: Stephen Ko <stephen.s.ko@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c21
-rw-r--r--drivers/net/ixgbe/ixgbe_82599.c20
-rw-r--r--drivers/net/ixgbe/ixgbe_common.c47
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h4
-rw-r--r--drivers/net/ixgbe/ixgbe_x540.c20
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
783mac_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
909mac_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 **/
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
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
2560struct ixgbe_mac_info { 2563struct 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
2584struct ixgbe_phy_info { 2588struct 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
115mac_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;