[dpdk-dev] [PATCH v2] drivers/net/nfb: add timestamp support
Rastislav Cernay
cernay at netcope.com
Tue Jul 2 12:32:57 CEST 2019
From: Rastislav Cernay <cernay at netcope.com>
This patch adds timestamping support to nfb driver.
Signed-off-by: Rastislav Cernay <cernay at netcope.com>
---
v2: rewrite timestamp enable to devargs
doc/guides/nics/nfb.rst | 19 +++++++++++++++++++
drivers/net/nfb/nfb_rx.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/nfb/nfb_rx.h | 21 +++++++++++++++++++++
3 files changed, 89 insertions(+)
diff --git a/doc/guides/nics/nfb.rst b/doc/guides/nics/nfb.rst
index 8df76c0..6258fd7 100644
--- a/doc/guides/nics/nfb.rst
+++ b/doc/guides/nics/nfb.rst
@@ -142,3 +142,22 @@ Example output:
TX threshold registers: pthresh=0 hthresh=0 wthresh=0
TX RS bit threshold=0 - TXQ flags=0x0
testpmd>
+
+Timestamp
+----------------
+
+The PMD supports hardware timestamps of frame receipt on physical network interface. In order to use
+the timestamps, the hardware timestamping unit must be enabled (follow the documentation of the NFB
+products) and the device argument `timestamp=1` must be used.
+
+.. code-block:: console
+
+ $RTE_TARGET/app/testpmd -w b3:00.0,timestamp=1 <other EAL params> -- <testpmd params>
+
+When the timestamps are enabled with the *devarg*, a timestamp validity flag is set in the MBUFs
+containing received frames and timestamp is inserted into the `rte_mbuf` struct.
+
+The timestamp is an `uint64_t` field. Its lower 32 bits represent *seconds* portion of the timestamp
+(number of seconds elapsed since 1.1.1970 00:00:00 UTC) and its higher 32 bits represent
+*nanosecond* portion of the timestamp (number of nanoseconds elapsed since the beginning of the
+second in the *seconds* portion.
diff --git a/drivers/net/nfb/nfb_rx.c b/drivers/net/nfb/nfb_rx.c
index 9147b00..805d893 100644
--- a/drivers/net/nfb/nfb_rx.c
+++ b/drivers/net/nfb/nfb_rx.c
@@ -4,9 +4,53 @@
* All rights reserved.
*/
+#include <rte_kvargs.h>
+
#include "nfb_rx.h"
#include "nfb.h"
+
+static int
+timestamp_check_handler(__rte_unused const char *key,
+ const char *value, __rte_unused void *opaque)
+{
+ if (strcmp(value, "1"))
+ return -1;
+
+ return 0;
+}
+
+
+static int
+nfb_check_timestamp(struct rte_devargs *devargs)
+{
+ struct rte_kvargs *kvlist;
+ const char *timestamp_key = "timestamp";
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+
+ if (!rte_kvargs_count(kvlist, timestamp_key)) {
+ rte_kvargs_free(kvlist);
+ return 0;
+ }
+ /* Timestamps are enabled when there is
+ * key-value pair: enable_timestamp=1
+ */
+ if (rte_kvargs_process(kvlist, timestamp_key,
+ timestamp_check_handler, NULL) < 0) {
+ rte_kvargs_free(kvlist);
+ return 0;
+ }
+ rte_kvargs_free(kvlist);
+
+ return 1;
+}
+
int
nfb_eth_rx_queue_start(struct rte_eth_dev *dev, uint16_t rxq_id)
{
@@ -70,6 +114,8 @@
return -ENOMEM;
}
+ rxq->flags = 0;
+
ret = nfb_eth_rx_queue_init(internals->nfb,
rx_queue_id,
dev->data->port_id,
@@ -81,6 +127,9 @@
else
rte_free(rxq);
+ if (nfb_check_timestamp(dev->device->devargs))
+ rxq->flags |= NFB_TIMESTAMP_FLAG;
+
return ret;
}
diff --git a/drivers/net/nfb/nfb_rx.h b/drivers/net/nfb/nfb_rx.h
index 88a0307..cf3899b 100644
--- a/drivers/net/nfb/nfb_rx.h
+++ b/drivers/net/nfb/nfb_rx.h
@@ -13,11 +13,14 @@
#include <rte_mbuf.h>
#include <rte_ethdev.h>
+#define NFB_TIMESTAMP_FLAG (1 << 0)
+
struct ndp_rx_queue {
struct nfb_device *nfb; /* nfb dev structure */
struct ndp_queue *queue; /* rx queue */
uint16_t rx_queue_id; /* index */
uint8_t in_port; /* port */
+ uint8_t flags; /* setup flags */
struct rte_mempool *mb_pool; /* memory pool to allocate packets */
uint16_t buf_size; /* mbuf size */
@@ -129,6 +132,7 @@ struct ndp_rx_queue {
uint16_t nb_pkts)
{
struct ndp_rx_queue *ndp = queue;
+ uint8_t timestamping_enabled;
uint16_t packet_size;
uint64_t num_bytes = 0;
uint16_t num_rx;
@@ -146,6 +150,8 @@ struct ndp_rx_queue {
return 0;
}
+ timestamping_enabled = ndp->flags & NFB_TIMESTAMP_FLAG;
+
/* returns either all or nothing */
i = rte_pktmbuf_alloc_bulk(ndp->mb_pool, mbufs, nb_pkts);
if (unlikely(i != 0))
@@ -181,6 +187,21 @@ struct ndp_rx_queue {
mbuf->pkt_len = packet_size;
mbuf->port = ndp->in_port;
+ mbuf->ol_flags = 0;
+
+ if (timestamping_enabled) {
+ /* nanoseconds */
+ mbuf->timestamp =
+ rte_le_to_cpu_32(*((uint32_t *)
+ (packets[i].header + 4)));
+ mbuf->timestamp <<= 32;
+ /* seconds */
+ mbuf->timestamp |=
+ rte_le_to_cpu_32(*((uint32_t *)
+ (packets[i].header + 8)));
+ mbuf->ol_flags |= PKT_RX_TIMESTAMP;
+ }
+
bufs[num_rx++] = mbuf;
num_bytes += packet_size;
} else {
--
1.8.3.1
More information about the dev
mailing list