* Re: [dpdk-dev] [PATCH] drivers/net/nfb: add timestamp support
2019-06-13 12:05 [dpdk-dev] [PATCH] drivers/net/nfb: add timestamp support Rastislav Cernay
@ 2019-06-27 15:45 ` Ferruh Yigit
2019-06-28 14:12 ` Jan Remeš
2019-07-02 10:32 ` [dpdk-dev] [PATCH v2] " Rastislav Cernay
2019-07-15 12:03 ` [dpdk-dev] [PATCH v3] " Rastislav Cernay
2 siblings, 1 reply; 7+ messages in thread
From: Ferruh Yigit @ 2019-06-27 15:45 UTC (permalink / raw)
To: Rastislav Cernay, dev; +Cc: remes
On 6/13/2019 1:05 PM, Rastislav Cernay wrote:
> From: Rastislav Cernay <cernay@netcope.com>
>
> This patch adds timestamping support to nfb driver.
>
> Signed-off-by: Rastislav Cernay <cernay@netcope.com>
> ---
> config/common_base | 1 +
> doc/guides/nics/nfb.rst | 22 ++++++++++++++++++++++
> drivers/net/nfb/Makefile | 5 +++++
> drivers/net/nfb/meson.build | 4 ++++
> drivers/net/nfb/nfb_rx.h | 13 +++++++++++++
> 5 files changed, 45 insertions(+)
>
> diff --git a/config/common_base b/config/common_base
> index 6f19ad5..f533136 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -383,6 +383,7 @@ CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
> # Compile software PMD backed by NFB device
> #
> CONFIG_RTE_LIBRTE_NFB_PMD=n
> +CONFIG_RTE_LIBRTE_NFB_HW_TIMESTAMP=n
>
> #
> # Compile burst-oriented Cavium Thunderx NICVF PMD driver
> diff --git a/doc/guides/nics/nfb.rst b/doc/guides/nics/nfb.rst
> index 8df76c0..a172f9a 100644
> --- a/doc/guides/nics/nfb.rst
> +++ b/doc/guides/nics/nfb.rst
> @@ -69,6 +69,10 @@ These configuration options can be modified before compilation in the
>
> Value **y** enables compilation of nfb PMD.
>
> +* ``CONFIG_RTE_LIBRTE_NFB_HW_TIMESTAMP`` default value: **n**
> +
> + Value **y** enables HW packet timestamping.
> +
> Using the NFB PMD
> ----------------------
>
> @@ -142,3 +146,21 @@ Example output:
> TX threshold registers: pthresh=0 hthresh=0 wthresh=0
> TX RS bit threshold=0 - TXQ flags=0x0
> testpmd>
> +
> +Timestamp
> +----------------
> +
> +Timestamping needs to be enabled during compile time, as there is no way
> +to check whether a timestamping unit is runnig during run time.
Even if this can't be detected on runtime, it should be possible to configure in
runtime with device args so need to compile the PMD again to change the behavior.
In this patch default behavior is no timestamps support, same can be done with
devargs, without any devargs timestamp support disable, but if user provides a
devarg, like "timestamp=1", feature enabled.
What do you think, can it be possible to convert runtime configuration?
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v2] drivers/net/nfb: add timestamp support
2019-06-13 12:05 [dpdk-dev] [PATCH] drivers/net/nfb: add timestamp support Rastislav Cernay
2019-06-27 15:45 ` Ferruh Yigit
@ 2019-07-02 10:32 ` Rastislav Cernay
2019-07-03 11:55 ` Ferruh Yigit
2019-07-15 12:03 ` [dpdk-dev] [PATCH v3] " Rastislav Cernay
2 siblings, 1 reply; 7+ messages in thread
From: Rastislav Cernay @ 2019-07-02 10:32 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Rastislav Cernay
From: Rastislav Cernay <cernay@netcope.com>
This patch adds timestamping support to nfb driver.
Signed-off-by: Rastislav Cernay <cernay@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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v3] drivers/net/nfb: add timestamp support
2019-06-13 12:05 [dpdk-dev] [PATCH] drivers/net/nfb: add timestamp support Rastislav Cernay
2019-06-27 15:45 ` Ferruh Yigit
2019-07-02 10:32 ` [dpdk-dev] [PATCH v2] " Rastislav Cernay
@ 2019-07-15 12:03 ` Rastislav Cernay
2019-07-15 13:08 ` Ferruh Yigit
2 siblings, 1 reply; 7+ messages in thread
From: Rastislav Cernay @ 2019-07-15 12:03 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit, Rastislav Cernay
From: Rastislav Cernay <cernay@netcope.com>
This patch adds timestamping support to nfb driver.
Signed-off-by: Rastislav Cernay <cernay@netcope.com>
---
v2: rewrite timestamp enable to devargs
v3: check valid devargs
move timestamp part of doc to configuration
fix shared build
doc/guides/nics/nfb.rst | 20 +++++++++++++++++++
drivers/net/nfb/Makefile | 2 +-
drivers/net/nfb/nfb.h | 4 ++++
drivers/net/nfb/nfb_ethdev.c | 18 +++++++++++++++++
drivers/net/nfb/nfb_rx.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
drivers/net/nfb/nfb_rx.h | 21 ++++++++++++++++++++
6 files changed, 111 insertions(+), 1 deletion(-)
diff --git a/doc/guides/nics/nfb.rst b/doc/guides/nics/nfb.rst
index 8df76c0..0e36c7e 100644
--- a/doc/guides/nics/nfb.rst
+++ b/doc/guides/nics/nfb.rst
@@ -69,6 +69,26 @@ These configuration options can be modified before compilation in the
Value **y** enables compilation of nfb PMD.
+
+Timestamps
+
+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.
+
+
Using the NFB PMD
----------------------
diff --git a/drivers/net/nfb/Makefile b/drivers/net/nfb/Makefile
index a84b423..8bba2ac 100644
--- a/drivers/net/nfb/Makefile
+++ b/drivers/net/nfb/Makefile
@@ -16,7 +16,7 @@ INCLUDES :=-I$(SRCDIR)
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
CFLAGS += $(shell command -v pkg-config > /dev/null 2>&1 && pkg-config --cflags netcope-common)
-LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_kvargs
LDLIBS += -lrte_ethdev -lrte_net
LDLIBS += -lrte_bus_pci
LDLIBS += $(shell command -v pkg-config > /dev/null 2>&1 && pkg-config --libs netcope-common)
diff --git a/drivers/net/nfb/nfb.h b/drivers/net/nfb/nfb.h
index 9d477ba..59d3ab4 100644
--- a/drivers/net/nfb/nfb.h
+++ b/drivers/net/nfb/nfb.h
@@ -36,6 +36,10 @@
#define RTE_NFB_DRIVER_NAME net_nfb
+/* Device arguments */
+#define TIMESTAMP_ARG "timestamp"
+static const char * const VALID_KEYS[] = {TIMESTAMP_ARG, NULL};
+
struct pmd_internals {
uint16_t max_rxmac;
uint16_t max_txmac;
diff --git a/drivers/net/nfb/nfb_ethdev.c b/drivers/net/nfb/nfb_ethdev.c
index 7782195..ff2e5c7 100644
--- a/drivers/net/nfb/nfb_ethdev.c
+++ b/drivers/net/nfb/nfb_ethdev.c
@@ -10,6 +10,7 @@
#include <netcope/txmac.h>
#include <rte_ethdev_pci.h>
+#include <rte_kvargs.h>
#include "nfb_stats.h"
#include "nfb_rx.h"
@@ -419,6 +420,7 @@
struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev);
struct rte_pci_addr *pci_addr = &pci_dev->addr;
struct rte_ether_addr eth_addr_init;
+ struct rte_kvargs *kvlist;
RTE_LOG(INFO, PMD, "Initializing NFB device (" PCI_PRI_FMT ")\n",
pci_addr->domain, pci_addr->bus, pci_addr->devid,
@@ -429,6 +431,21 @@
pci_addr->domain, pci_addr->bus, pci_addr->devid,
pci_addr->function);
+ /* Check validity of device args */
+ if (dev->device->devargs != NULL &&
+ dev->device->devargs->args != NULL &&
+ strlen(dev->device->devargs->args) > 0) {
+ kvlist = rte_kvargs_parse(dev->device->devargs->args,
+ VALID_KEYS);
+ if (kvlist == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to parse device arguments %s",
+ dev->device->devargs->args);
+ rte_kvargs_free(kvlist);
+ return -EINVAL;
+ }
+ rte_kvargs_free(kvlist);
+ }
+
/*
* Get number of available DMA RX and TX queues, which is maximum
* number of queues that can be created and store it in private device
@@ -579,3 +596,4 @@
RTE_PMD_REGISTER_PCI(RTE_NFB_DRIVER_NAME, nfb_eth_driver);
RTE_PMD_REGISTER_PCI_TABLE(RTE_NFB_DRIVER_NAME, nfb_pci_id_table);
RTE_PMD_REGISTER_KMOD_DEP(RTE_NFB_DRIVER_NAME, "* nfb");
+RTE_PMD_REGISTER_PARAM_STRING(RTE_NFB_DRIVER_NAME, TIMESTAMP_ARG "=<0|1>");
diff --git a/drivers/net/nfb/nfb_rx.c b/drivers/net/nfb/nfb_rx.c
index 9147b00..d97179f 100644
--- a/drivers/net/nfb/nfb_rx.c
+++ b/drivers/net/nfb/nfb_rx.c
@@ -4,9 +4,51 @@
* 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;
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+
+ if (!rte_kvargs_count(kvlist, TIMESTAMP_ARG)) {
+ rte_kvargs_free(kvlist);
+ return 0;
+ }
+ /* Timestamps are enabled when there is
+ * key-value pair: enable_timestamp=1
+ */
+ if (rte_kvargs_process(kvlist, TIMESTAMP_ARG,
+ 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 +112,8 @@
return -ENOMEM;
}
+ rxq->flags = 0;
+
ret = nfb_eth_rx_queue_init(internals->nfb,
rx_queue_id,
dev->data->port_id,
@@ -81,6 +125,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
^ permalink raw reply related [flat|nested] 7+ messages in thread