ethdev: fix representor port ID search by name
[dpdk.git] / drivers / net / mlx5 / linux / mlx5_os.c
index 81fbed2..0dcf500 100644 (file)
@@ -786,6 +786,32 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #endif
 }
 
+/**
+ * DR flow drop action support detect.
+ *
+ * @param dev
+ *   Pointer to rte_eth_dev structure.
+ *
+ */
+static void
+mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused)
+{
+#ifdef HAVE_MLX5DV_DR
+       struct mlx5_priv *priv = dev->data->dev_private;
+
+       if (!priv->config.dv_flow_en || !priv->sh->dr_drop_action)
+               return;
+       /**
+        * DR supports drop action placeholder when it is supported;
+        * otherwise, use the queue drop action.
+        */
+       if (mlx5_flow_discover_dr_action_support(dev))
+               priv->root_drop_action = priv->drop_queue.hrxq->action;
+       else
+               priv->root_drop_action = priv->sh->dr_drop_action;
+#endif
+}
+
 static void
 mlx5_queue_counter_id_prepare(struct rte_eth_dev *dev)
 {
@@ -1008,8 +1034,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
                err = mlx5_proc_priv_init(eth_dev);
                if (err)
                        return NULL;
-               mp_id.port_id = eth_dev->data->port_id;
-               strlcpy(mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN);
+               mlx5_mp_id_init(&mp_id, eth_dev->data->port_id);
                /* Receive command fd from primary process */
                err = mlx5_mp_req_verbs_cmd_fd(&mp_id);
                if (err < 0)
@@ -1181,6 +1206,13 @@ err_secondary:
        priv->vport_meta_tag = 0;
        priv->vport_meta_mask = 0;
        priv->pf_bond = spawn->pf_bond;
+
+       DRV_LOG(DEBUG,
+               "dev_port=%u bus=%s pci=%s master=%d representor=%d pf_bond=%d\n",
+               priv->dev_port, dpdk_dev->bus->name,
+               priv->pci_dev ? priv->pci_dev->name : "NONE",
+               priv->master, priv->representor, priv->pf_bond);
+
        /*
         * If we have E-Switch we should determine the vport attributes.
         * E-Switch may use either source vport field or reg_c[0] metadata
@@ -1253,7 +1285,7 @@ err_secondary:
         * Look for sibling devices in order to reuse their switch domain
         * if any, otherwise allocate one.
         */
-       MLX5_ETH_FOREACH_DEV(port_id, NULL) {
+       MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) {
                const struct mlx5_priv *opriv =
                        rte_eth_devices[port_id].data->dev_private;
 
@@ -1263,6 +1295,8 @@ err_secondary:
                        RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID)
                        continue;
                priv->domain_id = opriv->domain_id;
+               DRV_LOG(DEBUG, "dev_port-%u inherit domain_id=%u\n",
+                       priv->dev_port, priv->domain_id);
                break;
        }
        if (priv->domain_id == RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
@@ -1274,10 +1308,12 @@ err_secondary:
                        goto error;
                }
                own_domain_id = 1;
+               DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
+                       priv->dev_port, priv->domain_id);
        }
        /* Override some values set by hardware configuration. */
        mlx5_args(config, dpdk_dev->devargs);
-       err = mlx5_dev_check_sibling_config(priv, config);
+       err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
        if (err)
                goto error;
        config->hw_csum = !!(sh->device_attr.device_cap_flags_ex &
@@ -1640,6 +1676,19 @@ err_secondary:
        if (priv->representor) {
                eth_dev->data->dev_flags |= RTE_ETH_DEV_REPRESENTOR;
                eth_dev->data->representor_id = priv->representor_id;
+               MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) {
+                       struct mlx5_priv *opriv =
+                               rte_eth_devices[port_id].data->dev_private;
+                       if (opriv &&
+                           opriv->master &&
+                           opriv->domain_id == priv->domain_id &&
+                           opriv->sh == priv->sh) {
+                               eth_dev->data->backer_port_id = port_id;
+                               break;
+                       }
+               }
+               if (port_id >= RTE_MAX_ETHPORTS)
+                       eth_dev->data->backer_port_id = eth_dev->data->port_id;
        }
        priv->mp_id.port_id = eth_dev->data->port_id;
        strlcpy(priv->mp_id.name, MLX5_MP_NAME, RTE_MP_MAX_NAME_LEN);
@@ -1665,11 +1714,8 @@ err_secondary:
                goto error;
        }
        DRV_LOG(INFO,
-               "port %u MAC address is %02x:%02x:%02x:%02x:%02x:%02x",
-               eth_dev->data->port_id,
-               mac.addr_bytes[0], mac.addr_bytes[1],
-               mac.addr_bytes[2], mac.addr_bytes[3],
-               mac.addr_bytes[4], mac.addr_bytes[5]);
+               "port %u MAC address is " RTE_ETHER_ADDR_PRT_FMT,
+               eth_dev->data->port_id, RTE_ETHER_ADDR_BYTES(&mac));
 #ifdef RTE_LIBRTE_MLX5_DEBUG
        {
                char ifname[MLX5_NAMESIZE];
@@ -1778,6 +1824,21 @@ err_secondary:
        } else {
                priv->obj_ops = ibv_obj_ops;
        }
+       if (config->tx_pp &&
+           (priv->config.dv_esw_en ||
+            priv->obj_ops.txq_obj_new != mlx5_os_txq_obj_new)) {
+               /*
+                * HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support
+                * packet pacing and already checked above.
+                * Hence, we should only make sure the SQs will be created
+                * with DevX, not with Verbs.
+                * Verbs allocates the SQ UAR on its own and it can't be shared
+                * with Clock Queue UAR as required for Tx scheduling.
+                */
+               DRV_LOG(ERR, "Verbs SQs, UAR can't be shared as required for packet pacing");
+               err = ENODEV;
+               goto error;
+       }
        priv->drop_queue.hrxq = mlx5_drop_action_create(eth_dev);
        if (!priv->drop_queue.hrxq)
                goto error;
