diff options
author | Lendacky, Thomas <Thomas.Lendacky@amd.com> | 2014-07-29 09:57:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-30 21:46:53 -0400 |
commit | 169a6303b89a99c807328f6f9772a81605b17116 (patch) | |
tree | ad517fe0043d5ed6e3f0db706bda004411a40736 | |
parent | 853eb16b8b6a347315443f2ef010e5b97d8c1577 (diff) |
amd-xgbe-phy: Updates to rate change complete check
Currently, the logic will loop endlessly waiting for a rate change
to complete. Add a counter so that if the rate change signals
never indicate complete the loop will eventually exit.
Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/amd-xgbe-phy.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/drivers/net/phy/amd-xgbe-phy.c b/drivers/net/phy/amd-xgbe-phy.c index b35293da9f87..a2d778aefadf 100644 --- a/drivers/net/phy/amd-xgbe-phy.c +++ b/drivers/net/phy/amd-xgbe-phy.c | |||
@@ -95,6 +95,8 @@ MODULE_DESCRIPTION("AMD 10GbE (amd-xgbe) PHY driver"); | |||
95 | #define XNP_MP_FORMATTED (1 << 13) | 95 | #define XNP_MP_FORMATTED (1 << 13) |
96 | #define XNP_NP_EXCHANGE (1 << 15) | 96 | #define XNP_NP_EXCHANGE (1 << 15) |
97 | 97 | ||
98 | #define XGBE_PHY_RATECHANGE_COUNT 100 | ||
99 | |||
98 | #ifndef MDIO_PMA_10GBR_PMD_CTRL | 100 | #ifndef MDIO_PMA_10GBR_PMD_CTRL |
99 | #define MDIO_PMA_10GBR_PMD_CTRL 0x0096 | 101 | #define MDIO_PMA_10GBR_PMD_CTRL 0x0096 |
100 | #endif | 102 | #endif |
@@ -193,6 +195,16 @@ do { \ | |||
193 | (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \ | 195 | (_var) |= (((_val) & ((0x1 << (_width)) - 1)) << (_index)); \ |
194 | } while (0) | 196 | } while (0) |
195 | 197 | ||
198 | #define XSIR_GET_BITS(_var, _prefix, _field) \ | ||
199 | GET_BITS((_var), \ | ||
200 | _prefix##_##_field##_INDEX, \ | ||
201 | _prefix##_##_field##_WIDTH) | ||
202 | |||
203 | #define XSIR_SET_BITS(_var, _prefix, _field, _val) \ | ||
204 | SET_BITS((_var), \ | ||
205 | _prefix##_##_field##_INDEX, \ | ||
206 | _prefix##_##_field##_WIDTH, (_val)) | ||
207 | |||
196 | /* Macros for reading or writing SerDes integration registers | 208 | /* Macros for reading or writing SerDes integration registers |
197 | * The ioread macros will get bit fields or full values using the | 209 | * The ioread macros will get bit fields or full values using the |
198 | * register definitions formed using the input names | 210 | * register definitions formed using the input names |
@@ -387,14 +399,25 @@ static void amd_xgbe_phy_serdes_start_ratechange(struct phy_device *phydev) | |||
387 | static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev) | 399 | static void amd_xgbe_phy_serdes_complete_ratechange(struct phy_device *phydev) |
388 | { | 400 | { |
389 | struct amd_xgbe_phy_priv *priv = phydev->priv; | 401 | struct amd_xgbe_phy_priv *priv = phydev->priv; |
402 | unsigned int wait; | ||
403 | u16 status; | ||
390 | 404 | ||
391 | /* Release Rx and Tx ratechange */ | 405 | /* Release Rx and Tx ratechange */ |
392 | XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 0); | 406 | XSIR1_IOWRITE_BITS(priv, SIR1_SPEED, RATECHANGE, 0); |
393 | 407 | ||
394 | /* Wait for Rx and Tx ready */ | 408 | /* Wait for Rx and Tx ready */ |
395 | while (!XSIR0_IOREAD_BITS(priv, SIR0_STATUS, RX_READY) && | 409 | wait = XGBE_PHY_RATECHANGE_COUNT; |
396 | !XSIR0_IOREAD_BITS(priv, SIR0_STATUS, TX_READY)) | 410 | while (wait--) { |
397 | usleep_range(10, 20); | 411 | usleep_range(10, 20); |
412 | |||
413 | status = XSIR0_IOREAD(priv, SIR0_STATUS); | ||
414 | if (XSIR_GET_BITS(status, SIR0_STATUS, RX_READY) && | ||
415 | XSIR_GET_BITS(status, SIR0_STATUS, TX_READY)) | ||
416 | return; | ||
417 | } | ||
418 | |||
419 | netdev_err(phydev->attached_dev, "SerDes rx/tx not ready (%#hx)\n", | ||
420 | status); | ||
398 | } | 421 | } |
399 | 422 | ||
400 | static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev) | 423 | static int amd_xgbe_phy_xgmii_mode(struct phy_device *phydev) |