summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2019-10-16 09:35:06 -0400
committerDavid S. Miller <davem@davemloft.net>2019-10-17 19:31:51 -0400
commit8b95599c55ed24b36cf44a4720067cfe67edbcb4 (patch)
tree5212a2cec65138b89a25ab0fac44309765ac930b
parent013572a236ef53cbd1e315e0acf2ee632cc816d4 (diff)
net: phy: micrel: Discern KSZ8051 and KSZ8795 PHYs
The KSZ8051 PHY and the KSZ8794/KSZ8795/KSZ8765 switch share exactly the same PHY ID. Since KSZ8051 is higher in the ksphy_driver[] list of PHYs in the micrel PHY driver, it is used even with the KSZ87xx switch. This is wrong, since the KSZ8051 configures registers of the PHY which are not present on the simplified KSZ87xx switch PHYs and misconfigures other registers of the KSZ87xx switch PHYs. Fortunatelly, it is possible to tell apart the KSZ8051 PHY from the KSZ87xx switch by checking the Basic Status register Bit 0, which is read-only and indicates presence of the Extended Capability Registers. The KSZ8051 PHY has those registers while the KSZ87xx switch does not. This patch implements simple check for the presence of this bit for both the KSZ8051 PHY and KSZ87xx switch, to let both use the correct PHY driver instance. Fixes: 9d162ed69f51 ("net: phy: micrel: add support for KSZ8795") Signed-off-by: Marek Vasut <marex@denx.de> Cc: Andrew Lunn <andrew@lunn.ch> Cc: David S. Miller <davem@davemloft.net> Cc: Florian Fainelli <f.fainelli@gmail.com> Cc: George McCollister <george.mccollister@gmail.com> Cc: Heiner Kallweit <hkallweit1@gmail.com> Cc: Sean Nyekjaer <sean.nyekjaer@prevas.dk> Cc: Tristram Ha <Tristram.Ha@microchip.com> Cc: Woojung Huh <woojung.huh@microchip.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/phy/micrel.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 2fea5541c35a..a0444e28c6e7 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -341,6 +341,35 @@ static int ksz8041_config_aneg(struct phy_device *phydev)
341 return genphy_config_aneg(phydev); 341 return genphy_config_aneg(phydev);
342} 342}
343 343
344static int ksz8051_ksz8795_match_phy_device(struct phy_device *phydev,
345 const u32 ksz_phy_id)
346{
347 int ret;
348
349 if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id)
350 return 0;
351
352 ret = phy_read(phydev, MII_BMSR);
353 if (ret < 0)
354 return ret;
355
356 /* KSZ8051 PHY and KSZ8794/KSZ8795/KSZ8765 switch share the same
357 * exact PHY ID. However, they can be told apart by the extended
358 * capability registers presence. The KSZ8051 PHY has them while
359 * the switch does not.
360 */
361 ret &= BMSR_ERCAP;
362 if (ksz_phy_id == PHY_ID_KSZ8051)
363 return ret;
364 else
365 return !ret;
366}
367
368static int ksz8051_match_phy_device(struct phy_device *phydev)
369{
370 return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8051);
371}
372
344static int ksz8081_config_init(struct phy_device *phydev) 373static int ksz8081_config_init(struct phy_device *phydev)
345{ 374{
346 /* KSZPHY_OMSO_FACTORY_TEST is set at de-assertion of the reset line 375 /* KSZPHY_OMSO_FACTORY_TEST is set at de-assertion of the reset line
@@ -364,6 +393,11 @@ static int ksz8061_config_init(struct phy_device *phydev)
364 return kszphy_config_init(phydev); 393 return kszphy_config_init(phydev);
365} 394}
366 395
396static int ksz8795_match_phy_device(struct phy_device *phydev)
397{
398 return ksz8051_ksz8795_match_phy_device(phydev, PHY_ID_KSZ8795);
399}
400
367static int ksz9021_load_values_from_of(struct phy_device *phydev, 401static int ksz9021_load_values_from_of(struct phy_device *phydev,
368 const struct device_node *of_node, 402 const struct device_node *of_node,
369 u16 reg, 403 u16 reg,
@@ -1017,8 +1051,6 @@ static struct phy_driver ksphy_driver[] = {
1017 .suspend = genphy_suspend, 1051 .suspend = genphy_suspend,
1018 .resume = genphy_resume, 1052 .resume = genphy_resume,
1019}, { 1053}, {
1020 .phy_id = PHY_ID_KSZ8051,
1021 .phy_id_mask = MICREL_PHY_ID_MASK,
1022 .name = "Micrel KSZ8051", 1054 .name = "Micrel KSZ8051",
1023 /* PHY_BASIC_FEATURES */ 1055 /* PHY_BASIC_FEATURES */
1024 .driver_data = &ksz8051_type, 1056 .driver_data = &ksz8051_type,
@@ -1029,6 +1061,7 @@ static struct phy_driver ksphy_driver[] = {
1029 .get_sset_count = kszphy_get_sset_count, 1061 .get_sset_count = kszphy_get_sset_count,
1030 .get_strings = kszphy_get_strings, 1062 .get_strings = kszphy_get_strings,
1031 .get_stats = kszphy_get_stats, 1063 .get_stats = kszphy_get_stats,
1064 .match_phy_device = ksz8051_match_phy_device,
1032 .suspend = genphy_suspend, 1065 .suspend = genphy_suspend,
1033 .resume = genphy_resume, 1066 .resume = genphy_resume,
1034}, { 1067}, {
@@ -1141,13 +1174,12 @@ static struct phy_driver ksphy_driver[] = {
1141 .suspend = genphy_suspend, 1174 .suspend = genphy_suspend,
1142 .resume = genphy_resume, 1175 .resume = genphy_resume,
1143}, { 1176}, {
1144 .phy_id = PHY_ID_KSZ8795,
1145 .phy_id_mask = MICREL_PHY_ID_MASK,
1146 .name = "Micrel KSZ8795", 1177 .name = "Micrel KSZ8795",
1147 /* PHY_BASIC_FEATURES */ 1178 /* PHY_BASIC_FEATURES */
1148 .config_init = kszphy_config_init, 1179 .config_init = kszphy_config_init,
1149 .config_aneg = ksz8873mll_config_aneg, 1180 .config_aneg = ksz8873mll_config_aneg,
1150 .read_status = ksz8873mll_read_status, 1181 .read_status = ksz8873mll_read_status,
1182 .match_phy_device = ksz8795_match_phy_device,
1151 .suspend = genphy_suspend, 1183 .suspend = genphy_suspend,
1152 .resume = genphy_resume, 1184 .resume = genphy_resume,
1153}, { 1185}, {