871 lines
28 KiB
Diff
871 lines
28 KiB
Diff
From c5300de0fe982ae8a78e1b95ef7bf30b744e4ca1 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Fri, 25 Nov 2016 14:12:01 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix enabling of the TX-delay for
|
|
RTL8211F
|
|
|
|
The old logic always enabled the TX-delay when the phy-mode was set to
|
|
PHY_INTERFACE_MODE_RGMII. There are dedicated phy-modes which tell the
|
|
PHY driver to enable the RX and/or TX delays:
|
|
- PHY_INTERFACE_MODE_RGMII should disable the RX and TX delay in the
|
|
PHY (if required, the MAC should add the delays in this case)
|
|
- PHY_INTERFACE_MODE_RGMII_ID should enable RX and TX delay in the PHY
|
|
- PHY_INTERFACE_MODE_RGMII_TXID should enable the TX delay in the PHY
|
|
- PHY_INTERFACE_MODE_RGMII_RXID should enable the RX delay in the PHY
|
|
(currently not supported by RTL8211F)
|
|
|
|
With this patch we enable the TX delay for PHY_INTERFACE_MODE_RGMII_ID
|
|
and PHY_INTERFACE_MODE_RGMII_TXID.
|
|
Additionally we now explicity disable the TX-delay, which seems to be
|
|
enabled automatically after a hard-reset of the PHY (by triggering it's
|
|
reset pin) to get a consistent state (as defined by the phy-mode).
|
|
|
|
This fixes a compatibility problem with some SoCs where the TX-delay was
|
|
also added by the MAC. With the TX-delay being applied twice the TX
|
|
clock was off and TX traffic was broken or very slow (<10Mbit/s) on
|
|
1000Mbit/s links.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit e3230494b57ece68750e3e32d3e53d6b00917058)
|
|
---
|
|
drivers/net/phy/realtek.c | 20 ++++++++++++--------
|
|
1 file changed, 12 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 43ab691362d4..686f3b259dc0 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -102,15 +102,19 @@ static int rtl8211f_config_init(struct phy_device *phydev)
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
|
|
- /* enable TXDLY */
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
|
|
- reg = phy_read(phydev, 0x11);
|
|
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
|
|
+ reg = phy_read(phydev, 0x11);
|
|
+
|
|
+ /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
|
|
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
|
reg |= RTL8211F_TX_DELAY;
|
|
- phy_write(phydev, 0x11, reg);
|
|
- /* restore to default page 0 */
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
|
|
- }
|
|
+ else
|
|
+ reg &= ~RTL8211F_TX_DELAY;
|
|
+
|
|
+ phy_write(phydev, 0x11, reg);
|
|
+ /* restore to default page 0 */
|
|
+ phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
From 647c38d9964680f7fbb24c5a889ef74b23b4cbd4 Mon Sep 17 00:00:00 2001
|
|
From: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
Date: Tue, 12 Sep 2017 18:54:35 +0900
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL8211F_PAGE_SELECT to
|
|
RTL821x_PAGE_SELECT
|
|
|
|
This renames the definition of page select register from
|
|
RTL8211F_PAGE_SELECT to RTL821x_PAGE_SELECT to use it across models.
|
|
|
|
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 013955a6556766a76f9f2cc31e740fc6db6ecff4)
|
|
---
|
|
drivers/net/phy/realtek.c | 10 +++++-----
|
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 686f3b259dc0..d58cc8f518ac 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -22,11 +22,11 @@
|
|
#define RTL821x_INER 0x12
|
|
#define RTL821x_INER_INIT 0x6400
|
|
#define RTL821x_INSR 0x13
|
|
+#define RTL821x_PAGE_SELECT 0x1f
|
|
#define RTL8211E_INER_LINK_STATUS 0x400
|
|
|
|
#define RTL8211F_INER_LINK_STATUS 0x0010
|
|
#define RTL8211F_INSR 0x1d
|
|
-#define RTL8211F_PAGE_SELECT 0x1f
|
|
#define RTL8211F_TX_DELAY 0x100
|
|
|
|
MODULE_DESCRIPTION("Realtek PHY driver");
|
|
@@ -46,10 +46,10 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xa43);
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
|
|
err = phy_read(phydev, RTL8211F_INSR);
|
|
/* restore to default page 0 */
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
|
|
return (err < 0) ? err : 0;
|
|
}
|
|
@@ -102,7 +102,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0xd08);
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
|
|
reg = phy_read(phydev, 0x11);
|
|
|
|
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
|
|
@@ -114,7 +114,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
|
|
|
|
phy_write(phydev, 0x11, reg);
|
|
/* restore to default page 0 */
|
|
- phy_write(phydev, RTL8211F_PAGE_SELECT, 0x0);
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
From 724532e7b4ad78722821763c639a73383a0f4418 Mon Sep 17 00:00:00 2001
|
|
From: Jassi Brar <jaswinder.singh@linaro.org>
|
|
Date: Tue, 12 Sep 2017 18:54:36 +0900
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: add RTL8201F phy-id and
|
|
functions
|
|
|
|
Add RTL8201F phy-id and the related functions to the driver.
|
|
|
|
The original patch is as follows:
|
|
https://patchwork.kernel.org/patch/2538341/
|
|
|
|
Signed-off-by: Jongsung Kim <neidhard.kim@lge.com>
|
|
Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
|
|
Signed-off-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 513588dd44b09bb5fdd5066a4fbc1e7443b86d1c)
|
|
---
|
|
drivers/net/phy/realtek.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
|
1 file changed, 44 insertions(+)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index d58cc8f518ac..422cf1f6a60c 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -29,10 +29,22 @@
|
|
#define RTL8211F_INSR 0x1d
|
|
#define RTL8211F_TX_DELAY 0x100
|
|
|
|
+#define RTL8201F_ISR 0x1e
|
|
+#define RTL8201F_IER 0x13
|
|
+
|
|
MODULE_DESCRIPTION("Realtek PHY driver");
|
|
MODULE_AUTHOR("Johnson Leung");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
+static int rtl8201_ack_interrupt(struct phy_device *phydev)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ err = phy_read(phydev, RTL8201F_ISR);
|
|
+
|
|
+ return (err < 0) ? err : 0;
|
|
+}
|
|
+
|
|
static int rtl821x_ack_interrupt(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
@@ -54,6 +66,25 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
|
|
return (err < 0) ? err : 0;
|
|
}
|
|
|
|
+static int rtl8201_config_intr(struct phy_device *phydev)
|
|
+{
|
|
+ int err;
|
|
+
|
|
+ /* switch to page 7 */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
|
|
+
|
|
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
+ err = phy_write(phydev, RTL8201F_IER,
|
|
+ BIT(13) | BIT(12) | BIT(11));
|
|
+ else
|
|
+ err = phy_write(phydev, RTL8201F_IER, 0);
|
|
+
|
|
+ /* restore to default page 0 */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
static int rtl8211b_config_intr(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
@@ -129,6 +160,18 @@ static struct phy_driver realtek_drvs[] = {
|
|
.config_aneg = &genphy_config_aneg,
|
|
.read_status = &genphy_read_status,
|
|
.driver = { .owner = THIS_MODULE,},
|
|
+ }, {
|
|
+ .phy_id = 0x001cc816,
|
|
+ .name = "RTL8201F 10/100Mbps Ethernet",
|
|
+ .phy_id_mask = 0x001fffff,
|
|
+ .features = PHY_BASIC_FEATURES,
|
|
+ .flags = PHY_HAS_INTERRUPT,
|
|
+ .config_aneg = &genphy_config_aneg,
|
|
+ .read_status = &genphy_read_status,
|
|
+ .ack_interrupt = &rtl8201_ack_interrupt,
|
|
+ .config_intr = &rtl8201_config_intr,
|
|
+ .suspend = genphy_suspend,
|
|
+ .resume = genphy_resume,
|
|
}, {
|
|
.phy_id = 0x001cc912,
|
|
.name = "RTL8211B Gigabit Ethernet",
|
|
@@ -186,6 +229,7 @@ static struct phy_driver realtek_drvs[] = {
|
|
module_phy_driver(realtek_drvs);
|
|
|
|
static struct mdio_device_id __maybe_unused realtek_tbl[] = {
|
|
+ { 0x001cc816, 0x001fffff },
|
|
{ 0x001cc912, 0x001fffff },
|
|
{ 0x001cc914, 0x001fffff },
|
|
{ 0x001cc915, 0x001fffff },
|
|
|
|
From 933e1e195c40a941b6e5dec0c6a3a4bb7f804cf7 Mon Sep 17 00:00:00 2001
|
|
From: Heiner Kallweit <hkallweit1@gmail.com>
|
|
Date: Sun, 12 Nov 2017 16:16:04 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: fix RTL8211F interrupt mode
|
|
|
|
After commit b94d22d94ad22 "ARM64: dts: meson-gx: add external PHY
|
|
interrupt on some platforms" ethernet stopped working on my Odroid-C2
|
|
which has a RTL8211F phy.
|
|
|
|
It turned out that no interrupts were triggered. Further analysis
|
|
showed the register INER can't be altered on page 0.
|
|
Because register INSR needs to be accessed via page 0xa43 I assumed
|
|
that register INER needs to be accessed via some page too.
|
|
Some brute force check resulted in page 0xa42 being the right one.
|
|
|
|
With this patch the phy is working properly in interrupt mode.
|
|
|
|
Fixes: 3447cf2e9a11 ("net/phy: Add support for Realtek RTL8211F")
|
|
Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
|
|
Tested-by: Jerome Brunet <jbrunet@baylibre.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 3697d058b08d5b874f0253de173ef72e5d648f9a)
|
|
---
|
|
drivers/net/phy/realtek.c | 2 ++
|
|
1 file changed, 2 insertions(+)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 422cf1f6a60c..a30d0c08c63b 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -115,11 +115,13 @@ static int rtl8211f_config_intr(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
|
|
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
err = phy_write(phydev, RTL821x_INER,
|
|
RTL8211F_INER_LINK_STATUS);
|
|
else
|
|
err = phy_write(phydev, RTL821x_INER, 0);
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0);
|
|
|
|
return err;
|
|
}
|
|
|
|
From 046a2dc318a05236e06b09d8c0ca3f1005cbceca Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 22:51:24 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the BIT and GENMASK macros
|
|
|
|
This makes it easier to compare the #defines with the datasheets.
|
|
No functional changes.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 8cc5baefbc0266b6d6c8e99cb8568f59be36a575)
|
|
---
|
|
drivers/net/phy/realtek.c | 11 ++++++-----
|
|
1 file changed, 6 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index a30d0c08c63b..f8dc29a75828 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -13,21 +13,22 @@
|
|
* option) any later version.
|
|
*
|
|
*/
|
|
+#include <linux/bitops.h>
|
|
#include <linux/phy.h>
|
|
#include <linux/module.h>
|
|
|
|
#define RTL821x_PHYSR 0x11
|
|
-#define RTL821x_PHYSR_DUPLEX 0x2000
|
|
-#define RTL821x_PHYSR_SPEED 0xc000
|
|
+#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
|
#define RTL821x_INER 0x12
|
|
#define RTL821x_INER_INIT 0x6400
|
|
#define RTL821x_INSR 0x13
|
|
#define RTL821x_PAGE_SELECT 0x1f
|
|
-#define RTL8211E_INER_LINK_STATUS 0x400
|
|
+#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
|
|
-#define RTL8211F_INER_LINK_STATUS 0x0010
|
|
+#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
#define RTL8211F_INSR 0x1d
|
|
-#define RTL8211F_TX_DELAY 0x100
|
|
+#define RTL8211F_TX_DELAY BIT(8)
|
|
|
|
#define RTL8201F_ISR 0x1e
|
|
#define RTL8201F_IER 0x13
|
|
|
|
From 7894b1cae69475242cdb1ca0fb639a5d70ac6316 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 22:51:25 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: rename RTL821x_INER_INIT to
|
|
RTL8211B_INER_INIT
|
|
|
|
This macro is only used by the RTL8211B code. RTL8211E and RTL8211F both
|
|
use other bits to initialize the RTL821x_INER register.
|
|
No functional changes.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 69021e32ec3ef02170482f6ed8130febaed27357)
|
|
---
|
|
drivers/net/phy/realtek.c | 4 ++--
|
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index f8dc29a75828..89308eac4088 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -21,7 +21,7 @@
|
|
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
|
#define RTL821x_INER 0x12
|
|
-#define RTL821x_INER_INIT 0x6400
|
|
+#define RTL8211B_INER_INIT 0x6400
|
|
#define RTL821x_INSR 0x13
|
|
#define RTL821x_PAGE_SELECT 0x1f
|
|
#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
@@ -92,7 +92,7 @@ static int rtl8211b_config_intr(struct phy_device *phydev)
|
|
|
|
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
err = phy_write(phydev, RTL821x_INER,
|
|
- RTL821x_INER_INIT);
|
|
+ RTL8211B_INER_INIT);
|
|
else
|
|
err = phy_write(phydev, RTL821x_INER, 0);
|
|
|
|
|
|
From f6e8b6c88c6b3d4925607575bc4387a289d49708 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 22:51:26 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: group all register bit #defines
|
|
for RTL821x_INER
|
|
|
|
This simply moves all register bit #defines which describe the (PHY
|
|
specific) bits in the RTL821x_INER right below the RTL821x_INER register
|
|
definition. This makes it easier to spot which registers and bits belong
|
|
together.
|
|
No functional changes.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit a82f266d240d87e6111878bbfe287024fb6857c1)
|
|
---
|
|
drivers/net/phy/realtek.c | 7 +++++--
|
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 89308eac4088..df97d903d2bf 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -20,13 +20,16 @@
|
|
#define RTL821x_PHYSR 0x11
|
|
#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
|
+
|
|
#define RTL821x_INER 0x12
|
|
#define RTL8211B_INER_INIT 0x6400
|
|
+#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
+#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
+
|
|
#define RTL821x_INSR 0x13
|
|
+
|
|
#define RTL821x_PAGE_SELECT 0x1f
|
|
-#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
|
|
-#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
#define RTL8211F_INSR 0x1d
|
|
#define RTL8211F_TX_DELAY BIT(8)
|
|
|
|
|
|
From d5e2b112bb8e5707fc2fb727122ee5a8444ee462 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 22:51:27 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: use the same indentation for all
|
|
#defines
|
|
|
|
This simply makes the code easier to read. No functional changes.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit f609ab0ed8e7bef2cd61d230bf9e83e1ec5b9ddb)
|
|
---
|
|
drivers/net/phy/realtek.c | 27 ++++++++++++++-------------
|
|
1 file changed, 14 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index df97d903d2bf..701f34ad7d8d 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -17,24 +17,25 @@
|
|
#include <linux/phy.h>
|
|
#include <linux/module.h>
|
|
|
|
-#define RTL821x_PHYSR 0x11
|
|
-#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
-#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
|
+#define RTL821x_PHYSR 0x11
|
|
+#define RTL821x_PHYSR_DUPLEX BIT(13)
|
|
+#define RTL821x_PHYSR_SPEED GENMASK(15, 14)
|
|
|
|
-#define RTL821x_INER 0x12
|
|
-#define RTL8211B_INER_INIT 0x6400
|
|
-#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
-#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
+#define RTL821x_INER 0x12
|
|
+#define RTL8211B_INER_INIT 0x6400
|
|
+#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
+#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
|
|
-#define RTL821x_INSR 0x13
|
|
+#define RTL821x_INSR 0x13
|
|
|
|
-#define RTL821x_PAGE_SELECT 0x1f
|
|
+#define RTL821x_PAGE_SELECT 0x1f
|
|
|
|
-#define RTL8211F_INSR 0x1d
|
|
-#define RTL8211F_TX_DELAY BIT(8)
|
|
+#define RTL8211F_INSR 0x1d
|
|
|
|
-#define RTL8201F_ISR 0x1e
|
|
-#define RTL8201F_IER 0x13
|
|
+#define RTL8211F_TX_DELAY BIT(8)
|
|
+
|
|
+#define RTL8201F_ISR 0x1e
|
|
+#define RTL8201F_IER 0x13
|
|
|
|
MODULE_DESCRIPTION("Realtek PHY driver");
|
|
MODULE_AUTHOR("Johnson Leung");
|
|
|
|
From 8c16425a3c99a1cca4458eb17bd6414d65074027 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 22:51:28 +0100
|
|
Subject: [PATCH] UPSTREAM: net: phy: realtek: add utility functions to
|
|
read/write page addresses
|
|
|
|
Realtek PHYs implement the concept of so-called "extension pages". The
|
|
reason for this is probably because these PHYs expose more registers
|
|
than available in the standard address range.
|
|
After all read/write operations on such a page are done the driver
|
|
should switch back to page 0 where the standard MII registers (such as
|
|
MII_BMCR) are available.
|
|
|
|
When referring to such a register the datasheets of RTL8211E and
|
|
RTL8211F always specify:
|
|
- the page / "ext. page" which has to be written to RTL821x_PAGE_SELECT
|
|
- an address (sometimes also called reg)
|
|
|
|
These new utility functions make the existing code easier to read since
|
|
it removes some duplication (switching back to page 0 is done within the
|
|
new helpers for example).
|
|
|
|
No functional changes are intended.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
(cherry picked from commit 136819a6e8df374e6b9b424586ff11c9e241a1cb)
|
|
---
|
|
drivers/net/phy/realtek.c | 83 ++++++++++++++++++++++++++++++-----------------
|
|
1 file changed, 53 insertions(+), 30 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 701f34ad7d8d..b1d52e61d91c 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -41,6 +41,39 @@ MODULE_DESCRIPTION("Realtek PHY driver");
|
|
MODULE_AUTHOR("Johnson Leung");
|
|
MODULE_LICENSE("GPL");
|
|
|
|
+static int rtl8211x_page_read(struct phy_device *phydev, u16 page, u16 address)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = phy_read(phydev, address);
|
|
+
|
|
+ /* restore to default page 0 */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
|
|
+ u16 address, u16 val)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ ret = phy_write(phydev, RTL821x_PAGE_SELECT, page);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ ret = phy_write(phydev, address, val);
|
|
+
|
|
+ /* restore to default page 0 */
|
|
+ phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int rtl8201_ack_interrupt(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
@@ -63,31 +96,21 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa43);
|
|
- err = phy_read(phydev, RTL8211F_INSR);
|
|
- /* restore to default page 0 */
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
+ err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR);
|
|
|
|
return (err < 0) ? err : 0;
|
|
}
|
|
|
|
static int rtl8201_config_intr(struct phy_device *phydev)
|
|
{
|
|
- int err;
|
|
-
|
|
- /* switch to page 7 */
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x7);
|
|
+ u16 val;
|
|
|
|
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
- err = phy_write(phydev, RTL8201F_IER,
|
|
- BIT(13) | BIT(12) | BIT(11));
|
|
+ val = BIT(13) | BIT(12) | BIT(11);
|
|
else
|
|
- err = phy_write(phydev, RTL8201F_IER, 0);
|
|
+ val = 0;
|
|
|
|
- /* restore to default page 0 */
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
-
|
|
- return err;
|
|
+ return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val);
|
|
}
|
|
|
|
static int rtl8211b_config_intr(struct phy_device *phydev)
|
|
@@ -118,41 +141,41 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
|
|
|
|
static int rtl8211f_config_intr(struct phy_device *phydev)
|
|
{
|
|
- int err;
|
|
+ u16 val;
|
|
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xa42);
|
|
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
- err = phy_write(phydev, RTL821x_INER,
|
|
- RTL8211F_INER_LINK_STATUS);
|
|
+ val = RTL8211F_INER_LINK_STATUS;
|
|
else
|
|
- err = phy_write(phydev, RTL821x_INER, 0);
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0);
|
|
+ val = 0;
|
|
|
|
- return err;
|
|
+ return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
|
|
}
|
|
|
|
static int rtl8211f_config_init(struct phy_device *phydev)
|
|
{
|
|
int ret;
|
|
- u16 reg;
|
|
+ u16 val;
|
|
|
|
ret = genphy_config_init(phydev);
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0xd08);
|
|
- reg = phy_read(phydev, 0x11);
|
|
+ ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ val = ret & 0xffff;
|
|
|
|
/* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
|
|
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
|
- reg |= RTL8211F_TX_DELAY;
|
|
+ val |= RTL8211F_TX_DELAY;
|
|
else
|
|
- reg &= ~RTL8211F_TX_DELAY;
|
|
+ val &= ~RTL8211F_TX_DELAY;
|
|
|
|
- phy_write(phydev, 0x11, reg);
|
|
- /* restore to default page 0 */
|
|
- phy_write(phydev, RTL821x_PAGE_SELECT, 0x0);
|
|
+ ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
return 0;
|
|
}
|
|
|
|
From 13e556c6d4ece3c890edc414f205cc26381e9826 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 23:06:48 +0100
|
|
Subject: [PATCH] FROMLIST: net: phy: realtek: add support for configuring the
|
|
RX delay on RTL8211F
|
|
|
|
On RTL8211F the RX delay can also be enabled/disabled.
|
|
The overall behavior of the RX delay is similar to the behavior of the
|
|
TX delay, which was already supported by the driver.
|
|
|
|
The RX delay (similar to the TX delay) may be enabled using hardware pin
|
|
strapping. If the MAC already configures the RX delay (if required) then
|
|
the RX delay generated by the RTL8211F PHY has to be turned off.
|
|
|
|
While here, update the comment regarding the TX delay why it has to be
|
|
enabled or disabled within the driver.
|
|
Also avoid code-duplication by extracting the code to mask/unmask bits
|
|
in a paged register into a new rtl8211x_page_mask_bits helper function.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
---
|
|
drivers/net/phy/realtek.c | 55 ++++++++++++++++++++++++++++++++++++++---------
|
|
1 file changed, 45 insertions(+), 10 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index b1d52e61d91c..890ea9d18d27 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -32,7 +32,10 @@
|
|
|
|
#define RTL8211F_INSR 0x1d
|
|
|
|
-#define RTL8211F_TX_DELAY BIT(8)
|
|
+#define RTL8211F_RX_DELAY_REG 0x15
|
|
+#define RTL8211F_RX_DELAY_EN BIT(3)
|
|
+#define RTL8211F_TX_DELAY_REG 0x11
|
|
+#define RTL8211F_TX_DELAY_EN BIT(8)
|
|
|
|
#define RTL8201F_ISR 0x1e
|
|
#define RTL8201F_IER 0x13
|
|
@@ -74,6 +77,23 @@ static int rtl8211x_page_write(struct phy_device *phydev, u16 page,
|
|
return ret;
|
|
}
|
|
|
|
+static int rtl8211x_page_mask_bits(struct phy_device *phydev, u16 page,
|
|
+ u16 address, u16 mask, u16 set)
|
|
+{
|
|
+ int ret;
|
|
+ u16 val;
|
|
+
|
|
+ ret = rtl8211x_page_read(phydev, page, address);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+
|
|
+ val = ret & 0xffff;
|
|
+ val &= ~mask;
|
|
+ val |= (set & mask);
|
|
+
|
|
+ return rtl8211x_page_write(phydev, page, address, val);
|
|
+}
|
|
+
|
|
static int rtl8201_ack_interrupt(struct phy_device *phydev)
|
|
{
|
|
int err;
|
|
@@ -160,20 +180,35 @@ static int rtl8211f_config_init(struct phy_device *phydev)
|
|
if (ret < 0)
|
|
return ret;
|
|
|
|
- ret = rtl8211x_page_read(phydev, 0xd08, 0x11);
|
|
- if (ret < 0)
|
|
- return ret;
|
|
+ /*
|
|
+ * enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it.
|
|
+ * this is needed because it can be enabled by pin strapping and
|
|
+ * conflict with the TX-delay configured by the MAC.
|
|
+ */
|
|
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
|
+ val = RTL8211F_TX_DELAY_EN;
|
|
+ else
|
|
+ val = 0;
|
|
|
|
- val = ret & 0xffff;
|
|
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_TX_DELAY_REG,
|
|
+ RTL8211F_TX_DELAY_EN, val);
|
|
+ if (ret)
|
|
+ return ret;
|
|
|
|
- /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
|
|
+ /*
|
|
+ * enable RX-delay for rgmii-id and rgmii-rxid, otherwise disable it.
|
|
+ * this is needed because it can be enabled by pin strapping and
|
|
+ * conflict with the RX-delay configured by the MAC.
|
|
+ */
|
|
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
|
|
- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
|
|
- val |= RTL8211F_TX_DELAY;
|
|
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
|
|
+ val = RTL8211F_RX_DELAY_EN;
|
|
else
|
|
- val &= ~RTL8211F_TX_DELAY;
|
|
+ val = 0;
|
|
|
|
- ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val);
|
|
+ ret = rtl8211x_page_mask_bits(phydev, 0xd08, RTL8211F_RX_DELAY_REG,
|
|
+ RTL8211F_RX_DELAY_EN, val);
|
|
if (ret)
|
|
return ret;
|
|
|
|
|
|
From e8fa4ce26460af84f028b7d215134caa33aa9ecb Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 23:06:49 +0100
|
|
Subject: [PATCH] FROMLIST: net: phy: realtek: configure the INTB pin on
|
|
RTL8211F
|
|
|
|
The interrupt pin on the RTL8211F PHY can be used in two different
|
|
modes:
|
|
INTB
|
|
- the default mode of the PHY
|
|
- interrupts can be configured through page 0xa42 register RTL821x_INER
|
|
- interrupts can be ACK'ed through RTL8211F_INSR
|
|
- it acts as a level-interrupt which is active low
|
|
- Wake-on-LAN "wakeup" status is available in RTL8211F_INSR bit 7
|
|
|
|
PMEB:
|
|
- special mode for Wake-on-LAN
|
|
- interrupts configured through page 0xa42 register RTL821x_INER are
|
|
disabled
|
|
- it supports a "pulse low" waveform for the interrupt
|
|
|
|
For now we simply force the pin into INTB mode since the PHY driver does
|
|
not support Wake-on-LAN yet.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
---
|
|
drivers/net/phy/realtek.c | 27 +++++++++++++++++++++++++--
|
|
1 file changed, 25 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index 890ea9d18d27..f307d220b49a 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -40,6 +40,9 @@
|
|
#define RTL8201F_ISR 0x1e
|
|
#define RTL8201F_IER 0x13
|
|
|
|
+#define RTL8211F_INTBCR 0x16
|
|
+#define RTL8211F_INTBCR_INTB_PMEB BIT(5)
|
|
+
|
|
MODULE_DESCRIPTION("Realtek PHY driver");
|
|
MODULE_AUTHOR("Johnson Leung");
|
|
MODULE_LICENSE("GPL");
|
|
@@ -161,12 +164,32 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
|
|
|
|
static int rtl8211f_config_intr(struct phy_device *phydev)
|
|
{
|
|
+ int err;
|
|
u16 val;
|
|
|
|
- if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
|
|
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
|
|
+ /*
|
|
+ * The interrupt pin has two functions:
|
|
+ * 0: INTB: it acts as interrupt pin which can be configured
|
|
+ * through RTL821x_INER and the status can be read through
|
|
+ * RTL8211F_INSR
|
|
+ * 1: PMEB: a special "Power Management Event" mode for
|
|
+ * Wake-on-LAN operation (with support for a "pulse low"
|
|
+ * wave format). Interrupts configured through RTL821x_INER
|
|
+ * will not work in this mode
|
|
+ *
|
|
+ * select INTB mode in the "INTB pin control" register to
|
|
+ * ensure that the interrupt pin is in the correct mode.
|
|
+ */
|
|
+ err = rtl8211x_page_mask_bits(phydev, 0xd40, RTL8211F_INTBCR,
|
|
+ RTL8211F_INTBCR_INTB_PMEB, 0);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
val = RTL8211F_INER_LINK_STATUS;
|
|
- else
|
|
+ } else {
|
|
val = 0;
|
|
+ }
|
|
|
|
return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val);
|
|
}
|
|
|
|
From dd026c252cd898bca0b85eb14aa6479b415d2471 Mon Sep 17 00:00:00 2001
|
|
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
Date: Sat, 2 Dec 2017 23:06:50 +0100
|
|
Subject: [PATCH] FROMLIST: net: phy: realtek: add more interrupt bits for
|
|
RTL8211E and RTL8211F
|
|
|
|
This documents a few more bits in the RTL821x_INER register for RTL8211E
|
|
and RTL8211F. These are added only to document them (as no public
|
|
datasheets are available for these PHYs), they are currently not used.
|
|
|
|
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
|
|
---
|
|
drivers/net/phy/realtek.c | 7 +++++++
|
|
1 file changed, 7 insertions(+)
|
|
|
|
diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
|
|
index f307d220b49a..15d342eefd6d 100644
|
|
--- a/drivers/net/phy/realtek.c
|
|
+++ b/drivers/net/phy/realtek.c
|
|
@@ -24,7 +24,14 @@
|
|
#define RTL821x_INER 0x12
|
|
#define RTL8211B_INER_INIT 0x6400
|
|
#define RTL8211E_INER_LINK_STATUS BIT(10)
|
|
+#define RTL8211E_INER_ANEG_COMPLETED BIT(11)
|
|
+#define RTL8211E_INER_PAGE_RECEIVED BIT(12)
|
|
+#define RTL8211E_INER_ANEG_ERROR BIT(15)
|
|
#define RTL8211F_INER_LINK_STATUS BIT(4)
|
|
+#define RTL8211F_INER_PHY_REGISTER_ACCESSIBLE BIT(5)
|
|
+#define RTL8211F_INER_WOL_PME BIT(7)
|
|
+#define RTL8211F_INER_ALDPS_STATE_CHANGE BIT(9)
|
|
+#define RTL8211F_INER_JABBER BIT(10)
|
|
|
|
#define RTL821x_INSR 0x13
|
|
|