u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS];
        u64 mdio_100base_tx;
        u64 mdio_100base_t1;
+       u64 pcs_base[SJA1105_MAX_NUM_PORTS];
 };
 
 struct sja1105_mdio_private {
 void sja1105_mdiobus_unregister(struct dsa_switch *ds);
 int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg);
 int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val);
+int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg);
+int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val);
 
 /* From sja1105_devlink.c */
 int sja1105_devlink_setup(struct dsa_switch *ds);
 
 #include <linux/of_mdio.h>
 #include "sja1105.h"
 
+#define SJA1110_PCS_BANK_REG           SJA1110_SPI_ADDR(0x3fc)
+
 int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
 {
        struct sja1105_mdio_private *mdio_priv = bus->priv;
        return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL);
 }
 
+int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg)
+{
+       struct sja1105_mdio_private *mdio_priv = bus->priv;
+       struct sja1105_private *priv = mdio_priv->priv;
+       const struct sja1105_regs *regs = priv->info->regs;
+       int offset, bank;
+       u64 addr;
+       u32 tmp;
+       u16 mmd;
+       int rc;
+
+       if (!(reg & MII_ADDR_C45))
+               return -EINVAL;
+
+       if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
+               return -ENODEV;
+
+       mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
+       addr = (mmd << 16) | (reg & GENMASK(15, 0));
+
+       if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1)
+               return NXP_SJA1110_XPCS_ID >> 16;
+       if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2)
+               return NXP_SJA1110_XPCS_ID & GENMASK(15, 0);
+
+       bank = addr >> 8;
+       offset = addr & GENMASK(7, 0);
+
+       /* This addressing scheme reserves register 0xff for the bank address
+        * register, so that can never be addressed.
+        */
+       if (WARN_ON(offset == 0xff))
+               return -ENODEV;
+
+       tmp = bank;
+
+       rc = sja1105_xfer_u32(priv, SPI_WRITE,
+                             regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
+                             &tmp, NULL);
+       if (rc < 0)
+               return rc;
+
+       rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset,
+                             &tmp, NULL);
+       if (rc < 0)
+               return rc;
+
+       return tmp & 0xffff;
+}
+
+int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+       struct sja1105_mdio_private *mdio_priv = bus->priv;
+       struct sja1105_private *priv = mdio_priv->priv;
+       const struct sja1105_regs *regs = priv->info->regs;
+       int offset, bank;
+       u64 addr;
+       u32 tmp;
+       u16 mmd;
+       int rc;
+
+       if (!(reg & MII_ADDR_C45))
+               return -EINVAL;
+
+       if (regs->pcs_base[phy] == SJA1105_RSV_ADDR)
+               return -ENODEV;
+
+       mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f;
+       addr = (mmd << 16) | (reg & GENMASK(15, 0));
+
+       bank = addr >> 8;
+       offset = addr & GENMASK(7, 0);
+
+       /* This addressing scheme reserves register 0xff for the bank address
+        * register, so that can never be addressed.
+        */
+       if (WARN_ON(offset == 0xff))
+               return -ENODEV;
+
+       tmp = bank;
+
+       rc = sja1105_xfer_u32(priv, SPI_WRITE,
+                             regs->pcs_base[phy] + SJA1110_PCS_BANK_REG,
+                             &tmp, NULL);
+       if (rc < 0)
+               return rc;
+
+       tmp = val;
+
+       return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset,
+                               &tmp, NULL);
+}
+
 enum sja1105_mdio_opcode {
        SJA1105_C45_ADDR = 0,
        SJA1105_C22 = 1,
 
        .ptpsyncts = SJA1110_SPI_ADDR(0x84),
        .mdio_100base_tx = 0x1c2400,
        .mdio_100base_t1 = 0x1c1000,
+       .pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000,
+                    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR,
+                    SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR},
 };
 
 const struct sja1105_info sja1105e_info = {
        .rxtstamp               = sja1110_rxtstamp,
        .txtstamp               = sja1110_txtstamp,
        .clocking_setup         = sja1110_clocking_setup,
+       .pcs_mdio_read          = sja1110_pcs_mdio_read,
+       .pcs_mdio_write         = sja1110_pcs_mdio_write,
        .port_speed             = {
                [SJA1105_SPEED_AUTO] = 0,
                [SJA1105_SPEED_10MBPS] = 4,
        .rxtstamp               = sja1110_rxtstamp,
        .txtstamp               = sja1110_txtstamp,
        .clocking_setup         = sja1110_clocking_setup,
+       .pcs_mdio_read          = sja1110_pcs_mdio_read,
+       .pcs_mdio_write         = sja1110_pcs_mdio_write,
        .port_speed             = {
                [SJA1105_SPEED_AUTO] = 0,
                [SJA1105_SPEED_10MBPS] = 4,
        .rxtstamp               = sja1110_rxtstamp,
        .txtstamp               = sja1110_txtstamp,
        .clocking_setup         = sja1110_clocking_setup,
+       .pcs_mdio_read          = sja1110_pcs_mdio_read,
+       .pcs_mdio_write         = sja1110_pcs_mdio_write,
        .port_speed             = {
                [SJA1105_SPEED_AUTO] = 0,
                [SJA1105_SPEED_10MBPS] = 4,
        .rxtstamp               = sja1110_rxtstamp,
        .txtstamp               = sja1110_txtstamp,
        .clocking_setup         = sja1110_clocking_setup,
+       .pcs_mdio_read          = sja1110_pcs_mdio_read,
+       .pcs_mdio_write         = sja1110_pcs_mdio_write,
        .port_speed             = {
                [SJA1105_SPEED_AUTO] = 0,
                [SJA1105_SPEED_10MBPS] = 4,