From 80274abafc606f611c4ca8d5cebdcec8933835a9 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Thu, 30 Nov 2017 23:47:52 +0100 Subject: net: phy: remove generic settings for callbacks config_aneg and read_status from drivers Remove generic settings for callbacks config_aneg and read_status from drivers. Signed-off-by: Heiner Kallweit Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index eda0a6e..82efbf6 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -159,16 +159,12 @@ static struct phy_driver realtek_drvs[] = { .phy_id_mask = 0x0000ffff, .features = PHY_BASIC_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, }, { .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, @@ -179,8 +175,6 @@ static struct phy_driver realtek_drvs[] = { .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, .ack_interrupt = &rtl821x_ack_interrupt, .config_intr = &rtl8211b_config_intr, }, { @@ -189,8 +183,6 @@ static struct phy_driver realtek_drvs[] = { .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = genphy_config_aneg, - .read_status = genphy_read_status, .ack_interrupt = rtl821x_ack_interrupt, .config_intr = rtl8211e_config_intr, .suspend = genphy_suspend, @@ -201,8 +193,6 @@ static struct phy_driver realtek_drvs[] = { .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, - .read_status = &genphy_read_status, .ack_interrupt = &rtl821x_ack_interrupt, .config_intr = &rtl8211e_config_intr, .suspend = genphy_suspend, @@ -213,9 +203,7 @@ static struct phy_driver realtek_drvs[] = { .phy_id_mask = 0x001fffff, .features = PHY_GBIT_FEATURES, .flags = PHY_HAS_INTERRUPT, - .config_aneg = &genphy_config_aneg, .config_init = &rtl8211f_config_init, - .read_status = &genphy_read_status, .ack_interrupt = &rtl8211f_ack_interrupt, .config_intr = &rtl8211f_config_intr, .suspend = genphy_suspend, -- cgit v1.1 From 8cc5baefbc0266b6d6c8e99cb8568f59be36a575 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Dec 2017 22:51:24 +0100 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 82efbf6..86a5d36 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -13,21 +13,22 @@ * option) any later version. * */ +#include #include #include #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 -- cgit v1.1 From 69021e32ec3ef02170482f6ed8130febaed27357 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Dec 2017 22:51:25 +0100 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 86a5d36..5070de2 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); -- cgit v1.1 From a82f266d240d87e6111878bbfe287024fb6857c1 Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Dec 2017 22:51:26 +0100 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 5070de2..8e5f82e 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) -- cgit v1.1 From f609ab0ed8e7bef2cd61d230bf9e83e1ec5b9ddb Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Dec 2017 22:51:27 +0100 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 8e5f82e..cc0a02d 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -17,24 +17,25 @@ #include #include -#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"); -- cgit v1.1 From 136819a6e8df374e6b9b424586ff11c9e241a1cb Mon Sep 17 00:00:00 2001 From: Martin Blumenstingl Date: Sat, 2 Dec 2017 22:51:28 +0100 Subject: 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 Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 83 ++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 30 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index cc0a02d..7c1bf68 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; } -- cgit v1.1 From d98c8ccdebda9de011d3ea29ffb5aac57cd2b69a Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Fri, 12 Jan 2018 23:17:34 +0100 Subject: phy: realtek: use new helpers for paged register access Make use of the new helpers for paged register access. Signed-off-by: Heiner Kallweit Signed-off-by: David S. Miller --- drivers/net/phy/realtek.c | 59 +++++++++++------------------------------------ 1 file changed, 14 insertions(+), 45 deletions(-) (limited to 'drivers/net/phy/realtek.c') diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 7c1bf68..ee3ca4a 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -41,37 +41,14 @@ 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) +static int rtl821x_read_page(struct phy_device *phydev) { - 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; + return __phy_read(phydev, RTL821x_PAGE_SELECT); } -static int rtl8211x_page_write(struct phy_device *phydev, u16 page, - u16 address, u16 val) +static int rtl821x_write_page(struct phy_device *phydev, int page) { - 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; + return __phy_write(phydev, RTL821x_PAGE_SELECT, page); } static int rtl8201_ack_interrupt(struct phy_device *phydev) @@ -96,7 +73,7 @@ static int rtl8211f_ack_interrupt(struct phy_device *phydev) { int err; - err = rtl8211x_page_read(phydev, 0xa43, RTL8211F_INSR); + err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR); return (err < 0) ? err : 0; } @@ -110,7 +87,7 @@ static int rtl8201_config_intr(struct phy_device *phydev) else val = 0; - return rtl8211x_page_write(phydev, 0x7, RTL8201F_IER, val); + return phy_write_paged(phydev, 0x7, RTL8201F_IER, val); } static int rtl8211b_config_intr(struct phy_device *phydev) @@ -148,36 +125,24 @@ static int rtl8211f_config_intr(struct phy_device *phydev) else val = 0; - return rtl8211x_page_write(phydev, 0xa42, RTL821x_INER, val); + return phy_write_paged(phydev, 0xa42, RTL821x_INER, val); } static int rtl8211f_config_init(struct phy_device *phydev) { int ret; - u16 val; + u16 val = 0; ret = genphy_config_init(phydev); if (ret < 0) return ret; - 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) - val |= RTL8211F_TX_DELAY; - else - val &= ~RTL8211F_TX_DELAY; - - ret = rtl8211x_page_write(phydev, 0xd08, 0x11, val); - if (ret) - return ret; + val = RTL8211F_TX_DELAY; - return 0; + return phy_modify_paged(phydev, 0xd08, 0x11, RTL8211F_TX_DELAY, val); } static struct phy_driver realtek_drvs[] = { @@ -197,6 +162,8 @@ static struct phy_driver realtek_drvs[] = { .config_intr = &rtl8201_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, }, { .phy_id = 0x001cc912, .name = "RTL8211B Gigabit Ethernet", @@ -236,6 +203,8 @@ static struct phy_driver realtek_drvs[] = { .config_intr = &rtl8211f_config_intr, .suspend = genphy_suspend, .resume = genphy_resume, + .read_page = rtl821x_read_page, + .write_page = rtl821x_write_page, }, }; -- cgit v1.1