ctrl &= ~EEST;
 
        writel(ctrl, ioaddr + MTL_EST_CONTROL);
+
+       /* Configure EST interrupt */
+       if (cfg->enable)
+               ctrl = (IECGCE | IEHS | IEHF | IEBE | IECC);
+       else
+               ctrl = 0;
+
+       writel(ctrl, ioaddr + MTL_EST_INT_EN);
+
        return 0;
 }
 
+void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
+                         u32 txqcnt)
+{
+       u32 status, value, feqn, hbfq, hbfs, btrl;
+       u32 txqcnt_mask = (1 << txqcnt) - 1;
+
+       status = readl(ioaddr + MTL_EST_STATUS);
+
+       value = (CGCE | HLBS | HLBF | BTRE | SWLC);
+
+       /* Return if there is no error */
+       if (!(status & value))
+               return;
+
+       if (status & CGCE) {
+               /* Clear Interrupt */
+               writel(CGCE, ioaddr + MTL_EST_STATUS);
+       }
+
+       if (status & HLBS) {
+               value = readl(ioaddr + MTL_EST_SCH_ERR);
+               value &= txqcnt_mask;
+
+               /* Clear Interrupt */
+               writel(value, ioaddr + MTL_EST_SCH_ERR);
+
+               /* Collecting info to shows all the queues that has HLBS
+                * issue. The only way to clear this is to clear the
+                * statistic
+                */
+               if (net_ratelimit())
+                       netdev_err(dev, "EST: HLB(sched) Queue 0x%x\n", value);
+       }
+
+       if (status & HLBF) {
+               value = readl(ioaddr + MTL_EST_FRM_SZ_ERR);
+               feqn = value & txqcnt_mask;
+
+               value = readl(ioaddr + MTL_EST_FRM_SZ_CAP);
+               hbfq = (value & SZ_CAP_HBFQ_MASK(txqcnt)) >> SZ_CAP_HBFQ_SHIFT;
+               hbfs = value & SZ_CAP_HBFS_MASK;
+
+               /* Clear Interrupt */
+               writel(feqn, ioaddr + MTL_EST_FRM_SZ_ERR);
+
+               if (net_ratelimit())
+                       netdev_err(dev, "EST: HLB(size) Queue %u Size %u\n",
+                                  hbfq, hbfs);
+       }
+
+       if (status & BTRE) {
+               btrl = (status & BTRL) >> BTRL_SHIFT;
+
+               if (net_ratelimit())
+                       netdev_info(dev, "EST: BTR Error Loop Count %u\n",
+                                   btrl);
+
+               writel(BTRE, ioaddr + MTL_EST_STATUS);
+       }
+
+       if (status & SWLC) {
+               writel(SWLC, ioaddr + MTL_EST_STATUS);
+               netdev_info(dev, "EST: SWOL has been switched\n");
+       }
+}
+
 void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
                          bool enable)
 {
 
 #define PTOV_SHIFT                     24
 #define SSWL                           BIT(1)
 #define EEST                           BIT(0)
+
+#define MTL_EST_STATUS                 0x00000c58
+#define BTRL                           GENMASK(11, 8)
+#define BTRL_SHIFT                     8
+#define BTRL_MAX                       (0xF << BTRL_SHIFT)
+#define SWOL                           BIT(7)
+#define SWOL_SHIFT                     7
+#define CGCE                           BIT(4)
+#define HLBS                           BIT(3)
+#define HLBF                           BIT(2)
+#define BTRE                           BIT(1)
+#define SWLC                           BIT(0)
+
+#define MTL_EST_SCH_ERR                        0x00000c60
+#define MTL_EST_FRM_SZ_ERR             0x00000c64
+#define MTL_EST_FRM_SZ_CAP             0x00000c68
+#define SZ_CAP_HBFS_MASK               GENMASK(14, 0)
+#define SZ_CAP_HBFQ_SHIFT              16
+#define SZ_CAP_HBFQ_MASK(_val)         ({ typeof(_val) (val) = (_val); \
+                                       ((val) > 4 ? GENMASK(18, 16) :  \
+                                        (val) > 2 ? GENMASK(17, 16) :  \
+                                        BIT(16)); })
+
+#define MTL_EST_INT_EN                 0x00000c70
+#define IECGCE                         CGCE
+#define IEHS                           HLBS
+#define IEHF                           HLBF
+#define IEBE                           BTRE
+#define IECC                           SWLC
+
 #define MTL_EST_GCL_CONTROL            0x00000c80
 #define BTR_LOW                                0x0
 #define BTR_HIGH                       0x1
                           u32 sub_second_inc, u32 systime_flags);
 int dwmac5_est_configure(void __iomem *ioaddr, struct stmmac_est *cfg,
                         unsigned int ptp_rate);
+void dwmac5_est_irq_status(void __iomem *ioaddr, struct net_device *dev,
+                          u32 txqcnt);
 void dwmac5_fpe_configure(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
                          bool enable);
 
 
        void (*set_arp_offload)(struct mac_device_info *hw, bool en, u32 addr);
        int (*est_configure)(void __iomem *ioaddr, struct stmmac_est *cfg,
                             unsigned int ptp_rate);
+       void (*est_irq_status)(void __iomem *ioaddr, struct net_device *dev,
+                              u32 txqcnt);
        void (*fpe_configure)(void __iomem *ioaddr, u32 num_txq, u32 num_rxq,
                              bool enable);
 };
        stmmac_do_void_callback(__priv, mac, set_arp_offload, __args)
 #define stmmac_est_configure(__priv, __args...) \
        stmmac_do_callback(__priv, mac, est_configure, __args)
+#define stmmac_est_irq_status(__priv, __args...) \
+       stmmac_do_void_callback(__priv, mac, est_irq_status, __args)
 #define stmmac_fpe_configure(__priv, __args...) \
        stmmac_do_void_callback(__priv, mac, fpe_configure, __args)
 
 
        if (stmmac_safety_feat_interrupt(priv))
                return IRQ_HANDLED;
 
+       if (priv->dma_cap.estsel)
+               stmmac_est_irq_status(priv, priv->ioaddr, priv->dev, tx_cnt);
+
        /* To handle GMAC own interrupts */
        if ((priv->plat->has_gmac) || xmac) {
                int status = stmmac_host_irq_status(priv, priv->hw, &priv->xstats);