diff options
author | Zefir Kurtisi <zefir.kurtisi@neratec.com> | 2016-03-11 09:31:53 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-03-13 22:37:08 -0400 |
commit | 98267311fe3b334ae7c107fa0e2413adcf3ba735 (patch) | |
tree | 6645b5f6243b9282c3fb6c608dcf41a774459a0c | |
parent | 5d6084142e8c7535710ba83a6e11ef8952354b02 (diff) |
at803x: fix suspend/resume for SGMII link
When operating the at803x in SGMII mode, resuming the chip
from power down brings up the copper-side link but leaves
the SGMII link in unconnected state (tested with at8031
attached to gianfar). In effect, this caused a permanent
link loss once the related interface was put down.
This patch ensures that power down handling in supspend()
and resume() is also applied to the SGMII link.
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/at803x.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c index 2174ec937b4d..1e901c7cfaac 100644 --- a/drivers/net/phy/at803x.c +++ b/drivers/net/phy/at803x.c | |||
@@ -52,6 +52,9 @@ | |||
52 | #define AT803X_DEBUG_REG_5 0x05 | 52 | #define AT803X_DEBUG_REG_5 0x05 |
53 | #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) | 53 | #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) |
54 | 54 | ||
55 | #define AT803X_REG_CHIP_CONFIG 0x1f | ||
56 | #define AT803X_BT_BX_REG_SEL 0x8000 | ||
57 | |||
55 | #define ATH8030_PHY_ID 0x004dd076 | 58 | #define ATH8030_PHY_ID 0x004dd076 |
56 | #define ATH8031_PHY_ID 0x004dd074 | 59 | #define ATH8031_PHY_ID 0x004dd074 |
57 | #define ATH8035_PHY_ID 0x004dd072 | 60 | #define ATH8035_PHY_ID 0x004dd072 |
@@ -206,6 +209,7 @@ static int at803x_suspend(struct phy_device *phydev) | |||
206 | { | 209 | { |
207 | int value; | 210 | int value; |
208 | int wol_enabled; | 211 | int wol_enabled; |
212 | int ccr; | ||
209 | 213 | ||
210 | mutex_lock(&phydev->lock); | 214 | mutex_lock(&phydev->lock); |
211 | 215 | ||
@@ -221,6 +225,16 @@ static int at803x_suspend(struct phy_device *phydev) | |||
221 | 225 | ||
222 | phy_write(phydev, MII_BMCR, value); | 226 | phy_write(phydev, MII_BMCR, value); |
223 | 227 | ||
228 | if (phydev->interface != PHY_INTERFACE_MODE_SGMII) | ||
229 | goto done; | ||
230 | |||
231 | /* also power-down SGMII interface */ | ||
232 | ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); | ||
233 | phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL); | ||
234 | phy_write(phydev, MII_BMCR, phy_read(phydev, MII_BMCR) | BMCR_PDOWN); | ||
235 | phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL); | ||
236 | |||
237 | done: | ||
224 | mutex_unlock(&phydev->lock); | 238 | mutex_unlock(&phydev->lock); |
225 | 239 | ||
226 | return 0; | 240 | return 0; |
@@ -229,6 +243,7 @@ static int at803x_suspend(struct phy_device *phydev) | |||
229 | static int at803x_resume(struct phy_device *phydev) | 243 | static int at803x_resume(struct phy_device *phydev) |
230 | { | 244 | { |
231 | int value; | 245 | int value; |
246 | int ccr; | ||
232 | 247 | ||
233 | mutex_lock(&phydev->lock); | 248 | mutex_lock(&phydev->lock); |
234 | 249 | ||
@@ -236,6 +251,17 @@ static int at803x_resume(struct phy_device *phydev) | |||
236 | value &= ~(BMCR_PDOWN | BMCR_ISOLATE); | 251 | value &= ~(BMCR_PDOWN | BMCR_ISOLATE); |
237 | phy_write(phydev, MII_BMCR, value); | 252 | phy_write(phydev, MII_BMCR, value); |
238 | 253 | ||
254 | if (phydev->interface != PHY_INTERFACE_MODE_SGMII) | ||
255 | goto done; | ||
256 | |||
257 | /* also power-up SGMII interface */ | ||
258 | ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); | ||
259 | phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL); | ||
260 | value = phy_read(phydev, MII_BMCR) & ~(BMCR_PDOWN | BMCR_ISOLATE); | ||
261 | phy_write(phydev, MII_BMCR, value); | ||
262 | phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL); | ||
263 | |||
264 | done: | ||
239 | mutex_unlock(&phydev->lock); | 265 | mutex_unlock(&phydev->lock); |
240 | 266 | ||
241 | return 0; | 267 | return 0; |