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>] [day] [month] [year] [list]
Message-ID: <20251025160905.3857885-268-sashal@kernel.org>
Date: Sat, 25 Oct 2025 11:58:19 -0400
From: Sasha Levin <sashal@...nel.org>
To: patches@...ts.linux.dev,
	stable@...r.kernel.org
Cc: Bastien Curutchet <bastien.curutchet@...tlin.com>,
	Andrew Lunn <andrew@...n.ch>,
	Jakub Kicinski <kuba@...nel.org>,
	Sasha Levin <sashal@...nel.org>,
	woojung.huh@...rochip.com,
	UNGLinuxDriver@...rochip.com,
	netdev@...r.kernel.org
Subject: [PATCH AUTOSEL 6.17-6.12] net: dsa: microchip: Set SPI as bus interface during reset for KSZ8463

From: Bastien Curutchet <bastien.curutchet@...tlin.com>

[ Upstream commit a0b977a3d19368b235f2a6c06e800fb25452029b ]

At reset, the KSZ8463 uses a strap-based configuration to set SPI as
bus interface. SPI is the only bus supported by the driver. 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
preventing any communication with the switch.

Introduce a ksz8463_configure_straps_spi() function called during the
device reset. It relies on the 'straps-rxd-gpios' OF property and the
'reset' pinmux configuration to enforce SPI as bus interface.

Reviewed-by: Andrew Lunn <andrew@...n.ch>
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@...tlin.com>
Link: https://patch.msgid.link/20250918-ksz-strap-pins-v3-3-16662e881728@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---

LLM Generated explanations, may be completely bogus:

YES: This change is a small, self‑contained bug fix that protects
KSZ8463 boards from booting with the wrong host interface when the
hardware strap resistors are missing or weak.

- `drivers/net/dsa/microchip/ksz_common.c:5355` introduces
  `ksz8463_configure_straps_spi()`, which momentarily drives the
  `straps-rxd` GPIOs (if present) to the required low/high levels before
  reset, guaranteeing the switch samples “SPI” on the bus-strap pins.
  Without this, floating pins can leave the device in a non-SPI mode and
  make the switch unreachable.
- The new code path is gated tightly: it runs only for
  `microchip,ksz8463` devices that already provide a `reset-gpios` line,
  and it bails out harmlessly when the optional strap GPIOs aren’t
  described, so existing DTs keep working unchanged.
- After toggling reset, `drivers/net/dsa/microchip/ksz_common.c:5408`
  calls `ksz8463_release_straps_spi()` to restore the default pinctrl
  state; `pinctrl_select_default_state()` safely no-ops when no pinctrl
  data exist (`drivers/pinctrl/core.c:1637`), so there’s no regression
  risk for existing boards.
- The fix relies only on long-standing GPIO/pinctrl helpers, adds no
  architectural churn, and doesn’t touch other chips or subsystems; it
  simply lets boards that already wire the strap pins to GPIOs recover
  from a real hardware failure mode.

Given the user-visible failure it resolves and its low risk profile,
this commit is a good candidate for the stable series. Recommend
backporting alongside the corresponding DT binding update so board
descriptions can supply the new strap GPIOs and “reset” pinmux state
when needed.

 drivers/net/dsa/microchip/ksz_common.c | 45 ++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 9568cc391fe3e..a962055bfdbd8 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>
@@ -5345,6 +5346,38 @@ static int ksz_parse_drive_strength(struct ksz_device *dev)
 	return 0;
 }
 
+static int ksz8463_configure_straps_spi(struct ksz_device *dev)
+{
+	struct pinctrl *pinctrl;
+	struct gpio_desc *rxd0;
+	struct gpio_desc *rxd1;
+
+	rxd0 = devm_gpiod_get_index_optional(dev->dev, "straps-rxd", 0, GPIOD_OUT_LOW);
+	if (IS_ERR(rxd0))
+		return PTR_ERR(rxd0);
+
+	rxd1 = devm_gpiod_get_index_optional(dev->dev, "straps-rxd", 1, GPIOD_OUT_HIGH);
+	if (IS_ERR(rxd1))
+		return PTR_ERR(rxd1);
+
+	if (!rxd0 && !rxd1)
+		return 0;
+
+	if ((rxd0 && !rxd1) || (rxd1 && !rxd0))
+		return -EINVAL;
+
+	pinctrl = devm_pinctrl_get_select(dev->dev, "reset");
+	if (IS_ERR(pinctrl))
+		return PTR_ERR(pinctrl);
+
+	return 0;
+}
+
+static int ksz8463_release_straps_spi(struct ksz_device *dev)
+{
+	return pinctrl_select_default_state(dev->dev);
+}
+
 int ksz_switch_register(struct ksz_device *dev)
 {
 	const struct ksz_chip_data *info;
@@ -5360,10 +5393,22 @@ int ksz_switch_register(struct ksz_device *dev)
 		return PTR_ERR(dev->reset_gpio);
 
 	if (dev->reset_gpio) {
+		if (of_device_is_compatible(dev->dev->of_node, "microchip,ksz8463")) {
+			ret = ksz8463_configure_straps_spi(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);
+
+		if (of_device_is_compatible(dev->dev->of_node, "microchip,ksz8463")) {
+			ret = ksz8463_release_straps_spi(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