if (hw->vendor_id != PCI_VENDOR_ID_INTEL)
                return ICE_ERR_DEVICE_NOT_SUPPORTED;
 
-       hw->mac_type = ICE_MAC_GENERIC;
+       switch (hw->device_id) {
+       case ICE_DEV_ID_E810C_BACKPLANE:
+       case ICE_DEV_ID_E810C_QSFP:
+       case ICE_DEV_ID_E810C_SFP:
+       case ICE_DEV_ID_E810_XXV_SFP:
+               hw->mac_type = ICE_MAC_E810;
+               break;
+       case ICE_DEV_ID_E823C_10G_BASE_T:
+       case ICE_DEV_ID_E823C_BACKPLANE:
+       case ICE_DEV_ID_E823C_QSFP:
+       case ICE_DEV_ID_E823C_SFP:
+       case ICE_DEV_ID_E823C_SGMII:
+       case ICE_DEV_ID_E822C_10G_BASE_T:
+       case ICE_DEV_ID_E822C_BACKPLANE:
+       case ICE_DEV_ID_E822C_QSFP:
+       case ICE_DEV_ID_E822C_SFP:
+       case ICE_DEV_ID_E822C_SGMII:
+       case ICE_DEV_ID_E822L_10G_BASE_T:
+       case ICE_DEV_ID_E822L_BACKPLANE:
+       case ICE_DEV_ID_E822L_SFP:
+       case ICE_DEV_ID_E822L_SGMII:
+       case ICE_DEV_ID_E823L_10G_BASE_T:
+       case ICE_DEV_ID_E823L_1GBE:
+       case ICE_DEV_ID_E823L_BACKPLANE:
+       case ICE_DEV_ID_E823L_QSFP:
+       case ICE_DEV_ID_E823L_SFP:
+               hw->mac_type = ICE_MAC_GENERIC;
+               break;
+       default:
+               hw->mac_type = ICE_MAC_UNKNOWN;
+               break;
+       }
+
+       ice_debug(hw, ICE_DBG_INIT, "mac_type: %d\n", hw->mac_type);
        return 0;
 }
 
                goto out;
        }
 
-       ice_copy_phy_caps_to_cfg(pcaps, &cfg);
+       ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg);
 
        /* Configure the set PHY data */
        status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode);
 
 /**
  * ice_copy_phy_caps_to_cfg - Copy PHY ability data to configuration data
+ * @pi: port information structure
  * @caps: PHY ability structure to copy date from
  * @cfg: PHY configuration structure to copy data to
  *
  * data structure
  */
 void
