diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/fm/eth.c | 33 | ||||
-rw-r--r-- | drivers/net/fm/memac.c | 1 | ||||
-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 |
5 files changed, 78 insertions, 41 deletions
diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index eb8e936..bf5f89b 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -45,9 +45,12 @@ static void dtsec_configure_serdes(struct fm_eth *priv) qsgmii_loop: /* SGMII IF mode + AN enable only for 1G SGMII, not for 2.5G */ - value = PHY_SGMII_IF_MODE_SGMII; - if (!sgmii_2500) - value |= PHY_SGMII_IF_MODE_AN; + if (sgmii_2500) + value = PHY_SGMII_CR_PHY_RESET | + PHY_SGMII_IF_SPEED_GIGABIT | + PHY_SGMII_IF_MODE_SGMII; + else + value = PHY_SGMII_IF_MODE_SGMII | PHY_SGMII_IF_MODE_AN; memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x14, value); @@ -55,15 +58,24 @@ qsgmii_loop: value = PHY_SGMII_DEV_ABILITY_SGMII; memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x4, value); - /* Adjust link timer for SGMII - - 1.6 ms in units of 8 ns = 2 * 10^5 = 0x30d40 */ - memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x3); - memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xd40); + if (sgmii_2500) { + /* Adjust link timer for 2.5G SGMII, + * 1.6 ms in units of 3.2 ns: + * 1.6ms / 3.2ns = 5 * 10^5 = 0x7a120. + */ + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0007); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0xa120); + } else { + /* Adjust link timer for SGMII, + * 1.6 ms in units of 8 ns: + * 1.6ms / 8ns = 2 * 10^5 = 0x30d40. + */ + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x13, 0x0003); + memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0x12, 0x0d40); + } /* Restart AN */ - value = PHY_SGMII_CR_DEF_VAL; - if (!sgmii_2500) - value |= PHY_SGMII_CR_RESET_AN; + value = PHY_SGMII_CR_DEF_VAL | PHY_SGMII_CR_RESET_AN; memac_mdio_write(&bus, i, MDIO_DEVAD_NONE, 0, value); if ((priv->enet_if == PHY_INTERFACE_MODE_QSGMII) && (i < 3)) { @@ -391,6 +403,7 @@ static int fm_eth_startup(struct fm_eth *fm_eth) /* For some reason we need to set SPEED_100 */ if (((fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII) || + (fm_eth->enet_if == PHY_INTERFACE_MODE_SGMII_2500) || (fm_eth->enet_if == PHY_INTERFACE_MODE_QSGMII)) && mac->set_if_mode) mac->set_if_mode(mac, fm_eth->enet_if, SPEED_100); diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 81a64bf..1b5779c 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -90,6 +90,7 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac, if_mode |= (IF_MODE_GMII | IF_MODE_RM); break; case PHY_INTERFACE_MODE_SGMII: + case PHY_INTERFACE_MODE_SGMII_2500: case PHY_INTERFACE_MODE_QSGMII: if_mode &= ~IF_MODE_MASK; if_mode |= (IF_MODE_GMII); 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) |