diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c index 63134e300c33..023e47ad605b 100644 --- a/drivers/net/phy/realtek/realtek_main.c +++ b/drivers/net/phy/realtek/realtek_main.c @@ -172,6 +172,7 @@ #define RTL8224_SRAM_RTCT_LEN(pair) (0x8028 + (pair) * 4) #define RTL8224_VND1_MDI_PAIR_SWAP 0xa90 +#define RTL8224_VND1_MDI_POLARITY_SWAP 0xa94 #define RTL8366RB_POWER_SAVE 0x15 #define RTL8366RB_POWER_SAVE_ON BIT(12) @@ -1870,9 +1871,40 @@ static int rtl8224_mdi_config_order(struct phy_device *phydev) order ? BIT(port_offset) : 0); } +static int rtl8224_mdi_config_polarity(struct phy_device *phydev) +{ + struct device_node *np = phydev->mdio.dev.of_node; + u8 offset = (phydev->mdio.addr & 3) * 4; + u32 polarity = 0; + int ret; + + ret = of_property_read_u32(np, "enet-phy-pair-polarity", &polarity); + + /* Do nothing if the property is not present */ + if (ret == -EINVAL || ret == -ENOSYS) + return 0; + + if (ret) + return ret; + + if (polarity & ~0xf) + return -EINVAL; + + return rtl8224_package_modify_mmd(phydev, MDIO_MMD_VEND1, + RTL8224_VND1_MDI_POLARITY_SWAP, + 0xf << offset, + polarity << offset); +} + static int rtl8224_config_init(struct phy_device *phydev) { - return rtl8224_mdi_config_order(phydev); + int ret; + + ret = rtl8224_mdi_config_order(phydev); + if (ret) + return ret; + + return rtl8224_mdi_config_polarity(phydev); } static int rtl8224_probe(struct phy_device *phydev)