diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 3ccba4db80..9ef4538626 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -178,6 +178,12 @@ static int ice_timesync_read_time(struct rte_eth_dev *dev,
 static int ice_timesync_write_time(struct rte_eth_dev *dev,
 				   const struct timespec *timestamp);
 static int ice_timesync_disable(struct rte_eth_dev *dev);
+static int ice_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa,
+			   unsigned int num);
+static int ice_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa);
+static int ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa);
+
+
 static const uint32_t *ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev);
 
 static const struct rte_pci_id pci_id_ice_map[] = {
@@ -294,6 +300,9 @@ static const struct eth_dev_ops ice_eth_dev_ops = {
 	.timesync_write_time          = ice_timesync_write_time,
 	.timesync_disable             = ice_timesync_disable,
 	.tm_ops_get                   = ice_tm_ops_get,
+	.fec_get_capability           = ice_fec_get_capability,
+	.fec_get                      = ice_fec_get,
+	.fec_set                      = ice_fec_set,
 	.buffer_split_supported_hdr_ptypes_get = ice_buffer_split_supported_hdr_ptypes_get,
 };
 
@@ -6513,6 +6522,172 @@ ice_buffer_split_supported_hdr_ptypes_get(struct rte_eth_dev *dev __rte_unused)
 	return ptypes;
 }
 
+static int
+ice_fec_get_capa_num(struct ice_aqc_get_phy_caps_data *pcaps, struct rte_eth_fec_capa *speed_fec_capa)
+{
+	int num = 0;
+
+	if (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC) {
+		if (speed_fec_capa)
+			speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+		num++;
+	}
+
+	if (pcaps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_EN ||
+	    pcaps->link_fec_options & ICE_AQC_PHY_FEC_10G_KR_40G_KR4_REQ ||
+	    pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_CLAUSE74_EN ||
+	    pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_KR_REQ) {
+		if (speed_fec_capa)
+			speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+		num++;
+	}
+
+	if (pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_528_REQ ||
+	    pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_544_REQ ||
+	    pcaps->link_fec_options & ICE_AQC_PHY_FEC_25G_RS_CLAUSE91_EN) {
+		if (speed_fec_capa)
+			speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+		num++;
+	}
+
+	if (pcaps->link_fec_options == 0) {
+		if (speed_fec_capa)
+			speed_fec_capa[num].capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
+		num++;
+	}
+
+	return num;
+}
+
+static int
+ice_fec_get_capability(struct rte_eth_dev *dev, struct rte_eth_fec_capa *speed_fec_capa,
+			   unsigned int num)
+{
+	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ice_aqc_get_phy_caps_data *pcaps;
+	unsigned int capa_num;
+	int ret = 0;
+
+	pcaps = (struct ice_aqc_get_phy_caps_data *)
+			ice_malloc(hw, sizeof(*pcaps));
+		if (!pcaps)
+			return ICE_ERR_NO_MEMORY;
+
+	ret = ice_aq_get_phy_caps(hw->port_info, false, ICE_AQC_REPORT_TOPO_CAP_MEDIA,
+				  pcaps, NULL);
+
+	printf("cap support: %d\n", pcaps->link_fec_options);
+	if (ret)
+		goto done;
+
+	/* first time to get capa_num */
+	capa_num = ice_fec_get_capa_num(pcaps, NULL);
+	if (!speed_fec_capa || num < capa_num) {
+		ret = capa_num;
+		goto done;
+	}
+
+	ret = ice_fec_get_capa_num(pcaps, speed_fec_capa);
+	if (ret)
+		goto done;
+
+done:
+	ice_free(hw, pcaps);
+	return ret;
+}
+static int
+ice_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
+{
+	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ice_port_info *pi = hw->port_info;
+	u32 temp_fec_capa = 0;
+	int ret = 0;
+
+	if (!pi)
+		return -ENOTSUP;
+
+	/* Get current FEC mode from port info */
+	switch (pi->phy.curr_user_fec_req) {
+	case ICE_FEC_NONE:
+		temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
+		break;
+	case ICE_FEC_AUTO:
+	case ICE_FEC_DIS_AUTO:
+		temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+		break;
+	case ICE_FEC_BASER:
+		temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+		break;
+	case ICE_FEC_RS:
+		temp_fec_capa = RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+		break;
+	default:
+		ret = -ENOTSUP;
+		break;
+	}
+	*fec_capa = temp_fec_capa;
+	return ret;
+}
+
+static int
+ice_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa)
+{
+	struct ice_hw *hw = ICE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+	struct ice_port_info *pi = hw->port_info;
+	struct ice_aqc_set_phy_cfg_data config = { 0 };
+	enum ice_fec_mode req_fec;
+	int ret = 0;
+
+	if (!pi)
+		return -ENOTSUP;
+
+	/* Copy the current user PHY configuration. The current user PHY
+	 * configuration is initialized during probe from PHY capabilities
+	 * software mode, and updated on set PHY configuration.
+	 */
+	memcpy(&config, &pi->phy.curr_user_phy_cfg, sizeof(config));
+
+	switch (fec_capa) {
+	case RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC):
+		req_fec = ICE_FEC_NONE;
+		break;
+	case RTE_ETH_FEC_MODE_CAPA_MASK(AUTO):
+		if (ice_fw_supports_fec_dis_auto(hw))
+			req_fec = ICE_FEC_DIS_AUTO;
+		else
+			req_fec = ICE_FEC_AUTO;
+		break;
+	case RTE_ETH_FEC_MODE_CAPA_MASK(BASER):
+		req_fec = ICE_FEC_BASER;
+		break;
+	case RTE_ETH_FEC_MODE_CAPA_MASK(RS):
+		req_fec = ICE_FEC_RS;
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported FEC mode: %d\n", fec_capa);
+		return -EINVAL;
+	}
+
+	ret = ice_cfg_phy_fec(pi, &config, req_fec);
+	if (ret) {
+		PMD_DRV_LOG(ERR, "Failed to set FEC mode");
+		return -EINVAL;
+	}
+
+	config.caps |= ICE_AQ_PHY_ENA_AUTO_LINK_UPDT;
+
+	if (ice_aq_set_phy_cfg(pi->hw, pi, &config, NULL))
+		return -EAGAIN;
+
+	/* Save requested FEC config */
+	pi->phy.curr_user_fec_req = req_fec;
+	printf("set current mode: %d\n", pi->phy.curr_user_fec_req);
+
+	return 0;
+}
+
+
+
 static int
 ice_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	      struct rte_pci_device *pci_dev)
