| From c40be57e8761317f605df6e4de84b654c2250893 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Thu, 22 Apr 2021 13:46:44 +0300 |
| Subject: net: phy: marvell: fix m88e1111_set_downshift |
| |
| From: Maxim Kochetkov <fido_max@inbox.ru> |
| |
| [ Upstream commit e7679c55a7249f1315256cfc672d53e84072e223 ] |
| |
| Changing downshift params without software reset has no effect, |
| so call genphy_soft_reset() after change downshift params. |
| |
| As the datasheet says: |
| Changes to these bits are disruptive to the normal operation therefore, |
| any changes to these registers must be followed by software reset |
| to take effect. |
| |
| Fixes: 5c6bc5199b5d ("net: phy: marvell: add downshift support for M88E1111") |
| Signed-off-by: Maxim Kochetkov <fido_max@inbox.ru> |
| Reviewed-by: Andrew Lunn <andrew@lunn.ch> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/phy/marvell.c | 26 ++++++++++++++++---------- |
| 1 file changed, 16 insertions(+), 10 deletions(-) |
| |
| diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c |
| index 04e7b9a7799c..47e5200eb039 100644 |
| --- a/drivers/net/phy/marvell.c |
| +++ b/drivers/net/phy/marvell.c |
| @@ -964,22 +964,28 @@ static int m88e1111_get_downshift(struct phy_device *phydev, u8 *data) |
| |
| static int m88e1111_set_downshift(struct phy_device *phydev, u8 cnt) |
| { |
| - int val; |
| + int val, err; |
| |
| if (cnt > MII_M1111_PHY_EXT_CR_DOWNSHIFT_MAX) |
| return -E2BIG; |
| |
| - if (!cnt) |
| - return phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR, |
| - MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN); |
| + if (!cnt) { |
| + err = phy_clear_bits(phydev, MII_M1111_PHY_EXT_CR, |
| + MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN); |
| + } else { |
| + val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN; |
| + val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1); |
| |
| - val = MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN; |
| - val |= FIELD_PREP(MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, cnt - 1); |
| + err = phy_modify(phydev, MII_M1111_PHY_EXT_CR, |
| + MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN | |
| + MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, |
| + val); |
| + } |
| |
| - return phy_modify(phydev, MII_M1111_PHY_EXT_CR, |
| - MII_M1111_PHY_EXT_CR_DOWNSHIFT_EN | |
| - MII_M1111_PHY_EXT_CR_DOWNSHIFT_MASK, |
| - val); |
| + if (err < 0) |
| + return err; |
| + |
| + return genphy_soft_reset(phydev); |
| } |
| |
| static int m88e1111_get_tunable(struct phy_device *phydev, |
| -- |
| 2.30.2 |
| |