diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 8d82c68569..be60038810 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1643,6 +1643,8 @@ struct mlx5_priv {
 	struct mlx5dr_action *hw_drop[2];
 	/* HW steering global tag action. */
 	struct mlx5dr_action *hw_tag[2];
+	/* HW steering create ongoing rte flow table list header. */
+	LIST_HEAD(flow_hw_tbl_ongo, rte_flow_template_table) flow_hw_tbl_ongo;
 	struct mlx5_indexed_pool *acts_ipool; /* Action data indexed pool. */
 	struct mlx5_hws_cnt_pool *hws_cpool; /* HW steering's counter pool. */
 #endif
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index cdea4076d8..746cf439fc 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -2398,4 +2398,6 @@ int mlx5_flow_pattern_validate(struct rte_eth_dev *dev,
 		const struct rte_flow_pattern_template_attr *attr,
 		const struct rte_flow_item items[],
 		struct rte_flow_error *error);
+int flow_hw_table_update(struct rte_eth_dev *dev,
+			 struct rte_flow_error *error);
 #endif /* RTE_PMD_MLX5_FLOW_H_ */
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 8891f4a4e3..fe40b02c49 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -992,11 +992,11 @@ flow_hw_cnt_compile(struct rte_eth_dev *dev, uint32_t  start_pos,
  *    Table on success, NULL otherwise and rte_errno is set.
  */
 static int
-flow_hw_actions_translate(struct rte_eth_dev *dev,
-			  const struct mlx5_flow_template_table_cfg *cfg,
-			  struct mlx5_hw_actions *acts,
-			  struct rte_flow_actions_template *at,
-			  struct rte_flow_error *error)
+__flow_hw_actions_translate(struct rte_eth_dev *dev,
+			    const struct mlx5_flow_template_table_cfg *cfg,
+			    struct mlx5_hw_actions *acts,
+			    struct rte_flow_actions_template *at,
+			    struct rte_flow_error *error)
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	const struct rte_flow_template_table_attr *table_attr = &cfg->attr;
@@ -1309,6 +1309,40 @@ flow_hw_actions_translate(struct rte_eth_dev *dev,
 				  "fail to create rte table");
 }
 
+/**
+ * Translate rte_flow actions to DR action.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] tbl
+ *   Pointer to the flow template table.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    0 on success, negative value otherwise and rte_errno is set.
+ */
+static int
+flow_hw_actions_translate(struct rte_eth_dev *dev,
+			  struct rte_flow_template_table *tbl,
+			  struct rte_flow_error *error)
+{
+	uint32_t i;
+
+	for (i = 0; i < tbl->nb_action_templates; i++) {
+		if (__flow_hw_actions_translate(dev, &tbl->cfg,
+						&tbl->ats[i].acts,
+						tbl->ats[i].action_template,
+						error))
+			goto err;
+	}
+	return 0;
+err:
+	while (i--)
+		__flow_hw_action_template_destroy(dev, &tbl->ats[i].acts);
+	return -1;
+}
+
 /**
  * Get shared indirect action.
  *
@@ -1837,6 +1871,10 @@ flow_hw_async_flow_create(struct rte_eth_dev *dev,
 	uint32_t acts_num, flow_idx;
 	int ret;
 
+	if (unlikely((!dev->data->dev_started))) {
+		rte_errno = EINVAL;
+		goto error;
+	}
 	if (unlikely(!priv->hw_q[queue].job_idx)) {
 		rte_errno = ENOMEM;
 		goto error;
@@ -2231,6 +2269,7 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	struct mlx5_list_entry *ge;
 	uint32_t i, max_tpl = MLX5_HW_TBL_MAX_ITEM_TEMPLATE;
 	uint32_t nb_flows = rte_align32pow2(attr->nb_flows);
+	bool port_started = !!dev->data->dev_started;
 	int err;
 
 	/* HWS layer accepts only 1 item template with root table. */
@@ -2295,21 +2334,26 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 			rte_errno = EINVAL;
 			goto at_error;
 		}
+		tbl->ats[i].action_template = action_templates[i];
 		LIST_INIT(&tbl->ats[i].acts.act_list);
-		err = flow_hw_actions_translate(dev, &tbl->cfg,
-						&tbl->ats[i].acts,
-						action_templates[i], error);
+		if (!port_started)
+			continue;
+		err = __flow_hw_actions_translate(dev, &tbl->cfg,
+						  &tbl->ats[i].acts,
+						  action_templates[i], error);
 		if (err) {
 			i++;
 			goto at_error;
 		}
-		tbl->ats[i].action_template = action_templates[i];
 	}
 	tbl->nb_action_templates = nb_action_templates;
 	tbl->type = attr->flow_attr.transfer ? MLX5DR_TABLE_TYPE_FDB :
 		    (attr->flow_attr.egress ? MLX5DR_TABLE_TYPE_NIC_TX :
 		    MLX5DR_TABLE_TYPE_NIC_RX);
-	LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+	if (port_started)
+		LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+	else
+		LIST_INSERT_HEAD(&priv->flow_hw_tbl_ongo, tbl, next);
 	return tbl;
 at_error:
 	while (i--) {
@@ -2339,6 +2383,33 @@ flow_hw_table_create(struct rte_eth_dev *dev,
 	return NULL;
 }
 
+/**
+ * Update flow template table.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    0 on success, negative value otherwise and rte_errno is set.
+ */
+int
+flow_hw_table_update(struct rte_eth_dev *dev,
+		     struct rte_flow_error *error)
+{
+	struct mlx5_priv *priv = dev->data->dev_private;
+	struct rte_flow_template_table *tbl;
+
+	while ((tbl = LIST_FIRST(&priv->flow_hw_tbl_ongo)) != NULL) {
+		if (flow_hw_actions_translate(dev, tbl, error))
+			return -1;
+		LIST_REMOVE(tbl, next);
+		LIST_INSERT_HEAD(&priv->flow_hw_tbl, tbl, next);
+	}
+	return 0;
+}
+
 /**
  * Translates group index specified by the user in @p attr to internal
  * group index.
@@ -4440,6 +4511,10 @@ flow_hw_resource_release(struct rte_eth_dev *dev)
 	if (!priv->dr_ctx)
 		return;
 	flow_hw_flush_all_ctrl_flows(dev);
+	while (!LIST_EMPTY(&priv->flow_hw_tbl_ongo)) {
+		tbl = LIST_FIRST(&priv->flow_hw_tbl_ongo);
+		flow_hw_table_destroy(dev, tbl, NULL);
+	}
 	while (!LIST_EMPTY(&priv->flow_hw_tbl)) {
 		tbl = LIST_FIRST(&priv->flow_hw_tbl);
 		flow_hw_table_destroy(dev, tbl, NULL);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index 9e458356a0..ab2b83a870 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1170,6 +1170,14 @@ mlx5_dev_start(struct rte_eth_dev *dev)
 			dev->data->port_id, rte_strerror(rte_errno));
 		goto error;
 	}
+	if (priv->sh->config.dv_flow_en == 2) {
+		ret = flow_hw_table_update(dev, NULL);
+		if (ret) {
+			DRV_LOG(ERR, "port %u failed to update HWS tables",
+				dev->data->port_id);
+			goto error;
+		}
+	}
 	ret = mlx5_traffic_enable(dev);
 	if (ret) {
 		DRV_LOG(ERR, "port %u failed to set defaults flows",
