diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
| -rw-r--r-- | drivers/net/e1000/e1000_main.c | 49 |
1 files changed, 41 insertions, 8 deletions
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 | ||
| 2254 | static 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 | ||
| 2370 | link_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; |
