diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 92926c8..2635745 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -3926,6 +3926,8 @@ struct mlx5_flow_tunnel_info {
  *
  * @param[in] actions
  *   Pointer to the list of actions.
+ * @param[in] attr
+ *   Flow rule attributes.
  * @param[in] action
  *   The action to be check if exist.
  * @param[out] match_action_pos
@@ -3939,10 +3941,15 @@ struct mlx5_flow_tunnel_info {
  */
 static int
 flow_check_match_action(const struct rte_flow_action actions[],
+			const struct rte_flow_attr *attr,
 			enum rte_flow_action_type action,
 			int *match_action_pos, int *qrss_action_pos)
 {
+	const struct rte_flow_action_sample *sample;
 	int actions_n = 0;
+	int jump_flag = 0;
+	uint32_t ratio = 0;
+	int sub_type = 0;
 	int flag = 0;
 
 	*match_action_pos = -1;
@@ -3955,8 +3962,25 @@ struct mlx5_flow_tunnel_info {
 		if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE ||
 		    actions->type == RTE_FLOW_ACTION_TYPE_RSS)
 			*qrss_action_pos = actions_n;
+		if (actions->type == RTE_FLOW_ACTION_TYPE_JUMP)
+			jump_flag = 1;
+		if (actions->type == RTE_FLOW_ACTION_TYPE_SAMPLE) {
+			sample = actions->conf;
+			ratio = sample->ratio;
+			sub_type = ((const struct rte_flow_action *)
+					(sample->actions))->type;
+		}
 		actions_n++;
 	}
+	if (flag && action == RTE_FLOW_ACTION_TYPE_SAMPLE && attr->transfer) {
+		if (ratio == 1) {
+			/* JUMP Action not support for Mirroring;
+			 * Mirroring support multi-destination;
+			 */
+			if (!jump_flag && sub_type != RTE_FLOW_ACTION_TYPE_END)
+				flag = 0;
+		}
+	}
 	/* Count RTE_FLOW_ACTION_TYPE_END. */
 	return flag ? actions_n + 1 : 0;
 }
@@ -4508,7 +4532,7 @@ struct mlx5_flow_tunnel_info {
 	int ret = 0;
 
 	if (priv->sampler_en)
-		actions_n = flow_check_match_action(actions,
+		actions_n = flow_check_match_action(actions, attr,
 					RTE_FLOW_ACTION_TYPE_SAMPLE,
 					&sample_action_pos, &qrss_action_pos);
 	if (actions_n) {
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index ba816b6..9465a19 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -3324,6 +3324,8 @@ struct field_modify_info modify_tcp[] = {
 					    (dev, &res, dev_flow, error);
 }
 
+static int fdb_mirror;
+
 /**
  * Validate the modify-header actions.
  *
@@ -3351,6 +3353,12 @@ struct field_modify_info modify_tcp[] = {
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "can't have encap action before"
 					  " modify action");
+	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+					  "can't support sample action before"
+					  " modify action for E-Switch"
+					  " mirroring");
 	return 0;
 }
 
@@ -3674,6 +3682,12 @@ struct field_modify_info modify_tcp[] = {
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					  "jump with meter not support");
+	if ((action_flags & MLX5_FLOW_ACTION_SAMPLE) && fdb_mirror)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
+					  "E-Switch mirroring can't support"
+					  " Sample action and jump action in"
+					  " same flow now");
 	if (!action->conf)
 		return rte_flow_error_set(error, EINVAL,
 					  RTE_FLOW_ERROR_TYPE_ACTION_CONF,
@@ -4024,8 +4038,10 @@ struct field_modify_info modify_tcp[] = {
 	const struct rte_flow_action_sample *sample = action->conf;
 	const struct rte_flow_action *act;
 	uint64_t sub_action_flags = 0;
+	uint16_t queue_index = 0xFFFF;
 	int actions_n = 0;
 	int ret;
+	fdb_mirror = 0;
 
 	if (!sample)
 		return rte_flow_error_set(error, EINVAL,
@@ -4069,6 +4085,8 @@ struct field_modify_info modify_tcp[] = {
 							      attr, error);
 			if (ret < 0)
 				return ret;
+			queue_index = ((const struct rte_flow_action_queue *)
+							(act->conf))->index;
 			sub_action_flags |= MLX5_FLOW_ACTION_QUEUE;
 			++actions_n;
 			break;
@@ -4092,6 +4110,25 @@ struct field_modify_info modify_tcp[] = {
 			sub_action_flags |= MLX5_FLOW_ACTION_COUNT;
 			++actions_n;
 			break;
+		case RTE_FLOW_ACTION_TYPE_PORT_ID:
+			ret = flow_dv_validate_action_port_id(dev,
+							      sub_action_flags,
+							      act,
+							      attr,
+							      error);
+			if (ret)
+				return ret;
+			sub_action_flags |= MLX5_FLOW_ACTION_PORT_ID;
+			++actions_n;
+			break;
+		case RTE_FLOW_ACTION_TYPE_RAW_ENCAP:
+			ret = flow_dv_validate_action_raw_encap_decap
+				(dev, NULL, act->conf, attr, &sub_action_flags,
+				 &actions_n, error);
+			if (ret < 0)
+				return ret;
+			++actions_n;
+			break;
 		default:
 			return rte_flow_error_set(error, ENOTSUP,
 						  RTE_FLOW_ERROR_TYPE_ACTION,
@@ -4115,10 +4152,43 @@ struct field_modify_info modify_tcp[] = {
 					  "or E-Switch");
 	} else if (sample->actions->type != RTE_FLOW_ACTION_TYPE_END) {
 		MLX5_ASSERT(attr->transfer);
-		return rte_flow_error_set(error, ENOTSUP,
-					  RTE_FLOW_ERROR_TYPE_ACTION, NULL,
-					  "E-Switch doesn't support any "
-					  "optional action for sampling");
+		if (sample->ratio > 1)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "E-Switch doesn't support "
+						  "any optional action "
+						  "for sampling");
+		fdb_mirror = 1;
+		if (sub_action_flags & MLX5_FLOW_ACTION_QUEUE)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "unsupported action QUEUE");
+		if (!(sub_action_flags & MLX5_FLOW_ACTION_PORT_ID))
+			return rte_flow_error_set(error, EINVAL,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL,
+						  "E-Switch must has a dest "
+						  "port for mirroring");
+	}
+	/* Continue validation for Xcap actions.*/
+	if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) &&
+	    (queue_index == 0xFFFF ||
+	     mlx5_rxq_get_type(dev, queue_index) != MLX5_RXQ_TYPE_HAIRPIN)) {
+		if ((sub_action_flags & MLX5_FLOW_XCAP_ACTIONS) ==
+		     MLX5_FLOW_XCAP_ACTIONS)
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL, "encap and decap "
+						  "combination aren't "
+						  "supported");
+		if (!attr->transfer && attr->ingress && (sub_action_flags &
+							MLX5_FLOW_ACTION_ENCAP))
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION,
+						  NULL, "encap is not supported"
+						  " for ingress traffic");
 	}
 	return 0;
 }