-ice_copy_phy_caps_to_cfg(struct ice_aqc_get_phy_caps_data *caps,
+ice_copy_phy_caps_to_cfg(struct ice_port_info *pi,
+                        struct ice_aqc_get_phy_caps_data *caps,
                         struct ice_aqc_set_phy_cfg_data *cfg)
 {
-       if (!caps || !cfg)
+       if (!pi || !caps || !cfg)
                return;
 
        memset(cfg, 0, sizeof(*cfg));
        cfg->eee_cap = caps->eee_cap;
        cfg->eeer_value = caps->eeer_value;
        cfg->link_fec_opt = caps->link_fec_options;
+       cfg->module_compliance_enforcement =
+               caps->module_compliance_enforcement;
+
+       if (ice_fw_supports_link_override(pi->hw)) {
+               struct ice_link_default_override_tlv tlv;
+
+               if (ice_get_link_default_override(&tlv, pi))
+                       return;
+
+               if (tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE)
+                       cfg->module_compliance_enforcement |=
+                               ICE_LINK_OVERRIDE_STRICT_MODE;
+       }
 }
 
 /**
                break;
        }
 
+       if (fec == ICE_FEC_AUTO && ice_fw_supports_link_override(pi->hw)) {
+               struct ice_link_default_override_tlv tlv;
+
+               if (ice_get_link_default_override(&tlv, pi))
+                       goto out;
+
+               if (!(tlv.options & ICE_LINK_OVERRIDE_STRICT_MODE) &&
+                   (tlv.options & ICE_LINK_OVERRIDE_EN))
+                       cfg->link_fec_opt = tlv.fec_options;
+       }
+
 out:
        kfree(pcaps);
 
                ice_debug(hw, ICE_DBG_SCHED, "query element failed\n");
        return status;
 }
+
+/**
+ * ice_fw_supports_link_override
+ * @hw: pointer to the hardware structure
+ *
+ * Checks if the firmware supports link override
+ */
+bool ice_fw_supports_link_override(struct ice_hw *hw)
+{
+       /* Currently, only supported for E810 devices */
+       if (hw->mac_type != ICE_MAC_E810)
+               return false;
+
+       if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) {
+               if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN)
+                       return true;
+               if (hw->api_min_ver == ICE_FW_API_LINK_OVERRIDE_MIN &&
+                   hw->api_patch >= ICE_FW_API_LINK_OVERRIDE_PATCH)
+                       return true;
+       } else if (hw->api_maj_ver > ICE_FW_API_LINK_OVERRIDE_MAJ) {
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * ice_get_link_default_override
+ * @ldo: pointer to the link default override struct
+ * @pi: pointer to the port info struct
+ *
+ * Gets the link default override for a port
+ */
+enum ice_status
+ice_get_link_default_override(struct ice_link_default_override_tlv *ldo,
+                             struct ice_port_info *pi)
+{
+       u16 i, tlv, tlv_len, tlv_start, buf, offset;
+       struct ice_hw *hw = pi->hw;
+       enum ice_status status;
+
+       status = ice_get_pfa_module_tlv(hw, &tlv, &tlv_len,
+                                       ICE_SR_LINK_DEFAULT_OVERRIDE_PTR);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT,
+                         "Failed to read link override TLV.\n");
+               return status;
+       }
+
+       /* Each port has its own config; calculate for our port */
+       tlv_start = tlv + pi->lport * ICE_SR_PFA_LINK_OVERRIDE_WORDS +
+               ICE_SR_PFA_LINK_OVERRIDE_OFFSET;
+
+       /* link options first */
+       status = ice_read_sr_word(hw, tlv_start, &buf);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT,
+                         "Failed to read override link options.\n");
+               return status;
+       }
+       ldo->options = buf & ICE_LINK_OVERRIDE_OPT_M;
+       ldo->phy_config = (buf & ICE_LINK_OVERRIDE_PHY_CFG_M) >>
+               ICE_LINK_OVERRIDE_PHY_CFG_S;
+
+       /* link PHY config */
+       offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_FEC_OFFSET;
+       status = ice_read_sr_word(hw, offset, &buf);
+       if (status) {
+               ice_debug(hw, ICE_DBG_INIT,
+                         "Failed to read override phy config.\n");
+               return status;
+       }
+       ldo->fec_options = buf & ICE_LINK_OVERRIDE_FEC_OPT_M;
+
+       /* PHY types low */
+       offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET;
+       for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
+               status = ice_read_sr_word(hw, (offset + i), &buf);
+               if (status) {
+                       ice_debug(hw, ICE_DBG_INIT,
+                                 "Failed to read override link options.\n");
+                       return status;
+               }
+               /* shift 16 bits at a time to fill 64 bits */
+               ldo->phy_type_low |= ((u64)buf << (i * 16));
+       }
+
+       /* PHY types high */
+       offset = tlv_start + ICE_SR_PFA_LINK_OVERRIDE_PHY_OFFSET +
+               ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS;
+       for (i = 0; i < ICE_SR_PFA_LINK_OVERRIDE_PHY_WORDS; i++) {
+               status = ice_read_sr_word(hw, (offset + i), &buf);
+               if (status) {
+                       ice_debug(hw, ICE_DBG_INIT,
+                                 "Failed to read override link options.\n");
+                       return status;
+               }
+               /* shift 16 bits at a time to fill 64 bits */
+               ldo->phy_type_high |= ((u64)buf << (i * 16));
+       }
+
+       return status;
+}
 
        }
 }
 
