mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-29 08:01:08 +00:00
net: phy: Add PHY_RTL8211E_PINE64_GIGABIT_FIX for realtek phys
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 <kevans@FreeBSD.org> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
This commit is contained in:
parent
2511930193
commit
66526e7038
2 changed files with 44 additions and 0 deletions
|
@ -139,6 +139,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
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <phy.h>
|
||||
|
||||
#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,
|
||||
|
|
Loading…
Reference in a new issue