aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000/e1000_hw.c')
-rw-r--r--drivers/net/e1000/e1000_hw.c179
1 files changed, 113 insertions, 66 deletions
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