+#define ICE_PHY_TYPE_LOW_MASK_MIN_1G   (ICE_PHY_TYPE_LOW_100BASE_TX | \
+                                        ICE_PHY_TYPE_LOW_100M_SGMII)
+
+#define ICE_PHY_TYPE_LOW_MASK_MIN_25G  (ICE_PHY_TYPE_LOW_MASK_MIN_1G | \
+                                        ICE_PHY_TYPE_LOW_1000BASE_T | \
+                                        ICE_PHY_TYPE_LOW_1000BASE_SX | \
+                                        ICE_PHY_TYPE_LOW_1000BASE_LX | \
+                                        ICE_PHY_TYPE_LOW_1000BASE_KX | \
+                                        ICE_PHY_TYPE_LOW_1G_SGMII | \
+                                        ICE_PHY_TYPE_LOW_2500BASE_T | \
+                                        ICE_PHY_TYPE_LOW_2500BASE_X | \
+                                        ICE_PHY_TYPE_LOW_2500BASE_KX | \
+                                        ICE_PHY_TYPE_LOW_5GBASE_T | \
+                                        ICE_PHY_TYPE_LOW_5GBASE_KR | \
+                                        ICE_PHY_TYPE_LOW_10GBASE_T | \
+                                        ICE_PHY_TYPE_LOW_10G_SFI_DA | \
+                                        ICE_PHY_TYPE_LOW_10GBASE_SR | \
+                                        ICE_PHY_TYPE_LOW_10GBASE_LR | \
+                                        ICE_PHY_TYPE_LOW_10GBASE_KR_CR1 | \
+                                        ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC | \
+                                        ICE_PHY_TYPE_LOW_10G_SFI_C2C)
+
+#define ICE_PHY_TYPE_LOW_MASK_100G     (ICE_PHY_TYPE_LOW_100GBASE_CR4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_SR4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_LR4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_KR4 | \
+                                        ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC | \
+                                        ICE_PHY_TYPE_LOW_100G_CAUI4 | \
+                                        ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC | \
+                                        ICE_PHY_TYPE_LOW_100G_AUI4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_CP2 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_SR2 | \
+                                        ICE_PHY_TYPE_LOW_100GBASE_DR)
+
+#define ICE_PHY_TYPE_HIGH_MASK_100G    (ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4 | \
+                                        ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |\
+                                        ICE_PHY_TYPE_HIGH_100G_CAUI2 | \
+                                        ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC | \
+                                        ICE_PHY_TYPE_HIGH_100G_AUI2)
+
+/**
+ * ice_mask_min_supported_speeds
+ * @phy_types_high: PHY type high
+ * @phy_types_low: PHY type low to apply minimum supported speeds mask
+ *
+ * Apply minimum supported speeds mask to PHY type low. These are the speeds
+ * for ethtool supported link mode.
+ */
+static
+void ice_mask_min_supported_speeds(u64 phy_types_high, u64 *phy_types_low)
+{
+       /* if QSFP connection with 100G speed, minimum supported speed is 25G */
+       if (*phy_types_low & ICE_PHY_TYPE_LOW_MASK_100G ||
+           phy_types_high & ICE_PHY_TYPE_HIGH_MASK_100G)
+               *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_25G;
+       else
+               *phy_types_low &= ~ICE_PHY_TYPE_LOW_MASK_MIN_1G;
+}
+
+#define ice_ethtool_advertise_link_mode(aq_link_speed, ethtool_link_mode)    \
+       do {                                                                 \
+               if (req_speeds & (aq_link_speed) ||                          \
+                   (!req_speeds &&                                          \
+                    (adv_phy_type_lo & phy_type_mask_lo ||                  \
+                     adv_phy_type_hi & phy_type_mask_hi)))                  \
+                       ethtool_link_ksettings_add_link_mode(ks, advertising,\
+                                                       ethtool_link_mode);  \
+       } while (0)
+
 /**
  * ice_phy_type_to_ethtool - convert the phy_types to ethtool link modes
  * @netdev: network interface device structure
                        struct ethtool_link_ksettings *ks)
 {
        struct ice_netdev_priv *np = netdev_priv(netdev);
-       struct ice_link_status *hw_link_info;
-       bool need_add_adv_mode = false;
        struct ice_vsi *vsi = np->vsi;
-       u64 phy_types_high;
-       u64 phy_types_low;
+       struct ice_pf *pf = vsi->back;
+       u64 phy_type_mask_lo = 0;
+       u64 phy_type_mask_hi = 0;
+       u64 adv_phy_type_lo = 0;
+       u64 adv_phy_type_hi = 0;
+       u64 phy_types_high = 0;
+       u64 phy_types_low = 0;
+       u16 req_speeds;
+
+       req_speeds = vsi->port_info->phy.link_info.req_speeds;
+
+       /* Check if lenient mode is supported and enabled, or in strict mode.
+        *
+        * In lenient mode the Supported link modes are the PHY types without
+        * media. The Advertising link mode is either 1. the user requested
+        * speed, 2. the override PHY mask, or 3. the PHY types with media.
+        *
+        * In strict mode Supported link mode are the PHY type with media,
+        * and Advertising link modes are the media PHY type or the speed
+        * requested by user.
+        */
+       if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
+               struct ice_link_default_override_tlv *ldo;
 
