diff options
| author | Alvaro Gamez Machado <alvaro.gamez@hazent.com> | 2018-06-08 06:23:39 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2018-06-10 15:38:03 -0400 |
| commit | b718e8c8f4f5920aaddc2e52d5e32f494c91129c (patch) | |
| tree | f7147d1b843d1f8219bba61bb006f3e0da6f6fec | |
| parent | 6d8c50dcb029872b298eea68cc6209c866fd3e14 (diff) | |
net: phy: dp83822: use BMCR_ANENABLE instead of BMSR_ANEGCAPABLE for DP83620
DP83620 register set is compatible with the DP83848, but it also supports
100base-FX. When the hardware is configured such as that fiber mode is
enabled, autonegotiation is not possible.
The chip, however, doesn't expose this information via BMSR_ANEGCAPABLE.
Instead, this bit is always set high, even if the particular hardware
configuration makes it so that auto negotiation is not possible [1]. Under
these circumstances, the phy subsystem keeps trying for autonegotiation to
happen, without success.
Hereby, we inspect BMCR_ANENABLE bit after genphy_config_init, which on
reset is set to 0 when auto negotiation is disabled, and so we use this
value instead of BMSR_ANEGCAPABLE.
[1] https://e2e.ti.com/support/interface/ethernet/f/903/p/697165/2571170
Signed-off-by: Alvaro Gamez Machado <alvaro.gamez@hazent.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/phy/dp83848.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/drivers/net/phy/dp83848.c b/drivers/net/phy/dp83848.c index cd09c3af2117..6e8e42361fd5 100644 --- a/drivers/net/phy/dp83848.c +++ b/drivers/net/phy/dp83848.c | |||
| @@ -74,6 +74,25 @@ static int dp83848_config_intr(struct phy_device *phydev) | |||
| 74 | return phy_write(phydev, DP83848_MICR, control); | 74 | return phy_write(phydev, DP83848_MICR, control); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static int dp83848_config_init(struct phy_device *phydev) | ||
| 78 | { | ||
| 79 | int err; | ||
| 80 | int val; | ||
| 81 | |||
| 82 | err = genphy_config_init(phydev); | ||
| 83 | if (err < 0) | ||
| 84 | return err; | ||
| 85 | |||
| 86 | /* DP83620 always reports Auto Negotiation Ability on BMSR. Instead, | ||
| 87 | * we check initial value of BMCR Auto negotiation enable bit | ||
| 88 | */ | ||
| 89 | val = phy_read(phydev, MII_BMCR); | ||
| 90 | if (!(val & BMCR_ANENABLE)) | ||
| 91 | phydev->autoneg = AUTONEG_DISABLE; | ||
| 92 | |||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 77 | static struct mdio_device_id __maybe_unused dp83848_tbl[] = { | 96 | static struct mdio_device_id __maybe_unused dp83848_tbl[] = { |
| 78 | { TI_DP83848C_PHY_ID, 0xfffffff0 }, | 97 | { TI_DP83848C_PHY_ID, 0xfffffff0 }, |
| 79 | { NS_DP83848C_PHY_ID, 0xfffffff0 }, | 98 | { NS_DP83848C_PHY_ID, 0xfffffff0 }, |
| @@ -83,7 +102,7 @@ static struct mdio_device_id __maybe_unused dp83848_tbl[] = { | |||
| 83 | }; | 102 | }; |
| 84 | MODULE_DEVICE_TABLE(mdio, dp83848_tbl); | 103 | MODULE_DEVICE_TABLE(mdio, dp83848_tbl); |
| 85 | 104 | ||
| 86 | #define DP83848_PHY_DRIVER(_id, _name) \ | 105 | #define DP83848_PHY_DRIVER(_id, _name, _config_init) \ |
| 87 | { \ | 106 | { \ |
| 88 | .phy_id = _id, \ | 107 | .phy_id = _id, \ |
| 89 | .phy_id_mask = 0xfffffff0, \ | 108 | .phy_id_mask = 0xfffffff0, \ |
| @@ -92,7 +111,7 @@ MODULE_DEVICE_TABLE(mdio, dp83848_tbl); | |||
| 92 | .flags = PHY_HAS_INTERRUPT, \ | 111 | .flags = PHY_HAS_INTERRUPT, \ |
| 93 | \ | 112 | \ |
| 94 | .soft_reset = genphy_soft_reset, \ | 113 | .soft_reset = genphy_soft_reset, \ |
| 95 | .config_init = genphy_config_init, \ | 114 | .config_init = _config_init, \ |
| 96 | .suspend = genphy_suspend, \ | 115 | .suspend = genphy_suspend, \ |
| 97 | .resume = genphy_resume, \ | 116 | .resume = genphy_resume, \ |
| 98 | \ | 117 | \ |
| @@ -102,10 +121,14 @@ MODULE_DEVICE_TABLE(mdio, dp83848_tbl); | |||
| 102 | } | 121 | } |
| 103 | 122 | ||
| 104 | static struct phy_driver dp83848_driver[] = { | 123 | static struct phy_driver dp83848_driver[] = { |
| 105 | DP83848_PHY_DRIVER(TI_DP83848C_PHY_ID, "TI DP83848C 10/100 Mbps PHY"), | 124 | DP83848_PHY_DRIVER(TI_DP83848C_PHY_ID, "TI DP83848C 10/100 Mbps PHY", |
| 106 | DP83848_PHY_DRIVER(NS_DP83848C_PHY_ID, "NS DP83848C 10/100 Mbps PHY"), | 125 | genphy_config_init), |
| 107 | DP83848_PHY_DRIVER(TI_DP83620_PHY_ID, "TI DP83620 10/100 Mbps PHY"), | 126 | DP83848_PHY_DRIVER(NS_DP83848C_PHY_ID, "NS DP83848C 10/100 Mbps PHY", |
| 108 | DP83848_PHY_DRIVER(TLK10X_PHY_ID, "TI TLK10X 10/100 Mbps PHY"), | 127 | genphy_config_init), |
| 128 | DP83848_PHY_DRIVER(TI_DP83620_PHY_ID, "TI DP83620 10/100 Mbps PHY", | ||
| 129 | dp83848_config_init), | ||
| 130 | DP83848_PHY_DRIVER(TLK10X_PHY_ID, "TI TLK10X 10/100 Mbps PHY", | ||
| 131 | genphy_config_init), | ||
| 109 | }; | 132 | }; |
| 110 | module_phy_driver(dp83848_driver); | 133 | module_phy_driver(dp83848_driver); |
| 111 | 134 | ||
