/* Interrupt Source Register */
 #define LAN87XX_INTERRUPT_SOURCE                (0x18)
+#define LAN87XX_INTERRUPT_SOURCE_2              (0x08)
 
 /* Interrupt Mask Register */
 #define LAN87XX_INTERRUPT_MASK                  (0x19)
 #define LAN87XX_MASK_LINK_UP                    (0x0004)
 #define LAN87XX_MASK_LINK_DOWN                  (0x0002)
 
+#define LAN87XX_INTERRUPT_MASK_2                (0x09)
+#define LAN87XX_MASK_COMM_RDY                  BIT(10)
+
 /* MISC Control 1 Register */
 #define LAN87XX_CTRL_1                          (0x11)
 #define LAN87XX_MASK_RGMII_TXC_DLY_EN           (0x4000)
        int rc, val = 0;
 
        if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
-               /* unmask all source and clear them before enable */
-               rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, 0x7FFF);
+               /* clear all interrupt */
+               rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
+               if (rc < 0)
+                       return rc;
+
                rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
-               val = LAN87XX_MASK_LINK_UP | LAN87XX_MASK_LINK_DOWN;
+               if (rc < 0)
+                       return rc;
+
+               rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
+                                PHYACC_ATTR_BANK_MISC,
+                                LAN87XX_INTERRUPT_MASK_2, val);
+               if (rc < 0)
+                       return rc;
+
+               rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                                PHYACC_ATTR_BANK_MISC,
+                                LAN87XX_INTERRUPT_SOURCE_2, 0);
+               if (rc < 0)
+                       return rc;
+
+               /* enable link down and comm ready interrupt */
+               val = LAN87XX_MASK_LINK_DOWN;
                rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
+               if (rc < 0)
+                       return rc;
+
+               val = LAN87XX_MASK_COMM_RDY;
+               rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
+                                PHYACC_ATTR_BANK_MISC,
+                                LAN87XX_INTERRUPT_MASK_2, val);
        } else {
                rc = phy_write(phydev, LAN87XX_INTERRUPT_MASK, val);
-               if (rc)
+               if (rc < 0)
                        return rc;
 
                rc = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
+               if (rc < 0)
+                       return rc;
+
+               rc = access_ereg(phydev, PHYACC_ATTR_MODE_WRITE,
+                                PHYACC_ATTR_BANK_MISC,
+                                LAN87XX_INTERRUPT_MASK_2, val);
+               if (rc < 0)
+                       return rc;
+
+               rc = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                                PHYACC_ATTR_BANK_MISC,
+                                LAN87XX_INTERRUPT_SOURCE_2, 0);
        }
 
        return rc < 0 ? rc : 0;
 {
        int irq_status;
 
+       irq_status  = access_ereg(phydev, PHYACC_ATTR_MODE_READ,
+                                 PHYACC_ATTR_BANK_MISC,
+                                 LAN87XX_INTERRUPT_SOURCE_2, 0);
+       if (irq_status < 0) {
+               phy_error(phydev);
+               return IRQ_NONE;
+       }
+
        irq_status = phy_read(phydev, LAN87XX_INTERRUPT_SOURCE);
        if (irq_status < 0) {
                phy_error(phydev);