DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state
@ 2021-03-04 16:56 Ed Czeck
  2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 2/5] net/ark: refactor Rx buffer recovery Ed Czeck
                   ` (7 more replies)
  0 siblings, 8 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 16:56 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c | 1 +
 drivers/net/ark/ark_pktdir.c | 2 +-
 drivers/net/ark/ark_pktdir.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ef650a465..477e1de02 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -321,6 +321,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	ark->rqpacing =
 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
 	ark->started = 0;
+	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
 
 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
 		      ark->sysctrl.t32[4],
diff --git a/drivers/net/ark/ark_pktdir.c b/drivers/net/ark/ark_pktdir.c
index 25e121831..dbfd2924b 100644
--- a/drivers/net/ark/ark_pktdir.c
+++ b/drivers/net/ark/ark_pktdir.c
@@ -22,7 +22,7 @@ ark_pktdir_init(void *base)
 		return inst;
 	}
 	inst->regs = (struct ark_pkt_dir_regs *)base;
-	inst->regs->ctrl = 0x00110110;	/* POR state */
+	inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */
 	return inst;
 }
 
diff --git a/drivers/net/ark/ark_pktdir.h b/drivers/net/ark/ark_pktdir.h
index 4afd128f9..b5577cebb 100644
--- a/drivers/net/ark/ark_pktdir.h
+++ b/drivers/net/ark/ark_pktdir.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#define ARK_PKTDIR_BASE_ADR  0xa0000
+#define ARK_PKT_DIR_INIT_VAL 0x0110
 
 typedef void *ark_pkt_dir_t;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 2/5] net/ark: refactor Rx buffer recovery
  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 ` Ed Czeck
  2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 3/5] net/ark: update internal structs to reflect FPGA updates Ed Czeck
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 16:56 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Allocate mbufs for Rx path in bulk of at least 64 buffers
to improve performance. Allow recovery even without
a rx operation to support lack of buffers in pool.

Fixes: be410a861598 ("net/ark: add recovery for lack of mbufs")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev_rx.c | 49 ++++++++-------------------------
 1 file changed, 11 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index d29d3db78..8e55b851a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -26,9 +26,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 				 struct rte_mbuf *mbuf0,
 				 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-				    uint32_t *pnb,
-				    struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -54,7 +51,7 @@ struct ark_rx_queue {
 	/* The queue Index is used within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t last_cons;
+	uint32_t unused;
 
 	/* separate cache line */
 	/* second cache line - fields only used in slow path */
@@ -105,9 +102,8 @@ static inline void
 eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
 	queue->cons_index = cons_index;
-	eth_ark_rx_seed_mbufs(queue);
-	if (((cons_index - queue->last_cons) >= 64U)) {
-		queue->last_cons = cons_index;
+	if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) {
+		eth_ark_rx_seed_mbufs(queue);
 		ark_mpu_set_producer(queue->mpu, queue->seed_index);
 	}
 }
@@ -321,9 +317,7 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
-	if (unlikely(nb != 0))
-		/* report next free to FPGA */
-		eth_ark_rx_update_cons_index(queue, cons_index);
+	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
 }
@@ -458,11 +452,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
 	if (unlikely(status != 0)) {
-		/* Try to recover from lack of mbufs in pool */
-		status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
-		if (unlikely(status != 0)) {
-			return -1;
-		}
+		ARK_PMD_LOG(NOTICE,
+			    "Could not allocate %u mbufs from pool"
+			    " for RX queue %u;"
+			    " %u free buffers remaining in queue\n",
+			    nb, queue->queue_index,
+			    queue->seed_index - queue->cons_index);
+		return -1;
 	}
 
 	if (ARK_DEBUG_CORE) {		/* DEBUG */
@@ -511,29 +507,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	return 0;
 }
 
-int
-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-			 uint32_t *pnb,
-			 struct rte_mbuf **mbufs)
-{
-	int status = -1;
-
-	/* Ignore small allocation failures */
-	if (*pnb <= 64)
-		return -1;
-
-	*pnb = 64U;
-	status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
-	if (status != 0) {
-		ARK_PMD_LOG(NOTICE,
-			    "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
-			    " %u free buffers remaining in queue\n",
-			    *pnb, queue->queue_index,
-			    queue->seed_index - queue->cons_index);
-	}
-	return status;
-}
-
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
 		      const char *msg)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 3/5] net/ark: update internal structs to reflect FPGA updates
  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 ` Ed Czeck
  2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 16:56 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- New PCIe IDs using net/ark driver
- Update Version IDs and structures specified by hardware
- New internal descriptor status for TX
- Adjust data placement in RX operations, headroom in retained
for segmented mbufs

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ddm.c       |  18 +++--
 drivers/net/ark/ark_ddm.h       |  22 +++---
 drivers/net/ark/ark_ethdev.c    |   2 +
 drivers/net/ark/ark_ethdev_rx.c |   6 +-
 drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
 drivers/net/ark/ark_udm.c       |   2 +
 drivers/net/ark/ark_udm.h       |  13 ++--
 7 files changed, 115 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ark/ark_ddm.c b/drivers/net/ark/ark_ddm.c
index 91d1179d8..232137157 100644
--- a/drivers/net/ark/ark_ddm.c
+++ b/drivers/net/ark/ark_ddm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_ddm.h"
 
+static_assert(sizeof(union ark_tx_meta) == 8, "Unexpected struct size ark_tx_meta");
+
 /* ************************************************************************* */
 int
 ark_ddm_verify(struct ark_ddm_t *ddm)
@@ -19,18 +21,26 @@ ark_ddm_verify(struct ark_ddm_t *ddm)
 	}
 
 	hw_const = ddm->cfg.const0;
+	if (hw_const == ARK_DDM_CONST3)
+		return 0;
+
 	if (hw_const == ARK_DDM_CONST1) {
 		ARK_PMD_LOG(ERR,
 			    "ARK: DDM module is version 1, "
 			    "PMD expects version 2\n");
 		return -1;
-	} else if (hw_const != ARK_DDM_CONST2) {
+	}
+
+	if (hw_const == ARK_DDM_CONST2) {
 		ARK_PMD_LOG(ERR,
-			    "ARK: DDM module not found as expected 0x%08x\n",
-			    ddm->cfg.const0);
+			    "ARK: DDM module is version 2, "
+			    "PMD expects version 3\n");
 		return -1;
 	}
-	return 0;
+	ARK_PMD_LOG(ERR,
+		    "ARK: DDM module not found as expected 0x%08x\n",
+		    ddm->cfg.const0);
+	return -1;
 }
 
 void
diff --git a/drivers/net/ark/ark_ddm.h b/drivers/net/ark/ark_ddm.h
index 5456b4b5c..687ff2519 100644
--- a/drivers/net/ark/ark_ddm.h
+++ b/drivers/net/ark/ark_ddm.h
@@ -16,17 +16,22 @@
  * there is minimal documentation.
  */
 
-/* struct defining Tx meta data --  fixed in FPGA -- 16 bytes */
-struct ark_tx_meta {
+/* struct defining Tx meta data --  fixed in FPGA -- 8 bytes */
+union ark_tx_meta {
 	uint64_t physaddr;
-	uint32_t user1;
-	uint16_t data_len;		/* of this MBUF */
+	struct {
+		uint32_t usermeta0;
+		uint32_t usermeta1;
+	};
+	struct {
+		uint16_t data_len;	/* of this MBUF */
 #define   ARK_DDM_EOP   0x01
 #define   ARK_DDM_SOP   0x02
-	uint8_t flags;		/* bit 0 indicates last mbuf in chain. */
-	uint8_t reserved[1];
-};
-
+		uint8_t  flags;
+		uint8_t  meta_cnt;
+		uint32_t user1;
+	};
+} __rte_packed;
 
 /*
  * DDM core hardware structures
@@ -35,6 +40,7 @@ struct ark_tx_meta {
  */
 #define ARK_DDM_CFG 0x0000
 /* Set unique HW ID for hardware version */
+#define ARK_DDM_CONST3 (0x334d4444)
 #define ARK_DDM_CONST2 (0x324d4444)
 #define ARK_DDM_CONST1 (0xfacecafe)
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 477e1de02..fc6d53a35 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -95,6 +95,8 @@ static const char * const valid_arguments[] = {
 static const struct rte_pci_id pci_id_ark_map[] = {
 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1017)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1018)},
 	{.vendor_id = 0, /* sentinel */ },
 };
 
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 8e55b851a..21a9af41a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -60,7 +60,6 @@ struct ark_rx_queue {
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
 } __rte_cache_aligned;
 
-
 /* ************************************************************************* */
 static int
 eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
@@ -265,7 +264,6 @@ eth_ark_recv_pkts(void *rx_queue,
 		/* META DATA embedded in headroom */
 		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
 
-		mbuf->port = meta->port;
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
 		/* set timestamp if enabled at least on one device */
@@ -346,8 +344,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 	/* HW guarantees that the data does not exceed prod_index! */
 	while (remaining != 0) {
 		data_len = RTE_MIN(remaining,
-				   RTE_MBUF_DEFAULT_DATAROOM +
-				   RTE_PKTMBUF_HEADROOM);
+				   RTE_MBUF_DEFAULT_DATAROOM);
 
 		remaining -= data_len;
 		segments += 1;
@@ -356,7 +353,6 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 		mbuf_prev->next = mbuf;
 		mbuf_prev = mbuf;
 		mbuf->data_len = data_len;
-		mbuf->data_off = 0;
 
 		cons_index += 1;
 	}
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 612d918e3..efd3d3fca 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
+ * Copyright (c) 2015-2021 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -23,7 +23,7 @@
 
 /* ************************************************************************* */
 struct ark_tx_queue {
-	struct ark_tx_meta *meta_q;
+	union ark_tx_meta *meta_q;
 	struct rte_mbuf **bufs;
 
 	/* handles for hw objects */
@@ -37,8 +37,8 @@ struct ark_tx_queue {
 	uint32_t queue_mask;
 
 	/* 3 indexes to the paired data rings. */
-	uint32_t prod_index;		/* where to put the next one */
-	uint32_t free_index;		/* mbuf has been freed */
+	int32_t prod_index;		/* where to put the next one */
+	int32_t free_index;		/* mbuf has been freed */
 
 	/* The queue Id is used to identify the HW Q */
 	uint16_t phys_qid;
@@ -47,14 +47,15 @@ struct ark_tx_queue {
 
 	uint32_t pad[1];
 
-	/* second cache line - fields only used in slow path */
+	/* second cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-	uint32_t cons_index;		/* hw is done, can be freed */
+	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
 
 /* Forward declarations */
-static uint32_t eth_ark_tx_jumbo(struct ark_tx_queue *queue,
-				 struct rte_mbuf *mbuf);
+static int eth_ark_tx_jumbo(struct ark_tx_queue *queue,
+			    struct rte_mbuf *mbuf,
+			    uint32_t *user_meta, uint8_t meta_cnt);
 static int eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue);
 static void free_completed_tx(struct ark_tx_queue *queue);
 
@@ -66,16 +67,44 @@ ark_tx_hw_queue_stop(struct ark_tx_queue *queue)
 
 /* ************************************************************************* */
 static inline void
-eth_ark_tx_meta_from_mbuf(struct ark_tx_meta *meta,
-			  const struct rte_mbuf *mbuf,
-			  uint8_t flags)
+eth_ark_tx_desc_fill(struct ark_tx_queue *queue,
+		     struct rte_mbuf *mbuf,
+		     uint8_t  flags,
+		     uint32_t *user_meta,
+		     uint8_t  meta_cnt /* 0 to 5 */
+		     )
 {
-	meta->physaddr = rte_mbuf_data_iova(mbuf);
-	meta->user1 = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+	uint32_t tx_idx;
+	union ark_tx_meta *meta;
+	uint8_t m;
+
+	/* Header */
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
 	meta->data_len = rte_pktmbuf_data_len(mbuf);
 	meta->flags = flags;
+	meta->meta_cnt = meta_cnt / 2;
+	meta->user1 = meta_cnt ? (*user_meta++) : 0;
+	queue->prod_index++;
+
+	queue->bufs[tx_idx] = mbuf;
+
+	/* 1 or 2 user meta data entries, user words 1,2 and 3,4 */
+	for (m = 1; m < meta_cnt; m += 2) {
+		tx_idx = queue->prod_index & queue->queue_mask;
+		meta = &queue->meta_q[tx_idx];
+		meta->usermeta0 = *user_meta++;
+		meta->usermeta1 = *user_meta++;
+		queue->prod_index++;
+	}
+
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
+	meta->physaddr = rte_mbuf_data_iova(mbuf);
+	queue->prod_index++;
 }
 
+
 /* ************************************************************************* */
 uint16_t
 eth_ark_xmit_pkts_noop(void *vtxq __rte_unused,
@@ -91,12 +120,12 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
+	uint32_t user_meta;
 
-	uint32_t idx;
-	uint32_t prod_index_limit;
 	int stat;
+	int32_t prod_index_limit;
 	uint16_t nb;
+	uint8_t user_len = 1;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
 
 	queue = (struct ark_tx_queue *)vtxq;
@@ -104,10 +133,11 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
 
-	prod_index_limit = queue->queue_size + queue->free_index;
+	/* leave 4 elements mpu data */
+	prod_index_limit = queue->queue_size + queue->free_index - 4;
 
 	for (nb = 0;
-	     (nb < nb_pkts) && (queue->prod_index != prod_index_limit);
+	     (nb < nb_pkts) && (prod_index_limit - queue->prod_index) > 0;
 	     ++nb) {
 		mbuf = tx_pkts[nb];
 
@@ -133,19 +163,16 @@ 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 (unlikely(mbuf->nb_segs != 1)) {
-			stat = eth_ark_tx_jumbo(queue, mbuf);
+			stat = eth_ark_tx_jumbo(queue, mbuf,
+						&user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
-			idx = queue->prod_index & queue->queue_mask;
-			queue->bufs[idx] = mbuf;
-			meta = &queue->meta_q[idx];
-			eth_ark_tx_meta_from_mbuf(meta,
-						  mbuf,
-						  ARK_DDM_SOP |
-						  ARK_DDM_EOP);
-			queue->prod_index++;
+			eth_ark_tx_desc_fill(queue, mbuf,
+					     ARK_DDM_SOP | ARK_DDM_EOP,
+					     &user_meta, user_len);
 		}
 	}
 
@@ -173,32 +200,28 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 }
 
 /* ************************************************************************* */
-static uint32_t
-eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf)
+static int
+eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf,
+		 uint32_t *user_meta, uint8_t meta_cnt)
 {
 	struct rte_mbuf *next;
-	struct ark_tx_meta *meta;
-	uint32_t free_queue_space;
-	uint32_t idx;
+	int32_t free_queue_space;
 	uint8_t flags = ARK_DDM_SOP;
 
 	free_queue_space = queue->queue_mask -
 		(queue->prod_index - queue->free_index);
-	if (unlikely(free_queue_space < mbuf->nb_segs))
+	/* We need upto 4 mbufs for first header, and 2 for subsequent ones */
+	if (unlikely(free_queue_space < (2 + (2 * mbuf->nb_segs))))
 		return -1;
 
 	while (mbuf != NULL) {
 		next = mbuf->next;
-
-		idx = queue->prod_index & queue->queue_mask;
-		queue->bufs[idx] = mbuf;
-		meta = &queue->meta_q[idx];
-
 		flags |= (next == NULL) ? ARK_DDM_EOP : 0;
-		eth_ark_tx_meta_from_mbuf(meta, mbuf, flags);
-		queue->prod_index++;
+
+		eth_ark_tx_desc_fill(queue, mbuf, flags, user_meta, meta_cnt);
 
 		flags &= ~ARK_DDM_SOP;	/* drop SOP flags */
+		meta_cnt = 0;		/* Meta only on SOP */
 		mbuf = next;
 	}
 
@@ -227,6 +250,9 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
+	/* Each packet requires at least 2 mpu elements - double desc count */
+	nb_desc = 2 * nb_desc;
+
 	/* Allocate queue struct */
 	queue =	rte_zmalloc_socket("Ark_txqueue",
 				   sizeof(struct ark_tx_queue),
@@ -248,7 +274,7 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
-				   nb_desc * sizeof(struct ark_tx_meta),
+				   nb_desc * sizeof(union ark_tx_meta),
 				   64,
 				   socket_id);
 	queue->bufs =
@@ -289,7 +315,7 @@ eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue)
 	uint32_t write_interval_ns;
 
 	/* Verify HW -- MPU */
-	if (ark_mpu_verify(queue->mpu, sizeof(struct ark_tx_meta)))
+	if (ark_mpu_verify(queue->mpu, sizeof(union ark_tx_meta)))
 		return -1;
 
 	queue_base = rte_malloc_virt2iova(queue);
@@ -391,19 +417,19 @@ static void
 free_completed_tx(struct ark_tx_queue *queue)
 {
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
-	uint32_t top_index;
+	union ark_tx_meta *meta;
+	int32_t top_index;
 
 	top_index = queue->cons_index;	/* read once */
-	while (queue->free_index != top_index) {
+	while ((top_index - queue->free_index) > 0) {
 		meta = &queue->meta_q[queue->free_index & queue->queue_mask];
-		mbuf = queue->bufs[queue->free_index & queue->queue_mask];
-
 		if (likely((meta->flags & ARK_DDM_SOP) != 0)) {
+			mbuf = queue->bufs[queue->free_index &
+					   queue->queue_mask];
 			/* ref count of the mbuf is checked in this call. */
 			rte_pktmbuf_free(mbuf);
 		}
-		queue->free_index++;
+		queue->free_index += (meta->meta_cnt + 2);
 	}
 }
 
diff --git a/drivers/net/ark/ark_udm.c b/drivers/net/ark/ark_udm.c
index a740d36d4..28c4500a2 100644
--- a/drivers/net/ark/ark_udm.c
+++ b/drivers/net/ark/ark_udm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_udm.h"
 
+static_assert(sizeof(struct ark_rx_meta) == 32, "Unexpected struct size ark_rx_meta");
+
 int
 ark_udm_verify(struct ark_udm_t *udm)
 {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index 5846c825b..ea92d4b6e 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -15,14 +15,15 @@
  * there is minimal documentation.
  */
 
-/* Meta data structure apssed from FPGA, must match layout in FPGA */
+/* Meta data structure passed from FPGA, must match layout in FPGA
+ * -- 32 bytes
+ */
 struct ark_rx_meta {
 	uint64_t timestamp;
 	uint64_t user_data;
-	uint8_t port;
-	uint8_t dst_queue;
+	uint8_t  reserved[14];
 	uint16_t pkt_len;
-};
+} __rte_packed;
 
 /*
  * UDM hardware structures
@@ -32,7 +33,9 @@ struct ark_rx_meta {
 
 #define ARK_RX_WRITE_TIME_NS 2500
 #define ARK_UDM_SETUP 0
-#define ARK_UDM_CONST 0xbACECACE
+#define ARK_UDM_CONST2 0xbACECACE
+#define ARK_UDM_CONST3 0x334d4455
+#define ARK_UDM_CONST ARK_UDM_CONST3
 struct ark_udm_setup_t {
 	uint32_t r0;
 	uint32_t r4;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 4/5] net/ark: generalize meta data between FPGA and PMD
  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 ` Ed Czeck
  2021-03-04 16:56 ` [dpdk-dev] [PATCH v1 5/5] net/ark: localize internal packet generator code Ed Czeck
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 16:56 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

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   | 382 +++++++++++++++++++++++---------
 drivers/net/ark/version.map     |   7 -
 10 files changed, 485 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 efd3d3fca..bea0cb8d4 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..214f8fb77 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 *user, upto 20 bytes */
+typedef void (*rx_user_meta_hook_fn)(struct rte_mbuf *mbuf,
+				     const uint32_t *meta,
+				     void *ext_user_data);
+/* TX hook poplulate *user from mbuf, with up to 20 bytes.  user_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..015ba8130 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -1,125 +1,287 @@
 /* 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 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
+ *   stats 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, upto 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.  Upto 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


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v1 5/5] net/ark: localize internal packet generator code
  2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (2 preceding siblings ...)
  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 ` Ed Czeck
  2021-03-04 20:33 ` [dpdk-dev] [PATCH v2 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 16:56 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

preparation for baseband device -- no functional changes
remove unnecessary includes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c  | 17 ++---------------
 drivers/net/ark/ark_pktchkr.c |  4 ----
 drivers/net/ark/ark_pktgen.c  | 20 ++++++++++++++------
 drivers/net/ark/ark_pktgen.h  |  1 +
 4 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index edbcfe8d4..e635d0c89 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -532,20 +532,6 @@ eth_ark_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void *
-delay_pg_start(void *arg)
-{
-	struct ark_adapter *ark = (struct ark_adapter *)arg;
-
-	/* This function is used exclusively for regression testing, We
-	 * perform a blind sleep here to ensure that the external test
-	 * application has time to setup the test before we generate packets
-	 */
-	usleep(100000);
-	ark_pktgen_run(ark->pg);
-	return NULL;
-}
-
 static int
 eth_ark_dev_start(struct rte_eth_dev *dev)
 {
@@ -580,7 +566,8 @@ eth_ark_dev_start(struct rte_eth_dev *dev)
 		/* Delay packet generatpr start allow the hardware to be ready
 		 * This is only used for sanity checking with internal generator
 		 */
-		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
+		if (pthread_create(&thread, NULL,
+				   ark_pktgen_delay_start, ark->pg)) {
 			ARK_PMD_LOG(ERR, "Could not create pktgen "
 				    "starter thread\n");
 			return -1;
diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index 0f2d31e5b..84bb567a4 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -2,13 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktchkr.h"
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index ac4322a35..28a44f754 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -2,15 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_eal.h>
-
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktgen.h"
@@ -470,3 +464,17 @@ ark_pktgen_setup(ark_pkt_gen_t handle)
 		ark_pktgen_run(handle);
 	}
 }
+
+void *
+ark_pktgen_delay_start(void *arg)
+{
+	struct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)arg;
+
+	/* This function is used exclusively for regression testing, We
+	 * perform a blind sleep here to ensure that the external test
+	 * application has time to setup the test before we generate packets
+	 */
+	usleep(100000);
+	ark_pktgen_run(inst);
+	return NULL;
+}
diff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h
index c61dfee6d..7147fe1bd 100644
--- a/drivers/net/ark/ark_pktgen.h
+++ b/drivers/net/ark/ark_pktgen.h
@@ -75,5 +75,6 @@ void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);
 void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);
 void ark_pktgen_parse(char *argv);
 void ark_pktgen_setup(ark_pkt_gen_t handle);
+void *ark_pktgen_delay_start(void *arg);
 
 #endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 1/5] net/ark: update pkt director initial state
  2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (3 preceding siblings ...)
  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 ` Ed Czeck
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 2/5] net/ark: refactor Rx buffer recovery Ed Czeck
                     ` (3 more replies)
  2021-03-08 22:29 ` [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state Ed Czeck
                   ` (2 subsequent siblings)
  7 siblings, 4 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 20:33 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c | 1 +
 drivers/net/ark/ark_pktdir.c | 2 +-
 drivers/net/ark/ark_pktdir.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ef650a465..477e1de02 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -321,6 +321,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	ark->rqpacing =
 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
 	ark->started = 0;
+	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
 
 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
 		      ark->sysctrl.t32[4],
diff --git a/drivers/net/ark/ark_pktdir.c b/drivers/net/ark/ark_pktdir.c
index 25e121831..dbfd2924b 100644
--- a/drivers/net/ark/ark_pktdir.c
+++ b/drivers/net/ark/ark_pktdir.c
@@ -22,7 +22,7 @@ ark_pktdir_init(void *base)
 		return inst;
 	}
 	inst->regs = (struct ark_pkt_dir_regs *)base;
-	inst->regs->ctrl = 0x00110110;	/* POR state */
+	inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */
 	return inst;
 }
 
diff --git a/drivers/net/ark/ark_pktdir.h b/drivers/net/ark/ark_pktdir.h
index 4afd128f9..b5577cebb 100644
--- a/drivers/net/ark/ark_pktdir.h
+++ b/drivers/net/ark/ark_pktdir.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#define ARK_PKTDIR_BASE_ADR  0xa0000
+#define ARK_PKT_DIR_INIT_VAL 0x0110
 
 typedef void *ark_pkt_dir_t;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 2/5] net/ark: refactor Rx buffer recovery
  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   ` Ed Czeck
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 3/5] net/ark: update internal structs to reflect FPGA updates Ed Czeck
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 20:33 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Allocate mbufs for Rx path in bulk of at least 64 buffers
to improve performance. Allow recovery even without
a rx operation to support lack of buffers in pool.

