diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst
index 97261d6..ccf38b6 100644
--- a/doc/guides/nics/mlx5.rst
+++ b/doc/guides/nics/mlx5.rst
@@ -884,6 +884,16 @@ Driver options
 
   By default, the PMD will set this value to 0.
 
+- ``decap_en`` parameter [int]
+
+  The new devarg ``decap_en`` is introduced to provide the choice to the NICs
+  which does not support FCS (frame checksum) scattering for the tunnel
+  decapsulated packets. By set the devarg value 0 to force the FCS feature
+  enable and rejecting tunnel decap actions in the rte_flow engine for these
+  special NICs.
+
+  By default, the PMD will set this value to 1.
+
 .. _mlx5_firmware_config:
 
 Firmware configuration
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index 2dc57b2..37420cb 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -780,8 +780,6 @@
 		(config.hw_vlan_strip ? "" : "not "));
 	config.hw_fcs_strip = !!(sh->device_attr.raw_packet_caps &
 				 IBV_RAW_PACKET_CAP_SCATTER_FCS);
-	DRV_LOG(DEBUG, "FCS stripping configuration is %ssupported",
-		(config.hw_fcs_strip ? "" : "not "));
 #if defined(HAVE_IBV_WQ_FLAG_RX_END_PADDING)
 	hw_padding = !!sh->device_attr.rx_pad_end_addr_align;
 #elif defined(HAVE_IBV_WQ_FLAGS_PCI_WRITE_END_PADDING)
@@ -879,6 +877,15 @@
 		}
 #endif
 	}
+	/*
+	 * If HW has bug working with tunnel packet decapsulation and
+	 * scatter FCS, and decapsulation is needed, clear the hw_fcs_strip
+	 * bit. Then DEV_RX_OFFLOAD_KEEP_CRC bit will not be set anymore.
+	 */
+	if (config.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 "));
 	if (config.mprq.enabled && mprq) {
 		if (config.mprq.stride_num_n &&
 		    (config.mprq.stride_num_n > mprq_max_stride_num_n ||
@@ -1652,6 +1659,7 @@
 		},
 		.dv_esw_en = 1,
 		.dv_flow_en = 1,
+		.decap_en = 1,
 		.log_hp_size = MLX5_ARG_UNSET,
 	};
 	/* Device specific configuration. */
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 0c654ed..9daacaf 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -167,6 +167,9 @@
 /* Flow memory reclaim mode. */
 #define MLX5_RECLAIM_MEM "reclaim_mem_mode"
 
+/* Decap will be used or not. */
+#define MLX5_DECAP_EN "decap_en"
+
 static const char *MZ_MLX5_PMD_SHARED_DATA = "mlx5_pmd_shared_data";
 
 /* Shared memory between primary and secondary processes. */
@@ -1374,6 +1377,8 @@ struct mlx5_dev_ctx_shared *
 			return -rte_errno;
 		}
 		config->reclaim_mode = tmp;
+	} else if (strcmp(MLX5_DECAP_EN, key) == 0) {
+		config->decap_en = !!tmp;
 	} else {
 		DRV_LOG(WARNING, "%s: unknown parameter", key);
 		rte_errno = EINVAL;
@@ -1430,6 +1435,7 @@ struct mlx5_dev_ctx_shared *
 		MLX5_CLASS_ARG_NAME,
 		MLX5_HP_BUF_SIZE,
 		MLX5_RECLAIM_MEM,
+		MLX5_DECAP_EN,
 		NULL,
 	};
 	struct rte_kvargs *kvlist;
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 46e66eb..c7b6a84 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -216,6 +216,7 @@ struct mlx5_dev_config {
 	unsigned int devx:1; /* Whether devx interface is available or not. */
 	unsigned int dest_tir:1; /* Whether advanced DR API is available. */
 	unsigned int reclaim_mode:2; /* Memory reclaim mode. */
+	unsigned int decap_en:1; /* Whether decap will be used or not. */
 	struct {
 		unsigned int enabled:1; /* Whether MPRQ is enabled. */
 		unsigned int stride_num_n; /* Number of strides. */
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 8b5b683..37db7c5 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -2428,6 +2428,11 @@ struct field_modify_info modify_tcp[] = {
 {
 	const struct mlx5_priv *priv = dev->data->dev_private;
 
+	if (priv->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,
+					  "decap is not enabled");
 	if (action_flags & MLX5_FLOW_XCAP_ACTIONS)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
