aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000/e1000_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r--drivers/net/e1000/e1000_main.c49
1 files changed, 41 insertions, 8 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7af3255a8e9..11508afdfdb 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;