* [PATCH 0/3] net/sfc: support FEC feature
@ 2023-06-01 22:23 Denis Pryazhennikov
2023-06-01 22:23 ` [PATCH 1/3] net/sfc: split link update function Denis Pryazhennikov
` (3 more replies)
0 siblings, 4 replies; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-01 22:23 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko
This patch series adds setting and querying of Forward error
correction (FEC). AUTO, BASER and RS modes are supported
by EF10/EF100 hardware. LLRS mode is not supported.
Denis Pryazhennikov (3):
net/sfc: split link update function
common/sfc_efx/base: add FEC related macros
net/sfc: support FEC feature
doc/guides/nics/features/sfc.ini | 1 +
drivers/common/sfc_efx/base/efx.h | 9 +
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 365 +++++++++++++++++++++++++++++-
drivers/net/sfc/sfc_port.c | 24 +-
5 files changed, 381 insertions(+), 20 deletions(-)
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 1/3] net/sfc: split link update function
2023-06-01 22:23 [PATCH 0/3] net/sfc: support FEC feature Denis Pryazhennikov
@ 2023-06-01 22:23 ` Denis Pryazhennikov
2023-06-02 8:52 ` Andrew Rybchenko
2023-06-01 22:23 ` [PATCH 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
` (2 subsequent siblings)
3 siblings, 1 reply; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-01 22:23 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko, Ivan Malov, Andy Moreton
Separate the original link update function into
two functions: state retrieval and update.
This improves code clarity and maintainability.
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
drivers/net/sfc/sfc_ethdev.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 320043145495..6d41eb000345 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -248,28 +248,38 @@ sfc_dev_start(struct rte_eth_dev *dev)
return -rc;
}
-static int
-sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+static void
+sfc_dev_get_rte_link(struct rte_eth_dev *dev, int wait_to_complete,
+ struct rte_eth_link *link)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
- struct rte_eth_link current_link;
- int ret;
- sfc_log_init(sa, "entry");
+ SFC_ASSERT(link != NULL);
if (sa->state != SFC_ETHDEV_STARTED) {
- sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, ¤t_link);
+ sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, link);
} else if (wait_to_complete) {
efx_link_mode_t link_mode;
if (efx_port_poll(sa->nic, &link_mode) != 0)
link_mode = EFX_LINK_UNKNOWN;
- sfc_port_link_mode_to_info(link_mode, ¤t_link);
-
+ sfc_port_link_mode_to_info(link_mode, link);
} else {
sfc_ev_mgmt_qpoll(sa);
- rte_eth_linkstatus_get(dev, ¤t_link);
+ rte_eth_linkstatus_get(dev, link);
}
+}
+
+static int
+sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct rte_eth_link current_link;
+ int ret;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_dev_get_rte_link(dev, wait_to_complete, ¤t_link);
ret = rte_eth_linkstatus_set(dev, ¤t_link);
if (ret == 0)
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 2/3] common/sfc_efx/base: add FEC related macros
2023-06-01 22:23 [PATCH 0/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-01 22:23 ` [PATCH 1/3] net/sfc: split link update function Denis Pryazhennikov
@ 2023-06-01 22:23 ` Denis Pryazhennikov
2023-06-02 8:53 ` Andrew Rybchenko
2023-06-01 22:23 ` [PATCH 3/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
3 siblings, 1 reply; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-01 22:23 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko, Andy Moreton
Added new macros to simplify working with FEC bits
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
drivers/common/sfc_efx/base/efx.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
index 49e29dcc1c69..10c412bcd7dc 100644
--- a/drivers/common/sfc_efx/base/efx.h
+++ b/drivers/common/sfc_efx/base/efx.h
@@ -3958,6 +3958,15 @@ typedef enum efx_phy_fec_type_e {
EFX_PHY_FEC_RS
} efx_phy_fec_type_t;
+#define EFX_PHY_CAP_FEC_BIT(_fec_bit) (1U << EFX_PHY_CAP_##_fec_bit)
+#define EFX_PHY_CAP_FEC_MASK \
+ (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED) | \
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED) | \
+ EFX_PHY_CAP_FEC_BIT(RS_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED))
+
LIBEFX_API
extern __checkReturn efx_rc_t
efx_phy_fec_type_get(
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH 3/3] net/sfc: support FEC feature
2023-06-01 22:23 [PATCH 0/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-01 22:23 ` [PATCH 1/3] net/sfc: split link update function Denis Pryazhennikov
2023-06-01 22:23 ` [PATCH 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
@ 2023-06-01 22:23 ` Denis Pryazhennikov
2023-06-02 9:09 ` Andrew Rybchenko
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
3 siblings, 1 reply; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-01 22:23 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko, Ivan Malov, Andy Moreton
Support ethdev methods to query and set FEC information.
Limitations: ignoring rte_eth_fec_get_capability() results
can lead to NOFEC if the device is not strated.
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
doc/guides/nics/features/sfc.ini | 1 +
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 337 +++++++++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 24 ++-
4 files changed, 353 insertions(+), 11 deletions(-)
diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini
index f5ac644278ae..e0b9bfb7f7bf 100644
--- a/doc/guides/nics/features/sfc.ini
+++ b/doc/guides/nics/features/sfc.ini
@@ -24,6 +24,7 @@ RSS reta update = Y
SR-IOV = Y
Flow control = Y
VLAN offload = P
+FEC = Y
L3 checksum offload = Y
L4 checksum offload = Y
Inner L3 checksum = Y
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 730d054aea74..e42abe42cb8a 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -68,6 +68,8 @@ struct sfc_port {
uint32_t phy_adv_cap_mask;
uint32_t phy_adv_cap;
+ uint32_t fec_cfg;
+ bool fec_auto;
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6d41eb000345..05fc70541b10 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -2343,6 +2343,340 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features)
return 0;
}
+static unsigned int
+sfc_fec_get_capa_speed_to_fec(uint32_t supported_caps,
+ struct rte_eth_fec_capa *speed_fec_capa)
+{
+ int num = 0;
+
+ if (supported_caps & (1u << EFX_PHY_CAP_10000FDX)) {
+ if (speed_fec_capa) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_10G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_25000FDX)) {
+ if (speed_fec_capa) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_40000FDX)) {
+ if (speed_fec_capa) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_40G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_50000FDX)) {
+ if (speed_fec_capa) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_50G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_100000FDX)) {
+ if (speed_fec_capa) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_100G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ num++;
+ }
+
+ return num;
+}
+
+static int
+sfc_fec_get_capability(struct rte_eth_dev *dev,
+ struct rte_eth_fec_capa *speed_fec_capa,
+ unsigned int num)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ unsigned int num_entries;
+ uint32_t supported_caps;
+
+ sfc_adapter_lock(sa);
+
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
+ if (!speed_fec_capa || num < num_entries)
+ goto adapter_unlock;
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
+ speed_fec_capa);
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ return num_entries;
+}
+
+static uint32_t
+sfc_efx_caps_to_fec(uint32_t caps, bool is_25g)
+{
+ bool rs_req = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
+ bool rs = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC);
+ uint32_t fec_capa = 0;
+ bool baser_req;
+ bool baser;
+
+ if (is_25g) {
+ baser = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC);
+ baser_req = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
+ } else {
+ baser = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC);
+ baser_req = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
+ }
+
+ if (!baser && !rs)
+ return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
+
+ if (rs_req)
+ fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
+
+ if (baser_req)
+ fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
+
+
+ return fec_capa;
+}
+
+static int
+sfc_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct sfc_port *port = &sa->port;
+ struct rte_eth_link current_link;
+ efx_phy_fec_type_t active_fec;
+ bool is_25g = false;
+ int rc = 0;
+
+ sfc_adapter_lock(sa);
+
+ sfc_dev_get_rte_link(dev, 1, ¤t_link);
+
+ if (current_link.link_status == RTE_ETH_LINK_DOWN) {
+ uint32_t speed = current_link.link_speed;
+
+ if (port->fec_auto) {
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
+ goto adapter_unlock;
+ }
+
+ is_25g = (speed == RTE_ETH_SPEED_NUM_25G ||
+ speed == RTE_ETH_SPEED_NUM_50G);
+
+ *fec_capa = sfc_efx_caps_to_fec(port->fec_cfg, is_25g);
+
+ goto adapter_unlock;
+ }
+
+ rc = efx_phy_fec_type_get(sa->nic, &active_fec);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ switch (active_fec) {
+ case EFX_PHY_FEC_NONE:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
+ break;
+ case EFX_PHY_FEC_BASER:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
+ break;
+ case EFX_PHY_FEC_RS:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
+ break;
+ default:
+ break;
+ }
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ return rc;
+}
+
+static int
+sfc_fec_capa_check(struct rte_eth_dev *dev, uint32_t fec_capa,
+ uint32_t supported_caps)
+{
+ struct rte_eth_fec_capa *speed_fec_capa;
+ struct rte_eth_link current_link;
+ bool is_supported = false;
+ unsigned int num_entries;
+ bool auto_fec = false;
+ unsigned int i;
+
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+
+ if (sa->state != SFC_ETHDEV_STARTED)
+ return 0;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
+ auto_fec = true;
+ fec_capa &= ~RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
+ }
+
+ /*
+ * If only the AUTO bit is set, the decision on which FEC
+ * mode to use will be made by HW/FW or driver.
+ */
+ if (auto_fec && fec_capa == 0)
+ return 0;
+
+ sfc_dev_get_rte_link(dev, 1, ¤t_link);
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
+ if (num_entries == 0)
+ return -ENOTSUP;
+
+ speed_fec_capa = rte_calloc("fec_capa", num_entries,
+ sizeof(*speed_fec_capa), 0);
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
+ speed_fec_capa);
+
+ for (i = 0; i < num_entries; i++) {
+ if (speed_fec_capa[i].speed == current_link.link_speed) {
+ if ((fec_capa & speed_fec_capa[i].capa) != 0)
+ is_supported = true;
+
+ break;
+ }
+ }
+
+ rte_free(speed_fec_capa);
+
+ if (is_supported)
+ return 0;
+
+ return -ENOTSUP;
+}
+
+static int
+sfc_fec_capa_to_efx(uint32_t supported_caps, uint32_t fec_capa,
+ uint32_t *efx_fec_caps)
+{
+ bool fec_is_set = false;
+ bool auto_fec = false;
+ bool nofec = false;
+ uint32_t ret = 0;
+
+ if (efx_fec_caps == NULL)
+ return -EINVAL;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
+ auto_fec = true;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC))
+ nofec = true;
+
+ if (fec_capa == RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
+ ret |= (EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC)) & supported_caps;
+ goto done;
+ }
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS)) {
+ fec_is_set = true;
+
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(RS_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
+ }
+ }
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER)) {
+ if (!auto_fec && fec_is_set)
+ return -EINVAL;
+
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
+ }
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
+ }
+ }
+
+ if (ret == 0 && !nofec)
+ return -ENOTSUP;
+
+done:
+ *efx_fec_caps = ret;
+ return 0;
+}
+
+static int
+sfc_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct sfc_port *port = &sa->port;
+ uint32_t supported_caps;
+ uint32_t efx_fec_caps;
+ uint32_t updated_caps;
+ int rc = 0;
+
+ sfc_adapter_lock(sa);
+
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
+
+ rc = sfc_fec_capa_check(dev, fec_capa, supported_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ rc = sfc_fec_capa_to_efx(supported_caps, fec_capa, &efx_fec_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ if (sa->state == SFC_ETHDEV_STARTED) {
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT,
+ &updated_caps);
+ updated_caps = updated_caps & ~EFX_PHY_CAP_FEC_MASK;
+ updated_caps |= efx_fec_caps;
+
+ rc = efx_phy_adv_cap_set(sa->nic, updated_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+ }
+
+ port->fec_cfg = efx_fec_caps;
+ /*
+ * There is no chance to recognize AUTO mode from the
+ * saved FEC capabilities as AUTO mode can have the same
+ * set of bits as any other mode from the EFX point of view.
+ * Save it in the proper variable.
+ */
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
+ port->fec_auto = true;
+ else
+ port->fec_auto = false;
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ return rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -2392,6 +2726,9 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.pool_ops_supported = sfc_pool_ops_supported,
.representor_info_get = sfc_representor_info_get,
.rx_metadata_negotiate = sfc_rx_metadata_negotiate,
+ .fec_get_capability = sfc_fec_get_capability,
+ .fec_get = sfc_fec_get,
+ .fec_set = sfc_fec_set,
};
struct sfc_ethdev_init_data {
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 5f312ab1ba83..0c887ddedb09 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -228,17 +228,8 @@ sfc_port_start(struct sfc_adapter *sa)
/* Preserve pause capabilities set by above efx_mac_fcntl_set() */
efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, &phy_adv_cap);
SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0);
- phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps);
-
- /*
- * No controls for FEC yet. Use default FEC mode.
- * I.e. advertise everything supported (*_FEC=1), but do not request
- * anything explicitly (*_FEC_REQUESTED=0).
- */
- phy_adv_cap |= port->phy_adv_cap_mask &
- (1u << EFX_PHY_CAP_BASER_FEC |
- 1u << EFX_PHY_CAP_RS_FEC |
- 1u << EFX_PHY_CAP_25G_BASER_FEC);
+ phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps) |
+ port->fec_cfg;
sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap);
rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap);
@@ -469,6 +460,17 @@ sfc_port_attach(struct sfc_adapter *sa)
port->mac_stats_update_period_ms = kvarg_stats_update_period_ms;
+ /*
+ * Set default FEC mode.
+ * I.e. advertise everything supported (*_FEC=1), but do not request
+ * anything explicitly (*_FEC_REQUESTED=0).
+ */
+ port->fec_cfg = port->phy_adv_cap_mask &
+ (EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC));
+ port->fec_auto = true;
+
sfc_log_init(sa, "done");
return 0;
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/3] net/sfc: split link update function
2023-06-01 22:23 ` [PATCH 1/3] net/sfc: split link update function Denis Pryazhennikov
@ 2023-06-02 8:52 ` Andrew Rybchenko
2023-06-20 11:25 ` Ferruh Yigit
0 siblings, 1 reply; 17+ messages in thread
From: Andrew Rybchenko @ 2023-06-02 8:52 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Ferruh Yigit, Ivan Malov, Andy Moreton
On 6/2/23 01:23, Denis Pryazhennikov wrote:
> Separate the original link update function into
> two functions: state retrieval and update.
> This improves code clarity and maintainability.
>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 2/3] common/sfc_efx/base: add FEC related macros
2023-06-01 22:23 ` [PATCH 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
@ 2023-06-02 8:53 ` Andrew Rybchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andrew Rybchenko @ 2023-06-02 8:53 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Ferruh Yigit, Andy Moreton
On 6/2/23 01:23, Denis Pryazhennikov wrote:
> Added new macros to simplify working with FEC bits
Full stop missing above.
>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 3/3] net/sfc: support FEC feature
2023-06-01 22:23 ` [PATCH 3/3] net/sfc: support FEC feature Denis Pryazhennikov
@ 2023-06-02 9:09 ` Andrew Rybchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andrew Rybchenko @ 2023-06-02 9:09 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Ferruh Yigit, Ivan Malov, Andy Moreton
On 6/2/23 01:23, Denis Pryazhennikov wrote:
> Support ethdev methods to query and set FEC information.
> Limitations: ignoring rte_eth_fec_get_capability() results
> can lead to NOFEC if the device is not strated.
>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
> ---
> doc/guides/nics/features/sfc.ini | 1 +
> drivers/net/sfc/sfc.h | 2 +
> drivers/net/sfc/sfc_ethdev.c | 337 +++++++++++++++++++++++++++++++
> drivers/net/sfc/sfc_port.c | 24 ++-
> 4 files changed, 353 insertions(+), 11 deletions(-)
Let's advertise it in release notes.
>
> diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini
> index f5ac644278ae..e0b9bfb7f7bf 100644
> --- a/doc/guides/nics/features/sfc.ini
> +++ b/doc/guides/nics/features/sfc.ini
> @@ -24,6 +24,7 @@ RSS reta update = Y
> SR-IOV = Y
> Flow control = Y
> VLAN offload = P
> +FEC = Y
> L3 checksum offload = Y
> L4 checksum offload = Y
> Inner L3 checksum = Y
> diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
> index 730d054aea74..e42abe42cb8a 100644
> --- a/drivers/net/sfc/sfc.h
> +++ b/drivers/net/sfc/sfc.h
> @@ -68,6 +68,8 @@ struct sfc_port {
>
> uint32_t phy_adv_cap_mask;
> uint32_t phy_adv_cap;
> + uint32_t fec_cfg;
> + bool fec_auto;
>
> unsigned int flow_ctrl;
> boolean_t flow_ctrl_autoneg;
> diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
> index 6d41eb000345..05fc70541b10 100644
> --- a/drivers/net/sfc/sfc_ethdev.c
> +++ b/drivers/net/sfc/sfc_ethdev.c
> @@ -2343,6 +2343,340 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features)
> return 0;
> }
>
> +static unsigned int
> +sfc_fec_get_capa_speed_to_fec(uint32_t supported_caps,
> + struct rte_eth_fec_capa *speed_fec_capa)
> +{
> + int num = 0;
> +
> + if (supported_caps & (1u << EFX_PHY_CAP_10000FDX)) {
> + if (speed_fec_capa) {
Compare vs NULL as DPDK coding style says. Here and in similar cases below.
> + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_10G;
> + speed_fec_capa[num].capa =
> + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
I'd like to see a comment which explicilty says that supported
FEC depends on supported link speed only. So, there is no
special capability bits.
> + }
> + num++;
> + }
> + if (supported_caps & (1u << EFX_PHY_CAP_25000FDX)) {
> + if (speed_fec_capa) {
> + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G;
> + speed_fec_capa[num].capa =
> + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(RS);
> + }
> + num++;
> + }
> + if (supported_caps & (1u << EFX_PHY_CAP_40000FDX)) {
> + if (speed_fec_capa) {
> + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_40G;
> + speed_fec_capa[num].capa =
> + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
> + }
> + num++;
> + }
> + if (supported_caps & (1u << EFX_PHY_CAP_50000FDX)) {
> + if (speed_fec_capa) {
> + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_50G;
> + speed_fec_capa[num].capa =
> + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(BASER) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(RS);
> + }
> + num++;
> + }
> + if (supported_caps & (1u << EFX_PHY_CAP_100000FDX)) {
> + if (speed_fec_capa) {
> + speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_100G;
> + speed_fec_capa[num].capa =
> + RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(AUTO) |
> + RTE_ETH_FEC_MODE_CAPA_MASK(RS);
> + }
> + num++;
> + }
> +
> + return num;
> +}
> +
> +static int
> +sfc_fec_get_capability(struct rte_eth_dev *dev,
> + struct rte_eth_fec_capa *speed_fec_capa,
> + unsigned int num)
> +{
> + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
> + unsigned int num_entries;
> + uint32_t supported_caps;
> +
> + sfc_adapter_lock(sa);
> +
> + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
> +
> + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
> + if (!speed_fec_capa || num < num_entries)
Compare vs NULL as DPDK coding style says.
> + goto adapter_unlock;
> +
> + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
> + speed_fec_capa);
> +
> +adapter_unlock:
> + sfc_adapter_unlock(sa);
> +
> + return num_entries;
> +}
> +
> +static uint32_t
> +sfc_efx_caps_to_fec(uint32_t caps, bool is_25g)
> +{
> + bool rs_req = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
> + bool rs = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC);
> + uint32_t fec_capa = 0;
> + bool baser_req;
> + bool baser;
> +
> + if (is_25g) {
> + baser = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC);
> + baser_req = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
> + } else {
> + baser = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC);
> + baser_req = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
> + }
> +
> + if (!baser && !rs)
> + return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
> +
> + if (rs_req)
> + fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
> +
> + if (baser_req)
> + fec_capa |= RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
> +
> +
two many empty lines, just one is sufficient
> + return fec_capa;
> +}
> +
> +static int
> +sfc_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
> +{
> + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
> + struct sfc_port *port = &sa->port;
> + struct rte_eth_link current_link;
> + efx_phy_fec_type_t active_fec;
> + bool is_25g = false;
> + int rc = 0;
> +
> + sfc_adapter_lock(sa);
> +
> + sfc_dev_get_rte_link(dev, 1, ¤t_link);
> +
> + if (current_link.link_status == RTE_ETH_LINK_DOWN) {
> + uint32_t speed = current_link.link_speed;
> +
> + if (port->fec_auto) {
> + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
> + goto adapter_unlock;
> + }
> +
> + is_25g = (speed == RTE_ETH_SPEED_NUM_25G ||
> + speed == RTE_ETH_SPEED_NUM_50G);
> +
> + *fec_capa = sfc_efx_caps_to_fec(port->fec_cfg, is_25g);
> +
> + goto adapter_unlock;
> + }
> +
> + rc = efx_phy_fec_type_get(sa->nic, &active_fec);
> + if (rc != 0)
> + goto adapter_unlock;
> +
> + switch (active_fec) {
> + case EFX_PHY_FEC_NONE:
> + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
> + break;
> + case EFX_PHY_FEC_BASER:
> + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
> + break;
> + case EFX_PHY_FEC_RS:
> + *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
> + break;
> + default:
Don't we need an error message here and return failure?
> + break;
> + }
> +
> +adapter_unlock:
> + sfc_adapter_unlock(sa);
> +
> + return rc;
> +}
> +
> +static int
> +sfc_fec_capa_check(struct rte_eth_dev *dev, uint32_t fec_capa,
> + uint32_t supported_caps)
> +{
> + struct rte_eth_fec_capa *speed_fec_capa;
> + struct rte_eth_link current_link;
> + bool is_supported = false;
> + unsigned int num_entries;
> + bool auto_fec = false;
> + unsigned int i;
> +
> + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
> +
> + if (sa->state != SFC_ETHDEV_STARTED)
> + return 0;
> +
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
> + auto_fec = true;
> + fec_capa &= ~RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
> + }
> +
> + /*
> + * If only the AUTO bit is set, the decision on which FEC
> + * mode to use will be made by HW/FW or driver.
> + */
> + if (auto_fec && fec_capa == 0)
> + return 0;
> +
> + sfc_dev_get_rte_link(dev, 1, ¤t_link);
> +
> + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
> + if (num_entries == 0)
> + return -ENOTSUP;
> +
> + speed_fec_capa = rte_calloc("fec_capa", num_entries,
> + sizeof(*speed_fec_capa), 0);
> + num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
> + speed_fec_capa);
> +
> + for (i = 0; i < num_entries; i++) {
> + if (speed_fec_capa[i].speed == current_link.link_speed) {
> + if ((fec_capa & speed_fec_capa[i].capa) != 0)
> + is_supported = true;
> +
> + break;
> + }
> + }
> +
> + rte_free(speed_fec_capa);
> +
> + if (is_supported)
> + return 0;
> +
> + return -ENOTSUP;
> +}
> +
> +static int
> +sfc_fec_capa_to_efx(uint32_t supported_caps, uint32_t fec_capa,
> + uint32_t *efx_fec_caps)
> +{
> + bool fec_is_set = false;
> + bool auto_fec = false;
> + bool nofec = false;
> + uint32_t ret = 0;
> +
> + if (efx_fec_caps == NULL)
> + return -EINVAL;
> +
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
> + auto_fec = true;
> +
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC))
> + nofec = true;
> +
> + if (fec_capa == RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
> + ret |= (EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
> + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
> + EFX_PHY_CAP_FEC_BIT(RS_FEC)) & supported_caps;
> + goto done;
> + }
> +
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS)) {
> + fec_is_set = true;
> +
> + if (supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC)) {
> + ret |= EFX_PHY_CAP_FEC_BIT(RS_FEC) |
> + EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
> + }
> + }
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER)) {
> + if (!auto_fec && fec_is_set)
> + return -EINVAL;
> +
> + if (supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC)) {
> + ret |= EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
> + EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
> + }
> + if (supported_caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)) {
> + ret |= EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
> + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
> + }
> + }
> +
> + if (ret == 0 && !nofec)
> + return -ENOTSUP;
> +
> +done:
> + *efx_fec_caps = ret;
> + return 0;
> +}
> +
> +static int
> +sfc_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa)
> +{
> + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
> + struct sfc_port *port = &sa->port;
> + uint32_t supported_caps;
> + uint32_t efx_fec_caps;
> + uint32_t updated_caps;
> + int rc = 0;
> +
> + sfc_adapter_lock(sa);
> +
> + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
> +
> + rc = sfc_fec_capa_check(dev, fec_capa, supported_caps);
> + if (rc != 0)
> + goto adapter_unlock;
> +
> + rc = sfc_fec_capa_to_efx(supported_caps, fec_capa, &efx_fec_caps);
> + if (rc != 0)
> + goto adapter_unlock;
> +
> + if (sa->state == SFC_ETHDEV_STARTED) {
> + efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT,
> + &updated_caps);
> + updated_caps = updated_caps & ~EFX_PHY_CAP_FEC_MASK;
> + updated_caps |= efx_fec_caps;
> +
> + rc = efx_phy_adv_cap_set(sa->nic, updated_caps);
> + if (rc != 0)
> + goto adapter_unlock;
> + }
> +
> + port->fec_cfg = efx_fec_caps;
> + /*
> + * There is no chance to recognize AUTO mode from the
> + * saved FEC capabilities as AUTO mode can have the same
> + * set of bits as any other mode from the EFX point of view.
> + * Save it in the proper variable.
> + */
> + if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
> + port->fec_auto = true;
> + else
> + port->fec_auto = false;
> +
> +adapter_unlock:
> + sfc_adapter_unlock(sa);
> +
> + return rc;
> +}
> +
> static const struct eth_dev_ops sfc_eth_dev_ops = {
> .dev_configure = sfc_dev_configure,
> .dev_start = sfc_dev_start,
> @@ -2392,6 +2726,9 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
> .pool_ops_supported = sfc_pool_ops_supported,
> .representor_info_get = sfc_representor_info_get,
> .rx_metadata_negotiate = sfc_rx_metadata_negotiate,
> + .fec_get_capability = sfc_fec_get_capability,
> + .fec_get = sfc_fec_get,
> + .fec_set = sfc_fec_set,
> };
>
> struct sfc_ethdev_init_data {
[snip]
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 0/3] net/sfc: support FEC feature
2023-06-01 22:23 [PATCH 0/3] net/sfc: support FEC feature Denis Pryazhennikov
` (2 preceding siblings ...)
2023-06-01 22:23 ` [PATCH 3/3] net/sfc: support FEC feature Denis Pryazhennikov
@ 2023-06-15 8:38 ` Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 1/3] net/sfc: split link update function Denis Pryazhennikov
` (3 more replies)
3 siblings, 4 replies; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-15 8:38 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko
This patch series adds setting and querying of Forward error
correction (FEC). AUTO, BASER and RS modes are supported
by EF10/EF100 hardware. LLRS mode is not supported.
Changes in v2:
* Applied review notes in [2/3] and [3/3];
* Added a check for the supported by a device FEC modes
in sfc_fec_get_capa_speed_to_fec();
* Fixed error handling.
Denis Pryazhennikov (3):
net/sfc: split link update function
common/sfc_efx/base: add FEC related macros
net/sfc: support FEC feature
doc/guides/nics/features/sfc.ini | 1 +
doc/guides/rel_notes/release_23_07.rst | 6 +
drivers/common/sfc_efx/base/efx.h | 9 +
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 406 ++++++++++++++++++++++++-
drivers/net/sfc/sfc_port.c | 24 +-
6 files changed, 428 insertions(+), 20 deletions(-)
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 1/3] net/sfc: split link update function
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
@ 2023-06-15 8:38 ` Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
` (2 subsequent siblings)
3 siblings, 0 replies; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-15 8:38 UTC (permalink / raw)
To: dev
Cc: Ferruh Yigit, Andrew Rybchenko, Ivan Malov, Andy Moreton,
Andrew Rybchenko
Separate the original link update function into
two functions: state retrieval and update.
This improves code clarity and maintainability.
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
---
drivers/net/sfc/sfc_ethdev.c | 28 +++++++++++++++++++---------
1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 320043145495..6d41eb000345 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -248,28 +248,38 @@ sfc_dev_start(struct rte_eth_dev *dev)
return -rc;
}
-static int
-sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+static void
+sfc_dev_get_rte_link(struct rte_eth_dev *dev, int wait_to_complete,
+ struct rte_eth_link *link)
{
struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
- struct rte_eth_link current_link;
- int ret;
- sfc_log_init(sa, "entry");
+ SFC_ASSERT(link != NULL);
if (sa->state != SFC_ETHDEV_STARTED) {
- sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, ¤t_link);
+ sfc_port_link_mode_to_info(EFX_LINK_UNKNOWN, link);
} else if (wait_to_complete) {
efx_link_mode_t link_mode;
if (efx_port_poll(sa->nic, &link_mode) != 0)
link_mode = EFX_LINK_UNKNOWN;
- sfc_port_link_mode_to_info(link_mode, ¤t_link);
-
+ sfc_port_link_mode_to_info(link_mode, link);
} else {
sfc_ev_mgmt_qpoll(sa);
- rte_eth_linkstatus_get(dev, ¤t_link);
+ rte_eth_linkstatus_get(dev, link);
}
+}
+
+static int
+sfc_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct rte_eth_link current_link;
+ int ret;
+
+ sfc_log_init(sa, "entry");
+
+ sfc_dev_get_rte_link(dev, wait_to_complete, ¤t_link);
ret = rte_eth_linkstatus_set(dev, ¤t_link);
if (ret == 0)
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 1/3] net/sfc: split link update function Denis Pryazhennikov
@ 2023-06-15 8:38 ` Denis Pryazhennikov
2023-06-20 11:34 ` Ferruh Yigit
2023-06-15 8:38 ` [PATCH v2 3/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-20 11:47 ` [PATCH v2 0/3] " Ferruh Yigit
3 siblings, 1 reply; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-15 8:38 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko, Andy Moreton, Andrew Rybchenko
Added new macros to simplify working with FEC bits.
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
---
drivers/common/sfc_efx/base/efx.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
index 49e29dcc1c69..10c412bcd7dc 100644
--- a/drivers/common/sfc_efx/base/efx.h
+++ b/drivers/common/sfc_efx/base/efx.h
@@ -3958,6 +3958,15 @@ typedef enum efx_phy_fec_type_e {
EFX_PHY_FEC_RS
} efx_phy_fec_type_t;
+#define EFX_PHY_CAP_FEC_BIT(_fec_bit) (1U << EFX_PHY_CAP_##_fec_bit)
+#define EFX_PHY_CAP_FEC_MASK \
+ (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED) | \
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED) | \
+ EFX_PHY_CAP_FEC_BIT(RS_FEC) | \
+ EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED))
+
LIBEFX_API
extern __checkReturn efx_rc_t
efx_phy_fec_type_get(
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v2 3/3] net/sfc: support FEC feature
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 1/3] net/sfc: split link update function Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
@ 2023-06-15 8:38 ` Denis Pryazhennikov
2023-06-19 9:39 ` Andrew Rybchenko
2023-06-20 11:47 ` [PATCH v2 0/3] " Ferruh Yigit
3 siblings, 1 reply; 17+ messages in thread
From: Denis Pryazhennikov @ 2023-06-15 8:38 UTC (permalink / raw)
To: dev; +Cc: Ferruh Yigit, Andrew Rybchenko, Ivan Malov, Andy Moreton
Support ethdev methods to query and set FEC information.
Limitations: ignoring rte_eth_fec_get_capability() results
can lead to NOFEC if the device is not strated.
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
---
doc/guides/nics/features/sfc.ini | 1 +
doc/guides/rel_notes/release_23_07.rst | 6 +
drivers/net/sfc/sfc.h | 2 +
drivers/net/sfc/sfc_ethdev.c | 378 +++++++++++++++++++++++++
drivers/net/sfc/sfc_port.c | 24 +-
5 files changed, 400 insertions(+), 11 deletions(-)
diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini
index f5ac644278ae..e0b9bfb7f7bf 100644
--- a/doc/guides/nics/features/sfc.ini
+++ b/doc/guides/nics/features/sfc.ini
@@ -24,6 +24,7 @@ RSS reta update = Y
SR-IOV = Y
Flow control = Y
VLAN offload = P
+FEC = Y
L3 checksum offload = Y
L4 checksum offload = Y
Inner L3 checksum = Y
diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst
index 027ae7bd2d64..59a215a4a4f8 100644
--- a/doc/guides/rel_notes/release_23_07.rst
+++ b/doc/guides/rel_notes/release_23_07.rst
@@ -170,6 +170,12 @@ New Features
See :doc:`../prog_guide/pdcp_lib` for more information.
+* **Updated Solarflare network PMD.**
+
+ Updated the Solarflare ``sfc_efx`` driver with changes including:
+
+ * Added support for configuring FEC mode, querying FEC capabilities and
+ current FEC mode from a device.
Removed Items
-------------
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 730d054aea74..e42abe42cb8a 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -68,6 +68,8 @@ struct sfc_port {
uint32_t phy_adv_cap_mask;
uint32_t phy_adv_cap;
+ uint32_t fec_cfg;
+ bool fec_auto;
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c
index 6d41eb000345..f120ddc5a8d8 100644
--- a/drivers/net/sfc/sfc_ethdev.c
+++ b/drivers/net/sfc/sfc_ethdev.c
@@ -2343,6 +2343,381 @@ sfc_rx_metadata_negotiate(struct rte_eth_dev *dev, uint64_t *features)
return 0;
}
+static unsigned int
+sfc_fec_get_capa_speed_to_fec(uint32_t supported_caps,
+ struct rte_eth_fec_capa *speed_fec_capa)
+{
+ unsigned int num = 0;
+ bool baser = false;
+ bool rs = false;
+
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC))
+ baser = true;
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC))
+ rs = true;
+
+ /*
+ * NOFEC and AUTO FEC modes are always supported.
+ * FW does not provide information about the supported
+ * FEC modes per the link speed.
+ * Supported FEC depends on supported link speeds and
+ * supported FEC modes by a device.
+ */
+ if (supported_caps & (1u << EFX_PHY_CAP_10000FDX)) {
+ if (speed_fec_capa != NULL) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_10G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+ if (baser) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_25000FDX)) {
+ if (speed_fec_capa != NULL) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_25G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+ if (baser) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ if (rs) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_40000FDX)) {
+ if (speed_fec_capa != NULL) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_40G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+ if (baser) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_50000FDX)) {
+ if (speed_fec_capa != NULL) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_50G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+ if (baser) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(BASER);
+ }
+ if (rs) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ }
+ num++;
+ }
+ if (supported_caps & (1u << EFX_PHY_CAP_100000FDX)) {
+ if (speed_fec_capa != NULL) {
+ speed_fec_capa[num].speed = RTE_ETH_SPEED_NUM_100G;
+ speed_fec_capa[num].capa =
+ RTE_ETH_FEC_MODE_CAPA_MASK(NOFEC) |
+ RTE_ETH_FEC_MODE_CAPA_MASK(AUTO);
+ if (rs) {
+ speed_fec_capa[num].capa |=
+ RTE_ETH_FEC_MODE_CAPA_MASK(RS);
+ }
+ }
+ num++;
+ }
+
+ return num;
+}
+
+static int
+sfc_fec_get_capability(struct rte_eth_dev *dev,
+ struct rte_eth_fec_capa *speed_fec_capa,
+ unsigned int num)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ unsigned int num_entries;
+ uint32_t supported_caps;
+
+ sfc_adapter_lock(sa);
+
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
+ if (speed_fec_capa == NULL || num < num_entries)
+ goto adapter_unlock;
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
+ speed_fec_capa);
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ return num_entries;
+}
+
+static uint32_t
+sfc_efx_caps_to_fec(uint32_t caps, bool is_25g)
+{
+ bool rs_req = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
+ bool rs = caps & EFX_PHY_CAP_FEC_BIT(RS_FEC);
+ bool baser_req;
+ bool baser;
+
+ if (is_25g) {
+ baser = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC);
+ baser_req = caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
+ } else {
+ baser = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC);
+ baser_req = caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
+ }
+
+ if (!baser && !rs)
+ return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
+
+ if (rs_req)
+ return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
+
+ if (baser_req)
+ return RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
+
+ return 0;
+}
+
+static int
+sfc_fec_get(struct rte_eth_dev *dev, uint32_t *fec_capa)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct sfc_port *port = &sa->port;
+ struct rte_eth_link current_link;
+ efx_phy_fec_type_t active_fec;
+ bool is_25g = false;
+ int rc = 0;
+
+ sfc_adapter_lock(sa);
+
+ sfc_dev_get_rte_link(dev, 1, ¤t_link);
+
+ if (current_link.link_status == RTE_ETH_LINK_DOWN) {
+ uint32_t speed = current_link.link_speed;
+
+ if (port->fec_auto) {
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
+ goto adapter_unlock;
+ }
+
+ is_25g = (speed == RTE_ETH_SPEED_NUM_25G ||
+ speed == RTE_ETH_SPEED_NUM_50G);
+
+ *fec_capa = sfc_efx_caps_to_fec(port->fec_cfg, is_25g);
+ if (*fec_capa == 0)
+ rc = ENOTSUP;
+
+ goto adapter_unlock;
+ }
+
+ rc = efx_phy_fec_type_get(sa->nic, &active_fec);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ switch (active_fec) {
+ case EFX_PHY_FEC_NONE:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC);
+ break;
+ case EFX_PHY_FEC_BASER:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER);
+ break;
+ case EFX_PHY_FEC_RS:
+ *fec_capa = RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS);
+ break;
+ default:
+ rc = ENOTSUP;
+ break;
+ }
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ if (rc != 0)
+ sfc_err(sa, "failed to get FEC mode");
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
+
+static int
+sfc_fec_capa_check(struct rte_eth_dev *dev, uint32_t fec_capa,
+ uint32_t supported_caps)
+{
+ struct rte_eth_fec_capa *speed_fec_capa;
+ struct rte_eth_link current_link;
+ bool is_supported = false;
+ unsigned int num_entries;
+ bool auto_fec = false;
+ unsigned int i;
+
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+
+ if (sa->state != SFC_ETHDEV_STARTED)
+ return 0;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
+ auto_fec = true;
+ fec_capa &= ~RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO);
+ }
+
+ /*
+ * If only the AUTO bit is set, the decision on which FEC
+ * mode to use will be made by HW/FW or driver.
+ */
+ if (auto_fec && fec_capa == 0)
+ return 0;
+
+ sfc_dev_get_rte_link(dev, 1, ¤t_link);
+
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps, NULL);
+ if (num_entries == 0)
+ return ENOTSUP;
+
+ speed_fec_capa = rte_calloc("fec_capa", num_entries,
+ sizeof(*speed_fec_capa), 0);
+ num_entries = sfc_fec_get_capa_speed_to_fec(supported_caps,
+ speed_fec_capa);
+
+ for (i = 0; i < num_entries; i++) {
+ if (speed_fec_capa[i].speed == current_link.link_speed) {
+ if ((fec_capa & speed_fec_capa[i].capa) != 0)
+ is_supported = true;
+
+ break;
+ }
+ }
+
+ rte_free(speed_fec_capa);
+
+ if (is_supported)
+ return 0;
+
+ return ENOTSUP;
+}
+
+static int
+sfc_fec_capa_to_efx(uint32_t supported_caps, uint32_t fec_capa,
+ uint32_t *efx_fec_caps)
+{
+ bool fec_is_set = false;
+ bool auto_fec = false;
+ bool nofec = false;
+ uint32_t ret = 0;
+
+ if (efx_fec_caps == NULL)
+ return EINVAL;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
+ auto_fec = true;
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_NOFEC))
+ nofec = true;
+
+ if (fec_capa == RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO)) {
+ ret |= (EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC)) & supported_caps;
+ goto done;
+ }
+
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_RS)) {
+ fec_is_set = true;
+
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(RS_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(RS_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED);
+ }
+ }
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_BASER)) {
+ if (!auto_fec && fec_is_set)
+ return EINVAL;
+
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(BASER_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED);
+ }
+ if (supported_caps & EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC)) {
+ ret |= EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED);
+ }
+ }
+
+ if (ret == 0 && !nofec)
+ return ENOTSUP;
+
+done:
+ *efx_fec_caps = ret;
+ return 0;
+}
+
+static int
+sfc_fec_set(struct rte_eth_dev *dev, uint32_t fec_capa)
+{
+ struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev);
+ struct sfc_port *port = &sa->port;
+ uint32_t supported_caps;
+ uint32_t efx_fec_caps;
+ uint32_t updated_caps;
+ int rc = 0;
+
+ sfc_adapter_lock(sa);
+
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_PERM, &supported_caps);
+
+ rc = sfc_fec_capa_check(dev, fec_capa, supported_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ rc = sfc_fec_capa_to_efx(supported_caps, fec_capa, &efx_fec_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+
+ if (sa->state == SFC_ETHDEV_STARTED) {
+ efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT,
+ &updated_caps);
+ updated_caps = updated_caps & ~EFX_PHY_CAP_FEC_MASK;
+ updated_caps |= efx_fec_caps;
+
+ rc = efx_phy_adv_cap_set(sa->nic, updated_caps);
+ if (rc != 0)
+ goto adapter_unlock;
+ }
+
+ port->fec_cfg = efx_fec_caps;
+ /*
+ * There is no chance to recognize AUTO mode from the
+ * saved FEC capabilities as AUTO mode can have the same
+ * set of bits as any other mode from the EFX point of view.
+ * Save it in the proper variable.
+ */
+ if (fec_capa & RTE_ETH_FEC_MODE_TO_CAPA(RTE_ETH_FEC_AUTO))
+ port->fec_auto = true;
+ else
+ port->fec_auto = false;
+
+adapter_unlock:
+ sfc_adapter_unlock(sa);
+
+ SFC_ASSERT(rc >= 0);
+ return -rc;
+}
+
static const struct eth_dev_ops sfc_eth_dev_ops = {
.dev_configure = sfc_dev_configure,
.dev_start = sfc_dev_start,
@@ -2392,6 +2767,9 @@ static const struct eth_dev_ops sfc_eth_dev_ops = {
.pool_ops_supported = sfc_pool_ops_supported,
.representor_info_get = sfc_representor_info_get,
.rx_metadata_negotiate = sfc_rx_metadata_negotiate,
+ .fec_get_capability = sfc_fec_get_capability,
+ .fec_get = sfc_fec_get,
+ .fec_set = sfc_fec_set,
};
struct sfc_ethdev_init_data {
diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
index 5f312ab1ba83..0c887ddedb09 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -228,17 +228,8 @@ sfc_port_start(struct sfc_adapter *sa)
/* Preserve pause capabilities set by above efx_mac_fcntl_set() */
efx_phy_adv_cap_get(sa->nic, EFX_PHY_CAP_CURRENT, &phy_adv_cap);
SFC_ASSERT((port->phy_adv_cap & phy_pause_caps) == 0);
- phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps);
-
- /*
- * No controls for FEC yet. Use default FEC mode.
- * I.e. advertise everything supported (*_FEC=1), but do not request
- * anything explicitly (*_FEC_REQUESTED=0).
- */
- phy_adv_cap |= port->phy_adv_cap_mask &
- (1u << EFX_PHY_CAP_BASER_FEC |
- 1u << EFX_PHY_CAP_RS_FEC |
- 1u << EFX_PHY_CAP_25G_BASER_FEC);
+ phy_adv_cap = port->phy_adv_cap | (phy_adv_cap & phy_pause_caps) |
+ port->fec_cfg;
sfc_log_init(sa, "set phy adv caps to %#x", phy_adv_cap);
rc = efx_phy_adv_cap_set(sa->nic, phy_adv_cap);
@@ -469,6 +460,17 @@ sfc_port_attach(struct sfc_adapter *sa)
port->mac_stats_update_period_ms = kvarg_stats_update_period_ms;
+ /*
+ * Set default FEC mode.
+ * I.e. advertise everything supported (*_FEC=1), but do not request
+ * anything explicitly (*_FEC_REQUESTED=0).
+ */
+ port->fec_cfg = port->phy_adv_cap_mask &
+ (EFX_PHY_CAP_FEC_BIT(BASER_FEC) |
+ EFX_PHY_CAP_FEC_BIT(RS_FEC) |
+ EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC));
+ port->fec_auto = true;
+
sfc_log_init(sa, "done");
return 0;
--
2.37.0 (Apple Git-136)
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 3/3] net/sfc: support FEC feature
2023-06-15 8:38 ` [PATCH v2 3/3] net/sfc: support FEC feature Denis Pryazhennikov
@ 2023-06-19 9:39 ` Andrew Rybchenko
2023-06-20 11:33 ` Ferruh Yigit
0 siblings, 1 reply; 17+ messages in thread
From: Andrew Rybchenko @ 2023-06-19 9:39 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Ferruh Yigit, Ivan Malov, Andy Moreton
On 6/15/23 11:38, Denis Pryazhennikov wrote:
> Support ethdev methods to query and set FEC information.
> Limitations: ignoring rte_eth_fec_get_capability() results
> can lead to NOFEC if the device is not strated.
>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
> Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
> diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst
> index 027ae7bd2d64..59a215a4a4f8 100644
> --- a/doc/guides/rel_notes/release_23_07.rst
> +++ b/doc/guides/rel_notes/release_23_07.rst
> @@ -170,6 +170,12 @@ New Features
>
> See :doc:`../prog_guide/pdcp_lib` for more information.
>
> +* **Updated Solarflare network PMD.**
> +
> + Updated the Solarflare ``sfc_efx`` driver with changes including:
> +
> + * Added support for configuring FEC mode, querying FEC capabilities and
> + current FEC mode from a device.
Extra empty line is required here. Two empty lines before the next
section.
>
> Removed Items
> -------------
[snip]
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/3] net/sfc: split link update function
2023-06-02 8:52 ` Andrew Rybchenko
@ 2023-06-20 11:25 ` Ferruh Yigit
2023-06-20 11:43 ` Andrew Rybchenko
0 siblings, 1 reply; 17+ messages in thread
From: Ferruh Yigit @ 2023-06-20 11:25 UTC (permalink / raw)
To: Andrew Rybchenko, Denis Pryazhennikov, dev; +Cc: Ivan Malov, Andy Moreton
On 6/2/2023 9:52 AM, Andrew Rybchenko wrote:
> On 6/2/23 01:23, Denis Pryazhennikov wrote:
>> Separate the original link update function into
>> two functions: state retrieval and update.
>> This improves code clarity and maintainability.
>>
>> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
>> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
>> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
>
> Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
>
>
Hi Andrew,
You have other email address [1] recorded in .mailmap, I will keep using
it, if this is new preferred address please update .mailmap
[1]
Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 3/3] net/sfc: support FEC feature
2023-06-19 9:39 ` Andrew Rybchenko
@ 2023-06-20 11:33 ` Ferruh Yigit
0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2023-06-20 11:33 UTC (permalink / raw)
To: Andrew Rybchenko, Denis Pryazhennikov, dev; +Cc: Ivan Malov, Andy Moreton
On 6/19/2023 10:39 AM, Andrew Rybchenko wrote:
> On 6/15/23 11:38, Denis Pryazhennikov wrote:
>> Support ethdev methods to query and set FEC information.
>> Limitations: ignoring rte_eth_fec_get_capability() results
>> can lead to NOFEC if the device is not strated.
>>
>> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
>> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
>> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
>> Reviewed-by: Ferruh Yigit <ferruh.yigit@amd.com>
>
> Acked-by: Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>
>> diff --git a/doc/guides/rel_notes/release_23_07.rst
>> b/doc/guides/rel_notes/release_23_07.rst
>> index 027ae7bd2d64..59a215a4a4f8 100644
>> --- a/doc/guides/rel_notes/release_23_07.rst
>> +++ b/doc/guides/rel_notes/release_23_07.rst
>> @@ -170,6 +170,12 @@ New Features
>> See :doc:`../prog_guide/pdcp_lib` for more information.
>> +* **Updated Solarflare network PMD.**
>> +
>> + Updated the Solarflare ``sfc_efx`` driver with changes including:
>> +
>> + * Added support for configuring FEC mode, querying FEC capabilities
>> and
>> + current FEC mode from a device.
>
> Extra empty line is required here. Two empty lines before the next
> section.
>
Location of the update is wrong, please see section comment on where to
place the update, I will fix while merging.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros
2023-06-15 8:38 ` [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
@ 2023-06-20 11:34 ` Ferruh Yigit
0 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2023-06-20 11:34 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Andrew Rybchenko, Andy Moreton, Andrew Rybchenko
On 6/15/2023 9:38 AM, Denis Pryazhennikov wrote:
> Added new macros to simplify working with FEC bits.
>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
> Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
> ---
> drivers/common/sfc_efx/base/efx.h | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/common/sfc_efx/base/efx.h b/drivers/common/sfc_efx/base/efx.h
> index 49e29dcc1c69..10c412bcd7dc 100644
> --- a/drivers/common/sfc_efx/base/efx.h
> +++ b/drivers/common/sfc_efx/base/efx.h
> @@ -3958,6 +3958,15 @@ typedef enum efx_phy_fec_type_e {
> EFX_PHY_FEC_RS
> } efx_phy_fec_type_t;
>
> +#define EFX_PHY_CAP_FEC_BIT(_fec_bit) (1U << EFX_PHY_CAP_##_fec_bit)
> +#define EFX_PHY_CAP_FEC_MASK \
> + (EFX_PHY_CAP_FEC_BIT(BASER_FEC) | \
> + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC) | \
> + EFX_PHY_CAP_FEC_BIT(BASER_FEC_REQUESTED) | \
> + EFX_PHY_CAP_FEC_BIT(25G_BASER_FEC_REQUESTED) | \
> + EFX_PHY_CAP_FEC_BIT(RS_FEC) | \
> + EFX_PHY_CAP_FEC_BIT(RS_FEC_REQUESTED))
> +
> LIBEFX_API
> extern __checkReturn efx_rc_t
> efx_phy_fec_type_get(
will squash to commit 3/3 where actual functionality is added and these
macros are used.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH 1/3] net/sfc: split link update function
2023-06-20 11:25 ` Ferruh Yigit
@ 2023-06-20 11:43 ` Andrew Rybchenko
0 siblings, 0 replies; 17+ messages in thread
From: Andrew Rybchenko @ 2023-06-20 11:43 UTC (permalink / raw)
To: Ferruh Yigit, Denis Pryazhennikov, dev; +Cc: Ivan Malov, Andy Moreton
On 6/20/23 14:25, Ferruh Yigit wrote:
> On 6/2/2023 9:52 AM, Andrew Rybchenko wrote:
>> On 6/2/23 01:23, Denis Pryazhennikov wrote:
>>> Separate the original link update function into
>>> two functions: state retrieval and update.
>>> This improves code clarity and maintainability.
>>>
>>> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
>>> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
>>> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
>>
>> Acked-by: Andrew Rybchenko <arybchenko@oktetlabs.ru>
>>
>>
>
> Hi Andrew,
>
> You have other email address [1] recorded in .mailmap, I will keep using
> it, if this is new preferred address please update .mailmap
>
> [1]
> Andrew Rybchenko <andrew.rybchenko@oktetlabs.ru>
>
Thanks Ferruh, it was some kind of typo. [1] is the right one.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH v2 0/3] net/sfc: support FEC feature
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
` (2 preceding siblings ...)
2023-06-15 8:38 ` [PATCH v2 3/3] net/sfc: support FEC feature Denis Pryazhennikov
@ 2023-06-20 11:47 ` Ferruh Yigit
3 siblings, 0 replies; 17+ messages in thread
From: Ferruh Yigit @ 2023-06-20 11:47 UTC (permalink / raw)
To: Denis Pryazhennikov, dev; +Cc: Andrew Rybchenko
On 6/15/2023 9:38 AM, Denis Pryazhennikov wrote:
> This patch series adds setting and querying of Forward error
> correction (FEC). AUTO, BASER and RS modes are supported
> by EF10/EF100 hardware. LLRS mode is not supported.
>
> Changes in v2:
> * Applied review notes in [2/3] and [3/3];
> * Added a check for the supported by a device FEC modes
> in sfc_fec_get_capa_speed_to_fec();
> * Fixed error handling.
>
> Denis Pryazhennikov (3):
> net/sfc: split link update function
> common/sfc_efx/base: add FEC related macros
> net/sfc: support FEC feature
>
2/3 squashed into 3/3,
Series applied to dpdk-next-net/main, thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2023-06-20 11:48 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-01 22:23 [PATCH 0/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-01 22:23 ` [PATCH 1/3] net/sfc: split link update function Denis Pryazhennikov
2023-06-02 8:52 ` Andrew Rybchenko
2023-06-20 11:25 ` Ferruh Yigit
2023-06-20 11:43 ` Andrew Rybchenko
2023-06-01 22:23 ` [PATCH 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
2023-06-02 8:53 ` Andrew Rybchenko
2023-06-01 22:23 ` [PATCH 3/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-02 9:09 ` Andrew Rybchenko
2023-06-15 8:38 ` [PATCH v2 0/3] " Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 1/3] net/sfc: split link update function Denis Pryazhennikov
2023-06-15 8:38 ` [PATCH v2 2/3] common/sfc_efx/base: add FEC related macros Denis Pryazhennikov
2023-06-20 11:34 ` Ferruh Yigit
2023-06-15 8:38 ` [PATCH v2 3/3] net/sfc: support FEC feature Denis Pryazhennikov
2023-06-19 9:39 ` Andrew Rybchenko
2023-06-20 11:33 ` Ferruh Yigit
2023-06-20 11:47 ` [PATCH v2 0/3] " Ferruh Yigit
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).