#include <linux/acpi.h>
 #include <linux/acpi_mdio.h>
+#include <linux/clk.h>
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/mdio.h>
 } __packed;
 
 #define MDIO_STAT_ENC          BIT(6)
-#define MDIO_STAT_CLKDIV(x)    (((x>>1) & 0xff) << 8)
+#define MDIO_STAT_CLKDIV(x)    (((x) & 0x1ff) << 7)
 #define MDIO_STAT_BSY          BIT(0)
 #define MDIO_STAT_RD_ER                BIT(1)
 #define MDIO_STAT_PRE_DIS      BIT(5)
 
 struct mdio_fsl_priv {
        struct  tgec_mdio_controller __iomem *mdio_base;
+       struct  clk *enet_clk;
+       u32     mdc_freq;
        bool    is_little_endian;
        bool    has_a009885;
        bool    has_a011043;
        return ret;
 }
 
+static int xgmac_mdio_set_mdc_freq(struct mii_bus *bus)
+{
+       struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
+       struct tgec_mdio_controller __iomem *regs = priv->mdio_base;
+       struct device *dev = bus->parent;
+       u32 mdio_stat, div;
+
+       if (device_property_read_u32(dev, "clock-frequency", &priv->mdc_freq))
+               return 0;
+
+       priv->enet_clk = devm_clk_get(dev, NULL);
+       if (IS_ERR(priv->enet_clk)) {
+               dev_err(dev, "Input clock unknown, not changing MDC frequency");
+               return PTR_ERR(priv->enet_clk);
+       }
+
+       div = ((clk_get_rate(priv->enet_clk) / priv->mdc_freq) - 1) / 2;
+       if (div < 5 || div > 0x1ff) {
+               dev_err(dev, "Requested MDC frequecy is out of range, ignoring");
+               return -EINVAL;
+       }
+
+       mdio_stat = xgmac_read32(®s->mdio_stat, priv->is_little_endian);
+       mdio_stat &= ~MDIO_STAT_CLKDIV(0x1ff);
+       mdio_stat |= MDIO_STAT_CLKDIV(div);
+       xgmac_write32(mdio_stat, ®s->mdio_stat, priv->is_little_endian);
+       return 0;
+}
+
 static void xgmac_mdio_set_suppress_preamble(struct mii_bus *bus)
 {
        struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv;
 
        xgmac_mdio_set_suppress_preamble(bus);
 
+       ret = xgmac_mdio_set_mdc_freq(bus);
+       if (ret)
+               return ret;
+
        fwnode = pdev->dev.fwnode;
        if (is_of_node(fwnode))
                ret = of_mdiobus_register(bus, to_of_node(fwnode));