-       hw_link_info = &vsi->port_info->phy.link_info;
-       phy_types_low = vsi->port_info->phy.phy_type_low;
-       phy_types_high = vsi->port_info->phy.phy_type_high;
+               ldo = &pf->link_dflt_override;
+               phy_types_low = le64_to_cpu(pf->nvm_phy_type_lo);
+               phy_types_high = le64_to_cpu(pf->nvm_phy_type_hi);
+
+               ice_mask_min_supported_speeds(phy_types_high, &phy_types_low);
+
+               /* If override enabled and PHY mask set, then
+                * Advertising link mode is the intersection of the PHY
+                * types without media and the override PHY mask.
+                */
+               if (ldo->options & ICE_LINK_OVERRIDE_EN &&
+                   (ldo->phy_type_low || ldo->phy_type_high)) {
+                       adv_phy_type_lo =
+                               le64_to_cpu(pf->nvm_phy_type_lo) &
+                               ldo->phy_type_low;
+                       adv_phy_type_hi =
+                               le64_to_cpu(pf->nvm_phy_type_hi) &
+                               ldo->phy_type_high;
+               }
+       } else {
+               phy_types_low = vsi->port_info->phy.phy_type_low;
+               phy_types_high = vsi->port_info->phy.phy_type_high;
+       }
+
+       /* If Advertising link mode PHY type is not using override PHY type,
+        * then use PHY type with media.
+        */
+       if (!adv_phy_type_lo && !adv_phy_type_hi) {
+               adv_phy_type_lo = vsi->port_info->phy.phy_type_low;
+               adv_phy_type_hi = vsi->port_info->phy.phy_type_high;
+       }
 
        ethtool_link_ksettings_zero_link_mode(ks, supported);
        ethtool_link_ksettings_zero_link_mode(ks, advertising);
 
