diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 4f1093f..0ccc1c8 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -578,6 +578,55 @@ Run-time configuration
 
   Disabled by default.
 
+- ``dv_xmeta_en`` parameter [int]
+
+  A nonzero value enables extensive flow metadata support if device is
+  capable and driver supports it. This can enable extensive support of
+  ``MARK`` and ``META`` item of ``rte_flow``. The newly introduced
+  ``SET_TAG`` and ``SET_META`` actions do not depend on ``dv_xmeta_en``.
+
+  There are some possible configurations, depending on parameter value:
+
+  - 0, this is default value, defines the legacy mode, the ``MARK`` and
+    ``META`` related actions and items operate only within NIC Tx and
+    NIC Rx steering domains, no ``MARK`` and ``META`` information crosses
+    the domain boundaries. The ``MARK`` item is 24 bits wide, the ``META``
+    item is 32 bits wide and match supported on egress only.
+
+  - 1, this engages extensive metadata mode, the ``MARK`` and ``META``
+    related actions and items operate within all supported steering domains,
+    including FDB, ``MARK`` and ``META`` information may cross the domain
+    boundaries. The ``MARK`` item is 24 bits wide, the ``META`` item width
+    depends on kernel and firmware configurations and might be 0, 16 or
+    32 bits. Within NIC Tx domain ``META`` data width is 32 bits for
+    compatibility, the actual width of data transferred to the FDB domain
+    depends on kernel configuration and may be vary. The actual supported
+    width can be retrieved in runtime by series of rte_flow_validate()
+    trials.
+
+  - 2, this engages extensive metadata mode, the ``MARK`` and ``META``
+    related actions and items operate within all supported steering domains,
+    including FDB, ``MARK`` and ``META`` information may cross the domain
+    boundaries. The ``META`` item is 32 bits wide, the ``MARK`` item width
+    depends on kernel and firmware configurations and might be 0, 16 or
+    24 bits. The actual supported width can be retrieved in runtime by
+    series of rte_flow_validate() trials.
+
+  +------+-----------+-----------+-------------+-------------+
+  | Mode | ``MARK``  | ``META``  | ``META`` Tx | FDB/Through |
+  +======+===========+===========+=============+=============+
+  | 0    | 24 bits   | 32 bits   | 32 bits     | no          |
+  +------+-----------+-----------+-------------+-------------+
+  | 1    | 24 bits   | vary 0-32 | 32 bits     | yes         |
+  +------+-----------+-----------+-------------+-------------+
+  | 2    | vary 0-32 | 32 bits   | 32 bits     | yes         |
+  +------+-----------+-----------+-------------+-------------+
+
+  If there is no E-Switch configuration the ``dv_xmeta_en`` parameter is
+  ignored and the device is configured to operate in legacy mode (0).
+
+  Disabled by default (set to 0).
+
 - ``dv_flow_en`` parameter [int]
 
   A nonzero value enables the DV flow steering assuming it is supported
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 1b86b7b..943d0e8 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -125,6 +125,9 @@
 /* Activate DV flow steering. */
 #define MLX5_DV_FLOW_EN "dv_flow_en"
 
+/* Enable extensive flow metadata support. */
+#define MLX5_DV_XMETA_EN "dv_xmeta_en"
+
 /* Activate Netlink support in VF mode. */
 #define MLX5_VF_NL_EN "vf_nl_en"
 
@@ -1310,6 +1313,16 @@ struct mlx5_flow_id_pool *
 		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) {
+			DRV_LOG(WARNING, "invalid extensive "
+					 "metadata parameter");
+			rte_errno = EINVAL;
+			return -rte_errno;
+		}
+		config->dv_xmeta_en = tmp;
 	} else if (strcmp(MLX5_MR_EXT_MEMSEG_EN, key) == 0) {
 		config->mr_ext_memseg_en = !!tmp;
 	} else if (strcmp(MLX5_MAX_DUMP_FILES_NUM, key) == 0) {
@@ -1361,6 +1374,7 @@ struct mlx5_flow_id_pool *
 		MLX5_VF_NL_EN,
 		MLX5_DV_ESW_EN,
 		MLX5_DV_FLOW_EN,
+		MLX5_DV_XMETA_EN,
 		MLX5_MR_EXT_MEMSEG_EN,
 		MLX5_REPRESENTOR,
 		MLX5_MAX_DUMP_FILES_NUM,
@@ -1734,6 +1748,12 @@ struct mlx5_flow_id_pool *
 		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;
 }
 /**
@@ -2347,10 +2367,23 @@ struct mlx5_flow_id_pool *
 		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;
+	}
 	if (!mlx5_flow_ext_mreg_supported(eth_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) {
+			DRV_LOG(ERR, "metadata mode %u is not supported "
+				     "(no metadata registers available)",
+				     priv->config.dv_xmeta_en);
+			err = ENOTSUP;
+			goto error;
+		}
 	}
 	return eth_dev;
 error:
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 6b82c6d..e59f8f6 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -238,6 +238,7 @@ struct mlx5_dev_config {
 	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 swp:1; /* Tx generic tunnel checksum and TSO offload. */
 	unsigned int devx:1; /* Whether devx interface is available or not. */
 	unsigned int dest_tir:1; /* Whether advanced DR API is available. */
diff --git a/drivers/net/mlx5/mlx5_defs.h b/drivers/net/mlx5/mlx5_defs.h
index e36ab55..a77c430 100644
--- a/drivers/net/mlx5/mlx5_defs.h
+++ b/drivers/net/mlx5/mlx5_defs.h
@@ -141,6 +141,10 @@
 /* Cache size of mempool for Multi-Packet RQ. */
 #define MLX5_MPRQ_MP_CACHE_SZ 32U
 
+#define MLX5_XMETA_MODE_LEGACY 0
+#define MLX5_XMETA_MODE_META16 1
+#define MLX5_XMETA_MODE_META32 2
+
 /* Definition of static_assert found in /usr/include/assert.h */
 #ifndef HAVE_STATIC_ASSERT
 #define static_assert _Static_assert
diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h
index c17ba66..b405cb6 100644
--- a/drivers/net/mlx5/mlx5_prm.h
+++ b/drivers/net/mlx5/mlx5_prm.h
@@ -226,6 +226,9 @@
 /* Default mark value used when none is provided. */
 #define MLX5_FLOW_MARK_DEFAULT 0xffffff
 
+/* Default mark mask for metadata legacy mode. */
+#define MLX5_FLOW_MARK_MASK 0xffffff
+
 /* Maximum number of DS in WQE. Limited by 6-bit field. */
 #define MLX5_DSEG_MAX 63
 
