diff options
Diffstat (limited to 'drivers/net/phy')
-rw-r--r-- | drivers/net/phy/micrel.c | 6 | ||||
-rw-r--r-- | drivers/net/phy/realtek.c | 36 | ||||
-rw-r--r-- | drivers/net/phy/vitesse.c | 43 |
3 files changed, 54 insertions, 31 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 28a1401..7163fa2 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -300,10 +300,11 @@ static int ksz9021_of_config(struct phy_device *phydev) }; int i, ret = 0; - for (i = 0; i < ARRAY_SIZE(ofcfg); i++) + for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); if (ret) return ret; + } return 0; } @@ -408,10 +409,11 @@ static int ksz9031_of_config(struct phy_device *phydev) }; int i, ret = 0; - for (i = 0; i < ARRAY_SIZE(ofcfg); i++) + for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); if (ret) return ret; + } return 0; } diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 7a99cb0..635acf5 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -9,13 +9,16 @@ */ #include <config.h> #include <common.h> +#include <linux/bitops.h> #include <phy.h> +#define PHY_RTL8211x_FORCE_MASTER BIT(1) + #define PHY_AUTONEGOTIATE_TIMEOUT 5000 /* RTL8211x 1000BASE-T Control Register */ -#define MIIM_RTL8211x_CTRL1000T_MSCE (1 << 12); -#define MIIM_RTL8211X_CTRL1000T_MASTER (1 << 11); +#define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12); +#define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11); /* RTL8211x PHY Status Register */ #define MIIM_RTL8211x_PHY_STATUS 0x11 @@ -48,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) { @@ -58,14 +70,17 @@ static int rtl8211x_config(struct phy_device *phydev) */ phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER, MIIM_RTL8211x_PHY_INTR_DIS); -#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER - unsigned int 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); -#endif + + 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); @@ -248,6 +263,7 @@ static struct phy_driver RTL8211B_driver = { .uid = 0x1cc912, .mask = 0xffffff, .features = PHY_GBIT_FEATURES, + .probe = &rtl8211b_probe, .config = &rtl8211x_config, .startup = &rtl8211x_startup, .shutdown = &genphy_shutdown, diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 2635b82..a077b98 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -30,9 +30,8 @@ #define MIIM_CIS8204_SLEDCON_INIT 0x1115 /* Vitesse VSC8601 Extended PHY Control Register 1 */ -#define MIIM_VSC8601_EPHY_CON 0x17 -#define MIIM_VSC8601_EPHY_CON_INIT_SKEW 0x1120 -#define MIIM_VSC8601_SKEW_CTRL 0x1c +#define MII_VSC8601_EPHY_CTL 0x17 +#define MII_VSC8601_EPHY_CTL_RGMII_SKEW (1 << 8) #define PHY_EXT_PAGE_ACCESS 0x1f #define PHY_EXT_PAGE_ACCESS_GENERAL 0x10 @@ -142,26 +141,32 @@ static int cis8204_config(struct phy_device *phydev) } /* Vitesse VSC8601 */ +/* This adds a skew for both TX and RX clocks, so the skew should only be + * applied to "rgmii-id" interfaces. It may not work as expected + * on "rgmii-txid", "rgmii-rxid" or "rgmii" interfaces. */ +static int vsc8601_add_skew(struct phy_device *phydev) +{ + int ret; + + ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_VSC8601_EPHY_CTL); + if (ret < 0) + return ret; + + ret |= MII_VSC8601_EPHY_CTL_RGMII_SKEW; + return phy_write(phydev, MDIO_DEVAD_NONE, MII_VSC8601_EPHY_CTL, ret); +} + static int vsc8601_config(struct phy_device *phydev) { - /* Configure some basic stuff */ -#ifdef CONFIG_SYS_VSC8601_SKEWFIX - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_EPHY_CON, - MIIM_VSC8601_EPHY_CON_INIT_SKEW); -#if defined(CONFIG_SYS_VSC8601_SKEW_TX) && defined(CONFIG_SYS_VSC8601_SKEW_RX) - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 1); -#define VSC8101_SKEW \ - ((CONFIG_SYS_VSC8601_SKEW_TX << 14) \ - | (CONFIG_SYS_VSC8601_SKEW_RX << 12)) - phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8601_SKEW_CTRL, - VSC8101_SKEW); - phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); -#endif -#endif + int ret = 0; - genphy_config_aneg(phydev); + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) + ret = vsc8601_add_skew(phydev); - return 0; + if (ret < 0) + return ret; + + return genphy_config_aneg(phydev); } static int vsc8574_config(struct phy_device *phydev) |