igb: Fix for devices using ethtool for EEE settings
[deliverable/linux.git] / drivers / net / ethernet / intel / igb / igb_main.c
index a96beb67e9ee9cadb5fc501ded2241cd2afd95a8..340a3449e1e93ff0474c1a0f62488f953ffb0ec4 100644 (file)
@@ -1726,6 +1726,10 @@ int igb_up(struct igb_adapter *adapter)
        hw->mac.get_link_status = 1;
        schedule_work(&adapter->watchdog_task);
 
+       if ((adapter->flags & IGB_FLAG_EEE) &&
+           (!hw->dev_spec._82575.eee_disable))
+               adapter->eee_advert = MDIO_EEE_100TX | MDIO_EEE_1000T;
+
        return 0;
 }
 
@@ -1974,6 +1978,21 @@ void igb_reset(struct igb_adapter *adapter)
                }
        }
 #endif
+       /*Re-establish EEE setting */
+       if (hw->phy.media_type == e1000_media_type_copper) {
+               switch (mac->type) {
+               case e1000_i350:
+               case e1000_i210:
+               case e1000_i211:
+                       igb_set_eee_i350(hw);
+                       break;
+               case e1000_i354:
+                       igb_set_eee_i354(hw);
+                       break;
+               default:
+                       break;
+               }
+       }
        if (!netif_running(adapter->netdev))
                igb_power_down_link(adapter);
 
@@ -2560,23 +2579,36 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                (adapter->flags & IGB_FLAG_HAS_MSIX) ? "MSI-X" :
                (adapter->flags & IGB_FLAG_HAS_MSI) ? "MSI" : "legacy",
                adapter->num_rx_queues, adapter->num_tx_queues);
-       switch (hw->mac.type) {
-       case e1000_i350:
-       case e1000_i210:
-       case e1000_i211:
-               igb_set_eee_i350(hw);
-               break;
-       case e1000_i354:
-               if (hw->phy.media_type == e1000_media_type_copper) {
+       if (hw->phy.media_type == e1000_media_type_copper) {
+               switch (hw->mac.type) {
+               case e1000_i350:
+               case e1000_i210:
+               case e1000_i211:
+                       /* Enable EEE for internal copper PHY devices */
+                       err = igb_set_eee_i350(hw);
+                       if ((!err) &&
+                           (!hw->dev_spec._82575.eee_disable)) {
+                               adapter->eee_advert =
+                                       MDIO_EEE_100TX | MDIO_EEE_1000T;
+                               adapter->flags |= IGB_FLAG_EEE;
+                       }
+                       break;
+               case e1000_i354:
                        if ((rd32(E1000_CTRL_EXT) &
-                           E1000_CTRL_EXT_LINK_MODE_SGMII))
-                               igb_set_eee_i354(hw);
+                           E1000_CTRL_EXT_LINK_MODE_SGMII)) {
+                               err = igb_set_eee_i354(hw);
+                               if ((!err) &&
+                                       (!hw->dev_spec._82575.eee_disable)) {
+                                       adapter->eee_advert =
+                                          MDIO_EEE_100TX | MDIO_EEE_1000T;
+                                       adapter->flags |= IGB_FLAG_EEE;
+                               }
+                       }
+                       break;
+               default:
+                       break;
                }
-               break;
-       default:
-               break;
        }
-
        pm_runtime_put_noidle(&pdev->dev);
        return 0;
 
@@ -4158,6 +4190,15 @@ static void igb_watchdog_task(struct work_struct *work)
                               (ctrl & E1000_CTRL_RFCE) ?  "RX" :
                               (ctrl & E1000_CTRL_TFCE) ?  "TX" : "None");
 
+                       /* disable EEE if enabled */
+                       if ((adapter->flags & IGB_FLAG_EEE) &&
+                               (adapter->link_duplex == HALF_DUPLEX)) {
+                               dev_info(&adapter->pdev->dev,
+                               "EEE Disabled: unsupported at half duplex. Re-enable using ethtool when at full duplex.\n");
+                               adapter->hw.dev_spec._82575.eee_disable = true;
+                               adapter->flags &= ~IGB_FLAG_EEE;
+                       }
+
                        /* check if SmartSpeed worked */
                        igb_check_downshift(hw);
                        if (phy->speed_downgraded)
This page took 0.025595 seconds and 5 git commands to generate.