config->udp_dport = cfg->dst_port;
 }
 
-static int mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp,
-                                   unsigned int parsing_depth,
-                                   __be16 udp_dport)
+static int __mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp,
+                                     unsigned int parsing_depth,
+                                     __be16 udp_dport)
 {
        char mprs_pl[MLXSW_REG_MPRS_LEN];
 
        return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
 }
 
+static int mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp,
+                                   __be16 udp_dport)
+{
+       int parsing_depth = mlxsw_sp->nve->inc_parsing_depth_refs ?
+                               MLXSW_SP_NVE_VXLAN_PARSING_DEPTH :
+                               MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH;
+
+       return __mlxsw_sp_nve_parsing_set(mlxsw_sp, parsing_depth, udp_dport);
+}
+
+static int
+__mlxsw_sp_nve_inc_parsing_depth_get(struct mlxsw_sp *mlxsw_sp,
+                                    __be16 udp_dport)
+{
+       int err;
+
+       mlxsw_sp->nve->inc_parsing_depth_refs++;
+
+       err = mlxsw_sp_nve_parsing_set(mlxsw_sp, udp_dport);
+       if (err)
+               goto err_nve_parsing_set;
+       return 0;
+
+err_nve_parsing_set:
+       mlxsw_sp->nve->inc_parsing_depth_refs--;
+       return err;
+}
+
+static void
+__mlxsw_sp_nve_inc_parsing_depth_put(struct mlxsw_sp *mlxsw_sp,
+                                    __be16 udp_dport)
+{
+       mlxsw_sp->nve->inc_parsing_depth_refs--;
+       mlxsw_sp_nve_parsing_set(mlxsw_sp, udp_dport);
+}
+
+int mlxsw_sp_nve_inc_parsing_depth_get(struct mlxsw_sp *mlxsw_sp)
+{
+       __be16 udp_dport = mlxsw_sp->nve->config.udp_dport;
+
+       return __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, udp_dport);
+}
+
+void mlxsw_sp_nve_inc_parsing_depth_put(struct mlxsw_sp *mlxsw_sp)
+{
+       __be16 udp_dport = mlxsw_sp->nve->config.udp_dport;
+
+       __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, udp_dport);
+}
+
 static void
 mlxsw_sp_nve_vxlan_config_prepare(char *tngcr_pl,
                                  const struct mlxsw_sp_nve_config *config)
        struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
        int err;
 
-       err = mlxsw_sp_nve_parsing_set(mlxsw_sp,
-                                      MLXSW_SP_NVE_VXLAN_PARSING_DEPTH,
-                                      config->udp_dport);
+       err = __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, config->udp_dport);
        if (err)
                return err;
 
 err_rtdp_set:
        mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
 err_config_set:
-       mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
-                                config->udp_dport);
+       __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0);
        return err;
 }
 
        mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
                                         config->ul_proto, &config->ul_sip);
        mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
-       mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
-                                config->udp_dport);
+       __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0);
 }
 
 static int
        struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
        int err;
 
-       err = mlxsw_sp_nve_parsing_set(mlxsw_sp,
-                                      MLXSW_SP_NVE_VXLAN_PARSING_DEPTH,
-                                      config->udp_dport);
+       err = __mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp, config->udp_dport);
        if (err)
                return err;
 
 err_rtdp_set:
        mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
 err_config_set:
-       mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
-                                config->udp_dport);
+       __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0);
        return err;
 }
 
        mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
                                         config->ul_proto, &config->ul_sip);
        mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
-       mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
-                                config->udp_dport);
+       __mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp, 0);
 }
 
 const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
 
 {
        struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
        struct mlxsw_sp_port *tmp;
+       u16 orig_ing_types = 0;
+       u16 orig_egr_types = 0;
+       int err;
        int i;
 
        /* MTPPPC configures timestamping globally, not per port. Find the
         */
        for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) {
                tmp = mlxsw_sp->ports[i];
+               if (tmp) {
+                       orig_ing_types |= tmp->ptp.ing_types;
+                       orig_egr_types |= tmp->ptp.egr_types;
+               }
                if (tmp && tmp != mlxsw_sp_port) {
                        ing_types |= tmp->ptp.ing_types;
                        egr_types |= tmp->ptp.egr_types;
                }
        }
 
+       if ((ing_types || egr_types) && !(orig_egr_types || orig_egr_types)) {
+               err = mlxsw_sp_nve_inc_parsing_depth_get(mlxsw_sp);
+               if (err) {
+                       netdev_err(mlxsw_sp_port->dev, "Failed to increase parsing depth");
+                       return err;
+               }
+       }
+       if (!(ing_types || egr_types) && (orig_egr_types || orig_egr_types))
+               mlxsw_sp_nve_inc_parsing_depth_put(mlxsw_sp);
+
        return mlxsw_sp1_ptp_mtpppc_set(mlxsw_sp_port->mlxsw_sp,
                                       ing_types, egr_types);
 }