[4/4] net/sfc: add configurable Rx CRC stripping
Checks
Commit Message
Configurable Rx CRC stripping is allowed only if
running firmware variant supports it and if NIC is
configured with single PF per port and without VFs.
Signed-off-by: Roman Zhukov <roman.zhukov@arknetworks.am>
Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
doc/guides/nics/features/sfc.ini | 1 +
doc/guides/nics/sfc_efx.rst | 6 ++++--
drivers/net/sfc/sfc.h | 1 +
drivers/net/sfc/sfc_ef10_rx.c | 3 ++-
drivers/net/sfc/sfc_port.c | 12 ++++++++++++
drivers/net/sfc/sfc_rx.c | 6 +++++-
6 files changed, 25 insertions(+), 4 deletions(-)
Comments
On 6/1/23 14:42, Denis Pryazhennikov wrote:
> Configurable Rx CRC stripping is allowed only if
> running firmware variant supports it and if NIC is
> configured with single PF per port and without VFs.
I'd like to double-check one thing. Doesn't it require fixes on
datapath to report correct length? If no, it would be good to
see notes about it here.
>
> Signed-off-by: Roman Zhukov <roman.zhukov@arknetworks.am>
> Signed-off-by: Denis Pryazhennikov <denis.pryazhennikov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
> ---
> doc/guides/nics/features/sfc.ini | 1 +
> doc/guides/nics/sfc_efx.rst | 6 ++++--
> drivers/net/sfc/sfc.h | 1 +
> drivers/net/sfc/sfc_ef10_rx.c | 3 ++-
> drivers/net/sfc/sfc_port.c | 12 ++++++++++++
> drivers/net/sfc/sfc_rx.c | 6 +++++-
> 6 files changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/doc/guides/nics/features/sfc.ini b/doc/guides/nics/features/sfc.ini
> index f5ac644278ae..c41c47a63d49 100644
> --- a/doc/guides/nics/features/sfc.ini
> +++ b/doc/guides/nics/features/sfc.ini
> @@ -23,6 +23,7 @@ RSS key update = Y
> RSS reta update = Y
> SR-IOV = Y
> Flow control = Y
> +CRC offload = Y
> VLAN offload = P
> L3 checksum offload = Y
> L4 checksum offload = Y
> diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
> index de0656876b96..b3a44e7ddd92 100644
> --- a/doc/guides/nics/sfc_efx.rst
> +++ b/doc/guides/nics/sfc_efx.rst
> @@ -114,6 +114,10 @@ SFC EFX PMD has support for:
>
> - Loopback
>
> +- Configurable Rx CRC stripping (if running firmware variant supports it and
> + if NIC is configured with single PF per port and without VFs, otherwise
> + always stripped)
> +
> - SR-IOV PF
>
> - Port representors (see :ref: switch_representation)
> @@ -126,8 +130,6 @@ The features not yet supported include:
>
> - Priority-based flow control
>
> -- Configurable RX CRC stripping (always stripped)
> -
> - Header split on receive
>
> - VLAN filtering
> diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
> index 730d054aea74..5c97d5911eb2 100644
> --- a/drivers/net/sfc/sfc.h
> +++ b/drivers/net/sfc/sfc.h
> @@ -72,6 +72,7 @@ struct sfc_port {
> unsigned int flow_ctrl;
> boolean_t flow_ctrl_autoneg;
> size_t pdu;
> + boolean_t include_fcs;
Please, put it after flow_ctrl_autoneg to use available hole.
There is no requirements to put it after pdu.
>
> /*
> * Flow API isolated mode overrides promisc and allmulti settings;
> diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
> index 7be224c9c412..08fe41fe5d94 100644
> --- a/drivers/net/sfc/sfc_ef10_rx.c
> +++ b/drivers/net/sfc/sfc_ef10_rx.c
> @@ -826,7 +826,8 @@ struct sfc_dp_rx sfc_ef10_rx = {
> .dev_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
> RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
> RTE_ETH_RX_OFFLOAD_RSS_HASH,
> - .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER,
> + .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER |
> + RTE_ETH_RX_OFFLOAD_KEEP_CRC,
Why is it queue level offload? It is configured per port. So,
it should be device level offload if I'm not mistaken.
> .get_dev_info = sfc_ef10_rx_get_dev_info,
> .qsize_up_rings = sfc_ef10_rx_qsize_up_rings,
> .qcreate = sfc_ef10_rx_qcreate,
> diff --git a/drivers/net/sfc/sfc_port.c b/drivers/net/sfc/sfc_port.c
> index 5f312ab1ba83..24d2daf6282b 100644
> --- a/drivers/net/sfc/sfc_port.c
> +++ b/drivers/net/sfc/sfc_port.c
> @@ -250,6 +250,11 @@ sfc_port_start(struct sfc_adapter *sa)
> if (rc != 0)
> goto fail_mac_pdu_set;
>
> + sfc_log_init(sa, "set include FCS=%u", port->include_fcs);
> + rc = efx_mac_include_fcs_set(sa->nic, port->include_fcs);
> + if (rc != 0)
> + goto fail_include_fcs_set;
> +
> if (!sfc_sa2shared(sa)->isolated) {
> struct rte_ether_addr *addr = &port->default_mac_addr;
>
> @@ -337,6 +342,7 @@ sfc_port_start(struct sfc_adapter *sa)
> (void)efx_mac_drain(sa->nic, B_TRUE);
>
> fail_mac_drain:
> +fail_include_fcs_set:
> fail_mac_stats_upload:
> (void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
> 0, B_FALSE);
> @@ -384,11 +390,17 @@ sfc_port_configure(struct sfc_adapter *sa)
> {
> const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
> struct sfc_port *port = &sa->port;
> + const struct rte_eth_rxmode *rxmode = &dev_data->dev_conf.rxmode;
>
> sfc_log_init(sa, "entry");
>
> port->pdu = EFX_MAC_PDU(dev_data->mtu);
>
> + if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
> + port->include_fcs = true;
> + else
> + port->include_fcs = false;
> +
> return 0;
> }
>
> diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
> index edd0f0c03842..f80771778c64 100644
> --- a/drivers/net/sfc/sfc_rx.c
> +++ b/drivers/net/sfc/sfc_rx.c
> @@ -655,7 +655,8 @@ struct sfc_dp_rx sfc_efx_rx = {
> .features = SFC_DP_RX_FEAT_INTR,
> .dev_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
> RTE_ETH_RX_OFFLOAD_RSS_HASH,
> - .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER,
> + .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER |
> + RTE_ETH_RX_OFFLOAD_KEEP_CRC,
It seems it should be device level offload as above.
> .qsize_up_rings = sfc_efx_rx_qsize_up_rings,
> .qcreate = sfc_efx_rx_qcreate,
> .qdestroy = sfc_efx_rx_qdestroy,
> @@ -938,6 +939,9 @@ sfc_rx_get_offload_mask(struct sfc_adapter *sa)
> if (encp->enc_tunnel_encapsulations_supported == 0)
> no_caps |= RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM;
>
> + if (encp->enc_rx_include_fcs_supported == 0)
> + no_caps |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
> +
> return ~no_caps;
> }
>
@@ -23,6 +23,7 @@ RSS key update = Y
RSS reta update = Y
SR-IOV = Y
Flow control = Y
+CRC offload = Y
VLAN offload = P
L3 checksum offload = Y
L4 checksum offload = Y
@@ -114,6 +114,10 @@ SFC EFX PMD has support for:
- Loopback
+- Configurable Rx CRC stripping (if running firmware variant supports it and
+ if NIC is configured with single PF per port and without VFs, otherwise
+ always stripped)
+
- SR-IOV PF
- Port representors (see :ref: switch_representation)
@@ -126,8 +130,6 @@ The features not yet supported include:
- Priority-based flow control
-- Configurable RX CRC stripping (always stripped)
-
- Header split on receive
- VLAN filtering
@@ -72,6 +72,7 @@ struct sfc_port {
unsigned int flow_ctrl;
boolean_t flow_ctrl_autoneg;
size_t pdu;
+ boolean_t include_fcs;
/*
* Flow API isolated mode overrides promisc and allmulti settings;
@@ -826,7 +826,8 @@ struct sfc_dp_rx sfc_ef10_rx = {
.dev_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_RSS_HASH,
- .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER,
+ .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER |
+ RTE_ETH_RX_OFFLOAD_KEEP_CRC,
.get_dev_info = sfc_ef10_rx_get_dev_info,
.qsize_up_rings = sfc_ef10_rx_qsize_up_rings,
.qcreate = sfc_ef10_rx_qcreate,
@@ -250,6 +250,11 @@ sfc_port_start(struct sfc_adapter *sa)
if (rc != 0)
goto fail_mac_pdu_set;
+ sfc_log_init(sa, "set include FCS=%u", port->include_fcs);
+ rc = efx_mac_include_fcs_set(sa->nic, port->include_fcs);
+ if (rc != 0)
+ goto fail_include_fcs_set;
+
if (!sfc_sa2shared(sa)->isolated) {
struct rte_ether_addr *addr = &port->default_mac_addr;
@@ -337,6 +342,7 @@ sfc_port_start(struct sfc_adapter *sa)
(void)efx_mac_drain(sa->nic, B_TRUE);
fail_mac_drain:
+fail_include_fcs_set:
fail_mac_stats_upload:
(void)efx_mac_stats_periodic(sa->nic, &port->mac_stats_dma_mem,
0, B_FALSE);
@@ -384,11 +390,17 @@ sfc_port_configure(struct sfc_adapter *sa)
{
const struct rte_eth_dev_data *dev_data = sa->eth_dev->data;
struct sfc_port *port = &sa->port;
+ const struct rte_eth_rxmode *rxmode = &dev_data->dev_conf.rxmode;
sfc_log_init(sa, "entry");
port->pdu = EFX_MAC_PDU(dev_data->mtu);
+ if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC)
+ port->include_fcs = true;
+ else
+ port->include_fcs = false;
+
return 0;
}
@@ -655,7 +655,8 @@ struct sfc_dp_rx sfc_efx_rx = {
.features = SFC_DP_RX_FEAT_INTR,
.dev_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
RTE_ETH_RX_OFFLOAD_RSS_HASH,
- .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER,
+ .queue_offload_capa = RTE_ETH_RX_OFFLOAD_SCATTER |
+ RTE_ETH_RX_OFFLOAD_KEEP_CRC,
.qsize_up_rings = sfc_efx_rx_qsize_up_rings,
.qcreate = sfc_efx_rx_qcreate,
.qdestroy = sfc_efx_rx_qdestroy,
@@ -938,6 +939,9 @@ sfc_rx_get_offload_mask(struct sfc_adapter *sa)
if (encp->enc_tunnel_encapsulations_supported == 0)
no_caps |= RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM;
+ if (encp->enc_rx_include_fcs_supported == 0)
+ no_caps |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
+
return ~no_caps;
}