-       if (phy_types_low & ICE_PHY_TYPE_LOW_100BASE_TX ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100M_SGMII) {
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_100BASE_TX |
+                          ICE_PHY_TYPE_LOW_100M_SGMII;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     100baseT_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            100baseT_Full);
+
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100MB,
+                                               100baseT_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_T ||
-           phy_types_low & ICE_PHY_TYPE_LOW_1G_SGMII) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_T |
+                          ICE_PHY_TYPE_LOW_1G_SGMII;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     1000baseT_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            1000baseT_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+                                               1000baseT_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_KX) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_KX;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     1000baseKX_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            1000baseKX_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+                                               1000baseKX_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_SX ||
-           phy_types_low & ICE_PHY_TYPE_LOW_1000BASE_LX) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_1000BASE_SX |
+                          ICE_PHY_TYPE_LOW_1000BASE_LX;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     1000baseX_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_1000MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            1000baseX_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_1000MB,
+                                               1000baseX_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_T) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_T;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     2500baseT_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_2500MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            2500baseT_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
+                                               2500baseT_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_X ||
-           phy_types_low & ICE_PHY_TYPE_LOW_2500BASE_KX) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_2500BASE_X |
+                          ICE_PHY_TYPE_LOW_2500BASE_KX;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     2500baseX_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_2500MB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            2500baseX_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_2500MB,
+                                               2500baseX_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_T ||
-           phy_types_low & ICE_PHY_TYPE_LOW_5GBASE_KR) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_5GBASE_T |
+                          ICE_PHY_TYPE_LOW_5GBASE_KR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     5000baseT_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_5GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            5000baseT_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_T ||
-           phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_DA ||
-           phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_10G_SFI_C2C) {
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_5GB,
+                                               5000baseT_Full);
+       }
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_T |
+                          ICE_PHY_TYPE_LOW_10G_SFI_DA |
+                          ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_10G_SFI_C2C;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseT_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            10000baseT_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+                                               10000baseT_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_KR_CR1) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_KR_CR1;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseKR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            10000baseKR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+                                               10000baseKR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_SR) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_SR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseSR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            10000baseSR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+                                               10000baseSR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_10GBASE_LR) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_10GBASE_LR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     10000baseLR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_10GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            10000baseLR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_10GB,
+                                               10000baseLR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_T ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR_S ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_CR1 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25G_AUI_C2C) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_T |
+                          ICE_PHY_TYPE_LOW_25GBASE_CR |
+                          ICE_PHY_TYPE_LOW_25GBASE_CR_S |
+                          ICE_PHY_TYPE_LOW_25GBASE_CR1 |
+                          ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_25G_AUI_C2C;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     25000baseCR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            25000baseCR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+                                               25000baseCR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_SR ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_LR) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_SR |
+                          ICE_PHY_TYPE_LOW_25GBASE_LR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     25000baseSR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            25000baseSR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+                                               25000baseSR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR_S ||
-           phy_types_low & ICE_PHY_TYPE_LOW_25GBASE_KR1) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_25GBASE_KR |
+                          ICE_PHY_TYPE_LOW_25GBASE_KR_S |
+                          ICE_PHY_TYPE_LOW_25GBASE_KR1;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     25000baseKR_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_25GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            25000baseKR_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_25GB,
+                                               25000baseKR_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_KR4) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_KR4;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     40000baseKR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            40000baseKR4_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_CR4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_40G_XLAUI) {
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+                                               40000baseKR4_Full);
+       }
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_CR4 |
+                          ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_40G_XLAUI;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     40000baseCR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            40000baseCR4_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+                                               40000baseCR4_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_SR4) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_SR4;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     40000baseSR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            40000baseSR4_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+                                               40000baseSR4_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_40GBASE_LR4) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_40GBASE_LR4;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     40000baseLR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_40GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            40000baseLR4_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CR2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_LAUI2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_CP ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_SR ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50G_AUI1) {
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_40GB,
+                                               40000baseLR4_Full);
+       }
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_CR2 |
+                          ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_50G_LAUI2 |
+                          ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_50G_AUI2 |
+                          ICE_PHY_TYPE_LOW_50GBASE_CP |
+                          ICE_PHY_TYPE_LOW_50GBASE_SR |
+                          ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_50G_AUI1;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     50000baseCR2_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            50000baseCR2_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+                                               50000baseCR2_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_KR2 |
+                          ICE_PHY_TYPE_LOW_50GBASE_KR_PAM4;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     50000baseKR2_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            50000baseKR2_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_SR2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_LR2 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_FR ||
-           phy_types_low & ICE_PHY_TYPE_LOW_50GBASE_LR) {
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+                                               50000baseKR2_Full);
+       }
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_50GBASE_SR2 |
+                          ICE_PHY_TYPE_LOW_50GBASE_LR2 |
+                          ICE_PHY_TYPE_LOW_50GBASE_FR |
+                          ICE_PHY_TYPE_LOW_50GBASE_LR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     50000baseSR2_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_50GB)
-                       ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                            50000baseSR2_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CR4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100G_CAUI4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100G_AUI4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_CP2  ||
-           phy_types_high & ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC ||
-           phy_types_high & ICE_PHY_TYPE_HIGH_100G_CAUI2 ||
-           phy_types_high & ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC ||
-           phy_types_high & ICE_PHY_TYPE_HIGH_100G_AUI2) {
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_50GB,
+                                               50000baseSR2_Full);
+       }
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_CR4 |
+                          ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_100G_CAUI4 |
+                          ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC |
+                          ICE_PHY_TYPE_LOW_100G_AUI4 |
+                          ICE_PHY_TYPE_LOW_100GBASE_CR_PAM4 |
+                          ICE_PHY_TYPE_LOW_100GBASE_CP2;
+       phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC |
+                          ICE_PHY_TYPE_HIGH_100G_CAUI2 |
+                          ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC |
+                          ICE_PHY_TYPE_HIGH_100G_AUI2;
+       if (phy_types_low & phy_type_mask_lo ||
+           phy_types_high & phy_type_mask_hi) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     100000baseCR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
-                       need_add_adv_mode = true;
-       }
-       if (need_add_adv_mode) {
-               need_add_adv_mode = false;
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    100000baseCR4_Full);
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+                                               100000baseCR4_Full);
        }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_SR4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_SR2) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_SR4 |
