[PATCH v7 4/4] net/sfc: support VLAN stripping offload

Artemii Morozov artemii.morozov at arknetworks.am
Thu Jun 22 17:11:23 CEST 2023


Extract VLAN TCI provided by the HW in the prefix and put it to mbuf.
VLAN stripping is supported for ef100 datapath only. This is device
level offload.

Signed-off-by: Artemii Morozov <artemii.morozov at arknetworks.am>
Reviewed-by: Viacheslav Galaktionov <viacheslav.galaktionov at arknetworks.am>
Reviewed-by: Ivan Malov <ivan.malov at arknetworks.am>
Reviewed-by: Andy Moreton <amoreton at xilinx.com>
---
 doc/guides/nics/sfc_efx.rst            |  4 ++--
 doc/guides/rel_notes/release_23_07.rst |  6 ++++++
 drivers/net/sfc/sfc.h                  |  1 +
 drivers/net/sfc/sfc_dp_rx.h            |  1 +
 drivers/net/sfc/sfc_ef100_rx.c         | 16 +++++++++++++++-
 drivers/net/sfc/sfc_port.c             | 11 +++++++++++
 drivers/net/sfc/sfc_rx.c               | 10 ++++++++++
 7 files changed, 46 insertions(+), 3 deletions(-)

diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst
index 24459da33e..eafb88191a 100644
--- a/doc/guides/nics/sfc_efx.rst
+++ b/doc/guides/nics/sfc_efx.rst
@@ -122,6 +122,8 @@ SFC EFX PMD has support for:
 
 - Port representors (see :ref: switch_representation)
 
+- VLAN stripping (if running firmware variant supports it)
+
 
 Non-supported Features
 ----------------------
@@ -134,8 +136,6 @@ The features not yet supported include:
 
 - VLAN filtering
 
-- VLAN stripping
-
 - LRO
 
 
diff --git a/doc/guides/rel_notes/release_23_07.rst b/doc/guides/rel_notes/release_23_07.rst
index 738d35d9f7..ce523800c7 100644
--- a/doc/guides/rel_notes/release_23_07.rst
+++ b/doc/guides/rel_notes/release_23_07.rst
@@ -185,6 +185,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 VLAN stripping support on SN1000 SmartNICs
+
 
 Removed Items
 -------------
diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h
index 25cdeaa5cd..2432a2307e 100644
--- a/drivers/net/sfc/sfc.h
+++ b/drivers/net/sfc/sfc.h
@@ -75,6 +75,7 @@ struct sfc_port {
 	unsigned int			flow_ctrl;
 	boolean_t			flow_ctrl_autoneg;
 	boolean_t			include_fcs;
+	boolean_t			vlan_strip;
 	size_t				pdu;
 
 	/*
diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 8a504bdcf1..9f9bf28988 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -70,6 +70,7 @@ struct sfc_dp_rx_qcreate_info {
 	unsigned int		flags;
 #define SFC_RXQ_FLAG_RSS_HASH	0x1
 #define SFC_RXQ_FLAG_INGRESS_MPORT	0x2
+#define SFC_RXQ_FLAG_VLAN_STRIPPED_TCI	0x4
 
 	/** Rx queue size */
 	unsigned int		rxq_entries;
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 5563bd9a0b..2677003da3 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_STRIPPED_TCI	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,14 @@ 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_STRIPPED_TCI &&
+	    EFX_TEST_XWORD_BIT(rx_prefix[0],
+				   ESF_GZ_RX_PREFIX_VLAN_STRIPPED_LBN)) {
+		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;
 }
@@ -813,6 +823,9 @@ sfc_ef100_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 	if (info->flags & SFC_RXQ_FLAG_INGRESS_MPORT)
 		rxq->flags |= SFC_EF100_RXQ_INGRESS_MPORT;
 
