From patchwork Wed Feb 14 23:02:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [U-Boot, 1/2] net: phy: Add PHY_RTL8211E_PINE64_GIGABIT_FIX for realtek phys X-Patchwork-Submitter: Kyle Evans X-Patchwork-Id: 873752 Message-Id: <20180214230216.2001-2-kevans@FreeBSD.org> To: andre.przywara@arm.com, joe.hershberger@ni.com, philipp.tomsich@theobroma-systems.com, alex.g@adaptrum.com, hannes.schmelzer@br-automation.com, sbabic@denx.de, jagan@amarulasolutions.com, narmstrong@baylibre.com, tharvey@gateworks.com, york.sun@nxp.com, madalin.bucur@nxp.com, u-boot@lists.denx.de Date: Wed, 14 Feb 2018 17:02:15 -0600 From: kevans@FreeBSD.org List-Id: U-Boot discussion Setting PHY_RTL8211E_PINE64_GIGABIT_FIX forces internal rx/tx delays off on the PHY, as well as flipping some magical undocumented bits. The magic number comes from the Pine64 engineering team, presumably as a proxy from Realtek. This configuration fixes the throughput on some Pine64 models. Packet loss of up to 60-70% has been observed without this. Signed-off-by: Kyle Evans --- drivers/net/phy/Kconfig | 10 ++++++++++ drivers/net/phy/realtek.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index e32f1eb1c0..ad648a889d 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -114,6 +114,16 @@ config PHY_NATSEMI config PHY_REALTEK bool "Realtek Ethernet PHYs support" +config RTL8211E_PINE64_GIGABIT_FIX + bool "Fix gigabit throughput on some Pine64+ models" + depends on PHY_REALTEK + help + Configure the Realtek RTL8211E found on some Pine64+ models differently to + fix throughput on Gigabit links, turning off all internal delays in the + process. The settings that this touches are not documented in the CONFREG + section of the RTL8211E datasheet, but come from Realtek by way of the + Pine64 engineering team. + config RTL8211X_PHY_FORCE_MASTER bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode" depends on PHY_REALTEK diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 6d917f86f4..d5c2a46c67 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -13,6 +13,7 @@ #include #define PHY_RTL8211x_FORCE_MASTER BIT(1) +#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2) #define PHY_AUTONEGOTIATE_TIMEOUT 5000 @@ -47,6 +48,13 @@ #define MIIM_RTL8211F_PHYSTAT_SPDDONE 0x0800 #define MIIM_RTL8211F_PHYSTAT_LINK 0x0004 +#define MIIM_RTL8211E_CONFREG 0x1c +#define MIIM_RTL8211E_CONFREG_TXD 0x0002 +#define MIIM_RTL8211E_CONFREG_RXD 0x0004 +#define MIIM_RTL8211E_CONFREG_MAGIC 0xb400 /* Undocumented */ + +#define MIIM_RTL8211E_EXT_PAGE_SELECT 0x1e + #define MIIM_RTL8211F_PAGE_SELECT 0x1f #define MIIM_RTL8211F_TX_DELAY 0x100 #define MIIM_RTL8211F_LCR 0x10 @@ -60,6 +68,15 @@ static int rtl8211b_probe(struct phy_device *phydev) return 0; } +static int rtl8211e_probe(struct phy_device *phydev) +{ +#ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX + phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX; +#endif + + return 0; +} + /* RealTek RTL8211x */ static int rtl8211x_config(struct phy_device *phydev) { @@ -81,6 +98,22 @@ static int rtl8211x_config(struct phy_device *phydev) reg |= MIIM_RTL8211x_CTRL1000T_MASTER; phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg); } + if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) { + unsigned int reg; + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, + 7); + phy_write(phydev, MDIO_DEVAD_NONE, + MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4); + reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG); + /* Ensure both internal delays are turned off */ + reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD); + /* Flip the magic undocumented bits */ + reg |= MIIM_RTL8211E_CONFREG_MAGIC; + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, + 0); + } /* read interrupt status just to clear it */ phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER); @@ -279,6 +312,7 @@ static struct phy_driver RTL8211E_driver = { .uid = 0x1cc915, .mask = 0xffffff, .features = PHY_GBIT_FEATURES, + .probe = &rtl8211e_probe, .config = &rtl8211x_config, .startup = &rtl8211e_startup, .shutdown = &genphy_shutdown, From patchwork Wed Feb 14 23:02:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [U-Boot, 2/2] Configs: Use the newly added PHY_RTL8211E_PINE64_GIGABIT_FIX X-Patchwork-Submitter: Kyle Evans X-Patchwork-Id: 873751 Message-Id: <20180214230216.2001-3-kevans@FreeBSD.org> To: andre.przywara@arm.com, joe.hershberger@ni.com, philipp.tomsich@theobroma-systems.com, alex.g@adaptrum.com, hannes.schmelzer@br-automation.com, sbabic@denx.de, jagan@amarulasolutions.com, narmstrong@baylibre.com, tharvey@gateworks.com, york.sun@nxp.com, madalin.bucur@nxp.com, u-boot@lists.denx.de Date: Wed, 14 Feb 2018 17:02:16 -0600 From: kevans@FreeBSD.org List-Id: U-Boot discussion The Pine64+ uses a generic PHY driver, so flip it over to using the Realtek PHY driver to actually apply the RTL8211e fix. Signed-off-by: Kyle Evans --- configs/pine64_plus_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/pine64_plus_defconfig b/configs/pine64_plus_defconfig index 01ed23844b..149311f2c4 100644 --- a/configs/pine64_plus_defconfig +++ b/configs/pine64_plus_defconfig @@ -14,3 +14,5 @@ CONFIG_OF_LIST="sun50i-a64-pine64 sun50i-a64-pine64-plus" CONFIG_SUN8I_EMAC=y CONFIG_USB_EHCI_HCD=y CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y +CONFIG_PHY_REALTEK=y +CONFIG_RTL8211E_PINE64_GIGABIT_FIX=y