DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH] net/ice: support FEC feature
@ 2024-04-11  9:45 Mingjin Ye
  0 siblings, 0 replies; 3+ messages in thread
From: Mingjin Ye @ 2024-04-11  9:45 UTC (permalink / raw)
  To: dev; +Cc: Mingjin Ye

This patch enable three Forward Error Correction(FEC) related ops
in ice driver. As no speed information can get from HW, this patch
only show FEC capability.

Signed-off-by: Mingjin Ye <mingjinx.ye@intel.com>
---
 doc/guides/nics/features/ice.ini |   1 +
 doc/guides/nics/ice.rst          |   5 +
 drivers/net/ice/ice_ethdev.c     | 176 +++++++++++++++++++++++++++++++
 3 files changed, 182 insertions(+)

diff --git a/doc/guides/nics/features/ice.ini b/doc/guides/nics/features/ice.ini
index 62869ef0a0..a9be394696 100644
--- a/doc/guides/nics/features/ice.ini
+++ b/doc/guides/nics/features/ice.ini
@@ -9,6 +9,7 @@
 [Features]
 Speed capabilities   = Y
 Link speed configuration = Y
+FEC                  = Y
 Link status          = Y
 Link status event    = Y
 Rx interrupt         = Y
diff --git a/doc/guides/nics/ice.rst b/doc/guides/nics/ice.rst
index 3deeea9e6c..3d7e4ed7f1 100644
--- a/doc/guides/nics/ice.rst
+++ b/doc/guides/nics/ice.rst
@@ -323,6 +323,11 @@ The DCF PMD needs to advertise and acquire DCF capability which allows DCF to
 send AdminQ commands that it would like to execute over to the PF and receive
 responses for the same from PF.
 
+Forward Error Correction (FEC)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Supports get/set FEC mode and get FEC capability.
+
 Generic Flow Support
 ~~~~~~~~~~~~~~~~~~~~
 
diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c
index 87385d2649..56d0f2bb28 100644
--- a/drivers/net/ice/ice_ethdev.c
+++ b/drivers/net/ice/ice_ethdev.c
@@ -181,6 +181,10 @@ 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,
 						size_t *no_of_elements);
 
@@ -298,6 +302,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,
 };
 
@@ -6644,6 +6651,175 @@ 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)
+		return ICE_ERR_NO_MEMORY;
+
+	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;
+
+	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);
+	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);
+
+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;
+
+	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;
+	}
+
+	/* Proceed only if requesting different FEC mode */
+	if (pi->phy.curr_user_fec_req == req_fec)
+		return 0;
+
+	/* 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));
+
+	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;
+
+	return 0;
+}
+
 static int
 ice_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	      struct rte_pci_device *pci_dev)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH] net/ice: support FEC feature
  2023-12-11  4:22 Qiming Yang
@ 2024-01-02  4:33 ` Zhang, Qi Z
  0 siblings, 0 replies; 3+ messages in thread
From: Zhang, Qi Z @ 2024-01-02  4:33 UTC (permalink / raw)
  To: Yang, Qiming, dev



> -----Original Message-----
> From: Yang, Qiming <qiming.yang@intel.com>
> Sent: Monday, December 11, 2023 12:23 PM
> To: dev@dpdk.org
> Cc: Zhang, Qi Z <qi.z.zhang@intel.com>; Yang, Qiming
> <qiming.yang@intel.com>
> Subject: [PATCH] net/ice: support FEC feature
> 
> This patch enable three FEC related ops in ice driver. As no speed information
> can get from HW, this patch only show FEC capability.
> 
> Signed-off-by: Qiming Yang <qiming.yang@intel.com>

Please also update the document

FEC                  = Y



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] net/ice: support FEC feature
@ 2023-12-11  4:22 Qiming Yang
  2024-01-02  4:33 ` Zhang, Qi Z
  0 siblings, 1 reply; 3+ messages in thread
From: Qiming Yang @ 2023-12-11  4:22 UTC (permalink / raw)
  To: dev; +Cc: qi.z.zhang, Qiming Yang

This patch enable three FEC related ops in ice driver. As no speed
information can get from HW, this patch only show FEC capability.

Signed-off-by: Qiming Yang <qiming.yang@intel.com>
---
 drivers/net/ice/ice_ethdev.c | 175 +++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

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)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-04-11 10:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-11  9:45 [PATCH] net/ice: support FEC feature Mingjin Ye
  -- strict thread matches above, loose matches on Subject: below --
2023-12-11  4:22 Qiming Yang
2024-01-02  4:33 ` Zhang, Qi Z

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).