if (hw->mac.type >= e1000_pch_lpt) {
                /* Only unforce SMBus if ME is not active */
                if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+                       /* Switching PHY interface always returns MDI error
+                        * so disable retry mechanism to avoid wasting time
+                        */
+                       e1000e_disable_phy_retry(hw);
+
                        /* Unforce SMBus mode in PHY */
                        e1e_rphy_locked(hw, CV_SMB_CTRL, &phy_reg);
                        phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
                        e1e_wphy_locked(hw, CV_SMB_CTRL, phy_reg);
 
+                       e1000e_enable_phy_retry(hw);
+
                        /* Unforce SMBus mode in MAC */
                        mac_reg = er32(CTRL_EXT);
                        mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
                goto out;
        }
 
+       /* There is no guarantee that the PHY is accessible at this time
+        * so disable retry mechanism to avoid wasting time
+        */
+       e1000e_disable_phy_retry(hw);
+
        /* The MAC-PHY interconnect may be in SMBus mode.  If the PHY is
         * inaccessible and resetting the PHY is not blocked, toggle the
         * LANPHYPC Value bit to force the interconnect to PCIe mode.
                break;
        }
 
+       e1000e_enable_phy_retry(hw);
+
        hw->phy.ops.release(hw);
        if (!ret_val) {
 
 
        phy->id = e1000_phy_unknown;
 
+       if (hw->mac.type == e1000_pch_mtp) {
+               phy->retry_count = 2;
+               e1000e_enable_phy_retry(hw);
+       }
+
        ret_val = e1000_init_phy_workarounds_pchlan(hw);
        if (ret_val)
                return ret_val;
        if (ret_val)
                goto out;
 
+       /* Switching PHY interface always returns MDI error
+        * so disable retry mechanism to avoid wasting time
+        */
+       e1000e_disable_phy_retry(hw);
+
        /* Force SMBus mode in PHY */
        ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
        if (ret_val)
        phy_reg |= CV_SMB_CTRL_FORCE_SMBUS;
        e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
 
+       e1000e_enable_phy_retry(hw);
+
        /* Force SMBus mode in MAC */
        mac_reg = er32(CTRL_EXT);
        mac_reg |= E1000_CTRL_EXT_FORCE_SMBUS;
                /* Toggle LANPHYPC Value bit */
                e1000_toggle_lanphypc_pch_lpt(hw);
 
+       /* Switching PHY interface always returns MDI error
+        * so disable retry mechanism to avoid wasting time
+        */
+       e1000e_disable_phy_retry(hw);
+
        /* Unforce SMBus mode in PHY */
        ret_val = e1000_read_phy_reg_hv_locked(hw, CV_SMB_CTRL, &phy_reg);
        if (ret_val) {
        phy_reg &= ~CV_SMB_CTRL_FORCE_SMBUS;
        e1000_write_phy_reg_hv_locked(hw, CV_SMB_CTRL, phy_reg);
 
+       e1000e_enable_phy_retry(hw);
+
        /* Unforce SMBus mode in MAC */
        mac_reg = er32(CTRL_EXT);
        mac_reg &= ~E1000_CTRL_EXT_FORCE_SMBUS;
 
        return e1e_wphy(hw, M88E1000_PHY_GEN_CONTROL, 0);
 }
 
+void e1000e_disable_phy_retry(struct e1000_hw *hw)
+{
+       hw->phy.retry_enabled = false;
+}
+
+void e1000e_enable_phy_retry(struct e1000_hw *hw)
+{
+       hw->phy.retry_enabled = true;
+}
+
 /**
  *  e1000e_read_phy_reg_mdic - Read MDI control register
  *  @hw: pointer to the HW structure
  **/
 s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 {
+       u32 i, mdic = 0, retry_counter, retry_max;
        struct e1000_phy_info *phy = &hw->phy;
-       u32 i, mdic = 0;
+       bool success;
 
        if (offset > MAX_PHY_REG_ADDRESS) {
                e_dbg("PHY Address %d is out of range\n", offset);
                return -E1000_ERR_PARAM;
        }
 
+       retry_max = phy->retry_enabled ? phy->retry_count : 0;
+
        /* Set up Op-code, Phy Address, and register offset in the MDI
         * Control register.  The MAC will take care of interfacing with the
         * PHY to retrieve the desired data.
         */
-       mdic = ((offset << E1000_MDIC_REG_SHIFT) |
-               (phy->addr << E1000_MDIC_PHY_SHIFT) |
-               (E1000_MDIC_OP_READ));
+       for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
+               success = true;
 
-       ew32(MDIC, mdic);
+               mdic = ((offset << E1000_MDIC_REG_SHIFT) |
+                       (phy->addr << E1000_MDIC_PHY_SHIFT) |
+                       (E1000_MDIC_OP_READ));
 
-       /* Poll the ready bit to see if the MDI read completed
-        * Increasing the time out as testing showed failures with
-        * the lower time out
-        */
-       for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-               udelay(50);
-               mdic = er32(MDIC);
-               if (mdic & E1000_MDIC_READY)
-                       break;
-       }
-       if (!(mdic & E1000_MDIC_READY)) {
-               e_dbg("MDI Read PHY Reg Address %d did not complete\n", offset);
-               return -E1000_ERR_PHY;
-       }
-       if (mdic & E1000_MDIC_ERROR) {
-               e_dbg("MDI Read PHY Reg Address %d Error\n", offset);
-               return -E1000_ERR_PHY;
-       }
-       if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
-               e_dbg("MDI Read offset error - requested %d, returned %d\n",
-                     offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
-               return -E1000_ERR_PHY;
+               ew32(MDIC, mdic);
+
+               /* Poll the ready bit to see if the MDI read completed
+                * Increasing the time out as testing showed failures with
+                * the lower time out
+                */
+               for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+                       usleep_range(50, 60);
+                       mdic = er32(MDIC);
+                       if (mdic & E1000_MDIC_READY)
+                               break;
+               }
+               if (!(mdic & E1000_MDIC_READY)) {
+                       e_dbg("MDI Read PHY Reg Address %d did not complete\n",
+                             offset);
+                       success = false;
+               }
+               if (mdic & E1000_MDIC_ERROR) {
+                       e_dbg("MDI Read PHY Reg Address %d Error\n", offset);
+                       success = false;
+               }
+               if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
+                       e_dbg("MDI Read offset error - requested %d, returned %d\n",
+                             offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
+                       success = false;
+               }
+
+               /* Allow some time after each MDIC transaction to avoid
+                * reading duplicate data in the next MDIC transaction.
+                */
+               if (hw->mac.type == e1000_pch2lan)
+                       usleep_range(100, 150);
+
+               if (success) {
+                       *data = (u16)mdic;
+                       return 0;
+               }
+
+               if (retry_counter != retry_max) {
+                       e_dbg("Perform retry on PHY transaction...\n");
+                       mdelay(10);
+               }
        }
