diff --git a/drivers/common/mlx5/mlx5_prm.h b/drivers/common/mlx5/mlx5_prm.h
index bced5a59dd..e13ca3cd22 100644
--- a/drivers/common/mlx5/mlx5_prm.h
+++ b/drivers/common/mlx5/mlx5_prm.h
@@ -864,6 +864,18 @@ enum modify_reg {
 	REG_C_11,
 };
 
+static __rte_always_inline uint8_t
+mlx5_regc_index(enum modify_reg regc_val)
+{
+	return (uint8_t)(regc_val - REG_C_0);
+}
+
+static __rte_always_inline enum modify_reg
+mlx5_regc_value(uint8_t regc_ix)
+{
+	return REG_C_0 + regc_ix;
+}
+
 /* Modification sub command. */
 struct mlx5_modification_cmd {
 	union {
diff --git a/drivers/net/mlx5/linux/mlx5_os.c b/drivers/net/mlx5/linux/mlx5_os.c
index d5ef695e6d..96d32d11d8 100644
--- a/drivers/net/mlx5/linux/mlx5_os.c
+++ b/drivers/net/mlx5/linux/mlx5_os.c
@@ -1328,14 +1328,14 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				 * Prefer REG_C_3 if it is available.
 				 */
 				if (reg_c_mask & (1 << (REG_C_3 - REG_C_0)))
-					priv->mtr_color_reg = REG_C_3;
+					sh->registers.mtr_color_reg = REG_C_3;
 				else
-					priv->mtr_color_reg = ffs(reg_c_mask)
-							      - 1 + REG_C_0;
+					sh->registers.mtr_color_reg =
+						ffs(reg_c_mask) - 1 + REG_C_0;
 				priv->mtr_en = 1;
 				priv->mtr_reg_share = hca_attr->qos.flow_meter;
 				DRV_LOG(DEBUG, "The REG_C meter uses is %d",
-					priv->mtr_color_reg);
+					sh->registers.mtr_color_reg);
 			}
 		}
 		if (hca_attr->qos.sup && hca_attr->qos.flow_meter_aso_sup) {
@@ -1360,7 +1360,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 			sh->tunnel_header_2_3 = 1;
 #endif
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_ASO
-		if (hca_attr->flow_hit_aso && priv->mtr_color_reg == REG_C_3) {
+		if (hca_attr->flow_hit_aso && sh->registers.mtr_color_reg == REG_C_3) {
 			sh->flow_hit_aso_en = 1;
 			err = mlx5_flow_aso_age_mng_init(sh);
 			if (err) {
@@ -1374,7 +1374,7 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
     defined (HAVE_MLX5_DR_ACTION_ASO_CT)
 		/* HWS create CT ASO SQ based on HWS configure queue number. */
 		if (sh->config.dv_flow_en != 2 &&
-		    hca_attr->ct_offload && priv->mtr_color_reg == REG_C_3) {
+		    hca_attr->ct_offload && sh->registers.mtr_color_reg == REG_C_3) {
 			err = mlx5_flow_aso_ct_mng_init(sh);
 			if (err) {
 				err = -err;
@@ -1618,8 +1618,8 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 				goto error;
 		}
 		/* Only HWS requires this information. */
-		flow_hw_init_tags_set(eth_dev);
-		flow_hw_init_flow_metadata_config(eth_dev);
+		if (sh->refcnt == 1)
+			flow_hw_init_tags_set(eth_dev);
 		if (priv->sh->config.dv_esw_en &&
 		    flow_hw_create_vport_action(eth_dev)) {
 			DRV_LOG(ERR, "port %u failed to create vport action",
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 08b7b03365..c13ce2c13c 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2173,10 +2173,6 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 	flow_hw_destroy_vport_action(dev);
 	flow_hw_resource_release(dev);
 	flow_hw_clear_port_info(dev);
-	if (priv->sh->config.dv_flow_en == 2) {
-		flow_hw_clear_flow_metadata_config();
-		flow_hw_clear_tags_set(dev);
-	}
 #endif
 	if (priv->rxq_privs != NULL) {
 		/* XXX race condition if mlx5_rx_burst() is still running. */
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index f3b872f59c..01cb21fc93 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -1373,6 +1373,14 @@ struct mlx5_hws_cnt_svc_mng {
 	struct mlx5_hws_aso_mng aso_mng __rte_cache_aligned;
 };
 
+#define MLX5_FLOW_HW_TAGS_MAX 8
+
+struct mlx5_dev_registers {
+	enum modify_reg mlx5_flow_hw_aso_tag;
+	enum modify_reg mtr_color_reg; /* Meter color match REG_C. */
+	enum modify_reg hw_avl_tags[MLX5_FLOW_HW_TAGS_MAX];
+};
+
 /*
  * Shared Infiniband device context for Master/Representors
  * which belong to same IB device with multiple IB ports.
@@ -1393,7 +1401,6 @@ struct mlx5_dev_ctx_shared {
 	uint32_t drop_action_check_flag:1; /* Check Flag for drop action. */
 	uint32_t flow_priority_check_flag:1; /* Check Flag for flow priority. */
 	uint32_t metadata_regc_check_flag:1; /* Check Flag for metadata REGC. */
-	uint32_t hws_tags:1; /* Check if tags info for HWS initialized. */
 	uint32_t shared_mark_enabled:1;
 	/* If mark action is enabled on Rxqs (shared E-Switch domain). */
 	uint32_t lag_rx_port_affinity_en:1;
@@ -1482,6 +1489,7 @@ struct mlx5_dev_ctx_shared {
 	uint32_t host_shaper_rate:8;
 	uint32_t lwm_triggered:1;
 	struct mlx5_hws_cnt_svc_mng *cnt_svc;
+	struct mlx5_dev_registers registers;
 	struct mlx5_dev_shared_port port[]; /* per device port data array. */
 };
 
@@ -1811,7 +1819,6 @@ struct mlx5_priv {
 	/* Hash table of Rx metadata register copy table. */
 	struct mlx5_mtr_config mtr_config; /* Meter configuration */
 	uint8_t mtr_sfx_reg; /* Meter prefix-suffix flow match REG_C. */
-	uint8_t mtr_color_reg; /* Meter color match REG_C. */
 	struct mlx5_legacy_flow_meters flow_meters; /* MTR list. */
 	struct mlx5_l3t_tbl *mtr_profile_tbl; /* Meter index lookup table. */
 	struct mlx5_flow_meter_profile *mtr_profile_arr; /* Profile array. */
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index 45a67607ed..3ddc3ba772 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -39,18 +39,6 @@
  */
 struct flow_hw_port_info mlx5_flow_hw_port_infos[RTE_MAX_ETHPORTS];
 
-/*
- * A global structure to save the available REG_C_x for tags usage.
- * The Meter color REG (ASO) and the last available one will be reserved
- * for PMD internal usage.
- * Since there is no "port" concept in the driver, it is assumed that the
- * available tags set will be the minimum intersection.
- * 3 - in FDB mode / 5 - in legacy mode
- */
-uint32_t mlx5_flow_hw_avl_tags_init_cnt;
-enum modify_reg mlx5_flow_hw_avl_tags[MLX5_FLOW_HW_TAGS_MAX] = {REG_NON};
-enum modify_reg mlx5_flow_hw_aso_tag;
-
 struct tunnel_default_miss_ctx {
 	uint16_t *queue;
 	__extension__
@@ -1320,6 +1308,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 {
 	struct mlx5_priv *priv = dev->data->dev_private;
 	struct mlx5_sh_config *config = &priv->sh->config;
+	struct mlx5_dev_registers *reg = &priv->sh->registers;
 	enum modify_reg start_reg;
 	bool skip_mtr_reg = false;
 
@@ -1375,23 +1364,23 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 		 * should use the meter color register for match.
 		 */
 		if (priv->mtr_reg_share)
-			return priv->mtr_color_reg;
+			return reg->mtr_color_reg;
 		else
-			return priv->mtr_color_reg != REG_C_2 ? REG_C_2 :
+			return reg->mtr_color_reg != REG_C_2 ? REG_C_2 :
 			       REG_C_3;
 	case MLX5_MTR_COLOR:
 	case MLX5_ASO_FLOW_HIT:
 	case MLX5_ASO_CONNTRACK:
 	case MLX5_SAMPLE_ID:
 		/* All features use the same REG_C. */
-		MLX5_ASSERT(priv->mtr_color_reg != REG_NON);
-		return priv->mtr_color_reg;
+		MLX5_ASSERT(reg->mtr_color_reg != REG_NON);
+		return reg->mtr_color_reg;
 	case MLX5_COPY_MARK:
 		/*
 		 * Metadata COPY_MARK register using is in meter suffix sub
 		 * flow while with meter. It's safe to share the same register.
 		 */
-		return priv->mtr_color_reg != REG_C_2 ? REG_C_2 : REG_C_3;
+		return reg->mtr_color_reg != REG_C_2 ? REG_C_2 : REG_C_3;
 	case MLX5_APP_TAG:
 		/*
 		 * If meter is enable, it will engage the register for color
@@ -1400,7 +1389,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 		 * match.
 		 * If meter is disable, free to use all available registers.
 		 */
-		start_reg = priv->mtr_color_reg != REG_C_2 ? REG_C_2 :
+		start_reg = reg->mtr_color_reg != REG_C_2 ? REG_C_2 :
 			    (priv->mtr_reg_share ? REG_C_3 : REG_C_4);
 		skip_mtr_reg = !!(priv->mtr_en && start_reg == REG_C_2);
 		if (id > (uint32_t)(REG_C_7 - start_reg))
@@ -1418,7 +1407,7 @@ mlx5_flow_get_reg_id(struct rte_eth_dev *dev,
 		 * color register.
 		 */
 		if (skip_mtr_reg && priv->sh->flow_mreg_c
-		    [id + start_reg - REG_C_0] >= priv->mtr_color_reg) {
+		    [id + start_reg - REG_C_0] >= reg->mtr_color_reg) {
 			if (id >= (uint32_t)(REG_C_7 - start_reg))
 				return rte_flow_error_set(error, EINVAL,
 						       RTE_FLOW_ERROR_TYPE_ITEM,
@@ -6491,7 +6480,7 @@ flow_sample_split_prep(struct rte_eth_dev *dev,
 		 * metadata regC is REG_NON, back to use application tag
 		 * index 0.
 		 */
-		if (unlikely(priv->mtr_color_reg == REG_NON))
+		if (unlikely(priv->sh->registers.mtr_color_reg == REG_NON))
 			ret = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG, 0, error);
 		else
 			ret = mlx5_flow_get_reg_id(dev, MLX5_SAMPLE_ID, 0, error);
diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h
index 9344b5178a..011db1fb75 100644
--- a/drivers/net/mlx5/mlx5_flow.h
+++ b/drivers/net/mlx5/mlx5_flow.h
@@ -1618,11 +1618,6 @@ struct flow_hw_port_info {
 
 extern struct flow_hw_port_info mlx5_flow_hw_port_infos[RTE_MAX_ETHPORTS];
 
-#define MLX5_FLOW_HW_TAGS_MAX 8
-extern uint32_t mlx5_flow_hw_avl_tags_init_cnt;
-extern enum modify_reg mlx5_flow_hw_avl_tags[];
-extern enum modify_reg mlx5_flow_hw_aso_tag;
-
 /*
  * Get metadata match tag and mask for given rte_eth_dev port.
  * Used in HWS rule creation.
@@ -1664,13 +1659,6 @@ flow_hw_get_wire_port(struct ibv_context *ibctx)
 }
 #endif
 
-extern uint32_t mlx5_flow_hw_flow_metadata_config_refcnt;
-extern uint8_t mlx5_flow_hw_flow_metadata_esw_en;
-extern uint8_t mlx5_flow_hw_flow_metadata_xmeta_en;
-
-void flow_hw_init_flow_metadata_config(struct rte_eth_dev *dev);
-void flow_hw_clear_flow_metadata_config(void);
-
 /*
  * Convert metadata or tag to the actual register.
  * META: Can only be used to match in the FDB in this stage, fixed C_1.
@@ -1681,12 +1669,14 @@ static __rte_always_inline int
 flow_hw_get_reg_id(struct rte_eth_dev *dev,
 		   enum rte_flow_item_type type, uint32_t id)
 {
-	RTE_SET_USED(dev);
+	struct mlx5_dev_ctx_shared *sh = MLX5_SH(dev);
+	struct mlx5_dev_registers *reg = &sh->registers;
+
 	switch (type) {
 	case RTE_FLOW_ITEM_TYPE_META:
 #ifdef HAVE_MLX5_HWS_SUPPORT
-		if (mlx5_flow_hw_flow_metadata_esw_en &&
-		    mlx5_flow_hw_flow_metadata_xmeta_en == MLX5_XMETA_MODE_META32_HWS) {
+		if (sh->config.dv_esw_en &&
+		    sh->config.dv_xmeta_en == MLX5_XMETA_MODE_META32_HWS) {
 			return REG_C_1;
 		}
 #endif
@@ -1702,12 +1692,12 @@ flow_hw_get_reg_id(struct rte_eth_dev *dev,
 		return REG_A;
 	case RTE_FLOW_ITEM_TYPE_CONNTRACK:
 	case RTE_FLOW_ITEM_TYPE_METER_COLOR:
-		return mlx5_flow_hw_aso_tag;
+		return reg->mlx5_flow_hw_aso_tag;
 	case RTE_FLOW_ITEM_TYPE_TAG:
 		if (id == MLX5_LINEAR_HASH_TAG_INDEX)
 			return REG_C_3;
 		MLX5_ASSERT(id < MLX5_FLOW_HW_TAGS_MAX);
-		return mlx5_flow_hw_avl_tags[id];
+		return reg->hw_avl_tags[id];
 	default:
 		return REG_NON;
 	}
@@ -1740,7 +1730,6 @@ void flow_hw_set_port_info(struct rte_eth_dev *dev);
 void flow_hw_clear_port_info(struct rte_eth_dev *dev);
 
 void flow_hw_init_tags_set(struct rte_eth_dev *dev);
-void flow_hw_clear_tags_set(struct rte_eth_dev *dev);
 
 int flow_hw_create_vport_action(struct rte_eth_dev *dev);
 void flow_hw_destroy_vport_action(struct rte_eth_dev *dev);
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index 05a374493d..024023abb5 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c
@@ -1919,7 +1919,8 @@ mlx5_flow_field_id_to_modify_info
 			off_be = (tag_index == MLX5_LINEAR_HASH_TAG_INDEX) ?
 				 16 - (data->offset + width) + 16 : data->offset;
 			if (priv->sh->config.dv_flow_en == 2)
-				reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_TAG,
+				reg = flow_hw_get_reg_id(dev,
+							 RTE_FLOW_ITEM_TYPE_TAG,
 							 data->level);
 			else
 				reg = mlx5_flow_get_reg_id(dev, MLX5_APP_TAG,
@@ -2025,7 +2026,7 @@ mlx5_flow_field_id_to_modify_info
 
 			if (priv->sh->config.dv_flow_en == 2)
 				reg = flow_hw_get_reg_id
-					(dev, RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+				(dev, RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
 			else
 				reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR,
 						       0, error);
@@ -3922,7 +3923,7 @@ flow_dv_validate_item_meter_color(struct rte_eth_dev *dev,
 	};
 	int ret;
 
-	if (priv->mtr_color_reg == REG_NON)
+	if (priv->sh->registers.mtr_color_reg == REG_NON)
 		return rte_flow_error_set(error, ENOTSUP,
 					  RTE_FLOW_ERROR_TYPE_ITEM, item,
 					  "meter color register"
@@ -8373,7 +8374,8 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr,
 			if (ret < 0)
 				return ret;
 			if ((action_flags & MLX5_FLOW_ACTION_SET_TAG) &&
-			    tag_id == 0 && priv->mtr_color_reg == REG_NON)
+			    tag_id == 0 &&
+			    priv->sh->registers.mtr_color_reg == REG_NON)
 				return rte_flow_error_set(error, EINVAL,
 					RTE_FLOW_ERROR_TYPE_ACTION, NULL,
 					"sample after tag action causes metadata tag index 0 corruption");
@@ -11057,7 +11059,8 @@ flow_dv_translate_item_meter_color(struct rte_eth_dev *dev, void *key,
 	if (!!(key_type & MLX5_SET_MATCHER_SW))
 		reg = mlx5_flow_get_reg_id(dev, MLX5_MTR_COLOR, 0, NULL);
 	else
-		reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+		reg = flow_hw_get_reg_id(dev,
+					 RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
 	if (reg == REG_NON)
 		return;
 	flow_dv_match_meta_reg(key, (enum modify_reg)reg, value, mask);
diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index d3f065e9c1..22cf412035 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -5654,7 +5654,9 @@ flow_hw_pattern_validate(struct rte_eth_dev *dev,
 			break;
 		case RTE_FLOW_ITEM_TYPE_METER_COLOR:
 		{
-			int reg = flow_hw_get_reg_id(dev, RTE_FLOW_ITEM_TYPE_METER_COLOR, 0);
+			int reg = flow_hw_get_reg_id(dev,
+						     RTE_FLOW_ITEM_TYPE_METER_COLOR,
+						     0);
 			if (reg == REG_NON)
 				return rte_flow_error_set(error, EINVAL,
 							  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
@@ -8456,126 +8458,29 @@ flow_hw_clear_port_info(struct rte_eth_dev *dev)
  */
 void flow_hw_init_tags_set(struct rte_eth_dev *dev)
 {
-	struct mlx5_priv *priv = dev->data->dev_private;
-	uint32_t meta_mode = priv->sh->config.dv_xmeta_en;
-	uint8_t masks = (uint8_t)priv->sh->cdev->config.hca_attr.set_reg_c;
-	uint32_t i, j;
-	uint8_t reg_off;
+	struct mlx5_dev_ctx_shared *sh = MLX5_SH(dev);
+	struct mlx5_dev_registers *reg = &sh->registers;
+	uint32_t meta_mode = sh->config.dv_xmeta_en;
+	uint8_t masks = (uint8_t)sh->cdev->config.hca_attr.set_reg_c;
 	uint8_t unset = 0;
-	uint8_t common_masks = 0;
+	uint32_t i, j;
 
 	/*
 	 * The CAPA is global for common device but only used in net.
 	 * It is shared per eswitch domain.
 	 */
-	if (!!priv->sh->hws_tags)
-		return;
-	unset |= 1 << (priv->mtr_color_reg - REG_C_0);
-	unset |= 1 << (REG_C_6 - REG_C_0);
-	if (priv->sh->config.dv_esw_en)
-		unset |= 1 << (REG_C_0 - REG_C_0);
+	unset |= 1 << mlx5_regc_index(reg->mtr_color_reg);
+	unset |= 1 << mlx5_regc_index(REG_C_6);
+	if (sh->config.dv_esw_en)
+		unset |= 1 << mlx5_regc_index(REG_C_0);
 	if (meta_mode == MLX5_XMETA_MODE_META32_HWS)
-		unset |= 1 << (REG_C_1 - REG_C_0);
+		unset |= 1 << mlx5_regc_index(REG_C_1);
 	masks &= ~unset;
-	/*
-	 * If available tag registers were previously calculated,
-	 * calculate a bitmask with an intersection of sets of:
-	 * - registers supported by current port,
-	 * - previously calculated available tag registers.
-	 */
-	if (mlx5_flow_hw_avl_tags_init_cnt) {
-		MLX5_ASSERT(mlx5_flow_hw_aso_tag == priv->mtr_color_reg);
-		for (i = 0; i < MLX5_FLOW_HW_TAGS_MAX; i++) {
-			if (mlx5_flow_hw_avl_tags[i] == REG_NON)
-				continue;
-			reg_off = mlx5_flow_hw_avl_tags[i] - REG_C_0;
-			if ((1 << reg_off) & masks)
-				common_masks |= (1 << reg_off);
-		}
-		if (common_masks != masks)
-			masks = common_masks;
-		else
-			goto after_avl_tags;
+	for (i = 0, j = 0; i < MLX5_FLOW_HW_TAGS_MAX; i++) {
+		if (!!((1 << i) & masks))
+			reg->hw_avl_tags[j++] = mlx5_regc_value(i);
 	}
-	j = 0;
-	for (i = 0; i < MLX5_FLOW_HW_TAGS_MAX; i++) {
-		if ((1 << i) & masks)
-			mlx5_flow_hw_avl_tags[j++] = (enum modify_reg)(i + (uint32_t)REG_C_0);
-	}
-	/* Clear the rest of unusable tag indexes. */
-	for (; j < MLX5_FLOW_HW_TAGS_MAX; j++)
-		mlx5_flow_hw_avl_tags[j] = REG_NON;
-after_avl_tags:
-	priv->sh->hws_tags = 1;
-	mlx5_flow_hw_aso_tag = (enum modify_reg)priv->mtr_color_reg;
-	mlx5_flow_hw_avl_tags_init_cnt++;
-}
-
-/*
- * Reset the available tag registers information to NONE.
- *
- * @param[in] dev
- *   Pointer to the rte_eth_dev structure.
- */
-void flow_hw_clear_tags_set(struct rte_eth_dev *dev)
-{
-	struct mlx5_priv *priv = dev->data->dev_private;
-
-	if (!priv->sh->hws_tags)
-		return;
-	priv->sh->hws_tags = 0;
-	mlx5_flow_hw_avl_tags_init_cnt--;
-	if (!mlx5_flow_hw_avl_tags_init_cnt)
-		memset(mlx5_flow_hw_avl_tags, REG_NON,
-		       sizeof(enum modify_reg) * MLX5_FLOW_HW_TAGS_MAX);
-}
-
-uint32_t mlx5_flow_hw_flow_metadata_config_refcnt;
-uint8_t mlx5_flow_hw_flow_metadata_esw_en;
-uint8_t mlx5_flow_hw_flow_metadata_xmeta_en;
-
-/**
- * Initializes static configuration of META flow items.
- *
- * As a temporary workaround, META flow item is translated to a register,
- * based on statically saved dv_esw_en and dv_xmeta_en device arguments.
- * It is a workaround for flow_hw_get_reg_id() where port specific information
- * is not available at runtime.
- *
- * Values of dv_esw_en and dv_xmeta_en device arguments are taken from the first opened port.
- * This means that each mlx5 port will use the same configuration for translation
- * of META flow items.
- *
- * @param[in] dev
- *    Pointer to Ethernet device.
- */
-void
-flow_hw_init_flow_metadata_config(struct rte_eth_dev *dev)
-{
-	uint32_t refcnt;
-
-	refcnt = __atomic_fetch_add(&mlx5_flow_hw_flow_metadata_config_refcnt, 1,
-				    __ATOMIC_RELAXED);
-	if (refcnt > 0)
-		return;
-	mlx5_flow_hw_flow_metadata_esw_en = MLX5_SH(dev)->config.dv_esw_en;
-	mlx5_flow_hw_flow_metadata_xmeta_en = MLX5_SH(dev)->config.dv_xmeta_en;
-}
-
-/**
- * Clears statically stored configuration related to META flow items.
- */
-void
-flow_hw_clear_flow_metadata_config(void)
-{
-	uint32_t refcnt;
-
-	refcnt = __atomic_fetch_sub(&mlx5_flow_hw_flow_metadata_config_refcnt, 1,
-				    __ATOMIC_RELAXED) - 1;
-	if (refcnt > 0)
-		return;
-	mlx5_flow_hw_flow_metadata_esw_en = 0;
-	mlx5_flow_hw_flow_metadata_xmeta_en = 0;
+	reg->mlx5_flow_hw_aso_tag = reg->mtr_color_reg;
 }
 
 static int
diff --git a/drivers/net/mlx5/mlx5_flow_meter.c b/drivers/net/mlx5/mlx5_flow_meter.c
index 14a435d157..eb88dfe39c 100644
--- a/drivers/net/mlx5/mlx5_flow_meter.c
+++ b/drivers/net/mlx5/mlx5_flow_meter.c
@@ -67,7 +67,7 @@ mlx5_flow_meter_action_create(struct mlx5_priv *priv,
 	val = (ebs_eir >> ASO_DSEG_EBS_MAN_OFFSET) & ASO_DSEG_MAN_MASK;
 	MLX5_SET(flow_meter_parameters, fmp, ebs_mantissa, val);
 	mtr_init.next_table = def_policy->sub_policy.tbl_rsc->obj;
-	mtr_init.reg_c_index = priv->mtr_color_reg - REG_C_0;
+	mtr_init.reg_c_index = priv->sh->registers.mtr_color_reg - REG_C_0;
 	mtr_init.flow_meter_parameter = fmp;
 	mtr_init.flow_meter_parameter_sz =
 		MLX5_ST_SZ_BYTES(flow_meter_parameters);
@@ -1597,6 +1597,7 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
 		uint64_t modify_bits, uint32_t active_state, uint32_t is_enable)
 {
 #ifdef HAVE_MLX5_DR_CREATE_ACTION_FLOW_METER
+	struct mlx5_dev_ctx_shared *sh = priv->sh;
 	uint32_t in[MLX5_ST_SZ_DW(flow_meter_parameters)] = { 0 };
 	uint32_t *attr;
 	struct mlx5dv_dr_flow_meter_attr mod_attr = { 0 };
@@ -1604,19 +1605,20 @@ mlx5_flow_meter_action_modify(struct mlx5_priv *priv,
 	struct mlx5_aso_mtr *aso_mtr = NULL;
 	uint32_t cbs_cir, ebs_eir, val;
 
-	if (priv->sh->meter_aso_en) {
+	if (sh->meter_aso_en) {
 		fm->is_enable = !!is_enable;
 		aso_mtr = container_of(fm, struct mlx5_aso_mtr, fm);
-		ret = mlx5_aso_meter_update_by_wqe(priv->sh, MLX5_HW_INV_QUEUE,
-						   aso_mtr, &priv->mtr_bulk, NULL, true);
+		ret = mlx5_aso_meter_update_by_wqe(sh, MLX5_HW_INV_QUEUE,
+						   aso_mtr, &priv->mtr_bulk,
+						   NULL, true);
 		if (ret)
 			return ret;
-		ret = mlx5_aso_mtr_wait(priv->sh, MLX5_HW_INV_QUEUE, aso_mtr);
+		ret = mlx5_aso_mtr_wait(sh, MLX5_HW_INV_QUEUE, aso_mtr);
 		if (ret)
 			return ret;
 	} else {
 		/* Fill command parameters. */
-		mod_attr.reg_c_index = priv->mtr_color_reg - REG_C_0;
+		mod_attr.reg_c_index = sh->registers.mtr_color_reg - REG_C_0;
 		mod_attr.flow_meter_parameter = in;
 		mod_attr.flow_meter_parameter_sz =
 				MLX5_ST_SZ_BYTES(flow_meter_parameters);
