All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ed Czeck <ed.czeck@atomicrules.com>
To: dev@dpdk.org, ferruh.yigit@intel.com
Cc: shepard.siegel@atomicrules.com, john.miller@atomicrules.com
Subject: [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD
Date: Thu,  4 Mar 2021 15:33:20 -0500	[thread overview]
Message-ID: <20210304203321.6154-4-ed.czeck@atomicrules.com> (raw)
In-Reply-To: <20210304203321.6154-1-ed.czeck@atomicrules.com>

In this commit we generalize the movement of user-specified
meta data between mbufs and FPGA AXIS tuser fields using
user-defined hook functions.

- Previous use of PMD dynfields are removed
- Hook function added to ark_user_ext
- Add hook function calls in rx and tx paths
- Rename all extension function with rte_pmd_ark prefix
- Move extension prototype to rte_pmd_ark.h
- Update documentation with an extension example

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 doc/guides/nics/ark.rst         | 137 +++++++++++-
 drivers/net/ark/ark_ethdev.c    |  90 ++------
 drivers/net/ark/ark_ethdev_rx.c |  27 ++-
 drivers/net/ark/ark_ethdev_rx.h |   3 -
 drivers/net/ark/ark_ethdev_tx.c |  23 +-
 drivers/net/ark/ark_ext.h       |  90 --------
 drivers/net/ark/ark_global.h    |  20 ++
 drivers/net/ark/ark_udm.h       |   5 +-
 drivers/net/ark/rte_pmd_ark.h   | 384 +++++++++++++++++++++++---------
 drivers/net/ark/version.map     |   7 -
 10 files changed, 487 insertions(+), 299 deletions(-)
 delete mode 100644 drivers/net/ark/ark_ext.h

diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index 18434c7a4..b9c108b9b 100644
--- a/doc/guides/nics/ark.rst
+++ b/doc/guides/nics/ark.rst
@@ -1,5 +1,5 @@
 .. SPDX-License-Identifier: BSD-3-Clause
-    Copyright (c) 2015-2017 Atomic Rules LLC
+    Copyright (c) 2015-2021 Atomic Rules LLC
     All rights reserved.
 
 ARK Poll Mode Driver
@@ -130,6 +130,141 @@ Configuration Information
      be offloaded or remain in host software.
 
 
+Dynamic PMD Extension
+---------------------
+
+Dynamic PMD extensions allow users to customize net/ark functionality
+using their own code. Arkville RTL and this PMD support high-throughput data
+movement, and these extensions allow PMD support for users' FPGA
+features.
+Dynamic PMD extensions operate by having users supply a shared object
+file which is loaded by Arkville PMD during initialization.  The
+object file contains extension (or hook) functions that are registered
+and then called during PMD operations.
+
+The allowable set of extension functions are defined and documented in
+``rte_pmd_ark.h``, only the initialization function,
+``rte_pmd_ark_dev_init()``, is required; all others are optional. The
+following sections give a small extension example along with
+instructions for compiling and using the extension.
+
+
+Extension Example
+^^^^^^^^^^^^^^^^^
+
+The following example shows an extension which populates mbuf fields
+during RX from user meta data coming from FPGA hardware.
+
+.. code-block:: c
+
+   #include <rte_pmd_ark.h>
+   #include <rte_mbuf.h>
+   #include <rte_ethdev.h>
+   #include <rte_malloc.h>
+
+   /* Global structure passed to extension/hook functions */
+   struct ark_user_extension {
+       int timestamp_dynfield_offset;
+   };
+
+   /* RX tuser field based on user's hardware */
+   struct user_rx_meta {
+      uint64_t timestamp;
+      uint32_t rss;
+   } __rte_packed;
+
+   /* Create ark_user_extension object for use in other hook functions */
+   void *rte_pmd_ark_dev_init(struct rte_eth_dev * dev,
+                              void * abar, int port_id )
+   {
+      RTE_SET_USED(dev);
+      RTE_SET_USED(abar);
+      fprintf(stderr, "Called Arkville user extension for port %u\n",
+              port_id);
+
+      struct ark_user_extension *xdata = rte_zmalloc("macExtS",
+             sizeof(struct ark_user_extension), 64);
+      if (!xdata)
+         return NULL;
+
+      /* register dynfield for rx timestamp */
+      rte_mbuf_dyn_rx_timestamp_register(&xdata->timestamp_dynfield_offset,
+                                         NULL);
+
+      fprintf(stderr, "timestamp fields offset in extension is %d\n",
+              xdata->timestamp_dynfield_offset);
+      return xdata;
+   }
+
+   /* uninitialization */
+   void rte_pmd_ark_dev_uninit(struct rte_eth_dev * dev, void *user_data)
+   {
+      rte_free(user_data);
+   }
+
+   /* Hook function -- called for each RX packet
+    * Extract RX timestamp and RSS from meta and place in mbuf
+    */
+   void rte_pmd_ark_rx_user_meta_hook(struct rte_mbuf *mbuf,
+                                      const uint32_t *meta,
+                                      void *user_data)
+   {
+      struct ark_user_extension *xdata = user_data;
+      struct user_rx_meta *user_rx = (struct user_rx_meta*)meta;
+      *RTE_MBUF_DYNFIELD(mbuf, xdata->timestamp_dynfield_offset, uint64_t*) =
+                         user_rx->timestamp;
+      mbuf->hash.rss = user_rx->rss;
+   }
+
+
+Compiling Extension
+^^^^^^^^^^^^^^^^^^^
+
+It is recommended to the compile the extension code with
+``-Wmissing-prototypes`` flag to insure correct function types. Typical
+DPDK options will also be needed.
+
+
+An example command line is give below
+
+.. code-block:: console
+
+    cc `pkg-config --cflags libdpdk` \
+    -O3 -DALLOW_EXPERIMENTAL_API -fPIC -Wall -Wmissing-prototypes -c \
+    -o pmd_net_ark_ext.o pmd_net_ark_ext.c
+    # Linking
+    cc -o libfx1_100g_ext.so.1 -shared \
+    `pkg-config --libs libdpdk` \
+    -Wl,--unresolved-symbols=ignore-all \
+    -Wl,-soname,libpmd_net_ark_ext.so.1 pmd_net_ark_ext.o
+
+In a ``Makefile`` this would be
+
+.. code-block:: Makefile
+
+   CFLAGS += $(shell pkg-config --cflags libdpdk)
+   CFLAGS += -O3 -DALLOW_EXPERIMENTAL_API -fPIC -Wall -Wmissing-prototypes
+   # Linking
+   LDFLAGS += $(shell pkg-config --libs libdpdk)
+   LDFLAGS += -Wl,--unresolved-symbols=ignore-all -Wl,-soname,libpmd_net_ark_ext.so.1
+
+The application must be linked with the ``-export-dynamic`` flags if any
+DPDK or application specific code will called from the extension.
+
+
+Enabling Extension
+^^^^^^^^^^^^^^^^^^
+
+The extensions are enabled in the application through the use of an
+environment variable ``ARK_EXT_PATH`` This variable points to the lib
+extension file generated above.  For example:
+
+.. code-block:: console
+
+   export ARK_EXT_PATH=$(PWD)/libpmd_net_ark_ext.so.1
+   testpmd ...
+
+
 Building DPDK
 -------------
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index fc6d53a35..edbcfe8d4 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -79,12 +79,6 @@ static int  eth_ark_set_mtu(struct rte_eth_dev *dev, uint16_t size);
 #define ARK_TX_MAX_QUEUE (4096 * 4)
 #define ARK_TX_MIN_QUEUE (256)
 
-uint64_t ark_timestamp_rx_dynflag;
-int ark_timestamp_dynfield_offset = -1;
-
-int rte_pmd_ark_rx_userdata_dynfield_offset = -1;
-int rte_pmd_ark_tx_userdata_dynfield_offset = -1;
-
 static const char * const valid_arguments[] = {
 	ARK_PKTGEN_ARG,
 	ARK_PKTCHKR_ARG,
@@ -190,58 +184,64 @@ check_for_ext(struct ark_adapter *ark)
 	/* Get the entry points */
 	ark->user_ext.dev_init =
 		(void *(*)(struct rte_eth_dev *, void *, int))
-		dlsym(ark->d_handle, "dev_init");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_init");
 	ARK_PMD_LOG(DEBUG, "device ext init pointer = %p\n",
 		      ark->user_ext.dev_init);
 	ark->user_ext.dev_get_port_count =
 		(int (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_get_port_count");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_get_port_count");
 	ark->user_ext.dev_uninit =
 		(void (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_uninit");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_uninit");
 	ark->user_ext.dev_configure =
 		(int (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_configure");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_configure");
 	ark->user_ext.dev_start =
 		(int (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_start");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_start");
 	ark->user_ext.dev_stop =
 		(void (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_stop");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_stop");
 	ark->user_ext.dev_close =
 		(void (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_close");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_close");
 	ark->user_ext.link_update =
 		(int (*)(struct rte_eth_dev *, int, void *))
-		dlsym(ark->d_handle, "link_update");
+		dlsym(ark->d_handle, "rte_pmd_ark_link_update");
 	ark->user_ext.dev_set_link_up =
 		(int (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_set_link_up");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_up");
 	ark->user_ext.dev_set_link_down =
 		(int (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "dev_set_link_down");
+		dlsym(ark->d_handle, "rte_pmd_ark_dev_set_link_down");
 	ark->user_ext.stats_get =
 		(int (*)(struct rte_eth_dev *, struct rte_eth_stats *,
 			  void *))
-		dlsym(ark->d_handle, "stats_get");
+		dlsym(ark->d_handle, "rte_pmd_ark_stats_get");
 	ark->user_ext.stats_reset =
 		(void (*)(struct rte_eth_dev *, void *))
-		dlsym(ark->d_handle, "stats_reset");
+		dlsym(ark->d_handle, "rte_pmd_ark_stats_reset");
 	ark->user_ext.mac_addr_add =
 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
 			uint32_t, uint32_t, void *))
-		dlsym(ark->d_handle, "mac_addr_add");
+		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_add");
 	ark->user_ext.mac_addr_remove =
 		(void (*)(struct rte_eth_dev *, uint32_t, void *))
-		dlsym(ark->d_handle, "mac_addr_remove");
+		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_remove");
 	ark->user_ext.mac_addr_set =
 		(void (*)(struct rte_eth_dev *, struct rte_ether_addr *,
 			  void *))
-		dlsym(ark->d_handle, "mac_addr_set");
+		dlsym(ark->d_handle, "rte_pmd_ark_mac_addr_set");
 	ark->user_ext.set_mtu =
 		(int (*)(struct rte_eth_dev *, uint16_t,
 			  void *))
-		dlsym(ark->d_handle, "set_mtu");
+		dlsym(ark->d_handle, "rte_pmd_ark_set_mtu");
+	ark->user_ext.rx_user_meta_hook =
+		(rx_user_meta_hook_fn)dlsym(ark->d_handle,
+					    "rte_pmd_ark_rx_user_meta_hook");
+	ark->user_ext.tx_user_meta_hook =
+		(tx_user_meta_hook_fn)dlsym(ark->d_handle,
+					    "rte_pmd_ark_tx_user_meta_hook");
 
 	return found;
 }
@@ -254,16 +254,6 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	int ret;
 	int port_count = 1;
 	int p;
-	static const struct rte_mbuf_dynfield ark_tx_userdata_dynfield_desc = {
-		.name = RTE_PMD_ARK_TX_USERDATA_DYNFIELD_NAME,
-		.size = sizeof(rte_pmd_ark_tx_userdata_t),
-		.align = __alignof__(rte_pmd_ark_tx_userdata_t),
-	};
-	static const struct rte_mbuf_dynfield ark_rx_userdata_dynfield_desc = {
-		.name = RTE_PMD_ARK_RX_USERDATA_DYNFIELD_NAME,
-		.size = sizeof(rte_pmd_ark_rx_userdata_t),
-		.align = __alignof__(rte_pmd_ark_rx_userdata_t),
-	};
 
 	ark->eth_dev = dev;
 
@@ -274,30 +264,6 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	if (ret)
 		return ret;
 
-	/* Extra mbuf fields for user data */
-	if (RTE_PMD_ARK_TX_USERDATA_ENABLE) {
-		rte_pmd_ark_tx_userdata_dynfield_offset =
-		    rte_mbuf_dynfield_register(&ark_tx_userdata_dynfield_desc);
-		if (rte_pmd_ark_tx_userdata_dynfield_offset < 0) {
-			ARK_PMD_LOG(ERR,
-				    "Failed to register mbuf field for tx userdata\n");
-			return -rte_errno;
-		}
-		ARK_PMD_LOG(INFO, "Registered TX-meta dynamic field at %d\n",
-			    rte_pmd_ark_tx_userdata_dynfield_offset);
-	}
-	if (RTE_PMD_ARK_RX_USERDATA_ENABLE) {
-		rte_pmd_ark_rx_userdata_dynfield_offset =
-		    rte_mbuf_dynfield_register(&ark_rx_userdata_dynfield_desc);
-		if (rte_pmd_ark_rx_userdata_dynfield_offset < 0) {
-			ARK_PMD_LOG(ERR,
-				    "Failed to register mbuf field for rx userdata\n");
-			return -rte_errno;
-		}
-		ARK_PMD_LOG(INFO, "Registered RX-meta dynamic field at %d\n",
-			    rte_pmd_ark_rx_userdata_dynfield_offset);
-	}
-
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
 	rte_eth_copy_pci_info(dev, pci_dev);
 	dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
@@ -558,18 +524,6 @@ static int
 eth_ark_dev_configure(struct rte_eth_dev *dev)
 {
 	struct ark_adapter *ark = dev->data->dev_private;
-	int ret;
-
-	if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TIMESTAMP) {
-		ret = rte_mbuf_dyn_rx_timestamp_register(
-				&ark_timestamp_dynfield_offset,
-				&ark_timestamp_rx_dynflag);
-		if (ret != 0) {
-			ARK_PMD_LOG(ERR,
-				"Failed to register Rx timestamp field/flag\n");
-			return -rte_errno;
-		}
-	}
 
 	eth_ark_dev_set_link_up(dev);
 	if (ark->user_ext.dev_configure)
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 21a9af41a..48ea48404 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -39,6 +39,9 @@ struct ark_rx_queue {
 	struct ark_udm_t *udm;
 	struct ark_mpu_t *mpu;
 
+	rx_user_meta_hook_fn rx_user_meta_hook;
+	void *ext_user_data;
+
 	uint32_t queue_size;
 	uint32_t queue_mask;
 
@@ -53,8 +56,7 @@ struct ark_rx_queue {
 
 	uint32_t unused;
 
-	/* separate cache line */
-	/* second cache line - fields only used in slow path */
+	/* next cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
 
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
@@ -167,6 +169,8 @@ eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	queue->queue_index = queue_idx;
 	queue->queue_size = nb_desc;
 	queue->queue_mask = nb_desc - 1;
+	queue->rx_user_meta_hook = ark->user_ext.rx_user_meta_hook;
+	queue->ext_user_data = ark->user_data[dev->data->port_id];
 
 	queue->reserve_q =
 		rte_zmalloc_socket("Ark_rx_queue mbuf",
@@ -243,8 +247,11 @@ eth_ark_recv_pkts(void *rx_queue,
 	struct ark_rx_queue *queue;
 	register uint32_t cons_index, prod_index;
 	uint16_t nb;
+	uint16_t i;
 	struct rte_mbuf *mbuf;
+	struct rte_mbuf **pmbuf;
 	struct ark_rx_meta *meta;
+	rx_user_meta_hook_fn rx_user_meta_hook;
 
 	queue = (struct ark_rx_queue *)rx_queue;
 	if (unlikely(queue == 0))
@@ -253,6 +260,8 @@ eth_ark_recv_pkts(void *rx_queue,
 		return 0;
 	prod_index = queue->prod_index;
 	cons_index = queue->cons_index;
+	if (prod_index == cons_index)
+		return 0;
 	nb = 0;
 
 	while (prod_index != cons_index) {
@@ -266,13 +275,6 @@ eth_ark_recv_pkts(void *rx_queue,
 
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
-		/* set timestamp if enabled at least on one device */
-		if (ark_timestamp_rx_dynflag > 0) {
-			*RTE_MBUF_DYNFIELD(mbuf, ark_timestamp_dynfield_offset,
-				rte_mbuf_timestamp_t *) = meta->timestamp;
-			mbuf->ol_flags |= ark_timestamp_rx_dynflag;
-		}
-		rte_pmd_ark_mbuf_rx_userdata_set(mbuf, meta->user_data);
 
 		if (ARK_DEBUG_CORE) {	/* debug sanity checks */
 			if ((meta->pkt_len > (1024 * 16)) ||
@@ -315,6 +317,13 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
+	rx_user_meta_hook = queue->rx_user_meta_hook;
+	for (pmbuf = rx_pkts, i = 0; rx_user_meta_hook && i < nb; i++) {
+		mbuf = *pmbuf++;
+		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
+		rx_user_meta_hook(mbuf, meta->user_meta, queue->ext_user_data);
+	}
+
 	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
diff --git a/drivers/net/ark/ark_ethdev_rx.h b/drivers/net/ark/ark_ethdev_rx.h
index 33c1f2c95..c8dc340a8 100644
--- a/drivers/net/ark/ark_ethdev_rx.h
+++ b/drivers/net/ark/ark_ethdev_rx.h
@@ -11,9 +11,6 @@
 #include <rte_mempool.h>
 #include <ethdev_driver.h>
 
-extern uint64_t ark_timestamp_rx_dynflag;
-extern int ark_timestamp_dynfield_offset;
-
 int eth_ark_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			       uint16_t queue_idx,
 			       uint16_t nb_desc,
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 00e5dbf7c..d6e8345b2 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -33,6 +33,9 @@ struct ark_tx_queue {
 	/* Stats HW tracks bytes and packets, need to count send errors */
 	uint64_t tx_errors;
 
+	tx_user_meta_hook_fn tx_user_meta_hook;
+	void *ext_user_data;
+
 	uint32_t queue_size;
 	uint32_t queue_mask;
 
@@ -45,9 +48,7 @@ struct ark_tx_queue {
 	/* The queue Index within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t pad[1];
-
-	/* second cache line - fields written by device */
+	/* next cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
 	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
@@ -120,15 +121,17 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	uint32_t user_meta;
+	uint32_t user_meta[5];
 
 	int stat;
 	int32_t prod_index_limit;
 	uint16_t nb;
-	uint8_t user_len = 1;
+	uint8_t user_len = 0;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
+	tx_user_meta_hook_fn tx_user_meta_hook;
 
 	queue = (struct ark_tx_queue *)vtxq;
+	tx_user_meta_hook = queue->tx_user_meta_hook;
 
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
@@ -163,16 +166,18 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 			memset(appended, 0, to_add);
 		}
 
-		user_meta = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+		if (tx_user_meta_hook)
+			tx_user_meta_hook(mbuf, user_meta, &user_len,
+					  queue->ext_user_data);
 		if (unlikely(mbuf->nb_segs != 1)) {
 			stat = eth_ark_tx_jumbo(queue, mbuf,
-						&user_meta, user_len);
+						user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
 			eth_ark_tx_desc_fill(queue, mbuf,
 					     ARK_DDM_SOP | ARK_DDM_EOP,
-					     &user_meta, user_len);
+					     user_meta, user_len);
 		}
 	}
 
@@ -271,6 +276,8 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 	queue->phys_qid = qidx;
 	queue->queue_index = queue_idx;
 	dev->data->tx_queues[queue_idx] = queue;
+	queue->tx_user_meta_hook = ark->user_ext.tx_user_meta_hook;
+	queue->ext_user_data = ark->user_data[dev->data->port_id];
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
diff --git a/drivers/net/ark/ark_ext.h b/drivers/net/ark/ark_ext.h
deleted file mode 100644
index 821fb55bb..000000000
--- a/drivers/net/ark/ark_ext.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
- */
-
-#ifndef _ARK_EXT_H_
-#define _ARK_EXT_H_
-
-#include <ethdev_driver.h>
-
-/*
- * This is the template file for users who which to define a dynamic
- * extension to the Arkville PMD.   User's who create an extension
- * should include this file and define the necessary and desired
- * functions.
- * Only 1 function is required for an extension, dev_init(); all other
- * functions prototyped in this file are optional.
- */
-
-/*
- * Called post PMD init.
- * The implementation returns its private data that gets passed into
- * all other functions as user_data
- * The ARK extension implementation MUST implement this function
- */
-void *dev_init(struct rte_eth_dev *dev, void *a_bar, int port_id);
-
-/* Called during device shutdown */
-void dev_uninit(struct rte_eth_dev *dev, void *user_data);
-
-/* This call is optional and allows the
- * extension to specify the number of supported ports.
- */
-uint8_t dev_get_port_count(struct rte_eth_dev *dev,
-			   void *user_data);
-
-/*
- * The following functions are optional and are directly mapped
- * from the DPDK PMD ops structure.
- * Each function if implemented is called after the ARK PMD
- * implementation executes.
- */
-
-int dev_configure(struct rte_eth_dev *dev,
-		  void *user_data);
-
-int dev_start(struct rte_eth_dev *dev,
-	      void *user_data);
-
-void dev_stop(struct rte_eth_dev *dev,
-	      void *user_data);
-
-void dev_close(struct rte_eth_dev *dev,
-	       void *user_data);
-
-int link_update(struct rte_eth_dev *dev,
-		int wait_to_complete,
-		void *user_data);
-
-int dev_set_link_up(struct rte_eth_dev *dev,
-		    void *user_data);
-
-int dev_set_link_down(struct rte_eth_dev *dev,
-		      void *user_data);
-
-int stats_get(struct rte_eth_dev *dev,
-	       struct rte_eth_stats *stats,
-	       void *user_data);
-
-void stats_reset(struct rte_eth_dev *dev,
-		 void *user_data);
-
-void mac_addr_add(struct rte_eth_dev *dev,
-		  struct rte_ether_addr *macadr,
-		  uint32_t index,
-		  uint32_t pool,
-		  void *user_data);
-
-void mac_addr_remove(struct rte_eth_dev *dev,
-		     uint32_t index,
-		     void *user_data);
-
-void mac_addr_set(struct rte_eth_dev *dev,
-		  struct rte_ether_addr *mac_addr,
-		  void *user_data);
-
-int set_mtu(struct rte_eth_dev *dev,
-	    uint16_t size,
-	    void *user_data);
-
-#endif
diff --git a/drivers/net/ark/ark_global.h b/drivers/net/ark/ark_global.h
index 91726ecc2..6f9b3013d 100644
--- a/drivers/net/ark/ark_global.h
+++ b/drivers/net/ark/ark_global.h
@@ -57,6 +57,23 @@
 		void     *v;	   \
 	} name
 
+
+/* Extension hooks for extraction and placement of user meta data
+ * during RX an TX operations. These functions are the bridge
+ * between the mbuf struct and the tuser fields on the AXIS
+ * interfaces in the FPGA
+ */
+/* RX hook populates mbuf fields from user defined *meta up to 20 bytes */
+typedef void (*rx_user_meta_hook_fn)(struct rte_mbuf *mbuf,
+				     const uint32_t *meta,
+				     void *ext_user_data);
+/* TX hook poplulate *meta, with up to 20 bytes.  meta_cnt
+ * returns the number of uint32_t words populated, 0 to 5
+ */
+typedef void (*tx_user_meta_hook_fn)(const struct rte_mbuf *mbuf,
+				     uint32_t *meta, uint8_t *meta_cnt,
+				     void *ext_user_data);
+
 struct ark_user_ext {
 	void *(*dev_init)(struct rte_eth_dev *, void *abar, int port_id);
 	void (*dev_uninit)(struct rte_eth_dev *, void *);
@@ -79,6 +96,9 @@ struct ark_user_ext {
 	void (*mac_addr_set)(struct rte_eth_dev *, struct rte_ether_addr *,
 			void *);
 	int (*set_mtu)(struct rte_eth_dev *, uint16_t, void *);
+	/* user meta, hook functions  */
+	rx_user_meta_hook_fn rx_user_meta_hook;
+	tx_user_meta_hook_fn tx_user_meta_hook;
 };
 
 struct ark_adapter {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index ea92d4b6e..4e51a5e82 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -19,9 +19,8 @@
  * -- 32 bytes
  */
 struct ark_rx_meta {
-	uint64_t timestamp;
-	uint64_t user_data;
-	uint8_t  reserved[14];
+	uint32_t user_meta[5];	/* user defined based on fpga code */
+	uint8_t  reserved[10];
 	uint16_t pkt_len;
 } __rte_packed;
 
diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
index 6f26d66b1..4e9cadda9 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -1,125 +1,289 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2020 Atomic Rules LLC
+ * Copyright (c) 2020-2021 Atomic Rules LLC
  */
 
 #ifndef RTE_PMD_ARK_H
 #define RTE_PMD_ARK_H
 
+#include <stdint.h>
+struct rte_eth_dev;
+struct rte_mbuf;
+struct rte_ether_addr;
+struct rte_eth_stats;
+
 /**
  * @file
  * ARK driver-specific API
  */
 
-#include <rte_mbuf.h>
-#include <rte_mbuf_dyn.h>
+/* The following section lists function prototypes for Arkville's
+ * dynamic PMD extension. User's who create an extension
+ * must include this file and define the necessary and desired
+ * functions. Only 1 function is required for an extension,
+ * rte_pmd_ark_dev_init(); all other functions prototyped in this
+ * section are optional.
+ * See documentation for compiling and use of extensions.
+ */
+
+/**
+ * Extension prototype, required implementation if extensions are used.
+ * Called during device probe to initialize the user structure
+ * passed to other extension functions.  This is called once for each
+ * port of the device.
+ *
+ * @param dev
+ *   current device.
+ * @param a_bar
+ *   access to pcie device bar (application bar) and hence access to
+ *   user's portion of FPGA.
+ * @param port_id
+ *   port identifier.
+ * @return user_data
+ *   which will be passed to other extension functions.
+ */
+void *rte_pmd_ark_dev_init(struct rte_eth_dev *dev, void *a_bar, int port_id);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during device uninit.
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ */
+void rte_pmd_ark_dev_uninit(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during device probe to change the port count from 1.
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+uint8_t dev_get_port_count(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_configure().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_dev_configure(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_start().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_dev_start(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during  rte_eth_dev_stop().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_dev_stop(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_close().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_dev_close(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during link_update status event.
+ *
+ * @param dev
+ *   current device.
+ * @param wait_to_complete
+ *    argument from update event.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_link_update(struct rte_eth_dev *dev,
+			    int wait_to_complete,
+			    void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_set_link_up().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_dev_set_link_up(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_set_link_down().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_dev_set_link_down(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_stats_get(); allows updates to the stats
+ * struct in addition Ark's PMD operations.
+ *
+ * @param dev
+ *   current device.
+ * @param stats
+ *   statistics struct already populated by Ark PMD.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_stats_get(struct rte_eth_dev *dev,
+			  struct rte_eth_stats *stats,
+			  void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_stats_reset().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_stats_reset(struct rte_eth_dev *dev, void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_mac_addr_add().
+ *
+ * @param dev
+ *   current device.
+ * @param macadr
+ *   The MAC address to add
+ * @param pool
+ *   VMDq pool index from caller
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_mac_addr_add(struct rte_eth_dev *dev,
+			      struct rte_ether_addr *macadr,
+			      uint32_t index,
+			      uint32_t pool,
+			      void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_mac_addr_remove().
+ *
+ * @param dev
+ *   current device.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_mac_addr_remove(struct rte_eth_dev *dev,
+				 uint32_t index,
+				 void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_default_mac_addr_set().
+ *
+ * @param dev
+ *   current device.
+ * @param mac_addr
+ *   The new default MAC address.
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+void rte_pmd_ark_mac_addr_set(struct rte_eth_dev *dev,
+			      struct rte_ether_addr *mac_addr,
+			      void *user_data);
+
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_dev_set_mtu().
+ *
+ * @param dev
+ *   current device.
+ * @param size
+ *   The MTU to be applied
+ * @param user_data
+ *   user argument from dev_init() call.
+ * @return (0) if successful.
+ */
+int rte_pmd_ark_set_mtu(struct rte_eth_dev *dev,
+			uint16_t size,
+			void *user_data);
 
-#ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE
-#define RTE_PMD_ARK_TX_USERDATA_ENABLE 0
-#endif
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_rx_burst() for each packet. This extension
+ * function allows the transfer of meta data from the user's FPGA to
+ * mbuf fields.
+ *
+ * @param mbuf
+ *   The newly received mbuf
+ * @param meta
+ *   The meta data from the user, up to 20 bytes.
+ * @param user_data
+ *   user argument from dev_init() call.
+ */
+void rte_pmd_ark_rx_user_meta_hook(struct rte_mbuf *mbuf,
+				   const uint32_t *meta,
+				   void *user_data);
 
-#ifndef RTE_PMD_ARK_RX_USERDATA_ENABLE
-#define RTE_PMD_ARK_RX_USERDATA_ENABLE 0
-#endif
-
-typedef uint32_t rte_pmd_ark_tx_userdata_t;
-typedef uint64_t rte_pmd_ark_rx_userdata_t;
-
-extern int rte_pmd_ark_tx_userdata_dynfield_offset;
-extern int rte_pmd_ark_rx_userdata_dynfield_offset;
-
-/** mbuf dynamic field for custom Tx ARK data */
-#define RTE_PMD_ARK_TX_USERDATA_DYNFIELD_NAME "rte_net_ark_dynfield_tx_userdata"
-/** mbuf dynamic field for custom Rx ARK data */
-#define RTE_PMD_ARK_RX_USERDATA_DYNFIELD_NAME "rte_net_ark_dynfield_rx_userdata"
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
- * Read Tx user data from mbuf.
- *
- * @param mbuf Structure to read from.
- * @return user data
- */
-__rte_experimental
-static inline rte_pmd_ark_tx_userdata_t
-rte_pmd_ark_mbuf_tx_userdata_get(const struct rte_mbuf *mbuf)
-{
-#if RTE_PMD_ARK_TX_USERDATA_ENABLE
-	return *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_tx_userdata_dynfield_offset,
-				  rte_pmd_ark_tx_userdata_t *);
-#else
-	RTE_SET_USED(mbuf);
-	return 0;
-#endif
-}
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
- * Write Tx user data to mbuf.
- *
- * @param mbuf Structure to write into.
- * @param data User data.
- */
-__rte_experimental
-static inline void
-rte_pmd_ark_mbuf_tx_userdata_set(struct rte_mbuf *mbuf,
-		rte_pmd_ark_tx_userdata_t data)
-{
-#if RTE_PMD_ARK_TX_USERDATA_ENABLE
-	*RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_tx_userdata_dynfield_offset,
-			rte_pmd_ark_tx_userdata_t *) = data;
-#else
-	RTE_SET_USED(mbuf);
-	RTE_SET_USED(data);
-#endif
-}
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
- * Read Rx user data from mbuf.
- *
- * @param mbuf Structure to read from.
- * @return user data
- */
-__rte_experimental
-static inline rte_pmd_ark_rx_userdata_t
-rte_pmd_ark_mbuf_rx_userdata_get(const struct rte_mbuf *mbuf)
-{
-#if RTE_PMD_ARK_RX_USERDATA_ENABLE
-	return *RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_rx_userdata_dynfield_offset,
-			rte_pmd_ark_rx_userdata_t *);
-#else
-	RTE_SET_USED(mbuf);
-	return 0;
-#endif
-}
-
-/**
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- *
- * Write Rx user data to mbuf.
- *
- * @param mbuf Structure to write into.
- * @param data User data.
- */
-__rte_experimental
-static inline void
-rte_pmd_ark_mbuf_rx_userdata_set(struct rte_mbuf *mbuf,
-		rte_pmd_ark_rx_userdata_t data)
-{
-#if RTE_PMD_ARK_RX_USERDATA_ENABLE
-	*RTE_MBUF_DYNFIELD(mbuf, rte_pmd_ark_rx_userdata_dynfield_offset,
-			rte_pmd_ark_rx_userdata_t *) = data;
-#else
-	RTE_SET_USED(mbuf);
-	RTE_SET_USED(data);
-#endif
-}
+/**
+ * Extension prototype, optional implementation.
+ * Called during rte_eth_tx_burst() for each packet. This extension
+ * function allows the transfer of data from the mbuf to the user's
+ * FPGA.  Up to 20 bytes (5 32-bit words) are transferable
+ *
+ * @param mbuf
+ *   The mbuf about to be transmitted.
+ * @param meta
+ *   The meta data to be populate by this call.
+ * @param meta_cnt
+ *   The count in 32-bit words of the meta data populated, 0 to 5.
+ * @param user_data
+ *   user argument from dev_init() call.
+ */
+void rte_pmd_ark_tx_user_meta_hook(const struct rte_mbuf *mbuf,
+				   uint32_t *meta,
+				   uint8_t *meta_cnt,
+				   void *user_data);
 
 #endif /* RTE_PMD_ARK_H */
diff --git a/drivers/net/ark/version.map b/drivers/net/ark/version.map
index 954bea679..4a76d1d52 100644
--- a/drivers/net/ark/version.map
+++ b/drivers/net/ark/version.map
@@ -1,10 +1,3 @@
 DPDK_21 {
 	local: *;
 };
-
-EXPERIMENTAL {
-	global:
-
-	rte_pmd_ark_tx_userdata_dynfield_offset;
-	rte_pmd_ark_rx_userdata_dynfield_offset;
-};
-- 
2.17.1


  parent reply	other threads:[~2021-03-04 20:33 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 2/5] net/ark: refactor Rx buffer recovery Ed Czeck
2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 3/5] net/ark: update internal structs to reflect FPGA updates Ed Czeck
2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 5/5] net/ark: localize internal packet generator code Ed Czeck
2021-03-04 20:33 ` [dpdk-dev] [PATCH v2 1/5] net/ark: update pkt director initial state Ed Czeck
2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 2/5] net/ark: refactor Rx buffer recovery Ed Czeck
2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 3/5] net/ark: update internal structs to reflect FPGA updates Ed Czeck
2021-03-05 15:38     ` Ferruh Yigit
2021-03-04 20:33   ` Ed Czeck [this message]
2021-03-05 15:31     ` [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD Ferruh Yigit
2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 5/5] net/ark: localize internal packet generator code Ed Czeck
2021-03-08 22:29 ` [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state Ed Czeck
2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
2021-03-09 11:32     ` Ferruh Yigit
2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 4/6] net/ark: generalize meta data between FPGA and PMD Ed Czeck
2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 5/6] net/ark: cleanup and document ark dynamic extansion Ed Czeck
2021-03-09 11:43     ` Ferruh Yigit
2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 6/6] net/ark: localize internal packet generator code Ed Czeck
2021-03-09 16:08 ` [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state Ed Czeck
2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface Ed Czeck
2021-03-09 17:50     ` Ferruh Yigit
2021-03-10 15:11       ` Ed Czeck
2021-03-10 16:29         ` Ferruh Yigit
2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD Ed Czeck
2021-03-09 17:36     ` Ferruh Yigit
2021-03-10 15:02       ` Ed Czeck
2021-03-10 16:44         ` Ferruh Yigit
2021-03-10 21:53           ` Ed Czeck
2021-03-10 22:46             ` Ferruh Yigit
2021-03-11 13:15               ` Ed Czeck
2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 6/6] net/ark: localize internal packet generator code Ed Czeck
2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 4/6] net/ark: cleanup ark dynamic extension interface Ed Czeck
2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 5/6] net/ark: generalize meta data between FPGA and PMD Ed Czeck
2021-03-18 17:37   ` [dpdk-dev] [PATCH v5 6/6] net/ark: localize internal packet generator code Ed Czeck
2021-03-22 15:59   ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ferruh Yigit

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210304203321.6154-4-ed.czeck@atomicrules.com \
    --to=ed.czeck@atomicrules.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@intel.com \
    --cc=john.miller@atomicrules.com \
    --cc=shepard.siegel@atomicrules.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.