[PATCH v3] net/phy: tune get_phy_c45_ids to support more c45 phy
As some C45 10G PHYs(e.g. Cortina CS4315/CS4340 PHY) have zero Devices In package, current driver can't get correct devices_in_package value by non-zero Devices In package. so let's probe more with zero Devices In package to support more C45 PHYs. Signed-off-by: Shengzhou Liu --- v3: restructure the loop to probe naturally. v2: use MDIO_DEVS1 and MDIO_DEVS2 instead of constant '6', '5' drivers/net/phy/phy_device.c | 20 ++-- 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index bdfe51f..3e90037 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -230,7 +230,7 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id, for (i = 1; i < num_ids && c45_ids->devices_in_package == 0; i++) { - reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2; +retry: reg_addr = MII_ADDR_C45 | i << 16 | MDIO_DEVS2; phy_reg = mdiobus_read(bus, addr, reg_addr); if (phy_reg < 0) return -EIO; @@ -242,12 +242,20 @@ static int get_phy_c45_ids(struct mii_bus *bus, int addr, u32 *phy_id, return -EIO; c45_ids->devices_in_package |= (phy_reg & 0x); - /* If mostly Fs, there is no device there, -* let's get out of here. -*/ if ((c45_ids->devices_in_package & 0x1fff) == 0x1fff) { - *phy_id = 0x; - return 0; + if (i) { + /* If mostly Fs, there is no device there, +* then let's continue to probe more, as some +* 10G PHYs have zero Devices In package, +* e.g. Cortina CS4315/CS4340 PHY. +*/ + i = 0; + goto retry; + } else { + /* no device there, let's get out of here */ + *phy_id = 0x; + return 0; + } } } -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] net/phy: Add support for Realtek RTL8211F
RTL8211F has different register definitions from RTL8211E. Specially it needs to enable TXDLY in case of RGMII. Signed-off-by: Shengzhou Liu --- drivers/net/phy/realtek.c | 68 ++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 96a0f0f..4535361 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -22,8 +22,12 @@ #define RTL821x_INER 0x12 #define RTL821x_INER_INIT 0x6400 #define RTL821x_INSR 0x13 +#define RTL8211E_INER_LINK_STATUS 0x400 -#defineRTL8211E_INER_LINK_STATUS 0x400 +#define RTL8211F_INER_LINK_STATUS 0x0010 +#define RTL8211F_INSR 0x1d +#define RTL8211F_PAGE_SELECT 0x1f +#define RTL8211F_TX_DELAY 0x100 MODULE_DESCRIPTION("Realtek PHY driver"); MODULE_AUTHOR("Johnson Leung"); @@ -38,6 +42,18 @@ static int rtl821x_ack_interrupt(struct phy_device *phydev) return (err < 0) ? err : 0; } +static int rtl8211f_ack_interrupt(struct phy_device *phydev) +{ + int err; + + phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43); + err = phy_read(phydev, RTL8211F_INSR); + /* restore to default page 0 */ + phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); + + return (err < 0) ? err : 0; +} + static int rtl8211b_config_intr(struct phy_device *phydev) { int err; @@ -64,6 +80,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev) return err; } +static int rtl8211f_config_intr(struct phy_device *phydev) +{ + int err; + + if (phydev->interrupts == PHY_INTERRUPT_ENABLED) + err = phy_write(phydev, RTL821x_INER, + RTL8211F_INER_LINK_STATUS); + else + err = phy_write(phydev, RTL821x_INER, 0); + + return err; +} + +static int rtl8211f_config_init(struct phy_device *phydev) +{ + int ret; + u16 reg; + + ret = genphy_config_init(phydev); + if (ret < 0) + return ret; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { + /* enable TXDLY */ + phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08); + reg = phy_read(phydev, 0x11); + reg |= RTL8211F_TX_DELAY; + phy_write(phydev, 0x11, reg); + /* restore to default page 0 */ + phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0); + } + + return 0; +} + static struct phy_driver realtek_drvs[] = { { .phy_id = 0x8201, @@ -98,6 +149,20 @@ static struct phy_driver realtek_drvs[] = { .suspend= genphy_suspend, .resume = genphy_resume, .driver = { .owner = THIS_MODULE,}, + }, { + .phy_id = 0x001cc916, + .name = "RTL8211F Gigabit Ethernet", + .phy_id_mask= 0x001f, + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_aneg= &genphy_config_aneg, + .config_init= &rtl8211f_config_init, + .read_status= &genphy_read_status, + .ack_interrupt = &rtl8211f_ack_interrupt, + .config_intr= &rtl8211f_config_intr, + .suspend= genphy_suspend, + .resume = genphy_resume, + .driver = { .owner = THIS_MODULE }, }, }; @@ -106,6 +171,7 @@ module_phy_driver(realtek_drvs); static struct mdio_device_id __maybe_unused realtek_tbl[] = { { 0x001cc912, 0x001f }, { 0x001cc915, 0x001f }, + { 0x001cc916, 0x001f }, { } }; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] net/phy: refactor RTL8211F initialization
RTL8211F needs to enalbe TXDLY for RGMII during phy initialization, so move it to rtl8211f_config for early initialization. Signed-off-by: Shengzhou Liu cc: Joe Hershberger --- drivers/net/phy/realtek.c | 25 + 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 3917c82..d48095b 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -43,6 +43,22 @@ static int rtl8211x_config(struct phy_device *phydev) return 0; } +static int rtl8211f_config(struct phy_device *phydev) +{ + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET); + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { + /* enable TXDLY */ + phy_write(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211F_PAGE_SELECT, 0xd08); + phy_write(phydev, MDIO_DEVAD_NONE, 0x11, 0x109); + } + + genphy_config_aneg(phydev); + + return 0; +} + static int rtl8211x_parse_status(struct phy_device *phydev) { unsigned int speed; @@ -142,13 +158,6 @@ static int rtl8211f_parse_status(struct phy_device *phydev) phydev->speed = SPEED_10; } - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) { - /* enable TXDLY */ - phy_write(phydev, MDIO_DEVAD_NONE, - MIIM_RTL8211F_PAGE_SELECT, 0xd08); - phy_write(phydev, MDIO_DEVAD_NONE, 0x11, 0x109); - } - return 0; } @@ -209,7 +218,7 @@ static struct phy_driver RTL8211F_driver = { .uid = 0x1cc916, .mask = 0xff, .features = PHY_GBIT_FEATURES, - .config = &rtl8211x_config, + .config = &rtl8211f_config, .startup = &rtl8211f_startup, .shutdown = &genphy_shutdown, }; -- 2.1.0.27.g96db324 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html