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 <wa...@yunsilicon.com>
Signed-off-by: Na Na <n...@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(-)

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_ */
-- 
2.25.1

Reply via email to