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 | ||