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: <20210930125747.2511954-1-frieder@fris.de>
Date:   Thu, 30 Sep 2021 14:57:43 +0200
From:   Frieder Schrempf <frieder@...s.de>
To:     Andrew Lunn <andrew@...n.ch>,
        "David S. Miller" <davem@...emloft.net>,
        Heiner Kallweit <hkallweit1@...il.com>,
        Jakub Kicinski <kuba@...nel.org>, linux-kernel@...r.kernel.org,
        netdev@...r.kernel.org
Cc:     Frieder Schrempf <frieder.schrempf@...tron.de>,
        Bjarni Jonasson <bjarni.jonasson@...rochip.com>,
        Ioana Ciornei <ioana.ciornei@....com>,
        Russell King <linux@...linux.org.uk>,
        Steen Hegelund <steen.hegelund@...rochip.com>
Subject: [PATCH 1/3] net: phy: mscc: Add possibilty to disable combined LED mode

From: Frieder Schrempf <frieder.schrempf@...tron.de>

By default the LED modes offer to combine two indicators like speed/link
and activity in one LED. In order to use a LED only for the first of the
two modes, the combined feature needs to be disabled.

In order to do this we introduce a boolean devicetree property
'vsc8531,led-[N]-combine-disable' and wire it up to the matching
bits in the LED behavior register.

Signed-off-by: Frieder Schrempf <frieder.schrempf@...tron.de>
---
 drivers/net/phy/mscc/mscc.h      |  5 ++++
 drivers/net/phy/mscc/mscc_main.c | 47 ++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h
index a50235fdf7d9..114b087fc89a 100644
--- a/drivers/net/phy/mscc/mscc.h
+++ b/drivers/net/phy/mscc/mscc.h
@@ -85,6 +85,10 @@ enum rgmii_clock_delay {
 #define LED_MODE_SEL_MASK(x)		  (GENMASK(3, 0) << LED_MODE_SEL_POS(x))
 #define LED_MODE_SEL(x, mode)		  (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x))
 
+#define MSCC_PHY_LED_BEHAVIOR		  30
+#define LED_COMBINE_DIS_MASK(x)		  (1 << (x))
+#define LED_COMBINE_DIS(x, dis)		  (((dis) ? 1 : 0) << (x))
+
 #define MSCC_EXT_PAGE_CSR_CNTL_17	  17
 #define MSCC_EXT_PAGE_CSR_CNTL_18	  18
 
@@ -363,6 +367,7 @@ struct vsc8531_private {
 	int rate_magic;
 	u16 supp_led_modes;
 	u32 leds_mode[MAX_LEDS];
+	bool leds_combine[MAX_LEDS];
 	u8 nleds;
 	const struct vsc85xx_hw_stat *hw_stats;
 	u64 *stats;
diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c
index 6e32da28e138..d42723e04c98 100644
--- a/drivers/net/phy/mscc/mscc_main.c
+++ b/drivers/net/phy/mscc/mscc_main.c
@@ -171,7 +171,8 @@ static void vsc85xx_get_stats(struct phy_device *phydev,
 
 static int vsc85xx_led_cntl_set(struct phy_device *phydev,
 				u8 led_num,
-				u8 mode)
+				u8 mode,
+				bool combine_disable)
 {
 	int rc;
 	u16 reg_val;
@@ -181,6 +182,10 @@ static int vsc85xx_led_cntl_set(struct phy_device *phydev,
 	reg_val &= ~LED_MODE_SEL_MASK(led_num);
 	reg_val |= LED_MODE_SEL(led_num, (u16)mode);
 	rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val);
+	reg_val = phy_read(phydev, MSCC_PHY_LED_BEHAVIOR);
+	reg_val &= ~LED_COMBINE_DIS_MASK(led_num);
+	reg_val |= LED_COMBINE_DIS(led_num, combine_disable);
+	rc = phy_write(phydev, MSCC_PHY_LED_BEHAVIOR, reg_val);
 	mutex_unlock(&phydev->lock);
 
 	return rc;
@@ -432,6 +437,21 @@ static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 	return led_mode;
 }
 
+static bool vsc85xx_dt_led_combine_get(struct phy_device *phydev,
+				       char *led)
+{
+	struct vsc8531_private *priv = phydev->priv;
+	struct device *dev = &phydev->mdio.dev;
+	struct device_node *of_node = dev->of_node;
+	bool led_combine = false;
+	int err;
+
+	if (!of_node)
+		return false;
+
+	return of_property_read_bool(of_node, led);
+}
+
 #else
 static int vsc85xx_edge_rate_magic_get(struct phy_device *phydev)
 {
@@ -444,13 +464,19 @@ static int vsc85xx_dt_led_mode_get(struct phy_device *phydev,
 {
 	return default_mode;
 }
+
+static bool vsc85xx_dt_led_combine_get(struct phy_device *phydev,
+				       char *led)
+{
+	return false;
+}
 #endif /* CONFIG_OF_MDIO */
 
 static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
 				    u32 *default_mode)
 {
 	struct vsc8531_private *priv = phydev->priv;
-	char led_dt_prop[28];
+	char led_dt_prop[32];
 	int i, ret;
 
 	for (i = 0; i < priv->nleds; i++) {
@@ -463,6 +489,14 @@ static int vsc85xx_dt_led_modes_get(struct phy_device *phydev,
 		if (ret < 0)
 			return ret;
 		priv->leds_mode[i] = ret;
+
+		ret = sprintf(led_dt_prop,
+			      "vsc8531,led-%d-combine-disable", i);
+		if (ret < 0)
+			return ret;
+
+		priv->leds_combine[i] =
+			vsc85xx_dt_led_combine_get(phydev, led_dt_prop);
 	}
 
 	return 0;
@@ -1779,7 +1813,8 @@ static int vsc8584_config_init(struct phy_device *phydev)
 		return ret;
 
 	for (i = 0; i < vsc8531->nleds; i++) {
-		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i],
+					   vsc8531->leds_combine[i]);
 		if (ret)
 			return ret;
 	}
@@ -1846,7 +1881,8 @@ static int vsc85xx_config_init(struct phy_device *phydev)
 		return rc;
 
 	for (i = 0; i < vsc8531->nleds; i++) {
-		rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+		rc = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i],
+					  vsc8531->leds_combine[i]);
 		if (rc)
 			return rc;
 	}
@@ -2099,7 +2135,8 @@ static int vsc8514_config_init(struct phy_device *phydev)
 		return ret;
 
 	for (i = 0; i < vsc8531->nleds; i++) {
-		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i]);
+		ret = vsc85xx_led_cntl_set(phydev, i, vsc8531->leds_mode[i],
+					   vsc8531->leds_combine[i]);
 		if (ret)
 			return ret;
 	}
-- 
2.33.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