Fixes: be410a861598 ("net/ark: add recovery for lack of mbufs")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev_rx.c | 49 ++++++++-------------------------
 1 file changed, 11 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index d29d3db78..8e55b851a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -26,9 +26,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 				 struct rte_mbuf *mbuf0,
 				 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-				    uint32_t *pnb,
-				    struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -54,7 +51,7 @@ struct ark_rx_queue {
 	/* The queue Index is used within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t last_cons;
+	uint32_t unused;
 
 	/* separate cache line */
 	/* second cache line - fields only used in slow path */
@@ -105,9 +102,8 @@ static inline void
 eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
 	queue->cons_index = cons_index;
-	eth_ark_rx_seed_mbufs(queue);
-	if (((cons_index - queue->last_cons) >= 64U)) {
-		queue->last_cons = cons_index;
+	if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) {
+		eth_ark_rx_seed_mbufs(queue);
 		ark_mpu_set_producer(queue->mpu, queue->seed_index);
 	}
 }
@@ -321,9 +317,7 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
-	if (unlikely(nb != 0))
-		/* report next free to FPGA */
-		eth_ark_rx_update_cons_index(queue, cons_index);
+	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
 }
@@ -458,11 +452,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
 	if (unlikely(status != 0)) {
-		/* Try to recover from lack of mbufs in pool */
-		status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
-		if (unlikely(status != 0)) {
-			return -1;
-		}
+		ARK_PMD_LOG(NOTICE,
+			    "Could not allocate %u mbufs from pool"
+			    " for RX queue %u;"
+			    " %u free buffers remaining in queue\n",
+			    nb, queue->queue_index,
+			    queue->seed_index - queue->cons_index);
+		return -1;
 	}
 
 	if (ARK_DEBUG_CORE) {		/* DEBUG */
@@ -511,29 +507,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	return 0;
 }
 
-int
-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-			 uint32_t *pnb,
-			 struct rte_mbuf **mbufs)
-{
-	int status = -1;
-
-	/* Ignore small allocation failures */
-	if (*pnb <= 64)
-		return -1;
-
-	*pnb = 64U;
-	status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
-	if (status != 0) {
-		ARK_PMD_LOG(NOTICE,
-			    "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
-			    " %u free buffers remaining in queue\n",
-			    *pnb, queue->queue_index,
-			    queue->seed_index - queue->cons_index);
-	}
-	return status;
-}
-
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
 		      const char *msg)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 3/5] net/ark: update internal structs to reflect FPGA updates
  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   ` Ed Czeck
  2021-03-05 15:38     ` Ferruh Yigit
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 5/5] net/ark: localize internal packet generator code Ed Czeck
  3 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 20:33 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- New PCIe IDs using net/ark driver
- Update Version IDs and structures specified by hardware
- New internal descriptor status for TX
- Adjust data placement in RX operations, headroom in retained
for segmented mbufs

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ddm.c       |  18 +++--
 drivers/net/ark/ark_ddm.h       |  22 +++---
 drivers/net/ark/ark_ethdev.c    |   2 +
 drivers/net/ark/ark_ethdev_rx.c |   6 +-
 drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
 drivers/net/ark/ark_udm.c       |   2 +
 drivers/net/ark/ark_udm.h       |  13 ++--
 7 files changed, 115 insertions(+), 70 deletions(-)

diff --git a/drivers/net/ark/ark_ddm.c b/drivers/net/ark/ark_ddm.c
index 91d1179d8..232137157 100644
--- a/drivers/net/ark/ark_ddm.c
+++ b/drivers/net/ark/ark_ddm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_ddm.h"
 
+static_assert(sizeof(union ark_tx_meta) == 8, "Unexpected struct size ark_tx_meta");
+
 /* ************************************************************************* */
 int
 ark_ddm_verify(struct ark_ddm_t *ddm)
@@ -19,18 +21,26 @@ ark_ddm_verify(struct ark_ddm_t *ddm)
 	}
 
 	hw_const = ddm->cfg.const0;
+	if (hw_const == ARK_DDM_CONST3)
+		return 0;
+
 	if (hw_const == ARK_DDM_CONST1) {
 		ARK_PMD_LOG(ERR,
 			    "ARK: DDM module is version 1, "
 			    "PMD expects version 2\n");
 		return -1;
-	} else if (hw_const != ARK_DDM_CONST2) {
+	}
+
+	if (hw_const == ARK_DDM_CONST2) {
 		ARK_PMD_LOG(ERR,
-			    "ARK: DDM module not found as expected 0x%08x\n",
-			    ddm->cfg.const0);
+			    "ARK: DDM module is version 2, "
+			    "PMD expects version 3\n");
 		return -1;
 	}
-	return 0;
+	ARK_PMD_LOG(ERR,
+		    "ARK: DDM module not found as expected 0x%08x\n",
+		    ddm->cfg.const0);
+	return -1;
 }
 
 void
diff --git a/drivers/net/ark/ark_ddm.h b/drivers/net/ark/ark_ddm.h
index 5456b4b5c..687ff2519 100644
--- a/drivers/net/ark/ark_ddm.h
+++ b/drivers/net/ark/ark_ddm.h
@@ -16,17 +16,22 @@
  * there is minimal documentation.
  */
 
-/* struct defining Tx meta data --  fixed in FPGA -- 16 bytes */
-struct ark_tx_meta {
+/* struct defining Tx meta data --  fixed in FPGA -- 8 bytes */
+union ark_tx_meta {
 	uint64_t physaddr;
-	uint32_t user1;
-	uint16_t data_len;		/* of this MBUF */
+	struct {
+		uint32_t usermeta0;
+		uint32_t usermeta1;
+	};
+	struct {
+		uint16_t data_len;	/* of this MBUF */
 #define   ARK_DDM_EOP   0x01
 #define   ARK_DDM_SOP   0x02
-	uint8_t flags;		/* bit 0 indicates last mbuf in chain. */
-	uint8_t reserved[1];
-};
-
+		uint8_t  flags;
+		uint8_t  meta_cnt;
+		uint32_t user1;
+	};
+} __rte_packed;
 
 /*
  * DDM core hardware structures
@@ -35,6 +40,7 @@ struct ark_tx_meta {
  */
 #define ARK_DDM_CFG 0x0000
 /* Set unique HW ID for hardware version */
+#define ARK_DDM_CONST3 (0x334d4444)
 #define ARK_DDM_CONST2 (0x324d4444)
 #define ARK_DDM_CONST1 (0xfacecafe)
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 477e1de02..fc6d53a35 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -95,6 +95,8 @@ static const char * const valid_arguments[] = {
 static const struct rte_pci_id pci_id_ark_map[] = {
 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1017)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1018)},
 	{.vendor_id = 0, /* sentinel */ },
 };
 
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 8e55b851a..21a9af41a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -60,7 +60,6 @@ struct ark_rx_queue {
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
 } __rte_cache_aligned;
 
-
 /* ************************************************************************* */
 static int
 eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
@@ -265,7 +264,6 @@ eth_ark_recv_pkts(void *rx_queue,
 		/* META DATA embedded in headroom */
 		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
 
-		mbuf->port = meta->port;
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
 		/* set timestamp if enabled at least on one device */
@@ -346,8 +344,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 	/* HW guarantees that the data does not exceed prod_index! */
 	while (remaining != 0) {
 		data_len = RTE_MIN(remaining,
-				   RTE_MBUF_DEFAULT_DATAROOM +
-				   RTE_PKTMBUF_HEADROOM);
+				   RTE_MBUF_DEFAULT_DATAROOM);
 
 		remaining -= data_len;
 		segments += 1;
@@ -356,7 +353,6 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 		mbuf_prev->next = mbuf;
 		mbuf_prev = mbuf;
 		mbuf->data_len = data_len;
-		mbuf->data_off = 0;
 
 		cons_index += 1;
 	}
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 612d918e3..00e5dbf7c 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
+ * Copyright (c) 2015-2021 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -23,7 +23,7 @@
 
 /* ************************************************************************* */
 struct ark_tx_queue {
-	struct ark_tx_meta *meta_q;
+	union ark_tx_meta *meta_q;
 	struct rte_mbuf **bufs;
 
 	/* handles for hw objects */
@@ -37,8 +37,8 @@ struct ark_tx_queue {
 	uint32_t queue_mask;
 
 	/* 3 indexes to the paired data rings. */
-	uint32_t prod_index;		/* where to put the next one */
-	uint32_t free_index;		/* mbuf has been freed */
+	int32_t prod_index;		/* where to put the next one */
+	int32_t free_index;		/* mbuf has been freed */
 
 	/* The queue Id is used to identify the HW Q */
 	uint16_t phys_qid;
@@ -47,14 +47,15 @@ struct ark_tx_queue {
 
 	uint32_t pad[1];
 
-	/* second cache line - fields only used in slow path */
+	/* second cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-	uint32_t cons_index;		/* hw is done, can be freed */
+	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
 
 /* Forward declarations */
-static uint32_t eth_ark_tx_jumbo(struct ark_tx_queue *queue,
-				 struct rte_mbuf *mbuf);
+static int eth_ark_tx_jumbo(struct ark_tx_queue *queue,
+			    struct rte_mbuf *mbuf,
+			    uint32_t *user_meta, uint8_t meta_cnt);
 static int eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue);
 static void free_completed_tx(struct ark_tx_queue *queue);
 
@@ -66,16 +67,44 @@ ark_tx_hw_queue_stop(struct ark_tx_queue *queue)
 
 /* ************************************************************************* */
 static inline void
-eth_ark_tx_meta_from_mbuf(struct ark_tx_meta *meta,
-			  const struct rte_mbuf *mbuf,
-			  uint8_t flags)
+eth_ark_tx_desc_fill(struct ark_tx_queue *queue,
+		     struct rte_mbuf *mbuf,
+		     uint8_t  flags,
+		     uint32_t *user_meta,
+		     uint8_t  meta_cnt /* 0 to 5 */
+		     )
 {
-	meta->physaddr = rte_mbuf_data_iova(mbuf);
-	meta->user1 = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+	uint32_t tx_idx;
+	union ark_tx_meta *meta;
+	uint8_t m;
+
+	/* Header */
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
 	meta->data_len = rte_pktmbuf_data_len(mbuf);
 	meta->flags = flags;
+	meta->meta_cnt = meta_cnt / 2;
+	meta->user1 = meta_cnt ? (*user_meta++) : 0;
+	queue->prod_index++;
+
+	queue->bufs[tx_idx] = mbuf;
+
+	/* 1 or 2 user meta data entries, user words 1,2 and 3,4 */
+	for (m = 1; m < meta_cnt; m += 2) {
+		tx_idx = queue->prod_index & queue->queue_mask;
+		meta = &queue->meta_q[tx_idx];
+		meta->usermeta0 = *user_meta++;
+		meta->usermeta1 = *user_meta++;
+		queue->prod_index++;
+	}
+
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
+	meta->physaddr = rte_mbuf_data_iova(mbuf);
+	queue->prod_index++;
 }
 
+
 /* ************************************************************************* */
 uint16_t
 eth_ark_xmit_pkts_noop(void *vtxq __rte_unused,
@@ -91,12 +120,12 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
+	uint32_t user_meta;
 
-	uint32_t idx;
-	uint32_t prod_index_limit;
 	int stat;
+	int32_t prod_index_limit;
 	uint16_t nb;
+	uint8_t user_len = 1;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
 
 	queue = (struct ark_tx_queue *)vtxq;
@@ -104,10 +133,11 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
 
-	prod_index_limit = queue->queue_size + queue->free_index;
+	/* leave 4 elements mpu data */
+	prod_index_limit = queue->queue_size + queue->free_index - 4;
 
 	for (nb = 0;
-	     (nb < nb_pkts) && (queue->prod_index != prod_index_limit);
+	     (nb < nb_pkts) && (prod_index_limit - queue->prod_index) > 0;
 	     ++nb) {
 		mbuf = tx_pkts[nb];
 
@@ -133,19 +163,16 @@ 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 (unlikely(mbuf->nb_segs != 1)) {
-			stat = eth_ark_tx_jumbo(queue, mbuf);
+			stat = eth_ark_tx_jumbo(queue, mbuf,
+						&user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
-			idx = queue->prod_index & queue->queue_mask;
-			queue->bufs[idx] = mbuf;
-			meta = &queue->meta_q[idx];
-			eth_ark_tx_meta_from_mbuf(meta,
-						  mbuf,
-						  ARK_DDM_SOP |
-						  ARK_DDM_EOP);
-			queue->prod_index++;
+			eth_ark_tx_desc_fill(queue, mbuf,
+					     ARK_DDM_SOP | ARK_DDM_EOP,
+					     &user_meta, user_len);
 		}
 	}
 
@@ -173,32 +200,28 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 }
 
 /* ************************************************************************* */
-static uint32_t
-eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf)
+static int
+eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf,
+		 uint32_t *user_meta, uint8_t meta_cnt)
 {
 	struct rte_mbuf *next;
-	struct ark_tx_meta *meta;
-	uint32_t free_queue_space;
-	uint32_t idx;
+	int32_t free_queue_space;
 	uint8_t flags = ARK_DDM_SOP;
 
 	free_queue_space = queue->queue_mask -
 		(queue->prod_index - queue->free_index);
-	if (unlikely(free_queue_space < mbuf->nb_segs))
+	/* We need up to 4 mbufs for first header and 2 for subsequent ones */
+	if (unlikely(free_queue_space < (2 + (2 * mbuf->nb_segs))))
 		return -1;
 
 	while (mbuf != NULL) {
 		next = mbuf->next;
-
-		idx = queue->prod_index & queue->queue_mask;
-		queue->bufs[idx] = mbuf;
-		meta = &queue->meta_q[idx];
-
 		flags |= (next == NULL) ? ARK_DDM_EOP : 0;
-		eth_ark_tx_meta_from_mbuf(meta, mbuf, flags);
-		queue->prod_index++;
+
+		eth_ark_tx_desc_fill(queue, mbuf, flags, user_meta, meta_cnt);
 
 		flags &= ~ARK_DDM_SOP;	/* drop SOP flags */
+		meta_cnt = 0;		/* Meta only on SOP */
 		mbuf = next;
 	}
 
@@ -227,6 +250,9 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
+	/* Each packet requires at least 2 mpu elements - double desc count */
+	nb_desc = 2 * nb_desc;
+
 	/* Allocate queue struct */
 	queue =	rte_zmalloc_socket("Ark_txqueue",
 				   sizeof(struct ark_tx_queue),
@@ -248,7 +274,7 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
-				   nb_desc * sizeof(struct ark_tx_meta),
+				   nb_desc * sizeof(union ark_tx_meta),
 				   64,
 				   socket_id);
 	queue->bufs =
@@ -289,7 +315,7 @@ eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue)
 	uint32_t write_interval_ns;
 
 	/* Verify HW -- MPU */
-	if (ark_mpu_verify(queue->mpu, sizeof(struct ark_tx_meta)))
+	if (ark_mpu_verify(queue->mpu, sizeof(union ark_tx_meta)))
 		return -1;
 
 	queue_base = rte_malloc_virt2iova(queue);
@@ -391,19 +417,19 @@ static void
 free_completed_tx(struct ark_tx_queue *queue)
 {
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
-	uint32_t top_index;
+	union ark_tx_meta *meta;
+	int32_t top_index;
 
 	top_index = queue->cons_index;	/* read once */
-	while (queue->free_index != top_index) {
+	while ((top_index - queue->free_index) > 0) {
 		meta = &queue->meta_q[queue->free_index & queue->queue_mask];
-		mbuf = queue->bufs[queue->free_index & queue->queue_mask];
-
 		if (likely((meta->flags & ARK_DDM_SOP) != 0)) {
+			mbuf = queue->bufs[queue->free_index &
+					   queue->queue_mask];
 			/* ref count of the mbuf is checked in this call. */
 			rte_pktmbuf_free(mbuf);
 		}
-		queue->free_index++;
+		queue->free_index += (meta->meta_cnt + 2);
 	}
 }
 
diff --git a/drivers/net/ark/ark_udm.c b/drivers/net/ark/ark_udm.c
index a740d36d4..28c4500a2 100644
--- a/drivers/net/ark/ark_udm.c
+++ b/drivers/net/ark/ark_udm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_udm.h"
 
+static_assert(sizeof(struct ark_rx_meta) == 32, "Unexpected struct size ark_rx_meta");
+
 int
 ark_udm_verify(struct ark_udm_t *udm)
 {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index 5846c825b..ea92d4b6e 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -15,14 +15,15 @@
  * there is minimal documentation.
  */
 
-/* Meta data structure apssed from FPGA, must match layout in FPGA */
+/* Meta data structure passed from FPGA, must match layout in FPGA
+ * -- 32 bytes
+ */
 struct ark_rx_meta {
 	uint64_t timestamp;
 	uint64_t user_data;
-	uint8_t port;
-	uint8_t dst_queue;
+	uint8_t  reserved[14];
 	uint16_t pkt_len;
-};
+} __rte_packed;
 
 /*
  * UDM hardware structures
@@ -32,7 +33,9 @@ struct ark_rx_meta {
 
 #define ARK_RX_WRITE_TIME_NS 2500
 #define ARK_UDM_SETUP 0
-#define ARK_UDM_CONST 0xbACECACE
+#define ARK_UDM_CONST2 0xbACECACE
+#define ARK_UDM_CONST3 0x334d4455
+#define ARK_UDM_CONST ARK_UDM_CONST3
 struct ark_udm_setup_t {
 	uint32_t r0;
 	uint32_t r4;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD
  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-04 20:33   ` Ed Czeck
  2021-03-05 15:31     ` Ferruh Yigit
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 5/5] net/ark: localize internal packet generator code Ed Czeck
  3 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 20:33 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

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


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v2 5/5] net/ark: localize internal packet generator code
  2021-03-04 20:33 ` [dpdk-dev] [PATCH v2 1/5] net/ark: update pkt director initial state Ed Czeck
                     ` (2 preceding siblings ...)
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
@ 2021-03-04 20:33   ` Ed Czeck
  3 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-04 20:33 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

remove unnecessary includes
no functional changes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c  | 17 ++---------------
 drivers/net/ark/ark_pktchkr.c |  4 ----
 drivers/net/ark/ark_pktgen.c  | 20 ++++++++++++++------
 drivers/net/ark/ark_pktgen.h  |  1 +
 4 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index edbcfe8d4..e635d0c89 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -532,20 +532,6 @@ eth_ark_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void *
-delay_pg_start(void *arg)
-{
-	struct ark_adapter *ark = (struct ark_adapter *)arg;
-
-	/* This function is used exclusively for regression testing, We
-	 * perform a blind sleep here to ensure that the external test
-	 * application has time to setup the test before we generate packets
-	 */
-	usleep(100000);
-	ark_pktgen_run(ark->pg);
-	return NULL;
-}
-
 static int
 eth_ark_dev_start(struct rte_eth_dev *dev)
 {
@@ -580,7 +566,8 @@ eth_ark_dev_start(struct rte_eth_dev *dev)
 		/* Delay packet generatpr start allow the hardware to be ready
 		 * This is only used for sanity checking with internal generator
 		 */
-		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
+		if (pthread_create(&thread, NULL,
+				   ark_pktgen_delay_start, ark->pg)) {
 			ARK_PMD_LOG(ERR, "Could not create pktgen "
 				    "starter thread\n");
 			return -1;
diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index 0f2d31e5b..84bb567a4 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -2,13 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktchkr.h"
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index ac4322a35..28a44f754 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -2,15 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_eal.h>
-
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktgen.h"
@@ -470,3 +464,17 @@ ark_pktgen_setup(ark_pkt_gen_t handle)
 		ark_pktgen_run(handle);
 	}
 }
+
+void *
+ark_pktgen_delay_start(void *arg)
+{
+	struct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)arg;
+
+	/* This function is used exclusively for regression testing, We
+	 * perform a blind sleep here to ensure that the external test
+	 * application has time to setup the test before we generate packets
+	 */
+	usleep(100000);
+	ark_pktgen_run(inst);
+	return NULL;
+}
diff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h
index c61dfee6d..7147fe1bd 100644
--- a/drivers/net/ark/ark_pktgen.h
+++ b/drivers/net/ark/ark_pktgen.h
@@ -75,5 +75,6 @@ void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);
 void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);
 void ark_pktgen_parse(char *argv);
 void ark_pktgen_setup(ark_pkt_gen_t handle);
