[PATCH 2/3] net: dsa: microchip: parse KSZ87xx low-loss errata from DT

Fidelio Lawson posted 3 patches 1 week ago
[PATCH 2/3] net: dsa: microchip: parse KSZ87xx low-loss errata from DT
Posted by Fidelio Lawson 1 week ago
Add parsing of the new DT bindings related to the KSZ87xx low-loss cable
errata. The parsed values are stored in the ksz_device structure for use
during switch initialization.

If the enable property is present, the driver reads the errata mode
(microchip,low-loss-errata) and selects workaround 1 or 2 accordingly.
If the enable property is absent, the errata logic is fully disabled.

This keeps behavior fully backward-compatible with existing
device trees.

Signed-off-by: Fidelio Lawson <fidelio.lawson@exotec.com>
---
 drivers/net/dsa/microchip/ksz8.c       | 25 +++++++++++++++++++++++++
 drivers/net/dsa/microchip/ksz8.h       |  1 +
 drivers/net/dsa/microchip/ksz_common.h |  9 +++++++++
 3 files changed, 35 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz8.c b/drivers/net/dsa/microchip/ksz8.c
index c354abdafc1b..78b42cf50ce2 100644
--- a/drivers/net/dsa/microchip/ksz8.c
+++ b/drivers/net/dsa/microchip/ksz8.c
@@ -1989,6 +1989,10 @@ int ksz8_setup(struct dsa_switch *ds)
 			ret = ksz_rmw8(dev, REG_INT_ENABLE, INT_PME, 0);
 	}
 
+	/* Check if errata on low loss cable should be applied */
+	if (ksz_is_ksz87xx(dev))
+		ksz87xx_parse_errata_dt(dev);
+
 	if (!ret)
 		return ksz8_handle_global_errata(ds);
 	else
@@ -2096,6 +2100,27 @@ int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val)
 	return 0;
 }
 
+void ksz87xx_parse_errata_dt(struct ksz_device *dev)
+{
+	struct device_node *np = dev->dev->of_node;
+	u32 mode;
+	int ret;
+
+	dev->low_loss_wa_enable = of_property_read_bool(np, "microchip,low-loss-errata-enable");
+
+	if (!dev->low_loss_wa_enable) {
+		dev->low_loss_wa_mode = KSZ_LOW_LOSS_WA_NONE;
+		return;
+	}
+
+	ret = of_property_read_u32(np, "microchip,low-loss-errata", &mode);
+
+	if (!ret && (mode == 1 || mode == 2))
+		dev->low_loss_wa_mode = mode;
+	else
+		dev->low_loss_wa_mode = KSZ_LOW_LOSS_WA_1;
+}
+
 int ksz8_switch_init(struct ksz_device *dev)
 {
 	dev->cpu_port = fls(dev->info->cpu_ports) - 1;
diff --git a/drivers/net/dsa/microchip/ksz8.h b/drivers/net/dsa/microchip/ksz8.h
index 0f2cd1474b44..3a43769a4c53 100644
--- a/drivers/net/dsa/microchip/ksz8.h
+++ b/drivers/net/dsa/microchip/ksz8.h
@@ -66,5 +66,6 @@ int ksz8_all_queues_split(struct ksz_device *dev, int queues);
 u32 ksz8463_get_port_addr(int port, int offset);
 int ksz8463_r_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 *val);
 int ksz8463_w_phy(struct ksz_device *dev, u16 phy, u16 reg, u16 val);
+void ksz87xx_parse_errata_dt(struct ksz_device *dev);
 
 #endif
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 929aff4c55de..f40e7bd20b3e 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -158,6 +158,12 @@ struct ksz_port {
 	bool manual_flow;
 };
 
+enum ksz_low_loss_wa_mode {
+	KSZ_LOW_LOSS_WA_NONE = 0,
+	KSZ_LOW_LOSS_WA_1    = 1,
+	KSZ_LOW_LOSS_WA_2    = 2,
+};
+
 struct ksz_device {
 	struct dsa_switch *ds;
 	struct ksz_platform_data *pdata;
@@ -219,6 +225,9 @@ struct ksz_device {
 	 * the switch’s internal PHYs, bypassing the main SPI interface.
 	 */
 	struct mii_bus *parent_mdio_bus;
+
+	bool low_loss_wa_enable;     /* low-loss cable errata activation */
+	enum ksz_low_loss_wa_mode low_loss_wa_mode;     /* low-loss cable Workaround to apply */
 };
 
 /* List of supported models */

-- 
2.53.0