* [dpdk-dev] [PATCH 0/6] rawdev driver for ntb
@ 2019-06-03 8:46 Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
0 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb pmd
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 25 +
doc/guides/rel_notes/release_19_08.rst | 16 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 373 +++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 85 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 779 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 21 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 364 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2010 insertions(+), 11 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-04 2:20 ` Ye Xiaolong
2019-06-03 8:46 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 487 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 691 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index 6b96e0e80..44069af7d 100644
--- a/config/common_base
+++ b/config/common_base
@@ -741,6 +741,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..852b16c77
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_memzone
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..4634c9ef9
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,487 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (!dev || !attr_name) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (!dev || !attr_name || !attr_value) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret = 0;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ ret = (*hw->ntb_ops->set_link_up)(dev);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret = 0;
+
+ if (!pci_dev) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (!rawdev) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret = 0;
+
+ if (!pci_dev) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (!rawdev) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..80afb67aa
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link_up: Set local side up.
+ * @set_link_down: Set local side down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ uint64_t (*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link_up)(struct rte_rawdev *dev);
+ int (*set_link_down)(struct rte_rawdev *dev);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, int peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ int peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 7c9b4b538..4f69ee4a5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -303,6 +303,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-04 3:01 ` Ye Xiaolong
2019-06-03 8:46 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 373 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 85 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 7 +
5 files changed, 468 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index 852b16c77..fc50f7a4f 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..f8174916d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,373 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret = 0;
+ int i = 0;
+
+ if (!hw) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return (uint64_t)(hw->pci_dev->mem_resource[bar].addr);
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (!hw) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * 0x10;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * 0x10;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * 0x10;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret = 0;
+
+ if (!hw) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link_up(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link_down(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, int peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is non-zero, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ int peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is non-zero, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link_up = intel_ntb_set_link_up,
+ .set_link_down = intel_ntb_set_link_down,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..eb798b1de
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 4634c9ef9..54c52a340 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -146,6 +148,7 @@ static int
ntb_dev_start(struct rte_rawdev *dev)
{
/* TODO: init queues and start queues. */
+
dev->started = 1;
return 0;
@@ -155,6 +158,7 @@ static void
ntb_dev_stop(struct rte_rawdev *dev)
{
/* TODO: stop rx/tx queues. */
+
dev->started = 0;
}
@@ -355,6 +359,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 276 ++++++++++++++++++++++++++++
1 file changed, 276 insertions(+)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 54c52a340..35bc34c54 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,155 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_1GB, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: %lx", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_wirte only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,8 +296,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -157,14 +320,42 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int status;
+
/* TODO: stop rx/tx queues. */
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up)
+ rte_delay_us(10);
+
+clean:
+ /* Clear doorbells mask. */
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -172,6 +363,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -350,7 +555,10 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
int ret = 0;
+ int i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +585,74 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: %lx", i, hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-03 8:46 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-04 6:48 ` Ye Xiaolong
2019-06-04 8:48 ` Ye Xiaolong
2019-06-03 8:46 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 2 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 25 +-
examples/Makefile | 1 +
examples/meson.build | 21 +-
examples/ntb/Makefile | 68 ++++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 364 ++++++++++++++++++++++++++++
6 files changed, 477 insertions(+), 18 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 35bc34c54..1824842f2 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -212,11 +212,16 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for test memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t bar_addr, size;
+ unsigned int i;
+
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (uint64_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy((void *)bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -226,11 +231,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for test memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t size;
+ unsigned int i;
+
+ size = (uint64_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index de35656d4..dda4a07a8 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -25,16 +25,17 @@ all_examples = [
'l3fwd-acl', 'l3fwd-power',
'l3fwd-vf', 'link_status_interrupt',
'load_balancer', 'multi_process',
- 'netmap_compat', 'packet_ordering',
- 'performance-thread', 'ptpclient',
- 'qos_meter', 'qos_sched',
- 'quota_watermark', 'rxtx_callbacks',
- 'server_node_efd', 'service_cores',
- 'skeleton', 'tep_termination',
- 'timer', 'vdpa',
- 'vhost', 'vhost_crypto',
- 'vhost_scsi', 'vm_power_manager',
- 'vmdq', 'vmdq_dcb',
+ 'netmap_compat', 'ntb',
+ 'packet_ordering', 'performance-thread',
+ 'ptpclient', 'qos_meter',
+ 'qos_sched', 'quota_watermark',
+ 'rxtx_callbacks', 'server_node_efd',
+ 'service_cores', 'skeleton',
+ 'tep_termination', 'timer',
+ 'vdpa', 'vhost',
+ 'vhost_crypto', 'vhost_scsi',
+ 'vm_power_manager', 'vmdq',
+ 'vmdq_dcb',
]
# install all example code on install - irrespective of whether the example in
# question is to be built as part of this build or not.
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..7835d817a
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,364 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %lu)\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ char *filepath;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started)
+ printf("Device needs to be up first. Try later.\n");
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link)
+ printf("Link is not up, cannot send file.\n");
+
+ filepath = strdup(res->filepath);
+ if (filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(filepath, "r");
+ if (!file) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size)
+ size = max_file_size;
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+ rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1, (void *)size);
+ printf("Done sending file.\n");
+
+ fclose(file);
+ free((void *)filepath);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint64_t size, val;
+ char *filepath;
+ uint8_t *buff;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started)
+ printf("Device needs to be up first. Try later.\n");
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val)
+ printf("Link is not up, cannot receive file.\n");
+
+ filepath = strdup(res->filepath);
+ if (filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(filepath, "w");
+ if (!file) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size);
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+ fclose(file);
+ free((void *)filepath);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb", 7) == 0) &&
+ (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-03 8:46 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-04 7:53 ` Jerin Jacob Kollanukkaran
2019-06-03 8:46 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb pmd Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..470869ff3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+ntb_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "ntb" or status_dev == "all":
+ show_device_status(ntb_devices , "NTB")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(ntb_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(ntb_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 6/6] doc: update docs for ntb pmd
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-03 8:46 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-03 8:46 ` Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-03 8:46 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 25 ++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 16 +++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 98 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 15d0829c5..ee43f0c29 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1052,6 +1052,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1428,3 +1432,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..8a5fdb568
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,25 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index b9510f93a..387973922 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -55,6 +55,22 @@ New Features
=========================================================
+ * **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
+
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..5c872c3bf
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 4 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host
+* ``receive [filepath]``: Receive file to [filepath], need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-03 8:46 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-04 2:20 ` Ye Xiaolong
0 siblings, 0 replies; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-04 2:20 UTC (permalink / raw)
To: Xiaoyun Li; +Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev
On 06/03, Xiaoyun Li wrote:
>Introduce rawdev driver support for NTB (Non-transparent Bridge) which
>can help to connect two separate hosts with each other.
>
>Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
>---
> config/common_base | 5 +
> drivers/raw/Makefile | 1 +
> drivers/raw/meson.build | 2 +-
> drivers/raw/ntb_rawdev/Makefile | 27 +
> drivers/raw/ntb_rawdev/meson.build | 7 +
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 487 ++++++++++++++++++
> drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
> .../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
> mk/rte.app.mk | 1 +
> 9 files changed, 691 insertions(+), 1 deletion(-)
> create mode 100644 drivers/raw/ntb_rawdev/Makefile
> create mode 100644 drivers/raw/ntb_rawdev/meson.build
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
> create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
>
>diff --git a/config/common_base b/config/common_base
>index 6b96e0e80..44069af7d 100644
>--- a/config/common_base
>+++ b/config/common_base
>@@ -741,6 +741,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
> #
> CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
>
>+#
>+# Compile PMD for NTB raw device
>+#
>+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
>+
> #
> # Compile librte_ring
> #
>diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
>index 8e29b4a56..efe61f451 100644
>--- a/drivers/raw/Makefile
>+++ b/drivers/raw/Makefile
>@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
> endif
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
>+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
>
> include $(RTE_SDK)/mk/rte.subdir.mk
>diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
>index a61cdccef..6abf659d0 100644
>--- a/drivers/raw/meson.build
>+++ b/drivers/raw/meson.build
>@@ -1,7 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright 2018 NXP
>
>-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
>+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
> std_deps = ['rawdev']
> config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
> driver_name_fmt = 'rte_pmd_@0@'
>diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
>new file mode 100644
>index 000000000..852b16c77
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/Makefile
>@@ -0,0 +1,27 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 2019 Intel Corporation
>+
>+include $(RTE_SDK)/mk/rte.vars.mk
>+
>+#
>+# library name
>+#
>+LIB = librte_pmd_ntb_rawdev.a
>+
>+CFLAGS += -DALLOW_EXPERIMENTAL_API
>+CFLAGS += -O3
>+CFLAGS += $(WERROR_FLAGS)
>+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_memzone
>+LDLIBS += -lrte_pci -lrte_bus_pci
>+LDLIBS += -lrte_rawdev
>+
>+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
>+
>+LIBABIVER := 1
>+
>+#
>+# all source are stored in SRCS-y
>+#
>+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
>+
>+include $(RTE_SDK)/mk/rte.lib.mk
>diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
>new file mode 100644
>index 000000000..ca905049d
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/meson.build
>@@ -0,0 +1,7 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 2019 Intel Corporation.
>+
>+deps += ['rawdev', 'mbuf', 'mempool',
>+ 'pci', 'bus_pci']
>+sources = files('ntb_rawdev.c')
>+allow_experimental_apis = true
>diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>new file mode 100644
>index 000000000..4634c9ef9
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>@@ -0,0 +1,487 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2019 Intel Corporation.
>+ */
>+#include <stdint.h>
>+#include <stdio.h>
>+#include <string.h>
>+#include <errno.h>
>+
>+#include <rte_common.h>
>+#include <rte_lcore.h>
>+#include <rte_cycles.h>
>+#include <rte_eal.h>
>+#include <rte_log.h>
>+#include <rte_pci.h>
>+#include <rte_bus_pci.h>
>+#include <rte_memzone.h>
>+#include <rte_memcpy.h>
>+#include <rte_rawdev.h>
>+#include <rte_rawdev_pmd.h>
>+
>+#include "ntb_rawdev.h"
>+
>+int ntb_logtype;
>+
>+static const struct rte_pci_id pci_id_ntb_map[] = {
>+ { .vendor_id = 0, /* sentinel */ },
>+};
>+
>+static void
>+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
>+ uint16_t queue_id __rte_unused,
>+ rte_rawdev_obj_t queue_conf __rte_unused)
>+{
>+}
>+
>+static int
>+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
>+ uint16_t queue_id __rte_unused,
>+ rte_rawdev_obj_t queue_conf __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static int
>+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
>+ uint16_t queue_id __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static uint16_t
>+ntb_queue_count(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ return hw->queue_pairs;
>+}
>+
>+static int
>+ntb_enqueue_bufs(struct rte_rawdev *dev,
>+ struct rte_rawdev_buf **buffers,
>+ unsigned int count,
>+ rte_rawdev_obj_t context)
>+{
>+ RTE_SET_USED(dev);
>+ RTE_SET_USED(buffers);
>+ RTE_SET_USED(count);
>+ RTE_SET_USED(context);
>+
>+ return 0;
>+}
>+
>+static int
>+ntb_dequeue_bufs(struct rte_rawdev *dev,
>+ struct rte_rawdev_buf **buffers,
>+ unsigned int count,
>+ rte_rawdev_obj_t context)
>+{
>+ RTE_SET_USED(dev);
>+ RTE_SET_USED(buffers);
>+ RTE_SET_USED(count);
>+ RTE_SET_USED(context);
>+
>+ return 0;
>+}
>+
>+static void
>+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ struct ntb_attr *ntb_attrs = dev_info;
>+
>+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
>+ switch (hw->topo) {
>+ case NTB_TOPO_B2B_DSD:
>+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
>+ NTB_ATTR_NAME_LEN);
>+ break;
>+ case NTB_TOPO_B2B_USD:
>+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
>+ NTB_ATTR_NAME_LEN);
>+ break;
>+ default:
>+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
>+ NTB_ATTR_NAME_LEN);
>+ }
>+
>+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->link_status);
>+
>+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->link_speed);
>+
>+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->link_width);
>+
>+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->mw_cnt);
>+
>+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->db_cnt);
>+
>+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
>+ NTB_ATTR_NAME_LEN);
>+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
>+ "%d", hw->spad_cnt);
>+}
>+
>+static int
>+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
>+ rte_rawdev_obj_t config __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static int
>+ntb_dev_start(struct rte_rawdev *dev)
>+{
>+ /* TODO: init queues and start queues. */
>+ dev->started = 1;
>+
>+ return 0;
>+}
>+
>+static void
>+ntb_dev_stop(struct rte_rawdev *dev)
>+{
>+ /* TODO: stop rx/tx queues. */
>+ dev->started = 0;
>+}
>+
>+static int
>+ntb_dev_close(struct rte_rawdev *dev)
>+{
>+ int ret = 0;
>+
>+ if (dev->started)
>+ ntb_dev_stop(dev);
>+
>+ /* TODO: free queues. */
>+
>+ return ret;
>+}
>+
>+static int
>+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static int
>+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
>+ uint64_t attr_value)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+
>+ if (!dev || !attr_name) {
According to DPDP coding style 1.8.1 [1], it's preferred to test pointers against
NULL.
[1] https://doc.dpdk.org/guides/contributing/coding_style.html
>+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
>+ return -EINVAL;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
>+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
Do we need to check whether the function pointer exists before calling it?
I can see quite a few occurrences that calling function pointer without a check.
>+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
>+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
>+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, attr_value);
>+ return 0;
>+ }
>+
>+ /* Attribute not found. */
>+ return -EINVAL;
>+}
>+
>+static int
>+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
>+ uint64_t *attr_value)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+
>+ if (!dev || !attr_name || !attr_value) {
1.8.1
>+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
>+ return -EINVAL;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->topo;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->link_status;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->link_speed;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->link_width;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->mw_cnt;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->db_cnt;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = hw->spad_cnt;
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
>+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
>+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
>+ attr_name, *attr_value);
>+ return 0;
>+ }
>+
>+ /* Attribute not found. */
>+ return -EINVAL;
>+}
>+
>+static int
>+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
>+ const unsigned int ids[] __rte_unused,
>+ uint64_t values[] __rte_unused,
>+ unsigned int n __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static int
>+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
>+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
>+ unsigned int size __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static uint64_t
>+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
>+ const char *name __rte_unused,
>+ unsigned int *id __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static int
>+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
>+ const uint32_t ids[] __rte_unused,
>+ uint32_t nb_ids __rte_unused)
>+{
>+ return 0;
>+}
>+
>+static const struct rte_rawdev_ops ntb_rawdev_ops = {
>+ .dev_info_get = ntb_dev_info_get,
>+ .dev_configure = ntb_dev_configure,
>+ .dev_start = ntb_dev_start,
>+ .dev_stop = ntb_dev_stop,
>+ .dev_close = ntb_dev_close,
>+ .dev_reset = ntb_dev_reset,
>+
>+ .queue_def_conf = ntb_queue_conf_get,
>+ .queue_setup = ntb_queue_setup,
>+ .queue_release = ntb_queue_release,
>+ .queue_count = ntb_queue_count,
>+
>+ .enqueue_bufs = ntb_enqueue_bufs,
>+ .dequeue_bufs = ntb_dequeue_bufs,
>+
>+ .attr_get = ntb_attr_get,
>+ .attr_set = ntb_attr_set,
>+
>+ .xstats_get = ntb_xstats_get,
>+ .xstats_get_names = ntb_xstats_get_names,
>+ .xstats_get_by_name = ntb_xstats_get_by_name,
>+ .xstats_reset = ntb_xstats_reset,
>+};
>+
>+static int
>+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ int ret = 0;
No need to initialize ret.
>+
>+ hw->pci_dev = pci_dev;
>+ hw->peer_dev_up = 0;
>+ hw->link_status = 0;
>+ hw->link_speed = NTB_SPEED_NONE;
>+ hw->link_width = NTB_WIDTH_NONE;
>+
>+ switch (pci_dev->id.device_id) {
>+ default:
>+ NTB_LOG(ERR, "Not supported device.");
>+ return -EINVAL;
>+ }
>+
>+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
>+ if (ret) {
>+ NTB_LOG(ERR, "Unanle to init ntb dev.");
>+ return ret;
>+ }
>+
>+ ret = (*hw->ntb_ops->set_link_up)(dev);
>+ if (ret)
>+ return ret;
>+
>+ return ret;
>+}
>+
>+static int
>+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
>+{
>+ char name[RTE_RAWDEV_NAME_MAX_LEN];
>+ struct rte_rawdev *rawdev = NULL;
>+ int ret = 0;
>+
>+ if (!pci_dev) {
>+ NTB_LOG(ERR, "Invalid pci_dev.");
>+ ret = -EINVAL;
>+ goto fail;
>+ }
>+
>+ memset(name, 0, sizeof(name));
>+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
>+ pci_dev->addr.bus, pci_dev->addr.devid,
>+ pci_dev->addr.function);
>+
>+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
>+
>+ /* Allocate device structure. */
>+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
>+ socket_id);
>+ if (!rawdev) {
>+ NTB_LOG(ERR, "Unable to allocate rawdev.");
>+ ret = -EINVAL;
>+ goto fail;
>+ }
>+
>+ rawdev->dev_ops = &ntb_rawdev_ops;
>+ rawdev->device = &pci_dev->device;
>+ rawdev->driver_name = pci_dev->driver->driver.name;
>+
>+ ret = ntb_init_hw(rawdev, pci_dev);
>+ if (ret < 0) {
>+ NTB_LOG(ERR, "Unable to init ntb hw.");
>+ goto fail;
>+ }
>+
>+ return ret;
>+
>+fail:
>+ if (rawdev)
>+ rte_rawdev_pmd_release(rawdev);
>+
>+ return ret;
>+}
>+
>+static int
>+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
>+{
>+ char name[RTE_RAWDEV_NAME_MAX_LEN];
>+ struct rte_rawdev *rawdev;
>+ int ret = 0;
>+
>+ if (!pci_dev) {
>+ NTB_LOG(ERR, "Invalid pci_dev.");
>+ ret = -EINVAL;
>+ return ret;
>+ }
>+
>+ memset(name, 0, sizeof(name));
>+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
>+ pci_dev->addr.bus, pci_dev->addr.devid,
>+ pci_dev->addr.function);
>+
>+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
>+
>+ rawdev = rte_rawdev_pmd_get_named_dev(name);
>+ if (!rawdev) {
>+ NTB_LOG(ERR, "Invalid device name (%s)", name);
>+ ret = -EINVAL;
>+ return ret;
>+ }
>+
>+ ret = rte_rawdev_pmd_release(rawdev);
>+ if (ret)
>+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
>+
>+ return ret;
>+}
>+
>+static int
>+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
>+ struct rte_pci_device *pci_dev)
>+{
>+ return ntb_rawdev_create(pci_dev, rte_socket_id());
>+}
>+
>+static int ntb_rawdev_remove(struct rte_pci_device *pci_dev)
Put "ntb_rawdev_remove(struct rte_pci_device *pci_dev)" to a new line like other
functions.
>+{
>+ return ntb_rawdev_destroy(pci_dev);
>+}
>+
>+
>+static struct rte_pci_driver rte_ntb_pmd = {
>+ .id_table = pci_id_ntb_map,
>+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
>+ .probe = ntb_rawdev_probe,
>+ .remove = ntb_rawdev_remove,
>+};
>+
>+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
>+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
>+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
>+
>+RTE_INIT(ntb_init_log)
>+{
>+ ntb_logtype = rte_log_register("pmd.raw.ntb");
>+ if (ntb_logtype >= 0)
>+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
>+}
>diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
>new file mode 100644
>index 000000000..80afb67aa
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
>@@ -0,0 +1,158 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2019 Intel Corporation.
>+ */
>+
>+#ifndef _NTB_RAWDEV_H_
>+#define _NTB_RAWDEV_H_
>+
>+extern int ntb_logtype;
>+
>+#define NTB_LOG(level, fmt, args...) \
>+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
>+ __func__, ##args)
>+
>+/* Vendor ID */
>+#define NTB_INTEL_VENDOR_ID 0x8086
>+
>+/* Device IDs */
>+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
>+
>+#define NTB_TOPO_NAME "topo"
>+#define NTB_LINK_STATUS_NAME "link_status"
>+#define NTB_SPEED_NAME "speed"
>+#define NTB_WIDTH_NAME "width"
>+#define NTB_MW_CNT_NAME "mw_count"
>+#define NTB_DB_CNT_NAME "db_count"
>+#define NTB_SPAD_CNT_NAME "spad_count"
>+/* Reserved to app to use. */
>+#define NTB_PEER_SPAD_14 "spad14"
>+#define NTB_PEER_SPAD_15 "spad15"
>+#define NTB_ATTR_NAME_LEN 30
>+#define NTB_ATTR_MAX 20
>+
>+/* NTB Attributes */
>+struct ntb_attr {
>+ /**< Name of the attribute */
>+ char name[NTB_ATTR_NAME_LEN];
>+ /**< Value or reference of value of attribute */
>+ char value[NTB_ATTR_NAME_LEN];
>+};
>+
>+enum ntb_attr_idx {
>+ NTB_TOPO_ID = 0,
>+ NTB_LINK_STATUS_ID,
>+ NTB_SPEED_ID,
>+ NTB_WIDTH_ID,
>+ NTB_MW_CNT_ID,
>+ NTB_DB_CNT_ID,
>+ NTB_SPAD_CNT_ID,
>+};
>+
>+enum ntb_topo {
>+ NTB_TOPO_NONE = 0,
>+ NTB_TOPO_B2B_USD,
>+ NTB_TOPO_B2B_DSD,
>+};
>+
>+enum ntb_link {
>+ NTB_LINK_DOWN = 0,
>+ NTB_LINK_UP,
>+};
>+
>+enum ntb_speed {
>+ NTB_SPEED_NONE = 0,
>+ NTB_SPEED_GEN1 = 1,
>+ NTB_SPEED_GEN2 = 2,
>+ NTB_SPEED_GEN3 = 3,
>+ NTB_SPEED_GEN4 = 4,
>+};
>+
>+enum ntb_width {
>+ NTB_WIDTH_NONE = 0,
>+ NTB_WIDTH_1 = 1,
>+ NTB_WIDTH_2 = 2,
>+ NTB_WIDTH_4 = 4,
>+ NTB_WIDTH_8 = 8,
>+ NTB_WIDTH_12 = 12,
>+ NTB_WIDTH_16 = 16,
>+ NTB_WIDTH_32 = 32,
>+};
>+
>+/* Define spad registers usage. 0 is reserved. */
>+enum ntb_spad_idx {
>+ SPAD_NUM_MWS = 1,
>+ SPAD_NUM_QPS,
>+ SPAD_Q_SZ,
>+ SPAD_MW0_SZ_H,
>+ SPAD_MW0_SZ_L,
>+ SPAD_MW1_SZ_H,
>+ SPAD_MW1_SZ_L,
>+};
>+
>+/**
>+ * NTB device operations
>+ * @ntb_dev_init: Init ntb dev.
>+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
>+ * @mw_set_trans: Set translation of internal memory that remote can access.
>+ * @get_link_status: get link status, link speed and link width.
>+ * @set_link_up: Set local side up.
>+ * @set_link_down: Set local side down.
>+ * @spad_read: Read local/peer spad register val.
>+ * @spad_write: Write val to local/peer spad register.
>+ * @db_read: Read doorbells status.
>+ * @db_clear: Clear local doorbells.
>+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
>+ * for those db bits.
>+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
>+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
>+ */
>+struct ntb_dev_ops {
>+ int (*ntb_dev_init)(struct rte_rawdev *dev);
>+ uint64_t (*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
>+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
>+ uint64_t addr, uint64_t size);
>+ int (*get_link_status)(struct rte_rawdev *dev);
>+ int (*set_link_up)(struct rte_rawdev *dev);
>+ int (*set_link_down)(struct rte_rawdev *dev);
>+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, int peer);
>+ int (*spad_write)(struct rte_rawdev *dev, int spad,
>+ int peer, uint32_t spad_v);
>+ uint64_t (*db_read)(struct rte_rawdev *dev);
>+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
>+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
>+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
>+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
>+};
>+
>+/* ntb private data. */
>+struct ntb_hw {
>+ uint8_t mw_cnt;
>+ uint8_t peer_mw_cnt;
>+ uint8_t db_cnt;
>+ uint8_t spad_cnt;
>+
>+ uint64_t db_valid_mask;
>+ uint64_t db_mask;
>+
>+ enum ntb_topo topo;
>+
>+ enum ntb_link link_status;
>+ enum ntb_speed link_speed;
>+ enum ntb_width link_width;
>+
>+ const struct ntb_dev_ops *ntb_ops;
>+
>+ struct rte_pci_device *pci_dev;
>+
>+ uint64_t *mw_size;
>+ uint64_t *peer_mw_size;
>+ uint8_t peer_dev_up;
>+
>+ uint16_t queue_pairs;
>+ uint16_t queue_size;
>+
>+ /**< mem zone to populate RX ring. */
>+ const struct rte_memzone **mz;
>+};
>+
>+#endif /* _NTB_RAWDEV_H_ */
>diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
>new file mode 100644
>index 000000000..8861484fb
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
>@@ -0,0 +1,4 @@
>+DPDK_19.08 {
>+
>+ local: *;
>+};
>diff --git a/mk/rte.app.mk b/mk/rte.app.mk
>index 7c9b4b538..4f69ee4a5 100644
>--- a/mk/rte.app.mk
>+++ b/mk/rte.app.mk
>@@ -303,6 +303,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
> _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
> endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
>+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
> endif # CONFIG_RTE_LIBRTE_RAWDEV
>
> endif # !CONFIG_RTE_BUILD_SHARED_LIBS
>--
>2.17.1
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support
2019-06-03 8:46 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-04 3:01 ` Ye Xiaolong
0 siblings, 0 replies; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-04 3:01 UTC (permalink / raw)
To: Xiaoyun Li; +Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev
On 06/03, Xiaoyun Li wrote:
>Add in the list of registers for the device. And enable ntb device
>ops for intel skylake platform.
>
>Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
>---
> drivers/raw/ntb_rawdev/Makefile | 1 +
> drivers/raw/ntb_rawdev/meson.build | 3 +-
> drivers/raw/ntb_rawdev/ntb_hw_intel.c | 373 ++++++++++++++++++++++++++
> drivers/raw/ntb_rawdev/ntb_hw_intel.h | 85 ++++++
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 7 +
> 5 files changed, 468 insertions(+), 1 deletion(-)
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
>
>diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
>index 852b16c77..fc50f7a4f 100644
>--- a/drivers/raw/ntb_rawdev/Makefile
>+++ b/drivers/raw/ntb_rawdev/Makefile
>@@ -23,5 +23,6 @@ LIBABIVER := 1
> # all source are stored in SRCS-y
> #
> SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
>+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
>
> include $(RTE_SDK)/mk/rte.lib.mk
>diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
>index ca905049d..c696f60b3 100644
>--- a/drivers/raw/ntb_rawdev/meson.build
>+++ b/drivers/raw/ntb_rawdev/meson.build
>@@ -3,5 +3,6 @@
>
> deps += ['rawdev', 'mbuf', 'mempool',
> 'pci', 'bus_pci']
>-sources = files('ntb_rawdev.c')
>+sources = files('ntb_rawdev.c',
>+ 'ntb_hw_intel.c')
> allow_experimental_apis = true
>diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
>new file mode 100644
>index 000000000..f8174916d
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
>@@ -0,0 +1,373 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2019 Intel Corporation.
>+ */
>+#include <stdint.h>
>+#include <stdio.h>
>+#include <errno.h>
>+
>+#include <rte_eal.h>
>+#include <rte_pci.h>
>+#include <rte_bus_pci.h>
>+#include <rte_rawdev.h>
>+#include <rte_rawdev_pmd.h>
>+
>+#include "ntb_rawdev.h"
>+#include "ntb_hw_intel.h"
>+
>+enum xeon_ntb_bar {
>+ XEON_NTB_BAR23 = 2,
>+ XEON_NTB_BAR45 = 4,
>+};
>+
>+static enum xeon_ntb_bar intel_ntb_bar[] = {
>+ XEON_NTB_BAR23,
>+ XEON_NTB_BAR45,
>+};
>+
>+static int
>+intel_ntb_dev_init(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint8_t reg_val, bar;
>+ int ret = 0;
>+ int i = 0;
No need to do above initializations.
>+
>+ if (!hw) {
1.8.1
>+ NTB_LOG(ERR, "Invalid device.");
>+ return -EINVAL;
>+ }
>+
>+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
>+ sizeof(reg_val), XEON_PPD_OFFSET);
>+ if (ret < 0) {
>+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
>+ return -EIO;
>+ }
>+
>+ /* Check connection topo type. Only support B2B. */
>+ switch (reg_val & XEON_PPD_CONN_MASK) {
>+ case XEON_PPD_CONN_B2B:
>+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
>+ break;
>+ case XEON_PPD_CONN_TRANSPARENT:
>+ case XEON_PPD_CONN_RP:
>+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
>+ return -EINVAL;
>+ }
>+
>+ /* Check device type. */
>+ if (reg_val & XEON_PPD_DEV_DSD) {
>+ NTB_LOG(INFO, "DSD, Downstream Device.");
>+ hw->topo = NTB_TOPO_B2B_DSD;
>+ } else {
>+ NTB_LOG(INFO, "USD, Upstream device.");
>+ hw->topo = NTB_TOPO_B2B_USD;
>+ }
>+
>+ /* Check if bar4 is split. Do not support split bar. */
>+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
>+ NTB_LOG(ERR, "Do not support split bar.");
>+ return -EINVAL;
>+ }
>+
>+ hw->mw_cnt = XEON_MW_COUNT;
>+ hw->db_cnt = XEON_DB_COUNT;
>+ hw->spad_cnt = XEON_SPAD_COUNT;
>+
>+ hw->mw_size = rte_zmalloc("uint64_t",
>+ hw->mw_cnt * sizeof(uint64_t), 0);
>+ for (i = 0; i < hw->mw_cnt; i++) {
>+ bar = intel_ntb_bar[i];
>+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
>+ }
>+
>+ return 0;
>+}
>+
>+static uint64_t
>+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint8_t bar;
>+
>+ bar = intel_ntb_bar[mw_idx];
Do we need a sanity check for mw_idx here?
>+
>+ return (uint64_t)(hw->pci_dev->mem_resource[bar].addr);
>+}
>+
>+static int
>+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
>+ uint64_t addr, uint64_t size)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ void *xlat_addr, *limit_addr;
>+ uint64_t xlat_off, limit_off;
>+ uint64_t base, limit;
>+ uint8_t bar;
>+
>+ if (!hw) {
1.8.1
>+ NTB_LOG(ERR, "Invalid device.");
>+ return -EINVAL;
>+ }
>+
>+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
>+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
>+ hw->mw_cnt - 1);
>+ return -EINVAL;
>+ }
>+
>+ bar = intel_ntb_bar[mw_idx];
>+
>+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * 0x10;
>+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * 0x10;
Use Marco for the magical 0x10 ?
>+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
>+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
>+
>+ /* Limit reg val should be EMBAR base address plus MW size. */
>+ base = addr;
>+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
>+ *((volatile uint64_t *)xlat_addr) = base;
>+ *((volatile uint64_t *)limit_addr) = limit;
>+
>+ /* Setup the external point so that remote can access. */
>+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
>+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
>+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * 0x10;
>+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
>+ base = *((volatile uint64_t *)xlat_addr);
>+ base &= ~0xf;
>+ limit = base + size;
>+ *((volatile uint64_t *)limit_addr) = limit;
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_get_link_status(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint16_t reg_val;
>+ int ret = 0;
>+
>+ if (!hw) {
1.8.1
>+ NTB_LOG(ERR, "Invalid device.");
>+ return -EINVAL;
>+ }
>+
>+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
>+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
>+ if (ret < 0) {
>+ NTB_LOG(ERR, "Unable to get link status.");
>+ return -EIO;
>+ }
>+
>+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
>+
>+ if (hw->link_status) {
>+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
>+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
>+ } else {
>+ hw->link_speed = NTB_SPEED_NONE;
>+ hw->link_width = NTB_WIDTH_NONE;
>+ }
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_set_link_up(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint32_t ntb_ctrl, reg_off;
>+ void *reg_addr;
>+
>+ reg_off = XEON_NTBCNTL_OFFSET;
>+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
>+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
>+
>+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
>+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
>+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
>+
>+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_set_link_down(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint32_t ntb_ctrl, reg_off;
>+ void *reg_addr;
>+
>+ reg_off = XEON_NTBCNTL_OFFSET;
>+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
>+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
>+
>+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
>+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
>+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
>+
>+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
>+
>+ return 0;
>+}
Above two functions share most of the code, can consider to extract the common
part into one internal function.
>+
>+static uint32_t
>+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, int peer)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint32_t spad_v, reg_off;
>+ void *reg_addr;
>+
>+ if (spad < 0 || spad >= hw->spad_cnt) {
>+ NTB_LOG(ERR, "Invalid spad reg index.");
>+ return 0;
>+ }
>+
>+ /* When peer is non-zero, read peer spad reg */
>+ if (peer)
>+ reg_off = XEON_B2B_SPAD_OFFSET;
>+ else
>+ reg_off = XEON_IM_SPAD_OFFSET;
>+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
>+ reg_off + (spad << 2);
>+ spad_v = *((volatile uint32_t *)reg_addr);
>+
>+ return spad_v;
>+}
>+
>+static int
>+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
>+ int peer, uint32_t spad_v)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint32_t reg_off;
>+ void *reg_addr;
>+
>+ if (spad < 0 || spad >= hw->spad_cnt) {
>+ NTB_LOG(ERR, "Invalid spad reg index.");
>+ return -EINVAL;
>+ }
>+
>+ /* When peer is non-zero, write peer spad reg */
>+ if (peer)
>+ reg_off = XEON_B2B_SPAD_OFFSET;
>+ else
>+ reg_off = XEON_IM_SPAD_OFFSET;
>+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
>+ reg_off + (spad << 2);
>+
>+ *((volatile uint32_t *)reg_addr) = spad_v;
>+
>+ return 0;
>+}
>+
>+static uint64_t
>+intel_ntb_db_read(struct rte_rawdev *dev)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint64_t db_off, db_bits;
>+ void *db_addr;
>+
>+ db_off = XEON_IM_INT_STATUS_OFFSET;
>+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
>+
>+ db_bits = *((volatile uint64_t *)db_addr);
>+
>+ return db_bits;
>+}
>+
>+static int
>+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint64_t db_off;
>+ void *db_addr;
>+
>+ db_off = XEON_IM_INT_STATUS_OFFSET;
>+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
>+
>+ *((volatile uint64_t *)db_addr) = db_bits;
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint64_t db_m_off;
>+ void *db_m_addr;
>+
>+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
>+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
>+
>+ db_mask |= hw->db_mask;
>+
>+ *((volatile uint64_t *)db_m_addr) = db_mask;
>+
>+ hw->db_mask = db_mask;
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint32_t db_off;
>+ void *db_addr;
>+
>+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
>+ NTB_LOG(ERR, "Invalid doorbell.");
>+ return -EINVAL;
>+ }
>+
>+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
>+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
>+
>+ *((volatile uint32_t *)db_addr) = 1;
>+
>+ return 0;
>+}
>+
>+static int
>+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
>+{
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint8_t reg_off;
>+ void *reg_addr;
>+
>+ if (intr >= hw->db_cnt) {
>+ NTB_LOG(ERR, "Invalid intr source.");
>+ return -EINVAL;
>+ }
>+
>+ /* Bind intr source to msix vector */
>+ reg_off = XEON_INTVEC_OFFSET;
>+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
>+ reg_off + intr;
>+
>+ *((volatile uint8_t *)reg_addr) = msix;
>+
>+ return 0;
>+}
>+
>+/* operations for primary side of local ntb */
>+const struct ntb_dev_ops intel_ntb_ops = {
>+ .ntb_dev_init = intel_ntb_dev_init,
>+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
>+ .mw_set_trans = intel_ntb_mw_set_trans,
>+ .get_link_status = intel_ntb_get_link_status,
>+ .set_link_up = intel_ntb_set_link_up,
>+ .set_link_down = intel_ntb_set_link_down,
>+ .spad_read = intel_ntb_spad_read,
>+ .spad_write = intel_ntb_spad_write,
>+ .db_read = intel_ntb_db_read,
>+ .db_clear = intel_ntb_db_clear,
>+ .db_set_mask = intel_ntb_db_set_mask,
>+ .peer_db_set = intel_ntb_peer_db_set,
>+ .vector_bind = intel_ntb_vector_bind,
>+};
>diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
>new file mode 100644
>index 000000000..eb798b1de
>--- /dev/null
>+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
>@@ -0,0 +1,85 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2019 Intel Corporation.
>+ */
>+
>+#ifndef _NTB_HW_INTEL_H_
>+#define _NTB_HW_INTEL_H_
>+
>+/* Ntb control and link status */
>+#define NTB_CTL_CFG_LOCK 1
>+#define NTB_CTL_DISABLE 2
>+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
>+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
>+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
>+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
>+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
>+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
>+
>+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
>+#define NTB_LNK_STA_SPEED_MASK 0x000f
>+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
>+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
>+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
>+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
>+
>+/* Intel Skylake Xeon hardware */
>+#define XEON_IMBAR1SZ_OFFSET 0x00d0
>+#define XEON_IMBAR2SZ_OFFSET 0x00d1
>+#define XEON_EMBAR1SZ_OFFSET 0x00d2
>+#define XEON_EMBAR2SZ_OFFSET 0x00d3
>+#define XEON_DEVCTRL_OFFSET 0x0098
>+#define XEON_DEVSTS_OFFSET 0x009a
>+#define XEON_UNCERRSTS_OFFSET 0x014c
>+#define XEON_CORERRSTS_OFFSET 0x0158
>+#define XEON_LINK_STATUS_OFFSET 0x01a2
>+
>+#define XEON_NTBCNTL_OFFSET 0x0000
>+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
>+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
>+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
>+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
>+#define XEON_IM_INT_STATUS_OFFSET 0x0040
>+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
>+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
>+#define XEON_USMEMMISS_OFFSET 0x0070
>+#define XEON_INTVEC_OFFSET 0x00d0
>+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
>+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
>+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
>+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
>+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
>+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
>+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
>+#define XEON_EM_INT_STATUS_OFFSET 0x4040
>+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
>+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
>+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
>+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
>+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
>+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
>+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
>+
>+#define XEON_PPD_OFFSET 0x00d4
>+#define XEON_PPD_CONN_MASK 0x03
>+#define XEON_PPD_CONN_TRANSPARENT 0x00
>+#define XEON_PPD_CONN_B2B 0x01
>+#define XEON_PPD_CONN_RP 0x02
>+#define XEON_PPD_DEV_MASK 0x10
>+#define XEON_PPD_DEV_USD 0x00
>+#define XEON_PPD_DEV_DSD 0x10
>+#define XEON_PPD_SPLIT_BAR_MASK 0x40
>+
>+
>+#define XEON_MW_COUNT 2
>+
>+#define XEON_DB_COUNT 32
>+#define XEON_DB_LINK 32
>+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
>+#define XEON_DB_MSIX_VECTOR_COUNT 33
>+#define XEON_DB_MSIX_VECTOR_SHIFT 1
>+#define XEON_DB_TOTAL_SHIFT 33
>+#define XEON_SPAD_COUNT 16
>+
>+extern const struct ntb_dev_ops intel_ntb_ops;
>+
>+#endif /* _NTB_HW_INTEL_H_ */
>diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>index 4634c9ef9..54c52a340 100644
>--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
>+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>@@ -18,11 +18,13 @@
> #include <rte_rawdev.h>
> #include <rte_rawdev_pmd.h>
>
>+#include "ntb_hw_intel.h"
> #include "ntb_rawdev.h"
>
> int ntb_logtype;
>
> static const struct rte_pci_id pci_id_ntb_map[] = {
>+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
> { .vendor_id = 0, /* sentinel */ },
> };
>
>@@ -146,6 +148,7 @@ static int
> ntb_dev_start(struct rte_rawdev *dev)
> {
> /* TODO: init queues and start queues. */
>+
Remove this extra empty line.
> dev->started = 1;
>
> return 0;
>@@ -155,6 +158,7 @@ static void
> ntb_dev_stop(struct rte_rawdev *dev)
> {
> /* TODO: stop rx/tx queues. */
>+
Ditto.
> dev->started = 0;
> }
>
>@@ -355,6 +359,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
> hw->link_width = NTB_WIDTH_NONE;
>
> switch (pci_dev->id.device_id) {
>+ case NTB_INTEL_DEV_ID_B2B_SKX:
>+ hw->ntb_ops = &intel_ntb_ops;
>+ break;
> default:
> NTB_LOG(ERR, "Not supported device.");
> return -EINVAL;
>--
>2.17.1
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-03 8:46 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-04 6:48 ` Ye Xiaolong
2019-06-04 8:12 ` Li, Xiaoyun
2019-06-04 8:48 ` Ye Xiaolong
1 sibling, 1 reply; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-04 6:48 UTC (permalink / raw)
To: Xiaoyun Li; +Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev
On 06/03, Xiaoyun Li wrote:
>Enable an example for rawdev ntb. Support interactive mode to send
>file on one host and receive file from another host. The command line
>would be 'send [filepath]' and 'receive [filepath]'.
>
>But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
>and dequeue functions and only support transmitting file no more than 4M.
>
>Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
>---
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 25 +-
> examples/Makefile | 1 +
> examples/meson.build | 21 +-
> examples/ntb/Makefile | 68 ++++++
> examples/ntb/meson.build | 16 ++
> examples/ntb/ntb_fwd.c | 364 ++++++++++++++++++++++++++++
> 6 files changed, 477 insertions(+), 18 deletions(-)
> create mode 100644 examples/ntb/Makefile
> create mode 100644 examples/ntb/meson.build
> create mode 100644 examples/ntb/ntb_fwd.c
>
>diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>index 35bc34c54..1824842f2 100644
>--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
>+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
>@@ -212,11 +212,16 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
> unsigned int count,
> rte_rawdev_obj_t context)
> {
>- RTE_SET_USED(dev);
>- RTE_SET_USED(buffers);
>- RTE_SET_USED(count);
>- RTE_SET_USED(context);
>+ /* Not FIFO right now. Just for test memory write. */
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint64_t bar_addr, size;
>+ unsigned int i;
>+
>+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
check the func pointer before calling it.
>+ size = (uint64_t)context;
>
>+ for (i = 0; i < count; i++)
>+ rte_memcpy((void *)bar_addr, buffers[i]->buf_addr, size);
> return 0;
> }
>
>@@ -226,11 +231,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
> unsigned int count,
> rte_rawdev_obj_t context)
> {
>- RTE_SET_USED(dev);
>- RTE_SET_USED(buffers);
>- RTE_SET_USED(count);
>- RTE_SET_USED(context);
>+ /* Not FIFO. Just for test memory read. */
>+ struct ntb_hw *hw = dev->dev_private;
>+ uint64_t size;
>+ unsigned int i;
>+
>+ size = (uint64_t)context;
>
>+ for (i = 0; i < count; i++)
>+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
> return 0;
> }
>
>diff --git a/examples/Makefile b/examples/Makefile
>index 7562424d9..de11dd487 100644
>--- a/examples/Makefile
>+++ b/examples/Makefile
>@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
> DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
> DIRS-y += multi_process
> DIRS-y += netmap_compat/bridge
>+DIRS-y += ntb
> DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
> ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
> DIRS-y += performance-thread
>diff --git a/examples/meson.build b/examples/meson.build
>index de35656d4..dda4a07a8 100644
>--- a/examples/meson.build
>+++ b/examples/meson.build
>@@ -25,16 +25,17 @@ all_examples = [
> 'l3fwd-acl', 'l3fwd-power',
> 'l3fwd-vf', 'link_status_interrupt',
> 'load_balancer', 'multi_process',
>- 'netmap_compat', 'packet_ordering',
>- 'performance-thread', 'ptpclient',
>- 'qos_meter', 'qos_sched',
>- 'quota_watermark', 'rxtx_callbacks',
>- 'server_node_efd', 'service_cores',
>- 'skeleton', 'tep_termination',
>- 'timer', 'vdpa',
>- 'vhost', 'vhost_crypto',
>- 'vhost_scsi', 'vm_power_manager',
>- 'vmdq', 'vmdq_dcb',
>+ 'netmap_compat', 'ntb',
>+ 'packet_ordering', 'performance-thread',
>+ 'ptpclient', 'qos_meter',
>+ 'qos_sched', 'quota_watermark',
>+ 'rxtx_callbacks', 'server_node_efd',
>+ 'service_cores', 'skeleton',
>+ 'tep_termination', 'timer',
>+ 'vdpa', 'vhost',
>+ 'vhost_crypto', 'vhost_scsi',
>+ 'vm_power_manager', 'vmdq',
>+ 'vmdq_dcb',
> ]
> # install all example code on install - irrespective of whether the example in
> # question is to be built as part of this build or not.
>diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
>new file mode 100644
>index 000000000..5ddd9b95f
>--- /dev/null
>+++ b/examples/ntb/Makefile
>@@ -0,0 +1,68 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 2019 Intel Corporation
>+
>+# binary name
>+APP = ntb_fwd
>+
>+# all source are stored in SRCS-y
>+SRCS-y := ntb_fwd.c
>+
>+# Build using pkg-config variables if possible
>+$(shell pkg-config --exists libdpdk)
>+ifeq ($(.SHELLSTATUS),0)
>+
>+all: shared
>+.PHONY: shared static
>+shared: build/$(APP)-shared
>+ ln -sf $(APP)-shared build/$(APP)
>+static: build/$(APP)-static
>+ ln -sf $(APP)-static build/$(APP)
>+
>+CFLAGS += -D_FILE_OFFSET_BITS=64
>+LDFLAGS += -pthread
>+
>+PC_FILE := $(shell pkg-config --path libdpdk)
>+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
>+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
>+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
>+
>+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
>+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
>+
>+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
>+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
>+
>+build:
>+ @mkdir -p $@
>+
>+.PHONY: clean
>+clean:
>+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
>+ rmdir --ignore-fail-on-non-empty build
>+
>+else # Build using legacy build system
>+
>+ifeq ($(RTE_SDK),)
>+$(error "Please define RTE_SDK environment variable")
>+endif
>+
>+# Default target, can be overridden by command line or environment
>+RTE_TARGET ?= x86_64-native-linuxapp-gcc
>+
>+include $(RTE_SDK)/mk/rte.vars.mk
>+
>+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
>+$(info This application can only operate in a linuxapp environment, \
>+please change the definition of the RTE_TARGET environment variable)
>+all:
>+else
>+
>+CFLAGS += -D_FILE_OFFSET_BITS=64
>+CFLAGS += -O2
>+CFLAGS += $(WERROR_FLAGS)
>+CFLAGS += -DALLOW_EXPERIMENTAL_API
>+
>+include $(RTE_SDK)/mk/rte.extapp.mk
>+
>+endif
>+endif
>diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
>new file mode 100644
>index 000000000..9a6288f4f
>--- /dev/null
>+++ b/examples/ntb/meson.build
>@@ -0,0 +1,16 @@
>+# SPDX-License-Identifier: BSD-3-Clause
>+# Copyright(c) 2019 Intel Corporation
>+
>+# meson file, for building this example as part of a main DPDK build.
>+#
>+# To build this example as a standalone application with an already-installed
>+# DPDK instance, use 'make'
>+
>+if host_machine.system() != 'linux'
>+ build = false
>+endif
>+deps += 'rawdev'
>+cflags += ['-D_FILE_OFFSET_BITS=64']
>+sources = files(
>+ 'ntb_fwd.c'
>+)
>diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
>new file mode 100644
>index 000000000..7835d817a
>--- /dev/null
>+++ b/examples/ntb/ntb_fwd.c
>@@ -0,0 +1,364 @@
>+/* SPDX-License-Identifier: BSD-3-Clause
>+ * Copyright(c) 2019 Intel Corporation
>+ */
>+#include <stdint.h>
>+#include <stdio.h>
>+#include <unistd.h>
>+#include <signal.h>
>+#include <string.h>
>+#include <getopt.h>
>+
>+#include <cmdline_parse_string.h>
>+#include <cmdline_socket.h>
>+#include <cmdline.h>
>+#include <rte_common.h>
>+#include <rte_rawdev.h>
>+#include <rte_lcore.h>
>+
>+static uint64_t max_file_size = 0x400000;
>+static uint8_t interactive = 1;
>+static uint16_t dev_id;
>+
>+/* *** Help command with introduction. *** */
>+struct cmd_help_result {
>+ cmdline_fixed_string_t help;
>+};
>+
>+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
>+ struct cmdline *cl,
>+ __attribute__((unused)) void *data)
>+{
>+ cmdline_printf(
>+ cl,
>+ "\n"
>+ "The following commands are currently available:\n\n"
>+ "Control:\n"
>+ " quit :"
>+ " Quit the application.\n"
>+ "\nFile transmit:\n"
>+ " send [path] :"
>+ " Send [path] file. (No more than %lu)\n"
>+ " recv [path] :"
>+ " Receive file to [path]. Make sure sending is done"
>+ " on the other side.\n",
>+ max_file_size
>+ );
>+
>+}
>+
>+cmdline_parse_token_string_t cmd_help_help =
>+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
>+
>+cmdline_parse_inst_t cmd_help = {
>+ .f = cmd_help_parsed,
>+ .data = NULL,
>+ .help_str = "show help",
>+ .tokens = {
>+ (void *)&cmd_help_help,
>+ NULL,
>+ },
>+};
>+
>+/* *** QUIT *** */
>+struct cmd_quit_result {
>+ cmdline_fixed_string_t quit;
>+};
>+
>+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
>+ struct cmdline *cl,
>+ __attribute__((unused)) void *data)
>+{
>+ /* Stop traffic and Close port. */
>+ rte_rawdev_stop(dev_id);
>+ rte_rawdev_close(dev_id);
>+
>+ cmdline_quit(cl);
>+}
>+
>+cmdline_parse_token_string_t cmd_quit_quit =
>+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
>+
>+cmdline_parse_inst_t cmd_quit = {
>+ .f = cmd_quit_parsed,
>+ .data = NULL,
>+ .help_str = "exit application",
>+ .tokens = {
>+ (void *)&cmd_quit_quit,
>+ NULL,
>+ },
>+};
>+
>+/* *** SEND FILE PARAMETERS *** */
>+struct cmd_sendfile_result {
>+ cmdline_fixed_string_t send_string;
>+ char filepath[];
>+};
>+
>+static void
>+cmd_sendfile_parsed(void *parsed_result,
>+ __attribute__((unused)) struct cmdline *cl,
>+ __attribute__((unused)) void *data)
>+{
>+ struct cmd_sendfile_result *res = parsed_result;
>+ struct rte_rawdev_buf *pkts_send[1];
>+ uint64_t rsize, size, link;
>+ char *filepath;
>+ uint8_t *buff;
>+ uint32_t val;
>+ FILE *file;
>+
>+ if (!rte_rawdevs[dev_id].started)
>+ printf("Device needs to be up first. Try later.\n");
I think we can directly return here when the device is not started, instead of
continuing the execution.
>+
>+ rte_rawdev_get_attr(dev_id, "link_status", &link);
>+ if (!link)
>+ printf("Link is not up, cannot send file.\n");
return if link is down.
>+
>+ filepath = strdup(res->filepath);
>+ if (filepath == NULL) {
>+ printf("Fail to get filepath.\n");
>+ return;
>+ }
>+
>+ file = fopen(filepath, "r");
Actually I was thinking why we need the filepath, why not just
file = fopen(res->filepath, "r")
Then we don't need to handle filepath free at all.
>+ if (!file) {
style 1.8.1
>+ printf("Fail to open the file.\n");
Need to free filepath in this error handling.
>+ return;
>+ }
>+
>+ fseek(file, 0, SEEK_END);
>+ size = ftell(file);
>+ fseek(file, 0, SEEK_SET);
>+
>+ /**
>+ * No FIFO now. Only test memory. Limit sending file
>+ * size <= max_file_size.
>+ */
>+ if (size > max_file_size)
>+ size = max_file_size;
It's better to give the user some reminder info about the max size limition,
rather than truncate the file silently.
>+
>+ buff = (uint8_t *)malloc(size);
>+ rsize = fread(buff, size, 1, file);
>+ if (rsize != 1) {
>+ printf("Fail to read file.\n");
>+ fclose(file);
Need to free filepath and buff.
>+ return;
>+ }
>+
>+ /* Tell remote about the file size. */
>+ val = size >> 32;
>+ rte_rawdev_set_attr(dev_id, "spad14", val);
>+ val = size;
>+ rte_rawdev_set_attr(dev_id, "spad15", val);
>+
>+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
>+ (sizeof(struct rte_rawdev_buf));
>+ pkts_send[0]->buf_addr = buff;
>+ rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1, (void *)size);
May need to check the return value.
>+ printf("Done sending file.\n");
>+
>+ fclose(file);
>+ free((void *)filepath);
Need to free allocated pkts_send[0] and buff.
>+}
>+
>+cmdline_parse_token_string_t cmd_send_file_send =
>+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
>+ "send");
>+cmdline_parse_token_string_t cmd_send_file_filepath =
>+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
>+
>+
>+cmdline_parse_inst_t cmd_send_file = {
>+ .f = cmd_sendfile_parsed,
>+ .data = NULL,
>+ .help_str = "send <file_path>",
>+ .tokens = {
>+ (void *)&cmd_send_file_send,
>+ (void *)&cmd_send_file_filepath,
>+ NULL,
>+ },
>+};
>+
>+/* *** RECEIVE FILE PARAMETERS *** */
>+struct cmd_recvfile_result {
>+ cmdline_fixed_string_t recv_string;
>+ char filepath[];
>+};
>+
>+static void
>+cmd_recvfile_parsed(void *parsed_result,
>+ __attribute__((unused)) struct cmdline *cl,
>+ __attribute__((unused)) void *data)
>+{
>+ struct cmd_sendfile_result *res = parsed_result;
>+ struct rte_rawdev_buf *pkts_recv[1];
>+ uint64_t size, val;
>+ char *filepath;
>+ uint8_t *buff;
>+ FILE *file;
>+
>+ if (!rte_rawdevs[dev_id].started)
>+ printf("Device needs to be up first. Try later.\n");
return directly.
>+
>+ rte_rawdev_get_attr(dev_id, "link_status", &val);
>+ if (!val)
>+ printf("Link is not up, cannot receive file.\n");
return directly.
>+
>+ filepath = strdup(res->filepath);
>+ if (filepath == NULL) {
>+ printf("Fail to get filepath.\n");
>+ return;
>+ }
>+
>+ file = fopen(filepath, "w");
>+ if (!file) {
style 1.8.1
>+ printf("Fail to open the file.\n");
>+ return;
>+ }
>+
>+ rte_rawdev_get_attr(dev_id, "spad14", &val);
>+ size = val << 32;
>+ rte_rawdev_get_attr(dev_id, "spad15", &val);
>+ size |= val;
>+
>+ buff = (uint8_t *)malloc(size);
>+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
>+ (sizeof(struct rte_rawdev_buf));
>+ pkts_recv[0]->buf_addr = buff;
>+
>+ rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size);
>+
>+ fwrite(buff, size, 1, file);
>+ printf("Done receiving to file.\n");
>+
>+ fclose(file);
>+ free((void *)filepath);
free buff and pkts_recv[0] as well.
I noticed that there are two allocations, one for pkts_recv[0] and another for
pkts_recv[0]->buf_addr, How about we declare
struct rte_rawdev_buf pkts_recv[1];
and allocate memory for its buf_addr
pkts_recv[0].buf_addr = malloc(size);
then we call
rte_rawdev_dequeue_buffers(dev_id, &pkts_recv, 1, (void *)size);
After that, we just need to free once.
free(pkts_recv[0].buf_addr);
>+}
>+
>+cmdline_parse_token_string_t cmd_recv_file_recv =
>+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
>+ "recv");
>+cmdline_parse_token_string_t cmd_recv_file_filepath =
>+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
>+
>+
>+cmdline_parse_inst_t cmd_recv_file = {
>+ .f = cmd_recvfile_parsed,
>+ .data = NULL,
>+ .help_str = "recv <file_path>",
>+ .tokens = {
>+ (void *)&cmd_recv_file_recv,
>+ (void *)&cmd_recv_file_filepath,
>+ NULL,
>+ },
>+};
>+
>+/* list of instructions */
>+cmdline_parse_ctx_t main_ctx[] = {
>+ (cmdline_parse_inst_t *)&cmd_help,
>+ (cmdline_parse_inst_t *)&cmd_send_file,
>+ (cmdline_parse_inst_t *)&cmd_recv_file,
>+ (cmdline_parse_inst_t *)&cmd_quit,
>+ NULL,
>+};
>+
>+/* prompt function, called from main on MASTER lcore */
>+static void
>+prompt(void)
>+{
>+ struct cmdline *cl;
>+
>+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
>+ if (cl == NULL)
>+ return;
>+
>+ cmdline_interact(cl);
>+ cmdline_stdin_exit(cl);
>+}
>+
>+static void
>+signal_handler(int signum)
>+{
>+ if (signum == SIGINT || signum == SIGTERM) {
>+ printf("\nSignal %d received, preparing to exit...\n", signum);
>+ signal(signum, SIG_DFL);
>+ kill(getpid(), signum);
>+ }
>+}
>+
>+static void
>+ntb_usage(const char *prgname)
>+{
>+ printf("%s [EAL options] -- [options]\n"
>+ "-i : run in interactive mode (default value is 1)\n",
>+ prgname);
>+}
>+
>+static int
>+parse_args(int argc, char **argv)
>+{
>+ char *prgname = argv[0], **argvopt = argv;
>+ int opt, ret;
>+
>+ /* Only support interactive mode to send/recv file first. */
>+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
>+ switch (opt) {
>+ case 'i':
>+ printf("Interactive-mode selected\n");
>+ interactive = 1;
>+ break;
>+
>+ default:
>+ ntb_usage(prgname);
>+ return -1;
>+ }
>+ }
>+
>+ if (optind >= 0)
>+ argv[optind-1] = prgname;
>+
>+ ret = optind-1;
>+ optind = 1; /* reset getopt lib */
>+ return ret;
>+}
>+
>+int
>+main(int argc, char **argv)
>+{
>+ int ret, i;
>+
>+ signal(SIGINT, signal_handler);
>+ signal(SIGTERM, signal_handler);
>+
>+ ret = rte_eal_init(argc, argv);
>+ if (ret < 0)
>+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
>+
>+ /* Find 1st ntb rawdev. */
>+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
>+ if (rte_rawdevs[i].driver_name &&
>+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb", 7) == 0) &&
Use Macro for the 7.
>+ (rte_rawdevs[i].attached == 1))
>+ break;
>+
>+ if (i == RTE_RAWDEV_MAX_DEVS)
>+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
>+
>+ dev_id = i;
>+
>+ argc -= ret;
>+ argv += ret;
>+
>+ ret = parse_args(argc, argv);
>+ if (ret < 0)
>+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
>+
>+ rte_rawdev_start(dev_id);
>+
>+ if (interactive) {
>+ sleep(1);
>+ prompt();
>+ }
>+
>+ return 0;
>+}
>--
>2.17.1
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-03 8:46 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-04 7:53 ` Jerin Jacob Kollanukkaran
2019-06-04 8:16 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Jerin Jacob Kollanukkaran @ 2019-06-04 7:53 UTC (permalink / raw)
To: Xiaoyun Li, jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Xiaoyun Li
> Sent: Monday, June 3, 2019 2:16 PM
> To: jingjing.wu@intel.com; keith.wiles@intel.com; cunming.liang@intel.com;
> omkar.maslekar@intel.com
> Cc: dev@dpdk.org; Xiaoyun Li <xiaoyun.li@intel.com>
> Subject: [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support
> for ntb
>
> In order to allow binding/unbinding of devices for use by the ntb_rawdev,
> we need to update the devbind script to add a new class of device, and add
> device ids for the specific HW instances. And only support skx platform right
> now.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> ---
> usertools/dpdk-devbind.py | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py index
> 9e79f0d28..470869ff3 100755
> --- a/usertools/dpdk-devbind.py
> +++ b/usertools/dpdk-devbind.py
> @@ -36,11 +36,15 @@
> octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
> 'SVendor': None, 'SDevice': None}
>
> +intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
> + 'SVendor': None, 'SDevice': None}
> +
> network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
> crypto_devices = [encryption_class, intel_processor_class]
> eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
> mempool_devices = [cavium_fpa, octeontx2_npa] compress_devices =
> [cavium_zip]
> +ntb_devices = [intel_ntb_skx]
>
> # global dict ethernet devices present. Dictionary indexed by PCI address.
> # Each device within this is itself a dictionary of device properties @@ -595,6
> +599,9 @@ def show_status():
> if status_dev == "compress" or status_dev == "all":
> show_device_status(compress_devices , "Compress")
>
> + if status_dev == "ntb" or status_dev == "all":
> + show_device_status(ntb_devices , "NTB")
Please change ntb to some generic name. it look like it is the product name, does not reflect the
device type. How about, "communication devices" or any generic name appropriate for ntb.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-04 6:48 ` Ye Xiaolong
@ 2019-06-04 8:12 ` Li, Xiaoyun
2019-06-05 8:32 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-04 8:12 UTC (permalink / raw)
To: Ye, Xiaolong
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
OK. Will fix them in next version including other patches' comments. Thanks.
> -----Original Message-----
> From: Ye, Xiaolong
> Sent: Tuesday, June 4, 2019 14:48
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
>
> On 06/03, Xiaoyun Li wrote:
> >Enable an example for rawdev ntb. Support interactive mode to send file
> >on one host and receive file from another host. The command line would
> >be 'send [filepath]' and 'receive [filepath]'.
> >
> >But since the FIFO is not enabled right now, use rte_memcpy as the
> >enqueue and dequeue functions and only support transmitting file no more
> than 4M.
> >
> >Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> >---
> > drivers/raw/ntb_rawdev/ntb_rawdev.c | 25 +-
> > examples/Makefile | 1 +
> > examples/meson.build | 21 +-
> > examples/ntb/Makefile | 68 ++++++
> > examples/ntb/meson.build | 16 ++
> > examples/ntb/ntb_fwd.c | 364 ++++++++++++++++++++++++++++
> > 6 files changed, 477 insertions(+), 18 deletions(-) create mode
> >100644 examples/ntb/Makefile create mode 100644
> >examples/ntb/meson.build create mode 100644 examples/ntb/ntb_fwd.c
> >
> >diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c
> >b/drivers/raw/ntb_rawdev/ntb_rawdev.c
> >index 35bc34c54..1824842f2 100644
> >--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
> >+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
> >@@ -212,11 +212,16 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
> > unsigned int count,
> > rte_rawdev_obj_t context)
> > {
> >- RTE_SET_USED(dev);
> >- RTE_SET_USED(buffers);
> >- RTE_SET_USED(count);
> >- RTE_SET_USED(context);
> >+ /* Not FIFO right now. Just for test memory write. */
> >+ struct ntb_hw *hw = dev->dev_private;
> >+ uint64_t bar_addr, size;
> >+ unsigned int i;
> >+
> >+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
>
> check the func pointer before calling it.
>
> >+ size = (uint64_t)context;
> >
> >+ for (i = 0; i < count; i++)
> >+ rte_memcpy((void *)bar_addr, buffers[i]->buf_addr, size);
> > return 0;
> > }
> >
> >@@ -226,11 +231,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
> > unsigned int count,
> > rte_rawdev_obj_t context)
> > {
> >- RTE_SET_USED(dev);
> >- RTE_SET_USED(buffers);
> >- RTE_SET_USED(count);
> >- RTE_SET_USED(context);
> >+ /* Not FIFO. Just for test memory read. */
> >+ struct ntb_hw *hw = dev->dev_private;
> >+ uint64_t size;
> >+ unsigned int i;
> >+
> >+ size = (uint64_t)context;
> >
> >+ for (i = 0; i < count; i++)
> >+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
> > return 0;
> > }
> >
> >diff --git a/examples/Makefile b/examples/Makefile index
> >7562424d9..de11dd487 100644
> >--- a/examples/Makefile
> >+++ b/examples/Makefile
> >@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
> > DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer DIRS-y +=
> >multi_process DIRS-y += netmap_compat/bridge
> >+DIRS-y += ntb
> > DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering ifeq
> >($(CONFIG_RTE_ARCH_X86_64),y) DIRS-y += performance-thread diff --git
> >a/examples/meson.build b/examples/meson.build index
> >de35656d4..dda4a07a8 100644
> >--- a/examples/meson.build
> >+++ b/examples/meson.build
> >@@ -25,16 +25,17 @@ all_examples = [
> > 'l3fwd-acl', 'l3fwd-power',
> > 'l3fwd-vf', 'link_status_interrupt',
> > 'load_balancer', 'multi_process',
> >- 'netmap_compat', 'packet_ordering',
> >- 'performance-thread', 'ptpclient',
> >- 'qos_meter', 'qos_sched',
> >- 'quota_watermark', 'rxtx_callbacks',
> >- 'server_node_efd', 'service_cores',
> >- 'skeleton', 'tep_termination',
> >- 'timer', 'vdpa',
> >- 'vhost', 'vhost_crypto',
> >- 'vhost_scsi', 'vm_power_manager',
> >- 'vmdq', 'vmdq_dcb',
> >+ 'netmap_compat', 'ntb',
> >+ 'packet_ordering', 'performance-thread',
> >+ 'ptpclient', 'qos_meter',
> >+ 'qos_sched', 'quota_watermark',
> >+ 'rxtx_callbacks', 'server_node_efd',
> >+ 'service_cores', 'skeleton',
> >+ 'tep_termination', 'timer',
> >+ 'vdpa', 'vhost',
> >+ 'vhost_crypto', 'vhost_scsi',
> >+ 'vm_power_manager', 'vmdq',
> >+ 'vmdq_dcb',
> > ]
> > # install all example code on install - irrespective of whether the
> >example in # question is to be built as part of this build or not.
> >diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile new file
> >mode 100644 index 000000000..5ddd9b95f
> >--- /dev/null
> >+++ b/examples/ntb/Makefile
> >@@ -0,0 +1,68 @@
> >+# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2019 Intel
> >+Corporation
> >+
> >+# binary name
> >+APP = ntb_fwd
> >+
> >+# all source are stored in SRCS-y
> >+SRCS-y := ntb_fwd.c
> >+
> >+# Build using pkg-config variables if possible $(shell pkg-config
> >+--exists libdpdk) ifeq ($(.SHELLSTATUS),0)
> >+
> >+all: shared
> >+.PHONY: shared static
> >+shared: build/$(APP)-shared
> >+ ln -sf $(APP)-shared build/$(APP)
> >+static: build/$(APP)-static
> >+ ln -sf $(APP)-static build/$(APP)
> >+
> >+CFLAGS += -D_FILE_OFFSET_BITS=64
> >+LDFLAGS += -pthread
> >+
> >+PC_FILE := $(shell pkg-config --path libdpdk) CFLAGS += -O3 $(shell
> >+pkg-config --cflags libdpdk) LDFLAGS_SHARED = $(shell pkg-config
> >+--libs libdpdk) LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config
> >+--static --libs libdpdk)
> >+
> >+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
> >+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
> >+
> >+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
> >+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
> >+
> >+build:
> >+ @mkdir -p $@
> >+
> >+.PHONY: clean
> >+clean:
> >+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
> >+ rmdir --ignore-fail-on-non-empty build
> >+
> >+else # Build using legacy build system
> >+
> >+ifeq ($(RTE_SDK),)
> >+$(error "Please define RTE_SDK environment variable") endif
> >+
> >+# Default target, can be overridden by command line or environment
> >+RTE_TARGET ?= x86_64-native-linuxapp-gcc
> >+
> >+include $(RTE_SDK)/mk/rte.vars.mk
> >+
> >+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
> >+$(info This application can only operate in a linuxapp environment, \
> >+please change the definition of the RTE_TARGET environment variable)
> >+all:
> >+else
> >+
> >+CFLAGS += -D_FILE_OFFSET_BITS=64
> >+CFLAGS += -O2
> >+CFLAGS += $(WERROR_FLAGS)
> >+CFLAGS += -DALLOW_EXPERIMENTAL_API
> >+
> >+include $(RTE_SDK)/mk/rte.extapp.mk
> >+
> >+endif
> >+endif
> >diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build new
> >file mode 100644 index 000000000..9a6288f4f
> >--- /dev/null
> >+++ b/examples/ntb/meson.build
> >@@ -0,0 +1,16 @@
> >+# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2019 Intel
> >+Corporation
> >+
> >+# meson file, for building this example as part of a main DPDK build.
> >+#
> >+# To build this example as a standalone application with an
> >+already-installed # DPDK instance, use 'make'
> >+
> >+if host_machine.system() != 'linux'
> >+ build = false
> >+endif
> >+deps += 'rawdev'
> >+cflags += ['-D_FILE_OFFSET_BITS=64']
> >+sources = files(
> >+ 'ntb_fwd.c'
> >+)
> >diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c new file
> >mode 100644 index 000000000..7835d817a
> >--- /dev/null
> >+++ b/examples/ntb/ntb_fwd.c
> >@@ -0,0 +1,364 @@
> >+/* SPDX-License-Identifier: BSD-3-Clause
> >+ * Copyright(c) 2019 Intel Corporation */ #include <stdint.h>
> >+#include <stdio.h> #include <unistd.h> #include <signal.h> #include
> >+<string.h> #include <getopt.h>
> >+
> >+#include <cmdline_parse_string.h>
> >+#include <cmdline_socket.h>
> >+#include <cmdline.h>
> >+#include <rte_common.h>
> >+#include <rte_rawdev.h>
> >+#include <rte_lcore.h>
> >+
> >+static uint64_t max_file_size = 0x400000; static uint8_t interactive =
> >+1; static uint16_t dev_id;
> >+
> >+/* *** Help command with introduction. *** */ struct cmd_help_result {
> >+ cmdline_fixed_string_t help;
> >+};
> >+
> >+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
> >+ struct cmdline *cl,
> >+ __attribute__((unused)) void *data) {
> >+ cmdline_printf(
> >+ cl,
> >+ "\n"
> >+ "The following commands are currently available:\n\n"
> >+ "Control:\n"
> >+ " quit :"
> >+ " Quit the application.\n"
> >+ "\nFile transmit:\n"
> >+ " send [path] :"
> >+ " Send [path] file. (No more than %lu)\n"
> >+ " recv [path] :"
> >+ " Receive file to [path]. Make sure sending is done"
> >+ " on the other side.\n",
> >+ max_file_size
> >+ );
> >+
> >+}
> >+
> >+cmdline_parse_token_string_t cmd_help_help =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
> >+
> >+cmdline_parse_inst_t cmd_help = {
> >+ .f = cmd_help_parsed,
> >+ .data = NULL,
> >+ .help_str = "show help",
> >+ .tokens = {
> >+ (void *)&cmd_help_help,
> >+ NULL,
> >+ },
> >+};
> >+
> >+/* *** QUIT *** */
> >+struct cmd_quit_result {
> >+ cmdline_fixed_string_t quit;
> >+};
> >+
> >+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
> >+ struct cmdline *cl,
> >+ __attribute__((unused)) void *data) {
> >+ /* Stop traffic and Close port. */
> >+ rte_rawdev_stop(dev_id);
> >+ rte_rawdev_close(dev_id);
> >+
> >+ cmdline_quit(cl);
> >+}
> >+
> >+cmdline_parse_token_string_t cmd_quit_quit =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
> "quit");
> >+
> >+cmdline_parse_inst_t cmd_quit = {
> >+ .f = cmd_quit_parsed,
> >+ .data = NULL,
> >+ .help_str = "exit application",
> >+ .tokens = {
> >+ (void *)&cmd_quit_quit,
> >+ NULL,
> >+ },
> >+};
> >+
> >+/* *** SEND FILE PARAMETERS *** */
> >+struct cmd_sendfile_result {
> >+ cmdline_fixed_string_t send_string;
> >+ char filepath[];
> >+};
> >+
> >+static void
> >+cmd_sendfile_parsed(void *parsed_result,
> >+ __attribute__((unused)) struct cmdline *cl,
> >+ __attribute__((unused)) void *data) {
> >+ struct cmd_sendfile_result *res = parsed_result;
> >+ struct rte_rawdev_buf *pkts_send[1];
> >+ uint64_t rsize, size, link;
> >+ char *filepath;
> >+ uint8_t *buff;
> >+ uint32_t val;
> >+ FILE *file;
> >+
> >+ if (!rte_rawdevs[dev_id].started)
> >+ printf("Device needs to be up first. Try later.\n");
>
> I think we can directly return here when the device is not started, instead of
> continuing the execution.
>
> >+
> >+ rte_rawdev_get_attr(dev_id, "link_status", &link);
> >+ if (!link)
> >+ printf("Link is not up, cannot send file.\n");
>
> return if link is down.
>
> >+
> >+ filepath = strdup(res->filepath);
> >+ if (filepath == NULL) {
> >+ printf("Fail to get filepath.\n");
> >+ return;
> >+ }
> >+
> >+ file = fopen(filepath, "r");
>
> Actually I was thinking why we need the filepath, why not just
>
> file = fopen(res->filepath, "r")
>
> Then we don't need to handle filepath free at all.
>
> >+ if (!file) {
>
> style 1.8.1
>
> >+ printf("Fail to open the file.\n");
>
> Need to free filepath in this error handling.
>
> >+ return;
> >+ }
> >+
> >+ fseek(file, 0, SEEK_END);
> >+ size = ftell(file);
> >+ fseek(file, 0, SEEK_SET);
> >+
> >+ /**
> >+ * No FIFO now. Only test memory. Limit sending file
> >+ * size <= max_file_size.
> >+ */
> >+ if (size > max_file_size)
> >+ size = max_file_size;
>
> It's better to give the user some reminder info about the max size limition,
> rather than truncate the file silently.
>
> >+
> >+ buff = (uint8_t *)malloc(size);
> >+ rsize = fread(buff, size, 1, file);
> >+ if (rsize != 1) {
> >+ printf("Fail to read file.\n");
> >+ fclose(file);
>
> Need to free filepath and buff.
>
> >+ return;
> >+ }
> >+
> >+ /* Tell remote about the file size. */
> >+ val = size >> 32;
> >+ rte_rawdev_set_attr(dev_id, "spad14", val);
> >+ val = size;
> >+ rte_rawdev_set_attr(dev_id, "spad15", val);
> >+
> >+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
> >+ (sizeof(struct rte_rawdev_buf));
> >+ pkts_send[0]->buf_addr = buff;
> >+ rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1, (void *)size);
>
> May need to check the return value.
>
> >+ printf("Done sending file.\n");
> >+
> >+ fclose(file);
> >+ free((void *)filepath);
>
> Need to free allocated pkts_send[0] and buff.
>
> >+}
> >+
> >+cmdline_parse_token_string_t cmd_send_file_send =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
> >+ "send");
> >+cmdline_parse_token_string_t cmd_send_file_filepath =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
> >+
> >+
> >+cmdline_parse_inst_t cmd_send_file = {
> >+ .f = cmd_sendfile_parsed,
> >+ .data = NULL,
> >+ .help_str = "send <file_path>",
> >+ .tokens = {
> >+ (void *)&cmd_send_file_send,
> >+ (void *)&cmd_send_file_filepath,
> >+ NULL,
> >+ },
> >+};
> >+
> >+/* *** RECEIVE FILE PARAMETERS *** */
> >+struct cmd_recvfile_result {
> >+ cmdline_fixed_string_t recv_string;
> >+ char filepath[];
> >+};
> >+
> >+static void
> >+cmd_recvfile_parsed(void *parsed_result,
> >+ __attribute__((unused)) struct cmdline *cl,
> >+ __attribute__((unused)) void *data) {
> >+ struct cmd_sendfile_result *res = parsed_result;
> >+ struct rte_rawdev_buf *pkts_recv[1];
> >+ uint64_t size, val;
> >+ char *filepath;
> >+ uint8_t *buff;
> >+ FILE *file;
> >+
> >+ if (!rte_rawdevs[dev_id].started)
> >+ printf("Device needs to be up first. Try later.\n");
>
> return directly.
>
> >+
> >+ rte_rawdev_get_attr(dev_id, "link_status", &val);
> >+ if (!val)
> >+ printf("Link is not up, cannot receive file.\n");
>
> return directly.
>
> >+
> >+ filepath = strdup(res->filepath);
> >+ if (filepath == NULL) {
> >+ printf("Fail to get filepath.\n");
> >+ return;
> >+ }
> >+
> >+ file = fopen(filepath, "w");
> >+ if (!file) {
>
> style 1.8.1
>
> >+ printf("Fail to open the file.\n");
> >+ return;
> >+ }
> >+
> >+ rte_rawdev_get_attr(dev_id, "spad14", &val);
> >+ size = val << 32;
> >+ rte_rawdev_get_attr(dev_id, "spad15", &val);
> >+ size |= val;
> >+
> >+ buff = (uint8_t *)malloc(size);
> >+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
> >+ (sizeof(struct rte_rawdev_buf));
> >+ pkts_recv[0]->buf_addr = buff;
> >+
> >+ rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size);
> >+
> >+ fwrite(buff, size, 1, file);
> >+ printf("Done receiving to file.\n");
> >+
> >+ fclose(file);
> >+ free((void *)filepath);
>
> free buff and pkts_recv[0] as well.
>
> I noticed that there are two allocations, one for pkts_recv[0] and another for
> pkts_recv[0]->buf_addr, How about we declare
>
> struct rte_rawdev_buf pkts_recv[1];
>
> and allocate memory for its buf_addr
>
> pkts_recv[0].buf_addr = malloc(size);
>
> then we call
>
> rte_rawdev_dequeue_buffers(dev_id, &pkts_recv, 1, (void *)size);
>
> After that, we just need to free once.
>
> free(pkts_recv[0].buf_addr);
>
>
> >+}
> >+
> >+cmdline_parse_token_string_t cmd_recv_file_recv =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
> >+ "recv");
> >+cmdline_parse_token_string_t cmd_recv_file_filepath =
> >+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
> >+
> >+
> >+cmdline_parse_inst_t cmd_recv_file = {
> >+ .f = cmd_recvfile_parsed,
> >+ .data = NULL,
> >+ .help_str = "recv <file_path>",
> >+ .tokens = {
> >+ (void *)&cmd_recv_file_recv,
> >+ (void *)&cmd_recv_file_filepath,
> >+ NULL,
> >+ },
> >+};
> >+
> >+/* list of instructions */
> >+cmdline_parse_ctx_t main_ctx[] = {
> >+ (cmdline_parse_inst_t *)&cmd_help,
> >+ (cmdline_parse_inst_t *)&cmd_send_file,
> >+ (cmdline_parse_inst_t *)&cmd_recv_file,
> >+ (cmdline_parse_inst_t *)&cmd_quit,
> >+ NULL,
> >+};
> >+
> >+/* prompt function, called from main on MASTER lcore */ static void
> >+prompt(void)
> >+{
> >+ struct cmdline *cl;
> >+
> >+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
> >+ if (cl == NULL)
> >+ return;
> >+
> >+ cmdline_interact(cl);
> >+ cmdline_stdin_exit(cl);
> >+}
> >+
> >+static void
> >+signal_handler(int signum)
> >+{
> >+ if (signum == SIGINT || signum == SIGTERM) {
> >+ printf("\nSignal %d received, preparing to exit...\n", signum);
> >+ signal(signum, SIG_DFL);
> >+ kill(getpid(), signum);
> >+ }
> >+}
> >+
> >+static void
> >+ntb_usage(const char *prgname)
> >+{
> >+ printf("%s [EAL options] -- [options]\n"
> >+ "-i : run in interactive mode (default value is 1)\n",
> >+ prgname);
> >+}
> >+
> >+static int
> >+parse_args(int argc, char **argv)
> >+{
> >+ char *prgname = argv[0], **argvopt = argv;
> >+ int opt, ret;
> >+
> >+ /* Only support interactive mode to send/recv file first. */
> >+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
> >+ switch (opt) {
> >+ case 'i':
> >+ printf("Interactive-mode selected\n");
> >+ interactive = 1;
> >+ break;
> >+
> >+ default:
> >+ ntb_usage(prgname);
> >+ return -1;
> >+ }
> >+ }
> >+
> >+ if (optind >= 0)
> >+ argv[optind-1] = prgname;
> >+
> >+ ret = optind-1;
> >+ optind = 1; /* reset getopt lib */
> >+ return ret;
> >+}
> >+
> >+int
> >+main(int argc, char **argv)
> >+{
> >+ int ret, i;
> >+
> >+ signal(SIGINT, signal_handler);
> >+ signal(SIGTERM, signal_handler);
> >+
> >+ ret = rte_eal_init(argc, argv);
> >+ if (ret < 0)
> >+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
> >+
> >+ /* Find 1st ntb rawdev. */
> >+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
> >+ if (rte_rawdevs[i].driver_name &&
> >+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb", 7) == 0) &&
>
> Use Macro for the 7.
>
> >+ (rte_rawdevs[i].attached == 1))
> >+ break;
> >+
> >+ if (i == RTE_RAWDEV_MAX_DEVS)
> >+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
> >+
> >+ dev_id = i;
> >+
> >+ argc -= ret;
> >+ argv += ret;
> >+
> >+ ret = parse_args(argc, argv);
> >+ if (ret < 0)
> >+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
> >+
> >+ rte_rawdev_start(dev_id);
> >+
> >+ if (interactive) {
> >+ sleep(1);
> >+ prompt();
> >+ }
> >+
> >+ return 0;
> >+}
> >--
> >2.17.1
> >
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-04 7:53 ` Jerin Jacob Kollanukkaran
@ 2019-06-04 8:16 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-04 8:16 UTC (permalink / raw)
To: Jerin Jacob Kollanukkaran, Wu, Jingjing, Wiles, Keith, Liang,
Cunming, Maslekar, Omkar
Cc: dev
OK. "communication devices" seems a good option but a little long.
Will think if there is another choice. If not, will use it. Thanks.
> -----Original Message-----
> From: Jerin Jacob Kollanukkaran [mailto:jerinj@marvell.com]
> Sent: Tuesday, June 4, 2019 15:54
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Wiles, Keith <keith.wiles@intel.com>; Liang, Cunming
> <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support for
> ntb
>
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Xiaoyun Li
> > Sent: Monday, June 3, 2019 2:16 PM
> > To: jingjing.wu@intel.com; keith.wiles@intel.com;
> > cunming.liang@intel.com; omkar.maslekar@intel.com
> > Cc: dev@dpdk.org; Xiaoyun Li <xiaoyun.li@intel.com>
> > Subject: [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support
> > for ntb
> >
> > In order to allow binding/unbinding of devices for use by the
> > ntb_rawdev, we need to update the devbind script to add a new class of
> > device, and add device ids for the specific HW instances. And only
> > support skx platform right now.
> >
> > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> > ---
> > usertools/dpdk-devbind.py | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
> > index
> > 9e79f0d28..470869ff3 100755
> > --- a/usertools/dpdk-devbind.py
> > +++ b/usertools/dpdk-devbind.py
> > @@ -36,11 +36,15 @@
> > octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
> > 'SVendor': None, 'SDevice': None}
> >
> > +intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
> > + 'SVendor': None, 'SDevice': None}
> > +
> > network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
> > crypto_devices = [encryption_class, intel_processor_class]
> > eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
> > mempool_devices = [cavium_fpa, octeontx2_npa] compress_devices =
> > [cavium_zip]
> > +ntb_devices = [intel_ntb_skx]
> >
> > # global dict ethernet devices present. Dictionary indexed by PCI address.
> > # Each device within this is itself a dictionary of device properties
> > @@ -595,6
> > +599,9 @@ def show_status():
> > if status_dev == "compress" or status_dev == "all":
> > show_device_status(compress_devices , "Compress")
> >
> > + if status_dev == "ntb" or status_dev == "all":
> > + show_device_status(ntb_devices , "NTB")
>
>
> Please change ntb to some generic name. it look like it is the product name,
> does not reflect the device type. How about, "communication devices" or any
> generic name appropriate for ntb.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-03 8:46 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-04 6:48 ` Ye Xiaolong
@ 2019-06-04 8:48 ` Ye Xiaolong
2019-06-05 3:11 ` Li, Xiaoyun
1 sibling, 1 reply; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-04 8:48 UTC (permalink / raw)
To: Xiaoyun Li; +Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev
On 06/03, Xiaoyun Li wrote:
>Enable an example for rawdev ntb. Support interactive mode to send
>file on one host and receive file from another host. The command line
>would be 'send [filepath]' and 'receive [filepath]'.
>
>But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
>and dequeue functions and only support transmitting file no more than 4M.
>
>Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
[snip]
>---
>+
>+int
>+main(int argc, char **argv)
>+{
>+ int ret, i;
>+
>+ signal(SIGINT, signal_handler);
>+ signal(SIGTERM, signal_handler);
>+
>+ ret = rte_eal_init(argc, argv);
>+ if (ret < 0)
>+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
>+
>+ /* Find 1st ntb rawdev. */
>+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
>+ if (rte_rawdevs[i].driver_name &&
>+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb", 7) == 0) &&
>+ (rte_rawdevs[i].attached == 1))
>+ break;
Can replace above code block with rawdev API rte_rawdev_get_dev_id.
Thanks,
Xiaolong
>+
>+ if (i == RTE_RAWDEV_MAX_DEVS)
>+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
>+
>+ dev_id = i;
>+
>+ argc -= ret;
>+ argv += ret;
>+
>+ ret = parse_args(argc, argv);
>+ if (ret < 0)
>+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
>+
>+ rte_rawdev_start(dev_id);
>+
>+ if (interactive) {
>+ sleep(1);
>+ prompt();
>+ }
>+
>+ return 0;
>+}
>--
>2.17.1
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-04 8:48 ` Ye Xiaolong
@ 2019-06-05 3:11 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-05 3:11 UTC (permalink / raw)
To: Ye, Xiaolong
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
Hi
> -----Original Message-----
> From: Ye, Xiaolong
> Sent: Tuesday, June 4, 2019 16:49
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
> > [snip]
>
> >---
> >+
> >+int
> >+main(int argc, char **argv)
> >+{
> >+ int ret, i;
> >+
> >+ signal(SIGINT, signal_handler);
> >+ signal(SIGTERM, signal_handler);
> >+
> >+ ret = rte_eal_init(argc, argv);
> >+ if (ret < 0)
> >+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
> >+
> >+ /* Find 1st ntb rawdev. */
> >+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
> >+ if (rte_rawdevs[i].driver_name &&
> >+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb", 7) == 0) &&
> >+ (rte_rawdevs[i].attached == 1))
> >+ break;
>
> Can replace above code block with rawdev API rte_rawdev_get_dev_id.
>
In fact, I've considered this API. But this API uses name (device name) not driver name to identify device and it uses strcmp not strncmp.
But I want the first device who driver is ''raw_ntb". The device name is set to "NTB:[bus]:[dev].[func]" which is specific to the device.
> Thanks,
> Xiaolong
>
> >+
> >+ if (i == RTE_RAWDEV_MAX_DEVS)
> >+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
> >+
> >+ dev_id = i;
> >+
> >+ argc -= ret;
> >+ argv += ret;
> >+
> >+ ret = parse_args(argc, argv);
> >+ if (ret < 0)
> >+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
> >+
> >+ rte_rawdev_start(dev_id);
> >+
> >+ if (interactive) {
> >+ sleep(1);
> >+ prompt();
> >+ }
> >+
> >+ return 0;
> >+}
> >--
> >2.17.1
> >
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-04 8:12 ` Li, Xiaoyun
@ 2019-06-05 8:32 ` Li, Xiaoyun
2019-06-05 9:25 ` Ye Xiaolong
0 siblings, 1 reply; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-05 8:32 UTC (permalink / raw)
To: Li, Xiaoyun, Ye, Xiaolong
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
Hi
> > I noticed that there are two allocations, one for pkts_recv[0] and another for
> > pkts_recv[0]->buf_addr, How about we declare
> >
> > struct rte_rawdev_buf pkts_recv[1];
> >
> > and allocate memory for its buf_addr
> >
> > pkts_recv[0].buf_addr = malloc(size);
> >
> > then we call
> >
> > rte_rawdev_dequeue_buffers(dev_id, &pkts_recv, 1, (void *)size);
> >
> > After that, we just need to free once.
> >
> > free(pkts_recv[0].buf_addr);
> >
Double pointer does not represent 2D arrays. Please refer to
https://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays
It will cause segment fault in enqueue/dequeue.
I will free twice.
> > >2.17.1
> > >
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-05 8:32 ` Li, Xiaoyun
@ 2019-06-05 9:25 ` Ye Xiaolong
2019-06-05 13:36 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-05 9:25 UTC (permalink / raw)
To: Li, Xiaoyun
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
On 06/05, Li, Xiaoyun wrote:
>Hi
>> > I noticed that there are two allocations, one for pkts_recv[0] and another for
>> > pkts_recv[0]->buf_addr, How about we declare
>> >
>> > struct rte_rawdev_buf pkts_recv[1];
>> >
>> > and allocate memory for its buf_addr
>> >
>> > pkts_recv[0].buf_addr = malloc(size);
>> >
>> > then we call
>> >
>> > rte_rawdev_dequeue_buffers(dev_id, &pkts_recv, 1, (void *)size);
>> >
>> > After that, we just need to free once.
>> >
>> > free(pkts_recv[0].buf_addr);
>> >
>
>Double pointer does not represent 2D arrays. Please refer to
>https://stackoverflow.com/questions/4470950/why-cant-we-use-double-pointer-to-represent-two-dimensional-arrays
>
Yes, I agree, but I don't think it is the case here.
>It will cause segment fault in enqueue/dequeue.
Hmm, have you debug it? Which line caused the segfault?
You can refer to test_rawdev_enqdeq function in skeleton_rawdev_test.c, what it
does is similar to my suggestion, and you just need one alloc/free.
Thanks,
Xiaolong
>
>I will free twice.
>
>> > >2.17.1
>> > >
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-05 9:25 ` Ye Xiaolong
@ 2019-06-05 13:36 ` Li, Xiaoyun
2019-06-06 2:07 ` Ye Xiaolong
0 siblings, 1 reply; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-05 13:36 UTC (permalink / raw)
To: Ye, Xiaolong
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
>
> Yes, I agree, but I don't think it is the case here.
>
> >It will cause segment fault in enqueue/dequeue.
>
> Hmm, have you debug it? Which line caused the segfault?
>
> You can refer to test_rawdev_enqdeq function in skeleton_rawdev_test.c, what
> it does is similar to my suggestion, and you just need one alloc/free.
>
Of course I debug on it. It will cause seg fault at rte_memcpy. Because buffers[0]->buf_addr is not right.
You can see the debug log.
(gdb) p test_pkts_send[0].buf_addr
$3 = (void *) 0x5555562784c0
(gdb) n
164 rte_rawdev_set_attr(dev_id, "spad14", val);
(gdb)
ntb_attr_set(): Set attribute (spad14) Value (0)
165 val = size;
(gdb)
166 rte_rawdev_set_attr(dev_id, "spad15", val);
(gdb)
ntb_attr_set(): Set attribute (spad15) Value (35)
175 rte_rawdev_enqueue_buffers(dev_id, (struct rte_rawdev_buf **)&test_pkts_send, 1, (void *)size);
(gdb)
Thread 1 "ntb_fwd" hit Breakpoint 2, ntb_enqueue_bufs (dev=0x555556023b80 <rte_rawdevices>, buffers=0x7fffffff7fe0, count=1,
context=0x23) at /home/xiaoyun/ntb/dpdk-next-net-intel/drivers/raw/ntb_rawdev/ntb_rawdev.c:244
244 struct ntb_hw *hw = dev->dev_private;
(gdb) n
248 if (hw->ntb_ops->get_peer_mw_addr == NULL)
(gdb)
249 return -ENOTSUP;
(gdb) p buffers[0]->buf_addr
$4 = (void *) 0x6f77206f6c6c6568
(gdb) p &buffers[0]->buf_addr
$5 = (void **) 0x5555562784c0
> Thanks,
> Xiaolong
>
> >
> >I will free twice.
> >
> >> > >2.17.1
> >> > >
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-05 13:36 ` Li, Xiaoyun
@ 2019-06-06 2:07 ` Ye Xiaolong
0 siblings, 0 replies; 127+ messages in thread
From: Ye Xiaolong @ 2019-06-06 2:07 UTC (permalink / raw)
To: Li, Xiaoyun
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev
On 06/05, Li, Xiaoyun wrote:
>>
>> Yes, I agree, but I don't think it is the case here.
>>
>> >It will cause segment fault in enqueue/dequeue.
>>
>> Hmm, have you debug it? Which line caused the segfault?
>>
>> You can refer to test_rawdev_enqdeq function in skeleton_rawdev_test.c, what
>> it does is similar to my suggestion, and you just need one alloc/free.
>>
>Of course I debug on it. It will cause seg fault at rte_memcpy. Because buffers[0]->buf_addr is not right.
>You can see the debug log.
>(gdb) p test_pkts_send[0].buf_addr
>$3 = (void *) 0x5555562784c0
>(gdb) n
>164 rte_rawdev_set_attr(dev_id, "spad14", val);
>(gdb)
>ntb_attr_set(): Set attribute (spad14) Value (0)
>165 val = size;
>(gdb)
>166 rte_rawdev_set_attr(dev_id, "spad15", val);
>(gdb)
>ntb_attr_set(): Set attribute (spad15) Value (35)
>175 rte_rawdev_enqueue_buffers(dev_id, (struct rte_rawdev_buf **)&test_pkts_send, 1, (void *)size);
>(gdb)
>
>Thread 1 "ntb_fwd" hit Breakpoint 2, ntb_enqueue_bufs (dev=0x555556023b80 <rte_rawdevices>, buffers=0x7fffffff7fe0, count=1,
> context=0x23) at /home/xiaoyun/ntb/dpdk-next-net-intel/drivers/raw/ntb_rawdev/ntb_rawdev.c:244
>244 struct ntb_hw *hw = dev->dev_private;
>(gdb) n
>248 if (hw->ntb_ops->get_peer_mw_addr == NULL)
>(gdb)
>249 return -ENOTSUP;
>(gdb) p buffers[0]->buf_addr
>$4 = (void *) 0x6f77206f6c6c6568
>(gdb) p &buffers[0]->buf_addr
>$5 = (void **) 0x5555562784c0
Hmm, you're right, after a second thought, we do need double alloc/free in this
case, my bad.
Thanks,
Xiaolong
>
>> Thanks,
>> Xiaolong
>>
>> >
>> >I will free twice.
>> >
>> >> > >2.17.1
>> >> > >
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-03 8:46 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb pmd Xiaoyun Li
@ 2019-06-06 7:42 ` Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (7 more replies)
6 siblings, 8 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:42 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 16 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 849 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 21 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 384 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2112 insertions(+), 11 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-06 7:42 ` Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (6 subsequent siblings)
7 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:42 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index 6b96e0e80..44069af7d 100644
--- a/config/common_base
+++ b/config/common_base
@@ -741,6 +741,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..fb40204c1
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..7cd3b831a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ uint64_t (*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 7c9b4b538..4f69ee4a5 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -303,6 +303,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 2/6] raw/ntb: add intel ntb support
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-06 7:42 ` Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 3/6] raw/ntb: add handshake process Xiaoyun Li
` (5 subsequent siblings)
7 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:42 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index fb40204c1..337311ea4 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..66047ac81
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return (uint64_t)(hw->pci_dev->mem_resource[bar].addr);
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 3/6] raw/ntb: add handshake process
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-06 7:43 ` Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (4 subsequent siblings)
7 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:43 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 335 +++++++++++++++++++++++++++-
1 file changed, 334 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..1c29cec68 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: %lx", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,85 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: %lx", i, hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 4/6] examples/ntb: enable an example for ntb
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-06 7:43 ` Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (3 subsequent siblings)
7 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:43 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 27 +-
examples/Makefile | 1 +
examples/meson.build | 21 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 384 ++++++++++++++++++++++++++++
6 files changed, 499 insertions(+), 18 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 1c29cec68..1430bd8f1 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,18 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t bar_addr, size;
+ unsigned int i;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (uint64_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy((void *)bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +261,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t size;
+ unsigned int i;
+
+ size = (uint64_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index de35656d4..dda4a07a8 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -25,16 +25,17 @@ all_examples = [
'l3fwd-acl', 'l3fwd-power',
'l3fwd-vf', 'link_status_interrupt',
'load_balancer', 'multi_process',
- 'netmap_compat', 'packet_ordering',
- 'performance-thread', 'ptpclient',
- 'qos_meter', 'qos_sched',
- 'quota_watermark', 'rxtx_callbacks',
- 'server_node_efd', 'service_cores',
- 'skeleton', 'tep_termination',
- 'timer', 'vdpa',
- 'vhost', 'vhost_crypto',
- 'vhost_scsi', 'vm_power_manager',
- 'vmdq', 'vmdq_dcb',
+ 'netmap_compat', 'ntb',
+ 'packet_ordering', 'performance-thread',
+ 'ptpclient', 'qos_meter',
+ 'qos_sched', 'quota_watermark',
+ 'rxtx_callbacks', 'server_node_efd',
+ 'service_cores', 'skeleton',
+ 'tep_termination', 'timer',
+ 'vdpa', 'vhost',
+ 'vhost_crypto', 'vhost_scsi',
+ 'vm_power_manager', 'vmdq',
+ 'vmdq_dcb',
]
# install all example code on install - irrespective of whether the example in
# question is to be built as part of this build or not.
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..111d06cb9
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,384 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %lu)\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %lu bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1, (void *)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint64_t size, val;
+ uint8_t *buff;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-06 7:43 ` Xiaoyun Li
2019-06-06 8:23 ` Bruce Richardson
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 6/6] doc: update docs for ntb driver Xiaoyun Li
` (2 subsequent siblings)
7 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:43 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..3f7eafe28 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+communication_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "communication" or status_dev == "all":
+ show_device_status(communication_devices , "Communication")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(communication_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(communication_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v2 6/6] doc: update docs for ntb driver
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-06 7:43 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
7 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-06 7:43 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 16 +++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 114 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 15d0829c5..ee43f0c29 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1052,6 +1052,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1428,3 +1432,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index b9510f93a..387973922 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -55,6 +55,22 @@ New Features
=========================================================
+ * **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
+
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-06 8:23 ` Bruce Richardson
2019-06-10 1:38 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Bruce Richardson @ 2019-06-06 8:23 UTC (permalink / raw)
To: Xiaoyun Li
Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev, thomas
On Thu, Jun 06, 2019 at 03:43:02PM +0800, Xiaoyun Li wrote:
> In order to allow binding/unbinding of devices for use by the
> ntb_rawdev, we need to update the devbind script to add a new class
> of device, and add device ids for the specific HW instances. And
> only support skx platform right now.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> ---
> usertools/dpdk-devbind.py | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
> index 9e79f0d28..3f7eafe28 100755
> --- a/usertools/dpdk-devbind.py
> +++ b/usertools/dpdk-devbind.py
> @@ -36,11 +36,15 @@
> octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
> 'SVendor': None, 'SDevice': None}
>
> +intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
> + 'SVendor': None, 'SDevice': None}
> +
> network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
> crypto_devices = [encryption_class, intel_processor_class]
> eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
> mempool_devices = [cavium_fpa, octeontx2_npa]
> compress_devices = [cavium_zip]
> +communication_devices = [intel_ntb_skx]
>
Looking at this patch, and my own rawdev set for adding the ioat driver, I
wonder if it's really a good idea to add new categories for each rawdev
device type. Given we don't know how many device types there will be
overall, I wonder if it's better to just add a "misc" or "other" device
type section, where we put all raw devices.
/Bruce
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-06 8:23 ` Bruce Richardson
@ 2019-06-10 1:38 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-10 1:38 UTC (permalink / raw)
To: Richardson, Bruce
Cc: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar, dev, thomas
Well. Seems a good idea. I don't think there will be too many communication devices or dma devices anyway.
So use misc_devices? I can align with you.
> -----Original Message-----
> From: Richardson, Bruce
> Sent: Thursday, June 6, 2019 16:23
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>; dev@dpdk.org; thomas@monjalon.net
> Subject: Re: [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support
> for ntb
>
> On Thu, Jun 06, 2019 at 03:43:02PM +0800, Xiaoyun Li wrote:
> > In order to allow binding/unbinding of devices for use by the
> > ntb_rawdev, we need to update the devbind script to add a new class of
> > device, and add device ids for the specific HW instances. And only
> > support skx platform right now.
> >
> > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> > ---
> > usertools/dpdk-devbind.py | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
> > index 9e79f0d28..3f7eafe28 100755
> > --- a/usertools/dpdk-devbind.py
> > +++ b/usertools/dpdk-devbind.py
> > @@ -36,11 +36,15 @@
> > octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
> > 'SVendor': None, 'SDevice': None}
> >
> > +intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
> > + 'SVendor': None, 'SDevice': None}
> > +
> > network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
> > crypto_devices = [encryption_class, intel_processor_class]
> > eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
> > mempool_devices = [cavium_fpa, octeontx2_npa] compress_devices =
> > [cavium_zip]
> > +communication devices = [intel_ntb_skx]
> >
>
> Looking at this patch, and my own rawdev set for adding the ioat driver, I
> wonder if it's really a good idea to add new categories for each rawdev device
> type. Given we don't know how many device types there will be overall, I
> wonder if it's better to just add a "misc" or "other" device type section, where
> we put all raw devices.
>
> /Bruce
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 0/6] rawdev driver for ntb
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (5 more replies)
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
7 siblings, 6 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 851 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 387 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2106 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (4 subsequent siblings)
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index e406e7836..45e403130 100644
--- a/config/common_base
+++ b/config/common_base
@@ -746,6 +746,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..fb40204c1
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..a13815a1d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
` (3 subsequent siblings)
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index fb40204c1..337311ea4 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..8a1e9be2a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (2 subsequent siblings)
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..d9088e825 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-11 8:22 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb driver Xiaoyun Li
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 +-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 387 ++++++++++++++++++++++++++++
6 files changed, 493 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index d9088e825..9d7b8c07b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..0f54d0e2d
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-11 8:22 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb driver Xiaoyun Li
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH 6/6] doc: update docs for ntb driver
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-11 8:22 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-11 8:22 ` Xiaoyun Li
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:22 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0212fe6d0..b97cc18ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1056,6 +1056,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1432,3 +1436,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 575c590d9..a4c41a8c1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -72,6 +72,21 @@ New Features
Added the new Shared Memory Packet Interface (``memif``) PMD.
See the :doc:`../nics/memif` guide for more details on this new driver.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
` (6 preceding siblings ...)
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
7 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 851 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 387 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2106 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index e406e7836..45e403130 100644
--- a/config/common_base
+++ b/config/common_base
@@ -746,6 +746,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..fb40204c1
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..a13815a1d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 2/6] raw/ntb: add intel ntb support
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index fb40204c1..337311ea4 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..8a1e9be2a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 3/6] raw/ntb: add handshake process
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..d9088e825 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 4/6] examples/ntb: enable an example for ntb
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 +-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 387 ++++++++++++++++++++++++++++
6 files changed, 493 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index d9088e825..9d7b8c07b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..0f54d0e2d
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v3 6/6] doc: update docs for ntb driver
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-11 8:50 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-11 8:50 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0212fe6d0..b97cc18ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1056,6 +1056,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1432,3 +1436,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 575c590d9..a4c41a8c1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -72,6 +72,21 @@ New Features
Added the new Shared Memory Packet Interface (``memif``) PMD.
See the :doc:`../nics/memif` guide for more details on this new driver.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
6 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 851 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 387 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2106 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index e406e7836..45e403130 100644
--- a/config/common_base
+++ b/config/common_base
@@ -746,6 +746,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..fb40204c1
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..a13815a1d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 2/6] raw/ntb: add intel ntb support
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index fb40204c1..337311ea4 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..8a1e9be2a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 3/6] raw/ntb: add handshake process
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..d9088e825 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 4/6] examples/ntb: enable an example for ntb
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 +-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 387 ++++++++++++++++++++++++++++
6 files changed, 493 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index d9088e825..9d7b8c07b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..0f54d0e2d
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ if (res->filepath == NULL) {
+ printf("Fail to get filepath.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v4 6/6] doc: update docs for ntb driver
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-13 7:56 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-13 7:56 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0212fe6d0..b97cc18ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1056,6 +1056,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1432,3 +1436,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 575c590d9..a4c41a8c1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -72,6 +72,21 @@ New Features
Added the new Shared Memory Packet Interface (``memif``) PMD.
See the :doc:`../nics/memif` guide for more details on this new driver.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
6 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 851 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2096 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-17 12:49 ` Wang, Xiao W
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index e406e7836..45e403130 100644
--- a/config/common_base
+++ b/config/common_base
@@ -746,6 +746,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..fb40204c1
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..a13815a1d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 2/6] raw/ntb: add intel ntb support
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index fb40204c1..337311ea4 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..8a1e9be2a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 3/6] raw/ntb: add handshake process
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..d9088e825 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 4/6] examples/ntb: enable an example for ntb
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
6 files changed, 483 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index d9088e825..9d7b8c07b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..020e20bb5
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v5 6/6] doc: update docs for ntb driver
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-14 2:19 ` Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-14 2:19 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0212fe6d0..b97cc18ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1056,6 +1056,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1432,3 +1436,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 575c590d9..a4c41a8c1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -72,6 +72,21 @@ New Features
Added the new Shared Memory Packet Interface (``memif``) PMD.
See the :doc:`../nics/memif` guide for more details on this new driver.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-17 12:49 ` Wang, Xiao W
2019-06-18 1:28 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Wang, Xiao W @ 2019-06-17 12:49 UTC (permalink / raw)
To: Li, Xiaoyun, Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar
Cc: dev, Li, Xiaoyun
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Xiaoyun Li
> Sent: Friday, June 14, 2019 10:20 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver
>
> Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> can help to connect two separate hosts with each other.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> ---
> config/common_base | 5 +
> drivers/raw/Makefile | 1 +
> drivers/raw/meson.build | 2 +-
> drivers/raw/ntb_rawdev/Makefile | 27 +
> drivers/raw/ntb_rawdev/meson.build | 7 +
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
> drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
> .../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
> mk/rte.app.mk | 1 +
> 9 files changed, 704 insertions(+), 1 deletion(-)
> create mode 100644 drivers/raw/ntb_rawdev/Makefile
> create mode 100644 drivers/raw/ntb_rawdev/meson.build
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
> create mode 100644
> drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
>
> diff --git a/config/common_base b/config/common_base
> index e406e7836..45e403130 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -746,6 +746,11 @@
> CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
> #
> CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
>
> +#
> +# Compile PMD for NTB raw device
> +#
> +CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
> +
> #
> # Compile librte_ring
> #
> diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
> index 8e29b4a56..efe61f451 100644
> --- a/drivers/raw/Makefile
> +++ b/drivers/raw/Makefile
> @@ -10,5 +10,6 @@ DIRS-
> $(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
> endif
> DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
> +DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
>
> include $(RTE_SDK)/mk/rte.subdir.mk
> diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
> index a61cdccef..6abf659d0 100644
> --- a/drivers/raw/meson.build
> +++ b/drivers/raw/meson.build
> @@ -1,7 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright 2018 NXP
>
> -drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
> +drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev',
> 'ntb_rawdev']
> std_deps = ['rawdev']
> config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
> driver_name_fmt = 'rte_pmd_@0@'
> diff --git a/drivers/raw/ntb_rawdev/Makefile
> b/drivers/raw/ntb_rawdev/Makefile
> new file mode 100644
> index 000000000..fb40204c1
> --- /dev/null
> +++ b/drivers/raw/ntb_rawdev/Makefile
> @@ -0,0 +1,27 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2019 Intel Corporation
> +
> +include $(RTE_SDK)/mk/rte.vars.mk
> +
> +#
> +# library name
> +#
> +LIB = librte_pmd_ntb_rawdev.a
> +
> +CFLAGS += -DALLOW_EXPERIMENTAL_API
> +CFLAGS += -O3
> +CFLAGS += $(WERROR_FLAGS)
> +LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
> +LDLIBS += -lrte_pci -lrte_bus_pci
> +LDLIBS += -lrte_rawdev
> +
> +EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
> +
> +LIBABIVER := 1
> +
> +#
> +# all source are stored in SRCS-y
> +#
> +SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
Is it a typo? I think it should be CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV
BRs,
Xiao
> +
> +include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/drivers/raw/ntb_rawdev/meson.build
> b/drivers/raw/ntb_rawdev/meson.build
> new file mode 100644
> index 000000000..ca905049d
[...]
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-17 12:49 ` Wang, Xiao W
@ 2019-06-18 1:28 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-18 1:28 UTC (permalink / raw)
To: Wang, Xiao W, Wu, Jingjing, Wiles, Keith, Liang, Cunming,
Maslekar, Omkar
Cc: dev
Yes. Thanks for catching that.
> -----Original Message-----
> From: Wang, Xiao W
> Sent: Monday, June 17, 2019 20:49
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wu, Jingjing <jingjing.wu@intel.com>;
> Wiles, Keith <keith.wiles@intel.com>; Liang, Cunming
> <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver
>
> Hi,
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Xiaoyun Li
> > Sent: Friday, June 14, 2019 10:20 AM
> > To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>;
> > Maslekar, Omkar <omkar.maslekar@intel.com>
> > Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> > Subject: [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev
> > driver
> >
> > Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> > can help to connect two separate hosts with each other.
> >
> > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> > ---
> > config/common_base | 5 +
> > drivers/raw/Makefile | 1 +
> > drivers/raw/meson.build | 2 +-
> > drivers/raw/ntb_rawdev/Makefile | 27 +
> > drivers/raw/ntb_rawdev/meson.build | 7 +
> > drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
> > drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
> > .../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
> > mk/rte.app.mk | 1 +
> > 9 files changed, 704 insertions(+), 1 deletion(-) create mode 100644
> > drivers/raw/ntb_rawdev/Makefile create mode 100644
> > drivers/raw/ntb_rawdev/meson.build
> > create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
> > create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
> > create mode 100644
> > drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
> >
> > diff --git a/config/common_base b/config/common_base index
> > e406e7836..45e403130 100644
> > --- a/config/common_base
> > +++ b/config/common_base
> > @@ -746,6 +746,11 @@
> > CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
> > #
> > CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
> >
> > +#
> > +# Compile PMD for NTB raw device
> > +#
> > +CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
> > +
> > #
> > # Compile librte_ring
> > #
> > diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile index
> > 8e29b4a56..efe61f451 100644
> > --- a/drivers/raw/Makefile
> > +++ b/drivers/raw/Makefile
> > @@ -10,5 +10,6 @@ DIRS-
> > $(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
> > DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
> endif
> > DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
> > +DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
> >
> > include $(RTE_SDK)/mk/rte.subdir.mk
> > diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build index
> > a61cdccef..6abf659d0 100644
> > --- a/drivers/raw/meson.build
> > +++ b/drivers/raw/meson.build
> > @@ -1,7 +1,7 @@
> > # SPDX-License-Identifier: BSD-3-Clause # Copyright 2018 NXP
> >
> > -drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma',
> > 'ifpga_rawdev']
> > +drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma',
> > +'ifpga_rawdev',
> > 'ntb_rawdev']
> > std_deps = ['rawdev']
> > config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
> > driver_name_fmt = 'rte_pmd_@0@'
> > diff --git a/drivers/raw/ntb_rawdev/Makefile
> > b/drivers/raw/ntb_rawdev/Makefile new file mode 100644 index
> > 000000000..fb40204c1
> > --- /dev/null
> > +++ b/drivers/raw/ntb_rawdev/Makefile
> > @@ -0,0 +1,27 @@
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2019 Intel
> > +Corporation
> > +
> > +include $(RTE_SDK)/mk/rte.vars.mk
> > +
> > +#
> > +# library name
> > +#
> > +LIB = librte_pmd_ntb_rawdev.a
> > +
> > +CFLAGS += -DALLOW_EXPERIMENTAL_API
> > +CFLAGS += -O3
> > +CFLAGS += $(WERROR_FLAGS)
> > +LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool LDLIBS += -lrte_pci
> > +-lrte_bus_pci LDLIBS += -lrte_rawdev
> > +
> > +EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
> > +
> > +LIBABIVER := 1
> > +
> > +#
> > +# all source are stored in SRCS-y
> > +#
> > +SRCS-$(CONFIG_RTE_LIBRTE_PMD_SKELETON_RAWDEV) += ntb_rawdev.c
>
> Is it a typo? I think it should be CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV
>
> BRs,
> Xiao
>
> > +
> > +include $(RTE_SDK)/mk/rte.lib.mk
> > diff --git a/drivers/raw/ntb_rawdev/meson.build
> > b/drivers/raw/ntb_rawdev/meson.build
> > new file mode 100644
> > index 000000000..ca905049d
> [...]
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
6 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 851 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2096 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 500 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 158 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 704 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index e406e7836..45e403130 100644
--- a/config/common_base
+++ b/config/common_base
@@ -746,6 +746,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..518373f8f
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,500 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_NAME_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_NAME_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_NAME_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 14, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ *attr_value = (*hw->ntb_ops->spad_read)(dev, 15, 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = 0;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..a13815a1d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_PEER_SPAD_14 "spad14"
+#define NTB_PEER_SPAD_15 "spad15"
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..8a1e9be2a
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ *((volatile uint64_t *)xlat_addr) = base;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = (char *)hw->pci_dev->mem_resource[0].addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = (char *)hw->pci_dev->mem_resource[0].addr + limit_off;
+ base = *((volatile uint64_t *)xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ *((volatile uint64_t *)limit_addr) = limit;
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr + reg_off;
+ ntb_ctrl = *((volatile uint32_t *)reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ *((volatile uint32_t *)reg_addr) = ntb_ctrl;
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+ spad_v = *((volatile uint32_t *)reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ if (peer)
+ reg_off = XEON_B2B_SPAD_OFFSET;
+ else
+ reg_off = XEON_IM_SPAD_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + (spad << 2);
+
+ *((volatile uint32_t *)reg_addr) = spad_v;
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ db_bits = *((volatile uint64_t *)db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint64_t *)db_addr) = db_bits;
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ *((volatile uint64_t *)db_m_addr) = db_mask;
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = (char *)hw->pci_dev->mem_resource[0].addr + db_off;
+
+ *((volatile uint32_t *)db_addr) = 1;
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = (char *)hw->pci_dev->mem_resource[0].addr +
+ reg_off + intr;
+
+ *((volatile uint8_t *)reg_addr) = msix;
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 518373f8f..a03decd55 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -363,6 +365,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index a03decd55..d9088e825 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -356,7 +608,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 4/6] examples/ntb: enable an example for ntb
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
6 files changed, 483 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index d9088e825..9d7b8c07b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..020e20bb5
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad14", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad15", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad14", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad15", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v6 6/6] doc: update docs for ntb driver
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-18 2:10 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-18 2:10 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0212fe6d0..b97cc18ba 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1056,6 +1056,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1432,3 +1436,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 575c590d9..a4c41a8c1 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -72,6 +72,21 @@ New Features
Added the new Shared Memory Packet Interface (``memif``) PMD.
See the :doc:`../nics/memif` guide for more details on this new driver.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-18 16:07 ` Wu, Jingjing
0 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-18 16:07 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> +
> +static void
> +ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + struct ntb_attr *ntb_attrs = dev_info;
> +
> + strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME,
> NTB_ATTR_NAME_LEN);
> + switch (hw->topo) {
> + case NTB_TOPO_B2B_DSD:
> + strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
> + NTB_ATTR_NAME_LEN);
> + break;
> + case NTB_TOPO_B2B_USD:
> + strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
> + NTB_ATTR_NAME_LEN);
> + break;
> + default:
> + strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
> + NTB_ATTR_NAME_LEN);
> + }
> +
> + strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
> + NTB_ATTR_NAME_LEN);
> + snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_NAME_LEN,
> + "%d", hw->link_status);
> +
You are sharing NTB_ATTR_NAME_LEN for both name and value? How about NTB_ATTR_NUM_LEN/NTB_ATTR_VALUE_LEN?
[...]
> + if (!strncmp(attr_name, NTB_PEER_SPAD_14, NTB_ATTR_NAME_LEN)) {
> + if (hw->ntb_ops->spad_write == NULL)
> + return -ENOTSUP;
> + (*hw->ntb_ops->spad_write)(dev, 14, 1, attr_value);
> + NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
> + attr_name, attr_value);
> + return 0;
> + }
> +
> + if (!strncmp(attr_name, NTB_PEER_SPAD_15, NTB_ATTR_NAME_LEN)) {
> + if (hw->ntb_ops->spad_write == NULL)
> + return -ENOTSUP;
> + (*hw->ntb_ops->spad_write)(dev, 15, 1, attr_value);
> + NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
> + attr_name, attr_value);
> + return 0;
> + }
> +
What are 14 and 15 for? Is that generic?
> +static int
> +ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + int ret;
> +
> + hw->pci_dev = pci_dev;
> + hw->peer_dev_up = 0;
> + hw->link_status = 0;
> + hw->link_speed = NTB_SPEED_NONE;
> + hw->link_width = NTB_WIDTH_NONE;
> +
> + switch (pci_dev->id.device_id) {
> + default:
> + NTB_LOG(ERR, "Not supported device.");
> + return -EINVAL;
> + }
> +
> + if (hw->ntb_ops->ntb_dev_init == NULL)
> + return -ENOTSUP;
> + ret = (*hw->ntb_ops->ntb_dev_init)(dev);
> + if (ret) {
> + NTB_LOG(ERR, "Unanle to init ntb dev.");
Typo: unanle -> unable
[...]
> +static int
> +ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
> +{
> + char name[RTE_RAWDEV_NAME_MAX_LEN];
> + struct rte_rawdev *rawdev = NULL;
> + int ret;
> +
> + if (pci_dev == NULL) {
> + NTB_LOG(ERR, "Invalid pci_dev.");
> + ret = -EINVAL;
> + goto fail;
Is there possibility to release rawdev at fail? Return might be enough.
> + }
> +
> + memset(name, 0, sizeof(name));
> + snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
> + pci_dev->addr.bus, pci_dev->addr.devid,
> + pci_dev->addr.function);
> +
> + NTB_LOG(INFO, "Init %s on NUMA node %d", name, rte_socket_id());
Why not use the parameter "socket_id"?
> +
> + /* Allocate device structure. */
> + rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
> + socket_id);
> + if (rawdev == NULL) {
> + NTB_LOG(ERR, "Unable to allocate rawdev.");
> + ret = -EINVAL;
> + goto fail;
No need to goto fail as rawdev in NULL.
[...]
> +enum ntb_link {
> + NTB_LINK_DOWN = 0,
> + NTB_LINK_UP,
> +};
> +
You defined the enum, but you used 0 and 1 above.
Thanks
Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-18 16:07 ` Wu, Jingjing
2019-06-20 10:06 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-18 16:07 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Tuesday, June 18, 2019 10:11 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v6 3/6] raw/ntb: add handshake process
>
> Add handshake process using doorbell so that two hosts can
> communicate to start and stop.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> ---
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
> 1 file changed, 335 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c
> b/drivers/raw/ntb_rawdev/ntb_rawdev.c
> index a03decd55..d9088e825 100644
> --- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
> +++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
> @@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
> { .vendor_id = 0, /* sentinel */ },
> };
>
> +static int
> +ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + char mw_name[RTE_MEMZONE_NAMESIZE];
> + const struct rte_memzone *mz;
> + int ret = 0;
> +
> + if (hw->ntb_ops->mw_set_trans == NULL) {
> + NTB_LOG(ERR, "Not supported to set mw.");
> + return -ENOTSUP;
> + }
> +
> + snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
> + dev->dev_id, mw_idx);
> +
> + mz = rte_memzone_lookup(mw_name);
> + if (mz)
> + return 0;
> +
> + /**
> + * Hardware requires that mapped memory base address should be
> + * aligned with EMBARSZ and needs continuous memzone.
> + */
> + mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
> + RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
If the memzone is reserved inside of driver, how is the buffer be mapped without copy when enqueuer/dequeuer as the buffer might not be in the memzone?
How about to design the dev_config to set the mw to be a memzone (might address + size) which can be created by application instead of created internally?
[.....]
> +static void
> +ntb_dev_intr_handler(void *param)
> +{
> + struct rte_rawdev *dev = (struct rte_rawdev *)param;
> + struct ntb_hw *hw = dev->dev_private;
> + uint32_t mw_size_h, mw_size_l;
> + uint64_t db_bits = 0;
> + int i = 0;
> +
> + if (hw->ntb_ops->db_read == NULL ||
> + hw->ntb_ops->db_clear == NULL ||
> + hw->ntb_ops->peer_db_set == NULL) {
> + NTB_LOG(ERR, "Doorbell is not supported.");
> + return;
> + }
> +
> + db_bits = (*hw->ntb_ops->db_read)(dev);
> + if (!db_bits)
> + NTB_LOG(ERR, "No doorbells");
> +
Is the db_bits a common setting between different kind of NTB?
[......]
>
> @@ -356,7 +608,9 @@ static int
> ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
> {
> struct ntb_hw *hw = dev->dev_private;
> - int ret;
> + struct rte_intr_handle *intr_handle;
> + uint32_t val;
> + int ret, i;
>
> hw->pci_dev = pci_dev;
> hw->peer_dev_up = 0;
> @@ -387,6 +641,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device
> *pci_dev)
> if (ret)
> return ret;
>
> + /* Init doorbell. */
> + hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
Use RTE_LEN2MASK instead?
Thanks
Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-18 16:07 ` Wu, Jingjing
0 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-18 16:07 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
One general comment:
Think about to use rte_read32() and rte_write32() when reading and writing registers. Or you can define a Macro or inline function for NTB driver to touch registers. Then you can omit lots of "(char *)hw->pci_dev->mem_resource[0].addr " and "*((volatile uint32_t *)" like things. It will make the code much easier to read.
> +static void *
> +intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + uint8_t bar;
> +
> + if (hw == NULL) {
> + NTB_LOG(ERR, "Invalid device.");
> + return 0;
> + }
> +
> + if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
mw_idx >= hw->mw_cnt?
[...]
> +static int
> +intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
> + uint64_t addr, uint64_t size)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + void *xlat_addr, *limit_addr;
> + uint64_t xlat_off, limit_off;
> + uint64_t base, limit;
> + uint8_t bar;
> +
> + if (hw == NULL) {
> + NTB_LOG(ERR, "Invalid device.");
> + return -EINVAL;
> + }
> +
> + if (mw_idx < 0 || mw_idx > hw->mw_cnt) {
Same as above.
[...]
> +static uint32_t
> +intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + uint32_t spad_v, reg_off;
> + void *reg_addr;
> +
> + if (spad < 0 || spad >= hw->spad_cnt) {
> + NTB_LOG(ERR, "Invalid spad reg index.");
> + return 0;
> + }
> +
> + /* When peer is true, read peer spad reg */
> + if (peer)
> + reg_off = XEON_B2B_SPAD_OFFSET;
> + else
> + reg_off = XEON_IM_SPAD_OFFSET;
How about one line if check is simple?
reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
Thanks
Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process
2019-06-18 16:07 ` Wu, Jingjing
@ 2019-06-20 10:06 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-20 10:06 UTC (permalink / raw)
To: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
Thanks for comments for patch 1 & 2. Will refine them in the coming v7.
And
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Wednesday, June 19, 2019 00:08
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v6 3/6] raw/ntb: add handshake process
>
> >mw_size[mw_idx]);
>
> If the memzone is reserved inside of driver, how is the buffer be mapped without
> copy when enqueuer/dequeuer as the buffer might not be in the memzone?
> How about to design the dev_config to set the mw to be a memzone (might
> address + size) which can be created by application instead of created internally?
This is a temporary function to verify the memory w/r works and to suit the hw limitation.
There is no fifo right now. Will add the whole process of pkt mbuf pool create and aligned memzone allocation in next release.
>
> > + db_bits = (*hw->ntb_ops->db_read)(dev);
> > + if (!db_bits)
> > + NTB_LOG(ERR, "No doorbells");
> > +
>
> Is the db_bits a common setting between different kind of NTB?
Yes.
>
> [......]
> > + /* Init doorbell. */
> > + hw->db_valid_mask = ((uint64_t)1 << hw->db_cnt) - 1;
> Use RTE_LEN2MASK instead?
Sure. Thx.
>
> Thanks
> Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
6 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2091 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 698 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index 5cb73a7a8..d18dae7b0 100644
--- a/config/common_base
+++ b/config/common_base
@@ -747,6 +747,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d0df0b023..ff17bef46 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -301,6 +301,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 2/6] raw/ntb: add intel ntb support
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 463 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..1185cd189
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,369 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++) {
+ hw->spad_user_list[i] = hw->spad_cnt;
+ }
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 07ad81d44..113ef0169 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 3/6] raw/ntb: add handshake process
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 113ef0169..e4ae95a01 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 4/6] examples/ntb: enable an example for ntb
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
6 files changed, 483 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index e4ae95a01..145c77bd7 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v7 6/6] doc: update docs for ntb driver
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-20 10:21 ` Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-20 10:21 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 8 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 113 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index fdc083db9..8c919484d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1057,6 +1057,10 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1433,3 +1437,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 563999d57..3a35ffbd7 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -94,6 +94,21 @@ New Features
* Enabled Tx outer/inner L3/L4 checksum offload.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (6 more replies)
6 siblings, 7 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v8:
* Fixed a coding style issue.
* Rebased codes to the newwst master branch.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 9 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2091 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 16:31 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (5 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 698 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index fa1ae249a..6feb04602 100644
--- a/config/common_base
+++ b/config/common_base
@@ -747,6 +747,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 81be289a8..568ffe724 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -306,6 +306,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 17:06 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process Xiaoyun Li
` (4 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 368 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 462 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..c49831963
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
+ hw->spad_user_list[i] = hw->spad_cnt;
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 07ad81d44..113ef0169 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 17:19 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (3 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 113ef0169..e4ae95a01 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 17:30 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (2 subsequent siblings)
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
6 files changed, 483 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index e4ae95a01..145c77bd7 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index c695d52c9..2a4a084af 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 17:34 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..6e6f64bd3 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-26 7:12 ` Xiaoyun Li
2019-06-27 17:33 ` Wu, Jingjing
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
6 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-26 7:12 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 9 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 114 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0c3b48920..0b8dd5983 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1078,6 +1078,11 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1454,3 +1459,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 3da266705..f1858498a 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -99,6 +99,21 @@ New Features
Updated ``librte_telemetry`` to fetch the global metrics from the
``librte_metrics`` library.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-27 16:31 ` Wu, Jingjing
0 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 16:31 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Wednesday, June 26, 2019 3:12 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver
>
> Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> can help to connect two separate hosts with each other.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-27 17:06 ` Wu, Jingjing
2019-06-28 1:33 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 17:06 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
Few minor comments.
> +static int
> +intel_ntb_dev_init(struct rte_rawdev *dev)
> +{
> + struct ntb_hw *hw = dev->dev_private;
> + uint8_t reg_val, bar;
> + int ret, i;
> +
> + if (hw == NULL) {
> + NTB_LOG(ERR, "Invalid device.");
> + return -EINVAL;
> + }
> +
> + ret = rte_pci_read_config(hw->pci_dev, ®_val,
> + sizeof(reg_val), XEON_PPD_OFFSET);
> + if (ret < 0) {
> + NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
> + return -EIO;
> + }
> +
> + /* Check connection topo type. Only support B2B. */
> + switch (reg_val & XEON_PPD_CONN_MASK) {
> + case XEON_PPD_CONN_B2B:
> + NTB_LOG(INFO, "Topo B2B (back to back) is using.");
> + break;
> + case XEON_PPD_CONN_TRANSPARENT:
> + case XEON_PPD_CONN_RP:
> + NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
> + return -EINVAL;
Do We need "default:" ?
> + }
> +
> + /* Check device type. */
> + if (reg_val & XEON_PPD_DEV_DSD) {
> + NTB_LOG(INFO, "DSD, Downstream Device.");
> + hw->topo = NTB_TOPO_B2B_DSD;
> + } else {
> + NTB_LOG(INFO, "USD, Upstream device.");
> + hw->topo = NTB_TOPO_B2B_USD;
> + }
> +
> + /* Check if bar4 is split. Do not support split bar. */
> + if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
> + NTB_LOG(ERR, "Do not support split bar.");
> + return -EINVAL;
> + }
> +
> + hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
> +
> + hw->mw_cnt = XEON_MW_COUNT;
> + hw->db_cnt = XEON_DB_COUNT;
> + hw->spad_cnt = XEON_SPAD_COUNT;
> +
> + hw->mw_size = rte_zmalloc("uint64_t",
> + hw->mw_cnt * sizeof(uint64_t), 0);
> + for (i = 0; i < hw->mw_cnt; i++) {
> + bar = intel_ntb_bar[i];
> + hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
> + }
> +
> + /* Reserve the last 2 spad registers for users. */
> + for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
> + hw->spad_user_list[i] = hw->spad_cnt;
> + hw->spad_user_list[0] = hw->spad_cnt - 2;
> + hw->spad_user_list[1] = hw->spad_cnt - 1;
How about:
hw->spad_user_list[0] = hw->spad_cnt - 2;
hw->spad_user_list[1] = hw->spad_cnt - 1;
for (i = 2; i < NTB_SPAD_USER_MAX_NUM; i++)
hw->spad_user_list[i] = hw->spad_cnt;
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-27 17:19 ` Wu, Jingjing
2019-06-28 1:33 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 17:19 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Wednesday, June 26, 2019 3:12 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v8 3/6] raw/ntb: add handshake process
>
> Add handshake process using doorbell so that two hosts can
> communicate to start and stop.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
> + hw->db_mask = 0;
> + ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
> + if (ret) {
> + NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
Typo? Unanle -> unable?
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-27 17:30 ` Wu, Jingjing
2019-06-28 1:36 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 17:30 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Wednesday, June 26, 2019 3:12 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v8 4/6] examples/ntb: enable an example for ntb
>
> Enable an example for rawdev ntb. Support interactive mode to send
> file on one host and receive file from another host. The command line
> would be 'send [filepath]' and 'receive [filepath]'.
>
> But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
> and dequeue functions and only support transmitting file no more than 4M.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Reviewed-by: Jingjing Wu <jingjing.wu@intel.com>
The test app looks fine currently.
Just one thought, if this example is temporary, can we just move this patch to test instead of example. As when the FIFO is done, this one be modified, right?
Thanks
Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-27 17:33 ` Wu, Jingjing
0 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 17:33 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Wednesday, June 26, 2019 3:12 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v8 6/6] doc: update docs for ntb driver
>
> Update related documents for ntb pmd and example.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Reviewed-by: Jingjing Wu <jingjing.wu@intel.com>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-27 17:34 ` Wu, Jingjing
0 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-27 17:34 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Wednesday, June 26, 2019 3:12 PM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v8 5/6] usertools/dpdk-devbind.py: add support for ntb
>
> In order to allow binding/unbinding of devices for use by the
> ntb_rawdev, we need to update the devbind script to add a new class
> of device, and add device ids for the specific HW instances. And
> only support skx platform right now.
>
> Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Reviewed-by: Jingjing Wu <jingjing.wu@intel.com>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support
2019-06-27 17:06 ` Wu, Jingjing
@ 2019-06-28 1:33 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-28 1:33 UTC (permalink / raw)
To: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
Hi
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, June 28, 2019 01:07
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v8 2/6] raw/ntb: add intel ntb support
>
> Few minor comments.
>
> > + case XEON_PPD_CONN_TRANSPARENT:
> > + case XEON_PPD_CONN_RP:
> > + NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
> > + return -EINVAL;
>
> Do We need "default:" ?
Yes. Sure. Thx.
> > + }
> > +
> > + /* Reserve the last 2 spad registers for users. */
> > + for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
> > + hw->spad_user_list[i] = hw->spad_cnt;
> > + hw->spad_user_list[0] = hw->spad_cnt - 2;
> > + hw->spad_user_list[1] = hw->spad_cnt - 1;
>
> How about:
> hw->spad_user_list[0] = hw->spad_cnt - 2; spad_user_list[1] =
> hw->hw->spad_cnt - 1;
> for (i = 2; i < NTB_SPAD_USER_MAX_NUM; i++)
> hw->spad_user_list[i] = hw->spad_cnt;
>
I think this way is more straightforward in case that reserve more spad registers for users in the future.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process
2019-06-27 17:19 ` Wu, Jingjing
@ 2019-06-28 1:33 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-28 1:33 UTC (permalink / raw)
To: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
Yes. Thx.
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, June 28, 2019 01:20
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v8 3/6] raw/ntb: add handshake process
>
>
>
> > -----Original Message-----
> > From: Li, Xiaoyun
> > Sent: Wednesday, June 26, 2019 3:12 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>;
> > Maslekar, Omkar <omkar.maslekar@intel.com>
> > Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> > Subject: [PATCH v8 3/6] raw/ntb: add handshake process
> >
> > Add handshake process using doorbell so that two hosts can communicate
> > to start and stop.
> >
> > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> Acked-by: Jingjing Wu <jingjing.wu@intel.com>
>
>
> > + hw->db_mask = 0;
> > + ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
> > + if (ret) {
> > + NTB_LOG(ERR, "Unanle to enable intr for all dbs.");
>
> Typo? Unanle -> unable?
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb
2019-06-27 17:30 ` Wu, Jingjing
@ 2019-06-28 1:36 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-06-28 1:36 UTC (permalink / raw)
To: Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
Hi
> -----Original Message-----
> From: Wu, Jingjing
> Sent: Friday, June 28, 2019 01:30
> To: Li, Xiaoyun <xiaoyun.li@intel.com>; Wiles, Keith <keith.wiles@intel.com>;
> Liang, Cunming <cunming.liang@intel.com>; Maslekar, Omkar
> <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org
> Subject: RE: [PATCH v8 4/6] examples/ntb: enable an example for ntb
>
> > -----Original Message-----
> > From: Li, Xiaoyun
> > Sent: Wednesday, June 26, 2019 3:12 PM
> > To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>;
> > Maslekar, Omkar <omkar.maslekar@intel.com>
> > Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> > Subject: [PATCH v8 4/6] examples/ntb: enable an example for ntb
> >
> > Enable an example for rawdev ntb. Support interactive mode to send
> > file on one host and receive file from another host. The command line
> > would be 'send [filepath]' and 'receive [filepath]'.
> >
> > But since the FIFO is not enabled right now, use rte_memcpy as the
> > enqueue and dequeue functions and only support transmitting file no more
> than 4M.
> >
> > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
> Reviewed-by: Jingjing Wu <jingjing.wu@intel.com>
>
> The test app looks fine currently.
> Just one thought, if this example is temporary, can we just move this patch to
> test instead of example. As when the FIFO is done, this one be modified, right?
The file transmission will be reserved in next release, just support any size in next because of the introduce of FIFO.
And will add new cmdline to iofwd ntb device and eth device in next release. So example is a more appropriate choice.
>
> Thanks
> Jingjing
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (10 more replies)
6 siblings, 11 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v9:
* Fixed a typo.
* Added default case for PPD parse.
v8:
* Fixed a coding style issue.
* Rebased codes to the newest master branch.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (6):
raw/ntb: introduce ntb rawdev driver
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
usertools/dpdk-devbind.py: add support for ntb
doc: update docs for ntb driver
MAINTAINERS | 9 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 +
doc/guides/rel_notes/release_19_08.rst | 15 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2092 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 1/6] raw/ntb: introduce ntb rawdev driver
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 2/6] raw/ntb: add intel ntb support Xiaoyun Li
` (9 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
config/common_base | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
9 files changed, 698 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/config/common_base b/config/common_base
index fa1ae249a..6feb04602 100644
--- a/config/common_base
+++ b/config/common_base
@@ -747,6 +747,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 81be289a8..568ffe724 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -306,6 +306,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 2/6] raw/ntb: add intel ntb support
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 3/6] raw/ntb: add handshake process Xiaoyun Li
` (8 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for intel skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
5 files changed, 463 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..834436b37
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,369 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ default:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
+ hw->spad_user_list[i] = hw->spad_cnt;
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 07ad81d44..113ef0169 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 3/6] raw/ntb: add handshake process
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 2/6] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
` (7 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
1 file changed, 335 insertions(+), 1 deletion(-)
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 113ef0169..005c5c3be 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 4/6] examples/ntb: enable an example for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 3/6] raw/ntb: add handshake process Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
` (6 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
6 files changed, 483 insertions(+), 9 deletions(-)
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 005c5c3be..91d6a015b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index 87113bd70..a046b74ad 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 5/6] usertools/dpdk-devbind.py: add support for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver Xiaoyun Li
` (5 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support skx platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
usertools/dpdk-devbind.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..30d75f3f0 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc (rawdev)")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
@ 2019-06-28 2:53 ` Xiaoyun Li
2019-07-01 14:24 ` Thomas Monjalon
2019-06-28 10:17 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Wu, Jingjing
` (4 subsequent siblings)
10 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-06-28 2:53 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Update related documents for ntb pmd and example.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 9 +++++
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 41 ++++++++++++++++++++++
doc/guides/rel_notes/release_19_08.rst | 15 ++++++++
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++++++++++++++++++++++++
6 files changed, 114 insertions(+)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 0c3b48920..0b8dd5983 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1078,6 +1078,11 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
@@ -1454,3 +1459,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..429e2af3e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
+But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+And this PMD only supports intel skylake platform.
+
+BIOS setting on skylake platform
+--------------------------------
+
+Intel non-transparent bridge needs special BIOS setting. Since the PMD only
+supports intel skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
+Build options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_IFPGA_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 3da266705..f1858498a 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -99,6 +99,21 @@ New Features
Updated ``librte_telemetry`` to fetch the global metrics from the
``librte_metrics`` library.
+* **Introduced NTB PMD.**
+
+ The PMD provided a non-transparent bridge between two separate hosts so
+ that they can communicate with each other. Thus, many user cases can
+ benefit from this, such as fault tolerance and visual acceleration.
+
+ This PMD implemented the following features:
+ * Handshake for device start and stop between two hosts.
+ * Memory allocation for the peer to access and read/write allocated
+ memory from peer.
+ * Use doorbell registers to notify the peer and share some information
+ by using scratchpad registers.
+
+ But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
+ And this PMD only supports intel skylake platform.
Removed Items
-------------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (5 preceding siblings ...)
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-06-28 10:17 ` Wu, Jingjing
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
` (3 subsequent siblings)
10 siblings, 0 replies; 127+ messages in thread
From: Wu, Jingjing @ 2019-06-28 10:17 UTC (permalink / raw)
To: Li, Xiaoyun, Wiles, Keith, Liang, Cunming, Maslekar, Omkar; +Cc: dev
series Acked-by: Jingjing Wu <jingjing.wu@intel.com>
> -----Original Message-----
> From: Li, Xiaoyun
> Sent: Friday, June 28, 2019 10:54 AM
> To: Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith <keith.wiles@intel.com>; Liang,
> Cunming <cunming.liang@intel.com>; Maslekar, Omkar <omkar.maslekar@intel.com>
> Cc: dev@dpdk.org; Li, Xiaoyun <xiaoyun.li@intel.com>
> Subject: [PATCH v9 0/6] rawdev driver for ntb
>
> This patch set adds support for Intel NTB device with Skylake platform.
> It is a raw device for allowing two hosts to communicate with each other
> and access the peer memory.
>
> This patch set also provides a simple example to transmit a file between
> two hosts. But since there is no FIFO here, only support file which is
> no more than 4M. And will add FIFO in the future.
>
> v9:
> * Fixed a typo.
> * Added default case for PPD parse.
>
> v8:
> * Fixed a coding style issue.
> * Rebased codes to the newest master branch.
>
> v7:
> * Fixed a typo.
> * Generic spad registers to be spad_user and the specific spad is
> * defined by the specific hw.
> * Refined the codes by replacing with lib functions such as rte_read32.
> * Rebased the codes to the newest dpdk-next-net-intel branch.
>
> v6:
> * Fixed a typo.
>
> v5:
> * Actual v4. v4 patchset is the same as v3.
>
> v4:
> * Fix compile issues of comparison of array with null pointer.
>
> v3:
> * Fixed compilation issues with target i686.
> * Renamed communication devices to misc devices in usertool.
> * Rebased to the newest dpdk-next-net-intel branch.
>
> v2:
> * Replaced ! with NULL check for pointers.
> * Added ntb_ops valid check before use it.
> * Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
> not use 1G hugepage.
> * Added a timeout for dev_stop handshake in case that the peer stopped
> abnormally such as crashed while debugging.
> * Updated docs especailly about how to setup BIOS for skylake.
> * Fixed not return issue and not free issue in example.
> * Renamed ntb_devices to communication_devices to be more generic in
> usertools.
> * Polish the codes and docs.
>
> Xiaoyun Li (6):
> raw/ntb: introduce ntb rawdev driver
> raw/ntb: add intel ntb support
> raw/ntb: add handshake process
> examples/ntb: enable an example for ntb
> usertools/dpdk-devbind.py: add support for ntb
> doc: update docs for ntb driver
>
> MAINTAINERS | 9 +
> config/common_base | 5 +
> doc/guides/rawdevs/index.rst | 1 +
> doc/guides/rawdevs/ntb_rawdev.rst | 41 +
> doc/guides/rel_notes/release_19_08.rst | 15 +
> doc/guides/sample_app_ug/index.rst | 1 +
> doc/guides/sample_app_ug/ntb.rst | 47 +
> drivers/raw/Makefile | 1 +
> drivers/raw/meson.build | 2 +-
> drivers/raw/ntb_rawdev/Makefile | 28 +
> drivers/raw/ntb_rawdev/meson.build | 8 +
> drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
> drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
> drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
> .../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
> examples/Makefile | 1 +
> examples/meson.build | 2 +-
> examples/ntb/Makefile | 68 ++
> examples/ntb/meson.build | 16 +
> examples/ntb/ntb_fwd.c | 377 ++++++++
> mk/rte.app.mk | 1 +
> usertools/dpdk-devbind.py | 9 +
> 23 files changed, 2092 insertions(+), 2 deletions(-)
> create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
> create mode 100644 doc/guides/sample_app_ug/ntb.rst
> create mode 100644 drivers/raw/ntb_rawdev/Makefile
> create mode 100644 drivers/raw/ntb_rawdev/meson.build
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
> create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
> create mode 100644 examples/ntb/Makefile
> create mode 100644 examples/ntb/meson.build
> create mode 100644 examples/ntb/ntb_fwd.c
>
> --
> 2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver Xiaoyun Li
@ 2019-07-01 14:24 ` Thomas Monjalon
2019-07-02 1:18 ` Li, Xiaoyun
0 siblings, 1 reply; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-01 14:24 UTC (permalink / raw)
To: Xiaoyun Li
Cc: dev, jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar,
john.mcnamara
28/06/2019 04:53, Xiaoyun Li:
> +NTB Rawdev
> +M: Xiaoyun Li <xiaoyun.li@intel.com>
> +M: Jingjing Wu <jingjing.wu@intel.com>
> +F: drivers/raw/ntb_rawdev/
> +F: doc/guides/rawdevs/ntb_rawdev.rst
Please update MAINTAINERS while introducing files in previous patches.
> +++ b/doc/guides/rawdevs/ntb_rawdev.rst
> +And this PMD only supports intel skylake platform.
I guess the platform name require some uppercase or other characters.
Please request a full review of the doc by Intel colleagues.
> --- a/doc/guides/rel_notes/release_19_08.rst
> +++ b/doc/guides/rel_notes/release_19_08.rst
> +* **Introduced NTB PMD.**
> +
> + The PMD provided a non-transparent bridge between two separate hosts so
> + that they can communicate with each other. Thus, many user cases can
> + benefit from this, such as fault tolerance and visual acceleration.
> +
> + This PMD implemented the following features:
> + * Handshake for device start and stop between two hosts.
> + * Memory allocation for the peer to access and read/write allocated
> + memory from peer.
> + * Use doorbell registers to notify the peer and share some information
> + by using scratchpad registers.
> +
> + But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
> + And this PMD only supports intel skylake platform.
You don't need to repeat the full doc in the release notes.
Please make it shorter.
And please update the release notes in the same patch as the code.
Thanks
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver
2019-07-01 14:24 ` Thomas Monjalon
@ 2019-07-02 1:18 ` Li, Xiaoyun
0 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-07-02 1:18 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar,
Mcnamara, John
Got it. Thanks.
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, July 1, 2019 22:24
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>; Maslekar,
> Omkar <omkar.maslekar@intel.com>; Mcnamara, John
> <john.mcnamara@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver
>
> 28/06/2019 04:53, Xiaoyun Li:
> > +NTB Rawdev
> > +M: Xiaoyun Li <xiaoyun.li@intel.com>
> > +M: Jingjing Wu <jingjing.wu@intel.com>
> > +F: drivers/raw/ntb_rawdev/
> > +F: doc/guides/rawdevs/ntb_rawdev.rst
>
> Please update MAINTAINERS while introducing files in previous patches.
>
> > +++ b/doc/guides/rawdevs/ntb_rawdev.rst
> > +And this PMD only supports intel skylake platform.
>
> I guess the platform name require some uppercase or other characters.
> Please request a full review of the doc by Intel colleagues.
>
> > --- a/doc/guides/rel_notes/release_19_08.rst
> > +++ b/doc/guides/rel_notes/release_19_08.rst
> > +* **Introduced NTB PMD.**
> > +
> > + The PMD provided a non-transparent bridge between two separate
> > + hosts so that they can communicate with each other. Thus, many user
> > + cases can benefit from this, such as fault tolerance and visual acceleration.
> > +
> > + This PMD implemented the following features:
> > + * Handshake for device start and stop between two hosts.
> > + * Memory allocation for the peer to access and read/write allocated
> > + memory from peer.
> > + * Use doorbell registers to notify the peer and share some information
> > + by using scratchpad registers.
> > +
> > + But the PMD hasn't implemented FIFO. The FIFO will come in 19.11 release.
> > + And this PMD only supports intel skylake platform.
>
> You don't need to repeat the full doc in the release notes.
> Please make it shorter.
> And please update the release notes in the same patch as the code.
>
> Thanks
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (6 preceding siblings ...)
2019-06-28 10:17 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Wu, Jingjing
@ 2019-07-02 6:17 ` Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (4 more replies)
2019-07-02 6:23 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (2 subsequent siblings)
10 siblings, 5 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
series Acked-by: Jingjing Wu <jingjing.wu@intel.com>
v10:
* Updated and refined the release notes in the same patch as the code.
v9:
* Fixed a typo.
* Added default case for PPD parse.
v8:
* Fixed a coding style issue.
* Rebased codes to the newest master branch.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (5):
raw/ntb: introduce ntb rawdev driver
usertools/dpdk-devbind.py: add support for ntb
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
MAINTAINERS | 9 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 52 ++
doc/guides/rel_notes/release_19_08.rst | 5 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2093 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
@ 2019-07-02 6:17 ` Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
` (3 subsequent siblings)
4 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 22 +
doc/guides/rel_notes/release_19_08.rst | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
13 files changed, 731 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 97a009e43..9303624c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1094,6 +1094,11 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
diff --git a/config/common_base b/config/common_base
index e700bf1e7..d3f2b941a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -752,6 +752,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..ebc4dbc1e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+Build Options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
+
+Limitation
+----------
+
+- The FIFO hasn't been introduced and will come in 19.11 release.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 8e0b13e05..4c07a0210 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -126,6 +126,11 @@ New Features
Added telemetry mode to l3fwd-power application to report
application level busyness, empty and full polls of rte_eth_rx_burst().
+* **Introduced NTB PMD.**
+
+ Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implemented
+ handshake between two seperate hosts and can share local memory for peer
+ host to directly access.
Removed Items
-------------
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 2b5696a27..ead42ee3a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -307,6 +307,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-07-02 6:17 ` Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
` (2 subsequent siblings)
4 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support Intel Skylake platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 8 ++++++++
usertools/dpdk-devbind.py | 9 +++++++++
2 files changed, 17 insertions(+)
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index ebc4dbc1e..71496bf44 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -16,6 +16,14 @@ Build Options
Toggle compilation of the ``ntb_rawdev`` driver.
+Device Setup
+------------
+
+The Intel NTB devices need to be bound to a DPDK-supported kernel driver
+to use, i.e. igb_uio, vfio. The ``dpdk-devbind.py`` script can be used to
+show devices status and to bind them to a suitable kernel driver. They will
+appear under the category of "Misc (rawdev) devices".
+
Limitation
----------
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..30d75f3f0 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc (rawdev)")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
@ 2019-07-02 6:17 ` Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
4 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for Intel Skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 17 ++
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
6 files changed, 480 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index 71496bf44..0e74897db 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -9,6 +9,22 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+BIOS setting on Intel Skylake
+-----------------------------
+
+Intel Non-transparent Bridge needs special BIOS setting. Since the PMD only
+supports Intel Skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
Build Options
-------------
@@ -28,3 +44,4 @@ Limitation
----------
- The FIFO hasn't been introduced and will come in 19.11 release.
+- This PMD only supports Intel Skylake platform.
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..834436b37
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,369 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ default:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
+ hw->spad_user_list[i] = hw->spad_cnt;
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 07ad81d44..113ef0169 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
` (2 preceding siblings ...)
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-07-02 6:17 ` Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
4 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 5 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
2 files changed, 340 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index 0e74897db..223b2a867 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -9,6 +9,11 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
BIOS setting on Intel Skylake
-----------------------------
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 113ef0169..005c5c3be 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
` (3 preceding siblings ...)
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
@ 2019-07-02 6:17 ` Xiaoyun Li
4 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:17 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 4 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
9 files changed, 535 insertions(+), 9 deletions(-)
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 9303624c6..c94739d26 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1475,3 +1475,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 005c5c3be..91d6a015b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index 87113bd70..a046b74ad 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (7 preceding siblings ...)
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
@ 2019-07-02 6:23 ` Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
10 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:23 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 22 +
doc/guides/rel_notes/release_19_08.rst | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
13 files changed, 731 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 97a009e43..9303624c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1094,6 +1094,11 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
diff --git a/config/common_base b/config/common_base
index e700bf1e7..d3f2b941a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -752,6 +752,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..ebc4dbc1e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+Build Options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
+
+Limitation
+----------
+
+- The FIFO hasn't been introduced and will come in 19.11 release.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 8e0b13e05..4c07a0210 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -126,6 +126,11 @@ New Features
Added telemetry mode to l3fwd-power application to report
application level busyness, empty and full polls of rte_eth_rx_burst().
+* **Introduced NTB PMD.**
+
+ Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implemented
+ handshake between two separate hosts and can share local memory for peer
+ host to directly access.
Removed Items
-------------
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 2b5696a27..ead42ee3a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -307,6 +307,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (8 preceding siblings ...)
2019-07-02 6:23 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
` (5 more replies)
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
10 siblings, 6 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
series Acked-by: Jingjing Wu <jingjing.wu@intel.com>
v10:
* Updated and refined the release notes in the same patch as the code.
v9:
* Fixed a typo.
* Added default case for PPD parse.
v8:
* Fixed a coding style issue.
* Rebased codes to the newest master branch.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (5):
raw/ntb: introduce ntb rawdev driver
usertools/dpdk-devbind.py: add support for ntb
raw/ntb: add intel ntb support
raw/ntb: add handshake process
examples/ntb: enable an example for ntb
MAINTAINERS | 9 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 52 ++
doc/guides/rel_notes/release_19_08.rst | 5 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 28 +
drivers/raw/ntb_rawdev/meson.build | 8 +
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 ++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 9 +
23 files changed, 2093 insertions(+), 2 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-04 10:31 ` Thomas Monjalon
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
` (4 subsequent siblings)
5 siblings, 1 reply; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 5 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb_rawdev.rst | 22 +
doc/guides/rel_notes/release_19_08.rst | 5 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb_rawdev/Makefile | 27 +
drivers/raw/ntb_rawdev/meson.build | 7 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 488 ++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++++
.../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
mk/rte.app.mk | 1 +
13 files changed, 731 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
create mode 100644 drivers/raw/ntb_rawdev/Makefile
create mode 100644 drivers/raw/ntb_rawdev/meson.build
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 97a009e43..9303624c6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1094,6 +1094,11 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB Rawdev
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb_rawdev/
+F: doc/guides/rawdevs/ntb_rawdev.rst
Packet processing
-----------------
diff --git a/config/common_base b/config/common_base
index e700bf1e7..d3f2b941a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -752,6 +752,11 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
#
CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 7c3bd9586..cf6fcb06b 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -14,3 +14,4 @@ application through rawdev API.
dpaa2_cmdif
dpaa2_qdma
ifpga_rawdev
+ ntb_rawdev
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
new file mode 100644
index 000000000..ebc4dbc1e
--- /dev/null
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+Build Options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb_rawdev`` driver.
+
+Limitation
+----------
+
+- The FIFO hasn't been introduced and will come in 19.11 release.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 8e0b13e05..4c07a0210 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -126,6 +126,11 @@ New Features
Added telemetry mode to l3fwd-power application to report
application level busyness, empty and full polls of rte_eth_rx_burst().
+* **Introduced NTB PMD.**
+
+ Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implemented
+ handshake between two separate hosts and can share local memory for peer
+ host to directly access.
Removed Items
-------------
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index 8e29b4a56..efe61f451 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -10,5 +10,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_CMDIF_RAWDEV) += dpaa2_cmdif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index a61cdccef..6abf659d0 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2018 NXP
-drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev']
+drivers = ['skeleton_rawdev', 'dpaa2_cmdif', 'dpaa2_qdma', 'ifpga_rawdev', 'ntb_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
driver_name_fmt = 'rte_pmd_@0@'
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
new file mode 100644
index 000000000..da87a4610
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb_rawdev.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_rawdev_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
new file mode 100644
index 000000000..ca905049d
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb_rawdev.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
new file mode 100644
index 000000000..07ad81d44
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_rawdev_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_rawdev_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_rawdev_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_rawdev_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_rawdev_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_rawdev_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_rawdev_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_rawdev_probe,
+ .remove = ntb_rawdev_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.h b/drivers/raw/ntb_rawdev/ntb_rawdev.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 2b5696a27..ead42ee3a 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -307,6 +307,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb_rawdev
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
` (3 subsequent siblings)
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
In order to allow binding/unbinding of devices for use by the
ntb_rawdev, we need to update the devbind script to add a new class
of device, and add device ids for the specific HW instances. And
only support Intel Skylake platform right now.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 8 ++++++++
usertools/dpdk-devbind.py | 9 +++++++++
2 files changed, 17 insertions(+)
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index ebc4dbc1e..71496bf44 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -16,6 +16,14 @@ Build Options
Toggle compilation of the ``ntb_rawdev`` driver.
+Device Setup
+------------
+
+The Intel NTB devices need to be bound to a DPDK-supported kernel driver
+to use, i.e. igb_uio, vfio. The ``dpdk-devbind.py`` script can be used to
+show devices status and to bind them to a suitable kernel driver. They will
+appear under the category of "Misc (rawdev) devices".
+
Limitation
----------
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 9e79f0d28..30d75f3f0 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -36,11 +36,15 @@
octeontx2_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
+
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
+misc_devices = [intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
@@ -595,6 +599,9 @@ def show_status():
if status_dev == "compress" or status_dev == "all":
show_device_status(compress_devices , "Compress")
+ if status_dev == "misc" or status_dev == "all":
+ show_device_status(misc_devices , "Misc (rawdev)")
+
def parse_args():
'''Parses the command-line arguments given by the user and takes the
@@ -670,6 +677,7 @@ def do_arg_actions():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
show_status()
@@ -690,6 +698,7 @@ def main():
get_device_details(eventdev_devices)
get_device_details(mempool_devices)
get_device_details(compress_devices)
+ get_device_details(misc_devices)
do_arg_actions()
if __name__ == "__main__":
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
` (2 subsequent siblings)
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add in the list of registers for the device. And enable ntb device
ops for Intel Skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 17 ++
drivers/raw/ntb_rawdev/Makefile | 1 +
drivers/raw/ntb_rawdev/meson.build | 3 +-
drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++++++++++++++++++++
drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 5 +
6 files changed, 480 insertions(+), 1 deletion(-)
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index 71496bf44..0e74897db 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -9,6 +9,22 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+BIOS setting on Intel Skylake
+-----------------------------
+
+Intel Non-transparent Bridge needs special BIOS setting. Since the PMD only
+supports Intel Skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
Build Options
-------------
@@ -28,3 +44,4 @@ Limitation
----------
- The FIFO hasn't been introduced and will come in 19.11 release.
+- This PMD only supports Intel Skylake platform.
diff --git a/drivers/raw/ntb_rawdev/Makefile b/drivers/raw/ntb_rawdev/Makefile
index da87a4610..74c045a86 100644
--- a/drivers/raw/ntb_rawdev/Makefile
+++ b/drivers/raw/ntb_rawdev/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_rawdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb_rawdev/meson.build b/drivers/raw/ntb_rawdev/meson.build
index ca905049d..c696f60b3 100644
--- a/drivers/raw/ntb_rawdev/meson.build
+++ b/drivers/raw/ntb_rawdev/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb_rawdev.c')
+sources = files('ntb_rawdev.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.c b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
new file mode 100644
index 000000000..834436b37
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.c
@@ -0,0 +1,369 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb_rawdev.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ default:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
+ hw->spad_user_list[i] = hw->spad_cnt;
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb_rawdev/ntb_hw_intel.h b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb_rawdev/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 07ad81d44..113ef0169 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb_rawdev.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
` (2 preceding siblings ...)
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
2019-07-02 14:10 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver " Ye Xiaolong
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
doc/guides/rawdevs/ntb_rawdev.rst | 5 +
drivers/raw/ntb_rawdev/ntb_rawdev.c | 336 +++++++++++++++++++++++++++-
2 files changed, 340 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rawdevs/ntb_rawdev.rst b/doc/guides/rawdevs/ntb_rawdev.rst
index 0e74897db..223b2a867 100644
--- a/doc/guides/rawdevs/ntb_rawdev.rst
+++ b/doc/guides/rawdevs/ntb_rawdev.rst
@@ -9,6 +9,11 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
BIOS setting on Intel Skylake
-----------------------------
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 113ef0169..005c5c3be 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
` (3 preceding siblings ...)
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
@ 2019-07-02 6:25 ` Xiaoyun Li
2019-07-02 14:10 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver " Ye Xiaolong
5 siblings, 0 replies; 127+ messages in thread
From: Xiaoyun Li @ 2019-07-02 6:25 UTC (permalink / raw)
To: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar; +Cc: dev, Xiaoyun Li
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
---
MAINTAINERS | 4 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++
drivers/raw/ntb_rawdev/ntb_rawdev.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 +++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 ++++++++++++++++++++++++++++
9 files changed, 535 insertions(+), 9 deletions(-)
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 9303624c6..c94739d26 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1475,3 +1475,7 @@ F: examples/tep_termination/
F: examples/vmdq/
F: examples/vmdq_dcb/
F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
diff --git a/drivers/raw/ntb_rawdev/ntb_rawdev.c b/drivers/raw/ntb_rawdev/ntb_rawdev.c
index 005c5c3be..91d6a015b 100644
--- a/drivers/raw/ntb_rawdev/ntb_rawdev.c
+++ b/drivers/raw/ntb_rawdev/ntb_rawdev.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+
+ size = (size_t)context;
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index 87113bd70..a046b74ad 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.17.1
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
` (4 preceding siblings ...)
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
@ 2019-07-02 14:10 ` Ye Xiaolong
5 siblings, 0 replies; 127+ messages in thread
From: Ye Xiaolong @ 2019-07-02 14:10 UTC (permalink / raw)
To: Xiaoyun Li; +Cc: jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar, dev
On 07/02, Xiaoyun Li wrote:
>This patch set adds support for Intel NTB device with Skylake platform.
>It is a raw device for allowing two hosts to communicate with each other
>and access the peer memory.
>
>This patch set also provides a simple example to transmit a file between
>two hosts. But since there is no FIFO here, only support file which is
>no more than 4M. And will add FIFO in the future.
>
>series Acked-by: Jingjing Wu <jingjing.wu@intel.com>
>
>v10:
>* Updated and refined the release notes in the same patch as the code.
>
>v9:
>* Fixed a typo.
>* Added default case for PPD parse.
>
>v8:
>* Fixed a coding style issue.
>* Rebased codes to the newest master branch.
>
>v7:
>* Fixed a typo.
>* Generic spad registers to be spad_user and the specific spad is
>* defined by the specific hw.
>* Refined the codes by replacing with lib functions such as rte_read32.
>* Rebased the codes to the newest dpdk-next-net-intel branch.
>
>v6:
>* Fixed a typo.
>
>v5:
>* Actual v4. v4 patchset is the same as v3.
>
>v4:
>* Fix compile issues of comparison of array with null pointer.
>
>v3:
>* Fixed compilation issues with target i686.
>* Renamed communication devices to misc devices in usertool.
>* Rebased to the newest dpdk-next-net-intel branch.
>
>v2:
>* Replaced ! with NULL check for pointers.
>* Added ntb_ops valid check before use it.
>* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
> not use 1G hugepage.
>* Added a timeout for dev_stop handshake in case that the peer stopped
> abnormally such as crashed while debugging.
>* Updated docs especailly about how to setup BIOS for skylake.
>* Fixed not return issue and not free issue in example.
>* Renamed ntb_devices to communication_devices to be more generic in
> usertools.
>* Polish the codes and docs.
>
>Xiaoyun Li (5):
> raw/ntb: introduce ntb rawdev driver
> usertools/dpdk-devbind.py: add support for ntb
> raw/ntb: add intel ntb support
> raw/ntb: add handshake process
> examples/ntb: enable an example for ntb
>
> MAINTAINERS | 9 +
> config/common_base | 5 +
> doc/guides/rawdevs/index.rst | 1 +
> doc/guides/rawdevs/ntb_rawdev.rst | 52 ++
> doc/guides/rel_notes/release_19_08.rst | 5 +
> doc/guides/sample_app_ug/index.rst | 1 +
> doc/guides/sample_app_ug/ntb.rst | 47 +
> drivers/raw/Makefile | 1 +
> drivers/raw/meson.build | 2 +-
> drivers/raw/ntb_rawdev/Makefile | 28 +
> drivers/raw/ntb_rawdev/meson.build | 8 +
> drivers/raw/ntb_rawdev/ntb_hw_intel.c | 369 ++++++++
> drivers/raw/ntb_rawdev/ntb_hw_intel.h | 86 ++
> drivers/raw/ntb_rawdev/ntb_rawdev.c | 839 ++++++++++++++++++
> drivers/raw/ntb_rawdev/ntb_rawdev.h | 164 ++++
> .../ntb_rawdev/rte_pmd_ntb_rawdev_version.map | 4 +
> examples/Makefile | 1 +
> examples/meson.build | 2 +-
> examples/ntb/Makefile | 68 ++
> examples/ntb/meson.build | 16 +
> examples/ntb/ntb_fwd.c | 377 ++++++++
> mk/rte.app.mk | 1 +
> usertools/dpdk-devbind.py | 9 +
> 23 files changed, 2093 insertions(+), 2 deletions(-)
> create mode 100644 doc/guides/rawdevs/ntb_rawdev.rst
> create mode 100644 doc/guides/sample_app_ug/ntb.rst
> create mode 100644 drivers/raw/ntb_rawdev/Makefile
> create mode 100644 drivers/raw/ntb_rawdev/meson.build
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_hw_intel.h
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.c
> create mode 100644 drivers/raw/ntb_rawdev/ntb_rawdev.h
> create mode 100644 drivers/raw/ntb_rawdev/rte_pmd_ntb_rawdev_version.map
> create mode 100644 examples/ntb/Makefile
> create mode 100644 examples/ntb/meson.build
> create mode 100644 examples/ntb/ntb_fwd.c
>
For the series, Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
>--
>2.17.1
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
@ 2019-07-04 10:31 ` Thomas Monjalon
2019-07-04 10:37 ` Bruce Richardson
` (2 more replies)
0 siblings, 3 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 10:31 UTC (permalink / raw)
To: Xiaoyun Li
Cc: dev, jingjing.wu, keith.wiles, cunming.liang, omkar.maslekar,
bruce.richardson, ferruh.yigit
02/07/2019 08:25, Xiaoyun Li:
> Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> can help to connect two separate hosts with each other.
[...]
> +NTB Rawdev
Is it Intel property? If yes, I suggest "Intel NTB" as title.
> +M: Xiaoyun Li <xiaoyun.li@intel.com>
> +M: Jingjing Wu <jingjing.wu@intel.com>
> +F: drivers/raw/ntb_rawdev/
> +F: doc/guides/rawdevs/ntb_rawdev.rst
Sorry I missed to check the naming here.
Why is it called "ntb_rawdev" and not just "ntb" ?
If you are OK with "ntb" as directory name, I can rename it while applying.
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-04 10:31 ` Thomas Monjalon
@ 2019-07-04 10:37 ` Bruce Richardson
2019-07-05 1:21 ` Li, Xiaoyun
2019-07-05 1:28 ` Li, Xiaoyun
2 siblings, 0 replies; 127+ messages in thread
From: Bruce Richardson @ 2019-07-04 10:37 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Xiaoyun Li, dev, jingjing.wu, keith.wiles, cunming.liang,
omkar.maslekar, ferruh.yigit
On Thu, Jul 04, 2019 at 12:31:49PM +0200, Thomas Monjalon wrote:
> 02/07/2019 08:25, Xiaoyun Li:
> > Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> > can help to connect two separate hosts with each other.
> [...]
> > +NTB Rawdev
>
> Is it Intel property? If yes, I suggest "Intel NTB" as title.
>
> > +M: Xiaoyun Li <xiaoyun.li@intel.com>
> > +M: Jingjing Wu <jingjing.wu@intel.com>
> > +F: drivers/raw/ntb_rawdev/
> > +F: doc/guides/rawdevs/ntb_rawdev.rst
>
> Sorry I missed to check the naming here.
> Why is it called "ntb_rawdev" and not just "ntb" ?
> If you are OK with "ntb" as directory name, I can rename it while applying.
>
Although I'm not the submitter here, I'd just like to "+1" the use of "ntb"
on its own as the name of the directory.
/Bruce
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
` (9 preceding siblings ...)
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
@ 2019-07-04 12:29 ` Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 1/4] raw/ntb: introduce NTB raw device driver Thomas Monjalon
` (4 more replies)
10 siblings, 5 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 12:29 UTC (permalink / raw)
To: dev
This patch set adds support for Intel NTB device with Skylake platform.
It is a raw device for allowing two hosts to communicate with each other
and access the peer memory.
This patch set also provides a simple example to transmit a file between
two hosts. But since there is no FIFO here, only support file which is
no more than 4M. And will add FIFO in the future.
v11 (Thomas):
* rebased on top of IOAT driver
* squashed commit for binding script
* renamed ntb_rawdev to ntb as agreed with Bruce
Please review this version, I may have done mistakes.
v10:
* Updated and refined the release notes in the same patch as the code.
v9:
* Fixed a typo.
* Added default case for PPD parse.
v8:
* Fixed a coding style issue.
* Rebased codes to the newest master branch.
v7:
* Fixed a typo.
* Generic spad registers to be spad_user and the specific spad is
* defined by the specific hw.
* Refined the codes by replacing with lib functions such as rte_read32.
* Rebased the codes to the newest dpdk-next-net-intel branch.
v6:
* Fixed a typo.
v5:
* Actual v4. v4 patchset is the same as v3.
v4:
* Fix compile issues of comparison of array with null pointer.
v3:
* Fixed compilation issues with target i686.
* Renamed communication devices to misc devices in usertool.
* Rebased to the newest dpdk-next-net-intel branch.
v2:
* Replaced ! with NULL check for pointers.
* Added ntb_ops valid check before use it.
* Replaced RTE_MEMZONE_1GB with RTE_MEMZONE_IOVA_CONTIG in case users do
not use 1G hugepage.
* Added a timeout for dev_stop handshake in case that the peer stopped
abnormally such as crashed while debugging.
* Updated docs especailly about how to setup BIOS for skylake.
* Fixed not return issue and not free issue in example.
* Renamed ntb_devices to communication_devices to be more generic in
usertools.
* Polish the codes and docs.
Xiaoyun Li (4):
raw/ntb: introduce NTB raw device driver
raw/ntb: support Intel NTB
raw/ntb: add handshake process
examples/ntb: add example for NTB
MAINTAINERS | 8 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb.rst | 52 ++
doc/guides/rel_notes/release_19_08.rst | 6 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb/Makefile | 28 +
drivers/raw/ntb/meson.build | 8 +
drivers/raw/ntb/ntb.c | 839 ++++++++++++++++++++++++
drivers/raw/ntb/ntb.h | 164 +++++
drivers/raw/ntb/ntb_hw_intel.c | 369 +++++++++++
drivers/raw/ntb/ntb_hw_intel.h | 86 +++
drivers/raw/ntb/rte_pmd_ntb_version.map | 4 +
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++
examples/ntb/meson.build | 16 +
examples/ntb/ntb_fwd.c | 377 +++++++++++
mk/rte.app.mk | 1 +
usertools/dpdk-devbind.py | 4 +-
23 files changed, 2087 insertions(+), 3 deletions(-)
create mode 100644 doc/guides/rawdevs/ntb.rst
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 drivers/raw/ntb/Makefile
create mode 100644 drivers/raw/ntb/meson.build
create mode 100644 drivers/raw/ntb/ntb.c
create mode 100644 drivers/raw/ntb/ntb.h
create mode 100644 drivers/raw/ntb/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb/ntb_hw_intel.h
create mode 100644 drivers/raw/ntb/rte_pmd_ntb_version.map
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
--
2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v11 1/4] raw/ntb: introduce NTB raw device driver
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
@ 2019-07-04 12:29 ` Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 2/4] raw/ntb: support Intel NTB Thomas Monjalon
` (3 subsequent siblings)
4 siblings, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 12:29 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic, Xiaoyun Li, Jingjing Wu; +Cc: Xiaolong Ye
From: Xiaoyun Li <xiaoyun.li@intel.com>
Introduce rawdev driver support for NTB (Non-transparent Bridge) which
can help to connect two separate hosts with each other.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
---
MAINTAINERS | 6 +
config/common_base | 5 +
doc/guides/rawdevs/index.rst | 1 +
doc/guides/rawdevs/ntb.rst | 22 ++
doc/guides/rel_notes/release_19_08.rst | 6 +
drivers/raw/Makefile | 1 +
drivers/raw/meson.build | 2 +-
drivers/raw/ntb/Makefile | 27 ++
drivers/raw/ntb/meson.build | 7 +
drivers/raw/ntb/ntb.c | 488 ++++++++++++++++++++++++
drivers/raw/ntb/ntb.h | 164 ++++++++
drivers/raw/ntb/rte_pmd_ntb_version.map | 4 +
mk/rte.app.mk | 1 +
13 files changed, 733 insertions(+), 1 deletion(-)
create mode 100644 doc/guides/rawdevs/ntb.rst
create mode 100644 drivers/raw/ntb/Makefile
create mode 100644 drivers/raw/ntb/meson.build
create mode 100644 drivers/raw/ntb/ntb.c
create mode 100644 drivers/raw/ntb/ntb.h
create mode 100644 drivers/raw/ntb/rte_pmd_ntb_version.map
diff --git a/MAINTAINERS b/MAINTAINERS
index 605422077..9e6308aa4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1105,6 +1105,12 @@ M: Nipun Gupta <nipun.gupta@nxp.com>
F: drivers/raw/dpaa2_cmdif/
F: doc/guides/rawdevs/dpaa2_cmdif.rst
+NTB
+M: Xiaoyun Li <xiaoyun.li@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: drivers/raw/ntb/
+F: doc/guides/rawdevs/ntb.rst
+
Packet processing
-----------------
diff --git a/config/common_base b/config/common_base
index f68107e7a..75e130a43 100644
--- a/config/common_base
+++ b/config/common_base
@@ -762,6 +762,11 @@ CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
#
CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV=y
+#
+# Compile PMD for NTB raw device
+#
+CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV=y
+
#
# Compile librte_ring
#
diff --git a/doc/guides/rawdevs/index.rst b/doc/guides/rawdevs/index.rst
index 0a21989e4..e19c4ec26 100644
--- a/doc/guides/rawdevs/index.rst
+++ b/doc/guides/rawdevs/index.rst
@@ -15,3 +15,4 @@ application through rawdev API.
dpaa2_qdma
ifpga_rawdev
ioat_rawdev
+ ntb
diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
new file mode 100644
index 000000000..9559ea4b0
--- /dev/null
+++ b/doc/guides/rawdevs/ntb.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2018 Intel Corporation.
+
+NTB Rawdev Driver
+=================
+
+The ``ntb`` rawdev driver provides a non-transparent bridge between two
+separate hosts so that they can communicate with each other. Thus, many
+user cases can benefit from this, such as fault tolerance and visual
+acceleration.
+
+Build Options
+-------------
+
+- ``CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV`` (default ``y``)
+
+ Toggle compilation of the ``ntb`` driver.
+
+Limitation
+----------
+
+- The FIFO hasn't been introduced and will come in 19.11 release.
diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst
index 21934bf01..8cd90e0c3 100644
--- a/doc/guides/rel_notes/release_19_08.rst
+++ b/doc/guides/rel_notes/release_19_08.rst
@@ -129,6 +129,12 @@ New Features
of via software, reducing cycles spent copying large blocks of data in
applications.
+* **Introduced NTB PMD.**
+
+ Added a PMD for Intel NTB (Non-transparent Bridge). This PMD implemented
+ handshake between two separate hosts and can share local memory for peer
+ host to directly access.
+
* **Updated telemetry library for global metrics support.**
Updated ``librte_telemetry`` to fetch the global metrics from the
diff --git a/drivers/raw/Makefile b/drivers/raw/Makefile
index c1b85c8c7..84a13b697 100644
--- a/drivers/raw/Makefile
+++ b/drivers/raw/Makefile
@@ -11,5 +11,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += dpaa2_qdma
endif
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += ifpga_rawdev
DIRS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += ioat
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/raw/meson.build b/drivers/raw/meson.build
index 2af8a70d4..47f0a1d5f 100644
--- a/drivers/raw/meson.build
+++ b/drivers/raw/meson.build
@@ -2,7 +2,7 @@
# Copyright 2018 NXP
drivers = ['dpaa2_cmdif', 'dpaa2_qdma',
- 'ifpga_rawdev', 'ioat',
+ 'ifpga_rawdev', 'ioat', 'ntb',
'skeleton_rawdev']
std_deps = ['rawdev']
config_flag_fmt = 'RTE_LIBRTE_PMD_@0@_RAWDEV'
diff --git a/drivers/raw/ntb/Makefile b/drivers/raw/ntb/Makefile
new file mode 100644
index 000000000..ec53edd33
--- /dev/null
+++ b/drivers/raw/ntb/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_ntb.a
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool
+LDLIBS += -lrte_pci -lrte_bus_pci
+LDLIBS += -lrte_rawdev
+
+EXPORT_MAP := rte_pmd_ntb_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb.c
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb/meson.build b/drivers/raw/ntb/meson.build
new file mode 100644
index 000000000..0fb44452c
--- /dev/null
+++ b/drivers/raw/ntb/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation.
+
+deps += ['rawdev', 'mbuf', 'mempool',
+ 'pci', 'bus_pci']
+sources = files('ntb.c')
+allow_experimental_apis = true
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
new file mode 100644
index 000000000..2ae3cbea0
--- /dev/null
+++ b/drivers/raw/ntb/ntb.c
@@ -0,0 +1,488 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_common.h>
+#include <rte_lcore.h>
+#include <rte_cycles.h>
+#include <rte_eal.h>
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_memzone.h>
+#include <rte_memcpy.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb.h"
+
+int ntb_logtype;
+
+static const struct rte_pci_id pci_id_ntb_map[] = {
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+static void
+ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+}
+
+static int
+ntb_queue_setup(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused,
+ rte_rawdev_obj_t queue_conf __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_queue_release(struct rte_rawdev *dev __rte_unused,
+ uint16_t queue_id __rte_unused)
+{
+ return 0;
+}
+
+static uint16_t
+ntb_queue_count(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ return hw->queue_pairs;
+}
+
+static int
+ntb_enqueue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static int
+ntb_dequeue_bufs(struct rte_rawdev *dev,
+ struct rte_rawdev_buf **buffers,
+ unsigned int count,
+ rte_rawdev_obj_t context)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(buffers);
+ RTE_SET_USED(count);
+ RTE_SET_USED(context);
+
+ return 0;
+}
+
+static void
+ntb_dev_info_get(struct rte_rawdev *dev, rte_rawdev_obj_t dev_info)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ struct ntb_attr *ntb_attrs = dev_info;
+
+ strncpy(ntb_attrs[NTB_TOPO_ID].name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN);
+ switch (hw->topo) {
+ case NTB_TOPO_B2B_DSD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B DSD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ case NTB_TOPO_B2B_USD:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "B2B USD",
+ NTB_ATTR_VAL_LEN);
+ break;
+ default:
+ strncpy(ntb_attrs[NTB_TOPO_ID].value, "Unsupported",
+ NTB_ATTR_VAL_LEN);
+ }
+
+ strncpy(ntb_attrs[NTB_LINK_STATUS_ID].name, NTB_LINK_STATUS_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_LINK_STATUS_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_status);
+
+ strncpy(ntb_attrs[NTB_SPEED_ID].name, NTB_SPEED_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPEED_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_speed);
+
+ strncpy(ntb_attrs[NTB_WIDTH_ID].name, NTB_WIDTH_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_WIDTH_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->link_width);
+
+ strncpy(ntb_attrs[NTB_MW_CNT_ID].name, NTB_MW_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_MW_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->mw_cnt);
+
+ strncpy(ntb_attrs[NTB_DB_CNT_ID].name, NTB_DB_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_DB_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->db_cnt);
+
+ strncpy(ntb_attrs[NTB_SPAD_CNT_ID].name, NTB_SPAD_CNT_NAME,
+ NTB_ATTR_NAME_LEN);
+ snprintf(ntb_attrs[NTB_SPAD_CNT_ID].value, NTB_ATTR_VAL_LEN,
+ "%d", hw->spad_cnt);
+}
+
+static int
+ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
+ rte_rawdev_obj_t config __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_dev_start(struct rte_rawdev *dev)
+{
+ /* TODO: init queues and start queues. */
+ dev->started = 1;
+
+ return 0;
+}
+
+static void
+ntb_dev_stop(struct rte_rawdev *dev)
+{
+ /* TODO: stop rx/tx queues. */
+ dev->started = 0;
+}
+
+static int
+ntb_dev_close(struct rte_rawdev *dev)
+{
+ int ret = 0;
+
+ if (dev->started)
+ ntb_dev_stop(dev);
+
+ /* TODO: free queues. */
+
+ return ret;
+}
+
+static int
+ntb_dev_reset(struct rte_rawdev *rawdev __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_attr_set(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for setting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_write == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ (*hw->ntb_ops->spad_write)(dev, hw->spad_user_list[index],
+ 1, attr_value);
+ NTB_LOG(INFO, "Set attribute (%s) Value (%" PRIu64 ")",
+ attr_name, attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_attr_get(struct rte_rawdev *dev, const char *attr_name,
+ uint64_t *attr_value)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int index = 0;
+
+ if (dev == NULL || attr_name == NULL || attr_value == NULL) {
+ NTB_LOG(ERR, "Invalid arguments for getting attributes");
+ return -EINVAL;
+ }
+
+ if (!strncmp(attr_name, NTB_TOPO_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->topo;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_LINK_STATUS_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_status;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPEED_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_speed;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_WIDTH_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->link_width;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_MW_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->mw_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_DB_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->db_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_CNT_NAME, NTB_ATTR_NAME_LEN)) {
+ *attr_value = hw->spad_cnt;
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ if (!strncmp(attr_name, NTB_SPAD_USER, NTB_SPAD_USER_LEN)) {
+ if (hw->ntb_ops->spad_read == NULL)
+ return -ENOTSUP;
+ index = atoi(&attr_name[NTB_SPAD_USER_LEN]);
+ *attr_value = (*hw->ntb_ops->spad_read)(dev,
+ hw->spad_user_list[index], 0);
+ NTB_LOG(INFO, "Attribute (%s) Value (%" PRIu64 ")",
+ attr_name, *attr_value);
+ return 0;
+ }
+
+ /* Attribute not found. */
+ NTB_LOG(ERR, "Attribute not found.");
+ return -EINVAL;
+}
+
+static int
+ntb_xstats_get(const struct rte_rawdev *dev __rte_unused,
+ const unsigned int ids[] __rte_unused,
+ uint64_t values[] __rte_unused,
+ unsigned int n __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_get_names(const struct rte_rawdev *dev __rte_unused,
+ struct rte_rawdev_xstats_name *xstats_names __rte_unused,
+ unsigned int size __rte_unused)
+{
+ return 0;
+}
+
+static uint64_t
+ntb_xstats_get_by_name(const struct rte_rawdev *dev __rte_unused,
+ const char *name __rte_unused,
+ unsigned int *id __rte_unused)
+{
+ return 0;
+}
+
+static int
+ntb_xstats_reset(struct rte_rawdev *dev __rte_unused,
+ const uint32_t ids[] __rte_unused,
+ uint32_t nb_ids __rte_unused)
+{
+ return 0;
+}
+
+static const struct rte_rawdev_ops ntb_ops = {
+ .dev_info_get = ntb_dev_info_get,
+ .dev_configure = ntb_dev_configure,
+ .dev_start = ntb_dev_start,
+ .dev_stop = ntb_dev_stop,
+ .dev_close = ntb_dev_close,
+ .dev_reset = ntb_dev_reset,
+
+ .queue_def_conf = ntb_queue_conf_get,
+ .queue_setup = ntb_queue_setup,
+ .queue_release = ntb_queue_release,
+ .queue_count = ntb_queue_count,
+
+ .enqueue_bufs = ntb_enqueue_bufs,
+ .dequeue_bufs = ntb_dequeue_bufs,
+
+ .attr_get = ntb_attr_get,
+ .attr_set = ntb_attr_set,
+
+ .xstats_get = ntb_xstats_get,
+ .xstats_get_names = ntb_xstats_get_names,
+ .xstats_get_by_name = ntb_xstats_get_by_name,
+ .xstats_reset = ntb_xstats_reset,
+};
+
+static int
+ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret;
+
+ hw->pci_dev = pci_dev;
+ hw->peer_dev_up = 0;
+ hw->link_status = NTB_LINK_DOWN;
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+
+ switch (pci_dev->id.device_id) {
+ default:
+ NTB_LOG(ERR, "Not supported device.");
+ return -EINVAL;
+ }
+
+ if (hw->ntb_ops->ntb_dev_init == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->ntb_dev_init)(dev);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to init ntb dev.");
+ return ret;
+ }
+
+ if (hw->ntb_ops->set_link == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->set_link)(dev, 1);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int
+ntb_create(struct rte_pci_device *pci_dev, int socket_id)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev = NULL;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Init %s on NUMA node %d", name, socket_id);
+
+ /* Allocate device structure. */
+ rawdev = rte_rawdev_pmd_allocate(name, sizeof(struct ntb_hw),
+ socket_id);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Unable to allocate rawdev.");
+ ret = -EINVAL;
+ }
+
+ rawdev->dev_ops = &ntb_ops;
+ rawdev->device = &pci_dev->device;
+ rawdev->driver_name = pci_dev->driver->driver.name;
+
+ ret = ntb_init_hw(rawdev, pci_dev);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to init ntb hw.");
+ goto fail;
+ }
+
+ return ret;
+
+fail:
+ if (rawdev)
+ rte_rawdev_pmd_release(rawdev);
+
+ return ret;
+}
+
+static int
+ntb_destroy(struct rte_pci_device *pci_dev)
+{
+ char name[RTE_RAWDEV_NAME_MAX_LEN];
+ struct rte_rawdev *rawdev;
+ int ret;
+
+ if (pci_dev == NULL) {
+ NTB_LOG(ERR, "Invalid pci_dev.");
+ ret = -EINVAL;
+ return ret;
+ }
+
+ memset(name, 0, sizeof(name));
+ snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "NTB:%x:%02x.%x",
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ NTB_LOG(INFO, "Closing %s on NUMA node %d", name, rte_socket_id());
+
+ rawdev = rte_rawdev_pmd_get_named_dev(name);
+ if (rawdev == NULL) {
+ NTB_LOG(ERR, "Invalid device name (%s)", name);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = rte_rawdev_pmd_release(rawdev);
+ if (ret)
+ NTB_LOG(ERR, "Failed to destroy ntb rawdev.");
+
+ return ret;
+}
+
+static int
+ntb_probe(struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ return ntb_create(pci_dev, rte_socket_id());
+}
+
+static int
+ntb_remove(struct rte_pci_device *pci_dev)
+{
+ return ntb_destroy(pci_dev);
+}
+
+
+static struct rte_pci_driver rte_ntb_pmd = {
+ .id_table = pci_id_ntb_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ .probe = ntb_probe,
+ .remove = ntb_remove,
+};
+
+RTE_PMD_REGISTER_PCI(raw_ntb, rte_ntb_pmd);
+RTE_PMD_REGISTER_PCI_TABLE(raw_ntb, pci_id_ntb_map);
+RTE_PMD_REGISTER_KMOD_DEP(raw_ntb, "* igb_uio | uio_pci_generic | vfio-pci");
+
+RTE_INIT(ntb_init_log)
+{
+ ntb_logtype = rte_log_register("pmd.raw.ntb");
+ if (ntb_logtype >= 0)
+ rte_log_set_level(ntb_logtype, RTE_LOG_DEBUG);
+}
diff --git a/drivers/raw/ntb/ntb.h b/drivers/raw/ntb/ntb.h
new file mode 100644
index 000000000..d355231b0
--- /dev/null
+++ b/drivers/raw/ntb/ntb.h
@@ -0,0 +1,164 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_RAWDEV_H_
+#define _NTB_RAWDEV_H_
+
+#include <stdbool.h>
+
+extern int ntb_logtype;
+
+#define NTB_LOG(level, fmt, args...) \
+ rte_log(RTE_LOG_ ## level, ntb_logtype, "%s(): " fmt "\n", \
+ __func__, ##args)
+
+/* Vendor ID */
+#define NTB_INTEL_VENDOR_ID 0x8086
+
+/* Device IDs */
+#define NTB_INTEL_DEV_ID_B2B_SKX 0x201C
+
+#define NTB_TOPO_NAME "topo"
+#define NTB_LINK_STATUS_NAME "link_status"
+#define NTB_SPEED_NAME "speed"
+#define NTB_WIDTH_NAME "width"
+#define NTB_MW_CNT_NAME "mw_count"
+#define NTB_DB_CNT_NAME "db_count"
+#define NTB_SPAD_CNT_NAME "spad_count"
+/* Reserved to app to use. */
+#define NTB_SPAD_USER "spad_user_"
+#define NTB_SPAD_USER_LEN (sizeof(NTB_SPAD_USER) - 1)
+#define NTB_SPAD_USER_MAX_NUM 10
+#define NTB_ATTR_NAME_LEN 30
+#define NTB_ATTR_VAL_LEN 30
+#define NTB_ATTR_MAX 20
+
+/* NTB Attributes */
+struct ntb_attr {
+ /**< Name of the attribute */
+ char name[NTB_ATTR_NAME_LEN];
+ /**< Value or reference of value of attribute */
+ char value[NTB_ATTR_NAME_LEN];
+};
+
+enum ntb_attr_idx {
+ NTB_TOPO_ID = 0,
+ NTB_LINK_STATUS_ID,
+ NTB_SPEED_ID,
+ NTB_WIDTH_ID,
+ NTB_MW_CNT_ID,
+ NTB_DB_CNT_ID,
+ NTB_SPAD_CNT_ID,
+};
+
+enum ntb_topo {
+ NTB_TOPO_NONE = 0,
+ NTB_TOPO_B2B_USD,
+ NTB_TOPO_B2B_DSD,
+};
+
+enum ntb_link {
+ NTB_LINK_DOWN = 0,
+ NTB_LINK_UP,
+};
+
+enum ntb_speed {
+ NTB_SPEED_NONE = 0,
+ NTB_SPEED_GEN1 = 1,
+ NTB_SPEED_GEN2 = 2,
+ NTB_SPEED_GEN3 = 3,
+ NTB_SPEED_GEN4 = 4,
+};
+
+enum ntb_width {
+ NTB_WIDTH_NONE = 0,
+ NTB_WIDTH_1 = 1,
+ NTB_WIDTH_2 = 2,
+ NTB_WIDTH_4 = 4,
+ NTB_WIDTH_8 = 8,
+ NTB_WIDTH_12 = 12,
+ NTB_WIDTH_16 = 16,
+ NTB_WIDTH_32 = 32,
+};
+
+/* Define spad registers usage. 0 is reserved. */
+enum ntb_spad_idx {
+ SPAD_NUM_MWS = 1,
+ SPAD_NUM_QPS,
+ SPAD_Q_SZ,
+ SPAD_MW0_SZ_H,
+ SPAD_MW0_SZ_L,
+ SPAD_MW1_SZ_H,
+ SPAD_MW1_SZ_L,
+};
+
+/**
+ * NTB device operations
+ * @ntb_dev_init: Init ntb dev.
+ * @get_peer_mw_addr: To get the addr of peer mw[mw_idx].
+ * @mw_set_trans: Set translation of internal memory that remote can access.
+ * @get_link_status: get link status, link speed and link width.
+ * @set_link: Set local side up/down.
+ * @spad_read: Read local/peer spad register val.
+ * @spad_write: Write val to local/peer spad register.
+ * @db_read: Read doorbells status.
+ * @db_clear: Clear local doorbells.
+ * @db_set_mask: Set bits in db mask, preventing db interrpts generated
+ * for those db bits.
+ * @peer_db_set: Set doorbell bit to generate peer interrupt for that bit.
+ * @vector_bind: Bind vector source [intr] to msix vector [msix].
+ */
+struct ntb_dev_ops {
+ int (*ntb_dev_init)(struct rte_rawdev *dev);
+ void *(*get_peer_mw_addr)(struct rte_rawdev *dev, int mw_idx);
+ int (*mw_set_trans)(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size);
+ int (*get_link_status)(struct rte_rawdev *dev);
+ int (*set_link)(struct rte_rawdev *dev, bool up);
+ uint32_t (*spad_read)(struct rte_rawdev *dev, int spad, bool peer);
+ int (*spad_write)(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v);
+ uint64_t (*db_read)(struct rte_rawdev *dev);
+ int (*db_clear)(struct rte_rawdev *dev, uint64_t db_bits);
+ int (*db_set_mask)(struct rte_rawdev *dev, uint64_t db_mask);
+ int (*peer_db_set)(struct rte_rawdev *dev, uint8_t db_bit);
+ int (*vector_bind)(struct rte_rawdev *dev, uint8_t intr, uint8_t msix);
+};
+
+/* ntb private data. */
+struct ntb_hw {
+ uint8_t mw_cnt;
+ uint8_t peer_mw_cnt;
+ uint8_t db_cnt;
+ uint8_t spad_cnt;
+
+ uint64_t db_valid_mask;
+ uint64_t db_mask;
+
+ enum ntb_topo topo;
+
+ enum ntb_link link_status;
+ enum ntb_speed link_speed;
+ enum ntb_width link_width;
+
+ const struct ntb_dev_ops *ntb_ops;
+
+ struct rte_pci_device *pci_dev;
+ char *hw_addr;
+
+ uint64_t *mw_size;
+ uint64_t *peer_mw_size;
+ uint8_t peer_dev_up;
+
+ uint16_t queue_pairs;
+ uint16_t queue_size;
+
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone **mz;
+
+ /* Reserve several spad for app to use. */
+ int spad_user_list[NTB_SPAD_USER_MAX_NUM];
+};
+
+#endif /* _NTB_RAWDEV_H_ */
diff --git a/drivers/raw/ntb/rte_pmd_ntb_version.map b/drivers/raw/ntb/rte_pmd_ntb_version.map
new file mode 100644
index 000000000..8861484fb
--- /dev/null
+++ b/drivers/raw/ntb/rte_pmd_ntb_version.map
@@ -0,0 +1,4 @@
+DPDK_19.08 {
+
+ local: *;
+};
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 30f9a12da..d3d12350b 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -310,6 +310,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV) += -lrte_pmd_ifpga_rawdev
_LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD) += -lrte_pmd_ipn3ke
endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV) += -lrte_pmd_ioat_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += -lrte_pmd_ntb
endif # CONFIG_RTE_LIBRTE_RAWDEV
endif # !CONFIG_RTE_BUILD_SHARED_LIBS
--
2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v11 2/4] raw/ntb: support Intel NTB
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 1/4] raw/ntb: introduce NTB raw device driver Thomas Monjalon
@ 2019-07-04 12:29 ` Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 3/4] raw/ntb: add handshake process Thomas Monjalon
` (2 subsequent siblings)
4 siblings, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 12:29 UTC (permalink / raw)
To: dev, Xiaoyun Li, Jingjing Wu, John McNamara, Marko Kovacevic; +Cc: Xiaolong Ye
From: Xiaoyun Li <xiaoyun.li@intel.com>
Add in the list of registers for the device.
And enable NTB device ops for Intel Skylake platform.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
---
doc/guides/rawdevs/ntb.rst | 25 +++
drivers/raw/ntb/Makefile | 1 +
drivers/raw/ntb/meson.build | 3 +-
drivers/raw/ntb/ntb.c | 5 +
drivers/raw/ntb/ntb_hw_intel.c | 369 +++++++++++++++++++++++++++++++++
drivers/raw/ntb/ntb_hw_intel.h | 86 ++++++++
usertools/dpdk-devbind.py | 4 +-
7 files changed, 491 insertions(+), 2 deletions(-)
create mode 100644 drivers/raw/ntb/ntb_hw_intel.c
create mode 100644 drivers/raw/ntb/ntb_hw_intel.h
diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index 9559ea4b0..ff0795b47 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -9,6 +9,22 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+BIOS setting on Intel Skylake
+-----------------------------
+
+Intel Non-transparent Bridge needs special BIOS setting. Since the PMD only
+supports Intel Skylake platform, introduce BIOS setting here. The referencce
+is https://www.intel.com/content/dam/support/us/en/documents/server-products/Intel_Xeon_Processor_Scalable_Family_BIOS_User_Guide.pdf
+
+- Set the needed PCIe port as NTB to NTB mode on both hosts.
+- Enable NTB bars and set bar size of bar 23 and bar 45 as 12-29 (2K-512M)
+ on both hosts. Note that bar size on both hosts should be the same.
+- Disable split bars for both hosts.
+- Set crosslink control override as DSD/USP on one host, USD/DSP on
+ another host.
+- Disable PCIe PII SSC (Spread Spectrum Clocking) for both hosts. This
+ is a hardware requirement.
+
Build Options
-------------
@@ -16,7 +32,16 @@ Build Options
Toggle compilation of the ``ntb`` driver.
+Device Setup
+------------
+
+The Intel NTB devices need to be bound to a DPDK-supported kernel driver
+to use, i.e. igb_uio, vfio. The ``dpdk-devbind.py`` script can be used to
+show devices status and to bind them to a suitable kernel driver. They will
+appear under the category of "Misc (rawdev) devices".
+
Limitation
----------
- The FIFO hasn't been introduced and will come in 19.11 release.
+- This PMD only supports Intel Skylake platform.
diff --git a/drivers/raw/ntb/Makefile b/drivers/raw/ntb/Makefile
index ec53edd33..edd49fe75 100644
--- a/drivers/raw/ntb/Makefile
+++ b/drivers/raw/ntb/Makefile
@@ -23,5 +23,6 @@ LIBABIVER := 1
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_NTB_RAWDEV) += ntb_hw_intel.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/raw/ntb/meson.build b/drivers/raw/ntb/meson.build
index 0fb44452c..7f39437f8 100644
--- a/drivers/raw/ntb/meson.build
+++ b/drivers/raw/ntb/meson.build
@@ -3,5 +3,6 @@
deps += ['rawdev', 'mbuf', 'mempool',
'pci', 'bus_pci']
-sources = files('ntb.c')
+sources = files('ntb.c',
+ 'ntb_hw_intel.c')
allow_experimental_apis = true
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 2ae3cbea0..5fde704b7 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -18,11 +18,13 @@
#include <rte_rawdev.h>
#include <rte_rawdev_pmd.h>
+#include "ntb_hw_intel.h"
#include "ntb.h"
int ntb_logtype;
static const struct rte_pci_id pci_id_ntb_map[] = {
+ { RTE_PCI_DEVICE(NTB_INTEL_VENDOR_ID, NTB_INTEL_DEV_ID_B2B_SKX) },
{ .vendor_id = 0, /* sentinel */ },
};
@@ -353,6 +355,9 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
hw->link_width = NTB_WIDTH_NONE;
switch (pci_dev->id.device_id) {
+ case NTB_INTEL_DEV_ID_B2B_SKX:
+ hw->ntb_ops = &intel_ntb_ops;
+ break;
default:
NTB_LOG(ERR, "Not supported device.");
return -EINVAL;
diff --git a/drivers/raw/ntb/ntb_hw_intel.c b/drivers/raw/ntb/ntb_hw_intel.c
new file mode 100644
index 000000000..21eaa8511
--- /dev/null
+++ b/drivers/raw/ntb/ntb_hw_intel.c
@@ -0,0 +1,369 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <rte_io.h>
+#include <rte_eal.h>
+#include <rte_pci.h>
+#include <rte_bus_pci.h>
+#include <rte_rawdev.h>
+#include <rte_rawdev_pmd.h>
+
+#include "ntb.h"
+#include "ntb_hw_intel.h"
+
+enum xeon_ntb_bar {
+ XEON_NTB_BAR23 = 2,
+ XEON_NTB_BAR45 = 4,
+};
+
+static enum xeon_ntb_bar intel_ntb_bar[] = {
+ XEON_NTB_BAR23,
+ XEON_NTB_BAR45,
+};
+
+static int
+intel_ntb_dev_init(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_val, bar;
+ int ret, i;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_PPD_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Cannot get NTB PPD (PCIe port definition).");
+ return -EIO;
+ }
+
+ /* Check connection topo type. Only support B2B. */
+ switch (reg_val & XEON_PPD_CONN_MASK) {
+ case XEON_PPD_CONN_B2B:
+ NTB_LOG(INFO, "Topo B2B (back to back) is using.");
+ break;
+ case XEON_PPD_CONN_TRANSPARENT:
+ case XEON_PPD_CONN_RP:
+ default:
+ NTB_LOG(ERR, "Not supported conn topo. Please use B2B.");
+ return -EINVAL;
+ }
+
+ /* Check device type. */
+ if (reg_val & XEON_PPD_DEV_DSD) {
+ NTB_LOG(INFO, "DSD, Downstream Device.");
+ hw->topo = NTB_TOPO_B2B_DSD;
+ } else {
+ NTB_LOG(INFO, "USD, Upstream device.");
+ hw->topo = NTB_TOPO_B2B_USD;
+ }
+
+ /* Check if bar4 is split. Do not support split bar. */
+ if (reg_val & XEON_PPD_SPLIT_BAR_MASK) {
+ NTB_LOG(ERR, "Do not support split bar.");
+ return -EINVAL;
+ }
+
+ hw->hw_addr = (char *)hw->pci_dev->mem_resource[0].addr;
+
+ hw->mw_cnt = XEON_MW_COUNT;
+ hw->db_cnt = XEON_DB_COUNT;
+ hw->spad_cnt = XEON_SPAD_COUNT;
+
+ hw->mw_size = rte_zmalloc("uint64_t",
+ hw->mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ bar = intel_ntb_bar[i];
+ hw->mw_size[i] = hw->pci_dev->mem_resource[bar].len;
+ }
+
+ /* Reserve the last 2 spad registers for users. */
+ for (i = 0; i < NTB_SPAD_USER_MAX_NUM; i++)
+ hw->spad_user_list[i] = hw->spad_cnt;
+ hw->spad_user_list[0] = hw->spad_cnt - 2;
+ hw->spad_user_list[1] = hw->spad_cnt - 1;
+
+ return 0;
+}
+
+static void *
+intel_ntb_get_peer_mw_addr(struct rte_rawdev *dev, int mw_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return 0;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return 0;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ return hw->pci_dev->mem_resource[bar].addr;
+}
+
+static int
+intel_ntb_mw_set_trans(struct rte_rawdev *dev, int mw_idx,
+ uint64_t addr, uint64_t size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ void *xlat_addr, *limit_addr;
+ uint64_t xlat_off, limit_off;
+ uint64_t base, limit;
+ uint8_t bar;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ if (mw_idx < 0 || mw_idx >= hw->mw_cnt) {
+ NTB_LOG(ERR, "Invalid memory window index (0 - %u).",
+ hw->mw_cnt - 1);
+ return -EINVAL;
+ }
+
+ bar = intel_ntb_bar[mw_idx];
+
+ xlat_off = XEON_IMBAR1XBASE_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_off = XEON_IMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_addr = hw->hw_addr + limit_off;
+
+ /* Limit reg val should be EMBAR base address plus MW size. */
+ base = addr;
+ limit = hw->pci_dev->mem_resource[bar].phys_addr + size;
+ rte_write64(base, xlat_addr);
+ rte_write64(limit, limit_addr);
+
+ /* Setup the external point so that remote can access. */
+ xlat_off = XEON_EMBAR1_OFFSET + 8 * mw_idx;
+ xlat_addr = hw->hw_addr + xlat_off;
+ limit_off = XEON_EMBAR1XLMT_OFFSET + mw_idx * XEON_BAR_INTERVAL_OFFSET;
+ limit_addr = hw->hw_addr + limit_off;
+ base = rte_read64(xlat_addr);
+ base &= ~0xf;
+ limit = base + size;
+ rte_write64(limit, limit_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_get_link_status(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint16_t reg_val;
+ int ret;
+
+ if (hw == NULL) {
+ NTB_LOG(ERR, "Invalid device.");
+ return -EINVAL;
+ }
+
+ ret = rte_pci_read_config(hw->pci_dev, ®_val,
+ sizeof(reg_val), XEON_LINK_STATUS_OFFSET);
+ if (ret < 0) {
+ NTB_LOG(ERR, "Unable to get link status.");
+ return -EIO;
+ }
+
+ hw->link_status = NTB_LNK_STA_ACTIVE(reg_val);
+
+ if (hw->link_status) {
+ hw->link_speed = NTB_LNK_STA_SPEED(reg_val);
+ hw->link_width = NTB_LNK_STA_WIDTH(reg_val);
+ } else {
+ hw->link_speed = NTB_SPEED_NONE;
+ hw->link_width = NTB_WIDTH_NONE;
+ }
+
+ return 0;
+}
+
+static int
+intel_ntb_set_link(struct rte_rawdev *dev, bool up)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t ntb_ctrl, reg_off;
+ void *reg_addr;
+
+ reg_off = XEON_NTBCNTL_OFFSET;
+ reg_addr = hw->hw_addr + reg_off;
+ ntb_ctrl = rte_read32(reg_addr);
+
+ if (up) {
+ ntb_ctrl &= ~(NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK);
+ ntb_ctrl |= NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP;
+ ntb_ctrl |= NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP;
+ } else {
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR2_SNOOP | NTB_CTL_S2P_BAR2_SNOOP);
+ ntb_ctrl &= ~(NTB_CTL_P2S_BAR4_SNOOP | NTB_CTL_S2P_BAR4_SNOOP);
+ ntb_ctrl |= NTB_CTL_DISABLE | NTB_CTL_CFG_LOCK;
+ }
+
+ rte_write32(ntb_ctrl, reg_addr);
+
+ return 0;
+}
+
+static uint32_t
+intel_ntb_spad_read(struct rte_rawdev *dev, int spad, bool peer)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t spad_v, reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return 0;
+ }
+
+ /* When peer is true, read peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+ spad_v = rte_read32(reg_addr);
+
+ return spad_v;
+}
+
+static int
+intel_ntb_spad_write(struct rte_rawdev *dev, int spad,
+ bool peer, uint32_t spad_v)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t reg_off;
+ void *reg_addr;
+
+ if (spad < 0 || spad >= hw->spad_cnt) {
+ NTB_LOG(ERR, "Invalid spad reg index.");
+ return -EINVAL;
+ }
+
+ /* When peer is true, write peer spad reg */
+ reg_off = peer ? XEON_B2B_SPAD_OFFSET : XEON_IM_SPAD_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + (spad << 2);
+
+ rte_write32(spad_v, reg_addr);
+
+ return 0;
+}
+
+static uint64_t
+intel_ntb_db_read(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off, db_bits;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ db_bits = rte_read64(db_addr);
+
+ return db_bits;
+}
+
+static int
+intel_ntb_db_clear(struct rte_rawdev *dev, uint64_t db_bits)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_off;
+ void *db_addr;
+
+ db_off = XEON_IM_INT_STATUS_OFFSET;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write64(db_bits, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_db_set_mask(struct rte_rawdev *dev, uint64_t db_mask)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint64_t db_m_off;
+ void *db_m_addr;
+
+ db_m_off = XEON_IM_INT_DISABLE_OFFSET;
+ db_m_addr = hw->hw_addr + db_m_off;
+
+ db_mask |= hw->db_mask;
+
+ rte_write64(db_mask, db_m_addr);
+
+ hw->db_mask = db_mask;
+
+ return 0;
+}
+
+static int
+intel_ntb_peer_db_set(struct rte_rawdev *dev, uint8_t db_idx)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t db_off;
+ void *db_addr;
+
+ if (((uint64_t)1 << db_idx) & ~hw->db_valid_mask) {
+ NTB_LOG(ERR, "Invalid doorbell.");
+ return -EINVAL;
+ }
+
+ db_off = XEON_IM_DOORBELL_OFFSET + db_idx * 4;
+ db_addr = hw->hw_addr + db_off;
+
+ rte_write32(1, db_addr);
+
+ return 0;
+}
+
+static int
+intel_ntb_vector_bind(struct rte_rawdev *dev, uint8_t intr, uint8_t msix)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ uint8_t reg_off;
+ void *reg_addr;
+
+ if (intr >= hw->db_cnt) {
+ NTB_LOG(ERR, "Invalid intr source.");
+ return -EINVAL;
+ }
+
+ /* Bind intr source to msix vector */
+ reg_off = XEON_INTVEC_OFFSET;
+ reg_addr = hw->hw_addr + reg_off + intr;
+
+ rte_write8(msix, reg_addr);
+
+ return 0;
+}
+
+/* operations for primary side of local ntb */
+const struct ntb_dev_ops intel_ntb_ops = {
+ .ntb_dev_init = intel_ntb_dev_init,
+ .get_peer_mw_addr = intel_ntb_get_peer_mw_addr,
+ .mw_set_trans = intel_ntb_mw_set_trans,
+ .get_link_status = intel_ntb_get_link_status,
+ .set_link = intel_ntb_set_link,
+ .spad_read = intel_ntb_spad_read,
+ .spad_write = intel_ntb_spad_write,
+ .db_read = intel_ntb_db_read,
+ .db_clear = intel_ntb_db_clear,
+ .db_set_mask = intel_ntb_db_set_mask,
+ .peer_db_set = intel_ntb_peer_db_set,
+ .vector_bind = intel_ntb_vector_bind,
+};
diff --git a/drivers/raw/ntb/ntb_hw_intel.h b/drivers/raw/ntb/ntb_hw_intel.h
new file mode 100644
index 000000000..4d1e64504
--- /dev/null
+++ b/drivers/raw/ntb/ntb_hw_intel.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation.
+ */
+
+#ifndef _NTB_HW_INTEL_H_
+#define _NTB_HW_INTEL_H_
+
+/* Ntb control and link status */
+#define NTB_CTL_CFG_LOCK 1
+#define NTB_CTL_DISABLE 2
+#define NTB_CTL_S2P_BAR2_SNOOP (1 << 2)
+#define NTB_CTL_P2S_BAR2_SNOOP (1 << 4)
+#define NTB_CTL_S2P_BAR4_SNOOP (1 << 6)
+#define NTB_CTL_P2S_BAR4_SNOOP (1 << 8)
+#define NTB_CTL_S2P_BAR5_SNOOP (1 << 12)
+#define NTB_CTL_P2S_BAR5_SNOOP (1 << 14)
+
+#define NTB_LNK_STA_ACTIVE_BIT 0x2000
+#define NTB_LNK_STA_SPEED_MASK 0x000f
+#define NTB_LNK_STA_WIDTH_MASK 0x03f0
+#define NTB_LNK_STA_ACTIVE(x) (!!((x) & NTB_LNK_STA_ACTIVE_BIT))
+#define NTB_LNK_STA_SPEED(x) ((x) & NTB_LNK_STA_SPEED_MASK)
+#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 4)
+
+/* Intel Skylake Xeon hardware */
+#define XEON_IMBAR1SZ_OFFSET 0x00d0
+#define XEON_IMBAR2SZ_OFFSET 0x00d1
+#define XEON_EMBAR1SZ_OFFSET 0x00d2
+#define XEON_EMBAR2SZ_OFFSET 0x00d3
+#define XEON_DEVCTRL_OFFSET 0x0098
+#define XEON_DEVSTS_OFFSET 0x009a
+#define XEON_UNCERRSTS_OFFSET 0x014c
+#define XEON_CORERRSTS_OFFSET 0x0158
+#define XEON_LINK_STATUS_OFFSET 0x01a2
+
+#define XEON_NTBCNTL_OFFSET 0x0000
+#define XEON_BAR_INTERVAL_OFFSET 0x0010
+#define XEON_IMBAR1XBASE_OFFSET 0x0010 /* SBAR2XLAT */
+#define XEON_IMBAR1XLMT_OFFSET 0x0018 /* SBAR2LMT */
+#define XEON_IMBAR2XBASE_OFFSET 0x0020 /* SBAR4XLAT */
+#define XEON_IMBAR2XLMT_OFFSET 0x0028 /* SBAR4LMT */
+#define XEON_IM_INT_STATUS_OFFSET 0x0040
+#define XEON_IM_INT_DISABLE_OFFSET 0x0048
+#define XEON_IM_SPAD_OFFSET 0x0080 /* SPAD */
+#define XEON_USMEMMISS_OFFSET 0x0070
+#define XEON_INTVEC_OFFSET 0x00d0
+#define XEON_IM_DOORBELL_OFFSET 0x0100 /* SDOORBELL0 */
+#define XEON_B2B_SPAD_OFFSET 0x0180 /* B2B SPAD */
+#define XEON_EMBAR0XBASE_OFFSET 0x4008 /* B2B_XLAT */
+#define XEON_EMBAR1XBASE_OFFSET 0x4010 /* PBAR2XLAT */
+#define XEON_EMBAR1XLMT_OFFSET 0x4018 /* PBAR2LMT */
+#define XEON_EMBAR2XBASE_OFFSET 0x4020 /* PBAR4XLAT */
+#define XEON_EMBAR2XLMT_OFFSET 0x4028 /* PBAR4LMT */
+#define XEON_EM_INT_STATUS_OFFSET 0x4040
+#define XEON_EM_INT_DISABLE_OFFSET 0x4048
+#define XEON_EM_SPAD_OFFSET 0x4080 /* remote SPAD */
+#define XEON_EM_DOORBELL_OFFSET 0x4100 /* PDOORBELL0 */
+#define XEON_SPCICMD_OFFSET 0x4504 /* SPCICMD */
+#define XEON_EMBAR0_OFFSET 0x4510 /* SBAR0BASE */
+#define XEON_EMBAR1_OFFSET 0x4518 /* SBAR23BASE */
+#define XEON_EMBAR2_OFFSET 0x4520 /* SBAR45BASE */
+
+#define XEON_PPD_OFFSET 0x00d4
+#define XEON_PPD_CONN_MASK 0x03
+#define XEON_PPD_CONN_TRANSPARENT 0x00
+#define XEON_PPD_CONN_B2B 0x01
+#define XEON_PPD_CONN_RP 0x02
+#define XEON_PPD_DEV_MASK 0x10
+#define XEON_PPD_DEV_USD 0x00
+#define XEON_PPD_DEV_DSD 0x10
+#define XEON_PPD_SPLIT_BAR_MASK 0x40
+
+
+#define XEON_MW_COUNT 2
+
+#define XEON_DB_COUNT 32
+#define XEON_DB_LINK 32
+#define XEON_DB_LINK_BIT (1ULL << XEON_DB_LINK)
+#define XEON_DB_MSIX_VECTOR_COUNT 33
+#define XEON_DB_MSIX_VECTOR_SHIFT 1
+#define XEON_DB_TOTAL_SHIFT 33
+#define XEON_SPAD_COUNT 16
+
+extern const struct ntb_dev_ops intel_ntb_ops;
+
+#endif /* _NTB_HW_INTEL_H_ */
diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
index 5c1cd3548..13026858d 100755
--- a/usertools/dpdk-devbind.py
+++ b/usertools/dpdk-devbind.py
@@ -40,13 +40,15 @@
'SVendor': None, 'SDevice': None}
intel_ioat_skx = {'Class': '08', 'Vendor': '8086', 'Device': '2021',
'SVendor': None, 'SDevice': None}
+intel_ntb_skx = {'Class': '06', 'Vendor': '8086', 'Device': '201c',
+ 'SVendor': None, 'SDevice': None}
network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
crypto_devices = [encryption_class, intel_processor_class]
eventdev_devices = [cavium_sso, cavium_tim, octeontx2_sso]
mempool_devices = [cavium_fpa, octeontx2_npa]
compress_devices = [cavium_zip]
-misc_devices = [intel_ioat_bdw, intel_ioat_skx]
+misc_devices = [intel_ioat_bdw, intel_ioat_skx, intel_ntb_skx]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
--
2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v11 3/4] raw/ntb: add handshake process
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 1/4] raw/ntb: introduce NTB raw device driver Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 2/4] raw/ntb: support Intel NTB Thomas Monjalon
@ 2019-07-04 12:29 ` Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 4/4] examples/ntb: add example for NTB Thomas Monjalon
2019-07-05 2:41 ` [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb Li, Xiaoyun
4 siblings, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 12:29 UTC (permalink / raw)
To: dev, Xiaoyun Li, Jingjing Wu, John McNamara, Marko Kovacevic; +Cc: Xiaolong Ye
From: Xiaoyun Li <xiaoyun.li@intel.com>
Add handshake process using doorbell so that two hosts can
communicate to start and stop.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
---
doc/guides/rawdevs/ntb.rst | 5 +
drivers/raw/ntb/ntb.c | 336 ++++++++++++++++++++++++++++++++++++-
2 files changed, 340 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rawdevs/ntb.rst b/doc/guides/rawdevs/ntb.rst
index ff0795b47..0a61ec03d 100644
--- a/doc/guides/rawdevs/ntb.rst
+++ b/doc/guides/rawdevs/ntb.rst
@@ -9,6 +9,11 @@ separate hosts so that they can communicate with each other. Thus, many
user cases can benefit from this, such as fault tolerance and visual
acceleration.
+This PMD allows two hosts to handshake for device start and stop, memory
+allocation for the peer to access and read/write allocated memory from peer.
+Also, the PMD allows to use doorbell registers to notify the peer and share
+some information by using scratchpad registers.
+
BIOS setting on Intel Skylake
-----------------------------
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index 5fde704b7..c83b8d964 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -28,6 +28,183 @@ static const struct rte_pci_id pci_id_ntb_map[] = {
{ .vendor_id = 0, /* sentinel */ },
};
+static int
+ntb_set_mw(struct rte_rawdev *dev, int mw_idx, uint64_t mw_size)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ char mw_name[RTE_MEMZONE_NAMESIZE];
+ const struct rte_memzone *mz;
+ int ret = 0;
+
+ if (hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to set mw.");
+ return -ENOTSUP;
+ }
+
+ snprintf(mw_name, sizeof(mw_name), "ntb_%d_mw_%d",
+ dev->dev_id, mw_idx);
+
+ mz = rte_memzone_lookup(mw_name);
+ if (mz)
+ return 0;
+
+ /**
+ * Hardware requires that mapped memory base address should be
+ * aligned with EMBARSZ and needs continuous memzone.
+ */
+ mz = rte_memzone_reserve_aligned(mw_name, mw_size, dev->socket_id,
+ RTE_MEMZONE_IOVA_CONTIG, hw->mw_size[mw_idx]);
+ if (!mz) {
+ NTB_LOG(ERR, "Cannot allocate aligned memzone.");
+ return -EIO;
+ }
+ hw->mz[mw_idx] = mz;
+
+ ret = (*hw->ntb_ops->mw_set_trans)(dev, mw_idx, mz->iova, mw_size);
+ if (ret) {
+ NTB_LOG(ERR, "Cannot set mw translation.");
+ return ret;
+ }
+
+ return ret;
+}
+
+static void
+ntb_link_cleanup(struct rte_rawdev *dev)
+{
+ struct ntb_hw *hw = dev->dev_private;
+ int status, i;
+
+ if (hw->ntb_ops->spad_write == NULL ||
+ hw->ntb_ops->mw_set_trans == NULL) {
+ NTB_LOG(ERR, "Not supported to clean up link.");
+ return;
+ }
+
+ /* Clean spad registers. */
+ for (i = 0; i < hw->spad_cnt; i++) {
+ status = (*hw->ntb_ops->spad_write)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean local spad.");
+ }
+
+ /* Clear mw so that peer cannot access local memory.*/
+ for (i = 0; i < hw->mw_cnt; i++) {
+ status = (*hw->ntb_ops->mw_set_trans)(dev, i, 0, 0);
+ if (status)
+ NTB_LOG(ERR, "Failed to clean mw.");
+ }
+}
+
+static void
+ntb_dev_intr_handler(void *param)
+{
+ struct rte_rawdev *dev = (struct rte_rawdev *)param;
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t mw_size_h, mw_size_l;
+ uint64_t db_bits = 0;
+ int i = 0;
+
+ if (hw->ntb_ops->db_read == NULL ||
+ hw->ntb_ops->db_clear == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return;
+ }
+
+ db_bits = (*hw->ntb_ops->db_read)(dev);
+ if (!db_bits)
+ NTB_LOG(ERR, "No doorbells");
+
+ /* Doorbell 0 is for peer device ready. */
+ if (db_bits & 1) {
+ NTB_LOG(DEBUG, "DB0: Peer device is up.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 1);
+
+ /**
+ * Peer dev is already up. All mw settings are already done.
+ * Skip them.
+ */
+ if (hw->peer_dev_up)
+ return;
+
+ if (hw->ntb_ops->spad_read == NULL ||
+ hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return;
+ }
+
+ hw->peer_mw_cnt = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_NUM_MWS, 0);
+ hw->peer_mw_size = rte_zmalloc("uint64_t",
+ hw->peer_mw_cnt * sizeof(uint64_t), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ mw_size_h = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 0);
+ mw_size_l = (*hw->ntb_ops->spad_read)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 0);
+ hw->peer_mw_size[i] = ((uint64_t)mw_size_h << 32) |
+ mw_size_l;
+ NTB_LOG(DEBUG, "Peer %u mw size: 0x%"PRIx64"", i,
+ hw->peer_mw_size[i]);
+ }
+
+ hw->peer_dev_up = 1;
+
+ /**
+ * Handshake with peer. Spad_write only works when both
+ * devices are up. So write spad again when db is received.
+ * And set db again for the later device who may miss
+ * the 1st db.
+ */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS,
+ 1, hw->mw_cnt);
+ mw_size_h = hw->mw_size[i] >> 32;
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_H + 2 * i,
+ 1, mw_size_h);
+
+ mw_size_l = hw->mw_size[i];
+ (*hw->ntb_ops->spad_write)(dev, SPAD_MW0_SZ_L + 2 * i,
+ 1, mw_size_l);
+ }
+ (*hw->ntb_ops->peer_db_set)(dev, 0);
+
+ /* To get the link info. */
+ if (hw->ntb_ops->get_link_status == NULL) {
+ NTB_LOG(ERR, "Not supported to get link status.");
+ return;
+ }
+ (*hw->ntb_ops->get_link_status)(dev);
+ NTB_LOG(INFO, "Link is up. Link speed: %u. Link width: %u",
+ hw->link_speed, hw->link_width);
+ return;
+ }
+
+ if (db_bits & (1 << 1)) {
+ NTB_LOG(DEBUG, "DB1: Peer device is down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, 2);
+
+ /* Peer device will be down, So clean local side too. */
+ ntb_link_cleanup(dev);
+
+ hw->peer_dev_up = 0;
+ /* Response peer's dev_stop request. */
+ (*hw->ntb_ops->peer_db_set)(dev, 2);
+ return;
+ }
+
+ if (db_bits & (1 << 2)) {
+ NTB_LOG(DEBUG, "DB2: Peer device agrees dev to be down.");
+ /* Clear received doorbell. */
+ (*hw->ntb_ops->db_clear)(dev, (1 << 2));
+ hw->peer_dev_up = 0;
+ return;
+ }
+}
+
static void
ntb_queue_conf_get(struct rte_rawdev *dev __rte_unused,
uint16_t queue_id __rte_unused,
@@ -147,7 +324,22 @@ ntb_dev_configure(const struct rte_rawdev *dev __rte_unused,
static int
ntb_dev_start(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ int ret, i;
+
/* TODO: init queues and start queues. */
+
+ /* Map memory of bar_size to remote. */
+ hw->mz = rte_zmalloc("struct rte_memzone *",
+ hw->mw_cnt * sizeof(struct rte_memzone *), 0);
+ for (i = 0; i < hw->mw_cnt; i++) {
+ ret = ntb_set_mw(dev, i, hw->mw_size[i]);
+ if (ret) {
+ NTB_LOG(ERR, "Fail to set mw.");
+ return ret;
+ }
+ }
+
dev->started = 1;
return 0;
@@ -156,13 +348,59 @@ ntb_dev_start(struct rte_rawdev *dev)
static void
ntb_dev_stop(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ uint32_t time_out;
+ int status;
+
/* TODO: stop rx/tx queues. */
+
+ if (!hw->peer_dev_up)
+ goto clean;
+
+ ntb_link_cleanup(dev);
+
+ /* Notify the peer that device will be down. */
+ if (hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Peer doorbell setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->peer_db_set)(dev, 1);
+ if (status) {
+ NTB_LOG(ERR, "Failed to tell peer device is down.");
+ return;
+ }
+
+ /*
+ * Set time out as 1s in case that the peer is stopped accidently
+ * without any notification.
+ */
+ time_out = 1000000;
+
+ /* Wait for cleanup work down before db mask clear. */
+ while (hw->peer_dev_up && time_out) {
+ time_out -= 10;
+ rte_delay_us(10);
+ }
+
+clean:
+ /* Clear doorbells mask. */
+ if (hw->ntb_ops->db_set_mask == NULL) {
+ NTB_LOG(ERR, "Doorbell mask setting is not supported.");
+ return;
+ }
+ status = (*hw->ntb_ops->db_set_mask)(dev,
+ (((uint64_t)1 << hw->db_cnt) - 1));
+ if (status)
+ NTB_LOG(ERR, "Failed to clear doorbells.");
+
dev->started = 0;
}
static int
ntb_dev_close(struct rte_rawdev *dev)
{
+ struct ntb_hw *hw = dev->dev_private;
+ struct rte_intr_handle *intr_handle;
int ret = 0;
if (dev->started)
@@ -170,6 +408,20 @@ ntb_dev_close(struct rte_rawdev *dev)
/* TODO: free queues. */
+ intr_handle = &hw->pci_dev->intr_handle;
+ /* Clean datapath event and vec mapping */
+ rte_intr_efd_disable(intr_handle);
+ if (intr_handle->intr_vec) {
+ rte_free(intr_handle->intr_vec);
+ intr_handle->intr_vec = NULL;
+ }
+ /* Disable uio intr before callback unregister */
+ rte_intr_disable(intr_handle);
+
+ /* Unregister callback func to eal lib */
+ rte_intr_callback_unregister(intr_handle,
+ ntb_dev_intr_handler, dev);
+
return ret;
}
@@ -346,7 +598,9 @@ static int
ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
{
struct ntb_hw *hw = dev->dev_private;
- int ret;
+ struct rte_intr_handle *intr_handle;
+ uint32_t val;
+ int ret, i;
hw->pci_dev = pci_dev;
hw->peer_dev_up = 0;
@@ -377,6 +631,86 @@ ntb_init_hw(struct rte_rawdev *dev, struct rte_pci_device *pci_dev)
if (ret)
return ret;
+ /* Init doorbell. */
+ hw->db_valid_mask = RTE_LEN2MASK(hw->db_cnt, uint64_t);
+
+ intr_handle = &pci_dev->intr_handle;
+ /* Register callback func to eal lib */
+ rte_intr_callback_register(intr_handle,
+ ntb_dev_intr_handler, dev);
+
+ ret = rte_intr_efd_enable(intr_handle, hw->db_cnt);
+ if (ret)
+ return ret;
+
+ /* To clarify, the interrupt for each doorbell is already mapped
+ * by default for intel gen3. They are mapped to msix vec 1-32,
+ * and hardware intr is mapped to 0. Map all to 0 for uio.
+ */
+ if (!rte_intr_cap_multiple(intr_handle)) {
+ for (i = 0; i < hw->db_cnt; i++) {
+ if (hw->ntb_ops->vector_bind == NULL)
+ return -ENOTSUP;
+ ret = (*hw->ntb_ops->vector_bind)(dev, i, 0);
+ if (ret)
+ return ret;
+ }
+ }
+
+ if (hw->ntb_ops->db_set_mask == NULL ||
+ hw->ntb_ops->peer_db_set == NULL) {
+ NTB_LOG(ERR, "Doorbell is not supported.");
+ return -ENOTSUP;
+ }
+ hw->db_mask = 0;
+ ret = (*hw->ntb_ops->db_set_mask)(dev, hw->db_mask);
+ if (ret) {
+ NTB_LOG(ERR, "Unable to enable intr for all dbs.");
+ return ret;
+ }
+
+ /* enable uio intr after callback register */
+ rte_intr_enable(intr_handle);
+
+ if (hw->ntb_ops->spad_write == NULL) {
+ NTB_LOG(ERR, "Scratchpad is not supported.");
+ return -ENOTSUP;
+ }
+ /* Tell peer the mw_cnt of local side. */
+ ret = (*hw->ntb_ops->spad_write)(dev, SPAD_NUM_MWS, 1, hw->mw_cnt);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw count.");
+ return ret;
+ }
+
+ /* Tell peer each mw size on local side. */
+ for (i = 0; i < hw->mw_cnt; i++) {
+ NTB_LOG(DEBUG, "Local %u mw size: 0x%"PRIx64"", i,
+ hw->mw_size[i]);
+ val = hw->mw_size[i] >> 32;
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_H + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+
+ val = hw->mw_size[i];
+ ret = (*hw->ntb_ops->spad_write)
+ (dev, SPAD_MW0_SZ_L + 2 * i, 1, val);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer mw size.");
+ return ret;
+ }
+ }
+
+ /* Ring doorbell 0 to tell peer the device is ready. */
+ ret = (*hw->ntb_ops->peer_db_set)(dev, 0);
+ if (ret) {
+ NTB_LOG(ERR, "Failed to tell peer device is probed.");
+ return ret;
+ }
+
return ret;
}
--
2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* [dpdk-dev] [PATCH v11 4/4] examples/ntb: add example for NTB
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
` (2 preceding siblings ...)
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 3/4] raw/ntb: add handshake process Thomas Monjalon
@ 2019-07-04 12:29 ` Thomas Monjalon
2019-07-05 2:41 ` [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb Li, Xiaoyun
4 siblings, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-04 12:29 UTC (permalink / raw)
To: dev, John McNamara, Marko Kovacevic, Xiaoyun Li, Jingjing Wu; +Cc: Xiaolong Ye
From: Xiaoyun Li <xiaoyun.li@intel.com>
Enable an example for rawdev ntb. Support interactive mode to send
file on one host and receive file from another host. The command line
would be 'send [filepath]' and 'receive [filepath]'.
But since the FIFO is not enabled right now, use rte_memcpy as the enqueue
and dequeue functions and only support transmitting file no more than 4M.
Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com>
Acked-by: Jingjing Wu <jingjing.wu@intel.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
---
MAINTAINERS | 2 +
doc/guides/sample_app_ug/index.rst | 1 +
doc/guides/sample_app_ug/ntb.rst | 47 ++++
drivers/raw/ntb/ntb.c | 28 ++-
examples/Makefile | 1 +
examples/meson.build | 2 +-
examples/ntb/Makefile | 68 ++++++
examples/ntb/meson.build | 16 ++
examples/ntb/ntb_fwd.c | 377 +++++++++++++++++++++++++++++
9 files changed, 533 insertions(+), 9 deletions(-)
create mode 100644 doc/guides/sample_app_ug/ntb.rst
create mode 100644 examples/ntb/Makefile
create mode 100644 examples/ntb/meson.build
create mode 100644 examples/ntb/ntb_fwd.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 9e6308aa4..5667a4369 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1110,6 +1110,8 @@ M: Xiaoyun Li <xiaoyun.li@intel.com>
M: Jingjing Wu <jingjing.wu@intel.com>
F: drivers/raw/ntb/
F: doc/guides/rawdevs/ntb.rst
+F: examples/ntb/
+F: doc/guides/sample_app_ug/ntb.rst
Packet processing
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index 2945be08f..f23f8f59e 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -58,3 +58,4 @@ Sample Applications User Guides
fips_validation
ipsec_secgw
bbdev_app
+ ntb
diff --git a/doc/guides/sample_app_ug/ntb.rst b/doc/guides/sample_app_ug/ntb.rst
new file mode 100644
index 000000000..079242175
--- /dev/null
+++ b/doc/guides/sample_app_ug/ntb.rst
@@ -0,0 +1,47 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+ Copyright(c) 2019 Intel Corporation.
+
+NTB Sample Application
+======================
+
+The ntb sample application shows how to use ntb rawdev driver.
+This sample provides interactive mode to transmit file between
+two hosts.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the ``ntb`` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires an available core for each port, plus one.
+The only available options are the standard ones for the EAL:
+
+.. code-block:: console
+
+ ./build/ntb_fwd -c 0xf -n 6 -- -i
+
+Refer to the *DPDK Getting Started Guide* for general information on
+running applications and the Environment Abstraction Layer (EAL)
+options.
+
+Using the application
+---------------------
+
+The application is console-driven using the cmdline DPDK interface:
+
+.. code-block:: console
+
+ ntb>
+
+From this interface the available commands and descriptions of what
+they do as as follows:
+
+* ``send [filepath]``: Send file to the peer host.
+* ``receive [filepath]``: Receive file to [filepath]. Need the peer
+ to send file successfully first.
+* ``quit``: Exit program
diff --git a/drivers/raw/ntb/ntb.c b/drivers/raw/ntb/ntb.c
index c83b8d964..4ba2f3a38 100644
--- a/drivers/raw/ntb/ntb.c
+++ b/drivers/raw/ntb/ntb.c
@@ -240,11 +240,19 @@ ntb_enqueue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO right now. Just for testing memory write. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ void *bar_addr;
+ size_t size;
+ if (hw->ntb_ops->get_peer_mw_addr == NULL)
+ return -ENOTSUP;
+ bar_addr = (*hw->ntb_ops->get_peer_mw_addr)(dev, 0);
+ size = (size_t)context;
+
+ for (i = 0; i < count; i++)
+ rte_memcpy(bar_addr, buffers[i]->buf_addr, size);
return 0;
}
@@ -254,11 +262,15 @@ ntb_dequeue_bufs(struct rte_rawdev *dev,
unsigned int count,
rte_rawdev_obj_t context)
{
- RTE_SET_USED(dev);
- RTE_SET_USED(buffers);
- RTE_SET_USED(count);
- RTE_SET_USED(context);
+ /* Not FIFO. Just for testing memory read. */
+ struct ntb_hw *hw = dev->dev_private;
+ unsigned int i;
+ size_t size;
+ size = (size_t)context;
+
+ for (i = 0; i < count; i++)
+ rte_memcpy(buffers[i]->buf_addr, hw->mz[i]->addr, size);
return 0;
}
diff --git a/examples/Makefile b/examples/Makefile
index 7562424d9..de11dd487 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -53,6 +53,7 @@ DIRS-y += link_status_interrupt
DIRS-$(CONFIG_RTE_LIBRTE_LPM) += load_balancer
DIRS-y += multi_process
DIRS-y += netmap_compat/bridge
+DIRS-y += ntb
DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += packet_ordering
ifeq ($(CONFIG_RTE_ARCH_X86_64),y)
DIRS-y += performance-thread
diff --git a/examples/meson.build b/examples/meson.build
index 87113bd70..a046b74ad 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -30,7 +30,7 @@ all_examples = [
'multi_process/hotplug_mp',
'multi_process/simple_mp',
'multi_process/symmetric_mp',
- 'netmap_compat', 'packet_ordering',
+ 'netmap_compat', 'ntb', 'packet_ordering',
'performance-thread', 'ptpclient',
'qos_meter', 'qos_sched',
'quota_watermark', 'rxtx_callbacks',
diff --git a/examples/ntb/Makefile b/examples/ntb/Makefile
new file mode 100644
index 000000000..5ddd9b95f
--- /dev/null
+++ b/examples/ntb/Makefile
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# binary name
+APP = ntb_fwd
+
+# all source are stored in SRCS-y
+SRCS-y := ntb_fwd.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+ ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+ ln -sf $(APP)-static build/$(APP)
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+LDFLAGS += -pthread
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+ $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+ @mkdir -p $@
+
+.PHONY: clean
+clean:
+ rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+ rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+else
+
+CFLAGS += -D_FILE_OFFSET_BITS=64
+CFLAGS += -O2
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+
+endif
+endif
diff --git a/examples/ntb/meson.build b/examples/ntb/meson.build
new file mode 100644
index 000000000..9a6288f4f
--- /dev/null
+++ b/examples/ntb/meson.build
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# meson file, for building this example as part of a main DPDK build.
+#
+# To build this example as a standalone application with an already-installed
+# DPDK instance, use 'make'
+
+if host_machine.system() != 'linux'
+ build = false
+endif
+deps += 'rawdev'
+cflags += ['-D_FILE_OFFSET_BITS=64']
+sources = files(
+ 'ntb_fwd.c'
+)
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
new file mode 100644
index 000000000..c169f01a3
--- /dev/null
+++ b/examples/ntb/ntb_fwd.c
@@ -0,0 +1,377 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+#include <stdint.h>
+#include <stdio.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <signal.h>
+#include <string.h>
+#include <getopt.h>
+
+#include <cmdline_parse_string.h>
+#include <cmdline_socket.h>
+#include <cmdline.h>
+#include <rte_common.h>
+#include <rte_rawdev.h>
+#include <rte_lcore.h>
+
+#define NTB_DRV_NAME_LEN 7
+static uint64_t max_file_size = 0x400000;
+static uint8_t interactive = 1;
+static uint16_t dev_id;
+
+/* *** Help command with introduction. *** */
+struct cmd_help_result {
+ cmdline_fixed_string_t help;
+};
+
+static void cmd_help_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ cmdline_printf(
+ cl,
+ "\n"
+ "The following commands are currently available:\n\n"
+ "Control:\n"
+ " quit :"
+ " Quit the application.\n"
+ "\nFile transmit:\n"
+ " send [path] :"
+ " Send [path] file. (No more than %"PRIu64")\n"
+ " recv [path] :"
+ " Receive file to [path]. Make sure sending is done"
+ " on the other side.\n",
+ max_file_size
+ );
+
+}
+
+cmdline_parse_token_string_t cmd_help_help =
+ TOKEN_STRING_INITIALIZER(struct cmd_help_result, help, "help");
+
+cmdline_parse_inst_t cmd_help = {
+ .f = cmd_help_parsed,
+ .data = NULL,
+ .help_str = "show help",
+ .tokens = {
+ (void *)&cmd_help_help,
+ NULL,
+ },
+};
+
+/* *** QUIT *** */
+struct cmd_quit_result {
+ cmdline_fixed_string_t quit;
+};
+
+static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
+ struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ /* Stop traffic and Close port. */
+ rte_rawdev_stop(dev_id);
+ rte_rawdev_close(dev_id);
+
+ cmdline_quit(cl);
+}
+
+cmdline_parse_token_string_t cmd_quit_quit =
+ TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
+
+cmdline_parse_inst_t cmd_quit = {
+ .f = cmd_quit_parsed,
+ .data = NULL,
+ .help_str = "exit application",
+ .tokens = {
+ (void *)&cmd_quit_quit,
+ NULL,
+ },
+};
+
+/* *** SEND FILE PARAMETERS *** */
+struct cmd_sendfile_result {
+ cmdline_fixed_string_t send_string;
+ char filepath[];
+};
+
+static void
+cmd_sendfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_send[1];
+ uint64_t rsize, size, link;
+ uint8_t *buff;
+ uint32_t val;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &link);
+ if (!link) {
+ printf("Link is not up, cannot send file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "r");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ fseek(file, 0, SEEK_END);
+ size = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ /**
+ * No FIFO now. Only test memory. Limit sending file
+ * size <= max_file_size.
+ */
+ if (size > max_file_size) {
+ printf("Warning: The file is too large. Only send first"
+ " %"PRIu64" bits.\n", max_file_size);
+ size = max_file_size;
+ }
+
+ buff = (uint8_t *)malloc(size);
+ rsize = fread(buff, size, 1, file);
+ if (rsize != 1) {
+ printf("Fail to read file.\n");
+ fclose(file);
+ free(buff);
+ return;
+ }
+
+ /* Tell remote about the file size. */
+ val = size >> 32;
+ rte_rawdev_set_attr(dev_id, "spad_user_0", val);
+ val = size;
+ rte_rawdev_set_attr(dev_id, "spad_user_1", val);
+
+ pkts_send[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_send[0]->buf_addr = buff;
+
+ if (rte_rawdev_enqueue_buffers(dev_id, pkts_send, 1,
+ (void *)(size_t)size)) {
+ printf("Fail to enqueue.\n");
+ goto clean;
+ }
+ printf("Done sending file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_send[0]);
+}
+
+cmdline_parse_token_string_t cmd_send_file_send =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, send_string,
+ "send");
+cmdline_parse_token_string_t cmd_send_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_sendfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_send_file = {
+ .f = cmd_sendfile_parsed,
+ .data = NULL,
+ .help_str = "send <file_path>",
+ .tokens = {
+ (void *)&cmd_send_file_send,
+ (void *)&cmd_send_file_filepath,
+ NULL,
+ },
+};
+
+/* *** RECEIVE FILE PARAMETERS *** */
+struct cmd_recvfile_result {
+ cmdline_fixed_string_t recv_string;
+ char filepath[];
+};
+
+static void
+cmd_recvfile_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ struct cmd_sendfile_result *res = parsed_result;
+ struct rte_rawdev_buf *pkts_recv[1];
+ uint8_t *buff;
+ uint64_t val;
+ size_t size;
+ FILE *file;
+
+ if (!rte_rawdevs[dev_id].started) {
+ printf("Device needs to be up first. Try later.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "link_status", &val);
+ if (!val) {
+ printf("Link is not up, cannot receive file.\n");
+ return;
+ }
+
+ file = fopen(res->filepath, "w");
+ if (file == NULL) {
+ printf("Fail to open the file.\n");
+ return;
+ }
+
+ rte_rawdev_get_attr(dev_id, "spad_user_0", &val);
+ size = val << 32;
+ rte_rawdev_get_attr(dev_id, "spad_user_1", &val);
+ size |= val;
+
+ buff = (uint8_t *)malloc(size);
+ pkts_recv[0] = (struct rte_rawdev_buf *)malloc
+ (sizeof(struct rte_rawdev_buf));
+ pkts_recv[0]->buf_addr = buff;
+
+ if (rte_rawdev_dequeue_buffers(dev_id, pkts_recv, 1, (void *)size)) {
+ printf("Fail to dequeue.\n");
+ goto clean;
+ }
+
+ fwrite(buff, size, 1, file);
+ printf("Done receiving to file.\n");
+
+clean:
+ fclose(file);
+ free(buff);
+ free(pkts_recv[0]);
+}
+
+cmdline_parse_token_string_t cmd_recv_file_recv =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, recv_string,
+ "recv");
+cmdline_parse_token_string_t cmd_recv_file_filepath =
+ TOKEN_STRING_INITIALIZER(struct cmd_recvfile_result, filepath, NULL);
+
+
+cmdline_parse_inst_t cmd_recv_file = {
+ .f = cmd_recvfile_parsed,
+ .data = NULL,
+ .help_str = "recv <file_path>",
+ .tokens = {
+ (void *)&cmd_recv_file_recv,
+ (void *)&cmd_recv_file_filepath,
+ NULL,
+ },
+};
+
+/* list of instructions */
+cmdline_parse_ctx_t main_ctx[] = {
+ (cmdline_parse_inst_t *)&cmd_help,
+ (cmdline_parse_inst_t *)&cmd_send_file,
+ (cmdline_parse_inst_t *)&cmd_recv_file,
+ (cmdline_parse_inst_t *)&cmd_quit,
+ NULL,
+};
+
+/* prompt function, called from main on MASTER lcore */
+static void
+prompt(void)
+{
+ struct cmdline *cl;
+
+ cl = cmdline_stdin_new(main_ctx, "ntb> ");
+ if (cl == NULL)
+ return;
+
+ cmdline_interact(cl);
+ cmdline_stdin_exit(cl);
+}
+
+static void
+signal_handler(int signum)
+{
+ if (signum == SIGINT || signum == SIGTERM) {
+ printf("\nSignal %d received, preparing to exit...\n", signum);
+ signal(signum, SIG_DFL);
+ kill(getpid(), signum);
+ }
+}
+
+static void
+ntb_usage(const char *prgname)
+{
+ printf("%s [EAL options] -- [options]\n"
+ "-i : run in interactive mode (default value is 1)\n",
+ prgname);
+}
+
+static int
+parse_args(int argc, char **argv)
+{
+ char *prgname = argv[0], **argvopt = argv;
+ int opt, ret;
+
+ /* Only support interactive mode to send/recv file first. */
+ while ((opt = getopt(argc, argvopt, "i")) != EOF) {
+ switch (opt) {
+ case 'i':
+ printf("Interactive-mode selected\n");
+ interactive = 1;
+ break;
+
+ default:
+ ntb_usage(prgname);
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 1; /* reset getopt lib */
+ return ret;
+}
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ signal(SIGINT, signal_handler);
+ signal(SIGTERM, signal_handler);
+
+ ret = rte_eal_init(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Error with EAL initialization.\n");
+
+ /* Find 1st ntb rawdev. */
+ for (i = 0; i < RTE_RAWDEV_MAX_DEVS; i++)
+ if (rte_rawdevs[i].driver_name &&
+ (strncmp(rte_rawdevs[i].driver_name, "raw_ntb",
+ NTB_DRV_NAME_LEN) == 0) && (rte_rawdevs[i].attached == 1))
+ break;
+
+ if (i == RTE_RAWDEV_MAX_DEVS)
+ rte_exit(EXIT_FAILURE, "Cannot find any ntb device.\n");
+
+ dev_id = i;
+
+ argc -= ret;
+ argv += ret;
+
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ rte_rawdev_start(dev_id);
+
+ if (interactive) {
+ sleep(1);
+ prompt();
+ }
+
+ return 0;
+}
--
2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-04 10:31 ` Thomas Monjalon
2019-07-04 10:37 ` Bruce Richardson
@ 2019-07-05 1:21 ` Li, Xiaoyun
2019-07-05 1:28 ` Li, Xiaoyun
2 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-07-05 1:21 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar,
Richardson, Bruce, Yigit, Ferruh
Sure. Thanks.
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, July 4, 2019 18:32
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>; Maslekar,
> Omkar <omkar.maslekar@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
>
> 02/07/2019 08:25, Xiaoyun Li:
> > Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> > can help to connect two separate hosts with each other.
> [...]
> > +NTB Rawdev
>
> Is it Intel property? If yes, I suggest "Intel NTB" as title.
>
> > +M: Xiaoyun Li <xiaoyun.li@intel.com>
> > +M: Jingjing Wu <jingjing.wu@intel.com>
> > +F: drivers/raw/ntb_rawdev/
> > +F: doc/guides/rawdevs/ntb_rawdev.rst
>
> Sorry I missed to check the naming here.
> Why is it called "ntb_rawdev" and not just "ntb" ?
> If you are OK with "ntb" as directory name, I can rename it while applying.
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
2019-07-04 10:31 ` Thomas Monjalon
2019-07-04 10:37 ` Bruce Richardson
2019-07-05 1:21 ` Li, Xiaoyun
@ 2019-07-05 1:28 ` Li, Xiaoyun
2 siblings, 0 replies; 127+ messages in thread
From: Li, Xiaoyun @ 2019-07-05 1:28 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Wu, Jingjing, Wiles, Keith, Liang, Cunming, Maslekar, Omkar,
Richardson, Bruce, Yigit, Ferruh
Sorry. Miss the first question.
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, July 4, 2019 18:32
> To: Li, Xiaoyun <xiaoyun.li@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Wiles, Keith
> <keith.wiles@intel.com>; Liang, Cunming <cunming.liang@intel.com>; Maslekar,
> Omkar <omkar.maslekar@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver
>
> 02/07/2019 08:25, Xiaoyun Li:
> > Introduce rawdev driver support for NTB (Non-transparent Bridge) which
> > can help to connect two separate hosts with each other.
> [...]
> > +NTB Rawdev
>
> Is it Intel property? If yes, I suggest "Intel NTB" as title.
Not just Intel has NTB. AMD, PLX ... also have NTB. The rawdev should be compatible with many kinds of NTB. I implemented specific intel NTB in ntb_hw_intel.c/.h
But there is no other ntb in DPDK now. So I am fine to name it as Intel NTB.
>
> > +M: Xiaoyun Li <xiaoyun.li@intel.com>
> > +M: Jingjing Wu <jingjing.wu@intel.com>
> > +F: drivers/raw/ntb_rawdev/
> > +F: doc/guides/rawdevs/ntb_rawdev.rst
>
> Sorry I missed to check the naming here.
> Why is it called "ntb_rawdev" and not just "ntb" ?
> If you are OK with "ntb" as directory name, I can rename it while applying.
>
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
` (3 preceding siblings ...)
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 4/4] examples/ntb: add example for NTB Thomas Monjalon
@ 2019-07-05 2:41 ` Li, Xiaoyun
2019-07-05 10:52 ` Thomas Monjalon
4 siblings, 1 reply; 127+ messages in thread
From: Li, Xiaoyun @ 2019-07-05 2:41 UTC (permalink / raw)
To: Thomas Monjalon, dev
Hi
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Thursday, July 4, 2019 20:30
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb
>
> This patch set adds support for Intel NTB device with Skylake platform.
> It is a raw device for allowing two hosts to communicate with each other and
> access the peer memory.
>
> This patch set also provides a simple example to transmit a file between two
> hosts. But since there is no FIFO here, only support file which is no more than
> 4M. And will add FIFO in the future.
>
>
> v11 (Thomas):
> * rebased on top of IOAT driver
> * squashed commit for binding script
> * renamed ntb_rawdev to ntb as agreed with Bruce Please review this version, I
> may have done mistakes.
I've compared the new version code with v10 code. There is no change except "ntb_rawdev -> ntb".
And I also tested the new version. Works fine. No mistake. :)
Thanks!
> --
> 2.21.0
^ permalink raw reply [flat|nested] 127+ messages in thread
* Re: [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb
2019-07-05 2:41 ` [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb Li, Xiaoyun
@ 2019-07-05 10:52 ` Thomas Monjalon
0 siblings, 0 replies; 127+ messages in thread
From: Thomas Monjalon @ 2019-07-05 10:52 UTC (permalink / raw)
To: Li, Xiaoyun; +Cc: dev
05/07/2019 04:41, Li, Xiaoyun:
> From: Thomas Monjalon
> >
> > This patch set adds support for Intel NTB device with Skylake platform.
> > It is a raw device for allowing two hosts to communicate with each other and
> > access the peer memory.
> >
> > This patch set also provides a simple example to transmit a file between two
> > hosts. But since there is no FIFO here, only support file which is no more than
> > 4M. And will add FIFO in the future.
> >
> >
> > v11 (Thomas):
> > * rebased on top of IOAT driver
> > * squashed commit for binding script
> > * renamed ntb_rawdev to ntb as agreed with Bruce Please review this version, I
> > may have done mistakes.
>
> I've compared the new version code with v10 code. There is no change except "ntb_rawdev -> ntb".
> And I also tested the new version. Works fine. No mistake. :)
> Thanks!
Rebased on top of octeontx2_dma and applied, thanks
^ permalink raw reply [flat|nested] 127+ messages in thread
end of thread, other threads:[~2019-07-05 10:52 UTC | newest]
Thread overview: 127+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-03 8:46 [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-04 2:20 ` Ye Xiaolong
2019-06-03 8:46 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-04 3:01 ` Ye Xiaolong
2019-06-03 8:46 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-03 8:46 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-04 6:48 ` Ye Xiaolong
2019-06-04 8:12 ` Li, Xiaoyun
2019-06-05 8:32 ` Li, Xiaoyun
2019-06-05 9:25 ` Ye Xiaolong
2019-06-05 13:36 ` Li, Xiaoyun
2019-06-06 2:07 ` Ye Xiaolong
2019-06-04 8:48 ` Ye Xiaolong
2019-06-05 3:11 ` Li, Xiaoyun
2019-06-03 8:46 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-04 7:53 ` Jerin Jacob Kollanukkaran
2019-06-04 8:16 ` Li, Xiaoyun
2019-06-03 8:46 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb pmd Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-06 7:42 ` [dpdk-dev] [PATCH v2 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-06 8:23 ` Bruce Richardson
2019-06-10 1:38 ` Li, Xiaoyun
2019-06-06 7:43 ` [dpdk-dev] [PATCH v2 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-11 8:22 ` [dpdk-dev] [PATCH 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-11 8:50 ` [dpdk-dev] [PATCH v3 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-13 7:56 ` [dpdk-dev] [PATCH v4 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-17 12:49 ` Wang, Xiao W
2019-06-18 1:28 ` Li, Xiaoyun
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-14 2:19 ` [dpdk-dev] [PATCH v5 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-18 16:07 ` Wu, Jingjing
2019-06-20 10:06 ` Li, Xiaoyun
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-18 2:10 ` [dpdk-dev] [PATCH v6 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-20 10:21 ` [dpdk-dev] [PATCH v7 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-27 16:31 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-27 17:06 ` Wu, Jingjing
2019-06-28 1:33 ` Li, Xiaoyun
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-27 17:19 ` Wu, Jingjing
2019-06-28 1:33 ` Li, Xiaoyun
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-27 17:30 ` Wu, Jingjing
2019-06-28 1:36 ` Li, Xiaoyun
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-27 17:34 ` Wu, Jingjing
2019-06-26 7:12 ` [dpdk-dev] [PATCH v8 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-06-27 17:33 ` Wu, Jingjing
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 1/6] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 2/6] raw/ntb: add intel ntb support Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 3/6] raw/ntb: add handshake process Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 4/6] examples/ntb: enable an example for ntb Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 5/6] usertools/dpdk-devbind.py: add support " Xiaoyun Li
2019-06-28 2:53 ` [dpdk-dev] [PATCH v9 6/6] doc: update docs for ntb driver Xiaoyun Li
2019-07-01 14:24 ` Thomas Monjalon
2019-07-02 1:18 ` Li, Xiaoyun
2019-06-28 10:17 ` [dpdk-dev] [PATCH v9 0/6] rawdev driver for ntb Wu, Jingjing
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 0/5] " Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
2019-07-02 6:17 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
2019-07-02 6:23 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver for ntb Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 1/5] raw/ntb: introduce ntb rawdev driver Xiaoyun Li
2019-07-04 10:31 ` Thomas Monjalon
2019-07-04 10:37 ` Bruce Richardson
2019-07-05 1:21 ` Li, Xiaoyun
2019-07-05 1:28 ` Li, Xiaoyun
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 2/5] usertools/dpdk-devbind.py: add support for ntb Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 3/5] raw/ntb: add intel ntb support Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 4/5] raw/ntb: add handshake process Xiaoyun Li
2019-07-02 6:25 ` [dpdk-dev] [PATCH v10 5/5] examples/ntb: enable an example for ntb Xiaoyun Li
2019-07-02 14:10 ` [dpdk-dev] [PATCH v10 0/5] rawdev driver " Ye Xiaolong
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 0/4] " Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 1/4] raw/ntb: introduce NTB raw device driver Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 2/4] raw/ntb: support Intel NTB Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 3/4] raw/ntb: add handshake process Thomas Monjalon
2019-07-04 12:29 ` [dpdk-dev] [PATCH v11 4/4] examples/ntb: add example for NTB Thomas Monjalon
2019-07-05 2:41 ` [dpdk-dev] [PATCH v11 0/4] rawdev driver for ntb Li, Xiaoyun
2019-07-05 10:52 ` Thomas Monjalon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).