+void *ark_pktgen_delay_start(void *arg);
 
 #endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD
  2021-03-04 20:33   ` [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
@ 2021-03-05 15:31     ` Ferruh Yigit
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-05 15:31 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller

On 3/4/2021 8:33 PM, Ed Czeck wrote:
> 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

Can you please move this rename on its own patch, it is causing too much noise 
for this patch.

> - Move extension prototype to rte_pmd_ark.h
> - Update documentation with an extension example
>

+1

> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>

<...>

> +/**
> + * 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);
>   

<...>

> +/**
> + * 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);
>   

Why not define 'meta' as "void *" eventually it won't be used as "uint32_t *" 
and will be caseted, isn't it?
Same for both APIs.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v2 3/5] net/ark: update internal structs to reflect FPGA updates
  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
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-05 15:38 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller

On 3/4/2021 8:33 PM, Ed Czeck wrote:
> - New PCIe IDs using net/ark driver

Is this new devices support requires any documentation update?

Additional to the device documentation update, what do you think putting a 
release notes update to document new device support?

> - Update Version IDs and structures specified by hardware
> - New internal descriptor status for TX
> - Adjust data placement in RX operations, headroom in retained
> for segmented mbufs
> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>

<...>



^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state
  2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (4 preceding siblings ...)
  2021-03-04 20:33 ` [dpdk-dev] [PATCH v2 1/5] net/ark: update pkt director initial state Ed Czeck
@ 2021-03-08 22:29 ` Ed Czeck
  2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
                     ` (4 more replies)
  2021-03-09 16:08 ` [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state Ed Czeck
  2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
  7 siblings, 5 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c | 1 +
 drivers/net/ark/ark_pktdir.c | 2 +-
 drivers/net/ark/ark_pktdir.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ef650a465..477e1de02 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -321,6 +321,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	ark->rqpacing =
 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
 	ark->started = 0;
+	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
 
 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
 		      ark->sysctrl.t32[4],
diff --git a/drivers/net/ark/ark_pktdir.c b/drivers/net/ark/ark_pktdir.c
index 25e121831..dbfd2924b 100644
--- a/drivers/net/ark/ark_pktdir.c
+++ b/drivers/net/ark/ark_pktdir.c
@@ -22,7 +22,7 @@ ark_pktdir_init(void *base)
 		return inst;
 	}
 	inst->regs = (struct ark_pkt_dir_regs *)base;
-	inst->regs->ctrl = 0x00110110;	/* POR state */
+	inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */
 	return inst;
 }
 
diff --git a/drivers/net/ark/ark_pktdir.h b/drivers/net/ark/ark_pktdir.h
index 4afd128f9..b5577cebb 100644
--- a/drivers/net/ark/ark_pktdir.h
+++ b/drivers/net/ark/ark_pktdir.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#define ARK_PKTDIR_BASE_ADR  0xa0000
+#define ARK_PKT_DIR_INIT_VAL 0x0110
 
 typedef void *ark_pkt_dir_t;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 2/6] net/ark: refactor Rx buffer recovery
  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   ` Ed Czeck
  2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Allocate mbufs for Rx path in bulk of at least 64 buffers
to improve performance. Allow recovery even without
a Rx operation to support lack of buffers in pool.

Fixes: be410a861598 ("net/ark: add recovery for lack of mbufs")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev_rx.c | 49 ++++++++-------------------------
 1 file changed, 11 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index d29d3db78..8e55b851a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -26,9 +26,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 				 struct rte_mbuf *mbuf0,
 				 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-				    uint32_t *pnb,
-				    struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -54,7 +51,7 @@ struct ark_rx_queue {
 	/* The queue Index is used within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t last_cons;
+	uint32_t unused;
 
 	/* separate cache line */
 	/* second cache line - fields only used in slow path */
@@ -105,9 +102,8 @@ static inline void
 eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
 	queue->cons_index = cons_index;
-	eth_ark_rx_seed_mbufs(queue);
-	if (((cons_index - queue->last_cons) >= 64U)) {
-		queue->last_cons = cons_index;
+	if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) {
+		eth_ark_rx_seed_mbufs(queue);
 		ark_mpu_set_producer(queue->mpu, queue->seed_index);
 	}
 }
@@ -321,9 +317,7 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
-	if (unlikely(nb != 0))
-		/* report next free to FPGA */
-		eth_ark_rx_update_cons_index(queue, cons_index);
+	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
 }
@@ -458,11 +452,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
 	if (unlikely(status != 0)) {
-		/* Try to recover from lack of mbufs in pool */
-		status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
-		if (unlikely(status != 0)) {
-			return -1;
-		}
+		ARK_PMD_LOG(NOTICE,
+			    "Could not allocate %u mbufs from pool"
+			    " for RX queue %u;"
+			    " %u free buffers remaining in queue\n",
+			    nb, queue->queue_index,
+			    queue->seed_index - queue->cons_index);
+		return -1;
 	}
 
 	if (ARK_DEBUG_CORE) {		/* DEBUG */
@@ -511,29 +507,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	return 0;
 }
 
-int
-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-			 uint32_t *pnb,
-			 struct rte_mbuf **mbufs)
-{
-	int status = -1;
-
-	/* Ignore small allocation failures */
-	if (*pnb <= 64)
-		return -1;
-
-	*pnb = 64U;
-	status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
-	if (status != 0) {
-		ARK_PMD_LOG(NOTICE,
-			    "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
-			    " %u free buffers remaining in queue\n",
-			    *pnb, queue->queue_index,
-			    queue->seed_index - queue->cons_index);
-	}
-	return status;
-}
-
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
 		      const char *msg)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 3/6] net/ark: update internal structs to reflect FPGA updates
  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   ` 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
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- New PCIe IDs using net/ark driver
- Update Version IDs and structures specified by hardware
- New internal descriptor status for TX
- Adjust data placement in RX operations, headroom in retained
for segmented mbufs

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 doc/guides/nics/ark.rst         |   5 ++
 drivers/net/ark/ark_ddm.c       |  18 +++--
 drivers/net/ark/ark_ddm.h       |  22 +++---
 drivers/net/ark/ark_ethdev.c    |   3 +
 drivers/net/ark/ark_ethdev_rx.c |   6 +-
 drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
 drivers/net/ark/ark_udm.c       |   2 +
 drivers/net/ark/ark_udm.h       |  13 ++--
 8 files changed, 121 insertions(+), 70 deletions(-)

diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index 18434c7a4..dcccfee26 100644
--- a/doc/guides/nics/ark.rst
+++ b/doc/guides/nics/ark.rst
@@ -155,6 +155,11 @@ ARK PMD supports the following Arkville RTL PCIe instances including:
 
 * ``1d6c:100d`` - AR-ARKA-FX0 [Arkville 32B DPDK Data Mover]
 * ``1d6c:100e`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover]
+* ``1d6c:100f`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal]
+* ``1d6c:1010`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex]
+* ``1d6c:1017`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Primary Endpoint]
+* ``1d6c:1018`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Secondary Endpoint]
+* ``1d6c:1019`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Tertiary Endpoint]
 
 Supported Operating Systems
 ---------------------------
diff --git a/drivers/net/ark/ark_ddm.c b/drivers/net/ark/ark_ddm.c
index 91d1179d8..232137157 100644
--- a/drivers/net/ark/ark_ddm.c
+++ b/drivers/net/ark/ark_ddm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_ddm.h"
 
+static_assert(sizeof(union ark_tx_meta) == 8, "Unexpected struct size ark_tx_meta");
+
 /* ************************************************************************* */
 int
 ark_ddm_verify(struct ark_ddm_t *ddm)
@@ -19,18 +21,26 @@ ark_ddm_verify(struct ark_ddm_t *ddm)
 	}
 
 	hw_const = ddm->cfg.const0;
+	if (hw_const == ARK_DDM_CONST3)
+		return 0;
+
 	if (hw_const == ARK_DDM_CONST1) {
 		ARK_PMD_LOG(ERR,
 			    "ARK: DDM module is version 1, "
 			    "PMD expects version 2\n");
 		return -1;
-	} else if (hw_const != ARK_DDM_CONST2) {
+	}
+
+	if (hw_const == ARK_DDM_CONST2) {
 		ARK_PMD_LOG(ERR,
-			    "ARK: DDM module not found as expected 0x%08x\n",
-			    ddm->cfg.const0);
+			    "ARK: DDM module is version 2, "
+			    "PMD expects version 3\n");
 		return -1;
 	}
-	return 0;
+	ARK_PMD_LOG(ERR,
+		    "ARK: DDM module not found as expected 0x%08x\n",
+		    ddm->cfg.const0);
+	return -1;
 }
 
 void
diff --git a/drivers/net/ark/ark_ddm.h b/drivers/net/ark/ark_ddm.h
index 5456b4b5c..687ff2519 100644
--- a/drivers/net/ark/ark_ddm.h
+++ b/drivers/net/ark/ark_ddm.h
@@ -16,17 +16,22 @@
  * there is minimal documentation.
  */
 
-/* struct defining Tx meta data --  fixed in FPGA -- 16 bytes */
-struct ark_tx_meta {
+/* struct defining Tx meta data --  fixed in FPGA -- 8 bytes */
+union ark_tx_meta {
 	uint64_t physaddr;
-	uint32_t user1;
-	uint16_t data_len;		/* of this MBUF */
+	struct {
+		uint32_t usermeta0;
+		uint32_t usermeta1;
+	};
+	struct {
+		uint16_t data_len;	/* of this MBUF */
 #define   ARK_DDM_EOP   0x01
 #define   ARK_DDM_SOP   0x02
-	uint8_t flags;		/* bit 0 indicates last mbuf in chain. */
-	uint8_t reserved[1];
-};
-
+		uint8_t  flags;
+		uint8_t  meta_cnt;
+		uint32_t user1;
+	};
+} __rte_packed;
 
 /*
  * DDM core hardware structures
@@ -35,6 +40,7 @@ struct ark_tx_meta {
  */
 #define ARK_DDM_CFG 0x0000
 /* Set unique HW ID for hardware version */
+#define ARK_DDM_CONST3 (0x334d4444)
 #define ARK_DDM_CONST2 (0x324d4444)
 #define ARK_DDM_CONST1 (0xfacecafe)
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 477e1de02..9f0a8d9e8 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -95,6 +95,9 @@ static const char * const valid_arguments[] = {
 static const struct rte_pci_id pci_id_ark_map[] = {
 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1017)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1018)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1019)},
 	{.vendor_id = 0, /* sentinel */ },
 };
 
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 8e55b851a..21a9af41a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -60,7 +60,6 @@ struct ark_rx_queue {
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
 } __rte_cache_aligned;
 
-
 /* ************************************************************************* */
 static int
 eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
