aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Brandeburg <jesse.brandeburg@intel.com>2009-09-25 08:17:44 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-26 23:15:36 -0400
commitbe0f071956e2142e2e88e9d6d5655ba1c75d07c8 (patch)
treee0b1be3f259841aaabcfbb02c4495dd2580d0130
parentbaa34745fe6263c733f43feddb0b8100d6538f37 (diff)
e1000: test link state conclusively
e1000 was using one particular way to detect link, but with the advent of some of the newer hardware designs using SERDES connections, tests for link must completely cover all cases. Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: Don Skidmore <donald.c.skidmore@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000/e1000_ethtool.c4
-rw-r--r--drivers/net/e1000/e1000_hw.c179
-rw-r--r--drivers/net/e1000/e1000_hw.h2
-rw-r--r--drivers/net/e1000/e1000_main.c49
4 files changed, 157 insertions, 77 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f2e756f069c6..490b2b7cd3ab 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1481,13 +1481,13 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
1481 *data = 0; 1481 *data = 0;
1482 if (hw->media_type == e1000_media_type_internal_serdes) { 1482 if (hw->media_type == e1000_media_type_internal_serdes) {
1483 int i = 0; 1483 int i = 0;
1484 hw->serdes_link_down = true; 1484 hw->serdes_has_link = false;
1485 1485
1486 /* On some blade server designs, link establishment 1486 /* On some blade server designs, link establishment
1487 * could take as long as 2-3 minutes */ 1487 * could take as long as 2-3 minutes */
1488 do { 1488 do {
1489 e1000_check_for_link(hw); 1489 e1000_check_for_link(hw);
1490 if (!hw->serdes_link_down) 1490 if (hw->serdes_has_link)
1491 return *data; 1491 return *data;
1492 msleep(20); 1492 msleep(20);
1493 } while (i++ < 3750); 1493 } while (i++ < 3750);
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 765fd71ad5f2..076db19f69f4 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -2136,6 +2136,116 @@ static s32 e1000_config_fc_after_link_up(struct e1000_hw *hw)
2136 return E1000_SUCCESS; 2136 return E1000_SUCCESS;
2137} 2137}
2138 2138
2139/**
2140 * e1000_check_for_serdes_link_generic - Check for link (Serdes)
2141 * @hw: pointer to the HW structure
2142 *
2143 * Checks for link up on the hardware. If link is not up and we have
2144 * a signal, then we need to force link up.
2145 **/
2146s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw)
2147{
2148 u32 rxcw;
2149 u32 ctrl;
2150 u32 status;
2151 s32 ret_val = E1000_SUCCESS;
2152
2153 DEBUGFUNC("e1000_check_for_serdes_link_generic");
2154
2155 ctrl = er32(CTRL);
2156 status = er32(STATUS);
2157 rxcw = er32(RXCW);
2158
2159 /*
2160 * If we don't have link (auto-negotiation failed or link partner
2161 * cannot auto-negotiate), and our link partner is not trying to
2162 * auto-negotiate with us (we are receiving idles or data),
2163 * we need to force link up. We also need to give auto-negotiation
2164 * time to complete.
2165 */
2166 /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */
2167 if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) {
2168 if (hw->autoneg_failed == 0) {
2169 hw->autoneg_failed = 1;
2170 goto out;
2171 }
2172 DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
2173
2174 /* Disable auto-negotiation in the TXCW register */
2175 ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
2176
2177 /* Force link-up and also force full-duplex. */
2178 ctrl = er32(CTRL);
2179 ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD);
2180 ew32(CTRL, ctrl);
2181
2182 /* Configure Flow Control after forcing link up. */
2183 ret_val = e1000_config_fc_after_link_up(hw);
2184 if (ret_val) {
2185 DEBUGOUT("Error configuring flow control\n");
2186 goto out;
2187 }
2188 } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
2189 /*
2190 * If we are forcing link and we are receiving /C/ ordered
2191 * sets, re-enable auto-negotiation in the TXCW register
2192 * and disable forced link in the Device Control register
2193 * in an attempt to auto-negotiate with our link partner.
2194 */
2195 DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
2196 ew32(TXCW, hw->txcw);
2197 ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
2198
2199 hw->serdes_has_link = true;
2200 } else if (!(E1000_TXCW_ANE & er32(TXCW))) {
2201 /*
2202 * If we force link for non-auto-negotiation switch, check
2203 * link status based on MAC synchronization for internal
2204 * serdes media type.
2205 */
2206 /* SYNCH bit and IV bit are sticky. */
2207 udelay(10);
2208 rxcw = er32(RXCW);
2209 if (rxcw & E1000_RXCW_SYNCH) {
2210 if (!(rxcw & E1000_RXCW_IV)) {
2211 hw->serdes_has_link = true;
2212 DEBUGOUT("SERDES: Link up - forced.\n");
2213 }
2214 } else {
2215 hw->serdes_has_link = false;
2216 DEBUGOUT("SERDES: Link down - force failed.\n");
2217 }
2218 }
2219
2220 if (E1000_TXCW_ANE & er32(TXCW)) {
2221 status = er32(STATUS);
2222 if (status & E1000_STATUS_LU) {
2223 /* SYNCH bit and IV bit are sticky, so reread rxcw. */
2224 udelay(10);
2225 rxcw = er32(RXCW);
2226 if (rxcw & E1000_RXCW_SYNCH) {
2227 if (!(rxcw & E1000_RXCW_IV)) {
2228 hw->serdes_has_link = true;
2229 DEBUGOUT("SERDES: Link up - autoneg "
2230 "completed sucessfully.\n");
2231 } else {
2232 hw->serdes_has_link = false;
2233 DEBUGOUT("SERDES: Link down - invalid"
2234 "codewords detected in autoneg.\n");
2235 }
2236 } else {
2237 hw->serdes_has_link = false;
2238 DEBUGOUT("SERDES: Link down - no sync.\n");
2239 }
2240 } else {
2241 hw->serdes_has_link = false;
2242 DEBUGOUT("SERDES: Link down - autoneg failed\n");
2243 }
2244 }
2245
2246out:
2247 return ret_val;
2248}
2139/****************************************************************************** 2249/******************************************************************************
2140 * Checks to see if the link status of the hardware has changed. 2250 * Checks to see if the link status of the hardware has changed.
2141 * 2251 *
@@ -2300,74 +2410,11 @@ s32 e1000_check_for_link(struct e1000_hw *hw)
2300 } 2410 }
2301 } 2411 }
2302 } 2412 }
2303 /* If we don't have link (auto-negotiation failed or link partner cannot
2304 * auto-negotiate), the cable is plugged in (we have signal), and our
2305 * link partner is not trying to auto-negotiate with us (we are receiving
2306 * idles or data), we need to force link up. We also need to give
2307 * auto-negotiation time to complete, in case the cable was just plugged
2308 * in. The autoneg_failed flag does this.
2309 */
2310 else if ((((hw->media_type == e1000_media_type_fiber) &&
2311 ((ctrl & E1000_CTRL_SWDPIN1) == signal)) ||
2312 (hw->media_type == e1000_media_type_internal_serdes)) &&
2313 (!(status & E1000_STATUS_LU)) &&
2314 (!(rxcw & E1000_RXCW_C))) {
2315 if (hw->autoneg_failed == 0) {
2316 hw->autoneg_failed = 1;
2317 return 0;
2318 }
2319 DEBUGOUT("NOT RXing /C/, disable AutoNeg and force link.\n");
2320
2321 /* Disable auto-negotiation in the TXCW register */
2322 ew32(TXCW, (hw->txcw & ~E1000_TXCW_ANE));
2323 2413
2324 /* Force link-up and also force full-duplex. */ 2414 if ((hw->media_type == e1000_media_type_fiber) ||
2325 ctrl = er32(CTRL); 2415 (hw->media_type == e1000_media_type_internal_serdes))
2326 ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); 2416 e1000_check_for_serdes_link_generic(hw);
2327 ew32(CTRL, ctrl);
2328
2329 /* Configure Flow Control after forcing link up. */
2330 ret_val = e1000_config_fc_after_link_up(hw);
2331 if (ret_val) {
2332 DEBUGOUT("Error configuring flow control\n");
2333 return ret_val;
2334 }
2335 }
2336 /* If we are forcing link and we are receiving /C/ ordered sets, re-enable
2337 * auto-negotiation in the TXCW register and disable forced link in the
2338 * Device Control register in an attempt to auto-negotiate with our link
2339 * partner.
2340 */
2341 else if (((hw->media_type == e1000_media_type_fiber) ||
2342 (hw->media_type == e1000_media_type_internal_serdes)) &&
2343 (ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
2344 DEBUGOUT("RXing /C/, enable AutoNeg and stop forcing link.\n");
2345 ew32(TXCW, hw->txcw);
2346 ew32(CTRL, (ctrl & ~E1000_CTRL_SLU));
2347 2417
2348 hw->serdes_link_down = false;
2349 }
2350 /* If we force link for non-auto-negotiation switch, check link status
2351 * based on MAC synchronization for internal serdes media type.
2352 */
2353 else if ((hw->media_type == e1000_media_type_internal_serdes) &&
2354 !(E1000_TXCW_ANE & er32(TXCW))) {
2355 /* SYNCH bit and IV bit are sticky. */
2356 udelay(10);
2357 if (E1000_RXCW_SYNCH & er32(RXCW)) {
2358 if (!(rxcw & E1000_RXCW_IV)) {
2359 hw->serdes_link_down = false;
2360 DEBUGOUT("SERDES: Link is up.\n");
2361 }
2362 } else {
2363 hw->serdes_link_down = true;
2364 DEBUGOUT("SERDES: Link is down.\n");
2365 }
2366 }
2367 if ((hw->media_type == e1000_media_type_internal_serdes) &&
2368 (E1000_TXCW_ANE & er32(TXCW))) {
2369 hw->serdes_link_down = !(E1000_STATUS_LU & er32(STATUS));
2370 }
2371 return E1000_SUCCESS; 2418 return E1000_SUCCESS;
2372} 2419}
2373 2420
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 1a8a0006f3e3..1c782d2ff04e 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1372,7 +1372,7 @@ struct e1000_hw {
1372 e1000_smart_speed smart_speed; 1372 e1000_smart_speed smart_speed;
1373 e1000_dsp_config dsp_config_state; 1373 e1000_dsp_config dsp_config_state;
1374 bool get_link_status; 1374 bool get_link_status;
1375 bool serdes_link_down; 1375 bool serdes_has_link;
1376 bool tbi_compatibility_en; 1376 bool tbi_compatibility_en;
1377 bool tbi_compatibility_on; 1377 bool tbi_compatibility_on;
1378 bool laa_is_present; 1378 bool laa_is_present;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7af3255a8e9c..11508afdfdb9 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2251,6 +2251,41 @@ static void e1000_82547_tx_fifo_stall(unsigned long data)
2251 } 2251 }
2252} 2252}
2253 2253
2254static bool e1000_has_link(struct e1000_adapter *adapter)
2255{
2256 struct e1000_hw *hw = &adapter->hw;
2257 bool link_active = false;
2258 s32 ret_val = 0;
2259
2260 /* get_link_status is set on LSC (link status) interrupt or
2261 * rx sequence error interrupt. get_link_status will stay
2262 * false until the e1000_check_for_link establishes link
2263 * for copper adapters ONLY
2264 */
2265 switch (hw->media_type) {
2266 case e1000_media_type_copper:
2267 if (hw->get_link_status) {
2268 ret_val = e1000_check_for_link(hw);
2269 link_active = !hw->get_link_status;
2270 } else {
2271 link_active = true;
2272 }
2273 break;
2274 case e1000_media_type_fiber:
2275 ret_val = e1000_check_for_link(hw);
2276 link_active = !!(er32(STATUS) & E1000_STATUS_LU);
2277 break;
2278 case e1000_media_type_internal_serdes:
2279 ret_val = e1000_check_for_link(hw);
2280 link_active = hw->serdes_has_link;
2281 break;
2282 default:
2283 break;
2284 }
2285
2286 return link_active;
2287}
2288
2254/** 2289/**
2255 * e1000_watchdog - Timer Call-back 2290 * e1000_watchdog - Timer Call-back
2256 * @data: pointer to adapter cast into an unsigned long 2291 * @data: pointer to adapter cast into an unsigned long
@@ -2263,18 +2298,15 @@ static void e1000_watchdog(unsigned long data)
2263 struct e1000_tx_ring *txdr = adapter->tx_ring; 2298 struct e1000_tx_ring *txdr = adapter->tx_ring;
2264 u32 link, tctl; 2299 u32 link, tctl;
2265 2300
2266 e1000_check_for_link(hw); 2301 link = e1000_has_link(adapter);
2267 2302 if ((netif_carrier_ok(netdev)) && link)
2268 if ((hw->media_type == e1000_media_type_internal_serdes) && 2303 goto link_up;
2269 !(er32(TXCW) & E1000_TXCW_ANE))
2270 link = !hw->serdes_link_down;
2271 else
2272 link = er32(STATUS) & E1000_STATUS_LU;
2273 2304
2274 if (link) { 2305 if (link) {
2275 if (!netif_carrier_ok(netdev)) { 2306 if (!netif_carrier_ok(netdev)) {
2276 u32 ctrl; 2307 u32 ctrl;
2277 bool txb2b = true; 2308 bool txb2b = true;
2309 /* update snapshot of PHY registers on LSC */
2278 e1000_get_speed_and_duplex(hw, 2310 e1000_get_speed_and_duplex(hw,
2279 &adapter->link_speed, 2311 &adapter->link_speed,
2280 &adapter->link_duplex); 2312 &adapter->link_duplex);
@@ -2299,7 +2331,7 @@ static void e1000_watchdog(unsigned long data)
2299 case SPEED_10: 2331 case SPEED_10:
2300 txb2b = false; 2332 txb2b = false;
2301 netdev->tx_queue_len = 10; 2333 netdev->tx_queue_len = 10;
2302 adapter->tx_timeout_factor = 8; 2334 adapter->tx_timeout_factor = 16;
2303 break; 2335 break;
2304 case SPEED_100: 2336 case SPEED_100:
2305 txb2b = false; 2337 txb2b = false;
@@ -2335,6 +2367,7 @@ static void e1000_watchdog(unsigned long data)
2335 e1000_smartspeed(adapter); 2367 e1000_smartspeed(adapter);
2336 } 2368 }
2337 2369
2370link_up:
2338 e1000_update_stats(adapter); 2371 e1000_update_stats(adapter);
2339 2372
2340 hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old; 2373 hw->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;