summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/fm/eth.c33
-rw-r--r--drivers/net/fm/memac.c1
-rw-r--r--drivers/net/phy/micrel.c6
-rw-r--r--drivers/net/phy/realtek.c36
-rw-r--r--drivers/net/phy/vitesse.c43
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)