The TJA11xx PHYs have a vendor specific Master/Slave configuration bit,
which is not compatible with IEEE 803.2-2018 spec for 100Base-T1
devices. So, provide a custom config_ange call back to solve this
problem.

Signed-off-by: Oleksij Rempel <o.rem...@pengutronix.de>
---
 drivers/net/phy/nxp-tja11xx.c | 47 ++++++++++++++++++++++++++++++++++-
 1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/drivers/net/phy/nxp-tja11xx.c b/drivers/net/phy/nxp-tja11xx.c
index cc766b2d4136e..0a7ea4768bc78 100644
--- a/drivers/net/phy/nxp-tja11xx.c
+++ b/drivers/net/phy/nxp-tja11xx.c
@@ -30,6 +30,7 @@
 #define MII_ECTRL_WAKE_REQUEST         BIT(0)
 
 #define MII_CFG1                       18
+#define MII_CFG1_MASTER_SLAVE          BIT(15)
 #define MII_CFG1_AUTO_OP               BIT(14)
 #define MII_CFG1_SLEEP_CONFIRM         BIT(6)
 #define MII_CFG1_LED_MODE_MASK         GENMASK(5, 4)
@@ -167,6 +168,31 @@ static int tja11xx_soft_reset(struct phy_device *phydev)
        return genphy_soft_reset(phydev);
 }
 
+static int tja11xx_config_aneg(struct phy_device *phydev)
+{
+       u16 ctl = 0;
+       int ret;
+
+       switch (phydev->master_slave_set) {
+       case MASTER_SLAVE_CFG_MASTER_FORCE:
+               ctl |= MII_CFG1_MASTER_SLAVE;
+               break;
+       case MASTER_SLAVE_CFG_SLAVE_FORCE:
+               break;
+       case MASTER_SLAVE_CFG_UNKNOWN:
+               return 0;
+       default:
+               phydev_warn(phydev, "Unsupported Master/Slave mode\n");
+               return -ENOTSUPP;
+       }
+
+       ret = phy_modify_changed(phydev, MII_CFG1, MII_CFG1_MASTER_SLAVE, ctl);
+       if (ret < 0)
+               return ret;
+
+       return __genphy_config_aneg(phydev, ret);
+}
+
 static int tja11xx_config_init(struct phy_device *phydev)
 {
        int ret;
@@ -222,12 +248,25 @@ static int tja11xx_config_init(struct phy_device *phydev)
 
 static int tja11xx_read_status(struct phy_device *phydev)
 {
-       int ret;
+       int cfg, state = 0;
+       int ret, cfg1;
+
+       phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
+       phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
 
        ret = genphy_update_link(phydev);
        if (ret)
                return ret;
 
+       cfg1 = phy_read(phydev, MII_CFG1);
+       if (cfg1 < 0)
+               return cfg1;
+
+       if (cfg1 & MII_CFG1_MASTER_SLAVE)
+               cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
+       else
+               cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
+
        if (phydev->link) {
                ret = phy_read(phydev, MII_COMMSTAT);
                if (ret < 0)
@@ -237,6 +276,8 @@ static int tja11xx_read_status(struct phy_device *phydev)
                        phydev->link = 0;
        }
 
+       phydev->master_slave_get = cfg;
+
        return 0;
 }
 
@@ -504,6 +545,7 @@ static struct phy_driver tja11xx_driver[] = {
                .features       = PHY_BASIC_T1_FEATURES,
                .probe          = tja11xx_probe,
                .soft_reset     = tja11xx_soft_reset,
+               .config_aneg    = tja11xx_config_aneg,
                .config_init    = tja11xx_config_init,
                .read_status    = tja11xx_read_status,
                .suspend        = genphy_suspend,
@@ -519,6 +561,7 @@ static struct phy_driver tja11xx_driver[] = {
                .features       = PHY_BASIC_T1_FEATURES,
                .probe          = tja11xx_probe,
                .soft_reset     = tja11xx_soft_reset,
+               .config_aneg    = tja11xx_config_aneg,
                .config_init    = tja11xx_config_init,
                .read_status    = tja11xx_read_status,
                .suspend        = genphy_suspend,
@@ -533,6 +576,7 @@ static struct phy_driver tja11xx_driver[] = {
                .features       = PHY_BASIC_T1_FEATURES,
                .probe          = tja1102_p0_probe,
                .soft_reset     = tja11xx_soft_reset,
+               .config_aneg    = tja11xx_config_aneg,
                .config_init    = tja11xx_config_init,
                .read_status    = tja11xx_read_status,
                .match_phy_device = tja1102_p0_match_phy_device,
@@ -551,6 +595,7 @@ static struct phy_driver tja11xx_driver[] = {
                .features       = PHY_BASIC_T1_FEATURES,
                /* currently no probe for Port 1 is need */
                .soft_reset     = tja11xx_soft_reset,
+               .config_aneg    = tja11xx_config_aneg,
                .config_init    = tja11xx_config_init,
                .read_status    = tja11xx_read_status,
                .match_phy_device = tja1102_p1_match_phy_device,
-- 
2.26.2

Reply via email to