From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 688B7459C3; Wed, 18 Sep 2024 08:10:22 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 07C7A42E65; Wed, 18 Sep 2024 08:09:56 +0200 (CEST) Received: from lf-2-59.ptr.blmpb.com (lf-2-59.ptr.blmpb.com [101.36.218.59]) by mails.dpdk.org (Postfix) with ESMTP id D104642DF0 for ; Wed, 18 Sep 2024 08:09:51 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2403070942; d=yunsilicon.com; t=1726639786; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=+qvMIsySgKTh08f//6PboXrS1GwlddgcmIBl8auSuoY=; b=Jc/DU2sYjdgcmh4QSrDHjXiHpcB7KI+aiDqvRBUiqPGOZ8YmJr01RofmgEQ9UTDVY+Pn9w Un//Uqn+4r+4/ipWj5PzvXBAMqhBPjGzVJ9plN5kyf8vv4QY+dUw20q0fwWRYXbSgRfhZd GpJTVKxtXbF+213y/ZKR4iluuzKAmn+tYgpYgVu/Chf+IOqi8aYk7KoLg2oIhdChxCUuC/ tKQovbAlp04riwN0XEuzHmjSX9MUEYb6nkYD7XzTN01NaJdAS+rzx9Iv169RkvGq2KllHb RccyDpuDtG0Mth+ipDrZ55r8bWk+VjAU8Sj6qpoQzoWblplsU52H3XldEX481w== To: Cc: , "WanRenyong" Date: Wed, 18 Sep 2024 14:09:21 +0800 Message-Id: <20240918060936.1231758-5-wanry@yunsilicon.com> Received: from ubuntu-liun.yunsilicon.com ([58.34.192.114]) by smtp.feishu.cn with ESMTPS; Wed, 18 Sep 2024 14:09:44 +0800 Content-Transfer-Encoding: 7bit X-Original-From: WanRenyong X-Lms-Return-Path: Content-Type: text/plain; charset=UTF-8 From: "WanRenyong" Subject: [PATCH v3 04/19] net/xsc: add xsc device init and uninit Mime-Version: 1.0 X-Mailer: git-send-email 2.25.1 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 XSC device is a concept of low level device used to manage hardware resource and to interact with firmware. Signed-off-by: WanRenyong --- v3: * use snprintf instead of sprintf for safety * use getline instead of fgets to handle arbitrary length * change the xsc_dev_args_parse function name to newline v2: * fix compilation error caused by missing dependency --- drivers/net/xsc/meson.build | 20 +++++ drivers/net/xsc/xsc_defs.h | 23 +++++ drivers/net/xsc/xsc_dev.c | 162 +++++++++++++++++++++++++++++++++++ drivers/net/xsc/xsc_dev.h | 34 ++++++++ drivers/net/xsc/xsc_ethdev.c | 22 ++++- drivers/net/xsc/xsc_ethdev.h | 1 + drivers/net/xsc/xsc_utils.c | 88 +++++++++++++++++++ drivers/net/xsc/xsc_utils.h | 14 +++ 8 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 drivers/net/xsc/xsc_dev.c create mode 100644 drivers/net/xsc/xsc_dev.h create mode 100644 drivers/net/xsc/xsc_utils.c create mode 100644 drivers/net/xsc/xsc_utils.h diff --git a/drivers/net/xsc/meson.build b/drivers/net/xsc/meson.build index 7bd7a38483..57d67291df 100644 --- a/drivers/net/xsc/meson.build +++ b/drivers/net/xsc/meson.build @@ -13,6 +13,26 @@ endif sources = files( 'xsc_ethdev.c', + 'xsc_dev.c', + 'xsc_utils.c', ) +libnames = ['ibverbs'] +foreach libname:libnames + lib = dependency('lib' + libname, required: false, method : 'pkg-config') + if lib.found() + ext_deps += lib + else + build = false + reason = 'missing dependency, "' + libname + '"' + subdir_done() + endif +endforeach +lib = dependency('libxscale', required: false, method : 'pkg-config') +if lib.found() + ext_deps += lib + cflags += '-DHAVE_XSC_DV_PROVIDER=1' +else + cflags += '-DHAVE_XSC_DV_PROVIDER=0' +endif diff --git a/drivers/net/xsc/xsc_defs.h b/drivers/net/xsc/xsc_defs.h index b4ede6eca6..97cd61b2d1 100644 --- a/drivers/net/xsc/xsc_defs.h +++ b/drivers/net/xsc/xsc_defs.h @@ -8,5 +8,28 @@ #define XSC_PCI_VENDOR_ID 0x1f67 #define XSC_PCI_DEV_ID_MS 0x1111 +enum xsc_nic_mode { + XSC_NIC_MODE_LEGACY, + XSC_NIC_MODE_SWITCHDEV, + XSC_NIC_MODE_SOC, +}; + +enum xsc_pph_type { + XSC_PPH_NONE = 0, + XSC_RX_PPH = 0x1, + XSC_TX_PPH = 0x2, + XSC_VFREP_PPH = 0x4, + XSC_UPLINK_PPH = 0x8, +}; + +enum xsc_flow_mode { + XSC_FLOW_OFF_HW_ONLY, + XSC_FLOW_ON_HW_ONLY, + XSC_FLOW_ON_HW_FIRST, + XSC_FLOW_HOTSPOT, + XSC_FLOW_MODE_NULL = 7, + XSC_FLOW_MODE_MAX, +}; + #endif /* XSC_DEFS_H_ */ diff --git a/drivers/net/xsc/xsc_dev.c b/drivers/net/xsc/xsc_dev.c new file mode 100644 index 0000000000..73da702f6a --- /dev/null +++ b/drivers/net/xsc/xsc_dev.c @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2024 Yunsilicon Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xsc_log.h" +#include "xsc_defs.h" +#include "xsc_dev.h" +#include "xsc_utils.h" + +#define XSC_DEV_DEF_FLOW_MODE XSC_FLOW_MODE_NULL +#define XSC_DEV_CTRL_FILE_FMT "/dev/yunsilicon/port_ctrl_" PCI_PRI_FMT + +static void +xsc_dev_args_parse(struct xsc_dev *dev, struct rte_devargs *devargs) +{ + struct rte_kvargs *kvlist; + struct xsc_devargs *xdevargs = &dev->devargs; + const char *tmp; + + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (kvlist == NULL) + return; + + tmp = rte_kvargs_get(kvlist, XSC_PPH_MODE_ARG); + if (tmp != NULL) + xdevargs->pph_mode = atoi(tmp); + else + xdevargs->pph_mode = XSC_PPH_NONE; + tmp = rte_kvargs_get(kvlist, XSC_NIC_MODE_ARG); + if (tmp != NULL) + xdevargs->nic_mode = atoi(tmp); + else + xdevargs->nic_mode = XSC_NIC_MODE_LEGACY; + tmp = rte_kvargs_get(kvlist, XSC_FLOW_MODE_ARG); + if (tmp != NULL) + xdevargs->flow_mode = atoi(tmp); + else + xdevargs->flow_mode = XSC_DEV_DEF_FLOW_MODE; + + rte_kvargs_free(kvlist); +} + +static int +xsc_dev_open(struct xsc_dev *dev, struct rte_pci_device *pci_dev) +{ + struct ibv_device *ib_dev; + char ctrl_file[PATH_MAX]; + struct rte_pci_addr *pci_addr = &pci_dev->addr; + int ret; + + ib_dev = xsc_get_ibv_device(&pci_dev->addr); + if (ib_dev == NULL) { + PMD_DRV_LOG(ERR, "Could not get ibv device"); + return -ENODEV; + } + + dev->ibv_ctx = ibv_open_device(ib_dev); + if (dev->ibv_ctx == NULL) { + PMD_DRV_LOG(ERR, "Could not open ibv device: %s", ib_dev->name); + return -ENODEV; + } + + dev->ibv_pd = ibv_alloc_pd(dev->ibv_ctx); + if (dev->ibv_pd == NULL) { + PMD_DRV_LOG(ERR, "Failed to create pd:%s", ib_dev->name); + ret = -EINVAL; + goto alloc_pd_fail; + } + + strcpy(dev->ibv_name, ib_dev->name); + + snprintf(ctrl_file, PATH_MAX, XSC_DEV_CTRL_FILE_FMT, + pci_addr->domain, pci_addr->bus, pci_addr->devid, pci_addr->function); + + ret = open(ctrl_file, O_RDWR); + if (ret < 0) { + PMD_DRV_LOG(ERR, "Failed to open file: (%s) ", ctrl_file); + goto open_ctrl_file_fail; + } + dev->ctrl_fd = ret; + + dev->bar_len = pci_dev->mem_resource[0].len; + dev->bar_addr = mmap(NULL, dev->bar_len, PROT_READ | PROT_WRITE, + MAP_SHARED, dev->ctrl_fd, 0); + if (dev->bar_addr == MAP_FAILED) { + PMD_DRV_LOG(ERR, "Failed to mmap file: (%s) ", ctrl_file); + ret = -EINVAL; + goto mmap_fail; + } + + return 0; + +mmap_fail: + close(dev->ctrl_fd); +open_ctrl_file_fail: + ibv_dealloc_pd(dev->ibv_pd); +alloc_pd_fail: + ibv_close_device(dev->ibv_ctx); + + return ret; +} + +static void +xsc_dev_close(struct xsc_dev *dev) +{ + munmap(dev->bar_addr, dev->bar_len); + close(dev->ctrl_fd); + ibv_close_device(dev->ibv_ctx); +} + +int +xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev) +{ + struct xsc_dev *d; + int ret; + + PMD_INIT_FUNC_TRACE(); + + d = rte_zmalloc(NULL, sizeof(*d), RTE_CACHE_LINE_SIZE); + if (d == NULL) { + PMD_DRV_LOG(ERR, "Failed to alloc memory for xsc_dev"); + return -ENOMEM; + } + + xsc_dev_args_parse(d, pci_dev->device.devargs); + + ret = xsc_dev_open(d, pci_dev); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to open xsc device"); + goto dev_open_fail; + } + + d->pci_dev = pci_dev; + *dev = d; + + return 0; + +dev_open_fail: + rte_free(d); + return ret; +} + +void +xsc_dev_uninit(struct xsc_dev *dev) +{ + PMD_INIT_FUNC_TRACE(); + + xsc_dev_close(dev); + rte_free(dev); +} diff --git a/drivers/net/xsc/xsc_dev.h b/drivers/net/xsc/xsc_dev.h new file mode 100644 index 0000000000..ce9dd65400 --- /dev/null +++ b/drivers/net/xsc/xsc_dev.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2024 Yunsilicon Technology Co., Ltd. + */ + +#ifndef _XSC_DEV_H_ +#define _XSC_DEV_H_ + +#include + +#define XSC_PPH_MODE_ARG "pph_mode" +#define XSC_NIC_MODE_ARG "nic_mode" +#define XSC_FLOW_MODE_ARG "flow_mode" + +struct xsc_devargs { + int nic_mode; + int flow_mode; + int pph_mode; +}; + +struct xsc_dev { + struct rte_pci_device *pci_dev; + struct xsc_devargs devargs; + struct ibv_context *ibv_ctx; + struct ibv_pd *ibv_pd; + char ibv_name[IBV_SYSFS_NAME_MAX]; + void *bar_addr; + uint64_t bar_len; + int ctrl_fd; +}; + +int xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev); +void xsc_dev_uninit(struct xsc_dev *dev); + +#endif /* _XSC_DEV_H_ */ diff --git a/drivers/net/xsc/xsc_ethdev.c b/drivers/net/xsc/xsc_ethdev.c index 8f4d539848..6a33cbb2cd 100644 --- a/drivers/net/xsc/xsc_ethdev.c +++ b/drivers/net/xsc/xsc_ethdev.c @@ -6,27 +6,38 @@ #include "xsc_log.h" #include "xsc_defs.h" +#include "xsc_dev.h" #include "xsc_ethdev.h" static int xsc_ethdev_init(struct rte_eth_dev *eth_dev) { struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev); + int ret; PMD_INIT_FUNC_TRACE(); priv->eth_dev = eth_dev; priv->pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); + ret = xsc_dev_init(priv->pci_dev, &priv->xdev); + if (ret) { + PMD_DRV_LOG(ERR, "Failed to initialize xsc device"); + return ret; + } + return 0; } static int xsc_ethdev_uninit(struct rte_eth_dev *eth_dev) { - RTE_SET_USED(eth_dev); + struct xsc_ethdev_priv *priv = TO_XSC_ETHDEV_PRIV(eth_dev); + PMD_INIT_FUNC_TRACE(); + xsc_dev_uninit(priv->xdev); + return 0; } @@ -75,8 +86,17 @@ static struct rte_pci_driver xsc_ethdev_pci_driver = { .remove = xsc_ethdev_pci_remove, }; +RTE_INIT(xsc_pmd_init) +{ + ibv_fork_init(); +} + RTE_PMD_REGISTER_PCI(net_xsc, xsc_ethdev_pci_driver); RTE_PMD_REGISTER_PCI_TABLE(net_xsc, xsc_ethdev_pci_id_map); +RTE_PMD_REGISTER_PARAM_STRING(net_xsc, + XSC_PPH_MODE_ARG "=" + XSC_NIC_MODE_ARG "=" + XSC_FLOW_MODE_ARG "="); RTE_LOG_REGISTER_SUFFIX(xsc_logtype_init, init, NOTICE); RTE_LOG_REGISTER_SUFFIX(xsc_logtype_driver, driver, NOTICE); diff --git a/drivers/net/xsc/xsc_ethdev.h b/drivers/net/xsc/xsc_ethdev.h index 75aa34dc63..22fc462e25 100644 --- a/drivers/net/xsc/xsc_ethdev.h +++ b/drivers/net/xsc/xsc_ethdev.h @@ -8,6 +8,7 @@ struct xsc_ethdev_priv { struct rte_eth_dev *eth_dev; struct rte_pci_device *pci_dev; + struct xsc_dev *xdev; }; #define TO_XSC_ETHDEV_PRIV(dev) \ diff --git a/drivers/net/xsc/xsc_utils.c b/drivers/net/xsc/xsc_utils.c new file mode 100644 index 0000000000..ff4e837f96 --- /dev/null +++ b/drivers/net/xsc/xsc_utils.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2024 Yunsilicon Technology Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xsc_log.h" +#include "xsc_utils.h" + +static int +xsc_get_ibdev_pci_addr(const char *dev_path, struct rte_pci_addr *pci_addr) +{ + FILE *file; + char *line = NULL; + size_t len = 0; + char path[PATH_MAX]; + int ret = -ENOENT; + + ret = snprintf(path, sizeof(path), "%s/device/uevent", dev_path); + if (ret < 0 || ret >= (int)sizeof(path)) { + rte_errno = ENAMETOOLONG; + return -rte_errno; + } + + file = fopen(path, "rb"); + if (file == NULL) { + PMD_DRV_LOG(ERR, "Failed to open file: (%s) ", path); + return ret; + } + + while (getline(&line, &len, file) != -1) { + if (sscanf(line, + "PCI_SLOT_NAME=%04x:%hhx:%hhx.%hhx", + &pci_addr->domain, + &pci_addr->bus, + &pci_addr->devid, + &pci_addr->function) == 4) { + ret = 0; + break; + } + } + + free(line); + fclose(file); + return ret; +} + +struct ibv_device * +xsc_get_ibv_device(const struct rte_pci_addr *addr) +{ + int ibv_num, i; + struct ibv_device **ibv_list; + struct ibv_device *ibv_match = NULL; + struct rte_pci_addr ibv_pci_addr; + + ibv_list = ibv_get_device_list(&ibv_num); + if (ibv_list == NULL) + return NULL; + + for (i = 0; i < ibv_num; i++) { + if (xsc_get_ibdev_pci_addr(ibv_list[i]->ibdev_path, &ibv_pci_addr) != 0) + continue; + if (rte_pci_addr_cmp(addr, &ibv_pci_addr) != 0) + continue; + ibv_match = ibv_list[i]; + PMD_DRV_LOG(DEBUG, "Finding device \"name:%s, %s, path:%s, %s\"..", + ibv_list[i]->name, ibv_list[i]->dev_name, + ibv_list[i]->dev_path, ibv_list[i]->ibdev_path); + break; + } + ibv_free_device_list(ibv_list); + + if (ibv_match == NULL) { + PMD_DRV_LOG(WARNING, + "No Verbs device matches PCI device " PCI_PRI_FMT, + addr->domain, addr->bus, addr->devid, addr->function); + } + + return ibv_match; +} diff --git a/drivers/net/xsc/xsc_utils.h b/drivers/net/xsc/xsc_utils.h new file mode 100644 index 0000000000..0bc318e96a --- /dev/null +++ b/drivers/net/xsc/xsc_utils.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2024 Yunsilicon Technology Co., Ltd. + */ + +#ifndef _XSC_UTILS_H_ +#define _XSC_UTILS_H_ + +#include + +#include + +struct ibv_device *xsc_get_ibv_device(const struct rte_pci_addr *addr); + +#endif /* _XSC_UTILS_H_ */ -- 2.25.1