In discussion with Andrew [0] we figured out that it would be best to
make the RX delay of the RTL8211F PHY configurable (just like the TX
delay is already configurable).
While here I took the opportunity to add some logging to the TX delay
configuration as well.
There is no public documentation for the RX and TX delay registers.
I received this information a while ago (and created this RfC patch
back then: [1]). Realtek gave me permission to take the information
from the datasheet extracts and phase them in my own words and publish
that (I am not allowed to publish the datasheet extracts).
I have tested these patches on two boards:
- Amlogic Meson8b Odroid-C1
- Amlogic GXM Khadas VIM2
Both still behave as before these changes (iperf3 speeds are the same
in both directions: RX and TX), which is expected because they are
currently using phy-mode = "rgmii" with the RX delay not being generated
by the PHY.
[0] https://patchwork.ozlabs.org/patch/1215313/
[1] https://patchwork.ozlabs.org/patch/843946/
Martin Blumenstingl (2):
net: phy: realtek: add logging for the RGMII TX delay configuration
net: phy: realtek: add support for configuring the RX delay on
RTL8211F
drivers/net/phy/realtek.c | 59 +++++++++++++++++++++++++++++++++------
1 file changed, 51 insertions(+), 8 deletions(-)
--
2.24.1
RGMII requires a delay of 2ns between the data and the clock signal.
There are at least three ways this can happen. One possibility is by
having the PHY generate this delay.
This is a common source for problems (for example with slow TX speeds or
packet loss when sending data). The TX delay configuration of the
RTL8211F PHY can be set either by pin-strappping the RXD1 pin (HIGH
means enabled, LOW means disabled) or through configuring a paged
register. The setting from the RXD1 pin is also reflected in the
register.
Add debug logging to the TX delay configuration on RTL8211F so it's
easier to spot these issues (for example if the TX delay is enabled for
both, the RTL8211F PHY and the MAC).
This is especially helpful because there is no public datasheet for the
RTL8211F PHY available with all the RX/TX delay specifics.
Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/phy/realtek.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 476db5345e1a..879ca37c8508 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -171,7 +171,9 @@ static int rtl8211c_config_init(struct phy_device *phydev)
static int rtl8211f_config_init(struct phy_device *phydev)
{
+ struct device *dev = &phydev->mdio.dev;
u16 val;
+ int ret;
/* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
* rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
@@ -189,7 +191,22 @@ static int rtl8211f_config_init(struct phy_device *phydev)
return 0;
}
- return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val);
+ ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
+ val);
+ if (ret < 0) {
+ dev_err(dev, "Failed to update the TX delay register\n");
+ return ret;
+ } else if (ret) {
+ dev_dbg(dev,
+ "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
+ val ? "Enabling" : "Disabling");
+ } else {
+ dev_dbg(dev,
+ "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
+ val ? "enabled" : "disabled");
+ }
+
+ return 0;
}
static int rtl8211e_config_init(struct phy_device *phydev)
--
2.24.1
On RTL8211F the RX and TX delays (2ns) can be configured in two ways:
- pin strapping (RXD1 for the TX delay and RXD0 for the RX delay, LOW
means "off" and HIGH means "on") which is read during PHY reset
- using software to configure the TX and RX delay registers
So far only the configuration using pin strapping has been supported.
Add support for enabling or disabling the RGMII RX delay based on the
phy-mode to be able to get the RX delay into a known state. This is
important because the RX delay has to be coordinated between the PHY,
MAC and the PCB design (trace length). With an invalid RX delay applied
(for example if both PHY and MAC add a 2ns RX delay) Ethernet may not
work at all.
Also add debug logging when configuring the RX delay (just like the TX
delay) because this is a common source of problems.
Signed-off-by: Martin Blumenstingl <[email protected]>
---
drivers/net/phy/realtek.c | 46 ++++++++++++++++++++++++++++++---------
1 file changed, 36 insertions(+), 10 deletions(-)
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
index 879ca37c8508..f5fa2fff3ddc 100644
--- a/drivers/net/phy/realtek.c
+++ b/drivers/net/phy/realtek.c
@@ -29,6 +29,8 @@
#define RTL8211F_INSR 0x1d
#define RTL8211F_TX_DELAY BIT(8)
+#define RTL8211F_RX_DELAY BIT(3)
+
#define RTL8211E_TX_DELAY BIT(1)
#define RTL8211E_RX_DELAY BIT(2)
#define RTL8211E_MODE_MII_GMII BIT(3)
@@ -172,38 +174,62 @@ static int rtl8211c_config_init(struct phy_device *phydev)
static int rtl8211f_config_init(struct phy_device *phydev)
{
struct device *dev = &phydev->mdio.dev;
- u16 val;
+ u16 val_txdly, val_rxdly;
int ret;
- /* enable TX-delay for rgmii-{id,txid}, and disable it for rgmii and
- * rgmii-rxid. The RX-delay can be enabled by the external RXDLY pin.
- */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RGMII:
+ val_txdly = 0;
+ val_rxdly = 0;
+ break;
+
case PHY_INTERFACE_MODE_RGMII_RXID:
- val = 0;
+ val_txdly = 0;
+ val_rxdly = RTL8211F_RX_DELAY;
break;
- case PHY_INTERFACE_MODE_RGMII_ID:
+
case PHY_INTERFACE_MODE_RGMII_TXID:
- val = RTL8211F_TX_DELAY;
+ val_txdly = RTL8211F_TX_DELAY;
+ val_rxdly = 0;
+ break;
+
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ val_txdly = RTL8211F_TX_DELAY;
+ val_rxdly = RTL8211F_RX_DELAY;
break;
+
default: /* the rest of the modes imply leaving delay as is. */
return 0;
}
ret = phy_modify_paged_changed(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY,
- val);
+ val_txdly);
if (ret < 0) {
dev_err(dev, "Failed to update the TX delay register\n");
return ret;
} else if (ret) {
dev_dbg(dev,
"%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n",
- val ? "Enabling" : "Disabling");
+ val_txdly ? "Enabling" : "Disabling");
} else {
dev_dbg(dev,
"2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n",
- val ? "enabled" : "disabled");
+ val_txdly ? "enabled" : "disabled");
+ }
+
+ ret = phy_modify_paged_changed(phydev, 0xd08, 0x15, RTL8211F_RX_DELAY,
+ val_rxdly);
+ if (ret < 0) {
+ dev_err(dev, "Failed to update the RX delay register\n");
+ return ret;
+ } else if (ret) {
+ dev_dbg(dev,
+ "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n",
+ val_rxdly ? "Enabling" : "Disabling");
+ } else {
+ dev_dbg(dev,
+ "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
+ val_rxdly ? "enabled" : "disabled");
}
return 0;
--
2.24.1
On 12/26/2019 10:51 AM, Martin Blumenstingl wrote:
> RGMII requires a delay of 2ns between the data and the clock signal.
> There are at least three ways this can happen. One possibility is by
> having the PHY generate this delay.
> This is a common source for problems (for example with slow TX speeds or
> packet loss when sending data). The TX delay configuration of the
> RTL8211F PHY can be set either by pin-strappping the RXD1 pin (HIGH
> means enabled, LOW means disabled) or through configuring a paged
> register. The setting from the RXD1 pin is also reflected in the
> register.
>
> Add debug logging to the TX delay configuration on RTL8211F so it's
> easier to spot these issues (for example if the TX delay is enabled for
> both, the RTL8211F PHY and the MAC).
> This is especially helpful because there is no public datasheet for the
> RTL8211F PHY available with all the RX/TX delay specifics.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
--
Florian
On 12/26/2019 10:51 AM, Martin Blumenstingl wrote:
> On RTL8211F the RX and TX delays (2ns) can be configured in two ways:
> - pin strapping (RXD1 for the TX delay and RXD0 for the RX delay, LOW
> means "off" and HIGH means "on") which is read during PHY reset
> - using software to configure the TX and RX delay registers
>
> So far only the configuration using pin strapping has been supported.
> Add support for enabling or disabling the RGMII RX delay based on the
> phy-mode to be able to get the RX delay into a known state. This is
> important because the RX delay has to be coordinated between the PHY,
> MAC and the PCB design (trace length). With an invalid RX delay applied
> (for example if both PHY and MAC add a 2ns RX delay) Ethernet may not
> work at all.
>
> Also add debug logging when configuring the RX delay (just like the TX
> delay) because this is a common source of problems.
>
> Signed-off-by: Martin Blumenstingl <[email protected]>
Reviewed-by: Florian Fainelli <[email protected]>
--
Florian
From: Martin Blumenstingl <[email protected]>
Date: Thu, 26 Dec 2019 19:51:46 +0100
> In discussion with Andrew [0] we figured out that it would be best to
> make the RX delay of the RTL8211F PHY configurable (just like the TX
> delay is already configurable).
>
> While here I took the opportunity to add some logging to the TX delay
> configuration as well.
...
Series applied to net-next, thank you.