[v2,07/19] net/xsc: add representor ports probe

Message ID 20240911020740.3950704-8-wanry@yunsilicon.com (mailing list archive)
State Superseded
Delegated to: Ferruh Yigit
Headers
Series XSC PMD for Yunsilicon NICs |

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

WanRenyong Sept. 11, 2024, 2:07 a.m. UTC
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 <wanry@yunsilicon.com>
Signed-off-by: Na Na <nana@yunsilicon.com>
---
 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(-)
  

Patch

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 <infiniband/verbs.h>
 
+#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 <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
 #include <sys/mman.h>
 
 #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 <ethdev_pci.h>
 
 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_ */