u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
        bool link_up = false;
        bool negotiation;
+       int i;
 
        /* Mask off requested but non-supported speeds */
        hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
        speed &= phy_link_speed;
 
+       /*
+        * When the driver changes the link speeds that it can support,
+        * it sets autotry_restart to true to indicate that we need to
+        * initiate a new autotry session with the link partner.  To do
+        * so, we set the speed then disable and re-enable the tx laser, to
+        * alert the link partner that it also needs to restart autotry on its
+        * end.  This is consistent with true clause 37 autoneg, which also
+        * involves a loss of signal.
+        */
+
        /*
         * Try each speed one by one, highest priority first.  We do this in
         * software because 10gb fiber doesn't support speed autonegotiation.
                speedcnt++;
                highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
 
-               /* Set hardware SDP's */
+               /* If we already have link at this speed, just jump out */
+               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+               if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
                esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
 
-               ixgbe_setup_mac_link_speed_82599(hw,
-                                                IXGBE_LINK_SPEED_10GB_FULL,
-                                                autoneg,
-                                                autoneg_wait_to_complete);
-
-               msleep(50);
+               /* Allow module to change analog characteristics (1G->10G) */
+               msleep(40);
 
-               /* If we have link, just jump out */
-               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
-               if (link_up)
+               status = ixgbe_setup_mac_link_speed_82599(hw,
+                                                    IXGBE_LINK_SPEED_10GB_FULL,
+                                                    autoneg,
+                                                    autoneg_wait_to_complete);
+               if (status != 0)
                        goto out;
+
+               /* Flap the tx laser if it has not already been done */
+               if (hw->mac.autotry_restart) {
+                       /* Disable tx laser; allow 100us to go dark per spec */
+                       esdp_reg |= IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       udelay(100);
+
+                       /* Enable tx laser; allow 2ms to light up per spec */
+                       esdp_reg &= ~IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       msleep(2);
+
+                       hw->mac.autotry_restart = false;
+               }
+
+               /* The controller may take up to 500ms at 10g to acquire link */
+               for (i = 0; i < 5; i++) {
+                       /* Wait for the link partner to also set speed */
+                       msleep(100);
+
+                       /* If we have link, just jump out */
+                       hw->mac.ops.check_link(hw, &phy_link_speed,
+                                              &link_up, false);
+                       if (link_up)
+                               goto out;
+               }
        }
 
        if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
                if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
                        highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
 
-               /* Set hardware SDP's */
+               /* If we already have link at this speed, just jump out */
+               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+               if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
                esdp_reg &= ~IXGBE_ESDP_SDP5;
                esdp_reg |= IXGBE_ESDP_SDP5_DIR;
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
 
-               ixgbe_setup_mac_link_speed_82599(
-                       hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
-                       autoneg_wait_to_complete);
+               /* Allow module to change analog characteristics (10G->1G) */
+               msleep(40);
 
-               msleep(50);
+               status = ixgbe_setup_mac_link_speed_82599(hw,
+                                                     IXGBE_LINK_SPEED_1GB_FULL,
+                                                     autoneg,
+                                                     autoneg_wait_to_complete);
+               if (status != 0)
+                       goto out;
+
+               /* Flap the tx laser if it has not already been done */
+               if (hw->mac.autotry_restart) {
+                       /* Disable tx laser; allow 100us to go dark per spec */
+                       esdp_reg |= IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       udelay(100);
+
+                       /* Enable tx laser; allow 2ms to light up per spec */
+                       esdp_reg &= ~IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       msleep(2);
+
+                       hw->mac.autotry_restart = false;
+               }
+
+               /* Wait for the link partner to also set speed */
+               msleep(100);
 
                /* If we have link, just jump out */
                hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
        s32 status = 0;
        u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
        u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+       u32 start_autoc = autoc;
        u32 orig_autoc = 0;
        u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
        u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        hw->mac.ops.get_link_capabilities(hw, &link_capabilities, &autoneg);
        speed &= link_capabilities;
 
+       if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
+               status = IXGBE_ERR_LINK_SETUP;
+               goto out;
+       }
+
        /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
        if (hw->mac.orig_link_settings_stored)
                orig_autoc = hw->mac.orig_autoc;
                orig_autoc = autoc;
 
 
-       if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
-               status = IXGBE_ERR_LINK_SETUP;
-       } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
-                  link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
-                  link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+       if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
                /* Set KX4/KX/KR support according to speed requested */
                autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
                if (speed & IXGBE_LINK_SPEED_10GB_FULL)
                }
        }
 
-       if (status == 0) {
+       if (autoc != start_autoc) {
                /* Restart link */
                autoc |= IXGBE_AUTOC_AN_RESTART;
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
                msleep(50);
        }
 
+out:
        return status;
 }
 
        }
        IXGBE_WRITE_FLUSH(hw);
 
+       /* We need to run link autotry after the driver loads */
+       hw->mac.autotry_restart = true;
+
        return 0;
 }