+	if (info->flags & SFC_RXQ_FLAG_VLAN_STRIPPED_TCI)
+		rxq->flags |= SFC_EF100_RXQ_VLAN_STRIPPED_TCI;
+
 	sfc_ef100_rx_debug(rxq, "RxQ doorbell is %p", rxq->doorbell);
 
 	*dp_rxqp = &rxq->dp;
@@ -1004,7 +1017,8 @@ 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	= RTE_ETH_RX_OFFLOAD_KEEP_CRC,
+	.dev_offload_capa	= RTE_ETH_RX_OFFLOAD_KEEP_CRC |
+				  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_port.c b/drivers/net/sfc/sfc_port.c
index 3897facfbc..e5bb6d8620 100644
--- a/drivers/net/sfc/sfc_port.c
+++ b/drivers/net/sfc/sfc_port.c
@@ -225,6 +225,11 @@ sfc_port_start(struct sfc_adapter *sa)
 	if (rc != 0)
 		goto fail_mac_fcntl_set;
 
+	sfc_log_init(sa, "set vlan strip to %u", port->vlan_strip);
+	rc = efx_port_vlan_strip_set(sa->nic, port->vlan_strip);
+	if (rc != 0)
+		goto fail_mac_vlan_strip_set;
+
 	/* 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);
@@ -345,6 +350,7 @@ sfc_port_start(struct sfc_adapter *sa)
 fail_mac_pdu_set:
 fail_phy_adv_cap_set:
 fail_mac_fcntl_set:
+fail_mac_vlan_strip_set:
 #if EFSYS_OPT_LOOPBACK
 fail_loopback_set:
 #endif
@@ -392,6 +398,11 @@ sfc_port_configure(struct sfc_adapter *sa)
 	else
 		port->include_fcs = false;
 
+	if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP)
+		port->vlan_strip = true;
+	else
+		port->vlan_strip = false;
+
 	return 0;
 }
 
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index ac94d973de..1dde2c1110 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -942,6 +942,9 @@ sfc_rx_get_offload_mask(struct sfc_adapter *sa)
 	if (encp->enc_rx_include_fcs_supported == 0)
 		no_caps |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
 
+	if (encp->enc_rx_vlan_stripping_supported == 0)
+		no_caps |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
+
 	return ~no_caps;
 }
 
@@ -1113,6 +1116,7 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index,
 	struct sfc_rxq *rxq;
 	struct sfc_dp_rx_qcreate_info info;
 	struct sfc_dp_rx_hw_limits hw_limits;
+	struct sfc_port *port = &sa->port;
 	uint16_t rx_free_thresh;
 	const char *error;
 
@@ -1197,6 +1201,9 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index,
 	    sfc_ft_is_active(sa))
 		rxq_info->type_flags |= EFX_RXQ_FLAG_USER_MARK;
 
+	if (port->vlan_strip)
+		rxq_info->type_flags |= EFX_RXQ_FLAG_VLAN_STRIPPED_TCI;
+
 	rc = sfc_ev_qinit(sa, SFC_EVQ_TYPE_RX, sw_index,
 			  evq_entries, socket_id, &evq);
 	if (rc != 0)
@@ -1232,6 +1239,9 @@ sfc_rx_qinit(struct sfc_adapter *sa, sfc_sw_index_t sw_index,
 	if (rxq_info->type_flags & EFX_RXQ_FLAG_INGRESS_MPORT)
 		rxq_info->rxq_flags |= SFC_RXQ_FLAG_INGRESS_MPORT;
 
+	if (rxq_info->type_flags & EFX_RXQ_FLAG_VLAN_STRIPPED_TCI)
+		rxq_info->rxq_flags |= SFC_RXQ_FLAG_VLAN_STRIPPED_TCI;
+
 	rxq->buf_size = buf_size;
 
 	rc = sfc_dma_alloc(sa, "rxq", sw_index, EFX_NIC_DMA_ADDR_RX_RING,
-- 
2.34.1



More information about the dev mailing list