/* slave device setup *******************************************************/
 static int dsa_slave_phy_connect(struct dsa_slave_priv *p,
-                                struct net_device *slave_dev)
+                                struct net_device *slave_dev,
+                                int addr)
 {
        struct dsa_switch *ds = p->parent;
 
-       p->phy = ds->slave_mii_bus->phy_map[p->port];
+       p->phy = ds->slave_mii_bus->phy_map[addr];
        if (!p->phy)
                return -ENODEV;
 
        if (ds->drv->get_phy_flags)
                phy_flags = ds->drv->get_phy_flags(ds, p->port);
 
-       if (phy_dn)
-               p->phy = of_phy_connect(slave_dev, phy_dn,
-                                       dsa_slave_adjust_link, phy_flags,
-                                       p->phy_interface);
+       if (phy_dn) {
+               ret = of_mdio_parse_addr(&slave_dev->dev, phy_dn);
+               /* If this PHY address is part of phys_mii_mask, which means
+                * that we need to divert reads and writes to/from it, then we
+                * want to bind this device using the slave MII bus created by
+                * DSA to make that happen.
+                */
+               if (ret >= 0 && (ds->phys_mii_mask & (1 << ret))) {
+                       ret = dsa_slave_phy_connect(p, slave_dev, ret);
+                       if (ret)
+                               return ret;
+               } else {
+                       p->phy = of_phy_connect(slave_dev, phy_dn,
+                                               dsa_slave_adjust_link,
+                                               phy_flags,
+                                               p->phy_interface);
+               }
+       }
 
        if (p->phy && phy_is_fixed)
                fixed_phy_set_link_update(p->phy, dsa_slave_fixed_link_update);
         * MDIO bus instead
         */
        if (!p->phy) {
-               ret = dsa_slave_phy_connect(p, slave_dev);
+               ret = dsa_slave_phy_connect(p, slave_dev, p->port);
                if (ret)
                        return ret;
        } else {