DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 00/20] mlx5: refactor devargs management
@ 2022-01-27 15:39 Michael Baum
  2022-01-27 15:39 ` [PATCH 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
                   ` (20 more replies)
  0 siblings, 21 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

These patches rearrange the management of the devargs on two different
levels.

The first splits the net driver's devargs into two categories,
device-dependent devargs and port-dependent devargs.
Arguments that depend on the device are updated once in the creation of
the shared device context structure, and do not change even if the user
has sent new devargs in the probe again. In contrast, the arguments that
depend on the port are updated separately for each port.

The second layer deals with the parsing of devargs in the common driver.
The common driver once parses the devargs into a dictionary, then sends
it to all the drivers that will use it during the their probing. Each
driver updates within dictionary which keys it has used, then the common
driver checks the updated dictionary and reports about unknown devargs.

Michael Baum (20):
  net/mlx5: fix wrong check sibling device config mismatch
  net/mlx5: fix ineffective metadata argument adjustment
  net/mlx5: fix wrong place of ASO CT object release
  net/mlx5: fix inconsistency errno update in SH creation
  net/mlx5: remove declaration duplications
  net/mlx5: remove checking devargs duplication
  net/mlx5: remove HCA attr structure duplication
  net/mlx5: remove DevX flag duplication
  net/mlx5: remove Verbs query device duplication
  common/mlx5: share VF checking function
  net/mlx5: share realtime timestamp configure
  net/mlx5: share counter config function
  net/mlx5: add E-switch mode flag
  net/mlx5: rearrange device attribute structure
  net/mlx5: concentrate all device configurations
  net/mlx5: add share device context config structure
  net/mlx5: using function to detect operation by DevX
  net/mlx5: separate per port configuration
  common/mlx5: add check for common devargs in probing again
  common/mlx5: refactor devargs management

 drivers/common/mlx5/mlx5_common.c       | 345 +++++++--
 drivers/common/mlx5/mlx5_common.h       |  51 +-
 drivers/common/mlx5/mlx5_common_pci.c   |  18 +
 drivers/common/mlx5/version.map         |   3 +
 drivers/compress/mlx5/mlx5_compress.c   |  38 +-
 drivers/crypto/mlx5/mlx5_crypto.c       |  39 +-
 drivers/net/mlx5/linux/mlx5_flow_os.c   |   3 +-
 drivers/net/mlx5/linux/mlx5_os.c        | 885 +++++++++---------------
 drivers/net/mlx5/linux/mlx5_verbs.c     |   9 +-
 drivers/net/mlx5/linux/mlx5_vlan_os.c   |   3 +-
 drivers/net/mlx5/mlx5.c                 | 872 +++++++++++++++++------
 drivers/net/mlx5/mlx5.h                 | 216 +++---
 drivers/net/mlx5/mlx5_devx.c            |  19 +-
 drivers/net/mlx5/mlx5_ethdev.c          |  31 +-
 drivers/net/mlx5/mlx5_flow.c            |  50 +-
 drivers/net/mlx5/mlx5_flow.h            |   2 +-
 drivers/net/mlx5/mlx5_flow_dv.c         |  93 ++-
 drivers/net/mlx5/mlx5_flow_flex.c       |   4 +-
 drivers/net/mlx5/mlx5_flow_meter.c      |  14 +-
 drivers/net/mlx5/mlx5_rxmode.c          |   8 +-
 drivers/net/mlx5/mlx5_rxq.c             |  49 +-
 drivers/net/mlx5/mlx5_trigger.c         |  35 +-
 drivers/net/mlx5/mlx5_tx.c              |   2 +-
 drivers/net/mlx5/mlx5_txpp.c            |  14 +-
 drivers/net/mlx5/mlx5_txq.c             |  62 +-
 drivers/net/mlx5/mlx5_vlan.c            |   4 +-
 drivers/net/mlx5/windows/mlx5_flow_os.c |   2 +-
 drivers/net/mlx5/windows/mlx5_os.c      | 342 +++------
 drivers/regex/mlx5/mlx5_regex.c         |   3 +-
 drivers/vdpa/mlx5/mlx5_vdpa.c           |  32 +-
 30 files changed, 1841 insertions(+), 1407 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 01/20] net/mlx5: fix wrong check sibling device config mismatch
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
                   ` (19 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The MLX5 net driver supports "probe again". In probing again, it
creates a new ethdev under an existing infiniband device context.

Sibling devices sharing infiniband device context should have compatible
configurations, so some of the devargs given in the probe again, the
ones that are mainly relevant to the sharing device context are sent to
the mlx5_dev_check_sibling_config function which makes sure that they
compatible its siblings.
However, the arguments are adjusted according to the capability of the
device, and the function compares the arguments of the probe again
before the adjustment with the arguments of the siblings after the
adjustment. A user who sends the same values to all siblings may fail in
this comparison if he requested something that the device does not
support and adjusted.

This patch moves the call to the mlx5_dev_check_sibling_config function
after the relevant adjustments.

Fixes: 92d5dd483450 ("net/mlx5: check sibling device configurations mismatch")
Fixes: 2d241515ebaf ("net/mlx5: add devarg for extensive metadata support")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 41 ++++++++++++++++--------------
 drivers/net/mlx5/windows/mlx5_os.c | 28 ++++++++++++--------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index aecdc5a68a..de0bb87460 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1241,6 +1241,28 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
+	/* Update final values for devargs before check sibling config. */
+#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
+	if (config->dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	      (switch_info->representor || switch_info->master)))
+		config->dv_esw_en = 0;
+#else
+	config->dv_esw_en = 0;
+#endif
+	if (!priv->config.dv_esw_en &&
+	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			priv->config.dv_xmeta_en);
+		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
 	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
 	if (err)
 		goto error;
@@ -1251,12 +1273,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
 	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
 	DRV_LOG(DEBUG, "counters are not supported");
-#endif
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported");
-		config->dv_flow_en = 0;
-	}
 #endif
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
@@ -1652,13 +1668,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(config->hca_attr.eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
-		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
 	/* Detect minimal data bytes to inline. */
 	mlx5_set_min_inline(spawn, config);
 	/* Store device configuration on private structure. */
@@ -1725,12 +1734,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		err = -err;
 		goto error;
 	}
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING, "metadata mode %u is not supported "
-				 "(no E-Switch)", priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
 	mlx5_set_metadata_mask(eth_dev);
 	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index ac0af0ff7d..8eb53f2cb7 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -439,6 +439,21 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
+	/* Update final values for devargs before check sibling config. */
+	config->dv_esw_en = 0;
+	if (!config->dv_flow_en) {
+		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
+		err = ENOTSUP;
+		goto error;
+	}
+	if (!priv->config.dv_esw_en &&
+	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			priv->config.dv_xmeta_en);
+		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
 	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
 	if (err)
 		goto error;
@@ -600,7 +615,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	config->dv_esw_en = 0;
 	/* Detect minimal data bytes to inline. */
 	mlx5_set_min_inline(spawn, config);
 	/* Store device configuration on private structure. */
@@ -622,12 +636,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* No supported flow priority number detection. */
 	priv->sh->flow_max_priority = -1;
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING, "metadata mode %u is not supported "
-				 "(no E-Switch)", priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
 	mlx5_set_metadata_mask(eth_dev);
 	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
@@ -661,12 +669,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			goto error;
 		}
 	}
-	if (sh->devx && config->dv_flow_en) {
+	if (sh->devx) {
 		priv->obj_ops = devx_obj_ops;
 	} else {
-		DRV_LOG(ERR, "Flow mode %u is not supported "
-				"(Windows flow must be DevX with DV flow enabled).",
-				priv->config.dv_flow_en);
+		DRV_LOG(ERR, "Windows flow must be DevX.");
 		err = ENOTSUP;
 		goto error;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 02/20] net/mlx5: fix ineffective metadata argument adjustment
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
  2022-01-27 15:39 ` [PATCH 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
                   ` (18 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

In "dv_xmeta_en" devarg there is an option of dv_xmeta_en=3 which
engages tunnel offload mode. In E-Switch configuration, that mode
implicitly activates dv_xmeta_en=1.

The update according to E-switch support is done immediately after the
first parsing of the devargs, but there is another adjustment later.

This patch moves the adjustment after the second parsing.

Fixes: 4ec6360de37d ("net/mlx5: implement tunnel offload")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index de0bb87460..e45e56f4b6 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -977,10 +977,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		goto error;
 	}
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
@@ -1242,6 +1238,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
 	/* Update final values for devargs before check sibling config. */
+	if (config->dv_miss_info) {
+		if (switch_info->master || switch_info->representor)
+			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	}
 #if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
 	if (config->dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 03/20] net/mlx5: fix wrong place of ASO CT object release
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
  2022-01-27 15:39 ` [PATCH 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
  2022-01-27 15:39 ` [PATCH 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
                   ` (17 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The ASO connection tracking structure is initialized once for sharing
device context.

Its release takes place in the close function which is called for each
ethdev individually. i.e. when there is more than one ethdev under the
same sharing device context, it will be destroyed when one of them is
closed. If the other wants to use it later, it may cause it to crash.

In addition, the creation of this structure is performed in the spawn
function. if one of the creations of the objects following it fails, it
is supposed to be destroyed but this does not happen.

This patch moves its release to the sharing device context free function
and thus solves both problems.

Fixes: 0af8a2298a42 ("net/mlx5: release connection tracking management")
Fixes: ee9e5fad03eb ("net/mlx5: initialize connection tracking management")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/mlx5.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 67eda41a60..d1d398f49a 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1321,6 +1321,8 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)
 	 *  Only primary process handles async device events.
 	 **/
 	mlx5_flow_counters_mng_close(sh);
+	if (sh->ct_mng)
+		mlx5_flow_aso_ct_mng_close(sh);
 	if (sh->aso_age_mng) {
 		mlx5_flow_aso_age_mng_close(sh);
 		sh->aso_age_mng = NULL;
@@ -1594,8 +1596,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 	if (priv->mreg_cp_tbl)
 		mlx5_hlist_destroy(priv->mreg_cp_tbl);
 	mlx5_mprq_free_mp(dev);
-	if (priv->sh->ct_mng)
-		mlx5_flow_aso_ct_mng_close(priv->sh);
 	mlx5_os_free_shared_dr(priv);
 	if (priv->rss_conf.rss_key != NULL)
 		mlx5_free(priv->rss_conf.rss_key);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 04/20] net/mlx5: fix inconsistency errno update in SH creation
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (2 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 05/20] net/mlx5: remove declaration duplications Michael Baum
                   ` (16 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The mlx5_alloc_shared_dev_ctx() function has a local variable named
"err" which contains the errno value in case of failure.

When functions called by this function are failed, this variable is
updated with their return value (that should be a positive errno value).
However, some functions doesn't update errno value by themselves or
return negative errno value. If one of them fails, the "err" variable
contains negative value what cause to assertion failure.

This patch updates all functions uses by mlx5_alloc_shared_dev_ctx()
function to update rte_errno and take this value instead of "err" value.

Fixes: 5dfa003db53f ("common/mlx5: fix post doorbell barrier")
Fixes: 5d55a494f4e6 ("net/mlx5: split multi-thread flow handling per OS")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_flow_os.c   |  3 ++-
 drivers/net/mlx5/linux/mlx5_os.c        | 16 ++++++++++------
 drivers/net/mlx5/mlx5.c                 | 24 +++++++++++-------------
 drivers/net/mlx5/windows/mlx5_flow_os.c |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c      | 24 ++++++++++++------------
 5 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_flow_os.c b/drivers/net/mlx5/linux/mlx5_flow_os.c
index 893f00b824..a5956c255a 100644
--- a/drivers/net/mlx5/linux/mlx5_flow_os.c
+++ b/drivers/net/mlx5/linux/mlx5_flow_os.c
@@ -14,7 +14,8 @@ mlx5_flow_os_init_workspace_once(void)
 {
 	if (rte_thread_key_create(&key_workspace, flow_release_workspace)) {
 		DRV_LOG(ERR, "Can't create flow workspace data thread key.");
-		return -ENOMEM;
+		rte_errno = ENOMEM;
+		return -rte_errno;
 	}
 	return 0;
 }
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index e45e56f4b6..f587a47f6e 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -138,7 +138,7 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Pointer to mlx5 device attributes.
  *
  * @return
- *   0 on success, non zero error number otherwise
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
 mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
@@ -150,8 +150,10 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 
 	memset(device_attr, 0, sizeof(*device_attr));
 	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
-	if (err)
-		return err;
+	if (err) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	device_attr->device_cap_flags_ex = attr_ex.device_cap_flags_ex;
 	device_attr->max_qp_wr = attr_ex.orig_attr.max_qp_wr;
 	device_attr->max_sge = attr_ex.orig_attr.max_sge;
@@ -170,8 +172,10 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
-	if (err)
-		return err;
+	if (err) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 
 	device_attr->flags = dv_attr.flags;
 	device_attr->comp_mask = dv_attr.comp_mask;
@@ -195,7 +199,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	strlcpy(device_attr->fw_ver, attr_ex.orig_attr.fw_ver,
 		sizeof(device_attr->fw_ver));
 
-	return err;
+	return 0;
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index d1d398f49a..25d4d2082b 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1172,12 +1172,11 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	MLX5_ASSERT(spawn->max_port);
 	sh = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			 sizeof(struct mlx5_dev_ctx_shared) +
-			 spawn->max_port *
-			 sizeof(struct mlx5_dev_shared_port),
+			 spawn->max_port * sizeof(struct mlx5_dev_shared_port),
 			 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
 	if (!sh) {
-		DRV_LOG(ERR, "shared context allocation failure");
-		rte_errno  = ENOMEM;
+		DRV_LOG(ERR, "Shared context allocation failure.");
+		rte_errno = ENOMEM;
 		goto exit;
 	}
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
@@ -1199,9 +1198,8 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	strncpy(sh->ibdev_path, mlx5_os_get_ctx_device_path(sh->cdev->ctx),
 		sizeof(sh->ibdev_path) - 1);
 	/*
-	 * Setting port_id to max unallowed value means
-	 * there is no interrupt subhandler installed for
-	 * the given port index i.
+	 * Setting port_id to max unallowed value means there is no interrupt
+	 * subhandler installed for the given port index i.
 	 */
 	for (i = 0; i < sh->max_port; i++) {
 		sh->port[i].ih_port_id = RTE_MAX_ETHPORTS;
@@ -1211,12 +1209,12 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		sh->td = mlx5_devx_cmd_create_td(sh->cdev->ctx);
 		if (!sh->td) {
 			DRV_LOG(ERR, "TD allocation failure");
-			err = ENOMEM;
+			rte_errno = ENOMEM;
 			goto error;
 		}
 		if (mlx5_setup_tis(sh)) {
 			DRV_LOG(ERR, "TIS allocation failure");
-			err = ENOMEM;
+			rte_errno = ENOMEM;
 			goto error;
 		}
 		err = mlx5_rxtx_uars_prepare(sh);
@@ -1246,19 +1244,19 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
 	return sh;
 error:
+	err = rte_errno;
 	pthread_mutex_destroy(&sh->txpp.mutex);
 	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
 	MLX5_ASSERT(sh);
-	if (sh->td)
-		claim_zero(mlx5_devx_cmd_destroy(sh->td));
+	mlx5_rxtx_uars_release(sh);
 	i = 0;
 	do {
 		if (sh->tis[i])
 			claim_zero(mlx5_devx_cmd_destroy(sh->tis[i]));
 	} while (++i < (uint32_t)sh->bond.n_port);
-	mlx5_rxtx_uars_release(sh);
+	if (sh->td)
+		claim_zero(mlx5_devx_cmd_destroy(sh->td));
 	mlx5_free(sh);
-	MLX5_ASSERT(err > 0);
 	rte_errno = err;
 	return NULL;
 }
diff --git a/drivers/net/mlx5/windows/mlx5_flow_os.c b/drivers/net/mlx5/windows/mlx5_flow_os.c
index 7bb4c4590a..f5e3893ed4 100644
--- a/drivers/net/mlx5/windows/mlx5_flow_os.c
+++ b/drivers/net/mlx5/windows/mlx5_flow_os.c
@@ -372,7 +372,7 @@ mlx5_flow_os_init_workspace_once(void)
 
 	if (err) {
 		DRV_LOG(ERR, "Can't create flow workspace data thread key.");
-		return err;
+		return -rte_errno;
 	}
 	pthread_mutex_init(&lock_thread_list, NULL);
 	return 0;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 8eb53f2cb7..d31de6a5e8 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -152,7 +152,7 @@ mlx5_init_once(void)
  *   Pointer to mlx5 device attributes.
  *
  * @return
- *   0 on success, non zero error number otherwise.
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
 mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
@@ -161,10 +161,11 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	struct mlx5_context *mlx5_ctx;
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
-	int err = 0;
 
-	if (!cdev || !cdev->ctx)
-		return -EINVAL;
+	if (!cdev || !cdev->ctx) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
 	mlx5_ctx = (struct mlx5_context *)cdev->ctx;
 	memset(device_attr, 0, sizeof(*device_attr));
 	device_attr->max_cq = 1 << cdev->config.hca_attr.log_max_cq;
@@ -187,15 +188,14 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
 		DRV_LOG(ERR, "Failed to get device hca_iseg");
-		return errno;
-	}
-	if (!err) {
-		snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+		rte_errno = errno;
+		return -rte_errno;
 	}
-	return err;
+	snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+	return 0;
 }
 
 /**
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 05/20] net/mlx5: remove declaration duplications
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (3 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 06/20] net/mlx5: remove checking devargs duplication Michael Baum
                   ` (15 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

In mlx5_ethdev.c file are implemented those 4 functions:
 - mlx5_dev_infos_get
 - mlx5_fw_version_get
 - mlx5_dev_set_mtu
 - mlx5_hairpin_cap_get

In mlx5.h file they are declared twice. First time under mlx5.c file and
second time under mlx5_ethdev.c file.

This patch removes the redundant declaration.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/mlx5.h | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 737ad6895c..823a943978 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1532,11 +1532,6 @@ void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
 int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
 				  struct mlx5_dev_config *config,
 				  struct rte_device *dpdk_dev);
-int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
-int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
-int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
-			 struct rte_eth_hairpin_cap *cap);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 int mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh);
@@ -1556,10 +1551,8 @@ int mlx5_representor_info_get(struct rte_eth_dev *dev,
 		(((repr_id) >> 12) & 3)
 uint16_t mlx5_representor_id_encode(const struct mlx5_switch_info *info,
 				    enum rte_eth_representor_type hpf_type);
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver,
-			size_t fw_size);
-int mlx5_dev_infos_get(struct rte_eth_dev *dev,
-		       struct rte_eth_dev_info *info);
+int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
+int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
 const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 06/20] net/mlx5: remove checking devargs duplication
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (4 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 05/20] net/mlx5: remove declaration duplications Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
                   ` (14 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The device arguments are parsed and updated twice during spawning. First
time before creating the share device context, and again later after
updating a default value to one of the arguments.

This patch consolidates them into one parsing and updates the default
values before it.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 73 +++++++++++++-----------------
 drivers/net/mlx5/mlx5.c            | 23 +++++-----
 drivers/net/mlx5/mlx5.h            |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c | 49 ++++++++------------
 4 files changed, 65 insertions(+), 82 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index f587a47f6e..11d15d0aef 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -968,22 +968,45 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mlx5_dev_close(eth_dev);
 		return NULL;
 	}
-	/*
-	 * Some parameters ("tx_db_nc" in particularly) are needed in
-	 * advance to create dv/verbs device context. We proceed the
-	 * devargs here to get ones, and later proceed devargs again
-	 * to override some hardware settings.
-	 */
+	/* Process parameters. */
 	err = mlx5_args(config, dpdk_dev->devargs);
 	if (err) {
-		err = rte_errno;
 		DRV_LOG(ERR, "failed to process device arguments: %s",
 			strerror(rte_errno));
-		goto error;
+		return NULL;
 	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
+	/* Update final values for devargs before check sibling config. */
+	if (config->dv_miss_info) {
+		if (switch_info->master || switch_info->representor)
+			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	}
+#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
+	if (config->dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	      (switch_info->representor || switch_info->master)))
+		config->dv_esw_en = 0;
+#else
+	config->dv_esw_en = 0;
+#endif
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
+	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
+	if (err)
+		goto error;
 #ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
 	config->dest_tir = 1;
 #endif
@@ -1049,8 +1072,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			mprq_caps.max_single_wqe_log_num_of_strides;
 	}
 #endif
-	/* Rx CQE compression is enabled by default. */
-	config->cqe_comp = 1;
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
 	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
 		config->tunnel_en = dv_attr.tunnel_offloads_caps &
@@ -1239,37 +1260,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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);
-	/* Update final values for devargs before check sibling config. */
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported.");
-		config->dv_flow_en = 0;
-	}
-#endif
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
-		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
-	if (err)
-		goto error;
 	config->hw_csum = !!(sh->device_attr.device_cap_flags_ex &
 			    IBV_DEVICE_RAW_IP_CSUM);
 	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
@@ -2049,6 +2039,7 @@ mlx5_os_config_default(struct mlx5_dev_config *config,
 {
 	memset(config, 0, sizeof(*config));
 	config->mps = MLX5_ARG_UNSET;
+	config->cqe_comp = 1;
 	config->rx_vec_en = 1;
 	config->txq_inline_max = MLX5_ARG_UNSET;
 	config->txq_inline_min = MLX5_ARG_UNSET;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 25d4d2082b..60167450e4 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2216,25 +2216,26 @@ rte_pmd_mlx5_get_dyn_flag_names(char *names[], unsigned int n)
 }
 
 /**
- * Comparison callback to sort device data.
+ * Check sibling device configurations.
  *
- * This is meant to be used with qsort().
+ * Sibling devices sharing the Infiniband device context should have compatible
+ * configurations. This regards representors and bonding device.
  *
- * @param a[in]
- *   Pointer to pointer to first data object.
- * @param b[in]
- *   Pointer to pointer to second data object.
+ * @param sh
+ *   Shared device context.
+ * @param config
+ *   Configuration of the device is going to be created.
+ * @param dpdk_dev
+ *   Backing DPDK device.
  *
  * @return
- *   0 if both objects are equal, less than 0 if the first argument is less
- *   than the second, greater than 0 otherwise.
+ *   0 on success, EINVAL otherwise
  */
 int
-mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
+mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_dev_config *config,
 			      struct rte_device *dpdk_dev)
 {
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	struct mlx5_dev_config *sh_conf = NULL;
 	uint16_t port_id;
 
@@ -2247,7 +2248,7 @@ mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
 		struct mlx5_priv *opriv =
 			rte_eth_devices[port_id].data->dev_private;
 
-		if (opriv && opriv != priv && opriv->sh == sh) {
+		if (opriv && opriv->sh == sh) {
 			sh_conf = &opriv->config;
 			break;
 		}
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 823a943978..e4b2523eb0 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1529,7 +1529,7 @@ int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			 struct mlx5_dev_config *config);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
+int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 				  struct mlx5_dev_config *config,
 				  struct rte_device *dpdk_dev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index d31de6a5e8..c1f8bc9ee3 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -321,7 +321,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
-	unsigned int cqe_comp;
 	struct rte_ether_addr mac;
 	char name[RTE_ETH_NAME_MAX_LEN];
 	int own_domain_id = 0;
@@ -336,11 +335,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	/*
-	 * Some parameters are needed in advance to create device context. We
-	 * process the devargs here to get ones, and later process devargs
-	 * again to override some hardware settings.
-	 */
+	/* Process parameters. */
 	err = mlx5_args(config, dpdk_dev->devargs);
 	if (err) {
 		err = rte_errno;
@@ -351,6 +346,24 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
+	/* Update final values for devargs before check sibling config. */
+	config->dv_esw_en = 0;
+	if (!config->dv_flow_en) {
+		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
+		err = ENOTSUP;
+		goto error;
+	}
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
+	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
+	if (err)
+		goto error;
 	/* Initialize the shutdown event in mlx5_dev_spawn to
 	 * support mlx5_is_removed for Windows.
 	 */
@@ -367,8 +380,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
-	cqe_comp = 0;
-	config->cqe_comp = cqe_comp;
 	config->tunnel_en = device_attr.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
@@ -437,26 +448,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	/* Override some values set by hardware configuration. */
-	mlx5_args(config, dpdk_dev->devargs);
-	/* Update final values for devargs before check sibling config. */
-	config->dv_esw_en = 0;
-	if (!config->dv_flow_en) {
-		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
-		err = ENOTSUP;
-		goto error;
-	}
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
-	if (err)
-		goto error;
 	DRV_LOG(DEBUG, "counters are not supported");
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
@@ -479,7 +470,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (config->cqe_comp && !cqe_comp) {
+	if (config->cqe_comp) {
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 07/20] net/mlx5: remove HCA attr structure duplication
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (5 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 06/20] net/mlx5: remove checking devargs duplication Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 08/20] net/mlx5: remove DevX flag duplication Michael Baum
                   ` (13 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The HCA attribute structure is field of net configure structure.
It is also field of common configure structure.

There is no need for this duplication, because there is a reference to
the common structure from within the net structures.

This patch removes it from net configure structure and uses the common
config structure instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 95 ++++++++++++++----------------
 drivers/net/mlx5/mlx5.c            | 14 +++--
 drivers/net/mlx5/mlx5.h            |  1 -
 drivers/net/mlx5/mlx5_devx.c       |  8 ++-
 drivers/net/mlx5/mlx5_ethdev.c     |  2 +-
 drivers/net/mlx5/mlx5_flow.c       | 16 ++---
 drivers/net/mlx5/mlx5_flow_dv.c    | 13 ++--
 drivers/net/mlx5/mlx5_flow_flex.c  |  4 +-
 drivers/net/mlx5/mlx5_flow_meter.c |  4 +-
 drivers/net/mlx5/mlx5_rxq.c        |  4 +-
 drivers/net/mlx5/mlx5_trigger.c    | 12 ++--
 drivers/net/mlx5/mlx5_txpp.c       |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c | 25 ++++----
 13 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 11d15d0aef..39ca145e4a 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -675,6 +675,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	bool fallback;
 
 #ifndef HAVE_IBV_DEVX_ASYNC
@@ -682,16 +683,16 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #else
 	fallback = false;
 	if (!sh->devx || !priv->config.dv_flow_en ||
-	    !priv->config.hca_attr.flow_counters_dump ||
-	    !(priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
 		fallback = true;
 #endif
 	if (fallback)
 		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
 			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			priv->config.hca_attr.flow_counters_dump,
-			priv->config.hca_attr.flow_counter_bulk_alloc_bitmap);
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
 	/* Initialize fallback mode only on the port initializes sh. */
 	if (sh->refcnt == 1)
 		sh->cmng.counter_fallback = fallback;
@@ -875,6 +876,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
+	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	struct rte_eth_dev *eth_dev = NULL;
@@ -990,7 +992,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 #endif
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	if (!(hca_attr->eswitch_manager && config->dv_flow_en &&
 	      (switch_info->representor || switch_info->master)))
 		config->dv_esw_en = 0;
 #else
@@ -1315,14 +1317,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->devx) {
-		config->hca_attr = sh->cdev->config.hca_attr;
-		sh->steering_format_version =
-			config->hca_attr.steering_format_version;
+		sh->steering_format_version = hca_attr->steering_format_version;
 		/* Check for LRO support. */
-		if (config->dest_tir && config->hca_attr.lro_cap &&
+		if (config->dest_tir && hca_attr->lro_cap &&
 		    config->dv_flow_en) {
 			/* TBD check tunnel lro caps. */
-			config->lro.supported = config->hca_attr.lro_cap;
+			config->lro.supported = hca_attr->lro_cap;
 			DRV_LOG(DEBUG, "Device supports LRO");
 			/*
 			 * If LRO timeout is not configured by application,
@@ -1330,21 +1330,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			 */
 			if (!config->lro.timeout)
 				config->lro.timeout =
-				config->hca_attr.lro_timer_supported_periods[0];
+				       hca_attr->lro_timer_supported_periods[0];
 			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
 				config->lro.timeout);
 			DRV_LOG(DEBUG, "LRO minimal size of TCP segment "
 				"required for coalescing is %d bytes",
-				config->hca_attr.lro_min_mss_size);
+				hca_attr->lro_min_mss_size);
 		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
-		if (config->hca_attr.qos.sup &&
-		    config->hca_attr.qos.flow_meter_old &&
+		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_old &&
 		    config->dv_flow_en) {
-			uint8_t reg_c_mask =
-				config->hca_attr.qos.flow_meter_reg_c_ids;
+			uint8_t reg_c_mask = hca_attr->qos.flow_meter_reg_c_ids;
 			/*
 			 * Meter needs two REG_C's for color match and pre-sfx
 			 * flow match. Here get the REG_C for color match.
@@ -1368,20 +1366,18 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 					priv->mtr_color_reg = ffs(reg_c_mask)
 							      - 1 + REG_C_0;
 				priv->mtr_en = 1;
-				priv->mtr_reg_share =
-				      config->hca_attr.qos.flow_meter;
+				priv->mtr_reg_share = hca_attr->qos.flow_meter;
 				DRV_LOG(DEBUG, "The REG_C meter uses is %d",
 					priv->mtr_color_reg);
 			}
 		}
-		if (config->hca_attr.qos.sup &&
-			config->hca_attr.qos.flow_meter_aso_sup) {
+		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_aso_sup) {
 			uint32_t log_obj_size =
 				rte_log2_u32(MLX5_ASO_MTRS_PER_POOL >> 1);
 			if (log_obj_size >=
-			config->hca_attr.qos.log_meter_aso_granularity &&
-			log_obj_size <=
-			config->hca_attr.qos.log_meter_aso_max_alloc)
+			    hca_attr->qos.log_meter_aso_granularity &&
+			    log_obj_size <=
+			    hca_attr->qos.log_meter_aso_max_alloc)
 				sh->meter_aso_en = 1;
 		}
 		if (priv->mtr_en) {
@@ -1391,12 +1387,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				goto error;
 			}
 		}
-		if (config->hca_attr.flow.tunnel_header_0_1)
+		if (hca_attr->flow.tunnel_header_0_1)
 			sh->tunnel_header_0_1 = 1;
 #endif
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
-		if (config->hca_attr.flow_hit_aso &&
-		    priv->mtr_color_reg == REG_C_3) {
+		if (hca_attr->flow_hit_aso && priv->mtr_color_reg == REG_C_3) {
 			sh->flow_hit_aso_en = 1;
 			err = mlx5_flow_aso_age_mng_init(sh);
 			if (err) {
@@ -1408,8 +1403,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO */
 #if defined(HAVE_MLX5_DR_CREATE_ACTION_ASO) && \
 	defined(HAVE_MLX5_DR_ACTION_ASO_CT)
-		if (config->hca_attr.ct_offload &&
-		    priv->mtr_color_reg == REG_C_3) {
+		if (hca_attr->ct_offload && priv->mtr_color_reg == REG_C_3) {
 			err = mlx5_flow_aso_ct_mng_init(sh);
 			if (err) {
 				err = -err;
@@ -1420,13 +1414,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO && HAVE_MLX5_DR_ACTION_ASO_CT */
 #if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_SAMPLE)
-		if (config->hca_attr.log_max_ft_sampler_num > 0  &&
+		if (hca_attr->log_max_ft_sampler_num > 0  &&
 		    config->dv_flow_en) {
 			priv->sampler_en = 1;
 			DRV_LOG(DEBUG, "Sampler enabled!");
 		} else {
 			priv->sampler_en = 0;
-			if (!config->hca_attr.log_max_ft_sampler_num)
+			if (!hca_attr->log_max_ft_sampler_num)
 				DRV_LOG(WARNING,
 					"No available register for sampler.");
 			else
@@ -1440,13 +1434,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->devx || !config->hca_attr.mini_cqe_resp_flow_tag)) {
+	    (!sh->devx || !hca_attr->mini_cqe_resp_flow_tag)) {
 		DRV_LOG(WARNING, "Flow Tag CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->devx || !config->hca_attr.mini_cqe_resp_l3_l4_tag)) {
+	    (!sh->devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
 		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
@@ -1455,55 +1449,55 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			config->cqe_comp ? "" : "not ");
 	if (config->tx_pp) {
 		DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz",
-			config->hca_attr.dev_freq_khz);
+			hca_attr->dev_freq_khz);
 		DRV_LOG(DEBUG, "Packet pacing is %ssupported",
-			config->hca_attr.qos.packet_pacing ? "" : "not ");
+			hca_attr->qos.packet_pacing ? "" : "not ");
 		DRV_LOG(DEBUG, "Cross channel ops are %ssupported",
-			config->hca_attr.cross_channel ? "" : "not ");
+			hca_attr->cross_channel ? "" : "not ");
 		DRV_LOG(DEBUG, "WQE index ignore is %ssupported",
-			config->hca_attr.wqe_index_ignore ? "" : "not ");
+			hca_attr->wqe_index_ignore ? "" : "not ");
 		DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported",
-			config->hca_attr.non_wire_sq ? "" : "not ");
+			hca_attr->non_wire_sq ? "" : "not ");
 		DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
-			config->hca_attr.log_max_static_sq_wq ? "" : "not ",
-			config->hca_attr.log_max_static_sq_wq);
+			hca_attr->log_max_static_sq_wq ? "" : "not ",
+			hca_attr->log_max_static_sq_wq);
 		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
-			config->hca_attr.qos.wqe_rate_pp ? "" : "not ");
+			hca_attr->qos.wqe_rate_pp ? "" : "not ");
 		if (!sh->devx) {
 			DRV_LOG(ERR, "DevX is required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.qos.packet_pacing) {
+		if (!hca_attr->qos.packet_pacing) {
 			DRV_LOG(ERR, "Packet pacing is not supported");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.cross_channel) {
+		if (!hca_attr->cross_channel) {
 			DRV_LOG(ERR, "Cross channel operations are"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.wqe_index_ignore) {
+		if (!hca_attr->wqe_index_ignore) {
 			DRV_LOG(ERR, "WQE index ignore feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.non_wire_sq) {
+		if (!hca_attr->non_wire_sq) {
 			DRV_LOG(ERR, "Non-wire SQ feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.log_max_static_sq_wq) {
+		if (!hca_attr->log_max_static_sq_wq) {
 			DRV_LOG(ERR, "Static WQE SQ feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.qos.wqe_rate_pp) {
+		if (!hca_attr->qos.wqe_rate_pp) {
 			DRV_LOG(ERR, "WQE rate mode is required"
 				     " for packet pacing");
 			err = ENODEV;
@@ -1517,7 +1511,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
-		if (!config->hca_attr.rq_delay_drop) {
+		if (!hca_attr->rq_delay_drop) {
 			config->std_delay_drop = 0;
 			config->hp_delay_drop = 0;
 			DRV_LOG(WARNING,
@@ -1528,7 +1522,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (sh->devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
-		err = config->hca_attr.access_register_user ?
+		err = hca_attr->access_register_user ?
 			mlx5_devx_cmd_register_read
 				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
 				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
@@ -1542,8 +1536,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				config->rt_timestamp = 1;
 		} else {
 			/* Kernel does not support register reading. */
-			if (config->hca_attr.dev_freq_khz ==
-						 (NS_PER_S / MS_PER_S))
+			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
 				config->rt_timestamp = 1;
 		}
 	}
@@ -1552,7 +1545,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
 	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
 	 */
-	if (config->hca_attr.scatter_fcs_w_decap_disable && config->decap_en)
+	if (hca_attr->scatter_fcs_w_decap_disable && config->decap_en)
 		config->hw_fcs_strip = 0;
 	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
 		(config->hw_fcs_strip ? "" : "not "));
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 60167450e4..920b174b96 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -889,7 +889,7 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 	uint32_t ids[8];
 	int ret;
 
-	if (!priv->config.hca_attr.parse_graph_flex_node) {
+	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
 		DRV_LOG(ERR, "Dynamic flex parser is not supported "
 			"for device %s.", priv->dev_data->name);
 		return -ENOTSUP;
@@ -2035,6 +2035,8 @@ void
 mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 		    struct mlx5_dev_config *config)
 {
+	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
+
 	if (config->txq_inline_min != MLX5_ARG_UNSET) {
 		/* Application defines size of inlined data explicitly. */
 		if (spawn->pci_dev != NULL) {
@@ -2054,9 +2056,9 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 		}
 		goto exit;
 	}
-	if (config->hca_attr.eth_net_offloads) {
+	if (hca_attr->eth_net_offloads) {
 		/* We have DevX enabled, inline mode queried successfully. */
-		switch (config->hca_attr.wqe_inline_mode) {
+		switch (hca_attr->wqe_inline_mode) {
 		case MLX5_CAP_INLINE_MODE_L2:
 			/* outer L2 header must be inlined. */
 			config->txq_inline_min = MLX5_INLINE_HSIZE_L2;
@@ -2065,14 +2067,14 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			/* No inline data are required by NIC. */
 			config->txq_inline_min = MLX5_INLINE_HSIZE_NONE;
 			config->hw_vlan_insert =
-				config->hca_attr.wqe_vlan_insert;
+				hca_attr->wqe_vlan_insert;
 			DRV_LOG(DEBUG, "Tx VLAN insertion is supported");
 			goto exit;
 		case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
 			/* inline mode is defined by NIC vport context. */
-			if (!config->hca_attr.eth_virt)
+			if (!hca_attr->eth_virt)
 				break;
-			switch (config->hca_attr.vport_inline_mode) {
+			switch (hca_attr->vport_inline_mode) {
 			case MLX5_INLINE_MODE_NONE:
 				config->txq_inline_min =
 					MLX5_INLINE_HSIZE_NONE;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e4b2523eb0..ee485343ff 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -299,7 +299,6 @@ struct mlx5_dev_config {
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
-	struct mlx5_hca_attr hca_attr; /* HCA attributes. */
 	struct mlx5_lro_config lro; /* LRO configuration. */
 };
 
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 91243f684f..97c8925044 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -419,7 +419,8 @@ mlx5_rxq_obj_hairpin_new(struct mlx5_rxq_priv *rxq)
 	MLX5_ASSERT(rxq != NULL && rxq->ctrl != NULL && tmpl != NULL);
 	tmpl->rxq_ctrl = rxq_ctrl;
 	attr.hairpin = 1;
-	max_wq_data = priv->config.hca_attr.log_max_hairpin_wq_data_sz;
+	max_wq_data =
+		priv->sh->cdev->config.hca_attr.log_max_hairpin_wq_data_sz;
 	/* Jumbo frames > 9KB should be supported, and more packets. */
 	if (priv->config.log_hp_size != (uint32_t)MLX5_ARG_UNSET) {
 		if (priv->config.log_hp_size > max_wq_data) {
@@ -1117,7 +1118,8 @@ mlx5_txq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx)
 	tmpl->txq_ctrl = txq_ctrl;
 	attr.hairpin = 1;
 	attr.tis_lst_sz = 1;
-	max_wq_data = priv->config.hca_attr.log_max_hairpin_wq_data_sz;
+	max_wq_data =
+		priv->sh->cdev->config.hca_attr.log_max_hairpin_wq_data_sz;
 	/* Jumbo frames > 9KB should be supported, and more packets. */
 	if (priv->config.log_hp_size != (uint32_t)MLX5_ARG_UNSET) {
 		if (priv->config.log_hp_size > max_wq_data) {
@@ -1193,7 +1195,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 	struct mlx5_devx_create_sq_attr sq_attr = {
 		.flush_in_error_en = 1,
 		.allow_multi_pkt_send_wqe = !!priv->config.mps,
-		.min_wqe_inline_mode = priv->config.hca_attr.vport_inline_mode,
+		.min_wqe_inline_mode = cdev->config.hca_attr.vport_inline_mode,
 		.allow_swp = !!priv->config.swp,
 		.cqn = txq_obj->cq_obj.cq->id,
 		.tis_lst_sz = 1,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index dc647d5580..5b0eee3321 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -337,7 +337,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
 	mlx5_set_default_params(dev, info);
 	mlx5_set_txlimit_params(dev, info);
-	if (priv->config.hca_attr.mem_rq_rmp &&
+	if (priv->sh->cdev->config.hca_attr.mem_rq_rmp &&
 	    priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new)
 		info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE;
 	info->switch_info.name = dev->data->name;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index d7cb1eb89b..5a21803e18 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2906,7 +2906,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,
 	const struct rte_flow_item_geneve *mask = item->mask;
 	int ret;
 	uint16_t gbhdr;
-	uint8_t opt_len = priv->config.hca_attr.geneve_max_opt_len ?
+	uint8_t opt_len = priv->sh->cdev->config.hca_attr.geneve_max_opt_len ?
 			  MLX5_GENEVE_OPT_LEN_1 : MLX5_GENEVE_OPT_LEN_0;
 	const struct rte_flow_item_geneve nic_mask = {
 		.ver_opt_len_o_c_rsvd0 = RTE_BE16(0x3f80),
@@ -2914,7 +2914,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,
 		.protocol = RTE_BE16(UINT16_MAX),
 	};
 
-	if (!priv->config.hca_attr.tunnel_stateless_geneve_rx)
+	if (!priv->sh->cdev->config.hca_attr.tunnel_stateless_geneve_rx)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "L3 Geneve is not enabled by device"
@@ -2994,10 +2994,9 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	struct mlx5_geneve_tlv_option_resource *geneve_opt_resource;
-	struct mlx5_hca_attr *hca_attr = &priv->config.hca_attr;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	uint8_t data_max_supported =
 			hca_attr->max_geneve_tlv_option_data_len * 4;
-	struct mlx5_dev_config *config = &priv->config;
 	const struct rte_flow_item_geneve *geneve_spec;
 	const struct rte_flow_item_geneve *geneve_mask;
 	const struct rte_flow_item_geneve_opt *spec = item->spec;
@@ -3031,11 +3030,11 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 			"Geneve TLV opt class/type/length masks must be full");
 	/* Check if length is supported */
 	if ((uint32_t)spec->option_len >
-			config->hca_attr.max_geneve_tlv_option_data_len)
+			hca_attr->max_geneve_tlv_option_data_len)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
 			"Geneve TLV opt length not supported");
-	if (config->hca_attr.max_geneve_tlv_options > 1)
+	if (hca_attr->max_geneve_tlv_options > 1)
 		DRV_LOG(DEBUG,
 			"max_geneve_tlv_options supports more than 1 option");
 	/* Check GENEVE item preceding. */
@@ -3090,7 +3089,7 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 					"Data mask is of unsupported size");
 	}
 	/* Check GENEVE option is supported in NIC. */
-	if (!config->hca_attr.geneve_tlv_opt)
+	if (!hca_attr->geneve_tlv_opt)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
 			"Geneve TLV opt not supported");
@@ -6249,7 +6248,8 @@ flow_create_split_sample(struct rte_eth_dev *dev,
 		 * When reg_c_preserve is set, metadata registers Cx preserve
 		 * their value even through packet duplication.
 		 */
-		add_tag = (!fdb_tx || priv->config.hca_attr.reg_c_preserve);
+		add_tag = (!fdb_tx ||
+			   priv->sh->cdev->config.hca_attr.reg_c_preserve);
 		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index ef9c66eddf..b0ed9f93a0 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2317,7 +2317,7 @@ flow_dv_validate_item_gtp(struct rte_eth_dev *dev,
 		.teid = RTE_BE32(0xffffffff),
 	};
 
-	if (!priv->config.hca_attr.tunnel_stateless_gtp)
+	if (!priv->sh->cdev->config.hca_attr.tunnel_stateless_gtp)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "GTP support is not enabled");
@@ -2426,6 +2426,7 @@ flow_dv_validate_item_ipv4(struct rte_eth_dev *dev,
 {
 	int ret;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_attr *attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_item_ipv4 *spec = item->spec;
 	const struct rte_flow_item_ipv4 *last = item->last;
 	const struct rte_flow_item_ipv4 *mask = item->mask;
@@ -2444,8 +2445,8 @@ flow_dv_validate_item_ipv4(struct rte_eth_dev *dev,
 
 	if (mask && (mask->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK)) {
 		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
-		bool ihl_cap = !tunnel ? priv->config.hca_attr.outer_ipv4_ihl :
-			       priv->config.hca_attr.inner_ipv4_ihl;
+		bool ihl_cap = !tunnel ?
+			       attr->outer_ipv4_ihl : attr->inner_ipv4_ihl;
 		if (!ihl_cap)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ITEM,
@@ -3384,7 +3385,7 @@ flow_dv_validate_action_decap(struct rte_eth_dev *dev,
 {
 	const struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (priv->config.hca_attr.scatter_fcs_w_decap_disable &&
+	if (priv->sh->cdev->config.hca_attr.scatter_fcs_w_decap_disable &&
 	    !priv->config.decap_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -5753,7 +5754,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 						  NULL,
 						  "E-Switch must has a dest "
 						  "port for mirroring");
-		if (!priv->config.hca_attr.reg_c_preserve &&
+		if (!priv->sh->cdev->config.hca_attr.reg_c_preserve &&
 		     priv->representor_id != UINT16_MAX)
 			*fdb_mirror_limit = 1;
 	}
@@ -6686,7 +6687,7 @@ flow_dv_validate_item_integrity(struct rte_eth_dev *dev,
 	const struct rte_flow_item_integrity *spec = (typeof(spec))
 						     integrity_item->spec;
 
-	if (!priv->config.hca_attr.pkt_integrity_match)
+	if (!priv->sh->cdev->config.hca_attr.pkt_integrity_match)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM,
 					  integrity_item,
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c b/drivers/net/mlx5/mlx5_flow_flex.c
index 9413d4d817..26f0dfa36f 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -910,7 +910,7 @@ mlx5_flex_translate_sample(struct mlx5_hca_flex_attr *attr,
 	 * offsets in any order.
 	 *
 	 * Gather all similar fields together, build array of bit intervals
-	 * in asсending order and try to cover with the smallest set of sample
+	 * in ascending order and try to cover with the smallest set of sample
 	 * registers.
 	 */
 	memset(&cover, 0, sizeof(cover));
@@ -1153,7 +1153,7 @@ mlx5_flex_translate_conf(struct rte_eth_dev *dev,
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_hca_flex_attr *attr = &priv->config.hca_attr.flex;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	int ret;
 
 	ret = mlx5_flex_translate_length(attr, conf, devx, error);
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 0dc7fbfb32..77ae326bb7 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -155,7 +155,7 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 					  "Meter profile already exists.");
 	if (!priv->sh->meter_aso_en) {
 		/* Old version is even not supported. */
-		if (!priv->config.hca_attr.qos.flow_meter_old)
+		if (!priv->sh->cdev->config.hca_attr.qos.flow_meter_old)
 			return -rte_mtr_error_set(error, ENOTSUP,
 				RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				NULL, "Metering is not supported.");
@@ -426,7 +426,7 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
 		 struct rte_mtr_error *error __rte_unused)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_hca_qos_attr *qattr = &priv->config.hca_attr.qos;
+	struct mlx5_hca_qos_attr *qattr = &priv->sh->cdev->config.hca_attr.qos;
 
 	if (!priv->mtr_en)
 		return -rte_mtr_error_set(error, ENOTSUP,
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 580d7ae868..0ede46aa43 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -863,7 +863,7 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		MLX5_ASSERT(n_seg < MLX5_MAX_RXQ_NSEG);
 	}
 	if (conf->share_group > 0) {
-		if (!priv->config.hca_attr.mem_rq_rmp) {
+		if (!priv->sh->cdev->config.hca_attr.mem_rq_rmp) {
 			DRV_LOG(ERR, "port %u queue index %u shared Rx queue not supported by fw",
 				     dev->data->port_id, idx);
 			rte_errno = EINVAL;
@@ -1517,7 +1517,7 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint16_t idx,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (priv->config.hca_attr.lro_max_msg_sz_mode ==
+	if (priv->sh->cdev->config.hca_attr.lro_max_msg_sz_mode ==
 	    MLX5_LRO_MAX_MSG_SIZE_START_FROM_L4 && max_lro_size >
 	    MLX5_MAX_TCP_HDR_OFFSET)
 		max_lro_size -= MLX5_MAX_TCP_HDR_OFFSET;
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 74c9c0a4ff..4bb0331464 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -341,14 +341,16 @@ mlx5_hairpin_auto_bind(struct rte_eth_dev *dev)
 		sq_attr.state = MLX5_SQC_STATE_RDY;
 		sq_attr.sq_state = MLX5_SQC_STATE_RST;
 		sq_attr.hairpin_peer_rq = rq->id;
-		sq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
+		sq_attr.hairpin_peer_vhca =
+				priv->sh->cdev->config.hca_attr.vhca_id;
 		ret = mlx5_devx_cmd_modify_sq(sq, &sq_attr);
 		if (ret)
 			goto error;
 		rq_attr.state = MLX5_SQC_STATE_RDY;
 		rq_attr.rq_state = MLX5_SQC_STATE_RST;
 		rq_attr.hairpin_peer_sq = sq->id;
-		rq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
+		rq_attr.hairpin_peer_vhca =
+				priv->sh->cdev->config.hca_attr.vhca_id;
 		ret = mlx5_devx_cmd_modify_rq(rq, &rq_attr);
 		if (ret)
 			goto error;
@@ -425,7 +427,7 @@ mlx5_hairpin_queue_peer_update(struct rte_eth_dev *dev, uint16_t peer_queue,
 			return -rte_errno;
 		}
 		peer_info->qp_id = txq_ctrl->obj->sq->id;
-		peer_info->vhca_id = priv->config.hca_attr.vhca_id;
+		peer_info->vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		/* 1-to-1 mapping, only the first one is used. */
 		peer_info->peer_q = txq_ctrl->hairpin_conf.peers[0].queue;
 		peer_info->tx_explicit = txq_ctrl->hairpin_conf.tx_explicit;
@@ -455,7 +457,7 @@ mlx5_hairpin_queue_peer_update(struct rte_eth_dev *dev, uint16_t peer_queue,
 			return -rte_errno;
 		}
 		peer_info->qp_id = rxq_ctrl->obj->rq->id;
-		peer_info->vhca_id = priv->config.hca_attr.vhca_id;
+		peer_info->vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		peer_info->peer_q = rxq->hairpin_conf.peers[0].queue;
 		peer_info->tx_explicit = rxq->hairpin_conf.tx_explicit;
 		peer_info->manual_bind = rxq->hairpin_conf.manual_bind;
@@ -817,7 +819,7 @@ mlx5_hairpin_bind_single_port(struct rte_eth_dev *dev, uint16_t rx_port)
 		/* Pass TxQ's information to peer RxQ and try binding. */
 		cur.peer_q = rx_queue;
 		cur.qp_id = txq_ctrl->obj->sq->id;
-		cur.vhca_id = priv->config.hca_attr.vhca_id;
+		cur.vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		cur.tx_explicit = txq_ctrl->hairpin_conf.tx_explicit;
 		cur.manual_bind = txq_ctrl->hairpin_conf.manual_bind;
 		/*
diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c
index af77e91e4c..1d16ebcb41 100644
--- a/drivers/net/mlx5/mlx5_txpp.c
+++ b/drivers/net/mlx5/mlx5_txpp.c
@@ -825,7 +825,7 @@ mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh, struct mlx5_priv *priv)
 	sh->txpp.tick = tx_pp >= 0 ? tx_pp : -tx_pp;
 	sh->txpp.test = !!(tx_pp < 0);
 	sh->txpp.skew = priv->config.tx_skew;
-	sh->txpp.freq = priv->config.hca_attr.dev_freq_khz;
+	sh->txpp.freq = sh->cdev->config.hca_attr.dev_freq_khz;
 	ret = mlx5_txpp_create_event_channel(sh);
 	if (ret)
 		goto exit;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index c1f8bc9ee3..3d8bd2e100 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -268,6 +268,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	bool fallback;
 
 #ifndef HAVE_IBV_DEVX_ASYNC
@@ -275,16 +276,16 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #else
 	fallback = false;
 	if (!sh->devx || !priv->config.dv_flow_en ||
-	    !priv->config.hca_attr.flow_counters_dump ||
-	    !(priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
 		fallback = true;
 #endif
 	if (fallback)
 		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
 			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			priv->config.hca_attr.flow_counters_dump,
-			priv->config.hca_attr.flow_counter_bulk_alloc_bitmap);
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
 	/* Initialize fallback mode only on the port initializes sh. */
 	if (sh->refcnt == 1)
 		sh->cmng.counter_fallback = fallback;
@@ -318,6 +319,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_dev_attr device_attr;
+	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -475,19 +477,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (sh->devx) {
-		config->hca_attr = sh->cdev->config.hca_attr;
-		config->hw_csum = config->hca_attr.csum_cap;
+		hca_attr = &sh->cdev->config.hca_attr;
+		config->hw_csum = hca_attr->csum_cap;
 		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-		    (config->hw_csum ? "" : "not "));
-		config->hw_vlan_strip = config->hca_attr.vlan_cap;
+			(config->hw_csum ? "" : "not "));
+		config->hw_vlan_strip = hca_attr->vlan_cap;
 		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 			(config->hw_vlan_strip ? "" : "not "));
-		config->hw_fcs_strip = config->hca_attr.scatter_fcs;
+		config->hw_fcs_strip = hca_attr->scatter_fcs;
 	}
 	if (sh->devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
-		err = config->hca_attr.access_register_user ?
+		err = hca_attr->access_register_user ?
 			mlx5_devx_cmd_register_read
 				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
 				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
@@ -501,8 +503,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				config->rt_timestamp = 1;
 		} else {
 			/* Kernel does not support register reading. */
-			if (config->hca_attr.dev_freq_khz ==
-						 (NS_PER_S / MS_PER_S))
+			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
 				config->rt_timestamp = 1;
 		}
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 08/20] net/mlx5: remove DevX flag duplication
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (6 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
                   ` (12 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The sharing device context structure has a field named "devx" which
indicates if DevX is supported.
The common configure stracture has also field named "devx" with the same
meaning.

There is no need for this duplication, because there is a reference to
the common structure from within the sharing device context structure.

This patch removes it from sharing device context structure and uses the
common config structure instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c    | 16 ++++++++--------
 drivers/net/mlx5/linux/mlx5_verbs.c |  4 ++--
 drivers/net/mlx5/mlx5.c             |  3 +--
 drivers/net/mlx5/mlx5.h             |  1 -
 drivers/net/mlx5/mlx5_ethdev.c      |  3 ++-
 drivers/net/mlx5/mlx5_flow.c        |  2 +-
 drivers/net/mlx5/mlx5_flow_dv.c     | 23 ++++++++++++-----------
 drivers/net/mlx5/mlx5_trigger.c     |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c  |  6 +++---
 9 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 39ca145e4a..b579be25cb 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -682,7 +682,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -1316,7 +1316,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
 		/* Check for LRO support. */
 		if (config->dest_tir && hca_attr->lro_cap &&
@@ -1434,13 +1434,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->devx || !hca_attr->mini_cqe_resp_flow_tag)) {
+	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_flow_tag)) {
 		DRV_LOG(WARNING, "Flow Tag CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
+	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
 		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
@@ -1463,7 +1463,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			hca_attr->log_max_static_sq_wq);
 		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
 			hca_attr->qos.wqe_rate_pp ? "" : "not ");
-		if (!sh->devx) {
+		if (!sh->cdev->config.devx) {
 			DRV_LOG(ERR, "DevX is required for packet pacing");
 			err = ENODEV;
 			goto error;
@@ -1519,7 +1519,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
 		err = hca_attr->access_register_user ?
@@ -1676,7 +1676,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->devx && config->dv_flow_en && config->dest_tir) {
+	if (sh->cdev->config.devx && config->dv_flow_en && config->dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
@@ -2735,7 +2735,7 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh)
 			rte_intr_fd_set(sh->intr_handle, -1);
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 #ifdef HAVE_IBV_DEVX_ASYNC
 		sh->intr_handle_devx =
 			rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c
index 2b6eef44a7..722017efa4 100644
--- a/drivers/net/mlx5/linux/mlx5_verbs.c
+++ b/drivers/net/mlx5/linux/mlx5_verbs.c
@@ -998,7 +998,7 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	qp.comp_mask = MLX5DV_QP_MASK_UAR_MMAP_OFFSET;
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	/* If using DevX, need additional mask to read tisn value. */
-	if (priv->sh->devx && !priv->sh->tdn)
+	if (priv->sh->cdev->config.devx && !priv->sh->tdn)
 		qp.comp_mask |= MLX5DV_QP_MASK_RAW_QP_HANDLES;
 #endif
 	obj.cq.in = txq_obj->cq;
@@ -1042,7 +1042,7 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	 * This is done once per port.
 	 * Will use this value on Rx, when creating matching TIR.
 	 */
-	if (priv->sh->devx && !priv->sh->tdn) {
+	if (priv->sh->cdev->config.devx && !priv->sh->tdn) {
 		ret = mlx5_devx_cmd_qp_query_tis_td(txq_obj->qp, qp.tisn,
 						    &priv->sh->tdn);
 		if (ret) {
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 920b174b96..b371a87355 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1182,7 +1182,6 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
 	sh->numa_node = spawn->cdev->dev->numa_node;
 	sh->cdev = spawn->cdev;
-	sh->devx = sh->cdev->config.devx;
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
 	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
@@ -1205,7 +1204,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		sh->port[i].ih_port_id = RTE_MAX_ETHPORTS;
 		sh->port[i].devx_ih_port_id = RTE_MAX_ETHPORTS;
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		sh->td = mlx5_devx_cmd_create_td(sh->cdev->ctx);
 		if (!sh->td) {
 			DRV_LOG(ERR, "TD allocation failure");
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index ee485343ff..6bc7a34f60 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1146,7 +1146,6 @@ struct mlx5_flex_item {
 struct mlx5_dev_ctx_shared {
 	LIST_ENTRY(mlx5_dev_ctx_shared) next;
 	uint32_t refcnt;
-	uint32_t devx:1; /* Opened with DV. */
 	uint32_t flow_hit_aso_en:1; /* Flow Hit ASO is supported. */
 	uint32_t steering_format_version:4;
 	/* Indicates the device steering logic format. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 5b0eee3321..801c467bba 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -723,7 +723,8 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
 
-	if (!priv->sh->devx || !config->dest_tir || !config->dv_flow_en) {
+	if (!priv->sh->cdev->config.devx || !config->dest_tir ||
+	    !config->dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 5a21803e18..907f3fd75a 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -9966,7 +9966,7 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
 	type = mlx5_flow_os_get_type();
 	if (type == MLX5_FLOW_TYPE_MAX) {
 		type = MLX5_FLOW_TYPE_VERBS;
-		if (priv->sh->devx && priv->config.dv_flow_en)
+		if (priv->sh->cdev->config.devx && priv->config.dv_flow_en)
 			type = MLX5_FLOW_TYPE_DV;
 	}
 	fops = flow_get_drv_ops(type);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index b0ed9f93a0..4e60a54df3 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3291,7 +3291,7 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, bool shared,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		goto notsup_err;
 	if (action_flags & MLX5_FLOW_ACTION_COUNT)
 		return rte_flow_error_set(error, EINVAL,
@@ -5302,8 +5302,8 @@ flow_dv_validate_action_age(uint64_t action_flags,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const struct rte_flow_action_age *age = action->conf;
 
-	if (!priv->sh->devx || (priv->sh->cmng.counter_fallback &&
-	    !priv->sh->aso_age_mng))
+	if (!priv->sh->cdev->config.devx ||
+	    (priv->sh->cmng.counter_fallback && !priv->sh->aso_age_mng))
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -5587,7 +5587,8 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
 					  "ratio value starts from 1");
-	if (!priv->sh->devx || (sample->ratio > 0 && !priv->sampler_en))
+	if (!priv->sh->cdev->config.devx ||
+	    (sample->ratio > 0 && !priv->sampler_en))
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -6175,7 +6176,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t age)
 			age ? MLX5_COUNTER_TYPE_AGE : MLX5_COUNTER_TYPE_ORIGIN;
 	uint32_t cnt_idx;
 
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -6498,7 +6499,7 @@ flow_dv_mtr_alloc(struct rte_eth_dev *dev)
 	struct mlx5_aso_mtr_pool *pool;
 	uint32_t mtr_idx = 0;
 
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -12515,7 +12516,7 @@ flow_dv_aso_ct_alloc(struct rte_eth_dev *dev, struct rte_flow_error *error)
 	uint32_t ct_idx;
 
 	MLX5_ASSERT(mng);
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -12953,7 +12954,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 			}
 			break;
 		case RTE_FLOW_ACTION_TYPE_COUNT:
-			if (!priv->sh->devx) {
+			if (!priv->sh->cdev->config.devx) {
 				return rte_flow_error_set
 					      (error, ENOTSUP,
 					       RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -15834,7 +15835,7 @@ flow_dv_query_count(struct rte_eth_dev *dev, uint32_t cnt_idx, void *data,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct rte_flow_query_count *qc = data;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -15887,7 +15888,7 @@ flow_dv_query_count_ptr(struct rte_eth_dev *dev, uint32_t cnt_idx,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->devx || !action_ptr)
+	if (!priv->sh->cdev->config.devx || !action_ptr)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -17491,7 +17492,7 @@ flow_dv_counter_query(struct rte_eth_dev *dev, uint32_t counter, bool clear,
 	uint64_t inn_pkts, inn_bytes;
 	int ret;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		return -1;
 
 	ret = _flow_dv_query_count(dev, counter, &inn_pkts, &inn_bytes);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 4bb0331464..1dfe7da435 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,7 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->devx && priv->config.dv_flow_en &&
+	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
 	    priv->config.dest_tir) && priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 3d8bd2e100..5396365ec9 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -275,7 +275,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -476,7 +476,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		hca_attr = &sh->cdev->config.hca_attr;
 		config->hw_csum = hca_attr->csum_cap;
 		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
@@ -661,7 +661,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			goto error;
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		priv->obj_ops = devx_obj_ops;
 	} else {
 		DRV_LOG(ERR, "Windows flow must be DevX.");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 09/20] net/mlx5: remove Verbs query device duplication
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (7 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 08/20] net/mlx5: remove DevX flag duplication Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 10/20] common/mlx5: share VF checking function Michael Baum
                   ` (11 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The sharing device context structure has a field named "device_attr"
which s filled by mlx5_os_get_dev_attr() function.
The spawn function calls mlx5_os_get_dev_attr() again and save it to
local variable identical to "device_attr" field.

There is no need for this duplication, because there is a reference to
the sharing device context structure from spawn function.

This patch removes the local "device_attr" from spawn function, and uses
the context's field instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 63 ++++++++++++++----------------
 drivers/net/mlx5/windows/mlx5_os.c |  6 +--
 2 files changed, 32 insertions(+), 37 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index b579be25cb..e8e842a09e 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -171,6 +171,15 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	device_attr->tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
 
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
+#ifdef HAVE_IBV_MLX5_MOD_SWP
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
+#endif
+#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS;
+#endif
+#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
+#endif
 	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
 	if (err) {
 		rte_errno = errno;
@@ -183,6 +192,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	device_attr->sw_parsing_offloads =
 		dv_attr.sw_parsing_caps.sw_parsing_offloads;
 #endif
+#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
 	device_attr->min_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
 	device_attr->max_single_stride_log_num_of_bytes =
@@ -193,6 +203,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
 	device_attr->stride_supported_qpts =
 		dv_attr.striding_rq_caps.supported_qpts;
+#endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
 	device_attr->tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
 #endif
@@ -878,7 +889,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
-	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -1011,23 +1021,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 #ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
 	config->dest_tir = 1;
-#endif
-#ifdef HAVE_IBV_MLX5_MOD_SWP
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
 #endif
 	/*
 	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
 	 * as all ConnectX-5 devices.
 	 */
-#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS;
-#endif
-#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
-#endif
-	mlx5_glue->dv_query_device(sh->cdev->ctx, &dv_attr);
-	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+	if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
 			DRV_LOG(DEBUG, "enhanced MPW is supported");
 			mps = MLX5_MPW_ENHANCED;
 		} else {
@@ -1039,44 +1039,41 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mps = MLX5_MPW_DISABLED;
 	}
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = dv_attr.sw_parsing_caps.sw_parsing_offloads;
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		swp = sh->device_attr.sw_parsing_offloads;
 	DRV_LOG(DEBUG, "SWP support: %u", swp);
 #endif
 	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		MLX5_SW_PARSING_TSO_CAP);
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
-		struct mlx5dv_striding_rq_caps mprq_caps =
-			dv_attr.striding_rq_caps;
-
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
 		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			mprq_caps.min_single_stride_log_num_of_bytes);
+			sh->device_attr.min_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			mprq_caps.max_single_stride_log_num_of_bytes);
+			sh->device_attr.max_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			mprq_caps.min_single_wqe_log_num_of_strides);
+			sh->device_attr.min_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			mprq_caps.max_single_wqe_log_num_of_strides);
+			sh->device_attr.max_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			mprq_caps.supported_qpts);
+			sh->device_attr.stride_supported_qpts);
 		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
 			config->mprq.log_min_stride_wqe_size);
 		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
 		mprq = 1;
 		config->mprq.log_min_stride_size =
-			mprq_caps.min_single_stride_log_num_of_bytes;
+			sh->device_attr.min_single_stride_log_num_of_bytes;
 		config->mprq.log_max_stride_size =
-			mprq_caps.max_single_stride_log_num_of_bytes;
+			sh->device_attr.max_single_stride_log_num_of_bytes;
 		config->mprq.log_min_stride_num =
-			mprq_caps.min_single_wqe_log_num_of_strides;
+			sh->device_attr.min_single_wqe_log_num_of_strides;
 		config->mprq.log_max_stride_num =
-			mprq_caps.max_single_wqe_log_num_of_strides;
+			sh->device_attr.max_single_wqe_log_num_of_strides;
 	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = dv_attr.tunnel_offloads_caps &
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
 			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
@@ -1098,9 +1095,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		"tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((dv_attr.tunnel_offloads_caps &
+	mpls_en = ((sh->device_attr.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (dv_attr.tunnel_offloads_caps &
+		   (sh->device_attr.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
 	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
 		mpls_en ? "" : "not ");
@@ -1429,7 +1426,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(dv_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
+	    !(sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
 		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
 		config->cqe_comp = 0;
 	}
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 5396365ec9..31f0247be7 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -318,7 +318,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_dev_attr device_attr;
 	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
@@ -376,13 +375,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	DRV_LOG(DEBUG, "MPW isn't supported");
-	mlx5_os_get_dev_attr(sh->cdev, &device_attr);
-	config->swp = device_attr.sw_parsing_offloads &
+	config->swp = sh->device_attr.sw_parsing_offloads &
 		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
-	config->tunnel_en = device_attr.tunnel_offloads_caps &
+	config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 10/20] common/mlx5: share VF checking function
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (8 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 11/20] net/mlx5: share realtime timestamp configure Michael Baum
                   ` (10 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The check if device is VF work for Linux as same as Windows.
This patch removes it to the function implemented in the folder shared
between the operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.h     | 15 +++++++++++++++
 drivers/common/mlx5/mlx5_common_pci.c | 18 ++++++++++++++++++
 drivers/common/mlx5/version.map       |  1 +
 drivers/net/mlx5/linux/mlx5_os.c      | 18 +-----------------
 drivers/net/mlx5/windows/mlx5_os.c    | 16 +---------------
 5 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index e8809844af..80f59c81fb 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -8,6 +8,7 @@
 #include <stdio.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_debug.h>
 #include <rte_atomic.h>
 #include <rte_rwlock.h>
@@ -487,6 +488,20 @@ __rte_internal
 bool
 mlx5_dev_is_pci(const struct rte_device *dev);
 
+/**
+ * Test PCI device is a VF device.
+ *
+ * @param pci_dev
+ *   Pointer to PCI device.
+ *
+ * @return
+ *   - True on PCI device is a VF device.
+ *   - False otherwise.
+ */
+__rte_internal
+bool
+mlx5_dev_is_vf_pci(struct rte_pci_device *pci_dev);
+
 __rte_internal
 int
 mlx5_dev_mempool_subscribe(struct mlx5_common_device *cdev);
diff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c
index 8b38091d87..8fd2cb076c 100644
--- a/drivers/common/mlx5/mlx5_common_pci.c
+++ b/drivers/common/mlx5/mlx5_common_pci.c
@@ -108,6 +108,24 @@ mlx5_dev_is_pci(const struct rte_device *dev)
 	return strcmp(dev->bus->name, "pci") == 0;
 }
 
+bool
+mlx5_dev_is_vf_pci(struct rte_pci_device *pci_dev)
+{
+	switch (pci_dev->id.device_id) {
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
 bool
 mlx5_dev_pci_match(const struct mlx5_class_driver *drv,
 		   const struct rte_device *dev)
diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map
index 462b7cea5e..59ab434631 100644
--- a/drivers/common/mlx5/version.map
+++ b/drivers/common/mlx5/version.map
@@ -13,6 +13,7 @@ INTERNAL {
 	mlx5_common_verbs_dereg_mr; # WINDOWS_NO_EXPORT
 
 	mlx5_dev_is_pci;
+	mlx5_dev_is_vf_pci;
 	mlx5_dev_mempool_unregister;
 	mlx5_dev_mempool_subscribe;
 
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index e8e842a09e..2fb91fec06 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -2100,7 +2100,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data *list = NULL;
 	struct mlx5_dev_config dev_config;
-	unsigned int dev_config_vf;
 	struct rte_eth_devargs eth_da = *req_eth_da;
 	struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
 	struct mlx5_bond_info bond_info;
@@ -2421,21 +2420,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	 * (i.e. master first, then representors from lowest to highest ID).
 	 */
 	qsort(list, ns, sizeof(*list), mlx5_dev_spawn_data_cmp);
-	/* Device specific configuration. */
-	switch (pci_dev->id.device_id) {
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
-		dev_config_vf = 1;
-		break;
-	default:
-		dev_config_vf = 0;
-		break;
-	}
 	if (eth_da.type != RTE_ETH_REPRESENTOR_NONE) {
 		/* Set devargs default values. */
 		if (eth_da.nb_mh_controllers == 0) {
@@ -2459,7 +2443,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 
 		/* Default configuration. */
 		mlx5_os_config_default(&dev_config, &cdev->config);
-		dev_config.vf = dev_config_vf;
+		dev_config.vf = mlx5_dev_is_vf_pci(pci_dev);
 		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
 						 &dev_config, &eth_da);
 		if (!list[i].eth_dev) {
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 31f0247be7..178e58b4d7 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -926,6 +926,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 		},
 		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
+		.vf = mlx5_dev_is_vf_pci(pci_dev),
 	};
 	int ret;
 	uint32_t restore;
@@ -940,21 +941,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	/* Device specific configuration. */
-	switch (pci_dev->id.device_id) {
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
-		dev_config.vf = 1;
-		break;
-	default:
-		dev_config.vf = 0;
-		break;
-	}
 	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, &dev_config);
 	if (!spawn.eth_dev)
 		return -rte_errno;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 11/20] net/mlx5: share realtime timestamp configure
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (9 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 10/20] common/mlx5: share VF checking function Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 12/20] net/mlx5: share counter config function Michael Baum
                   ` (9 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The realtime timestamp configure work for Linux as same as Windows.
This patch removes it to the function implemented in the folder shared
between the operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 23 ++-----------------
 drivers/net/mlx5/mlx5.c            | 37 ++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h            |  3 +++
 drivers/net/mlx5/windows/mlx5_os.c | 22 +-----------------
 4 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 2fb91fec06..bb90cc4426 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1516,27 +1516,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->cdev->config.devx) {
-		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
-
-		err = hca_attr->access_register_user ?
-			mlx5_devx_cmd_register_read
-				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
-				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
-		if (!err) {
-			uint32_t ts_mode;
-
-			/* MTUTC register is read successfully. */
-			ts_mode = MLX5_GET(register_mtutc, reg,
-					   time_stamp_mode);
-			if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-				config->rt_timestamp = 1;
-		} else {
-			/* Kernel does not support register reading. */
-			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-				config->rt_timestamp = 1;
-		}
-	}
+	if (sh->cdev->config.devx)
+		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	/*
 	 * If HW has bug working with tunnel packet decapsulation and
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b371a87355..5146359100 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1129,6 +1129,43 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
 	return 0;
 }
 
+/**
+ * Configure realtime timestamp format.
+ *
+ * @param sh
+ *   Pointer to mlx5_dev_ctx_shared object.
+ * @param config
+ *   Device configuration parameters.
+ * @param hca_attr
+ *   Pointer to DevX HCA capabilities structure.
+ */
+void
+mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
+			 struct mlx5_dev_config *config,
+			 struct mlx5_hca_attr *hca_attr)
+{
+	uint32_t dw_cnt = MLX5_ST_SZ_DW(register_mtutc);
+	uint32_t reg[dw_cnt];
+	int ret = ENOTSUP;
+
+	if (hca_attr->access_register_user)
+		ret = mlx5_devx_cmd_register_read(sh->cdev->ctx,
+						  MLX5_REGISTER_ID_MTUTC, 0,
+						  reg, dw_cnt);
+	if (!ret) {
+		uint32_t ts_mode;
+
+		/* MTUTC register is read successfully. */
+		ts_mode = MLX5_GET(register_mtutc, reg, time_stamp_mode);
+		if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
+			config->rt_timestamp = 1;
+	} else {
+		/* Kernel does not support register reading. */
+		if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
+			config->rt_timestamp = 1;
+	}
+}
+
 /**
  * Allocate shared device context. If there is multiport device the
  * master and representors will share this context, if there is single
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 6bc7a34f60..0f90d757e9 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1517,6 +1517,9 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	     port_id < RTE_MAX_ETHPORTS; \
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
 int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
+void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
+			      struct mlx5_dev_config *config,
+			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
 mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 			   const struct mlx5_dev_config *config);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 178e58b4d7..a9c7ba2a14 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -483,27 +483,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 			(config->hw_vlan_strip ? "" : "not "));
 		config->hw_fcs_strip = hca_attr->scatter_fcs;
-	}
-	if (sh->devx) {
-		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
-
-		err = hca_attr->access_register_user ?
-			mlx5_devx_cmd_register_read
-				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
-				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
-		if (!err) {
-			uint32_t ts_mode;
-
-			/* MTUTC register is read successfully. */
-			ts_mode = MLX5_GET(register_mtutc, reg,
-					   time_stamp_mode);
-			if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-				config->rt_timestamp = 1;
-		} else {
-			/* Kernel does not support register reading. */
-			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-				config->rt_timestamp = 1;
-		}
+		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	}
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 12/20] net/mlx5: share counter config function
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (10 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 11/20] net/mlx5: share realtime timestamp configure Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 13/20] net/mlx5: add E-switch mode flag Michael Baum
                   ` (8 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The mlx5_flow_counter_mode_config function exists for both Linux and
Windows with the same name and content.
This patch moves its implementation to the folder shared between the
operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 40 ------------------------------
 drivers/net/mlx5/mlx5.c            | 40 ++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h            |  1 +
 drivers/net/mlx5/windows/mlx5_os.c | 40 ------------------------------
 4 files changed, 41 insertions(+), 80 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index bb90cc4426..9a05c1ba44 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -673,46 +673,6 @@ mlx5_init_once(void)
 	return ret;
 }
 
-/**
- * DV flow counter mode detect and config.
- *
- * @param dev
- *   Pointer to rte_eth_dev structure.
- *
- */
-static void
-mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
-{
-#ifdef HAVE_IBV_FLOW_DV_SUPPORT
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
-	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
-	bool fallback;
-
-#ifndef HAVE_IBV_DEVX_ASYNC
-	fallback = true;
-#else
-	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
-	    !hca_attr->flow_counters_dump ||
-	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
-	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
-		fallback = true;
-#endif
-	if (fallback)
-		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
-			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			hca_attr->flow_counters_dump,
-			hca_attr->flow_counter_bulk_alloc_bitmap);
-	/* Initialize fallback mode only on the port initializes sh. */
-	if (sh->refcnt == 1)
-		sh->cmng.counter_fallback = fallback;
-	else if (fallback != sh->cmng.counter_fallback)
-		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
-			"with others:%d.", PORT_ID(priv), fallback);
-#endif
-}
-
 /**
  * DR flow drop action support detect.
  *
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 5146359100..27bcca9012 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -513,6 +513,46 @@ mlx5_flow_aging_init(struct mlx5_dev_ctx_shared *sh)
 	}
 }
 
+/**
+ * DV flow counter mode detect and config.
+ *
+ * @param dev
+ *   Pointer to rte_eth_dev structure.
+ *
+ */
+void
+mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+	bool fallback;
+
+#ifndef HAVE_IBV_DEVX_ASYNC
+	fallback = true;
+#else
+	fallback = false;
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
+		fallback = true;
+#endif
+	if (fallback)
+		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
+			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
+	/* Initialize fallback mode only on the port initializes sh. */
+	if (sh->refcnt == 1)
+		sh->cmng.counter_fallback = fallback;
+	else if (fallback != sh->cmng.counter_fallback)
+		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
+			"with others:%d.", PORT_ID(priv), fallback);
+#endif
+}
+
 /**
  * Initialize the counters management structure.
  *
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 0f90d757e9..d69b6a357b 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1535,6 +1535,7 @@ int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 				  struct rte_device *dpdk_dev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
+void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
 int mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh);
 int mlx5_aso_flow_mtrs_mng_init(struct mlx5_dev_ctx_shared *sh);
 int mlx5_flow_aso_ct_mng_init(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index a9c7ba2a14..eaa63ad50f 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -255,46 +255,6 @@ mlx5_os_set_nonblock_channel_fd(int fd)
 	return -ENOTSUP;
 }
 
-/**
- * DV flow counter mode detect and config.
- *
- * @param dev
- *   Pointer to rte_eth_dev structure.
- *
- */
-static void
-mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
-{
-#ifdef HAVE_IBV_FLOW_DV_SUPPORT
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
-	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
-	bool fallback;
-
-#ifndef HAVE_IBV_DEVX_ASYNC
-	fallback = true;
-#else
-	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
-	    !hca_attr->flow_counters_dump ||
-	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
-	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
-		fallback = true;
-#endif
-	if (fallback)
-		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
-			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			hca_attr->flow_counters_dump,
-			hca_attr->flow_counter_bulk_alloc_bitmap);
-	/* Initialize fallback mode only on the port initializes sh. */
-	if (sh->refcnt == 1)
-		sh->cmng.counter_fallback = fallback;
-	else if (fallback != sh->cmng.counter_fallback)
-		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
-			"with others:%d.", PORT_ID(priv), fallback);
-#endif
-}
-
 /**
  * Spawn an Ethernet device from DevX information.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 13/20] net/mlx5: add E-switch mode flag
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (11 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 12/20] net/mlx5: share counter config function Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 14/20] net/mlx5: rearrange device attribute structure Michael Baum
                   ` (7 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

This patch adds in SH structure a flag which indicates whether is
E-Switch mode.
When configure "dv_esw_en" from devargs, it is enabled only when is
E-switch mode. So, since dv_esw_en has been configure, it is enough to
check if "dv_esw_en" is valid.
This patch also removes E-Switch mode check when "dv_esw_en" is checked
too.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c | 14 +++++---------
 drivers/net/mlx5/mlx5.c          |  1 +
 drivers/net/mlx5/mlx5.h          |  1 +
 drivers/net/mlx5/mlx5_ethdev.c   |  4 ++--
 drivers/net/mlx5/mlx5_flow_dv.c  | 12 +++---------
 drivers/net/mlx5/mlx5_trigger.c  |  5 ++---
 6 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 9a05c1ba44..47b088db83 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -951,10 +951,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (!sh)
 		return NULL;
 	/* Update final values for devargs before check sibling config. */
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
 #if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
 	if (config->dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
@@ -962,12 +958,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 #endif
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(hca_attr->eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
+	if (!(hca_attr->eswitch_manager && config->dv_flow_en && sh->esw_mode))
 		config->dv_esw_en = 0;
 #else
 	config->dv_esw_en = 0;
 #endif
+	if (config->dv_miss_info && config->dv_esw_en)
+		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
 	if (!config->dv_esw_en &&
 	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 		DRV_LOG(WARNING,
@@ -1133,7 +1130,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * register to match on vport index. The engaged part of metadata
 	 * register is defined by mask.
 	 */
-	if (switch_info->representor || switch_info->master) {
+	if (sh->esw_mode) {
 		err = mlx5_glue->devx_port_query(sh->cdev->ctx,
 						 spawn->phys_port,
 						 &vport_info);
@@ -1164,8 +1161,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	if (vport_info.query_flags & MLX5_PORT_QUERY_VPORT) {
 		priv->vport_id = vport_info.vport_id;
-	} else if (spawn->pf_bond >= 0 &&
-		   (switch_info->representor || switch_info->master)) {
+	} else if (spawn->pf_bond >= 0 && sh->esw_mode) {
 		DRV_LOG(ERR,
 			"Cannot deduce vport index for port %d on bonding device %s",
 			spawn->phys_port, spawn->phys_dev_name);
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 27bcca9012..e1fe8f9375 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1259,6 +1259,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
 	sh->numa_node = spawn->cdev->dev->numa_node;
 	sh->cdev = spawn->cdev;
+	sh->esw_mode = !!(spawn->info.master || spawn->info.representor);
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
 	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index d69b6a357b..a713e61572 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1146,6 +1146,7 @@ struct mlx5_flex_item {
 struct mlx5_dev_ctx_shared {
 	LIST_ENTRY(mlx5_dev_ctx_shared) next;
 	uint32_t refcnt;
+	uint32_t esw_mode:1; /* Whether is E-Switch mode. */
 	uint32_t flow_hit_aso_en:1; /* Flow Hit ASO is supported. */
 	uint32_t steering_format_version:4;
 	/* Indicates the device steering logic format. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 801c467bba..06d5acb75f 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -672,7 +672,7 @@ mlx5_port_to_eswitch_info(uint16_t port, bool valid)
 	}
 	dev = &rte_eth_devices[port];
 	priv = dev->data->dev_private;
-	if (!(priv->representor || priv->master)) {
+	if (!priv->sh->esw_mode) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
@@ -699,7 +699,7 @@ mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
 	struct mlx5_priv *priv;
 
 	priv = dev->data->dev_private;
-	if (!(priv->representor || priv->master)) {
+	if (!priv->sh->esw_mode) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 4e60a54df3..6a5ac01c2a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -6600,11 +6600,6 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 				 "E-Switch dr is not supported");
-		if (!(priv->representor || priv->master))
-			return rte_flow_error_set
-				(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				 NULL, "E-Switch configuration can only be"
-				 " done by a master or a representor device");
 		if (attributes->egress)
 			return rte_flow_error_set
 				(error, ENOTSUP,
@@ -13612,8 +13607,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 	 * E-Switch rule where no port_id item was found. In both cases
 	 * the source port is set according the current port in use.
 	 */
-	if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) &&
-	    (priv->representor || priv->master)) {
+	if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, match_mask,
 						   match_value, NULL, attr))
 			return -rte_errno;
@@ -16173,7 +16167,7 @@ __flow_dv_create_policy_flow(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	uint8_t misc_mask;
 
-	if (match_src_port && (priv->representor || priv->master)) {
+	if (match_src_port && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, matcher.buf,
 						   value.buf, item, attr)) {
 			DRV_LOG(ERR, "Failed to create meter policy%d flow's"
@@ -16225,7 +16219,7 @@ __flow_dv_create_policy_matcher(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const uint32_t color_mask = (UINT32_C(1) << MLX5_MTR_COLOR_BITS) - 1;
 
-	if (match_src_port && (priv->representor || priv->master)) {
+	if (match_src_port && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, matcher.mask.buf,
 						   value.buf, item, attr)) {
 			DRV_LOG(ERR, "Failed to register meter policy%d matcher"
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 1dfe7da435..d128b3e978 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1330,8 +1330,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				goto error;
 			}
 		}
-		if ((priv->representor || priv->master) &&
-		    priv->config.dv_esw_en) {
+		if (priv->config.dv_esw_en) {
 			if (mlx5_flow_create_devx_sq_miss_flow(dev, i) == 0) {
 				DRV_LOG(ERR,
 					"Port %u Tx queue %u SQ create representor devx default miss rule failed.",
@@ -1341,7 +1340,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 		}
 		mlx5_txq_release(dev, i);
 	}
-	if ((priv->master || priv->representor) && priv->config.dv_esw_en) {
+	if (priv->config.dv_esw_en) {
 		if (mlx5_flow_create_esw_table_zero_flow(dev))
 			priv->fdb_def_rule = 1;
 		else
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 14/20] net/mlx5: rearrange device attribute structure
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (12 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 13/20] net/mlx5: add E-switch mode flag Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 15/20] net/mlx5: concentrate all device configurations Michael Baum
                   ` (6 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Rearrange the mlx5_os_get_dev_attr() function in such a way that it
first executes the queries and only then updates the fields.
In addition, it changed its name in preparation for expanding its
operations to configure the capabilities inside it.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c    | 122 +++++++++++++---------------
 drivers/net/mlx5/linux/mlx5_verbs.c |   5 +-
 drivers/net/mlx5/mlx5.c             |   4 +-
 drivers/net/mlx5/mlx5.h             |  56 ++++++-------
 drivers/net/mlx5/mlx5_devx.c        |   2 +-
 drivers/net/mlx5/mlx5_ethdev.c      |   5 +-
 drivers/net/mlx5/mlx5_trigger.c     |   8 +-
 drivers/net/mlx5/mlx5_txq.c         |  18 ++--
 drivers/net/mlx5/windows/mlx5_os.c  |  67 ++++++---------
 9 files changed, 127 insertions(+), 160 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 47b088db83..b6848fc34c 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -131,46 +131,25 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  * with out parameter of type 'struct ibv_device_attr_ex *'. Then fill in mlx5
  * device attributes from the glue out parameter.
  *
- * @param cdev
- *   Pointer to mlx5 device.
- *
- * @param device_attr
- *   Pointer to mlx5 device attributes.
+ * @param sh
+ *   Pointer to shared device context.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
-		     struct mlx5_dev_attr *device_attr)
+mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
 	int err;
-	struct ibv_context *ctx = cdev->ctx;
+	struct ibv_context *ctx = sh->cdev->ctx;
 	struct ibv_device_attr_ex attr_ex;
+	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 
-	memset(device_attr, 0, sizeof(*device_attr));
 	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
 	}
-	device_attr->device_cap_flags_ex = attr_ex.device_cap_flags_ex;
-	device_attr->max_qp_wr = attr_ex.orig_attr.max_qp_wr;
-	device_attr->max_sge = attr_ex.orig_attr.max_sge;
-	device_attr->max_cq = attr_ex.orig_attr.max_cq;
-	device_attr->max_cqe = attr_ex.orig_attr.max_cqe;
-	device_attr->max_mr = attr_ex.orig_attr.max_mr;
-	device_attr->max_pd = attr_ex.orig_attr.max_pd;
-	device_attr->max_qp = attr_ex.orig_attr.max_qp;
-	device_attr->max_srq = attr_ex.orig_attr.max_srq;
-	device_attr->max_srq_wr = attr_ex.orig_attr.max_srq_wr;
-	device_attr->raw_packet_caps = attr_ex.raw_packet_caps;
-	device_attr->max_rwq_indirection_table_size =
-		attr_ex.rss_caps.max_rwq_indirection_table_size;
-	device_attr->max_tso = attr_ex.tso_caps.max_tso;
-	device_attr->tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
-
-	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 #ifdef HAVE_IBV_MLX5_MOD_SWP
 	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
 #endif
@@ -185,31 +164,40 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 		rte_errno = errno;
 		return -rte_errno;
 	}
-
-	device_attr->flags = dv_attr.flags;
-	device_attr->comp_mask = dv_attr.comp_mask;
+	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.device_cap_flags_ex = attr_ex.device_cap_flags_ex;
+	sh->dev_cap.max_qp_wr = attr_ex.orig_attr.max_qp_wr;
+	sh->dev_cap.max_sge = attr_ex.orig_attr.max_sge;
+	sh->dev_cap.max_cq = attr_ex.orig_attr.max_cq;
+	sh->dev_cap.max_qp = attr_ex.orig_attr.max_qp;
+	sh->dev_cap.raw_packet_caps = attr_ex.raw_packet_caps;
+	sh->dev_cap.max_rwq_indirection_table_size =
+		attr_ex.rss_caps.max_rwq_indirection_table_size;
+	sh->dev_cap.max_tso = attr_ex.tso_caps.max_tso;
+	sh->dev_cap.tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
+	strlcpy(sh->dev_cap.fw_ver, attr_ex.orig_attr.fw_ver,
+		sizeof(sh->dev_cap.fw_ver));
+	sh->dev_cap.flags = dv_attr.flags;
+	sh->dev_cap.comp_mask = dv_attr.comp_mask;
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	device_attr->sw_parsing_offloads =
+	sh->dev_cap.sw_parsing_offloads =
 		dv_attr.sw_parsing_caps.sw_parsing_offloads;
 #endif
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	device_attr->min_single_stride_log_num_of_bytes =
+	sh->dev_cap.min_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
-	device_attr->max_single_stride_log_num_of_bytes =
+	sh->dev_cap.max_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.max_single_stride_log_num_of_bytes;
-	device_attr->min_single_wqe_log_num_of_strides =
+	sh->dev_cap.min_single_wqe_log_num_of_strides =
 		dv_attr.striding_rq_caps.min_single_wqe_log_num_of_strides;
-	device_attr->max_single_wqe_log_num_of_strides =
+	sh->dev_cap.max_single_wqe_log_num_of_strides =
 		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
-	device_attr->stride_supported_qpts =
+	sh->dev_cap.stride_supported_qpts =
 		dv_attr.striding_rq_caps.supported_qpts;
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	device_attr->tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
+	sh->dev_cap.tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
 #endif
-	strlcpy(device_attr->fw_ver, attr_ex.orig_attr.fw_ver,
-		sizeof(device_attr->fw_ver));
-
 	return 0;
 }
 
@@ -983,8 +971,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
 	 * as all ConnectX-5 devices.
 	 */
-	if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+	if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
 			DRV_LOG(DEBUG, "enhanced MPW is supported");
 			mps = MLX5_MPW_ENHANCED;
 		} else {
@@ -996,41 +984,41 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mps = MLX5_MPW_DISABLED;
 	}
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = sh->device_attr.sw_parsing_offloads;
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		swp = sh->dev_cap.sw_parsing_offloads;
 	DRV_LOG(DEBUG, "SWP support: %u", swp);
 #endif
 	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		MLX5_SW_PARSING_TSO_CAP);
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
 		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			sh->device_attr.min_single_stride_log_num_of_bytes);
+			sh->dev_cap.min_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			sh->device_attr.max_single_stride_log_num_of_bytes);
+			sh->dev_cap.max_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			sh->device_attr.min_single_wqe_log_num_of_strides);
+			sh->dev_cap.min_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			sh->device_attr.max_single_wqe_log_num_of_strides);
+			sh->dev_cap.max_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			sh->device_attr.stride_supported_qpts);
+			sh->dev_cap.stride_supported_qpts);
 		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
 			config->mprq.log_min_stride_wqe_size);
 		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
 		mprq = 1;
 		config->mprq.log_min_stride_size =
-			sh->device_attr.min_single_stride_log_num_of_bytes;
+			sh->dev_cap.min_single_stride_log_num_of_bytes;
 		config->mprq.log_max_stride_size =
-			sh->device_attr.max_single_stride_log_num_of_bytes;
+			sh->dev_cap.max_single_stride_log_num_of_bytes;
 		config->mprq.log_min_stride_num =
-			sh->device_attr.min_single_wqe_log_num_of_strides;
+			sh->dev_cap.min_single_wqe_log_num_of_strides;
 		config->mprq.log_max_stride_num =
-			sh->device_attr.max_single_wqe_log_num_of_strides;
+			sh->dev_cap.max_single_wqe_log_num_of_strides;
 	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
 			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
@@ -1052,9 +1040,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		"tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((sh->device_attr.tunnel_offloads_caps &
+	mpls_en = ((sh->dev_cap.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (sh->device_attr.tunnel_offloads_caps &
+		   (sh->dev_cap.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
 	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
 		mpls_en ? "" : "not ");
@@ -1215,7 +1203,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	config->hw_csum = !!(sh->device_attr.device_cap_flags_ex &
+	config->hw_csum = !!(sh->dev_cap.device_cap_flags_ex &
 			    IBV_DEVICE_RAW_IP_CSUM);
 	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
 		(config->hw_csum ? "" : "not "));
@@ -1224,7 +1212,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	DRV_LOG(DEBUG, "counters are not supported");
 #endif
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
+		sh->dev_cap.max_rwq_indirection_table_size;
 	/*
 	 * Remove this check once DPDK supports larger/variable
 	 * indirection tables.
@@ -1233,16 +1221,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
 	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
 		config->ind_table_max_size);
-	config->hw_vlan_strip = !!(sh->device_attr.raw_packet_caps &
+	config->hw_vlan_strip = !!(sh->dev_cap.raw_packet_caps &
 				  IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
 	DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 		(config->hw_vlan_strip ? "" : "not "));
-	config->hw_fcs_strip = !!(sh->device_attr.raw_packet_caps &
+	config->hw_fcs_strip = !!(sh->dev_cap.raw_packet_caps &
 				 IBV_RAW_PACKET_CAP_SCATTER_FCS);
 #if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
-	hw_padding = !!sh->device_attr.rx_pad_end_addr_align;
+	hw_padding = !!sh->dev_cap.rx_pad_end_addr_align;
 #elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
-	hw_padding = !!(sh->device_attr.device_cap_flags_ex &
+	hw_padding = !!(sh->dev_cap.device_cap_flags_ex &
 			IBV_DEVICE_PCI_WRITE_END_PADDING);
 #endif
 	if (config->hw_padding && !hw_padding) {
@@ -1251,11 +1239,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	} else if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
 	}
-	config->tso = (sh->device_attr.max_tso > 0 &&
-		      (sh->device_attr.tso_supported_qpts &
+	config->tso = (sh->dev_cap.max_tso > 0 &&
+		      (sh->dev_cap.tso_supported_qpts &
 		       (1 << IBV_QPT_RAW_PACKET)));
 	if (config->tso)
-		config->tso_max_payload_sz = sh->device_attr.max_tso;
+		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	/*
 	 * MPW is disabled by default, while the Enhanced MPW is enabled
 	 * by default.
@@ -1382,7 +1370,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
+	    !(sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
 		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
 		config->cqe_comp = 0;
 	}
diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c
index 722017efa4..73c44138de 100644
--- a/drivers/net/mlx5/linux/mlx5_verbs.c
+++ b/drivers/net/mlx5/linux/mlx5_verbs.c
@@ -872,13 +872,12 @@ mlx5_txq_ibv_qp_create(struct rte_eth_dev *dev, uint16_t idx)
 	/* CQ to be associated with the receive queue. */
 	qp_attr.recv_cq = txq_ctrl->obj->cq;
 	/* Max number of outstanding WRs. */
-	qp_attr.cap.max_send_wr = ((priv->sh->device_attr.max_qp_wr < desc) ?
-				   priv->sh->device_attr.max_qp_wr : desc);
+	qp_attr.cap.max_send_wr = RTE_MIN(priv->sh->dev_cap.max_qp_wr, desc);
 	/*
 	 * Max number of scatter/gather elements in a WR, must be 1 to prevent
 	 * libmlx5 from trying to affect must be 1 to prevent libmlx5 from
 	 * trying to affect too much memory. TX gather is not impacted by the
-	 * device_attr.max_sge limit and will still work properly.
+	 * dev_cap.max_sge limit and will still work properly.
 	 */
 	qp_attr.cap.max_send_sge = 1;
 	qp_attr.qp_type = IBV_QPT_RAW_PACKET,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index e1fe8f9375..b33dc0e7b4 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1262,9 +1262,9 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	sh->esw_mode = !!(spawn->info.master || spawn->info.representor);
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
-	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
+	err = mlx5_os_capabilities_prepare(sh);
 	if (err) {
-		DRV_LOG(DEBUG, "mlx5_os_get_dev_attr() failed");
+		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
 	sh->refcnt = 1;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a713e61572..fd6350eee7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -114,32 +114,31 @@ struct mlx5_flow_cb_ctx {
 	void *data2;
 };
 
-/* Device attributes used in mlx5 PMD */
-struct mlx5_dev_attr {
-	uint64_t	device_cap_flags_ex;
-	int		max_qp_wr;
-	int		max_sge;
-	int		max_cq;
-	int		max_qp;
-	int		max_cqe;
-	uint32_t	max_pd;
-	uint32_t	max_mr;
-	uint32_t	max_srq;
-	uint32_t	max_srq_wr;
-	uint32_t	raw_packet_caps;
-	uint32_t	max_rwq_indirection_table_size;
-	uint32_t	max_tso;
-	uint32_t	tso_supported_qpts;
-	uint64_t	flags;
-	uint64_t	comp_mask;
-	uint32_t	sw_parsing_offloads;
-	uint32_t	min_single_stride_log_num_of_bytes;
-	uint32_t	max_single_stride_log_num_of_bytes;
-	uint32_t	min_single_wqe_log_num_of_strides;
-	uint32_t	max_single_wqe_log_num_of_strides;
-	uint32_t	stride_supported_qpts;
-	uint32_t	tunnel_offloads_caps;
-	char		fw_ver[64];
+/* Device capabilities structure which isn't changed in any stage. */
+struct mlx5_dev_cap {
+	uint64_t device_cap_flags_ex;
+	int max_cq; /* Maximum number of supported CQs */
+	int max_qp; /* Maximum number of supported QPs. */
+	int max_qp_wr; /* Maximum number of outstanding WR on any WQ. */
+	int max_sge;
+	/* Maximum number of s/g per WR for SQ & RQ of QP for non RDMA Read
+	 * operations.
+	 */
+	uint32_t raw_packet_caps;
+	uint32_t max_rwq_indirection_table_size;
+	/* Maximum receive WQ indirection table size. */
+	uint32_t max_tso; /* Maximum TCP payload for TSO. */
+	uint32_t tso_supported_qpts;
+	uint64_t flags;
+	uint64_t comp_mask;
+	uint32_t sw_parsing_offloads;
+	uint32_t min_single_stride_log_num_of_bytes;
+	uint32_t max_single_stride_log_num_of_bytes;
+	uint32_t min_single_wqe_log_num_of_strides;
+	uint32_t max_single_wqe_log_num_of_strides;
+	uint32_t stride_supported_qpts;
+	uint32_t tunnel_offloads_caps;
+	char fw_ver[64]; /* Firmware version of this device. */
 };
 
 /** Data associated with devices to spawn. */
@@ -1165,7 +1164,7 @@ struct mlx5_dev_ctx_shared {
 	uint32_t tdn; /* Transport Domain number. */
 	char ibdev_name[MLX5_FS_NAME_MAX]; /* SYSFS dev name. */
 	char ibdev_path[MLX5_FS_PATH_MAX]; /* SYSFS dev path for secondary */
-	struct mlx5_dev_attr device_attr; /* Device properties. */
+	struct mlx5_dev_cap dev_cap; /* Device capabilities. */
 	int numa_node; /* Numa node of backing physical device. */
 	/* Packet pacing related structure. */
 	struct mlx5_dev_txpp txpp;
@@ -1792,8 +1791,7 @@ void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev);
 /* mlx5_os.c */
 
 struct rte_pci_driver;
-int mlx5_os_get_dev_attr(struct mlx5_common_device *dev,
-			 struct mlx5_dev_attr *dev_attr);
+int mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_free_shared_dr(struct mlx5_priv *priv);
 int mlx5_os_net_probe(struct mlx5_common_device *cdev);
 void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 97c8925044..553df6424d 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -1305,7 +1305,7 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	wqe_size = RTE_ALIGN(wqe_size, MLX5_WQE_SIZE) / MLX5_WQE_SIZE;
 	/* Create Send Queue object with DevX. */
 	wqe_n = RTE_MIN((1UL << txq_data->elts_n) * wqe_size,
-			(uint32_t)priv->sh->device_attr.max_qp_wr);
+			(uint32_t)priv->sh->dev_cap.max_qp_wr);
 	log_desc_n = log2above(wqe_n);
 	ret = mlx5_txq_create_devx_sq_resources(dev, idx, log_desc_n);
 	if (ret) {
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 06d5acb75f..d970eb6904 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -313,8 +313,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * Since we need one CQ per QP, the limit is the minimum number
 	 * between the two values.
 	 */
-	max = RTE_MIN(priv->sh->device_attr.max_cq,
-		      priv->sh->device_attr.max_qp);
+	max = RTE_MIN(priv->sh->dev_cap.max_cq, priv->sh->dev_cap.max_qp);
 	/* max_rx_queues is uint16_t. */
 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
 	info->max_rx_queues = max;
@@ -516,7 +515,7 @@ int
 mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_attr *attr = &priv->sh->device_attr;
+	struct mlx5_dev_cap *attr = &priv->sh->dev_cap;
 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
 
 	if (fw_size < size)
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index d128b3e978..cd8c451286 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -215,10 +215,10 @@ mlx5_rxq_start(struct rte_eth_dev *dev)
 		/* Should not release Rx queues but return immediately. */
 		return -rte_errno;
 	}
-	DRV_LOG(DEBUG, "Port %u device_attr.max_qp_wr is %d.",
-		dev->data->port_id, priv->sh->device_attr.max_qp_wr);
-	DRV_LOG(DEBUG, "Port %u device_attr.max_sge is %d.",
-		dev->data->port_id, priv->sh->device_attr.max_sge);
+	DRV_LOG(DEBUG, "Port %u dev_cap.max_qp_wr is %d.",
+		dev->data->port_id, priv->sh->dev_cap.max_qp_wr);
+	DRV_LOG(DEBUG, "Port %u dev_cap.max_sge is %d.",
+		dev->data->port_id, priv->sh->dev_cap.max_sge);
 	for (i = 0; i != priv->rxqs_n; ++i) {
 		struct mlx5_rxq_priv *rxq = mlx5_rxq_ref(dev, i);
 		struct mlx5_rxq_ctrl *rxq_ctrl;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4e0bf7af9c..56e0937ca3 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -714,7 +714,7 @@ txq_calc_inline_max(struct mlx5_txq_ctrl *txq_ctrl)
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	unsigned int wqe_size;
 
-	wqe_size = priv->sh->device_attr.max_qp_wr / desc;
+	wqe_size = priv->sh->dev_cap.max_qp_wr / desc;
 	if (!wqe_size)
 		return 0;
 	/*
@@ -982,8 +982,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_mode, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_send > max_inline &&
@@ -994,8 +993,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_send, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_empw > max_inline &&
@@ -1006,8 +1004,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_empw, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.tso_en && max_inline < MLX5_MAX_TSO_HEADER) {
@@ -1016,8 +1013,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			MLX5_MAX_TSO_HEADER, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_send > max_inline) {
@@ -1098,12 +1094,12 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (txq_adjust_params(tmpl))
 		goto error;
 	if (txq_calc_wqebb_cnt(tmpl) >
-	    priv->sh->device_attr.max_qp_wr) {
+	    priv->sh->dev_cap.max_qp_wr) {
 		DRV_LOG(ERR,
 			"port %u Tx WQEBB count (%d) exceeds the limit (%d),"
 			" try smaller queue size",
 			dev->data->port_id, txq_calc_wqebb_cnt(tmpl),
-			priv->sh->device_attr.max_qp_wr);
+			priv->sh->dev_cap.max_qp_wr);
 		rte_errno = ENOMEM;
 		goto error;
 	}
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index eaa63ad50f..16fd54091e 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -143,55 +143,42 @@ mlx5_init_once(void)
 }
 
 /**
- * Get mlx5 device attributes.
+ * Get mlx5 device capabilities.
  *
- * @param cdev
- *   Pointer to mlx5 device.
- *
- * @param device_attr
- *   Pointer to mlx5 device attributes.
+ * @param sh
+ *   Pointer to shared device context.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
-		     struct mlx5_dev_attr *device_attr)
+mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
-	struct mlx5_context *mlx5_ctx;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+	struct mlx5_context *mlx5_ctx = sh->cdev->ctx;
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
 
-	if (!cdev || !cdev->ctx) {
-		rte_errno = EINVAL;
-		return -rte_errno;
-	}
-	mlx5_ctx = (struct mlx5_context *)cdev->ctx;
-	memset(device_attr, 0, sizeof(*device_attr));
-	device_attr->max_cq = 1 << cdev->config.hca_attr.log_max_cq;
-	device_attr->max_qp = 1 << cdev->config.hca_attr.log_max_qp;
-	device_attr->max_qp_wr = 1 << cdev->config.hca_attr.log_max_qp_sz;
-	device_attr->max_cqe = 1 << cdev->config.hca_attr.log_max_cq_sz;
-	device_attr->max_mr = 1 << cdev->config.hca_attr.log_max_mrw_sz;
-	device_attr->max_pd = 1 << cdev->config.hca_attr.log_max_pd;
-	device_attr->max_srq = 1 << cdev->config.hca_attr.log_max_srq;
-	device_attr->max_srq_wr = 1 << cdev->config.hca_attr.log_max_srq_sz;
-	device_attr->max_tso = 1 << cdev->config.hca_attr.max_lso_cap;
-	if (cdev->config.hca_attr.rss_ind_tbl_cap) {
-		device_attr->max_rwq_indirection_table_size =
-			1 << cdev->config.hca_attr.rss_ind_tbl_cap;
-	}
-	device_attr->sw_parsing_offloads =
-		mlx5_get_supported_sw_parsing_offloads(&cdev->config.hca_attr);
-	device_attr->tunnel_offloads_caps =
-		mlx5_get_supported_tunneling_offloads(&cdev->config.hca_attr);
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
-		DRV_LOG(ERR, "Failed to get device hca_iseg");
+		DRV_LOG(ERR, "Failed to get device hca_iseg.");
 		rte_errno = errno;
 		return -rte_errno;
 	}
-	snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
+	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.max_cq = 1 << hca_attr->log_max_cq;
+	sh->dev_cap.max_qp = 1 << hca_attr->log_max_qp;
+	sh->dev_cap.max_qp_wr = 1 << hca_attr->log_max_qp_sz;
+	sh->dev_cap.max_tso = 1 << hca_attr->max_lso_cap;
+	if (hca_attr->rss_ind_tbl_cap) {
+		sh->dev_cap.max_rwq_indirection_table_size =
+			1 << hca_attr->rss_ind_tbl_cap;
+	}
+	sh->dev_cap.sw_parsing_offloads =
+		mlx5_get_supported_sw_parsing_offloads(hca_attr);
+	sh->dev_cap.tunnel_offloads_caps =
+		mlx5_get_supported_tunneling_offloads(hca_attr);
+	snprintf(sh->dev_cap.fw_ver, 64, "%x.%x.%04x",
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
@@ -335,12 +322,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	DRV_LOG(DEBUG, "MPW isn't supported");
-	config->swp = sh->device_attr.sw_parsing_offloads &
+	config->swp = sh->dev_cap.sw_parsing_offloads &
 		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
-	config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
+		sh->dev_cap.max_rwq_indirection_table_size;
+	config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
@@ -410,7 +397,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "counters are not supported");
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
+		sh->dev_cap.max_rwq_indirection_table_size;
 	/*
 	 * Remove this check once DPDK supports larger/variable
 	 * indirection tables.
@@ -423,9 +410,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	}
-	config->tso = (sh->device_attr.max_tso > 0);
+	config->tso = (sh->dev_cap.max_tso > 0);
 	if (config->tso)
-		config->tso_max_payload_sz = sh->device_attr.max_tso;
+		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	DRV_LOG(DEBUG, "%sMPS is %s.",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 15/20] net/mlx5: concentrate all device configurations
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (13 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 14/20] net/mlx5: rearrange device attribute structure Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 16/20] net/mlx5: add share device context config structure Michael Baum
                   ` (5 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Move all device configure to be performed by mlx5_os_cap_config()
function instead of the spawn function.
In addition move all relevant fields from mlx5_dev_config structure to
mlx5_dev_cap.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c      | 497 +++++++++++++-------------
 drivers/net/mlx5/linux/mlx5_vlan_os.c |   3 +-
 drivers/net/mlx5/mlx5.c               |  11 +-
 drivers/net/mlx5/mlx5.h               |  78 ++--
 drivers/net/mlx5/mlx5_devx.c          |   6 +-
 drivers/net/mlx5/mlx5_ethdev.c        |  12 +-
 drivers/net/mlx5/mlx5_flow.c          |   4 +-
 drivers/net/mlx5/mlx5_rxmode.c        |   8 +-
 drivers/net/mlx5/mlx5_rxq.c           |  34 +-
 drivers/net/mlx5/mlx5_trigger.c       |   5 +-
 drivers/net/mlx5/mlx5_txq.c           |  36 +-
 drivers/net/mlx5/mlx5_vlan.c          |   4 +-
 drivers/net/mlx5/windows/mlx5_os.c    | 101 +++---
 13 files changed, 380 insertions(+), 419 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index b6848fc34c..13db399b5e 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -141,11 +141,12 @@ int
 mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
 	int err;
-	struct ibv_context *ctx = sh->cdev->ctx;
+	struct mlx5_common_device *cdev = sh->cdev;
+	struct mlx5_hca_attr *hca_attr = &cdev->config.hca_attr;
 	struct ibv_device_attr_ex attr_ex;
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 
-	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
+	err = mlx5_glue->query_device_ex(cdev->ctx, NULL, &attr_ex);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
@@ -159,45 +160,229 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
 	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
 #endif
-	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
+	err = mlx5_glue->dv_query_device(cdev->ctx, &dv_attr);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
 	}
 	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
-	sh->dev_cap.device_cap_flags_ex = attr_ex.device_cap_flags_ex;
+	if (mlx5_dev_is_pci(cdev->dev))
+		sh->dev_cap.vf = mlx5_dev_is_vf_pci(RTE_DEV_TO_PCI(cdev->dev));
+	else
+		sh->dev_cap.sf = 1;
 	sh->dev_cap.max_qp_wr = attr_ex.orig_attr.max_qp_wr;
 	sh->dev_cap.max_sge = attr_ex.orig_attr.max_sge;
 	sh->dev_cap.max_cq = attr_ex.orig_attr.max_cq;
 	sh->dev_cap.max_qp = attr_ex.orig_attr.max_qp;
-	sh->dev_cap.raw_packet_caps = attr_ex.raw_packet_caps;
-	sh->dev_cap.max_rwq_indirection_table_size =
-		attr_ex.rss_caps.max_rwq_indirection_table_size;
-	sh->dev_cap.max_tso = attr_ex.tso_caps.max_tso;
-	sh->dev_cap.tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
+#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
+	sh->dev_cap.dest_tir = 1;
+#endif
+#if defined(HAVE_IBV_FLOW_DV_SUPPORT) && defined(HAVE_MLX5DV_DR)
+	DRV_LOG(DEBUG, "DV flow is supported.");
+	sh->dev_cap.dv_flow_en = 1;
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (hca_attr->eswitch_manager && sh->dev_cap.dv_flow_en && sh->esw_mode)
+		sh->dev_cap.dv_esw_en = 1;
+#endif
+	/*
+	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
+	 * as all ConnectX-5 devices.
+	 */
+	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+			DRV_LOG(DEBUG, "Enhanced MPW is supported.");
+			sh->dev_cap.mps = MLX5_MPW_ENHANCED;
+		} else {
+			DRV_LOG(DEBUG, "MPW is supported.");
+			sh->dev_cap.mps = MLX5_MPW;
+		}
+	} else {
+		DRV_LOG(DEBUG, "MPW isn't supported.");
+		sh->dev_cap.mps = MLX5_MPW_DISABLED;
+	}
+#if (RTE_CACHE_LINE_SIZE == 128)
+	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)
+		sh->dev_cap.cqe_comp = 1;
+	DRV_LOG(DEBUG, "Rx CQE 128B compression is %ssupported.",
+		sh->dev_cap.cqe_comp ? "" : "not ");
+#else
+	sh->dev_cap.cqe_comp = 1;
+#endif
+#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
+	sh->dev_cap.mpls_en =
+		((dv_attr.tunnel_offloads_caps &
+		  MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
+		 (dv_attr.tunnel_offloads_caps &
+		  MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
+	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported.",
+		sh->dev_cap.mpls_en ? "" : "not ");
+#else
+	DRV_LOG(WARNING,
+		"MPLS over GRE/UDP tunnel offloading disabled due to old OFED/rdma-core version or firmware configuration");
+#endif
+#if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
+	sh->dev_cap.hw_padding = !!attr_ex.rx_pad_end_addr_align;
+#elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
+	sh->dev_cap.hw_padding = !!(attr_ex.device_cap_flags_ex &
+				    IBV_DEVICE_PCI_WRITE_END_PADDING);
+#endif
+	sh->dev_cap.hw_csum =
+		!!(attr_ex.device_cap_flags_ex & IBV_DEVICE_RAW_IP_CSUM);
+	DRV_LOG(DEBUG, "Checksum offloading is %ssupported.",
+		sh->dev_cap.hw_csum ? "" : "not ");
+	sh->dev_cap.hw_vlan_strip = !!(attr_ex.raw_packet_caps &
+				       IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
+	DRV_LOG(DEBUG, "VLAN stripping is %ssupported.",
+		(sh->dev_cap.hw_vlan_strip ? "" : "not "));
+	sh->dev_cap.hw_fcs_strip = !!(attr_ex.raw_packet_caps &
+				      IBV_RAW_PACKET_CAP_SCATTER_FCS);
+#if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
+	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
+	DRV_LOG(DEBUG, "Counters are not supported.");
+#endif
+	/*
+	 * DPDK doesn't support larger/variable indirection tables.
+	 * Once DPDK supports it, take max size from device attr.
+	 */
+	sh->dev_cap.ind_table_max_size =
+			RTE_MIN(attr_ex.rss_caps.max_rwq_indirection_table_size,
+				(unsigned int)RTE_ETH_RSS_RETA_SIZE_512);
+	DRV_LOG(DEBUG, "Maximum Rx indirection table size is %u",
+		sh->dev_cap.ind_table_max_size);
+	sh->dev_cap.tso = (attr_ex.tso_caps.max_tso > 0 &&
+			   (attr_ex.tso_caps.supported_qpts &
+			    (1 << IBV_QPT_RAW_PACKET)));
+	if (sh->dev_cap.tso)
+		sh->dev_cap.tso_max_payload_sz = attr_ex.tso_caps.max_tso;
 	strlcpy(sh->dev_cap.fw_ver, attr_ex.orig_attr.fw_ver,
 		sizeof(sh->dev_cap.fw_ver));
-	sh->dev_cap.flags = dv_attr.flags;
-	sh->dev_cap.comp_mask = dv_attr.comp_mask;
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	sh->dev_cap.sw_parsing_offloads =
-		dv_attr.sw_parsing_caps.sw_parsing_offloads;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		sh->dev_cap.swp = dv_attr.sw_parsing_caps.sw_parsing_offloads &
+				  (MLX5_SW_PARSING_CAP |
+				   MLX5_SW_PARSING_CSUM_CAP |
+				   MLX5_SW_PARSING_TSO_CAP);
+	DRV_LOG(DEBUG, "SWP support: %u", sh->dev_cap.swp);
 #endif
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	sh->dev_cap.min_single_stride_log_num_of_bytes =
-		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
-	sh->dev_cap.max_single_stride_log_num_of_bytes =
-		dv_attr.striding_rq_caps.max_single_stride_log_num_of_bytes;
-	sh->dev_cap.min_single_wqe_log_num_of_strides =
-		dv_attr.striding_rq_caps.min_single_wqe_log_num_of_strides;
-	sh->dev_cap.max_single_wqe_log_num_of_strides =
-		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
-	sh->dev_cap.stride_supported_qpts =
-		dv_attr.striding_rq_caps.supported_qpts;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
+		struct mlx5dv_striding_rq_caps *strd_rq_caps =
+				&dv_attr.striding_rq_caps;
+
+		sh->dev_cap.mprq.enabled = 1;
+		sh->dev_cap.mprq.log_min_stride_size =
+			strd_rq_caps->min_single_stride_log_num_of_bytes;
+		sh->dev_cap.mprq.log_max_stride_size =
+			strd_rq_caps->max_single_stride_log_num_of_bytes;
+		sh->dev_cap.mprq.log_min_stride_num =
+			strd_rq_caps->min_single_wqe_log_num_of_strides;
+		sh->dev_cap.mprq.log_max_stride_num =
+			strd_rq_caps->max_single_wqe_log_num_of_strides;
+		sh->dev_cap.mprq.log_min_stride_wqe_size =
+					cdev->config.devx ?
+					hca_attr->log_min_stride_wqe_sz :
+					MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE;
+		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %u",
+			sh->dev_cap.mprq.log_min_stride_size);
+		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %u",
+			sh->dev_cap.mprq.log_max_stride_size);
+		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %u",
+			sh->dev_cap.mprq.log_min_stride_num);
+		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %u",
+			sh->dev_cap.mprq.log_max_stride_num);
+		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %u",
+			sh->dev_cap.mprq.log_min_stride_wqe_size);
+		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
+			strd_rq_caps->supported_qpts);
+		DRV_LOG(DEBUG, "Device supports Multi-Packet RQ.");
+	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	sh->dev_cap.tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		sh->dev_cap.tunnel_en = dv_attr.tunnel_offloads_caps &
+					(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
+					 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
+					 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
+	}
+	if (sh->dev_cap.tunnel_en) {
+		DRV_LOG(DEBUG, "Tunnel offloading is supported for %s%s%s",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : "");
+	} else {
+		DRV_LOG(DEBUG, "Tunnel offloading is not supported.");
+	}
+#else
+	DRV_LOG(WARNING,
+		"Tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
+	if (!sh->cdev->config.devx)
+		return 0;
+	/* Check capabilities for Packet Pacing. */
+	DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz.",
+		hca_attr->dev_freq_khz);
+	DRV_LOG(DEBUG, "Packet pacing is %ssupported.",
+		hca_attr->qos.packet_pacing ? "" : "not ");
+	DRV_LOG(DEBUG, "Cross channel ops are %ssupported.",
+		hca_attr->cross_channel ? "" : "not ");
+	DRV_LOG(DEBUG, "WQE index ignore is %ssupported.",
+		hca_attr->wqe_index_ignore ? "" : "not ");
+	DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported.",
+		hca_attr->non_wire_sq ? "" : "not ");
+	DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
+		hca_attr->log_max_static_sq_wq ? "" : "not ",
+		hca_attr->log_max_static_sq_wq);
+	DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported.",
+		hca_attr->qos.wqe_rate_pp ? "" : "not ");
+	sh->dev_cap.txpp_en = hca_attr->qos.packet_pacing;
+	if (!hca_attr->cross_channel) {
+		DRV_LOG(DEBUG,
+			"Cross channel operations are required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->wqe_index_ignore) {
+		DRV_LOG(DEBUG,
+			"WQE index ignore feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->non_wire_sq) {
+		DRV_LOG(DEBUG,
+			"Non-wire SQ feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->log_max_static_sq_wq) {
+		DRV_LOG(DEBUG,
+			"Static WQE SQ feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->qos.wqe_rate_pp) {
+		DRV_LOG(DEBUG,
+			"WQE rate mode is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET
+	DRV_LOG(DEBUG,
+		"DevX does not provide UAR offset, can't create queues for packet pacing.");
+	sh->dev_cap.txpp_en = 0;
+#endif
+	/* Check for LRO support. */
+	if (sh->dev_cap.dest_tir && sh->dev_cap.dv_flow_en &&
+	    hca_attr->lro_cap) {
+		/* TBD check tunnel lro caps. */
+		sh->dev_cap.lro_supported = 1;
+		DRV_LOG(DEBUG, "Device supports LRO.");
+		DRV_LOG(DEBUG,
+			"LRO minimal size of TCP segment required for coalescing is %d bytes.",
+			hca_attr->lro_min_mss_size);
+	}
+	sh->dev_cap.scatter_fcs_w_decap_disable =
+					hca_attr->scatter_fcs_w_decap_disable;
+	sh->dev_cap.rq_delay_drop_en = hca_attr->rq_delay_drop;
+	mlx5_rt_timestamp_config(sh, hca_attr);
 	return 0;
 }
 
@@ -840,11 +1025,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
-	unsigned int hw_padding = 0;
-	unsigned int mps;
-	unsigned int mpls_en = 0;
-	unsigned int swp = 0;
-	unsigned int mprq = 0;
 	struct rte_ether_addr mac;
 	char name[RTE_ETH_NAME_MAX_LEN];
 	int own_domain_id = 0;
@@ -939,18 +1119,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (!sh)
 		return NULL;
 	/* Update final values for devargs before check sibling config. */
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
+	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
 		config->dv_flow_en = 0;
 	}
-#endif
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(hca_attr->eswitch_manager && config->dv_flow_en && sh->esw_mode))
+	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
+		DRV_LOG(WARNING, "E-Switch DV flow is not supported.");
 		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
+	}
 	if (config->dv_miss_info && config->dv_esw_en)
 		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
 	if (!config->dv_esw_en &&
@@ -964,93 +1140,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
 	if (err)
 		goto error;
-#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
-	config->dest_tir = 1;
-#endif
-	/*
-	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
-	 * as all ConnectX-5 devices.
-	 */
-	if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
-			DRV_LOG(DEBUG, "enhanced MPW is supported");
-			mps = MLX5_MPW_ENHANCED;
-		} else {
-			DRV_LOG(DEBUG, "MPW is supported");
-			mps = MLX5_MPW;
-		}
-	} else {
-		DRV_LOG(DEBUG, "MPW isn't supported");
-		mps = MLX5_MPW_DISABLED;
-	}
-#ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = sh->dev_cap.sw_parsing_offloads;
-	DRV_LOG(DEBUG, "SWP support: %u", swp);
-#endif
-	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
-		MLX5_SW_PARSING_TSO_CAP);
-#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
-		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			sh->dev_cap.min_single_stride_log_num_of_bytes);
-		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			sh->dev_cap.max_single_stride_log_num_of_bytes);
-		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			sh->dev_cap.min_single_wqe_log_num_of_strides);
-		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			sh->dev_cap.max_single_wqe_log_num_of_strides);
-		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			sh->dev_cap.stride_supported_qpts);
-		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
-			config->mprq.log_min_stride_wqe_size);
-		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
-		mprq = 1;
-		config->mprq.log_min_stride_size =
-			sh->dev_cap.min_single_stride_log_num_of_bytes;
-		config->mprq.log_max_stride_size =
-			sh->dev_cap.max_single_stride_log_num_of_bytes;
-		config->mprq.log_min_stride_num =
-			sh->dev_cap.min_single_wqe_log_num_of_strides;
-		config->mprq.log_max_stride_num =
-			sh->dev_cap.max_single_wqe_log_num_of_strides;
-	}
-#endif
-#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
-			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
-			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
-			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
-	}
-	if (config->tunnel_en) {
-		DRV_LOG(DEBUG, "tunnel offloading is supported for %s%s%s",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN ? "[VXLAN]" : "",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE ? "[GRE]" : "",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE ? "[GENEVE]" : ""
-		);
-	} else {
-		DRV_LOG(DEBUG, "tunnel offloading is not supported");
-	}
-#else
-	DRV_LOG(WARNING,
-		"tunnel offloading disabled due to old OFED/rdma-core version");
-#endif
-#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((sh->dev_cap.tunnel_offloads_caps &
-		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (sh->dev_cap.tunnel_offloads_caps &
-		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
-	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
-		mpls_en ? "" : "not ");
-#else
-	DRV_LOG(WARNING, "MPLS over GRE/UDP tunnel offloading disabled due to"
-		" old OFED/rdma-core version or firmware configuration");
-#endif
-	config->mpls_en = mpls_en;
 	nl_rdma = mlx5_nl_init(NETLINK_RDMA);
 	/* Check port status. */
 	if (spawn->phys_port <= UINT8_MAX) {
@@ -1203,80 +1292,40 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	config->hw_csum = !!(sh->dev_cap.device_cap_flags_ex &
-			    IBV_DEVICE_RAW_IP_CSUM);
-	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-		(config->hw_csum ? "" : "not "));
-#if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
-	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
-	DRV_LOG(DEBUG, "counters are not supported");
-#endif
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	/*
-	 * Remove this check once DPDK supports larger/variable
-	 * indirection tables.
-	 */
-	if (config->ind_table_max_size > (unsigned int)RTE_ETH_RSS_RETA_SIZE_512)
-		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
-	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
-		config->ind_table_max_size);
-	config->hw_vlan_strip = !!(sh->dev_cap.raw_packet_caps &
-				  IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
-	DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
-		(config->hw_vlan_strip ? "" : "not "));
-	config->hw_fcs_strip = !!(sh->dev_cap.raw_packet_caps &
-				 IBV_RAW_PACKET_CAP_SCATTER_FCS);
-#if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
-	hw_padding = !!sh->dev_cap.rx_pad_end_addr_align;
-#elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
-	hw_padding = !!(sh->dev_cap.device_cap_flags_ex &
-			IBV_DEVICE_PCI_WRITE_END_PADDING);
-#endif
-	if (config->hw_padding && !hw_padding) {
+	if (config->hw_padding && !sh->dev_cap.hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	} else if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
 	}
-	config->tso = (sh->dev_cap.max_tso > 0 &&
-		      (sh->dev_cap.tso_supported_qpts &
-		       (1 << IBV_QPT_RAW_PACKET)));
-	if (config->tso)
-		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	/*
 	 * MPW is disabled by default, while the Enhanced MPW is enabled
 	 * by default.
 	 */
 	if (config->mps == MLX5_ARG_UNSET)
-		config->mps = (mps == MLX5_MPW_ENHANCED) ? MLX5_MPW_ENHANCED :
-							  MLX5_MPW_DISABLED;
+		config->mps = (sh->dev_cap.mps == MLX5_MPW_ENHANCED) ?
+			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
 	else
-		config->mps = config->mps ? mps : MLX5_MPW_DISABLED;
+		config->mps = config->mps ? sh->dev_cap.mps : MLX5_MPW_DISABLED;
 	DRV_LOG(INFO, "%sMPS is %s",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
-		/* Check for LRO support. */
-		if (config->dest_tir && hca_attr->lro_cap &&
-		    config->dv_flow_en) {
-			/* TBD check tunnel lro caps. */
-			config->lro.supported = hca_attr->lro_cap;
-			DRV_LOG(DEBUG, "Device supports LRO");
+		/* LRO is supported only when DV flow enabled. */
+		if (sh->dev_cap.lro_supported && config->dv_flow_en)
+			sh->dev_cap.lro_supported = 0;
+		if (sh->dev_cap.lro_supported) {
 			/*
 			 * If LRO timeout is not configured by application,
 			 * use the minimal supported value.
 			 */
-			if (!config->lro.timeout)
-				config->lro.timeout =
+			if (!config->lro_timeout)
+				config->lro_timeout =
 				       hca_attr->lro_timer_supported_periods[0];
 			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
-				config->lro.timeout);
-			DRV_LOG(DEBUG, "LRO minimal size of TCP segment "
-				"required for coalescing is %d bytes",
-				hca_attr->lro_min_mss_size);
+				config->lro_timeout);
 		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
@@ -1369,9 +1418,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif
 	}
-	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
-		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
+	if (config->cqe_comp && !sh->dev_cap.cqe_comp) {
+		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
@@ -1388,68 +1436,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
 			config->cqe_comp ? "" : "not ");
-	if (config->tx_pp) {
-		DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz",
-			hca_attr->dev_freq_khz);
-		DRV_LOG(DEBUG, "Packet pacing is %ssupported",
-			hca_attr->qos.packet_pacing ? "" : "not ");
-		DRV_LOG(DEBUG, "Cross channel ops are %ssupported",
-			hca_attr->cross_channel ? "" : "not ");
-		DRV_LOG(DEBUG, "WQE index ignore is %ssupported",
-			hca_attr->wqe_index_ignore ? "" : "not ");
-		DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported",
-			hca_attr->non_wire_sq ? "" : "not ");
-		DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
-			hca_attr->log_max_static_sq_wq ? "" : "not ",
-			hca_attr->log_max_static_sq_wq);
-		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
-			hca_attr->qos.wqe_rate_pp ? "" : "not ");
-		if (!sh->cdev->config.devx) {
-			DRV_LOG(ERR, "DevX is required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->qos.packet_pacing) {
-			DRV_LOG(ERR, "Packet pacing is not supported");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->cross_channel) {
-			DRV_LOG(ERR, "Cross channel operations are"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->wqe_index_ignore) {
-			DRV_LOG(ERR, "WQE index ignore feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->non_wire_sq) {
-			DRV_LOG(ERR, "Non-wire SQ feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->log_max_static_sq_wq) {
-			DRV_LOG(ERR, "Static WQE SQ feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->qos.wqe_rate_pp) {
-			DRV_LOG(ERR, "WQE rate mode is required"
-				     " for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET
-		DRV_LOG(ERR, "DevX does not provide UAR offset,"
-			     " can't create queues for packet pacing");
+	if (config->tx_pp && !sh->dev_cap.txpp_en) {
+		DRV_LOG(ERR, "Packet pacing is not supported.");
 		err = ENODEV;
 		goto error;
-#endif
 	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
 		if (!hca_attr->rq_delay_drop) {
@@ -1460,19 +1450,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->cdev->config.devx)
-		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	/*
 	 * If HW has bug working with tunnel packet decapsulation and
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
 	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
 	 */
-	if (hca_attr->scatter_fcs_w_decap_disable && config->decap_en)
+	if (sh->dev_cap.scatter_fcs_w_decap_disable && config->decap_en)
 		config->hw_fcs_strip = 0;
+	else
+		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
 		(config->hw_fcs_strip ? "" : "not "));
-	if (config->mprq.enabled && !mprq) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
+	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
+		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
 		config->mprq.enabled = 0;
 	}
 	if (config->max_dump_files_num == 0)
@@ -1556,7 +1546,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	eth_dev->rx_queue_count = mlx5_rx_queue_count;
 	/* Register MAC address. */
 	claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
-	if (config->vf && config->vf_nl_en)
+	if (sh->dev_cap.vf && config->vf_nl_en)
 		mlx5_nl_mac_addr_sync(priv->nl_socket_route,
 				      mlx5_ifindex(eth_dev),
 				      eth_dev->data->mac_addrs,
@@ -1598,7 +1588,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && config->dv_flow_en && config->dest_tir) {
+	if (sh->cdev->config.devx && config->dv_flow_en &&
+	    sh->dev_cap.dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
@@ -1949,8 +1940,7 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 }
 
 static void
-mlx5_os_config_default(struct mlx5_dev_config *config,
-		       struct mlx5_common_dev_config *cconf)
+mlx5_os_config_default(struct mlx5_dev_config *config)
 {
 	memset(config, 0, sizeof(*config));
 	config->mps = MLX5_ARG_UNSET;
@@ -1963,9 +1953,6 @@ mlx5_os_config_default(struct mlx5_dev_config *config,
 	config->vf_nl_en = 1;
 	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
 	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
-	config->mprq.log_min_stride_wqe_size = cconf->devx ?
-					cconf->hca_attr.log_min_stride_wqe_sz :
-					MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE;
 	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
 	config->dv_esw_en = 1;
 	config->dv_flow_en = 1;
@@ -2367,8 +2354,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 		uint32_t restore;
 
 		/* Default configuration. */
-		mlx5_os_config_default(&dev_config, &cdev->config);
-		dev_config.vf = mlx5_dev_is_vf_pci(pci_dev);
+		mlx5_os_config_default(&dev_config);
 		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
 						 &dev_config, &eth_da);
 		if (!list[i].eth_dev) {
@@ -2537,8 +2523,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	if (ret != 0)
 		return ret;
 	/* Set default config data. */
-	mlx5_os_config_default(&config, &cdev->config);
-	config.sf = 1;
+	mlx5_os_config_default(&config);
 	/* Init spawn data. */
 	spawn.max_port = 1;
 	spawn.phys_port = 1;
@@ -2769,7 +2754,7 @@ void
 mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const int vf = priv->config.vf;
+	const int vf = priv->sh->dev_cap.vf;
 
 	if (vf)
 		mlx5_nl_mac_addr_remove(priv->nl_socket_route,
@@ -2795,7 +2780,7 @@ mlx5_os_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
 		     uint32_t index)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const int vf = priv->config.vf;
+	const int vf = priv->sh->dev_cap.vf;
 	int ret = 0;
 
 	if (vf)
diff --git a/drivers/net/mlx5/linux/mlx5_vlan_os.c b/drivers/net/mlx5/linux/mlx5_vlan_os.c
index 005904bdfe..80ccd5a460 100644
--- a/drivers/net/mlx5/linux/mlx5_vlan_os.c
+++ b/drivers/net/mlx5/linux/mlx5_vlan_os.c
@@ -103,12 +103,11 @@ void *
 mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	struct mlx5_nl_vlan_vmwa_context *vmwa;
 	enum rte_hypervisor hv_type;
 
 	/* Do not engage workaround over PF. */
-	if (!config->vf)
+	if (!priv->sh->dev_cap.vf)
 		return NULL;
 	/* Check whether there is desired virtual environment */
 	hv_type = rte_hypervisor_get();
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b33dc0e7b4..bd23ce5afd 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1174,14 +1174,11 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
  *
  * @param sh
  *   Pointer to mlx5_dev_ctx_shared object.
- * @param config
- *   Device configuration parameters.
  * @param hca_attr
  *   Pointer to DevX HCA capabilities structure.
  */
 void
 mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
-			 struct mlx5_dev_config *config,
 			 struct mlx5_hca_attr *hca_attr)
 {
 	uint32_t dw_cnt = MLX5_ST_SZ_DW(register_mtutc);
@@ -1198,11 +1195,11 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 		/* MTUTC register is read successfully. */
 		ts_mode = MLX5_GET(register_mtutc, reg, time_stamp_mode);
 		if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-			config->rt_timestamp = 1;
+			sh->dev_cap.rt_timestamp = 1;
 	} else {
 		/* Kernel does not support register reading. */
 		if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-			config->rt_timestamp = 1;
+			sh->dev_cap.rt_timestamp = 1;
 	}
 }
 
@@ -1676,7 +1673,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 		mlx5_free(priv->rss_conf.rss_key);
 	if (priv->reta_idx != NULL)
 		mlx5_free(priv->reta_idx);
-	if (priv->config.vf)
+	if (priv->sh->dev_cap.vf)
 		mlx5_os_mac_addr_flush(dev);
 	if (priv->nl_socket_route >= 0)
 		close(priv->nl_socket_route);
@@ -2028,7 +2025,7 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 	} else if (strcmp(MLX5_MAX_DUMP_FILES_NUM, key) == 0) {
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
-		config->lro.timeout = tmp;
+		config->lro_timeout = tmp;
 	} else if (strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0) {
 		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index fd6350eee7..bda09cf96e 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -116,7 +116,6 @@ struct mlx5_flow_cb_ctx {
 
 /* Device capabilities structure which isn't changed in any stage. */
 struct mlx5_dev_cap {
-	uint64_t device_cap_flags_ex;
 	int max_cq; /* Maximum number of supported CQs */
 	int max_qp; /* Maximum number of supported QPs. */
 	int max_qp_wr; /* Maximum number of outstanding WR on any WQ. */
@@ -124,20 +123,40 @@ struct mlx5_dev_cap {
 	/* Maximum number of s/g per WR for SQ & RQ of QP for non RDMA Read
 	 * operations.
 	 */
-	uint32_t raw_packet_caps;
-	uint32_t max_rwq_indirection_table_size;
+	int mps; /* Multi-packet send supported mode. */
+	uint32_t vf:1; /* This is a VF. */
+	uint32_t sf:1; /* This is a SF. */
+	uint32_t txpp_en:1; /* Tx packet pacing is supported. */
+	uint32_t mpls_en:1; /* MPLS over GRE/UDP is supported. */
+	uint32_t cqe_comp:1; /* CQE compression is supported. */
+	uint32_t hw_csum:1; /* Checksum offload is supported. */
+	uint32_t hw_padding:1; /* End alignment padding is supported. */
+	uint32_t dest_tir:1; /* Whether advanced DR API is available. */
+	uint32_t dv_esw_en:1; /* E-Switch DV flow is supported. */
+	uint32_t dv_flow_en:1; /* DV flow is supported. */
+	uint32_t swp:3; /* Tx generic tunnel checksum and TSO offload. */
+	uint32_t hw_vlan_strip:1; /* VLAN stripping is supported. */
+	uint32_t scatter_fcs_w_decap_disable:1;
+	/* HW has bug working with tunnel packet decap and scatter FCS. */
+	uint32_t hw_fcs_strip:1; /* FCS stripping is supported. */
+	uint32_t rt_timestamp:1; /* Realtime timestamp format. */
+	uint32_t lro_supported:1; /* Whether LRO is supported. */
+	uint32_t rq_delay_drop_en:1; /* Enable RxQ delay drop. */
+	uint32_t tunnel_en:3;
+	/* Whether tunnel stateless offloads are supported. */
+	uint32_t ind_table_max_size;
 	/* Maximum receive WQ indirection table size. */
-	uint32_t max_tso; /* Maximum TCP payload for TSO. */
-	uint32_t tso_supported_qpts;
-	uint64_t flags;
-	uint64_t comp_mask;
-	uint32_t sw_parsing_offloads;
-	uint32_t min_single_stride_log_num_of_bytes;
-	uint32_t max_single_stride_log_num_of_bytes;
-	uint32_t min_single_wqe_log_num_of_strides;
-	uint32_t max_single_wqe_log_num_of_strides;
-	uint32_t stride_supported_qpts;
-	uint32_t tunnel_offloads_caps;
+	uint32_t tso:1; /* Whether TSO is supported. */
+	uint32_t tso_max_payload_sz; /* Maximum TCP payload for TSO. */
+	struct {
+		uint32_t enabled:1; /* Whether MPRQ is enabled. */
+		uint32_t log_min_stride_size; /* Log min size of a stride. */
+		uint32_t log_max_stride_size; /* Log max size of a stride. */
+		uint32_t log_min_stride_num; /* Log min num of strides. */
+		uint32_t log_max_stride_num; /* Log max num of strides. */
+		uint32_t log_min_stride_wqe_size;
+		/* Log min WQE size, (size of single stride)*(num of strides).*/
+	} mprq; /* Capability for Multi-Packet RQ. */
 	char fw_ver[64]; /* Firmware version of this device. */
 };
 
@@ -214,9 +233,6 @@ struct mlx5_stats_ctrl {
 	uint64_t imissed;
 };
 
-#define MLX5_LRO_SUPPORTED(dev) \
-	(((struct mlx5_priv *)((dev)->data->dev_private))->config.lro.supported)
-
 /* Maximal size of coalesced segment for LRO is set in chunks of 256 Bytes. */
 #define MLX5_LRO_SEG_CHUNK_SIZE	256u
 
@@ -226,12 +242,6 @@ struct mlx5_stats_ctrl {
 /* Maximal number of segments to split. */
 #define MLX5_MAX_RXQ_NSEG (1u << MLX5_MAX_LOG_RQ_SEGS)
 
-/* LRO configurations structure. */
-struct mlx5_lro_config {
-	uint32_t supported:1; /* Whether LRO is supported. */
-	uint32_t timeout; /* User configuration. */
-};
-
 /*
  * Device configuration structure.
  *
@@ -241,19 +251,11 @@ struct mlx5_lro_config {
  *  - User device parameters disabled features.
  */
 struct mlx5_dev_config {
-	unsigned int hw_csum:1; /* Checksum offload is supported. */
-	unsigned int hw_vlan_strip:1; /* VLAN stripping is supported. */
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
 	unsigned int hw_fcs_strip:1; /* FCS stripping is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
-	unsigned int vf:1; /* This is a VF. */
-	unsigned int sf:1; /* This is a SF. */
-	unsigned int tunnel_en:3;
-	/* Whether tunnel stateless offloads are supported. */
-	unsigned int mpls_en:1; /* MPLS over GRE/UDP is enabled. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
 	unsigned int cqe_comp_fmt:3; /* CQE compression format. */
-	unsigned int tso:1; /* Whether TSO is supported. */
 	unsigned int rx_vec_en:1; /* Rx vector is enabled. */
 	unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
 	unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */
@@ -262,10 +264,7 @@ struct mlx5_dev_config {
 	unsigned int dv_xmeta_en:2; /* Enable extensive flow metadata. */
 	unsigned int lacp_by_user:1;
 	/* Enable user to manage LACP traffic. */
-	unsigned int swp:3; /* Tx generic tunnel checksum and TSO offload. */
-	unsigned int dest_tir:1; /* Whether advanced DR API is available. */
 	unsigned int reclaim_mode:2; /* Memory reclaim mode. */
-	unsigned int rt_timestamp:1; /* realtime timestamp format. */
 	unsigned int decap_en:1; /* Whether decap will be used or not. */
 	unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
 	unsigned int allow_duplicate_pattern:1;
@@ -276,29 +275,21 @@ struct mlx5_dev_config {
 		unsigned int enabled:1; /* Whether MPRQ is enabled. */
 		unsigned int log_stride_num; /* Log number of strides. */
 		unsigned int log_stride_size; /* Log size of a stride. */
-		unsigned int log_min_stride_size; /* Log min size of a stride.*/
-		unsigned int log_max_stride_size; /* Log max size of a stride.*/
-		unsigned int log_min_stride_num; /* Log min num of strides. */
-		unsigned int log_max_stride_num; /* Log max num of strides. */
-		unsigned int log_min_stride_wqe_size;
-		/* Log min WQE size, (size of single stride)*(num of strides).*/
 		unsigned int max_memcpy_len;
 		/* Maximum packet size to memcpy Rx packets. */
 		unsigned int min_rxqs_num;
 		/* Rx queue count threshold to enable MPRQ. */
 	} mprq; /* Configurations for Multi-Packet RQ. */
 	int mps; /* Multi-packet send supported mode. */
-	unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */
-	unsigned int ind_table_max_size; /* Maximum indirection table size. */
 	unsigned int max_dump_files_num; /* Maximum dump files per queue. */
 	unsigned int log_hp_size; /* Single hairpin queue data size in total. */
+	unsigned int lro_timeout; /* LRO user configuration. */
 	int txqs_inline; /* Queue number threshold for inlining. */
 	int txq_inline_min; /* Minimal amount of data bytes to inline. */
 	int txq_inline_max; /* Max packet size for inlining with SEND. */
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
-	struct mlx5_lro_config lro; /* LRO configuration. */
 };
 
 
@@ -1518,7 +1509,6 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
 int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
-			      struct mlx5_dev_config *config,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
 mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 553df6424d..de0f3672c1 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -571,7 +571,7 @@ mlx5_devx_ind_table_create_rqt_attr(struct rte_eth_dev *dev,
 		rte_errno = ENOMEM;
 		return NULL;
 	}
-	rqt_attr->rqt_max_size = priv->config.ind_table_max_size;
+	rqt_attr->rqt_max_size = priv->sh->dev_cap.ind_table_max_size;
 	rqt_attr->rqt_actual_size = rqt_n;
 	if (queues == NULL) {
 		for (i = 0; i < rqt_n; i++)
@@ -769,7 +769,7 @@ mlx5_devx_tir_attr_set(struct rte_eth_dev *dev, const uint8_t *rss_key,
 		tir_attr->self_lb_block =
 					MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
 	if (lro) {
-		tir_attr->lro_timeout_period_usecs = priv->config.lro.timeout;
+		tir_attr->lro_timeout_period_usecs = priv->config.lro_timeout;
 		tir_attr->lro_max_msg_sz = priv->max_lro_msg_size;
 		tir_attr->lro_enable_mask =
 				MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
@@ -1196,7 +1196,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 		.flush_in_error_en = 1,
 		.allow_multi_pkt_send_wqe = !!priv->config.mps,
 		.min_wqe_inline_mode = cdev->config.hca_attr.vport_inline_mode,
-		.allow_swp = !!priv->config.swp,
+		.allow_swp = !!priv->sh->dev_cap.swp,
 		.cqn = txq_obj->cq_obj.cq->id,
 		.tis_lst_sz = 1,
 		.wq_attr = (struct mlx5_devx_wq_attr){
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d970eb6904..b7fe781d3a 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -121,7 +121,7 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 			dev->data->port_id, priv->txqs_n, txqs_n);
 		priv->txqs_n = txqs_n;
 	}
-	if (rxqs_n > priv->config.ind_table_max_size) {
+	if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) {
 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
 			dev->data->port_id, rxqs_n);
 		rte_errno = EINVAL;
@@ -177,7 +177,7 @@ mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
 			rss_queue_arr[j++] = i;
 	}
 	rss_queue_n = j;
-	if (rss_queue_n > priv->config.ind_table_max_size) {
+	if (rss_queue_n > priv->sh->dev_cap.ind_table_max_size) {
 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
 			dev->data->port_id, rss_queue_n);
 		rte_errno = EINVAL;
@@ -193,8 +193,8 @@ mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
 	 * The result is always rounded to the next power of two.
 	 */
 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
-				priv->config.ind_table_max_size :
-				rss_queue_n));
+				     priv->sh->dev_cap.ind_table_max_size :
+				     rss_queue_n));
 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
 	if (ret) {
 		mlx5_free(rss_queue_arr);
@@ -330,7 +330,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
 	info->if_index = mlx5_ifindex(dev);
 	info->reta_size = priv->reta_idx_n ?
-		priv->reta_idx_n : config->ind_table_max_size;
+		priv->reta_idx_n : priv->sh->dev_cap.ind_table_max_size;
 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
 	info->speed_capa = priv->link_speed_capa;
 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
@@ -722,7 +722,7 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
 
-	if (!priv->sh->cdev->config.devx || !config->dest_tir ||
+	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
 	    !config->dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 907f3fd75a..8bb9a72ba5 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1759,7 +1759,7 @@ mlx5_validate_action_rss(struct rte_eth_dev *dev,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  &rss->key_len,
 					  "RSS hash key too large");
-	if (rss->queue_num > priv->config.ind_table_max_size)
+	if (rss->queue_num > priv->sh->dev_cap.ind_table_max_size)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  &rss->queue_num,
@@ -3138,7 +3138,7 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	int ret;
 
-	if (!priv->config.mpls_en)
+	if (!priv->sh->dev_cap.mpls_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "MPLS not supported or"
diff --git a/drivers/net/mlx5/mlx5_rxmode.c b/drivers/net/mlx5/mlx5_rxmode.c
index 7f19b235c2..f44906e1a7 100644
--- a/drivers/net/mlx5/mlx5_rxmode.c
+++ b/drivers/net/mlx5/mlx5_rxmode.c
@@ -36,7 +36,7 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 			dev->data->port_id);
 		return 0;
 	}
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_promisc(dev, 1);
 		if (ret)
 			return ret;
@@ -69,7 +69,7 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	dev->data->promiscuous = 0;
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_promisc(dev, 0);
 		if (ret)
 			return ret;
@@ -109,7 +109,7 @@ mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 			dev->data->port_id);
 		return 0;
 	}
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_allmulti(dev, 1);
 		if (ret)
 			goto error;
@@ -142,7 +142,7 @@ mlx5_allmulticast_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	dev->data->all_multicast = 0;
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_allmulti(dev, 0);
 		if (ret)
 			goto error;
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 0ede46aa43..bcb04018f8 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -368,13 +368,13 @@ mlx5_get_rx_queue_offloads(struct rte_eth_dev *dev)
 		offloads |= RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT;
 	if (config->hw_fcs_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
-	if (config->hw_csum)
+	if (priv->sh->dev_cap.hw_csum)
 		offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
 			     RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
 			     RTE_ETH_RX_OFFLOAD_TCP_CKSUM);
-	if (config->hw_vlan_strip)
+	if (priv->sh->dev_cap.hw_vlan_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
-	if (MLX5_LRO_SUPPORTED(dev))
+	if (priv->sh->dev_cap.lro_supported)
 		offloads |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
 	return offloads;
 }
@@ -1564,14 +1564,15 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
-	uint32_t log_min_stride_num = config->mprq.log_min_stride_num;
-	uint32_t log_max_stride_num = config->mprq.log_max_stride_num;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
+	uint32_t log_min_stride_num = dev_cap->mprq.log_min_stride_num;
+	uint32_t log_max_stride_num = dev_cap->mprq.log_max_stride_num;
 	uint32_t log_def_stride_num =
 			RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM,
 					log_min_stride_num),
 				log_max_stride_num);
-	uint32_t log_min_stride_size = config->mprq.log_min_stride_size;
-	uint32_t log_max_stride_size = config->mprq.log_max_stride_size;
+	uint32_t log_min_stride_size = dev_cap->mprq.log_min_stride_size;
+	uint32_t log_max_stride_size = dev_cap->mprq.log_max_stride_size;
 	uint32_t log_def_stride_size =
 			RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_SIZE,
 					log_min_stride_size),
@@ -1610,7 +1611,7 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	}
 	log_stride_wqe_size = *actual_log_stride_num + *actual_log_stride_size;
 	/* Check if WQE buffer size is supported by hardware. */
-	if (log_stride_wqe_size < config->mprq.log_min_stride_wqe_size) {
+	if (log_stride_wqe_size < dev_cap->mprq.log_min_stride_wqe_size) {
 		*actual_log_stride_num = log_def_stride_num;
 		*actual_log_stride_size = log_def_stride_size;
 		DRV_LOG(WARNING,
@@ -1619,7 +1620,8 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			RTE_BIT32(log_def_stride_size));
 		log_stride_wqe_size = log_def_stride_num + log_def_stride_size;
 	}
-	MLX5_ASSERT(log_stride_wqe_size >= config->mprq.log_min_stride_wqe_size);
+	MLX5_ASSERT(log_stride_wqe_size >=
+		    dev_cap->mprq.log_min_stride_wqe_size);
 	if (desc <= RTE_BIT32(*actual_log_stride_num))
 		goto unsupport;
 	if (min_mbuf_size > RTE_BIT32(log_stride_wqe_size)) {
@@ -1648,9 +1650,9 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			RTE_BIT32(config->mprq.log_stride_size),
 			RTE_BIT32(config->mprq.log_stride_num),
 			config->mprq.min_rxqs_num,
-			RTE_BIT32(config->mprq.log_min_stride_wqe_size),
-			RTE_BIT32(config->mprq.log_min_stride_size),
-			RTE_BIT32(config->mprq.log_max_stride_size),
+			RTE_BIT32(dev_cap->mprq.log_min_stride_wqe_size),
+			RTE_BIT32(dev_cap->mprq.log_min_stride_size),
+			RTE_BIT32(dev_cap->mprq.log_max_stride_size),
 			rx_seg_en ? "" : "not ");
 	return -1;
 }
@@ -2370,7 +2372,7 @@ mlx5_ind_table_obj_setup(struct rte_eth_dev *dev,
 	int ret = 0, err;
 	const unsigned int n = rte_is_power_of_2(queues_n) ?
 			       log2above(queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 
 	if (ref_qs)
 		for (i = 0; i != queues_n; ++i) {
@@ -2495,7 +2497,7 @@ mlx5_ind_table_obj_modify(struct rte_eth_dev *dev,
 	int ret = 0, err;
 	const unsigned int n = rte_is_power_of_2(queues_n) ?
 			       log2above(queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 
 	MLX5_ASSERT(standalone);
 	RTE_SET_USED(standalone);
@@ -2576,7 +2578,7 @@ mlx5_ind_table_obj_detach(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const unsigned int n = rte_is_power_of_2(ind_tbl->queues_n) ?
 			       log2above(ind_tbl->queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 	unsigned int i;
 	int ret;
 
@@ -2994,6 +2996,6 @@ mlx5_rxq_timestamp_set(struct rte_eth_dev *dev)
 		if (data == NULL)
 			continue;
 		data->sh = sh;
-		data->rt_timestamp = priv->config.rt_timestamp;
+		data->rt_timestamp = sh->dev_cap.rt_timestamp;
 	}
 }
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index cd8c451286..72dfb2128a 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1105,7 +1105,8 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 		goto error;
 	}
 	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
-	    priv->config.dest_tir) && priv->obj_ops.lb_dummy_queue_create) {
+	     priv->sh->dev_cap.dest_tir) &&
+	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
 			goto error;
@@ -1117,7 +1118,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 		goto error;
 	}
 	if (priv->config.std_delay_drop || priv->config.hp_delay_drop) {
-		if (!priv->config.vf && !priv->config.sf &&
+		if (!priv->sh->dev_cap.vf && !priv->sh->dev_cap.sf &&
 		    !priv->representor) {
 			ret = mlx5_get_flag_dropless_rq(dev);
 			if (ret < 0)
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 56e0937ca3..47bca9e3ea 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -101,33 +101,34 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 	uint64_t offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
 			     RTE_ETH_TX_OFFLOAD_VLAN_INSERT);
 	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 
-	if (config->hw_csum)
+	if (dev_cap->hw_csum)
 		offloads |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
 			     RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
 			     RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
-	if (config->tso)
+	if (dev_cap->tso)
 		offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
 	if (config->tx_pp)
 		offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
-	if (config->swp) {
-		if (config->swp & MLX5_SW_PARSING_CSUM_CAP)
+	if (dev_cap->swp) {
+		if (dev_cap->swp & MLX5_SW_PARSING_CSUM_CAP)
 			offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
-		if (config->swp & MLX5_SW_PARSING_TSO_CAP)
+		if (dev_cap->swp & MLX5_SW_PARSING_TSO_CAP)
 			offloads |= (RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
 				     RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO);
 	}
-	if (config->tunnel_en) {
-		if (config->hw_csum)
+	if (dev_cap->tunnel_en) {
+		if (dev_cap->hw_csum)
 			offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
-		if (config->tso) {
-			if (config->tunnel_en &
+		if (dev_cap->tso) {
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
-			if (config->tunnel_en &
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_GRE_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO;
-			if (config->tunnel_en &
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
 		}
@@ -741,6 +742,7 @@ txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	unsigned int inlen_send; /* Inline data for ordinary SEND.*/
 	unsigned int inlen_empw; /* Inline data for enhanced MPW. */
 	unsigned int inlen_mode; /* Minimal required Inline data. */
@@ -924,19 +926,19 @@ txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 		txq_ctrl->txq.tso_en = 1;
 	}
 	if (((RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
 	   ((RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
 	   ((RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
-	   (config->swp  & MLX5_SW_PARSING_TSO_CAP))
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
+	   (dev_cap->swp  & MLX5_SW_PARSING_TSO_CAP))
 		txq_ctrl->txq.tunnel_en = 1;
 	txq_ctrl->txq.swp_en = (((RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
 				  RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO) &
-				  txq_ctrl->txq.offloads) && (config->swp &
+				  txq_ctrl->txq.offloads) && (dev_cap->swp &
 				  MLX5_SW_PARSING_TSO_CAP)) |
 				((RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM &
-				 txq_ctrl->txq.offloads) && (config->swp &
+				 txq_ctrl->txq.offloads) && (dev_cap->swp &
 				 MLX5_SW_PARSING_CSUM_CAP));
 }
 
diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c
index ea841bb32f..e7161b66fe 100644
--- a/drivers/net/mlx5/mlx5_vlan.c
+++ b/drivers/net/mlx5/mlx5_vlan.c
@@ -97,7 +97,7 @@ mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 
 	MLX5_ASSERT(rxq != NULL && rxq->ctrl != NULL);
 	/* Validate hw support */
-	if (!priv->config.hw_vlan_strip) {
+	if (!priv->sh->dev_cap.hw_vlan_strip) {
 		DRV_LOG(ERR, "port %u VLAN stripping is not supported",
 			dev->data->port_id);
 		return;
@@ -146,7 +146,7 @@ mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 		int hw_vlan_strip = !!(dev->data->dev_conf.rxmode.offloads &
 				       RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
 
-		if (!priv->config.hw_vlan_strip) {
+		if (!priv->sh->dev_cap.hw_vlan_strip) {
 			DRV_LOG(ERR, "port %u VLAN stripping is not supported",
 				dev->data->port_id);
 			return 0;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 16fd54091e..dfcd28901a 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -159,6 +159,8 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
 
+	MLX5_ASSERT(sh->cdev->config.devx);
+	MLX5_ASSERT(mlx5_dev_is_pci(sh->cdev->dev));
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
 		DRV_LOG(ERR, "Failed to get device hca_iseg.");
@@ -166,22 +168,55 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 		return -rte_errno;
 	}
 	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.vf = mlx5_dev_is_vf_pci(RTE_DEV_TO_PCI(sh->cdev->dev));
 	sh->dev_cap.max_cq = 1 << hca_attr->log_max_cq;
 	sh->dev_cap.max_qp = 1 << hca_attr->log_max_qp;
 	sh->dev_cap.max_qp_wr = 1 << hca_attr->log_max_qp_sz;
-	sh->dev_cap.max_tso = 1 << hca_attr->max_lso_cap;
+	sh->dev_cap.dv_flow_en = 1;
+	sh->dev_cap.mps = MLX5_MPW_DISABLED;
+	DRV_LOG(DEBUG, "MPW isn't supported.");
+	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is no supported.");
+	sh->dev_cap.hw_csum = hca_attr->csum_cap;
+	DRV_LOG(DEBUG, "Checksum offloading is %ssupported.",
+		(sh->dev_cap.hw_csum ? "" : "not "));
+	sh->dev_cap.hw_vlan_strip = hca_attr->vlan_cap;
+	DRV_LOG(DEBUG, "VLAN stripping is %ssupported.",
+		(sh->dev_cap.hw_vlan_strip ? "" : "not "));
+	sh->dev_cap.hw_fcs_strip = hca_attr->scatter_fcs;
+	sh->dev_cap.tso = ((1 << hca_attr->max_lso_cap) > 0);
+	if (sh->dev_cap.tso)
+		sh->dev_cap.tso_max_payload_sz = 1 << hca_attr->max_lso_cap;
+	DRV_LOG(DEBUG, "Counters are not supported.");
 	if (hca_attr->rss_ind_tbl_cap) {
-		sh->dev_cap.max_rwq_indirection_table_size =
-			1 << hca_attr->rss_ind_tbl_cap;
+		/*
+		 * DPDK doesn't support larger/variable indirection tables.
+		 * Once DPDK supports it, take max size from device attr.
+		 */
+		sh->dev_cap.ind_table_max_size =
+			RTE_MIN(1 << hca_attr->rss_ind_tbl_cap,
+				(unsigned int)RTE_ETH_RSS_RETA_SIZE_512);
+		DRV_LOG(DEBUG, "Maximum Rx indirection table size is %u",
+			sh->dev_cap.ind_table_max_size);
+	}
+	sh->dev_cap.swp = mlx5_get_supported_sw_parsing_offloads(hca_attr);
+	sh->dev_cap.tunnel_en = mlx5_get_supported_tunneling_offloads(hca_attr);
+	if (sh->dev_cap.tunnel_en) {
+		DRV_LOG(DEBUG, "Tunnel offloading is supported for %s%s%s",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : "");
+	} else {
+		DRV_LOG(DEBUG, "Tunnel offloading is not supported.");
 	}
-	sh->dev_cap.sw_parsing_offloads =
-		mlx5_get_supported_sw_parsing_offloads(hca_attr);
-	sh->dev_cap.tunnel_offloads_caps =
-		mlx5_get_supported_tunneling_offloads(hca_attr);
 	snprintf(sh->dev_cap.fw_ver, 64, "%x.%x.%04x",
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+	DRV_LOG(DEBUG, "Packet pacing is not supported.");
+	mlx5_rt_timestamp_config(sh, hca_attr);
 	return 0;
 }
 
@@ -265,7 +300,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -321,30 +355,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(errno));
 		goto error;
 	}
-	DRV_LOG(DEBUG, "MPW isn't supported");
-	config->swp = sh->dev_cap.sw_parsing_offloads &
-		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
-		 MLX5_SW_PARSING_TSO_CAP);
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
-		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
-		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
-		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
-	if (config->tunnel_en) {
-		DRV_LOG(DEBUG, "tunnel offloading is supported for %s%s%s",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : ""
-		);
-	} else {
-		DRV_LOG(DEBUG, "tunnel offloading is not supported");
-	}
-	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is no supported");
-	config->mpls_en = 0;
 	/* Allocate private eth device data. */
 	priv = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			   sizeof(*priv),
@@ -395,24 +405,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	DRV_LOG(DEBUG, "counters are not supported");
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	/*
-	 * Remove this check once DPDK supports larger/variable
-	 * indirection tables.
-	 */
-	if (config->ind_table_max_size > (unsigned int)RTE_ETH_RSS_RETA_SIZE_512)
-		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
-	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
-		config->ind_table_max_size);
 	if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	}
-	config->tso = (sh->dev_cap.max_tso > 0);
-	if (config->tso)
-		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	DRV_LOG(DEBUG, "%sMPS is %s.",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
@@ -421,17 +417,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	if (sh->cdev->config.devx) {
-		hca_attr = &sh->cdev->config.hca_attr;
-		config->hw_csum = hca_attr->csum_cap;
-		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-			(config->hw_csum ? "" : "not "));
-		config->hw_vlan_strip = hca_attr->vlan_cap;
-		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
-			(config->hw_vlan_strip ? "" : "not "));
-		config->hw_fcs_strip = hca_attr->scatter_fcs;
-		mlx5_rt_timestamp_config(sh, config, hca_attr);
-	}
+	config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
 		config->mprq.enabled = 0;
@@ -853,7 +839,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 		},
 		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
-		.vf = mlx5_dev_is_vf_pci(pci_dev),
 	};
 	int ret;
 	uint32_t restore;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 16/20] net/mlx5: add share device context config structure
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (14 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 15/20] net/mlx5: concentrate all device configurations Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
                   ` (4 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add configuration structure for shared device context. This structure
contains all configurations coming from devargs which oriented to
device. It is a field of shared device context (SH) structure, and is
updated once in mlx5_alloc_shared_dev_ctx() function.
This structure cannot be changed when probing again, so add function to
prevent it. The mlx5_probe_again_args_validate() function creates a
temporary IB context configure structure according to new devargs
attached in probing again, then checks the match between the temporary
structure and the existing IB context configure structure.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   |  95 ++----
 drivers/net/mlx5/mlx5.c            | 453 +++++++++++++++++++++--------
 drivers/net/mlx5/mlx5.h            |  43 +--
 drivers/net/mlx5/mlx5_ethdev.c     |   3 +-
 drivers/net/mlx5/mlx5_flow.c       |  30 +-
 drivers/net/mlx5/mlx5_flow.h       |   2 +-
 drivers/net/mlx5/mlx5_flow_dv.c    |  45 +--
 drivers/net/mlx5/mlx5_flow_meter.c |  10 +-
 drivers/net/mlx5/mlx5_rxq.c        |   7 +-
 drivers/net/mlx5/mlx5_trigger.c    |  10 +-
 drivers/net/mlx5/mlx5_txpp.c       |  12 +-
 drivers/net/mlx5/mlx5_txq.c        |   2 +-
 drivers/net/mlx5/windows/mlx5_os.c |  35 +--
 13 files changed, 457 insertions(+), 290 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 13db399b5e..50cc287e73 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -436,7 +436,7 @@ __mlx5_discovery_misc5_cap(struct mlx5_priv *priv)
 	dv_attr.priority = 3;
 #ifdef HAVE_MLX5DV_DR_ESWITCH
 	void *misc2_m;
-	if (priv->config.dv_esw_en) {
+	if (priv->sh->config.dv_esw_en) {
 		/* FDB enabled reg_c_0 */
 		dv_attr.match_criteria_enable |=
 				(1 << MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT);
@@ -557,7 +557,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 	}
 	sh->tx_domain = domain;
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (priv->config.dv_esw_en) {
+	if (sh->config.dv_esw_en) {
 		domain = mlx5_glue->dr_create_domain(sh->cdev->ctx,
 						     MLX5DV_DR_DOMAIN_TYPE_FDB);
 		if (!domain) {
@@ -579,20 +579,20 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 		goto error;
 	}
 #endif
-	if (!sh->tunnel_hub && priv->config.dv_miss_info)
+	if (!sh->tunnel_hub && sh->config.dv_miss_info)
 		err = mlx5_alloc_tunnel_hub(sh);
 	if (err) {
 		DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed err=%d", err);
 		goto error;
 	}
-	if (priv->config.reclaim_mode == MLX5_RCM_AGGR) {
+	if (sh->config.reclaim_mode == MLX5_RCM_AGGR) {
 		mlx5_glue->dr_reclaim_domain_memory(sh->rx_domain, 1);
 		mlx5_glue->dr_reclaim_domain_memory(sh->tx_domain, 1);
 		if (sh->fdb_domain)
 			mlx5_glue->dr_reclaim_domain_memory(sh->fdb_domain, 1);
 	}
 	sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan();
-	if (!priv->config.allow_duplicate_pattern) {
+	if (!sh->config.allow_duplicate_pattern) {
 #ifndef HAVE_MLX5_DR_ALLOW_DUPLICATE
 		DRV_LOG(WARNING, "Disallow duplicate pattern is not supported - maybe old rdma-core version?");
 #endif
@@ -859,7 +859,7 @@ 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)
+	if (!priv->sh->config.dv_flow_en || !priv->sh->dr_drop_action)
 		return;
 	/**
 	 * DR supports drop action placeholder when it is supported;
@@ -1115,31 +1115,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		return NULL;
 	}
-	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
+	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
-	/* Update final values for devargs before check sibling config. */
-	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported.");
-		config->dv_flow_en = 0;
-	}
-	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
-		DRV_LOG(WARNING, "E-Switch DV flow is not supported.");
-		config->dv_esw_en = 0;
-	}
-	if (config->dv_miss_info && config->dv_esw_en)
-		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	if (!config->dv_esw_en &&
-	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			config->dv_xmeta_en);
-		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
-	if (err)
-		goto error;
 	nl_rdma = mlx5_nl_init(NETLINK_RDMA);
 	/* Check port status. */
 	if (spawn->phys_port <= UINT8_MAX) {
@@ -1314,7 +1292,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
 		/* LRO is supported only when DV flow enabled. */
-		if (sh->dev_cap.lro_supported && config->dv_flow_en)
+		if (sh->dev_cap.lro_supported && sh->config.dv_flow_en)
 			sh->dev_cap.lro_supported = 0;
 		if (sh->dev_cap.lro_supported) {
 			/*
@@ -1331,7 +1309,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
 		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_old &&
-		    config->dv_flow_en) {
+		    sh->config.dv_flow_en) {
 			uint8_t reg_c_mask = hca_attr->qos.flow_meter_reg_c_ids;
 			/*
 			 * Meter needs two REG_C's for color match and pre-sfx
@@ -1405,7 +1383,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO && HAVE_MLX5_DR_ACTION_ASO_CT */
 #if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_SAMPLE)
 		if (hca_attr->log_max_ft_sampler_num > 0  &&
-		    config->dv_flow_en) {
+		    sh->config.dv_flow_en) {
 			priv->sampler_en = 1;
 			DRV_LOG(DEBUG, "Sampler enabled!");
 		} else {
@@ -1436,11 +1414,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
 			config->cqe_comp ? "" : "not ");
-	if (config->tx_pp && !sh->dev_cap.txpp_en) {
-		DRV_LOG(ERR, "Packet pacing is not supported.");
-		err = ENODEV;
-		goto error;
-	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
 		if (!hca_attr->rq_delay_drop) {
 			config->std_delay_drop = 0;
@@ -1450,17 +1423,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	/*
-	 * If HW has bug working with tunnel packet decapsulation and
-	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
-	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
-	 */
-	if (sh->dev_cap.scatter_fcs_w_decap_disable && config->decap_en)
-		config->hw_fcs_strip = 0;
-	else
-		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
-	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
-		(config->hw_fcs_strip ? "" : "not "));
 	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
 		config->mprq.enabled = 0;
@@ -1546,7 +1508,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	eth_dev->rx_queue_count = mlx5_rx_queue_count;
 	/* Register MAC address. */
 	claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
-	if (sh->dev_cap.vf && config->vf_nl_en)
+	if (sh->dev_cap.vf && sh->config.vf_nl_en)
 		mlx5_nl_mac_addr_sync(priv->nl_socket_route,
 				      mlx5_ifindex(eth_dev),
 				      eth_dev->data->mac_addrs,
@@ -1572,8 +1534,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Store device configuration on private structure. */
 	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
-		icfg[i].release_mem_en = !!config->reclaim_mode;
-		if (config->reclaim_mode)
+		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
+		if (sh->config.reclaim_mode)
 			icfg[i].per_core_cache = 0;
 		priv->flows[i] = mlx5_ipool_create(&icfg[i]);
 		if (!priv->flows[i])
@@ -1581,14 +1543,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Create context for virtual machine VLAN workaround. */
 	priv->vmwa_context = mlx5_vlan_vmwa_init(eth_dev, spawn->ifindex);
-	if (config->dv_flow_en) {
+	if (sh->config.dv_flow_en) {
 		err = mlx5_alloc_shared_dr(priv);
 		if (err)
 			goto error;
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && config->dv_flow_en &&
+	if (sh->cdev->config.devx && sh->config.dv_flow_en &&
 	    sh->dev_cap.dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
@@ -1604,7 +1566,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	} else {
 		priv->obj_ops = ibv_obj_ops;
 	}
-	if (config->tx_pp &&
+	if (sh->config.tx_pp &&
 	    priv->obj_ops.txq_obj_new != mlx5_txq_devx_obj_new) {
 		/*
 		 * HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support
@@ -1635,11 +1597,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	mlx5_set_metadata_mask(eth_dev);
-	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
 		DRV_LOG(ERR, "metadata mode %u is not supported "
 			     "(no metadata reg_c[0] is available)",
-			     priv->config.dv_xmeta_en);
+			     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 	}
@@ -1664,16 +1626,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG,
 			"port %u extensive metadata register is not supported",
 			eth_dev->data->port_id);
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 			DRV_LOG(ERR, "metadata mode %u is not supported "
 				     "(no metadata registers available)",
-				     priv->config.dv_xmeta_en);
+				     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 		}
 	}
-	if (priv->config.dv_flow_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_flow_en &&
+	    sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    mlx5_flow_ext_mreg_supported(eth_dev) &&
 	    priv->sh->dv_regc0_mask) {
 		priv->mreg_cp_tbl = mlx5_hlist_create(MLX5_FLOW_MREG_HNAME,
@@ -1692,7 +1654,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	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)
+	if (sh->config.dv_flow_en)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
 	return eth_dev;
 error:
@@ -1950,15 +1912,10 @@ mlx5_os_config_default(struct mlx5_dev_config *config)
 	config->txq_inline_min = MLX5_ARG_UNSET;
 	config->txq_inline_mpw = MLX5_ARG_UNSET;
 	config->txqs_inline = MLX5_ARG_UNSET;
-	config->vf_nl_en = 1;
 	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
 	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
 	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
-	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;
 	config->std_delay_drop = 0;
 	config->hp_delay_drop = 0;
 }
@@ -2574,6 +2531,12 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
+	ret = mlx5_probe_again_args_validate(cdev);
+	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);
 	else
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index bd23ce5afd..75ff11c357 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -533,7 +533,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !sh->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -836,12 +836,9 @@ mlx5_flow_aso_ct_mng_close(struct mlx5_dev_ctx_shared *sh)
  *
  * @param[in] sh
  *   Pointer to mlx5_dev_ctx_shared object.
- * @param[in] config
- *   Pointer to user dev config.
  */
 static void
-mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh,
-		       const struct mlx5_dev_config *config)
+mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh)
 {
 	uint8_t i;
 	struct mlx5_indexed_pool_config cfg;
@@ -856,12 +853,12 @@ mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh,
 		 * according to PCI function flow configuration.
 		 */
 		case MLX5_IPOOL_MLX5_FLOW:
-			cfg.size = config->dv_flow_en ?
+			cfg.size = sh->config.dv_flow_en ?
 				sizeof(struct mlx5_flow_handle) :
 				MLX5_FLOW_HANDLE_VERBS_SIZE;
 			break;
 		}
-		if (config->reclaim_mode) {
+		if (sh->config.reclaim_mode) {
 			cfg.release_mem_en = 1;
 			cfg.per_core_cache = 0;
 		} else {
@@ -1169,6 +1166,191 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
 	return 0;
 }
 
+/**
+ * Verify and store value for share device argument.
+ *
+ * @param[in] key
+ *   Key argument to verify.
+ * @param[in] val
+ *   Value associated with key.
+ * @param opaque
+ *   User data.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
+{
+	struct mlx5_sh_config *config = opaque;
+	signed long tmp;
+
+	errno = 0;
+	tmp = strtol(val, NULL, 0);
+	if (errno) {
+		rte_errno = errno;
+		DRV_LOG(WARNING, "%s: \"%s\" is not a valid integer", key, val);
+		return -rte_errno;
+	}
+	if (tmp < 0 && strcmp(MLX5_TX_PP, key) && strcmp(MLX5_TX_SKEW, key)) {
+		/* Negative values are acceptable for some keys only. */
+		rte_errno = EINVAL;
+		DRV_LOG(WARNING, "%s: invalid negative value \"%s\"", key, val);
+		return -rte_errno;
+	}
+	if (strcmp(MLX5_TX_PP, key) == 0) {
+		unsigned long mod = tmp >= 0 ? tmp : -tmp;
+
+		if (!mod) {
+			DRV_LOG(ERR, "Zero Tx packet pacing parameter.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		config->tx_pp = tmp;
+	} else if (strcmp(MLX5_TX_SKEW, key) == 0) {
+		config->tx_skew = tmp;
+	} else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
+		config->l3_vxlan_en = !!tmp;
+	} else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
+		config->vf_nl_en = !!tmp;
+	} else if (strcmp(MLX5_DV_ESW_EN, key) == 0) {
+		config->dv_esw_en = !!tmp;
+	} else if (strcmp(MLX5_DV_FLOW_EN, key) == 0) {
+		config->dv_flow_en = !!tmp;
+	} else if (strcmp(MLX5_DV_XMETA_EN, key) == 0) {
+		if (tmp != MLX5_XMETA_MODE_LEGACY &&
+		    tmp != MLX5_XMETA_MODE_META16 &&
+		    tmp != MLX5_XMETA_MODE_META32 &&
+		    tmp != MLX5_XMETA_MODE_MISS_INFO) {
+			DRV_LOG(ERR, "Invalid extensive metadata parameter.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		if (tmp != MLX5_XMETA_MODE_MISS_INFO)
+			config->dv_xmeta_en = tmp;
+		else
+			config->dv_miss_info = 1;
+	} else if (strcmp(MLX5_LACP_BY_USER, key) == 0) {
+		config->lacp_by_user = !!tmp;
+	} else if (strcmp(MLX5_RECLAIM_MEM, key) == 0) {
+		if (tmp != MLX5_RCM_NONE &&
+		    tmp != MLX5_RCM_LIGHT &&
+		    tmp != MLX5_RCM_AGGR) {
+			DRV_LOG(ERR, "Unrecognize %s: \"%s\"", key, val);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		config->reclaim_mode = tmp;
+	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
+		config->decap_en = !!tmp;
+	} else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
+		config->allow_duplicate_pattern = !!tmp;
+	}
+	return 0;
+}
+
+/**
+ * Parse user device parameters and adjust them according to device
+ * capabilities.
+ *
+ * @param sh
+ *   Pointer to shared device context.
+ * @param devargs
+ *   Device arguments structure.
+ * @param config
+ *   Pointer to shared device configuration structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
+				struct rte_devargs *devargs,
+				struct mlx5_sh_config *config)
+{
+	struct rte_kvargs *kvlist;
+	int ret = 0;
+
+	/* Default configuration. */
+	memset(config, 0, sizeof(*config));
+	config->vf_nl_en = 1;
+	config->dv_esw_en = 1;
+	config->dv_flow_en = 1;
+	config->decap_en = 1;
+	config->allow_duplicate_pattern = 1;
+	/* Parse device parameters. */
+	if (devargs != NULL) {
+		kvlist = rte_kvargs_parse(devargs->args, NULL);
+		if (kvlist == NULL) {
+			DRV_LOG(ERR,
+				"Failed to parse shared device arguments.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		/* Process parameters. */
+		ret = rte_kvargs_process(kvlist, NULL,
+					 mlx5_dev_args_check_handler, config);
+		rte_kvargs_free(kvlist);
+		if (ret) {
+			DRV_LOG(ERR, "Failed to process device arguments: %s",
+				strerror(rte_errno));
+			return -rte_errno;
+		}
+	}
+	/* Adjust parameters according to device capabilities. */
+	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
+		DRV_LOG(DEBUG, "E-Switch DV flow is not supported.");
+		config->dv_esw_en = 0;
+	}
+	if (config->dv_miss_info && config->dv_esw_en)
+		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	if (config->tx_pp && !sh->dev_cap.txpp_en) {
+		DRV_LOG(ERR, "Packet pacing is not supported.");
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
+	if (!config->tx_pp && config->tx_skew) {
+		DRV_LOG(WARNING,
+			"\"tx_skew\" doesn't affect without \"tx_pp\".");
+	}
+	/*
+	 * If HW has bug working with tunnel packet decapsulation and scatter
+	 * FCS, and decapsulation is needed, clear the hw_fcs_strip bit.
+	 * Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
+	 */
+	if (sh->dev_cap.scatter_fcs_w_decap_disable && sh->config.decap_en)
+		config->hw_fcs_strip = 0;
+	else
+		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
+	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
+		(config->hw_fcs_strip ? "" : "not "));
+	DRV_LOG(DEBUG, "\"tx_pp\" is %d.", config->tx_pp);
+	DRV_LOG(DEBUG, "\"tx_skew\" is %d.", config->tx_skew);
+	DRV_LOG(DEBUG, "\"reclaim_mode\" is %u.", config->reclaim_mode);
+	DRV_LOG(DEBUG, "\"dv_esw_en\" is %u.", config->dv_esw_en);
+	DRV_LOG(DEBUG, "\"dv_flow_en\" is %u.", config->dv_flow_en);
+	DRV_LOG(DEBUG, "\"dv_xmeta_en\" is %u.", config->dv_xmeta_en);
+	DRV_LOG(DEBUG, "\"dv_miss_info\" is %u.", config->dv_miss_info);
+	DRV_LOG(DEBUG, "\"l3_vxlan_en\" is %u.", config->l3_vxlan_en);
+	DRV_LOG(DEBUG, "\"vf_nl_en\" is %u.", config->vf_nl_en);
+	DRV_LOG(DEBUG, "\"lacp_by_user\" is %u.", config->lacp_by_user);
+	DRV_LOG(DEBUG, "\"decap_en\" is %u.", config->decap_en);
+	DRV_LOG(DEBUG, "\"allow_duplicate_pattern\" is %u.",
+		config->allow_duplicate_pattern);
+	return 0;
+}
+
 /**
  * Configure realtime timestamp format.
  *
@@ -1216,16 +1398,13 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
  *
  * @param[in] spawn
  *   Pointer to the device attributes (name, port, etc).
- * @param[in] config
- *   Pointer to device configuration structure.
  *
  * @return
  *   Pointer to mlx5_dev_ctx_shared object on success,
  *   otherwise NULL and rte_errno is set.
  */
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
-			  const struct mlx5_dev_config *config)
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
 {
 	struct mlx5_dev_ctx_shared *sh;
 	int err = 0;
@@ -1264,9 +1443,15 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
+	err = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
+					      &sh->config);
+	if (err) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		goto error;
+	}
 	sh->refcnt = 1;
 	sh->max_port = spawn->max_port;
-	sh->reclaim_mode = config->reclaim_mode;
 	strncpy(sh->ibdev_name, mlx5_os_get_ctx_device_name(sh->cdev->ctx),
 		sizeof(sh->ibdev_name) - 1);
 	strncpy(sh->ibdev_path, mlx5_os_get_ctx_device_path(sh->cdev->ctx),
@@ -1310,7 +1495,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	}
 	mlx5_flow_aging_init(sh);
 	mlx5_flow_counters_mng_init(sh);
-	mlx5_flow_ipool_create(sh, config);
+	mlx5_flow_ipool_create(sh);
 	/* Add context to the global device list. */
 	LIST_INSERT_HEAD(&mlx5_dev_ctx_list, sh, next);
 	rte_spinlock_init(&sh->geneve_tlv_opt_sl);
@@ -1919,14 +2104,18 @@ static int
 mlx5_args_check(const char *key, const char *val, void *opaque)
 {
 	struct mlx5_dev_config *config = opaque;
-	unsigned long mod;
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
 	if (!strcmp(MLX5_DRIVER_KEY, key) || !strcmp(MLX5_REPRESENTOR, key) ||
 	    !strcmp(MLX5_SYS_MEM_EN, key) || !strcmp(MLX5_TX_DB_NC, key) ||
-	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) ||
-	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key))
+	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) || !strcmp(MLX5_TX_PP, key) ||
+	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key) || !strcmp(MLX5_TX_SKEW, key) ||
+	    !strcmp(MLX5_RECLAIM_MEM, key) || !strcmp(MLX5_DECAP_EN, key) ||
+	    !strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) ||
+	    !strcmp(MLX5_L3_VXLAN_EN, key) || !strcmp(MLX5_VF_NL_EN, key) ||
+	    !strcmp(MLX5_DV_ESW_EN, key) || !strcmp(MLX5_DV_FLOW_EN, key) ||
+	    !strcmp(MLX5_DV_XMETA_EN, key) || !strcmp(MLX5_LACP_BY_USER, key))
 		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
@@ -1935,13 +2124,12 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		DRV_LOG(WARNING, "%s: \"%s\" is not a valid integer", key, val);
 		return -rte_errno;
 	}
-	if (tmp < 0 && strcmp(MLX5_TX_PP, key) && strcmp(MLX5_TX_SKEW, key)) {
+	if (tmp < 0) {
 		/* Negative values are acceptable for some keys only. */
 		rte_errno = EINVAL;
 		DRV_LOG(WARNING, "%s: invalid negative value \"%s\"", key, val);
 		return -rte_errno;
 	}
-	mod = tmp >= 0 ? tmp : -tmp;
 	if (strcmp(MLX5_RXQ_CQE_COMP_EN, key) == 0) {
 		if (tmp > MLX5_CQE_RESP_FORMAT_L34H_STRIDX) {
 			DRV_LOG(ERR, "invalid CQE compression "
@@ -1987,41 +2175,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		config->txq_inline_mpw = tmp;
 	} else if (strcmp(MLX5_TX_VEC_EN, key) == 0) {
 		DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
-	} else if (strcmp(MLX5_TX_PP, key) == 0) {
-		if (!mod) {
-			DRV_LOG(ERR, "Zero Tx packet pacing parameter");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		config->tx_pp = tmp;
-	} else if (strcmp(MLX5_TX_SKEW, key) == 0) {
-		config->tx_skew = tmp;
 	} else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
 		config->rx_vec_en = !!tmp;
-	} else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
-		config->l3_vxlan_en = !!tmp;
-	} else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
-		config->vf_nl_en = !!tmp;
-	} else if (strcmp(MLX5_DV_ESW_EN, key) == 0) {
-		config->dv_esw_en = !!tmp;
-	} else if (strcmp(MLX5_DV_FLOW_EN, key) == 0) {
-		config->dv_flow_en = !!tmp;
-	} else if (strcmp(MLX5_DV_XMETA_EN, key) == 0) {
-		if (tmp != MLX5_XMETA_MODE_LEGACY &&
-		    tmp != MLX5_XMETA_MODE_META16 &&
-		    tmp != MLX5_XMETA_MODE_META32 &&
-		    tmp != MLX5_XMETA_MODE_MISS_INFO) {
-			DRV_LOG(ERR, "invalid extensive "
-				     "metadata parameter");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		if (tmp != MLX5_XMETA_MODE_MISS_INFO)
-			config->dv_xmeta_en = tmp;
-		else
-			config->dv_miss_info = 1;
-	} else if (strcmp(MLX5_LACP_BY_USER, key) == 0) {
-		config->lacp_by_user = !!tmp;
 	} else if (strcmp(MLX5_MAX_DUMP_FILES_NUM, key) == 0) {
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
@@ -2030,19 +2185,6 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
 		config->log_hp_size = tmp;
-	} else if (strcmp(MLX5_RECLAIM_MEM, key) == 0) {
-		if (tmp != MLX5_RCM_NONE &&
-		    tmp != MLX5_RCM_LIGHT &&
-		    tmp != MLX5_RCM_AGGR) {
-			DRV_LOG(ERR, "Unrecognized %s: \"%s\"", key, val);
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		config->reclaim_mode = tmp;
-	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
-		config->decap_en = !!tmp;
-	} else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
-		config->allow_duplicate_pattern = !!tmp;
 	} else if (strcmp(MLX5_DELAY_DROP, key) == 0) {
 		config->std_delay_drop = !!(tmp & MLX5_DELAY_DROP_STANDARD);
 		config->hp_delay_drop = !!(tmp & MLX5_DELAY_DROP_HAIRPIN);
@@ -2089,6 +2231,130 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
 	return ret;
 }
 
+/**
+ * Check sibling device configurations when probing again.
+ *
+ * Sibling devices sharing infiniband device context should have compatible
+ * configurations. This regards representors and bonding device.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
+{
+	struct mlx5_dev_ctx_shared *sh = NULL;
+	struct mlx5_sh_config *config;
+	int ret;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	pthread_mutex_lock(&mlx5_dev_ctx_list_mutex);
+	/* Search for IB context by common device pointer. */
+	LIST_FOREACH(sh, &mlx5_dev_ctx_list, next)
+		if (sh->cdev == cdev)
+			break;
+	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
+	/* There is sh for this device -> it isn't probe again. */
+	if (sh == NULL)
+		return 0;
+	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
+			     sizeof(struct mlx5_sh_config),
+			     RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+	if (config == NULL) {
+		rte_errno = -ENOMEM;
+		return -rte_errno;
+	}
+	/*
+	 * Creates a temporary IB context configure structure according to new
+	 * devargs attached in probing again.
+	 */
+	ret = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
+					      config);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		mlx5_free(config);
+		return ret;
+	}
+	/*
+	 * Checks the match between the temporary structure and the existing
+	 * IB context structure.
+	 */
+	if (sh->config.dv_flow_en ^ config->dv_flow_en) {
+		DRV_LOG(ERR, "\"dv_flow_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if ((sh->config.dv_xmeta_en ^ config->dv_xmeta_en) ||
+	    (sh->config.dv_miss_info ^ config->dv_miss_info)) {
+		DRV_LOG(ERR, "\"dv_xmeta_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.dv_esw_en ^ config->dv_esw_en) {
+		DRV_LOG(ERR, "\"dv_esw_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.reclaim_mode ^ config->reclaim_mode) {
+		DRV_LOG(ERR, "\"reclaim_mode\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.allow_duplicate_pattern ^
+	    config->allow_duplicate_pattern) {
+		DRV_LOG(ERR, "\"allow_duplicate_pattern\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.l3_vxlan_en ^ config->l3_vxlan_en) {
+		DRV_LOG(ERR, "\"l3_vxlan_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.decap_en ^ config->decap_en) {
+		DRV_LOG(ERR, "\"decap_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.lacp_by_user ^ config->lacp_by_user) {
+		DRV_LOG(ERR, "\"lacp_by_user\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.tx_pp ^ config->tx_pp) {
+		DRV_LOG(ERR, "\"tx_pp\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.tx_skew ^ config->tx_skew) {
+		DRV_LOG(ERR, "\"tx_skew\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	mlx5_free(config);
+	return 0;
+error:
+	mlx5_free(config);
+	rte_errno = EINVAL;
+	return -rte_errno;
+}
+
 /**
  * Configures the minimal amount of data to inline into WQE
  * while sending packets.
@@ -2231,7 +2497,7 @@ mlx5_set_metadata_mask(struct rte_eth_dev *dev)
 	uint32_t meta, mark, reg_c0;
 
 	reg_c0 = ~priv->vport_meta_mask;
-	switch (priv->config.dv_xmeta_en) {
+	switch (sh->config.dv_xmeta_en) {
 	case MLX5_XMETA_MODE_LEGACY:
 		meta = UINT32_MAX;
 		mark = MLX5_FLOW_MARK_MASK;
@@ -2265,7 +2531,7 @@ mlx5_set_metadata_mask(struct rte_eth_dev *dev)
 				 sh->dv_meta_mask, reg_c0);
 	else
 		sh->dv_regc0_mask = reg_c0;
-	DRV_LOG(DEBUG, "metadata mode %u", priv->config.dv_xmeta_en);
+	DRV_LOG(DEBUG, "metadata mode %u", sh->config.dv_xmeta_en);
 	DRV_LOG(DEBUG, "metadata MARK mask %08X", sh->dv_mark_mask);
 	DRV_LOG(DEBUG, "metadata META mask %08X", sh->dv_meta_mask);
 	DRV_LOG(DEBUG, "metadata reg_c0 mask %08X", sh->dv_regc0_mask);
@@ -2291,61 +2557,6 @@ rte_pmd_mlx5_get_dyn_flag_names(char *names[], unsigned int n)
 	return RTE_DIM(dynf_names);
 }
 
-/**
- * Check sibling device configurations.
- *
- * Sibling devices sharing the Infiniband device context should have compatible
- * configurations. This regards representors and bonding device.
- *
- * @param sh
- *   Shared device context.
- * @param config
- *   Configuration of the device is going to be created.
- * @param dpdk_dev
- *   Backing DPDK device.
- *
- * @return
- *   0 on success, EINVAL otherwise
- */
-int
-mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
-			      struct mlx5_dev_config *config,
-			      struct rte_device *dpdk_dev)
-{
-	struct mlx5_dev_config *sh_conf = NULL;
-	uint16_t port_id;
-
-	MLX5_ASSERT(sh);
-	/* Nothing to compare for the single/first device. */
-	if (sh->refcnt == 1)
-		return 0;
-	/* Find the device with shared context. */
-	MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) {
-		struct mlx5_priv *opriv =
-			rte_eth_devices[port_id].data->dev_private;
-
-		if (opriv && opriv->sh == sh) {
-			sh_conf = &opriv->config;
-			break;
-		}
-	}
-	if (!sh_conf)
-		return 0;
-	if (sh_conf->dv_flow_en ^ config->dv_flow_en) {
-		DRV_LOG(ERR, "\"dv_flow_en\" configuration mismatch"
-			     " for shared %s context", sh->ibdev_name);
-		rte_errno = EINVAL;
-		return rte_errno;
-	}
-	if (sh_conf->dv_xmeta_en ^ config->dv_xmeta_en) {
-		DRV_LOG(ERR, "\"dv_xmeta_en\" configuration mismatch"
-			     " for shared %s context", sh->ibdev_name);
-		rte_errno = EINVAL;
-		return rte_errno;
-	}
-	return 0;
-}
-
 /**
  * Look for the ethernet device belonging to mlx5 driver.
  *
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index bda09cf96e..5ca48ef68f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -252,23 +252,10 @@ struct mlx5_stats_ctrl {
  */
 struct mlx5_dev_config {
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
-	unsigned int hw_fcs_strip:1; /* FCS stripping is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
 	unsigned int cqe_comp_fmt:3; /* CQE compression format. */
 	unsigned int rx_vec_en:1; /* Rx vector is enabled. */
-	unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
-	unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */
-	unsigned int dv_esw_en:1; /* Enable E-Switch DV flow. */
-	unsigned int dv_flow_en:1; /* Enable DV flow. */
-	unsigned int dv_xmeta_en:2; /* Enable extensive flow metadata. */
-	unsigned int lacp_by_user:1;
-	/* Enable user to manage LACP traffic. */
-	unsigned int reclaim_mode:2; /* Memory reclaim mode. */
-	unsigned int decap_en:1; /* Whether decap will be used or not. */
-	unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
-	unsigned int allow_duplicate_pattern:1;
-	/* Allow/Prevent the duplicate rules pattern. */
 	unsigned int std_delay_drop:1; /* Enable standard Rxq delay drop. */
 	unsigned int hp_delay_drop:1; /* Enable hairpin Rxq delay drop. */
 	struct {
@@ -288,8 +275,29 @@ struct mlx5_dev_config {
 	int txq_inline_min; /* Minimal amount of data bytes to inline. */
 	int txq_inline_max; /* Max packet size for inlining with SEND. */
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
+};
+
+/*
+ * Share context device configuration structure.
+ * User device parameters disabled features.
+ * This structure updated once for device in mlx5_alloc_shared_dev_ctx()
+ * function and cannot change even when probing again.
+ */
+struct mlx5_sh_config {
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
+	uint32_t reclaim_mode:2; /* Memory reclaim mode. */
+	uint32_t dv_esw_en:1; /* Enable E-Switch DV flow. */
+	uint32_t dv_flow_en:1; /* Enable DV flow. */
+	uint32_t dv_xmeta_en:2; /* Enable extensive flow metadata. */
+	uint32_t dv_miss_info:1; /* Restore packet after partial hw miss. */
+	uint32_t l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
+	uint32_t vf_nl_en:1; /* Enable Netlink requests in VF mode. */
+	uint32_t lacp_by_user:1; /* Enable user to manage LACP traffic. */
+	uint32_t decap_en:1; /* Whether decap will be used or not. */
+	uint32_t hw_fcs_strip:1; /* FCS stripping is supported. */
+	uint32_t allow_duplicate_pattern:1;
+	/* Allow/Prevent the duplicate rules pattern. */
 };
 
 
@@ -1144,7 +1152,6 @@ struct mlx5_dev_ctx_shared {
 	uint32_t ct_aso_en:1; /* Connection Tracking ASO is supported. */
 	uint32_t tunnel_header_0_1:1; /* tunnel_header_0_1 is supported. */
 	uint32_t misc5_cap:1; /* misc5 matcher parameter is supported. */
-	uint32_t reclaim_mode:1; /* Reclaim memory. */
 	uint32_t dr_drop_action_en:1; /* Use DR drop action. */
 	uint32_t drop_action_check_flag:1; /* Check Flag for drop action. */
 	uint32_t flow_priority_check_flag:1; /* Check Flag for flow priority. */
@@ -1156,6 +1163,7 @@ struct mlx5_dev_ctx_shared {
 	char ibdev_name[MLX5_FS_NAME_MAX]; /* SYSFS dev name. */
 	char ibdev_path[MLX5_FS_PATH_MAX]; /* SYSFS dev path for secondary */
 	struct mlx5_dev_cap dev_cap; /* Device capabilities. */
+	struct mlx5_sh_config config; /* Device configuration. */
 	int numa_node; /* Numa node of backing physical device. */
 	/* Packet pacing related structure. */
 	struct mlx5_dev_txpp txpp;
@@ -1511,8 +1519,7 @@ int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
-			   const struct mlx5_dev_config *config);
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn);
 void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
@@ -1520,9 +1527,7 @@ int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			 struct mlx5_dev_config *config);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
-				  struct mlx5_dev_config *config,
-				  struct rte_device *dpdk_dev);
+int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b7fe781d3a..9e478db8df 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -720,10 +720,9 @@ int
 mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 
 	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
-	    !config->dv_flow_en) {
+	    !priv->sh->config.dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 8bb9a72ba5..f8fc4621c9 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -901,7 +901,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 		     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	enum modify_reg start_reg;
 	bool skip_mtr_reg = false;
 
@@ -1994,7 +1994,7 @@ mlx5_flow_validate_attributes(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
 					  "egress is not supported");
-	if (attributes->transfer && !priv->config.dv_esw_en)
+	if (attributes->transfer && !priv->sh->config.dv_esw_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
 					  NULL, "transfer is not supported");
@@ -2711,7 +2711,7 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item,
 		uint8_t vni[4];
 	} id = { .vlan_id = 0, };
 
-	if (!priv->config.l3_vxlan_en)
+	if (!priv->sh->config.l3_vxlan_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "L3 VXLAN is not enabled by device"
@@ -3429,11 +3429,11 @@ flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr)
 	if (type != MLX5_FLOW_TYPE_MAX)
 		return type;
 	/* If no OS specific type - continue with DV/VERBS selection */
-	if (attr->transfer && priv->config.dv_esw_en)
+	if (attr->transfer && priv->sh->config.dv_esw_en)
 		type = MLX5_FLOW_TYPE_DV;
 	if (!attr->transfer)
-		type = priv->config.dv_flow_en ? MLX5_FLOW_TYPE_DV :
-						 MLX5_FLOW_TYPE_VERBS;
+		type = priv->sh->config.dv_flow_en ? MLX5_FLOW_TYPE_DV :
+						     MLX5_FLOW_TYPE_VERBS;
 	return type;
 }
 
@@ -4105,7 +4105,7 @@ static bool flow_check_modify_action_type(struct rte_eth_dev *dev,
 		return true;
 	case RTE_FLOW_ACTION_TYPE_FLAG:
 	case RTE_FLOW_ACTION_TYPE_MARK:
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY)
+		if (priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY)
 			return true;
 		else
 			return false;
@@ -4544,8 +4544,8 @@ flow_mreg_add_default_copy_action(struct rte_eth_dev *dev,
 	uint32_t mark_id;
 
 	/* Check whether extensive metadata feature is engaged. */
-	if (!priv->config.dv_flow_en ||
-	    priv->config.dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
+	if (!priv->sh->config.dv_flow_en ||
+	    priv->sh->config.dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
 	    !mlx5_flow_ext_mreg_supported(dev) ||
 	    !priv->sh->dv_regc0_mask)
 		return 0;
@@ -4604,7 +4604,7 @@ flow_mreg_update_copy_table(struct rte_eth_dev *dev,
 			    struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_flow_mreg_copy_resource *mcp_res;
 	const struct rte_flow_action_mark *mark;
 
@@ -5740,7 +5740,7 @@ flow_create_split_metadata(struct rte_eth_dev *dev,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action *qrss = NULL;
 	struct rte_flow_action *ext_actions = NULL;
 	struct mlx5_flow *dev_flow = NULL;
@@ -8249,7 +8249,7 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev)
 		struct rte_flow *flow;
 		struct rte_flow_error error;
 
-		if (!priv->config.dv_flow_en)
+		if (!priv->sh->config.dv_flow_en)
 			break;
 		/* Create internal flow, validation skips copy action. */
 		flow_idx = flow_list_create(dev, MLX5_FLOW_TYPE_GEN, &attr,
@@ -8563,7 +8563,7 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx,
 	struct mlx5_flow_handle *dh;
 	struct rte_flow *flow;
 
-	if (!priv->config.dv_flow_en) {
+	if (!sh->config.dv_flow_en) {
 		if (fputs("device dv flow disabled\n", file) <= 0)
 			return -errno;
 		return -ENOTSUP;
@@ -9547,7 +9547,7 @@ mlx5_flow_tunnel_validate(struct rte_eth_dev *dev,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->config.dv_flow_en)
+	if (!priv->sh->config.dv_flow_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
 					  "flow DV interface is off");
@@ -9966,7 +9966,7 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
 	type = mlx5_flow_os_get_type();
 	if (type == MLX5_FLOW_TYPE_MAX) {
 		type = MLX5_FLOW_TYPE_VERBS;
-		if (priv->sh->cdev->config.devx && priv->config.dv_flow_en)
+		if (priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en)
 			type = MLX5_FLOW_TYPE_DV;
 	}
 	fops = flow_get_drv_ops(type);
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 7fec79afb3..583e8b7321 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -963,7 +963,7 @@ is_tunnel_offload_active(const struct rte_eth_dev *dev)
 {
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	const struct mlx5_priv *priv = dev->data->dev_private;
-	return !!priv->config.dv_miss_info;
+	return !!priv->sh->config.dv_miss_info;
 #else
 	RTE_SET_USED(dev);
 	return false;
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 6a5ac01c2a..c30cb4c203 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1146,7 +1146,8 @@ flow_dv_convert_action_copy_mreg(struct rte_eth_dev *dev,
 		uint32_t reg_c0 = priv->sh->dv_regc0_mask;
 
 		MLX5_ASSERT(reg_c0);
-		MLX5_ASSERT(priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY);
+		MLX5_ASSERT(priv->sh->config.dv_xmeta_en !=
+			    MLX5_XMETA_MODE_LEGACY);
 		if (conf->dst == REG_C_0) {
 			/* Copy to reg_c[0], within mask only. */
 			reg_dst.offset = rte_bsf32(reg_c0);
@@ -1917,7 +1918,7 @@ flow_dv_validate_item_mark(struct rte_eth_dev *dev,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_item_mark *spec = item->spec;
 	const struct rte_flow_item_mark *mask = item->mask;
 	const struct rte_flow_item_mark nic_mask = {
@@ -1991,7 +1992,7 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_item_meta *spec = item->spec;
 	const struct rte_flow_item_meta *mask = item->mask;
 	struct rte_flow_item_meta nic_mask = {
@@ -3041,7 +3042,7 @@ flow_dv_validate_action_flag(struct rte_eth_dev *dev,
 			     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	int ret;
 
 	/* Fall back if no extended metadata register support. */
@@ -3100,7 +3101,7 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev,
 			     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_mark *mark = action->conf;
 	int ret;
 
@@ -3174,7 +3175,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev,
 				 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_set_meta *conf;
 	uint32_t nic_mask = UINT32_MAX;
 	int reg;
@@ -3386,7 +3387,7 @@ flow_dv_validate_action_decap(struct rte_eth_dev *dev,
 	const struct mlx5_priv *priv = dev->data->dev_private;
 
 	if (priv->sh->cdev->config.hca_attr.scatter_fcs_w_decap_disable &&
-	    !priv->config.decap_en)
+	    !priv->sh->config.decap_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "decap is not enabled");
@@ -4811,7 +4812,7 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 {
 	int ret = 0;
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_modify_field *action_modify_field =
 		action->conf;
 	uint32_t dst_width = mlx5_flow_item_field_width(dev,
@@ -5423,8 +5424,9 @@ flow_dv_modify_ipool_get(struct mlx5_dev_ctx_shared *sh, uint8_t index)
 		       .grow_trunk = 3,
 		       .grow_shift = 2,
 		       .need_lock = 1,
-		       .release_mem_en = !!sh->reclaim_mode,
-		       .per_core_cache = sh->reclaim_mode ? 0 : (1 << 16),
+		       .release_mem_en = !!sh->config.reclaim_mode,
+		       .per_core_cache =
+				       sh->config.reclaim_mode ? 0 : (1 << 16),
 		       .malloc = mlx5_malloc,
 		       .free = mlx5_free,
 		       .type = "mlx5_modify_action_resource",
@@ -5571,7 +5573,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	const struct rte_flow_action_sample *sample = action->conf;
 	const struct rte_flow_action *act;
 	uint64_t sub_action_flags = 0;
@@ -6595,7 +6597,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
 					  NULL,
 					  "priority out of range");
 	if (attributes->transfer) {
-		if (!priv->config.dv_esw_en)
+		if (!priv->sh->config.dv_esw_en)
 			return rte_flow_error_set
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
@@ -6880,7 +6882,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 		},
 	};
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	uint16_t queue_index = 0xFFFF;
 	const struct rte_flow_item_vlan *vlan_m = NULL;
 	uint32_t rw_act_num = 0;
@@ -6904,7 +6906,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 	tunnel = is_tunnel_offload_active(dev) ?
 		 mlx5_get_tof(items, actions, &tof_rule_type) : NULL;
 	if (tunnel) {
-		if (!priv->config.dv_flow_en)
+		if (!dev_conf->dv_flow_en)
 			return rte_flow_error_set
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -12640,7 +12642,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 		  struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5_flow_handle *handle = dev_flow->handle;
 	struct mlx5_flow_workspace *wks = mlx5_flow_get_thread_workspace();
@@ -13994,7 +13996,7 @@ flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
 				(error, errno,
 				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				NULL,
-				(!priv->config.allow_duplicate_pattern &&
+				(!priv->sh->config.allow_duplicate_pattern &&
 				errno == EEXIST) ?
 				"duplicating pattern is not allowed" :
 				"hardware refuses to create flow");
@@ -16064,7 +16066,7 @@ flow_dv_destroy_mtr_tbls(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	int i;
 
-	if (!fm || !priv->config.dv_flow_en)
+	if (!fm || !priv->sh->config.dv_flow_en)
 		return;
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
 		if (fm->drop_rule[i]) {
@@ -16670,7 +16672,8 @@ flow_dv_create_def_policy(struct rte_eth_dev *dev)
 
 	/* Non-termination policy table. */
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
-		if (!priv->config.dv_esw_en && i == MLX5_MTR_DOMAIN_TRANSFER)
+		if (!priv->sh->config.dv_esw_en &&
+		    i == MLX5_MTR_DOMAIN_TRANSFER)
 			continue;
 		if (__flow_dv_create_domain_def_policy(dev, i)) {
 			DRV_LOG(ERR, "Failed to create default policy");
@@ -17781,7 +17784,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 			struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	const struct rte_flow_action *act;
 	uint64_t action_flags[RTE_COLORS] = {0};
 	int actions_n;
@@ -17795,7 +17798,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 	bool def_yellow = false;
 	const struct rte_flow_action_rss *rss_color[RTE_COLORS] = {NULL};
 
-	if (!priv->config.dv_esw_en)
+	if (!dev_conf->dv_esw_en)
 		def_domain &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
 	*domain_bitmap = def_domain;
 	/* Red color could only support DROP action. */
@@ -17839,7 +17842,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
 			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
-				if (!priv->config.dv_esw_en)
+				if (!dev_conf->dv_esw_en)
 					return -rte_mtr_error_set(error,
 					ENOTSUP,
 					RTE_MTR_ERROR_TYPE_METER_POLICY,
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 77ae326bb7..393c13e3c5 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -650,8 +650,8 @@ mlx5_flow_meter_policy_validate(struct rte_eth_dev *dev,
 	struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct rte_flow_attr attr = { .transfer =
-			priv->config.dv_esw_en ? 1 : 0};
+	struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ?
+						  1 : 0 };
 	bool is_rss = false;
 	uint8_t policy_mode;
 	uint8_t domain_bitmap;
@@ -738,8 +738,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 			struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct rte_flow_attr attr = { .transfer =
-			priv->config.dv_esw_en ? 1 : 0};
+	struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ?
+						  1 : 0 };
 	uint32_t sub_policy_idx = 0;
 	uint32_t policy_idx = 0;
 	struct mlx5_flow_meter_policy *mtr_policy = NULL;
@@ -1205,7 +1205,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
 			(&priv->sh->mtrmng->def_policy_ref_cnt,
 			1, __ATOMIC_RELAXED);
 		domain_bitmap = MLX5_MTR_ALL_DOMAIN_BIT;
-		if (!priv->config.dv_esw_en)
+		if (!priv->sh->config.dv_esw_en)
 			domain_bitmap &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
 	} else {
 		if (!priv->sh->meter_aso_en)
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index bcb04018f8..1d1f2556de 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -359,14 +359,13 @@ uint64_t
 mlx5_get_rx_queue_offloads(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	uint64_t offloads = (RTE_ETH_RX_OFFLOAD_SCATTER |
 			     RTE_ETH_RX_OFFLOAD_TIMESTAMP |
 			     RTE_ETH_RX_OFFLOAD_RSS_HASH);
 
-	if (!config->mprq.enabled)
+	if (!priv->config.mprq.enabled)
 		offloads |= RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT;
-	if (config->hw_fcs_strip)
+	if (priv->sh->config.hw_fcs_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
 	if (priv->sh->dev_cap.hw_csum)
 		offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
@@ -1896,7 +1895,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
 	tmpl->rxq.crc_present = 0;
 	tmpl->rxq.lro = lro_on_queue;
 	if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) {
-		if (config->hw_fcs_strip) {
+		if (priv->sh->config.hw_fcs_strip) {
 			/*
 			 * RQs used for LRO-enabled TIRs should not be
 			 * configured to scatter the FCS.
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 72dfb2128a..eb03e9f7b1 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,7 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
+	if ((priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en &&
 	     priv->sh->dev_cap.dest_tir) &&
 	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
@@ -1277,8 +1277,6 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
  * Enable traffic flows configured by control plane
  *
  * @param dev
- *   Pointer to Ethernet device private data.
- * @param dev
  *   Pointer to Ethernet device structure.
  *
  * @return
@@ -1331,7 +1329,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				goto error;
 			}
 		}
-		if (priv->config.dv_esw_en) {
+		if (priv->sh->config.dv_esw_en) {
 			if (mlx5_flow_create_devx_sq_miss_flow(dev, i) == 0) {
 				DRV_LOG(ERR,
 					"Port %u Tx queue %u SQ create representor devx default miss rule failed.",
@@ -1341,7 +1339,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 		}
 		mlx5_txq_release(dev, i);
 	}
-	if (priv->config.dv_esw_en) {
+	if (priv->sh->config.dv_esw_en) {
 		if (mlx5_flow_create_esw_table_zero_flow(dev))
 			priv->fdb_def_rule = 1;
 		else
@@ -1349,7 +1347,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				" configured - only Eswitch group 0 flows are"
 				" supported.", dev->data->port_id);
 	}
-	if (!priv->config.lacp_by_user && priv->pf_bond >= 0) {
+	if (!priv->sh->config.lacp_by_user && priv->pf_bond >= 0) {
 		ret = mlx5_flow_lacp_miss(dev);
 		if (ret)
 			DRV_LOG(INFO, "port %u LACP rule cannot be created - "
diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c
index 1d16ebcb41..fe74317fe8 100644
--- a/drivers/net/mlx5/mlx5_txpp.c
+++ b/drivers/net/mlx5/mlx5_txpp.c
@@ -816,15 +816,15 @@ mlx5_txpp_start_service(struct mlx5_dev_ctx_shared *sh)
  * Returns 0 on success, negative otherwise
  */
 static int
-mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh, struct mlx5_priv *priv)
+mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh)
 {
-	int tx_pp = priv->config.tx_pp;
+	int tx_pp = sh->config.tx_pp;
 	int ret;
 
 	/* Store the requested pacing parameters. */
 	sh->txpp.tick = tx_pp >= 0 ? tx_pp : -tx_pp;
 	sh->txpp.test = !!(tx_pp < 0);
-	sh->txpp.skew = priv->config.tx_skew;
+	sh->txpp.skew = sh->config.tx_skew;
 	sh->txpp.freq = sh->cdev->config.hca_attr.dev_freq_khz;
 	ret = mlx5_txpp_create_event_channel(sh);
 	if (ret)
@@ -891,7 +891,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	int err = 0;
 
-	if (!priv->config.tx_pp) {
+	if (!sh->config.tx_pp) {
 		/* Packet pacing is not requested for the device. */
 		MLX5_ASSERT(priv->txpp_en == 0);
 		return 0;
@@ -901,7 +901,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 		MLX5_ASSERT(sh->txpp.refcnt);
 		return 0;
 	}
-	if (priv->config.tx_pp > 0) {
+	if (sh->config.tx_pp > 0) {
 		err = rte_mbuf_dynflag_lookup
 			(RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL);
 		/* No flag registered means no service needed. */
@@ -914,7 +914,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 		priv->txpp_en = 1;
 		++sh->txpp.refcnt;
 	} else {
-		err = mlx5_txpp_create(sh, priv);
+		err = mlx5_txpp_create(sh);
 		if (!err) {
 			MLX5_ASSERT(sh->txpp.tick);
 			priv->txpp_en = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 47bca9e3ea..3373ee66b4 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -109,7 +109,7 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 			     RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
 	if (dev_cap->tso)
 		offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
-	if (config->tx_pp)
+	if (priv->sh->config.tx_pp)
 		offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
 	if (dev_cap->swp) {
 		if (dev_cap->swp & MLX5_SW_PARSING_CSUM_CAP)
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index dfcd28901a..04f9590096 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -325,27 +325,18 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		goto error;
 	}
-	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
+	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
-	/* Update final values for devargs before check sibling config. */
-	config->dv_esw_en = 0;
-	if (!config->dv_flow_en) {
+	if (!sh->config.dv_flow_en) {
 		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
 		err = ENOTSUP;
 		goto error;
 	}
-	if (!config->dv_esw_en &&
-	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			config->dv_xmeta_en);
-		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	if (sh->config.vf_nl_en) {
+		DRV_LOG(DEBUG, "VF netlink isn't supported.");
+		sh->config.vf_nl_en = 0;
 	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
-	if (err)
-		goto error;
 	/* Initialize the shutdown event in mlx5_dev_spawn to
 	 * support mlx5_is_removed for Windows.
 	 */
@@ -417,7 +408,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
 		config->mprq.enabled = 0;
@@ -523,8 +513,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Store device configuration on private structure. */
 	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
-		icfg[i].release_mem_en = !!config->reclaim_mode;
-		if (config->reclaim_mode)
+		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
+		if (sh->config.reclaim_mode)
 			icfg[i].per_core_cache = 0;
 		priv->flows[i] = mlx5_ipool_create(&icfg[i]);
 		if (!priv->flows[i])
@@ -532,7 +522,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Create context for virtual machine VLAN workaround. */
 	priv->vmwa_context = NULL;
-	if (config->dv_flow_en) {
+	if (sh->config.dv_flow_en) {
 		err = mlx5_alloc_shared_dr(priv);
 		if (err)
 			goto error;
@@ -540,11 +530,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* No supported flow priority number detection. */
 	priv->sh->flow_max_priority = -1;
 	mlx5_set_metadata_mask(eth_dev);
-	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
 		DRV_LOG(ERR, "metadata mode %u is not supported "
 			     "(no metadata reg_c[0] is available).",
-			     priv->config.dv_xmeta_en);
+			     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 	}
@@ -564,10 +554,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG,
 			"port %u extensive metadata register is not supported.",
 			eth_dev->data->port_id);
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 			DRV_LOG(ERR, "metadata mode %u is not supported "
 				     "(no metadata registers available).",
-				     priv->config.dv_xmeta_en);
+				     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 		}
@@ -837,7 +827,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN,
 			.min_rxqs_num = MLX5_MPRQ_MIN_RXQS,
 		},
-		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
 	};
 	int ret;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 17/20] net/mlx5: using function to detect operation by DevX
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (15 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 16/20] net/mlx5: add share device context config structure Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 18/20] net/mlx5: separate per port configuration Michael Baum
                   ` (3 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add inline function indicating whether HW objects operations can be
created by DevX. It makes the code more readable.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c |  6 ++----
 drivers/net/mlx5/mlx5.h          | 24 ++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_ethdev.c   |  3 +--
 drivers/net/mlx5/mlx5_trigger.c  |  3 +--
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 50cc287e73..c432cf0858 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -370,8 +370,7 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 	sh->dev_cap.txpp_en = 0;
 #endif
 	/* Check for LRO support. */
-	if (sh->dev_cap.dest_tir && sh->dev_cap.dv_flow_en &&
-	    hca_attr->lro_cap) {
+	if (mlx5_devx_obj_ops_en(sh) && hca_attr->lro_cap) {
 		/* TBD check tunnel lro caps. */
 		sh->dev_cap.lro_supported = 1;
 		DRV_LOG(DEBUG, "Device supports LRO.");
@@ -1550,8 +1549,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && sh->config.dv_flow_en &&
-	    sh->dev_cap.dest_tir) {
+	if (mlx5_devx_obj_ops_en(sh)) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 5ca48ef68f..46fa5131a7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1496,6 +1496,30 @@ enum dr_dump_rec_type {
 	DR_DUMP_REC_TYPE_PMD_COUNTER = 4430,
 };
 
+/**
+ * Indicates whether HW objects operations can be created by DevX.
+ *
+ * This function is used for both:
+ *  Before creation - deciding whether to create HW objects operations by DevX.
+ *  After creation - indicator if HW objects operations were created by DevX.
+ *
+ * @param sh
+ *   Pointer to shared device context.
+ *
+ * @return
+ *   True if HW objects were created by DevX, False otherwise.
+ */
+static inline bool
+mlx5_devx_obj_ops_en(struct mlx5_dev_ctx_shared *sh)
+{
+	/*
+	 * When advanced DR API is available and DV flow is supported and
+	 * DevX is supported, HW objects operations are created by DevX.
+	 */
+	return (sh->cdev->config.devx && sh->config.dv_flow_en &&
+		sh->dev_cap.dest_tir);
+}
+
 /* mlx5.c */
 
 int mlx5_getenv_int(const char *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 9e478db8df..d637dee98d 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -721,8 +721,7 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
-	    !priv->sh->config.dv_flow_en) {
+	if (!mlx5_devx_obj_ops_en(priv->sh)) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index eb03e9f7b1..e234d11215 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,8 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en &&
-	     priv->sh->dev_cap.dest_tir) &&
+	if (mlx5_devx_obj_ops_en(priv->sh) &&
 	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 18/20] net/mlx5: separate per port configuration
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (16 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
                   ` (2 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add configuration structure for port (ethdev). This structure contains
all configurations coming from devargs which oriented to port. It is a
field of mlx5_priv structure, and is updated in spawn function for each
port.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 121 ++------------------
 drivers/net/mlx5/mlx5.c            | 178 ++++++++++++++++++++++++-----
 drivers/net/mlx5/mlx5.h            |  21 ++--
 drivers/net/mlx5/mlx5_devx.c       |   3 +-
 drivers/net/mlx5/mlx5_ethdev.c     |   7 +-
 drivers/net/mlx5/mlx5_rxq.c        |   4 +-
 drivers/net/mlx5/mlx5_tx.c         |   2 +-
 drivers/net/mlx5/mlx5_txq.c        |   6 +-
 drivers/net/mlx5/windows/mlx5_os.c |  55 ++-------
 9 files changed, 188 insertions(+), 209 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index c432cf0858..6979385782 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -999,8 +999,6 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
  * @param eth_da
  *   Device arguments.
  *
@@ -1014,12 +1012,10 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	       struct mlx5_dev_spawn_data *spawn,
-	       struct mlx5_dev_config *config,
 	       struct rte_eth_devargs *eth_da)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
@@ -1029,7 +1025,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	int own_domain_id = 0;
 	uint16_t port_id;
 	struct mlx5_port_info vport_info = { .query_flags = 0 };
-	int nl_rdma = -1;
+	int nl_rdma;
 	int i;
 
 	/* Determine if this port representor is supposed to be spawned. */
@@ -1107,13 +1103,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mlx5_dev_close(eth_dev);
 		return NULL;
 	}
-	/* Process parameters. */
-	err = mlx5_args(config, dpdk_dev->devargs);
-	if (err) {
-		DRV_LOG(ERR, "failed to process device arguments: %s",
-			strerror(rte_errno));
-		return NULL;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
@@ -1269,41 +1258,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	if (config->hw_padding && !sh->dev_cap.hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
-		config->hw_padding = 0;
-	} else if (config->hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
-	}
-	/*
-	 * MPW is disabled by default, while the Enhanced MPW is enabled
-	 * by default.
-	 */
-	if (config->mps == MLX5_ARG_UNSET)
-		config->mps = (sh->dev_cap.mps == MLX5_MPW_ENHANCED) ?
-			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
-	else
-		config->mps = config->mps ? sh->dev_cap.mps : MLX5_MPW_DISABLED;
-	DRV_LOG(INFO, "%sMPS is %s",
-		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
-		config->mps == MLX5_MPW ? "legacy " : "",
-		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->cdev->config.devx) {
+		struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+
 		sh->steering_format_version = hca_attr->steering_format_version;
-		/* LRO is supported only when DV flow enabled. */
-		if (sh->dev_cap.lro_supported && sh->config.dv_flow_en)
-			sh->dev_cap.lro_supported = 0;
-		if (sh->dev_cap.lro_supported) {
-			/*
-			 * If LRO timeout is not configured by application,
-			 * use the minimal supported value.
-			 */
-			if (!config->lro_timeout)
-				config->lro_timeout =
-				       hca_attr->lro_timer_supported_periods[0];
-			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
-				config->lro_timeout);
-		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
@@ -1395,39 +1353,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif
 	}
-	if (config->cqe_comp && !sh->dev_cap.cqe_comp) {
-		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_flow_tag)) {
-		DRV_LOG(WARNING, "Flow Tag CQE compression"
-				 " format isn't supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
-		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
-				 " format isn't supported.");
-		config->cqe_comp = 0;
-	}
-	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
-			config->cqe_comp ? "" : "not ");
-	if (config->std_delay_drop || config->hp_delay_drop) {
-		if (!hca_attr->rq_delay_drop) {
-			config->std_delay_drop = 0;
-			config->hp_delay_drop = 0;
-			DRV_LOG(WARNING,
-				"dev_port-%u: Rxq delay drop is not supported",
-				priv->dev_port);
-		}
-	}
-	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
-		config->mprq.enabled = 0;
+	/* Process parameters and store port configuration on priv structure. */
+	err = mlx5_port_args_config(priv, dpdk_dev->devargs, &priv->config);
+	if (err) {
+		err = rte_errno;
+		DRV_LOG(ERR, "Failed to process port configure: %s",
+			strerror(rte_errno));
+		goto error;
 	}
-	if (config->max_dump_files_num == 0)
-		config->max_dump_files_num = 128;
 	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL) {
 		DRV_LOG(ERR, "can not allocate rte ethdev");
@@ -1528,10 +1461,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	/* Detect minimal data bytes to inline. */
-	mlx5_set_min_inline(spawn, config);
-	/* Store device configuration on private structure. */
-	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
 		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
 		if (sh->config.reclaim_mode)
@@ -1899,25 +1828,6 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 	return pf;
 }
 
-static void
-mlx5_os_config_default(struct mlx5_dev_config *config)
-{
-	memset(config, 0, sizeof(*config));
-	config->mps = MLX5_ARG_UNSET;
-	config->cqe_comp = 1;
-	config->rx_vec_en = 1;
-	config->txq_inline_max = MLX5_ARG_UNSET;
-	config->txq_inline_min = MLX5_ARG_UNSET;
-	config->txq_inline_mpw = MLX5_ARG_UNSET;
-	config->txqs_inline = MLX5_ARG_UNSET;
-	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
-	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
-	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
-	config->log_hp_size = MLX5_ARG_UNSET;
-	config->std_delay_drop = 0;
-	config->hp_delay_drop = 0;
-}
-
 /**
  * Register a PCI device within bonding.
  *
@@ -1966,7 +1876,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	int bd = -1;
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data *list = NULL;
-	struct mlx5_dev_config dev_config;
 	struct rte_eth_devargs eth_da = *req_eth_da;
 	struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
 	struct mlx5_bond_info bond_info;
@@ -2308,10 +2217,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	for (i = 0; i != ns; ++i) {
 		uint32_t restore;
 
-		/* Default configuration. */
-		mlx5_os_config_default(&dev_config);
-		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
-						 &dev_config, &eth_da);
+		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da);
 		if (!list[i].eth_dev) {
 			if (rte_errno != EBUSY && rte_errno != EEXIST)
 				break;
@@ -2466,7 +2372,6 @@ static int
 mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 {
 	struct rte_eth_devargs eth_da = { .nb_ports = 0 };
-	struct mlx5_dev_config config;
 	struct mlx5_dev_spawn_data spawn = { .pf_bond = -1 };
 	struct rte_device *dev = cdev->dev;
 	struct rte_auxiliary_device *adev = RTE_DEV_TO_AUXILIARY(dev);
@@ -2477,8 +2382,6 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	ret = mlx5_os_parse_eth_devargs(dev, &eth_da);
 	if (ret != 0)
 		return ret;
-	/* Set default config data. */
-	mlx5_os_config_default(&config);
 	/* Init spawn data. */
 	spawn.max_port = 1;
 	spawn.phys_port = 1;
@@ -2491,7 +2394,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	spawn.ifindex = ret;
 	spawn.cdev = cdev;
 	/* Spawn device. */
-	eth_dev = mlx5_dev_spawn(dev, &spawn, &config, &eth_da);
+	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da);
 	if (eth_dev == NULL)
 		return -rte_errno;
 	/* Post create. */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 75ff11c357..b3601155d7 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2101,9 +2101,9 @@ const struct eth_dev_ops mlx5_dev_ops_isolate = {
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-mlx5_args_check(const char *key, const char *val, void *opaque)
+mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 {
-	struct mlx5_dev_config *config = opaque;
+	struct mlx5_port_config *config = opaque;
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
@@ -2197,38 +2197,156 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 }
 
 /**
- * Parse device parameters.
+ * Parse user port parameters and adjust them according to device capabilities.
  *
- * @param config
- *   Pointer to device configuration structure.
+ * @param priv
+ *   Pointer to shared device context.
  * @param devargs
  *   Device arguments structure.
+ * @param config
+ *   Pointer to port configuration structure.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
+mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+		      struct mlx5_port_config *config)
 {
 	struct rte_kvargs *kvlist;
+	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
+	bool devx = priv->sh->cdev->config.devx;
 	int ret = 0;
 
-	if (devargs == NULL)
-		return 0;
-	/* Following UGLY cast is done to pass checkpatch. */
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		rte_errno = EINVAL;
-		return -rte_errno;
+	/* Default configuration. */
+	memset(config, 0, sizeof(*config));
+	config->mps = MLX5_ARG_UNSET;
+	config->cqe_comp = 1;
+	config->rx_vec_en = 1;
+	config->txq_inline_max = MLX5_ARG_UNSET;
+	config->txq_inline_min = MLX5_ARG_UNSET;
+	config->txq_inline_mpw = MLX5_ARG_UNSET;
+	config->txqs_inline = MLX5_ARG_UNSET;
+	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
+	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
+	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
+	config->log_hp_size = MLX5_ARG_UNSET;
+	config->std_delay_drop = 0;
+	config->hp_delay_drop = 0;
+	/* Parse device parameters. */
+	if (devargs != NULL) {
+		kvlist = rte_kvargs_parse(devargs->args, NULL);
+		if (kvlist == NULL) {
+			DRV_LOG(ERR,
+				"Failed to parse device arguments.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		/* Process parameters. */
+		ret = rte_kvargs_process(kvlist, NULL,
+					 mlx5_port_args_check_handler, config);
+		rte_kvargs_free(kvlist);
+		if (ret) {
+			DRV_LOG(ERR, "Failed to process port arguments: %s",
+				strerror(rte_errno));
+			return -rte_errno;
+		}
 	}
-	/* Process parameters. */
-	ret = rte_kvargs_process(kvlist, NULL, mlx5_args_check, config);
-	if (ret) {
-		rte_errno = EINVAL;
-		ret = -rte_errno;
+	/* Adjust parameters according to device capabilities. */
+	if (config->hw_padding && !dev_cap->hw_padding) {
+		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported.");
+		config->hw_padding = 0;
+	} else if (config->hw_padding) {
+		DRV_LOG(DEBUG, "Rx end alignment padding is enabled.");
 	}
-	rte_kvargs_free(kvlist);
-	return ret;
+	/*
+	 * MPW is disabled by default, while the Enhanced MPW is enabled
+	 * by default.
+	 */
+	if (config->mps == MLX5_ARG_UNSET)
+		config->mps = (dev_cap->mps == MLX5_MPW_ENHANCED) ?
+			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
+	else
+		config->mps = config->mps ? dev_cap->mps : MLX5_MPW_DISABLED;
+	DRV_LOG(INFO, "%sMPS is %s",
+		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
+		config->mps == MLX5_MPW ? "legacy " : "",
+		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
+	/* LRO is supported only when DV flow enabled. */
+	if (dev_cap->lro_supported && !priv->sh->config.dv_flow_en)
+		dev_cap->lro_supported = 0;
+	if (dev_cap->lro_supported) {
+		/*
+		 * If LRO timeout is not configured by application,
+		 * use the minimal supported value.
+		 */
+		if (!config->lro_timeout)
+			config->lro_timeout =
+				       hca_attr->lro_timer_supported_periods[0];
+		DRV_LOG(DEBUG, "LRO session timeout set to %d usec.",
+			config->lro_timeout);
+	}
+	if (config->cqe_comp && !dev_cap->cqe_comp) {
+		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
+		config->cqe_comp = 0;
+	}
+	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
+	    (!devx || !hca_attr->mini_cqe_resp_flow_tag)) {
+		DRV_LOG(WARNING,
+			"Flow Tag CQE compression format isn't supported.");
+		config->cqe_comp = 0;
+	}
+	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
+	    (!devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
+		DRV_LOG(WARNING,
+			"L3/L4 Header CQE compression format isn't supported.");
+		config->cqe_comp = 0;
+	}
+	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported.",
+		config->cqe_comp ? "" : "not ");
+	if ((config->std_delay_drop || config->hp_delay_drop) &&
+	    !dev_cap->rq_delay_drop_en) {
+		config->std_delay_drop = 0;
+		config->hp_delay_drop = 0;
+		DRV_LOG(WARNING, "dev_port-%u: Rxq delay drop isn't supported.",
+			priv->dev_port);
+	}
+	if (config->mprq.enabled && !priv->sh->dev_cap.mprq.enabled) {
+		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
+		config->mprq.enabled = 0;
+	}
+	if (config->max_dump_files_num == 0)
+		config->max_dump_files_num = 128;
+	/* Detect minimal data bytes to inline. */
+	mlx5_set_min_inline(priv);
+	DRV_LOG(DEBUG, "VLAN insertion in WQE is %ssupported.",
+		config->hw_vlan_insert ? "" : "not ");
+	DRV_LOG(DEBUG, "\"rxq_pkt_pad_en\" is %u.", config->hw_padding);
+	DRV_LOG(DEBUG, "\"rxq_cqe_comp_en\" is %u.", config->cqe_comp);
+	DRV_LOG(DEBUG, "\"cqe_comp_fmt\" is %u.", config->cqe_comp_fmt);
+	DRV_LOG(DEBUG, "\"rx_vec_en\" is %u.", config->rx_vec_en);
+	DRV_LOG(DEBUG, "Standard \"delay_drop\" is %u.",
+		config->std_delay_drop);
+	DRV_LOG(DEBUG, "Hairpin \"delay_drop\" is %u.", config->hp_delay_drop);
+	DRV_LOG(DEBUG, "\"max_dump_files_num\" is %u.",
+		config->max_dump_files_num);
+	DRV_LOG(DEBUG, "\"log_hp_size\" is %u.", config->log_hp_size);
+	DRV_LOG(DEBUG, "\"mprq_en\" is %u.", config->mprq.enabled);
+	DRV_LOG(DEBUG, "\"mprq_log_stride_num\" is %u.",
+		config->mprq.log_stride_num);
+	DRV_LOG(DEBUG, "\"mprq_log_stride_size\" is %u.",
+		config->mprq.log_stride_size);
+	DRV_LOG(DEBUG, "\"mprq_max_memcpy_len\" is %u.",
+		config->mprq.max_memcpy_len);
+	DRV_LOG(DEBUG, "\"rxqs_min_mprq\" is %u.", config->mprq.min_rxqs_num);
+	DRV_LOG(DEBUG, "\"lro_timeout_usec\" is %u.", config->lro_timeout);
+	DRV_LOG(DEBUG, "\"txq_mpw_en\" is %d.", config->mps);
+	DRV_LOG(DEBUG, "\"txqs_min_inline\" is %d.", config->txqs_inline);
+	DRV_LOG(DEBUG, "\"txq_inline_min\" is %d.", config->txq_inline_min);
+	DRV_LOG(DEBUG, "\"txq_inline_max\" is %d.", config->txq_inline_max);
+	DRV_LOG(DEBUG, "\"txq_inline_mpw\" is %d.", config->txq_inline_mpw);
+	return 0;
 }
 
 /**
@@ -2366,21 +2484,19 @@ mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
  * - otherwise L2 mode (18 bytes) is assumed for ConnectX-4/4 Lx
  *   and none (0 bytes) for other NICs
  *
- * @param spawn
- *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
+ * @param priv
+ *   Pointer to the private device data structure.
  */
 void
-mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
-		    struct mlx5_dev_config *config)
+mlx5_set_min_inline(struct mlx5_priv *priv)
 {
-	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
+	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
+	struct mlx5_port_config *config = &priv->config;
 
 	if (config->txq_inline_min != MLX5_ARG_UNSET) {
 		/* Application defines size of inlined data explicitly. */
-		if (spawn->pci_dev != NULL) {
-			switch (spawn->pci_dev->id.device_id) {
+		if (priv->pci_dev != NULL) {
+			switch (priv->pci_dev->id.device_id) {
 			case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
 			case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
 				if (config->txq_inline_min <
@@ -2446,7 +2562,7 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			}
 		}
 	}
-	if (spawn->pci_dev == NULL) {
+	if (priv->pci_dev == NULL) {
 		config->txq_inline_min = MLX5_INLINE_HSIZE_NONE;
 		goto exit;
 	}
@@ -2455,7 +2571,7 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 	 * inline data size with DevX. Try PCI ID
 	 * to determine old NICs.
 	 */
-	switch (spawn->pci_dev->id.device_id) {
+	switch (priv->pci_dev->id.device_id) {
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LX:
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 46fa5131a7..95910aba1b 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -243,14 +243,13 @@ struct mlx5_stats_ctrl {
 #define MLX5_MAX_RXQ_NSEG (1u << MLX5_MAX_LOG_RQ_SEGS)
 
 /*
- * Device configuration structure.
- *
- * Merged configuration from:
- *
- *  - Device capabilities,
- *  - User device parameters disabled features.
+ * Port configuration structure.
+ * User device parameters disabled features.
+ * This structure contains all configurations coming from devargs which
+ * oriented to port. When probing again, devargs doesn't have to be compatible
+ * with primary devargs. It is updated for each port in spawn function.
  */
-struct mlx5_dev_config {
+struct mlx5_port_config {
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
@@ -1450,7 +1449,7 @@ struct mlx5_priv {
 	uint32_t link_speed_capa; /* Link speed capabilities. */
 	struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
 	struct mlx5_stats_ctrl stats_ctrl; /* Stats control. */
-	struct mlx5_dev_config config; /* Device configuration. */
+	struct mlx5_port_config config; /* Port configuration. */
 	/* Context for Verbs allocator. */
 	int nl_socket_rdma; /* Netlink socket (NETLINK_RDMA). */
 	int nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */
@@ -1539,7 +1538,6 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	for (port_id = mlx5_eth_find_next(0, dev); \
 	     port_id < RTE_MAX_ETHPORTS; \
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
-int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
@@ -1548,10 +1546,11 @@ void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
 int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
-void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
-			 struct mlx5_dev_config *config);
+void mlx5_set_min_inline(struct mlx5_priv *priv);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
 int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
+int mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+			  struct mlx5_port_config *config);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index de0f3672c1..e57787cfec 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -766,8 +766,7 @@ mlx5_devx_tir_attr_set(struct rte_eth_dev *dev, const uint8_t *rss_key,
 	memcpy(tir_attr->rx_hash_toeplitz_key, rss_key, MLX5_RSS_HASH_KEY_LEN);
 	tir_attr->indirect_table = ind_tbl->rqt->id;
 	if (dev->data->dev_conf.lpbk_mode)
-		tir_attr->self_lb_block =
-					MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
+		tir_attr->self_lb_block = MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
 	if (lro) {
 		tir_attr->lro_timeout_period_usecs = priv->config.lro_timeout;
 		tir_attr->lro_max_msg_sz = priv->max_lro_msg_size;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d637dee98d..72bf8ac914 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -266,7 +266,7 @@ static void
 mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	unsigned int inlen;
 	uint16_t nb_max;
 
@@ -302,7 +302,6 @@ int
 mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	unsigned int max;
 
 	/* FIXME: we should ask the device for these values. */
@@ -321,8 +320,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
-	info->rx_seg_capa.multi_pools = !config->mprq.enabled;
-	info->rx_seg_capa.offset_allowed = !config->mprq.enabled;
+	info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled;
+	info->rx_seg_capa.offset_allowed = !priv->config.mprq.enabled;
 	info->rx_seg_capa.offset_align_log2 = 0;
 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
 				 info->rx_queue_offload_capa);
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 1d1f2556de..2625fa3308 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -1562,7 +1562,7 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		  uint32_t *actual_log_stride_size)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	uint32_t log_min_stride_num = dev_cap->mprq.log_min_stride_num;
 	uint32_t log_max_stride_num = dev_cap->mprq.log_max_stride_num;
@@ -1681,7 +1681,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_rxq_ctrl *tmpl;
 	unsigned int mb_len = rte_pktmbuf_data_room_size(rx_seg[0].mp);
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	uint64_t offloads = conf->offloads |
 			   dev->data->dev_conf.rxmode.offloads;
 	unsigned int lro_on_queue = !!(offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO);
diff --git a/drivers/net/mlx5/mlx5_tx.c b/drivers/net/mlx5/mlx5_tx.c
index fd2cf20967..fecec7dad7 100644
--- a/drivers/net/mlx5/mlx5_tx.c
+++ b/drivers/net/mlx5/mlx5_tx.c
@@ -517,7 +517,7 @@ eth_tx_burst_t
 mlx5_select_tx_function(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 	unsigned int diff = 0, olx = 0, i, m;
 
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 3373ee66b4..edbaa50692 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -100,7 +100,7 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	uint64_t offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
 			     RTE_ETH_TX_OFFLOAD_VLAN_INSERT);
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 
 	if (dev_cap->hw_csum)
@@ -741,7 +741,7 @@ static void
 txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	unsigned int inlen_send; /* Inline data for ordinary SEND.*/
 	unsigned int inlen_empw; /* Inline data for enhanced MPW. */
@@ -960,7 +960,7 @@ static int
 txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	unsigned int max_inline;
 
 	max_inline = txq_calc_inline_max(txq_ctrl);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 04f9590096..f511f97494 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -284,8 +284,6 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
  *
  * @return
  *   A valid Ethernet device object on success, NULL otherwise and rte_errno
@@ -295,8 +293,7 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  */
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
-	       struct mlx5_dev_spawn_data *spawn,
-	       struct mlx5_dev_config *config)
+	       struct mlx5_dev_spawn_data *spawn)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
@@ -317,14 +314,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	/* Process parameters. */
-	err = mlx5_args(config, dpdk_dev->devargs);
-	if (err) {
-		err = rte_errno;
-		DRV_LOG(ERR, "failed to process device arguments: %s",
-			strerror(rte_errno));
-		goto error;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
@@ -396,24 +385,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	if (config->hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
-		config->hw_padding = 0;
-	}
-	DRV_LOG(DEBUG, "%sMPS is %s.",
-		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
-		config->mps == MLX5_MPW ? "legacy " : "",
-		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (config->cqe_comp) {
-		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->mprq.enabled) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
-		config->mprq.enabled = 0;
+	/* Process parameters and store port configuration on priv structure. */
+	err = mlx5_port_args_config(priv, dpdk_dev->devargs, &priv->config);
+	if (err) {
+		err = rte_errno;
+		DRV_LOG(ERR, "Failed to process port configure: %s",
+			strerror(rte_errno));
+		goto error;
 	}
-	if (config->max_dump_files_num == 0)
-		config->max_dump_files_num = 128;
 	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL) {
 		DRV_LOG(ERR, "can not allocate rte ethdev");
@@ -508,10 +487,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	/* Detect minimal data bytes to inline. */
-	mlx5_set_min_inline(spawn, config);
-	/* Store device configuration on private structure. */
-	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
 		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
 		if (sh->config.reclaim_mode)
@@ -817,18 +792,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			.name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK,
 		},
 	};
-	struct mlx5_dev_config dev_config = {
-		.rx_vec_en = 1,
-		.txq_inline_max = MLX5_ARG_UNSET,
-		.txq_inline_min = MLX5_ARG_UNSET,
-		.txq_inline_mpw = MLX5_ARG_UNSET,
-		.txqs_inline = MLX5_ARG_UNSET,
-		.mprq = {
-			.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN,
-			.min_rxqs_num = MLX5_MPRQ_MIN_RXQS,
-		},
-		.log_hp_size = MLX5_ARG_UNSET,
-	};
 	int ret;
 	uint32_t restore;
 
@@ -842,7 +805,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, &dev_config);
+	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn);
 	if (!spawn.eth_dev)
 		return -rte_errno;
 	restore = spawn.eth_dev->data->dev_flags;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 19/20] common/mlx5: add check for common devargs in probing again
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (17 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 18/20] net/mlx5: separate per port configuration Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-01-27 15:39 ` [PATCH 20/20] common/mlx5: refactor devargs management Michael Baum
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

MLX5 common driver supports probing again in two scenarios:
 - Add new driver under existing device. common probe function gets
   it in devargs, then calls the requested driver's probe function
   (regardless of the driver's own support in probing again) with the
   existing device as parameter.
 - Transfer the probing again support of the drivers themselves
   (currently only net). In this scenario, the existing device is sent
   as a parameter to the existing driver's probe too.

In both cases it gets a new set of arguments that do not necessarily
match the configured arguments in the existing device.
Some of the arguments belong to the configuration of the existing
device, so they can't be updated in the probing again. On the other
hand, there are arguments that belong to a specific driver or specific
port and might get a new value in the probing again.
The user might generate any argument he wants in probing again, but when
he generates arguments belonging to the common device configuration, it
does not affect.

This patch adds an explicit check for the devargs belonging to the
common device configuration. If there is no match to the existing
configuration, it returns an error.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.c | 100 ++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index 47a541f5ef..f74d27e74d 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -613,6 +613,86 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
 	return cdev;
 }
 
+/**
+ * Validate common devargs when probing again.
+ *
+ * When common device probing again, it cannot change its configurations.
+ * If user ask non compatible configurations in devargs, it is error.
+ * This function checks the match between:
+ *  - Common device configurations requested by probe again devargs.
+ *  - Existing common device configurations.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
+{
+	struct mlx5_common_dev_config *config;
+	int ret;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	/* Probe again doesn't have to generate devargs. */
+	if (cdev->dev->devargs == NULL)
+		return 0;
+	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
+			     sizeof(struct mlx5_common_dev_config),
+			     RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+	if (config == NULL) {
+		rte_errno = -ENOMEM;
+		return -rte_errno;
+	}
+	/*
+	 * Creates a temporary common configure structure according to new
+	 * devargs attached in probing again.
+	 */
+	ret = mlx5_common_config_get(cdev->dev->devargs, config);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		mlx5_free(config);
+		return ret;
+	}
+	/*
+	 * Checks the match between the temporary structure and the existing
+	 * common device structure.
+	 */
+	if (cdev->config.mr_ext_memseg_en ^ config->mr_ext_memseg_en) {
+		DRV_LOG(ERR, "\"mr_ext_memseg_en\" "
+			"configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.mr_mempool_reg_en ^ config->mr_mempool_reg_en) {
+		DRV_LOG(ERR, "\"mr_mempool_reg_en\" "
+			"configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.sys_mem_en ^ config->sys_mem_en) {
+		DRV_LOG(ERR,
+			"\"sys_mem_en\" configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.dbnc ^ config->dbnc) {
+		DRV_LOG(ERR, "\"dbnc\" configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	mlx5_free(config);
+	return 0;
+error:
+	mlx5_free(config);
+	rte_errno = EINVAL;
+	return -rte_errno;
+}
+
 static int
 drivers_remove(struct mlx5_common_device *cdev, uint32_t enabled_classes)
 {
@@ -699,12 +779,32 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 	if (classes == 0)
 		/* Default to net class. */
 		classes = MLX5_CLASS_ETH;
+	/*
+	 * MLX5 common driver supports probing again in two scenarios:
+	 * - Add new driver under existing common device (regardless of the
+	 *   driver's own support in probing again).
+	 * - Transfer the probing again support of the drivers themselves.
+	 *
+	 * In both scenarios it uses in the existing device. here it looks for
+	 * device that match to rte device, if it exists, the request classes
+	 * were probed with this device.
+	 */
 	cdev = to_mlx5_device(eal_dev);
 	if (!cdev) {
+		/* It isn't probing again, creates a new device. */
 		cdev = mlx5_common_dev_create(eal_dev, classes);
 		if (!cdev)
 			return -ENOMEM;
 		new_device = true;
+	} else {
+		/* It is probing again, validate common devargs match. */
+		ret = mlx5_common_probe_again_args_validate(cdev);
+		if (ret) {
+			DRV_LOG(ERR,
+				"Probe again parameters aren't compatible : %s",
+				strerror(rte_errno));
+			return ret;
+		}
 	}
 	/*
 	 * Validate combination here.
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH 20/20] common/mlx5: refactor devargs management
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (18 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
@ 2022-01-27 15:39 ` Michael Baum
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-01-27 15:39 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Improve the devargs handling in two aspects:
 - Parse the devargs string only once.
 - Return error and report for unknown keys.

The common driver parses once the devargs string into a dictionary, then
provides it to all the drivers' probe. Each driver updates within it
which keys it has used, then common driver receives the updated
dictionary and reports about unknown devargs.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.c     | 255 +++++++++++++++++++++-----
 drivers/common/mlx5/mlx5_common.h     |  36 +++-
 drivers/common/mlx5/version.map       |   2 +
 drivers/compress/mlx5/mlx5_compress.c |  38 ++--
 drivers/crypto/mlx5/mlx5_crypto.c     |  39 ++--
 drivers/net/mlx5/linux/mlx5_os.c      |  47 +++--
 drivers/net/mlx5/mlx5.c               | 212 ++++++++++++++-------
 drivers/net/mlx5/mlx5.h               |  14 +-
 drivers/net/mlx5/windows/mlx5_os.c    |  18 +-
 drivers/regex/mlx5/mlx5_regex.c       |   3 +-
 drivers/vdpa/mlx5/mlx5_vdpa.c         |  32 ++--
 11 files changed, 498 insertions(+), 198 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index f74d27e74d..96906d3f39 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -21,6 +21,24 @@
 
 uint8_t haswell_broadwell_cpu;
 
+/* Driver type key for new device global syntax. */
+#define MLX5_DRIVER_KEY "driver"
+
+/* Enable extending memsegs when creating a MR. */
+#define MLX5_MR_EXT_MEMSEG_EN "mr_ext_memseg_en"
+
+/* Device parameter to configure implicit registration of mempool memory. */
+#define MLX5_MR_MEMPOOL_REG_EN "mr_mempool_reg_en"
+
+/* The default memory allocator used in PMD. */
+#define MLX5_SYS_MEM_EN "sys_mem_en"
+
+/*
+ * Device parameter to force doorbell register mapping
+ * to non-cahed region eliminating the extra write memory barrier.
+ */
+#define MLX5_TX_DB_NC "tx_db_nc"
+
 /* In case this is an x86_64 intel processor to check if
  * we should use relaxed ordering.
  */
@@ -92,6 +110,122 @@ driver_get(uint32_t class)
 	return NULL;
 }
 
+int
+mlx5_kvargs_process(struct mlx5_kvargs_ctrl *mkvlist, const char *const keys[],
+		    arg_handler_t handler, void *opaque_arg)
+{
+	const struct rte_kvargs_pair *pair;
+	uint32_t i, j;
+
+	MLX5_ASSERT(mkvlist && mkvlist->kvlist);
+	/* Process parameters. */
+	for (i = 0; i < mkvlist->kvlist->count; i++) {
+		pair = &mkvlist->kvlist->pairs[i];
+		for (j = 0; keys[j] != NULL; ++j) {
+			if (strcmp(pair->key, keys[j]) != 0)
+				continue;
+			if ((*handler)(pair->key, pair->value, opaque_arg) < 0)
+				return -1;
+			mkvlist->is_used[i] = true;
+			break;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Prepare a mlx5 kvargs control.
+ *
+ * @param[out] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ * @param[in] devargs
+ *   The input string containing the key/value associations.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_kvargs_prepare(struct mlx5_kvargs_ctrl *mkvlist,
+		    const struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	uint32_t i;
+
+	if (devargs == NULL)
+		return 0;
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+	/*
+	 * rte_kvargs_parse enable key without value, in mlx5 PMDs we disable
+	 * this syntax.
+	 */
+	for (i = 0; i < kvlist->count; i++) {
+		const struct rte_kvargs_pair *pair = &kvlist->pairs[i];
+		if (pair->value == NULL || *(pair->value) == '\0') {
+			DRV_LOG(ERR, "Key %s is missing value.", pair->key);
+			rte_kvargs_free(kvlist);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+	}
+	/* Makes sure all devargs used array is false. */
+	memset(mkvlist, 0, sizeof(*mkvlist));
+	mkvlist->kvlist = kvlist;
+	DRV_LOG(DEBUG, "Parse successfully %u devargs.",
+		mkvlist->kvlist->count);
+	return 0;
+}
+
+/**
+ * Release a mlx5 kvargs control.
+ *
+ * @param[out] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ */
+static void
+mlx5_kvargs_release(struct mlx5_kvargs_ctrl *mkvlist)
+{
+	if (mkvlist == NULL)
+		return;
+	rte_kvargs_free(mkvlist->kvlist);
+	memset(mkvlist, 0, sizeof(*mkvlist));
+}
+
+/**
+ * Validate device arguments list.
+ * It report about the first unknown parameter.
+ *
+ * @param[in] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_kvargs_validate(struct mlx5_kvargs_ctrl *mkvlist)
+{
+	uint32_t i;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	if (mkvlist == NULL)
+		return 0;
+	for (i = 0; i < mkvlist->kvlist->count; i++) {
+		if (mkvlist->is_used[i] == 0) {
+			DRV_LOG(ERR, "Key \"%s\" "
+				"is unknown for the provided classes.",
+				mkvlist->kvlist->pairs[i].key);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+	}
+	return 0;
+}
+
 /**
  * Verify and store value for devargs.
  *
@@ -111,11 +245,9 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 	struct mlx5_common_dev_config *config = opaque;
 	signed long tmp;
 
-	if (val == NULL || *val == '\0') {
-		DRV_LOG(ERR, "Key %s is missing value.", key);
-		rte_errno = EINVAL;
-		return -rte_errno;
-	}
+	if (strcmp(MLX5_DRIVER_KEY, key) == 0 ||
+	    strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0)
+		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
 	if (errno) {
@@ -123,7 +255,7 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 		DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.", key, val);
 		return -rte_errno;
 	}
-	if (strcmp(key, "tx_db_nc") == 0) {
+	if (strcmp(key, MLX5_TX_DB_NC) == 0) {
 		if (tmp != MLX5_TXDB_CACHED &&
 		    tmp != MLX5_TXDB_NCACHED &&
 		    tmp != MLX5_TXDB_HEURISTIC) {
@@ -132,11 +264,11 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 			return -rte_errno;
 		}
 		config->dbnc = tmp;
-	} else if (strcmp(key, "mr_ext_memseg_en") == 0) {
+	} else if (strcmp(key, MLX5_MR_EXT_MEMSEG_EN) == 0) {
 		config->mr_ext_memseg_en = !!tmp;
-	} else if (strcmp(key, "mr_mempool_reg_en") == 0) {
+	} else if (strcmp(key, MLX5_MR_MEMPOOL_REG_EN) == 0) {
 		config->mr_mempool_reg_en = !!tmp;
-	} else if (strcmp(key, "sys_mem_en") == 0) {
+	} else if (strcmp(key, MLX5_SYS_MEM_EN) == 0) {
 		config->sys_mem_en = !!tmp;
 	}
 	return 0;
@@ -154,29 +286,34 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-mlx5_common_config_get(struct rte_devargs *devargs,
+mlx5_common_config_get(struct mlx5_kvargs_ctrl *mkvlist,
 		       struct mlx5_common_dev_config *config)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		RTE_DEVARGS_KEY_CLASS,
+		MLX5_DRIVER_KEY,
+		MLX5_TX_DB_NC,
+		MLX5_MR_EXT_MEMSEG_EN,
+		MLX5_SYS_MEM_EN,
+		MLX5_MR_MEMPOOL_REG_EN,
+		NULL,
+	};
 	int ret = 0;
 
+	if (mkvlist == NULL)
+		return 0;
 	/* Set defaults. */
 	config->mr_ext_memseg_en = 1;
 	config->mr_mempool_reg_en = 1;
 	config->sys_mem_en = 0;
 	config->dbnc = MLX5_ARG_UNSET;
-	if (devargs == NULL)
-		return 0;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
+	/* Process common parameters. */
+	ret = mlx5_kvargs_process(mkvlist, params,
+				  mlx5_common_args_check_handler, config);
+	if (ret) {
 		rte_errno = EINVAL;
-		return -rte_errno;
-	}
-	ret = rte_kvargs_process(kvlist, NULL, mlx5_common_args_check_handler,
-				 config);
-	if (ret)
 		ret = -rte_errno;
-	rte_kvargs_free(kvlist);
+	}
 	DRV_LOG(DEBUG, "mr_ext_memseg_en is %u.", config->mr_ext_memseg_en);
 	DRV_LOG(DEBUG, "mr_mempool_reg_en is %u.", config->mr_mempool_reg_en);
 	DRV_LOG(DEBUG, "sys_mem_en is %u.", config->sys_mem_en);
@@ -225,9 +362,9 @@ devargs_class_handler(__rte_unused const char *key,
 }
 
 static int
-parse_class_options(const struct rte_devargs *devargs)
+parse_class_options(const struct rte_devargs *devargs,
+		    struct mlx5_kvargs_ctrl *mkvlist)
 {
-	struct rte_kvargs *kvlist;
 	int ret = 0;
 
 	if (devargs == NULL)
@@ -236,12 +373,8 @@ parse_class_options(const struct rte_devargs *devargs)
 		/* Global syntax, only one class type. */
 		return class_name_to_value(devargs->cls->name);
 	/* Legacy devargs support multiple classes. */
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
-		return 0;
-	rte_kvargs_process(kvlist, RTE_DEVARGS_KEY_CLASS,
+	rte_kvargs_process(mkvlist->kvlist, RTE_DEVARGS_KEY_CLASS,
 			   devargs_class_handler, &ret);
-	rte_kvargs_free(kvlist);
 	return ret;
 }
 
@@ -564,7 +697,8 @@ mlx5_common_dev_release(struct mlx5_common_device *cdev)
 }
 
 static struct mlx5_common_device *
-mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
+mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes,
+		       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_common_device *cdev;
 	int ret;
@@ -579,7 +713,7 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		goto exit;
 	/* Parse device parameters. */
-	ret = mlx5_common_config_get(eal_dev->devargs, &cdev->config);
+	ret = mlx5_common_config_get(mkvlist, &cdev->config);
 	if (ret < 0) {
 		DRV_LOG(ERR, "Failed to process device arguments: %s",
 			strerror(rte_errno));
@@ -624,12 +758,15 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
  *
  * @param cdev
  *   Pointer to mlx5 device structure.
+ * @param 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_common_probe_again_args_validate(struct mlx5_common_device *cdev)
+mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev,
+				      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_common_dev_config *config;
 	int ret;
@@ -638,7 +775,7 @@ mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 	/* Probe again doesn't have to generate devargs. */
-	if (cdev->dev->devargs == NULL)
+	if (mkvlist == NULL)
 		return 0;
 	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			     sizeof(struct mlx5_common_dev_config),
@@ -651,7 +788,7 @@ mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
 	 * Creates a temporary common configure structure according to new
 	 * devargs attached in probing again.
 	 */
-	ret = mlx5_common_config_get(cdev->dev->devargs, config);
+	ret = mlx5_common_config_get(mkvlist, config);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
@@ -719,7 +856,8 @@ drivers_remove(struct mlx5_common_device *cdev, uint32_t enabled_classes)
 }
 
 static int
-drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes)
+drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes,
+	      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_class_driver *driver;
 	uint32_t enabled_classes = 0;
@@ -738,7 +876,7 @@ drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes)
 			ret = -EEXIST;
 			goto probe_err;
 		}
-		ret = driver->probe(cdev);
+		ret = driver->probe(cdev, mkvlist);
 		if (ret < 0) {
 			DRV_LOG(ERR, "Failed to load driver %s",
 				driver->name);
@@ -764,17 +902,27 @@ int
 mlx5_common_dev_probe(struct rte_device *eal_dev)
 {
 	struct mlx5_common_device *cdev;
+	struct mlx5_kvargs_ctrl mkvlist;
+	struct mlx5_kvargs_ctrl *mkvlist_p = NULL;
 	uint32_t classes = 0;
 	bool new_device = false;
 	int ret;
 
 	DRV_LOG(INFO, "probe device \"%s\".", eal_dev->name);
-	ret = parse_class_options(eal_dev->devargs);
+	if (eal_dev->devargs != NULL)
+		mkvlist_p = &mkvlist;
+	ret = mlx5_kvargs_prepare(mkvlist_p, eal_dev->devargs);
 	if (ret < 0) {
-		DRV_LOG(ERR, "Unsupported mlx5 class type: %s",
+		DRV_LOG(ERR, "Unsupported device arguments: %s",
 			eal_dev->devargs->args);
 		return ret;
 	}
+	ret = parse_class_options(eal_dev->devargs, mkvlist_p);
+	if (ret < 0) {
+		DRV_LOG(ERR, "Unsupported mlx5 class type: %s",
+			eal_dev->devargs->args);
+		goto class_err;
+	}
 	classes = ret;
 	if (classes == 0)
 		/* Default to net class. */
@@ -792,18 +940,20 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 	cdev = to_mlx5_device(eal_dev);
 	if (!cdev) {
 		/* It isn't probing again, creates a new device. */
-		cdev = mlx5_common_dev_create(eal_dev, classes);
-		if (!cdev)
-			return -ENOMEM;
+		cdev = mlx5_common_dev_create(eal_dev, classes, mkvlist_p);
+		if (!cdev) {
+			ret = -ENOMEM;
+			goto class_err;
+		}
 		new_device = true;
 	} else {
 		/* It is probing again, validate common devargs match. */
-		ret = mlx5_common_probe_again_args_validate(cdev);
+		ret = mlx5_common_probe_again_args_validate(cdev, mkvlist_p);
 		if (ret) {
 			DRV_LOG(ERR,
 				"Probe again parameters aren't compatible : %s",
 				strerror(rte_errno));
-			return ret;
+			goto class_err;
 		}
 	}
 	/*
@@ -816,13 +966,30 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 		DRV_LOG(ERR, "Unsupported mlx5 classes combination.");
 		goto class_err;
 	}
-	ret = drivers_probe(cdev, classes);
+	ret = drivers_probe(cdev, classes, mkvlist_p);
+	if (ret)
+		goto class_err;
+	/*
+	 * Validate that all devargs have been used, unused key -> unknown Key.
+	 * When probe again validate is failed, the added drivers aren't removed
+	 * here but when device is released.
+	 */
+	ret = mlx5_kvargs_validate(mkvlist_p);
 	if (ret)
 		goto class_err;
+	mlx5_kvargs_release(mkvlist_p);
 	return 0;
 class_err:
-	if (new_device)
+	if (new_device) {
+		/*
+		 * For new device, classes_loaded is always 0 before
+		 * drivers_probe function.
+		 */
+		if (cdev->classes_loaded)
+			drivers_remove(cdev, cdev->classes_loaded);
 		mlx5_common_dev_release(cdev);
+	}
+	mlx5_kvargs_release(mkvlist_p);
 	return ret;
 }
 
diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index 80f59c81fb..49bcea1d91 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -281,6 +281,37 @@ struct mlx5_klm {
 	uint64_t address;
 };
 
+/** Control for key/values list. */
+struct mlx5_kvargs_ctrl {
+	struct rte_kvargs *kvlist; /* Structure containing list of key/values.*/
+	bool is_used[RTE_KVARGS_MAX]; /* Indicator which devargs were used. */
+};
+
+/**
+ * Call a handler function for each key/value in the list of keys.
+ *
+ * For each key/value association that matches the given key, calls the
+ * handler function with the for a given arg_name passing the value on the
+ * dictionary for that key and a given extra argument.
+ *
+ * @param mkvlist
+ *   The mlx5_kvargs structure.
+ * @param keys
+ *   A list of keys to process (table of const char *, the last must be NULL).
+ * @param handler
+ *   The function to call for each matching key.
+ * @param opaque_arg
+ *   A pointer passed unchanged to the handler.
+ *
+ * @return
+ *   - 0 on success
+ *   - Negative on error
+ */
+__rte_internal
+int
+mlx5_kvargs_process(struct mlx5_kvargs_ctrl *mkvlist, const char *const keys[],
+		    arg_handler_t handler, void *opaque_arg);
+
 /* All UAR arguments using doorbell register in datapath. */
 struct mlx5_uar_data {
 	uint64_t *db;
@@ -437,12 +468,13 @@ struct mlx5_common_device {
 /**
  * Initialization function for the driver called during device probing.
  */
-typedef int (mlx5_class_driver_probe_t)(struct mlx5_common_device *dev);
+typedef int (mlx5_class_driver_probe_t)(struct mlx5_common_device *cdev,
+					struct mlx5_kvargs_ctrl *mkvlist);
 
 /**
  * Uninitialization function for the driver called during hot-unplugging.
  */
-typedef int (mlx5_class_driver_remove_t)(struct mlx5_common_device *dev);
+typedef int (mlx5_class_driver_remove_t)(struct mlx5_common_device *cdev);
 
 /** Device already probed can be probed again to check for new ports. */
 #define MLX5_DRV_PROBE_AGAIN 0x0004
diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map
index 59ab434631..1c6153c576 100644
--- a/drivers/common/mlx5/version.map
+++ b/drivers/common/mlx5/version.map
@@ -85,6 +85,8 @@ INTERNAL {
 
 	mlx5_glue;
 
+	mlx5_kvargs_process;
+
 	mlx5_list_create;
 	mlx5_list_register;
 	mlx5_list_unregister;
diff --git a/drivers/compress/mlx5/mlx5_compress.c b/drivers/compress/mlx5/mlx5_compress.c
index 82b871bd86..3fc7f4c434 100644
--- a/drivers/compress/mlx5/mlx5_compress.c
+++ b/drivers/compress/mlx5/mlx5_compress.c
@@ -657,41 +657,36 @@ mlx5_compress_args_check_handler(const char *key, const char *val, void *opaque)
 		errno = 0;
 		devarg_prms->log_block_sz = (uint32_t)strtoul(val, NULL, 10);
 		if (errno) {
-			DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer."
-				, key, val);
+			DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.",
+				key, val);
 			return -errno;
 		}
-		return 0;
 	}
 	return 0;
 }
 
 static int
-mlx5_compress_handle_devargs(struct rte_devargs *devargs,
-			  struct mlx5_compress_devarg_params *devarg_prms,
-			  struct mlx5_hca_attr *att)
+mlx5_compress_handle_devargs(struct mlx5_kvargs_ctrl *mkvlist,
+			     struct mlx5_compress_devarg_params *devarg_prms,
+			     struct mlx5_hca_attr *att)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"log-block-size",
+		NULL,
+	};
 
 	devarg_prms->log_block_sz = MLX5_GGA_COMP_LOG_BLOCK_SIZE_MAX;
-	if (devargs == NULL)
+	if (mkvlist == NULL)
 		return 0;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		DRV_LOG(ERR, "Failed to parse devargs.");
-		rte_errno = EINVAL;
-		return -1;
-	}
-	if (rte_kvargs_process(kvlist, NULL, mlx5_compress_args_check_handler,
-			   devarg_prms) != 0) {
+	if (mlx5_kvargs_process(mkvlist, params,
+				mlx5_compress_args_check_handler,
+				devarg_prms) != 0) {
 		DRV_LOG(ERR, "Devargs handler function Failed.");
-		rte_kvargs_free(kvlist);
 		rte_errno = EINVAL;
 		return -1;
 	}
-	rte_kvargs_free(kvlist);
 	if (devarg_prms->log_block_sz > MLX5_GGA_COMP_LOG_BLOCK_SIZE_MAX ||
-		devarg_prms->log_block_sz < att->compress_min_block_size) {
+	    devarg_prms->log_block_sz < att->compress_min_block_size) {
 		DRV_LOG(WARNING, "Log block size provided is out of range("
 			"%u); default it to %u.",
 			devarg_prms->log_block_sz,
@@ -702,7 +697,8 @@ mlx5_compress_handle_devargs(struct rte_devargs *devargs,
 }
 
 static int
-mlx5_compress_dev_probe(struct mlx5_common_device *cdev)
+mlx5_compress_dev_probe(struct mlx5_common_device *cdev,
+			struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct rte_compressdev *compressdev;
 	struct mlx5_compress_priv *priv;
@@ -726,7 +722,7 @@ mlx5_compress_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = ENOTSUP;
 		return -ENOTSUP;
 	}
-	mlx5_compress_handle_devargs(cdev->dev->devargs, &devarg_prms, attr);
+	mlx5_compress_handle_devargs(mkvlist, &devarg_prms, attr);
 	compressdev = rte_compressdev_pmd_create(ibdev_name, cdev->dev,
 						 sizeof(*priv), &init_params);
 	if (compressdev == NULL) {
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index 421c23748a..e14f867797 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -722,8 +722,6 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
 	int ret;
 	int i;
 
-	if (strcmp(key, "class") == 0)
-		return 0;
 	if (strcmp(key, "wcs_file") == 0) {
 		file = fopen(val, "rb");
 		if (file == NULL) {
@@ -763,48 +761,44 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
 		attr->credential_pointer = (uint32_t)tmp;
 	} else if (strcmp(key, "keytag") == 0) {
 		devarg_prms->keytag = tmp;
-	} else {
-		DRV_LOG(WARNING, "Invalid key %s.", key);
 	}
 	return 0;
 }
 
 static int
-mlx5_crypto_parse_devargs(struct rte_devargs *devargs,
+mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
 			  struct mlx5_crypto_devarg_params *devarg_prms)
 {
 	struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"credential_id",
+		"import_kek_id",
+		"keytag",
+		"max_segs_num",
+		"wcs_file",
+		NULL,
+	};
 
 	/* Default values. */
 	attr->credential_pointer = 0;
 	attr->session_import_kek_ptr = 0;
 	devarg_prms->keytag = 0;
 	devarg_prms->max_segs_num = 8;
-	if (devargs == NULL) {
+	if (mkvlist == NULL) {
 		DRV_LOG(ERR,
-	"No login devargs in order to enable crypto operations in the device.");
-		rte_errno = EINVAL;
-		return -1;
-	}
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		DRV_LOG(ERR, "Failed to parse devargs.");
+			"No login devargs in order to enable crypto operations in the device.");
 		rte_errno = EINVAL;
 		return -1;
 	}
-	if (rte_kvargs_process(kvlist, NULL, mlx5_crypto_args_check_handler,
-			   devarg_prms) != 0) {
+	if (mlx5_kvargs_process(mkvlist, params, mlx5_crypto_args_check_handler,
+				devarg_prms) != 0) {
 		DRV_LOG(ERR, "Devargs handler function Failed.");
-		rte_kvargs_free(kvlist);
 		rte_errno = EINVAL;
 		return -1;
 	}
-	rte_kvargs_free(kvlist);
 	if (devarg_prms->login_devarg == false) {
 		DRV_LOG(ERR,
-	"No login credential devarg in order to enable crypto operations "
-	"in the device.");
+			"No login credential devarg in order to enable crypto operations in the device.");
 		rte_errno = EINVAL;
 		return -1;
 	}
@@ -887,7 +881,8 @@ mlx5_crypto_configure_wqe_size(struct mlx5_crypto_priv *priv,
 }
 
 static int
-mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
+mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
+		      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct rte_cryptodev *crypto_dev;
 	struct mlx5_devx_obj *login;
@@ -914,7 +909,7 @@ mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = ENOTSUP;
 		return -ENOTSUP;
 	}
-	ret = mlx5_crypto_parse_devargs(cdev->dev->devargs, &devarg_prms);
+	ret = mlx5_crypto_parse_devargs(mkvlist, &devarg_prms);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to parse devargs.");
 		return -rte_errno;
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 6979385782..b2172ed1fd 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1001,6 +1001,8 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
  *   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
@@ -1012,7 +1014,8 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
 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;
@@ -1062,6 +1065,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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;
 	}
@@ -1103,7 +1112,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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);
@@ -1354,7 +1363,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #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",
@@ -1840,6 +1849,8 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
  *   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.
@@ -1847,7 +1858,7 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 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;
 	/*
@@ -2217,7 +2228,8 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	for (i = 0; i != ns; ++i) {
 		uint32_t restore;
 
-		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da);
+		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da,
+						 mkvlist);
 		if (!list[i].eth_dev) {
 			if (rte_errno != EBUSY && rte_errno != EEXIST)
 				break;
@@ -2329,12 +2341,15 @@ mlx5_os_parse_eth_devargs(struct rte_device *dev,
  *
  * @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 };
@@ -2349,7 +2364,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev)
 		/* 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, &eth_da,
-						   eth_da.ports[p]);
+						   eth_da.ports[p], mkvlist);
 			if (ret)
 				break;
 		}
@@ -2362,14 +2377,15 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev)
 			mlx5_net_remove(cdev);
 		}
 	} else {
-		ret = mlx5_os_pci_probe_pf(cdev, &eth_da, 0);
+		ret = mlx5_os_pci_probe_pf(cdev, &eth_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 };
@@ -2394,7 +2410,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	spawn.ifindex = ret;
 	spawn.cdev = cdev;
 	/* Spawn device. */
-	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da);
+	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da, mkvlist);
 	if (eth_dev == NULL)
 		return -rte_errno;
 	/* Post create. */
@@ -2415,12 +2431,15 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
  *
  * @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;
 
@@ -2432,16 +2451,16 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			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);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b3601155d7..a59a46bb27 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -43,9 +43,6 @@
 
 #define MLX5_ETH_DRIVER_NAME mlx5_eth
 
-/* Driver type key for new device global syntax. */
-#define MLX5_DRIVER_KEY "driver"
-
 /* Device parameter to enable RX completion queue compression. */
 #define MLX5_RXQ_CQE_COMP_EN "rxq_cqe_comp_en"
 
@@ -94,12 +91,6 @@
 /* Device parameter to enable multi-packet send WQEs. */
 #define MLX5_TXQ_MPW_EN "txq_mpw_en"
 
-/*
- * Device parameter to force doorbell register mapping
- * to non-cahed region eliminating the extra write memory barrier.
- */
-#define MLX5_TX_DB_NC "tx_db_nc"
-
 /*
  * Device parameter to include 2 dsegs in the title WQEBB.
  * Deprecated, ignored.
@@ -152,9 +143,6 @@
 /* Activate Netlink support in VF mode. */
 #define MLX5_VF_NL_EN "vf_nl_en"
 
-/* Enable extending memsegs when creating a MR. */
-#define MLX5_MR_EXT_MEMSEG_EN "mr_ext_memseg_en"
-
 /* Select port representors to instantiate. */
 #define MLX5_REPRESENTOR "representor"
 
@@ -173,17 +161,12 @@
 /* Flow memory reclaim mode. */
 #define MLX5_RECLAIM_MEM "reclaim_mem_mode"
 
-/* The default memory allocator used in PMD. */
-#define MLX5_SYS_MEM_EN "sys_mem_en"
 /* Decap will be used or not. */
 #define MLX5_DECAP_EN "decap_en"
 
 /* Device parameter to configure allow or prevent duplicate rules pattern. */
 #define MLX5_ALLOW_DUPLICATE_PATTERN "allow_duplicate_pattern"
 
-/* Device parameter to configure implicit registration of mempool memory. */
-#define MLX5_MR_MEMPOOL_REG_EN "mr_mempool_reg_en"
-
 /* Device parameter to configure the delay drop when creating Rxqs. */
 #define MLX5_DELAY_DROP "delay_drop"
 
@@ -1255,8 +1238,8 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
  *
  * @param sh
  *   Pointer to shared device context.
- * @param devargs
- *   Device arguments structure.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  * @param config
  *   Pointer to shared device configuration structure.
  *
@@ -1265,10 +1248,23 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
  */
 static int
 mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
-				struct rte_devargs *devargs,
+				struct mlx5_kvargs_ctrl *mkvlist,
 				struct mlx5_sh_config *config)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		MLX5_TX_PP,
+		MLX5_TX_SKEW,
+		MLX5_L3_VXLAN_EN,
+		MLX5_VF_NL_EN,
+		MLX5_DV_ESW_EN,
+		MLX5_DV_FLOW_EN,
+		MLX5_DV_XMETA_EN,
+		MLX5_LACP_BY_USER,
+		MLX5_RECLAIM_MEM,
+		MLX5_DECAP_EN,
+		MLX5_ALLOW_DUPLICATE_PATTERN,
+		NULL,
+	};
 	int ret = 0;
 
 	/* Default configuration. */
@@ -1278,19 +1274,10 @@ mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
 	config->dv_flow_en = 1;
 	config->decap_en = 1;
 	config->allow_duplicate_pattern = 1;
-	/* Parse device parameters. */
-	if (devargs != NULL) {
-		kvlist = rte_kvargs_parse(devargs->args, NULL);
-		if (kvlist == NULL) {
-			DRV_LOG(ERR,
-				"Failed to parse shared device arguments.");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
+	if (mkvlist != NULL) {
 		/* Process parameters. */
-		ret = rte_kvargs_process(kvlist, NULL,
-					 mlx5_dev_args_check_handler, config);
-		rte_kvargs_free(kvlist);
+		ret = mlx5_kvargs_process(mkvlist, params,
+					  mlx5_dev_args_check_handler, config);
 		if (ret) {
 			DRV_LOG(ERR, "Failed to process device arguments: %s",
 				strerror(rte_errno));
@@ -1398,13 +1385,16 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
  *
  * @param[in] spawn
  *   Pointer to the device attributes (name, port, etc).
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  *
  * @return
  *   Pointer to mlx5_dev_ctx_shared object on success,
  *   otherwise NULL and rte_errno is set.
  */
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+			  struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_dev_ctx_shared *sh;
 	int err = 0;
@@ -1443,8 +1433,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
 		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
-	err = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
-					      &sh->config);
+	err = mlx5_shared_dev_ctx_args_config(sh, mkvlist, &sh->config);
 	if (err) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
@@ -2107,15 +2096,7 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
-	if (!strcmp(MLX5_DRIVER_KEY, key) || !strcmp(MLX5_REPRESENTOR, key) ||
-	    !strcmp(MLX5_SYS_MEM_EN, key) || !strcmp(MLX5_TX_DB_NC, key) ||
-	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) || !strcmp(MLX5_TX_PP, key) ||
-	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key) || !strcmp(MLX5_TX_SKEW, key) ||
-	    !strcmp(MLX5_RECLAIM_MEM, key) || !strcmp(MLX5_DECAP_EN, key) ||
-	    !strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) ||
-	    !strcmp(MLX5_L3_VXLAN_EN, key) || !strcmp(MLX5_VF_NL_EN, key) ||
-	    !strcmp(MLX5_DV_ESW_EN, key) || !strcmp(MLX5_DV_FLOW_EN, key) ||
-	    !strcmp(MLX5_DV_XMETA_EN, key) || !strcmp(MLX5_LACP_BY_USER, key))
+	if (!strcmp(MLX5_REPRESENTOR, key))
 		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
@@ -2181,17 +2162,11 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
 		config->lro_timeout = tmp;
-	} else if (strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0) {
-		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
 		config->log_hp_size = tmp;
 	} else if (strcmp(MLX5_DELAY_DROP, key) == 0) {
 		config->std_delay_drop = !!(tmp & MLX5_DELAY_DROP_STANDARD);
 		config->hp_delay_drop = !!(tmp & MLX5_DELAY_DROP_HAIRPIN);
-	} else {
-		DRV_LOG(WARNING,
-			"%s: unknown parameter, maybe it's for another class.",
-			key);
 	}
 	return 0;
 }
@@ -2201,8 +2176,8 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
  *
  * @param priv
  *   Pointer to shared device context.
- * @param devargs
- *   Device arguments structure.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  * @param config
  *   Pointer to port configuration structure.
  *
@@ -2210,13 +2185,38 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+mlx5_port_args_config(struct mlx5_priv *priv, struct mlx5_kvargs_ctrl *mkvlist,
 		      struct mlx5_port_config *config)
 {
-	struct rte_kvargs *kvlist;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	bool devx = priv->sh->cdev->config.devx;
+	const char **params = (const char *[]){
+		MLX5_RXQ_CQE_COMP_EN,
+		MLX5_RXQ_PKT_PAD_EN,
+		MLX5_RX_MPRQ_EN,
+		MLX5_RX_MPRQ_LOG_STRIDE_NUM,
+		MLX5_RX_MPRQ_LOG_STRIDE_SIZE,
+		MLX5_RX_MPRQ_MAX_MEMCPY_LEN,
+		MLX5_RXQS_MIN_MPRQ,
+		MLX5_TXQ_INLINE,
+		MLX5_TXQ_INLINE_MIN,
+		MLX5_TXQ_INLINE_MAX,
+		MLX5_TXQ_INLINE_MPW,
+		MLX5_TXQS_MIN_INLINE,
+		MLX5_TXQS_MAX_VEC,
+		MLX5_TXQ_MPW_EN,
+		MLX5_TXQ_MPW_HDR_DSEG_EN,
+		MLX5_TXQ_MAX_INLINE_LEN,
+		MLX5_TX_VEC_EN,
+		MLX5_RX_VEC_EN,
+		MLX5_REPRESENTOR,
+		MLX5_MAX_DUMP_FILES_NUM,
+		MLX5_LRO_TIMEOUT_USEC,
+		MLX5_HP_BUF_SIZE,
+		MLX5_DELAY_DROP,
+		NULL,
+	};
 	int ret = 0;
 
 	/* Default configuration. */
@@ -2234,19 +2234,10 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
 	config->log_hp_size = MLX5_ARG_UNSET;
 	config->std_delay_drop = 0;
 	config->hp_delay_drop = 0;
-	/* Parse device parameters. */
-	if (devargs != NULL) {
-		kvlist = rte_kvargs_parse(devargs->args, NULL);
-		if (kvlist == NULL) {
-			DRV_LOG(ERR,
-				"Failed to parse device arguments.");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
+	if (mkvlist != NULL) {
 		/* Process parameters. */
-		ret = rte_kvargs_process(kvlist, NULL,
-					 mlx5_port_args_check_handler, config);
-		rte_kvargs_free(kvlist);
+		ret = mlx5_kvargs_process(mkvlist, params,
+					  mlx5_port_args_check_handler, config);
 		if (ret) {
 			DRV_LOG(ERR, "Failed to process port arguments: %s",
 				strerror(rte_errno));
@@ -2349,6 +2340,85 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
 	return 0;
 }
 
+/**
+ * Print the key for device argument.
+ *
+ * It is "dummy" handler whose whole purpose is to enable using
+ * mlx5_kvargs_process() function which set devargs as used.
+ *
+ * @param key
+ *   Key argument.
+ * @param val
+ *   Value associated with key, unused.
+ * @param opaque
+ *   Unused, can be NULL.
+ *
+ * @return
+ *   0 on success, function cannot fail.
+ */
+static int
+mlx5_dummy_handler(const char *key, const char *val, void *opaque)
+{
+	DRV_LOG(DEBUG, "\tKey: \"%s\" is set as used.", key);
+	RTE_SET_USED(opaque);
+	RTE_SET_USED(val);
+	return 0;
+}
+
+/**
+ * Set requested devargs as used when device is already spawned.
+ *
+ * It is necessary since it is valid to ask probe again for existing device,
+ * if its devargs don't assign as used, mlx5_kvargs_validate() will fail.
+ *
+ * @param name
+ *   Name of the existing device.
+ * @param port_id
+ *   Port identifier of the device.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control to sign as used.
+ */
+void
+mlx5_port_args_set_used(const char *name, uint16_t port_id,
+			struct mlx5_kvargs_ctrl *mkvlist)
+{
+	const char **params = (const char *[]){
+		MLX5_RXQ_CQE_COMP_EN,
+		MLX5_RXQ_PKT_PAD_EN,
+		MLX5_RX_MPRQ_EN,
+		MLX5_RX_MPRQ_LOG_STRIDE_NUM,
+		MLX5_RX_MPRQ_LOG_STRIDE_SIZE,
+		MLX5_RX_MPRQ_MAX_MEMCPY_LEN,
+		MLX5_RXQS_MIN_MPRQ,
+		MLX5_TXQ_INLINE,
+		MLX5_TXQ_INLINE_MIN,
+		MLX5_TXQ_INLINE_MAX,
+		MLX5_TXQ_INLINE_MPW,
+		MLX5_TXQS_MIN_INLINE,
+		MLX5_TXQS_MAX_VEC,
+		MLX5_TXQ_MPW_EN,
+		MLX5_TXQ_MPW_HDR_DSEG_EN,
+		MLX5_TXQ_MAX_INLINE_LEN,
+		MLX5_TX_VEC_EN,
+		MLX5_RX_VEC_EN,
+		MLX5_REPRESENTOR,
+		MLX5_MAX_DUMP_FILES_NUM,
+		MLX5_LRO_TIMEOUT_USEC,
+		MLX5_HP_BUF_SIZE,
+		MLX5_DELAY_DROP,
+		NULL,
+	};
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return;
+	MLX5_ASSERT(mkvlist != NULL);
+	DRV_LOG(DEBUG, "Ethernet device \"%s\" for port %u "
+		"already exists, set devargs as used:", name, port_id);
+	/* This function cannot fail with this handler. */
+	mlx5_kvargs_process(mkvlist, params, mlx5_dummy_handler, NULL);
+}
+
 /**
  * Check sibling device configurations when probing again.
  *
@@ -2357,12 +2427,15 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
  *
  * @param cdev
  *   Pointer to mlx5 device structure.
+ * @param 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_probe_again_args_validate(struct mlx5_common_device *cdev)
+mlx5_probe_again_args_validate(struct mlx5_common_device *cdev,
+			       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_sh_config *config;
@@ -2391,8 +2464,7 @@ mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
 	 * Creates a temporary IB context configure structure according to new
 	 * devargs attached in probing again.
 	 */
-	ret = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
-					      config);
+	ret = mlx5_shared_dev_ctx_args_config(sh, mkvlist, config);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 95910aba1b..35ea3fb47c 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1541,16 +1541,21 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn);
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+			  struct mlx5_kvargs_ctrl *mkvlist);
 void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
 int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_priv *priv);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
-int mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev,
+				   struct mlx5_kvargs_ctrl *mkvlist);
+int mlx5_port_args_config(struct mlx5_priv *priv,
+			  struct mlx5_kvargs_ctrl *mkvlist,
 			  struct mlx5_port_config *config);
+void mlx5_port_args_set_used(const char *name, uint16_t port_id,
+			     struct mlx5_kvargs_ctrl *mkvlist);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
@@ -1811,7 +1816,8 @@ void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev);
 struct rte_pci_driver;
 int mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_free_shared_dr(struct mlx5_priv *priv);
-int mlx5_os_net_probe(struct mlx5_common_device *cdev);
+int mlx5_os_net_probe(struct mlx5_common_device *cdev,
+		      struct mlx5_kvargs_ctrl *mkvlist);
 void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index f511f97494..965df80106 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -284,6 +284,8 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
+ * @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
@@ -293,7 +295,8 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  */
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
-	       struct mlx5_dev_spawn_data *spawn)
+	       struct mlx5_dev_spawn_data *spawn,
+	       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
@@ -314,7 +317,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	sh = mlx5_alloc_shared_dev_ctx(spawn);
+	sh = mlx5_alloc_shared_dev_ctx(spawn, mkvlist);
 	if (!sh)
 		return NULL;
 	if (!sh->config.dv_flow_en) {
@@ -386,7 +389,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		own_domain_id = 1;
 	}
 	/* 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",
@@ -770,14 +773,17 @@ mlx5_os_set_allmulti(struct rte_eth_dev *dev, int enable)
  *
  * This function spawns Ethernet devices out of a given device.
  *
- * @param[in] dev
+ * @param[in] cdev
  *   Pointer to the common 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)
 {
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data spawn = {
@@ -805,7 +811,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn);
+	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, mkvlist);
 	if (!spawn.eth_dev)
 		return -rte_errno;
 	restore = spawn.eth_dev->data->dev_flags;
diff --git a/drivers/regex/mlx5/mlx5_regex.c b/drivers/regex/mlx5/mlx5_regex.c
index e5a12fb3cc..dc2bd868ea 100644
--- a/drivers/regex/mlx5/mlx5_regex.c
+++ b/drivers/regex/mlx5/mlx5_regex.c
@@ -67,7 +67,8 @@ mlx5_regex_get_name(char *name, struct rte_device *dev)
 }
 
 static int
-mlx5_regex_dev_probe(struct mlx5_common_device *cdev)
+mlx5_regex_dev_probe(struct mlx5_common_device *cdev,
+		     struct mlx5_kvargs_ctrl *mkvlist __rte_unused)
 {
 	struct mlx5_regex_priv *priv = NULL;
 	struct mlx5_hca_attr *attr = &cdev->config.hca_attr;
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index b9e84dd9bf..cb3a1ac340 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -443,8 +443,6 @@ mlx5_vdpa_args_check_handler(const char *key, const char *val, void *opaque)
 	unsigned long tmp;
 	int n_cores = sysconf(_SC_NPROCESSORS_ONLN);
 
-	if (strcmp(key, RTE_DEVARGS_KEY_CLASS) == 0)
-		return 0;
 	errno = 0;
 	tmp = strtoul(val, NULL, 0);
 	if (errno) {
@@ -471,28 +469,33 @@ mlx5_vdpa_args_check_handler(const char *key, const char *val, void *opaque)
 		priv->hw_max_latency_us = (uint32_t)tmp;
 	} else if (strcmp(key, "hw_max_pending_comp") == 0) {
 		priv->hw_max_pending_comp = (uint32_t)tmp;
-	} else {
-		DRV_LOG(WARNING, "Invalid key %s.", key);
 	}
 	return 0;
 }
 
 static void
-mlx5_vdpa_config_get(struct rte_devargs *devargs, struct mlx5_vdpa_priv *priv)
+mlx5_vdpa_config_get(struct mlx5_kvargs_ctrl *mkvlist,
+		     struct mlx5_vdpa_priv *priv)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"event_core",
+		"event_mode",
+		"event_us",
+		"hw_latency_mode",
+		"hw_max_latency_us",
+		"hw_max_pending_comp",
+		"no_traffic_time",
+		NULL,
+	};
 
 	priv->event_mode = MLX5_VDPA_EVENT_MODE_FIXED_TIMER;
 	priv->event_us = 0;
 	priv->event_core = -1;
 	priv->no_traffic_max = MLX5_VDPA_DEFAULT_NO_TRAFFIC_MAX;
-	if (devargs == NULL)
-		return;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (mkvlist == NULL)
 		return;
-	rte_kvargs_process(kvlist, NULL, mlx5_vdpa_args_check_handler, priv);
-	rte_kvargs_free(kvlist);
+	mlx5_kvargs_process(mkvlist, params, mlx5_vdpa_args_check_handler,
+			    priv);
 	if (!priv->event_us &&
 	    priv->event_mode == MLX5_VDPA_EVENT_MODE_DYNAMIC_TIMER)
 		priv->event_us = MLX5_VDPA_DEFAULT_TIMER_STEP_US;
@@ -502,7 +505,8 @@ mlx5_vdpa_config_get(struct rte_devargs *devargs, struct mlx5_vdpa_priv *priv)
 }
 
 static int
-mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev)
+mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev,
+		    struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_vdpa_priv *priv = NULL;
 	struct mlx5_hca_attr *attr = &cdev->config.hca_attr;
@@ -555,7 +559,7 @@ mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = rte_errno ? rte_errno : EINVAL;
 		goto error;
 	}
-	mlx5_vdpa_config_get(cdev->dev->devargs, priv);
+	mlx5_vdpa_config_get(mkvlist, priv);
 	SLIST_INIT(&priv->mr_list);
 	pthread_mutex_init(&priv->vq_config_lock, NULL);
 	pthread_mutex_lock(&priv_list_lock);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 00/20] mlx5: refactor devargs management
  2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
                   ` (19 preceding siblings ...)
  2022-01-27 15:39 ` [PATCH 20/20] common/mlx5: refactor devargs management Michael Baum
@ 2022-02-14  9:34 ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
                     ` (20 more replies)
  20 siblings, 21 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

v2: rebase + fix coverity issue.

These patches rearrange the management of the devargs on two different
levels.

The first splits the net driver's devargs into two categories,
device-dependent devargs and port-dependent devargs.
Arguments that depend on the device are updated once in the creation of
the shared device context structure, and do not change even if the user
has sent new devargs in the probe again. In contrast, the arguments that
depend on the port are updated separately for each port.

The second layer deals with the parsing of devargs in the common driver.
The common driver once parses the devargs into a dictionary, then sends
it to all the drivers that will use it during the their probing. Each
driver updates within dictionary which keys it has used, then the common
driver checks the updated dictionary and reports about unknown devargs.

Michael Baum (20):
  net/mlx5: fix wrong check sibling device config mismatch
  net/mlx5: fix ineffective metadata argument adjustment
  net/mlx5: fix wrong place of ASO CT object release
  net/mlx5: fix inconsistency errno update in SH creation
  net/mlx5: remove declaration duplications
  net/mlx5: remove checking devargs duplication
  net/mlx5: remove HCA attr structure duplication
  net/mlx5: remove DevX flag duplication
  net/mlx5: remove Verbs query device duplication
  common/mlx5: share VF checking function
  net/mlx5: share realtime timestamp configure
  net/mlx5: share counter config function
  net/mlx5: add E-switch mode flag
  net/mlx5: rearrange device attribute structure
  net/mlx5: concentrate all device configurations
  net/mlx5: add share device context config structure
  net/mlx5: using function to detect operation by DevX
  net/mlx5: separate per port configuration
  common/mlx5: add check for common devargs in probing again
  common/mlx5: refactor devargs management

 drivers/common/mlx5/mlx5_common.c       | 345 +++++++--
 drivers/common/mlx5/mlx5_common.h       |  51 +-
 drivers/common/mlx5/mlx5_common_pci.c   |  18 +
 drivers/common/mlx5/version.map         |   3 +
 drivers/compress/mlx5/mlx5_compress.c   |  38 +-
 drivers/crypto/mlx5/mlx5_crypto.c       |  39 +-
 drivers/net/mlx5/linux/mlx5_flow_os.c   |   3 +-
 drivers/net/mlx5/linux/mlx5_os.c        | 887 +++++++++---------------
 drivers/net/mlx5/linux/mlx5_verbs.c     |   9 +-
 drivers/net/mlx5/linux/mlx5_vlan_os.c   |   3 +-
 drivers/net/mlx5/mlx5.c                 | 872 +++++++++++++++++------
 drivers/net/mlx5/mlx5.h                 | 216 +++---
 drivers/net/mlx5/mlx5_devx.c            |  19 +-
 drivers/net/mlx5/mlx5_ethdev.c          |  31 +-
 drivers/net/mlx5/mlx5_flow.c            |  50 +-
 drivers/net/mlx5/mlx5_flow.h            |   2 +-
 drivers/net/mlx5/mlx5_flow_dv.c         |  93 ++-
 drivers/net/mlx5/mlx5_flow_flex.c       |   4 +-
 drivers/net/mlx5/mlx5_flow_meter.c      |  14 +-
 drivers/net/mlx5/mlx5_rxmode.c          |   8 +-
 drivers/net/mlx5/mlx5_rxq.c             |  49 +-
 drivers/net/mlx5/mlx5_trigger.c         |  35 +-
 drivers/net/mlx5/mlx5_tx.c              |   2 +-
 drivers/net/mlx5/mlx5_txpp.c            |  14 +-
 drivers/net/mlx5/mlx5_txq.c             |  62 +-
 drivers/net/mlx5/mlx5_vlan.c            |   4 +-
 drivers/net/mlx5/windows/mlx5_flow_os.c |   2 +-
 drivers/net/mlx5/windows/mlx5_os.c      | 342 +++------
 drivers/regex/mlx5/mlx5_regex.c         |   3 +-
 drivers/vdpa/mlx5/mlx5_vdpa.c           |  32 +-
 30 files changed, 1842 insertions(+), 1408 deletions(-)

-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 01/20] net/mlx5: fix wrong check sibling device config mismatch
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
                     ` (19 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The MLX5 net driver supports "probe again". In probing again, it
creates a new ethdev under an existing infiniband device context.

Sibling devices sharing infiniband device context should have compatible
configurations, so some of the devargs given in the probe again, the
ones that are mainly relevant to the sharing device context are sent to
the mlx5_dev_check_sibling_config function which makes sure that they
compatible its siblings.
However, the arguments are adjusted according to the capability of the
device, and the function compares the arguments of the probe again
before the adjustment with the arguments of the siblings after the
adjustment. A user who sends the same values to all siblings may fail in
this comparison if he requested something that the device does not
support and adjusted.

This patch moves the call to the mlx5_dev_check_sibling_config function
after the relevant adjustments.

Fixes: 92d5dd483450 ("net/mlx5: check sibling device configurations mismatch")
Fixes: 2d241515ebaf ("net/mlx5: add devarg for extensive metadata support")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 41 ++++++++++++++++--------------
 drivers/net/mlx5/windows/mlx5_os.c | 28 ++++++++++++--------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index bbe05bb837..e157795b63 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1241,6 +1241,28 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
+	/* Update final values for devargs before check sibling config. */
+#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
+	if (config->dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	      (switch_info->representor || switch_info->master)))
+		config->dv_esw_en = 0;
+#else
+	config->dv_esw_en = 0;
+#endif
+	if (!priv->config.dv_esw_en &&
+	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			priv->config.dv_xmeta_en);
+		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
 	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
 	if (err)
 		goto error;
@@ -1251,12 +1273,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
 	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
 	DRV_LOG(DEBUG, "counters are not supported");
-#endif
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported");
-		config->dv_flow_en = 0;
-	}
 #endif
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
@@ -1652,13 +1668,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(config->hca_attr.eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
-		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
 	/* Detect minimal data bytes to inline. */
 	mlx5_set_min_inline(spawn, config);
 	/* Store device configuration on private structure. */
@@ -1725,12 +1734,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		err = -err;
 		goto error;
 	}
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING, "metadata mode %u is not supported "
-				 "(no E-Switch)", priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
 	mlx5_set_metadata_mask(eth_dev);
 	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 7f3532426f..3db33cd0cf 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -439,6 +439,21 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
+	/* Update final values for devargs before check sibling config. */
+	config->dv_esw_en = 0;
+	if (!config->dv_flow_en) {
+		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
+		err = ENOTSUP;
+		goto error;
+	}
+	if (!priv->config.dv_esw_en &&
+	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			priv->config.dv_xmeta_en);
+		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
 	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
 	if (err)
 		goto error;
@@ -600,7 +615,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	config->dv_esw_en = 0;
 	/* Detect minimal data bytes to inline. */
 	mlx5_set_min_inline(spawn, config);
 	/* Store device configuration on private structure. */
@@ -622,12 +636,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* No supported flow priority number detection. */
 	priv->sh->flow_max_priority = -1;
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING, "metadata mode %u is not supported "
-				 "(no E-Switch)", priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
 	mlx5_set_metadata_mask(eth_dev);
 	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
@@ -661,12 +669,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			goto error;
 		}
 	}
-	if (sh->devx && config->dv_flow_en) {
+	if (sh->devx) {
 		priv->obj_ops = devx_obj_ops;
 	} else {
-		DRV_LOG(ERR, "Flow mode %u is not supported "
-				"(Windows flow must be DevX with DV flow enabled).",
-				priv->config.dv_flow_en);
+		DRV_LOG(ERR, "Windows flow must be DevX.");
 		err = ENOTSUP;
 		goto error;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 02/20] net/mlx5: fix ineffective metadata argument adjustment
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
  2022-02-14  9:34   ` [PATCH v2 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
                     ` (18 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

In "dv_xmeta_en" devarg there is an option of dv_xmeta_en=3 which
engages tunnel offload mode. In E-Switch configuration, that mode
implicitly activates dv_xmeta_en=1.

The update according to E-switch support is done immediately after the
first parsing of the devargs, but there is another adjustment later.

This patch moves the adjustment after the second parsing.

Fixes: 4ec6360de37d ("net/mlx5: implement tunnel offload")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index e157795b63..69d3e1e3ad 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -977,10 +977,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		goto error;
 	}
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
@@ -1242,6 +1238,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Override some values set by hardware configuration. */
 	mlx5_args(config, dpdk_dev->devargs);
 	/* Update final values for devargs before check sibling config. */
+	if (config->dv_miss_info) {
+		if (switch_info->master || switch_info->representor)
+			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	}
 #if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
 	if (config->dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 03/20] net/mlx5: fix wrong place of ASO CT object release
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
  2022-02-14  9:34   ` [PATCH v2 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
  2022-02-14  9:34   ` [PATCH v2 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
                     ` (17 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The ASO connection tracking structure is initialized once for sharing
device context.

Its release takes place in the close function which is called for each
ethdev individually. i.e. when there is more than one ethdev under the
same sharing device context, it will be destroyed when one of them is
closed. If the other wants to use it later, it may cause it to crash.

In addition, the creation of this structure is performed in the spawn
function. if one of the creations of the objects following it fails, it
is supposed to be destroyed but this does not happen.

This patch moves its release to the sharing device context free function
and thus solves both problems.

Fixes: 0af8a2298a42 ("net/mlx5: release connection tracking management")
Fixes: ee9e5fad03eb ("net/mlx5: initialize connection tracking management")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/mlx5.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 5571e90677..cde8d022cd 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1321,6 +1321,8 @@ mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh)
 	 *  Only primary process handles async device events.
 	 **/
 	mlx5_flow_counters_mng_close(sh);
+	if (sh->ct_mng)
+		mlx5_flow_aso_ct_mng_close(sh);
 	if (sh->aso_age_mng) {
 		mlx5_flow_aso_age_mng_close(sh);
 		sh->aso_age_mng = NULL;
@@ -1594,8 +1596,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 	if (priv->mreg_cp_tbl)
 		mlx5_hlist_destroy(priv->mreg_cp_tbl);
 	mlx5_mprq_free_mp(dev);
-	if (priv->sh->ct_mng)
-		mlx5_flow_aso_ct_mng_close(priv->sh);
 	mlx5_os_free_shared_dr(priv);
 	if (priv->rss_conf.rss_key != NULL)
 		mlx5_free(priv->rss_conf.rss_key);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 04/20] net/mlx5: fix inconsistency errno update in SH creation
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (2 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 05/20] net/mlx5: remove declaration duplications Michael Baum
                     ` (16 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko, stable

The mlx5_alloc_shared_dev_ctx() function has a local variable named
"err" which contains the errno value in case of failure.

When functions called by this function are failed, this variable is
updated with their return value (that should be a positive errno value).
However, some functions doesn't update errno value by themselves or
return negative errno value. If one of them fails, the "err" variable
contains negative value what cause to assertion failure.

This patch updates all functions uses by mlx5_alloc_shared_dev_ctx()
function to update rte_errno and take this value instead of "err" value.

Fixes: 5dfa003db53f ("common/mlx5: fix post doorbell barrier")
Fixes: 5d55a494f4e6 ("net/mlx5: split multi-thread flow handling per OS")
Cc: stable@dpdk.org

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_flow_os.c   |  3 ++-
 drivers/net/mlx5/linux/mlx5_os.c        | 16 ++++++++++------
 drivers/net/mlx5/mlx5.c                 | 24 +++++++++++-------------
 drivers/net/mlx5/windows/mlx5_flow_os.c |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c      | 24 ++++++++++++------------
 5 files changed, 36 insertions(+), 33 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_flow_os.c b/drivers/net/mlx5/linux/mlx5_flow_os.c
index 893f00b824..a5956c255a 100644
--- a/drivers/net/mlx5/linux/mlx5_flow_os.c
+++ b/drivers/net/mlx5/linux/mlx5_flow_os.c
@@ -14,7 +14,8 @@ mlx5_flow_os_init_workspace_once(void)
 {
 	if (rte_thread_key_create(&key_workspace, flow_release_workspace)) {
 		DRV_LOG(ERR, "Can't create flow workspace data thread key.");
-		return -ENOMEM;
+		rte_errno = ENOMEM;
+		return -rte_errno;
 	}
 	return 0;
 }
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 69d3e1e3ad..faab310b11 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -138,7 +138,7 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Pointer to mlx5 device attributes.
  *
  * @return
- *   0 on success, non zero error number otherwise
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
 mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
@@ -150,8 +150,10 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 
 	memset(device_attr, 0, sizeof(*device_attr));
 	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
-	if (err)
-		return err;
+	if (err) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 	device_attr->device_cap_flags_ex = attr_ex.device_cap_flags_ex;
 	device_attr->max_qp_wr = attr_ex.orig_attr.max_qp_wr;
 	device_attr->max_sge = attr_ex.orig_attr.max_sge;
@@ -170,8 +172,10 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
-	if (err)
-		return err;
+	if (err) {
+		rte_errno = errno;
+		return -rte_errno;
+	}
 
 	device_attr->flags = dv_attr.flags;
 	device_attr->comp_mask = dv_attr.comp_mask;
@@ -195,7 +199,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	strlcpy(device_attr->fw_ver, attr_ex.orig_attr.fw_ver,
 		sizeof(device_attr->fw_ver));
 
-	return err;
+	return 0;
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index cde8d022cd..0e154b88ed 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1172,12 +1172,11 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	MLX5_ASSERT(spawn->max_port);
 	sh = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			 sizeof(struct mlx5_dev_ctx_shared) +
-			 spawn->max_port *
-			 sizeof(struct mlx5_dev_shared_port),
+			 spawn->max_port * sizeof(struct mlx5_dev_shared_port),
 			 RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
 	if (!sh) {
-		DRV_LOG(ERR, "shared context allocation failure");
-		rte_errno  = ENOMEM;
+		DRV_LOG(ERR, "Shared context allocation failure.");
+		rte_errno = ENOMEM;
 		goto exit;
 	}
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
@@ -1199,9 +1198,8 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	strncpy(sh->ibdev_path, mlx5_os_get_ctx_device_path(sh->cdev->ctx),
 		sizeof(sh->ibdev_path) - 1);
 	/*
-	 * Setting port_id to max unallowed value means
-	 * there is no interrupt subhandler installed for
-	 * the given port index i.
+	 * Setting port_id to max unallowed value means there is no interrupt
+	 * subhandler installed for the given port index i.
 	 */
 	for (i = 0; i < sh->max_port; i++) {
 		sh->port[i].ih_port_id = RTE_MAX_ETHPORTS;
@@ -1211,12 +1209,12 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		sh->td = mlx5_devx_cmd_create_td(sh->cdev->ctx);
 		if (!sh->td) {
 			DRV_LOG(ERR, "TD allocation failure");
-			err = ENOMEM;
+			rte_errno = ENOMEM;
 			goto error;
 		}
 		if (mlx5_setup_tis(sh)) {
 			DRV_LOG(ERR, "TIS allocation failure");
-			err = ENOMEM;
+			rte_errno = ENOMEM;
 			goto error;
 		}
 		err = mlx5_rxtx_uars_prepare(sh);
@@ -1246,19 +1244,19 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
 	return sh;
 error:
+	err = rte_errno;
 	pthread_mutex_destroy(&sh->txpp.mutex);
 	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
 	MLX5_ASSERT(sh);
-	if (sh->td)
-		claim_zero(mlx5_devx_cmd_destroy(sh->td));
+	mlx5_rxtx_uars_release(sh);
 	i = 0;
 	do {
 		if (sh->tis[i])
 			claim_zero(mlx5_devx_cmd_destroy(sh->tis[i]));
 	} while (++i < (uint32_t)sh->bond.n_port);
-	mlx5_rxtx_uars_release(sh);
+	if (sh->td)
+		claim_zero(mlx5_devx_cmd_destroy(sh->td));
 	mlx5_free(sh);
-	MLX5_ASSERT(err > 0);
 	rte_errno = err;
 	return NULL;
 }
diff --git a/drivers/net/mlx5/windows/mlx5_flow_os.c b/drivers/net/mlx5/windows/mlx5_flow_os.c
index 7bb4c4590a..f5e3893ed4 100644
--- a/drivers/net/mlx5/windows/mlx5_flow_os.c
+++ b/drivers/net/mlx5/windows/mlx5_flow_os.c
@@ -372,7 +372,7 @@ mlx5_flow_os_init_workspace_once(void)
 
 	if (err) {
 		DRV_LOG(ERR, "Can't create flow workspace data thread key.");
-		return err;
+		return -rte_errno;
 	}
 	pthread_mutex_init(&lock_thread_list, NULL);
 	return 0;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 3db33cd0cf..a9619e5bda 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -152,7 +152,7 @@ mlx5_init_once(void)
  *   Pointer to mlx5 device attributes.
  *
  * @return
- *   0 on success, non zero error number otherwise.
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
 mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
@@ -161,10 +161,11 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	struct mlx5_context *mlx5_ctx;
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
-	int err = 0;
 
-	if (!cdev || !cdev->ctx)
-		return -EINVAL;
+	if (!cdev || !cdev->ctx) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
 	mlx5_ctx = (struct mlx5_context *)cdev->ctx;
 	memset(device_attr, 0, sizeof(*device_attr));
 	device_attr->max_cq = 1 << cdev->config.hca_attr.log_max_cq;
@@ -187,15 +188,14 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
 		DRV_LOG(ERR, "Failed to get device hca_iseg");
-		return errno;
-	}
-	if (!err) {
-		snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
-			MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+		rte_errno = errno;
+		return -rte_errno;
 	}
-	return err;
+	snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
+		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+	return 0;
 }
 
 /**
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 05/20] net/mlx5: remove declaration duplications
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (3 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 06/20] net/mlx5: remove checking devargs duplication Michael Baum
                     ` (15 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

In mlx5_ethdev.c file are implemented those 4 functions:
 - mlx5_dev_infos_get
 - mlx5_fw_version_get
 - mlx5_dev_set_mtu
 - mlx5_hairpin_cap_get

In mlx5.h file they are declared twice. First time under mlx5.c file and
second time under mlx5_ethdev.c file.

This patch removes the redundant declaration.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/mlx5.h | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 737ad6895c..823a943978 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1532,11 +1532,6 @@ void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
 int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
 				  struct mlx5_dev_config *config,
 				  struct rte_device *dpdk_dev);
-int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
-int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
-int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
-			 struct rte_eth_hairpin_cap *cap);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 int mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh);
@@ -1556,10 +1551,8 @@ int mlx5_representor_info_get(struct rte_eth_dev *dev,
 		(((repr_id) >> 12) & 3)
 uint16_t mlx5_representor_id_encode(const struct mlx5_switch_info *info,
 				    enum rte_eth_representor_type hpf_type);
-int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver,
-			size_t fw_size);
-int mlx5_dev_infos_get(struct rte_eth_dev *dev,
-		       struct rte_eth_dev_info *info);
+int mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info);
+int mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size);
 const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 int mlx5_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu);
 int mlx5_hairpin_cap_get(struct rte_eth_dev *dev,
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 06/20] net/mlx5: remove checking devargs duplication
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (4 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 05/20] net/mlx5: remove declaration duplications Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
                     ` (14 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The device arguments are parsed and updated twice during spawning. First
time before creating the share device context, and again later after
updating a default value to one of the arguments.

This patch consolidates them into one parsing and updates the default
values before it.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 73 +++++++++++++-----------------
 drivers/net/mlx5/mlx5.c            | 23 +++++-----
 drivers/net/mlx5/mlx5.h            |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c | 49 ++++++++------------
 4 files changed, 65 insertions(+), 82 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index faab310b11..191da1bee9 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -968,22 +968,45 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mlx5_dev_close(eth_dev);
 		return NULL;
 	}
-	/*
-	 * Some parameters ("tx_db_nc" in particularly) are needed in
-	 * advance to create dv/verbs device context. We proceed the
-	 * devargs here to get ones, and later proceed devargs again
-	 * to override some hardware settings.
-	 */
+	/* Process parameters. */
 	err = mlx5_args(config, dpdk_dev->devargs);
 	if (err) {
-		err = rte_errno;
 		DRV_LOG(ERR, "failed to process device arguments: %s",
 			strerror(rte_errno));
-		goto error;
+		return NULL;
 	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
+	/* Update final values for devargs before check sibling config. */
+	if (config->dv_miss_info) {
+		if (switch_info->master || switch_info->representor)
+			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	}
+#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
+	if (config->dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	      (switch_info->representor || switch_info->master)))
+		config->dv_esw_en = 0;
+#else
+	config->dv_esw_en = 0;
+#endif
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
+	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
+	if (err)
+		goto error;
 #ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
 	config->dest_tir = 1;
 #endif
@@ -1049,8 +1072,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			mprq_caps.max_single_wqe_log_num_of_strides;
 	}
 #endif
-	/* Rx CQE compression is enabled by default. */
-	config->cqe_comp = 1;
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
 	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
 		config->tunnel_en = dv_attr.tunnel_offloads_caps &
@@ -1239,37 +1260,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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);
-	/* Update final values for devargs before check sibling config. */
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported.");
-		config->dv_flow_en = 0;
-	}
-#endif
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
-		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
-	if (err)
-		goto error;
 	config->hw_csum = !!(sh->device_attr.device_cap_flags_ex &
 			    IBV_DEVICE_RAW_IP_CSUM);
 	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
@@ -2049,6 +2039,7 @@ mlx5_os_config_default(struct mlx5_dev_config *config,
 {
 	memset(config, 0, sizeof(*config));
 	config->mps = MLX5_ARG_UNSET;
+	config->cqe_comp = 1;
 	config->rx_vec_en = 1;
 	config->txq_inline_max = MLX5_ARG_UNSET;
 	config->txq_inline_min = MLX5_ARG_UNSET;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 0e154b88ed..d1215e5627 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2216,25 +2216,26 @@ rte_pmd_mlx5_get_dyn_flag_names(char *names[], unsigned int n)
 }
 
 /**
- * Comparison callback to sort device data.
+ * Check sibling device configurations.
  *
- * This is meant to be used with qsort().
+ * Sibling devices sharing the Infiniband device context should have compatible
+ * configurations. This regards representors and bonding device.
  *
- * @param a[in]
- *   Pointer to pointer to first data object.
- * @param b[in]
- *   Pointer to pointer to second data object.
+ * @param sh
+ *   Shared device context.
+ * @param config
+ *   Configuration of the device is going to be created.
+ * @param dpdk_dev
+ *   Backing DPDK device.
  *
  * @return
- *   0 if both objects are equal, less than 0 if the first argument is less
- *   than the second, greater than 0 otherwise.
+ *   0 on success, EINVAL otherwise
  */
 int
-mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
+mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_dev_config *config,
 			      struct rte_device *dpdk_dev)
 {
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	struct mlx5_dev_config *sh_conf = NULL;
 	uint16_t port_id;
 
@@ -2247,7 +2248,7 @@ mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
 		struct mlx5_priv *opriv =
 			rte_eth_devices[port_id].data->dev_private;
 
-		if (opriv && opriv != priv && opriv->sh == sh) {
+		if (opriv && opriv->sh == sh) {
 			sh_conf = &opriv->config;
 			break;
 		}
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 823a943978..e4b2523eb0 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1529,7 +1529,7 @@ int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			 struct mlx5_dev_config *config);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_dev_check_sibling_config(struct mlx5_priv *priv,
+int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 				  struct mlx5_dev_config *config,
 				  struct rte_device *dpdk_dev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index a9619e5bda..0966da10f4 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -321,7 +321,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
-	unsigned int cqe_comp;
 	struct rte_ether_addr mac;
 	char name[RTE_ETH_NAME_MAX_LEN];
 	int own_domain_id = 0;
@@ -336,11 +335,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	/*
-	 * Some parameters are needed in advance to create device context. We
-	 * process the devargs here to get ones, and later process devargs
-	 * again to override some hardware settings.
-	 */
+	/* Process parameters. */
 	err = mlx5_args(config, dpdk_dev->devargs);
 	if (err) {
 		err = rte_errno;
@@ -351,6 +346,24 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
 	if (!sh)
 		return NULL;
+	/* Update final values for devargs before check sibling config. */
+	config->dv_esw_en = 0;
+	if (!config->dv_flow_en) {
+		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
+		err = ENOTSUP;
+		goto error;
+	}
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	/* Check sibling device configurations. */
+	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
+	if (err)
+		goto error;
 	/* Initialize the shutdown event in mlx5_dev_spawn to
 	 * support mlx5_is_removed for Windows.
 	 */
@@ -367,8 +380,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
-	cqe_comp = 0;
-	config->cqe_comp = cqe_comp;
 	config->tunnel_en = device_attr.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
@@ -437,26 +448,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	/* Override some values set by hardware configuration. */
-	mlx5_args(config, dpdk_dev->devargs);
-	/* Update final values for devargs before check sibling config. */
-	config->dv_esw_en = 0;
-	if (!config->dv_flow_en) {
-		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
-		err = ENOTSUP;
-		goto error;
-	}
-	if (!priv->config.dv_esw_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			priv->config.dv_xmeta_en);
-		priv->config.dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(priv, config, dpdk_dev);
-	if (err)
-		goto error;
 	DRV_LOG(DEBUG, "counters are not supported");
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
@@ -479,7 +470,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (config->cqe_comp && !cqe_comp) {
+	if (config->cqe_comp) {
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 07/20] net/mlx5: remove HCA attr structure duplication
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (5 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 06/20] net/mlx5: remove checking devargs duplication Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:34   ` [PATCH v2 08/20] net/mlx5: remove DevX flag duplication Michael Baum
                     ` (13 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The HCA attribute structure is field of net configure structure.
It is also field of common configure structure.

There is no need for this duplication, because there is a reference to
the common structure from within the net structures.

This patch removes it from net configure structure and uses the common
config structure instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 95 ++++++++++++++----------------
 drivers/net/mlx5/mlx5.c            | 14 +++--
 drivers/net/mlx5/mlx5.h            |  1 -
 drivers/net/mlx5/mlx5_devx.c       |  8 ++-
 drivers/net/mlx5/mlx5_ethdev.c     |  2 +-
 drivers/net/mlx5/mlx5_flow.c       | 16 ++---
 drivers/net/mlx5/mlx5_flow_dv.c    | 13 ++--
 drivers/net/mlx5/mlx5_flow_flex.c  |  4 +-
 drivers/net/mlx5/mlx5_flow_meter.c |  4 +-
 drivers/net/mlx5/mlx5_rxq.c        |  4 +-
 drivers/net/mlx5/mlx5_trigger.c    | 12 ++--
 drivers/net/mlx5/mlx5_txpp.c       |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c | 25 ++++----
 13 files changed, 100 insertions(+), 100 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 191da1bee9..b3ee1f7dc4 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -675,6 +675,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	bool fallback;
 
 #ifndef HAVE_IBV_DEVX_ASYNC
@@ -682,16 +683,16 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #else
 	fallback = false;
 	if (!sh->devx || !priv->config.dv_flow_en ||
-	    !priv->config.hca_attr.flow_counters_dump ||
-	    !(priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
 		fallback = true;
 #endif
 	if (fallback)
 		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
 			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			priv->config.hca_attr.flow_counters_dump,
-			priv->config.hca_attr.flow_counter_bulk_alloc_bitmap);
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
 	/* Initialize fallback mode only on the port initializes sh. */
 	if (sh->refcnt == 1)
 		sh->cmng.counter_fallback = fallback;
@@ -875,6 +876,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
+	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	struct rte_eth_dev *eth_dev = NULL;
@@ -990,7 +992,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 #endif
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(sh->cdev->config.hca_attr.eswitch_manager && config->dv_flow_en &&
+	if (!(hca_attr->eswitch_manager && config->dv_flow_en &&
 	      (switch_info->representor || switch_info->master)))
 		config->dv_esw_en = 0;
 #else
@@ -1315,14 +1317,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->devx) {
-		config->hca_attr = sh->cdev->config.hca_attr;
-		sh->steering_format_version =
-			config->hca_attr.steering_format_version;
+		sh->steering_format_version = hca_attr->steering_format_version;
 		/* Check for LRO support. */
-		if (config->dest_tir && config->hca_attr.lro_cap &&
+		if (config->dest_tir && hca_attr->lro_cap &&
 		    config->dv_flow_en) {
 			/* TBD check tunnel lro caps. */
-			config->lro.supported = config->hca_attr.lro_cap;
+			config->lro.supported = hca_attr->lro_cap;
 			DRV_LOG(DEBUG, "Device supports LRO");
 			/*
 			 * If LRO timeout is not configured by application,
@@ -1330,21 +1330,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			 */
 			if (!config->lro.timeout)
 				config->lro.timeout =
-				config->hca_attr.lro_timer_supported_periods[0];
+				       hca_attr->lro_timer_supported_periods[0];
 			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
 				config->lro.timeout);
 			DRV_LOG(DEBUG, "LRO minimal size of TCP segment "
 				"required for coalescing is %d bytes",
-				config->hca_attr.lro_min_mss_size);
+				hca_attr->lro_min_mss_size);
 		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
-		if (config->hca_attr.qos.sup &&
-		    config->hca_attr.qos.flow_meter_old &&
+		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_old &&
 		    config->dv_flow_en) {
-			uint8_t reg_c_mask =
-				config->hca_attr.qos.flow_meter_reg_c_ids;
+			uint8_t reg_c_mask = hca_attr->qos.flow_meter_reg_c_ids;
 			/*
 			 * Meter needs two REG_C's for color match and pre-sfx
 			 * flow match. Here get the REG_C for color match.
@@ -1368,20 +1366,18 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 					priv->mtr_color_reg = ffs(reg_c_mask)
 							      - 1 + REG_C_0;
 				priv->mtr_en = 1;
-				priv->mtr_reg_share =
-				      config->hca_attr.qos.flow_meter;
+				priv->mtr_reg_share = hca_attr->qos.flow_meter;
 				DRV_LOG(DEBUG, "The REG_C meter uses is %d",
 					priv->mtr_color_reg);
 			}
 		}
-		if (config->hca_attr.qos.sup &&
-			config->hca_attr.qos.flow_meter_aso_sup) {
+		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_aso_sup) {
 			uint32_t log_obj_size =
 				rte_log2_u32(MLX5_ASO_MTRS_PER_POOL >> 1);
 			if (log_obj_size >=
-			config->hca_attr.qos.log_meter_aso_granularity &&
-			log_obj_size <=
-			config->hca_attr.qos.log_meter_aso_max_alloc)
+			    hca_attr->qos.log_meter_aso_granularity &&
+			    log_obj_size <=
+			    hca_attr->qos.log_meter_aso_max_alloc)
 				sh->meter_aso_en = 1;
 		}
 		if (priv->mtr_en) {
@@ -1391,12 +1387,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				goto error;
 			}
 		}
-		if (config->hca_attr.flow.tunnel_header_0_1)
+		if (hca_attr->flow.tunnel_header_0_1)
 			sh->tunnel_header_0_1 = 1;
 #endif
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
-		if (config->hca_attr.flow_hit_aso &&
-		    priv->mtr_color_reg == REG_C_3) {
+		if (hca_attr->flow_hit_aso && priv->mtr_color_reg == REG_C_3) {
 			sh->flow_hit_aso_en = 1;
 			err = mlx5_flow_aso_age_mng_init(sh);
 			if (err) {
@@ -1408,8 +1403,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO */
 #if defined(HAVE_MLX5_DR_CREATE_ACTION_ASO) && \
 	defined(HAVE_MLX5_DR_ACTION_ASO_CT)
-		if (config->hca_attr.ct_offload &&
-		    priv->mtr_color_reg == REG_C_3) {
+		if (hca_attr->ct_offload && priv->mtr_color_reg == REG_C_3) {
 			err = mlx5_flow_aso_ct_mng_init(sh);
 			if (err) {
 				err = -err;
@@ -1420,13 +1414,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO && HAVE_MLX5_DR_ACTION_ASO_CT */
 #if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_SAMPLE)
-		if (config->hca_attr.log_max_ft_sampler_num > 0  &&
+		if (hca_attr->log_max_ft_sampler_num > 0  &&
 		    config->dv_flow_en) {
 			priv->sampler_en = 1;
 			DRV_LOG(DEBUG, "Sampler enabled!");
 		} else {
 			priv->sampler_en = 0;
-			if (!config->hca_attr.log_max_ft_sampler_num)
+			if (!hca_attr->log_max_ft_sampler_num)
 				DRV_LOG(WARNING,
 					"No available register for sampler.");
 			else
@@ -1440,13 +1434,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->devx || !config->hca_attr.mini_cqe_resp_flow_tag)) {
+	    (!sh->devx || !hca_attr->mini_cqe_resp_flow_tag)) {
 		DRV_LOG(WARNING, "Flow Tag CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->devx || !config->hca_attr.mini_cqe_resp_l3_l4_tag)) {
+	    (!sh->devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
 		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
@@ -1455,55 +1449,55 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			config->cqe_comp ? "" : "not ");
 	if (config->tx_pp) {
 		DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz",
-			config->hca_attr.dev_freq_khz);
+			hca_attr->dev_freq_khz);
 		DRV_LOG(DEBUG, "Packet pacing is %ssupported",
-			config->hca_attr.qos.packet_pacing ? "" : "not ");
+			hca_attr->qos.packet_pacing ? "" : "not ");
 		DRV_LOG(DEBUG, "Cross channel ops are %ssupported",
-			config->hca_attr.cross_channel ? "" : "not ");
+			hca_attr->cross_channel ? "" : "not ");
 		DRV_LOG(DEBUG, "WQE index ignore is %ssupported",
-			config->hca_attr.wqe_index_ignore ? "" : "not ");
+			hca_attr->wqe_index_ignore ? "" : "not ");
 		DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported",
-			config->hca_attr.non_wire_sq ? "" : "not ");
+			hca_attr->non_wire_sq ? "" : "not ");
 		DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
-			config->hca_attr.log_max_static_sq_wq ? "" : "not ",
-			config->hca_attr.log_max_static_sq_wq);
+			hca_attr->log_max_static_sq_wq ? "" : "not ",
+			hca_attr->log_max_static_sq_wq);
 		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
-			config->hca_attr.qos.wqe_rate_pp ? "" : "not ");
+			hca_attr->qos.wqe_rate_pp ? "" : "not ");
 		if (!sh->devx) {
 			DRV_LOG(ERR, "DevX is required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.qos.packet_pacing) {
+		if (!hca_attr->qos.packet_pacing) {
 			DRV_LOG(ERR, "Packet pacing is not supported");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.cross_channel) {
+		if (!hca_attr->cross_channel) {
 			DRV_LOG(ERR, "Cross channel operations are"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.wqe_index_ignore) {
+		if (!hca_attr->wqe_index_ignore) {
 			DRV_LOG(ERR, "WQE index ignore feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.non_wire_sq) {
+		if (!hca_attr->non_wire_sq) {
 			DRV_LOG(ERR, "Non-wire SQ feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.log_max_static_sq_wq) {
+		if (!hca_attr->log_max_static_sq_wq) {
 			DRV_LOG(ERR, "Static WQE SQ feature is"
 				     " required for packet pacing");
 			err = ENODEV;
 			goto error;
 		}
-		if (!config->hca_attr.qos.wqe_rate_pp) {
+		if (!hca_attr->qos.wqe_rate_pp) {
 			DRV_LOG(ERR, "WQE rate mode is required"
 				     " for packet pacing");
 			err = ENODEV;
@@ -1517,7 +1511,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
-		if (!config->hca_attr.rq_delay_drop) {
+		if (!hca_attr->rq_delay_drop) {
 			config->std_delay_drop = 0;
 			config->hp_delay_drop = 0;
 			DRV_LOG(WARNING,
@@ -1528,7 +1522,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (sh->devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
-		err = config->hca_attr.access_register_user ?
+		err = hca_attr->access_register_user ?
 			mlx5_devx_cmd_register_read
 				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
 				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
@@ -1542,8 +1536,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				config->rt_timestamp = 1;
 		} else {
 			/* Kernel does not support register reading. */
-			if (config->hca_attr.dev_freq_khz ==
-						 (NS_PER_S / MS_PER_S))
+			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
 				config->rt_timestamp = 1;
 		}
 	}
@@ -1552,7 +1545,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
 	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
 	 */
-	if (config->hca_attr.scatter_fcs_w_decap_disable && config->decap_en)
+	if (hca_attr->scatter_fcs_w_decap_disable && config->decap_en)
 		config->hw_fcs_strip = 0;
 	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
 		(config->hw_fcs_strip ? "" : "not "));
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index d1215e5627..a713391268 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -889,7 +889,7 @@ mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev)
 	uint32_t ids[8];
 	int ret;
 
-	if (!priv->config.hca_attr.parse_graph_flex_node) {
+	if (!priv->sh->cdev->config.hca_attr.parse_graph_flex_node) {
 		DRV_LOG(ERR, "Dynamic flex parser is not supported "
 			"for device %s.", priv->dev_data->name);
 		return -ENOTSUP;
@@ -2035,6 +2035,8 @@ void
 mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 		    struct mlx5_dev_config *config)
 {
+	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
+
 	if (config->txq_inline_min != MLX5_ARG_UNSET) {
 		/* Application defines size of inlined data explicitly. */
 		if (spawn->pci_dev != NULL) {
@@ -2054,9 +2056,9 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 		}
 		goto exit;
 	}
-	if (config->hca_attr.eth_net_offloads) {
+	if (hca_attr->eth_net_offloads) {
 		/* We have DevX enabled, inline mode queried successfully. */
-		switch (config->hca_attr.wqe_inline_mode) {
+		switch (hca_attr->wqe_inline_mode) {
 		case MLX5_CAP_INLINE_MODE_L2:
 			/* outer L2 header must be inlined. */
 			config->txq_inline_min = MLX5_INLINE_HSIZE_L2;
@@ -2065,14 +2067,14 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			/* No inline data are required by NIC. */
 			config->txq_inline_min = MLX5_INLINE_HSIZE_NONE;
 			config->hw_vlan_insert =
-				config->hca_attr.wqe_vlan_insert;
+				hca_attr->wqe_vlan_insert;
 			DRV_LOG(DEBUG, "Tx VLAN insertion is supported");
 			goto exit;
 		case MLX5_CAP_INLINE_MODE_VPORT_CONTEXT:
 			/* inline mode is defined by NIC vport context. */
-			if (!config->hca_attr.eth_virt)
+			if (!hca_attr->eth_virt)
 				break;
-			switch (config->hca_attr.vport_inline_mode) {
+			switch (hca_attr->vport_inline_mode) {
 			case MLX5_INLINE_MODE_NONE:
 				config->txq_inline_min =
 					MLX5_INLINE_HSIZE_NONE;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index e4b2523eb0..ee485343ff 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -299,7 +299,6 @@ struct mlx5_dev_config {
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
-	struct mlx5_hca_attr hca_attr; /* HCA attributes. */
 	struct mlx5_lro_config lro; /* LRO configuration. */
 };
 
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 91243f684f..97c8925044 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -419,7 +419,8 @@ mlx5_rxq_obj_hairpin_new(struct mlx5_rxq_priv *rxq)
 	MLX5_ASSERT(rxq != NULL && rxq->ctrl != NULL && tmpl != NULL);
 	tmpl->rxq_ctrl = rxq_ctrl;
 	attr.hairpin = 1;
-	max_wq_data = priv->config.hca_attr.log_max_hairpin_wq_data_sz;
+	max_wq_data =
+		priv->sh->cdev->config.hca_attr.log_max_hairpin_wq_data_sz;
 	/* Jumbo frames > 9KB should be supported, and more packets. */
 	if (priv->config.log_hp_size != (uint32_t)MLX5_ARG_UNSET) {
 		if (priv->config.log_hp_size > max_wq_data) {
@@ -1117,7 +1118,8 @@ mlx5_txq_obj_hairpin_new(struct rte_eth_dev *dev, uint16_t idx)
 	tmpl->txq_ctrl = txq_ctrl;
 	attr.hairpin = 1;
 	attr.tis_lst_sz = 1;
-	max_wq_data = priv->config.hca_attr.log_max_hairpin_wq_data_sz;
+	max_wq_data =
+		priv->sh->cdev->config.hca_attr.log_max_hairpin_wq_data_sz;
 	/* Jumbo frames > 9KB should be supported, and more packets. */
 	if (priv->config.log_hp_size != (uint32_t)MLX5_ARG_UNSET) {
 		if (priv->config.log_hp_size > max_wq_data) {
@@ -1193,7 +1195,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 	struct mlx5_devx_create_sq_attr sq_attr = {
 		.flush_in_error_en = 1,
 		.allow_multi_pkt_send_wqe = !!priv->config.mps,
-		.min_wqe_inline_mode = priv->config.hca_attr.vport_inline_mode,
+		.min_wqe_inline_mode = cdev->config.hca_attr.vport_inline_mode,
 		.allow_swp = !!priv->config.swp,
 		.cqn = txq_obj->cq_obj.cq->id,
 		.tis_lst_sz = 1,
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index dc647d5580..5b0eee3321 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -337,7 +337,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
 	mlx5_set_default_params(dev, info);
 	mlx5_set_txlimit_params(dev, info);
-	if (priv->config.hca_attr.mem_rq_rmp &&
+	if (priv->sh->cdev->config.hca_attr.mem_rq_rmp &&
 	    priv->obj_ops.rxq_obj_new == devx_obj_ops.rxq_obj_new)
 		info->dev_capa |= RTE_ETH_DEV_CAPA_RXQ_SHARE;
 	info->switch_info.name = dev->data->name;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 179cc3b303..29b4516709 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2906,7 +2906,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,
 	const struct rte_flow_item_geneve *mask = item->mask;
 	int ret;
 	uint16_t gbhdr;
-	uint8_t opt_len = priv->config.hca_attr.geneve_max_opt_len ?
+	uint8_t opt_len = priv->sh->cdev->config.hca_attr.geneve_max_opt_len ?
 			  MLX5_GENEVE_OPT_LEN_1 : MLX5_GENEVE_OPT_LEN_0;
 	const struct rte_flow_item_geneve nic_mask = {
 		.ver_opt_len_o_c_rsvd0 = RTE_BE16(0x3f80),
@@ -2914,7 +2914,7 @@ mlx5_flow_validate_item_geneve(const struct rte_flow_item *item,
 		.protocol = RTE_BE16(UINT16_MAX),
 	};
 
-	if (!priv->config.hca_attr.tunnel_stateless_geneve_rx)
+	if (!priv->sh->cdev->config.hca_attr.tunnel_stateless_geneve_rx)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "L3 Geneve is not enabled by device"
@@ -2994,10 +2994,9 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	struct mlx5_geneve_tlv_option_resource *geneve_opt_resource;
-	struct mlx5_hca_attr *hca_attr = &priv->config.hca_attr;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	uint8_t data_max_supported =
 			hca_attr->max_geneve_tlv_option_data_len * 4;
-	struct mlx5_dev_config *config = &priv->config;
 	const struct rte_flow_item_geneve *geneve_spec;
 	const struct rte_flow_item_geneve *geneve_mask;
 	const struct rte_flow_item_geneve_opt *spec = item->spec;
@@ -3031,11 +3030,11 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 			"Geneve TLV opt class/type/length masks must be full");
 	/* Check if length is supported */
 	if ((uint32_t)spec->option_len >
-			config->hca_attr.max_geneve_tlv_option_data_len)
+			hca_attr->max_geneve_tlv_option_data_len)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
 			"Geneve TLV opt length not supported");
-	if (config->hca_attr.max_geneve_tlv_options > 1)
+	if (hca_attr->max_geneve_tlv_options > 1)
 		DRV_LOG(DEBUG,
 			"max_geneve_tlv_options supports more than 1 option");
 	/* Check GENEVE item preceding. */
@@ -3090,7 +3089,7 @@ mlx5_flow_validate_item_geneve_opt(const struct rte_flow_item *item,
 					"Data mask is of unsupported size");
 	}
 	/* Check GENEVE option is supported in NIC. */
-	if (!config->hca_attr.geneve_tlv_opt)
+	if (!hca_attr->geneve_tlv_opt)
 		return rte_flow_error_set
 			(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item,
 			"Geneve TLV opt not supported");
@@ -6249,7 +6248,8 @@ flow_create_split_sample(struct rte_eth_dev *dev,
 		 * When reg_c_preserve is set, metadata registers Cx preserve
 		 * their value even through packet duplication.
 		 */
-		add_tag = (!fdb_tx || priv->config.hca_attr.reg_c_preserve);
+		add_tag = (!fdb_tx ||
+			   priv->sh->cdev->config.hca_attr.reg_c_preserve);
 		if (add_tag)
 			sfx_items = (struct rte_flow_item *)((char *)sfx_actions
 					+ act_size);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index ef9c66eddf..b0ed9f93a0 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2317,7 +2317,7 @@ flow_dv_validate_item_gtp(struct rte_eth_dev *dev,
 		.teid = RTE_BE32(0xffffffff),
 	};
 
-	if (!priv->config.hca_attr.tunnel_stateless_gtp)
+	if (!priv->sh->cdev->config.hca_attr.tunnel_stateless_gtp)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "GTP support is not enabled");
@@ -2426,6 +2426,7 @@ flow_dv_validate_item_ipv4(struct rte_eth_dev *dev,
 {
 	int ret;
 	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_hca_attr *attr = &priv->sh->cdev->config.hca_attr;
 	const struct rte_flow_item_ipv4 *spec = item->spec;
 	const struct rte_flow_item_ipv4 *last = item->last;
 	const struct rte_flow_item_ipv4 *mask = item->mask;
@@ -2444,8 +2445,8 @@ flow_dv_validate_item_ipv4(struct rte_eth_dev *dev,
 
 	if (mask && (mask->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK)) {
 		int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL);
-		bool ihl_cap = !tunnel ? priv->config.hca_attr.outer_ipv4_ihl :
-			       priv->config.hca_attr.inner_ipv4_ihl;
+		bool ihl_cap = !tunnel ?
+			       attr->outer_ipv4_ihl : attr->inner_ipv4_ihl;
 		if (!ihl_cap)
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ITEM,
@@ -3384,7 +3385,7 @@ flow_dv_validate_action_decap(struct rte_eth_dev *dev,
 {
 	const struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (priv->config.hca_attr.scatter_fcs_w_decap_disable &&
+	if (priv->sh->cdev->config.hca_attr.scatter_fcs_w_decap_disable &&
 	    !priv->config.decap_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
@@ -5753,7 +5754,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 						  NULL,
 						  "E-Switch must has a dest "
 						  "port for mirroring");
-		if (!priv->config.hca_attr.reg_c_preserve &&
+		if (!priv->sh->cdev->config.hca_attr.reg_c_preserve &&
 		     priv->representor_id != UINT16_MAX)
 			*fdb_mirror_limit = 1;
 	}
@@ -6686,7 +6687,7 @@ flow_dv_validate_item_integrity(struct rte_eth_dev *dev,
 	const struct rte_flow_item_integrity *spec = (typeof(spec))
 						     integrity_item->spec;
 
-	if (!priv->config.hca_attr.pkt_integrity_match)
+	if (!priv->sh->cdev->config.hca_attr.pkt_integrity_match)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM,
 					  integrity_item,
diff --git a/drivers/net/mlx5/mlx5_flow_flex.c b/drivers/net/mlx5/mlx5_flow_flex.c
index 9413d4d817..26f0dfa36f 100644
--- a/drivers/net/mlx5/mlx5_flow_flex.c
+++ b/drivers/net/mlx5/mlx5_flow_flex.c
@@ -910,7 +910,7 @@ mlx5_flex_translate_sample(struct mlx5_hca_flex_attr *attr,
 	 * offsets in any order.
 	 *
 	 * Gather all similar fields together, build array of bit intervals
-	 * in asсending order and try to cover with the smallest set of sample
+	 * in ascending order and try to cover with the smallest set of sample
 	 * registers.
 	 */
 	memset(&cover, 0, sizeof(cover));
@@ -1153,7 +1153,7 @@ mlx5_flex_translate_conf(struct rte_eth_dev *dev,
 			 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_hca_flex_attr *attr = &priv->config.hca_attr.flex;
+	struct mlx5_hca_flex_attr *attr = &priv->sh->cdev->config.hca_attr.flex;
 	int ret;
 
 	ret = mlx5_flex_translate_length(attr, conf, devx, error);
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 4f5de5e422..2310ea6a86 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -155,7 +155,7 @@ mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
 					  "Meter profile already exists.");
 	if (!priv->sh->meter_aso_en) {
 		/* Old version is even not supported. */
-		if (!priv->config.hca_attr.qos.flow_meter_old)
+		if (!priv->sh->cdev->config.hca_attr.qos.flow_meter_old)
 			return -rte_mtr_error_set(error, ENOTSUP,
 				RTE_MTR_ERROR_TYPE_METER_PROFILE,
 				NULL, "Metering is not supported.");
@@ -428,7 +428,7 @@ mlx5_flow_mtr_cap_get(struct rte_eth_dev *dev,
 		 struct rte_mtr_error *error __rte_unused)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_hca_qos_attr *qattr = &priv->config.hca_attr.qos;
+	struct mlx5_hca_qos_attr *qattr = &priv->sh->cdev->config.hca_attr.qos;
 
 	if (!priv->mtr_en)
 		return -rte_mtr_error_set(error, ENOTSUP,
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 580d7ae868..0ede46aa43 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -863,7 +863,7 @@ mlx5_rx_queue_setup(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		MLX5_ASSERT(n_seg < MLX5_MAX_RXQ_NSEG);
 	}
 	if (conf->share_group > 0) {
-		if (!priv->config.hca_attr.mem_rq_rmp) {
+		if (!priv->sh->cdev->config.hca_attr.mem_rq_rmp) {
 			DRV_LOG(ERR, "port %u queue index %u shared Rx queue not supported by fw",
 				     dev->data->port_id, idx);
 			rte_errno = EINVAL;
@@ -1517,7 +1517,7 @@ mlx5_max_lro_msg_size_adjust(struct rte_eth_dev *dev, uint16_t idx,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (priv->config.hca_attr.lro_max_msg_sz_mode ==
+	if (priv->sh->cdev->config.hca_attr.lro_max_msg_sz_mode ==
 	    MLX5_LRO_MAX_MSG_SIZE_START_FROM_L4 && max_lro_size >
 	    MLX5_MAX_TCP_HDR_OFFSET)
 		max_lro_size -= MLX5_MAX_TCP_HDR_OFFSET;
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 3a59237b1a..0418ce2faf 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -341,14 +341,16 @@ mlx5_hairpin_auto_bind(struct rte_eth_dev *dev)
 		sq_attr.state = MLX5_SQC_STATE_RDY;
 		sq_attr.sq_state = MLX5_SQC_STATE_RST;
 		sq_attr.hairpin_peer_rq = rq->id;
-		sq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
+		sq_attr.hairpin_peer_vhca =
+				priv->sh->cdev->config.hca_attr.vhca_id;
 		ret = mlx5_devx_cmd_modify_sq(sq, &sq_attr);
 		if (ret)
 			goto error;
 		rq_attr.state = MLX5_SQC_STATE_RDY;
 		rq_attr.rq_state = MLX5_SQC_STATE_RST;
 		rq_attr.hairpin_peer_sq = sq->id;
-		rq_attr.hairpin_peer_vhca = priv->config.hca_attr.vhca_id;
+		rq_attr.hairpin_peer_vhca =
+				priv->sh->cdev->config.hca_attr.vhca_id;
 		ret = mlx5_devx_cmd_modify_rq(rq, &rq_attr);
 		if (ret)
 			goto error;
@@ -425,7 +427,7 @@ mlx5_hairpin_queue_peer_update(struct rte_eth_dev *dev, uint16_t peer_queue,
 			return -rte_errno;
 		}
 		peer_info->qp_id = txq_ctrl->obj->sq->id;
-		peer_info->vhca_id = priv->config.hca_attr.vhca_id;
+		peer_info->vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		/* 1-to-1 mapping, only the first one is used. */
 		peer_info->peer_q = txq_ctrl->hairpin_conf.peers[0].queue;
 		peer_info->tx_explicit = txq_ctrl->hairpin_conf.tx_explicit;
@@ -455,7 +457,7 @@ mlx5_hairpin_queue_peer_update(struct rte_eth_dev *dev, uint16_t peer_queue,
 			return -rte_errno;
 		}
 		peer_info->qp_id = rxq_ctrl->obj->rq->id;
-		peer_info->vhca_id = priv->config.hca_attr.vhca_id;
+		peer_info->vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		peer_info->peer_q = rxq->hairpin_conf.peers[0].queue;
 		peer_info->tx_explicit = rxq->hairpin_conf.tx_explicit;
 		peer_info->manual_bind = rxq->hairpin_conf.manual_bind;
@@ -817,7 +819,7 @@ mlx5_hairpin_bind_single_port(struct rte_eth_dev *dev, uint16_t rx_port)
 		/* Pass TxQ's information to peer RxQ and try binding. */
 		cur.peer_q = rx_queue;
 		cur.qp_id = txq_ctrl->obj->sq->id;
-		cur.vhca_id = priv->config.hca_attr.vhca_id;
+		cur.vhca_id = priv->sh->cdev->config.hca_attr.vhca_id;
 		cur.tx_explicit = txq_ctrl->hairpin_conf.tx_explicit;
 		cur.manual_bind = txq_ctrl->hairpin_conf.manual_bind;
 		/*
diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c
index af77e91e4c..1d16ebcb41 100644
--- a/drivers/net/mlx5/mlx5_txpp.c
+++ b/drivers/net/mlx5/mlx5_txpp.c
@@ -825,7 +825,7 @@ mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh, struct mlx5_priv *priv)
 	sh->txpp.tick = tx_pp >= 0 ? tx_pp : -tx_pp;
 	sh->txpp.test = !!(tx_pp < 0);
 	sh->txpp.skew = priv->config.tx_skew;
-	sh->txpp.freq = priv->config.hca_attr.dev_freq_khz;
+	sh->txpp.freq = sh->cdev->config.hca_attr.dev_freq_khz;
 	ret = mlx5_txpp_create_event_channel(sh);
 	if (ret)
 		goto exit;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 0966da10f4..07a9583cab 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -268,6 +268,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
 	bool fallback;
 
 #ifndef HAVE_IBV_DEVX_ASYNC
@@ -275,16 +276,16 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 #else
 	fallback = false;
 	if (!sh->devx || !priv->config.dv_flow_en ||
-	    !priv->config.hca_attr.flow_counters_dump ||
-	    !(priv->config.hca_attr.flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
 		fallback = true;
 #endif
 	if (fallback)
 		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
 			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			priv->config.hca_attr.flow_counters_dump,
-			priv->config.hca_attr.flow_counter_bulk_alloc_bitmap);
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
 	/* Initialize fallback mode only on the port initializes sh. */
 	if (sh->refcnt == 1)
 		sh->cmng.counter_fallback = fallback;
@@ -318,6 +319,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_dev_attr device_attr;
+	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -475,19 +477,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (sh->devx) {
-		config->hca_attr = sh->cdev->config.hca_attr;
-		config->hw_csum = config->hca_attr.csum_cap;
+		hca_attr = &sh->cdev->config.hca_attr;
+		config->hw_csum = hca_attr->csum_cap;
 		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-		    (config->hw_csum ? "" : "not "));
-		config->hw_vlan_strip = config->hca_attr.vlan_cap;
+			(config->hw_csum ? "" : "not "));
+		config->hw_vlan_strip = hca_attr->vlan_cap;
 		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 			(config->hw_vlan_strip ? "" : "not "));
-		config->hw_fcs_strip = config->hca_attr.scatter_fcs;
+		config->hw_fcs_strip = hca_attr->scatter_fcs;
 	}
 	if (sh->devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
-		err = config->hca_attr.access_register_user ?
+		err = hca_attr->access_register_user ?
 			mlx5_devx_cmd_register_read
 				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
 				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
@@ -501,8 +503,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				config->rt_timestamp = 1;
 		} else {
 			/* Kernel does not support register reading. */
-			if (config->hca_attr.dev_freq_khz ==
-						 (NS_PER_S / MS_PER_S))
+			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
 				config->rt_timestamp = 1;
 		}
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 08/20] net/mlx5: remove DevX flag duplication
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (6 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
@ 2022-02-14  9:34   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
                     ` (12 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:34 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The sharing device context structure has a field named "devx" which
indicates if DevX is supported.
The common configure stracture has also field named "devx" with the same
meaning.

There is no need for this duplication, because there is a reference to
the common structure from within the sharing device context structure.

This patch removes it from sharing device context structure and uses the
common config structure instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c    | 16 ++++++++--------
 drivers/net/mlx5/linux/mlx5_verbs.c |  4 ++--
 drivers/net/mlx5/mlx5.c             |  3 +--
 drivers/net/mlx5/mlx5.h             |  1 -
 drivers/net/mlx5/mlx5_ethdev.c      |  3 ++-
 drivers/net/mlx5/mlx5_flow.c        |  2 +-
 drivers/net/mlx5/mlx5_flow_dv.c     | 23 ++++++++++++-----------
 drivers/net/mlx5/mlx5_trigger.c     |  2 +-
 drivers/net/mlx5/windows/mlx5_os.c  |  6 +++---
 9 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index b3ee1f7dc4..7ca10ae9d0 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -682,7 +682,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -1316,7 +1316,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
 		/* Check for LRO support. */
 		if (config->dest_tir && hca_attr->lro_cap &&
@@ -1434,13 +1434,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->devx || !hca_attr->mini_cqe_resp_flow_tag)) {
+	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_flow_tag)) {
 		DRV_LOG(WARNING, "Flow Tag CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
+	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
 		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
 				 " format isn't supported.");
 		config->cqe_comp = 0;
@@ -1463,7 +1463,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			hca_attr->log_max_static_sq_wq);
 		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
 			hca_attr->qos.wqe_rate_pp ? "" : "not ");
-		if (!sh->devx) {
+		if (!sh->cdev->config.devx) {
 			DRV_LOG(ERR, "DevX is required for packet pacing");
 			err = ENODEV;
 			goto error;
@@ -1519,7 +1519,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
 
 		err = hca_attr->access_register_user ?
@@ -1676,7 +1676,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->devx && config->dv_flow_en && config->dest_tir) {
+	if (sh->cdev->config.devx && config->dv_flow_en && config->dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
@@ -2735,7 +2735,7 @@ mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh)
 			rte_intr_fd_set(sh->intr_handle, -1);
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 #ifdef HAVE_IBV_DEVX_ASYNC
 		sh->intr_handle_devx =
 			rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_SHARED);
diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c
index 2b6eef44a7..722017efa4 100644
--- a/drivers/net/mlx5/linux/mlx5_verbs.c
+++ b/drivers/net/mlx5/linux/mlx5_verbs.c
@@ -998,7 +998,7 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	qp.comp_mask = MLX5DV_QP_MASK_UAR_MMAP_OFFSET;
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	/* If using DevX, need additional mask to read tisn value. */
-	if (priv->sh->devx && !priv->sh->tdn)
+	if (priv->sh->cdev->config.devx && !priv->sh->tdn)
 		qp.comp_mask |= MLX5DV_QP_MASK_RAW_QP_HANDLES;
 #endif
 	obj.cq.in = txq_obj->cq;
@@ -1042,7 +1042,7 @@ mlx5_txq_ibv_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	 * This is done once per port.
 	 * Will use this value on Rx, when creating matching TIR.
 	 */
-	if (priv->sh->devx && !priv->sh->tdn) {
+	if (priv->sh->cdev->config.devx && !priv->sh->tdn) {
 		ret = mlx5_devx_cmd_qp_query_tis_td(txq_obj->qp, qp.tisn,
 						    &priv->sh->tdn);
 		if (ret) {
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index a713391268..34b3f3f137 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1182,7 +1182,6 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
 	sh->numa_node = spawn->cdev->dev->numa_node;
 	sh->cdev = spawn->cdev;
-	sh->devx = sh->cdev->config.devx;
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
 	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
@@ -1205,7 +1204,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		sh->port[i].ih_port_id = RTE_MAX_ETHPORTS;
 		sh->port[i].devx_ih_port_id = RTE_MAX_ETHPORTS;
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		sh->td = mlx5_devx_cmd_create_td(sh->cdev->ctx);
 		if (!sh->td) {
 			DRV_LOG(ERR, "TD allocation failure");
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index ee485343ff..6bc7a34f60 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1146,7 +1146,6 @@ struct mlx5_flex_item {
 struct mlx5_dev_ctx_shared {
 	LIST_ENTRY(mlx5_dev_ctx_shared) next;
 	uint32_t refcnt;
-	uint32_t devx:1; /* Opened with DV. */
 	uint32_t flow_hit_aso_en:1; /* Flow Hit ASO is supported. */
 	uint32_t steering_format_version:4;
 	/* Indicates the device steering logic format. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 5b0eee3321..801c467bba 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -723,7 +723,8 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
 
-	if (!priv->sh->devx || !config->dest_tir || !config->dv_flow_en) {
+	if (!priv->sh->cdev->config.devx || !config->dest_tir ||
+	    !config->dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 29b4516709..29011b12a8 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -9965,7 +9965,7 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
 	type = mlx5_flow_os_get_type();
 	if (type == MLX5_FLOW_TYPE_MAX) {
 		type = MLX5_FLOW_TYPE_VERBS;
-		if (priv->sh->devx && priv->config.dv_flow_en)
+		if (priv->sh->cdev->config.devx && priv->config.dv_flow_en)
 			type = MLX5_FLOW_TYPE_DV;
 	}
 	fops = flow_get_drv_ops(type);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index b0ed9f93a0..4e60a54df3 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3291,7 +3291,7 @@ flow_dv_validate_action_count(struct rte_eth_dev *dev, bool shared,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		goto notsup_err;
 	if (action_flags & MLX5_FLOW_ACTION_COUNT)
 		return rte_flow_error_set(error, EINVAL,
@@ -5302,8 +5302,8 @@ flow_dv_validate_action_age(uint64_t action_flags,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const struct rte_flow_action_age *age = action->conf;
 
-	if (!priv->sh->devx || (priv->sh->cmng.counter_fallback &&
-	    !priv->sh->aso_age_mng))
+	if (!priv->sh->cdev->config.devx ||
+	    (priv->sh->cmng.counter_fallback && !priv->sh->aso_age_mng))
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -5587,7 +5587,8 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION, action,
 					  "ratio value starts from 1");
-	if (!priv->sh->devx || (sample->ratio > 0 && !priv->sampler_en))
+	if (!priv->sh->cdev->config.devx ||
+	    (sample->ratio > 0 && !priv->sampler_en))
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -6175,7 +6176,7 @@ flow_dv_counter_alloc(struct rte_eth_dev *dev, uint32_t age)
 			age ? MLX5_COUNTER_TYPE_AGE : MLX5_COUNTER_TYPE_ORIGIN;
 	uint32_t cnt_idx;
 
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -6498,7 +6499,7 @@ flow_dv_mtr_alloc(struct rte_eth_dev *dev)
 	struct mlx5_aso_mtr_pool *pool;
 	uint32_t mtr_idx = 0;
 
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -12515,7 +12516,7 @@ flow_dv_aso_ct_alloc(struct rte_eth_dev *dev, struct rte_flow_error *error)
 	uint32_t ct_idx;
 
 	MLX5_ASSERT(mng);
-	if (!priv->sh->devx) {
+	if (!priv->sh->cdev->config.devx) {
 		rte_errno = ENOTSUP;
 		return 0;
 	}
@@ -12953,7 +12954,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 			}
 			break;
 		case RTE_FLOW_ACTION_TYPE_COUNT:
-			if (!priv->sh->devx) {
+			if (!priv->sh->cdev->config.devx) {
 				return rte_flow_error_set
 					      (error, ENOTSUP,
 					       RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -15834,7 +15835,7 @@ flow_dv_query_count(struct rte_eth_dev *dev, uint32_t cnt_idx, void *data,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct rte_flow_query_count *qc = data;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -15887,7 +15888,7 @@ flow_dv_query_count_ptr(struct rte_eth_dev *dev, uint32_t cnt_idx,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->devx || !action_ptr)
+	if (!priv->sh->cdev->config.devx || !action_ptr)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 					  NULL,
@@ -17491,7 +17492,7 @@ flow_dv_counter_query(struct rte_eth_dev *dev, uint32_t counter, bool clear,
 	uint64_t inn_pkts, inn_bytes;
 	int ret;
 
-	if (!priv->sh->devx)
+	if (!priv->sh->cdev->config.devx)
 		return -1;
 
 	ret = _flow_dv_query_count(dev, counter, &inn_pkts, &inn_bytes);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 0418ce2faf..7aefc93350 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,7 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->devx && priv->config.dv_flow_en &&
+	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
 	    priv->config.dest_tir) && priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 07a9583cab..00c27d68c1 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -275,7 +275,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -476,7 +476,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		hca_attr = &sh->cdev->config.hca_attr;
 		config->hw_csum = hca_attr->csum_cap;
 		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
@@ -661,7 +661,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			goto error;
 		}
 	}
-	if (sh->devx) {
+	if (sh->cdev->config.devx) {
 		priv->obj_ops = devx_obj_ops;
 	} else {
 		DRV_LOG(ERR, "Windows flow must be DevX.");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 09/20] net/mlx5: remove Verbs query device duplication
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (7 preceding siblings ...)
  2022-02-14  9:34   ` [PATCH v2 08/20] net/mlx5: remove DevX flag duplication Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 10/20] common/mlx5: share VF checking function Michael Baum
                     ` (11 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The sharing device context structure has a field named "device_attr"
which s filled by mlx5_os_get_dev_attr() function.
The spawn function calls mlx5_os_get_dev_attr() again and save it to
local variable identical to "device_attr" field.

There is no need for this duplication, because there is a reference to
the sharing device context structure from spawn function.

This patch removes the local "device_attr" from spawn function, and uses
the context's field instead.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 63 ++++++++++++++----------------
 drivers/net/mlx5/windows/mlx5_os.c |  6 +--
 2 files changed, 32 insertions(+), 37 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 7ca10ae9d0..2616668149 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -171,6 +171,15 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	device_attr->tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
 
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
+#ifdef HAVE_IBV_MLX5_MOD_SWP
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
+#endif
+#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS;
+#endif
+#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
+	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
+#endif
 	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
 	if (err) {
 		rte_errno = errno;
@@ -183,6 +192,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 	device_attr->sw_parsing_offloads =
 		dv_attr.sw_parsing_caps.sw_parsing_offloads;
 #endif
+#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
 	device_attr->min_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
 	device_attr->max_single_stride_log_num_of_bytes =
@@ -193,6 +203,7 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
 	device_attr->stride_supported_qpts =
 		dv_attr.striding_rq_caps.supported_qpts;
+#endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
 	device_attr->tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
 #endif
@@ -878,7 +889,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
-	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -1011,23 +1021,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 #ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
 	config->dest_tir = 1;
-#endif
-#ifdef HAVE_IBV_MLX5_MOD_SWP
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
 #endif
 	/*
 	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
 	 * as all ConnectX-5 devices.
 	 */
-#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS;
-#endif
-#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
-#endif
-	mlx5_glue->dv_query_device(sh->cdev->ctx, &dv_attr);
-	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+	if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
 			DRV_LOG(DEBUG, "enhanced MPW is supported");
 			mps = MLX5_MPW_ENHANCED;
 		} else {
@@ -1039,44 +1039,41 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mps = MLX5_MPW_DISABLED;
 	}
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = dv_attr.sw_parsing_caps.sw_parsing_offloads;
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		swp = sh->device_attr.sw_parsing_offloads;
 	DRV_LOG(DEBUG, "SWP support: %u", swp);
 #endif
 	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		MLX5_SW_PARSING_TSO_CAP);
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
-		struct mlx5dv_striding_rq_caps mprq_caps =
-			dv_attr.striding_rq_caps;
-
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
 		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			mprq_caps.min_single_stride_log_num_of_bytes);
+			sh->device_attr.min_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			mprq_caps.max_single_stride_log_num_of_bytes);
+			sh->device_attr.max_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			mprq_caps.min_single_wqe_log_num_of_strides);
+			sh->device_attr.min_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			mprq_caps.max_single_wqe_log_num_of_strides);
+			sh->device_attr.max_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			mprq_caps.supported_qpts);
+			sh->device_attr.stride_supported_qpts);
 		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
 			config->mprq.log_min_stride_wqe_size);
 		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
 		mprq = 1;
 		config->mprq.log_min_stride_size =
-			mprq_caps.min_single_stride_log_num_of_bytes;
+			sh->device_attr.min_single_stride_log_num_of_bytes;
 		config->mprq.log_max_stride_size =
-			mprq_caps.max_single_stride_log_num_of_bytes;
+			sh->device_attr.max_single_stride_log_num_of_bytes;
 		config->mprq.log_min_stride_num =
-			mprq_caps.min_single_wqe_log_num_of_strides;
+			sh->device_attr.min_single_wqe_log_num_of_strides;
 		config->mprq.log_max_stride_num =
-			mprq_caps.max_single_wqe_log_num_of_strides;
+			sh->device_attr.max_single_wqe_log_num_of_strides;
 	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = dv_attr.tunnel_offloads_caps &
+	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
 			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
@@ -1098,9 +1095,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		"tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((dv_attr.tunnel_offloads_caps &
+	mpls_en = ((sh->device_attr.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (dv_attr.tunnel_offloads_caps &
+		   (sh->device_attr.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
 	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
 		mpls_en ? "" : "not ");
@@ -1429,7 +1426,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(dv_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
+	    !(sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
 		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
 		config->cqe_comp = 0;
 	}
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 00c27d68c1..9d25dcfa40 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -318,7 +318,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_dev_attr device_attr;
 	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
@@ -376,13 +375,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	DRV_LOG(DEBUG, "MPW isn't supported");
-	mlx5_os_get_dev_attr(sh->cdev, &device_attr);
-	config->swp = device_attr.sw_parsing_offloads &
+	config->swp = sh->device_attr.sw_parsing_offloads &
 		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
 		sh->device_attr.max_rwq_indirection_table_size;
-	config->tunnel_en = device_attr.tunnel_offloads_caps &
+	config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 10/20] common/mlx5: share VF checking function
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (8 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 11/20] net/mlx5: share realtime timestamp configure Michael Baum
                     ` (10 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The check if device is VF work for Linux as same as Windows.
This patch removes it to the function implemented in the folder shared
between the operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.h     | 15 +++++++++++++++
 drivers/common/mlx5/mlx5_common_pci.c | 18 ++++++++++++++++++
 drivers/common/mlx5/version.map       |  1 +
 drivers/net/mlx5/linux/mlx5_os.c      | 18 +-----------------
 drivers/net/mlx5/windows/mlx5_os.c    | 16 +---------------
 5 files changed, 36 insertions(+), 32 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index e8809844af..80f59c81fb 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -8,6 +8,7 @@
 #include <stdio.h>
 
 #include <rte_pci.h>
+#include <rte_bus_pci.h>
 #include <rte_debug.h>
 #include <rte_atomic.h>
 #include <rte_rwlock.h>
@@ -487,6 +488,20 @@ __rte_internal
 bool
 mlx5_dev_is_pci(const struct rte_device *dev);
 
+/**
+ * Test PCI device is a VF device.
+ *
+ * @param pci_dev
+ *   Pointer to PCI device.
+ *
+ * @return
+ *   - True on PCI device is a VF device.
+ *   - False otherwise.
+ */
+__rte_internal
+bool
+mlx5_dev_is_vf_pci(struct rte_pci_device *pci_dev);
+
 __rte_internal
 int
 mlx5_dev_mempool_subscribe(struct mlx5_common_device *cdev);
diff --git a/drivers/common/mlx5/mlx5_common_pci.c b/drivers/common/mlx5/mlx5_common_pci.c
index 458630351c..66626953f1 100644
--- a/drivers/common/mlx5/mlx5_common_pci.c
+++ b/drivers/common/mlx5/mlx5_common_pci.c
@@ -107,6 +107,24 @@ mlx5_dev_is_pci(const struct rte_device *dev)
 	return strcmp(dev->bus->name, "pci") == 0;
 }
 
+bool
+mlx5_dev_is_vf_pci(struct rte_pci_device *pci_dev)
+{
+	switch (pci_dev->id.device_id) {
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
+	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
+		return true;
+	default:
+		break;
+	}
+	return false;
+}
+
 bool
 mlx5_dev_pci_match(const struct mlx5_class_driver *drv,
 		   const struct rte_device *dev)
diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map
index 462b7cea5e..59ab434631 100644
--- a/drivers/common/mlx5/version.map
+++ b/drivers/common/mlx5/version.map
@@ -13,6 +13,7 @@ INTERNAL {
 	mlx5_common_verbs_dereg_mr; # WINDOWS_NO_EXPORT
 
 	mlx5_dev_is_pci;
+	mlx5_dev_is_vf_pci;
 	mlx5_dev_mempool_unregister;
 	mlx5_dev_mempool_subscribe;
 
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 2616668149..d1bf89922e 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -2100,7 +2100,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data *list = NULL;
 	struct mlx5_dev_config dev_config;
-	unsigned int dev_config_vf;
 	struct rte_eth_devargs eth_da = *req_eth_da;
 	struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
 	struct mlx5_bond_info bond_info;
@@ -2421,21 +2420,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	 * (i.e. master first, then representors from lowest to highest ID).
 	 */
 	qsort(list, ns, sizeof(*list), mlx5_dev_spawn_data_cmp);
-	/* Device specific configuration. */
-	switch (pci_dev->id.device_id) {
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
-		dev_config_vf = 1;
-		break;
-	default:
-		dev_config_vf = 0;
-		break;
-	}
 	if (eth_da.type != RTE_ETH_REPRESENTOR_NONE) {
 		/* Set devargs default values. */
 		if (eth_da.nb_mh_controllers == 0) {
@@ -2459,7 +2443,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 
 		/* Default configuration. */
 		mlx5_os_config_default(&dev_config, &cdev->config);
-		dev_config.vf = dev_config_vf;
+		dev_config.vf = mlx5_dev_is_vf_pci(pci_dev);
 		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
 						 &dev_config, &eth_da);
 		if (!list[i].eth_dev) {
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 9d25dcfa40..cca99f3eea 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -926,6 +926,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 		},
 		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
+		.vf = mlx5_dev_is_vf_pci(pci_dev),
 	};
 	int ret;
 	uint32_t restore;
@@ -940,21 +941,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	/* Device specific configuration. */
-	switch (pci_dev->id.device_id) {
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5EXVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX5BFVF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTX6VF:
-	case PCI_DEVICE_ID_MELLANOX_CONNECTXVF:
-		dev_config.vf = 1;
-		break;
-	default:
-		dev_config.vf = 0;
-		break;
-	}
 	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, &dev_config);
 	if (!spawn.eth_dev)
 		return -rte_errno;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 11/20] net/mlx5: share realtime timestamp configure
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (9 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 10/20] common/mlx5: share VF checking function Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 12/20] net/mlx5: share counter config function Michael Baum
                     ` (9 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The realtime timestamp configure work for Linux as same as Windows.
This patch removes it to the function implemented in the folder shared
between the operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 23 ++-----------------
 drivers/net/mlx5/mlx5.c            | 37 ++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h            |  3 +++
 drivers/net/mlx5/windows/mlx5_os.c | 22 +-----------------
 4 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index d1bf89922e..bee055772b 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1516,27 +1516,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->cdev->config.devx) {
-		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
-
-		err = hca_attr->access_register_user ?
-			mlx5_devx_cmd_register_read
-				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
-				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
-		if (!err) {
-			uint32_t ts_mode;
-
-			/* MTUTC register is read successfully. */
-			ts_mode = MLX5_GET(register_mtutc, reg,
-					   time_stamp_mode);
-			if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-				config->rt_timestamp = 1;
-		} else {
-			/* Kernel does not support register reading. */
-			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-				config->rt_timestamp = 1;
-		}
-	}
+	if (sh->cdev->config.devx)
+		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	/*
 	 * If HW has bug working with tunnel packet decapsulation and
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 34b3f3f137..4884198509 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1129,6 +1129,43 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
 	return 0;
 }
 
+/**
+ * Configure realtime timestamp format.
+ *
+ * @param sh
+ *   Pointer to mlx5_dev_ctx_shared object.
+ * @param config
+ *   Device configuration parameters.
+ * @param hca_attr
+ *   Pointer to DevX HCA capabilities structure.
+ */
+void
+mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
+			 struct mlx5_dev_config *config,
+			 struct mlx5_hca_attr *hca_attr)
+{
+	uint32_t dw_cnt = MLX5_ST_SZ_DW(register_mtutc);
+	uint32_t reg[dw_cnt];
+	int ret = ENOTSUP;
+
+	if (hca_attr->access_register_user)
+		ret = mlx5_devx_cmd_register_read(sh->cdev->ctx,
+						  MLX5_REGISTER_ID_MTUTC, 0,
+						  reg, dw_cnt);
+	if (!ret) {
+		uint32_t ts_mode;
+
+		/* MTUTC register is read successfully. */
+		ts_mode = MLX5_GET(register_mtutc, reg, time_stamp_mode);
+		if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
+			config->rt_timestamp = 1;
+	} else {
+		/* Kernel does not support register reading. */
+		if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
+			config->rt_timestamp = 1;
+	}
+}
+
 /**
  * Allocate shared device context. If there is multiport device the
  * master and representors will share this context, if there is single
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 6bc7a34f60..0f90d757e9 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1517,6 +1517,9 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	     port_id < RTE_MAX_ETHPORTS; \
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
 int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
+void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
+			      struct mlx5_dev_config *config,
+			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
 mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 			   const struct mlx5_dev_config *config);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index cca99f3eea..cf0819e013 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -483,27 +483,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 			(config->hw_vlan_strip ? "" : "not "));
 		config->hw_fcs_strip = hca_attr->scatter_fcs;
-	}
-	if (sh->devx) {
-		uint32_t reg[MLX5_ST_SZ_DW(register_mtutc)];
-
-		err = hca_attr->access_register_user ?
-			mlx5_devx_cmd_register_read
-				(sh->cdev->ctx, MLX5_REGISTER_ID_MTUTC, 0,
-				reg, MLX5_ST_SZ_DW(register_mtutc)) : ENOTSUP;
-		if (!err) {
-			uint32_t ts_mode;
-
-			/* MTUTC register is read successfully. */
-			ts_mode = MLX5_GET(register_mtutc, reg,
-					   time_stamp_mode);
-			if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-				config->rt_timestamp = 1;
-		} else {
-			/* Kernel does not support register reading. */
-			if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-				config->rt_timestamp = 1;
-		}
+		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	}
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 12/20] net/mlx5: share counter config function
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (10 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 11/20] net/mlx5: share realtime timestamp configure Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 13/20] net/mlx5: add E-switch mode flag Michael Baum
                     ` (8 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

The mlx5_flow_counter_mode_config function exists for both Linux and
Windows with the same name and content.
This patch moves its implementation to the folder shared between the
operating systems, removing the duplication.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 40 ------------------------------
 drivers/net/mlx5/mlx5.c            | 40 ++++++++++++++++++++++++++++++
 drivers/net/mlx5/mlx5.h            |  1 +
 drivers/net/mlx5/windows/mlx5_os.c | 40 ------------------------------
 4 files changed, 41 insertions(+), 80 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index bee055772b..1ff2b8dc22 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -673,46 +673,6 @@ mlx5_init_once(void)
 	return ret;
 }
 
-/**
- * DV flow counter mode detect and config.
- *
- * @param dev
- *   Pointer to rte_eth_dev structure.
- *
- */
-static void
-mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
-{
-#ifdef HAVE_IBV_FLOW_DV_SUPPORT
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
-	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
-	bool fallback;
-
-#ifndef HAVE_IBV_DEVX_ASYNC
-	fallback = true;
-#else
-	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
-	    !hca_attr->flow_counters_dump ||
-	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
-	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
-		fallback = true;
-#endif
-	if (fallback)
-		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
-			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			hca_attr->flow_counters_dump,
-			hca_attr->flow_counter_bulk_alloc_bitmap);
-	/* Initialize fallback mode only on the port initializes sh. */
-	if (sh->refcnt == 1)
-		sh->cmng.counter_fallback = fallback;
-	else if (fallback != sh->cmng.counter_fallback)
-		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
-			"with others:%d.", PORT_ID(priv), fallback);
-#endif
-}
-
 /**
  * DR flow drop action support detect.
  *
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 4884198509..531916f3a5 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -513,6 +513,46 @@ mlx5_flow_aging_init(struct mlx5_dev_ctx_shared *sh)
 	}
 }
 
+/**
+ * DV flow counter mode detect and config.
+ *
+ * @param dev
+ *   Pointer to rte_eth_dev structure.
+ *
+ */
+void
+mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
+{
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct mlx5_dev_ctx_shared *sh = priv->sh;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+	bool fallback;
+
+#ifndef HAVE_IBV_DEVX_ASYNC
+	fallback = true;
+#else
+	fallback = false;
+	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
+	    !hca_attr->flow_counters_dump ||
+	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
+	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
+		fallback = true;
+#endif
+	if (fallback)
+		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
+			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
+			hca_attr->flow_counters_dump,
+			hca_attr->flow_counter_bulk_alloc_bitmap);
+	/* Initialize fallback mode only on the port initializes sh. */
+	if (sh->refcnt == 1)
+		sh->cmng.counter_fallback = fallback;
+	else if (fallback != sh->cmng.counter_fallback)
+		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
+			"with others:%d.", PORT_ID(priv), fallback);
+#endif
+}
+
 /**
  * Initialize the counters management structure.
  *
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 0f90d757e9..d69b6a357b 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1535,6 +1535,7 @@ int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
 				  struct rte_device *dpdk_dev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
+void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
 int mlx5_flow_aso_age_mng_init(struct mlx5_dev_ctx_shared *sh);
 int mlx5_aso_flow_mtrs_mng_init(struct mlx5_dev_ctx_shared *sh);
 int mlx5_flow_aso_ct_mng_init(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index cf0819e013..e509c34083 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -255,46 +255,6 @@ mlx5_os_set_nonblock_channel_fd(int fd)
 	return -ENOTSUP;
 }
 
-/**
- * DV flow counter mode detect and config.
- *
- * @param dev
- *   Pointer to rte_eth_dev structure.
- *
- */
-static void
-mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
-{
-#ifdef HAVE_IBV_FLOW_DV_SUPPORT
-	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_ctx_shared *sh = priv->sh;
-	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
-	bool fallback;
-
-#ifndef HAVE_IBV_DEVX_ASYNC
-	fallback = true;
-#else
-	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
-	    !hca_attr->flow_counters_dump ||
-	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
-	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
-		fallback = true;
-#endif
-	if (fallback)
-		DRV_LOG(INFO, "Use fall-back DV counter management. Flow "
-			"counter dump:%d, bulk_alloc_bitmap:0x%hhx.",
-			hca_attr->flow_counters_dump,
-			hca_attr->flow_counter_bulk_alloc_bitmap);
-	/* Initialize fallback mode only on the port initializes sh. */
-	if (sh->refcnt == 1)
-		sh->cmng.counter_fallback = fallback;
-	else if (fallback != sh->cmng.counter_fallback)
-		DRV_LOG(WARNING, "Port %d in sh has different fallback mode "
-			"with others:%d.", PORT_ID(priv), fallback);
-#endif
-}
-
 /**
  * Spawn an Ethernet device from DevX information.
  *
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 13/20] net/mlx5: add E-switch mode flag
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (11 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 12/20] net/mlx5: share counter config function Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 14/20] net/mlx5: rearrange device attribute structure Michael Baum
                     ` (7 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

This patch adds in SH structure a flag which indicates whether is
E-Switch mode.
When configure "dv_esw_en" from devargs, it is enabled only when is
E-switch mode. So, since dv_esw_en has been configure, it is enough to
check if "dv_esw_en" is valid.
This patch also removes E-Switch mode check when "dv_esw_en" is checked
too.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c | 14 +++++---------
 drivers/net/mlx5/mlx5.c          |  1 +
 drivers/net/mlx5/mlx5.h          |  1 +
 drivers/net/mlx5/mlx5_ethdev.c   |  4 ++--
 drivers/net/mlx5/mlx5_flow_dv.c  | 12 +++---------
 drivers/net/mlx5/mlx5_trigger.c  |  5 ++---
 6 files changed, 14 insertions(+), 23 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 1ff2b8dc22..69ba2aaf88 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -951,10 +951,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (!sh)
 		return NULL;
 	/* Update final values for devargs before check sibling config. */
-	if (config->dv_miss_info) {
-		if (switch_info->master || switch_info->representor)
-			config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	}
 #if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
 	if (config->dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
@@ -962,12 +958,13 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 #endif
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(hca_attr->eswitch_manager && config->dv_flow_en &&
-	      (switch_info->representor || switch_info->master)))
+	if (!(hca_attr->eswitch_manager && config->dv_flow_en && sh->esw_mode))
 		config->dv_esw_en = 0;
 #else
 	config->dv_esw_en = 0;
 #endif
+	if (config->dv_miss_info && config->dv_esw_en)
+		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
 	if (!config->dv_esw_en &&
 	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 		DRV_LOG(WARNING,
@@ -1133,7 +1130,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * register to match on vport index. The engaged part of metadata
 	 * register is defined by mask.
 	 */
-	if (switch_info->representor || switch_info->master) {
+	if (sh->esw_mode) {
 		err = mlx5_glue->devx_port_query(sh->cdev->ctx,
 						 spawn->phys_port,
 						 &vport_info);
@@ -1164,8 +1161,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	if (vport_info.query_flags & MLX5_PORT_QUERY_VPORT) {
 		priv->vport_id = vport_info.vport_id;
-	} else if (spawn->pf_bond >= 0 &&
-		   (switch_info->representor || switch_info->master)) {
+	} else if (spawn->pf_bond >= 0 && sh->esw_mode) {
 		DRV_LOG(ERR,
 			"Cannot deduce vport index for port %d on bonding device %s",
 			spawn->phys_port, spawn->phys_dev_name);
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 531916f3a5..b26632d249 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1259,6 +1259,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	pthread_mutex_init(&sh->txpp.mutex, NULL);
 	sh->numa_node = spawn->cdev->dev->numa_node;
 	sh->cdev = spawn->cdev;
+	sh->esw_mode = !!(spawn->info.master || spawn->info.representor);
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
 	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index d69b6a357b..a713e61572 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1146,6 +1146,7 @@ struct mlx5_flex_item {
 struct mlx5_dev_ctx_shared {
 	LIST_ENTRY(mlx5_dev_ctx_shared) next;
 	uint32_t refcnt;
+	uint32_t esw_mode:1; /* Whether is E-Switch mode. */
 	uint32_t flow_hit_aso_en:1; /* Flow Hit ASO is supported. */
 	uint32_t steering_format_version:4;
 	/* Indicates the device steering logic format. */
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 801c467bba..06d5acb75f 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -672,7 +672,7 @@ mlx5_port_to_eswitch_info(uint16_t port, bool valid)
 	}
 	dev = &rte_eth_devices[port];
 	priv = dev->data->dev_private;
-	if (!(priv->representor || priv->master)) {
+	if (!priv->sh->esw_mode) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
@@ -699,7 +699,7 @@ mlx5_dev_to_eswitch_info(struct rte_eth_dev *dev)
 	struct mlx5_priv *priv;
 
 	priv = dev->data->dev_private;
-	if (!(priv->representor || priv->master)) {
+	if (!priv->sh->esw_mode) {
 		rte_errno = EINVAL;
 		return NULL;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 4e60a54df3..6a5ac01c2a 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -6600,11 +6600,6 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
 				 "E-Switch dr is not supported");
-		if (!(priv->representor || priv->master))
-			return rte_flow_error_set
-				(error, EINVAL, RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
-				 NULL, "E-Switch configuration can only be"
-				 " done by a master or a representor device");
 		if (attributes->egress)
 			return rte_flow_error_set
 				(error, ENOTSUP,
@@ -13612,8 +13607,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 	 * E-Switch rule where no port_id item was found. In both cases
 	 * the source port is set according the current port in use.
 	 */
-	if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) &&
-	    (priv->representor || priv->master)) {
+	if (!(item_flags & MLX5_FLOW_ITEM_PORT_ID) && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, match_mask,
 						   match_value, NULL, attr))
 			return -rte_errno;
@@ -16173,7 +16167,7 @@ __flow_dv_create_policy_flow(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	uint8_t misc_mask;
 
-	if (match_src_port && (priv->representor || priv->master)) {
+	if (match_src_port && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, matcher.buf,
 						   value.buf, item, attr)) {
 			DRV_LOG(ERR, "Failed to create meter policy%d flow's"
@@ -16225,7 +16219,7 @@ __flow_dv_create_policy_matcher(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const uint32_t color_mask = (UINT32_C(1) << MLX5_MTR_COLOR_BITS) - 1;
 
-	if (match_src_port && (priv->representor || priv->master)) {
+	if (match_src_port && priv->sh->esw_mode) {
 		if (flow_dv_translate_item_port_id(dev, matcher.mask.buf,
 						   value.buf, item, attr)) {
 			DRV_LOG(ERR, "Failed to register meter policy%d matcher"
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 7aefc93350..a00b56eecf 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1330,8 +1330,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				goto error;
 			}
 		}
-		if ((priv->representor || priv->master) &&
-		    priv->config.dv_esw_en) {
+		if (priv->config.dv_esw_en) {
 			if (mlx5_flow_create_devx_sq_miss_flow(dev, i) == 0) {
 				DRV_LOG(ERR,
 					"Port %u Tx queue %u SQ create representor devx default miss rule failed.",
@@ -1341,7 +1340,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 		}
 		mlx5_txq_release(dev, i);
 	}
-	if ((priv->master || priv->representor) && priv->config.dv_esw_en) {
+	if (priv->config.dv_esw_en) {
 		if (mlx5_flow_create_esw_table_zero_flow(dev))
 			priv->fdb_def_rule = 1;
 		else
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 14/20] net/mlx5: rearrange device attribute structure
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (12 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 13/20] net/mlx5: add E-switch mode flag Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 15/20] net/mlx5: concentrate all device configurations Michael Baum
                     ` (6 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Rearrange the mlx5_os_get_dev_attr() function in such a way that it
first executes the queries and only then updates the fields.
In addition, it changed its name in preparation for expanding its
operations to configure the capabilities inside it.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c    | 124 +++++++++++++---------------
 drivers/net/mlx5/linux/mlx5_verbs.c |   5 +-
 drivers/net/mlx5/mlx5.c             |   4 +-
 drivers/net/mlx5/mlx5.h             |  56 ++++++-------
 drivers/net/mlx5/mlx5_devx.c        |   2 +-
 drivers/net/mlx5/mlx5_ethdev.c      |   5 +-
 drivers/net/mlx5/mlx5_trigger.c     |   8 +-
 drivers/net/mlx5/mlx5_txq.c         |  18 ++--
 drivers/net/mlx5/windows/mlx5_os.c  |  67 ++++++---------
 9 files changed, 128 insertions(+), 161 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 69ba2aaf88..f0aa0f4164 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -131,46 +131,25 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  * with out parameter of type 'struct ibv_device_attr_ex *'. Then fill in mlx5
  * device attributes from the glue out parameter.
  *
- * @param cdev
- *   Pointer to mlx5 device.
- *
- * @param device_attr
- *   Pointer to mlx5 device attributes.
+ * @param sh
+ *   Pointer to shared device context.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
-		     struct mlx5_dev_attr *device_attr)
+mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
 	int err;
-	struct ibv_context *ctx = cdev->ctx;
-	struct ibv_device_attr_ex attr_ex;
+	struct ibv_context *ctx = sh->cdev->ctx;
+	struct ibv_device_attr_ex attr_ex = { .comp_mask = 0 };
+	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 
-	memset(device_attr, 0, sizeof(*device_attr));
 	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
 	}
-	device_attr->device_cap_flags_ex = attr_ex.device_cap_flags_ex;
-	device_attr->max_qp_wr = attr_ex.orig_attr.max_qp_wr;
-	device_attr->max_sge = attr_ex.orig_attr.max_sge;
-	device_attr->max_cq = attr_ex.orig_attr.max_cq;
-	device_attr->max_cqe = attr_ex.orig_attr.max_cqe;
-	device_attr->max_mr = attr_ex.orig_attr.max_mr;
-	device_attr->max_pd = attr_ex.orig_attr.max_pd;
-	device_attr->max_qp = attr_ex.orig_attr.max_qp;
-	device_attr->max_srq = attr_ex.orig_attr.max_srq;
-	device_attr->max_srq_wr = attr_ex.orig_attr.max_srq_wr;
-	device_attr->raw_packet_caps = attr_ex.raw_packet_caps;
-	device_attr->max_rwq_indirection_table_size =
-		attr_ex.rss_caps.max_rwq_indirection_table_size;
-	device_attr->max_tso = attr_ex.tso_caps.max_tso;
-	device_attr->tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
-
-	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 #ifdef HAVE_IBV_MLX5_MOD_SWP
 	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_SWP;
 #endif
@@ -185,31 +164,40 @@ mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
 		rte_errno = errno;
 		return -rte_errno;
 	}
-
-	device_attr->flags = dv_attr.flags;
-	device_attr->comp_mask = dv_attr.comp_mask;
+	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.device_cap_flags_ex = attr_ex.device_cap_flags_ex;
+	sh->dev_cap.max_qp_wr = attr_ex.orig_attr.max_qp_wr;
+	sh->dev_cap.max_sge = attr_ex.orig_attr.max_sge;
+	sh->dev_cap.max_cq = attr_ex.orig_attr.max_cq;
+	sh->dev_cap.max_qp = attr_ex.orig_attr.max_qp;
+	sh->dev_cap.raw_packet_caps = attr_ex.raw_packet_caps;
+	sh->dev_cap.max_rwq_indirection_table_size =
+		attr_ex.rss_caps.max_rwq_indirection_table_size;
+	sh->dev_cap.max_tso = attr_ex.tso_caps.max_tso;
+	sh->dev_cap.tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
+	strlcpy(sh->dev_cap.fw_ver, attr_ex.orig_attr.fw_ver,
+		sizeof(sh->dev_cap.fw_ver));
+	sh->dev_cap.flags = dv_attr.flags;
+	sh->dev_cap.comp_mask = dv_attr.comp_mask;
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	device_attr->sw_parsing_offloads =
+	sh->dev_cap.sw_parsing_offloads =
 		dv_attr.sw_parsing_caps.sw_parsing_offloads;
 #endif
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	device_attr->min_single_stride_log_num_of_bytes =
+	sh->dev_cap.min_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
-	device_attr->max_single_stride_log_num_of_bytes =
+	sh->dev_cap.max_single_stride_log_num_of_bytes =
 		dv_attr.striding_rq_caps.max_single_stride_log_num_of_bytes;
-	device_attr->min_single_wqe_log_num_of_strides =
+	sh->dev_cap.min_single_wqe_log_num_of_strides =
 		dv_attr.striding_rq_caps.min_single_wqe_log_num_of_strides;
-	device_attr->max_single_wqe_log_num_of_strides =
+	sh->dev_cap.max_single_wqe_log_num_of_strides =
 		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
-	device_attr->stride_supported_qpts =
+	sh->dev_cap.stride_supported_qpts =
 		dv_attr.striding_rq_caps.supported_qpts;
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	device_attr->tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
+	sh->dev_cap.tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
 #endif
-	strlcpy(device_attr->fw_ver, attr_ex.orig_attr.fw_ver,
-		sizeof(device_attr->fw_ver));
-
 	return 0;
 }
 
@@ -983,8 +971,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
 	 * as all ConnectX-5 devices.
 	 */
-	if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+	if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
 			DRV_LOG(DEBUG, "enhanced MPW is supported");
 			mps = MLX5_MPW_ENHANCED;
 		} else {
@@ -996,41 +984,41 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mps = MLX5_MPW_DISABLED;
 	}
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = sh->device_attr.sw_parsing_offloads;
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		swp = sh->dev_cap.sw_parsing_offloads;
 	DRV_LOG(DEBUG, "SWP support: %u", swp);
 #endif
 	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		MLX5_SW_PARSING_TSO_CAP);
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
 		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			sh->device_attr.min_single_stride_log_num_of_bytes);
+			sh->dev_cap.min_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			sh->device_attr.max_single_stride_log_num_of_bytes);
+			sh->dev_cap.max_single_stride_log_num_of_bytes);
 		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			sh->device_attr.min_single_wqe_log_num_of_strides);
+			sh->dev_cap.min_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			sh->device_attr.max_single_wqe_log_num_of_strides);
+			sh->dev_cap.max_single_wqe_log_num_of_strides);
 		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			sh->device_attr.stride_supported_qpts);
+			sh->dev_cap.stride_supported_qpts);
 		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
 			config->mprq.log_min_stride_wqe_size);
 		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
 		mprq = 1;
 		config->mprq.log_min_stride_size =
-			sh->device_attr.min_single_stride_log_num_of_bytes;
+			sh->dev_cap.min_single_stride_log_num_of_bytes;
 		config->mprq.log_max_stride_size =
-			sh->device_attr.max_single_stride_log_num_of_bytes;
+			sh->dev_cap.max_single_stride_log_num_of_bytes;
 		config->mprq.log_min_stride_num =
-			sh->device_attr.min_single_wqe_log_num_of_strides;
+			sh->dev_cap.min_single_wqe_log_num_of_strides;
 		config->mprq.log_max_stride_num =
-			sh->device_attr.max_single_wqe_log_num_of_strides;
+			sh->dev_cap.max_single_wqe_log_num_of_strides;
 	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (sh->device_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
+	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
 			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
 			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
@@ -1052,9 +1040,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		"tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
 #ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((sh->device_attr.tunnel_offloads_caps &
+	mpls_en = ((sh->dev_cap.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (sh->device_attr.tunnel_offloads_caps &
+		   (sh->dev_cap.tunnel_offloads_caps &
 		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
 	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
 		mpls_en ? "" : "not ");
@@ -1215,7 +1203,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	config->hw_csum = !!(sh->device_attr.device_cap_flags_ex &
+	config->hw_csum = !!(sh->dev_cap.device_cap_flags_ex &
 			    IBV_DEVICE_RAW_IP_CSUM);
 	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
 		(config->hw_csum ? "" : "not "));
@@ -1224,7 +1212,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	DRV_LOG(DEBUG, "counters are not supported");
 #endif
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
+		sh->dev_cap.max_rwq_indirection_table_size;
 	/*
 	 * Remove this check once DPDK supports larger/variable
 	 * indirection tables.
@@ -1233,16 +1221,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
 	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
 		config->ind_table_max_size);
-	config->hw_vlan_strip = !!(sh->device_attr.raw_packet_caps &
+	config->hw_vlan_strip = !!(sh->dev_cap.raw_packet_caps &
 				  IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
 	DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
 		(config->hw_vlan_strip ? "" : "not "));
-	config->hw_fcs_strip = !!(sh->device_attr.raw_packet_caps &
+	config->hw_fcs_strip = !!(sh->dev_cap.raw_packet_caps &
 				 IBV_RAW_PACKET_CAP_SCATTER_FCS);
 #if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
-	hw_padding = !!sh->device_attr.rx_pad_end_addr_align;
+	hw_padding = !!sh->dev_cap.rx_pad_end_addr_align;
 #elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
-	hw_padding = !!(sh->device_attr.device_cap_flags_ex &
+	hw_padding = !!(sh->dev_cap.device_cap_flags_ex &
 			IBV_DEVICE_PCI_WRITE_END_PADDING);
 #endif
 	if (config->hw_padding && !hw_padding) {
@@ -1251,11 +1239,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	} else if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
 	}
-	config->tso = (sh->device_attr.max_tso > 0 &&
-		      (sh->device_attr.tso_supported_qpts &
+	config->tso = (sh->dev_cap.max_tso > 0 &&
+		      (sh->dev_cap.tso_supported_qpts &
 		       (1 << IBV_QPT_RAW_PACKET)));
 	if (config->tso)
-		config->tso_max_payload_sz = sh->device_attr.max_tso;
+		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	/*
 	 * MPW is disabled by default, while the Enhanced MPW is enabled
 	 * by default.
@@ -1382,7 +1370,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif
 	}
 	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(sh->device_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
+	    !(sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
 		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
 		config->cqe_comp = 0;
 	}
diff --git a/drivers/net/mlx5/linux/mlx5_verbs.c b/drivers/net/mlx5/linux/mlx5_verbs.c
index 722017efa4..73c44138de 100644
--- a/drivers/net/mlx5/linux/mlx5_verbs.c
+++ b/drivers/net/mlx5/linux/mlx5_verbs.c
@@ -872,13 +872,12 @@ mlx5_txq_ibv_qp_create(struct rte_eth_dev *dev, uint16_t idx)
 	/* CQ to be associated with the receive queue. */
 	qp_attr.recv_cq = txq_ctrl->obj->cq;
 	/* Max number of outstanding WRs. */
-	qp_attr.cap.max_send_wr = ((priv->sh->device_attr.max_qp_wr < desc) ?
-				   priv->sh->device_attr.max_qp_wr : desc);
+	qp_attr.cap.max_send_wr = RTE_MIN(priv->sh->dev_cap.max_qp_wr, desc);
 	/*
 	 * Max number of scatter/gather elements in a WR, must be 1 to prevent
 	 * libmlx5 from trying to affect must be 1 to prevent libmlx5 from
 	 * trying to affect too much memory. TX gather is not impacted by the
-	 * device_attr.max_sge limit and will still work properly.
+	 * dev_cap.max_sge limit and will still work properly.
 	 */
 	qp_attr.cap.max_send_sge = 1;
 	qp_attr.qp_type = IBV_QPT_RAW_PACKET,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index b26632d249..7487b1f87d 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1262,9 +1262,9 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	sh->esw_mode = !!(spawn->info.master || spawn->info.representor);
 	if (spawn->bond_info)
 		sh->bond = *spawn->bond_info;
-	err = mlx5_os_get_dev_attr(sh->cdev, &sh->device_attr);
+	err = mlx5_os_capabilities_prepare(sh);
 	if (err) {
-		DRV_LOG(DEBUG, "mlx5_os_get_dev_attr() failed");
+		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
 	sh->refcnt = 1;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index a713e61572..fd6350eee7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -114,32 +114,31 @@ struct mlx5_flow_cb_ctx {
 	void *data2;
 };
 
-/* Device attributes used in mlx5 PMD */
-struct mlx5_dev_attr {
-	uint64_t	device_cap_flags_ex;
-	int		max_qp_wr;
-	int		max_sge;
-	int		max_cq;
-	int		max_qp;
-	int		max_cqe;
-	uint32_t	max_pd;
-	uint32_t	max_mr;
-	uint32_t	max_srq;
-	uint32_t	max_srq_wr;
-	uint32_t	raw_packet_caps;
-	uint32_t	max_rwq_indirection_table_size;
-	uint32_t	max_tso;
-	uint32_t	tso_supported_qpts;
-	uint64_t	flags;
-	uint64_t	comp_mask;
-	uint32_t	sw_parsing_offloads;
-	uint32_t	min_single_stride_log_num_of_bytes;
-	uint32_t	max_single_stride_log_num_of_bytes;
-	uint32_t	min_single_wqe_log_num_of_strides;
-	uint32_t	max_single_wqe_log_num_of_strides;
-	uint32_t	stride_supported_qpts;
-	uint32_t	tunnel_offloads_caps;
-	char		fw_ver[64];
+/* Device capabilities structure which isn't changed in any stage. */
+struct mlx5_dev_cap {
+	uint64_t device_cap_flags_ex;
+	int max_cq; /* Maximum number of supported CQs */
+	int max_qp; /* Maximum number of supported QPs. */
+	int max_qp_wr; /* Maximum number of outstanding WR on any WQ. */
+	int max_sge;
+	/* Maximum number of s/g per WR for SQ & RQ of QP for non RDMA Read
+	 * operations.
+	 */
+	uint32_t raw_packet_caps;
+	uint32_t max_rwq_indirection_table_size;
+	/* Maximum receive WQ indirection table size. */
+	uint32_t max_tso; /* Maximum TCP payload for TSO. */
+	uint32_t tso_supported_qpts;
+	uint64_t flags;
+	uint64_t comp_mask;
+	uint32_t sw_parsing_offloads;
+	uint32_t min_single_stride_log_num_of_bytes;
+	uint32_t max_single_stride_log_num_of_bytes;
+	uint32_t min_single_wqe_log_num_of_strides;
+	uint32_t max_single_wqe_log_num_of_strides;
+	uint32_t stride_supported_qpts;
+	uint32_t tunnel_offloads_caps;
+	char fw_ver[64]; /* Firmware version of this device. */
 };
 
 /** Data associated with devices to spawn. */
@@ -1165,7 +1164,7 @@ struct mlx5_dev_ctx_shared {
 	uint32_t tdn; /* Transport Domain number. */
 	char ibdev_name[MLX5_FS_NAME_MAX]; /* SYSFS dev name. */
 	char ibdev_path[MLX5_FS_PATH_MAX]; /* SYSFS dev path for secondary */
-	struct mlx5_dev_attr device_attr; /* Device properties. */
+	struct mlx5_dev_cap dev_cap; /* Device capabilities. */
 	int numa_node; /* Numa node of backing physical device. */
 	/* Packet pacing related structure. */
 	struct mlx5_dev_txpp txpp;
@@ -1792,8 +1791,7 @@ void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev);
 /* mlx5_os.c */
 
 struct rte_pci_driver;
-int mlx5_os_get_dev_attr(struct mlx5_common_device *dev,
-			 struct mlx5_dev_attr *dev_attr);
+int mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_free_shared_dr(struct mlx5_priv *priv);
 int mlx5_os_net_probe(struct mlx5_common_device *cdev);
 void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 97c8925044..553df6424d 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -1305,7 +1305,7 @@ mlx5_txq_devx_obj_new(struct rte_eth_dev *dev, uint16_t idx)
 	wqe_size = RTE_ALIGN(wqe_size, MLX5_WQE_SIZE) / MLX5_WQE_SIZE;
 	/* Create Send Queue object with DevX. */
 	wqe_n = RTE_MIN((1UL << txq_data->elts_n) * wqe_size,
-			(uint32_t)priv->sh->device_attr.max_qp_wr);
+			(uint32_t)priv->sh->dev_cap.max_qp_wr);
 	log_desc_n = log2above(wqe_n);
 	ret = mlx5_txq_create_devx_sq_resources(dev, idx, log_desc_n);
 	if (ret) {
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 06d5acb75f..d970eb6904 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -313,8 +313,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	 * Since we need one CQ per QP, the limit is the minimum number
 	 * between the two values.
 	 */
-	max = RTE_MIN(priv->sh->device_attr.max_cq,
-		      priv->sh->device_attr.max_qp);
+	max = RTE_MIN(priv->sh->dev_cap.max_cq, priv->sh->dev_cap.max_qp);
 	/* max_rx_queues is uint16_t. */
 	max = RTE_MIN(max, (unsigned int)UINT16_MAX);
 	info->max_rx_queues = max;
@@ -516,7 +515,7 @@ int
 mlx5_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_attr *attr = &priv->sh->device_attr;
+	struct mlx5_dev_cap *attr = &priv->sh->dev_cap;
 	size_t size = strnlen(attr->fw_ver, sizeof(attr->fw_ver)) + 1;
 
 	if (fw_size < size)
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index a00b56eecf..f46089fd56 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -215,10 +215,10 @@ mlx5_rxq_start(struct rte_eth_dev *dev)
 		/* Should not release Rx queues but return immediately. */
 		return -rte_errno;
 	}
-	DRV_LOG(DEBUG, "Port %u device_attr.max_qp_wr is %d.",
-		dev->data->port_id, priv->sh->device_attr.max_qp_wr);
-	DRV_LOG(DEBUG, "Port %u device_attr.max_sge is %d.",
-		dev->data->port_id, priv->sh->device_attr.max_sge);
+	DRV_LOG(DEBUG, "Port %u dev_cap.max_qp_wr is %d.",
+		dev->data->port_id, priv->sh->dev_cap.max_qp_wr);
+	DRV_LOG(DEBUG, "Port %u dev_cap.max_sge is %d.",
+		dev->data->port_id, priv->sh->dev_cap.max_sge);
 	for (i = 0; i != priv->rxqs_n; ++i) {
 		struct mlx5_rxq_priv *rxq = mlx5_rxq_ref(dev, i);
 		struct mlx5_rxq_ctrl *rxq_ctrl;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 4e0bf7af9c..56e0937ca3 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -714,7 +714,7 @@ txq_calc_inline_max(struct mlx5_txq_ctrl *txq_ctrl)
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	unsigned int wqe_size;
 
-	wqe_size = priv->sh->device_attr.max_qp_wr / desc;
+	wqe_size = priv->sh->dev_cap.max_qp_wr / desc;
 	if (!wqe_size)
 		return 0;
 	/*
@@ -982,8 +982,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_mode, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_send > max_inline &&
@@ -994,8 +993,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_send, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_empw > max_inline &&
@@ -1006,8 +1004,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			txq_ctrl->txq.inlen_empw, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.tso_en && max_inline < MLX5_MAX_TSO_HEADER) {
@@ -1016,8 +1013,7 @@ txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 			" satisfied (%u) on port %u, try the smaller"
 			" Tx queue size (%d)",
 			MLX5_MAX_TSO_HEADER, max_inline,
-			priv->dev_data->port_id,
-			priv->sh->device_attr.max_qp_wr);
+			priv->dev_data->port_id, priv->sh->dev_cap.max_qp_wr);
 		goto error;
 	}
 	if (txq_ctrl->txq.inlen_send > max_inline) {
@@ -1098,12 +1094,12 @@ mlx5_txq_new(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	if (txq_adjust_params(tmpl))
 		goto error;
 	if (txq_calc_wqebb_cnt(tmpl) >
-	    priv->sh->device_attr.max_qp_wr) {
+	    priv->sh->dev_cap.max_qp_wr) {
 		DRV_LOG(ERR,
 			"port %u Tx WQEBB count (%d) exceeds the limit (%d),"
 			" try smaller queue size",
 			dev->data->port_id, txq_calc_wqebb_cnt(tmpl),
-			priv->sh->device_attr.max_qp_wr);
+			priv->sh->dev_cap.max_qp_wr);
 		rte_errno = ENOMEM;
 		goto error;
 	}
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index e509c34083..91e91e4d36 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -143,55 +143,42 @@ mlx5_init_once(void)
 }
 
 /**
- * Get mlx5 device attributes.
+ * Get mlx5 device capabilities.
  *
- * @param cdev
- *   Pointer to mlx5 device.
- *
- * @param device_attr
- *   Pointer to mlx5 device attributes.
+ * @param sh
+ *   Pointer to shared device context.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_os_get_dev_attr(struct mlx5_common_device *cdev,
-		     struct mlx5_dev_attr *device_attr)
+mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
-	struct mlx5_context *mlx5_ctx;
+	struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+	struct mlx5_context *mlx5_ctx = sh->cdev->ctx;
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
 
-	if (!cdev || !cdev->ctx) {
-		rte_errno = EINVAL;
-		return -rte_errno;
-	}
-	mlx5_ctx = (struct mlx5_context *)cdev->ctx;
-	memset(device_attr, 0, sizeof(*device_attr));
-	device_attr->max_cq = 1 << cdev->config.hca_attr.log_max_cq;
-	device_attr->max_qp = 1 << cdev->config.hca_attr.log_max_qp;
-	device_attr->max_qp_wr = 1 << cdev->config.hca_attr.log_max_qp_sz;
-	device_attr->max_cqe = 1 << cdev->config.hca_attr.log_max_cq_sz;
-	device_attr->max_mr = 1 << cdev->config.hca_attr.log_max_mrw_sz;
-	device_attr->max_pd = 1 << cdev->config.hca_attr.log_max_pd;
-	device_attr->max_srq = 1 << cdev->config.hca_attr.log_max_srq;
-	device_attr->max_srq_wr = 1 << cdev->config.hca_attr.log_max_srq_sz;
-	device_attr->max_tso = 1 << cdev->config.hca_attr.max_lso_cap;
-	if (cdev->config.hca_attr.rss_ind_tbl_cap) {
-		device_attr->max_rwq_indirection_table_size =
-			1 << cdev->config.hca_attr.rss_ind_tbl_cap;
-	}
-	device_attr->sw_parsing_offloads =
-		mlx5_get_supported_sw_parsing_offloads(&cdev->config.hca_attr);
-	device_attr->tunnel_offloads_caps =
-		mlx5_get_supported_tunneling_offloads(&cdev->config.hca_attr);
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
-		DRV_LOG(ERR, "Failed to get device hca_iseg");
+		DRV_LOG(ERR, "Failed to get device hca_iseg.");
 		rte_errno = errno;
 		return -rte_errno;
 	}
-	snprintf(device_attr->fw_ver, 64, "%x.%x.%04x",
+	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.max_cq = 1 << hca_attr->log_max_cq;
+	sh->dev_cap.max_qp = 1 << hca_attr->log_max_qp;
+	sh->dev_cap.max_qp_wr = 1 << hca_attr->log_max_qp_sz;
+	sh->dev_cap.max_tso = 1 << hca_attr->max_lso_cap;
+	if (hca_attr->rss_ind_tbl_cap) {
+		sh->dev_cap.max_rwq_indirection_table_size =
+			1 << hca_attr->rss_ind_tbl_cap;
+	}
+	sh->dev_cap.sw_parsing_offloads =
+		mlx5_get_supported_sw_parsing_offloads(hca_attr);
+	sh->dev_cap.tunnel_offloads_caps =
+		mlx5_get_supported_tunneling_offloads(hca_attr);
+	snprintf(sh->dev_cap.fw_ver, 64, "%x.%x.%04x",
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
@@ -335,12 +322,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	DRV_LOG(DEBUG, "MPW isn't supported");
-	config->swp = sh->device_attr.sw_parsing_offloads &
+	config->swp = sh->dev_cap.sw_parsing_offloads &
 		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
 		 MLX5_SW_PARSING_TSO_CAP);
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
-	config->tunnel_en = sh->device_attr.tunnel_offloads_caps &
+		sh->dev_cap.max_rwq_indirection_table_size;
+	config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
 		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
 		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
@@ -410,7 +397,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "counters are not supported");
 	config->ind_table_max_size =
-		sh->device_attr.max_rwq_indirection_table_size;
+		sh->dev_cap.max_rwq_indirection_table_size;
 	/*
 	 * Remove this check once DPDK supports larger/variable
 	 * indirection tables.
@@ -423,9 +410,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	}
-	config->tso = (sh->device_attr.max_tso > 0);
+	config->tso = (sh->dev_cap.max_tso > 0);
 	if (config->tso)
-		config->tso_max_payload_sz = sh->device_attr.max_tso;
+		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	DRV_LOG(DEBUG, "%sMPS is %s.",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 15/20] net/mlx5: concentrate all device configurations
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (13 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 14/20] net/mlx5: rearrange device attribute structure Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 16/20] net/mlx5: add share device context config structure Michael Baum
                     ` (5 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Move all device configure to be performed by mlx5_os_cap_config()
function instead of the spawn function.
In addition move all relevant fields from mlx5_dev_config structure to
mlx5_dev_cap.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c      | 497 +++++++++++++-------------
 drivers/net/mlx5/linux/mlx5_vlan_os.c |   3 +-
 drivers/net/mlx5/mlx5.c               |  11 +-
 drivers/net/mlx5/mlx5.h               |  78 ++--
 drivers/net/mlx5/mlx5_devx.c          |   6 +-
 drivers/net/mlx5/mlx5_ethdev.c        |  12 +-
 drivers/net/mlx5/mlx5_flow.c          |   4 +-
 drivers/net/mlx5/mlx5_rxmode.c        |   8 +-
 drivers/net/mlx5/mlx5_rxq.c           |  34 +-
 drivers/net/mlx5/mlx5_trigger.c       |   5 +-
 drivers/net/mlx5/mlx5_txq.c           |  36 +-
 drivers/net/mlx5/mlx5_vlan.c          |   4 +-
 drivers/net/mlx5/windows/mlx5_os.c    | 101 +++---
 13 files changed, 380 insertions(+), 419 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index f0aa0f4164..5d2c9b9c8b 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -141,11 +141,12 @@ int
 mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 {
 	int err;
-	struct ibv_context *ctx = sh->cdev->ctx;
+	struct mlx5_common_device *cdev = sh->cdev;
+	struct mlx5_hca_attr *hca_attr = &cdev->config.hca_attr;
 	struct ibv_device_attr_ex attr_ex = { .comp_mask = 0 };
 	struct mlx5dv_context dv_attr = { .comp_mask = 0 };
 
-	err = mlx5_glue->query_device_ex(ctx, NULL, &attr_ex);
+	err = mlx5_glue->query_device_ex(cdev->ctx, NULL, &attr_ex);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
@@ -159,45 +160,229 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
 	dv_attr.comp_mask |= MLX5DV_CONTEXT_MASK_STRIDING_RQ;
 #endif
-	err = mlx5_glue->dv_query_device(ctx, &dv_attr);
+	err = mlx5_glue->dv_query_device(cdev->ctx, &dv_attr);
 	if (err) {
 		rte_errno = errno;
 		return -rte_errno;
 	}
 	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
-	sh->dev_cap.device_cap_flags_ex = attr_ex.device_cap_flags_ex;
+	if (mlx5_dev_is_pci(cdev->dev))
+		sh->dev_cap.vf = mlx5_dev_is_vf_pci(RTE_DEV_TO_PCI(cdev->dev));
+	else
+		sh->dev_cap.sf = 1;
 	sh->dev_cap.max_qp_wr = attr_ex.orig_attr.max_qp_wr;
 	sh->dev_cap.max_sge = attr_ex.orig_attr.max_sge;
 	sh->dev_cap.max_cq = attr_ex.orig_attr.max_cq;
 	sh->dev_cap.max_qp = attr_ex.orig_attr.max_qp;
-	sh->dev_cap.raw_packet_caps = attr_ex.raw_packet_caps;
-	sh->dev_cap.max_rwq_indirection_table_size =
-		attr_ex.rss_caps.max_rwq_indirection_table_size;
-	sh->dev_cap.max_tso = attr_ex.tso_caps.max_tso;
-	sh->dev_cap.tso_supported_qpts = attr_ex.tso_caps.supported_qpts;
+#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
+	sh->dev_cap.dest_tir = 1;
+#endif
+#if defined(HAVE_IBV_FLOW_DV_SUPPORT) && defined(HAVE_MLX5DV_DR)
+	DRV_LOG(DEBUG, "DV flow is supported.");
+	sh->dev_cap.dv_flow_en = 1;
+#endif
+#ifdef HAVE_MLX5DV_DR_ESWITCH
+	if (hca_attr->eswitch_manager && sh->dev_cap.dv_flow_en && sh->esw_mode)
+		sh->dev_cap.dv_esw_en = 1;
+#endif
+	/*
+	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
+	 * as all ConnectX-5 devices.
+	 */
+	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
+		if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
+			DRV_LOG(DEBUG, "Enhanced MPW is supported.");
+			sh->dev_cap.mps = MLX5_MPW_ENHANCED;
+		} else {
+			DRV_LOG(DEBUG, "MPW is supported.");
+			sh->dev_cap.mps = MLX5_MPW;
+		}
+	} else {
+		DRV_LOG(DEBUG, "MPW isn't supported.");
+		sh->dev_cap.mps = MLX5_MPW_DISABLED;
+	}
+#if (RTE_CACHE_LINE_SIZE == 128)
+	if (dv_attr.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)
+		sh->dev_cap.cqe_comp = 1;
+	DRV_LOG(DEBUG, "Rx CQE 128B compression is %ssupported.",
+		sh->dev_cap.cqe_comp ? "" : "not ");
+#else
+	sh->dev_cap.cqe_comp = 1;
+#endif
+#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
+	sh->dev_cap.mpls_en =
+		((dv_attr.tunnel_offloads_caps &
+		  MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
+		 (dv_attr.tunnel_offloads_caps &
+		  MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
+	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported.",
+		sh->dev_cap.mpls_en ? "" : "not ");
+#else
+	DRV_LOG(WARNING,
+		"MPLS over GRE/UDP tunnel offloading disabled due to old OFED/rdma-core version or firmware configuration");
+#endif
+#if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
+	sh->dev_cap.hw_padding = !!attr_ex.rx_pad_end_addr_align;
+#elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
+	sh->dev_cap.hw_padding = !!(attr_ex.device_cap_flags_ex &
+				    IBV_DEVICE_PCI_WRITE_END_PADDING);
+#endif
+	sh->dev_cap.hw_csum =
+		!!(attr_ex.device_cap_flags_ex & IBV_DEVICE_RAW_IP_CSUM);
+	DRV_LOG(DEBUG, "Checksum offloading is %ssupported.",
+		sh->dev_cap.hw_csum ? "" : "not ");
+	sh->dev_cap.hw_vlan_strip = !!(attr_ex.raw_packet_caps &
+				       IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
+	DRV_LOG(DEBUG, "VLAN stripping is %ssupported.",
+		(sh->dev_cap.hw_vlan_strip ? "" : "not "));
+	sh->dev_cap.hw_fcs_strip = !!(attr_ex.raw_packet_caps &
+				      IBV_RAW_PACKET_CAP_SCATTER_FCS);
+#if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
+	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
+	DRV_LOG(DEBUG, "Counters are not supported.");
+#endif
+	/*
+	 * DPDK doesn't support larger/variable indirection tables.
+	 * Once DPDK supports it, take max size from device attr.
+	 */
+	sh->dev_cap.ind_table_max_size =
+			RTE_MIN(attr_ex.rss_caps.max_rwq_indirection_table_size,
+				(unsigned int)RTE_ETH_RSS_RETA_SIZE_512);
+	DRV_LOG(DEBUG, "Maximum Rx indirection table size is %u",
+		sh->dev_cap.ind_table_max_size);
+	sh->dev_cap.tso = (attr_ex.tso_caps.max_tso > 0 &&
+			   (attr_ex.tso_caps.supported_qpts &
+			    (1 << IBV_QPT_RAW_PACKET)));
+	if (sh->dev_cap.tso)
+		sh->dev_cap.tso_max_payload_sz = attr_ex.tso_caps.max_tso;
 	strlcpy(sh->dev_cap.fw_ver, attr_ex.orig_attr.fw_ver,
 		sizeof(sh->dev_cap.fw_ver));
-	sh->dev_cap.flags = dv_attr.flags;
-	sh->dev_cap.comp_mask = dv_attr.comp_mask;
 #ifdef HAVE_IBV_MLX5_MOD_SWP
-	sh->dev_cap.sw_parsing_offloads =
-		dv_attr.sw_parsing_caps.sw_parsing_offloads;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
+		sh->dev_cap.swp = dv_attr.sw_parsing_caps.sw_parsing_offloads &
+				  (MLX5_SW_PARSING_CAP |
+				   MLX5_SW_PARSING_CSUM_CAP |
+				   MLX5_SW_PARSING_TSO_CAP);
+	DRV_LOG(DEBUG, "SWP support: %u", sh->dev_cap.swp);
 #endif
 #ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	sh->dev_cap.min_single_stride_log_num_of_bytes =
-		dv_attr.striding_rq_caps.min_single_stride_log_num_of_bytes;
-	sh->dev_cap.max_single_stride_log_num_of_bytes =
-		dv_attr.striding_rq_caps.max_single_stride_log_num_of_bytes;
-	sh->dev_cap.min_single_wqe_log_num_of_strides =
-		dv_attr.striding_rq_caps.min_single_wqe_log_num_of_strides;
-	sh->dev_cap.max_single_wqe_log_num_of_strides =
-		dv_attr.striding_rq_caps.max_single_wqe_log_num_of_strides;
-	sh->dev_cap.stride_supported_qpts =
-		dv_attr.striding_rq_caps.supported_qpts;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
+		struct mlx5dv_striding_rq_caps *strd_rq_caps =
+				&dv_attr.striding_rq_caps;
+
+		sh->dev_cap.mprq.enabled = 1;
+		sh->dev_cap.mprq.log_min_stride_size =
+			strd_rq_caps->min_single_stride_log_num_of_bytes;
+		sh->dev_cap.mprq.log_max_stride_size =
+			strd_rq_caps->max_single_stride_log_num_of_bytes;
+		sh->dev_cap.mprq.log_min_stride_num =
+			strd_rq_caps->min_single_wqe_log_num_of_strides;
+		sh->dev_cap.mprq.log_max_stride_num =
+			strd_rq_caps->max_single_wqe_log_num_of_strides;
+		sh->dev_cap.mprq.log_min_stride_wqe_size =
+					cdev->config.devx ?
+					hca_attr->log_min_stride_wqe_sz :
+					MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE;
+		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %u",
+			sh->dev_cap.mprq.log_min_stride_size);
+		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %u",
+			sh->dev_cap.mprq.log_max_stride_size);
+		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %u",
+			sh->dev_cap.mprq.log_min_stride_num);
+		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %u",
+			sh->dev_cap.mprq.log_max_stride_num);
+		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %u",
+			sh->dev_cap.mprq.log_min_stride_wqe_size);
+		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
+			strd_rq_caps->supported_qpts);
+		DRV_LOG(DEBUG, "Device supports Multi-Packet RQ.");
+	}
 #endif
 #ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	sh->dev_cap.tunnel_offloads_caps = dv_attr.tunnel_offloads_caps;
+	if (dv_attr.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
+		sh->dev_cap.tunnel_en = dv_attr.tunnel_offloads_caps &
+					(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
+					 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
+					 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
+	}
+	if (sh->dev_cap.tunnel_en) {
+		DRV_LOG(DEBUG, "Tunnel offloading is supported for %s%s%s",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : "");
+	} else {
+		DRV_LOG(DEBUG, "Tunnel offloading is not supported.");
+	}
+#else
+	DRV_LOG(WARNING,
+		"Tunnel offloading disabled due to old OFED/rdma-core version");
 #endif
+	if (!sh->cdev->config.devx)
+		return 0;
+	/* Check capabilities for Packet Pacing. */
+	DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz.",
+		hca_attr->dev_freq_khz);
+	DRV_LOG(DEBUG, "Packet pacing is %ssupported.",
+		hca_attr->qos.packet_pacing ? "" : "not ");
+	DRV_LOG(DEBUG, "Cross channel ops are %ssupported.",
+		hca_attr->cross_channel ? "" : "not ");
+	DRV_LOG(DEBUG, "WQE index ignore is %ssupported.",
+		hca_attr->wqe_index_ignore ? "" : "not ");
+	DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported.",
+		hca_attr->non_wire_sq ? "" : "not ");
+	DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
+		hca_attr->log_max_static_sq_wq ? "" : "not ",
+		hca_attr->log_max_static_sq_wq);
+	DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported.",
+		hca_attr->qos.wqe_rate_pp ? "" : "not ");
+	sh->dev_cap.txpp_en = hca_attr->qos.packet_pacing;
+	if (!hca_attr->cross_channel) {
+		DRV_LOG(DEBUG,
+			"Cross channel operations are required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->wqe_index_ignore) {
+		DRV_LOG(DEBUG,
+			"WQE index ignore feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->non_wire_sq) {
+		DRV_LOG(DEBUG,
+			"Non-wire SQ feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->log_max_static_sq_wq) {
+		DRV_LOG(DEBUG,
+			"Static WQE SQ feature is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+	if (!hca_attr->qos.wqe_rate_pp) {
+		DRV_LOG(DEBUG,
+			"WQE rate mode is required for packet pacing.");
+		sh->dev_cap.txpp_en = 0;
+	}
+#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET
+	DRV_LOG(DEBUG,
+		"DevX does not provide UAR offset, can't create queues for packet pacing.");
+	sh->dev_cap.txpp_en = 0;
+#endif
+	/* Check for LRO support. */
+	if (sh->dev_cap.dest_tir && sh->dev_cap.dv_flow_en &&
+	    hca_attr->lro_cap) {
+		/* TBD check tunnel lro caps. */
+		sh->dev_cap.lro_supported = 1;
+		DRV_LOG(DEBUG, "Device supports LRO.");
+		DRV_LOG(DEBUG,
+			"LRO minimal size of TCP segment required for coalescing is %d bytes.",
+			hca_attr->lro_min_mss_size);
+	}
+	sh->dev_cap.scatter_fcs_w_decap_disable =
+					hca_attr->scatter_fcs_w_decap_disable;
+	sh->dev_cap.rq_delay_drop_en = hca_attr->rq_delay_drop;
+	mlx5_rt_timestamp_config(sh, hca_attr);
 	return 0;
 }
 
@@ -840,11 +1025,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
-	unsigned int hw_padding = 0;
-	unsigned int mps;
-	unsigned int mpls_en = 0;
-	unsigned int swp = 0;
-	unsigned int mprq = 0;
 	struct rte_ether_addr mac;
 	char name[RTE_ETH_NAME_MAX_LEN];
 	int own_domain_id = 0;
@@ -939,18 +1119,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (!sh)
 		return NULL;
 	/* Update final values for devargs before check sibling config. */
-#if !defined(HAVE_IBV_FLOW_DV_SUPPORT) || !defined(HAVE_MLX5DV_DR)
-	if (config->dv_flow_en) {
+	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
 		DRV_LOG(WARNING, "DV flow is not supported.");
 		config->dv_flow_en = 0;
 	}
-#endif
-#ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (!(hca_attr->eswitch_manager && config->dv_flow_en && sh->esw_mode))
+	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
+		DRV_LOG(WARNING, "E-Switch DV flow is not supported.");
 		config->dv_esw_en = 0;
-#else
-	config->dv_esw_en = 0;
-#endif
+	}
 	if (config->dv_miss_info && config->dv_esw_en)
 		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
 	if (!config->dv_esw_en &&
@@ -964,93 +1140,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
 	if (err)
 		goto error;
-#ifdef HAVE_MLX5DV_DR_ACTION_DEST_DEVX_TIR
-	config->dest_tir = 1;
-#endif
-	/*
-	 * Multi-packet send is supported by ConnectX-4 Lx PF as well
-	 * as all ConnectX-5 devices.
-	 */
-	if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_MPW_ALLOWED) {
-		if (sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_ENHANCED_MPW) {
-			DRV_LOG(DEBUG, "enhanced MPW is supported");
-			mps = MLX5_MPW_ENHANCED;
-		} else {
-			DRV_LOG(DEBUG, "MPW is supported");
-			mps = MLX5_MPW;
-		}
-	} else {
-		DRV_LOG(DEBUG, "MPW isn't supported");
-		mps = MLX5_MPW_DISABLED;
-	}
-#ifdef HAVE_IBV_MLX5_MOD_SWP
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_SWP)
-		swp = sh->dev_cap.sw_parsing_offloads;
-	DRV_LOG(DEBUG, "SWP support: %u", swp);
-#endif
-	config->swp = swp & (MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
-		MLX5_SW_PARSING_TSO_CAP);
-#ifdef HAVE_IBV_DEVICE_STRIDING_RQ_SUPPORT
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_STRIDING_RQ) {
-		DRV_LOG(DEBUG, "\tmin_single_stride_log_num_of_bytes: %d",
-			sh->dev_cap.min_single_stride_log_num_of_bytes);
-		DRV_LOG(DEBUG, "\tmax_single_stride_log_num_of_bytes: %d",
-			sh->dev_cap.max_single_stride_log_num_of_bytes);
-		DRV_LOG(DEBUG, "\tmin_single_wqe_log_num_of_strides: %d",
-			sh->dev_cap.min_single_wqe_log_num_of_strides);
-		DRV_LOG(DEBUG, "\tmax_single_wqe_log_num_of_strides: %d",
-			sh->dev_cap.max_single_wqe_log_num_of_strides);
-		DRV_LOG(DEBUG, "\tsupported_qpts: %d",
-			sh->dev_cap.stride_supported_qpts);
-		DRV_LOG(DEBUG, "\tmin_stride_wqe_log_size: %d",
-			config->mprq.log_min_stride_wqe_size);
-		DRV_LOG(DEBUG, "device supports Multi-Packet RQ");
-		mprq = 1;
-		config->mprq.log_min_stride_size =
-			sh->dev_cap.min_single_stride_log_num_of_bytes;
-		config->mprq.log_max_stride_size =
-			sh->dev_cap.max_single_stride_log_num_of_bytes;
-		config->mprq.log_min_stride_num =
-			sh->dev_cap.min_single_wqe_log_num_of_strides;
-		config->mprq.log_max_stride_num =
-			sh->dev_cap.max_single_wqe_log_num_of_strides;
-	}
-#endif
-#ifdef HAVE_IBV_DEVICE_TUNNEL_SUPPORT
-	if (sh->dev_cap.comp_mask & MLX5DV_CONTEXT_MASK_TUNNEL_OFFLOADS) {
-		config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
-			     (MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN |
-			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE |
-			      MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE);
-	}
-	if (config->tunnel_en) {
-		DRV_LOG(DEBUG, "tunnel offloading is supported for %s%s%s",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_VXLAN ? "[VXLAN]" : "",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GRE ? "[GRE]" : "",
-		config->tunnel_en &
-		MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_GENEVE ? "[GENEVE]" : ""
-		);
-	} else {
-		DRV_LOG(DEBUG, "tunnel offloading is not supported");
-	}
-#else
-	DRV_LOG(WARNING,
-		"tunnel offloading disabled due to old OFED/rdma-core version");
-#endif
-#ifdef HAVE_IBV_DEVICE_MPLS_SUPPORT
-	mpls_en = ((sh->dev_cap.tunnel_offloads_caps &
-		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_GRE) &&
-		   (sh->dev_cap.tunnel_offloads_caps &
-		    MLX5DV_RAW_PACKET_CAP_TUNNELED_OFFLOAD_CW_MPLS_OVER_UDP));
-	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is %ssupported",
-		mpls_en ? "" : "not ");
-#else
-	DRV_LOG(WARNING, "MPLS over GRE/UDP tunnel offloading disabled due to"
-		" old OFED/rdma-core version or firmware configuration");
-#endif
-	config->mpls_en = mpls_en;
 	nl_rdma = mlx5_nl_init(NETLINK_RDMA);
 	/* Check port status. */
 	if (spawn->phys_port <= UINT8_MAX) {
@@ -1203,80 +1292,40 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	config->hw_csum = !!(sh->dev_cap.device_cap_flags_ex &
-			    IBV_DEVICE_RAW_IP_CSUM);
-	DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-		(config->hw_csum ? "" : "not "));
-#if !defined(HAVE_IBV_DEVICE_COUNTERS_SET_V42) && \
-	!defined(HAVE_IBV_DEVICE_COUNTERS_SET_V45)
-	DRV_LOG(DEBUG, "counters are not supported");
-#endif
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	/*
-	 * Remove this check once DPDK supports larger/variable
-	 * indirection tables.
-	 */
-	if (config->ind_table_max_size > (unsigned int)RTE_ETH_RSS_RETA_SIZE_512)
-		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
-	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
-		config->ind_table_max_size);
-	config->hw_vlan_strip = !!(sh->dev_cap.raw_packet_caps &
-				  IBV_RAW_PACKET_CAP_CVLAN_STRIPPING);
-	DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
-		(config->hw_vlan_strip ? "" : "not "));
-	config->hw_fcs_strip = !!(sh->dev_cap.raw_packet_caps &
-				 IBV_RAW_PACKET_CAP_SCATTER_FCS);
-#if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
-	hw_padding = !!sh->dev_cap.rx_pad_end_addr_align;
-#elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
-	hw_padding = !!(sh->dev_cap.device_cap_flags_ex &
-			IBV_DEVICE_PCI_WRITE_END_PADDING);
-#endif
-	if (config->hw_padding && !hw_padding) {
+	if (config->hw_padding && !sh->dev_cap.hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	} else if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
 	}
-	config->tso = (sh->dev_cap.max_tso > 0 &&
-		      (sh->dev_cap.tso_supported_qpts &
-		       (1 << IBV_QPT_RAW_PACKET)));
-	if (config->tso)
-		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	/*
 	 * MPW is disabled by default, while the Enhanced MPW is enabled
 	 * by default.
 	 */
 	if (config->mps == MLX5_ARG_UNSET)
-		config->mps = (mps == MLX5_MPW_ENHANCED) ? MLX5_MPW_ENHANCED :
-							  MLX5_MPW_DISABLED;
+		config->mps = (sh->dev_cap.mps == MLX5_MPW_ENHANCED) ?
+			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
 	else
-		config->mps = config->mps ? mps : MLX5_MPW_DISABLED;
+		config->mps = config->mps ? sh->dev_cap.mps : MLX5_MPW_DISABLED;
 	DRV_LOG(INFO, "%sMPS is %s",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
 		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
-		/* Check for LRO support. */
-		if (config->dest_tir && hca_attr->lro_cap &&
-		    config->dv_flow_en) {
-			/* TBD check tunnel lro caps. */
-			config->lro.supported = hca_attr->lro_cap;
-			DRV_LOG(DEBUG, "Device supports LRO");
+		/* LRO is supported only when DV flow enabled. */
+		if (sh->dev_cap.lro_supported && config->dv_flow_en)
+			sh->dev_cap.lro_supported = 0;
+		if (sh->dev_cap.lro_supported) {
 			/*
 			 * If LRO timeout is not configured by application,
 			 * use the minimal supported value.
 			 */
-			if (!config->lro.timeout)
-				config->lro.timeout =
+			if (!config->lro_timeout)
+				config->lro_timeout =
 				       hca_attr->lro_timer_supported_periods[0];
 			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
-				config->lro.timeout);
-			DRV_LOG(DEBUG, "LRO minimal size of TCP segment "
-				"required for coalescing is %d bytes",
-				hca_attr->lro_min_mss_size);
+				config->lro_timeout);
 		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
@@ -1369,9 +1418,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif
 	}
-	if (config->cqe_comp && RTE_CACHE_LINE_SIZE == 128 &&
-	    !(sh->dev_cap.flags & MLX5DV_CONTEXT_FLAGS_CQE_128B_COMP)) {
-		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported");
+	if (config->cqe_comp && !sh->dev_cap.cqe_comp) {
+		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
 		config->cqe_comp = 0;
 	}
 	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
@@ -1388,68 +1436,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
 			config->cqe_comp ? "" : "not ");
-	if (config->tx_pp) {
-		DRV_LOG(DEBUG, "Timestamp counter frequency %u kHz",
-			hca_attr->dev_freq_khz);
-		DRV_LOG(DEBUG, "Packet pacing is %ssupported",
-			hca_attr->qos.packet_pacing ? "" : "not ");
-		DRV_LOG(DEBUG, "Cross channel ops are %ssupported",
-			hca_attr->cross_channel ? "" : "not ");
-		DRV_LOG(DEBUG, "WQE index ignore is %ssupported",
-			hca_attr->wqe_index_ignore ? "" : "not ");
-		DRV_LOG(DEBUG, "Non-wire SQ feature is %ssupported",
-			hca_attr->non_wire_sq ? "" : "not ");
-		DRV_LOG(DEBUG, "Static WQE SQ feature is %ssupported (%d)",
-			hca_attr->log_max_static_sq_wq ? "" : "not ",
-			hca_attr->log_max_static_sq_wq);
-		DRV_LOG(DEBUG, "WQE rate PP mode is %ssupported",
-			hca_attr->qos.wqe_rate_pp ? "" : "not ");
-		if (!sh->cdev->config.devx) {
-			DRV_LOG(ERR, "DevX is required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->qos.packet_pacing) {
-			DRV_LOG(ERR, "Packet pacing is not supported");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->cross_channel) {
-			DRV_LOG(ERR, "Cross channel operations are"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->wqe_index_ignore) {
-			DRV_LOG(ERR, "WQE index ignore feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->non_wire_sq) {
-			DRV_LOG(ERR, "Non-wire SQ feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->log_max_static_sq_wq) {
-			DRV_LOG(ERR, "Static WQE SQ feature is"
-				     " required for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-		if (!hca_attr->qos.wqe_rate_pp) {
-			DRV_LOG(ERR, "WQE rate mode is required"
-				     " for packet pacing");
-			err = ENODEV;
-			goto error;
-		}
-#ifndef HAVE_MLX5DV_DEVX_UAR_OFFSET
-		DRV_LOG(ERR, "DevX does not provide UAR offset,"
-			     " can't create queues for packet pacing");
+	if (config->tx_pp && !sh->dev_cap.txpp_en) {
+		DRV_LOG(ERR, "Packet pacing is not supported.");
 		err = ENODEV;
 		goto error;
-#endif
 	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
 		if (!hca_attr->rq_delay_drop) {
@@ -1460,19 +1450,19 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	if (sh->cdev->config.devx)
-		mlx5_rt_timestamp_config(sh, config, hca_attr);
 	/*
 	 * If HW has bug working with tunnel packet decapsulation and
 	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
 	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
 	 */
-	if (hca_attr->scatter_fcs_w_decap_disable && config->decap_en)
+	if (sh->dev_cap.scatter_fcs_w_decap_disable && config->decap_en)
 		config->hw_fcs_strip = 0;
+	else
+		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
 		(config->hw_fcs_strip ? "" : "not "));
-	if (config->mprq.enabled && !mprq) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
+	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
+		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
 		config->mprq.enabled = 0;
 	}
 	if (config->max_dump_files_num == 0)
@@ -1556,7 +1546,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	eth_dev->rx_queue_count = mlx5_rx_queue_count;
 	/* Register MAC address. */
 	claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
-	if (config->vf && config->vf_nl_en)
+	if (sh->dev_cap.vf && config->vf_nl_en)
 		mlx5_nl_mac_addr_sync(priv->nl_socket_route,
 				      mlx5_ifindex(eth_dev),
 				      eth_dev->data->mac_addrs,
@@ -1598,7 +1588,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && config->dv_flow_en && config->dest_tir) {
+	if (sh->cdev->config.devx && config->dv_flow_en &&
+	    sh->dev_cap.dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
@@ -1949,8 +1940,7 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 }
 
 static void
-mlx5_os_config_default(struct mlx5_dev_config *config,
-		       struct mlx5_common_dev_config *cconf)
+mlx5_os_config_default(struct mlx5_dev_config *config)
 {
 	memset(config, 0, sizeof(*config));
 	config->mps = MLX5_ARG_UNSET;
@@ -1963,9 +1953,6 @@ mlx5_os_config_default(struct mlx5_dev_config *config,
 	config->vf_nl_en = 1;
 	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
 	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
-	config->mprq.log_min_stride_wqe_size = cconf->devx ?
-					cconf->hca_attr.log_min_stride_wqe_sz :
-					MLX5_MPRQ_LOG_MIN_STRIDE_WQE_SIZE;
 	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
 	config->dv_esw_en = 1;
 	config->dv_flow_en = 1;
@@ -2367,8 +2354,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 		uint32_t restore;
 
 		/* Default configuration. */
-		mlx5_os_config_default(&dev_config, &cdev->config);
-		dev_config.vf = mlx5_dev_is_vf_pci(pci_dev);
+		mlx5_os_config_default(&dev_config);
 		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
 						 &dev_config, &eth_da);
 		if (!list[i].eth_dev) {
@@ -2537,8 +2523,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	if (ret != 0)
 		return ret;
 	/* Set default config data. */
-	mlx5_os_config_default(&config, &cdev->config);
-	config.sf = 1;
+	mlx5_os_config_default(&config);
 	/* Init spawn data. */
 	spawn.max_port = 1;
 	spawn.phys_port = 1;
@@ -2769,7 +2754,7 @@ void
 mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const int vf = priv->config.vf;
+	const int vf = priv->sh->dev_cap.vf;
 
 	if (vf)
 		mlx5_nl_mac_addr_remove(priv->nl_socket_route,
@@ -2795,7 +2780,7 @@ mlx5_os_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac,
 		     uint32_t index)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	const int vf = priv->config.vf;
+	const int vf = priv->sh->dev_cap.vf;
 	int ret = 0;
 
 	if (vf)
diff --git a/drivers/net/mlx5/linux/mlx5_vlan_os.c b/drivers/net/mlx5/linux/mlx5_vlan_os.c
index 005904bdfe..80ccd5a460 100644
--- a/drivers/net/mlx5/linux/mlx5_vlan_os.c
+++ b/drivers/net/mlx5/linux/mlx5_vlan_os.c
@@ -103,12 +103,11 @@ void *
 mlx5_vlan_vmwa_init(struct rte_eth_dev *dev, uint32_t ifindex)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	struct mlx5_nl_vlan_vmwa_context *vmwa;
 	enum rte_hypervisor hv_type;
 
 	/* Do not engage workaround over PF. */
-	if (!config->vf)
+	if (!priv->sh->dev_cap.vf)
 		return NULL;
 	/* Check whether there is desired virtual environment */
 	hv_type = rte_hypervisor_get();
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 7487b1f87d..92cf148231 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1174,14 +1174,11 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
  *
  * @param sh
  *   Pointer to mlx5_dev_ctx_shared object.
- * @param config
- *   Device configuration parameters.
  * @param hca_attr
  *   Pointer to DevX HCA capabilities structure.
  */
 void
 mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
-			 struct mlx5_dev_config *config,
 			 struct mlx5_hca_attr *hca_attr)
 {
 	uint32_t dw_cnt = MLX5_ST_SZ_DW(register_mtutc);
@@ -1198,11 +1195,11 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 		/* MTUTC register is read successfully. */
 		ts_mode = MLX5_GET(register_mtutc, reg, time_stamp_mode);
 		if (ts_mode == MLX5_MTUTC_TIMESTAMP_MODE_REAL_TIME)
-			config->rt_timestamp = 1;
+			sh->dev_cap.rt_timestamp = 1;
 	} else {
 		/* Kernel does not support register reading. */
 		if (hca_attr->dev_freq_khz == (NS_PER_S / MS_PER_S))
-			config->rt_timestamp = 1;
+			sh->dev_cap.rt_timestamp = 1;
 	}
 }
 
@@ -1676,7 +1673,7 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 		mlx5_free(priv->rss_conf.rss_key);
 	if (priv->reta_idx != NULL)
 		mlx5_free(priv->reta_idx);
-	if (priv->config.vf)
+	if (priv->sh->dev_cap.vf)
 		mlx5_os_mac_addr_flush(dev);
 	if (priv->nl_socket_route >= 0)
 		close(priv->nl_socket_route);
@@ -2028,7 +2025,7 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 	} else if (strcmp(MLX5_MAX_DUMP_FILES_NUM, key) == 0) {
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
-		config->lro.timeout = tmp;
+		config->lro_timeout = tmp;
 	} else if (strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0) {
 		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index fd6350eee7..bda09cf96e 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -116,7 +116,6 @@ struct mlx5_flow_cb_ctx {
 
 /* Device capabilities structure which isn't changed in any stage. */
 struct mlx5_dev_cap {
-	uint64_t device_cap_flags_ex;
 	int max_cq; /* Maximum number of supported CQs */
 	int max_qp; /* Maximum number of supported QPs. */
 	int max_qp_wr; /* Maximum number of outstanding WR on any WQ. */
@@ -124,20 +123,40 @@ struct mlx5_dev_cap {
 	/* Maximum number of s/g per WR for SQ & RQ of QP for non RDMA Read
 	 * operations.
 	 */
-	uint32_t raw_packet_caps;
-	uint32_t max_rwq_indirection_table_size;
+	int mps; /* Multi-packet send supported mode. */
+	uint32_t vf:1; /* This is a VF. */
+	uint32_t sf:1; /* This is a SF. */
+	uint32_t txpp_en:1; /* Tx packet pacing is supported. */
+	uint32_t mpls_en:1; /* MPLS over GRE/UDP is supported. */
+	uint32_t cqe_comp:1; /* CQE compression is supported. */
+	uint32_t hw_csum:1; /* Checksum offload is supported. */
+	uint32_t hw_padding:1; /* End alignment padding is supported. */
+	uint32_t dest_tir:1; /* Whether advanced DR API is available. */
+	uint32_t dv_esw_en:1; /* E-Switch DV flow is supported. */
+	uint32_t dv_flow_en:1; /* DV flow is supported. */
+	uint32_t swp:3; /* Tx generic tunnel checksum and TSO offload. */
+	uint32_t hw_vlan_strip:1; /* VLAN stripping is supported. */
+	uint32_t scatter_fcs_w_decap_disable:1;
+	/* HW has bug working with tunnel packet decap and scatter FCS. */
+	uint32_t hw_fcs_strip:1; /* FCS stripping is supported. */
+	uint32_t rt_timestamp:1; /* Realtime timestamp format. */
+	uint32_t lro_supported:1; /* Whether LRO is supported. */
+	uint32_t rq_delay_drop_en:1; /* Enable RxQ delay drop. */
+	uint32_t tunnel_en:3;
+	/* Whether tunnel stateless offloads are supported. */
+	uint32_t ind_table_max_size;
 	/* Maximum receive WQ indirection table size. */
-	uint32_t max_tso; /* Maximum TCP payload for TSO. */
-	uint32_t tso_supported_qpts;
-	uint64_t flags;
-	uint64_t comp_mask;
-	uint32_t sw_parsing_offloads;
-	uint32_t min_single_stride_log_num_of_bytes;
-	uint32_t max_single_stride_log_num_of_bytes;
-	uint32_t min_single_wqe_log_num_of_strides;
-	uint32_t max_single_wqe_log_num_of_strides;
-	uint32_t stride_supported_qpts;
-	uint32_t tunnel_offloads_caps;
+	uint32_t tso:1; /* Whether TSO is supported. */
+	uint32_t tso_max_payload_sz; /* Maximum TCP payload for TSO. */
+	struct {
+		uint32_t enabled:1; /* Whether MPRQ is enabled. */
+		uint32_t log_min_stride_size; /* Log min size of a stride. */
+		uint32_t log_max_stride_size; /* Log max size of a stride. */
+		uint32_t log_min_stride_num; /* Log min num of strides. */
+		uint32_t log_max_stride_num; /* Log max num of strides. */
+		uint32_t log_min_stride_wqe_size;
+		/* Log min WQE size, (size of single stride)*(num of strides).*/
+	} mprq; /* Capability for Multi-Packet RQ. */
 	char fw_ver[64]; /* Firmware version of this device. */
 };
 
@@ -214,9 +233,6 @@ struct mlx5_stats_ctrl {
 	uint64_t imissed;
 };
 
-#define MLX5_LRO_SUPPORTED(dev) \
-	(((struct mlx5_priv *)((dev)->data->dev_private))->config.lro.supported)
-
 /* Maximal size of coalesced segment for LRO is set in chunks of 256 Bytes. */
 #define MLX5_LRO_SEG_CHUNK_SIZE	256u
 
@@ -226,12 +242,6 @@ struct mlx5_stats_ctrl {
 /* Maximal number of segments to split. */
 #define MLX5_MAX_RXQ_NSEG (1u << MLX5_MAX_LOG_RQ_SEGS)
 
-/* LRO configurations structure. */
-struct mlx5_lro_config {
-	uint32_t supported:1; /* Whether LRO is supported. */
-	uint32_t timeout; /* User configuration. */
-};
-
 /*
  * Device configuration structure.
  *
@@ -241,19 +251,11 @@ struct mlx5_lro_config {
  *  - User device parameters disabled features.
  */
 struct mlx5_dev_config {
-	unsigned int hw_csum:1; /* Checksum offload is supported. */
-	unsigned int hw_vlan_strip:1; /* VLAN stripping is supported. */
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
 	unsigned int hw_fcs_strip:1; /* FCS stripping is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
-	unsigned int vf:1; /* This is a VF. */
-	unsigned int sf:1; /* This is a SF. */
-	unsigned int tunnel_en:3;
-	/* Whether tunnel stateless offloads are supported. */
-	unsigned int mpls_en:1; /* MPLS over GRE/UDP is enabled. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
 	unsigned int cqe_comp_fmt:3; /* CQE compression format. */
-	unsigned int tso:1; /* Whether TSO is supported. */
 	unsigned int rx_vec_en:1; /* Rx vector is enabled. */
 	unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
 	unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */
@@ -262,10 +264,7 @@ struct mlx5_dev_config {
 	unsigned int dv_xmeta_en:2; /* Enable extensive flow metadata. */
 	unsigned int lacp_by_user:1;
 	/* Enable user to manage LACP traffic. */
-	unsigned int swp:3; /* Tx generic tunnel checksum and TSO offload. */
-	unsigned int dest_tir:1; /* Whether advanced DR API is available. */
 	unsigned int reclaim_mode:2; /* Memory reclaim mode. */
-	unsigned int rt_timestamp:1; /* realtime timestamp format. */
 	unsigned int decap_en:1; /* Whether decap will be used or not. */
 	unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
 	unsigned int allow_duplicate_pattern:1;
@@ -276,29 +275,21 @@ struct mlx5_dev_config {
 		unsigned int enabled:1; /* Whether MPRQ is enabled. */
 		unsigned int log_stride_num; /* Log number of strides. */
 		unsigned int log_stride_size; /* Log size of a stride. */
-		unsigned int log_min_stride_size; /* Log min size of a stride.*/
-		unsigned int log_max_stride_size; /* Log max size of a stride.*/
-		unsigned int log_min_stride_num; /* Log min num of strides. */
-		unsigned int log_max_stride_num; /* Log max num of strides. */
-		unsigned int log_min_stride_wqe_size;
-		/* Log min WQE size, (size of single stride)*(num of strides).*/
 		unsigned int max_memcpy_len;
 		/* Maximum packet size to memcpy Rx packets. */
 		unsigned int min_rxqs_num;
 		/* Rx queue count threshold to enable MPRQ. */
 	} mprq; /* Configurations for Multi-Packet RQ. */
 	int mps; /* Multi-packet send supported mode. */
-	unsigned int tso_max_payload_sz; /* Maximum TCP payload for TSO. */
-	unsigned int ind_table_max_size; /* Maximum indirection table size. */
 	unsigned int max_dump_files_num; /* Maximum dump files per queue. */
 	unsigned int log_hp_size; /* Single hairpin queue data size in total. */
+	unsigned int lro_timeout; /* LRO user configuration. */
 	int txqs_inline; /* Queue number threshold for inlining. */
 	int txq_inline_min; /* Minimal amount of data bytes to inline. */
 	int txq_inline_max; /* Max packet size for inlining with SEND. */
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
-	struct mlx5_lro_config lro; /* LRO configuration. */
 };
 
 
@@ -1518,7 +1509,6 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
 int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
-			      struct mlx5_dev_config *config,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
 mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index 553df6424d..de0f3672c1 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -571,7 +571,7 @@ mlx5_devx_ind_table_create_rqt_attr(struct rte_eth_dev *dev,
 		rte_errno = ENOMEM;
 		return NULL;
 	}
-	rqt_attr->rqt_max_size = priv->config.ind_table_max_size;
+	rqt_attr->rqt_max_size = priv->sh->dev_cap.ind_table_max_size;
 	rqt_attr->rqt_actual_size = rqt_n;
 	if (queues == NULL) {
 		for (i = 0; i < rqt_n; i++)
@@ -769,7 +769,7 @@ mlx5_devx_tir_attr_set(struct rte_eth_dev *dev, const uint8_t *rss_key,
 		tir_attr->self_lb_block =
 					MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
 	if (lro) {
-		tir_attr->lro_timeout_period_usecs = priv->config.lro.timeout;
+		tir_attr->lro_timeout_period_usecs = priv->config.lro_timeout;
 		tir_attr->lro_max_msg_sz = priv->max_lro_msg_size;
 		tir_attr->lro_enable_mask =
 				MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
@@ -1196,7 +1196,7 @@ mlx5_txq_create_devx_sq_resources(struct rte_eth_dev *dev, uint16_t idx,
 		.flush_in_error_en = 1,
 		.allow_multi_pkt_send_wqe = !!priv->config.mps,
 		.min_wqe_inline_mode = cdev->config.hca_attr.vport_inline_mode,
-		.allow_swp = !!priv->config.swp,
+		.allow_swp = !!priv->sh->dev_cap.swp,
 		.cqn = txq_obj->cq_obj.cq->id,
 		.tis_lst_sz = 1,
 		.wq_attr = (struct mlx5_devx_wq_attr){
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d970eb6904..b7fe781d3a 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -121,7 +121,7 @@ mlx5_dev_configure(struct rte_eth_dev *dev)
 			dev->data->port_id, priv->txqs_n, txqs_n);
 		priv->txqs_n = txqs_n;
 	}
-	if (rxqs_n > priv->config.ind_table_max_size) {
+	if (rxqs_n > priv->sh->dev_cap.ind_table_max_size) {
 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
 			dev->data->port_id, rxqs_n);
 		rte_errno = EINVAL;
@@ -177,7 +177,7 @@ mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
 			rss_queue_arr[j++] = i;
 	}
 	rss_queue_n = j;
-	if (rss_queue_n > priv->config.ind_table_max_size) {
+	if (rss_queue_n > priv->sh->dev_cap.ind_table_max_size) {
 		DRV_LOG(ERR, "port %u cannot handle this many Rx queues (%u)",
 			dev->data->port_id, rss_queue_n);
 		rte_errno = EINVAL;
@@ -193,8 +193,8 @@ mlx5_dev_configure_rss_reta(struct rte_eth_dev *dev)
 	 * The result is always rounded to the next power of two.
 	 */
 	reta_idx_n = (1 << log2above((rss_queue_n & (rss_queue_n - 1)) ?
-				priv->config.ind_table_max_size :
-				rss_queue_n));
+				     priv->sh->dev_cap.ind_table_max_size :
+				     rss_queue_n));
 	ret = mlx5_rss_reta_index_resize(dev, reta_idx_n);
 	if (ret) {
 		mlx5_free(rss_queue_arr);
@@ -330,7 +330,7 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->dev_capa = RTE_ETH_DEV_CAPA_FLOW_SHARED_OBJECT_KEEP;
 	info->if_index = mlx5_ifindex(dev);
 	info->reta_size = priv->reta_idx_n ?
-		priv->reta_idx_n : config->ind_table_max_size;
+		priv->reta_idx_n : priv->sh->dev_cap.ind_table_max_size;
 	info->hash_key_size = MLX5_RSS_HASH_KEY_LEN;
 	info->speed_capa = priv->link_speed_capa;
 	info->flow_type_rss_offloads = ~MLX5_RSS_HF_MASK;
@@ -722,7 +722,7 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
 
-	if (!priv->sh->cdev->config.devx || !config->dest_tir ||
+	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
 	    !config->dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 29011b12a8..4889fc8ae6 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -1759,7 +1759,7 @@ mlx5_validate_action_rss(struct rte_eth_dev *dev,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  &rss->key_len,
 					  "RSS hash key too large");
-	if (rss->queue_num > priv->config.ind_table_max_size)
+	if (rss->queue_num > priv->sh->dev_cap.ind_table_max_size)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
 					  &rss->queue_num,
@@ -3138,7 +3138,7 @@ mlx5_flow_validate_item_mpls(struct rte_eth_dev *dev __rte_unused,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	int ret;
 
-	if (!priv->config.mpls_en)
+	if (!priv->sh->dev_cap.mpls_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "MPLS not supported or"
diff --git a/drivers/net/mlx5/mlx5_rxmode.c b/drivers/net/mlx5/mlx5_rxmode.c
index 7f19b235c2..f44906e1a7 100644
--- a/drivers/net/mlx5/mlx5_rxmode.c
+++ b/drivers/net/mlx5/mlx5_rxmode.c
@@ -36,7 +36,7 @@ mlx5_promiscuous_enable(struct rte_eth_dev *dev)
 			dev->data->port_id);
 		return 0;
 	}
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_promisc(dev, 1);
 		if (ret)
 			return ret;
@@ -69,7 +69,7 @@ mlx5_promiscuous_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	dev->data->promiscuous = 0;
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_promisc(dev, 0);
 		if (ret)
 			return ret;
@@ -109,7 +109,7 @@ mlx5_allmulticast_enable(struct rte_eth_dev *dev)
 			dev->data->port_id);
 		return 0;
 	}
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_allmulti(dev, 1);
 		if (ret)
 			goto error;
@@ -142,7 +142,7 @@ mlx5_allmulticast_disable(struct rte_eth_dev *dev)
 	int ret;
 
 	dev->data->all_multicast = 0;
-	if (priv->config.vf || priv->config.sf) {
+	if (priv->sh->dev_cap.vf || priv->sh->dev_cap.sf) {
 		ret = mlx5_os_set_allmulti(dev, 0);
 		if (ret)
 			goto error;
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 0ede46aa43..bcb04018f8 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -368,13 +368,13 @@ mlx5_get_rx_queue_offloads(struct rte_eth_dev *dev)
 		offloads |= RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT;
 	if (config->hw_fcs_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
-	if (config->hw_csum)
+	if (priv->sh->dev_cap.hw_csum)
 		offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
 			     RTE_ETH_RX_OFFLOAD_UDP_CKSUM |
 			     RTE_ETH_RX_OFFLOAD_TCP_CKSUM);
-	if (config->hw_vlan_strip)
+	if (priv->sh->dev_cap.hw_vlan_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
-	if (MLX5_LRO_SUPPORTED(dev))
+	if (priv->sh->dev_cap.lro_supported)
 		offloads |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
 	return offloads;
 }
@@ -1564,14 +1564,15 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_dev_config *config = &priv->config;
-	uint32_t log_min_stride_num = config->mprq.log_min_stride_num;
-	uint32_t log_max_stride_num = config->mprq.log_max_stride_num;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
+	uint32_t log_min_stride_num = dev_cap->mprq.log_min_stride_num;
+	uint32_t log_max_stride_num = dev_cap->mprq.log_max_stride_num;
 	uint32_t log_def_stride_num =
 			RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM,
 					log_min_stride_num),
 				log_max_stride_num);
-	uint32_t log_min_stride_size = config->mprq.log_min_stride_size;
-	uint32_t log_max_stride_size = config->mprq.log_max_stride_size;
+	uint32_t log_min_stride_size = dev_cap->mprq.log_min_stride_size;
+	uint32_t log_max_stride_size = dev_cap->mprq.log_max_stride_size;
 	uint32_t log_def_stride_size =
 			RTE_MIN(RTE_MAX(MLX5_MPRQ_DEFAULT_LOG_STRIDE_SIZE,
 					log_min_stride_size),
@@ -1610,7 +1611,7 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 	}
 	log_stride_wqe_size = *actual_log_stride_num + *actual_log_stride_size;
 	/* Check if WQE buffer size is supported by hardware. */
-	if (log_stride_wqe_size < config->mprq.log_min_stride_wqe_size) {
+	if (log_stride_wqe_size < dev_cap->mprq.log_min_stride_wqe_size) {
 		*actual_log_stride_num = log_def_stride_num;
 		*actual_log_stride_size = log_def_stride_size;
 		DRV_LOG(WARNING,
@@ -1619,7 +1620,8 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			RTE_BIT32(log_def_stride_size));
 		log_stride_wqe_size = log_def_stride_num + log_def_stride_size;
 	}
-	MLX5_ASSERT(log_stride_wqe_size >= config->mprq.log_min_stride_wqe_size);
+	MLX5_ASSERT(log_stride_wqe_size >=
+		    dev_cap->mprq.log_min_stride_wqe_size);
 	if (desc <= RTE_BIT32(*actual_log_stride_num))
 		goto unsupport;
 	if (min_mbuf_size > RTE_BIT32(log_stride_wqe_size)) {
@@ -1648,9 +1650,9 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 			RTE_BIT32(config->mprq.log_stride_size),
 			RTE_BIT32(config->mprq.log_stride_num),
 			config->mprq.min_rxqs_num,
-			RTE_BIT32(config->mprq.log_min_stride_wqe_size),
-			RTE_BIT32(config->mprq.log_min_stride_size),
-			RTE_BIT32(config->mprq.log_max_stride_size),
+			RTE_BIT32(dev_cap->mprq.log_min_stride_wqe_size),
+			RTE_BIT32(dev_cap->mprq.log_min_stride_size),
+			RTE_BIT32(dev_cap->mprq.log_max_stride_size),
 			rx_seg_en ? "" : "not ");
 	return -1;
 }
@@ -2370,7 +2372,7 @@ mlx5_ind_table_obj_setup(struct rte_eth_dev *dev,
 	int ret = 0, err;
 	const unsigned int n = rte_is_power_of_2(queues_n) ?
 			       log2above(queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 
 	if (ref_qs)
 		for (i = 0; i != queues_n; ++i) {
@@ -2495,7 +2497,7 @@ mlx5_ind_table_obj_modify(struct rte_eth_dev *dev,
 	int ret = 0, err;
 	const unsigned int n = rte_is_power_of_2(queues_n) ?
 			       log2above(queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 
 	MLX5_ASSERT(standalone);
 	RTE_SET_USED(standalone);
@@ -2576,7 +2578,7 @@ mlx5_ind_table_obj_detach(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const unsigned int n = rte_is_power_of_2(ind_tbl->queues_n) ?
 			       log2above(ind_tbl->queues_n) :
-			       log2above(priv->config.ind_table_max_size);
+			       log2above(priv->sh->dev_cap.ind_table_max_size);
 	unsigned int i;
 	int ret;
 
@@ -2994,6 +2996,6 @@ mlx5_rxq_timestamp_set(struct rte_eth_dev *dev)
 		if (data == NULL)
 			continue;
 		data->sh = sh;
-		data->rt_timestamp = priv->config.rt_timestamp;
+		data->rt_timestamp = sh->dev_cap.rt_timestamp;
 	}
 }
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index f46089fd56..11ae0d9480 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1105,7 +1105,8 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 		goto error;
 	}
 	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
-	    priv->config.dest_tir) && priv->obj_ops.lb_dummy_queue_create) {
+	     priv->sh->dev_cap.dest_tir) &&
+	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
 			goto error;
@@ -1117,7 +1118,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 		goto error;
 	}
 	if (priv->config.std_delay_drop || priv->config.hp_delay_drop) {
-		if (!priv->config.vf && !priv->config.sf &&
+		if (!priv->sh->dev_cap.vf && !priv->sh->dev_cap.sf &&
 		    !priv->representor) {
 			ret = mlx5_get_flag_dropless_rq(dev);
 			if (ret < 0)
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 56e0937ca3..47bca9e3ea 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -101,33 +101,34 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 	uint64_t offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
 			     RTE_ETH_TX_OFFLOAD_VLAN_INSERT);
 	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 
-	if (config->hw_csum)
+	if (dev_cap->hw_csum)
 		offloads |= (RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
 			     RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
 			     RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
-	if (config->tso)
+	if (dev_cap->tso)
 		offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
 	if (config->tx_pp)
 		offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
-	if (config->swp) {
-		if (config->swp & MLX5_SW_PARSING_CSUM_CAP)
+	if (dev_cap->swp) {
+		if (dev_cap->swp & MLX5_SW_PARSING_CSUM_CAP)
 			offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
-		if (config->swp & MLX5_SW_PARSING_TSO_CAP)
+		if (dev_cap->swp & MLX5_SW_PARSING_TSO_CAP)
 			offloads |= (RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
 				     RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO);
 	}
-	if (config->tunnel_en) {
-		if (config->hw_csum)
+	if (dev_cap->tunnel_en) {
+		if (dev_cap->hw_csum)
 			offloads |= RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM;
-		if (config->tso) {
-			if (config->tunnel_en &
+		if (dev_cap->tso) {
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO;
-			if (config->tunnel_en &
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_GRE_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO;
-			if (config->tunnel_en &
+			if (dev_cap->tunnel_en &
 				MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)
 				offloads |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
 		}
@@ -741,6 +742,7 @@ txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
 	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	unsigned int inlen_send; /* Inline data for ordinary SEND.*/
 	unsigned int inlen_empw; /* Inline data for enhanced MPW. */
 	unsigned int inlen_mode; /* Minimal required Inline data. */
@@ -924,19 +926,19 @@ txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 		txq_ctrl->txq.tso_en = 1;
 	}
 	if (((RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_VXLAN_CAP)) |
 	   ((RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_GRE_CAP)) |
 	   ((RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO & txq_ctrl->txq.offloads) &&
-	    (config->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
-	   (config->swp  & MLX5_SW_PARSING_TSO_CAP))
+	    (dev_cap->tunnel_en & MLX5_TUNNELED_OFFLOADS_GENEVE_CAP)) |
+	   (dev_cap->swp  & MLX5_SW_PARSING_TSO_CAP))
 		txq_ctrl->txq.tunnel_en = 1;
 	txq_ctrl->txq.swp_en = (((RTE_ETH_TX_OFFLOAD_IP_TNL_TSO |
 				  RTE_ETH_TX_OFFLOAD_UDP_TNL_TSO) &
-				  txq_ctrl->txq.offloads) && (config->swp &
+				  txq_ctrl->txq.offloads) && (dev_cap->swp &
 				  MLX5_SW_PARSING_TSO_CAP)) |
 				((RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM &
-				 txq_ctrl->txq.offloads) && (config->swp &
+				 txq_ctrl->txq.offloads) && (dev_cap->swp &
 				 MLX5_SW_PARSING_CSUM_CAP));
 }
 
diff --git a/drivers/net/mlx5/mlx5_vlan.c b/drivers/net/mlx5/mlx5_vlan.c
index ea841bb32f..e7161b66fe 100644
--- a/drivers/net/mlx5/mlx5_vlan.c
+++ b/drivers/net/mlx5/mlx5_vlan.c
@@ -97,7 +97,7 @@ mlx5_vlan_strip_queue_set(struct rte_eth_dev *dev, uint16_t queue, int on)
 
 	MLX5_ASSERT(rxq != NULL && rxq->ctrl != NULL);
 	/* Validate hw support */
-	if (!priv->config.hw_vlan_strip) {
+	if (!priv->sh->dev_cap.hw_vlan_strip) {
 		DRV_LOG(ERR, "port %u VLAN stripping is not supported",
 			dev->data->port_id);
 		return;
@@ -146,7 +146,7 @@ mlx5_vlan_offload_set(struct rte_eth_dev *dev, int mask)
 		int hw_vlan_strip = !!(dev->data->dev_conf.rxmode.offloads &
 				       RTE_ETH_RX_OFFLOAD_VLAN_STRIP);
 
-		if (!priv->config.hw_vlan_strip) {
+		if (!priv->sh->dev_cap.hw_vlan_strip) {
 			DRV_LOG(ERR, "port %u VLAN stripping is not supported",
 				dev->data->port_id);
 			return 0;
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 91e91e4d36..b7542da69d 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -159,6 +159,8 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 	void *pv_iseg = NULL;
 	u32 cb_iseg = 0;
 
+	MLX5_ASSERT(sh->cdev->config.devx);
+	MLX5_ASSERT(mlx5_dev_is_pci(sh->cdev->dev));
 	pv_iseg = mlx5_glue->query_hca_iseg(mlx5_ctx, &cb_iseg);
 	if (pv_iseg == NULL) {
 		DRV_LOG(ERR, "Failed to get device hca_iseg.");
@@ -166,22 +168,55 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 		return -rte_errno;
 	}
 	memset(&sh->dev_cap, 0, sizeof(struct mlx5_dev_cap));
+	sh->dev_cap.vf = mlx5_dev_is_vf_pci(RTE_DEV_TO_PCI(sh->cdev->dev));
 	sh->dev_cap.max_cq = 1 << hca_attr->log_max_cq;
 	sh->dev_cap.max_qp = 1 << hca_attr->log_max_qp;
 	sh->dev_cap.max_qp_wr = 1 << hca_attr->log_max_qp_sz;
-	sh->dev_cap.max_tso = 1 << hca_attr->max_lso_cap;
+	sh->dev_cap.dv_flow_en = 1;
+	sh->dev_cap.mps = MLX5_MPW_DISABLED;
+	DRV_LOG(DEBUG, "MPW isn't supported.");
+	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is no supported.");
+	sh->dev_cap.hw_csum = hca_attr->csum_cap;
+	DRV_LOG(DEBUG, "Checksum offloading is %ssupported.",
+		(sh->dev_cap.hw_csum ? "" : "not "));
+	sh->dev_cap.hw_vlan_strip = hca_attr->vlan_cap;
+	DRV_LOG(DEBUG, "VLAN stripping is %ssupported.",
+		(sh->dev_cap.hw_vlan_strip ? "" : "not "));
+	sh->dev_cap.hw_fcs_strip = hca_attr->scatter_fcs;
+	sh->dev_cap.tso = ((1 << hca_attr->max_lso_cap) > 0);
+	if (sh->dev_cap.tso)
+		sh->dev_cap.tso_max_payload_sz = 1 << hca_attr->max_lso_cap;
+	DRV_LOG(DEBUG, "Counters are not supported.");
 	if (hca_attr->rss_ind_tbl_cap) {
-		sh->dev_cap.max_rwq_indirection_table_size =
-			1 << hca_attr->rss_ind_tbl_cap;
+		/*
+		 * DPDK doesn't support larger/variable indirection tables.
+		 * Once DPDK supports it, take max size from device attr.
+		 */
+		sh->dev_cap.ind_table_max_size =
+			RTE_MIN(1 << hca_attr->rss_ind_tbl_cap,
+				(unsigned int)RTE_ETH_RSS_RETA_SIZE_512);
+		DRV_LOG(DEBUG, "Maximum Rx indirection table size is %u",
+			sh->dev_cap.ind_table_max_size);
+	}
+	sh->dev_cap.swp = mlx5_get_supported_sw_parsing_offloads(hca_attr);
+	sh->dev_cap.tunnel_en = mlx5_get_supported_tunneling_offloads(hca_attr);
+	if (sh->dev_cap.tunnel_en) {
+		DRV_LOG(DEBUG, "Tunnel offloading is supported for %s%s%s",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
+			sh->dev_cap.tunnel_en &
+			MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : "");
+	} else {
+		DRV_LOG(DEBUG, "Tunnel offloading is not supported.");
 	}
-	sh->dev_cap.sw_parsing_offloads =
-		mlx5_get_supported_sw_parsing_offloads(hca_attr);
-	sh->dev_cap.tunnel_offloads_caps =
-		mlx5_get_supported_tunneling_offloads(hca_attr);
 	snprintf(sh->dev_cap.fw_ver, 64, "%x.%x.%04x",
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_major),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_minor),
 		 MLX5_GET(initial_seg, pv_iseg, fw_rev_subminor));
+	DRV_LOG(DEBUG, "Packet pacing is not supported.");
+	mlx5_rt_timestamp_config(sh, hca_attr);
 	return 0;
 }
 
@@ -265,7 +300,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_hca_attr *hca_attr;
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
 	int err = 0;
@@ -321,30 +355,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(errno));
 		goto error;
 	}
-	DRV_LOG(DEBUG, "MPW isn't supported");
-	config->swp = sh->dev_cap.sw_parsing_offloads &
-		(MLX5_SW_PARSING_CAP | MLX5_SW_PARSING_CSUM_CAP |
-		 MLX5_SW_PARSING_TSO_CAP);
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	config->tunnel_en = sh->dev_cap.tunnel_offloads_caps &
-		(MLX5_TUNNELED_OFFLOADS_VXLAN_CAP |
-		 MLX5_TUNNELED_OFFLOADS_GRE_CAP |
-		 MLX5_TUNNELED_OFFLOADS_GENEVE_CAP);
-	if (config->tunnel_en) {
-		DRV_LOG(DEBUG, "tunnel offloading is supported for %s%s%s",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_VXLAN_CAP ? "[VXLAN]" : "",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_GRE_CAP ? "[GRE]" : "",
-		config->tunnel_en &
-		MLX5_TUNNELED_OFFLOADS_GENEVE_CAP ? "[GENEVE]" : ""
-		);
-	} else {
-		DRV_LOG(DEBUG, "tunnel offloading is not supported");
-	}
-	DRV_LOG(DEBUG, "MPLS over GRE/UDP tunnel offloading is no supported");
-	config->mpls_en = 0;
 	/* Allocate private eth device data. */
 	priv = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			   sizeof(*priv),
@@ -395,24 +405,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	DRV_LOG(DEBUG, "counters are not supported");
-	config->ind_table_max_size =
-		sh->dev_cap.max_rwq_indirection_table_size;
-	/*
-	 * Remove this check once DPDK supports larger/variable
-	 * indirection tables.
-	 */
-	if (config->ind_table_max_size > (unsigned int)RTE_ETH_RSS_RETA_SIZE_512)
-		config->ind_table_max_size = RTE_ETH_RSS_RETA_SIZE_512;
-	DRV_LOG(DEBUG, "maximum Rx indirection table size is %u",
-		config->ind_table_max_size);
 	if (config->hw_padding) {
 		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
 		config->hw_padding = 0;
 	}
-	config->tso = (sh->dev_cap.max_tso > 0);
-	if (config->tso)
-		config->tso_max_payload_sz = sh->dev_cap.max_tso;
 	DRV_LOG(DEBUG, "%sMPS is %s.",
 		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
 		config->mps == MLX5_MPW ? "legacy " : "",
@@ -421,17 +417,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	if (sh->cdev->config.devx) {
-		hca_attr = &sh->cdev->config.hca_attr;
-		config->hw_csum = hca_attr->csum_cap;
-		DRV_LOG(DEBUG, "checksum offloading is %ssupported",
-			(config->hw_csum ? "" : "not "));
-		config->hw_vlan_strip = hca_attr->vlan_cap;
-		DRV_LOG(DEBUG, "VLAN stripping is %ssupported",
-			(config->hw_vlan_strip ? "" : "not "));
-		config->hw_fcs_strip = hca_attr->scatter_fcs;
-		mlx5_rt_timestamp_config(sh, config, hca_attr);
-	}
+	config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
 		config->mprq.enabled = 0;
@@ -853,7 +839,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 		},
 		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
-		.vf = mlx5_dev_is_vf_pci(pci_dev),
 	};
 	int ret;
 	uint32_t restore;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 16/20] net/mlx5: add share device context config structure
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (14 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 15/20] net/mlx5: concentrate all device configurations Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
                     ` (4 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add configuration structure for shared device context. This structure
contains all configurations coming from devargs which oriented to
device. It is a field of shared device context (SH) structure, and is
updated once in mlx5_alloc_shared_dev_ctx() function.
This structure cannot be changed when probing again, so add function to
prevent it. The mlx5_probe_again_args_validate() function creates a
temporary IB context configure structure according to new devargs
attached in probing again, then checks the match between the temporary
structure and the existing IB context configure structure.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   |  95 ++----
 drivers/net/mlx5/mlx5.c            | 453 +++++++++++++++++++++--------
 drivers/net/mlx5/mlx5.h            |  43 +--
 drivers/net/mlx5/mlx5_ethdev.c     |   3 +-
 drivers/net/mlx5/mlx5_flow.c       |  30 +-
 drivers/net/mlx5/mlx5_flow.h       |   2 +-
 drivers/net/mlx5/mlx5_flow_dv.c    |  45 +--
 drivers/net/mlx5/mlx5_flow_meter.c |  10 +-
 drivers/net/mlx5/mlx5_rxq.c        |   7 +-
 drivers/net/mlx5/mlx5_trigger.c    |  10 +-
 drivers/net/mlx5/mlx5_txpp.c       |  12 +-
 drivers/net/mlx5/mlx5_txq.c        |   2 +-
 drivers/net/mlx5/windows/mlx5_os.c |  35 +--
 13 files changed, 457 insertions(+), 290 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 5d2c9b9c8b..7ee76d54bd 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -436,7 +436,7 @@ __mlx5_discovery_misc5_cap(struct mlx5_priv *priv)
 	dv_attr.priority = 3;
 #ifdef HAVE_MLX5DV_DR_ESWITCH
 	void *misc2_m;
-	if (priv->config.dv_esw_en) {
+	if (priv->sh->config.dv_esw_en) {
 		/* FDB enabled reg_c_0 */
 		dv_attr.match_criteria_enable |=
 				(1 << MLX5_MATCH_CRITERIA_ENABLE_MISC2_BIT);
@@ -557,7 +557,7 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 	}
 	sh->tx_domain = domain;
 #ifdef HAVE_MLX5DV_DR_ESWITCH
-	if (priv->config.dv_esw_en) {
+	if (sh->config.dv_esw_en) {
 		domain = mlx5_glue->dr_create_domain(sh->cdev->ctx,
 						     MLX5DV_DR_DOMAIN_TYPE_FDB);
 		if (!domain) {
@@ -579,20 +579,20 @@ mlx5_alloc_shared_dr(struct mlx5_priv *priv)
 		goto error;
 	}
 #endif
-	if (!sh->tunnel_hub && priv->config.dv_miss_info)
+	if (!sh->tunnel_hub && sh->config.dv_miss_info)
 		err = mlx5_alloc_tunnel_hub(sh);
 	if (err) {
 		DRV_LOG(ERR, "mlx5_alloc_tunnel_hub failed err=%d", err);
 		goto error;
 	}
-	if (priv->config.reclaim_mode == MLX5_RCM_AGGR) {
+	if (sh->config.reclaim_mode == MLX5_RCM_AGGR) {
 		mlx5_glue->dr_reclaim_domain_memory(sh->rx_domain, 1);
 		mlx5_glue->dr_reclaim_domain_memory(sh->tx_domain, 1);
 		if (sh->fdb_domain)
 			mlx5_glue->dr_reclaim_domain_memory(sh->fdb_domain, 1);
 	}
 	sh->pop_vlan_action = mlx5_glue->dr_create_flow_action_pop_vlan();
-	if (!priv->config.allow_duplicate_pattern) {
+	if (!sh->config.allow_duplicate_pattern) {
 #ifndef HAVE_MLX5_DR_ALLOW_DUPLICATE
 		DRV_LOG(WARNING, "Disallow duplicate pattern is not supported - maybe old rdma-core version?");
 #endif
@@ -859,7 +859,7 @@ 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)
+	if (!priv->sh->config.dv_flow_en || !priv->sh->dr_drop_action)
 		return;
 	/**
 	 * DR supports drop action placeholder when it is supported;
@@ -1115,31 +1115,9 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		return NULL;
 	}
-	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
+	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
-	/* Update final values for devargs before check sibling config. */
-	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
-		DRV_LOG(WARNING, "DV flow is not supported.");
-		config->dv_flow_en = 0;
-	}
-	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
-		DRV_LOG(WARNING, "E-Switch DV flow is not supported.");
-		config->dv_esw_en = 0;
-	}
-	if (config->dv_miss_info && config->dv_esw_en)
-		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
-	if (!config->dv_esw_en &&
-	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			config->dv_xmeta_en);
-		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
-	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
-	if (err)
-		goto error;
 	nl_rdma = mlx5_nl_init(NETLINK_RDMA);
 	/* Check port status. */
 	if (spawn->phys_port <= UINT8_MAX) {
@@ -1314,7 +1292,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	if (sh->cdev->config.devx) {
 		sh->steering_format_version = hca_attr->steering_format_version;
 		/* LRO is supported only when DV flow enabled. */
-		if (sh->dev_cap.lro_supported && config->dv_flow_en)
+		if (sh->dev_cap.lro_supported && sh->config.dv_flow_en)
 			sh->dev_cap.lro_supported = 0;
 		if (sh->dev_cap.lro_supported) {
 			/*
@@ -1331,7 +1309,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
 		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_old &&
-		    config->dv_flow_en) {
+		    sh->config.dv_flow_en) {
 			uint8_t reg_c_mask = hca_attr->qos.flow_meter_reg_c_ids;
 			/*
 			 * Meter needs two REG_C's for color match and pre-sfx
@@ -1405,7 +1383,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #endif /* HAVE_MLX5_DR_CREATE_ACTION_ASO && HAVE_MLX5_DR_ACTION_ASO_CT */
 #if defined(HAVE_MLX5DV_DR) && defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_SAMPLE)
 		if (hca_attr->log_max_ft_sampler_num > 0  &&
-		    config->dv_flow_en) {
+		    sh->config.dv_flow_en) {
 			priv->sampler_en = 1;
 			DRV_LOG(DEBUG, "Sampler enabled!");
 		} else {
@@ -1436,11 +1414,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
 			config->cqe_comp ? "" : "not ");
-	if (config->tx_pp && !sh->dev_cap.txpp_en) {
-		DRV_LOG(ERR, "Packet pacing is not supported.");
-		err = ENODEV;
-		goto error;
-	}
 	if (config->std_delay_drop || config->hp_delay_drop) {
 		if (!hca_attr->rq_delay_drop) {
 			config->std_delay_drop = 0;
@@ -1450,17 +1423,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				priv->dev_port);
 		}
 	}
-	/*
-	 * If HW has bug working with tunnel packet decapsulation and
-	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
-	 * bit. Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
-	 */
-	if (sh->dev_cap.scatter_fcs_w_decap_disable && config->decap_en)
-		config->hw_fcs_strip = 0;
-	else
-		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
-	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
-		(config->hw_fcs_strip ? "" : "not "));
 	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
 		config->mprq.enabled = 0;
@@ -1546,7 +1508,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	eth_dev->rx_queue_count = mlx5_rx_queue_count;
 	/* Register MAC address. */
 	claim_zero(mlx5_mac_addr_add(eth_dev, &mac, 0, 0));
-	if (sh->dev_cap.vf && config->vf_nl_en)
+	if (sh->dev_cap.vf && sh->config.vf_nl_en)
 		mlx5_nl_mac_addr_sync(priv->nl_socket_route,
 				      mlx5_ifindex(eth_dev),
 				      eth_dev->data->mac_addrs,
@@ -1572,8 +1534,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Store device configuration on private structure. */
 	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
-		icfg[i].release_mem_en = !!config->reclaim_mode;
-		if (config->reclaim_mode)
+		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
+		if (sh->config.reclaim_mode)
 			icfg[i].per_core_cache = 0;
 		priv->flows[i] = mlx5_ipool_create(&icfg[i]);
 		if (!priv->flows[i])
@@ -1581,14 +1543,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Create context for virtual machine VLAN workaround. */
 	priv->vmwa_context = mlx5_vlan_vmwa_init(eth_dev, spawn->ifindex);
-	if (config->dv_flow_en) {
+	if (sh->config.dv_flow_en) {
 		err = mlx5_alloc_shared_dr(priv);
 		if (err)
 			goto error;
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && config->dv_flow_en &&
+	if (sh->cdev->config.devx && sh->config.dv_flow_en &&
 	    sh->dev_cap.dest_tir) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
@@ -1604,7 +1566,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	} else {
 		priv->obj_ops = ibv_obj_ops;
 	}
-	if (config->tx_pp &&
+	if (sh->config.tx_pp &&
 	    priv->obj_ops.txq_obj_new != mlx5_txq_devx_obj_new) {
 		/*
 		 * HAVE_MLX5DV_DEVX_UAR_OFFSET is required to support
@@ -1635,11 +1597,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		goto error;
 	}
 	mlx5_set_metadata_mask(eth_dev);
-	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
 		DRV_LOG(ERR, "metadata mode %u is not supported "
 			     "(no metadata reg_c[0] is available)",
-			     priv->config.dv_xmeta_en);
+			     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 	}
@@ -1664,16 +1626,16 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG,
 			"port %u extensive metadata register is not supported",
 			eth_dev->data->port_id);
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 			DRV_LOG(ERR, "metadata mode %u is not supported "
 				     "(no metadata registers available)",
-				     priv->config.dv_xmeta_en);
+				     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 		}
 	}
-	if (priv->config.dv_flow_en &&
-	    priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_flow_en &&
+	    sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    mlx5_flow_ext_mreg_supported(eth_dev) &&
 	    priv->sh->dv_regc0_mask) {
 		priv->mreg_cp_tbl = mlx5_hlist_create(MLX5_FLOW_MREG_HNAME,
@@ -1692,7 +1654,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	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)
+	if (sh->config.dv_flow_en)
 		eth_dev->data->dev_flags |= RTE_ETH_DEV_FLOW_OPS_THREAD_SAFE;
 	return eth_dev;
 error:
@@ -1950,15 +1912,10 @@ mlx5_os_config_default(struct mlx5_dev_config *config)
 	config->txq_inline_min = MLX5_ARG_UNSET;
 	config->txq_inline_mpw = MLX5_ARG_UNSET;
 	config->txqs_inline = MLX5_ARG_UNSET;
-	config->vf_nl_en = 1;
 	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
 	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
 	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
-	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;
 	config->std_delay_drop = 0;
 	config->hp_delay_drop = 0;
 }
@@ -2574,6 +2531,12 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
+	ret = mlx5_probe_again_args_validate(cdev);
+	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);
 	else
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 92cf148231..f3a9e749ab 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -533,7 +533,7 @@ mlx5_flow_counter_mode_config(struct rte_eth_dev *dev __rte_unused)
 	fallback = true;
 #else
 	fallback = false;
-	if (!sh->cdev->config.devx || !priv->config.dv_flow_en ||
+	if (!sh->cdev->config.devx || !sh->config.dv_flow_en ||
 	    !hca_attr->flow_counters_dump ||
 	    !(hca_attr->flow_counter_bulk_alloc_bitmap & 0x4) ||
 	    (mlx5_flow_dv_discover_counter_offset_support(dev) == -ENOTSUP))
@@ -836,12 +836,9 @@ mlx5_flow_aso_ct_mng_close(struct mlx5_dev_ctx_shared *sh)
  *
  * @param[in] sh
  *   Pointer to mlx5_dev_ctx_shared object.
- * @param[in] config
- *   Pointer to user dev config.
  */
 static void
-mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh,
-		       const struct mlx5_dev_config *config)
+mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh)
 {
 	uint8_t i;
 	struct mlx5_indexed_pool_config cfg;
@@ -856,12 +853,12 @@ mlx5_flow_ipool_create(struct mlx5_dev_ctx_shared *sh,
 		 * according to PCI function flow configuration.
 		 */
 		case MLX5_IPOOL_MLX5_FLOW:
-			cfg.size = config->dv_flow_en ?
+			cfg.size = sh->config.dv_flow_en ?
 				sizeof(struct mlx5_flow_handle) :
 				MLX5_FLOW_HANDLE_VERBS_SIZE;
 			break;
 		}
-		if (config->reclaim_mode) {
+		if (sh->config.reclaim_mode) {
 			cfg.release_mem_en = 1;
 			cfg.per_core_cache = 0;
 		} else {
@@ -1169,6 +1166,191 @@ mlx5_setup_tis(struct mlx5_dev_ctx_shared *sh)
 	return 0;
 }
 
+/**
+ * Verify and store value for share device argument.
+ *
+ * @param[in] key
+ *   Key argument to verify.
+ * @param[in] val
+ *   Value associated with key.
+ * @param opaque
+ *   User data.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
+{
+	struct mlx5_sh_config *config = opaque;
+	signed long tmp;
+
+	errno = 0;
+	tmp = strtol(val, NULL, 0);
+	if (errno) {
+		rte_errno = errno;
+		DRV_LOG(WARNING, "%s: \"%s\" is not a valid integer", key, val);
+		return -rte_errno;
+	}
+	if (tmp < 0 && strcmp(MLX5_TX_PP, key) && strcmp(MLX5_TX_SKEW, key)) {
+		/* Negative values are acceptable for some keys only. */
+		rte_errno = EINVAL;
+		DRV_LOG(WARNING, "%s: invalid negative value \"%s\"", key, val);
+		return -rte_errno;
+	}
+	if (strcmp(MLX5_TX_PP, key) == 0) {
+		unsigned long mod = tmp >= 0 ? tmp : -tmp;
+
+		if (!mod) {
+			DRV_LOG(ERR, "Zero Tx packet pacing parameter.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		config->tx_pp = tmp;
+	} else if (strcmp(MLX5_TX_SKEW, key) == 0) {
+		config->tx_skew = tmp;
+	} else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
+		config->l3_vxlan_en = !!tmp;
+	} else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
+		config->vf_nl_en = !!tmp;
+	} else if (strcmp(MLX5_DV_ESW_EN, key) == 0) {
+		config->dv_esw_en = !!tmp;
+	} else if (strcmp(MLX5_DV_FLOW_EN, key) == 0) {
+		config->dv_flow_en = !!tmp;
+	} else if (strcmp(MLX5_DV_XMETA_EN, key) == 0) {
+		if (tmp != MLX5_XMETA_MODE_LEGACY &&
+		    tmp != MLX5_XMETA_MODE_META16 &&
+		    tmp != MLX5_XMETA_MODE_META32 &&
+		    tmp != MLX5_XMETA_MODE_MISS_INFO) {
+			DRV_LOG(ERR, "Invalid extensive metadata parameter.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		if (tmp != MLX5_XMETA_MODE_MISS_INFO)
+			config->dv_xmeta_en = tmp;
+		else
+			config->dv_miss_info = 1;
+	} else if (strcmp(MLX5_LACP_BY_USER, key) == 0) {
+		config->lacp_by_user = !!tmp;
+	} else if (strcmp(MLX5_RECLAIM_MEM, key) == 0) {
+		if (tmp != MLX5_RCM_NONE &&
+		    tmp != MLX5_RCM_LIGHT &&
+		    tmp != MLX5_RCM_AGGR) {
+			DRV_LOG(ERR, "Unrecognize %s: \"%s\"", key, val);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		config->reclaim_mode = tmp;
+	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
+		config->decap_en = !!tmp;
+	} else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
+		config->allow_duplicate_pattern = !!tmp;
+	}
+	return 0;
+}
+
+/**
+ * Parse user device parameters and adjust them according to device
+ * capabilities.
+ *
+ * @param sh
+ *   Pointer to shared device context.
+ * @param devargs
+ *   Device arguments structure.
+ * @param config
+ *   Pointer to shared device configuration structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
+				struct rte_devargs *devargs,
+				struct mlx5_sh_config *config)
+{
+	struct rte_kvargs *kvlist;
+	int ret = 0;
+
+	/* Default configuration. */
+	memset(config, 0, sizeof(*config));
+	config->vf_nl_en = 1;
+	config->dv_esw_en = 1;
+	config->dv_flow_en = 1;
+	config->decap_en = 1;
+	config->allow_duplicate_pattern = 1;
+	/* Parse device parameters. */
+	if (devargs != NULL) {
+		kvlist = rte_kvargs_parse(devargs->args, NULL);
+		if (kvlist == NULL) {
+			DRV_LOG(ERR,
+				"Failed to parse shared device arguments.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		/* Process parameters. */
+		ret = rte_kvargs_process(kvlist, NULL,
+					 mlx5_dev_args_check_handler, config);
+		rte_kvargs_free(kvlist);
+		if (ret) {
+			DRV_LOG(ERR, "Failed to process device arguments: %s",
+				strerror(rte_errno));
+			return -rte_errno;
+		}
+	}
+	/* Adjust parameters according to device capabilities. */
+	if (config->dv_flow_en && !sh->dev_cap.dv_flow_en) {
+		DRV_LOG(WARNING, "DV flow is not supported.");
+		config->dv_flow_en = 0;
+	}
+	if (config->dv_esw_en && !sh->dev_cap.dv_esw_en) {
+		DRV_LOG(DEBUG, "E-Switch DV flow is not supported.");
+		config->dv_esw_en = 0;
+	}
+	if (config->dv_miss_info && config->dv_esw_en)
+		config->dv_xmeta_en = MLX5_XMETA_MODE_META16;
+	if (!config->dv_esw_en &&
+	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		DRV_LOG(WARNING,
+			"Metadata mode %u is not supported (no E-Switch).",
+			config->dv_xmeta_en);
+		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	}
+	if (config->tx_pp && !sh->dev_cap.txpp_en) {
+		DRV_LOG(ERR, "Packet pacing is not supported.");
+		rte_errno = ENODEV;
+		return -rte_errno;
+	}
+	if (!config->tx_pp && config->tx_skew) {
+		DRV_LOG(WARNING,
+			"\"tx_skew\" doesn't affect without \"tx_pp\".");
+	}
+	/*
+	 * If HW has bug working with tunnel packet decapsulation and scatter
+	 * FCS, and decapsulation is needed, clear the hw_fcs_strip bit.
+	 * Then RTE_ETH_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
+	 */
+	if (sh->dev_cap.scatter_fcs_w_decap_disable && sh->config.decap_en)
+		config->hw_fcs_strip = 0;
+	else
+		config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
+	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
+		(config->hw_fcs_strip ? "" : "not "));
+	DRV_LOG(DEBUG, "\"tx_pp\" is %d.", config->tx_pp);
+	DRV_LOG(DEBUG, "\"tx_skew\" is %d.", config->tx_skew);
+	DRV_LOG(DEBUG, "\"reclaim_mode\" is %u.", config->reclaim_mode);
+	DRV_LOG(DEBUG, "\"dv_esw_en\" is %u.", config->dv_esw_en);
+	DRV_LOG(DEBUG, "\"dv_flow_en\" is %u.", config->dv_flow_en);
+	DRV_LOG(DEBUG, "\"dv_xmeta_en\" is %u.", config->dv_xmeta_en);
+	DRV_LOG(DEBUG, "\"dv_miss_info\" is %u.", config->dv_miss_info);
+	DRV_LOG(DEBUG, "\"l3_vxlan_en\" is %u.", config->l3_vxlan_en);
+	DRV_LOG(DEBUG, "\"vf_nl_en\" is %u.", config->vf_nl_en);
+	DRV_LOG(DEBUG, "\"lacp_by_user\" is %u.", config->lacp_by_user);
+	DRV_LOG(DEBUG, "\"decap_en\" is %u.", config->decap_en);
+	DRV_LOG(DEBUG, "\"allow_duplicate_pattern\" is %u.",
+		config->allow_duplicate_pattern);
+	return 0;
+}
+
 /**
  * Configure realtime timestamp format.
  *
@@ -1216,16 +1398,13 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
  *
  * @param[in] spawn
  *   Pointer to the device attributes (name, port, etc).
- * @param[in] config
- *   Pointer to device configuration structure.
  *
  * @return
  *   Pointer to mlx5_dev_ctx_shared object on success,
  *   otherwise NULL and rte_errno is set.
  */
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
-			  const struct mlx5_dev_config *config)
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
 {
 	struct mlx5_dev_ctx_shared *sh;
 	int err = 0;
@@ -1264,9 +1443,15 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
+	err = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
+					      &sh->config);
+	if (err) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		goto error;
+	}
 	sh->refcnt = 1;
 	sh->max_port = spawn->max_port;
-	sh->reclaim_mode = config->reclaim_mode;
 	strncpy(sh->ibdev_name, mlx5_os_get_ctx_device_name(sh->cdev->ctx),
 		sizeof(sh->ibdev_name) - 1);
 	strncpy(sh->ibdev_path, mlx5_os_get_ctx_device_path(sh->cdev->ctx),
@@ -1310,7 +1495,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
 	}
 	mlx5_flow_aging_init(sh);
 	mlx5_flow_counters_mng_init(sh);
-	mlx5_flow_ipool_create(sh, config);
+	mlx5_flow_ipool_create(sh);
 	/* Add context to the global device list. */
 	LIST_INSERT_HEAD(&mlx5_dev_ctx_list, sh, next);
 	rte_spinlock_init(&sh->geneve_tlv_opt_sl);
@@ -1919,14 +2104,18 @@ static int
 mlx5_args_check(const char *key, const char *val, void *opaque)
 {
 	struct mlx5_dev_config *config = opaque;
-	unsigned long mod;
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
 	if (!strcmp(MLX5_DRIVER_KEY, key) || !strcmp(MLX5_REPRESENTOR, key) ||
 	    !strcmp(MLX5_SYS_MEM_EN, key) || !strcmp(MLX5_TX_DB_NC, key) ||
-	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) ||
-	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key))
+	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) || !strcmp(MLX5_TX_PP, key) ||
+	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key) || !strcmp(MLX5_TX_SKEW, key) ||
+	    !strcmp(MLX5_RECLAIM_MEM, key) || !strcmp(MLX5_DECAP_EN, key) ||
+	    !strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) ||
+	    !strcmp(MLX5_L3_VXLAN_EN, key) || !strcmp(MLX5_VF_NL_EN, key) ||
+	    !strcmp(MLX5_DV_ESW_EN, key) || !strcmp(MLX5_DV_FLOW_EN, key) ||
+	    !strcmp(MLX5_DV_XMETA_EN, key) || !strcmp(MLX5_LACP_BY_USER, key))
 		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
@@ -1935,13 +2124,12 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		DRV_LOG(WARNING, "%s: \"%s\" is not a valid integer", key, val);
 		return -rte_errno;
 	}
-	if (tmp < 0 && strcmp(MLX5_TX_PP, key) && strcmp(MLX5_TX_SKEW, key)) {
+	if (tmp < 0) {
 		/* Negative values are acceptable for some keys only. */
 		rte_errno = EINVAL;
 		DRV_LOG(WARNING, "%s: invalid negative value \"%s\"", key, val);
 		return -rte_errno;
 	}
-	mod = tmp >= 0 ? tmp : -tmp;
 	if (strcmp(MLX5_RXQ_CQE_COMP_EN, key) == 0) {
 		if (tmp > MLX5_CQE_RESP_FORMAT_L34H_STRIDX) {
 			DRV_LOG(ERR, "invalid CQE compression "
@@ -1987,41 +2175,8 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		config->txq_inline_mpw = tmp;
 	} else if (strcmp(MLX5_TX_VEC_EN, key) == 0) {
 		DRV_LOG(WARNING, "%s: deprecated parameter, ignored", key);
-	} else if (strcmp(MLX5_TX_PP, key) == 0) {
-		if (!mod) {
-			DRV_LOG(ERR, "Zero Tx packet pacing parameter");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		config->tx_pp = tmp;
-	} else if (strcmp(MLX5_TX_SKEW, key) == 0) {
-		config->tx_skew = tmp;
 	} else if (strcmp(MLX5_RX_VEC_EN, key) == 0) {
 		config->rx_vec_en = !!tmp;
-	} else if (strcmp(MLX5_L3_VXLAN_EN, key) == 0) {
-		config->l3_vxlan_en = !!tmp;
-	} else if (strcmp(MLX5_VF_NL_EN, key) == 0) {
-		config->vf_nl_en = !!tmp;
-	} else if (strcmp(MLX5_DV_ESW_EN, key) == 0) {
-		config->dv_esw_en = !!tmp;
-	} else if (strcmp(MLX5_DV_FLOW_EN, key) == 0) {
-		config->dv_flow_en = !!tmp;
-	} else if (strcmp(MLX5_DV_XMETA_EN, key) == 0) {
-		if (tmp != MLX5_XMETA_MODE_LEGACY &&
-		    tmp != MLX5_XMETA_MODE_META16 &&
-		    tmp != MLX5_XMETA_MODE_META32 &&
-		    tmp != MLX5_XMETA_MODE_MISS_INFO) {
-			DRV_LOG(ERR, "invalid extensive "
-				     "metadata parameter");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		if (tmp != MLX5_XMETA_MODE_MISS_INFO)
-			config->dv_xmeta_en = tmp;
-		else
-			config->dv_miss_info = 1;
-	} else if (strcmp(MLX5_LACP_BY_USER, key) == 0) {
-		config->lacp_by_user = !!tmp;
 	} else if (strcmp(MLX5_MAX_DUMP_FILES_NUM, key) == 0) {
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
@@ -2030,19 +2185,6 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
 		config->log_hp_size = tmp;
-	} else if (strcmp(MLX5_RECLAIM_MEM, key) == 0) {
-		if (tmp != MLX5_RCM_NONE &&
-		    tmp != MLX5_RCM_LIGHT &&
-		    tmp != MLX5_RCM_AGGR) {
-			DRV_LOG(ERR, "Unrecognized %s: \"%s\"", key, val);
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
-		config->reclaim_mode = tmp;
-	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
-		config->decap_en = !!tmp;
-	} else if (strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) == 0) {
-		config->allow_duplicate_pattern = !!tmp;
 	} else if (strcmp(MLX5_DELAY_DROP, key) == 0) {
 		config->std_delay_drop = !!(tmp & MLX5_DELAY_DROP_STANDARD);
 		config->hp_delay_drop = !!(tmp & MLX5_DELAY_DROP_HAIRPIN);
@@ -2089,6 +2231,130 @@ mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
 	return ret;
 }
 
+/**
+ * Check sibling device configurations when probing again.
+ *
+ * Sibling devices sharing infiniband device context should have compatible
+ * configurations. This regards representors and bonding device.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
+{
+	struct mlx5_dev_ctx_shared *sh = NULL;
+	struct mlx5_sh_config *config;
+	int ret;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	pthread_mutex_lock(&mlx5_dev_ctx_list_mutex);
+	/* Search for IB context by common device pointer. */
+	LIST_FOREACH(sh, &mlx5_dev_ctx_list, next)
+		if (sh->cdev == cdev)
+			break;
+	pthread_mutex_unlock(&mlx5_dev_ctx_list_mutex);
+	/* There is sh for this device -> it isn't probe again. */
+	if (sh == NULL)
+		return 0;
+	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
+			     sizeof(struct mlx5_sh_config),
+			     RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+	if (config == NULL) {
+		rte_errno = -ENOMEM;
+		return -rte_errno;
+	}
+	/*
+	 * Creates a temporary IB context configure structure according to new
+	 * devargs attached in probing again.
+	 */
+	ret = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
+					      config);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		mlx5_free(config);
+		return ret;
+	}
+	/*
+	 * Checks the match between the temporary structure and the existing
+	 * IB context structure.
+	 */
+	if (sh->config.dv_flow_en ^ config->dv_flow_en) {
+		DRV_LOG(ERR, "\"dv_flow_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if ((sh->config.dv_xmeta_en ^ config->dv_xmeta_en) ||
+	    (sh->config.dv_miss_info ^ config->dv_miss_info)) {
+		DRV_LOG(ERR, "\"dv_xmeta_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.dv_esw_en ^ config->dv_esw_en) {
+		DRV_LOG(ERR, "\"dv_esw_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.reclaim_mode ^ config->reclaim_mode) {
+		DRV_LOG(ERR, "\"reclaim_mode\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.allow_duplicate_pattern ^
+	    config->allow_duplicate_pattern) {
+		DRV_LOG(ERR, "\"allow_duplicate_pattern\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.l3_vxlan_en ^ config->l3_vxlan_en) {
+		DRV_LOG(ERR, "\"l3_vxlan_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.decap_en ^ config->decap_en) {
+		DRV_LOG(ERR, "\"decap_en\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.lacp_by_user ^ config->lacp_by_user) {
+		DRV_LOG(ERR, "\"lacp_by_user\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.tx_pp ^ config->tx_pp) {
+		DRV_LOG(ERR, "\"tx_pp\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	if (sh->config.tx_skew ^ config->tx_skew) {
+		DRV_LOG(ERR, "\"tx_skew\" "
+			"configuration mismatch for shared %s context.",
+			sh->ibdev_name);
+		goto error;
+	}
+	mlx5_free(config);
+	return 0;
+error:
+	mlx5_free(config);
+	rte_errno = EINVAL;
+	return -rte_errno;
+}
+
 /**
  * Configures the minimal amount of data to inline into WQE
  * while sending packets.
@@ -2231,7 +2497,7 @@ mlx5_set_metadata_mask(struct rte_eth_dev *dev)
 	uint32_t meta, mark, reg_c0;
 
 	reg_c0 = ~priv->vport_meta_mask;
-	switch (priv->config.dv_xmeta_en) {
+	switch (sh->config.dv_xmeta_en) {
 	case MLX5_XMETA_MODE_LEGACY:
 		meta = UINT32_MAX;
 		mark = MLX5_FLOW_MARK_MASK;
@@ -2265,7 +2531,7 @@ mlx5_set_metadata_mask(struct rte_eth_dev *dev)
 				 sh->dv_meta_mask, reg_c0);
 	else
 		sh->dv_regc0_mask = reg_c0;
-	DRV_LOG(DEBUG, "metadata mode %u", priv->config.dv_xmeta_en);
+	DRV_LOG(DEBUG, "metadata mode %u", sh->config.dv_xmeta_en);
 	DRV_LOG(DEBUG, "metadata MARK mask %08X", sh->dv_mark_mask);
 	DRV_LOG(DEBUG, "metadata META mask %08X", sh->dv_meta_mask);
 	DRV_LOG(DEBUG, "metadata reg_c0 mask %08X", sh->dv_regc0_mask);
@@ -2291,61 +2557,6 @@ rte_pmd_mlx5_get_dyn_flag_names(char *names[], unsigned int n)
 	return RTE_DIM(dynf_names);
 }
 
-/**
- * Check sibling device configurations.
- *
- * Sibling devices sharing the Infiniband device context should have compatible
- * configurations. This regards representors and bonding device.
- *
- * @param sh
- *   Shared device context.
- * @param config
- *   Configuration of the device is going to be created.
- * @param dpdk_dev
- *   Backing DPDK device.
- *
- * @return
- *   0 on success, EINVAL otherwise
- */
-int
-mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
-			      struct mlx5_dev_config *config,
-			      struct rte_device *dpdk_dev)
-{
-	struct mlx5_dev_config *sh_conf = NULL;
-	uint16_t port_id;
-
-	MLX5_ASSERT(sh);
-	/* Nothing to compare for the single/first device. */
-	if (sh->refcnt == 1)
-		return 0;
-	/* Find the device with shared context. */
-	MLX5_ETH_FOREACH_DEV(port_id, dpdk_dev) {
-		struct mlx5_priv *opriv =
-			rte_eth_devices[port_id].data->dev_private;
-
-		if (opriv && opriv->sh == sh) {
-			sh_conf = &opriv->config;
-			break;
-		}
-	}
-	if (!sh_conf)
-		return 0;
-	if (sh_conf->dv_flow_en ^ config->dv_flow_en) {
-		DRV_LOG(ERR, "\"dv_flow_en\" configuration mismatch"
-			     " for shared %s context", sh->ibdev_name);
-		rte_errno = EINVAL;
-		return rte_errno;
-	}
-	if (sh_conf->dv_xmeta_en ^ config->dv_xmeta_en) {
-		DRV_LOG(ERR, "\"dv_xmeta_en\" configuration mismatch"
-			     " for shared %s context", sh->ibdev_name);
-		rte_errno = EINVAL;
-		return rte_errno;
-	}
-	return 0;
-}
-
 /**
  * Look for the ethernet device belonging to mlx5 driver.
  *
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index bda09cf96e..5ca48ef68f 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -252,23 +252,10 @@ struct mlx5_stats_ctrl {
  */
 struct mlx5_dev_config {
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
-	unsigned int hw_fcs_strip:1; /* FCS stripping is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
 	unsigned int cqe_comp_fmt:3; /* CQE compression format. */
 	unsigned int rx_vec_en:1; /* Rx vector is enabled. */
-	unsigned int l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
-	unsigned int vf_nl_en:1; /* Enable Netlink requests in VF mode. */
-	unsigned int dv_esw_en:1; /* Enable E-Switch DV flow. */
-	unsigned int dv_flow_en:1; /* Enable DV flow. */
-	unsigned int dv_xmeta_en:2; /* Enable extensive flow metadata. */
-	unsigned int lacp_by_user:1;
-	/* Enable user to manage LACP traffic. */
-	unsigned int reclaim_mode:2; /* Memory reclaim mode. */
-	unsigned int decap_en:1; /* Whether decap will be used or not. */
-	unsigned int dv_miss_info:1; /* restore packet after partial hw miss */
-	unsigned int allow_duplicate_pattern:1;
-	/* Allow/Prevent the duplicate rules pattern. */
 	unsigned int std_delay_drop:1; /* Enable standard Rxq delay drop. */
 	unsigned int hp_delay_drop:1; /* Enable hairpin Rxq delay drop. */
 	struct {
@@ -288,8 +275,29 @@ struct mlx5_dev_config {
 	int txq_inline_min; /* Minimal amount of data bytes to inline. */
 	int txq_inline_max; /* Max packet size for inlining with SEND. */
 	int txq_inline_mpw; /* Max packet size for inlining with eMPW. */
+};
+
+/*
+ * Share context device configuration structure.
+ * User device parameters disabled features.
+ * This structure updated once for device in mlx5_alloc_shared_dev_ctx()
+ * function and cannot change even when probing again.
+ */
+struct mlx5_sh_config {
 	int tx_pp; /* Timestamp scheduling granularity in nanoseconds. */
 	int tx_skew; /* Tx scheduling skew between WQE and data on wire. */
+	uint32_t reclaim_mode:2; /* Memory reclaim mode. */
+	uint32_t dv_esw_en:1; /* Enable E-Switch DV flow. */
+	uint32_t dv_flow_en:1; /* Enable DV flow. */
+	uint32_t dv_xmeta_en:2; /* Enable extensive flow metadata. */
+	uint32_t dv_miss_info:1; /* Restore packet after partial hw miss. */
+	uint32_t l3_vxlan_en:1; /* Enable L3 VXLAN flow creation. */
+	uint32_t vf_nl_en:1; /* Enable Netlink requests in VF mode. */
+	uint32_t lacp_by_user:1; /* Enable user to manage LACP traffic. */
+	uint32_t decap_en:1; /* Whether decap will be used or not. */
+	uint32_t hw_fcs_strip:1; /* FCS stripping is supported. */
+	uint32_t allow_duplicate_pattern:1;
+	/* Allow/Prevent the duplicate rules pattern. */
 };
 
 
@@ -1144,7 +1152,6 @@ struct mlx5_dev_ctx_shared {
 	uint32_t ct_aso_en:1; /* Connection Tracking ASO is supported. */
 	uint32_t tunnel_header_0_1:1; /* tunnel_header_0_1 is supported. */
 	uint32_t misc5_cap:1; /* misc5 matcher parameter is supported. */
-	uint32_t reclaim_mode:1; /* Reclaim memory. */
 	uint32_t dr_drop_action_en:1; /* Use DR drop action. */
 	uint32_t drop_action_check_flag:1; /* Check Flag for drop action. */
 	uint32_t flow_priority_check_flag:1; /* Check Flag for flow priority. */
@@ -1156,6 +1163,7 @@ struct mlx5_dev_ctx_shared {
 	char ibdev_name[MLX5_FS_NAME_MAX]; /* SYSFS dev name. */
 	char ibdev_path[MLX5_FS_PATH_MAX]; /* SYSFS dev path for secondary */
 	struct mlx5_dev_cap dev_cap; /* Device capabilities. */
+	struct mlx5_sh_config config; /* Device configuration. */
 	int numa_node; /* Numa node of backing physical device. */
 	/* Packet pacing related structure. */
 	struct mlx5_dev_txpp txpp;
@@ -1511,8 +1519,7 @@ int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
-			   const struct mlx5_dev_config *config);
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn);
 void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
@@ -1520,9 +1527,7 @@ int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			 struct mlx5_dev_config *config);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_dev_check_sibling_config(struct mlx5_dev_ctx_shared *sh,
-				  struct mlx5_dev_config *config,
-				  struct rte_device *dpdk_dev);
+int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index b7fe781d3a..9e478db8df 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -720,10 +720,9 @@ int
 mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 
 	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
-	    !config->dv_flow_en) {
+	    !priv->sh->config.dv_flow_en) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 4889fc8ae6..5b5b00cc3e 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -901,7 +901,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 		     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	enum modify_reg start_reg;
 	bool skip_mtr_reg = false;
 
@@ -1994,7 +1994,7 @@ mlx5_flow_validate_attributes(struct rte_eth_dev *dev,
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, NULL,
 					  "egress is not supported");
-	if (attributes->transfer && !priv->config.dv_esw_en)
+	if (attributes->transfer && !priv->sh->config.dv_esw_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
 					  NULL, "transfer is not supported");
@@ -2711,7 +2711,7 @@ mlx5_flow_validate_item_vxlan_gpe(const struct rte_flow_item *item,
 		uint8_t vni[4];
 	} id = { .vlan_id = 0, };
 
-	if (!priv->config.l3_vxlan_en)
+	if (!priv->sh->config.l3_vxlan_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "L3 VXLAN is not enabled by device"
@@ -3429,11 +3429,11 @@ flow_get_drv_type(struct rte_eth_dev *dev, const struct rte_flow_attr *attr)
 	if (type != MLX5_FLOW_TYPE_MAX)
 		return type;
 	/* If no OS specific type - continue with DV/VERBS selection */
-	if (attr->transfer && priv->config.dv_esw_en)
+	if (attr->transfer && priv->sh->config.dv_esw_en)
 		type = MLX5_FLOW_TYPE_DV;
 	if (!attr->transfer)
-		type = priv->config.dv_flow_en ? MLX5_FLOW_TYPE_DV :
-						 MLX5_FLOW_TYPE_VERBS;
+		type = priv->sh->config.dv_flow_en ? MLX5_FLOW_TYPE_DV :
+						     MLX5_FLOW_TYPE_VERBS;
 	return type;
 }
 
@@ -4105,7 +4105,7 @@ static bool flow_check_modify_action_type(struct rte_eth_dev *dev,
 		return true;
 	case RTE_FLOW_ACTION_TYPE_FLAG:
 	case RTE_FLOW_ACTION_TYPE_MARK:
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY)
+		if (priv->sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY)
 			return true;
 		else
 			return false;
@@ -4544,8 +4544,8 @@ flow_mreg_add_default_copy_action(struct rte_eth_dev *dev,
 	uint32_t mark_id;
 
 	/* Check whether extensive metadata feature is engaged. */
-	if (!priv->config.dv_flow_en ||
-	    priv->config.dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
+	if (!priv->sh->config.dv_flow_en ||
+	    priv->sh->config.dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
 	    !mlx5_flow_ext_mreg_supported(dev) ||
 	    !priv->sh->dv_regc0_mask)
 		return 0;
@@ -4604,7 +4604,7 @@ flow_mreg_update_copy_table(struct rte_eth_dev *dev,
 			    struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	struct mlx5_flow_mreg_copy_resource *mcp_res;
 	const struct rte_flow_action_mark *mark;
 
@@ -5740,7 +5740,7 @@ flow_create_split_metadata(struct rte_eth_dev *dev,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action *qrss = NULL;
 	struct rte_flow_action *ext_actions = NULL;
 	struct mlx5_flow *dev_flow = NULL;
@@ -8248,7 +8248,7 @@ mlx5_flow_discover_mreg_c(struct rte_eth_dev *dev)
 		struct rte_flow *flow;
 		struct rte_flow_error error;
 
-		if (!priv->config.dv_flow_en)
+		if (!priv->sh->config.dv_flow_en)
 			break;
 		/* Create internal flow, validation skips copy action. */
 		flow_idx = flow_list_create(dev, MLX5_FLOW_TYPE_GEN, &attr,
@@ -8562,7 +8562,7 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx,
 	struct mlx5_flow_handle *dh;
 	struct rte_flow *flow;
 
-	if (!priv->config.dv_flow_en) {
+	if (!sh->config.dv_flow_en) {
 		if (fputs("device dv flow disabled\n", file) <= 0)
 			return -errno;
 		return -ENOTSUP;
@@ -9546,7 +9546,7 @@ mlx5_flow_tunnel_validate(struct rte_eth_dev *dev,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->config.dv_flow_en)
+	if (!priv->sh->config.dv_flow_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF, NULL,
 					  "flow DV interface is off");
@@ -9965,7 +9965,7 @@ mlx5_flow_discover_priorities(struct rte_eth_dev *dev)
 	type = mlx5_flow_os_get_type();
 	if (type == MLX5_FLOW_TYPE_MAX) {
 		type = MLX5_FLOW_TYPE_VERBS;
-		if (priv->sh->cdev->config.devx && priv->config.dv_flow_en)
+		if (priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en)
 			type = MLX5_FLOW_TYPE_DV;
 	}
 	fops = flow_get_drv_ops(type);
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 7fec79afb3..583e8b7321 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -963,7 +963,7 @@ is_tunnel_offload_active(const struct rte_eth_dev *dev)
 {
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
 	const struct mlx5_priv *priv = dev->data->dev_private;
-	return !!priv->config.dv_miss_info;
+	return !!priv->sh->config.dv_miss_info;
 #else
 	RTE_SET_USED(dev);
 	return false;
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 6a5ac01c2a..c30cb4c203 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1146,7 +1146,8 @@ flow_dv_convert_action_copy_mreg(struct rte_eth_dev *dev,
 		uint32_t reg_c0 = priv->sh->dv_regc0_mask;
 
 		MLX5_ASSERT(reg_c0);
-		MLX5_ASSERT(priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY);
+		MLX5_ASSERT(priv->sh->config.dv_xmeta_en !=
+			    MLX5_XMETA_MODE_LEGACY);
 		if (conf->dst == REG_C_0) {
 			/* Copy to reg_c[0], within mask only. */
 			reg_dst.offset = rte_bsf32(reg_c0);
@@ -1917,7 +1918,7 @@ flow_dv_validate_item_mark(struct rte_eth_dev *dev,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_item_mark *spec = item->spec;
 	const struct rte_flow_item_mark *mask = item->mask;
 	const struct rte_flow_item_mark nic_mask = {
@@ -1991,7 +1992,7 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused,
 			   struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_item_meta *spec = item->spec;
 	const struct rte_flow_item_meta *mask = item->mask;
 	struct rte_flow_item_meta nic_mask = {
@@ -3041,7 +3042,7 @@ flow_dv_validate_action_flag(struct rte_eth_dev *dev,
 			     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	int ret;
 
 	/* Fall back if no extended metadata register support. */
@@ -3100,7 +3101,7 @@ flow_dv_validate_action_mark(struct rte_eth_dev *dev,
 			     struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_mark *mark = action->conf;
 	int ret;
 
@@ -3174,7 +3175,7 @@ flow_dv_validate_action_set_meta(struct rte_eth_dev *dev,
 				 struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_set_meta *conf;
 	uint32_t nic_mask = UINT32_MAX;
 	int reg;
@@ -3386,7 +3387,7 @@ flow_dv_validate_action_decap(struct rte_eth_dev *dev,
 	const struct mlx5_priv *priv = dev->data->dev_private;
 
 	if (priv->sh->cdev->config.hca_attr.scatter_fcs_w_decap_disable &&
-	    !priv->config.decap_en)
+	    !priv->sh->config.decap_en)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "decap is not enabled");
@@ -4811,7 +4812,7 @@ flow_dv_validate_action_modify_field(struct rte_eth_dev *dev,
 {
 	int ret = 0;
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_sh_config *config = &priv->sh->config;
 	const struct rte_flow_action_modify_field *action_modify_field =
 		action->conf;
 	uint32_t dst_width = mlx5_flow_item_field_width(dev,
@@ -5423,8 +5424,9 @@ flow_dv_modify_ipool_get(struct mlx5_dev_ctx_shared *sh, uint8_t index)
 		       .grow_trunk = 3,
 		       .grow_shift = 2,
 		       .need_lock = 1,
-		       .release_mem_en = !!sh->reclaim_mode,
-		       .per_core_cache = sh->reclaim_mode ? 0 : (1 << 16),
+		       .release_mem_en = !!sh->config.reclaim_mode,
+		       .per_core_cache =
+				       sh->config.reclaim_mode ? 0 : (1 << 16),
 		       .malloc = mlx5_malloc,
 		       .free = mlx5_free,
 		       .type = "mlx5_modify_action_resource",
@@ -5571,7 +5573,7 @@ flow_dv_validate_action_sample(uint64_t *action_flags,
 			       struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	const struct rte_flow_action_sample *sample = action->conf;
 	const struct rte_flow_action *act;
 	uint64_t sub_action_flags = 0;
@@ -6595,7 +6597,7 @@ flow_dv_validate_attributes(struct rte_eth_dev *dev,
 					  NULL,
 					  "priority out of range");
 	if (attributes->transfer) {
-		if (!priv->config.dv_esw_en)
+		if (!priv->sh->config.dv_esw_en)
 			return rte_flow_error_set
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
@@ -6880,7 +6882,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 		},
 	};
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	uint16_t queue_index = 0xFFFF;
 	const struct rte_flow_item_vlan *vlan_m = NULL;
 	uint32_t rw_act_num = 0;
@@ -6904,7 +6906,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 	tunnel = is_tunnel_offload_active(dev) ?
 		 mlx5_get_tof(items, actions, &tof_rule_type) : NULL;
 	if (tunnel) {
-		if (!priv->config.dv_flow_en)
+		if (!dev_conf->dv_flow_en)
 			return rte_flow_error_set
 				(error, ENOTSUP,
 				 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -12640,7 +12642,7 @@ flow_dv_translate(struct rte_eth_dev *dev,
 		  struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	struct rte_flow *flow = dev_flow->flow;
 	struct mlx5_flow_handle *handle = dev_flow->handle;
 	struct mlx5_flow_workspace *wks = mlx5_flow_get_thread_workspace();
@@ -13994,7 +13996,7 @@ flow_dv_apply(struct rte_eth_dev *dev, struct rte_flow *flow,
 				(error, errno,
 				RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				NULL,
-				(!priv->config.allow_duplicate_pattern &&
+				(!priv->sh->config.allow_duplicate_pattern &&
 				errno == EEXIST) ?
 				"duplicating pattern is not allowed" :
 				"hardware refuses to create flow");
@@ -16064,7 +16066,7 @@ flow_dv_destroy_mtr_tbls(struct rte_eth_dev *dev,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	int i;
 
-	if (!fm || !priv->config.dv_flow_en)
+	if (!fm || !priv->sh->config.dv_flow_en)
 		return;
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
 		if (fm->drop_rule[i]) {
@@ -16670,7 +16672,8 @@ flow_dv_create_def_policy(struct rte_eth_dev *dev)
 
 	/* Non-termination policy table. */
 	for (i = 0; i < MLX5_MTR_DOMAIN_MAX; i++) {
-		if (!priv->config.dv_esw_en && i == MLX5_MTR_DOMAIN_TRANSFER)
+		if (!priv->sh->config.dv_esw_en &&
+		    i == MLX5_MTR_DOMAIN_TRANSFER)
 			continue;
 		if (__flow_dv_create_domain_def_policy(dev, i)) {
 			DRV_LOG(ERR, "Failed to create default policy");
@@ -17781,7 +17784,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 			struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *dev_conf = &priv->config;
+	struct mlx5_sh_config *dev_conf = &priv->sh->config;
 	const struct rte_flow_action *act;
 	uint64_t action_flags[RTE_COLORS] = {0};
 	int actions_n;
@@ -17795,7 +17798,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 	bool def_yellow = false;
 	const struct rte_flow_action_rss *rss_color[RTE_COLORS] = {NULL};
 
-	if (!priv->config.dv_esw_en)
+	if (!dev_conf->dv_esw_en)
 		def_domain &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
 	*domain_bitmap = def_domain;
 	/* Red color could only support DROP action. */
@@ -17839,7 +17842,7 @@ flow_dv_validate_mtr_policy_acts(struct rte_eth_dev *dev,
 			switch (act->type) {
 			case RTE_FLOW_ACTION_TYPE_PORT_ID:
 			case RTE_FLOW_ACTION_TYPE_REPRESENTED_PORT:
-				if (!priv->config.dv_esw_en)
+				if (!dev_conf->dv_esw_en)
 					return -rte_mtr_error_set(error,
 					ENOTSUP,
 					RTE_MTR_ERROR_TYPE_METER_POLICY,
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 2310ea6a86..3b3f3cb7fd 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -658,8 +658,8 @@ mlx5_flow_meter_policy_validate(struct rte_eth_dev *dev,
 	struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct rte_flow_attr attr = { .transfer =
-			priv->config.dv_esw_en ? 1 : 0};
+	struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ?
+						  1 : 0 };
 	bool is_rss = false;
 	uint8_t policy_mode;
 	uint8_t domain_bitmap;
@@ -746,8 +746,8 @@ mlx5_flow_meter_policy_add(struct rte_eth_dev *dev,
 			struct rte_mtr_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct rte_flow_attr attr = { .transfer =
-			priv->config.dv_esw_en ? 1 : 0};
+	struct rte_flow_attr attr = { .transfer = priv->sh->config.dv_esw_en ?
+						  1 : 0 };
 	uint32_t sub_policy_idx = 0;
 	uint32_t policy_idx = 0;
 	struct mlx5_flow_meter_policy *mtr_policy = NULL;
@@ -1213,7 +1213,7 @@ mlx5_flow_meter_create(struct rte_eth_dev *dev, uint32_t meter_id,
 			(&priv->sh->mtrmng->def_policy_ref_cnt,
 			1, __ATOMIC_RELAXED);
 		domain_bitmap = MLX5_MTR_ALL_DOMAIN_BIT;
-		if (!priv->config.dv_esw_en)
+		if (!priv->sh->config.dv_esw_en)
 			domain_bitmap &= ~MLX5_MTR_DOMAIN_TRANSFER_BIT;
 	} else {
 		if (!priv->sh->meter_aso_en)
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index bcb04018f8..1d1f2556de 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -359,14 +359,13 @@ uint64_t
 mlx5_get_rx_queue_offloads(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	uint64_t offloads = (RTE_ETH_RX_OFFLOAD_SCATTER |
 			     RTE_ETH_RX_OFFLOAD_TIMESTAMP |
 			     RTE_ETH_RX_OFFLOAD_RSS_HASH);
 
-	if (!config->mprq.enabled)
+	if (!priv->config.mprq.enabled)
 		offloads |= RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT;
-	if (config->hw_fcs_strip)
+	if (priv->sh->config.hw_fcs_strip)
 		offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
 	if (priv->sh->dev_cap.hw_csum)
 		offloads |= (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM |
@@ -1896,7 +1895,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
 	tmpl->rxq.crc_present = 0;
 	tmpl->rxq.lro = lro_on_queue;
 	if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) {
-		if (config->hw_fcs_strip) {
+		if (priv->sh->config.hw_fcs_strip) {
 			/*
 			 * RQs used for LRO-enabled TIRs should not be
 			 * configured to scatter the FCS.
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 11ae0d9480..a67a6af728 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,7 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->cdev->config.devx && priv->config.dv_flow_en &&
+	if ((priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en &&
 	     priv->sh->dev_cap.dest_tir) &&
 	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
@@ -1277,8 +1277,6 @@ mlx5_dev_stop(struct rte_eth_dev *dev)
  * Enable traffic flows configured by control plane
  *
  * @param dev
- *   Pointer to Ethernet device private data.
- * @param dev
  *   Pointer to Ethernet device structure.
  *
  * @return
@@ -1331,7 +1329,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				goto error;
 			}
 		}
-		if (priv->config.dv_esw_en) {
+		if (priv->sh->config.dv_esw_en) {
 			if (mlx5_flow_create_devx_sq_miss_flow(dev, i) == 0) {
 				DRV_LOG(ERR,
 					"Port %u Tx queue %u SQ create representor devx default miss rule failed.",
@@ -1341,7 +1339,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 		}
 		mlx5_txq_release(dev, i);
 	}
-	if (priv->config.dv_esw_en) {
+	if (priv->sh->config.dv_esw_en) {
 		if (mlx5_flow_create_esw_table_zero_flow(dev))
 			priv->fdb_def_rule = 1;
 		else
@@ -1349,7 +1347,7 @@ mlx5_traffic_enable(struct rte_eth_dev *dev)
 				" configured - only Eswitch group 0 flows are"
 				" supported.", dev->data->port_id);
 	}
-	if (!priv->config.lacp_by_user && priv->pf_bond >= 0) {
+	if (!priv->sh->config.lacp_by_user && priv->pf_bond >= 0) {
 		ret = mlx5_flow_lacp_miss(dev);
 		if (ret)
 			DRV_LOG(INFO, "port %u LACP rule cannot be created - "
diff --git a/drivers/net/mlx5/mlx5_txpp.c b/drivers/net/mlx5/mlx5_txpp.c
index 1d16ebcb41..fe74317fe8 100644
--- a/drivers/net/mlx5/mlx5_txpp.c
+++ b/drivers/net/mlx5/mlx5_txpp.c
@@ -816,15 +816,15 @@ mlx5_txpp_start_service(struct mlx5_dev_ctx_shared *sh)
  * Returns 0 on success, negative otherwise
  */
 static int
-mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh, struct mlx5_priv *priv)
+mlx5_txpp_create(struct mlx5_dev_ctx_shared *sh)
 {
-	int tx_pp = priv->config.tx_pp;
+	int tx_pp = sh->config.tx_pp;
 	int ret;
 
 	/* Store the requested pacing parameters. */
 	sh->txpp.tick = tx_pp >= 0 ? tx_pp : -tx_pp;
 	sh->txpp.test = !!(tx_pp < 0);
-	sh->txpp.skew = priv->config.tx_skew;
+	sh->txpp.skew = sh->config.tx_skew;
 	sh->txpp.freq = sh->cdev->config.hca_attr.dev_freq_khz;
 	ret = mlx5_txpp_create_event_channel(sh);
 	if (ret)
@@ -891,7 +891,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	int err = 0;
 
-	if (!priv->config.tx_pp) {
+	if (!sh->config.tx_pp) {
 		/* Packet pacing is not requested for the device. */
 		MLX5_ASSERT(priv->txpp_en == 0);
 		return 0;
@@ -901,7 +901,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 		MLX5_ASSERT(sh->txpp.refcnt);
 		return 0;
 	}
-	if (priv->config.tx_pp > 0) {
+	if (sh->config.tx_pp > 0) {
 		err = rte_mbuf_dynflag_lookup
 			(RTE_MBUF_DYNFLAG_TX_TIMESTAMP_NAME, NULL);
 		/* No flag registered means no service needed. */
@@ -914,7 +914,7 @@ mlx5_txpp_start(struct rte_eth_dev *dev)
 		priv->txpp_en = 1;
 		++sh->txpp.refcnt;
 	} else {
-		err = mlx5_txpp_create(sh, priv);
+		err = mlx5_txpp_create(sh);
 		if (!err) {
 			MLX5_ASSERT(sh->txpp.tick);
 			priv->txpp_en = 1;
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 47bca9e3ea..3373ee66b4 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -109,7 +109,7 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 			     RTE_ETH_TX_OFFLOAD_TCP_CKSUM);
 	if (dev_cap->tso)
 		offloads |= RTE_ETH_TX_OFFLOAD_TCP_TSO;
-	if (config->tx_pp)
+	if (priv->sh->config.tx_pp)
 		offloads |= RTE_ETH_TX_OFFLOAD_SEND_ON_TIMESTAMP;
 	if (dev_cap->swp) {
 		if (dev_cap->swp & MLX5_SW_PARSING_CSUM_CAP)
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index b7542da69d..9e6a46ad3a 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -325,27 +325,18 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			strerror(rte_errno));
 		goto error;
 	}
-	sh = mlx5_alloc_shared_dev_ctx(spawn, config);
+	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
-	/* Update final values for devargs before check sibling config. */
-	config->dv_esw_en = 0;
-	if (!config->dv_flow_en) {
+	if (!sh->config.dv_flow_en) {
 		DRV_LOG(ERR, "Windows flow mode must be DV flow enable.");
 		err = ENOTSUP;
 		goto error;
 	}
-	if (!config->dv_esw_en &&
-	    config->dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
-		DRV_LOG(WARNING,
-			"Metadata mode %u is not supported (no E-Switch).",
-			config->dv_xmeta_en);
-		config->dv_xmeta_en = MLX5_XMETA_MODE_LEGACY;
+	if (sh->config.vf_nl_en) {
+		DRV_LOG(DEBUG, "VF netlink isn't supported.");
+		sh->config.vf_nl_en = 0;
 	}
-	/* Check sibling device configurations. */
-	err = mlx5_dev_check_sibling_config(sh, config, dpdk_dev);
-	if (err)
-		goto error;
 	/* Initialize the shutdown event in mlx5_dev_spawn to
 	 * support mlx5_is_removed for Windows.
 	 */
@@ -417,7 +408,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
 		config->cqe_comp = 0;
 	}
-	config->hw_fcs_strip = sh->dev_cap.hw_fcs_strip;
 	if (config->mprq.enabled) {
 		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
 		config->mprq.enabled = 0;
@@ -523,8 +513,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* Store device configuration on private structure. */
 	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
-		icfg[i].release_mem_en = !!config->reclaim_mode;
-		if (config->reclaim_mode)
+		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
+		if (sh->config.reclaim_mode)
 			icfg[i].per_core_cache = 0;
 		priv->flows[i] = mlx5_ipool_create(&icfg[i]);
 		if (!priv->flows[i])
@@ -532,7 +522,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	}
 	/* Create context for virtual machine VLAN workaround. */
 	priv->vmwa_context = NULL;
-	if (config->dv_flow_en) {
+	if (sh->config.dv_flow_en) {
 		err = mlx5_alloc_shared_dr(priv);
 		if (err)
 			goto error;
@@ -540,11 +530,11 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	/* No supported flow priority number detection. */
 	priv->sh->flow_max_priority = -1;
 	mlx5_set_metadata_mask(eth_dev);
-	if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
+	if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY &&
 	    !priv->sh->dv_regc0_mask) {
 		DRV_LOG(ERR, "metadata mode %u is not supported "
 			     "(no metadata reg_c[0] is available).",
-			     priv->config.dv_xmeta_en);
+			     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 	}
@@ -564,10 +554,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG,
 			"port %u extensive metadata register is not supported.",
 			eth_dev->data->port_id);
-		if (priv->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
+		if (sh->config.dv_xmeta_en != MLX5_XMETA_MODE_LEGACY) {
 			DRV_LOG(ERR, "metadata mode %u is not supported "
 				     "(no metadata registers available).",
-				     priv->config.dv_xmeta_en);
+				     sh->config.dv_xmeta_en);
 			err = ENOTSUP;
 			goto error;
 		}
@@ -837,7 +827,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN,
 			.min_rxqs_num = MLX5_MPRQ_MIN_RXQS,
 		},
-		.dv_flow_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
 	};
 	int ret;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 17/20] net/mlx5: using function to detect operation by DevX
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (15 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 16/20] net/mlx5: add share device context config structure Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 18/20] net/mlx5: separate per port configuration Michael Baum
                     ` (3 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add inline function indicating whether HW objects operations can be
created by DevX. It makes the code more readable.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c |  6 ++----
 drivers/net/mlx5/mlx5.h          | 24 ++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_ethdev.c   |  3 +--
 drivers/net/mlx5/mlx5_trigger.c  |  3 +--
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 7ee76d54bd..c1eda00899 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -370,8 +370,7 @@ mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh)
 	sh->dev_cap.txpp_en = 0;
 #endif
 	/* Check for LRO support. */
-	if (sh->dev_cap.dest_tir && sh->dev_cap.dv_flow_en &&
-	    hca_attr->lro_cap) {
+	if (mlx5_devx_obj_ops_en(sh) && hca_attr->lro_cap) {
 		/* TBD check tunnel lro caps. */
 		sh->dev_cap.lro_supported = 1;
 		DRV_LOG(DEBUG, "Device supports LRO.");
@@ -1550,8 +1549,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		if (mlx5_flex_item_port_init(eth_dev) < 0)
 			goto error;
 	}
-	if (sh->cdev->config.devx && sh->config.dv_flow_en &&
-	    sh->dev_cap.dest_tir) {
+	if (mlx5_devx_obj_ops_en(sh)) {
 		priv->obj_ops = devx_obj_ops;
 		mlx5_queue_counter_id_prepare(eth_dev);
 		priv->obj_ops.lb_dummy_queue_create =
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 5ca48ef68f..46fa5131a7 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1496,6 +1496,30 @@ enum dr_dump_rec_type {
 	DR_DUMP_REC_TYPE_PMD_COUNTER = 4430,
 };
 
+/**
+ * Indicates whether HW objects operations can be created by DevX.
+ *
+ * This function is used for both:
+ *  Before creation - deciding whether to create HW objects operations by DevX.
+ *  After creation - indicator if HW objects operations were created by DevX.
+ *
+ * @param sh
+ *   Pointer to shared device context.
+ *
+ * @return
+ *   True if HW objects were created by DevX, False otherwise.
+ */
+static inline bool
+mlx5_devx_obj_ops_en(struct mlx5_dev_ctx_shared *sh)
+{
+	/*
+	 * When advanced DR API is available and DV flow is supported and
+	 * DevX is supported, HW objects operations are created by DevX.
+	 */
+	return (sh->cdev->config.devx && sh->config.dv_flow_en &&
+		sh->dev_cap.dest_tir);
+}
+
 /* mlx5.c */
 
 int mlx5_getenv_int(const char *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 9e478db8df..d637dee98d 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -721,8 +721,7 @@ mlx5_hairpin_cap_get(struct rte_eth_dev *dev, struct rte_eth_hairpin_cap *cap)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 
-	if (!priv->sh->cdev->config.devx || !priv->sh->dev_cap.dest_tir ||
-	    !priv->sh->config.dv_flow_en) {
+	if (!mlx5_devx_obj_ops_en(priv->sh)) {
 		rte_errno = ENOTSUP;
 		return -rte_errno;
 	}
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index a67a6af728..74c3bc8a13 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1104,8 +1104,7 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, strerror(rte_errno));
 		goto error;
 	}
-	if ((priv->sh->cdev->config.devx && priv->sh->config.dv_flow_en &&
-	     priv->sh->dev_cap.dest_tir) &&
+	if (mlx5_devx_obj_ops_en(priv->sh) &&
 	    priv->obj_ops.lb_dummy_queue_create) {
 		ret = priv->obj_ops.lb_dummy_queue_create(dev);
 		if (ret)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 18/20] net/mlx5: separate per port configuration
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (16 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
                     ` (2 subsequent siblings)
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Add configuration structure for port (ethdev). This structure contains
all configurations coming from devargs which oriented to port. It is a
field of mlx5_priv structure, and is updated in spawn function for each
port.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/net/mlx5/linux/mlx5_os.c   | 121 ++------------------
 drivers/net/mlx5/mlx5.c            | 178 ++++++++++++++++++++++++-----
 drivers/net/mlx5/mlx5.h            |  21 ++--
 drivers/net/mlx5/mlx5_devx.c       |   3 +-
 drivers/net/mlx5/mlx5_ethdev.c     |   7 +-
 drivers/net/mlx5/mlx5_rxq.c        |   4 +-
 drivers/net/mlx5/mlx5_tx.c         |   2 +-
 drivers/net/mlx5/mlx5_txq.c        |   6 +-
 drivers/net/mlx5/windows/mlx5_os.c |  55 ++-------
 9 files changed, 188 insertions(+), 209 deletions(-)

diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index c1eda00899..fa1af06f7d 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -999,8 +999,6 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
  * @param eth_da
  *   Device arguments.
  *
@@ -1014,12 +1012,10 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	       struct mlx5_dev_spawn_data *spawn,
-	       struct mlx5_dev_config *config,
 	       struct rte_eth_devargs *eth_da)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
-	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
 	struct ibv_port_attr port_attr = { .state = IBV_PORT_NOP };
 	struct rte_eth_dev *eth_dev = NULL;
 	struct mlx5_priv *priv = NULL;
@@ -1029,7 +1025,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	int own_domain_id = 0;
 	uint16_t port_id;
 	struct mlx5_port_info vport_info = { .query_flags = 0 };
-	int nl_rdma = -1;
+	int nl_rdma;
 	int i;
 
 	/* Determine if this port representor is supposed to be spawned. */
@@ -1107,13 +1103,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		mlx5_dev_close(eth_dev);
 		return NULL;
 	}
-	/* Process parameters. */
-	err = mlx5_args(config, dpdk_dev->devargs);
-	if (err) {
-		DRV_LOG(ERR, "failed to process device arguments: %s",
-			strerror(rte_errno));
-		return NULL;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
@@ -1269,41 +1258,10 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		DRV_LOG(DEBUG, "dev_port-%u new domain_id=%u\n",
 			priv->dev_port, priv->domain_id);
 	}
-	if (config->hw_padding && !sh->dev_cap.hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
-		config->hw_padding = 0;
-	} else if (config->hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding is enabled");
-	}
-	/*
-	 * MPW is disabled by default, while the Enhanced MPW is enabled
-	 * by default.
-	 */
-	if (config->mps == MLX5_ARG_UNSET)
-		config->mps = (sh->dev_cap.mps == MLX5_MPW_ENHANCED) ?
-			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
-	else
-		config->mps = config->mps ? sh->dev_cap.mps : MLX5_MPW_DISABLED;
-	DRV_LOG(INFO, "%sMPS is %s",
-		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
-		config->mps == MLX5_MPW ? "legacy " : "",
-		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
 	if (sh->cdev->config.devx) {
+		struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
+
 		sh->steering_format_version = hca_attr->steering_format_version;
-		/* LRO is supported only when DV flow enabled. */
-		if (sh->dev_cap.lro_supported && sh->config.dv_flow_en)
-			sh->dev_cap.lro_supported = 0;
-		if (sh->dev_cap.lro_supported) {
-			/*
-			 * If LRO timeout is not configured by application,
-			 * use the minimal supported value.
-			 */
-			if (!config->lro_timeout)
-				config->lro_timeout =
-				       hca_attr->lro_timer_supported_periods[0];
-			DRV_LOG(DEBUG, "LRO session timeout set to %d usec",
-				config->lro_timeout);
-		}
 #if defined(HAVE_MLX5DV_DR) && \
 	(defined(HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER) || \
 	 defined(HAVE_MLX5_DR_CREATE_ACTION_ASO))
@@ -1395,39 +1353,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 #endif
 	}
-	if (config->cqe_comp && !sh->dev_cap.cqe_comp) {
-		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
-	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_flow_tag)) {
-		DRV_LOG(WARNING, "Flow Tag CQE compression"
-				 " format isn't supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
-	    (!sh->cdev->config.devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
-		DRV_LOG(WARNING, "L3/L4 Header CQE compression"
-				 " format isn't supported.");
-		config->cqe_comp = 0;
-	}
-	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported",
-			config->cqe_comp ? "" : "not ");
-	if (config->std_delay_drop || config->hp_delay_drop) {
-		if (!hca_attr->rq_delay_drop) {
-			config->std_delay_drop = 0;
-			config->hp_delay_drop = 0;
-			DRV_LOG(WARNING,
-				"dev_port-%u: Rxq delay drop is not supported",
-				priv->dev_port);
-		}
-	}
-	if (config->mprq.enabled && !sh->dev_cap.mprq.enabled) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
-		config->mprq.enabled = 0;
+	/* Process parameters and store port configuration on priv structure. */
+	err = mlx5_port_args_config(priv, dpdk_dev->devargs, &priv->config);
+	if (err) {
+		err = rte_errno;
+		DRV_LOG(ERR, "Failed to process port configure: %s",
+			strerror(rte_errno));
+		goto error;
 	}
-	if (config->max_dump_files_num == 0)
-		config->max_dump_files_num = 128;
 	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL) {
 		DRV_LOG(ERR, "can not allocate rte ethdev");
@@ -1528,10 +1461,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	/* Detect minimal data bytes to inline. */
-	mlx5_set_min_inline(spawn, config);
-	/* Store device configuration on private structure. */
-	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
 		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
 		if (sh->config.reclaim_mode)
@@ -1899,25 +1828,6 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 	return pf;
 }
 
-static void
-mlx5_os_config_default(struct mlx5_dev_config *config)
-{
-	memset(config, 0, sizeof(*config));
-	config->mps = MLX5_ARG_UNSET;
-	config->cqe_comp = 1;
-	config->rx_vec_en = 1;
-	config->txq_inline_max = MLX5_ARG_UNSET;
-	config->txq_inline_min = MLX5_ARG_UNSET;
-	config->txq_inline_mpw = MLX5_ARG_UNSET;
-	config->txqs_inline = MLX5_ARG_UNSET;
-	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
-	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
-	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
-	config->log_hp_size = MLX5_ARG_UNSET;
-	config->std_delay_drop = 0;
-	config->hp_delay_drop = 0;
-}
-
 /**
  * Register a PCI device within bonding.
  *
@@ -1966,7 +1876,6 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	int bd = -1;
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data *list = NULL;
-	struct mlx5_dev_config dev_config;
 	struct rte_eth_devargs eth_da = *req_eth_da;
 	struct rte_pci_addr owner_pci = pci_dev->addr; /* Owner PF. */
 	struct mlx5_bond_info bond_info;
@@ -2308,10 +2217,7 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	for (i = 0; i != ns; ++i) {
 		uint32_t restore;
 
-		/* Default configuration. */
-		mlx5_os_config_default(&dev_config);
-		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i],
-						 &dev_config, &eth_da);
+		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da);
 		if (!list[i].eth_dev) {
 			if (rte_errno != EBUSY && rte_errno != EEXIST)
 				break;
@@ -2466,7 +2372,6 @@ static int
 mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 {
 	struct rte_eth_devargs eth_da = { .nb_ports = 0 };
-	struct mlx5_dev_config config;
 	struct mlx5_dev_spawn_data spawn = { .pf_bond = -1 };
 	struct rte_device *dev = cdev->dev;
 	struct rte_auxiliary_device *adev = RTE_DEV_TO_AUXILIARY(dev);
@@ -2477,8 +2382,6 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	ret = mlx5_os_parse_eth_devargs(dev, &eth_da);
 	if (ret != 0)
 		return ret;
-	/* Set default config data. */
-	mlx5_os_config_default(&config);
 	/* Init spawn data. */
 	spawn.max_port = 1;
 	spawn.phys_port = 1;
@@ -2491,7 +2394,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	spawn.ifindex = ret;
 	spawn.cdev = cdev;
 	/* Spawn device. */
-	eth_dev = mlx5_dev_spawn(dev, &spawn, &config, &eth_da);
+	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da);
 	if (eth_dev == NULL)
 		return -rte_errno;
 	/* Post create. */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index f3a9e749ab..02ddc87313 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2101,9 +2101,9 @@ const struct eth_dev_ops mlx5_dev_ops_isolate = {
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-mlx5_args_check(const char *key, const char *val, void *opaque)
+mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 {
-	struct mlx5_dev_config *config = opaque;
+	struct mlx5_port_config *config = opaque;
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
@@ -2197,38 +2197,156 @@ mlx5_args_check(const char *key, const char *val, void *opaque)
 }
 
 /**
- * Parse device parameters.
+ * Parse user port parameters and adjust them according to device capabilities.
  *
- * @param config
- *   Pointer to device configuration structure.
+ * @param priv
+ *   Pointer to shared device context.
  * @param devargs
  *   Device arguments structure.
+ * @param config
+ *   Pointer to port configuration structure.
  *
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs)
+mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+		      struct mlx5_port_config *config)
 {
 	struct rte_kvargs *kvlist;
+	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
+	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
+	bool devx = priv->sh->cdev->config.devx;
 	int ret = 0;
 
-	if (devargs == NULL)
-		return 0;
-	/* Following UGLY cast is done to pass checkpatch. */
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		rte_errno = EINVAL;
-		return -rte_errno;
+	/* Default configuration. */
+	memset(config, 0, sizeof(*config));
+	config->mps = MLX5_ARG_UNSET;
+	config->cqe_comp = 1;
+	config->rx_vec_en = 1;
+	config->txq_inline_max = MLX5_ARG_UNSET;
+	config->txq_inline_min = MLX5_ARG_UNSET;
+	config->txq_inline_mpw = MLX5_ARG_UNSET;
+	config->txqs_inline = MLX5_ARG_UNSET;
+	config->mprq.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN;
+	config->mprq.min_rxqs_num = MLX5_MPRQ_MIN_RXQS;
+	config->mprq.log_stride_num = MLX5_MPRQ_DEFAULT_LOG_STRIDE_NUM;
+	config->log_hp_size = MLX5_ARG_UNSET;
+	config->std_delay_drop = 0;
+	config->hp_delay_drop = 0;
+	/* Parse device parameters. */
+	if (devargs != NULL) {
+		kvlist = rte_kvargs_parse(devargs->args, NULL);
+		if (kvlist == NULL) {
+			DRV_LOG(ERR,
+				"Failed to parse device arguments.");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		/* Process parameters. */
+		ret = rte_kvargs_process(kvlist, NULL,
+					 mlx5_port_args_check_handler, config);
+		rte_kvargs_free(kvlist);
+		if (ret) {
+			DRV_LOG(ERR, "Failed to process port arguments: %s",
+				strerror(rte_errno));
+			return -rte_errno;
+		}
 	}
-	/* Process parameters. */
-	ret = rte_kvargs_process(kvlist, NULL, mlx5_args_check, config);
-	if (ret) {
-		rte_errno = EINVAL;
-		ret = -rte_errno;
+	/* Adjust parameters according to device capabilities. */
+	if (config->hw_padding && !dev_cap->hw_padding) {
+		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported.");
+		config->hw_padding = 0;
+	} else if (config->hw_padding) {
+		DRV_LOG(DEBUG, "Rx end alignment padding is enabled.");
 	}
-	rte_kvargs_free(kvlist);
-	return ret;
+	/*
+	 * MPW is disabled by default, while the Enhanced MPW is enabled
+	 * by default.
+	 */
+	if (config->mps == MLX5_ARG_UNSET)
+		config->mps = (dev_cap->mps == MLX5_MPW_ENHANCED) ?
+			      MLX5_MPW_ENHANCED : MLX5_MPW_DISABLED;
+	else
+		config->mps = config->mps ? dev_cap->mps : MLX5_MPW_DISABLED;
+	DRV_LOG(INFO, "%sMPS is %s",
+		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
+		config->mps == MLX5_MPW ? "legacy " : "",
+		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
+	/* LRO is supported only when DV flow enabled. */
+	if (dev_cap->lro_supported && !priv->sh->config.dv_flow_en)
+		dev_cap->lro_supported = 0;
+	if (dev_cap->lro_supported) {
+		/*
+		 * If LRO timeout is not configured by application,
+		 * use the minimal supported value.
+		 */
+		if (!config->lro_timeout)
+			config->lro_timeout =
+				       hca_attr->lro_timer_supported_periods[0];
+		DRV_LOG(DEBUG, "LRO session timeout set to %d usec.",
+			config->lro_timeout);
+	}
+	if (config->cqe_comp && !dev_cap->cqe_comp) {
+		DRV_LOG(WARNING, "Rx CQE 128B compression is not supported.");
+		config->cqe_comp = 0;
+	}
+	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_FTAG_STRIDX &&
+	    (!devx || !hca_attr->mini_cqe_resp_flow_tag)) {
+		DRV_LOG(WARNING,
+			"Flow Tag CQE compression format isn't supported.");
+		config->cqe_comp = 0;
+	}
+	if (config->cqe_comp_fmt == MLX5_CQE_RESP_FORMAT_L34H_STRIDX &&
+	    (!devx || !hca_attr->mini_cqe_resp_l3_l4_tag)) {
+		DRV_LOG(WARNING,
+			"L3/L4 Header CQE compression format isn't supported.");
+		config->cqe_comp = 0;
+	}
+	DRV_LOG(DEBUG, "Rx CQE compression is %ssupported.",
+		config->cqe_comp ? "" : "not ");
+	if ((config->std_delay_drop || config->hp_delay_drop) &&
+	    !dev_cap->rq_delay_drop_en) {
+		config->std_delay_drop = 0;
+		config->hp_delay_drop = 0;
+		DRV_LOG(WARNING, "dev_port-%u: Rxq delay drop isn't supported.",
+			priv->dev_port);
+	}
+	if (config->mprq.enabled && !priv->sh->dev_cap.mprq.enabled) {
+		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported.");
+		config->mprq.enabled = 0;
+	}
+	if (config->max_dump_files_num == 0)
+		config->max_dump_files_num = 128;
+	/* Detect minimal data bytes to inline. */
+	mlx5_set_min_inline(priv);
+	DRV_LOG(DEBUG, "VLAN insertion in WQE is %ssupported.",
+		config->hw_vlan_insert ? "" : "not ");
+	DRV_LOG(DEBUG, "\"rxq_pkt_pad_en\" is %u.", config->hw_padding);
+	DRV_LOG(DEBUG, "\"rxq_cqe_comp_en\" is %u.", config->cqe_comp);
+	DRV_LOG(DEBUG, "\"cqe_comp_fmt\" is %u.", config->cqe_comp_fmt);
+	DRV_LOG(DEBUG, "\"rx_vec_en\" is %u.", config->rx_vec_en);
+	DRV_LOG(DEBUG, "Standard \"delay_drop\" is %u.",
+		config->std_delay_drop);
+	DRV_LOG(DEBUG, "Hairpin \"delay_drop\" is %u.", config->hp_delay_drop);
+	DRV_LOG(DEBUG, "\"max_dump_files_num\" is %u.",
+		config->max_dump_files_num);
+	DRV_LOG(DEBUG, "\"log_hp_size\" is %u.", config->log_hp_size);
+	DRV_LOG(DEBUG, "\"mprq_en\" is %u.", config->mprq.enabled);
+	DRV_LOG(DEBUG, "\"mprq_log_stride_num\" is %u.",
+		config->mprq.log_stride_num);
+	DRV_LOG(DEBUG, "\"mprq_log_stride_size\" is %u.",
+		config->mprq.log_stride_size);
+	DRV_LOG(DEBUG, "\"mprq_max_memcpy_len\" is %u.",
+		config->mprq.max_memcpy_len);
+	DRV_LOG(DEBUG, "\"rxqs_min_mprq\" is %u.", config->mprq.min_rxqs_num);
+	DRV_LOG(DEBUG, "\"lro_timeout_usec\" is %u.", config->lro_timeout);
+	DRV_LOG(DEBUG, "\"txq_mpw_en\" is %d.", config->mps);
+	DRV_LOG(DEBUG, "\"txqs_min_inline\" is %d.", config->txqs_inline);
+	DRV_LOG(DEBUG, "\"txq_inline_min\" is %d.", config->txq_inline_min);
+	DRV_LOG(DEBUG, "\"txq_inline_max\" is %d.", config->txq_inline_max);
+	DRV_LOG(DEBUG, "\"txq_inline_mpw\" is %d.", config->txq_inline_mpw);
+	return 0;
 }
 
 /**
@@ -2366,21 +2484,19 @@ mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
  * - otherwise L2 mode (18 bytes) is assumed for ConnectX-4/4 Lx
  *   and none (0 bytes) for other NICs
  *
- * @param spawn
- *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
+ * @param priv
+ *   Pointer to the private device data structure.
  */
 void
-mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
-		    struct mlx5_dev_config *config)
+mlx5_set_min_inline(struct mlx5_priv *priv)
 {
-	struct mlx5_hca_attr *hca_attr = &spawn->cdev->config.hca_attr;
+	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
+	struct mlx5_port_config *config = &priv->config;
 
 	if (config->txq_inline_min != MLX5_ARG_UNSET) {
 		/* Application defines size of inlined data explicitly. */
-		if (spawn->pci_dev != NULL) {
-			switch (spawn->pci_dev->id.device_id) {
+		if (priv->pci_dev != NULL) {
+			switch (priv->pci_dev->id.device_id) {
 			case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
 			case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
 				if (config->txq_inline_min <
@@ -2446,7 +2562,7 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 			}
 		}
 	}
-	if (spawn->pci_dev == NULL) {
+	if (priv->pci_dev == NULL) {
 		config->txq_inline_min = MLX5_INLINE_HSIZE_NONE;
 		goto exit;
 	}
@@ -2455,7 +2571,7 @@ mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
 	 * inline data size with DevX. Try PCI ID
 	 * to determine old NICs.
 	 */
-	switch (spawn->pci_dev->id.device_id) {
+	switch (priv->pci_dev->id.device_id) {
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4:
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4VF:
 	case PCI_DEVICE_ID_MELLANOX_CONNECTX4LX:
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 46fa5131a7..95910aba1b 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -243,14 +243,13 @@ struct mlx5_stats_ctrl {
 #define MLX5_MAX_RXQ_NSEG (1u << MLX5_MAX_LOG_RQ_SEGS)
 
 /*
- * Device configuration structure.
- *
- * Merged configuration from:
- *
- *  - Device capabilities,
- *  - User device parameters disabled features.
+ * Port configuration structure.
+ * User device parameters disabled features.
+ * This structure contains all configurations coming from devargs which
+ * oriented to port. When probing again, devargs doesn't have to be compatible
+ * with primary devargs. It is updated for each port in spawn function.
  */
-struct mlx5_dev_config {
+struct mlx5_port_config {
 	unsigned int hw_vlan_insert:1; /* VLAN insertion in WQE is supported. */
 	unsigned int hw_padding:1; /* End alignment padding is supported. */
 	unsigned int cqe_comp:1; /* CQE compression is enabled. */
@@ -1450,7 +1449,7 @@ struct mlx5_priv {
 	uint32_t link_speed_capa; /* Link speed capabilities. */
 	struct mlx5_xstats_ctrl xstats_ctrl; /* Extended stats control. */
 	struct mlx5_stats_ctrl stats_ctrl; /* Stats control. */
-	struct mlx5_dev_config config; /* Device configuration. */
+	struct mlx5_port_config config; /* Port configuration. */
 	/* Context for Verbs allocator. */
 	int nl_socket_rdma; /* Netlink socket (NETLINK_RDMA). */
 	int nl_socket_route; /* Netlink socket (NETLINK_ROUTE). */
@@ -1539,7 +1538,6 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 	for (port_id = mlx5_eth_find_next(0, dev); \
 	     port_id < RTE_MAX_ETHPORTS; \
 	     port_id = mlx5_eth_find_next(port_id + 1, dev))
-int mlx5_args(struct mlx5_dev_config *config, struct rte_devargs *devargs);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
@@ -1548,10 +1546,11 @@ void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
 int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
-void mlx5_set_min_inline(struct mlx5_dev_spawn_data *spawn,
-			 struct mlx5_dev_config *config);
+void mlx5_set_min_inline(struct mlx5_priv *priv);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
 int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
+int mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+			  struct mlx5_port_config *config);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_devx.c b/drivers/net/mlx5/mlx5_devx.c
index de0f3672c1..e57787cfec 100644
--- a/drivers/net/mlx5/mlx5_devx.c
+++ b/drivers/net/mlx5/mlx5_devx.c
@@ -766,8 +766,7 @@ mlx5_devx_tir_attr_set(struct rte_eth_dev *dev, const uint8_t *rss_key,
 	memcpy(tir_attr->rx_hash_toeplitz_key, rss_key, MLX5_RSS_HASH_KEY_LEN);
 	tir_attr->indirect_table = ind_tbl->rqt->id;
 	if (dev->data->dev_conf.lpbk_mode)
-		tir_attr->self_lb_block =
-					MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
+		tir_attr->self_lb_block = MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST;
 	if (lro) {
 		tir_attr->lro_timeout_period_usecs = priv->config.lro_timeout;
 		tir_attr->lro_max_msg_sz = priv->max_lro_msg_size;
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index d637dee98d..72bf8ac914 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -266,7 +266,7 @@ static void
 mlx5_set_txlimit_params(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	unsigned int inlen;
 	uint16_t nb_max;
 
@@ -302,7 +302,6 @@ int
 mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
 	unsigned int max;
 
 	/* FIXME: we should ask the device for these values. */
@@ -321,8 +320,8 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	info->max_mac_addrs = MLX5_MAX_UC_MAC_ADDRESSES;
 	info->rx_queue_offload_capa = mlx5_get_rx_queue_offloads(dev);
 	info->rx_seg_capa.max_nseg = MLX5_MAX_RXQ_NSEG;
-	info->rx_seg_capa.multi_pools = !config->mprq.enabled;
-	info->rx_seg_capa.offset_allowed = !config->mprq.enabled;
+	info->rx_seg_capa.multi_pools = !priv->config.mprq.enabled;
+	info->rx_seg_capa.offset_allowed = !priv->config.mprq.enabled;
 	info->rx_seg_capa.offset_align_log2 = 0;
 	info->rx_offload_capa = (mlx5_get_rx_port_offloads() |
 				 info->rx_queue_offload_capa);
diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
index 1d1f2556de..2625fa3308 100644
--- a/drivers/net/mlx5/mlx5_rxq.c
+++ b/drivers/net/mlx5/mlx5_rxq.c
@@ -1562,7 +1562,7 @@ mlx5_mprq_prepare(struct rte_eth_dev *dev, uint16_t idx, uint16_t desc,
 		  uint32_t *actual_log_stride_size)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	uint32_t log_min_stride_num = dev_cap->mprq.log_min_stride_num;
 	uint32_t log_max_stride_num = dev_cap->mprq.log_max_stride_num;
@@ -1681,7 +1681,7 @@ mlx5_rxq_new(struct rte_eth_dev *dev, struct mlx5_rxq_priv *rxq,
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_rxq_ctrl *tmpl;
 	unsigned int mb_len = rte_pktmbuf_data_room_size(rx_seg[0].mp);
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	uint64_t offloads = conf->offloads |
 			   dev->data->dev_conf.rxmode.offloads;
 	unsigned int lro_on_queue = !!(offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO);
diff --git a/drivers/net/mlx5/mlx5_tx.c b/drivers/net/mlx5/mlx5_tx.c
index 8453b2701a..a13c7e937c 100644
--- a/drivers/net/mlx5/mlx5_tx.c
+++ b/drivers/net/mlx5/mlx5_tx.c
@@ -492,7 +492,7 @@ eth_tx_burst_t
 mlx5_select_tx_function(struct rte_eth_dev *dev)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	uint64_t tx_offloads = dev->data->dev_conf.txmode.offloads;
 	unsigned int diff = 0, olx = 0, i, m;
 
diff --git a/drivers/net/mlx5/mlx5_txq.c b/drivers/net/mlx5/mlx5_txq.c
index 3373ee66b4..edbaa50692 100644
--- a/drivers/net/mlx5/mlx5_txq.c
+++ b/drivers/net/mlx5/mlx5_txq.c
@@ -100,7 +100,7 @@ mlx5_get_tx_port_offloads(struct rte_eth_dev *dev)
 	struct mlx5_priv *priv = dev->data->dev_private;
 	uint64_t offloads = (RTE_ETH_TX_OFFLOAD_MULTI_SEGS |
 			     RTE_ETH_TX_OFFLOAD_VLAN_INSERT);
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 
 	if (dev_cap->hw_csum)
@@ -741,7 +741,7 @@ static void
 txq_set_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	unsigned int inlen_send; /* Inline data for ordinary SEND.*/
 	unsigned int inlen_empw; /* Inline data for enhanced MPW. */
@@ -960,7 +960,7 @@ static int
 txq_adjust_params(struct mlx5_txq_ctrl *txq_ctrl)
 {
 	struct mlx5_priv *priv = txq_ctrl->priv;
-	struct mlx5_dev_config *config = &priv->config;
+	struct mlx5_port_config *config = &priv->config;
 	unsigned int max_inline;
 
 	max_inline = txq_calc_inline_max(txq_ctrl);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 9e6a46ad3a..52be589083 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -284,8 +284,6 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
- * @param config
- *   Device configuration parameters.
  *
  * @return
  *   A valid Ethernet device object on success, NULL otherwise and rte_errno
@@ -295,8 +293,7 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  */
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
-	       struct mlx5_dev_spawn_data *spawn,
-	       struct mlx5_dev_config *config)
+	       struct mlx5_dev_spawn_data *spawn)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
@@ -317,14 +314,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	/* Process parameters. */
-	err = mlx5_args(config, dpdk_dev->devargs);
-	if (err) {
-		err = rte_errno;
-		DRV_LOG(ERR, "failed to process device arguments: %s",
-			strerror(rte_errno));
-		goto error;
-	}
 	sh = mlx5_alloc_shared_dev_ctx(spawn);
 	if (!sh)
 		return NULL;
@@ -396,24 +385,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		}
 		own_domain_id = 1;
 	}
-	if (config->hw_padding) {
-		DRV_LOG(DEBUG, "Rx end alignment padding isn't supported");
-		config->hw_padding = 0;
-	}
-	DRV_LOG(DEBUG, "%sMPS is %s.",
-		config->mps == MLX5_MPW_ENHANCED ? "enhanced " :
-		config->mps == MLX5_MPW ? "legacy " : "",
-		config->mps != MLX5_MPW_DISABLED ? "enabled" : "disabled");
-	if (config->cqe_comp) {
-		DRV_LOG(WARNING, "Rx CQE compression isn't supported.");
-		config->cqe_comp = 0;
-	}
-	if (config->mprq.enabled) {
-		DRV_LOG(WARNING, "Multi-Packet RQ isn't supported");
-		config->mprq.enabled = 0;
+	/* Process parameters and store port configuration on priv structure. */
+	err = mlx5_port_args_config(priv, dpdk_dev->devargs, &priv->config);
+	if (err) {
+		err = rte_errno;
+		DRV_LOG(ERR, "Failed to process port configure: %s",
+			strerror(rte_errno));
+		goto error;
 	}
-	if (config->max_dump_files_num == 0)
-		config->max_dump_files_num = 128;
 	eth_dev = rte_eth_dev_allocate(name);
 	if (eth_dev == NULL) {
 		DRV_LOG(ERR, "can not allocate rte ethdev");
@@ -508,10 +487,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	 * Verbs context returned by ibv_open_device().
 	 */
 	mlx5_link_update(eth_dev, 0);
-	/* Detect minimal data bytes to inline. */
-	mlx5_set_min_inline(spawn, config);
-	/* Store device configuration on private structure. */
-	priv->config = *config;
 	for (i = 0; i < MLX5_FLOW_TYPE_MAXI; i++) {
 		icfg[i].release_mem_en = !!sh->config.reclaim_mode;
 		if (sh->config.reclaim_mode)
@@ -817,18 +792,6 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			.name_type = MLX5_PHYS_PORT_NAME_TYPE_UPLINK,
 		},
 	};
-	struct mlx5_dev_config dev_config = {
-		.rx_vec_en = 1,
-		.txq_inline_max = MLX5_ARG_UNSET,
-		.txq_inline_min = MLX5_ARG_UNSET,
-		.txq_inline_mpw = MLX5_ARG_UNSET,
-		.txqs_inline = MLX5_ARG_UNSET,
-		.mprq = {
-			.max_memcpy_len = MLX5_MPRQ_MEMCPY_DEFAULT_LEN,
-			.min_rxqs_num = MLX5_MPRQ_MIN_RXQS,
-		},
-		.log_hp_size = MLX5_ARG_UNSET,
-	};
 	int ret;
 	uint32_t restore;
 
@@ -842,7 +805,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, &dev_config);
+	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn);
 	if (!spawn.eth_dev)
 		return -rte_errno;
 	restore = spawn.eth_dev->data->dev_flags;
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 19/20] common/mlx5: add check for common devargs in probing again
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (17 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 18/20] net/mlx5: separate per port configuration Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-14  9:35   ` [PATCH v2 20/20] common/mlx5: refactor devargs management Michael Baum
  2022-02-21  8:54   ` [PATCH v2 00/20] mlx5: " Raslan Darawsheh
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

MLX5 common driver supports probing again in two scenarios:
 - Add new driver under existing device. common probe function gets
   it in devargs, then calls the requested driver's probe function
   (regardless of the driver's own support in probing again) with the
   existing device as parameter.
 - Transfer the probing again support of the drivers themselves
   (currently only net). In this scenario, the existing device is sent
   as a parameter to the existing driver's probe too.

In both cases it gets a new set of arguments that do not necessarily
match the configured arguments in the existing device.
Some of the arguments belong to the configuration of the existing
device, so they can't be updated in the probing again. On the other
hand, there are arguments that belong to a specific driver or specific
port and might get a new value in the probing again.
The user might generate any argument he wants in probing again, but when
he generates arguments belonging to the common device configuration, it
does not affect.

This patch adds an explicit check for the devargs belonging to the
common device configuration. If there is no match to the existing
configuration, it returns an error.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.c | 100 ++++++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index 47a541f5ef..f74d27e74d 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -613,6 +613,86 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
 	return cdev;
 }
 
+/**
+ * Validate common devargs when probing again.
+ *
+ * When common device probing again, it cannot change its configurations.
+ * If user ask non compatible configurations in devargs, it is error.
+ * This function checks the match between:
+ *  - Common device configurations requested by probe again devargs.
+ *  - Existing common device configurations.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
+{
+	struct mlx5_common_dev_config *config;
+	int ret;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	/* Probe again doesn't have to generate devargs. */
+	if (cdev->dev->devargs == NULL)
+		return 0;
+	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
+			     sizeof(struct mlx5_common_dev_config),
+			     RTE_CACHE_LINE_SIZE, SOCKET_ID_ANY);
+	if (config == NULL) {
+		rte_errno = -ENOMEM;
+		return -rte_errno;
+	}
+	/*
+	 * Creates a temporary common configure structure according to new
+	 * devargs attached in probing again.
+	 */
+	ret = mlx5_common_config_get(cdev->dev->devargs, config);
+	if (ret) {
+		DRV_LOG(ERR, "Failed to process device configure: %s",
+			strerror(rte_errno));
+		mlx5_free(config);
+		return ret;
+	}
+	/*
+	 * Checks the match between the temporary structure and the existing
+	 * common device structure.
+	 */
+	if (cdev->config.mr_ext_memseg_en ^ config->mr_ext_memseg_en) {
+		DRV_LOG(ERR, "\"mr_ext_memseg_en\" "
+			"configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.mr_mempool_reg_en ^ config->mr_mempool_reg_en) {
+		DRV_LOG(ERR, "\"mr_mempool_reg_en\" "
+			"configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.sys_mem_en ^ config->sys_mem_en) {
+		DRV_LOG(ERR,
+			"\"sys_mem_en\" configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	if (cdev->config.dbnc ^ config->dbnc) {
+		DRV_LOG(ERR, "\"dbnc\" configuration mismatch for device %s.",
+			cdev->dev->name);
+		goto error;
+	}
+	mlx5_free(config);
+	return 0;
+error:
+	mlx5_free(config);
+	rte_errno = EINVAL;
+	return -rte_errno;
+}
+
 static int
 drivers_remove(struct mlx5_common_device *cdev, uint32_t enabled_classes)
 {
@@ -699,12 +779,32 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 	if (classes == 0)
 		/* Default to net class. */
 		classes = MLX5_CLASS_ETH;
+	/*
+	 * MLX5 common driver supports probing again in two scenarios:
+	 * - Add new driver under existing common device (regardless of the
+	 *   driver's own support in probing again).
+	 * - Transfer the probing again support of the drivers themselves.
+	 *
+	 * In both scenarios it uses in the existing device. here it looks for
+	 * device that match to rte device, if it exists, the request classes
+	 * were probed with this device.
+	 */
 	cdev = to_mlx5_device(eal_dev);
 	if (!cdev) {
+		/* It isn't probing again, creates a new device. */
 		cdev = mlx5_common_dev_create(eal_dev, classes);
 		if (!cdev)
 			return -ENOMEM;
 		new_device = true;
+	} else {
+		/* It is probing again, validate common devargs match. */
+		ret = mlx5_common_probe_again_args_validate(cdev);
+		if (ret) {
+			DRV_LOG(ERR,
+				"Probe again parameters aren't compatible : %s",
+				strerror(rte_errno));
+			return ret;
+		}
 	}
 	/*
 	 * Validate combination here.
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [PATCH v2 20/20] common/mlx5: refactor devargs management
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (18 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
@ 2022-02-14  9:35   ` Michael Baum
  2022-02-21  8:54   ` [PATCH v2 00/20] mlx5: " Raslan Darawsheh
  20 siblings, 0 replies; 43+ messages in thread
From: Michael Baum @ 2022-02-14  9:35 UTC (permalink / raw)
  To: dev; +Cc: Matan Azrad, Raslan Darawsheh, Viacheslav Ovsiienko

Improve the devargs handling in two aspects:
 - Parse the devargs string only once.
 - Return error and report for unknown keys.

The common driver parses once the devargs string into a dictionary, then
provides it to all the drivers' probe. Each driver updates within it
which keys it has used, then common driver receives the updated
dictionary and reports about unknown devargs.

Signed-off-by: Michael Baum <michaelba@nvidia.com>
Acked-by: Matan Azrad <matan@nvidia.com>
---
 drivers/common/mlx5/mlx5_common.c     | 255 +++++++++++++++++++++-----
 drivers/common/mlx5/mlx5_common.h     |  36 +++-
 drivers/common/mlx5/version.map       |   2 +
 drivers/compress/mlx5/mlx5_compress.c |  38 ++--
 drivers/crypto/mlx5/mlx5_crypto.c     |  39 ++--
 drivers/net/mlx5/linux/mlx5_os.c      |  47 +++--
 drivers/net/mlx5/mlx5.c               | 212 ++++++++++++++-------
 drivers/net/mlx5/mlx5.h               |  14 +-
 drivers/net/mlx5/windows/mlx5_os.c    |  18 +-
 drivers/regex/mlx5/mlx5_regex.c       |   3 +-
 drivers/vdpa/mlx5/mlx5_vdpa.c         |  32 ++--
 11 files changed, 498 insertions(+), 198 deletions(-)

diff --git a/drivers/common/mlx5/mlx5_common.c b/drivers/common/mlx5/mlx5_common.c
index f74d27e74d..96906d3f39 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -21,6 +21,24 @@
 
 uint8_t haswell_broadwell_cpu;
 
+/* Driver type key for new device global syntax. */
+#define MLX5_DRIVER_KEY "driver"
+
+/* Enable extending memsegs when creating a MR. */
+#define MLX5_MR_EXT_MEMSEG_EN "mr_ext_memseg_en"
+
+/* Device parameter to configure implicit registration of mempool memory. */
+#define MLX5_MR_MEMPOOL_REG_EN "mr_mempool_reg_en"
+
+/* The default memory allocator used in PMD. */
+#define MLX5_SYS_MEM_EN "sys_mem_en"
+
+/*
+ * Device parameter to force doorbell register mapping
+ * to non-cahed region eliminating the extra write memory barrier.
+ */
+#define MLX5_TX_DB_NC "tx_db_nc"
+
 /* In case this is an x86_64 intel processor to check if
  * we should use relaxed ordering.
  */
@@ -92,6 +110,122 @@ driver_get(uint32_t class)
 	return NULL;
 }
 
+int
+mlx5_kvargs_process(struct mlx5_kvargs_ctrl *mkvlist, const char *const keys[],
+		    arg_handler_t handler, void *opaque_arg)
+{
+	const struct rte_kvargs_pair *pair;
+	uint32_t i, j;
+
+	MLX5_ASSERT(mkvlist && mkvlist->kvlist);
+	/* Process parameters. */
+	for (i = 0; i < mkvlist->kvlist->count; i++) {
+		pair = &mkvlist->kvlist->pairs[i];
+		for (j = 0; keys[j] != NULL; ++j) {
+			if (strcmp(pair->key, keys[j]) != 0)
+				continue;
+			if ((*handler)(pair->key, pair->value, opaque_arg) < 0)
+				return -1;
+			mkvlist->is_used[i] = true;
+			break;
+		}
+	}
+	return 0;
+}
+
+/**
+ * Prepare a mlx5 kvargs control.
+ *
+ * @param[out] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ * @param[in] devargs
+ *   The input string containing the key/value associations.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_kvargs_prepare(struct mlx5_kvargs_ctrl *mkvlist,
+		    const struct rte_devargs *devargs)
+{
+	struct rte_kvargs *kvlist;
+	uint32_t i;
+
+	if (devargs == NULL)
+		return 0;
+	kvlist = rte_kvargs_parse(devargs->args, NULL);
+	if (kvlist == NULL) {
+		rte_errno = EINVAL;
+		return -rte_errno;
+	}
+	/*
+	 * rte_kvargs_parse enable key without value, in mlx5 PMDs we disable
+	 * this syntax.
+	 */
+	for (i = 0; i < kvlist->count; i++) {
+		const struct rte_kvargs_pair *pair = &kvlist->pairs[i];
+		if (pair->value == NULL || *(pair->value) == '\0') {
+			DRV_LOG(ERR, "Key %s is missing value.", pair->key);
+			rte_kvargs_free(kvlist);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+	}
+	/* Makes sure all devargs used array is false. */
+	memset(mkvlist, 0, sizeof(*mkvlist));
+	mkvlist->kvlist = kvlist;
+	DRV_LOG(DEBUG, "Parse successfully %u devargs.",
+		mkvlist->kvlist->count);
+	return 0;
+}
+
+/**
+ * Release a mlx5 kvargs control.
+ *
+ * @param[out] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ */
+static void
+mlx5_kvargs_release(struct mlx5_kvargs_ctrl *mkvlist)
+{
+	if (mkvlist == NULL)
+		return;
+	rte_kvargs_free(mkvlist->kvlist);
+	memset(mkvlist, 0, sizeof(*mkvlist));
+}
+
+/**
+ * Validate device arguments list.
+ * It report about the first unknown parameter.
+ *
+ * @param[in] mkvlist
+ *   Pointer to mlx5 kvargs control.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_kvargs_validate(struct mlx5_kvargs_ctrl *mkvlist)
+{
+	uint32_t i;
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return 0;
+	if (mkvlist == NULL)
+		return 0;
+	for (i = 0; i < mkvlist->kvlist->count; i++) {
+		if (mkvlist->is_used[i] == 0) {
+			DRV_LOG(ERR, "Key \"%s\" "
+				"is unknown for the provided classes.",
+				mkvlist->kvlist->pairs[i].key);
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+	}
+	return 0;
+}
+
 /**
  * Verify and store value for devargs.
  *
@@ -111,11 +245,9 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 	struct mlx5_common_dev_config *config = opaque;
 	signed long tmp;
 
-	if (val == NULL || *val == '\0') {
-		DRV_LOG(ERR, "Key %s is missing value.", key);
-		rte_errno = EINVAL;
-		return -rte_errno;
-	}
+	if (strcmp(MLX5_DRIVER_KEY, key) == 0 ||
+	    strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0)
+		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
 	if (errno) {
@@ -123,7 +255,7 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 		DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.", key, val);
 		return -rte_errno;
 	}
-	if (strcmp(key, "tx_db_nc") == 0) {
+	if (strcmp(key, MLX5_TX_DB_NC) == 0) {
 		if (tmp != MLX5_TXDB_CACHED &&
 		    tmp != MLX5_TXDB_NCACHED &&
 		    tmp != MLX5_TXDB_HEURISTIC) {
@@ -132,11 +264,11 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
 			return -rte_errno;
 		}
 		config->dbnc = tmp;
-	} else if (strcmp(key, "mr_ext_memseg_en") == 0) {
+	} else if (strcmp(key, MLX5_MR_EXT_MEMSEG_EN) == 0) {
 		config->mr_ext_memseg_en = !!tmp;
-	} else if (strcmp(key, "mr_mempool_reg_en") == 0) {
+	} else if (strcmp(key, MLX5_MR_MEMPOOL_REG_EN) == 0) {
 		config->mr_mempool_reg_en = !!tmp;
-	} else if (strcmp(key, "sys_mem_en") == 0) {
+	} else if (strcmp(key, MLX5_SYS_MEM_EN) == 0) {
 		config->sys_mem_en = !!tmp;
 	}
 	return 0;
@@ -154,29 +286,34 @@ mlx5_common_args_check_handler(const char *key, const char *val, void *opaque)
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 static int
-mlx5_common_config_get(struct rte_devargs *devargs,
+mlx5_common_config_get(struct mlx5_kvargs_ctrl *mkvlist,
 		       struct mlx5_common_dev_config *config)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		RTE_DEVARGS_KEY_CLASS,
+		MLX5_DRIVER_KEY,
+		MLX5_TX_DB_NC,
+		MLX5_MR_EXT_MEMSEG_EN,
+		MLX5_SYS_MEM_EN,
+		MLX5_MR_MEMPOOL_REG_EN,
+		NULL,
+	};
 	int ret = 0;
 
+	if (mkvlist == NULL)
+		return 0;
 	/* Set defaults. */
 	config->mr_ext_memseg_en = 1;
 	config->mr_mempool_reg_en = 1;
 	config->sys_mem_en = 0;
 	config->dbnc = MLX5_ARG_UNSET;
-	if (devargs == NULL)
-		return 0;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
+	/* Process common parameters. */
+	ret = mlx5_kvargs_process(mkvlist, params,
+				  mlx5_common_args_check_handler, config);
+	if (ret) {
 		rte_errno = EINVAL;
-		return -rte_errno;
-	}
-	ret = rte_kvargs_process(kvlist, NULL, mlx5_common_args_check_handler,
-				 config);
-	if (ret)
 		ret = -rte_errno;
-	rte_kvargs_free(kvlist);
+	}
 	DRV_LOG(DEBUG, "mr_ext_memseg_en is %u.", config->mr_ext_memseg_en);
 	DRV_LOG(DEBUG, "mr_mempool_reg_en is %u.", config->mr_mempool_reg_en);
 	DRV_LOG(DEBUG, "sys_mem_en is %u.", config->sys_mem_en);
@@ -225,9 +362,9 @@ devargs_class_handler(__rte_unused const char *key,
 }
 
 static int
-parse_class_options(const struct rte_devargs *devargs)
+parse_class_options(const struct rte_devargs *devargs,
+		    struct mlx5_kvargs_ctrl *mkvlist)
 {
-	struct rte_kvargs *kvlist;
 	int ret = 0;
 
 	if (devargs == NULL)
@@ -236,12 +373,8 @@ parse_class_options(const struct rte_devargs *devargs)
 		/* Global syntax, only one class type. */
 		return class_name_to_value(devargs->cls->name);
 	/* Legacy devargs support multiple classes. */
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
-		return 0;
-	rte_kvargs_process(kvlist, RTE_DEVARGS_KEY_CLASS,
+	rte_kvargs_process(mkvlist->kvlist, RTE_DEVARGS_KEY_CLASS,
 			   devargs_class_handler, &ret);
-	rte_kvargs_free(kvlist);
 	return ret;
 }
 
@@ -564,7 +697,8 @@ mlx5_common_dev_release(struct mlx5_common_device *cdev)
 }
 
 static struct mlx5_common_device *
-mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
+mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes,
+		       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_common_device *cdev;
 	int ret;
@@ -579,7 +713,7 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		goto exit;
 	/* Parse device parameters. */
-	ret = mlx5_common_config_get(eal_dev->devargs, &cdev->config);
+	ret = mlx5_common_config_get(mkvlist, &cdev->config);
 	if (ret < 0) {
 		DRV_LOG(ERR, "Failed to process device arguments: %s",
 			strerror(rte_errno));
@@ -624,12 +758,15 @@ mlx5_common_dev_create(struct rte_device *eal_dev, uint32_t classes)
  *
  * @param cdev
  *   Pointer to mlx5 device structure.
+ * @param 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_common_probe_again_args_validate(struct mlx5_common_device *cdev)
+mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev,
+				      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_common_dev_config *config;
 	int ret;
@@ -638,7 +775,7 @@ mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 	/* Probe again doesn't have to generate devargs. */
-	if (cdev->dev->devargs == NULL)
+	if (mkvlist == NULL)
 		return 0;
 	config = mlx5_malloc(MLX5_MEM_ZERO | MLX5_MEM_RTE,
 			     sizeof(struct mlx5_common_dev_config),
@@ -651,7 +788,7 @@ mlx5_common_probe_again_args_validate(struct mlx5_common_device *cdev)
 	 * Creates a temporary common configure structure according to new
 	 * devargs attached in probing again.
 	 */
-	ret = mlx5_common_config_get(cdev->dev->devargs, config);
+	ret = mlx5_common_config_get(mkvlist, config);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
@@ -719,7 +856,8 @@ drivers_remove(struct mlx5_common_device *cdev, uint32_t enabled_classes)
 }
 
 static int
-drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes)
+drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes,
+	      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_class_driver *driver;
 	uint32_t enabled_classes = 0;
@@ -738,7 +876,7 @@ drivers_probe(struct mlx5_common_device *cdev, uint32_t user_classes)
 			ret = -EEXIST;
 			goto probe_err;
 		}
-		ret = driver->probe(cdev);
+		ret = driver->probe(cdev, mkvlist);
 		if (ret < 0) {
 			DRV_LOG(ERR, "Failed to load driver %s",
 				driver->name);
@@ -764,17 +902,27 @@ int
 mlx5_common_dev_probe(struct rte_device *eal_dev)
 {
 	struct mlx5_common_device *cdev;
+	struct mlx5_kvargs_ctrl mkvlist;
+	struct mlx5_kvargs_ctrl *mkvlist_p = NULL;
 	uint32_t classes = 0;
 	bool new_device = false;
 	int ret;
 
 	DRV_LOG(INFO, "probe device \"%s\".", eal_dev->name);
-	ret = parse_class_options(eal_dev->devargs);
+	if (eal_dev->devargs != NULL)
+		mkvlist_p = &mkvlist;
+	ret = mlx5_kvargs_prepare(mkvlist_p, eal_dev->devargs);
 	if (ret < 0) {
-		DRV_LOG(ERR, "Unsupported mlx5 class type: %s",
+		DRV_LOG(ERR, "Unsupported device arguments: %s",
 			eal_dev->devargs->args);
 		return ret;
 	}
+	ret = parse_class_options(eal_dev->devargs, mkvlist_p);
+	if (ret < 0) {
+		DRV_LOG(ERR, "Unsupported mlx5 class type: %s",
+			eal_dev->devargs->args);
+		goto class_err;
+	}
 	classes = ret;
 	if (classes == 0)
 		/* Default to net class. */
@@ -792,18 +940,20 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 	cdev = to_mlx5_device(eal_dev);
 	if (!cdev) {
 		/* It isn't probing again, creates a new device. */
-		cdev = mlx5_common_dev_create(eal_dev, classes);
-		if (!cdev)
-			return -ENOMEM;
+		cdev = mlx5_common_dev_create(eal_dev, classes, mkvlist_p);
+		if (!cdev) {
+			ret = -ENOMEM;
+			goto class_err;
+		}
 		new_device = true;
 	} else {
 		/* It is probing again, validate common devargs match. */
-		ret = mlx5_common_probe_again_args_validate(cdev);
+		ret = mlx5_common_probe_again_args_validate(cdev, mkvlist_p);
 		if (ret) {
 			DRV_LOG(ERR,
 				"Probe again parameters aren't compatible : %s",
 				strerror(rte_errno));
-			return ret;
+			goto class_err;
 		}
 	}
 	/*
@@ -816,13 +966,30 @@ mlx5_common_dev_probe(struct rte_device *eal_dev)
 		DRV_LOG(ERR, "Unsupported mlx5 classes combination.");
 		goto class_err;
 	}
-	ret = drivers_probe(cdev, classes);
+	ret = drivers_probe(cdev, classes, mkvlist_p);
+	if (ret)
+		goto class_err;
+	/*
+	 * Validate that all devargs have been used, unused key -> unknown Key.
+	 * When probe again validate is failed, the added drivers aren't removed
+	 * here but when device is released.
+	 */
+	ret = mlx5_kvargs_validate(mkvlist_p);
 	if (ret)
 		goto class_err;
+	mlx5_kvargs_release(mkvlist_p);
 	return 0;
 class_err:
-	if (new_device)
+	if (new_device) {
+		/*
+		 * For new device, classes_loaded is always 0 before
+		 * drivers_probe function.
+		 */
+		if (cdev->classes_loaded)
+			drivers_remove(cdev, cdev->classes_loaded);
 		mlx5_common_dev_release(cdev);
+	}
+	mlx5_kvargs_release(mkvlist_p);
 	return ret;
 }
 
diff --git a/drivers/common/mlx5/mlx5_common.h b/drivers/common/mlx5/mlx5_common.h
index 80f59c81fb..49bcea1d91 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -281,6 +281,37 @@ struct mlx5_klm {
 	uint64_t address;
 };
 
+/** Control for key/values list. */
+struct mlx5_kvargs_ctrl {
+	struct rte_kvargs *kvlist; /* Structure containing list of key/values.*/
+	bool is_used[RTE_KVARGS_MAX]; /* Indicator which devargs were used. */
+};
+
+/**
+ * Call a handler function for each key/value in the list of keys.
+ *
+ * For each key/value association that matches the given key, calls the
+ * handler function with the for a given arg_name passing the value on the
+ * dictionary for that key and a given extra argument.
+ *
+ * @param mkvlist
+ *   The mlx5_kvargs structure.
+ * @param keys
+ *   A list of keys to process (table of const char *, the last must be NULL).
+ * @param handler
+ *   The function to call for each matching key.
+ * @param opaque_arg
+ *   A pointer passed unchanged to the handler.
+ *
+ * @return
+ *   - 0 on success
+ *   - Negative on error
+ */
+__rte_internal
+int
+mlx5_kvargs_process(struct mlx5_kvargs_ctrl *mkvlist, const char *const keys[],
+		    arg_handler_t handler, void *opaque_arg);
+
 /* All UAR arguments using doorbell register in datapath. */
 struct mlx5_uar_data {
 	uint64_t *db;
@@ -437,12 +468,13 @@ struct mlx5_common_device {
 /**
  * Initialization function for the driver called during device probing.
  */
-typedef int (mlx5_class_driver_probe_t)(struct mlx5_common_device *dev);
+typedef int (mlx5_class_driver_probe_t)(struct mlx5_common_device *cdev,
+					struct mlx5_kvargs_ctrl *mkvlist);
 
 /**
  * Uninitialization function for the driver called during hot-unplugging.
  */
-typedef int (mlx5_class_driver_remove_t)(struct mlx5_common_device *dev);
+typedef int (mlx5_class_driver_remove_t)(struct mlx5_common_device *cdev);
 
 /** Device already probed can be probed again to check for new ports. */
 #define MLX5_DRV_PROBE_AGAIN 0x0004
diff --git a/drivers/common/mlx5/version.map b/drivers/common/mlx5/version.map
index 59ab434631..1c6153c576 100644
--- a/drivers/common/mlx5/version.map
+++ b/drivers/common/mlx5/version.map
@@ -85,6 +85,8 @@ INTERNAL {
 
 	mlx5_glue;
 
+	mlx5_kvargs_process;
+
 	mlx5_list_create;
 	mlx5_list_register;
 	mlx5_list_unregister;
diff --git a/drivers/compress/mlx5/mlx5_compress.c b/drivers/compress/mlx5/mlx5_compress.c
index b12951da8b..7a482c3fbb 100644
--- a/drivers/compress/mlx5/mlx5_compress.c
+++ b/drivers/compress/mlx5/mlx5_compress.c
@@ -656,41 +656,36 @@ mlx5_compress_args_check_handler(const char *key, const char *val, void *opaque)
 		errno = 0;
 		devarg_prms->log_block_sz = (uint32_t)strtoul(val, NULL, 10);
 		if (errno) {
-			DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer."
-				, key, val);
+			DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.",
+				key, val);
 			return -errno;
 		}
-		return 0;
 	}
 	return 0;
 }
 
 static int
-mlx5_compress_handle_devargs(struct rte_devargs *devargs,
-			  struct mlx5_compress_devarg_params *devarg_prms,
-			  struct mlx5_hca_attr *att)
+mlx5_compress_handle_devargs(struct mlx5_kvargs_ctrl *mkvlist,
+			     struct mlx5_compress_devarg_params *devarg_prms,
+			     struct mlx5_hca_attr *att)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"log-block-size",
+		NULL,
+	};
 
 	devarg_prms->log_block_sz = MLX5_GGA_COMP_LOG_BLOCK_SIZE_MAX;
-	if (devargs == NULL)
+	if (mkvlist == NULL)
 		return 0;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		DRV_LOG(ERR, "Failed to parse devargs.");
-		rte_errno = EINVAL;
-		return -1;
-	}
-	if (rte_kvargs_process(kvlist, NULL, mlx5_compress_args_check_handler,
-			   devarg_prms) != 0) {
+	if (mlx5_kvargs_process(mkvlist, params,
+				mlx5_compress_args_check_handler,
+				devarg_prms) != 0) {
 		DRV_LOG(ERR, "Devargs handler function Failed.");
-		rte_kvargs_free(kvlist);
 		rte_errno = EINVAL;
 		return -1;
 	}
-	rte_kvargs_free(kvlist);
 	if (devarg_prms->log_block_sz > MLX5_GGA_COMP_LOG_BLOCK_SIZE_MAX ||
-		devarg_prms->log_block_sz < att->compress_min_block_size) {
+	    devarg_prms->log_block_sz < att->compress_min_block_size) {
 		DRV_LOG(WARNING, "Log block size provided is out of range("
 			"%u); default it to %u.",
 			devarg_prms->log_block_sz,
@@ -701,7 +696,8 @@ mlx5_compress_handle_devargs(struct rte_devargs *devargs,
 }
 
 static int
-mlx5_compress_dev_probe(struct mlx5_common_device *cdev)
+mlx5_compress_dev_probe(struct mlx5_common_device *cdev,
+			struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct rte_compressdev *compressdev;
 	struct mlx5_compress_priv *priv;
@@ -725,7 +721,7 @@ mlx5_compress_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = ENOTSUP;
 		return -ENOTSUP;
 	}
-	mlx5_compress_handle_devargs(cdev->dev->devargs, &devarg_prms, attr);
+	mlx5_compress_handle_devargs(mkvlist, &devarg_prms, attr);
 	compressdev = rte_compressdev_pmd_create(ibdev_name, cdev->dev,
 						 sizeof(*priv), &init_params);
 	if (compressdev == NULL) {
diff --git a/drivers/crypto/mlx5/mlx5_crypto.c b/drivers/crypto/mlx5/mlx5_crypto.c
index 421c23748a..e14f867797 100644
--- a/drivers/crypto/mlx5/mlx5_crypto.c
+++ b/drivers/crypto/mlx5/mlx5_crypto.c
@@ -722,8 +722,6 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
 	int ret;
 	int i;
 
-	if (strcmp(key, "class") == 0)
-		return 0;
 	if (strcmp(key, "wcs_file") == 0) {
 		file = fopen(val, "rb");
 		if (file == NULL) {
@@ -763,48 +761,44 @@ mlx5_crypto_args_check_handler(const char *key, const char *val, void *opaque)
 		attr->credential_pointer = (uint32_t)tmp;
 	} else if (strcmp(key, "keytag") == 0) {
 		devarg_prms->keytag = tmp;
-	} else {
-		DRV_LOG(WARNING, "Invalid key %s.", key);
 	}
 	return 0;
 }
 
 static int
-mlx5_crypto_parse_devargs(struct rte_devargs *devargs,
+mlx5_crypto_parse_devargs(struct mlx5_kvargs_ctrl *mkvlist,
 			  struct mlx5_crypto_devarg_params *devarg_prms)
 {
 	struct mlx5_devx_crypto_login_attr *attr = &devarg_prms->login_attr;
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"credential_id",
+		"import_kek_id",
+		"keytag",
+		"max_segs_num",
+		"wcs_file",
+		NULL,
+	};
 
 	/* Default values. */
 	attr->credential_pointer = 0;
 	attr->session_import_kek_ptr = 0;
 	devarg_prms->keytag = 0;
 	devarg_prms->max_segs_num = 8;
-	if (devargs == NULL) {
+	if (mkvlist == NULL) {
 		DRV_LOG(ERR,
-	"No login devargs in order to enable crypto operations in the device.");
-		rte_errno = EINVAL;
-		return -1;
-	}
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL) {
-		DRV_LOG(ERR, "Failed to parse devargs.");
+			"No login devargs in order to enable crypto operations in the device.");
 		rte_errno = EINVAL;
 		return -1;
 	}
-	if (rte_kvargs_process(kvlist, NULL, mlx5_crypto_args_check_handler,
-			   devarg_prms) != 0) {
+	if (mlx5_kvargs_process(mkvlist, params, mlx5_crypto_args_check_handler,
+				devarg_prms) != 0) {
 		DRV_LOG(ERR, "Devargs handler function Failed.");
-		rte_kvargs_free(kvlist);
 		rte_errno = EINVAL;
 		return -1;
 	}
-	rte_kvargs_free(kvlist);
 	if (devarg_prms->login_devarg == false) {
 		DRV_LOG(ERR,
-	"No login credential devarg in order to enable crypto operations "
-	"in the device.");
+			"No login credential devarg in order to enable crypto operations in the device.");
 		rte_errno = EINVAL;
 		return -1;
 	}
@@ -887,7 +881,8 @@ mlx5_crypto_configure_wqe_size(struct mlx5_crypto_priv *priv,
 }
 
 static int
-mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
+mlx5_crypto_dev_probe(struct mlx5_common_device *cdev,
+		      struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct rte_cryptodev *crypto_dev;
 	struct mlx5_devx_obj *login;
@@ -914,7 +909,7 @@ mlx5_crypto_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = ENOTSUP;
 		return -ENOTSUP;
 	}
-	ret = mlx5_crypto_parse_devargs(cdev->dev->devargs, &devarg_prms);
+	ret = mlx5_crypto_parse_devargs(mkvlist, &devarg_prms);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to parse devargs.");
 		return -rte_errno;
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index fa1af06f7d..ecf823da56 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1001,6 +1001,8 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
  *   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
@@ -1012,7 +1014,8 @@ mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
 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;
@@ -1062,6 +1065,12 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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;
 	}
@@ -1103,7 +1112,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		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);
@@ -1354,7 +1363,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 #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",
@@ -1840,6 +1849,8 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
  *   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.
@@ -1847,7 +1858,7 @@ mlx5_device_bond_pci_match(const char *ibdev_name,
 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;
 	/*
@@ -2217,7 +2228,8 @@ mlx5_os_pci_probe_pf(struct mlx5_common_device *cdev,
 	for (i = 0; i != ns; ++i) {
 		uint32_t restore;
 
-		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da);
+		list[i].eth_dev = mlx5_dev_spawn(cdev->dev, &list[i], &eth_da,
+						 mkvlist);
 		if (!list[i].eth_dev) {
 			if (rte_errno != EBUSY && rte_errno != EEXIST)
 				break;
@@ -2329,12 +2341,15 @@ mlx5_os_parse_eth_devargs(struct rte_device *dev,
  *
  * @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 };
@@ -2349,7 +2364,7 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev)
 		/* 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, &eth_da,
-						   eth_da.ports[p]);
+						   eth_da.ports[p], mkvlist);
 			if (ret)
 				break;
 		}
@@ -2362,14 +2377,15 @@ mlx5_os_pci_probe(struct mlx5_common_device *cdev)
 			mlx5_net_remove(cdev);
 		}
 	} else {
-		ret = mlx5_os_pci_probe_pf(cdev, &eth_da, 0);
+		ret = mlx5_os_pci_probe_pf(cdev, &eth_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 };
@@ -2394,7 +2410,7 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
 	spawn.ifindex = ret;
 	spawn.cdev = cdev;
 	/* Spawn device. */
-	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da);
+	eth_dev = mlx5_dev_spawn(dev, &spawn, &eth_da, mkvlist);
 	if (eth_dev == NULL)
 		return -rte_errno;
 	/* Post create. */
@@ -2415,12 +2431,15 @@ mlx5_os_auxiliary_probe(struct mlx5_common_device *cdev)
  *
  * @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;
 
@@ -2432,16 +2451,16 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			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);
 }
 
 /**
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 02ddc87313..9f65a8f901 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -43,9 +43,6 @@
 
 #define MLX5_ETH_DRIVER_NAME mlx5_eth
 
-/* Driver type key for new device global syntax. */
-#define MLX5_DRIVER_KEY "driver"
-
 /* Device parameter to enable RX completion queue compression. */
 #define MLX5_RXQ_CQE_COMP_EN "rxq_cqe_comp_en"
 
@@ -94,12 +91,6 @@
 /* Device parameter to enable multi-packet send WQEs. */
 #define MLX5_TXQ_MPW_EN "txq_mpw_en"
 
-/*
- * Device parameter to force doorbell register mapping
- * to non-cahed region eliminating the extra write memory barrier.
- */
-#define MLX5_TX_DB_NC "tx_db_nc"
-
 /*
  * Device parameter to include 2 dsegs in the title WQEBB.
  * Deprecated, ignored.
@@ -152,9 +143,6 @@
 /* Activate Netlink support in VF mode. */
 #define MLX5_VF_NL_EN "vf_nl_en"
 
-/* Enable extending memsegs when creating a MR. */
-#define MLX5_MR_EXT_MEMSEG_EN "mr_ext_memseg_en"
-
 /* Select port representors to instantiate. */
 #define MLX5_REPRESENTOR "representor"
 
@@ -173,17 +161,12 @@
 /* Flow memory reclaim mode. */
 #define MLX5_RECLAIM_MEM "reclaim_mem_mode"
 
-/* The default memory allocator used in PMD. */
-#define MLX5_SYS_MEM_EN "sys_mem_en"
 /* Decap will be used or not. */
 #define MLX5_DECAP_EN "decap_en"
 
 /* Device parameter to configure allow or prevent duplicate rules pattern. */
 #define MLX5_ALLOW_DUPLICATE_PATTERN "allow_duplicate_pattern"
 
-/* Device parameter to configure implicit registration of mempool memory. */
-#define MLX5_MR_MEMPOOL_REG_EN "mr_mempool_reg_en"
-
 /* Device parameter to configure the delay drop when creating Rxqs. */
 #define MLX5_DELAY_DROP "delay_drop"
 
@@ -1255,8 +1238,8 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
  *
  * @param sh
  *   Pointer to shared device context.
- * @param devargs
- *   Device arguments structure.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  * @param config
  *   Pointer to shared device configuration structure.
  *
@@ -1265,10 +1248,23 @@ mlx5_dev_args_check_handler(const char *key, const char *val, void *opaque)
  */
 static int
 mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
-				struct rte_devargs *devargs,
+				struct mlx5_kvargs_ctrl *mkvlist,
 				struct mlx5_sh_config *config)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		MLX5_TX_PP,
+		MLX5_TX_SKEW,
+		MLX5_L3_VXLAN_EN,
+		MLX5_VF_NL_EN,
+		MLX5_DV_ESW_EN,
+		MLX5_DV_FLOW_EN,
+		MLX5_DV_XMETA_EN,
+		MLX5_LACP_BY_USER,
+		MLX5_RECLAIM_MEM,
+		MLX5_DECAP_EN,
+		MLX5_ALLOW_DUPLICATE_PATTERN,
+		NULL,
+	};
 	int ret = 0;
 
 	/* Default configuration. */
@@ -1278,19 +1274,10 @@ mlx5_shared_dev_ctx_args_config(struct mlx5_dev_ctx_shared *sh,
 	config->dv_flow_en = 1;
 	config->decap_en = 1;
 	config->allow_duplicate_pattern = 1;
-	/* Parse device parameters. */
-	if (devargs != NULL) {
-		kvlist = rte_kvargs_parse(devargs->args, NULL);
-		if (kvlist == NULL) {
-			DRV_LOG(ERR,
-				"Failed to parse shared device arguments.");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
+	if (mkvlist != NULL) {
 		/* Process parameters. */
-		ret = rte_kvargs_process(kvlist, NULL,
-					 mlx5_dev_args_check_handler, config);
-		rte_kvargs_free(kvlist);
+		ret = mlx5_kvargs_process(mkvlist, params,
+					  mlx5_dev_args_check_handler, config);
 		if (ret) {
 			DRV_LOG(ERR, "Failed to process device arguments: %s",
 				strerror(rte_errno));
@@ -1398,13 +1385,16 @@ mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
  *
  * @param[in] spawn
  *   Pointer to the device attributes (name, port, etc).
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  *
  * @return
  *   Pointer to mlx5_dev_ctx_shared object on success,
  *   otherwise NULL and rte_errno is set.
  */
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+			  struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_dev_ctx_shared *sh;
 	int err = 0;
@@ -1443,8 +1433,7 @@ mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn)
 		DRV_LOG(ERR, "Fail to configure device capabilities.");
 		goto error;
 	}
-	err = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
-					      &sh->config);
+	err = mlx5_shared_dev_ctx_args_config(sh, mkvlist, &sh->config);
 	if (err) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
@@ -2107,15 +2096,7 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 	signed long tmp;
 
 	/* No-op, port representors are processed in mlx5_dev_spawn(). */
-	if (!strcmp(MLX5_DRIVER_KEY, key) || !strcmp(MLX5_REPRESENTOR, key) ||
-	    !strcmp(MLX5_SYS_MEM_EN, key) || !strcmp(MLX5_TX_DB_NC, key) ||
-	    !strcmp(MLX5_MR_MEMPOOL_REG_EN, key) || !strcmp(MLX5_TX_PP, key) ||
-	    !strcmp(MLX5_MR_EXT_MEMSEG_EN, key) || !strcmp(MLX5_TX_SKEW, key) ||
-	    !strcmp(MLX5_RECLAIM_MEM, key) || !strcmp(MLX5_DECAP_EN, key) ||
-	    !strcmp(MLX5_ALLOW_DUPLICATE_PATTERN, key) ||
-	    !strcmp(MLX5_L3_VXLAN_EN, key) || !strcmp(MLX5_VF_NL_EN, key) ||
-	    !strcmp(MLX5_DV_ESW_EN, key) || !strcmp(MLX5_DV_FLOW_EN, key) ||
-	    !strcmp(MLX5_DV_XMETA_EN, key) || !strcmp(MLX5_LACP_BY_USER, key))
+	if (!strcmp(MLX5_REPRESENTOR, key))
 		return 0;
 	errno = 0;
 	tmp = strtol(val, NULL, 0);
@@ -2181,17 +2162,11 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
 		config->max_dump_files_num = tmp;
 	} else if (strcmp(MLX5_LRO_TIMEOUT_USEC, key) == 0) {
 		config->lro_timeout = tmp;
-	} else if (strcmp(RTE_DEVARGS_KEY_CLASS, key) == 0) {
-		DRV_LOG(DEBUG, "class argument is %s.", val);
 	} else if (strcmp(MLX5_HP_BUF_SIZE, key) == 0) {
 		config->log_hp_size = tmp;
 	} else if (strcmp(MLX5_DELAY_DROP, key) == 0) {
 		config->std_delay_drop = !!(tmp & MLX5_DELAY_DROP_STANDARD);
 		config->hp_delay_drop = !!(tmp & MLX5_DELAY_DROP_HAIRPIN);
-	} else {
-		DRV_LOG(WARNING,
-			"%s: unknown parameter, maybe it's for another class.",
-			key);
 	}
 	return 0;
 }
@@ -2201,8 +2176,8 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
  *
  * @param priv
  *   Pointer to shared device context.
- * @param devargs
- *   Device arguments structure.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control, can be NULL if there is no devargs.
  * @param config
  *   Pointer to port configuration structure.
  *
@@ -2210,13 +2185,38 @@ mlx5_port_args_check_handler(const char *key, const char *val, void *opaque)
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
 int
-mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+mlx5_port_args_config(struct mlx5_priv *priv, struct mlx5_kvargs_ctrl *mkvlist,
 		      struct mlx5_port_config *config)
 {
-	struct rte_kvargs *kvlist;
 	struct mlx5_hca_attr *hca_attr = &priv->sh->cdev->config.hca_attr;
 	struct mlx5_dev_cap *dev_cap = &priv->sh->dev_cap;
 	bool devx = priv->sh->cdev->config.devx;
+	const char **params = (const char *[]){
+		MLX5_RXQ_CQE_COMP_EN,
+		MLX5_RXQ_PKT_PAD_EN,
+		MLX5_RX_MPRQ_EN,
+		MLX5_RX_MPRQ_LOG_STRIDE_NUM,
+		MLX5_RX_MPRQ_LOG_STRIDE_SIZE,
+		MLX5_RX_MPRQ_MAX_MEMCPY_LEN,
+		MLX5_RXQS_MIN_MPRQ,
+		MLX5_TXQ_INLINE,
+		MLX5_TXQ_INLINE_MIN,
+		MLX5_TXQ_INLINE_MAX,
+		MLX5_TXQ_INLINE_MPW,
+		MLX5_TXQS_MIN_INLINE,
+		MLX5_TXQS_MAX_VEC,
+		MLX5_TXQ_MPW_EN,
+		MLX5_TXQ_MPW_HDR_DSEG_EN,
+		MLX5_TXQ_MAX_INLINE_LEN,
+		MLX5_TX_VEC_EN,
+		MLX5_RX_VEC_EN,
+		MLX5_REPRESENTOR,
+		MLX5_MAX_DUMP_FILES_NUM,
+		MLX5_LRO_TIMEOUT_USEC,
+		MLX5_HP_BUF_SIZE,
+		MLX5_DELAY_DROP,
+		NULL,
+	};
 	int ret = 0;
 
 	/* Default configuration. */
@@ -2234,19 +2234,10 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
 	config->log_hp_size = MLX5_ARG_UNSET;
 	config->std_delay_drop = 0;
 	config->hp_delay_drop = 0;
-	/* Parse device parameters. */
-	if (devargs != NULL) {
-		kvlist = rte_kvargs_parse(devargs->args, NULL);
-		if (kvlist == NULL) {
-			DRV_LOG(ERR,
-				"Failed to parse device arguments.");
-			rte_errno = EINVAL;
-			return -rte_errno;
-		}
+	if (mkvlist != NULL) {
 		/* Process parameters. */
-		ret = rte_kvargs_process(kvlist, NULL,
-					 mlx5_port_args_check_handler, config);
-		rte_kvargs_free(kvlist);
+		ret = mlx5_kvargs_process(mkvlist, params,
+					  mlx5_port_args_check_handler, config);
 		if (ret) {
 			DRV_LOG(ERR, "Failed to process port arguments: %s",
 				strerror(rte_errno));
@@ -2349,6 +2340,85 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
 	return 0;
 }
 
+/**
+ * Print the key for device argument.
+ *
+ * It is "dummy" handler whose whole purpose is to enable using
+ * mlx5_kvargs_process() function which set devargs as used.
+ *
+ * @param key
+ *   Key argument.
+ * @param val
+ *   Value associated with key, unused.
+ * @param opaque
+ *   Unused, can be NULL.
+ *
+ * @return
+ *   0 on success, function cannot fail.
+ */
+static int
+mlx5_dummy_handler(const char *key, const char *val, void *opaque)
+{
+	DRV_LOG(DEBUG, "\tKey: \"%s\" is set as used.", key);
+	RTE_SET_USED(opaque);
+	RTE_SET_USED(val);
+	return 0;
+}
+
+/**
+ * Set requested devargs as used when device is already spawned.
+ *
+ * It is necessary since it is valid to ask probe again for existing device,
+ * if its devargs don't assign as used, mlx5_kvargs_validate() will fail.
+ *
+ * @param name
+ *   Name of the existing device.
+ * @param port_id
+ *   Port identifier of the device.
+ * @param mkvlist
+ *   Pointer to mlx5 kvargs control to sign as used.
+ */
+void
+mlx5_port_args_set_used(const char *name, uint16_t port_id,
+			struct mlx5_kvargs_ctrl *mkvlist)
+{
+	const char **params = (const char *[]){
+		MLX5_RXQ_CQE_COMP_EN,
+		MLX5_RXQ_PKT_PAD_EN,
+		MLX5_RX_MPRQ_EN,
+		MLX5_RX_MPRQ_LOG_STRIDE_NUM,
+		MLX5_RX_MPRQ_LOG_STRIDE_SIZE,
+		MLX5_RX_MPRQ_MAX_MEMCPY_LEN,
+		MLX5_RXQS_MIN_MPRQ,
+		MLX5_TXQ_INLINE,
+		MLX5_TXQ_INLINE_MIN,
+		MLX5_TXQ_INLINE_MAX,
+		MLX5_TXQ_INLINE_MPW,
+		MLX5_TXQS_MIN_INLINE,
+		MLX5_TXQS_MAX_VEC,
+		MLX5_TXQ_MPW_EN,
+		MLX5_TXQ_MPW_HDR_DSEG_EN,
+		MLX5_TXQ_MAX_INLINE_LEN,
+		MLX5_TX_VEC_EN,
+		MLX5_RX_VEC_EN,
+		MLX5_REPRESENTOR,
+		MLX5_MAX_DUMP_FILES_NUM,
+		MLX5_LRO_TIMEOUT_USEC,
+		MLX5_HP_BUF_SIZE,
+		MLX5_DELAY_DROP,
+		NULL,
+	};
+
+	/* Secondary process should not handle devargs. */
+	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+		return;
+	MLX5_ASSERT(mkvlist != NULL);
+	DRV_LOG(DEBUG, "Ethernet device \"%s\" for port %u "
+		"already exists, set devargs as used:", name, port_id);
+	/* This function cannot fail with this handler. */
+	mlx5_kvargs_process(mkvlist, params, mlx5_dummy_handler, NULL);
+}
+
 /**
  * Check sibling device configurations when probing again.
  *
@@ -2357,12 +2427,15 @@ mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
  *
  * @param cdev
  *   Pointer to mlx5 device structure.
+ * @param 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_probe_again_args_validate(struct mlx5_common_device *cdev)
+mlx5_probe_again_args_validate(struct mlx5_common_device *cdev,
+			       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_dev_ctx_shared *sh = NULL;
 	struct mlx5_sh_config *config;
@@ -2391,8 +2464,7 @@ mlx5_probe_again_args_validate(struct mlx5_common_device *cdev)
 	 * Creates a temporary IB context configure structure according to new
 	 * devargs attached in probing again.
 	 */
-	ret = mlx5_shared_dev_ctx_args_config(sh, sh->cdev->dev->devargs,
-					      config);
+	ret = mlx5_shared_dev_ctx_args_config(sh, mkvlist, config);
 	if (ret) {
 		DRV_LOG(ERR, "Failed to process device configure: %s",
 			strerror(rte_errno));
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 95910aba1b..35ea3fb47c 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1541,16 +1541,21 @@ void mlx5_age_event_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_rt_timestamp_config(struct mlx5_dev_ctx_shared *sh,
 			      struct mlx5_hca_attr *hca_attr);
 struct mlx5_dev_ctx_shared *
-mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn);
+mlx5_alloc_shared_dev_ctx(const struct mlx5_dev_spawn_data *spawn,
+			  struct mlx5_kvargs_ctrl *mkvlist);
 void mlx5_free_shared_dev_ctx(struct mlx5_dev_ctx_shared *sh);
 int mlx5_dev_ctx_shared_mempool_subscribe(struct rte_eth_dev *dev);
 void mlx5_free_table_hash_list(struct mlx5_priv *priv);
 int mlx5_alloc_table_hash_list(struct mlx5_priv *priv);
 void mlx5_set_min_inline(struct mlx5_priv *priv);
 void mlx5_set_metadata_mask(struct rte_eth_dev *dev);
-int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev);
-int mlx5_port_args_config(struct mlx5_priv *priv, struct rte_devargs *devargs,
+int mlx5_probe_again_args_validate(struct mlx5_common_device *cdev,
+				   struct mlx5_kvargs_ctrl *mkvlist);
+int mlx5_port_args_config(struct mlx5_priv *priv,
+			  struct mlx5_kvargs_ctrl *mkvlist,
 			  struct mlx5_port_config *config);
+void mlx5_port_args_set_used(const char *name, uint16_t port_id,
+			     struct mlx5_kvargs_ctrl *mkvlist);
 bool mlx5_flex_parser_ecpri_exist(struct rte_eth_dev *dev);
 int mlx5_flex_parser_ecpri_alloc(struct rte_eth_dev *dev);
 void mlx5_flow_counter_mode_config(struct rte_eth_dev *dev);
@@ -1811,7 +1816,8 @@ void mlx5_flow_meter_rxq_flush(struct rte_eth_dev *dev);
 struct rte_pci_driver;
 int mlx5_os_capabilities_prepare(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_free_shared_dr(struct mlx5_priv *priv);
-int mlx5_os_net_probe(struct mlx5_common_device *cdev);
+int mlx5_os_net_probe(struct mlx5_common_device *cdev,
+		      struct mlx5_kvargs_ctrl *mkvlist);
 void mlx5_os_dev_shared_handler_install(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_dev_shared_handler_uninstall(struct mlx5_dev_ctx_shared *sh);
 void mlx5_os_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
diff --git a/drivers/net/mlx5/windows/mlx5_os.c b/drivers/net/mlx5/windows/mlx5_os.c
index 52be589083..c7bb81549e 100644
--- a/drivers/net/mlx5/windows/mlx5_os.c
+++ b/drivers/net/mlx5/windows/mlx5_os.c
@@ -284,6 +284,8 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  *   Backing DPDK device.
  * @param spawn
  *   Verbs device parameters (name, port, switch_info) to spawn.
+ * @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
@@ -293,7 +295,8 @@ mlx5_os_set_nonblock_channel_fd(int fd)
  */
 static struct rte_eth_dev *
 mlx5_dev_spawn(struct rte_device *dpdk_dev,
-	       struct mlx5_dev_spawn_data *spawn)
+	       struct mlx5_dev_spawn_data *spawn,
+	       struct mlx5_kvargs_ctrl *mkvlist)
 {
 	const struct mlx5_switch_info *switch_info = &spawn->info;
 	struct mlx5_dev_ctx_shared *sh = NULL;
@@ -314,7 +317,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		return NULL;
 	}
 	DRV_LOG(DEBUG, "naming Ethernet device \"%s\"", name);
-	sh = mlx5_alloc_shared_dev_ctx(spawn);
+	sh = mlx5_alloc_shared_dev_ctx(spawn, mkvlist);
 	if (!sh)
 		return NULL;
 	if (!sh->config.dv_flow_en) {
@@ -386,7 +389,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 		own_domain_id = 1;
 	}
 	/* 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",
@@ -770,14 +773,17 @@ mlx5_os_set_allmulti(struct rte_eth_dev *dev, int enable)
  *
  * This function spawns Ethernet devices out of a given device.
  *
- * @param[in] dev
+ * @param[in] cdev
  *   Pointer to the common 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)
 {
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(cdev->dev);
 	struct mlx5_dev_spawn_data spawn = {
@@ -805,7 +811,7 @@ mlx5_os_net_probe(struct mlx5_common_device *cdev)
 			strerror(rte_errno));
 		return -rte_errno;
 	}
-	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn);
+	spawn.eth_dev = mlx5_dev_spawn(cdev->dev, &spawn, mkvlist);
 	if (!spawn.eth_dev)
 		return -rte_errno;
 	restore = spawn.eth_dev->data->dev_flags;
diff --git a/drivers/regex/mlx5/mlx5_regex.c b/drivers/regex/mlx5/mlx5_regex.c
index 48e39f6b88..9f79c6907c 100644
--- a/drivers/regex/mlx5/mlx5_regex.c
+++ b/drivers/regex/mlx5/mlx5_regex.c
@@ -67,7 +67,8 @@ mlx5_regex_get_name(char *name, struct rte_device *dev)
 }
 
 static int
-mlx5_regex_dev_probe(struct mlx5_common_device *cdev)
+mlx5_regex_dev_probe(struct mlx5_common_device *cdev,
+		     struct mlx5_kvargs_ctrl *mkvlist __rte_unused)
 {
 	struct mlx5_regex_priv *priv = NULL;
 	struct mlx5_hca_attr *attr = &cdev->config.hca_attr;
diff --git a/drivers/vdpa/mlx5/mlx5_vdpa.c b/drivers/vdpa/mlx5/mlx5_vdpa.c
index 8dfaba791d..749c9d097c 100644
--- a/drivers/vdpa/mlx5/mlx5_vdpa.c
+++ b/drivers/vdpa/mlx5/mlx5_vdpa.c
@@ -443,8 +443,6 @@ mlx5_vdpa_args_check_handler(const char *key, const char *val, void *opaque)
 	unsigned long tmp;
 	int n_cores = sysconf(_SC_NPROCESSORS_ONLN);
 
-	if (strcmp(key, RTE_DEVARGS_KEY_CLASS) == 0)
-		return 0;
 	errno = 0;
 	tmp = strtoul(val, NULL, 0);
 	if (errno) {
@@ -471,28 +469,33 @@ mlx5_vdpa_args_check_handler(const char *key, const char *val, void *opaque)
 		priv->hw_max_latency_us = (uint32_t)tmp;
 	} else if (strcmp(key, "hw_max_pending_comp") == 0) {
 		priv->hw_max_pending_comp = (uint32_t)tmp;
-	} else {
-		DRV_LOG(WARNING, "Invalid key %s.", key);
 	}
 	return 0;
 }
 
 static void
-mlx5_vdpa_config_get(struct rte_devargs *devargs, struct mlx5_vdpa_priv *priv)
+mlx5_vdpa_config_get(struct mlx5_kvargs_ctrl *mkvlist,
+		     struct mlx5_vdpa_priv *priv)
 {
-	struct rte_kvargs *kvlist;
+	const char **params = (const char *[]){
+		"event_core",
+		"event_mode",
+		"event_us",
+		"hw_latency_mode",
+		"hw_max_latency_us",
+		"hw_max_pending_comp",
+		"no_traffic_time",
+		NULL,
+	};
 
 	priv->event_mode = MLX5_VDPA_EVENT_MODE_FIXED_TIMER;
 	priv->event_us = 0;
 	priv->event_core = -1;
 	priv->no_traffic_max = MLX5_VDPA_DEFAULT_NO_TRAFFIC_MAX;
-	if (devargs == NULL)
-		return;
-	kvlist = rte_kvargs_parse(devargs->args, NULL);
-	if (kvlist == NULL)
+	if (mkvlist == NULL)
 		return;
-	rte_kvargs_process(kvlist, NULL, mlx5_vdpa_args_check_handler, priv);
-	rte_kvargs_free(kvlist);
+	mlx5_kvargs_process(mkvlist, params, mlx5_vdpa_args_check_handler,
+			    priv);
 	if (!priv->event_us &&
 	    priv->event_mode == MLX5_VDPA_EVENT_MODE_DYNAMIC_TIMER)
 		priv->event_us = MLX5_VDPA_DEFAULT_TIMER_STEP_US;
@@ -502,7 +505,8 @@ mlx5_vdpa_config_get(struct rte_devargs *devargs, struct mlx5_vdpa_priv *priv)
 }
 
 static int
-mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev)
+mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev,
+		    struct mlx5_kvargs_ctrl *mkvlist)
 {
 	struct mlx5_vdpa_priv *priv = NULL;
 	struct mlx5_hca_attr *attr = &cdev->config.hca_attr;
@@ -555,7 +559,7 @@ mlx5_vdpa_dev_probe(struct mlx5_common_device *cdev)
 		rte_errno = rte_errno ? rte_errno : EINVAL;
 		goto error;
 	}
-	mlx5_vdpa_config_get(cdev->dev->devargs, priv);
+	mlx5_vdpa_config_get(mkvlist, priv);
 	SLIST_INIT(&priv->mr_list);
 	pthread_mutex_init(&priv->vq_config_lock, NULL);
 	pthread_mutex_lock(&priv_list_lock);
-- 
2.25.1


^ permalink raw reply	[flat|nested] 43+ messages in thread

* RE: [PATCH v2 00/20] mlx5: refactor devargs management
  2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
                     ` (19 preceding siblings ...)
  2022-02-14  9:35   ` [PATCH v2 20/20] common/mlx5: refactor devargs management Michael Baum
@ 2022-02-21  8:54   ` Raslan Darawsheh
  20 siblings, 0 replies; 43+ messages in thread
From: Raslan Darawsheh @ 2022-02-21  8:54 UTC (permalink / raw)
  To: Michael Baum, dev; +Cc: Matan Azrad, Slava Ovsiienko

Hi,

> -----Original Message-----
> From: Michael Baum <michaelba@nvidia.com>
> Sent: Monday, February 14, 2022 11:35 AM
> To: dev@dpdk.org
> Cc: Matan Azrad <matan@nvidia.com>; Raslan Darawsheh
> <rasland@nvidia.com>; Slava Ovsiienko <viacheslavo@nvidia.com>
> Subject: [PATCH v2 00/20] mlx5: refactor devargs management
> 
> v2: rebase + fix coverity issue.
> 
> These patches rearrange the management of the devargs on two different
> levels.
> 
> The first splits the net driver's devargs into two categories,
> device-dependent devargs and port-dependent devargs.
> Arguments that depend on the device are updated once in the creation of
> the shared device context structure, and do not change even if the user
> has sent new devargs in the probe again. In contrast, the arguments that
> depend on the port are updated separately for each port.
> 
> The second layer deals with the parsing of devargs in the common driver.
> The common driver once parses the devargs into a dictionary, then sends
> it to all the drivers that will use it during the their probing. Each
> driver updates within dictionary which keys it has used, then the common
> driver checks the updated dictionary and reports about unknown devargs.
> 
> Michael Baum (20):
>   net/mlx5: fix wrong check sibling device config mismatch
>   net/mlx5: fix ineffective metadata argument adjustment
>   net/mlx5: fix wrong place of ASO CT object release
>   net/mlx5: fix inconsistency errno update in SH creation
>   net/mlx5: remove declaration duplications
>   net/mlx5: remove checking devargs duplication
>   net/mlx5: remove HCA attr structure duplication
>   net/mlx5: remove DevX flag duplication
>   net/mlx5: remove Verbs query device duplication
>   common/mlx5: share VF checking function
>   net/mlx5: share realtime timestamp configure
>   net/mlx5: share counter config function
>   net/mlx5: add E-switch mode flag
>   net/mlx5: rearrange device attribute structure
>   net/mlx5: concentrate all device configurations
>   net/mlx5: add share device context config structure
>   net/mlx5: using function to detect operation by DevX
>   net/mlx5: separate per port configuration
>   common/mlx5: add check for common devargs in probing again
>   common/mlx5: refactor devargs management
> 
>  drivers/common/mlx5/mlx5_common.c       | 345 +++++++--
>  drivers/common/mlx5/mlx5_common.h       |  51 +-
>  drivers/common/mlx5/mlx5_common_pci.c   |  18 +
>  drivers/common/mlx5/version.map         |   3 +
>  drivers/compress/mlx5/mlx5_compress.c   |  38 +-
>  drivers/crypto/mlx5/mlx5_crypto.c       |  39 +-
>  drivers/net/mlx5/linux/mlx5_flow_os.c   |   3 +-
>  drivers/net/mlx5/linux/mlx5_os.c        | 887 +++++++++---------------
>  drivers/net/mlx5/linux/mlx5_verbs.c     |   9 +-
>  drivers/net/mlx5/linux/mlx5_vlan_os.c   |   3 +-
>  drivers/net/mlx5/mlx5.c                 | 872 +++++++++++++++++------
>  drivers/net/mlx5/mlx5.h                 | 216 +++---
>  drivers/net/mlx5/mlx5_devx.c            |  19 +-
>  drivers/net/mlx5/mlx5_ethdev.c          |  31 +-
>  drivers/net/mlx5/mlx5_flow.c            |  50 +-
>  drivers/net/mlx5/mlx5_flow.h            |   2 +-
>  drivers/net/mlx5/mlx5_flow_dv.c         |  93 ++-
>  drivers/net/mlx5/mlx5_flow_flex.c       |   4 +-
>  drivers/net/mlx5/mlx5_flow_meter.c      |  14 +-
>  drivers/net/mlx5/mlx5_rxmode.c          |   8 +-
>  drivers/net/mlx5/mlx5_rxq.c             |  49 +-
>  drivers/net/mlx5/mlx5_trigger.c         |  35 +-
>  drivers/net/mlx5/mlx5_tx.c              |   2 +-
>  drivers/net/mlx5/mlx5_txpp.c            |  14 +-
>  drivers/net/mlx5/mlx5_txq.c             |  62 +-
>  drivers/net/mlx5/mlx5_vlan.c            |   4 +-
>  drivers/net/mlx5/windows/mlx5_flow_os.c |   2 +-
>  drivers/net/mlx5/windows/mlx5_os.c      | 342 +++------
>  drivers/regex/mlx5/mlx5_regex.c         |   3 +-
>  drivers/vdpa/mlx5/mlx5_vdpa.c           |  32 +-
>  30 files changed, 1842 insertions(+), 1408 deletions(-)
> 
> --
> 2.25.1

Series applied to next-net-mlx,

Kindest regards,
Raslan Darawsheh

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2022-02-21  8:54 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-27 15:39 [PATCH 00/20] mlx5: refactor devargs management Michael Baum
2022-01-27 15:39 ` [PATCH 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
2022-01-27 15:39 ` [PATCH 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
2022-01-27 15:39 ` [PATCH 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
2022-01-27 15:39 ` [PATCH 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
2022-01-27 15:39 ` [PATCH 05/20] net/mlx5: remove declaration duplications Michael Baum
2022-01-27 15:39 ` [PATCH 06/20] net/mlx5: remove checking devargs duplication Michael Baum
2022-01-27 15:39 ` [PATCH 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
2022-01-27 15:39 ` [PATCH 08/20] net/mlx5: remove DevX flag duplication Michael Baum
2022-01-27 15:39 ` [PATCH 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
2022-01-27 15:39 ` [PATCH 10/20] common/mlx5: share VF checking function Michael Baum
2022-01-27 15:39 ` [PATCH 11/20] net/mlx5: share realtime timestamp configure Michael Baum
2022-01-27 15:39 ` [PATCH 12/20] net/mlx5: share counter config function Michael Baum
2022-01-27 15:39 ` [PATCH 13/20] net/mlx5: add E-switch mode flag Michael Baum
2022-01-27 15:39 ` [PATCH 14/20] net/mlx5: rearrange device attribute structure Michael Baum
2022-01-27 15:39 ` [PATCH 15/20] net/mlx5: concentrate all device configurations Michael Baum
2022-01-27 15:39 ` [PATCH 16/20] net/mlx5: add share device context config structure Michael Baum
2022-01-27 15:39 ` [PATCH 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
2022-01-27 15:39 ` [PATCH 18/20] net/mlx5: separate per port configuration Michael Baum
2022-01-27 15:39 ` [PATCH 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
2022-01-27 15:39 ` [PATCH 20/20] common/mlx5: refactor devargs management Michael Baum
2022-02-14  9:34 ` [PATCH v2 00/20] mlx5: " Michael Baum
2022-02-14  9:34   ` [PATCH v2 01/20] net/mlx5: fix wrong check sibling device config mismatch Michael Baum
2022-02-14  9:34   ` [PATCH v2 02/20] net/mlx5: fix ineffective metadata argument adjustment Michael Baum
2022-02-14  9:34   ` [PATCH v2 03/20] net/mlx5: fix wrong place of ASO CT object release Michael Baum
2022-02-14  9:34   ` [PATCH v2 04/20] net/mlx5: fix inconsistency errno update in SH creation Michael Baum
2022-02-14  9:34   ` [PATCH v2 05/20] net/mlx5: remove declaration duplications Michael Baum
2022-02-14  9:34   ` [PATCH v2 06/20] net/mlx5: remove checking devargs duplication Michael Baum
2022-02-14  9:34   ` [PATCH v2 07/20] net/mlx5: remove HCA attr structure duplication Michael Baum
2022-02-14  9:34   ` [PATCH v2 08/20] net/mlx5: remove DevX flag duplication Michael Baum
2022-02-14  9:35   ` [PATCH v2 09/20] net/mlx5: remove Verbs query device duplication Michael Baum
2022-02-14  9:35   ` [PATCH v2 10/20] common/mlx5: share VF checking function Michael Baum
2022-02-14  9:35   ` [PATCH v2 11/20] net/mlx5: share realtime timestamp configure Michael Baum
2022-02-14  9:35   ` [PATCH v2 12/20] net/mlx5: share counter config function Michael Baum
2022-02-14  9:35   ` [PATCH v2 13/20] net/mlx5: add E-switch mode flag Michael Baum
2022-02-14  9:35   ` [PATCH v2 14/20] net/mlx5: rearrange device attribute structure Michael Baum
2022-02-14  9:35   ` [PATCH v2 15/20] net/mlx5: concentrate all device configurations Michael Baum
2022-02-14  9:35   ` [PATCH v2 16/20] net/mlx5: add share device context config structure Michael Baum
2022-02-14  9:35   ` [PATCH v2 17/20] net/mlx5: using function to detect operation by DevX Michael Baum
2022-02-14  9:35   ` [PATCH v2 18/20] net/mlx5: separate per port configuration Michael Baum
2022-02-14  9:35   ` [PATCH v2 19/20] common/mlx5: add check for common devargs in probing again Michael Baum
2022-02-14  9:35   ` [PATCH v2 20/20] common/mlx5: refactor devargs management Michael Baum
2022-02-21  8:54   ` [PATCH v2 00/20] mlx5: " Raslan Darawsheh

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).