From patchwork Thu Jan 7 07:14:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jingjing Wu X-Patchwork-Id: 86085 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (xvm-189-124.dc0.ghst.net [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 9708AA09FF; Thu, 7 Jan 2021 08:28:55 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 6C898140EB6; Thu, 7 Jan 2021 08:28:53 +0100 (CET) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mails.dpdk.org (Postfix) with ESMTP id A6E8B140EB4 for ; Thu, 7 Jan 2021 08:28:51 +0100 (CET) IronPort-SDR: i5UgY6gRYjVKjqg1HEAH66nNKML3dZFNYvAMmsqfumDmxciUVS6MiSmrnov88q0qeyEFCjkZqF F+0jQSqW1g0g== X-IronPort-AV: E=McAfee;i="6000,8403,9856"; a="173880036" X-IronPort-AV: E=Sophos;i="5.79,329,1602572400"; d="scan'208";a="173880036" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 06 Jan 2021 23:28:51 -0800 IronPort-SDR: D/E5iMgDEDSa8xzXRwMxv/87fkwai9QUQujsy+Smh5j+MhRcjmEi3fQ8nHojNfwIQnZexxVjuK QKAr6E942IQQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,329,1602572400"; d="scan'208";a="379617046" Received: from dpdk-wujingji.sh.intel.com ([10.67.119.101]) by orsmga008.jf.intel.com with ESMTP; 06 Jan 2021 23:28:47 -0800 From: Jingjing Wu To: dev@dpdk.org Cc: jingjing.wu@intel.com, beilei.xing@intel.com, chenbo.xia@intel.com, xiuchun.lu@intel.com, Kun Qiu Date: Thu, 7 Jan 2021 15:14:58 +0800 Message-Id: <20210107071503.14720-2-jingjing.wu@intel.com> X-Mailer: git-send-email 2.21.1 In-Reply-To: <20210107071503.14720-1-jingjing.wu@intel.com> References: <20201219075454.40266-1-jingjing.wu@intel.com> <20210107071503.14720-1-jingjing.wu@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 1/6] net/iavf_be: introduce iavf backend driver X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Introduce driver for iavf backend vdev which is based on vfio-user protocol and emudev libs. Signed-off-by: Jingjing Wu Signed-off-by: Kun Qiu --- drivers/net/iavf_be/iavf_be.h | 39 ++++ drivers/net/iavf_be/iavf_be_ethdev.c | 330 +++++++++++++++++++++++++++ drivers/net/iavf_be/meson.build | 12 + drivers/net/iavf_be/version.map | 3 + drivers/net/meson.build | 1 + 5 files changed, 385 insertions(+) create mode 100644 drivers/net/iavf_be/iavf_be.h create mode 100644 drivers/net/iavf_be/iavf_be_ethdev.c create mode 100644 drivers/net/iavf_be/meson.build create mode 100644 drivers/net/iavf_be/version.map diff --git a/drivers/net/iavf_be/iavf_be.h b/drivers/net/iavf_be/iavf_be.h new file mode 100644 index 0000000000..956955786a --- /dev/null +++ b/drivers/net/iavf_be/iavf_be.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#ifndef _IAVF_BE_H_ +#define _IAVF_BE_H_ + +/* Structure to store private data for backend instance*/ +struct iavfbe_adapter { + struct rte_eth_dev *eth_dev; + struct rte_emudev *emu_dev; + uint16_t edev_id; /* Emulated Device ID */ + struct rte_emudev_info dev_info; + + uint16_t nb_qps; + bool link_up; + int cq_irqfd; + rte_atomic32_t irq_enable; + + uint8_t unicast_promisc:1, + multicast_promisc:1, + vlan_filter:1, + vlan_strip:1; + + int adapter_stopped; + uint8_t *reset; /* Reset status */ + volatile int started; +}; + +#define IAVFBE_DEV_PRIVATE_TO_ADAPTER(adapter) \ + ((struct iavfbe_adapter *)adapter) + +int iavfbe_dev_link_update(struct rte_eth_dev *dev, int wait_to_complete); + +extern int iavfbe_logtype; +#define IAVF_BE_LOG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, iavfbe_logtype, "%s(): " fmt "\n", \ + __func__, ## args) +#endif /* _IAVF_BE_H_ */ diff --git a/drivers/net/iavf_be/iavf_be_ethdev.c b/drivers/net/iavf_be/iavf_be_ethdev.c new file mode 100644 index 0000000000..3d5ca34ec0 --- /dev/null +++ b/drivers/net/iavf_be/iavf_be_ethdev.c @@ -0,0 +1,330 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2020 Intel Corporation + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include "iavf_be.h" + +#define AVFBE_EDEV_ID_ARG "emu" +#define AVFBE_MAC_ARG "mac" + +int iavfbe_logtype; + +static const char *iavfbe_valid_arg[] = { + AVFBE_EDEV_ID_ARG, + AVFBE_MAC_ARG, + NULL +}; + +static struct rte_eth_link iavfbe_link = { + .link_speed = ETH_SPEED_NUM_NONE, + .link_duplex = ETH_LINK_FULL_DUPLEX, + .link_status = ETH_LINK_DOWN +}; + +static int iavfbe_dev_configure(struct rte_eth_dev *dev); +static int iavfbe_dev_close(struct rte_eth_dev *dev); +static int iavfbe_dev_start(struct rte_eth_dev *dev); +static int iavfbe_dev_stop(struct rte_eth_dev *dev); +static int iavfbe_dev_info_get(struct rte_eth_dev *dev, + struct rte_eth_dev_info *dev_info); +static void iavfbe_destroy_adapter(struct rte_eth_dev *dev); + +static const struct eth_dev_ops iavfbe_eth_dev_ops = { + .dev_configure = iavfbe_dev_configure, + .dev_close = iavfbe_dev_close, + .dev_start = iavfbe_dev_start, + .dev_stop = iavfbe_dev_stop, + .dev_infos_get = iavfbe_dev_info_get, + .link_update = iavfbe_dev_link_update, +}; + +static int +iavfbe_dev_info_get(struct rte_eth_dev *dev __rte_unused, struct rte_eth_dev_info *dev_info) +{ + dev_info->max_rx_queues = 0; + dev_info->max_tx_queues = 0; + dev_info->min_rx_bufsize = 0; + dev_info->max_rx_pktlen = 0; + + return 0; +} + + +static int +iavfbe_dev_configure(struct rte_eth_dev *dev __rte_unused) +{ + /* Any configuration? */ + return 0; +} + +static int +iavfbe_dev_start(struct rte_eth_dev *dev) +{ + struct iavfbe_adapter *adapter = + IAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + + adapter->adapter_stopped = 0; + + return 0; +} + +static int +iavfbe_dev_stop(struct rte_eth_dev *dev) +{ + struct iavfbe_adapter *adapter = + IAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + + if (adapter->adapter_stopped == 1) + return 0; + + adapter->adapter_stopped = 1; + + return 0; +} + +int +iavfbe_dev_link_update(struct rte_eth_dev *dev, + __rte_unused int wait_to_complete) +{ + struct iavfbe_adapter *ad = + IAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + struct rte_eth_link new_link = dev->data->dev_link; + + /* Only link status is updated */ + new_link.link_status = ad->link_up ? ETH_LINK_UP : ETH_LINK_DOWN; + + if (rte_atomic64_cmpset((volatile uint64_t *)&dev->data->dev_link, + *(uint64_t *)&dev->data->dev_link, + *(uint64_t *)&new_link) == 0) + return -EAGAIN; + + return 0; +} + +static int +iavfbe_dev_close(struct rte_eth_dev *dev) +{ + iavfbe_destroy_adapter(dev); + rte_eth_dev_release_port(dev); + + return 0; +} + +static inline int +save_str(const char *key __rte_unused, const char *value, + void *extra_args) +{ + const char **str = extra_args; + + if (value == NULL) + return -1; + + *str = value; + + return 0; +} + +static inline int +set_mac(const char *key __rte_unused, const char *value, void *extra_args) +{ + struct rte_ether_addr *ether_addr = (struct rte_ether_addr *)extra_args; + + if (rte_ether_unformat_addr(value, ether_addr) < 0) + IAVF_BE_LOG(ERR, "Failed to parse mac '%s'.", value); + return 0; +} + +static int +iavfbe_init_adapter(struct rte_eth_dev *eth_dev, + struct rte_emudev *emu_dev, + struct rte_ether_addr *ether_addr __rte_unused) +{ + struct iavfbe_adapter *adapter; + struct rte_iavf_emu_config *conf; + int ret; + + adapter = IAVFBE_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private); + + adapter->eth_dev = eth_dev; + adapter->emu_dev = emu_dev; + adapter->edev_id = emu_dev->dev_id; + emu_dev->backend_priv = (void *)adapter; + rte_wmb(); + + conf = rte_zmalloc_socket("iavfbe", sizeof(*conf), 0, + eth_dev->device->numa_node); + if (!conf) { + IAVF_BE_LOG(ERR, "Fail to allocate emulated " + "iavf configuration"); + return -ENOMEM; + } + adapter->dev_info.dev_priv = (rte_emudev_obj_t)conf; + + ret = rte_emudev_get_dev_info(emu_dev->dev_id, &adapter->dev_info); + if (ret) + goto err_info; + + adapter->nb_qps = conf->qp_num; + return 0; + +err_info: + rte_free(conf); + return ret; +} + +static void +iavfbe_destroy_adapter(struct rte_eth_dev *dev) +{ + struct iavfbe_adapter *adapter = + IAVFBE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private); + + if (adapter->emu_dev) { + adapter->emu_dev->backend_priv = NULL; + rte_wmb(); + } + + rte_free(adapter->dev_info.dev_priv); +} + +static int +eth_dev_iavfbe_create(struct rte_vdev_device *dev, + struct rte_emudev *emu_dev, + struct rte_ether_addr *addr) +{ + struct rte_eth_dev *eth_dev = NULL; + struct iavfbe_adapter *adapter; + int ret = 0; + + if (dev->device.numa_node == SOCKET_ID_ANY) + dev->device.numa_node = rte_socket_id(); + + IAVF_BE_LOG(INFO, "Creating iavfbe ethdev on numa socket %u\n", + dev->device.numa_node); + + eth_dev = rte_eth_vdev_allocate(dev, sizeof(*adapter)); + if (!eth_dev) { + IAVF_BE_LOG(ERR, "fail to allocate eth_dev\n"); + ret = -ENOMEM; + } + + iavfbe_init_adapter(eth_dev, emu_dev, addr); + adapter = IAVFBE_DEV_PRIVATE_TO_ADAPTER(eth_dev->data->dev_private); + + /* Initializing default address with devarg */ + eth_dev->data->mac_addrs = + rte_zmalloc_socket(rte_vdev_device_name(dev), + sizeof(struct rte_ether_addr), 0, + dev->device.numa_node); + if (eth_dev->data->mac_addrs == NULL) { + IAVF_BE_LOG(ERR, "fail to allocate eth_addr\n"); + ret = -ENOMEM; + } + rte_ether_addr_copy(addr, ð_dev->data->mac_addrs[0]); + + eth_dev->dev_ops = &iavfbe_eth_dev_ops; + + eth_dev->data->dev_link = iavfbe_link; + eth_dev->data->numa_node = dev->device.numa_node; + + rte_eth_dev_probing_finish(eth_dev); + + return ret; +} + +static int +rte_pmd_iavfbe_probe(struct rte_vdev_device *dev) +{ + struct rte_kvargs *kvlist = NULL; + struct rte_emudev *emu_dev; + const char *emudev_name; + struct rte_ether_addr ether_addr; + int ret = 0; + + if (!dev) + return -EINVAL; + + IAVF_BE_LOG(INFO, "Initializing pmd_iavfbe for %s\n", + dev->device.name); + + kvlist = rte_kvargs_parse(rte_vdev_device_args(dev), iavfbe_valid_arg); + if (kvlist == NULL) + return -1; + + if (rte_kvargs_count(kvlist, AVFBE_EDEV_ID_ARG) == 1) { + ret = rte_kvargs_process(kvlist, AVFBE_EDEV_ID_ARG, + &save_str, &emudev_name); + if (ret < 0) + goto free_kvlist; + } else { + ret = -EINVAL; + goto free_kvlist; + } + + if (rte_kvargs_count(kvlist, AVFBE_MAC_ARG) == 1) { + ret = rte_kvargs_process(kvlist, AVFBE_MAC_ARG, + &set_mac, ðer_addr); + if (ret < 0) + goto free_kvlist; + } else + rte_eth_random_addr(ðer_addr.addr_bytes[0]); + + emu_dev = rte_emudev_allocated(emudev_name); + if (!emu_dev || strcmp(emu_dev->dev_info.dev_type, RTE_IAVF_EMUDEV_TYPE)) { + IAVF_BE_LOG(ERR, "emulated device isn't avf device\n"); + ret = -EINVAL; + goto free_kvlist; + } + + ret = eth_dev_iavfbe_create(dev, emu_dev, ðer_addr); + +free_kvlist: + rte_kvargs_free(kvlist); + return ret; +} + +static int +rte_pmd_iavfbe_remove(struct rte_vdev_device *dev) +{ + const char *name; + struct rte_eth_dev *eth_dev = NULL; + + name = rte_vdev_device_name(dev); + + eth_dev = rte_eth_dev_allocated(name); + if (!eth_dev) + return 0; + + iavfbe_dev_close(eth_dev); + + return 0; +} + +static struct rte_vdev_driver pmd_iavfbe_drv = { + .probe = rte_pmd_iavfbe_probe, + .remove = rte_pmd_iavfbe_remove, +}; + +RTE_PMD_REGISTER_VDEV(net_iavfbe, pmd_iavfbe_drv); +RTE_PMD_REGISTER_ALIAS(net_iavfbe, eth_iavfbe); +RTE_PMD_REGISTER_PARAM_STRING(net_iavfbe, + AVFBE_EDEV_ID_ARG "=" + AVFBE_MAC_ARG "=xx:xx:xx:xx:xx:xx"); + +RTE_INIT(iavfbe_init_log) +{ + iavfbe_logtype = rte_log_register("pmd.net.iavfbe"); + if (iavfbe_logtype >= 0) + rte_log_set_level(iavfbe_logtype, RTE_LOG_INFO); +} diff --git a/drivers/net/iavf_be/meson.build b/drivers/net/iavf_be/meson.build new file mode 100644 index 0000000000..24c625fa18 --- /dev/null +++ b/drivers/net/iavf_be/meson.build @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2020 Intel Corporation + +cflags += ['-Wno-strict-aliasing'] + +includes += include_directories('../../common/iavf') + +deps += ['bus_vdev', 'common_iavf', 'vfio_user', 'emu_iavf'] + +sources = files( + 'iavf_be_ethdev.c', +) diff --git a/drivers/net/iavf_be/version.map b/drivers/net/iavf_be/version.map new file mode 100644 index 0000000000..4a76d1d52d --- /dev/null +++ b/drivers/net/iavf_be/version.map @@ -0,0 +1,3 @@ +DPDK_21 { + local: *; +}; diff --git a/drivers/net/meson.build b/drivers/net/meson.build index 29f4777500..4676ef4b3e 100644 --- a/drivers/net/meson.build +++ b/drivers/net/meson.build @@ -24,6 +24,7 @@ drivers = ['af_packet', 'hinic', 'hns3', 'iavf', + 'iavf_be', 'ice', 'igc', 'ipn3ke',