-       *data = (u16)mdic;
 
-       /* Allow some time after each MDIC transaction to avoid
-        * reading duplicate data in the next MDIC transaction.
-        */
-       if (hw->mac.type == e1000_pch2lan)
-               udelay(100);
-       return 0;
+       return -E1000_ERR_PHY;
 }
 
 /**
  **/
 s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 {
+       u32 i, mdic = 0, retry_counter, retry_max;
        struct e1000_phy_info *phy = &hw->phy;
-       u32 i, mdic = 0;
+       bool success;
 
        if (offset > MAX_PHY_REG_ADDRESS) {
                e_dbg("PHY Address %d is out of range\n", offset);
                return -E1000_ERR_PARAM;
        }
 
+       retry_max = phy->retry_enabled ? phy->retry_count : 0;
+
        /* Set up Op-code, Phy Address, and register offset in the MDI
         * Control register.  The MAC will take care of interfacing with the
         * PHY to retrieve the desired data.
         */
-       mdic = (((u32)data) |
-               (offset << E1000_MDIC_REG_SHIFT) |
-               (phy->addr << E1000_MDIC_PHY_SHIFT) |
-               (E1000_MDIC_OP_WRITE));
+       for (retry_counter = 0; retry_counter <= retry_max; retry_counter++) {
+               success = true;
 
-       ew32(MDIC, mdic);
+               mdic = (((u32)data) |
+                       (offset << E1000_MDIC_REG_SHIFT) |
+                       (phy->addr << E1000_MDIC_PHY_SHIFT) |
+                       (E1000_MDIC_OP_WRITE));
 
-       /* Poll the ready bit to see if the MDI read completed
-        * Increasing the time out as testing showed failures with
-        * the lower time out
-        */
-       for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
-               udelay(50);
-               mdic = er32(MDIC);
-               if (mdic & E1000_MDIC_READY)
-                       break;
-       }
-       if (!(mdic & E1000_MDIC_READY)) {
-               e_dbg("MDI Write PHY Reg Address %d did not complete\n", offset);
-               return -E1000_ERR_PHY;
-       }
-       if (mdic & E1000_MDIC_ERROR) {
-               e_dbg("MDI Write PHY Red Address %d Error\n", offset);
-               return -E1000_ERR_PHY;
-       }
-       if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
-               e_dbg("MDI Write offset error - requested %d, returned %d\n",
-                     offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
-               return -E1000_ERR_PHY;
-       }
+               ew32(MDIC, mdic);
 
-       /* Allow some time after each MDIC transaction to avoid
-        * reading duplicate data in the next MDIC transaction.
-        */
-       if (hw->mac.type == e1000_pch2lan)
-               udelay(100);
+               /* Poll the ready bit to see if the MDI read completed
+                * Increasing the time out as testing showed failures with
+                * the lower time out
+                */
+               for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+                       usleep_range(50, 60);
+                       mdic = er32(MDIC);
+                       if (mdic & E1000_MDIC_READY)
+                               break;
+               }
+               if (!(mdic & E1000_MDIC_READY)) {
+                       e_dbg("MDI Write PHY Reg Address %d did not complete\n",
+                             offset);
+                       success = false;
+               }
+               if (mdic & E1000_MDIC_ERROR) {
+                       e_dbg("MDI Write PHY Reg Address %d Error\n", offset);
+                       success = false;
+               }
+               if (FIELD_GET(E1000_MDIC_REG_MASK, mdic) != offset) {
+                       e_dbg("MDI Write offset error - requested %d, returned %d\n",
+                             offset, FIELD_GET(E1000_MDIC_REG_MASK, mdic));
+                       success = false;
+               }
 
-       return 0;
+               /* Allow some time after each MDIC transaction to avoid
+                * reading duplicate data in the next MDIC transaction.
+                */
+               if (hw->mac.type == e1000_pch2lan)
+                       usleep_range(100, 150);
+
+               if (success)
+                       return 0;
+
+               if (retry_counter != retry_max) {
+                       e_dbg("Perform retry on PHY transaction...\n");
+                       mdelay(10);
+               }
+       }
+
+       return -E1000_ERR_PHY;
 }
 
 /**