[3/8] net/nfp: add new metadata type for achieving VLAN strip

Message ID 20221128065359.12737-4-chaoyong.he@corigine.com (mailing list archive)
State Accepted, archived
Delegated to: Ferruh Yigit
Headers
Series Add the features for nfp include VLAN strip, QinQ strip, VLAN insert |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Chaoyong He Nov. 28, 2022, 6:53 a.m. UTC
  From: Peng Zhang <peng.zhang@corigine.com>

The firmware supplies VLAN strip information is stroed in
packet metadata. The field of this VLAN metadata includes
VLAN TPID, VLAN TCI and offload flag.

The new metadata type is NFP_NET_META_VLAN.

Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
---
 doc/guides/nics/nfp.rst    | 22 ++++++++++++++++
 drivers/net/nfp/nfp_ctrl.h | 10 ++++++++
 drivers/net/nfp/nfp_rxtx.c | 51 +++++++++++++++++++++++++++++++++-----
 drivers/net/nfp/nfp_rxtx.h | 22 ++++++++++++++++
 4 files changed, 99 insertions(+), 6 deletions(-)
  

Patch

diff --git a/doc/guides/nics/nfp.rst b/doc/guides/nics/nfp.rst
index 8034b2a668..fffff00f1e 100644
--- a/doc/guides/nics/nfp.rst
+++ b/doc/guides/nics/nfp.rst
@@ -271,3 +271,25 @@  the header. The hash value is 32 bit which need 1 data field.
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            Hash value                         |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+NFP_NET_META_VLAN
+Metadata with L2 (1W/4B)
+::
+
+   ----------------------------------------------------------------
+      3                   2                   1                   0
+    1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   |f|            reserved   | tpid| PCP |p|   vlan outermost VID  |
+   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                   ^                               ^
+                             NOTE: |             TCI               |
+                                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+   f 0 -> not stripping
+   1 -> stripping
+
+   tpid 0 -> RTE_ETHER_TYPE_VLAN 0x8100 IEEE 802.1Q VLAN tagging
+        1 -> RTE_ETHER_TYPE_QINQ 0x88a8 IEEE 802.1ad QINQ tagging
+   Tpid just be stored, now we don't handle it
+
+   The vlan[0] is the innermost VLAN
diff --git a/drivers/net/nfp/nfp_ctrl.h b/drivers/net/nfp/nfp_ctrl.h
index 372d537462..a90846fddf 100644
--- a/drivers/net/nfp/nfp_ctrl.h
+++ b/drivers/net/nfp/nfp_ctrl.h
@@ -30,8 +30,18 @@ 
 #define NFP_NET_META_FIELD_SIZE         4
 #define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1)
 
+/* Working with metadata vlan api (NFD version >= 2.0) */
+#define NFP_NET_META_VLAN_INFO          16
+#define NFP_NET_META_VLAN_OFFLOAD       31
+#define NFP_NET_META_VLAN_TPID          3
+#define NFP_NET_META_VLAN_MASK          ((1 << NFP_NET_META_VLAN_INFO) - 1)
+#define NFP_NET_META_VLAN_TPID_MASK     ((1 << NFP_NET_META_VLAN_TPID) - 1)
+#define NFP_NET_META_TPID(d)            (((d) >> NFP_NET_META_VLAN_INFO) & \
+						NFP_NET_META_VLAN_TPID_MASK)
+
 /* Prepend field types */
 #define NFP_NET_META_HASH               1 /* next field carries hash type */
