diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/igb/igb_main.c | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c index 13b10ba8a3c4..b59088eace1d 100644 --- a/drivers/net/igb/igb_main.c +++ b/drivers/net/igb/igb_main.c | |||
@@ -2261,6 +2261,46 @@ static void igb_update_phy_info(unsigned long data) | |||
2261 | } | 2261 | } |
2262 | 2262 | ||
2263 | /** | 2263 | /** |
2264 | * igb_has_link - check shared code for link and determine up/down | ||
2265 | * @adapter: pointer to driver private info | ||
2266 | **/ | ||
2267 | static bool igb_has_link(struct igb_adapter *adapter) | ||
2268 | { | ||
2269 | struct e1000_hw *hw = &adapter->hw; | ||
2270 | bool link_active = false; | ||
2271 | s32 ret_val = 0; | ||
2272 | |||
2273 | /* get_link_status is set on LSC (link status) interrupt or | ||
2274 | * rx sequence error interrupt. get_link_status will stay | ||
2275 | * false until the e1000_check_for_link establishes link | ||
2276 | * for copper adapters ONLY | ||
2277 | */ | ||
2278 | switch (hw->phy.media_type) { | ||
2279 | case e1000_media_type_copper: | ||
2280 | if (hw->mac.get_link_status) { | ||
2281 | ret_val = hw->mac.ops.check_for_link(hw); | ||
2282 | link_active = !hw->mac.get_link_status; | ||
2283 | } else { | ||
2284 | link_active = true; | ||
2285 | } | ||
2286 | break; | ||
2287 | case e1000_media_type_fiber: | ||
2288 | ret_val = hw->mac.ops.check_for_link(hw); | ||
2289 | link_active = !!(rd32(E1000_STATUS) & E1000_STATUS_LU); | ||
2290 | break; | ||
2291 | case e1000_media_type_internal_serdes: | ||
2292 | ret_val = hw->mac.ops.check_for_link(hw); | ||
2293 | link_active = hw->mac.serdes_has_link; | ||
2294 | break; | ||
2295 | default: | ||
2296 | case e1000_media_type_unknown: | ||
2297 | break; | ||
2298 | } | ||
2299 | |||
2300 | return link_active; | ||
2301 | } | ||
2302 | |||
2303 | /** | ||
2264 | * igb_watchdog - Timer Call-back | 2304 | * igb_watchdog - Timer Call-back |
2265 | * @data: pointer to adapter cast into an unsigned long | 2305 | * @data: pointer to adapter cast into an unsigned long |
2266 | **/ | 2306 | **/ |
@@ -2285,25 +2325,10 @@ static void igb_watchdog_task(struct work_struct *work) | |||
2285 | s32 ret_val; | 2325 | s32 ret_val; |
2286 | int i; | 2326 | int i; |
2287 | 2327 | ||
2288 | if ((netif_carrier_ok(netdev)) && | 2328 | link = igb_has_link(adapter); |
2289 | (rd32(E1000_STATUS) & E1000_STATUS_LU)) | 2329 | if ((netif_carrier_ok(netdev)) && link) |
2290 | goto link_up; | 2330 | goto link_up; |
2291 | 2331 | ||
2292 | ret_val = hw->mac.ops.check_for_link(&adapter->hw); | ||
2293 | if ((ret_val == E1000_ERR_PHY) && | ||
2294 | (hw->phy.type == e1000_phy_igp_3) && | ||
2295 | (rd32(E1000_CTRL) & | ||
2296 | E1000_PHY_CTRL_GBE_DISABLE)) | ||
2297 | dev_info(&adapter->pdev->dev, | ||
2298 | "Gigabit has been disabled, downgrading speed\n"); | ||
2299 | |||
2300 | if ((hw->phy.media_type == e1000_media_type_internal_serdes) && | ||
2301 | !(rd32(E1000_TXCW) & E1000_TXCW_ANE)) | ||
2302 | link = mac->serdes_has_link; | ||
2303 | else | ||
2304 | link = rd32(E1000_STATUS) & | ||
2305 | E1000_STATUS_LU; | ||
2306 | |||
2307 | if (link) { | 2332 | if (link) { |
2308 | if (!netif_carrier_ok(netdev)) { | 2333 | if (!netif_carrier_ok(netdev)) { |
2309 | u32 ctrl; | 2334 | u32 ctrl; |