net/mlx5: add representor recognition on Linux 5.x
[dpdk.git] / drivers / net / mlx5 / mlx5_nl.c
index 8a10109..58bbfed 100644 (file)
 #endif
 
 /* These are normally found in linux/if_link.h. */
+#ifndef HAVE_IFLA_NUM_VF
+#define IFLA_NUM_VF 21
+#endif
+#ifndef HAVE_IFLA_EXT_MASK
+#define IFLA_EXT_MASK 29
+#endif
 #ifndef HAVE_IFLA_PHYS_SWITCH_ID
 #define IFLA_PHYS_SWITCH_ID 36
 #endif
@@ -837,6 +843,7 @@ mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg)
        size_t off = NLMSG_LENGTH(sizeof(struct ifinfomsg));
        bool port_name_set = false;
        bool switch_id_set = false;
+       bool num_vf_set = false;
 
        if (nh->nlmsg_type != RTM_NEWLINK)
                goto error;
@@ -848,6 +855,9 @@ mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg)
                if (ra->rta_len > nh->nlmsg_len - off)
                        goto error;
                switch (ra->rta_type) {
+               case IFLA_NUM_VF:
+                       num_vf_set = true;
+                       break;
                case IFLA_PHYS_PORT_NAME:
                        port_name_set =
                                mlx5_translate_port_name((char *)payload,
@@ -864,8 +874,20 @@ mlx5_nl_switch_info_cb(struct nlmsghdr *nh, void *arg)
                }
                off += RTA_ALIGN(ra->rta_len);
        }
-       info.master = switch_id_set && !port_name_set;
-       info.representor = switch_id_set && port_name_set;
+       if (switch_id_set) {
+               if (info.port_name_new) {
+                       /* New representors naming schema. */
+                       if (port_name_set) {
+                               info.master = (info.port_name == -1);
+                               info.representor = (info.port_name != -1);
+                       }
+               } else {
+                       /* Legacy representors naming schema. */
+                       info.master = (!port_name_set || num_vf_set);
+                       info.representor = port_name_set && !num_vf_set;
+               }
+       }
+       assert(!(info.master && info.representor));
        memcpy(arg, &info, sizeof(info));
        return 0;
 error:
@@ -893,9 +915,13 @@ mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info)
        struct {
                struct nlmsghdr nh;
                struct ifinfomsg info;
+               struct rtattr rta;
+               uint32_t extmask;
        } req = {
                .nh = {
-                       .nlmsg_len = NLMSG_LENGTH(sizeof(req.info)),
+                       .nlmsg_len = NLMSG_LENGTH
+                                       (sizeof(req.info) +
+                                        RTA_LENGTH(sizeof(uint32_t))),
                        .nlmsg_type = RTM_GETLINK,
                        .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK,
                },
@@ -903,11 +929,22 @@ mlx5_nl_switch_info(int nl, unsigned int ifindex, struct mlx5_switch_info *info)
                        .ifi_family = AF_UNSPEC,
                        .ifi_index = ifindex,
                },
+               .rta = {
+                       .rta_type = IFLA_EXT_MASK,
+                       .rta_len = RTA_LENGTH(sizeof(int32_t)),
+               },
+               .extmask = RTE_LE32(1),
        };
        int ret;
 
        ret = mlx5_nl_send(nl, &req.nh, seq);
        if (ret >= 0)
                ret = mlx5_nl_recv(nl, seq, mlx5_nl_switch_info_cb, info);
+       if (info->master && info->representor) {
+               DRV_LOG(ERR, "ifindex %u device is recognized as master"
+                            " and as representor", ifindex);
+               rte_errno = ENODEV;
+               ret = -rte_errno;
+       }
        return ret;
 }