err = mlx5_alloc_table_hash_list(priv);
if (err)
goto error;
+ if (priv->sh->config.dv_flow_en == 2)
+ return 0;
/* The resources below are only valid with DV support. */
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
/* Init port id action list. */
* Verbs device parameters (name, port, switch_info) to spawn.
* @param eth_da
* Device arguments.
+ * @param mkvlist
+ * Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
*
* @return
* A valid Ethernet device object on success, NULL otherwise and rte_errno
static struct rte_eth_dev *
mlx5_dev_spawn(struct rte_device *dpdk_dev,
struct mlx5_dev_spawn_data *spawn,
- struct rte_eth_devargs *eth_da)
+ struct rte_eth_devargs *eth_da,
+ struct mlx5_kvargs_ctrl *mkvlist)
{
const struct mlx5_switch_info *switch_info = &spawn->info;
struct mlx5_dev_ctx_shared *sh = NULL;
DRV_LOG(WARNING, "device name overflow %s", name);
/* check if the device is already spawned */
if (rte_eth_dev_get_port_by_name(name, &port_id) == 0) {
+ /*
+ * When device is already spawned, its devargs should be set
+ * as used. otherwise, mlx5_kvargs_validate() will fail.
+ */
+ if (mkvlist)
+ mlx5_port_args_set_used(name, port_id, mkvlist);
rte_errno = EEXIST;
return NULL;
}
mlx5_dev_close(eth_dev);
return NULL;
}
- sh = mlx5_alloc_shared_dev_ctx(spawn);
+ sh = mlx5_alloc_shared_dev_ctx(spawn, mkvlist);
if (!sh)
return NULL;
nl_rdma = mlx5_nl_init(NETLINK_RDMA);
err = ENOMEM;
goto error;
}
+ /*
+ * When user configures remote PD and CTX and device creates RxQ by
+ * DevX, external RxQ is both supported and requested.
+ */
+ if (mlx5_imported_pd_and_ctx(sh->cdev) && mlx5_devx_obj_ops_en(sh)) {
+ priv->ext_rxqs = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
+ sizeof(struct mlx5_external_rxq) *
+ MLX5_MAX_EXT_RX_QUEUES, 0,
+ SOCKET_ID_ANY);
+ if (priv->ext_rxqs == NULL) {
+ DRV_LOG(ERR, "Fail to allocate external RxQ array.");
+ err = ENOMEM;
+ goto error;
+ }
+ DRV_LOG(DEBUG, "External RxQ is supported.");
+ }
priv->sh = sh;
priv->dev_port = spawn->phys_port;
priv->pci_dev = spawn->pci_dev;
}
if (hca_attr->flow.tunnel_header_0_1)
sh->tunnel_header_0_1 = 1;
+ if (hca_attr->flow.tunnel_header_2_3)
+ sh->tunnel_header_2_3 = 1;
#endif
#ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
if (hca_attr->flow_hit_aso && priv->mtr_color_reg == REG_C_3) {
#endif
}
/* Process parameters and store port configuration on priv structure. */
- err = mlx5_port_args_config(priv, dpdk_dev->devargs, &priv->config);
+ err = mlx5_port_args_config(priv, mkvlist, &priv->config);
if (err) {
err = rte_errno;
DRV_LOG(ERR, "Failed to process port configure: %s",
priv->drop_queue.hrxq = mlx5_drop_action_create(eth_dev);
if (!priv->drop_queue.hrxq)
goto error;
+ priv->hrxqs = mlx5_list_create("hrxq", eth_dev, true,
+ mlx5_hrxq_create_cb,
+ mlx5_hrxq_match_cb,
+ mlx5_hrxq_remove_cb,
+ mlx5_hrxq_clone_cb,
+ mlx5_hrxq_clone_free_cb);
+ if (!priv->hrxqs)
+ goto error;
+ rte_rwlock_init(&priv->ind_tbls_lock);
+ if (priv->sh->config.dv_flow_en == 2)
+ return eth_dev;
/* Port representor shares the same max priority with pf port. */
if (!priv->sh->flow_priority_check_flag) {
/* Supported Verbs flow priority number detection. */
err = ENOTSUP;
goto error;
}
- priv->hrxqs = mlx5_list_create("hrxq", eth_dev, true,
- mlx5_hrxq_create_cb,
- mlx5_hrxq_match_cb,
- mlx5_hrxq_remove_cb,
- mlx5_hrxq_clone_cb,
- mlx5_hrxq_clone_free_cb);
- if (!priv->hrxqs)
- goto error;
- rte_rwlock_init(&priv->ind_tbls_lock);
/* Query availability of metadata reg_c's. */
if (!priv->sh->metadata_regc_check_flag) {
err = mlx5_flow_discover_mreg_c(eth_dev);
mlx5_list_destroy(priv->hrxqs);
if (eth_dev && priv->flex_item_map)
mlx5_flex_item_port_cleanup(eth_dev);
+ mlx5_free(priv->ext_rxqs);
mlx5_free(priv);
if (eth_dev != NULL)
eth_dev->data->dev_private = NULL;
* Requested ethdev device argument.
* @param[in] owner_id
* Requested owner PF port ID within bonding device, default to 0.
+ * @param[in, out] mkvlist
+ * Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
*
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
static int
mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
struct rte_eth_devargs *req_eth_da,
- uint16_t owner_id)
+ uint16_t owner_id, struct mlx5_kvargs_ctrl *mkvlist)
{
struct ibv_device **ibv_list;
/*
for (i = 0; i != ns; ++i) {
uint32_t restore;
- list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], ð_da);
+ list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], ð_da,
+ mkvlist);
if (!list[i].eth_dev) {
if (rte_errno != EBUSY && rte_errno != EEXIST)
break;
*
* @param[in] cdev
* Pointer to common mlx5 device structure.
+ * @param[in, out] mkvlist
+ * Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
*
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
static int
-mlx5_os_pci_probe(struct mlx5_common_device *cdev)
+mlx5_os_pci_probe(struct mlx5_common_device *cdev,
+ struct mlx5_kvargs_ctrl *mkvlist)
{
struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
struct rte_eth_devargs 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++) {
ret = mlx5_os_pci_probe_pf(cdev, ð_da,
- eth_da.ports[p]);
+ eth_da.ports[p], mkvlist);
if (ret)
break;
}
mlx5_net_remove(cdev);
}
} else {
- ret = mlx5_os_pci_probe_pf(cdev, ð_da, 0);
+ ret = mlx5_os_pci_probe_pf(cdev, ð_da, 0, mkvlist);
}
return ret;
}
/* Probe a single SF device on auxiliary bus, no representor support. */
static int
-mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
+mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev,
+ struct mlx5_kvargs_ctrl *mkvlist)
{
struct rte_eth_devargs eth_da = { .nb_ports = 0 };
struct mlx5_dev_spawn_data spawn = { .pf_bond = -1 };
spawn.ifindex = ret;
spawn.cdev = cdev;
/* Spawn device. */
- eth_dev = mlx5_dev_spawn(dev, &spawn, ð_da);
+ eth_dev = mlx5_dev_spawn(dev, &spawn, ð_da, mkvlist);
if (eth_dev == NULL)
return -rte_errno;
/* Post create. */
*
* @param[in] cdev
* Pointer to the common mlx5 device.
+ * @param[in, out] mkvlist
+ * Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
*
* @return
* 0 on success, a negative errno value otherwise and rte_errno is set.
*/
int
-mlx5_os_net_probe(struct mlx5_common_device *cdev)
+mlx5_os_net_probe(struct mlx5_common_device *cdev,
+ struct mlx5_kvargs_ctrl *mkvlist)
{
int ret;
strerror(rte_errno));
return -rte_errno;
}
- ret = mlx5_probe_again_args_validate(cdev);
+ ret = mlx5_probe_again_args_validate(cdev, mkvlist);
if (ret) {
DRV_LOG(ERR, "Probe again parameters are not compatible : %s",
strerror(rte_errno));
return -rte_errno;
}
if (mlx5_dev_is_pci(cdev->dev))
- return mlx5_os_pci_probe(cdev);
+ return mlx5_os_pci_probe(cdev, mkvlist);
else
- return mlx5_os_auxiliary_probe(cdev);
+ return mlx5_os_auxiliary_probe(cdev, mkvlist);
}
/**