[PATCH 2/2] net/cnxk: add FEC get set and capability ops
rkudurumalla
rkudurumalla at marvell.com
Thu Apr 16 14:00:31 CEST 2026
From: Rakesh Kudurumalla <rkudurumalla at marvell.com>
Add ethdev FEC operations for cnxk NIX driver:
- fec_get_capability: Report supported FEC modes per speed.
If firmware provides supported FEC info, return actual
capabilities for current link speed. Otherwise, fall back
to a default capability table for common speeds.
- fec_get: Query current FEC mode from link info
- fec_set: Configure FEC mode on the link. AUTO mode
defaults to Reed-Solomon FEC.
Signed-off-by: Rakesh Kudurumalla <rkudurumalla at marvell.com>
---
drivers/net/cnxk/cnxk_ethdev.c | 3 +
drivers/net/cnxk/cnxk_ethdev.h | 6 ++
drivers/net/cnxk/cnxk_ethdev_ops.c | 94 ++++++++++++++++++++++++++++++
3 files changed, 103 insertions(+)
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 06d1c9b362..1cb0dd5bf1 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -2138,6 +2138,9 @@ struct eth_dev_ops cnxk_eth_dev_ops = {
.cman_config_set = cnxk_nix_cman_config_set,
.cman_config_get = cnxk_nix_cman_config_get,
.eth_tx_descriptor_dump = cnxk_nix_tx_descriptor_dump,
+ .fec_get_capability = cnxk_nix_fec_get_capability,
+ .fec_get = cnxk_nix_fec_get,
+ .fec_set = cnxk_nix_fec_set,
};
void
diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h
index 8691acc642..b1078397d3 100644
--- a/drivers/net/cnxk/cnxk_ethdev.h
+++ b/drivers/net/cnxk/cnxk_ethdev.h
@@ -660,6 +660,12 @@ int cnxk_nix_tm_mark_ip_dscp(struct rte_eth_dev *eth_dev, int mark_green,
int cnxk_nix_tx_descriptor_dump(const struct rte_eth_dev *eth_dev, uint16_t qid, uint16_t offset,
uint16_t num, FILE *file);
+/* FEC */
+int cnxk_nix_fec_get_capability(struct rte_eth_dev *eth_dev,
+ struct rte_eth_fec_capa *speed_fec_capa, unsigned int num);
+int cnxk_nix_fec_get(struct rte_eth_dev *eth_dev, uint32_t *fec_capa);
+int cnxk_nix_fec_set(struct rte_eth_dev *eth_dev, uint32_t fec_capa);
+
/* MTR */
int cnxk_nix_mtr_ops_get(struct rte_eth_dev *dev, void *ops);
diff --git a/drivers/net/cnxk/cnxk_ethdev_ops.c b/drivers/net/cnxk/cnxk_ethdev_ops.c
index 49e77e49a6..a45721d414 100644
--- a/drivers/net/cnxk/cnxk_ethdev_ops.c
+++ b/drivers/net/cnxk/cnxk_ethdev_ops.c
@@ -1414,3 +1414,97 @@ cnxk_nix_tx_descriptor_dump(const struct rte_eth_dev *eth_dev, uint16_t qid, uin
return roc_nix_sq_desc_dump(nix, qid, offset, num, file);
}
+
+static uint32_t
+cnxk_roc_fec_to_ethdev_capa(int roc_fec)
+{
+ switch (roc_fec) {
+ case ROC_FEC_BASER:
+ return RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ case ROC_FEC_RS:
+ return RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ default:
+ return RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC);
+ }
+}
+
+static int
+cnxk_ethdev_fec_to_roc(uint32_t fec_capa)
+{
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(RS))
+ return ROC_FEC_RS;
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(BASER))
+ return ROC_FEC_BASER;
+ return ROC_FEC_NONE;
+}
+
+static uint32_t
+cnxk_fec_capa_from_supported(uint64_t supported_fec)
+{
+ uint32_t capa = RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) | RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+
+ if (supported_fec & (1ULL << ROC_FEC_BASER))
+ capa |= RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ if (supported_fec & (1ULL << ROC_FEC_RS))
+ capa |= RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+
+ return capa;
+}
+
+int
+cnxk_nix_fec_get_capability(struct rte_eth_dev *eth_dev, struct rte_eth_fec_capa *speed_fec_capa,
+ unsigned int num)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *nix = &dev->nix;
+ struct roc_nix_link_info link_info;
+ uint64_t supported_fec = 0;
+ int rc;
+
+ rc = roc_nix_mac_fec_supported_get(nix, &supported_fec);
+ if (rc == 0 && supported_fec != 0) {
+ rc = roc_nix_mac_link_info_get(nix, &link_info);
+ if (rc)
+ return rc;
+
+ if (speed_fec_capa == NULL || num == 0)
+ return 1;
+
+ speed_fec_capa[0].speed = link_info.speed;
+ speed_fec_capa[0].capa = cnxk_fec_capa_from_supported(supported_fec);
+ return 1;
+ }
+
+ return rc;
+}
+
+int
+cnxk_nix_fec_get(struct rte_eth_dev *eth_dev, uint32_t *fec_capa)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *nix = &dev->nix;
+ struct roc_nix_link_info link_info;
+ int rc;
+
+ rc = roc_nix_mac_link_info_get(nix, &link_info);
+ if (rc)
+ return rc;
+
+ *fec_capa = cnxk_roc_fec_to_ethdev_capa(link_info.fec);
+ return 0;
+}
+
+int
+cnxk_nix_fec_set(struct rte_eth_dev *eth_dev, uint32_t fec_capa)
+{
+ struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev);
+ struct roc_nix *nix = &dev->nix;
+ int roc_fec;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_CAPA_MASK(AUTO))
+ roc_fec = ROC_FEC_RS;
+ else
+ roc_fec = cnxk_ethdev_fec_to_roc(fec_capa);
+
+ return roc_nix_mac_fec_set(nix, roc_fec);
+}
--
2.25.1
More information about the dev
mailing list