[RFC] ethdev: add Forward Error Correction support

Message ID 1598614332-48508-1-git-send-email-humin29@huawei.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series [RFC] ethdev: add Forward Error Correction support |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch warning coding style issues

Commit Message

humin (Q) Aug. 28, 2020, 11:32 a.m. UTC
  Hi All,

I would like to add FEC support of ethdev for DPDK.
I am planning to add this support in v20.11 release.

This RFC attempts to get feedback from the community.

In current DPDK version, Forward Error Correction(FEC) is not
supported.

Forward error correction (FEC) is a bit error correction mode.
It adds error correction information to data packets at the
transmit end, and uses the error correction information to correct
the bit errors generated during data packet transmission at the
receive end. This improves signal quality but also brings a delay
to signals. You can enable or disable this function as required.

To enable FEC support in DPDK, following items need to work out:
a) Add three API:
	rte_eth_fec_get_capability
	rte_eth_fec_get
	rte_eth_fec_set

b) Add new data structure:
	enum rte_fec_mode {
		ETH_FEC_NOFEC,
		ETH_FEC_BASER,
		ETH_FEC_RS,
		ETH_FEC_AUTO
	};

c) Add items in "struct eth_dev_ops":
	struct eth_dev_ops {
	+	eth_fec_get_capability_t fec_get_capability;
	+	/**< Get Forward Error Correction(FEC) capability; */
	+	eth_fec_get_t fec_get;
	+	/**< Get Forward Error Correction(FEC) mode; */
	+	eth_fec_set_t fec_set;
	+	/**< Set Forward Error Correction(FEC) mode; */
 };

The details are as follows:
---
 lib/librte_ethdev/rte_ethdev.c      | 33 +++++++++++++++++++
 lib/librte_ethdev/rte_ethdev.h      | 52 +++++++++++++++++++++++++++++
 lib/librte_ethdev/rte_ethdev_core.h | 65 +++++++++++++++++++++++++++++++++++++
 3 files changed, 150 insertions(+)
  

Comments

Andrew Rybchenko Aug. 30, 2020, 12:43 p.m. UTC | #1
On 8/28/20 2:32 PM, Min Hu(Connor) wrote:
> Hi All,
> 
> I would like to add FEC support of ethdev for DPDK.
> I am planning to add this support in v20.11 release.
> 
> This RFC attempts to get feedback from the community.
> 
> In current DPDK version, Forward Error Correction(FEC) is not
> supported.
> 
> Forward error correction (FEC) is a bit error correction mode.
> It adds error correction information to data packets at the
> transmit end, and uses the error correction information to correct
> the bit errors generated during data packet transmission at the
> receive end. This improves signal quality but also brings a delay
> to signals. You can enable or disable this function as required.
> 
> To enable FEC support in DPDK, following items need to work out:
> a) Add three API:
> 	rte_eth_fec_get_capability
> 	rte_eth_fec_get
> 	rte_eth_fec_set
> 
> b) Add new data structure:
> 	enum rte_fec_mode {
> 		ETH_FEC_NOFEC,
> 		ETH_FEC_BASER,
> 		ETH_FEC_RS,
> 		ETH_FEC_AUTO
> 	};
> 
> c) Add items in "struct eth_dev_ops":
> 	struct eth_dev_ops {
> 	+	eth_fec_get_capability_t fec_get_capability;
> 	+	/**< Get Forward Error Correction(FEC) capability; */
> 	+	eth_fec_get_t fec_get;
> 	+	/**< Get Forward Error Correction(FEC) mode; */
> 	+	eth_fec_set_t fec_set;
> 	+	/**< Set Forward Error Correction(FEC) mode; */
>  };
> 
> The details are as follows:

1. New API should be experimental with corresponding markup.

2. FEC capabilities may depend on link speed if I'm not
   mistaken and it should be properly reported in capabilities.

3. Hopefully Ferruh's patches will make the dev_ops structure
   ethdev internal and these additions could be done in 20.11.

4. Format in mode_mask is not defined below.
  

Patch

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 7858ad5..0a96718 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -3642,6 +3642,39 @@  rte_eth_led_off(uint16_t port_id)
 	return eth_err(port_id, (*dev->dev_ops->dev_led_off)(dev));
 }
 
+void
+rte_eth_fec_get_capability(uint16_t port_id, int *mode_mask)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_RET(port_id);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_RET(*dev->dev_ops->fec_get_capability);
+	(*dev->dev_ops->fec_get_capability)(dev, mode_mask);
+}
+
+int
+rte_eth_fec_get(uint16_t port_id, enum rte_fec_mode *mode)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_get, -ENOTSUP);
+	return eth_err(port_id, (*dev->dev_ops->fec_get)(dev, mode));
+}
+
+int
+rte_eth_fec_set(uint16_t port_id, enum rte_fec_mode mode)
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fec_set, -ENOTSUP);
+	return eth_err(port_id, (*dev->dev_ops->fec_set)(dev, mode));
+}
+
 /*
  * Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
  * an empty spot.
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 70295d7..ff82771 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -1511,6 +1511,17 @@  struct rte_eth_dcb_info {
 	struct rte_eth_dcb_tc_queue_mapping tc_queue;
 };
 
+/**
+ * This enum indicates the possible FEC modes
+ * of an ethdev port.
+ */
+enum rte_fec_mode {
+	ETH_FEC_NOFEC,
+	ETH_FEC_BASER,
+	ETH_FEC_RS,
+	ETH_FEC_AUTO
+};
+
 #define RTE_ETH_ALL RTE_MAX_ETHPORTS
 
 /* Macros to check for valid port */
