net/nfb: support timestamp
This patch adds timestamping support to nfb driver. Signed-off-by: Rastislav Cernay <cernay@netcope.com>
This commit is contained in:
parent
5e33bebdd8
commit
9c7fd48fee
@ -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
|
||||
----------------------
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 @@ nfb_eth_dev_init(struct rte_eth_dev *dev)
|
||||
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 @@ nfb_eth_dev_init(struct rte_eth_dev *dev)
|
||||
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
|
||||
@ -577,3 +594,4 @@ static struct rte_pci_driver nfb_eth_driver = {
|
||||
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>");
|
||||
|
@ -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 @@ nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
rxq->flags = 0;
|
||||
|
||||
ret = nfb_eth_rx_queue_init(internals->nfb,
|
||||
rx_queue_id,
|
||||
dev->data->port_id,
|
||||
@ -81,6 +125,9 @@ nfb_eth_rx_queue_setup(struct rte_eth_dev *dev,
|
||||
else
|
||||
rte_free(rxq);
|
||||
|
||||
if (nfb_check_timestamp(dev->device->devargs))
|
||||
rxq->flags |= NFB_TIMESTAMP_FLAG;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -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 @@ nfb_eth_ndp_rx(void *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 @@ nfb_eth_ndp_rx(void *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 @@ nfb_eth_ndp_rx(void *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 {
|
||||
|
Loading…
Reference in New Issue
Block a user