@@ -265,7 +264,6 @@ eth_ark_recv_pkts(void *rx_queue,
 		/* META DATA embedded in headroom */
 		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
 
-		mbuf->port = meta->port;
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
 		/* set timestamp if enabled at least on one device */
@@ -346,8 +344,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 	/* HW guarantees that the data does not exceed prod_index! */
 	while (remaining != 0) {
 		data_len = RTE_MIN(remaining,
-				   RTE_MBUF_DEFAULT_DATAROOM +
-				   RTE_PKTMBUF_HEADROOM);
+				   RTE_MBUF_DEFAULT_DATAROOM);
 
 		remaining -= data_len;
 		segments += 1;
@@ -356,7 +353,6 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 		mbuf_prev->next = mbuf;
 		mbuf_prev = mbuf;
 		mbuf->data_len = data_len;
-		mbuf->data_off = 0;
 
 		cons_index += 1;
 	}
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 612d918e3..00e5dbf7c 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
+ * Copyright (c) 2015-2021 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -23,7 +23,7 @@
 
 /* ************************************************************************* */
 struct ark_tx_queue {
-	struct ark_tx_meta *meta_q;
+	union ark_tx_meta *meta_q;
 	struct rte_mbuf **bufs;
 
 	/* handles for hw objects */
@@ -37,8 +37,8 @@ struct ark_tx_queue {
 	uint32_t queue_mask;
 
 	/* 3 indexes to the paired data rings. */
-	uint32_t prod_index;		/* where to put the next one */
-	uint32_t free_index;		/* mbuf has been freed */
+	int32_t prod_index;		/* where to put the next one */
+	int32_t free_index;		/* mbuf has been freed */
 
 	/* The queue Id is used to identify the HW Q */
 	uint16_t phys_qid;
@@ -47,14 +47,15 @@ struct ark_tx_queue {
 
 	uint32_t pad[1];
 
-	/* second cache line - fields only used in slow path */
+	/* second cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-	uint32_t cons_index;		/* hw is done, can be freed */
+	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
 
 /* Forward declarations */
-static uint32_t eth_ark_tx_jumbo(struct ark_tx_queue *queue,
-				 struct rte_mbuf *mbuf);
+static int eth_ark_tx_jumbo(struct ark_tx_queue *queue,
+			    struct rte_mbuf *mbuf,
+			    uint32_t *user_meta, uint8_t meta_cnt);
 static int eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue);
 static void free_completed_tx(struct ark_tx_queue *queue);
 
@@ -66,16 +67,44 @@ ark_tx_hw_queue_stop(struct ark_tx_queue *queue)
 
 /* ************************************************************************* */
 static inline void
-eth_ark_tx_meta_from_mbuf(struct ark_tx_meta *meta,
-			  const struct rte_mbuf *mbuf,
-			  uint8_t flags)
+eth_ark_tx_desc_fill(struct ark_tx_queue *queue,
+		     struct rte_mbuf *mbuf,
+		     uint8_t  flags,
+		     uint32_t *user_meta,
+		     uint8_t  meta_cnt /* 0 to 5 */
+		     )
 {
-	meta->physaddr = rte_mbuf_data_iova(mbuf);
-	meta->user1 = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+	uint32_t tx_idx;
+	union ark_tx_meta *meta;
+	uint8_t m;
+
+	/* Header */
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
 	meta->data_len = rte_pktmbuf_data_len(mbuf);
 	meta->flags = flags;
+	meta->meta_cnt = meta_cnt / 2;
+	meta->user1 = meta_cnt ? (*user_meta++) : 0;
+	queue->prod_index++;
+
+	queue->bufs[tx_idx] = mbuf;
+
+	/* 1 or 2 user meta data entries, user words 1,2 and 3,4 */
+	for (m = 1; m < meta_cnt; m += 2) {
+		tx_idx = queue->prod_index & queue->queue_mask;
+		meta = &queue->meta_q[tx_idx];
+		meta->usermeta0 = *user_meta++;
+		meta->usermeta1 = *user_meta++;
+		queue->prod_index++;
+	}
+
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
+	meta->physaddr = rte_mbuf_data_iova(mbuf);
+	queue->prod_index++;
 }
 
+
 /* ************************************************************************* */
 uint16_t
 eth_ark_xmit_pkts_noop(void *vtxq __rte_unused,
@@ -91,12 +120,12 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
+	uint32_t user_meta;
 
-	uint32_t idx;
-	uint32_t prod_index_limit;
 	int stat;
+	int32_t prod_index_limit;
 	uint16_t nb;
+	uint8_t user_len = 1;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
 
 	queue = (struct ark_tx_queue *)vtxq;
@@ -104,10 +133,11 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
 
-	prod_index_limit = queue->queue_size + queue->free_index;
+	/* leave 4 elements mpu data */
+	prod_index_limit = queue->queue_size + queue->free_index - 4;
 
 	for (nb = 0;
-	     (nb < nb_pkts) && (queue->prod_index != prod_index_limit);
+	     (nb < nb_pkts) && (prod_index_limit - queue->prod_index) > 0;
 	     ++nb) {
 		mbuf = tx_pkts[nb];
 
@@ -133,19 +163,16 @@ 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 (unlikely(mbuf->nb_segs != 1)) {
-			stat = eth_ark_tx_jumbo(queue, mbuf);
+			stat = eth_ark_tx_jumbo(queue, mbuf,
+						&user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
-			idx = queue->prod_index & queue->queue_mask;
-			queue->bufs[idx] = mbuf;
-			meta = &queue->meta_q[idx];
-			eth_ark_tx_meta_from_mbuf(meta,
-						  mbuf,
-						  ARK_DDM_SOP |
-						  ARK_DDM_EOP);
-			queue->prod_index++;
+			eth_ark_tx_desc_fill(queue, mbuf,
+					     ARK_DDM_SOP | ARK_DDM_EOP,
+					     &user_meta, user_len);
 		}
 	}
 
@@ -173,32 +200,28 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 }
 
 /* ************************************************************************* */
-static uint32_t
-eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf)
+static int
+eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf,
+		 uint32_t *user_meta, uint8_t meta_cnt)
 {
 	struct rte_mbuf *next;
-	struct ark_tx_meta *meta;
-	uint32_t free_queue_space;
-	uint32_t idx;
+	int32_t free_queue_space;
 	uint8_t flags = ARK_DDM_SOP;
 
 	free_queue_space = queue->queue_mask -
 		(queue->prod_index - queue->free_index);
-	if (unlikely(free_queue_space < mbuf->nb_segs))
+	/* We need up to 4 mbufs for first header and 2 for subsequent ones */
+	if (unlikely(free_queue_space < (2 + (2 * mbuf->nb_segs))))
 		return -1;
 
 	while (mbuf != NULL) {
 		next = mbuf->next;
-
-		idx = queue->prod_index & queue->queue_mask;
-		queue->bufs[idx] = mbuf;
-		meta = &queue->meta_q[idx];
-
 		flags |= (next == NULL) ? ARK_DDM_EOP : 0;
-		eth_ark_tx_meta_from_mbuf(meta, mbuf, flags);
-		queue->prod_index++;
+
+		eth_ark_tx_desc_fill(queue, mbuf, flags, user_meta, meta_cnt);
 
 		flags &= ~ARK_DDM_SOP;	/* drop SOP flags */
+		meta_cnt = 0;		/* Meta only on SOP */
 		mbuf = next;
 	}
 
@@ -227,6 +250,9 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
+	/* Each packet requires at least 2 mpu elements - double desc count */
+	nb_desc = 2 * nb_desc;
+
 	/* Allocate queue struct */
 	queue =	rte_zmalloc_socket("Ark_txqueue",
 				   sizeof(struct ark_tx_queue),
@@ -248,7 +274,7 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
-				   nb_desc * sizeof(struct ark_tx_meta),
+				   nb_desc * sizeof(union ark_tx_meta),
 				   64,
 				   socket_id);
 	queue->bufs =
@@ -289,7 +315,7 @@ eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue)
 	uint32_t write_interval_ns;
 
 	/* Verify HW -- MPU */
-	if (ark_mpu_verify(queue->mpu, sizeof(struct ark_tx_meta)))
+	if (ark_mpu_verify(queue->mpu, sizeof(union ark_tx_meta)))
 		return -1;
 
 	queue_base = rte_malloc_virt2iova(queue);
@@ -391,19 +417,19 @@ static void
 free_completed_tx(struct ark_tx_queue *queue)
 {
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
-	uint32_t top_index;
+	union ark_tx_meta *meta;
+	int32_t top_index;
 
 	top_index = queue->cons_index;	/* read once */
-	while (queue->free_index != top_index) {
+	while ((top_index - queue->free_index) > 0) {
 		meta = &queue->meta_q[queue->free_index & queue->queue_mask];
-		mbuf = queue->bufs[queue->free_index & queue->queue_mask];
-
 		if (likely((meta->flags & ARK_DDM_SOP) != 0)) {
+			mbuf = queue->bufs[queue->free_index &
+					   queue->queue_mask];
 			/* ref count of the mbuf is checked in this call. */
 			rte_pktmbuf_free(mbuf);
 		}
-		queue->free_index++;
+		queue->free_index += (meta->meta_cnt + 2);
 	}
 }
 
diff --git a/drivers/net/ark/ark_udm.c b/drivers/net/ark/ark_udm.c
index a740d36d4..28c4500a2 100644
--- a/drivers/net/ark/ark_udm.c
+++ b/drivers/net/ark/ark_udm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_udm.h"
 
+static_assert(sizeof(struct ark_rx_meta) == 32, "Unexpected struct size ark_rx_meta");
+
 int
 ark_udm_verify(struct ark_udm_t *udm)
 {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index 5846c825b..ea92d4b6e 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -15,14 +15,15 @@
  * there is minimal documentation.
  */
 
-/* Meta data structure apssed from FPGA, must match layout in FPGA */
+/* Meta data structure passed from FPGA, must match layout in FPGA
+ * -- 32 bytes
+ */
 struct ark_rx_meta {
 	uint64_t timestamp;
 	uint64_t user_data;
-	uint8_t port;
-	uint8_t dst_queue;
+	uint8_t  reserved[14];
 	uint16_t pkt_len;
-};
+} __rte_packed;
 
 /*
  * UDM hardware structures
@@ -32,7 +33,9 @@ struct ark_rx_meta {
 
 #define ARK_RX_WRITE_TIME_NS 2500
 #define ARK_UDM_SETUP 0
-#define ARK_UDM_CONST 0xbACECACE
+#define ARK_UDM_CONST2 0xbACECACE
+#define ARK_UDM_CONST3 0x334d4455
+#define ARK_UDM_CONST ARK_UDM_CONST3
 struct ark_udm_setup_t {
 	uint32_t r0;
 	uint32_t r4;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 4/6] net/ark: generalize meta data between FPGA and PMD
  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-08 22:29   ` 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-08 22:29   ` [dpdk-dev] [PATCH v3 6/6] net/ark: localize internal packet generator code Ed Czeck
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

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

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename to separate commit
---
 drivers/net/ark/ark_ethdev.c    |  58 ++---------------
 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_global.h    |  20 ++++++
 drivers/net/ark/ark_udm.h       |   5 +-
 drivers/net/ark/rte_pmd_ark.h   | 112 --------------------------------
 drivers/net/ark/version.map     |   7 --
 8 files changed, 61 insertions(+), 194 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 9f0a8d9e8..15ec83893 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,
@@ -243,6 +237,12 @@ check_for_ext(struct ark_adapter *ark)
 		(int (*)(struct rte_eth_dev *, uint16_t,
 			  void *))
 		dlsym(ark->d_handle, "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;
 }
@@ -255,16 +255,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;
 
@@ -275,30 +265,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;
@@ -559,18 +525,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_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..a77dd311f 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -10,116 +10,4 @@
  * ARK driver-specific API
  */
 
-#include <rte_mbuf.h>
-#include <rte_mbuf_dyn.h>
-
-#ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE
-#define RTE_PMD_ARK_TX_USERDATA_ENABLE 0
-#endif
-
-#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
-}
-
 #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


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 5/6] net/ark: cleanup and document ark dynamic extansion
  2021-03-08 22:29 ` [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (2 preceding siblings ...)
  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   ` 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
  4 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- Rename extension functions with rte_pmd_ark prefix
- Move extension prototype to rte_pmd_ark.h
- Update documentation for extension

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename from previous commit
---
 doc/guides/nics/ark.rst       | 139 ++++++++++++++++-
 drivers/net/ark/ark_ethdev.c  |  32 ++--
 drivers/net/ark/ark_ext.h     |  90 -----------
 drivers/net/ark/rte_pmd_ark.h | 284 +++++++++++++++++++++++++++++++++-
 4 files changed, 437 insertions(+), 108 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 dcccfee26..bcc3babd5 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
 -------------
 
@@ -144,6 +279,8 @@ documentation that comes with DPDK suite <linux_gsg>`.
 To build with a non-zero minimum tx packet length, set the above macro in your
 CFLAGS environment prior to the meson build step. I.e.,
 
+.. code-block:: console
+
     export CFLAGS="-DRTE_LIBRTE_ARK_MIN_TX_PKTLEN=60"
     meson build
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 15ec83893..f8a4b8711 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -185,58 +185,58 @@ 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");
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/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
index a77dd311f..7c093711f 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -1,13 +1,295 @@
 /* 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
  */
 
+/* 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 prototypes 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 macaddr
+ *   The MAC address to add
+ * @param index
+ *   The index into the MAC address array.
+ * @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 *macaddr,
+			      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 index
+ *   The index into the MAC address array.
+ * @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);
+
+/**
+ * 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. The
+ *   underlying data in the PMD is of type uint32_t meta[5];
+ * @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);
+
+/**
+ * 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. The
+ *   underlying in the PMD is of type uint32_t meta[5];
+ * @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 */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v3 6/6] net/ark: localize internal packet generator code
  2021-03-08 22:29 ` [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (3 preceding siblings ...)
  2021-03-08 22:29   ` [dpdk-dev] [PATCH v3 5/6] net/ark: cleanup and document ark dynamic extansion Ed Czeck
@ 2021-03-08 22:29   ` Ed Czeck
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-08 22:29 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

remove unnecessary includes
no functional changes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c  | 17 ++---------------
 drivers/net/ark/ark_pktchkr.c |  4 ----
 drivers/net/ark/ark_pktgen.c  | 20 ++++++++++++++------
 drivers/net/ark/ark_pktgen.h  |  1 +
 4 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index f8a4b8711..d1f18a991 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -533,20 +533,6 @@ eth_ark_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void *
-delay_pg_start(void *arg)
-{
-	struct ark_adapter *ark = (struct ark_adapter *)arg;
-
-	/* This function is used exclusively for regression testing, We
-	 * perform a blind sleep here to ensure that the external test
-	 * application has time to setup the test before we generate packets
-	 */
-	usleep(100000);
-	ark_pktgen_run(ark->pg);
-	return NULL;
-}
-
 static int
 eth_ark_dev_start(struct rte_eth_dev *dev)
 {
@@ -581,7 +567,8 @@ eth_ark_dev_start(struct rte_eth_dev *dev)
 		/* Delay packet generatpr start allow the hardware to be ready
 		 * This is only used for sanity checking with internal generator
 		 */
-		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
+		if (pthread_create(&thread, NULL,
+				   ark_pktgen_delay_start, ark->pg)) {
 			ARK_PMD_LOG(ERR, "Could not create pktgen "
 				    "starter thread\n");
 			return -1;
diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index 0f2d31e5b..84bb567a4 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -2,13 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktchkr.h"
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index ac4322a35..28a44f754 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -2,15 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_eal.h>
-
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktgen.h"
@@ -470,3 +464,17 @@ ark_pktgen_setup(ark_pkt_gen_t handle)
 		ark_pktgen_run(handle);
 	}
 }
+
+void *
+ark_pktgen_delay_start(void *arg)
+{
+	struct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)arg;
+
+	/* This function is used exclusively for regression testing, We
+	 * perform a blind sleep here to ensure that the external test
+	 * application has time to setup the test before we generate packets
+	 */
+	usleep(100000);
+	ark_pktgen_run(inst);
+	return NULL;
+}
diff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h
index c61dfee6d..7147fe1bd 100644
--- a/drivers/net/ark/ark_pktgen.h
+++ b/drivers/net/ark/ark_pktgen.h
@@ -75,5 +75,6 @@ void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);
 void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);
 void ark_pktgen_parse(char *argv);
 void ark_pktgen_setup(ark_pkt_gen_t handle);
+void *ark_pktgen_delay_start(void *arg);
 
 #endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 3/6] net/ark: update internal structs to reflect FPGA updates
  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
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-09 11:32 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller

On 3/8/2021 10:29 PM, Ed Czeck wrote:
> - New PCIe IDs using net/ark driver
> - Update Version IDs and structures specified by hardware
> - New internal descriptor status for TX
> - Adjust data placement in RX operations, headroom in retained
> for segmented mbufs
> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> ---
>   doc/guides/nics/ark.rst         |   5 ++
>   drivers/net/ark/ark_ddm.c       |  18 +++--
>   drivers/net/ark/ark_ddm.h       |  22 +++---
>   drivers/net/ark/ark_ethdev.c    |   3 +
>   drivers/net/ark/ark_ethdev_rx.c |   6 +-
>   drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
>   drivers/net/ark/ark_udm.c       |   2 +
>   drivers/net/ark/ark_udm.h       |  13 ++--
>   8 files changed, 121 insertions(+), 70 deletions(-)
> 
> diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
> index 18434c7a4..dcccfee26 100644
> --- a/doc/guides/nics/ark.rst
> +++ b/doc/guides/nics/ark.rst
> @@ -155,6 +155,11 @@ ARK PMD supports the following Arkville RTL PCIe instances including:
>   
>   * ``1d6c:100d`` - AR-ARKA-FX0 [Arkville 32B DPDK Data Mover]
>   * ``1d6c:100e`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover]
> +* ``1d6c:100f`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal]
> +* ``1d6c:1010`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex]
> +* ``1d6c:1017`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Primary Endpoint]
> +* ``1d6c:1018`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Secondary Endpoint]
> +* ``1d6c:1019`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Tertiary Endpoint]
>   

Thanks for documenting them, but '100f' && '1010' are not in the 
'pci_id_ark_map', are they missing in the code?


Also can you please update the release notes related to the features updated in 
this set?

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v3 5/6] net/ark: cleanup and document ark dynamic extansion
  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
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-09 11:43 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller

On 3/8/2021 10:29 PM, Ed Czeck wrote:
> - Rename extension functions with rte_pmd_ark prefix
> - Move extension prototype to rte_pmd_ark.h
> - Update documentation for extension

Hi Ed,

I think better to have the documentation with the previous patch, where it has 
the hooks.
It has a benefit to have the documentation and the code in same commit, when you 
want to investigate some code it is easy the find the commit that has been 
introduced and documentation being in the same commit gives the full intentions 
to investigate, if documentation is in different commit it is easy the miss the 
documentation part.
But I can see documentation is using renamed, and latest, APIs that may be the 
reason to have the documentation in this commit.

Sorry it will require some playing with git but can you do the renaming first, 
and in second patch you can add the new hooks with documentation in same patch? 
This way the API names will be correct in the documentation again when you add it.

Thanks,
ferruh

> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> ---
> v3:
> - split function rename from previous commit

<...>


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state
  2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (5 preceding siblings ...)
  2021-03-08 22:29 ` [dpdk-dev] [PATCH v3 1/6] net/ark: update pkt director initial state Ed Czeck
@ 2021-03-09 16:08 ` Ed Czeck
  2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
                     ` (4 more replies)
  2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
  7 siblings, 5 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c | 1 +
 drivers/net/ark/ark_pktdir.c | 2 +-
 drivers/net/ark/ark_pktdir.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ef650a465..477e1de02 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -321,6 +321,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	ark->rqpacing =
 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
 	ark->started = 0;
+	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
 
 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
 		      ark->sysctrl.t32[4],
diff --git a/drivers/net/ark/ark_pktdir.c b/drivers/net/ark/ark_pktdir.c
index 25e121831..dbfd2924b 100644
--- a/drivers/net/ark/ark_pktdir.c
+++ b/drivers/net/ark/ark_pktdir.c
@@ -22,7 +22,7 @@ ark_pktdir_init(void *base)
 		return inst;
 	}
 	inst->regs = (struct ark_pkt_dir_regs *)base;
-	inst->regs->ctrl = 0x00110110;	/* POR state */
+	inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */
 	return inst;
 }
 
diff --git a/drivers/net/ark/ark_pktdir.h b/drivers/net/ark/ark_pktdir.h
index 4afd128f9..b5577cebb 100644
--- a/drivers/net/ark/ark_pktdir.h
+++ b/drivers/net/ark/ark_pktdir.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#define ARK_PKTDIR_BASE_ADR  0xa0000
+#define ARK_PKT_DIR_INIT_VAL 0x0110
 
 typedef void *ark_pkt_dir_t;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 2/6] net/ark: refactor Rx buffer recovery
  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   ` Ed Czeck
  2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller, stable

Allocate mbufs for Rx path in bulk of at least 64 buffers
to improve performance. Allow recovery even without
a Rx operation to support lack of buffers in pool.

Fixes: be410a861598 ("net/ark: add recovery for lack of mbufs")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev_rx.c | 49 ++++++++-------------------------
 1 file changed, 11 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index d29d3db78..8e55b851a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -26,9 +26,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 				 struct rte_mbuf *mbuf0,
 				 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-				    uint32_t *pnb,
-				    struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -54,7 +51,7 @@ struct ark_rx_queue {
 	/* The queue Index is used within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t last_cons;
+	uint32_t unused;
 
 	/* separate cache line */
 	/* second cache line - fields only used in slow path */
@@ -105,9 +102,8 @@ static inline void
 eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
 	queue->cons_index = cons_index;
-	eth_ark_rx_seed_mbufs(queue);
-	if (((cons_index - queue->last_cons) >= 64U)) {
-		queue->last_cons = cons_index;
+	if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) {
+		eth_ark_rx_seed_mbufs(queue);
 		ark_mpu_set_producer(queue->mpu, queue->seed_index);
 	}
 }
@@ -321,9 +317,7 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
-	if (unlikely(nb != 0))
-		/* report next free to FPGA */
-		eth_ark_rx_update_cons_index(queue, cons_index);
+	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
 }
@@ -458,11 +452,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
 	if (unlikely(status != 0)) {
-		/* Try to recover from lack of mbufs in pool */
-		status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
-		if (unlikely(status != 0)) {
-			return -1;
-		}
+		ARK_PMD_LOG(NOTICE,
+			    "Could not allocate %u mbufs from pool"
+			    " for RX queue %u;"
+			    " %u free buffers remaining in queue\n",
+			    nb, queue->queue_index,
+			    queue->seed_index - queue->cons_index);
+		return -1;
 	}
 
 	if (ARK_DEBUG_CORE) {		/* DEBUG */
@@ -511,29 +507,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	return 0;
 }
 
-int
-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-			 uint32_t *pnb,
-			 struct rte_mbuf **mbufs)
-{
-	int status = -1;
-
-	/* Ignore small allocation failures */
-	if (*pnb <= 64)
-		return -1;
-
-	*pnb = 64U;
-	status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
-	if (status != 0) {
-		ARK_PMD_LOG(NOTICE,
-			    "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
-			    " %u free buffers remaining in queue\n",
-			    *pnb, queue->queue_index,
-			    queue->seed_index - queue->cons_index);
-	}
-	return status;
-}
-
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
 		      const char *msg)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 3/6] net/ark: update internal structs to reflect FPGA updates
  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   ` Ed Czeck
  2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface Ed Czeck
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- New PCIe IDs using net/ark driver
- Update Version IDs and structures specified by hardware
- New internal descriptor status for TX
- Adjust data placement in RX operations, headroom in retained
for segmented mbufs

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 doc/guides/nics/ark.rst         |   5 ++
 drivers/net/ark/ark_ddm.c       |  18 +++--
 drivers/net/ark/ark_ddm.h       |  22 +++---
 drivers/net/ark/ark_ethdev.c    |   5 ++
 drivers/net/ark/ark_ethdev_rx.c |   6 +-
 drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
 drivers/net/ark/ark_udm.c       |   2 +
 drivers/net/ark/ark_udm.h       |  13 ++--
 8 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index 18434c7a4..dcccfee26 100644
--- a/doc/guides/nics/ark.rst
+++ b/doc/guides/nics/ark.rst
@@ -155,6 +155,11 @@ ARK PMD supports the following Arkville RTL PCIe instances including:
 
 * ``1d6c:100d`` - AR-ARKA-FX0 [Arkville 32B DPDK Data Mover]
 * ``1d6c:100e`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover]