@@ -3328,6 +3339,47 @@  int  rte_eth_led_on(uint16_t port_id);
 int  rte_eth_led_off(uint16_t port_id);
 
 /**
+ * Get Forward Error Correction(FEC) capability.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param mode_mask
+ *   returns the FEC capability from the device.
+ */
+void rte_eth_fec_get_capability(uint16_t port_id, int *mode_mask);
+
+/**
+ * Get Forward Error Correction(FEC) mode.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param mode
+ *   returns the FEC mode from the device.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if underlying hardware OR driver doesn't support
+ *     that operation.
+ *   - (-EBUSY) if device is in resetting.
+ *   - (-ENOMEM) if device unable to allocate resources.
+ */
+int rte_eth_fec_get(uint16_t port_id, enum rte_fec_mode *mode);
+
+/**
+ * Set Forward Error Correction(FEC) mode.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param mode
+ *   the FEC mode.
+ * @return
+ *   - (0) if successful.
+ *   - (-EINVAL) if the FEC mode is not valid.
+ *   - (-EBUSY) if device is in resetting.
+ *   - (-ENOMEM) if device unable to allocate resources.
+ */
+int rte_eth_fec_set(uint16_t port_id, enum rte_fec_mode mode);
+
+/**
  * Get current status of the Ethernet link flow control for Ethernet device
  *
  * @param port_id
diff --git a/lib/librte_ethdev/rte_ethdev_core.h b/lib/librte_ethdev/rte_ethdev_core.h
index 32407dd..1f2c414 100644
--- a/lib/librte_ethdev/rte_ethdev_core.h
+++ b/lib/librte_ethdev/rte_ethdev_core.h
@@ -604,6 +604,64 @@  typedef int (*eth_tx_hairpin_queue_setup_t)
 	 const struct rte_eth_hairpin_conf *hairpin_conf);
 
 /**
+ * @internal
+ * Get Forward Error Correction(FEC) capability.
+ *
+ * @param dev
+ *   ethdev handle of port.
+ * @param mode_mask
+ *   returns the FEC capability from the device.
+ */
+typedef void (*eth_fec_get_capability_t)(struct rte_eth_dev *dev,
+					   int *mode_mask);
+
+/**
+ * @internal
+ * Get Forward Error Correction(FEC) mode.
+ *
+ * @param dev
+ *   ethdev handle of port.
+ * @param mode
+ *   returns the FEC mode from the device.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ *
+ * @retval 0
+ *   Success, get FEC success.
+ * @retval -EOPNOTSUPP
+ *   opreation is not supported.
+ * @retval -EBUSY
+ *   detect device is in resetting
+ * @retval -ENOMEM
+ *   Unable to allocate resources.
+ */
+typedef int (*eth_fec_get_t)(struct rte_eth_dev *dev, enum rte_fec_mode *mode);
+
+/**
+ * @internal
+ *   Set Forward Error Correction(FEC) mode.
+ *
+ * @param dev
+ *   ethdev handle of port.
+ * @param mode
+ *   the FEC mode.
+ *
+ * @return
+ *   Negative errno value on error, 0 on success.
+ *
+ * @retval 0
+ *   Success, set FEC success.
+ * @retval -EINVAL
+ *   the FEC mode is not valid.
+ * @retval -EBUSY
+ *   detect device is in resetting
+ * @retval -ENOMEM
+ *   Unable to allocate resources.
+ */
+typedef int (*eth_fec_set_t)(struct rte_eth_dev *dev, enum rte_fec_mode mode);
+
+/**
  * @internal A structure containing the functions exported by an Ethernet driver.
  */
 struct eth_dev_ops {
@@ -752,6 +810,13 @@  struct eth_dev_ops {
 	/**< Set up device RX hairpin queue. */
 	eth_tx_hairpin_queue_setup_t tx_hairpin_queue_setup;
 	/**< Set up device TX hairpin queue. */
+
+	eth_fec_get_capability_t fec_get_capability;
+	/**< Get Forward Error Correction(FEC) capability; */
+	eth_fec_get_t fec_get;
+	/**< Get Forward Error Correction(FEC) mode; */
+	eth_fec_set_t fec_set;
+	/**< Set Forward Error Correction(FEC) mode; */
 };
 
 /**