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 DBEB84595A; Wed, 11 Sep 2024 04:09:16 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7C70042FA1; Wed, 11 Sep 2024 04:08:18 +0200 (CEST) Received: from lf-2-39.ptr.blmpb.com (lf-2-39.ptr.blmpb.com [101.36.218.39]) by mails.dpdk.org (Postfix) with ESMTP id 0DEDC42EFE for ; Wed, 11 Sep 2024 04:08:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2403070942; d=yunsilicon.com; t=1726020482; h=from:subject: mime-version:from:date:message-id:subject:to:cc:reply-to:content-type: mime-version:in-reply-to:message-id; bh=oN8fgGlO/mZy3UtuQ+A6RhUjuIBfonN7Dtl7mT4LJhw=; b=LBPk7KCgM3VEM9sDdCFUMcq0oPNpvvQgWkal92juTd6MHuaVLe9gszsA+jyorCT9obzVbC bGVNEueL4L+3DeEesj9gSMzdHiXMBN4FoXpXHfCkYyr6xtBlaN704GcpwJxpNqJ9PXA0kz fnUt3Xm9ygvcmgIFUenRQoUxWfPVu1GoMYeV46RNvqAiyYVLJYZZMrnPxbUqqJxwYIamLc /060PWWDmVrvhwAulaHKQCDUaa8AK3Arwl3FdsX/MyxJ+pHXGNCMj7tWaGN2FaPnnLIr88 5+2dOlSyrKJJza0utkzZrCK9R0wO0qF9pVnuxd/20LJ6HjO3bcoDyAhrjkhxYA== Received: from ubuntu-liun.yunsilicon.com ([58.34.192.114]) by smtp.feishu.cn with ESMTPS; Wed, 11 Sep 2024 10:08:01 +0800 Content-Type: text/plain; charset=UTF-8 Subject: [PATCH v2 07/19] net/xsc: add representor ports probe Message-Id: <20240911020740.3950704-8-wanry@yunsilicon.com> Mime-Version: 1.0 X-Lms-Return-Path: Cc: , , "WanRenyong" , "Na Na" From: "WanRenyong" X-Mailer: git-send-email 2.25.1 Content-Transfer-Encoding: 7bit X-Original-From: WanRenyong To: Date: Wed, 11 Sep 2024 10:07:28 +0800 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 representor port is designed to store representor resources. In addition to common representor ports, xsc device is a special representor port. Signed-off-by: WanRenyong Signed-off-by: Na Na --- drivers/net/xsc/xsc_defs.h | 24 +++++++ drivers/net/xsc/xsc_dev.c | 103 +++++++++++++++++++++++++++++- drivers/net/xsc/xsc_dev.h | 27 ++++++++ drivers/net/xsc/xsc_utils.c | 122 ++++++++++++++++++++++++++++++++++++ drivers/net/xsc/xsc_utils.h | 3 + 5 files changed, 278 insertions(+), 1 deletion(-) diff --git a/drivers/net/xsc/xsc_defs.h b/drivers/net/xsc/xsc_defs.h index 97cd61b2d1..8cb67ed2e1 100644 --- a/drivers/net/xsc/xsc_defs.h +++ b/drivers/net/xsc/xsc_defs.h @@ -8,6 +8,10 @@ #define XSC_PCI_VENDOR_ID 0x1f67 #define XSC_PCI_DEV_ID_MS 0x1111 +#define XSC_VFREP_BASE_LOGICAL_PORT 1081 + + + enum xsc_nic_mode { XSC_NIC_MODE_LEGACY, XSC_NIC_MODE_SWITCHDEV, @@ -31,5 +35,25 @@ enum xsc_flow_mode { XSC_FLOW_MODE_MAX, }; +enum xsc_funcid_type { + XSC_FUNCID_TYPE_INVAL = 0x0, + XSC_EMU_FUNCID = 0x1, + XSC_PHYPORT_MAC_FUNCID = 0x2, + XSC_VF_IOCTL_FUNCID = 0x3, + XSC_PHYPORT_LAG_FUNCID = 0x4, + XSC_FUNCID_TYPE_UNKNOWN = 0x5, +}; + +enum xsc_phy_port_type { + XSC_PORT_TYPE_NONE = 0, + XSC_PORT_TYPE_UPLINK, /* mac0rep */ + XSC_PORT_TYPE_UPLINK_BOND, /* bondrep */ + XSC_PORT_TYPE_PFVF, /*hasreps: vfrep*/ + XSC_PORT_TYPE_PFHPF, /*hasreps: host pf rep*/ + XSC_PORT_TYPE_UNKNOWN, +}; + +#define XSC_PHY_PORT_NUM 1 + #endif /* XSC_DEFS_H_ */ diff --git a/drivers/net/xsc/xsc_dev.c b/drivers/net/xsc/xsc_dev.c index 1eb68ac95d..3ba9a16116 100644 --- a/drivers/net/xsc/xsc_dev.c +++ b/drivers/net/xsc/xsc_dev.c @@ -23,6 +23,31 @@ #define XSC_DEV_DEF_FLOW_MODE XSC_FLOW_MODE_NULL #define XSC_DEV_CTRL_FILE_FMT "/dev/yunsilicon/port_ctrl_" PCI_PRI_FMT +static int +xsc_dev_alloc_vfos_info(struct xsc_dev *dev) +{ + struct xsc_hwinfo *hwinfo; + int vfrep_offset = 0; + int base_lp = 0; + + hwinfo = &dev->hwinfo; + if (hwinfo->pcie_no == 1) { + vfrep_offset = hwinfo->func_id - + hwinfo->pcie1_pf_funcid_base + + hwinfo->pcie0_pf_funcid_top - + hwinfo->pcie0_pf_funcid_base + 1; + } else { + vfrep_offset = hwinfo->func_id - hwinfo->pcie0_pf_funcid_base; + } + + base_lp = XSC_VFREP_BASE_LOGICAL_PORT; + if (dev->devargs.nic_mode == XSC_NIC_MODE_LEGACY) + base_lp = base_lp + vfrep_offset; + + dev->vfos_logical_in_port = base_lp; + return 0; +} + static int xsc_hwinfo_init(struct xsc_dev *dev) { struct { @@ -174,6 +199,73 @@ xsc_dev_close(struct xsc_dev *dev) ibv_close_device(dev->ibv_ctx); } +static void +xsc_repr_info_init(struct xsc_repr_info *info, enum xsc_phy_port_type port_type, + enum xsc_funcid_type funcid_type, int32_t repr_id) +{ + info->repr_id = repr_id; + info->port_type = port_type; + if (port_type == XSC_PORT_TYPE_UPLINK_BOND) { + info->pf_bond = 1; + info->funcid = XSC_PHYPORT_LAG_FUNCID << 14; + } else if (port_type == XSC_PORT_TYPE_UPLINK) { + info->pf_bond = -1; + info->funcid = XSC_PHYPORT_MAC_FUNCID << 14; + } else if (port_type == XSC_PORT_TYPE_PFVF) { + info->funcid = funcid_type << 14; + } +} + +int +xsc_repr_ports_probe(struct xsc_dev *dev, int nb_ports, int max_nb_ports) +{ + int funcid_type; + struct xsc_repr_port *repr_port; + int i; + int ret; + + PMD_INIT_FUNC_TRACE(); + + ret = xsc_get_ifindex_by_pci_addr(&dev->pci_dev->addr, &dev->ifindex); + if (ret) { + PMD_DRV_LOG(ERR, "Could not get xsc dev ifindex"); + return ret; + } + + dev->num_repr_ports = nb_ports + 1; + + dev->repr_ports = rte_zmalloc(NULL, + sizeof(struct xsc_repr_port) * dev->num_repr_ports, + RTE_CACHE_LINE_SIZE); + if (dev->repr_ports == NULL) { + PMD_DRV_LOG(ERR, "Failed to allocate memory for repr_ports"); + return -ENOMEM; + } + + funcid_type = (dev->devargs.nic_mode == XSC_NIC_MODE_SWITCHDEV) ? + XSC_VF_IOCTL_FUNCID : XSC_PHYPORT_MAC_FUNCID; + + repr_port = &dev->repr_ports[XSC_DEV_REPR_PORT]; + xsc_repr_info_init(&repr_port->info, + XSC_PORT_TYPE_UPLINK, XSC_FUNCID_TYPE_UNKNOWN, -1); + repr_port->info.ifindex = dev->ifindex; + repr_port->xdev = dev; + + if ((dev->devargs.pph_mode & XSC_TX_PPH) == 0) + repr_port->info.repr_id = 510; + else + repr_port->info.repr_id = max_nb_ports - 1; + + for (i = 1; i < dev->num_repr_ports; i++) { + repr_port = &dev->repr_ports[i]; + xsc_repr_info_init(&repr_port->info, + XSC_PORT_TYPE_PFVF, funcid_type, i - XSC_PHY_PORT_NUM); + repr_port->xdev = dev; + } + + return 0; +} + int xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev) { @@ -199,8 +291,15 @@ xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev) ret = xsc_hwinfo_init(d); if (ret) { PMD_DRV_LOG(ERR, "Failed to initialize hardware info"); + ret = -EINVAL; + goto hwinfo_init_fail; + } + + ret = xsc_dev_alloc_vfos_info(d); + if (ret) { + PMD_DRV_LOG(ERR, "Alloc vfos info failed"); + ret = -EINVAL; goto hwinfo_init_fail; - return ret; } d->pci_dev = pci_dev; @@ -220,6 +319,8 @@ xsc_dev_uninit(struct xsc_dev *dev) { PMD_INIT_FUNC_TRACE(); + if (dev->repr_ports != NULL) + rte_free(dev->repr_ports); xsc_dev_close(dev); rte_free(dev); } diff --git a/drivers/net/xsc/xsc_dev.h b/drivers/net/xsc/xsc_dev.h index 5f0e911b42..93ab1e24fe 100644 --- a/drivers/net/xsc/xsc_dev.h +++ b/drivers/net/xsc/xsc_dev.h @@ -7,10 +7,14 @@ #include +#include "xsc_defs.h" + #define XSC_PPH_MODE_ARG "pph_mode" #define XSC_NIC_MODE_ARG "nic_mode" #define XSC_FLOW_MODE_ARG "flow_mode" +#define XSC_DEV_REPR_PORT 0 + struct xsc_hwinfo { uint8_t valid; /* 1: current phy info is valid, 0 : invalid */ uint32_t pcie_no; /* pcie number , 0 or 1 */ @@ -48,10 +52,32 @@ struct xsc_devargs { int pph_mode; }; +struct xsc_repr_info { + int32_t repr_id; + enum xsc_phy_port_type port_type; + int pf_bond; + + uint32_t ifindex; + const char *phys_dev_name; + uint32_t funcid; +}; + +struct xsc_repr_port { + struct xsc_dev *xdev; + struct xsc_repr_info info; + void *drv_data; +}; + struct xsc_dev { struct rte_pci_device *pci_dev; struct xsc_devargs devargs; struct xsc_hwinfo hwinfo; + int vfos_logical_in_port; + + struct xsc_repr_port *repr_ports; + int num_repr_ports; + int ifindex; + struct ibv_context *ibv_ctx; struct ibv_pd *ibv_pd; char ibv_name[IBV_SYSFS_NAME_MAX]; @@ -62,5 +88,6 @@ struct xsc_dev { int xsc_dev_init(struct rte_pci_device *pci_dev, struct xsc_dev **dev); void xsc_dev_uninit(struct xsc_dev *dev); +int xsc_repr_ports_probe(struct xsc_dev *dev, int nb_port, int max_nb_ports); #endif /* _XSC_DEV_H_ */ diff --git a/drivers/net/xsc/xsc_utils.c b/drivers/net/xsc/xsc_utils.c index cd4e3d9bad..0d8f3f5be9 100644 --- a/drivers/net/xsc/xsc_utils.c +++ b/drivers/net/xsc/xsc_utils.c @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #include #include "xsc_log.h" @@ -94,3 +97,122 @@ xsc_get_ibv_device(const struct rte_pci_addr *addr) return ibv_match; } + +int +xsc_get_ifname_by_pci_addr(struct rte_pci_addr *addr, char *ifname) +{ + DIR *dir; + struct dirent *dent; + unsigned int dev_type = 0; + unsigned int dev_port_prev = ~0u; + char match[IF_NAMESIZE] = ""; + char net_path[PATH_MAX]; + + snprintf(net_path, sizeof(net_path), "%s/" PCI_PRI_FMT "/net", + rte_pci_get_sysfs_path(), addr->domain, addr->bus, + addr->devid, addr->function); + + dir = opendir(net_path); + if (dir == NULL) { + PMD_DRV_LOG(ERR, "Could not open %s", net_path); + return -ENOENT; + } + + while ((dent = readdir(dir)) != NULL) { + char *name = dent->d_name; + FILE *file; + unsigned int dev_port; + int r; + char path[PATH_MAX]; + + if ((name[0] == '.') && + ((name[1] == '\0') || + ((name[1] == '.') && (name[2] == '\0')))) + continue; + + snprintf(path, sizeof(path), "%s/%s/%s", + net_path, name, (dev_type ? "dev_id" : "dev_port")); + + file = fopen(path, "rb"); + if (file == NULL) { + if (errno != ENOENT) + continue; + /* + * Switch to dev_id when dev_port does not exist as + * is the case with Linux kernel versions < 3.15. + */ +try_dev_id: + match[0] = '\0'; + if (dev_type) + break; + dev_type = 1; + dev_port_prev = ~0u; + rewinddir(dir); + continue; + } + r = fscanf(file, (dev_type ? "%x" : "%u"), &dev_port); + fclose(file); + if (r != 1) + continue; + /* + * Switch to dev_id when dev_port returns the same value for + * all ports. May happen when using a MOFED release older than + * 3.0 with a Linux kernel >= 3.15. + */ + if (dev_port == dev_port_prev) + goto try_dev_id; + dev_port_prev = dev_port; + if (dev_port == 0) + snprintf(match, IF_NAMESIZE, "%s", name); + } + closedir(dir); + if (match[0] == '\0') + return -ENOENT; + + snprintf(ifname, IF_NAMESIZE, "%s", match); + return 0; +} + +int +xsc_get_ifindex_by_ifname(const char *ifname, int *ifindex) +{ + struct ifreq ifr; + int sockfd; + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd == -1) + return -EINVAL; + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1); + if (ioctl(sockfd, SIOCGIFINDEX, &ifr) == -1) { + close(sockfd); + return -EINVAL; + } + + *ifindex = ifr.ifr_ifindex; + + close(sockfd); + return 0; +} + +int +xsc_get_ifindex_by_pci_addr(struct rte_pci_addr *addr, int *ifindex) +{ + char ifname[IF_NAMESIZE]; + int ret; + + ret = xsc_get_ifname_by_pci_addr(addr, ifname); + if (ret) { + PMD_DRV_LOG(ERR, "Could not get ifname by pci address:" PCI_PRI_FMT, + addr->domain, addr->bus, addr->devid, addr->function); + return ret; + } + + ret = xsc_get_ifindex_by_ifname(ifname, ifindex); + if (ret) { + PMD_DRV_LOG(ERR, "Could not get ifindex by ifname:%s", ifname); + return ret; + } + + return 0; +} diff --git a/drivers/net/xsc/xsc_utils.h b/drivers/net/xsc/xsc_utils.h index 0bc318e96a..0d4596489a 100644 --- a/drivers/net/xsc/xsc_utils.h +++ b/drivers/net/xsc/xsc_utils.h @@ -10,5 +10,8 @@ #include struct ibv_device *xsc_get_ibv_device(const struct rte_pci_addr *addr); +int xsc_get_ifname_by_pci_addr(struct rte_pci_addr *addr, char *ifname); +int xsc_get_ifindex_by_ifname(const char *ifname, int *ifindex); +int xsc_get_ifindex_by_pci_addr(struct rte_pci_addr *addr, int *ifindex); #endif /* _XSC_UTILS_H_ */ -- 2.25.1