+#define NFP_NET_META_VLAN               4
 
 /* Hash type pre-pended when a RSS hash was computed */
 #define NFP_NET_RSS_NONE                0
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index 320387eb7c..fb271e6d96 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -124,6 +124,7 @@  nfp_net_parse_meta(struct nfp_meta_parsed *meta,
 		struct rte_mbuf *mbuf)
 {
 	uint32_t meta_info;
+	uint32_t vlan_info;
 	uint8_t *meta_offset;
 	struct nfp_net_hw *hw = rxq->hw;
 
@@ -145,6 +146,15 @@  nfp_net_parse_meta(struct nfp_meta_parsed *meta,
 			meta->hash = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
 			meta->hash_type = meta_info & NFP_NET_META_FIELD_MASK;
 			break;
+		case NFP_NET_META_VLAN:
+			vlan_info = rte_be_to_cpu_32(*(rte_be32_t *)meta_offset);
+			meta->vlan[meta->vlan_layer].offload =
+					vlan_info >> NFP_NET_META_VLAN_OFFLOAD;
+			meta->vlan[meta->vlan_layer].tci =
+					vlan_info & NFP_NET_META_VLAN_MASK;
+			meta->vlan[meta->vlan_layer].tpid = NFP_NET_META_TPID(vlan_info);
+			++meta->vlan_layer;
+			break;
 		default:
 			/* Unsupported metadata can be a performance issue */
 			return;
@@ -213,6 +223,40 @@  nfp_net_parse_meta_hash(const struct nfp_meta_parsed *meta,
 	}
 }
 
+/*
+ * nfp_net_parse_meta_vlan() - Set mbuf vlan_strip data based on metadata info
+ *
+ * The VLAN info TPID and TCI are prepended to the packet data.
+ * Extract and decode it and set the mbuf fields.
+ */
+static void
+nfp_net_parse_meta_vlan(const struct nfp_meta_parsed *meta,
+		struct nfp_net_rx_desc *rxd,
+		struct nfp_net_rxq *rxq,
+		struct rte_mbuf *mb)
+{
+	struct nfp_net_hw *hw = rxq->hw;
+
+	if ((hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN) == 0)
+		return;
+
+	/*
+	 * The nic support the two way to send the VLAN info,
+	 * 1. According the metadata to send the VLAN info
+	 * 2. According the descriptor to sned the VLAN info
+	 *
+	 * If the nic doesn't send the VLAN info, it is not necessary
+	 * to do anything.
+	 */
+	if (meta->vlan_layer >= 1 && meta->vlan[0].offload != 0) {
+		mb->vlan_tci = rte_cpu_to_le_32(meta->vlan[0].tci);
+		mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+	} else if ((rxd->rxd.flags & PCIE_DESC_RX_VLAN) != 0) {
+		mb->vlan_tci = rte_cpu_to_le_32(rxd->rxd.vlan);
+		mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
+	}
+}
+
 /*
  * RX path design:
  *
@@ -349,16 +393,11 @@  nfp_net_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		memset(&meta, 0, sizeof(meta));
 		nfp_net_parse_meta(&meta, rxds, rxq, mb);
 		nfp_net_parse_meta_hash(&meta, rxds, rxq, mb);
+		nfp_net_parse_meta_vlan(&meta, rxds, rxq, mb);
 
 		/* Checking the checksum flag */
 		nfp_net_rx_cksum(rxq, rxds, mb);
 
-		if ((rxds->rxd.flags & PCIE_DESC_RX_VLAN) &&
-		    (hw->ctrl & NFP_NET_CFG_CTRL_RXVLAN)) {
-			mb->vlan_tci = rte_cpu_to_le_32(rxds->rxd.vlan);
-			mb->ol_flags |= RTE_MBUF_F_RX_VLAN | RTE_MBUF_F_RX_VLAN_STRIPPED;
-		}
-
 		/* Adding the mbuf to the mbuf array passed by the app */
 		rx_pkts[avail++] = mb;
 
diff --git a/drivers/net/nfp/nfp_rxtx.h b/drivers/net/nfp/nfp_rxtx.h
index 4cbf4080c5..a24ec9e560 100644
--- a/drivers/net/nfp/nfp_rxtx.h
+++ b/drivers/net/nfp/nfp_rxtx.h
@@ -25,6 +25,9 @@ 
 #define RTE_MBUF_DMA_ADDR_DEFAULT(mb) \
 	((uint64_t)((mb)->buf_iova + RTE_PKTMBUF_HEADROOM))
 
+/* Maximum number of supported VLANs in parsed form packet metadata. */
+#define NFP_META_MAX_VLANS       2
+
 /*
  * struct nfp_meta_parsed - Record metadata parsed from packet
  *
@@ -33,10 +36,29 @@ 
  *
  * @hash: RSS hash value
  * @hash_type: RSS hash type
+ * @vlan_layer: The layers of VLAN info which are passed from nic.
+ *              Only this number of entries of the @vlan array are valid.
+ *
+ * @vlan: Holds information parses from NFP_NET_META_VLAN. The inner most vlan
+ *        starts at position 0 and only @vlan_layer entries contain valid
+ *        information.
+ *
+ *        Currently only 1 layer of vlan is supported,
+ *        vlan[0] - vlan strip info
+ *
+ * @vlan.offload:  Flag indicates whether VLAN is offloaded
+ * @vlan.tpid: Vlan TPID
+ * @vlan.tci: Vlan TCI including PCP + Priority + VID
  */
 struct nfp_meta_parsed {
 	uint32_t hash;
 	uint8_t hash_type;
+	uint8_t vlan_layer;
+	struct {
+		uint8_t offload;
+		uint8_t tpid;
+		uint16_t tci;
+	} vlan[NFP_META_MAX_VLANS];
 };
 
 /*