aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/realtek
diff options
context:
space:
mode:
authorDaniel Golle <daniel@makrotopia.org>2022-02-10 20:17:58 +0000
committerDaniel Golle <daniel@makrotopia.org>2022-02-17 15:37:03 +0000
commiteef7f17652001ce7c087b8576c0021494a0e7e7e (patch)
treeadc5535f213b48d291652959e011fc67979e6fbf /target/linux/realtek
parent68c66b0fa3a101841acf163baa2db6f884a4a24d (diff)
downloadupstream-eef7f17652001ce7c087b8576c0021494a0e7e7e.tar.gz
upstream-eef7f17652001ce7c087b8576c0021494a0e7e7e.tar.bz2
upstream-eef7f17652001ce7c087b8576c0021494a0e7e7e.zip
realtek: rtl83xx-phy: abstract and document PHY features
Replace magic values with more self-descriptive code now that I start to understand more about the design of the PHY (and MDIO controller). Remove one line before reading RTL8214FC internal PHY id which turned out to be a no-op and can hence safely be removed (confirmed by INAGAKI Hiroshi[1]) [1]: https://github.com/openwrt/openwrt/commit/df8e6be59a1fbce3f8c6878fe7440a129b1245d6#r66890713 Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Diffstat (limited to 'target/linux/realtek')
-rw-r--r--target/linux/realtek/files-5.10/drivers/net/phy/rtl83xx-phy.c249
1 files changed, 135 insertions, 114 deletions
diff --git a/target/linux/realtek/files-5.10/drivers/net/phy/rtl83xx-phy.c b/target/linux/realtek/files-5.10/drivers/net/phy/rtl83xx-phy.c
index 9b674e51ab..f0c30b3655 100644
--- a/target/linux/realtek/files-5.10/drivers/net/phy/rtl83xx-phy.c
+++ b/target/linux/realtek/files-5.10/drivers/net/phy/rtl83xx-phy.c
@@ -22,7 +22,34 @@ extern struct mutex smi_lock;
#define PHY_PAGE_2 2
#define PHY_PAGE_4 4
-#define PARK_PAGE 0x1f
+
+/* all Clause-22 RealTek MDIO PHYs use register 0x1f for page select */
+#define RTL8XXX_PAGE_SELECT 0x1f
+
+#define RTL8XXX_PAGE_MAIN 0x0000
+#define RTL821X_PAGE_PORT 0x0266
+#define RTL821X_PAGE_POWER 0x0a40
+#define RTL821X_PAGE_GPHY 0x0a42
+#define RTL821X_PAGE_MAC 0x0a43
+#define RTL821X_PAGE_STATE 0x0b80
+#define RTL821X_PAGE_PATCH 0x0b82
+
+/*
+ * Using the special page 0xfff with the MDIO controller found in
+ * RealTek SoCs allows to access the PHY in RAW mode, ie. bypassing
+ * the cache and paging engine of the MDIO controller.
+ */
+#define RTL83XX_PAGE_RAW 0x0fff
+
+/* internal RTL821X PHY uses register 0x1d to select media page */
+#define RTL821XINT_MEDIA_PAGE_SELECT 0x1d
+/* external RTL821X PHY uses register 0x1e to select media page */
+#define RTL821XEXT_MEDIA_PAGE_SELECT 0x1e
+
+#define RTL821X_MEDIA_PAGE_AUTO 0
+#define RTL821X_MEDIA_PAGE_COPPER 1
+#define RTL821X_MEDIA_PAGE_FIBRE 3
+#define RTL821X_MEDIA_PAGE_INTERNAL 8
#define RTL9300_PHY_ID_MASK 0xf0ffffff
@@ -103,12 +130,12 @@ static void rtl8380_int_phy_on_off(struct phy_device *phydev, bool on)
static void rtl8380_rtl8214fc_on_off(struct phy_device *phydev, bool on)
{
/* fiber ports */
- phy_write_paged(phydev, 4095, 30, 3);
- phy_modify(phydev, 16, BIT(11), on?0:BIT(11));
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
+ phy_modify(phydev, 0x10, BIT(11), on?0:BIT(11));
/* copper ports */
- phy_write_paged(phydev, 4095, 30, 1);
- phy_modify_paged(phydev, 0xa40, 16, BIT(11), on?0:BIT(11));
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ phy_modify_paged(phydev, RTL821X_PAGE_POWER, 0x10, BIT(11), on?0:BIT(11));
}
static void rtl8380_phy_reset(struct phy_device *phydev)
@@ -400,12 +427,12 @@ static int rtl8393_read_status(struct phy_device *phydev)
static int rtl8226_read_page(struct phy_device *phydev)
{
- return __phy_read(phydev, 0x1f);
+ return __phy_read(phydev, RTL8XXX_PAGE_SELECT);
}
static int rtl8226_write_page(struct phy_device *phydev, int page)
{
- return __phy_write(phydev, 0x1f, page);
+ return __phy_write(phydev, RTL8XXX_PAGE_SELECT, page);
}
static int rtl8226_read_status(struct phy_device *phydev)
@@ -641,6 +668,25 @@ out:
return NULL;
}
+static void rtl821x_phy_setup_package_broadcast(struct phy_device *phydev, bool enable)
+{
+ int mac = phydev->mdio.addr;
+
+ /* select main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ /* write to 0x8 to register 0x1d on main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ /* select page 0x266 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PORT);
+ /* set phy id and target broadcast bitmap in register 0x16 on page 0x266 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x16, (enable?0xff00:0x00) | mac);
+ /* return to main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ /* write to 0x0 to register 0x1d on main page 0 */
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
+ mdelay(1);
+}
+
static int rtl8390_configure_generic(struct phy_device *phydev)
{
int mac = phydev->mdio.addr;
@@ -714,13 +760,13 @@ static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev)
/* Ready PHY for patch */
for (p = 0; p < 8; p++) {
- phy_package_port_write_paged(phydev, p, 0xfff, 0x1f, 0x0b82);
- phy_package_port_write_paged(phydev, p, 0xfff, 0x10, 0x0010);
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW, 0x10, 0x0010);
}
msleep(500);
for (p = 0; p < 8; p++) {
for (i = 0; i < 100 ; i++) {
- val = phy_package_port_read_paged(phydev, p, 0x0b80, 0x10);
+ val = phy_package_port_read_paged(phydev, p, RTL821X_PAGE_STATE, 0x10);
if (val & 0x40)
break;
}
@@ -734,14 +780,14 @@ static int rtl8380_configure_int_rtl8218b(struct phy_device *phydev)
for (p = 0; p < 8; p++) {
i = 0;
while (rtl838x_6275B_intPhy_perport[i * 2]) {
- phy_package_port_write_paged(phydev, p, 0xfff,
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
rtl838x_6275B_intPhy_perport[i * 2],
rtl838x_6275B_intPhy_perport[i * 2 + 1]);
i++;
}
i = 0;
while (rtl8218b_6276B_hwEsd_perport[i * 2]) {
- phy_package_port_write_paged(phydev, p, 0xfff,
+ phy_package_port_write_paged(phydev, p, RTL83XX_PAGE_RAW,
rtl8218b_6276B_hwEsd_perport[i * 2],
rtl8218b_6276B_hwEsd_perport[i * 2 + 1]);
i++;
@@ -806,9 +852,9 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
msleep(100);
/* Get Chip revision */
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0);
- phy_write_paged(phydev, 0xfff, 0x1b, 0x4);
- val = phy_read_paged(phydev, 0xfff, 0x1c);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 0x1b, 0x4);
+ val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 0x1c);
phydev_info(phydev, "Detected chip revision %04x\n", val);
@@ -816,22 +862,22 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
while (rtl8380_rtl8218b_perchip[i * 3]
&& rtl8380_rtl8218b_perchip[i * 3 + 1]) {
phy_package_port_write_paged(phydev, rtl8380_rtl8218b_perchip[i * 3],
- 0xfff, rtl8380_rtl8218b_perchip[i * 3 + 1],
+ RTL83XX_PAGE_RAW, rtl8380_rtl8218b_perchip[i * 3 + 1],
rtl8380_rtl8218b_perchip[i * 3 + 2]);
i++;
}
/* Enable PHY */
for (i = 0; i < 8; i++) {
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1f, 0x0000);
- phy_package_port_write_paged(phydev, i, 0xfff, 0x00, 0x1140);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
}
mdelay(100);
/* Request patch */
for (i = 0; i < 8; i++) {
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1f, 0x0b82);
- phy_package_port_write_paged(phydev, i, 0xfff, 0x10, 0x0010);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
}
mdelay(300);
@@ -839,7 +885,7 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
/* Verify patch readiness */
for (i = 0; i < 8; i++) {
for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, 0xb80, 0x10);
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
if (val & 0x40)
break;
}
@@ -850,15 +896,9 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
}
/* Use Broadcast ID method for patching */
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0008);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0266);
- phy_write_paged(phydev, 0xfff, 0x16, 0xff00 + mac);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0000);
- mdelay(1);
+ rtl821x_phy_setup_package_broadcast(phydev, true);
- phy_write_paged(phydev, 0xfff, 30, 8);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 30, 8);
phy_write_paged(phydev, 0x26e, 17, 0xb);
phy_write_paged(phydev, 0x26e, 16, 0x2);
mdelay(1);
@@ -868,19 +908,13 @@ static int rtl8380_configure_ext_rtl8218b(struct phy_device *phydev)
i = 0;
while (rtl8218B_6276B_rtl8380_perport[i * 2]) {
- phy_write_paged(phydev, 0xfff, rtl8218B_6276B_rtl8380_perport[i * 2],
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8218B_6276B_rtl8380_perport[i * 2],
rtl8218B_6276B_rtl8380_perport[i * 2 + 1]);
i++;
}
/*Disable broadcast ID*/
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0008);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0266);
- phy_write_paged(phydev, 0xfff, 0x16, 0x00 + mac);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0000);
- mdelay(1);
+ rtl821x_phy_setup_package_broadcast(phydev, false);
return 0;
}
@@ -908,25 +942,25 @@ static void rtl8380_rtl8214fc_media_set(struct phy_device *phydev, bool set_fibr
int val, media, power;
pr_info("%s: port %d, set_fibre: %d\n", __func__, mac, set_fibre);
- phy_package_write_paged(phydev, 0xfff, 29, 8);
- val = phy_package_read_paged(phydev, 0x266, reg[mac % 4]);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
media = (val >> 10) & 0x3;
pr_info("Current media %x\n", media);
if (media & 0x2) {
pr_info("Powering off COPPER\n");
- phy_package_write_paged(phydev, 0xfff, 29, 1);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
/* Ensure power is off */
- power = phy_package_read_paged(phydev, 0xa40, 16);
+ power = phy_package_read_paged(phydev, RTL821X_PAGE_POWER, 0x10);
if (!(power & (1 << 11)))
- phy_package_write_paged(phydev, 0xa40, 16, power | (1 << 11));
+ phy_package_write_paged(phydev, RTL821X_PAGE_POWER, 0x10, power | (1 << 11));
} else {
pr_info("Powering off FIBRE");
- phy_package_write_paged(phydev, 0xfff, 29, 3);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
/* Ensure power is off */
- power = phy_package_read_paged(phydev, 0xa40, 16);
+ power = phy_package_read_paged(phydev, RTL821X_PAGE_POWER, 0x10);
if (!(power & (1 << 11)))
- phy_package_write_paged(phydev, 0xa40, 16, power | (1 << 11));
+ phy_package_write_paged(phydev, RTL821X_PAGE_POWER, 0x10, power | (1 << 11));
}
if (set_fibre) {
@@ -936,27 +970,27 @@ static void rtl8380_rtl8214fc_media_set(struct phy_device *phydev, bool set_fibr
val |= 1 << 10;
val |= 1 << 11;
}
- phy_package_write_paged(phydev, 0xfff, 29, 8);
- phy_package_write_paged(phydev, 0x266, reg[mac % 4], val);
- phy_package_write_paged(phydev, 0xfff, 29, 0);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ phy_package_write_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4], val);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
if (set_fibre) {
pr_info("Powering on FIBRE");
- phy_package_write_paged(phydev, 0xfff, 29, 3);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_FIBRE);
/* Ensure power is off */
- power = phy_package_read_paged(phydev, 0xa40, 16);
+ power = phy_package_read_paged(phydev, RTL821X_PAGE_POWER, 0x10);
if (power & (1 << 11))
- phy_package_write_paged(phydev, 0xa40, 16, power & ~(1 << 11));
+ phy_package_write_paged(phydev, RTL821X_PAGE_POWER, 0x10, power & ~(1 << 11));
} else {
pr_info("Powering on COPPER\n");
- phy_package_write_paged(phydev, 0xfff, 29, 1);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
/* Ensure power is off */
- power = phy_package_read_paged(phydev, 0xa40, 16);
+ power = phy_package_read_paged(phydev, RTL821X_PAGE_POWER, 0x10);
if (power & (1 << 11))
- phy_package_write_paged(phydev, 0xa40, 16, power & ~(1 << 11));
+ phy_package_write_paged(phydev, RTL821X_PAGE_POWER, 0x10, power & ~(1 << 11));
}
- phy_package_write_paged(phydev, 0xfff, 29, 0);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
}
static bool rtl8380_rtl8214fc_media_is_fibre(struct phy_device *phydev)
@@ -966,9 +1000,9 @@ static bool rtl8380_rtl8214fc_media_is_fibre(struct phy_device *phydev)
static int reg[] = {16, 19, 20, 21};
u32 val;
- phy_package_write_paged(phydev, 0xfff, 29, 8);
- val = phy_package_read_paged(phydev, 0x266, reg[mac % 4]);
- phy_package_write_paged(phydev, 0xfff, 29, 0);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_INTERNAL);
+ val = phy_package_read_paged(phydev, RTL821X_PAGE_PORT, reg[mac % 4]);
+ phy_package_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
if (val & (1 << 11))
return false;
return true;
@@ -1008,7 +1042,7 @@ void rtl8218d_eee_set(struct phy_device *phydev, bool enable)
pr_debug("In %s %d, enable %d\n", __func__, phydev->mdio.addr, enable);
/* Set GPHY page to copper */
- phy_write_paged(phydev, 0xa42, 30, 0x0001);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
val = phy_read(phydev, 0);
an_enabled = val & BIT(12);
@@ -1019,12 +1053,12 @@ void rtl8218d_eee_set(struct phy_device *phydev, bool enable)
phy_write_mmd(phydev, 7, 60, enable ? 0x6 : 0);
/* 500M EEE ability */
- val = phy_read_paged(phydev, 0xa42, 20);
+ val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
if (enable)
val |= BIT(7);
else
val &= ~BIT(7);
- phy_write_paged(phydev, 0xa42, 20, val);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
/* Restart AN if enabled */
if (an_enabled) {
@@ -1034,7 +1068,7 @@ void rtl8218d_eee_set(struct phy_device *phydev, bool enable)
}
/* GPHY page back to auto*/
- phy_write_paged(phydev, 0xa42, 30, 0);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
}
static int rtl8218b_get_eee(struct phy_device *phydev,
@@ -1046,21 +1080,21 @@ static int rtl8218b_get_eee(struct phy_device *phydev,
pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
/* Set GPHY page to copper */
- phy_write_paged(phydev, 0xa42, 29, 0x0001);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
val = phy_read_paged(phydev, 7, 60);
if (e->eee_enabled) {
// Verify vs MAC-based EEE
e->eee_enabled = !!(val & BIT(7));
if (!e->eee_enabled) {
- val = phy_read_paged(phydev, 0x0A43, 25);
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
e->eee_enabled = !!(val & BIT(4));
}
}
pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
/* GPHY page to auto */
- phy_write_paged(phydev, 0xa42, 29, 0x0000);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
return 0;
}
@@ -1074,7 +1108,7 @@ static int rtl8218d_get_eee(struct phy_device *phydev,
pr_debug("In %s, port %d, was enabled: %d\n", __func__, addr, e->eee_enabled);
/* Set GPHY page to copper */
- phy_write_paged(phydev, 0xa42, 30, 0x0001);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
val = phy_read_paged(phydev, 7, 60);
if (e->eee_enabled)
@@ -1082,7 +1116,7 @@ static int rtl8218d_get_eee(struct phy_device *phydev,
pr_debug("%s: enabled: %d\n", __func__, e->eee_enabled);
/* GPHY page to auto */
- phy_write_paged(phydev, 0xa42, 30, 0x0000);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
return 0;
}
@@ -1105,28 +1139,28 @@ static int rtl8214fc_set_eee(struct phy_device *phydev,
poll_state = disable_polling(port);
/* Set GPHY page to copper */
- phy_write_paged(phydev, 0xa42, 29, 0x0001);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
// Get auto-negotiation status
val = phy_read(phydev, 0);
an_enabled = val & BIT(12);
pr_info("%s: aneg: %d\n", __func__, an_enabled);
- val = phy_read_paged(phydev, 0x0A43, 25);
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
val &= ~BIT(5); // Use MAC-based EEE
- phy_write_paged(phydev, 0x0A43, 25, val);
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
/* Enable 100M (bit 1) / 1000M (bit 2) EEE */
phy_write_paged(phydev, 7, 60, e->eee_enabled ? 0x6 : 0);
/* 500M EEE ability */
- val = phy_read_paged(phydev, 0xa42, 20);
+ val = phy_read_paged(phydev, RTL821X_PAGE_GPHY, 20);
if (e->eee_enabled)
val |= BIT(7);
else
val &= ~BIT(7);
- phy_write_paged(phydev, 0xa42, 20, val);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, 20, val);
/* Restart AN if enabled */
if (an_enabled) {
@@ -1137,7 +1171,7 @@ static int rtl8214fc_set_eee(struct phy_device *phydev,
}
/* GPHY page back to auto*/
- phy_write_paged(phydev, 0xa42, 29, 0);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
resume_polling(poll_state);
@@ -1170,7 +1204,7 @@ static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
poll_state = disable_polling(port);
/* Set GPHY page to copper */
- phy_write(phydev, 30, 0x0001);
+ phy_write(phydev, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
val = phy_read(phydev, 0);
an_enabled = val & BIT(12);
@@ -1181,9 +1215,9 @@ static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
phy_write(phydev, 13, 0x4007);
phy_write(phydev, 14, 0x0006);
- val = phy_read_paged(phydev, 0x0A43, 25);
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
val |= BIT(4);
- phy_write_paged(phydev, 0x0A43, 25, val);
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
} else {
/* 100/1000M EEE Capability */
phy_write(phydev, 13, 0x0007);
@@ -1191,9 +1225,9 @@ static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
phy_write(phydev, 13, 0x0007);
phy_write(phydev, 14, 0x0000);
- val = phy_read_paged(phydev, 0x0A43, 25);
+ val = phy_read_paged(phydev, RTL821X_PAGE_MAC, 25);
val &= ~BIT(4);
- phy_write_paged(phydev, 0x0A43, 25, val);
+ phy_write_paged(phydev, RTL821X_PAGE_MAC, 25, val);
}
/* Restart AN if enabled */
@@ -1204,7 +1238,7 @@ static int rtl8218b_set_eee(struct phy_device *phydev, struct ethtool_eee *e)
}
/* GPHY page back to auto*/
- phy_write_paged(phydev, 0xa42, 30, 0);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
pr_info("%s done\n", __func__);
resume_polling(poll_state);
@@ -1247,7 +1281,7 @@ static int rtl8380_configure_rtl8214c(struct phy_device *phydev)
phydev_info(phydev, "Detected external RTL8214C\n");
/* GPHY auto conf */
- phy_write_paged(phydev, 0xa42, 29, 0);
+ phy_write_paged(phydev, RTL821X_PAGE_GPHY, RTL821XINT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
return 0;
}
@@ -1267,10 +1301,9 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
pr_debug("Phy on MAC %d: %x\n", mac, phy_id);
/* Read internal PHY id */
- phy_write_paged(phydev, 0, 30, 0x0001);
- phy_write_paged(phydev, 0, 31, 0x0a42);
- phy_write_paged(phydev, 31, 27, 0x0002);
- val = phy_read_paged(phydev, 31, 28);
+ phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
+ phy_write_paged(phydev, 0x1f, 0x1b, 0x0002);
+ val = phy_read_paged(phydev, 0x1f, 0x1c);
if (val != 0x6276) {
phydev_err(phydev, "Expected external RTL8214FC, found PHY-ID %x\n", val);
return -1;
@@ -1293,8 +1326,8 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
+ h->parts[1].start;
/* detect phy version */
- phy_write_paged(phydev, 0xfff, 27, 0x0004);
- val = phy_read_paged(phydev, 0xfff, 28);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, 27, 0x0004);
+ val = phy_read_paged(phydev, RTL83XX_PAGE_RAW, 28);
val = phy_read(phydev, 16);
if (val & (1 << 11))
@@ -1303,7 +1336,7 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
rtl8380_phy_reset(phydev);
msleep(100);
- phy_write_paged(phydev, 0, 30, 0x0001);
+ phy_write_paged(phydev, 0, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
i = 0;
while (rtl8380_rtl8214fc_perchip[i * 3]
@@ -1314,10 +1347,10 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
val = phy_read_paged(phydev, 0x260, 13);
val = (val & 0x1f00) | (rtl8380_rtl8214fc_perchip[i * 3 + 2]
& 0xe0ff);
- phy_write_paged(phydev, 0xfff,
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW,
rtl8380_rtl8214fc_perchip[i * 3 + 1], val);
} else {
- phy_write_paged(phydev, 0xfff,
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW,
rtl8380_rtl8214fc_perchip[i * 3 + 1],
rtl8380_rtl8214fc_perchip[i * 3 + 2]);
}
@@ -1326,21 +1359,21 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
/* Force copper medium */
for (i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1f, 0x0000);
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1e, 0x0001);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_COPPER);
}
/* Enable PHY */
for (i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1f, 0x0000);
- phy_package_port_write_paged(phydev, i, 0xfff, 0x00, 0x1140);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x00, 0x1140);
}
mdelay(100);
/* Disable Autosensing */
for (i = 0; i < 4; i++) {
for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, 0x0a42, 0x10);
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_GPHY, 0x10);
if ((val & 0x7) >= 3)
break;
}
@@ -1352,15 +1385,15 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
/* Request patch */
for (i = 0; i < 4; i++) {
- phy_package_port_write_paged(phydev, i, 0xfff, 0x1f, 0x0b82);
- phy_package_port_write_paged(phydev, i, 0xfff, 0x10, 0x0010);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL821X_PAGE_PATCH);
+ phy_package_port_write_paged(phydev, i, RTL83XX_PAGE_RAW, 0x10, 0x0010);
}
mdelay(300);
/* Verify patch readiness */
for (i = 0; i < 4; i++) {
for (l = 0; l < 100; l++) {
- val = phy_package_port_read_paged(phydev, i, 0xb80, 0x10);
+ val = phy_package_port_read_paged(phydev, i, RTL821X_PAGE_STATE, 0x10);
if (val & 0x40)
break;
}
@@ -1370,34 +1403,22 @@ static int rtl8380_configure_rtl8214fc(struct phy_device *phydev)
}
}
/* Use Broadcast ID method for patching */
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0008);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0266);
- phy_write_paged(phydev, 0xfff, 0x16, 0xff00 + mac);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0000);
- mdelay(1);
+ rtl821x_phy_setup_package_broadcast(phydev, true);
i = 0;
while (rtl8380_rtl8214fc_perport[i * 2]) {
- phy_write_paged(phydev, 0xfff, rtl8380_rtl8214fc_perport[i * 2],
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, rtl8380_rtl8214fc_perport[i * 2],
rtl8380_rtl8214fc_perport[i * 2 + 1]);
i++;
}
/*Disable broadcast ID*/
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0008);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0266);
- phy_write_paged(phydev, 0xfff, 0x16, 0x00 + mac);
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1d, 0x0000);
- mdelay(1);
+ rtl821x_phy_setup_package_broadcast(phydev, false);
/* Auto medium selection */
for (i = 0; i < 4; i++) {
- phy_write_paged(phydev, 0xfff, 0x1f, 0x0000);
- phy_write_paged(phydev, 0xfff, 0x1e, 0x0000);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL8XXX_PAGE_SELECT, RTL8XXX_PAGE_MAIN);
+ phy_write_paged(phydev, RTL83XX_PAGE_RAW, RTL821XEXT_MEDIA_PAGE_SELECT, RTL821X_MEDIA_PAGE_AUTO);
}
return 0;