#define RTL8224_SRAM_RTCT_LEN(pair) (0x8028 + (pair) * 4)
+#define RTL8224_VND1_MDI_PAIR_SWAP 0xa90
+
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
return rtl8224_cable_test_report(phydev, finished);
}
+static int rtl8224_package_modify_mmd(struct phy_device *phydev, int devad,
+ u32 regnum, u16 mask, u16 set)
+{
+ int val, ret;
+
+ phy_lock_mdio_bus(phydev);
+
+ val = __phy_package_read_mmd(phydev, 0, devad, regnum);
+ if (val < 0) {
+ ret = val;
+ goto exit;
+ }
+
+ val &= ~mask;
+ val |= set;
+
+ ret = __phy_package_write_mmd(phydev, 0, devad, regnum, val);
+
+exit:
+ phy_unlock_mdio_bus(phydev);
+ return ret;
+}
+
+static int rtl8224_mdi_config_order(struct phy_device *phydev)
+{
+ struct device_node *np = phydev->mdio.dev.of_node;
+ u8 port_offset = phydev->mdio.addr & 3;
+ u32 order = 0;
+ int ret;
+
+ ret = of_property_read_u32(np, "enet-phy-pair-order", &order);
+
+ /* Do nothing in case the property is not present */
+ if (ret == -EINVAL || ret == -ENOSYS)
+ return 0;
+
+ if (ret)
+ return ret;
+
+ if (order & ~1)
+ return -EINVAL;
+
+ return rtl8224_package_modify_mmd(phydev, MDIO_MMD_VEND1,
+ RTL8224_VND1_MDI_PAIR_SWAP,
+ BIT(port_offset),
+ order ? BIT(port_offset) : 0);
+}
+
+static int rtl8224_config_init(struct phy_device *phydev)
+{
+ return rtl8224_mdi_config_order(phydev);
+}
+
+static int rtl8224_probe(struct phy_device *phydev)
+{
+ /* Chip exposes 4 ports, join all of them in the same package */
+ return devm_phy_package_join(&phydev->mdio.dev, phydev,
+ phydev->mdio.addr & ~3, 0);
+}
+
static bool rtlgen_supports_2_5gbps(struct phy_device *phydev)
{
int val;
PHY_ID_MATCH_EXACT(0x001ccad0),
.name = "RTL8224 2.5Gbps PHY",
.flags = PHY_POLL_CABLE_TEST,
+ .probe = rtl8224_probe,
+ .config_init = rtl8224_config_init,
.get_features = rtl822x_c45_get_features,
.config_aneg = rtl822x_c45_config_aneg,
.read_status = rtl822x_c45_read_status,