[PATCH] net: phy: Add RGMII_ID/TXID/RXID handling to the DP83822 driver
From: Marek Vasut <marex@denx.de>
Date: 2021-07-16 18:23:34
Subsystem:
ethernet phy library, networking drivers, the rest · Maintainers:
Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Add support for setting the internal clock shift of the PHY based on the interface requirements. RX/TX/both is supported for RGMII. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: Dan Murphy <redacted> Cc: David S. Miller <davem@davemloft.net> --- drivers/net/phy/dp83822.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c
index f7a2ec150e54..971c8d6b85d2 100644
--- a/drivers/net/phy/dp83822.c
+++ b/drivers/net/phy/dp83822.c@@ -72,6 +72,10 @@ #define DP83822_ANEG_ERR_INT_EN BIT(6) #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7) +/* RCSR bits */ +#define DP83822_RGMII_RX_CLOCK_SHIFT BIT(12) +#define DP83822_RGMII_TX_CLOCK_SHIFT BIT(11) + /* INT_STAT1 bits */ #define DP83822_WOL_INT_EN BIT(4) #define DP83822_WOL_INT_STAT BIT(12)
@@ -326,11 +330,36 @@ static irqreturn_t dp83822_handle_interrupt(struct phy_device *phydev) static int dp8382x_disable_wol(struct phy_device *phydev) { - int value = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | - DP83822_WOL_SECURE_ON; + u16 val = DP83822_WOL_EN | DP83822_WOL_MAGIC_EN | DP83822_WOL_SECURE_ON; + + ret = phy_clear_bits_mmd(phydev, DP83822_DEVADDR, + MII_DP83822_WOL_CFG, val); + if (ret < 0) + return ret; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) { + ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RGMII_RX_CLOCK_SHIFT, + DP83822_RGMII_RX_CLOCK_SHIFT); + } else { + ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RGMII_RX_CLOCK_SHIFT, 0); + } + if (ret < 0) + return ret; + + if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || + phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) { + ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RGMII_TX_CLOCK_SHIFT, + DP83822_RGMII_TX_CLOCK_SHIFT); + } else { + ret = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR, + DP83822_RGMII_TX_CLOCK_SHIFT, 0); + } - return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, - MII_DP83822_WOL_CFG, value); + return ret; } static int dp83822_read_status(struct phy_device *phydev)
--
2.30.2