In case this PHY is bootstrapped for managed mode, we need to manually wake it. Otherwise no link will be detected.
Cc: stable@vger.kernel.org Fixes: cb80ee2f9bee1 ("net: phy: Add support for the DP83TG720S Ethernet PHY") Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de --- drivers/net/phy/dp83tg720.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c index 326c9770a6dcc..1186dfc70fb3c 100644 --- a/drivers/net/phy/dp83tg720.c +++ b/drivers/net/phy/dp83tg720.c @@ -17,6 +17,11 @@ #define DP83TG720S_PHY_RESET 0x1f #define DP83TG720S_HW_RESET BIT(15)
+#define DP83TG720S_LPS_CFG3 0x18c +/* Power modes are documented as bit fields but used as values */ +/* Power Mode 0 is Normal mode */ +#define DP83TG720S_LPS_CFG3_PWR_MODE_0 BIT(0) + #define DP83TG720S_RGMII_DELAY_CTRL 0x602 /* In RGMII mode, Enable or disable the internal delay for RXD */ #define DP83TG720S_RGMII_RX_CLK_SEL BIT(1) @@ -154,10 +159,17 @@ static int dp83tg720_config_init(struct phy_device *phydev) */ usleep_range(1000, 2000);
- if (phy_interface_is_rgmii(phydev)) - return dp83tg720_config_rgmii_delay(phydev); + if (phy_interface_is_rgmii(phydev)) { + ret = dp83tg720_config_rgmii_delay(phydev); + if (ret) + return ret; + }
- return 0; + /* In case the PHY is bootstrapped in managed mode, we need to + * wake it. + */ + return phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3, + DP83TG720S_LPS_CFG3_PWR_MODE_0); }
static struct phy_driver dp83tg720_driver[] = {
Get initial master/slave configuration, otherwise ethtool wont be able to provide this information until link is established. This makes troubleshooting harder, since wrong role configuration would prevent the link start.
Fixes: cb80ee2f9bee1 ("net: phy: Add support for the DP83TG720S Ethernet PHY") Cc: stable@vger.kernel.org Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de --- drivers/net/phy/dp83tg720.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/dp83tg720.c b/drivers/net/phy/dp83tg720.c index 1186dfc70fb3c..84256827a03bf 100644 --- a/drivers/net/phy/dp83tg720.c +++ b/drivers/net/phy/dp83tg720.c @@ -168,8 +168,12 @@ static int dp83tg720_config_init(struct phy_device *phydev) /* In case the PHY is bootstrapped in managed mode, we need to * wake it. */ - return phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3, - DP83TG720S_LPS_CFG3_PWR_MODE_0); + ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, DP83TG720S_LPS_CFG3, + DP83TG720S_LPS_CFG3_PWR_MODE_0); + if (ret) + return ret; + + return genphy_c45_pma_baset1_read_master_slave(phydev); }
static struct phy_driver dp83tg720_driver[] = {
On Thu, Jun 13, 2024 at 08:30:34PM +0200, Oleksij Rempel wrote:
Get initial master/slave configuration, otherwise ethtool wont be able to provide this information until link is established. This makes troubleshooting harder, since wrong role configuration would prevent the link start.
I looked at how genphy_c45_read_status() works. If we have phydev->autoneg == AUTONEG_ENABLE then genphy_c45_baset1_read_status() is called which sets phydev->master_slave_get. If not AUTONEG_ENABLE it calls genphy_c45_read_pma() which ends up calling genphy_c45_pma_baset1_read_master_slave().
So it seems like the .read_status op should be setting master/slave each time it is called, and not one time during .config_init.
What do you think?
Andrew
On Thu, Jun 13, 2024 at 09:33:01PM +0200, Andrew Lunn wrote:
On Thu, Jun 13, 2024 at 08:30:34PM +0200, Oleksij Rempel wrote:
Get initial master/slave configuration, otherwise ethtool wont be able to provide this information until link is established. This makes troubleshooting harder, since wrong role configuration would prevent the link start.
I looked at how genphy_c45_read_status() works. If we have phydev->autoneg == AUTONEG_ENABLE then genphy_c45_baset1_read_status() is called which sets phydev->master_slave_get. If not AUTONEG_ENABLE it calls genphy_c45_read_pma() which ends up calling genphy_c45_pma_baset1_read_master_slave().
So it seems like the .read_status op should be setting master/slave each time it is called, and not one time during .config_init.
What do you think?
Yes, you are right. I verified it: In case of this driver, .config_init will be executed every time no link is detected over phy_init_hw() call. If link is detected genphy_c45_pma_baset1_read_master_slave() is called directly. It is not directly visible but read_master_slave() will be executed on every .read_status.
On Fri, Jun 14, 2024 at 07:21:15AM +0200, Oleksij Rempel wrote:
On Thu, Jun 13, 2024 at 09:33:01PM +0200, Andrew Lunn wrote:
On Thu, Jun 13, 2024 at 08:30:34PM +0200, Oleksij Rempel wrote:
Get initial master/slave configuration, otherwise ethtool wont be able to provide this information until link is established. This makes troubleshooting harder, since wrong role configuration would prevent the link start.
I looked at how genphy_c45_read_status() works. If we have phydev->autoneg == AUTONEG_ENABLE then genphy_c45_baset1_read_status() is called which sets phydev->master_slave_get. If not AUTONEG_ENABLE it calls genphy_c45_read_pma() which ends up calling genphy_c45_pma_baset1_read_master_slave().
So it seems like the .read_status op should be setting master/slave each time it is called, and not one time during .config_init.
What do you think?
Yes, you are right. I verified it: In case of this driver, .config_init will be executed every time no link is detected over phy_init_hw() call. If link is detected genphy_c45_pma_baset1_read_master_slave() is called directly. It is not directly visible but read_master_slave() will be executed on every .read_status.
Hm.. on other hand. Since the configuration state is readed only on init and reset, we will see on user space side only default state not updated after config_aneg().
linux-stable-mirror@lists.linaro.org