#define RTL_GENERIC_PHYID                      0x001cc800
 #define RTL_8211FVD_PHYID                      0x001cc878
+#define RTL_8221B                              0x001cc840
 #define RTL_8221B_VB_CG                                0x001cc849
 #define RTL_8221B_VN_CG                                0x001cc84a
 #define RTL_8251B                              0x001cc862
        return val >= 0 && val & MDIO_PMA_SPEED_2_5G;
 }
 
+/* On internal PHY's MMD reads over C22 always return 0.
+ * Check a MMD register which is known to be non-zero.
+ */
+static bool rtlgen_supports_mmd(struct phy_device *phydev)
+{
+       int val;
+
+       phy_lock_mdio_bus(phydev);
+       __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS);
+       __phy_write(phydev, MII_MMD_DATA, MDIO_PCS_EEE_ABLE);
+       __phy_write(phydev, MII_MMD_CTRL, MDIO_MMD_PCS | MII_MMD_CTRL_NOINCR);
+       val = __phy_read(phydev, MII_MMD_DATA);
+       phy_unlock_mdio_bus(phydev);
+
+       return val > 0;
+}
+
 static int rtlgen_match_phy_device(struct phy_device *phydev)
 {
        return phydev->phy_id == RTL_GENERIC_PHYID &&
 static int rtl8226_match_phy_device(struct phy_device *phydev)
 {
        return phydev->phy_id == RTL_GENERIC_PHYID &&
-              rtlgen_supports_2_5gbps(phydev);
+              rtlgen_supports_2_5gbps(phydev) &&
+              rtlgen_supports_mmd(phydev);
 }
 
 static int rtlgen_is_c45_match(struct phy_device *phydev, unsigned int id,
                return !is_c45 && (id == phydev->phy_id);
 }
 
+static int rtl8221b_match_phy_device(struct phy_device *phydev)
+{
+       return phydev->phy_id == RTL_8221B && rtlgen_supports_mmd(phydev);
+}
+
 static int rtl8221b_vb_cg_c22_match_phy_device(struct phy_device *phydev)
 {
        return rtlgen_is_c45_match(phydev, RTL_8221B_VB_CG, false);
        return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true);
 }
 
-static int rtl8251b_c22_match_phy_device(struct phy_device *phydev)
+static int rtl_internal_nbaset_match_phy_device(struct phy_device *phydev)
 {
-       return rtlgen_is_c45_match(phydev, RTL_8251B, false);
+       if (phydev->is_c45)
+               return false;
+
+       switch (phydev->phy_id) {
+       case RTL_GENERIC_PHYID:
+       case RTL_8221B:
+       case RTL_8251B:
+               break;
+       default:
+               return false;
+       }
+
+       return rtlgen_supports_2_5gbps(phydev) && !rtlgen_supports_mmd(phydev);
 }
 
 static int rtl8251b_c45_match_phy_device(struct phy_device *phydev)
                .resume         = rtlgen_resume,
                .read_page      = rtl821x_read_page,
                .write_page     = rtl821x_write_page,
-               .read_mmd       = rtl822x_read_mmd,
-               .write_mmd      = rtl822x_write_mmd,
        }, {
-               PHY_ID_MATCH_EXACT(0x001cc840),
+               .match_phy_device = rtl8221b_match_phy_device,
                .name           = "RTL8226B_RTL8221B 2.5Gbps PHY",
                .get_features   = rtl822x_get_features,
                .config_aneg    = rtl822x_config_aneg,
                .resume         = rtlgen_resume,
                .read_page      = rtl821x_read_page,
                .write_page     = rtl821x_write_page,
-               .read_mmd       = rtl822x_read_mmd,
-               .write_mmd      = rtl822x_write_mmd,
        }, {
                PHY_ID_MATCH_EXACT(0x001cc838),
                .name           = "RTL8226-CG 2.5Gbps PHY",
                .read_page      = rtl821x_read_page,
                .write_page     = rtl821x_write_page,
        }, {
-               .match_phy_device = rtl8251b_c22_match_phy_device,
-               .name           = "RTL8126A-internal 5Gbps PHY",
+               .match_phy_device = rtl_internal_nbaset_match_phy_device,
+               .name           = "Realtek Internal NBASE-T PHY",
+               .flags          = PHY_IS_INTERNAL,
                .get_features   = rtl822x_get_features,
                .config_aneg    = rtl822x_config_aneg,
                .read_status    = rtl822x_read_status,