[v4,3/3] net/sfc: support VLAN stripping offload
Checks
Commit Message
Extract vlan tci provided by the HW in the prefix and put it to mbuf.
VLAN stripping is supported for ef100 datapath only.
Signed-off-by: Artemii Morozov <artemii.morozov@arknetworks.am>
Reviewed-by: Viacheslav Galaktionov <viacheslav.galaktionov@arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
---
doc/guides/nics/sfc_efx.rst | 4 ++--
drivers/net/sfc/sfc_ef100_rx.c | 21 ++++++++++++++++++++-
drivers/net/sfc/sfc_rx.c | 19 +++++++++++++++++++
3 files changed, 41 insertions(+), 3 deletions(-)
Comments
On 6/1/23 18:30, Artemii Morozov wrote:
> Extract vlan tci provided by the HW in the prefix and put it to mbuf.
vlan -> VLAN, tci -> TCI
> VLAN stripping is supported for ef100 datapath only.
It should be highlighted that it is device level offload.
>
> Signed-off-by: Artemii Morozov <artemii.morozov@arknetworks.am>
> Reviewed-by: Viacheslav Galaktionov <viacheslav.galaktionov@arknetworks.am>
> Reviewed-by: Ivan Malov <ivan.malov@arknetworks.am>
> Reviewed-by: Andy Moreton <amoreton@xilinx.com>
> ---
> doc/guides/nics/sfc_efx.rst | 4 ++--
> drivers/net/sfc/sfc_ef100_rx.c | 21 ++++++++++++++++++++-
> drivers/net/sfc/sfc_rx.c | 19 +++++++++++++++++++
Release notes should be updated to advertise the feature.
> 3 files changed, 41 insertions(+), 3 deletions(-)
>
> diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
> index de0656876b..44fa24e1ba 100644
> --- a/doc/guides/nics/sfc_efx.rst
> +++ b/doc/guides/nics/sfc_efx.rst
> @@ -118,6 +118,8 @@ SFC EFX PMD has support for:
>
> - Port representors (see :ref: switch_representation)
>
> +- VLAN stripping (if running firmware variant supports it)
> +
>
> Non-supported Features
> ----------------------
> @@ -132,8 +134,6 @@ The features not yet supported include:
>
> - VLAN filtering
>
> -- VLAN stripping
> -
> - LRO
>
>
> diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
> index 37b754fa33..e323156a26 100644
> --- a/drivers/net/sfc/sfc_ef100_rx.c
> +++ b/drivers/net/sfc/sfc_ef100_rx.c
> @@ -68,6 +68,7 @@ struct sfc_ef100_rxq {
> #define SFC_EF100_RXQ_INGRESS_MPORT 0x80
> #define SFC_EF100_RXQ_USER_FLAG 0x100
> #define SFC_EF100_RXQ_NIC_DMA_MAP 0x200
> +#define SFC_EF100_RXQ_VLAN_STRIP 0x400
> unsigned int ptr_mask;
> unsigned int evq_phase_bit_shift;
> unsigned int ready_pkts;
> @@ -392,6 +393,7 @@ static const efx_rx_prefix_layout_t sfc_ef100_rx_prefix_layout = {
> SFC_EF100_RX_PREFIX_FIELD(RSS_HASH, B_FALSE),
> SFC_EF100_RX_PREFIX_FIELD(USER_FLAG, B_FALSE),
> SFC_EF100_RX_PREFIX_FIELD(USER_MARK, B_FALSE),
> + SFC_EF100_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_FALSE),
>
> #undef SFC_EF100_RX_PREFIX_FIELD
> }
> @@ -472,6 +474,17 @@ sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq,
> ESF_GZ_RX_PREFIX_INGRESS_MPORT);
> }
>
> + if (rxq->flags & SFC_EF100_RXQ_VLAN_STRIP) {
> + uint32_t vlan_stripped;
Please, add empty line after variable declaration.
IMHO, bool type should be used here.
> + vlan_stripped = EFX_XWORD_FIELD(rx_prefix[0], ESF_GZ_RX_PREFIX_VLAN_STRIPPED);
> +
> + if (vlan_stripped != 0) {
No comparison if bool is used.
> + ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
> + m->vlan_tci = EFX_XWORD_FIELD(rx_prefix[0],
> + ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI);
> + }
> + }
> +
> m->ol_flags = ol_flags;
> return true;
> }
> @@ -892,6 +905,12 @@ sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr,
> (rxq->flags & SFC_EF100_RXQ_INGRESS_MPORT))
> return ENOTSUP;
>
> + if ((unsup_rx_prefix_fields &
> + (1U << EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI)) == 0)
Shouldn't offload enable/disable be taken into account here?
If offload is not enabled, it is better to skip extra read
from Rx prefix and branching on fast path.
> + rxq->flags |= SFC_EF100_RXQ_VLAN_STRIP;
> + else
> + rxq->flags &= ~SFC_EF100_RXQ_VLAN_STRIP;
> +
> rxq->prefix_size = pinfo->erpl_length;
> rxq->rearm_data = sfc_ef100_mk_mbuf_rearm_data(rxq->dp.dpq.port_id,
> rxq->prefix_size);
> @@ -1004,7 +1023,7 @@ struct sfc_dp_rx sfc_ef100_rx = {
> SFC_DP_RX_FEAT_FLOW_MARK |
> SFC_DP_RX_FEAT_INTR |
> SFC_DP_RX_FEAT_STATS,
> - .dev_offload_capa = 0,
> + .dev_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP,
> .queue_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
> RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
> RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM |
> diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
> index edd0f0c038..e9ef1d92ed 100644
> --- a/drivers/net/sfc/sfc_rx.c
> +++ b/drivers/net/sfc/sfc_rx.c
> @@ -938,6 +938,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_vlan_stripping == 0)
> + no_caps |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
> +
> return ~no_caps;
> }
>
> @@ -1186,6 +1189,16 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index,
> if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)
> rxq_info->type_flags |= EFX_RXQ_FLAG_RSS_HASH;
>
> +
Too many empty lines
> + if (sa->eth_dev->data->dev_conf.rxmode.offloads &
> + RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
> + rxq_info->type_flags |= EFX_RXQ_FLAG_VLAN_STRIP;
> + } else if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
> + sfc_err(sa, "VLAN stripping must be configured during device configure");
> + rc = EINVAL;
> + goto fail_bad_conf;
As far as I know generic ethdev code will reject the request
earlier. So, the code is unreachable and dead.
> + }
> +
> if ((sa->negotiated_rx_metadata & RTE_ETH_RX_METADATA_USER_FLAG) != 0)
> rxq_info->type_flags |= EFX_RXQ_FLAG_USER_FLAG;
>
> @@ -1691,6 +1704,12 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
> rxmode->offloads |= RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM;
> }
>
> + if ((rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) &&
> + (~offloads_supported & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)) {
> + sfc_err(sa, "VLAN stripping offload is requested but not supported");
> + rc = ENOTSUP;
> + }
> +
If I'm not mistaken generic ethdev code will reject the request
earlier and will not allow to reach the code here.
> return rc;
> }
>
@@ -118,6 +118,8 @@ SFC EFX PMD has support for:
- Port representors (see :ref: switch_representation)
+- VLAN stripping (if running firmware variant supports it)
+
Non-supported Features
----------------------
@@ -132,8 +134,6 @@ The features not yet supported include:
- VLAN filtering
-- VLAN stripping
-
- LRO
@@ -68,6 +68,7 @@ struct sfc_ef100_rxq {
#define SFC_EF100_RXQ_INGRESS_MPORT 0x80
#define SFC_EF100_RXQ_USER_FLAG 0x100
#define SFC_EF100_RXQ_NIC_DMA_MAP 0x200
+#define SFC_EF100_RXQ_VLAN_STRIP 0x400
unsigned int ptr_mask;
unsigned int evq_phase_bit_shift;
unsigned int ready_pkts;
@@ -392,6 +393,7 @@ static const efx_rx_prefix_layout_t sfc_ef100_rx_prefix_layout = {
SFC_EF100_RX_PREFIX_FIELD(RSS_HASH, B_FALSE),
SFC_EF100_RX_PREFIX_FIELD(USER_FLAG, B_FALSE),
SFC_EF100_RX_PREFIX_FIELD(USER_MARK, B_FALSE),
+ SFC_EF100_RX_PREFIX_FIELD(VLAN_STRIP_TCI, B_FALSE),
#undef SFC_EF100_RX_PREFIX_FIELD
}
@@ -472,6 +474,17 @@ sfc_ef100_rx_prefix_to_offloads(const struct sfc_ef100_rxq *rxq,
ESF_GZ_RX_PREFIX_INGRESS_MPORT);
}
+ if (rxq->flags & SFC_EF100_RXQ_VLAN_STRIP) {
+ uint32_t vlan_stripped;
+ vlan_stripped = EFX_XWORD_FIELD(rx_prefix[0], ESF_GZ_RX_PREFIX_VLAN_STRIPPED);
+
+ if (vlan_stripped != 0) {
+ ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+ m->vlan_tci = EFX_XWORD_FIELD(rx_prefix[0],
+ ESF_GZ_RX_PREFIX_VLAN_STRIP_TCI);
+ }
+ }
+
m->ol_flags = ol_flags;
return true;
}
@@ -892,6 +905,12 @@ sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr,
(rxq->flags & SFC_EF100_RXQ_INGRESS_MPORT))
return ENOTSUP;
+ if ((unsup_rx_prefix_fields &
+ (1U << EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI)) == 0)
+ rxq->flags |= SFC_EF100_RXQ_VLAN_STRIP;
+ else
+ rxq->flags &= ~SFC_EF100_RXQ_VLAN_STRIP;
+
rxq->prefix_size = pinfo->erpl_length;
rxq->rearm_data = sfc_ef100_mk_mbuf_rearm_data(rxq->dp.dpq.port_id,
rxq->prefix_size);
@@ -1004,7 +1023,7 @@ struct sfc_dp_rx sfc_ef100_rx = {
SFC_DP_RX_FEAT_FLOW_MARK |
SFC_DP_RX_FEAT_INTR |
SFC_DP_RX_FEAT_STATS,
- .dev_offload_capa = 0,
+ .dev_offload_capa = RTE_ETH_RX_OFFLOAD_VLAN_STRIP,
.queue_offload_capa = RTE_ETH_RX_OFFLOAD_CHECKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM |
RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM |
@@ -938,6 +938,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_vlan_stripping == 0)
+ no_caps |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+
return ~no_caps;
}
@@ -1186,6 +1189,16 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index,
if (offloads & RTE_ETH_RX_OFFLOAD_RSS_HASH)
rxq_info->type_flags |= EFX_RXQ_FLAG_RSS_HASH;
+
+ if (sa->eth_dev->data->dev_conf.rxmode.offloads &
+ RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
+ rxq_info->type_flags |= EFX_RXQ_FLAG_VLAN_STRIP;
+ } else if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) {
+ sfc_err(sa, "VLAN stripping must be configured during device configure");
+ rc = EINVAL;
+ goto fail_bad_conf;
+ }
+
if ((sa->negotiated_rx_metadata & RTE_ETH_RX_METADATA_USER_FLAG) != 0)
rxq_info->type_flags |= EFX_RXQ_FLAG_USER_FLAG;
@@ -1691,6 +1704,12 @@ sfc_rx_check_mode(struct sfc_adapter *sa, struct rte_eth_rxmode *rxmode)
rxmode->offloads |= RTE_ETH_RX_OFFLOAD_OUTER_IPV4_CKSUM;
}
+ if ((rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) &&
+ (~offloads_supported & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)) {
+ sfc_err(sa, "VLAN stripping offload is requested but not supported");
+ rc = ENOTSUP;
+ }
+
return rc;
}