+                          ICE_PHY_TYPE_LOW_100GBASE_SR2;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     100000baseSR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
-                       need_add_adv_mode = true;
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+                                               100000baseSR4_Full);
        }
-       if (need_add_adv_mode) {
-               need_add_adv_mode = false;
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    100000baseSR4_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_LR4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_DR) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_LR4 |
+                          ICE_PHY_TYPE_LOW_100GBASE_DR;
+       if (phy_types_low & phy_type_mask_lo) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     100000baseLR4_ER4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
-                       need_add_adv_mode = true;
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+                                               100000baseLR4_ER4_Full);
        }
-       if (need_add_adv_mode) {
-               need_add_adv_mode = false;
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    100000baseLR4_ER4_Full);
-       }
-       if (phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR4 ||
-           phy_types_low & ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4 ||
-           phy_types_high & ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4) {
+
+       phy_type_mask_lo = ICE_PHY_TYPE_LOW_100GBASE_KR4 |
+                          ICE_PHY_TYPE_LOW_100GBASE_KR_PAM4;
+       phy_type_mask_hi = ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4;
+       if (phy_types_low & phy_type_mask_lo ||
+           phy_types_high & phy_type_mask_hi) {
                ethtool_link_ksettings_add_link_mode(ks, supported,
                                                     100000baseKR4_Full);
-               if (!hw_link_info->req_speeds ||
-                   hw_link_info->req_speeds & ICE_AQ_LINK_SPEED_100GB)
-                       need_add_adv_mode = true;
+               ice_ethtool_advertise_link_mode(ICE_AQ_LINK_SPEED_100GB,
+                                               100000baseKR4_Full);
        }
-       if (need_add_adv_mode)
-               ethtool_link_ksettings_add_link_mode(ks, advertising,
-                                                    100000baseKR4_Full);
 
        /* Autoneg PHY types */
        if (phy_types_low & ICE_PHY_TYPE_LOW_100BASE_TX ||
        struct ice_port_info *p;
        u8 autoneg_changed = 0;
        enum ice_status status;
-       u64 phy_type_high;
-       u64 phy_type_low;
+       u64 phy_type_high = 0;
+       u64 phy_type_low = 0;
        int err = 0;
        bool linkup;
 
        if (!bitmap_subset(copy_ks.link_modes.advertising,
                           safe_ks.link_modes.supported,
                           __ETHTOOL_LINK_MODE_MASK_NBITS)) {
+               if (!test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags))
+                       netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
                err = -EINVAL;
                goto done;
        }
                        abilities->phy_type_low;
 
        if (!(config.phy_type_high || config.phy_type_low)) {
-               netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
-               err = -EAGAIN;
-               goto done;
+               /* If there is no intersection and lenient mode is enabled, then
+                * intersect the requested advertised speed with NVM media type
+                * PHY types.
+                */
+               if (test_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags)) {
+                       config.phy_type_high = cpu_to_le64(phy_type_high) &
+                                              pf->nvm_phy_type_hi;
+                       config.phy_type_low = cpu_to_le64(phy_type_low) &
+                                             pf->nvm_phy_type_lo;
+               } else {
+                       netdev_info(netdev, "The selected speed is not supported by the current media. Please select a link speed that is supported by the current media.\n");
+                       err = -EAGAIN;
+                       goto done;
+               }
        }
 
        /* If link is up put link down */
 
  * ice_init_nvm_phy_type - Initialize the NVM PHY type
  * @pi: port info structure
  *
