From: Peng Zhang <peng.zhang@corigine.com>
The firmware supplies VLAN insert information as packet metadata.
The field of this VLAN metadata includes VLAN TPID and VLAN
TCI.
Configuration control bit NFP_NET_CFG_CTRL_TXVLAN_V2 is to
signal availability of VLAN insert features of the firmware.
This feature already was implemented with NFD3, now it can be
supported with NFDk.
Signed-off-by: Peng Zhang <peng.zhang@corigine.com>
Reviewed-by: Chaoyong He <chaoyong.he@corigine.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@corigine.com>
---
doc/guides/nics/nfp.rst | 42 +++++++++++++++++++++++++++
drivers/net/nfp/nfp_ctrl.h | 1 +
drivers/net/nfp/nfp_rxtx.c | 58 ++++++++++++++++++++++++++++++++++++++
drivers/net/nfp/nfp_rxtx.h | 3 +-
4 files changed, 103 insertions(+), 1 deletion(-)
@@ -219,6 +219,9 @@ Metadata Format
The NFP packet metadata format
+NFD3
+~~~~
+
The packet metadata starts with a field type header that can contain up-to
8 4-bit datatype specifiers (32-bits in total). This is followed by up to 8
32-bit words of data for each field described in the header. And directly
@@ -254,6 +257,45 @@ be wrote N times in the heads.
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+NFDk
+~~~~
+
+The packet metadata starts with a field type header that can contain 8 bit
+metadata length and 6 4-bit datatype specifiers (32-bits in total). This is
+followed by up to 6 32-bit words of data for each field described in the
+header. And directly following the metadata (header and data) comes the
+packet.
+
+The order of type is correspond with the data, but the nums of data field are
+decided by the corresponding type, if the type need N data field, it need to
+be wrote N times in the heads. It is the same with NFD3.
+::
+
+ 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
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Type5 | Type4 | Type3 | Type2 | Type1 | Type0 |metadata length|
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 0 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 1 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 3 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 4 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 5 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 6 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Data for field 7 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | Packet Data |
+ | ... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
There are two classes of metadata one for ingress and one for egress. In each
class the supported NFP types are:
@@ -30,6 +30,7 @@
#define NFP_NET_META_FIELD_SIZE 4
#define NFP_NET_META_FIELD_MASK ((1 << NFP_NET_META_FIELD_SIZE) - 1)
#define NFP_NET_META_HEADER_SIZE 4
+#define NFP_NET_META_NFDK_LENGTH 8
/* Working with metadata vlan api (NFD version >= 2.0) */
#define NFP_NET_META_VLAN_INFO 16
@@ -1058,6 +1058,63 @@ nfp_net_nfd3_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pk
return i;
}
+static void
+nfp_net_nfdk_set_meta_data(struct rte_mbuf *pkt,
+ struct nfp_net_txq *txq,
+ uint64_t *metadata)
+{
+ char *meta;
+ uint8_t layer = 0;
+ uint32_t meta_type;
+ struct nfp_net_hw *hw;
+ uint32_t header_offset;
+ uint8_t vlan_layer = 0;
+ struct nfp_net_meta_raw meta_data;
+
+ memset(&meta_data, 0, sizeof(meta_data));
+ hw = txq->hw;
+
+ if ((pkt->ol_flags & RTE_MBUF_F_TX_VLAN) != 0 &&
+ (hw->ctrl & NFP_NET_CFG_CTRL_TXVLAN_V2) != 0) {
+ if (meta_data.length == 0)
+ meta_data.length = NFP_NET_META_HEADER_SIZE;
+ meta_data.length += NFP_NET_META_FIELD_SIZE;
+ meta_data.header |= NFP_NET_META_VLAN;
+ }
+
+ if (meta_data.length == 0)
+ return;
+
+ meta_type = meta_data.header;
+ header_offset = meta_type << NFP_NET_META_NFDK_LENGTH;
+ meta_data.header = header_offset | meta_data.length;
+ meta_data.header = rte_cpu_to_be_32(meta_data.header);
+ meta = rte_pktmbuf_prepend(pkt, meta_data.length);
+ memcpy(meta, &meta_data.header, sizeof(meta_data.header));
+ meta += NFP_NET_META_HEADER_SIZE;
+
+ for (; meta_type != 0; meta_type >>= NFP_NET_META_FIELD_SIZE, layer++,
+ meta += NFP_NET_META_FIELD_SIZE) {
+ switch (meta_type & NFP_NET_META_FIELD_MASK) {
+ case NFP_NET_META_VLAN:
+ if (vlan_layer > 0) {
+ PMD_DRV_LOG(ERR, "At most 1 layers of vlan is supported");
+ return;
+ }
+ nfp_net_set_meta_vlan(&meta_data, pkt, layer);
+ vlan_layer++;
+ break;
+ default:
+ PMD_DRV_LOG(ERR, "The metadata type not supported");
+ return;
+ }
+
+ memcpy(meta, &meta_data.data[layer], sizeof(meta_data.data[layer]));
+ }
+
+ *metadata = NFDK_DESC_TX_CHAIN_META;
+}
+
static int
nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,
uint16_t queue_idx,
@@ -1383,6 +1440,7 @@ nfp_net_nfdk_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pk
RTE_MBUF_PREFETCH_TO_FREE(*lmbuf);
temp_pkt = pkt;
+ nfp_net_nfdk_set_meta_data(pkt, txq, &metadata);
if (unlikely(pkt->nb_segs > 1 &&
!(hw->cap & NFP_NET_CFG_CTRL_GATHER))) {
@@ -36,7 +36,7 @@
* Describe the raw metadata format, useful when preparing metadata for a
* transmission mbuf.
*
- * @header: NFD3 Contains the 8 4-bit type fields
+ * @header: NFD3 or NFDk field type header (see format in nfp.rst)
* @data: Array of each fields data member
* @length: Keep track of number of valid fields in @header and data. Not part
* of the raw metadata.
@@ -118,6 +118,7 @@ struct nfp_meta_parsed {
#define NFDK_DESC_TX_TYPE_SIMPLE 8
#define NFDK_DESC_TX_TYPE_GATHER 1
#define NFDK_DESC_TX_EOP BIT(14)
+#define NFDK_DESC_TX_CHAIN_META BIT(3)
#define NFDK_DESC_TX_L4_CSUM BIT(1)
#define NFDK_DESC_TX_L3_CSUM BIT(0)