diff options
author | Oleksij Rempel <o.rempel@pengutronix.de> | 2022-08-05 09:31:59 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2022-08-08 20:54:28 -0700 |
commit | 3702e4041cfda50bc697363d29511ce8f6b24795 (patch) | |
tree | a4f164b4948650994938f2c8a1e8bd8c81650248 /drivers | |
parent | 3f4093e2bf4673f218c0bf17d8362337c400e77b (diff) | |
download | linux-3702e4041cfda50bc697363d29511ce8f6b24795.tar.bz2 |
net: phy: c45 baset1: do not skip aneg configuration if clock role is not specified
In case master/slave clock role is not specified (which is default), the
aneg registers will not be written.
The visible impact of this is missing pause advertisement.
So, rework genphy_c45_baset1_an_config_aneg() to be able to write
advertisement registers even if clock role is unknown.
Fixes: 3da8ffd8545f ("net: phy: Add 10BASE-T1L support in phy-c45")
Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20220805073159.908643-1-o.rempel@pengutronix.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/phy/phy-c45.c | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/drivers/net/phy/phy-c45.c b/drivers/net/phy/phy-c45.c index 29b1df03f3e8..a87a4b3ffce4 100644 --- a/drivers/net/phy/phy-c45.c +++ b/drivers/net/phy/phy-c45.c @@ -190,44 +190,42 @@ EXPORT_SYMBOL_GPL(genphy_c45_pma_setup_forced); */ static int genphy_c45_baset1_an_config_aneg(struct phy_device *phydev) { + u16 adv_l_mask, adv_l = 0; + u16 adv_m_mask, adv_m = 0; int changed = 0; - u16 adv_l = 0; - u16 adv_m = 0; int ret; + adv_l_mask = MDIO_AN_T1_ADV_L_FORCE_MS | MDIO_AN_T1_ADV_L_PAUSE_CAP | + MDIO_AN_T1_ADV_L_PAUSE_ASYM; + adv_m_mask = MDIO_AN_T1_ADV_M_MST | MDIO_AN_T1_ADV_M_B10L; + switch (phydev->master_slave_set) { case MASTER_SLAVE_CFG_MASTER_FORCE: + adv_m |= MDIO_AN_T1_ADV_M_MST; + fallthrough; case MASTER_SLAVE_CFG_SLAVE_FORCE: adv_l |= MDIO_AN_T1_ADV_L_FORCE_MS; break; case MASTER_SLAVE_CFG_MASTER_PREFERRED: + adv_m |= MDIO_AN_T1_ADV_M_MST; + fallthrough; case MASTER_SLAVE_CFG_SLAVE_PREFERRED: break; case MASTER_SLAVE_CFG_UNKNOWN: case MASTER_SLAVE_CFG_UNSUPPORTED: - return 0; + /* if master/slave role is not specified, do not overwrite it */ + adv_l_mask &= ~MDIO_AN_T1_ADV_L_FORCE_MS; + adv_m_mask &= ~MDIO_AN_T1_ADV_M_MST; + break; default: phydev_warn(phydev, "Unsupported Master/Slave mode\n"); return -EOPNOTSUPP; } - switch (phydev->master_slave_set) { - case MASTER_SLAVE_CFG_MASTER_FORCE: - case MASTER_SLAVE_CFG_MASTER_PREFERRED: - adv_m |= MDIO_AN_T1_ADV_M_MST; - break; - case MASTER_SLAVE_CFG_SLAVE_FORCE: - case MASTER_SLAVE_CFG_SLAVE_PREFERRED: - break; - default: - break; - } - adv_l |= linkmode_adv_to_mii_t1_adv_l_t(phydev->advertising); ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_L, - (MDIO_AN_T1_ADV_L_FORCE_MS | MDIO_AN_T1_ADV_L_PAUSE_CAP - | MDIO_AN_T1_ADV_L_PAUSE_ASYM), adv_l); + adv_l_mask, adv_l); if (ret < 0) return ret; if (ret > 0) @@ -236,7 +234,7 @@ static int genphy_c45_baset1_an_config_aneg(struct phy_device *phydev) adv_m |= linkmode_adv_to_mii_t1_adv_m_t(phydev->advertising); ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_T1_ADV_M, - MDIO_AN_T1_ADV_M_MST | MDIO_AN_T1_ADV_M_B10L, adv_m); + adv_m_mask, adv_m); if (ret < 0) return ret; if (ret > 0) |