*/
 #include <linux/kernel.h>
 #include <linux/bitfield.h>
+#include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #define ADIN1300_CLOCK_STOP_REG                        0x9400
 #define ADIN1300_LPI_WAKE_ERR_CNT_REG          0xa000
 
+#define ADIN1300_GE_SOFT_RESET_REG             0xff0c
+#define   ADIN1300_GE_SOFT_RESET               BIT(0)
+
 #define ADIN1300_GE_RGMII_CFG_REG              0xff23
 #define   ADIN1300_GE_RGMII_RX_MSK             GENMASK(8, 6)
 #define   ADIN1300_GE_RGMII_RX_SEL(x)          \
        return genphy_read_status(phydev);
 }
 
+static int adin_soft_reset(struct phy_device *phydev)
+{
+       int rc;
+
+       /* The reset bit is self-clearing, set it and wait */
+       rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+                             ADIN1300_GE_SOFT_RESET_REG,
+                             ADIN1300_GE_SOFT_RESET);
+       if (rc < 0)
+               return rc;
+
+       msleep(10);
+
+       /* If we get a read error something may be wrong */
+       rc = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+                         ADIN1300_GE_SOFT_RESET_REG);
+
+       return rc < 0 ? rc : 0;
+}
+
 static struct phy_driver adin_driver[] = {
        {
                PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
                .name           = "ADIN1200",
                .config_init    = adin_config_init,
+               .soft_reset     = adin_soft_reset,
                .config_aneg    = adin_config_aneg,
                .read_status    = adin_read_status,
                .ack_interrupt  = adin_phy_ack_intr,
                PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
                .name           = "ADIN1300",
                .config_init    = adin_config_init,
+               .soft_reset     = adin_soft_reset,
                .config_aneg    = adin_config_aneg,
                .read_status    = adin_read_status,
                .ack_interrupt  = adin_phy_ack_intr,