From f6ae47be1ac5f3b16ac2b702ffa89e5709711ce5 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Thu, 7 May 2020 00:11:55 +0200 Subject: phy: atheros: introduce debug read and write functions Provide functions to read and write the Atheros debug registers. Signed-off-by: Michael Walle Acked-by: Joe Hershberger --- drivers/net/phy/atheros.c | 57 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 16 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c index 5ff5875d3df..660dcd9491d 100644 --- a/drivers/net/phy/atheros.c +++ b/drivers/net/phy/atheros.c @@ -30,32 +30,57 @@ #define AR8031_PHY_ID 0x004dd074 #define AR8035_PHY_ID 0x004dd072 -static void ar803x_enable_rx_delay(struct phy_device *phydev, bool on) +static int ar803x_debug_reg_read(struct phy_device *phydev, u16 reg) { - int regval; + int ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG, + reg); + if (ret < 0) + return ret; + + return phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG); +} + +static int ar803x_debug_reg_mask(struct phy_device *phydev, u16 reg, + u16 clear, u16 set) +{ + int val; + + val = ar803x_debug_reg_read(phydev, reg); + if (val < 0) + return val; + + val &= 0xffff; + val &= ~clear; + val |= set; + + return phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, + val); +} + +static int ar803x_enable_rx_delay(struct phy_device *phydev, bool on) +{ + u16 clear = 0, set = 0; - phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG, - AR803x_DEBUG_REG_0); - regval = phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG); if (on) - regval |= AR803x_RGMII_RX_CLK_DLY; + set = AR803x_RGMII_RX_CLK_DLY; else - regval &= ~AR803x_RGMII_RX_CLK_DLY; - phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, regval); + clear = AR803x_RGMII_RX_CLK_DLY; + + return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_0, clear, set); } -static void ar803x_enable_tx_delay(struct phy_device *phydev, bool on) +static int ar803x_enable_tx_delay(struct phy_device *phydev, bool on) { - int regval; + u16 clear = 0, set = 0; - phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_ADDR_REG, - AR803x_DEBUG_REG_5); - regval = phy_read(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG); if (on) - regval |= AR803x_RGMII_TX_CLK_DLY; + set = AR803x_RGMII_TX_CLK_DLY; else - regval &= ~AR803x_RGMII_TX_CLK_DLY; - phy_write(phydev, MDIO_DEVAD_NONE, AR803x_PHY_DEBUG_DATA_REG, regval); + clear = AR803x_RGMII_TX_CLK_DLY; + + return ar803x_debug_reg_mask(phydev, AR803x_DEBUG_REG_5, clear, set); } static int ar8021_config(struct phy_device *phydev) -- cgit v1.2.3