Skip to content

Commit

Permalink
net: phy: adin: allow control of Fast Link Down
Browse files Browse the repository at this point in the history
Add support to allow Fast Link Down (aka "Enhanced link detection") to
be controlled via the ETHTOOL_PHY_FAST_LINK_DOWN tunable.  These PHYs
have this feature enabled by default.

Signed-off-by: Vincent Whitchurch <[email protected]>
Acked-by: Nuno Sa <[email protected]>
Reviewed-by: Andrew Lunn <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
vwax authored and kuba-moo committed Nov 30, 2023
1 parent 127532c commit cb2f01b
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions drivers/net/phy/adin.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@
#define ADIN1300_EEE_CAP_REG 0x8000
#define ADIN1300_EEE_ADV_REG 0x8001
#define ADIN1300_EEE_LPABLE_REG 0x8002

#define ADIN1300_FLD_EN_REG 0x8E27
#define ADIN1300_FLD_PCS_ERR_100_EN BIT(7)
#define ADIN1300_FLD_PCS_ERR_1000_EN BIT(6)
#define ADIN1300_FLD_SLCR_OUT_STUCK_100_EN BIT(5)
#define ADIN1300_FLD_SLCR_OUT_STUCK_1000_EN BIT(4)
#define ADIN1300_FLD_SLCR_IN_ZDET_100_EN BIT(3)
#define ADIN1300_FLD_SLCR_IN_ZDET_1000_EN BIT(2)
#define ADIN1300_FLD_SLCR_IN_INVLD_100_EN BIT(1)
#define ADIN1300_FLD_SLCR_IN_INVLD_1000_EN BIT(0)
/* These bits are the ones which are enabled by default. */
#define ADIN1300_FLD_EN_ON \
(ADIN1300_FLD_SLCR_OUT_STUCK_100_EN | \
ADIN1300_FLD_SLCR_OUT_STUCK_1000_EN | \
ADIN1300_FLD_SLCR_IN_ZDET_100_EN | \
ADIN1300_FLD_SLCR_IN_ZDET_1000_EN | \
ADIN1300_FLD_SLCR_IN_INVLD_1000_EN)

#define ADIN1300_CLOCK_STOP_REG 0x9400
#define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000

Expand Down Expand Up @@ -416,6 +434,37 @@ static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
val);
}

static int adin_get_fast_down(struct phy_device *phydev, u8 *msecs)
{
int reg;

reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_FLD_EN_REG);
if (reg < 0)
return reg;

if (reg & ADIN1300_FLD_EN_ON)
*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_ON;
else
*msecs = ETHTOOL_PHY_FAST_LINK_DOWN_OFF;

return 0;
}

static int adin_set_fast_down(struct phy_device *phydev, const u8 *msecs)
{
if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_ON)
return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
ADIN1300_FLD_EN_REG,
ADIN1300_FLD_EN_ON);

if (*msecs == ETHTOOL_PHY_FAST_LINK_DOWN_OFF)
return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
ADIN1300_FLD_EN_REG,
ADIN1300_FLD_EN_ON);

return -EINVAL;
}

static int adin_get_tunable(struct phy_device *phydev,
struct ethtool_tunable *tuna, void *data)
{
Expand All @@ -424,6 +473,8 @@ static int adin_get_tunable(struct phy_device *phydev,
return adin_get_downshift(phydev, data);
case ETHTOOL_PHY_EDPD:
return adin_get_edpd(phydev, data);
case ETHTOOL_PHY_FAST_LINK_DOWN:
return adin_get_fast_down(phydev, data);
default:
return -EOPNOTSUPP;
}
Expand All @@ -437,6 +488,8 @@ static int adin_set_tunable(struct phy_device *phydev,
return adin_set_downshift(phydev, *(const u8 *)data);
case ETHTOOL_PHY_EDPD:
return adin_set_edpd(phydev, *(const u16 *)data);
case ETHTOOL_PHY_FAST_LINK_DOWN:
return adin_set_fast_down(phydev, data);
default:
return -EOPNOTSUPP;
}
Expand Down

0 comments on commit cb2f01b

Please sign in to comment.