- * Initialize nvm_phy_type_[low|high]
+ * Initialize nvm_phy_type_[low|high] for link lenient mode support
  */
 static int ice_init_nvm_phy_type(struct ice_port_info *pi)
 {
        return err;
 }
 
+/**
+ * ice_init_link_dflt_override - Initialize link default override
+ * @pi: port info structure
+ */
+static void ice_init_link_dflt_override(struct ice_port_info *pi)
+{
+       struct ice_link_default_override_tlv *ldo;
+       struct ice_pf *pf = pi->hw->back;
+
+       ldo = &pf->link_dflt_override;
+       ice_get_link_default_override(ldo, pi);
+}
+
+/**
+ * ice_init_phy_cfg_dflt_override - Initialize PHY cfg default override settings
+ * @pi: port info structure
+ *
+ * If default override is enabled, initialized the user PHY cfg speed and FEC
+ * settings using the default override mask from the NVM.
+ *
+ * The PHY should only be configured with the default override settings the
+ * first time media is available. The __ICE_LINK_DEFAULT_OVERRIDE_PENDING state
+ * is used to indicate that the user PHY cfg default override is initialized
+ * and the PHY has not been configured with the default override settings. The
+ * state is set here, and cleared in ice_configure_phy the first time the PHY is
+ * configured.
+ */
+static void ice_init_phy_cfg_dflt_override(struct ice_port_info *pi)
+{
+       struct ice_link_default_override_tlv *ldo;
+       struct ice_aqc_set_phy_cfg_data *cfg;
+       struct ice_phy_info *phy = &pi->phy;
+       struct ice_pf *pf = pi->hw->back;
+
+       ldo = &pf->link_dflt_override;
+
+       /* If link default override is enabled, use to mask NVM PHY capabilities
+        * for speed and FEC default configuration.
+        */
+       cfg = &phy->curr_user_phy_cfg;
+
+       if (ldo->phy_type_low || ldo->phy_type_high) {
+               cfg->phy_type_low = pf->nvm_phy_type_lo &
+                                   cpu_to_le64(ldo->phy_type_low);
+               cfg->phy_type_high = pf->nvm_phy_type_hi &
+                                    cpu_to_le64(ldo->phy_type_high);
+       }
+       cfg->link_fec_opt = ldo->fec_options;
+       phy->curr_user_fec_req = ICE_FEC_AUTO;
+
+       set_bit(__ICE_LINK_DEFAULT_OVERRIDE_PENDING, pf->state);
+}
+
 /**
  * ice_init_phy_user_cfg - Initialize the PHY user configuration
  * @pi: port info structure
                goto err_out;
        }
 
-       ice_copy_phy_caps_to_cfg(pcaps, &pi->phy.curr_user_phy_cfg);
-       /* initialize PHY using topology with media */
+       ice_copy_phy_caps_to_cfg(pi, pcaps, &pi->phy.curr_user_phy_cfg);
+
+       /* check if lenient mode is supported and enabled */
+       if (ice_fw_supports_link_override(&vsi->back->hw) &&
+           !(pcaps->module_compliance_enforcement &
+             ICE_AQC_MOD_ENFORCE_STRICT_MODE)) {
+               set_bit(ICE_FLAG_LINK_LENIENT_MODE_ENA, pf->flags);
+
+               /* if link default override is enabled, initialize user PHY
+                * configuration with link default override values
+                */
+               if (pf->link_dflt_override.options & ICE_LINK_OVERRIDE_EN) {
+                       ice_init_phy_cfg_dflt_override(pi);
+                       goto out;
+               }
+       }
+
+       /* if link default override is not enabled, initialize PHY using
+        * topology with media
+        */
        phy->curr_user_fec_req = ice_caps_to_fec_mode(pcaps->caps,
                                                      pcaps->link_fec_options);
        phy->curr_user_fc_req = ice_caps_to_fc_mode(pcaps->caps);
 
