From b16cf4b27fe4c02fc3609485bdcf0f5643f2f609 Mon Sep 17 00:00:00 2001 From: Andrew Rybchenko Date: Mon, 9 Apr 2018 12:58:58 +0100 Subject: [PATCH] net/sfc: support loopback mode configuration All loopback modes are listed in efx_loopback_type_t. Available loopback modes are listed per link speed in the enc_loopback_types member of the efx_nic_cfg_t. Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- doc/guides/nics/sfc_efx.rst | 4 ++-- drivers/net/sfc/efsys.h | 2 +- drivers/net/sfc/sfc.c | 2 ++ drivers/net/sfc/sfc_port.c | 40 +++++++++++++++++++++++++++++++++++++ 4 files changed, 45 insertions(+), 3 deletions(-) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index c170e363d3..abaed67f52 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -88,6 +88,8 @@ SFC EFX PMD has support for: - Flow API +- Loopback + Non-supported Features ---------------------- @@ -98,8 +100,6 @@ The features not yet supported include: - Priority-based flow control -- Loopback - - Configurable RX CRC stripping (always stripped) - Header split on receive diff --git a/drivers/net/sfc/efsys.h b/drivers/net/sfc/efsys.h index 7eb2c3f11a..12f77dc52f 100644 --- a/drivers/net/sfc/efsys.h +++ b/drivers/net/sfc/efsys.h @@ -166,7 +166,7 @@ prefetch_read_once(const volatile void *addr) #define EFSYS_OPT_MAC_STATS 1 -#define EFSYS_OPT_LOOPBACK 0 +#define EFSYS_OPT_LOOPBACK 1 #define EFSYS_OPT_MON_MCDI 0 #define EFSYS_OPT_MON_STATS 0 diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index 69abafff36..716683b8f5 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -123,10 +123,12 @@ sfc_check_conf(struct sfc_adapter *sa) rc = EINVAL; } +#if !EFSYS_OPT_LOOPBACK if (conf->lpbk_mode != 0) { sfc_err(sa, "Loopback not supported"); rc = EINVAL; } +#endif if (conf->dcb_capability_en != 0) { sfc_err(sa, "Priority-based flow control not supported"); diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c index fd267e179a..5cc3ad7bd6 100644 --- a/drivers/net/sfc/sfc_port.c +++ b/drivers/net/sfc/sfc_port.c @@ -121,6 +121,28 @@ sfc_port_init_dev_link(struct sfc_adapter *sa) return 0; } +#if EFSYS_OPT_LOOPBACK + +static efx_link_mode_t +sfc_port_phy_caps_to_max_link_speed(uint32_t phy_caps) +{ + if (phy_caps & (1u << EFX_PHY_CAP_100000FDX)) + return EFX_LINK_100000FDX; + if (phy_caps & (1u << EFX_PHY_CAP_50000FDX)) + return EFX_LINK_50000FDX; + if (phy_caps & (1u << EFX_PHY_CAP_40000FDX)) + return EFX_LINK_40000FDX; + if (phy_caps & (1u << EFX_PHY_CAP_25000FDX)) + return EFX_LINK_25000FDX; + if (phy_caps & (1u << EFX_PHY_CAP_10000FDX)) + return EFX_LINK_10000FDX; + if (phy_caps & (1u << EFX_PHY_CAP_1000FDX)) + return EFX_LINK_1000FDX; + return EFX_LINK_UNKNOWN; +} + +#endif + int sfc_port_start(struct sfc_adapter *sa) { @@ -143,6 +165,21 @@ sfc_port_start(struct sfc_adapter *sa) if (rc != 0) goto fail_port_init; +#if EFSYS_OPT_LOOPBACK + if (sa->eth_dev->data->dev_conf.lpbk_mode != 0) { + efx_link_mode_t link_mode; + + link_mode = + sfc_port_phy_caps_to_max_link_speed(port->phy_adv_cap); + sfc_log_init(sa, "set loopback link_mode=%u type=%u", link_mode, + sa->eth_dev->data->dev_conf.lpbk_mode); + rc = efx_port_loopback_set(sa->nic, link_mode, + sa->eth_dev->data->dev_conf.lpbk_mode); + if (rc != 0) + goto fail_loopback_set; + } +#endif + sfc_log_init(sa, "set flow control to %#x autoneg=%u", port->flow_ctrl, port->flow_ctrl_autoneg); rc = efx_mac_fcntl_set(sa->nic, port->flow_ctrl, @@ -268,6 +305,9 @@ fail_mac_addr_set: fail_mac_pdu_set: fail_phy_adv_cap_set: fail_mac_fcntl_set: +#if EFSYS_OPT_LOOPBACK +fail_loopback_set: +#endif efx_port_fini(sa->nic); fail_port_init: -- 2.20.1