lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250910-ksz-strap-pins-v1-2-6308bb2e139e@bootlin.com>
Date: Wed, 10 Sep 2025 16:55:25 +0200
From: Bastien Curutchet <bastien.curutchet@...tlin.com>
To: Woojung Huh <woojung.huh@...rochip.com>, UNGLinuxDriver@...rochip.com, 
 Andrew Lunn <andrew@...n.ch>, Vladimir Oltean <olteanv@...il.com>, 
 "David S. Miller" <davem@...emloft.net>, Eric Dumazet <edumazet@...gle.com>, 
 Jakub Kicinski <kuba@...nel.org>, Paolo Abeni <pabeni@...hat.com>, 
 Rob Herring <robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>, 
 Conor Dooley <conor+dt@...nel.org>, Marek Vasut <marex@...x.de>
Cc: Thomas Petazzoni <thomas.petazzoni@...tlin.com>, 
 Miquèl Raynal <miquel.raynal@...tlin.com>, 
 Pascal Eberhard <pascal.eberhard@...com>, 
 Woojung Huh <Woojung.Huh@...rochip.com>, netdev@...r.kernel.org, 
 devicetree@...r.kernel.org, linux-kernel@...r.kernel.org, 
 "Bastien Curutchet (Schneider Electric)" <bastien.curutchet@...tlin.com>
Subject: [PATCH net-next 2/2] net: dsa: microchip: configure strap pins
 during reset

At reset, some KSZ switches use strap based configuration. If the
required pull-ups/pull-downs are missing (by mistake or by design to
save power) the pins may float and the configuration can go wrong.

Introduce a configure_strap() function, called during the device reset.
It relies on the 'strap-gpios' OF property and the 'reset' pinmux
configuration to drive the configuration pins to the proper state.
Support the KSZ8463's strap configuration that enforces SPI as
communication bus, since it is the only bus supported by the driver.

Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@...tlin.com>
---
 drivers/net/dsa/microchip/ksz_common.c | 47 ++++++++++++++++++++++++++++++++++
 1 file changed, 47 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 7292bfe2f7cac3a0d88bb51339cc287f56ca1d1f..0ab201a3c336b99ba92d87c003ba48f7f82a098a 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -23,6 +23,7 @@
 #include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <linux/micrel_phy.h>
+#include <linux/pinctrl/consumer.h>
 #include <net/dsa.h>
 #include <net/ieee8021q.h>
 #include <net/pkt_cls.h>
@@ -5338,6 +5339,44 @@ static int ksz_parse_drive_strength(struct ksz_device *dev)
 	return 0;
 }
 
+static int ksz_configure_strap(struct ksz_device *dev)
+{
+	struct pinctrl_state *state = NULL;
+	struct pinctrl *pinctrl;
+	int ret;
+
+	if (of_device_is_compatible(dev->dev->of_node, "microchip,ksz8463")) {
+		struct gpio_desc *rxd0;
+		struct gpio_desc *rxd1;
+
+		rxd0 = devm_gpiod_get_index_optional(dev->dev, "strap", 0, GPIOD_OUT_LOW);
+		if (IS_ERR(rxd0))
+			return PTR_ERR(rxd0);
+
+		rxd1 = devm_gpiod_get_index_optional(dev->dev, "strap", 1, GPIOD_OUT_HIGH);
+		if (IS_ERR(rxd1))
+			return PTR_ERR(rxd1);
+
+		/* If at least one strap definition is missing we don't do anything */
+		if (!rxd0 || !rxd1)
+			return 0;
+
+		pinctrl = devm_pinctrl_get(dev->dev);
+		if (IS_ERR(pinctrl))
+			return PTR_ERR(pinctrl);
+
+		state = pinctrl_lookup_state(pinctrl, "reset");
+		if (IS_ERR(state))
+			return PTR_ERR(state);
+
+		ret = pinctrl_select_state(pinctrl, state);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 int ksz_switch_register(struct ksz_device *dev)
 {
 	const struct ksz_chip_data *info;
@@ -5353,10 +5392,18 @@ int ksz_switch_register(struct ksz_device *dev)
 		return PTR_ERR(dev->reset_gpio);
 
 	if (dev->reset_gpio) {
+		ret = ksz_configure_strap(dev);
+		if (ret)
+			return ret;
+
 		gpiod_set_value_cansleep(dev->reset_gpio, 1);
 		usleep_range(10000, 12000);
 		gpiod_set_value_cansleep(dev->reset_gpio, 0);
 		msleep(100);
+
+		ret = pinctrl_select_default_state(dev->dev);
+		if (ret)
+			return ret;
 	}
 
 	mutex_init(&dev->dev_mutex);

-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