+* ``1d6c:100f`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal]
+* ``1d6c:1010`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex]
+* ``1d6c:1017`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Primary Endpoint]
+* ``1d6c:1018`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Secondary Endpoint]
+* ``1d6c:1019`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Tertiary Endpoint]
 
 Supported Operating Systems
 ---------------------------
diff --git a/drivers/net/ark/ark_ddm.c b/drivers/net/ark/ark_ddm.c
index 91d1179d8..232137157 100644
--- a/drivers/net/ark/ark_ddm.c
+++ b/drivers/net/ark/ark_ddm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_ddm.h"
 
+static_assert(sizeof(union ark_tx_meta) == 8, "Unexpected struct size ark_tx_meta");
+
 /* ************************************************************************* */
 int
 ark_ddm_verify(struct ark_ddm_t *ddm)
@@ -19,18 +21,26 @@ ark_ddm_verify(struct ark_ddm_t *ddm)
 	}
 
 	hw_const = ddm->cfg.const0;
+	if (hw_const == ARK_DDM_CONST3)
+		return 0;
+
 	if (hw_const == ARK_DDM_CONST1) {
 		ARK_PMD_LOG(ERR,
 			    "ARK: DDM module is version 1, "
 			    "PMD expects version 2\n");
 		return -1;
-	} else if (hw_const != ARK_DDM_CONST2) {
+	}
+
+	if (hw_const == ARK_DDM_CONST2) {
 		ARK_PMD_LOG(ERR,
-			    "ARK: DDM module not found as expected 0x%08x\n",
-			    ddm->cfg.const0);
+			    "ARK: DDM module is version 2, "
+			    "PMD expects version 3\n");
 		return -1;
 	}
-	return 0;
+	ARK_PMD_LOG(ERR,
+		    "ARK: DDM module not found as expected 0x%08x\n",
+		    ddm->cfg.const0);
+	return -1;
 }
 
 void
diff --git a/drivers/net/ark/ark_ddm.h b/drivers/net/ark/ark_ddm.h
index 5456b4b5c..687ff2519 100644
--- a/drivers/net/ark/ark_ddm.h
+++ b/drivers/net/ark/ark_ddm.h
@@ -16,17 +16,22 @@
  * there is minimal documentation.
  */
 
-/* struct defining Tx meta data --  fixed in FPGA -- 16 bytes */
-struct ark_tx_meta {
+/* struct defining Tx meta data --  fixed in FPGA -- 8 bytes */
+union ark_tx_meta {
 	uint64_t physaddr;
-	uint32_t user1;
-	uint16_t data_len;		/* of this MBUF */
+	struct {
+		uint32_t usermeta0;
+		uint32_t usermeta1;
+	};
+	struct {
+		uint16_t data_len;	/* of this MBUF */
 #define   ARK_DDM_EOP   0x01
 #define   ARK_DDM_SOP   0x02
-	uint8_t flags;		/* bit 0 indicates last mbuf in chain. */
-	uint8_t reserved[1];
-};
-
+		uint8_t  flags;
+		uint8_t  meta_cnt;
+		uint32_t user1;
+	};
+} __rte_packed;
 
 /*
  * DDM core hardware structures
@@ -35,6 +40,7 @@ struct ark_tx_meta {
  */
 #define ARK_DDM_CFG 0x0000
 /* Set unique HW ID for hardware version */
+#define ARK_DDM_CONST3 (0x334d4444)
 #define ARK_DDM_CONST2 (0x324d4444)
 #define ARK_DDM_CONST1 (0xfacecafe)
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 477e1de02..95546a891 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -95,6 +95,11 @@ static const char * const valid_arguments[] = {
 static const struct rte_pci_id pci_id_ark_map[] = {
 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x100f)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1010)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1017)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1018)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1019)},
 	{.vendor_id = 0, /* sentinel */ },
 };
 
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 8e55b851a..21a9af41a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -60,7 +60,6 @@ struct ark_rx_queue {
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
 } __rte_cache_aligned;
 
-
 /* ************************************************************************* */
 static int
 eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
@@ -265,7 +264,6 @@ eth_ark_recv_pkts(void *rx_queue,
 		/* META DATA embedded in headroom */
 		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
 
-		mbuf->port = meta->port;
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
 		/* set timestamp if enabled at least on one device */
@@ -346,8 +344,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 	/* HW guarantees that the data does not exceed prod_index! */
 	while (remaining != 0) {
 		data_len = RTE_MIN(remaining,
-				   RTE_MBUF_DEFAULT_DATAROOM +
-				   RTE_PKTMBUF_HEADROOM);
+				   RTE_MBUF_DEFAULT_DATAROOM);
 
 		remaining -= data_len;
 		segments += 1;
@@ -356,7 +353,6 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 		mbuf_prev->next = mbuf;
 		mbuf_prev = mbuf;
 		mbuf->data_len = data_len;
-		mbuf->data_off = 0;
 
 		cons_index += 1;
 	}
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 612d918e3..00e5dbf7c 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
+ * Copyright (c) 2015-2021 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -23,7 +23,7 @@
 
 /* ************************************************************************* */
 struct ark_tx_queue {
-	struct ark_tx_meta *meta_q;
+	union ark_tx_meta *meta_q;
 	struct rte_mbuf **bufs;
 
 	/* handles for hw objects */
@@ -37,8 +37,8 @@ struct ark_tx_queue {
 	uint32_t queue_mask;
 
 	/* 3 indexes to the paired data rings. */
-	uint32_t prod_index;		/* where to put the next one */
-	uint32_t free_index;		/* mbuf has been freed */
+	int32_t prod_index;		/* where to put the next one */
+	int32_t free_index;		/* mbuf has been freed */
 
 	/* The queue Id is used to identify the HW Q */
 	uint16_t phys_qid;
@@ -47,14 +47,15 @@ struct ark_tx_queue {
 
 	uint32_t pad[1];
 
-	/* second cache line - fields only used in slow path */
+	/* second cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-	uint32_t cons_index;		/* hw is done, can be freed */
+	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
 
 /* Forward declarations */
-static uint32_t eth_ark_tx_jumbo(struct ark_tx_queue *queue,
-				 struct rte_mbuf *mbuf);
+static int eth_ark_tx_jumbo(struct ark_tx_queue *queue,
+			    struct rte_mbuf *mbuf,
+			    uint32_t *user_meta, uint8_t meta_cnt);
 static int eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue);
 static void free_completed_tx(struct ark_tx_queue *queue);
 
@@ -66,16 +67,44 @@ ark_tx_hw_queue_stop(struct ark_tx_queue *queue)
 
 /* ************************************************************************* */
 static inline void
-eth_ark_tx_meta_from_mbuf(struct ark_tx_meta *meta,
-			  const struct rte_mbuf *mbuf,
-			  uint8_t flags)
+eth_ark_tx_desc_fill(struct ark_tx_queue *queue,
+		     struct rte_mbuf *mbuf,
+		     uint8_t  flags,
+		     uint32_t *user_meta,
+		     uint8_t  meta_cnt /* 0 to 5 */
+		     )
 {
-	meta->physaddr = rte_mbuf_data_iova(mbuf);
-	meta->user1 = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+	uint32_t tx_idx;
+	union ark_tx_meta *meta;
+	uint8_t m;
+
+	/* Header */
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
 	meta->data_len = rte_pktmbuf_data_len(mbuf);
 	meta->flags = flags;
+	meta->meta_cnt = meta_cnt / 2;
+	meta->user1 = meta_cnt ? (*user_meta++) : 0;
+	queue->prod_index++;
+
+	queue->bufs[tx_idx] = mbuf;
+
+	/* 1 or 2 user meta data entries, user words 1,2 and 3,4 */
+	for (m = 1; m < meta_cnt; m += 2) {
+		tx_idx = queue->prod_index & queue->queue_mask;
+		meta = &queue->meta_q[tx_idx];
+		meta->usermeta0 = *user_meta++;
+		meta->usermeta1 = *user_meta++;
+		queue->prod_index++;
+	}
+
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
+	meta->physaddr = rte_mbuf_data_iova(mbuf);
+	queue->prod_index++;
 }
 
+
 /* ************************************************************************* */
 uint16_t
 eth_ark_xmit_pkts_noop(void *vtxq __rte_unused,
@@ -91,12 +120,12 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
+	uint32_t user_meta;
 
-	uint32_t idx;
-	uint32_t prod_index_limit;
 	int stat;
+	int32_t prod_index_limit;
 	uint16_t nb;
+	uint8_t user_len = 1;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
 
 	queue = (struct ark_tx_queue *)vtxq;
@@ -104,10 +133,11 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
 
-	prod_index_limit = queue->queue_size + queue->free_index;
+	/* leave 4 elements mpu data */
+	prod_index_limit = queue->queue_size + queue->free_index - 4;
 
 	for (nb = 0;
-	     (nb < nb_pkts) && (queue->prod_index != prod_index_limit);
+	     (nb < nb_pkts) && (prod_index_limit - queue->prod_index) > 0;
 	     ++nb) {
 		mbuf = tx_pkts[nb];
 
@@ -133,19 +163,16 @@ 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 (unlikely(mbuf->nb_segs != 1)) {
-			stat = eth_ark_tx_jumbo(queue, mbuf);
+			stat = eth_ark_tx_jumbo(queue, mbuf,
+						&user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
-			idx = queue->prod_index & queue->queue_mask;
-			queue->bufs[idx] = mbuf;
-			meta = &queue->meta_q[idx];
-			eth_ark_tx_meta_from_mbuf(meta,
-						  mbuf,
-						  ARK_DDM_SOP |
-						  ARK_DDM_EOP);
-			queue->prod_index++;
+			eth_ark_tx_desc_fill(queue, mbuf,
+					     ARK_DDM_SOP | ARK_DDM_EOP,
+					     &user_meta, user_len);
 		}
 	}
 
@@ -173,32 +200,28 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 }
 
 /* ************************************************************************* */
-static uint32_t
-eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf)
+static int
+eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf,
+		 uint32_t *user_meta, uint8_t meta_cnt)
 {
 	struct rte_mbuf *next;
-	struct ark_tx_meta *meta;
-	uint32_t free_queue_space;
-	uint32_t idx;
+	int32_t free_queue_space;
 	uint8_t flags = ARK_DDM_SOP;
 
 	free_queue_space = queue->queue_mask -
 		(queue->prod_index - queue->free_index);
-	if (unlikely(free_queue_space < mbuf->nb_segs))
+	/* We need up to 4 mbufs for first header and 2 for subsequent ones */
+	if (unlikely(free_queue_space < (2 + (2 * mbuf->nb_segs))))
 		return -1;
 
 	while (mbuf != NULL) {
 		next = mbuf->next;
-
-		idx = queue->prod_index & queue->queue_mask;
-		queue->bufs[idx] = mbuf;
-		meta = &queue->meta_q[idx];
-
 		flags |= (next == NULL) ? ARK_DDM_EOP : 0;
-		eth_ark_tx_meta_from_mbuf(meta, mbuf, flags);
-		queue->prod_index++;
+
+		eth_ark_tx_desc_fill(queue, mbuf, flags, user_meta, meta_cnt);
 
 		flags &= ~ARK_DDM_SOP;	/* drop SOP flags */
+		meta_cnt = 0;		/* Meta only on SOP */
 		mbuf = next;
 	}
 
@@ -227,6 +250,9 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
+	/* Each packet requires at least 2 mpu elements - double desc count */
+	nb_desc = 2 * nb_desc;
+
 	/* Allocate queue struct */
 	queue =	rte_zmalloc_socket("Ark_txqueue",
 				   sizeof(struct ark_tx_queue),
@@ -248,7 +274,7 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
-				   nb_desc * sizeof(struct ark_tx_meta),
+				   nb_desc * sizeof(union ark_tx_meta),
 				   64,
 				   socket_id);
 	queue->bufs =
@@ -289,7 +315,7 @@ eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue)
 	uint32_t write_interval_ns;
 
 	/* Verify HW -- MPU */
-	if (ark_mpu_verify(queue->mpu, sizeof(struct ark_tx_meta)))
+	if (ark_mpu_verify(queue->mpu, sizeof(union ark_tx_meta)))
 		return -1;
 
 	queue_base = rte_malloc_virt2iova(queue);
@@ -391,19 +417,19 @@ static void
 free_completed_tx(struct ark_tx_queue *queue)
 {
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
-	uint32_t top_index;
+	union ark_tx_meta *meta;
+	int32_t top_index;
 
 	top_index = queue->cons_index;	/* read once */
-	while (queue->free_index != top_index) {
+	while ((top_index - queue->free_index) > 0) {
 		meta = &queue->meta_q[queue->free_index & queue->queue_mask];
-		mbuf = queue->bufs[queue->free_index & queue->queue_mask];
-
 		if (likely((meta->flags & ARK_DDM_SOP) != 0)) {
+			mbuf = queue->bufs[queue->free_index &
+					   queue->queue_mask];
 			/* ref count of the mbuf is checked in this call. */
 			rte_pktmbuf_free(mbuf);
 		}
-		queue->free_index++;
+		queue->free_index += (meta->meta_cnt + 2);
 	}
 }
 
diff --git a/drivers/net/ark/ark_udm.c b/drivers/net/ark/ark_udm.c
index a740d36d4..28c4500a2 100644
--- a/drivers/net/ark/ark_udm.c
+++ b/drivers/net/ark/ark_udm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_udm.h"
 
+static_assert(sizeof(struct ark_rx_meta) == 32, "Unexpected struct size ark_rx_meta");
+
 int
 ark_udm_verify(struct ark_udm_t *udm)
 {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index 5846c825b..ea92d4b6e 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -15,14 +15,15 @@
  * there is minimal documentation.
  */
 
-/* Meta data structure apssed from FPGA, must match layout in FPGA */
+/* Meta data structure passed from FPGA, must match layout in FPGA
+ * -- 32 bytes
+ */
 struct ark_rx_meta {
 	uint64_t timestamp;
 	uint64_t user_data;
-	uint8_t port;
-	uint8_t dst_queue;
+	uint8_t  reserved[14];
 	uint16_t pkt_len;
-};
+} __rte_packed;
 
 /*
  * UDM hardware structures
@@ -32,7 +33,9 @@ struct ark_rx_meta {
 
 #define ARK_RX_WRITE_TIME_NS 2500
 #define ARK_UDM_SETUP 0
-#define ARK_UDM_CONST 0xbACECACE
+#define ARK_UDM_CONST2 0xbACECACE
+#define ARK_UDM_CONST3 0x334d4455
+#define ARK_UDM_CONST ARK_UDM_CONST3
 struct ark_udm_setup_t {
 	uint32_t r0;
 	uint32_t r4;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface
  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   ` Ed Czeck
  2021-03-09 17:50     ` 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 16:08   ` [dpdk-dev] [PATCH v4 6/6] net/ark: localize internal packet generator code Ed Czeck
  4 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

- Rename extension functions with rte_pmd_ark prefix
- Move extension prototype to rte_pmd_ark.h
- Update local function documentation

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename from previous commit
v4:
- reorder patches renaming before adding
---
 drivers/net/ark/ark_ethdev.c  |  32 ++---
 drivers/net/ark/ark_ext.h     |  90 ------------
 drivers/net/ark/rte_pmd_ark.h | 251 +++++++++++++++++++++++++++++++++-
 3 files changed, 263 insertions(+), 110 deletions(-)
 delete mode 100644 drivers/net/ark/ark_ext.h

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 95546a891..5282534d3 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -193,58 +193,58 @@ 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");
 
 	return found;
 }
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/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
index 6f26d66b1..0f24a347d 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -1,18 +1,24 @@
 /* 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 <rte_mbuf.h>
+#include <rte_mbuf_dyn.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>
-
 #ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE
 #define RTE_PMD_ARK_TX_USERDATA_ENABLE 0
 #endif
@@ -122,4 +128,241 @@ rte_pmd_ark_mbuf_rx_userdata_set(struct rte_mbuf *mbuf,
 #endif
 }
 
+/* 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 prototypes 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 macaddr
+ *   The MAC address to add
+ * @param index
+ *   The index into the MAC address array.
+ * @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 *macaddr,
+			      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 index
+ *   The index into the MAC address array.
+ * @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);
+
 #endif /* RTE_PMD_ARK_H */
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-09 16:08 ` [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (2 preceding siblings ...)
  2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface Ed Czeck
@ 2021-03-09 16:08   ` Ed Czeck
  2021-03-09 17:36     ` Ferruh Yigit
  2021-03-09 16:08   ` [dpdk-dev] [PATCH v4 6/6] net/ark: localize internal packet generator code Ed Czeck
  4 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

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
- Update guide with example of hook function use
- Add release notes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename to separate commit

v4:
- reorder patches renaming before adding
-
---
 doc/guides/nics/ark.rst                | 139 ++++++++++++++++++++++-
 doc/guides/rel_notes/release_21_05.rst |  11 ++
 drivers/net/ark/ark_ethdev.c           |  58 +---------
 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_global.h           |  20 ++++
 drivers/net/ark/ark_udm.h              |   5 +-
 drivers/net/ark/rte_pmd_ark.h          | 151 +++++++------------------
 drivers/net/ark/version.map            |   7 --
 10 files changed, 249 insertions(+), 195 deletions(-)

diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index dcccfee26..bcc3babd5 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
 -------------
 