@@ -1849,6 +1910,7 @@ err_secondary:
        }
        rte_spinlock_init(&priv->shared_act_sl);
        mlx5_flow_counter_mode_config(eth_dev);
+       mlx5_flow_drop_action_config(eth_dev);
        if (priv->config.dv_flow_en)
                eth_dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
        return eth_dev;
@@ -2083,12 +2145,14 @@ mlx5_os_config_default(struct mlx5_dev_config *config)
        config->txqs_inline = MLX5_ARG_UNSET;
        config->vf_nl_en = 1;
        config->mr_ext_memseg_en = 1;
+       config->mr_mempool_reg_en = 1;
        config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
        config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
        config->dv_esw_en = 1;
        config->dv_flow_en = 1;
        config->decap_en = 1;
        config->log_hp_size = MLX5_ARG_UNSET;
+       config->allow_duplicate_pattern = 1;
 }
 
 /**
@@ -2238,19 +2302,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
                        goto exit;
                }
        }
-#ifndef HAVE_MLX5DV_DR_DEVX_PORT
-       if (bd >= 0) {
-               /*
-                * This may happen if there is VF LAG kernel support and
-                * application is compiled with older rdma_core library.
-                */
-               DRV_LOG(ERR,
-                       "No kernel/verbs support for VF LAG bonding found.");
-               rte_errno = ENOTSUP;
-               ret = -rte_errno;
-               goto exit;
-       }
-#endif
        /*
         * Now we can determine the maximal
         * amount of devices to be spawned.
@@ -2314,10 +2365,18 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
                                                (list[ns].ifindex,
                                                 &list[ns].info);
                        }
-#ifdef HAVE_MLX5DV_DR_DEVX_PORT
                        if (!ret && bd >= 0) {
                                switch (list[ns].info.name_type) {
                                case MLX5_PHYS_PORT_NAME_TYPE_UPLINK:
+                                       if (np == 1) {
+                                               /*
+                                                * Force standalone bonding
+                                                * device for ROCE LAG
+                                                * confgiurations.
+                                                */
+                                               list[ns].info.master = 0;
+                                               list[ns].info.representor = 0;
+                                       }
                                        if (list[ns].info.port_name == bd)
                                                ns++;
                                        break;
@@ -2334,7 +2393,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
                                }
                                continue;
                        }
-#endif
                        if (!ret && (list[ns].info.representor ^
                                     list[ns].info.master))
                                ns++;
@@ -2517,7 +2575,6 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
                /* Default configuration. */
                mlx5_os_config_default(&dev_config);
                dev_config.vf = dev_config_vf;
-               dev_config.allow_duplicate_pattern = 1;
                list[i].numa_node = pci_dev->device.numa_node;
                list[i].eth_dev = mlx5_dev_spawn(&pci_dev->device,
                                                 &list[i],
@@ -2531,6 +2588,31 @@ mlx5_os_pci_probe_pf(struct rte_pci_device *pci_dev,
                }
                restore = list[i].eth_dev->data->dev_flags;
                rte_eth_copy_pci_info(list[i].eth_dev, pci_dev);
+               /**
+                * Each representor has a dedicated interrupts vector.
+                * rte_eth_copy_pci_info() assigns PF interrupts handle to
+                * representor eth_dev object because representor and PF
+                * share the same PCI address.
+                * Override representor device with a dedicated
+                * interrupts handle here.
+                * Representor interrupts handle is released in mlx5_dev_stop().
+                */
+               if (list[i].info.representor) {
+                       struct rte_intr_handle *intr_handle;
+                       intr_handle = mlx5_malloc(MLX5_MEM_SYS | MLX5_MEM_ZERO,
+                                                 sizeof(*intr_handle), 0,
+                                                 SOCKET_ID_ANY);
+                       if (!intr_handle) {
+                               DRV_LOG(ERR,
+                                       "port %u failed to allocate memory for interrupt handler "
+                                       "Rx interrupts will not be supported",
+                                       i);
+                               rte_errno = ENOMEM;
+                               ret = -rte_errno;
+                               goto exit;
+                       }
+                       list[i].eth_dev->intr_handle = intr_handle;
+               }
                /* Restore non-PCI flags cleared by the above call. */
                list[i].eth_dev->data->dev_flags |= restore;
                rte_eth_dev_probing_finish(list[i].eth_dev);
@@ -2628,9 +2710,20 @@ mlx5_os_pci_probe(struct rte_pci_device *pci_dev)
 
        if (eth_da.nb_ports > 0) {
                /* Iterate all port if devargs pf is range: "pf[0-1]vf[...]". */
-               for (p = 0; p < eth_da.nb_ports; p++)
+               for (p = 0; p < eth_da.nb_ports; p++) {
                        ret = mlx5_os_pci_probe_pf(pci_dev, &eth_da,
                                                   eth_da.ports[p]);
+                       if (ret)
+                               break;
+               }
+               if (ret) {
+                       DRV_LOG(ERR, "Probe of PCI device " PCI_PRI_FMT " "
+                               "aborted due to proding failure of PF %u",
+                               pci_dev->addr.domain, pci_dev->addr.bus,
+                               pci_dev->addr.devid, pci_dev->addr.function,
+                               eth_da.ports[p]);
+                       mlx5_net_remove(&pci_dev->device);
+               }
        } else {
                ret = mlx5_os_pci_probe_pf(pci_dev, &eth_da, 0);
        }