#define AT803X_MIN_DOWNSHIFT 2
 #define AT803X_MAX_DOWNSHIFT 9
 
+#define AT803X_MMD3_SMARTEEE_CTL1              0x805b
+#define AT803X_MMD3_SMARTEEE_CTL2              0x805c
+#define AT803X_MMD3_SMARTEEE_CTL3              0x805d
+#define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN       BIT(8)
+
 #define ATH9331_PHY_ID 0x004dd041
 #define ATH8030_PHY_ID 0x004dd076
 #define ATH8031_PHY_ID 0x004dd074
 struct at803x_priv {
        int flags;
 #define AT803X_KEEP_PLL_ENABLED        BIT(0)  /* don't turn off internal PLL */
+#define AT803X_DISABLE_SMARTEEE        BIT(1)
        u16 clk_25m_reg;
        u16 clk_25m_mask;
+       u8 smarteee_lpi_tw_1g;
+       u8 smarteee_lpi_tw_100m;
        struct regulator_dev *vddio_rdev;
        struct regulator_dev *vddh_rdev;
        struct regulator *vddio;
 {
        struct device_node *node = phydev->mdio.dev.of_node;
        struct at803x_priv *priv = phydev->priv;
-       u32 freq, strength;
+       u32 freq, strength, tw;
        unsigned int sel;
        int ret;
 
        if (!IS_ENABLED(CONFIG_OF_MDIO))
                return 0;
 
+       if (of_property_read_bool(node, "qca,disable-smarteee"))
+               priv->flags |= AT803X_DISABLE_SMARTEEE;
+
+       if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) {
+               if (!tw || tw > 255) {
+                       phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n");
+                       return -EINVAL;
+               }
+               priv->smarteee_lpi_tw_1g = tw;
+       }
+
+       if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) {
+               if (!tw || tw > 255) {
+                       phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n");
+                       return -EINVAL;
+               }
+               priv->smarteee_lpi_tw_100m = tw;
+       }
+
        ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
        if (!ret) {
                switch (freq) {
                regulator_disable(priv->vddio);
 }
 
+static int at803x_smarteee_config(struct phy_device *phydev)
+{
+       struct at803x_priv *priv = phydev->priv;
+       u16 mask = 0, val = 0;
+       int ret;
+
+       if (priv->flags & AT803X_DISABLE_SMARTEEE)
+               return phy_modify_mmd(phydev, MDIO_MMD_PCS,
+                                     AT803X_MMD3_SMARTEEE_CTL3,
+                                     AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0);
+
+       if (priv->smarteee_lpi_tw_1g) {
+               mask |= 0xff00;
+               val |= priv->smarteee_lpi_tw_1g << 8;
+       }
+       if (priv->smarteee_lpi_tw_100m) {
+               mask |= 0x00ff;
+               val |= priv->smarteee_lpi_tw_100m;
+       }
+       if (!mask)
+               return 0;
+
+       ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1,
+                            mask, val);
+       if (ret)
+               return ret;
+
+       return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3,
+                             AT803X_MMD3_SMARTEEE_CTL3_LPI_EN,
+                             AT803X_MMD3_SMARTEEE_CTL3_LPI_EN);
+}
+
 static int at803x_clk_out_config(struct phy_device *phydev)
 {
        struct at803x_priv *priv = phydev->priv;
        if (ret < 0)
                return ret;
 
+       ret = at803x_smarteee_config(phydev);
+       if (ret < 0)
+               return ret;
+
        ret = at803x_clk_out_config(phydev);
        if (ret < 0)
                return ret;