From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by dpdk.org (Postfix) with ESMTP id 420031B2F4 for ; Wed, 1 Nov 2017 16:47:43 +0100 (CET) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga105.jf.intel.com with ESMTP; 01 Nov 2017 08:47:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.44,329,1505804400"; d="scan'208";a="144707241" Received: from awal-z170x.ir.intel.com ([163.33.210.59]) by orsmga004.jf.intel.com with ESMTP; 01 Nov 2017 08:47:41 -0700 From: Mohammad Abdul Awal To: dev@dpdk.org Cc: Mohammad Abdul Awal , Remy Horton , Declan Doherty Date: Wed, 1 Nov 2017 15:46:25 +0000 Message-Id: <1509551187-25726-4-git-send-email-mohammad.abdul.awal@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509551187-25726-1-git-send-email-mohammad.abdul.awal@intel.com> References: <1509551187-25726-1-git-send-email-mohammad.abdul.awal@intel.com> Subject: [dpdk-dev] [PATCH 4/6] net/representor: Implement port representor PMD X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Nov 2017 15:47:44 -0000 Representor PMD is a virtual PMD which provides a logical representation in DPDK for ports of a multi port device. This supports configuration, management, and monitoring of VFs of a physical function bound to a userspace control plane application. Signed-off-by: Mohammad Abdul Awal Signed-off-by: Remy Horton Signed-off-by: Declan Doherty --- drivers/net/Makefile | 1 + drivers/net/representor/Makefile | 52 ++++ drivers/net/representor/port_representor.c | 323 +++++++++++++++++++++ .../representor/rte_pmd_representor_version.map | 4 + mk/rte.app.mk | 1 + 5 files changed, 381 insertions(+) create mode 100644 drivers/net/representor/Makefile create mode 100644 drivers/net/representor/port_representor.c create mode 100644 drivers/net/representor/rte_pmd_representor_version.map diff --git a/drivers/net/Makefile b/drivers/net/Makefile index cf33233..3e98cd7 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -71,6 +71,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap DIRS-$(CONFIG_RTE_LIBRTE_THUNDERX_NICVF_PMD) += thunderx DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3 +DIRS-$(CONFIG_RTE_LIBRTE_REPRESENTOR) += representor ifeq ($(CONFIG_RTE_LIBRTE_KNI),y) DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni diff --git a/drivers/net/representor/Makefile b/drivers/net/representor/Makefile new file mode 100644 index 0000000..5647045 --- /dev/null +++ b/drivers/net/representor/Makefile @@ -0,0 +1,52 @@ +# BSD LICENSE +# +# Copyright(c) 2017 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include $(RTE_SDK)/mk/rte.vars.mk + +# +# library name +# +LIB = librte_pmd_representor.a + +CFLAGS += -O3 +CFLAGS += $(WERROR_FLAGS) +LDLIBS += -lrte_representor + +EXPORT_MAP := rte_pmd_representor_version.map + +LIBABIVER := 1 + +# +# all source are stored in SRCS-y +# +SRCS-$(CONFIG_RTE_LIBRTE_REPRESENTOR) += port_representor.c + +include $(RTE_SDK)/mk/rte.lib.mk diff --git a/drivers/net/representor/port_representor.c b/drivers/net/representor/port_representor.c new file mode 100644 index 0000000..2c934bd --- /dev/null +++ b/drivers/net/representor/port_representor.c @@ -0,0 +1,323 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2017 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include + +#include + +struct port_rep_parameters { + uint64_t vport_mask; + struct { + char bus[RTE_DEV_NAME_MAX_LEN]; + char device[RTE_DEV_NAME_MAX_LEN]; + } parent; +}; + +static int +representor_port_create(struct rte_vdev_device *vdev, + struct port_rep_parameters *params, + const uint16_t vport_id) +{ + struct rte_eth_dev *ethdev; + struct rte_representor_broker *broker; + + int32_t ret = 0; + + + if (vdev->device.numa_node == SOCKET_ID_ANY) + vdev->device.numa_node = rte_socket_id(); + + RTE_LOG(INFO, PMD, + "Creating representor port %s ethdev on numa socket %u\n", + vdev->device.name, vdev->device.numa_node); + + ethdev = rte_eth_vdev_allocate(vdev, + sizeof(struct rte_representor_port)); + if (!ethdev) + return -ENOMEM; + + /* + * Allocate memory for MAC address of port, this should be configured by + * broker + */ + ethdev->data->mac_addrs = rte_malloc("representor_port_mac", + sizeof(struct ether_addr), 0); + + ethdev->data->dev_flags = RTE_ETH_DEV_REPRESENTOR_PORT; + + broker = rte_representor_broker_find(params->parent.bus, + params->parent.device); + if (!broker) + goto create_err; + + ret = rte_representor_port_register(broker, vport_id, ethdev); + if (ret) + goto create_err; + + return 0; + +create_err: + if (broker) + rte_representor_port_unregister(ethdev); + + if (ethdev) + rte_eth_dev_release_port(ethdev); + + return -ENODEV; +} + + +static inline void +apply_range_to_mask(int lower, int upper, uint64_t *mask) +{ + int idx_mask; + + for (idx_mask = lower; idx_mask <= upper; idx_mask++) + *mask = *mask | (0x01ULL << idx_mask); +} + +static int +range_to_mask(const char *range_str, uint64_t *mask) +{ + int value; + int state; + int lower_bound; + + state = 0; + while (1) { + switch (state) { + case 0: /* Initial */ + if (!isdigit(*range_str)) + return -EINVAL; + value = *range_str - '0'; + state = 1; + break; + + case 1: /* Parsing lower bound */ + if (isdigit(*range_str)) { + value *= 10; + value += *range_str - '0'; + } else if (*range_str == '-') { + state = '-'; + lower_bound = value; + value = 0; + } else if (*range_str == '\0') { + apply_range_to_mask(value, value, mask); + return 0; + } else if (*range_str == ':') { + apply_range_to_mask(value, value, mask); + value = 0; + state = 0; + } else { + return -EINVAL; + } + break; + + case '-': /* Parsing upper bound */ + if (isdigit(*range_str)) { + value *= 10; + value += *range_str - '0'; + } else if (*range_str == '\0') { + apply_range_to_mask(lower_bound, value, mask); + return 0; + } else if (*range_str == ':') { + apply_range_to_mask(lower_bound, value, mask); + value = 0; + state = 0; + } else { + return -EINVAL; + } + break; + } + range_str++; + } + + return -EINVAL; +} + + +static int +port_rep_kvargs_parent(__rte_unused const char *key, + const char *value, void *ptr) +{ + struct port_rep_parameters *params = ptr; + int ret = 0; + char *pivot; + uint32_t len; + + /* the parent param has to be provided with type_name formatted */ + pivot = strchr(value, '_'); + if (pivot) { + len = pivot - value; + strncpy(params->parent.bus, value, len); + strncpy(params->parent.device, pivot + 1, strlen(value) - len); + } else { + RTE_LOG(ERR, PMD, "'parent=%s' has invalid format\n", value); + } + + return ret; +} + + +static int +port_rep_kvargs_vport_id(__rte_unused const char *key, + const char *value, void *ptr) +{ + struct port_rep_parameters *params = ptr; + int ret; + + ret = range_to_mask(value, ¶ms->vport_mask); + if (ret != 0) + RTE_LOG(ERR, PMD, "'vport_id=%s' does not give a valid device " + "name\n", value); + return ret; +} + +typedef int (*port_rep_arg_func_t)(const char*, const char*, void*); + +static const char * const port_rep_kvargs_codes[] = { + "parent", "vport_id", NULL +}; + +static port_rep_arg_func_t port_rep_kvargs_callbacks[] = { + &port_rep_kvargs_parent, + &port_rep_kvargs_vport_id, + NULL +}; + +static int +port_rep_probe(struct rte_vdev_device *dev) +{ + struct rte_kvargs *kvlist = NULL; + struct port_rep_parameters params; + const char *args; + int ret, idx; + + uint16_t vport_id = 0; + + if (!dev) + return -EINVAL; + + if (!rte_representor_enabled()) { + RTE_LOG(ERR, PMD, + "Tried creating representor port pmd without" + " --enable-representor\n"); + return -ENODEV; + } + + args = rte_vdev_device_args(dev); + RTE_LOG(INFO, PMD, "Initializing representor port pmd for %s\n", + rte_vdev_device_name(dev)); + + if (args) { + kvlist = rte_kvargs_parse(args, port_rep_kvargs_codes); + if (!kvlist) + return -1; + + idx = 0; + while (port_rep_kvargs_codes[idx] != NULL) { + ret = rte_kvargs_process(kvlist, + port_rep_kvargs_codes[idx], + port_rep_kvargs_callbacks[idx], + ¶ms); + if (ret != 0) { + RTE_LOG(ERR, PMD, "port_representor pmd " + "parameter error\n"); + rte_kvargs_free(kvlist); + return -1; + } + idx++; + } + } + RTE_LOG(INFO, PMD, "Configure port_representor pmd with args=\"%s\"\n", + args); + + while (params.vport_mask) { + if (params.vport_mask & 0x1) { + ret = representor_port_create(dev, ¶ms, vport_id); + if (ret) { + RTE_LOG(ERR, PMD, + "representor port create error for " + "vport_id (%d)\n", vport_id); + break; + } + } + /* Keep bitmask and bit index in sync */ + params.vport_mask = params.vport_mask << 1; + vport_id++; + } + + if (kvlist) + rte_kvargs_free(kvlist); + + return ret; +} + +static int +port_rep_remove(struct rte_vdev_device *dev) +{ + struct rte_eth_dev *eth_dev = NULL; + int32_t ret = 0; + + if (!dev) + return -EINVAL; + + RTE_LOG(INFO, PMD, "Closing representor port on numa socket %u\n", + rte_socket_id()); + + eth_dev = rte_eth_dev_allocated( + rte_vdev_device_name(dev)); + if (!eth_dev) + return -EINVAL; + + ret = rte_representor_port_unregister(eth_dev); + if (ret) + return ret; + + rte_eth_dev_release_port(eth_dev); + + return 0; +} + +static struct rte_vdev_driver port_rep_vdev_drv = { + .probe = port_rep_probe, + .remove = port_rep_remove, +}; + +RTE_PMD_REGISTER_VDEV(net_representor, port_rep_vdev_drv); +RTE_PMD_REGISTER_ALIAS(net_representor, eth_representor); +RTE_PMD_REGISTER_PARAM_STRING(net_representor, + "parent=,vport_id="); diff --git a/drivers/net/representor/rte_pmd_representor_version.map b/drivers/net/representor/rte_pmd_representor_version.map new file mode 100644 index 0000000..ef35398 --- /dev/null +++ b/drivers/net/representor/rte_pmd_representor_version.map @@ -0,0 +1,4 @@ +DPDK_2.0 { + + local: *; +}; diff --git a/mk/rte.app.mk b/mk/rte.app.mk index 0778589..460514b 100644 --- a/mk/rte.app.mk +++ b/mk/rte.app.mk @@ -146,6 +146,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 -libverbs -lmlx5 _LDLIBS-$(CONFIG_RTE_LIBRTE_MRVL_PMD) += -lrte_pmd_mrvl -L$(LIBMUSDK_PATH)/lib -lmusdk _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += -lrte_pmd_null +_LDLIBS-$(CONFIG_RTE_LIBRTE_REPRESENTOR) += -lrte_pmd_representor _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap _LDLIBS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += -lrte_pmd_qede _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring -- 2.7.4