@@ -144,6 +279,8 @@ documentation that comes with DPDK suite <linux_gsg>`.
 To build with a non-zero minimum tx packet length, set the above macro in your
 CFLAGS environment prior to the meson build step. I.e.,
 
+.. code-block:: console
+
     export CFLAGS="-DRTE_LIBRTE_ARK_MIN_TX_PKTLEN=60"
     meson build
 
diff --git a/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
index 5aa9ed7db..4789bf782 100644
--- a/doc/guides/rel_notes/release_21_05.rst
+++ b/doc/guides/rel_notes/release_21_05.rst
@@ -55,6 +55,17 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Arkville PMD driver.**
+
+  Updated Arkville net driver with new features and improvements, including:
+
+  * Generalized passing meta data between PMD and FPGA, allowing up to 20
+    bytes of user specified information in RX and TX paths.
+
+  * Updated dynamic PMD extensions API using standardized names.
+
+  * Added support for new Atomic Rules PCI device IDs ``0x100f, 0x1010, 0x1017,
+    0x1018, 0x1019``.
 
 Removed Items
 -------------
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 5282534d3..bdebfdba4 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,
@@ -245,6 +239,12 @@ check_for_ext(struct ark_adapter *ark)
 		(int (*)(struct rte_eth_dev *, uint16_t,
 			  void *))
 		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;
 }
@@ -257,16 +257,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;
 
@@ -277,30 +267,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;
@@ -561,18 +527,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_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 0f24a347d..7c093711f 100644
--- a/drivers/net/ark/rte_pmd_ark.h
+++ b/drivers/net/ark/rte_pmd_ark.h
@@ -5,9 +5,6 @@
 #ifndef RTE_PMD_ARK_H
 #define RTE_PMD_ARK_H
 
-#include <rte_mbuf.h>
-#include <rte_mbuf_dyn.h>
-
 #include <stdint.h>
 struct rte_eth_dev;
 struct rte_mbuf;
@@ -19,115 +16,6 @@ struct rte_eth_stats;
  * ARK driver-specific API
  */
 
-#ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE
-#define RTE_PMD_ARK_TX_USERDATA_ENABLE 0
-#endif
-
-#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
-}
-
 /* 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
@@ -365,4 +253,43 @@ int rte_pmd_ark_set_mtu(struct rte_eth_dev *dev,
 			uint16_t size,
 			void *user_data);
 
+/**
+ * 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. The
+ *   underlying data in the PMD is of type uint32_t meta[5];
+ * @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);
+
+/**
+ * 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. The
+ *   underlying in the PMD is of type uint32_t meta[5];
+ * @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


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v4 6/6] net/ark: localize internal packet generator code
  2021-03-09 16:08 ` [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (3 preceding siblings ...)
  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 16:08   ` Ed Czeck
  4 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-09 16:08 UTC (permalink / raw)
  To: dev, ferruh.yigit; +Cc: shepard.siegel, john.miller

remove unnecessary includes
no functional changes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c  | 17 ++---------------
 drivers/net/ark/ark_pktchkr.c |  4 ----
 drivers/net/ark/ark_pktgen.c  | 20 ++++++++++++++------
 drivers/net/ark/ark_pktgen.h  |  1 +
 4 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index bdebfdba4..9a5835d70 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -535,20 +535,6 @@ eth_ark_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void *
-delay_pg_start(void *arg)
-{
-	struct ark_adapter *ark = (struct ark_adapter *)arg;
-
-	/* This function is used exclusively for regression testing, We
-	 * perform a blind sleep here to ensure that the external test
-	 * application has time to setup the test before we generate packets
-	 */
-	usleep(100000);
-	ark_pktgen_run(ark->pg);
-	return NULL;
-}
-
 static int
 eth_ark_dev_start(struct rte_eth_dev *dev)
 {
@@ -583,7 +569,8 @@ eth_ark_dev_start(struct rte_eth_dev *dev)
 		/* Delay packet generatpr start allow the hardware to be ready
 		 * This is only used for sanity checking with internal generator
 		 */
-		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
+		if (pthread_create(&thread, NULL,
+				   ark_pktgen_delay_start, ark->pg)) {
 			ARK_PMD_LOG(ERR, "Could not create pktgen "
 				    "starter thread\n");
 			return -1;
diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index 0f2d31e5b..84bb567a4 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -2,13 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktchkr.h"
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index ac4322a35..28a44f754 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -2,15 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_eal.h>
-
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktgen.h"
@@ -470,3 +464,17 @@ ark_pktgen_setup(ark_pkt_gen_t handle)
 		ark_pktgen_run(handle);
 	}
 }
+
+void *
+ark_pktgen_delay_start(void *arg)
+{
+	struct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)arg;
+
+	/* This function is used exclusively for regression testing, We
+	 * perform a blind sleep here to ensure that the external test
+	 * application has time to setup the test before we generate packets
+	 */
+	usleep(100000);
+	ark_pktgen_run(inst);
+	return NULL;
+}
diff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h
index c61dfee6d..7147fe1bd 100644
--- a/drivers/net/ark/ark_pktgen.h
+++ b/drivers/net/ark/ark_pktgen.h
@@ -75,5 +75,6 @@ void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);
 void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);
 void ark_pktgen_parse(char *argv);
 void ark_pktgen_setup(ark_pkt_gen_t handle);
+void *ark_pktgen_delay_start(void *arg);
 
 #endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  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
  0 siblings, 1 reply; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-09 17:36 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller, Bruce Richardson

On 3/9/2021 4:08 PM, Ed Czeck wrote:
> 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
> - Update guide with example of hook function use
> - Add release notes
> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> ---
> v3:
> - split function rename to separate commit
> 
> v4:
> - reorder patches renaming before adding

<...>

> 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;
> -};
> 

Since there is no more public APIs by driver, I think it should stop installing 
the header, and remove it from 'meson.build' file, and remove the header from 
API documentation, 'doc/api/doxy-api-index.md'.

I can see the header needs to be used by the extension developer, but that is 
still kind of PMD, the public headers are installed for the application developers.

Still there is a desire to install the required headers for PMD developers, as 
far as I know Bruce is working on it, cc'ed. This header can be installed as 
part of that effort.

Thanks,
ferruh

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface
  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
  0 siblings, 1 reply; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-09 17:50 UTC (permalink / raw)
  To: Ed Czeck, dev; +Cc: shepard.siegel, john.miller

On 3/9/2021 4:08 PM, Ed Czeck wrote:
> - Rename extension functions with rte_pmd_ark prefix
> - Move extension prototype to rte_pmd_ark.h
> - Update local function documentation
> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> ---
> v3:
> - split function rename from previous commit
> v4:
> - reorder patches renaming before adding

<...>

> diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
> index 6f26d66b1..0f24a347d 100644
> --- a/drivers/net/ark/rte_pmd_ark.h
> +++ b/drivers/net/ark/rte_pmd_ark.h
> @@ -1,18 +1,24 @@
>   /* 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 <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#include <stdint.h>
> +struct rte_eth_dev;
> +struct rte_mbuf;
> +struct rte_ether_addr;
> +struct rte_eth_stats;
> +

Is the declaring structures instead of including header preferred intentionally?

I guess both works, and it may not differ for the PMD at all, but for the 
extension developer that is including this header, it may need to include 
required headers again, this header including all required headers and be a self 
contained may help extension code, up to you.

Plus just a detail but I guess mbuf struct is redundant for this patch, it can 
be added in next patch where mbufs header removed and hooks added.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-09 17:36     ` Ferruh Yigit
@ 2021-03-10 15:02       ` Ed Czeck
  2021-03-10 16:44         ` Ferruh Yigit
  0 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-10 15:02 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Shepard Siegel, John Miller, Bruce Richardson

On Tue, Mar 9, 2021 at 12:36 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 3/9/2021 4:08 PM, Ed Czeck wrote:
> > 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
> > - Update guide with example of hook function use
> > - Add release notes
> >
> > Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> > ---
> > v3:
> > - split function rename to separate commit
> >
> > v4:
> > - reorder patches renaming before adding
>
> <...>
>
> > 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;
> > -};
> >
>
> Since there is no more public APIs by driver, I think it should stop installing
> the header, and remove it from 'meson.build' file, and remove the header from
> API documentation, 'doc/api/doxy-api-index.md'.
>
> I can see the header needs to be used by the extension developer, but that is
> still kind of PMD, the public headers are installed for the application developers.
>
> Still there is a desire to install the required headers for PMD developers, as
> far as I know Bruce is working on it, cc'ed. This header can be installed as
> part of that effort.
>
> Thanks,
> ferruh

The function prototypes in the header are required by the extension
developer, hence
they need to be accessible in an installed file. Placing them in
rte_pmd-ark.h seems
like the existing solution. If there is a better location or solution
for publishing these
definitions, I have not found it yet. Please advise if I should change
this in some way.

Ed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface
  2021-03-09 17:50     ` Ferruh Yigit
@ 2021-03-10 15:11       ` Ed Czeck
  2021-03-10 16:29         ` Ferruh Yigit
  0 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-10 15:11 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Shepard Siegel, John Miller

On Tue, Mar 9, 2021 at 12:50 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 3/9/2021 4:08 PM, Ed Czeck wrote:
> > - Rename extension functions with rte_pmd_ark prefix
> > - Move extension prototype to rte_pmd_ark.h
> > - Update local function documentation
> >
> > Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> > ---
> > v3:
> > - split function rename from previous commit
> > v4:
> > - reorder patches renaming before adding
>
> <...>
>
> > diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
> > index 6f26d66b1..0f24a347d 100644
> > --- a/drivers/net/ark/rte_pmd_ark.h
> > +++ b/drivers/net/ark/rte_pmd_ark.h
> > @@ -1,18 +1,24 @@
> >   /* 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 <rte_mbuf.h>
> > +#include <rte_mbuf_dyn.h>
> > +
> > +#include <stdint.h>
> > +struct rte_eth_dev;
> > +struct rte_mbuf;
> > +struct rte_ether_addr;
> > +struct rte_eth_stats;
> > +
>
> Is the declaring structures instead of including header preferred intentionally?
>
> I guess both works, and it may not differ for the PMD at all, but for the
> extension developer that is including this header, it may need to include
> required headers again, this header including all required headers and be a self
> contained may help extension code, up to you.

My experience/style has been to use a declaration rather than a full include to
avoid include bloat and speed up compiles.  If the extension developer needs
the declaration in the header, they can include it as needed.

>
> Plus just a detail but I guess mbuf struct is redundant for this patch, it can
> be added in next patch where mbufs header removed and hooks added.

Agreed.  Would you like another patch?

Thanks
Ed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 4/6] net/ark: cleanup ark dynamic extension interface
  2021-03-10 15:11       ` Ed Czeck
@ 2021-03-10 16:29         ` Ferruh Yigit
  0 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-10 16:29 UTC (permalink / raw)
  To: Ed Czeck; +Cc: dev, Shepard Siegel, John Miller

On 3/10/2021 3:11 PM, Ed Czeck wrote:
> On Tue, Mar 9, 2021 at 12:50 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 3/9/2021 4:08 PM, Ed Czeck wrote:
>>> - Rename extension functions with rte_pmd_ark prefix
>>> - Move extension prototype to rte_pmd_ark.h
>>> - Update local function documentation
>>>
>>> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
>>> ---
>>> v3:
>>> - split function rename from previous commit
>>> v4:
>>> - reorder patches renaming before adding
>>
>> <...>
>>
>>> diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
>>> index 6f26d66b1..0f24a347d 100644
>>> --- a/drivers/net/ark/rte_pmd_ark.h
>>> +++ b/drivers/net/ark/rte_pmd_ark.h
>>> @@ -1,18 +1,24 @@
>>>    /* 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 <rte_mbuf.h>
>>> +#include <rte_mbuf_dyn.h>
>>> +
>>> +#include <stdint.h>
>>> +struct rte_eth_dev;
>>> +struct rte_mbuf;
>>> +struct rte_ether_addr;
>>> +struct rte_eth_stats;
>>> +
>>
>> Is the declaring structures instead of including header preferred intentionally?
>>
>> I guess both works, and it may not differ for the PMD at all, but for the
>> extension developer that is including this header, it may need to include
>> required headers again, this header including all required headers and be a self
>> contained may help extension code, up to you.
> 
> My experience/style has been to use a declaration rather than a full include to
> avoid include bloat and speed up compiles.  If the extension developer needs
> the declaration in the header, they can include it as needed.
> 

OK.

>>
>> Plus just a detail but I guess mbuf struct is redundant for this patch, it can
>> be added in next patch where mbufs header removed and hooks added.
> 
> Agreed.  Would you like another patch?
> 
> Thanks
> Ed.
> 


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-10 15:02       ` Ed Czeck
@ 2021-03-10 16:44         ` Ferruh Yigit
  2021-03-10 21:53           ` Ed Czeck
  0 siblings, 1 reply; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-10 16:44 UTC (permalink / raw)
  To: Ed Czeck; +Cc: dev, Shepard Siegel, John Miller, Bruce Richardson

On 3/10/2021 3:02 PM, Ed Czeck wrote:
> On Tue, Mar 9, 2021 at 12:36 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 3/9/2021 4:08 PM, Ed Czeck wrote:
>>> 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
>>> - Update guide with example of hook function use
>>> - Add release notes
>>>
>>> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
>>> ---
>>> v3:
>>> - split function rename to separate commit
>>>
>>> v4:
>>> - reorder patches renaming before adding
>>
>> <...>
>>
>>> 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;
>>> -};
>>>
>>
>> Since there is no more public APIs by driver, I think it should stop installing
>> the header, and remove it from 'meson.build' file, and remove the header from
>> API documentation, 'doc/api/doxy-api-index.md'.
>>
>> I can see the header needs to be used by the extension developer, but that is
>> still kind of PMD, the public headers are installed for the application developers.
>>
>> Still there is a desire to install the required headers for PMD developers, as
>> far as I know Bruce is working on it, cc'ed. This header can be installed as
>> part of that effort.
>>
>> Thanks,
>> ferruh
> 
> The function prototypes in the header are required by the extension
> developer, hence
> they need to be accessible in an installed file. Placing them in
> rte_pmd-ark.h seems
> like the existing solution. If there is a better location or solution
> for publishing these
> definitions, I have not found it yet. Please advise if I should change
> this in some way.
> 

I slightly remember we had same discussion before.

Installed public headers are for application usage, but for ark PMD the header 
is for the PMD extension development. Currently there is no similar usage or 
requirement.

'rte_pmd-ark.h' seems installed last release because of the public object it had 
for dynamic mbuf, which should be accessed by application. Now since those 
objects are gone and the content of the header is changed, it is not for 
applications anymore, hence I think it shouldn't be installed.

As far as I can see the PMD extensions are very much related to the FPGA 
implementation, so the header is not for everyone to use to develop new code, I 
expect whoever needs the 'rte_pmd-ark.h' should have the source code already, 
instead of using the header from installed system path.

I think overall it is good to add doxygen comments and dpdk prefix to the 
extension symbols, but still they shouldn't be part of the API documentation.



^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-10 16:44         ` Ferruh Yigit
@ 2021-03-10 21:53           ` Ed Czeck
  2021-03-10 22:46             ` Ferruh Yigit
  0 siblings, 1 reply; 42+ messages in thread
From: Ed Czeck @ 2021-03-10 21:53 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Shepard Siegel, John Miller, Bruce Richardson

On Wed, Mar 10, 2021 at 11:44 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 3/10/2021 3:02 PM, Ed Czeck wrote:
> > On Tue, Mar 9, 2021 at 12:36 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >>
> >> On 3/9/2021 4:08 PM, Ed Czeck wrote:
> >>> 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
> >>> - Update guide with example of hook function use
> >>> - Add release notes
> >>>
> >>> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> >>> ---
> >>> v3:
> >>> - split function rename to separate commit
> >>>
> >>> v4:
> >>> - reorder patches renaming before adding
> >>
> >> <...>
> >>
> >>> 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;
> >>> -};
> >>>
> >>
> >> Since there is no more public APIs by driver, I think it should stop installing
> >> the header, and remove it from 'meson.build' file, and remove the header from
> >> API documentation, 'doc/api/doxy-api-index.md'.
> >>
> >> I can see the header needs to be used by the extension developer, but that is
> >> still kind of PMD, the public headers are installed for the application developers.
> >>
> >> Still there is a desire to install the required headers for PMD developers, as
> >> far as I know Bruce is working on it, cc'ed. This header can be installed as
> >> part of that effort.
> >>
> >> Thanks,
> >> ferruh
> >
> > The function prototypes in the header are required by the extension
> > developer, hence
> > they need to be accessible in an installed file. Placing them in
> > rte_pmd-ark.h seems
> > like the existing solution. If there is a better location or solution
> > for publishing these
> > definitions, I have not found it yet. Please advise if I should change
> > this in some way.
> >
>
> I slightly remember we had same discussion before.
>
> Installed public headers are for application usage, but for ark PMD the header
> is for the PMD extension development. Currently there is no similar usage or
> requirement.

The extension is part of the application as it executes in the same space and
has access to the same data as the application.
The function definitions are required as a sanity check for the
application, without
them (or with a stale version)  we lose that ability.  The access to
this header file
should be part of DPDK's exported interface, without it there is not a
standard include
location for this file.

>
> 'rte_pmd-ark.h' seems installed last release because of the public object it had
> for dynamic mbuf, which should be accessed by application. Now since those
> objects are gone and the content of the header is changed, it is not for
> applications anymore, hence I think it shouldn't be installed.
>
> As far as I can see the PMD extensions are very much related to the FPGA
> implementation, so the header is not for everyone to use to develop new code, I
> expect whoever needs the 'rte_pmd-ark.h' should have the source code already,
> instead of using the header from installed system path.

The PMD extensions are the bridge between DPDK and the FPGA details; they
are not for everyone. The same argument can be made for the other 12 net drivers
which provide PMD public methods. We are attempting to have a standard way to
access these prototypes for the installed version of DPDK.

>
> I think overall it is good to add doxygen comments and dpdk prefix to the
> extension symbols, but still they shouldn't be part of the API documentation.
>
Please consider my arguments and offer an alternative suggestion on how we can
provide these prototypes to our users.

Thanks,
Ed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-10 21:53           ` Ed Czeck
@ 2021-03-10 22:46             ` Ferruh Yigit
  2021-03-11 13:15               ` Ed Czeck
  0 siblings, 1 reply; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-10 22:46 UTC (permalink / raw)
  To: Ed Czeck; +Cc: dev, Shepard Siegel, John Miller, Bruce Richardson

On 3/10/2021 9:53 PM, Ed Czeck wrote:
> On Wed, Mar 10, 2021 at 11:44 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 3/10/2021 3:02 PM, Ed Czeck wrote:
>>> On Tue, Mar 9, 2021 at 12:36 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>>>
>>>> On 3/9/2021 4:08 PM, Ed Czeck wrote:
>>>>> 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
>>>>> - Update guide with example of hook function use
>>>>> - Add release notes
>>>>>
>>>>> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
>>>>> ---
>>>>> v3:
>>>>> - split function rename to separate commit
>>>>>
>>>>> v4:
>>>>> - reorder patches renaming before adding
>>>>
>>>> <...>
>>>>
>>>>> 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;
>>>>> -};
>>>>>
>>>>
>>>> Since there is no more public APIs by driver, I think it should stop installing
>>>> the header, and remove it from 'meson.build' file, and remove the header from
>>>> API documentation, 'doc/api/doxy-api-index.md'.
>>>>
>>>> I can see the header needs to be used by the extension developer, but that is
>>>> still kind of PMD, the public headers are installed for the application developers.
>>>>
>>>> Still there is a desire to install the required headers for PMD developers, as
>>>> far as I know Bruce is working on it, cc'ed. This header can be installed as
>>>> part of that effort.
>>>>
>>>> Thanks,
>>>> ferruh
>>>
>>> The function prototypes in the header are required by the extension
>>> developer, hence
>>> they need to be accessible in an installed file. Placing them in
>>> rte_pmd-ark.h seems
>>> like the existing solution. If there is a better location or solution
>>> for publishing these
>>> definitions, I have not found it yet. Please advise if I should change
>>> this in some way.
>>>
>>
>> I slightly remember we had same discussion before.
>>
>> Installed public headers are for application usage, but for ark PMD the header
>> is for the PMD extension development. Currently there is no similar usage or
>> requirement.
> 
> The extension is part of the application as it executes in the same space and
> has access to the same data as the application.
> The function definitions are required as a sanity check for the
> application, without
> them (or with a stale version)  we lose that ability.  The access to
> this header file
> should be part of DPDK's exported interface, without it there is not a
> standard include
> location for this file.
> 

I would argue the extension is part of PMD, not part of application.

Extension is loaded by driver dynamically and provides callbacks that is called 
by PMD, transparent to the application.


>>
>> 'rte_pmd-ark.h' seems installed last release because of the public object it had
>> for dynamic mbuf, which should be accessed by application. Now since those
>> objects are gone and the content of the header is changed, it is not for
>> applications anymore, hence I think it shouldn't be installed.
>>
>> As far as I can see the PMD extensions are very much related to the FPGA
>> implementation, so the header is not for everyone to use to develop new code, I
>> expect whoever needs the 'rte_pmd-ark.h' should have the source code already,
>> instead of using the header from installed system path.
> 
> The PMD extensions are the bridge between DPDK and the FPGA details; they
> are not for everyone. The same argument can be made for the other 12 net drivers
> which provide PMD public methods. We are attempting to have a standard way to
> access these prototypes for the installed version of DPDK.
> 

The PMD specific APIs are different, any application developer can be using 
them, if the developer wants the PMD specific feature with the trade of making 
their code non-portable.

The extension callbacks is needed for whoever developing bit-streams for the 
FPGA. Of course the extension developer needs to include the header you are 
providing, but the standard way is for the public APIs not for this case.
Do you expect anyone developing the drivers extensions without having the DPDK 
source code, if not the extension developer can copy the header.

>>
>> I think overall it is good to add doxygen comments and dpdk prefix to the
>> extension symbols, but still they shouldn't be part of the API documentation.
>>
> Please consider my arguments and offer an alternative suggestion on how we can
> provide these prototypes to our users.
> 

As mentioned before there was a request to support out of tree driver support, I 
believe your use case matches more to this request, Bruce was looking to it and 
that solution can be the alternative solution you are looking for.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v4 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-10 22:46             ` Ferruh Yigit
@ 2021-03-11 13:15               ` Ed Czeck
  0 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-11 13:15 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Shepard Siegel, John Miller, Bruce Richardson