+out:
        phy->curr_user_speed_req = ICE_AQ_LINK_SPEED_M;
        set_bit(__ICE_PHY_INIT_COMPLETE, pf->state);
 err_out:
        struct device *dev = ice_pf_to_dev(vsi->back);
        struct ice_aqc_get_phy_caps_data *pcaps;
        struct ice_aqc_set_phy_cfg_data *cfg;
-       u64 phy_low = 0, phy_high = 0;
        struct ice_port_info *pi;
        enum ice_status status;
        int err = 0;
                goto done;
        }
 
-       ice_copy_phy_caps_to_cfg(pcaps, cfg);
+       ice_copy_phy_caps_to_cfg(pi, pcaps, cfg);
 
        /* Speed - If default override pending, use curr_user_phy_cfg set in
         * ice_init_phy_user_cfg_ldo.
         */
-       ice_update_phy_type(&phy_low, &phy_high, pi->phy.curr_user_speed_req);
-       cfg->phy_type_low = pcaps->phy_type_low & cpu_to_le64(phy_low);
-       cfg->phy_type_high = pcaps->phy_type_high & cpu_to_le64(phy_high);
+       if (test_and_clear_bit(__ICE_LINK_DEFAULT_OVERRIDE_PENDING,
+                              vsi->back->state)) {
+               cfg->phy_type_low = pi->phy.curr_user_phy_cfg.phy_type_low;
+               cfg->phy_type_high = pi->phy.curr_user_phy_cfg.phy_type_high;
+       } else {
+               u64 phy_low = 0, phy_high = 0;
+
+               ice_update_phy_type(&phy_low, &phy_high,
+                                   pi->phy.curr_user_speed_req);
+               cfg->phy_type_low = pcaps->phy_type_low & cpu_to_le64(phy_low);
+               cfg->phy_type_high = pcaps->phy_type_high &
+                                    cpu_to_le64(phy_high);
+       }
 
        /* Can't provide what was requested; use PHY capabilities */
        if (!cfg->phy_type_low && !cfg->phy_type_high) {
                goto err_alloc_sw_unroll;
        }
 
+       ice_init_link_dflt_override(pf->hw.port_info);
+
        /* if media available, initialize PHY settings */
        if (pf->hw.port_info->phy.link_info.link_info &
            ICE_AQ_MEDIA_AVAILABLE) {