X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fphy%2Frealtek.c;h=635acf5844e3e73c89b751a6f820b6949fb6affb;hb=21342d4aed6c77a4aa7a5b2579b3c23e21aea31a;hp=259a87fcc59ed4bd29c7c96cfc88e865ab975473;hpb=bed6bd326e89366152609821a752d361b2183b46;p=oweals%2Fu-boot.git diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 259a87fcc5..635acf5844 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -5,13 +5,21 @@ * * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc. * author Andy Fleming + * Copyright 2016 Karsten Merker */ #include #include +#include #include +#define PHY_RTL8211x_FORCE_MASTER BIT(1) + #define PHY_AUTONEGOTIATE_TIMEOUT 5000 +/* RTL8211x 1000BASE-T Control Register */ +#define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12); +#define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11); + /* RTL8211x PHY Status Register */ #define MIIM_RTL8211x_PHY_STATUS 0x11 #define MIIM_RTL8211x_PHYSTAT_SPEED 0xc000 @@ -43,6 +51,15 @@ #define MIIM_RTL8211F_TX_DELAY 0x100 #define MIIM_RTL8211F_LCR 0x10 +static int rtl8211b_probe(struct phy_device *phydev) +{ +#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER + phydev->flags |= PHY_RTL8211x_FORCE_MASTER; +#endif + + return 0; +} + /* RealTek RTL8211x */ static int rtl8211x_config(struct phy_device *phydev) { @@ -54,6 +71,16 @@ static int rtl8211x_config(struct phy_device *phydev) phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, MIIM_RTL8211x_PHY_INTR_DIS); + if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) { + unsigned int reg; + + reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000); + /* force manual master/slave configuration */ + reg |= MIIM_RTL8211x_CTRL1000T_MSCE; + /* force master mode */ + reg |= MIIM_RTL8211x_CTRL1000T_MASTER; + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); + } /* read interrupt status just to clear it */ phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); @@ -196,36 +223,47 @@ static int rtl8211f_parse_status(struct phy_device *phydev) static int rtl8211x_startup(struct phy_device *phydev) { + int ret; + /* Read the Status (2x to make sure link is right) */ - genphy_update_link(phydev); - rtl8211x_parse_status(phydev); + ret = genphy_update_link(phydev); + if (ret) + return ret; - return 0; + return rtl8211x_parse_status(phydev); } static int rtl8211e_startup(struct phy_device *phydev) { - genphy_update_link(phydev); - genphy_parse_link(phydev); + int ret; - return 0; + ret = genphy_update_link(phydev); + if (ret) + return ret; + + return genphy_parse_link(phydev); } static int rtl8211f_startup(struct phy_device *phydev) { + int ret; + + /* Read the Status (2x to make sure link is right) */ + ret = genphy_update_link(phydev); + if (ret) + return ret; /* Read the Status (2x to make sure link is right) */ - genphy_update_link(phydev); - rtl8211f_parse_status(phydev); - return 0; + return rtl8211f_parse_status(phydev); } /* Support for RTL8211B PHY */ static struct phy_driver RTL8211B_driver = { .name = "RealTek RTL8211B", - .uid = 0x1cc910, + .uid = 0x1cc912, .mask = 0xffffff, .features = PHY_GBIT_FEATURES, + .probe = &rtl8211b_probe, .config = &rtl8211x_config, .startup = &rtl8211x_startup, .shutdown = &genphy_shutdown,