On Wed, Mar 10, 2021 at 5:46 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 3/10/2021 9:53 PM, Ed Czeck wrote:
> > On Wed, Mar 10, 2021 at 11:44 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >>
> >> On 3/10/2021 3:02 PM, Ed Czeck wrote:
> >>> On Tue, Mar 9, 2021 at 12:36 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >>>>
> >>>> On 3/9/2021 4:08 PM, Ed Czeck wrote:
> >>>>> 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
> >>>>> - Update guide with example of hook function use
> >>>>> - Add release notes
> >>>>>
> >>>>> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
> >>>>> ---
> >>>>> v3:
> >>>>> - split function rename to separate commit
> >>>>>
> >>>>> v4:
> >>>>> - reorder patches renaming before adding
> >>>>
> >>>> <...>
> >>>>
> >>>> Since there is no more public APIs by driver, I think it should stop installing
> >>>> the header, and remove it from 'meson.build' file, and remove the header from
> >>>> API documentation, 'doc/api/doxy-api-index.md'.
> >>>>
> >>>> I can see the header needs to be used by the extension developer, but that is
> >>>> still kind of PMD, the public headers are installed for the application developers.
> >>>>
> >>>> Still there is a desire to install the required headers for PMD developers, as
> >>>> far as I know Bruce is working on it, cc'ed. This header can be installed as
> >>>> part of that effort.
> >>>>
> >>>> Thanks,
> >>>> ferruh
> >>>
> >>> The function prototypes in the header are required by the extension
> >>> developer, hence
> >>> they need to be accessible in an installed file. Placing them in
> >>> rte_pmd-ark.h seems
> >>> like the existing solution. If there is a better location or solution
> >>> for publishing these
> >>> definitions, I have not found it yet. Please advise if I should change
> >>> this in some way.
> >>>
> >>
> >> I slightly remember we had same discussion before.
> >>
> >> Installed public headers are for application usage, but for ark PMD the header
> >> is for the PMD extension development. Currently there is no similar usage or
> >> requirement.
> >
> > The extension is part of the application as it executes in the same space and
> > has access to the same data as the application.
> > The function definitions are required as a sanity check for the
> > application, without
> > them (or with a stale version)  we lose that ability.  The access to
> > this header file
> > should be part of DPDK's exported interface, without it there is not a
> > standard include
> > location for this file.
> >
>
> I would argue the extension is part of PMD, not part of application.
>
> Extension is loaded by driver dynamically and provides callbacks that is called
> by PMD, transparent to the application.
>
>
> >>
> >> 'rte_pmd-ark.h' seems installed last release because of the public object it had
> >> for dynamic mbuf, which should be accessed by application. Now since those
> >> objects are gone and the content of the header is changed, it is not for
> >> applications anymore, hence I think it shouldn't be installed.
> >>
> >> As far as I can see the PMD extensions are very much related to the FPGA
> >> implementation, so the header is not for everyone to use to develop new code, I
> >> expect whoever needs the 'rte_pmd-ark.h' should have the source code already,
> >> instead of using the header from installed system path.
> >
> > The PMD extensions are the bridge between DPDK and the FPGA details; they
> > are not for everyone. The same argument can be made for the other 12 net drivers
> > which provide PMD public methods. We are attempting to have a standard way to
> > access these prototypes for the installed version of DPDK.
> >
>
> The PMD specific APIs are different, any application developer can be using
> them, if the developer wants the PMD specific feature with the trade of making
> their code non-portable.
>
> The extension callbacks is needed for whoever developing bit-streams for the
> FPGA. Of course the extension developer needs to include the header you are
> providing, but the standard way is for the public APIs not for this case.
> Do you expect anyone developing the drivers extensions without having the DPDK
> source code, if not the extension developer can copy the header.
>
> >>
> >> I think overall it is good to add doxygen comments and dpdk prefix to the
> >> extension symbols, but still they shouldn't be part of the API documentation.
> >>
> > Please consider my arguments and offer an alternative suggestion on how we can
> > provide these prototypes to our users.
> >
>
> As mentioned before there was a request to support out of tree driver support, I
> believe your use case matches more to this request, Bruce was looking to it and
> that solution can be the alternative solution you are looking for.

OK.   I will submit another patch.
Ed.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state
  2021-03-04 16:56 [dpdk-dev] [PATCH v1 1/5] net/ark: update pkt director initial state Ed Czeck
                   ` (6 preceding siblings ...)
  2021-03-09 16:08 ` [dpdk-dev] [PATCH v4 1/6] net/ark: update pkt director initial state Ed Czeck
@ 2021-03-18 17:36 ` Ed Czeck
  2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 2/6] net/ark: refactor Rx buffer recovery Ed Czeck
                     ` (5 more replies)
  7 siblings, 6 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:36 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller, stable

Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c | 1 +
 drivers/net/ark/ark_pktdir.c | 2 +-
 drivers/net/ark/ark_pktdir.h | 2 +-
 3 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index ef650a465..477e1de02 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -321,6 +321,7 @@ eth_ark_dev_init(struct rte_eth_dev *dev)
 	ark->rqpacing =
 		(struct ark_rqpace_t *)(ark->bar0 + ARK_RCPACING_BASE);
 	ark->started = 0;
+	ark->pkt_dir_v = ARK_PKT_DIR_INIT_VAL;
 
 	ARK_PMD_LOG(INFO, "Sys Ctrl Const = 0x%x  HW Commit_ID: %08x\n",
 		      ark->sysctrl.t32[4],
diff --git a/drivers/net/ark/ark_pktdir.c b/drivers/net/ark/ark_pktdir.c
index 25e121831..dbfd2924b 100644
--- a/drivers/net/ark/ark_pktdir.c
+++ b/drivers/net/ark/ark_pktdir.c
@@ -22,7 +22,7 @@ ark_pktdir_init(void *base)
 		return inst;
 	}
 	inst->regs = (struct ark_pkt_dir_regs *)base;
-	inst->regs->ctrl = 0x00110110;	/* POR state */
+	inst->regs->ctrl = ARK_PKT_DIR_INIT_VAL; /* POR state */
 	return inst;
 }
 
diff --git a/drivers/net/ark/ark_pktdir.h b/drivers/net/ark/ark_pktdir.h
index 4afd128f9..b5577cebb 100644
--- a/drivers/net/ark/ark_pktdir.h
+++ b/drivers/net/ark/ark_pktdir.h
@@ -7,7 +7,7 @@
 
 #include <stdint.h>
 
-#define ARK_PKTDIR_BASE_ADR  0xa0000
+#define ARK_PKT_DIR_INIT_VAL 0x0110
 
 typedef void *ark_pkt_dir_t;
 
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 2/6] net/ark: refactor Rx buffer recovery
  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   ` Ed Czeck
  2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 3/6] net/ark: update internal structs to reflect FPGA updates Ed Czeck
                     ` (4 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:36 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller, stable

Allocate mbufs for Rx path in bulk of at least 64 buffers
to improve performance. Allow recovery even without
a Rx operation to support lack of buffers in pool.

Fixes: be410a861598 ("net/ark: add recovery for lack of mbufs")
Cc: stable@dpdk.org

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev_rx.c | 49 ++++++++-------------------------
 1 file changed, 11 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index d29d3db78..8e55b851a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -26,9 +26,6 @@ static uint32_t eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 				 struct rte_mbuf *mbuf0,
 				 uint32_t cons_index);
 static inline int eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue);
-static int eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-				    uint32_t *pnb,
-				    struct rte_mbuf **mbufs);
 
 /* ************************************************************************* */
 struct ark_rx_queue {
@@ -54,7 +51,7 @@ struct ark_rx_queue {
 	/* The queue Index is used within the dpdk device structures */
 	uint16_t queue_index;
 
-	uint32_t last_cons;
+	uint32_t unused;
 
 	/* separate cache line */
 	/* second cache line - fields only used in slow path */
@@ -105,9 +102,8 @@ static inline void
 eth_ark_rx_update_cons_index(struct ark_rx_queue *queue, uint32_t cons_index)
 {
 	queue->cons_index = cons_index;
-	eth_ark_rx_seed_mbufs(queue);
-	if (((cons_index - queue->last_cons) >= 64U)) {
-		queue->last_cons = cons_index;
+	if ((cons_index + queue->queue_size - queue->seed_index) >= 64U) {
+		eth_ark_rx_seed_mbufs(queue);
 		ark_mpu_set_producer(queue->mpu, queue->seed_index);
 	}
 }
@@ -321,9 +317,7 @@ eth_ark_recv_pkts(void *rx_queue,
 			break;
 	}
 
-	if (unlikely(nb != 0))
-		/* report next free to FPGA */
-		eth_ark_rx_update_cons_index(queue, cons_index);
+	eth_ark_rx_update_cons_index(queue, cons_index);
 
 	return nb;
 }
@@ -458,11 +452,13 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	int status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, nb);
 
 	if (unlikely(status != 0)) {
-		/* Try to recover from lack of mbufs in pool */
-		status = eth_ark_rx_seed_recovery(queue, &nb, mbufs);
-		if (unlikely(status != 0)) {
-			return -1;
-		}
+		ARK_PMD_LOG(NOTICE,
+			    "Could not allocate %u mbufs from pool"
+			    " for RX queue %u;"
+			    " %u free buffers remaining in queue\n",
+			    nb, queue->queue_index,
+			    queue->seed_index - queue->cons_index);
+		return -1;
 	}
 
 	if (ARK_DEBUG_CORE) {		/* DEBUG */
@@ -511,29 +507,6 @@ eth_ark_rx_seed_mbufs(struct ark_rx_queue *queue)
 	return 0;
 }
 
-int
-eth_ark_rx_seed_recovery(struct ark_rx_queue *queue,
-			 uint32_t *pnb,
-			 struct rte_mbuf **mbufs)
-{
-	int status = -1;
-
-	/* Ignore small allocation failures */
-	if (*pnb <= 64)
-		return -1;
-
-	*pnb = 64U;
-	status = rte_pktmbuf_alloc_bulk(queue->mb_pool, mbufs, *pnb);
-	if (status != 0) {
-		ARK_PMD_LOG(NOTICE,
-			    "ARK: Could not allocate %u mbufs from pool for RX queue %u;"
-			    " %u free buffers remaining in queue\n",
-			    *pnb, queue->queue_index,
-			    queue->seed_index - queue->cons_index);
-	}
-	return status;
-}
-
 void
 eth_ark_rx_dump_queue(struct rte_eth_dev *dev, uint16_t queue_id,
 		      const char *msg)
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 3/6] net/ark: update internal structs to reflect FPGA updates
  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   ` Ed Czeck
  2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 4/6] net/ark: cleanup ark dynamic extension interface Ed Czeck
                     ` (3 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:36 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller

- New PCIe IDs using net/ark driver
- Update Version IDs and structures specified by hardware
- New internal descriptor status for TX
- Adjust data placement in RX operations, headroom in retained
for segmented mbufs

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 doc/guides/nics/ark.rst         |   5 ++
 drivers/net/ark/ark_ddm.c       |  18 +++--
 drivers/net/ark/ark_ddm.h       |  22 +++---
 drivers/net/ark/ark_ethdev.c    |   5 ++
 drivers/net/ark/ark_ethdev_rx.c |   6 +-
 drivers/net/ark/ark_ethdev_tx.c | 122 +++++++++++++++++++-------------
 drivers/net/ark/ark_udm.c       |   2 +
 drivers/net/ark/ark_udm.h       |  13 ++--
 8 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index 18434c7a4..dcccfee26 100644
--- a/doc/guides/nics/ark.rst
+++ b/doc/guides/nics/ark.rst
@@ -155,6 +155,11 @@ ARK PMD supports the following Arkville RTL PCIe instances including:
 
 * ``1d6c:100d`` - AR-ARKA-FX0 [Arkville 32B DPDK Data Mover]
 * ``1d6c:100e`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover]
+* ``1d6c:100f`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Versal]
+* ``1d6c:1010`` - AR-ARKA-FX1 [Arkville 64B DPDK Data Mover for Agilex]
+* ``1d6c:1017`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Primary Endpoint]
+* ``1d6c:1018`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Secondary Endpoint]
+* ``1d6c:1019`` - AR-ARK-FX1 [Arkville 64B Multi-Homed Tertiary Endpoint]
 
 Supported Operating Systems
 ---------------------------
diff --git a/drivers/net/ark/ark_ddm.c b/drivers/net/ark/ark_ddm.c
index 91d1179d8..232137157 100644
--- a/drivers/net/ark/ark_ddm.c
+++ b/drivers/net/ark/ark_ddm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_ddm.h"
 
+static_assert(sizeof(union ark_tx_meta) == 8, "Unexpected struct size ark_tx_meta");
+
 /* ************************************************************************* */
 int
 ark_ddm_verify(struct ark_ddm_t *ddm)
@@ -19,18 +21,26 @@ ark_ddm_verify(struct ark_ddm_t *ddm)
 	}
 
 	hw_const = ddm->cfg.const0;
+	if (hw_const == ARK_DDM_CONST3)
+		return 0;
+
 	if (hw_const == ARK_DDM_CONST1) {
 		ARK_PMD_LOG(ERR,
 			    "ARK: DDM module is version 1, "
 			    "PMD expects version 2\n");
 		return -1;
-	} else if (hw_const != ARK_DDM_CONST2) {
+	}
+
+	if (hw_const == ARK_DDM_CONST2) {
 		ARK_PMD_LOG(ERR,
-			    "ARK: DDM module not found as expected 0x%08x\n",
-			    ddm->cfg.const0);
+			    "ARK: DDM module is version 2, "
+			    "PMD expects version 3\n");
 		return -1;
 	}
-	return 0;
+	ARK_PMD_LOG(ERR,
+		    "ARK: DDM module not found as expected 0x%08x\n",
+		    ddm->cfg.const0);
+	return -1;
 }
 
 void
diff --git a/drivers/net/ark/ark_ddm.h b/drivers/net/ark/ark_ddm.h
index 5456b4b5c..687ff2519 100644
--- a/drivers/net/ark/ark_ddm.h
+++ b/drivers/net/ark/ark_ddm.h
@@ -16,17 +16,22 @@
  * there is minimal documentation.
  */
 
-/* struct defining Tx meta data --  fixed in FPGA -- 16 bytes */
-struct ark_tx_meta {
+/* struct defining Tx meta data --  fixed in FPGA -- 8 bytes */
+union ark_tx_meta {
 	uint64_t physaddr;
-	uint32_t user1;
-	uint16_t data_len;		/* of this MBUF */
+	struct {
+		uint32_t usermeta0;
+		uint32_t usermeta1;
+	};
+	struct {
+		uint16_t data_len;	/* of this MBUF */
 #define   ARK_DDM_EOP   0x01
 #define   ARK_DDM_SOP   0x02
-	uint8_t flags;		/* bit 0 indicates last mbuf in chain. */
-	uint8_t reserved[1];
-};
-
+		uint8_t  flags;
+		uint8_t  meta_cnt;
+		uint32_t user1;
+	};
+} __rte_packed;
 
 /*
  * DDM core hardware structures
@@ -35,6 +40,7 @@ struct ark_tx_meta {
  */
 #define ARK_DDM_CFG 0x0000
 /* Set unique HW ID for hardware version */
+#define ARK_DDM_CONST3 (0x334d4444)
 #define ARK_DDM_CONST2 (0x324d4444)
 #define ARK_DDM_CONST1 (0xfacecafe)
 
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 477e1de02..95546a891 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -95,6 +95,11 @@ static const char * const valid_arguments[] = {
 static const struct rte_pci_id pci_id_ark_map[] = {
 	{RTE_PCI_DEVICE(0x1d6c, 0x100d)},
 	{RTE_PCI_DEVICE(0x1d6c, 0x100e)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x100f)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1010)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1017)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1018)},
+	{RTE_PCI_DEVICE(0x1d6c, 0x1019)},
 	{.vendor_id = 0, /* sentinel */ },
 };
 
diff --git a/drivers/net/ark/ark_ethdev_rx.c b/drivers/net/ark/ark_ethdev_rx.c
index 8e55b851a..21a9af41a 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -60,7 +60,6 @@ struct ark_rx_queue {
 	volatile uint32_t prod_index;	/* step 2 filled by FPGA */
 } __rte_cache_aligned;
 
