net/dpaa2: fix the ethdev offload checks
[dpdk.git] / drivers / net / mlx5 / mlx5.c
index 99b6223..68783c3 100644 (file)
@@ -13,6 +13,7 @@
 #include <errno.h>
 #include <net/if.h>
 #include <sys/mman.h>
+#include <linux/rtnetlink.h>
 
 /* Verbs header. */
 /* ISO C doesn't support unnamed structs/unions, disabling -pedantic. */
@@ -68,6 +69,9 @@
 /* Device parameter to enable hardware Rx vector. */
 #define MLX5_RX_VEC_EN "rx_vec_en"
 
+/* Activate Netlink support in VF mode. */
+#define MLX5_VF_NL_EN "vf_nl_en"
+
 #ifndef HAVE_IBV_MLX5_MOD_MPW
 #define MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED (1 << 2)
 #define MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW (1 << 3)
@@ -205,6 +209,10 @@ mlx5_dev_close(struct rte_eth_dev *dev)
                rte_free(priv->reta_idx);
        if (priv->primary_socket)
                mlx5_socket_uninit(dev);
+       if (priv->config.vf)
+               mlx5_nl_mac_addr_flush(dev);
+       if (priv->nl_socket >= 0)
+               close(priv->nl_socket);
        ret = mlx5_hrxq_ibv_verify(dev);
        if (ret)
                DRV_LOG(WARNING, "port %u some hash Rx queue still remain",
@@ -407,6 +415,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
                config->tx_vec_en = !!tmp;
        } else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
                config->rx_vec_en = !!tmp;
+       } else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
+               config->vf_nl_en = !!tmp;
        } else {
                DRV_LOG(WARNING, "%s: unknown parameter", key);
                rte_errno = EINVAL;
@@ -438,6 +448,7 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
                MLX5_TXQ_MAX_INLINE_LEN,
                MLX5_TX_VEC_EN,
                MLX5_RX_VEC_EN,
+               MLX5_VF_NL_EN,
                NULL,
        };
        struct rte_kvargs *kvlist;
@@ -477,6 +488,20 @@ static struct rte_pci_driver mlx5_driver;
  */
 static void *uar_base;
 
+static int
+find_lower_va_bound(const struct rte_memseg_list *msl __rte_unused,
+               const struct rte_memseg *ms, void *arg)
+{
+       void **addr = arg;
+
+       if (*addr == NULL)
+               *addr = ms->addr;
+       else
+               *addr = RTE_MIN(*addr, ms->addr);
+
+       return 0;
+}
+
 /**
  * Reserve UAR address space for primary process.
  *
@@ -491,21 +516,14 @@ mlx5_uar_init_primary(struct rte_eth_dev *dev)
 {
        struct priv *priv = dev->data->dev_private;
        void *addr = (void *)0;
-       int i;
-       const struct rte_mem_config *mcfg;
 
        if (uar_base) { /* UAR address space mapped. */
                priv->uar_base = uar_base;
                return 0;
        }
        /* find out lower bound of hugepage segments */
-       mcfg = rte_eal_get_configuration()->mem_config;
-       for (i = 0; i < RTE_MAX_MEMSEG && mcfg->memseg[i].addr; i++) {
-               if (addr)
-                       addr = RTE_MIN(addr, mcfg->memseg[i].addr);
-               else
-                       addr = mcfg->memseg[i].addr;
-       }
+       rte_memseg_walk(find_lower_va_bound, &addr);
+
        /* keep distance to hugepages to minimize potential conflicts. */
        addr = RTE_PTR_SUB(addr, MLX5_UAR_OFFSET + MLX5_UAR_SIZE);
        /* anonymous mmap, no real memory consumption. */
@@ -597,6 +615,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
        int err = 0;
        struct ibv_context *attr_ctx = NULL;
        struct ibv_device_attr_ex device_attr;
+       unsigned int vf;
        unsigned int mps;
        unsigned int cqe_comp;
        unsigned int tunnel_en = 0;
@@ -646,6 +665,14 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        continue;
                DRV_LOG(INFO, "PCI information matches, using device \"%s\"",
                        list[i]->name);
+               vf = ((pci_dev->id.device_id ==
+                      PCI_DEVICE_ID_MELLANOX_CONNECTX4VF) ||
+                     (pci_dev->id.device_id ==
+                      PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF) ||
+                     (pci_dev->id.device_id ==
+                      PCI_DEVICE_ID_MELLANOX_CONNECTX5VF) ||
+                     (pci_dev->id.device_id ==
+                      PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF));
                attr_ctx = mlx5_glue->open_device(list[i]);
                rte_errno = errno;
                err = rte_errno;
@@ -733,6 +760,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                        .txq_inline = MLX5_ARG_UNSET,
                        .txqs_inline = MLX5_ARG_UNSET,
                        .inline_max_packet_sz = MLX5_ARG_UNSET,
+                       .vf_nl_en = 1,
                };
 
                len = snprintf(name, sizeof(name), PCI_PRI_FMT,
@@ -869,6 +897,7 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                DRV_LOG(DEBUG,
                        "hardware Rx end alignment padding is %ssupported",
                        (config.hw_padding ? "" : "not "));
+               config.vf = vf;
                config.tso = ((device_attr_ex.tso_caps.max_tso > 0) &&
                              (device_attr_ex.tso_caps.supported_qpts &
                              (1 << IBV_QPT_RAW_PACKET)));
@@ -946,6 +975,14 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                eth_dev->dev_ops = &mlx5_dev_ops;
                /* Register MAC address. */
                claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
+               priv->nl_socket = -1;
+               priv->nl_sn = 0;
+               if (vf && config.vf_nl_en) {
+                       priv->nl_socket = mlx5_nl_init(RTMGRP_LINK);
+                       if (priv->nl_socket < 0)
+                               priv->nl_socket = -1;
+                       mlx5_nl_mac_addr_sync(eth_dev);
+               }
                TAILQ_INIT(&priv->flows);
                TAILQ_INIT(&priv->ctrl_flows);
                /* Hint libmlx5 to use PMD allocator for data plane resources */
@@ -961,6 +998,12 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
                DRV_LOG(DEBUG, "port %u forcing Ethernet interface up",
                        eth_dev->data->port_id);
                mlx5_set_link_up(eth_dev);
+               /*
+                * Even though the interrupt handler is not installed yet,
+                * interrupts will still trigger on the asyn_fd from
+                * Verbs context returned by ibv_open_device().
+                */
+               mlx5_link_update(eth_dev, 0);
                /* Store device configuration on private structure. */
                priv->config = config;
                continue;