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-next>] [day] [month] [year] [list]
Message-ID: <20241001090151.876200-1-alexander.sverdlin@siemens.com>
Date: Tue,  1 Oct 2024 11:01:48 +0200
From: "A. Sverdlin" <alexander.sverdlin@...mens.com>
To: netdev@...r.kernel.org
Cc: Anatolij Gustschin <agust@...x.de>,
	Andrew Lunn <andrew@...n.ch>,
	Florian Fainelli <f.fainelli@...il.com>,
	Vladimir Oltean <olteanv@...il.com>,
	Alexander Sverdlin <alexander.sverdlin@...mens.com>
Subject: [PATCH net-next] net: dsa: lan9303: ensure chip reset and wait for READY status

From: Anatolij Gustschin <agust@...x.de>

Accessing device registers seems to be not reliable, the chip
revision is sometimes detected wrongly (0 instead of expected 1).

Ensure that the chip reset is performed via reset GPIO and then
wait for 'Device Ready' status in HW_CFG register before doing
any register initializations.

Signed-off-by: Anatolij Gustschin <agust@...x.de>
[alex: added msleep() + justification for tout]
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@...mens.com>
---
 drivers/net/dsa/lan9303-core.c | 38 ++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 268949939636a..5744e7ac436fb 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -839,6 +839,8 @@ static void lan9303_handle_reset(struct lan9303 *chip)
 	if (!chip->reset_gpio)
 		return;
 
+	gpiod_set_value_cansleep(chip->reset_gpio, 1);
+
 	if (chip->reset_duration != 0)
 		msleep(chip->reset_duration);
 
@@ -863,9 +865,45 @@ static int lan9303_disable_processing(struct lan9303 *chip)
 
 static int lan9303_check_device(struct lan9303 *chip)
 {
+	/*
+	 * Loading of the largest supported EEPROM is expected to take at least
+	 * 5.9s
+	 */
+	int tout = 6000 / 30;
 	int ret;
 	u32 reg;
 
+	do {
+		ret = lan9303_read(chip->regmap, LAN9303_HW_CFG, &reg);
+		if (ret) {
+			dev_err(chip->dev, "failed to read HW_CFG reg: %d\n",
+				ret);
+		}
+		tout--;
+
+		dev_dbg(chip->dev, "%s: HW_CFG: 0x%08x\n", __func__, reg);
+		if ((reg & LAN9303_HW_CFG_READY) || !tout)
+			break;
+
+		/*
+		 * In I2C-managed configurations this polling loop will clash
+		 * with switch's reading of EEPROM right after reset and this
+		 * behaviour is not configurable. While lan9303_read() already
+		 * has quite long retry timeout, seems not all cases are being
+		 * detected as arbitration error.
+		 *
+		 * According to datasheet, EEPROM loader has 30ms timeout
+		 * (in case of missing EEPROM).
+		 */
+		msleep(30);
+	} while (true);
+
+	if (!tout) {
+		dev_err(chip->dev, "%s: HW_CFG not ready: 0x%08x\n",
+			__func__, reg);
+		return -ENODEV;
+	}
+
 	ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, &reg);
 	if (ret) {
 		dev_err(chip->dev, "failed to read chip revision register: %d\n",
-- 
2.46.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