[RFC] ethdev: add Forward Error Correction support
Checks
Commit Message
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
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.
@@ -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.
@@ -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
@@ -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; */
};
/**