-
 /* ************************************************************************* */
 static int
 eth_ark_rx_hw_setup(struct rte_eth_dev *dev,
@@ -265,7 +264,6 @@ eth_ark_recv_pkts(void *rx_queue,
 		/* META DATA embedded in headroom */
 		meta = RTE_PTR_ADD(mbuf->buf_addr, ARK_RX_META_OFFSET);
 
-		mbuf->port = meta->port;
 		mbuf->pkt_len = meta->pkt_len;
 		mbuf->data_len = meta->pkt_len;
 		/* set timestamp if enabled at least on one device */
@@ -346,8 +344,7 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 	/* HW guarantees that the data does not exceed prod_index! */
 	while (remaining != 0) {
 		data_len = RTE_MIN(remaining,
-				   RTE_MBUF_DEFAULT_DATAROOM +
-				   RTE_PKTMBUF_HEADROOM);
+				   RTE_MBUF_DEFAULT_DATAROOM);
 
 		remaining -= data_len;
 		segments += 1;
@@ -356,7 +353,6 @@ eth_ark_rx_jumbo(struct ark_rx_queue *queue,
 		mbuf_prev->next = mbuf;
 		mbuf_prev = mbuf;
 		mbuf->data_len = data_len;
-		mbuf->data_off = 0;
 
 		cons_index += 1;
 	}
diff --git a/drivers/net/ark/ark_ethdev_tx.c b/drivers/net/ark/ark_ethdev_tx.c
index 612d918e3..00e5dbf7c 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2015-2018 Atomic Rules LLC
+ * Copyright (c) 2015-2021 Atomic Rules LLC
  */
 
 #include <unistd.h>
@@ -23,7 +23,7 @@
 
 /* ************************************************************************* */
 struct ark_tx_queue {
-	struct ark_tx_meta *meta_q;
+	union ark_tx_meta *meta_q;
 	struct rte_mbuf **bufs;
 
 	/* handles for hw objects */
@@ -37,8 +37,8 @@ struct ark_tx_queue {
 	uint32_t queue_mask;
 
 	/* 3 indexes to the paired data rings. */
-	uint32_t prod_index;		/* where to put the next one */
-	uint32_t free_index;		/* mbuf has been freed */
+	int32_t prod_index;		/* where to put the next one */
+	int32_t free_index;		/* mbuf has been freed */
 
 	/* The queue Id is used to identify the HW Q */
 	uint16_t phys_qid;
@@ -47,14 +47,15 @@ struct ark_tx_queue {
 
 	uint32_t pad[1];
 
-	/* second cache line - fields only used in slow path */
+	/* second cache line - fields written by device */
 	RTE_MARKER cacheline1 __rte_cache_min_aligned;
-	uint32_t cons_index;		/* hw is done, can be freed */
+	volatile int32_t cons_index;		/* hw is done, can be freed */
 } __rte_cache_aligned;
 
 /* Forward declarations */
-static uint32_t eth_ark_tx_jumbo(struct ark_tx_queue *queue,
-				 struct rte_mbuf *mbuf);
+static int eth_ark_tx_jumbo(struct ark_tx_queue *queue,
+			    struct rte_mbuf *mbuf,
+			    uint32_t *user_meta, uint8_t meta_cnt);
 static int eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue);
 static void free_completed_tx(struct ark_tx_queue *queue);
 
@@ -66,16 +67,44 @@ ark_tx_hw_queue_stop(struct ark_tx_queue *queue)
 
 /* ************************************************************************* */
 static inline void
-eth_ark_tx_meta_from_mbuf(struct ark_tx_meta *meta,
-			  const struct rte_mbuf *mbuf,
-			  uint8_t flags)
+eth_ark_tx_desc_fill(struct ark_tx_queue *queue,
+		     struct rte_mbuf *mbuf,
+		     uint8_t  flags,
+		     uint32_t *user_meta,
+		     uint8_t  meta_cnt /* 0 to 5 */
+		     )
 {
-	meta->physaddr = rte_mbuf_data_iova(mbuf);
-	meta->user1 = rte_pmd_ark_mbuf_tx_userdata_get(mbuf);
+	uint32_t tx_idx;
+	union ark_tx_meta *meta;
+	uint8_t m;
+
+	/* Header */
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
 	meta->data_len = rte_pktmbuf_data_len(mbuf);
 	meta->flags = flags;
+	meta->meta_cnt = meta_cnt / 2;
+	meta->user1 = meta_cnt ? (*user_meta++) : 0;
+	queue->prod_index++;
+
+	queue->bufs[tx_idx] = mbuf;
+
+	/* 1 or 2 user meta data entries, user words 1,2 and 3,4 */
+	for (m = 1; m < meta_cnt; m += 2) {
+		tx_idx = queue->prod_index & queue->queue_mask;
+		meta = &queue->meta_q[tx_idx];
+		meta->usermeta0 = *user_meta++;
+		meta->usermeta1 = *user_meta++;
+		queue->prod_index++;
+	}
+
+	tx_idx = queue->prod_index & queue->queue_mask;
+	meta = &queue->meta_q[tx_idx];
+	meta->physaddr = rte_mbuf_data_iova(mbuf);
+	queue->prod_index++;
 }
 
+
 /* ************************************************************************* */
 uint16_t
 eth_ark_xmit_pkts_noop(void *vtxq __rte_unused,
@@ -91,12 +120,12 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
 	struct ark_tx_queue *queue;
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
+	uint32_t user_meta;
 
-	uint32_t idx;
-	uint32_t prod_index_limit;
 	int stat;
+	int32_t prod_index_limit;
 	uint16_t nb;
+	uint8_t user_len = 1;
 	const uint32_t min_pkt_len = ARK_MIN_TX_PKTLEN;
 
 	queue = (struct ark_tx_queue *)vtxq;
@@ -104,10 +133,11 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 	/* free any packets after the HW is done with them */
 	free_completed_tx(queue);
 
-	prod_index_limit = queue->queue_size + queue->free_index;
+	/* leave 4 elements mpu data */
+	prod_index_limit = queue->queue_size + queue->free_index - 4;
 
 	for (nb = 0;
-	     (nb < nb_pkts) && (queue->prod_index != prod_index_limit);
+	     (nb < nb_pkts) && (prod_index_limit - queue->prod_index) > 0;
 	     ++nb) {
 		mbuf = tx_pkts[nb];
 
@@ -133,19 +163,16 @@ 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 (unlikely(mbuf->nb_segs != 1)) {
-			stat = eth_ark_tx_jumbo(queue, mbuf);
+			stat = eth_ark_tx_jumbo(queue, mbuf,
+						&user_meta, user_len);
 			if (unlikely(stat != 0))
 				break;		/* Queue is full */
 		} else {
-			idx = queue->prod_index & queue->queue_mask;
-			queue->bufs[idx] = mbuf;
-			meta = &queue->meta_q[idx];
-			eth_ark_tx_meta_from_mbuf(meta,
-						  mbuf,
-						  ARK_DDM_SOP |
-						  ARK_DDM_EOP);
-			queue->prod_index++;
+			eth_ark_tx_desc_fill(queue, mbuf,
+					     ARK_DDM_SOP | ARK_DDM_EOP,
+					     &user_meta, user_len);
 		}
 	}
 
@@ -173,32 +200,28 @@ eth_ark_xmit_pkts(void *vtxq, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 }
 
 /* ************************************************************************* */
-static uint32_t
-eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf)
+static int
+eth_ark_tx_jumbo(struct ark_tx_queue *queue, struct rte_mbuf *mbuf,
+		 uint32_t *user_meta, uint8_t meta_cnt)
 {
 	struct rte_mbuf *next;
-	struct ark_tx_meta *meta;
-	uint32_t free_queue_space;
-	uint32_t idx;
+	int32_t free_queue_space;
 	uint8_t flags = ARK_DDM_SOP;
 
 	free_queue_space = queue->queue_mask -
 		(queue->prod_index - queue->free_index);
-	if (unlikely(free_queue_space < mbuf->nb_segs))
+	/* We need up to 4 mbufs for first header and 2 for subsequent ones */
+	if (unlikely(free_queue_space < (2 + (2 * mbuf->nb_segs))))
 		return -1;
 
 	while (mbuf != NULL) {
 		next = mbuf->next;
-
-		idx = queue->prod_index & queue->queue_mask;
-		queue->bufs[idx] = mbuf;
-		meta = &queue->meta_q[idx];
-
 		flags |= (next == NULL) ? ARK_DDM_EOP : 0;
-		eth_ark_tx_meta_from_mbuf(meta, mbuf, flags);
-		queue->prod_index++;
+
+		eth_ark_tx_desc_fill(queue, mbuf, flags, user_meta, meta_cnt);
 
 		flags &= ~ARK_DDM_SOP;	/* drop SOP flags */
+		meta_cnt = 0;		/* Meta only on SOP */
 		mbuf = next;
 	}
 
@@ -227,6 +250,9 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 		return -1;
 	}
 
+	/* Each packet requires at least 2 mpu elements - double desc count */
+	nb_desc = 2 * nb_desc;
+
 	/* Allocate queue struct */
 	queue =	rte_zmalloc_socket("Ark_txqueue",
 				   sizeof(struct ark_tx_queue),
@@ -248,7 +274,7 @@ eth_ark_tx_queue_setup(struct rte_eth_dev *dev,
 
 	queue->meta_q =
 		rte_zmalloc_socket("Ark_txqueue meta",
-				   nb_desc * sizeof(struct ark_tx_meta),
+				   nb_desc * sizeof(union ark_tx_meta),
 				   64,
 				   socket_id);
 	queue->bufs =
@@ -289,7 +315,7 @@ eth_ark_tx_hw_queue_config(struct ark_tx_queue *queue)
 	uint32_t write_interval_ns;
 
 	/* Verify HW -- MPU */
-	if (ark_mpu_verify(queue->mpu, sizeof(struct ark_tx_meta)))
+	if (ark_mpu_verify(queue->mpu, sizeof(union ark_tx_meta)))
 		return -1;
 
 	queue_base = rte_malloc_virt2iova(queue);
@@ -391,19 +417,19 @@ static void
 free_completed_tx(struct ark_tx_queue *queue)
 {
 	struct rte_mbuf *mbuf;
-	struct ark_tx_meta *meta;
-	uint32_t top_index;
+	union ark_tx_meta *meta;
+	int32_t top_index;
 
 	top_index = queue->cons_index;	/* read once */
-	while (queue->free_index != top_index) {
+	while ((top_index - queue->free_index) > 0) {
 		meta = &queue->meta_q[queue->free_index & queue->queue_mask];
-		mbuf = queue->bufs[queue->free_index & queue->queue_mask];
-
 		if (likely((meta->flags & ARK_DDM_SOP) != 0)) {
+			mbuf = queue->bufs[queue->free_index &
+					   queue->queue_mask];
 			/* ref count of the mbuf is checked in this call. */
 			rte_pktmbuf_free(mbuf);
 		}
-		queue->free_index++;
+		queue->free_index += (meta->meta_cnt + 2);
 	}
 }
 
diff --git a/drivers/net/ark/ark_udm.c b/drivers/net/ark/ark_udm.c
index a740d36d4..28c4500a2 100644
--- a/drivers/net/ark/ark_udm.c
+++ b/drivers/net/ark/ark_udm.c
@@ -7,6 +7,8 @@
 #include "ark_logs.h"
 #include "ark_udm.h"
 
+static_assert(sizeof(struct ark_rx_meta) == 32, "Unexpected struct size ark_rx_meta");
+
 int
 ark_udm_verify(struct ark_udm_t *udm)
 {
diff --git a/drivers/net/ark/ark_udm.h b/drivers/net/ark/ark_udm.h
index 5846c825b..ea92d4b6e 100644
--- a/drivers/net/ark/ark_udm.h
+++ b/drivers/net/ark/ark_udm.h
@@ -15,14 +15,15 @@
  * there is minimal documentation.
  */
 
-/* Meta data structure apssed from FPGA, must match layout in FPGA */
+/* Meta data structure passed from FPGA, must match layout in FPGA
+ * -- 32 bytes
+ */
 struct ark_rx_meta {
 	uint64_t timestamp;
 	uint64_t user_data;
-	uint8_t port;
-	uint8_t dst_queue;
+	uint8_t  reserved[14];
 	uint16_t pkt_len;
-};
+} __rte_packed;
 
 /*
  * UDM hardware structures
@@ -32,7 +33,9 @@ struct ark_rx_meta {
 
 #define ARK_RX_WRITE_TIME_NS 2500
 #define ARK_UDM_SETUP 0
-#define ARK_UDM_CONST 0xbACECACE
+#define ARK_UDM_CONST2 0xbACECACE
+#define ARK_UDM_CONST3 0x334d4455
+#define ARK_UDM_CONST ARK_UDM_CONST3
 struct ark_udm_setup_t {
 	uint32_t r0;
 	uint32_t r4;
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 4/6] net/ark: cleanup ark dynamic extension interface
  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   ` Ed Czeck
  2021-03-18 17:36   ` [dpdk-dev] [PATCH v5 5/6] net/ark: generalize meta data between FPGA and PMD Ed Czeck
                     ` (2 subsequent siblings)
  5 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:36 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller

- Rename extension functions with rte_pmd_ark prefix
- Update local function documentation

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename from previous commit
v4:
- reorder patches renaming before adding
v5:
- Keep the extension function changes in ark_ext.h
---
 drivers/net/ark/ark_ethdev.c |  32 ++--
 drivers/net/ark/ark_ext.h    | 304 ++++++++++++++++++++++++++---------
 2 files changed, 247 insertions(+), 89 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 95546a891..5282534d3 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -193,58 +193,58 @@ 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");
 
 	return found;
 }
diff --git a/drivers/net/ark/ark_ext.h b/drivers/net/ark/ark_ext.h
index 821fb55bb..9c7d55a14 100644
--- a/drivers/net/ark/ark_ext.h
+++ b/drivers/net/ark/ark_ext.h
@@ -7,84 +7,242 @@
 
 #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.
+/* 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 prototypes in this
+ * section are optional.
+ * See documentation for compiling and use of extensions.
  */
 
-/*
- * 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
+/**
+ * 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 *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.
+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.
  */
-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.
+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 macaddr
+ *   The MAC address to add
+ * @param index
+ *   The index into the MAC address array.
+ * @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 *macaddr,
+			      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 index
+ *   The index into the MAC address array.
+ * @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);
 
-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
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 5/6] net/ark: generalize meta data between FPGA and PMD
  2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (2 preceding siblings ...)
  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   ` 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
  5 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:36 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller

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
- Remove emptied rte_pmd_ark.h
- Hook function added to ark_user_ext
- Add hook function calls in Rx and Tx paths
- Update guide with example of hook function use
- Add release notes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
v3:
- split function rename to separate commit
v4:
- reorder patches renaming before adding
v5:
- remove rte_pmd_ark.h
---
 doc/api/doxy-api-index.md              |   1 -
 doc/guides/nics/ark.rst                | 139 ++++++++++++++++++++++++-
 doc/guides/rel_notes/release_21_05.rst |  11 ++
 drivers/net/ark/ark_ethdev.c           |  59 ++---------
 drivers/net/ark/ark_ethdev_rx.c        |  28 +++--
 drivers/net/ark/ark_ethdev_rx.h        |   3 -
 drivers/net/ark/ark_ethdev_tx.c        |  24 +++--
 drivers/net/ark/ark_ext.h              |  38 +++++++
 drivers/net/ark/ark_global.h           |  20 ++++
 drivers/net/ark/ark_udm.h              |   5 +-
 drivers/net/ark/meson.build            |   2 -
 drivers/net/ark/rte_pmd_ark.h          | 125 ----------------------
 drivers/net/ark/version.map            |   7 --
 13 files changed, 248 insertions(+), 214 deletions(-)
 delete mode 100644 drivers/net/ark/rte_pmd_ark.h

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 748514e24..66572a75f 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -41,7 +41,6 @@ The public API headers are grouped by topics:
   [vhost]              (@ref rte_vhost.h),
   [vdpa]               (@ref rte_vdpa.h),
   [KNI]                (@ref rte_kni.h),
-  [ark]                (@ref rte_pmd_ark.h),
   [ixgbe]              (@ref rte_pmd_ixgbe.h),
   [i40e]               (@ref rte_pmd_i40e.h),
   [ice]                (@ref rte_pmd_ice.h),
diff --git a/doc/guides/nics/ark.rst b/doc/guides/nics/ark.rst
index dcccfee26..da61814b5 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
+``ark_ext.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 <ark_ext.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
 -------------
 
@@ -144,6 +279,8 @@ documentation that comes with DPDK suite <linux_gsg>`.
 To build with a non-zero minimum tx packet length, set the above macro in your
 CFLAGS environment prior to the meson build step. I.e.,
 
+.. code-block:: console
+
     export CFLAGS="-DRTE_LIBRTE_ARK_MIN_TX_PKTLEN=60"
     meson build
 
diff --git a/doc/guides/rel_notes/release_21_05.rst b/doc/guides/rel_notes/release_21_05.rst
index 5aa9ed7db..4789bf782 100644
--- a/doc/guides/rel_notes/release_21_05.rst
+++ b/doc/guides/rel_notes/release_21_05.rst
@@ -55,6 +55,17 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Updated Arkville PMD driver.**
+
+  Updated Arkville net driver with new features and improvements, including:
+
+  * Generalized passing meta data between PMD and FPGA, allowing up to 20
+    bytes of user specified information in RX and TX paths.
+
+  * Updated dynamic PMD extensions API using standardized names.
+
+  * Added support for new Atomic Rules PCI device IDs ``0x100f, 0x1010, 0x1017,
+    0x1018, 0x1019``.
 
 Removed Items
 -------------
diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index 5282534d3..dea779a98 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -10,7 +10,6 @@
 #include <ethdev_pci.h>
 #include <rte_kvargs.h>
 
-#include "rte_pmd_ark.h"
 #include "ark_global.h"
 #include "ark_logs.h"
 #include "ark_ethdev_tx.h"
@@ -79,12 +78,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,
@@ -245,6 +238,12 @@ check_for_ext(struct ark_adapter *ark)
 		(int (*)(struct rte_eth_dev *, uint16_t,
 			  void *))
 		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;
 }
@@ -257,16 +256,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;
 
@@ -277,30 +266,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;
@@ -561,18 +526,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..d255f0177 100644
--- a/drivers/net/ark/ark_ethdev_rx.c
+++ b/drivers/net/ark/ark_ethdev_rx.c
@@ -4,7 +4,6 @@
 
 #include <unistd.h>
 
-#include "rte_pmd_ark.h"
 #include "ark_ethdev_rx.h"
 #include "ark_global.h"
 #include "ark_logs.h"
@@ -39,6 +38,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 +55,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 +168,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 +246,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 +259,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 +274,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 +316,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..676e4115d 100644
--- a/drivers/net/ark/ark_ethdev_tx.c
+++ b/drivers/net/ark/ark_ethdev_tx.c
@@ -4,7 +4,6 @@
 
 #include <unistd.h>
 
-#include "rte_pmd_ark.h"
 #include "ark_ethdev_tx.h"
 #include "ark_global.h"
 #include "ark_mpu.h"
@@ -33,6 +32,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 +47,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 +120,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 +165,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 +275,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
index 9c7d55a14..d235d0ff8 100644
--- a/drivers/net/ark/ark_ext.h
+++ b/drivers/net/ark/ark_ext.h
@@ -244,5 +244,43 @@ int rte_pmd_ark_set_mtu(struct rte_eth_dev *dev,
 			uint16_t size,
 			void *user_data);
 
+/**
+ * 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. The
+ *   underlying data in the PMD is of type uint32_t meta[5];
+ * @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);
+
+/**
+ * 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. The
+ *   underlying in the PMD is of type uint32_t meta[5];
+ * @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
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/meson.build b/drivers/net/ark/meson.build
index aea3ba493..91e8c0dda 100644
--- a/drivers/net/ark/meson.build
+++ b/drivers/net/ark/meson.build
@@ -7,8 +7,6 @@ if is_windows
 	subdir_done()
 endif
 
-headers = files('rte_pmd_ark.h')
-
 sources = files('ark_ddm.c',
 	'ark_ethdev.c',
 	'ark_ethdev_rx.c',
diff --git a/drivers/net/ark/rte_pmd_ark.h b/drivers/net/ark/rte_pmd_ark.h
deleted file mode 100644
index 6f26d66b1..000000000
--- a/drivers/net/ark/rte_pmd_ark.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2020 Atomic Rules LLC
- */
-
-#ifndef RTE_PMD_ARK_H
-#define RTE_PMD_ARK_H
-
-/**
- * @file
- * ARK driver-specific API
- */
-
-#include <rte_mbuf.h>
-#include <rte_mbuf_dyn.h>
-
-#ifndef RTE_PMD_ARK_TX_USERDATA_ENABLE
-#define RTE_PMD_ARK_TX_USERDATA_ENABLE 0
-#endif
-
-#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
-}
-
-#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


^ permalink raw reply	[flat|nested] 42+ messages in thread

* [dpdk-dev] [PATCH v5 6/6] net/ark: localize internal packet generator code
  2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (3 preceding siblings ...)
  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   ` Ed Czeck
  2021-03-22 15:59   ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ferruh Yigit
  5 siblings, 0 replies; 42+ messages in thread
From: Ed Czeck @ 2021-03-18 17:37 UTC (permalink / raw)
  To: dev, ferruh.yigit, bruce.richardson; +Cc: shepard.siegel, john.miller

remove unnecessary includes
no functional changes

Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>
---
 drivers/net/ark/ark_ethdev.c  | 17 ++---------------
 drivers/net/ark/ark_pktchkr.c |  4 ----
 drivers/net/ark/ark_pktgen.c  | 20 ++++++++++++++------
 drivers/net/ark/ark_pktgen.h  |  1 +
 4 files changed, 17 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ark/ark_ethdev.c b/drivers/net/ark/ark_ethdev.c
index dea779a98..9dea5facb 100644
--- a/drivers/net/ark/ark_ethdev.c
+++ b/drivers/net/ark/ark_ethdev.c
@@ -534,20 +534,6 @@ eth_ark_dev_configure(struct rte_eth_dev *dev)
 	return 0;
 }
 
-static void *
-delay_pg_start(void *arg)
-{
-	struct ark_adapter *ark = (struct ark_adapter *)arg;
-
-	/* This function is used exclusively for regression testing, We
-	 * perform a blind sleep here to ensure that the external test
-	 * application has time to setup the test before we generate packets
-	 */
-	usleep(100000);
-	ark_pktgen_run(ark->pg);
-	return NULL;
-}
-
 static int
 eth_ark_dev_start(struct rte_eth_dev *dev)
 {
@@ -582,7 +568,8 @@ eth_ark_dev_start(struct rte_eth_dev *dev)
 		/* Delay packet generatpr start allow the hardware to be ready
 		 * This is only used for sanity checking with internal generator
 		 */
-		if (pthread_create(&thread, NULL, delay_pg_start, ark)) {
+		if (pthread_create(&thread, NULL,
+				   ark_pktgen_delay_start, ark->pg)) {
 			ARK_PMD_LOG(ERR, "Could not create pktgen "
 				    "starter thread\n");
 			return -1;
diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index 0f2d31e5b..84bb567a4 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -2,13 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktchkr.h"
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index ac4322a35..28a44f754 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -2,15 +2,9 @@
  * Copyright (c) 2015-2018 Atomic Rules LLC
  */
 
-#include <getopt.h>
-#include <sys/time.h>
-#include <locale.h>
 #include <unistd.h>
 
 #include <rte_string_fns.h>
-#include <rte_eal.h>
-
-#include <ethdev_driver.h>
 #include <rte_malloc.h>
 
 #include "ark_pktgen.h"
@@ -470,3 +464,17 @@ ark_pktgen_setup(ark_pkt_gen_t handle)
 		ark_pktgen_run(handle);
 	}
 }
+
+void *
+ark_pktgen_delay_start(void *arg)
+{
+	struct ark_pkt_gen_inst *inst = (struct ark_pkt_gen_inst *)arg;
+
+	/* This function is used exclusively for regression testing, We
+	 * perform a blind sleep here to ensure that the external test
+	 * application has time to setup the test before we generate packets
+	 */
+	usleep(100000);
+	ark_pktgen_run(inst);
+	return NULL;
+}
diff --git a/drivers/net/ark/ark_pktgen.h b/drivers/net/ark/ark_pktgen.h
index c61dfee6d..7147fe1bd 100644
--- a/drivers/net/ark/ark_pktgen.h
+++ b/drivers/net/ark/ark_pktgen.h
@@ -75,5 +75,6 @@ void ark_pktgen_set_hdr_dW(ark_pkt_gen_t handle, uint32_t *hdr);
 void ark_pktgen_set_start_offset(ark_pkt_gen_t handle, uint32_t x);
 void ark_pktgen_parse(char *argv);
 void ark_pktgen_setup(ark_pkt_gen_t handle);
+void *ark_pktgen_delay_start(void *arg);
 
 #endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state
  2021-03-18 17:36 ` [dpdk-dev] [PATCH v5 1/6] net/ark: update pkt director initial state Ed Czeck
                     ` (4 preceding siblings ...)
  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   ` Ferruh Yigit
  5 siblings, 0 replies; 42+ messages in thread
From: Ferruh Yigit @ 2021-03-22 15:59 UTC (permalink / raw)
  To: Ed Czeck, dev, bruce.richardson; +Cc: shepard.siegel, john.miller, stable

On 3/18/2021 5:36 PM, Ed Czeck wrote:
> Fixes: b33ccdb17f55 ("net/ark: provide API for hardware modules MPU RQP and pktdir")
> Cc: stable@dpdk.org
> 
> Signed-off-by: Ed Czeck <ed.czeck@atomicrules.com>

Series applied to dpdk-next-net/main, thanks.


Release note updates distributed into relevant patches while merging.

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2021-03-22 16:00 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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   ` [dpdk-dev] [PATCH v2 4/5] net/ark: generalize meta data between FPGA and PMD Ed Czeck
2021-03-05 15:31     ` 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

DPDK patches and discussions

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://inbox.dpdk.org/dev/0 dev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dev dev/ https://inbox.dpdk.org/dev \
		dev@dpdk.org
	public-inbox-index dev

Example config snippet for mirrors.
Newsgroup available over NNTP:
	nntp://inbox.dpdk.org/inbox.dpdk.dev


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git