]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: phy: microchip_t1s: configure link status control for LAN867x Rev.D0
authorParthiban Veerasooran <parthiban.veerasooran@microchip.com>
Thu, 30 Oct 2025 10:22:58 +0000 (15:52 +0530)
committerJakub Kicinski <kuba@kernel.org>
Fri, 31 Oct 2025 23:52:06 +0000 (16:52 -0700)
Configure the link status in the Link Status Control register for
LAN8670/1/2 Rev.D0 PHYs, depending on whether PLCA or CSMA/CD mode
is enabled. When PLCA is enabled, the link status reflects the PLCA
status. When PLCA is disabled (CSMA/CD mode), the PHY does not support
autonegotiation, so the link status is forced active by setting
the LINK_STATUS_SEMAPHORE bit.

The link status control is configured:
- During PHY initialization, for default CSMA/CD mode.
- Whenever PLCA configuration is updated.

This ensures correct link reporting and consistent behavior for
LAN867x Rev.D0 devices.

Signed-off-by: Parthiban Veerasooran <parthiban.veerasooran@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20251030102258.180061-3-parthiban.veerasooran@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/microchip_t1s.c

index 03e3bacb02bd1e42954171827aee1380310ce2d0..bce5cf087b194f29716b73c131b09bd91291b98a 100644 (file)
 #define COL_DET_ENABLE                 BIT(15)
 #define COL_DET_DISABLE                        0x0000
 
+/* LAN8670/1/2 Rev.D0 Link Status Selection Register */
+#define LAN867X_REG_LINK_STATUS_CTRL   0x0012
+#define LINK_STATUS_CONFIGURATION      GENMASK(12, 11)
+#define LINK_STATUS_SEMAPHORE          BIT(0)
+
+/* Link Status Configuration */
+#define LINK_STATUS_CONFIG_PLCA_STATUS 0x1
+#define LINK_STATUS_CONFIG_SEMAPHORE   0x2
+
+#define LINK_STATUS_SEMAPHORE_SET      0x1
+
 #define LAN865X_CFGPARAM_READ_ENABLE BIT(1)
 
 /* The arrays below are pulled from the following table from AN1699
@@ -393,6 +404,32 @@ static int lan867x_revb1_config_init(struct phy_device *phydev)
        return 0;
 }
 
+static int lan867x_revd0_link_active_selection(struct phy_device *phydev,
+                                              bool plca_enabled)
+{
+       u16 value;
+
+       if (plca_enabled) {
+               /* 0x1 - When PLCA is enabled: link status reflects plca_status.
+                */
+               value = FIELD_PREP(LINK_STATUS_CONFIGURATION,
+                                  LINK_STATUS_CONFIG_PLCA_STATUS);
+       } else {
+               /* 0x2 - Link status is controlled by the value written into the
+                * LINK_STATUS_SEMAPHORE bit written. Here the link semaphore
+                * bit is written with 0x1 to set the link always active in
+                * CSMA/CD mode as it doesn't support autoneg.
+                */
+               value = FIELD_PREP(LINK_STATUS_CONFIGURATION,
+                                  LINK_STATUS_CONFIG_SEMAPHORE) |
+                       FIELD_PREP(LINK_STATUS_SEMAPHORE,
+                                  LINK_STATUS_SEMAPHORE_SET);
+       }
+
+       return phy_write_mmd(phydev, MDIO_MMD_VEND2,
+                            LAN867X_REG_LINK_STATUS_CTRL, value);
+}
+
 /* As per LAN8650/1 Rev.B0/B1 AN1760 (Revision F (DS60001760G - June 2024)) and
  * LAN8670/1/2 Rev.C1/C2 AN1699 (Revision E (DS60001699F - June 2024)), under
  * normal operation, the device should be operated in PLCA mode. Disabling
@@ -409,6 +446,14 @@ static int lan86xx_plca_set_cfg(struct phy_device *phydev,
 {
        int ret;
 
+       /* Link status selection must be configured for LAN8670/1/2 Rev.D0 */
+       if (phydev->phy_id == PHY_ID_LAN867X_REVD0) {
+               ret = lan867x_revd0_link_active_selection(phydev,
+                                                         plca_cfg->enabled);
+               if (ret)
+                       return ret;
+       }
+
        ret = genphy_c45_plca_set_cfg(phydev, plca_cfg);
        if (ret)
                return ret;
@@ -439,7 +484,11 @@ static int lan867x_revd0_config_init(struct phy_device *phydev)
                        return ret;
        }
 
-       return 0;
+       /* Initially the PHY will be in CSMA/CD mode by default. So it is
+        * required to set the link always active as it doesn't support
+        * autoneg.
+        */
+       return lan867x_revd0_link_active_selection(phydev, false);
 }
 
 static int lan86xx_read_status(struct phy_device *phydev)