netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC net-next v2 00/18] Add support for PSE port priority
@ 2024-10-30 16:53 Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 01/18] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration Kory Maincent
                   ` (17 more replies)
  0 siblings, 18 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent, Kalesh AP

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

This series brings support for port priority in the PSE subsystem.
PSE controllers can set priorities to decide which ports should be
turned off in case of special events like over-current.

I have added regulator maintainers to have their opinion on adding power
budget regulator constraint see patches 11 and 12.

This patch series adds support for two mode port priority modes.
1. Static Method:

   This method involves distributing power based on PD classification.
   It’s straightforward and stable, the PSE core keeping track of the
   budget and subtracting the power requested by each PD’s class.

   Advantages: Every PD gets its promised power at any time, which
   guarantees reliability.

   Disadvantages: PD classification steps are large, meaning devices
   request much more power than they actually need. As a result, the power
   supply may only operate at, say, 50% capacity, which is inefficient and
   wastes money.

2. Dynamic Method:

   To address the inefficiencies of the static method, vendors like
   Microchip have introduced dynamic power budgeting, as seen in the
   PD692x0 firmware. This method monitors the current consumption per port
   and subtracts it from the available power budget. When the budget is
   exceeded, lower-priority ports are shut down.

   Advantages: This method optimizes resource utilization, saving costs.

   Disadvantages: Low-priority devices may experience instability.

The UAPI allows adding support for software port priority mode managed from
userspace later if needed.

This patch series is currently untested and still lacks driver-level
support for port priority. I would appreciate your feedback on the current
implementation of port priority in the PSE core before proceeding further.

Several Reviewed-by have been removed due to the changes.

Thanks Oleksij for your pointers.

Patches 1-3: Cosmetics.
Patch 4: Adds support for last supported features in the TPS23881 drivers.
Patches 5,6: Add support for PSE index in PSE core and ethtool.
Patches 7-9: Add support for interrupt event report in PSE core, ethtool
	     and ethtool specs.
Patch 10: Adds support for interrupt and event report in TPS23881 driver.
Patches 11,12: Add support for power budget in regulator framework.
Patches 13,14: Add support for PSE power domain in PSE core and ethtool.
Patches 15-17: Add support for port priority in PSE core, ethtool and
	       ethtool specs.
Patches 18: Add support for port priority in PD692x0 drivers.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
Changes in v2:
- Rethink the port priority management.
- Add PSE id.
- Add support for PSE power domains.
- Add get power budget regulator constraint.
- Link to v1: https://lore.kernel.org/r/20241002-feature_poe_port_prio-v1-0-787054f74ed5@bootlin.com

---
Kory Maincent (18):
      net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration
      net: pse-pd: tps23881: Simplify function returns by removing redundant checks
      net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
      net: pse-pd: tps23881: Add support for power limit and measurement features
      net: pse-pd: Add support for PSE device index
      net: ethtool: Add support for new PSE device index description
      net: ethtool: Add support for ethnl_info_init_ntf helper function
      net: pse-pd: Add support for reporting events
      netlink: specs: Add support for PSE netlink notifications
      net: pse-pd: tps23881: Add support for PSE events and interrupts
      regulator: Add support for power budget description
      regulator: dt-bindings: Add regulator-power-budget property
      net: pse-pd: Add support for PSE power domains
      net: ethtool: Add support for new power domains index description
      net: pse-pd: Add support for getting and setting port priority
      net: ethtool: Add PSE new port priority support feature
      netlink: specs: Expand the PSE netlink command with newly supported features
      net: pse-pd: pd692x0: Add support for PSE PI priority feature

 .../devicetree/bindings/regulator/regulator.yaml   |   3 +
 Documentation/netlink/specs/ethtool.yaml           |  53 ++
 Documentation/networking/ethtool-netlink.rst       |  71 +++
 drivers/net/mdio/fwnode_mdio.c                     |  26 +-
 drivers/net/pse-pd/pd692x0.c                       |  24 +
 drivers/net/pse-pd/pse_core.c                      | 568 ++++++++++++++++++++-
 drivers/net/pse-pd/tps23881.c                      | 529 ++++++++++++++++---
 drivers/regulator/core.c                           |  11 +
 drivers/regulator/of_regulator.c                   |   3 +
 include/linux/ethtool_netlink.h                    |   9 +
 include/linux/pse-pd/pse.h                         |  75 ++-
 include/linux/regulator/consumer.h                 |   6 +
 include/linux/regulator/machine.h                  |   2 +
 include/uapi/linux/ethtool.h                       |  35 ++
 include/uapi/linux/ethtool_netlink.h               |  17 +
 net/ethtool/netlink.c                              |   5 +
 net/ethtool/netlink.h                              |   2 +
 net/ethtool/pse-pd.c                               |  93 ++++
 18 files changed, 1442 insertions(+), 90 deletions(-)
---
base-commit: 982a5437362e09def6c3152a9ec1392b9da16ece
change-id: 20240913-feature_poe_port_prio-a51aed7332ec

Best regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com


^ permalink raw reply	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 01/18] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 02/18] net: pse-pd: tps23881: Simplify function returns by removing redundant checks Kory Maincent
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent, Kalesh AP

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Removed the unused pse_ethtool_get_pw_limit() function declaration from
pse.h. This function was declared but never implemented or used,
making the declaration unnecessary.

Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Kyle Swenson <kyle.swenson@est.tech>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 include/linux/pse-pd/pse.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 591a53e082e6..85a08c349256 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -184,8 +184,6 @@ int pse_ethtool_set_config(struct pse_control *psec,
 int pse_ethtool_set_pw_limit(struct pse_control *psec,
 			     struct netlink_ext_ack *extack,
 			     const unsigned int pw_limit);
-int pse_ethtool_get_pw_limit(struct pse_control *psec,
-			     struct netlink_ext_ack *extack);
 
 bool pse_has_podl(struct pse_control *psec);
 bool pse_has_c33(struct pse_control *psec);
@@ -222,12 +220,6 @@ static inline int pse_ethtool_set_pw_limit(struct pse_control *psec,
 	return -EOPNOTSUPP;
 }
 
-static inline int pse_ethtool_get_pw_limit(struct pse_control *psec,
-					   struct netlink_ext_ack *extack)
-{
-	return -EOPNOTSUPP;
-}
-
 static inline bool pse_has_podl(struct pse_control *psec)
 {
 	return false;

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 02/18] net: pse-pd: tps23881: Simplify function returns by removing redundant checks
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 01/18] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Cleaned up several functions in tps23881 by removing redundant checks on
return values at the end of functions. These check has been removed, and
the return statement now directly returns the function result, reducing
the code's complexity and making it more concise.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>
Reviewed-by: Kyle Swenson <kyle.swenson@est.tech>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/tps23881.c | 26 +++++---------------------
 1 file changed, 5 insertions(+), 21 deletions(-)

diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c
index 5c4e88be46ee..20eab9857817 100644
--- a/drivers/net/pse-pd/tps23881.c
+++ b/drivers/net/pse-pd/tps23881.c
@@ -118,11 +118,7 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
 			val |= BIT(chan + 8);
 	}
 
-	ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
-	if (ret)
-		return ret;
-
-	return 0;
+	return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
 }
 
 static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
@@ -488,7 +484,7 @@ tps23881_write_port_matrix(struct tps23881_priv *priv,
 	struct i2c_client *client = priv->client;
 	u8 pi_id, lgcl_chan, hw_chan;
 	u16 val = 0;
-	int i, ret;
+	int i;
 
 	for (i = 0; i < port_cnt; i++) {
 		pi_id = port_matrix[i].pi_id;
@@ -519,11 +515,7 @@ tps23881_write_port_matrix(struct tps23881_priv *priv,
 	}
 
 	/* Write hardware ports matrix */
-	ret = i2c_smbus_write_word_data(client, TPS23881_REG_PORT_MAP, val);
-	if (ret)
-		return ret;
-
-	return 0;
+	return i2c_smbus_write_word_data(client, TPS23881_REG_PORT_MAP, val);
 }
 
 static int
@@ -572,11 +564,7 @@ tps23881_set_ports_conf(struct tps23881_priv *priv,
 			val |= BIT(port_matrix[i].lgcl_chan[1]) |
 			       BIT(port_matrix[i].lgcl_chan[1] + 4);
 	}
-	ret = i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
-	if (ret)
-		return ret;
-
-	return 0;
+	return i2c_smbus_write_word_data(client, TPS23881_REG_DET_CLA_EN, val);
 }
 
 static int
@@ -602,11 +590,7 @@ tps23881_set_ports_matrix(struct tps23881_priv *priv,
 	if (ret)
 		return ret;
 
-	ret = tps23881_set_ports_conf(priv, port_matrix);
-	if (ret)
-		return ret;
-
-	return 0;
+	return tps23881_set_ports_conf(priv, port_matrix);
 }
 
 static int tps23881_setup_pi_matrix(struct pse_controller_dev *pcdev)

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 01/18] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 02/18] net: pse-pd: tps23881: Simplify function returns by removing redundant checks Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:18   ` Oleksij Rempel
  2024-10-31 21:11   ` Andrew Lunn
  2024-10-30 16:53 ` [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features Kory Maincent
                   ` (14 subsequent siblings)
  17 siblings, 2 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

This driver frequently follows a pattern where two registers are read or
written in a single operation, followed by calculating the bit offset for
a specific channel.

Introduce helpers to streamline this process and reduce code redundancy,
making the codebase cleaner and more maintainable.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Thanks to Oleksij for the design of the helpers functions.

Change in v2:
- New patch
---
 drivers/net/pse-pd/tps23881.c | 107 +++++++++++++++++++++++++++---------------
 1 file changed, 69 insertions(+), 38 deletions(-)

diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c
index 20eab9857817..391b8964f687 100644
--- a/drivers/net/pse-pd/tps23881.c
+++ b/drivers/net/pse-pd/tps23881.c
@@ -53,6 +53,55 @@ static struct tps23881_priv *to_tps23881_priv(struct pse_controller_dev *pcdev)
 	return container_of(pcdev, struct tps23881_priv, pcdev);
 }
 
+/*
+ * Helper to extract a value from a u16 register value, which is made of two
+ * u8 registers. The function calculates the bit offset based on the channel
+ * and extracts the relevant bits using a provided field mask.
+ *
+ * @param reg_val: The u16 register value (composed of two u8 registers).
+ * @param chan: The channel number (0-7).
+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
+ * @param field_mask: The mask to apply to extract the required bits.
+ * @return: The extracted value for the specific channel.
+ */
+static u16 tps23881_calc_val(u16 reg_val, u8 chan, u8 field_offset,
+			     u16 field_mask)
+{
+	if (chan > 4)
+		reg_val >>= 8;
+
+	return (reg_val >> field_offset) & field_mask;
+}
+
+/*
+ * Helper to combine individual channel values into a u16 register value.
+ * The function sets the value for a specific channel in the appropriate
+ * position.
+ *
+ * @param reg_val: The current u16 register value.
+ * @param chan: The channel number (0-7).
+ * @param field_offset: The base bit offset to apply (e.g., 0 or 4).
+ * @param field_mask: The mask to apply for the field (e.g., 0x0F).
+ * @param field_val: The value to set for the specific channel (masked by
+ *                   field_mask).
+ * @return: The updated u16 register value with the channel value set.
+ */
+static u16 tps23881_set_val(u16 reg_val, u8 chan, u8 field_offset,
+			    u16 field_mask, u16 field_val)
+{
+	field_val &= field_mask;
+
+	if (chan < 4) {
+		reg_val &= ~(field_mask << field_offset);
+		reg_val |= (field_val << field_offset);
+	} else {
+		reg_val &= ~(field_mask << (field_offset + 8));
+		reg_val |= (field_val << (field_offset + 8));
+	}
+
+	return reg_val;
+}
+
 static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
 {
 	struct tps23881_priv *priv = to_tps23881_priv(pcdev);
@@ -69,17 +118,12 @@ static int tps23881_pi_enable(struct pse_controller_dev *pcdev, int id)
 		return ret;
 
 	chan = priv->port[id].chan[0];
-	if (chan < 4)
-		val = (u16)(ret | BIT(chan));
-	else
-		val = (u16)(ret | BIT(chan + 4));
+	val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
 
 	if (priv->port[id].is_4p) {
 		chan = priv->port[id].chan[1];
-		if (chan < 4)
-			val |= BIT(chan);
-		else
-			val |= BIT(chan + 4);
+		val = tps23881_set_val(val, chan, 0, BIT(chan % 4),
+				       BIT(chan % 4));
 	}
 
 	ret = i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
@@ -105,17 +149,12 @@ static int tps23881_pi_disable(struct pse_controller_dev *pcdev, int id)
 		return ret;
 
 	chan = priv->port[id].chan[0];
-	if (chan < 4)
-		val = (u16)(ret | BIT(chan + 4));
-	else
-		val = (u16)(ret | BIT(chan + 8));
+	val = tps23881_set_val(ret, chan, 4, BIT(chan % 4), BIT(chan % 4));
 
 	if (priv->port[id].is_4p) {
 		chan = priv->port[id].chan[1];
-		if (chan < 4)
-			val |= BIT(chan + 4);
-		else
-			val |= BIT(chan + 8);
+		val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
+				       BIT(chan % 4));
 	}
 
 	return i2c_smbus_write_word_data(client, TPS23881_REG_PW_EN, val);
@@ -127,6 +166,7 @@ static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
 	struct i2c_client *client = priv->client;
 	bool enabled;
 	u8 chan;
+	u16 val;
 	int ret;
 
 	ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
@@ -134,17 +174,13 @@ static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
 		return ret;
 
 	chan = priv->port[id].chan[0];
-	if (chan < 4)
-		enabled = ret & BIT(chan);
-	else
-		enabled = ret & BIT(chan + 4);
+	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+	enabled = !!(val);
 
 	if (priv->port[id].is_4p) {
 		chan = priv->port[id].chan[1];
-		if (chan < 4)
-			enabled &= !!(ret & BIT(chan));
-		else
-			enabled &= !!(ret & BIT(chan + 4));
+		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+		enabled &= !!(val);
 	}
 
 	/* Return enabled status only if both channel are on this state */
@@ -160,6 +196,7 @@ static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
 	struct i2c_client *client = priv->client;
 	bool enabled, delivering;
 	u8 chan;
+	u16 val;
 	int ret;
 
 	ret = i2c_smbus_read_word_data(client, TPS23881_REG_PW_STATUS);
@@ -167,23 +204,17 @@ static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
 		return ret;
 
 	chan = priv->port[id].chan[0];
-	if (chan < 4) {
-		enabled = ret & BIT(chan);
-		delivering = ret & BIT(chan + 4);
-	} else {
-		enabled = ret & BIT(chan + 4);
-		delivering = ret & BIT(chan + 8);
-	}
+	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+	enabled = !!(val);
+	val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
+	delivering = !!(val);
 
 	if (priv->port[id].is_4p) {
 		chan = priv->port[id].chan[1];
-		if (chan < 4) {
-			enabled &= !!(ret & BIT(chan));
-			delivering &= !!(ret & BIT(chan + 4));
-		} else {
-			enabled &= !!(ret & BIT(chan + 4));
-			delivering &= !!(ret & BIT(chan + 8));
-		}
+		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
+		enabled &= !!(val);
+		val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
+		delivering &= !!(val);
 	}
 
 	/* Return delivering status only if both channel are on this state */

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (2 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:20   ` Oleksij Rempel
  2024-10-30 16:53 ` [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index Kory Maincent
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Expand PSE callbacks to support the newly introduced
pi_get/set_current_limit() and pi_get_voltage() functions. These callbacks
allow for power limit configuration in the TPS23881 controller.

Additionally, the patch includes the detected class, the current power
delivered and the power limit ranges in the status returned, providing more
comprehensive PoE status reporting.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v2:
- Use newly introduced helpers.
---
 drivers/net/pse-pd/tps23881.c | 306 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 306 insertions(+)

diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c
index 391b8964f687..928d9844462c 100644
--- a/drivers/net/pse-pd/tps23881.c
+++ b/drivers/net/pse-pd/tps23881.c
@@ -25,17 +25,29 @@
 #define TPS23881_REG_GEN_MASK	0x17
 #define TPS23881_REG_NBITACC	BIT(5)
 #define TPS23881_REG_PW_EN	0x19
+#define TPS23881_REG_2PAIR_POL1	0x1e
 #define TPS23881_REG_PORT_MAP	0x26
 #define TPS23881_REG_PORT_POWER	0x29
+#define TPS23881_REG_4PAIR_POL1	0x2a
+#define TPS23881_REG_INPUT_V	0x2e
+#define TPS23881_REG_CHAN1_A	0x30
+#define TPS23881_REG_CHAN1_V	0x32
 #define TPS23881_REG_POEPLUS	0x40
 #define TPS23881_REG_TPON	BIT(0)
 #define TPS23881_REG_FWREV	0x41
 #define TPS23881_REG_DEVID	0x43
 #define TPS23881_REG_DEVID_MASK	0xF0
 #define TPS23881_DEVICE_ID	0x02
+#define TPS23881_REG_CHAN1_CLASS	0x4c
 #define TPS23881_REG_SRAM_CTRL	0x60
 #define TPS23881_REG_SRAM_DATA	0x61
 
+#define TPS23881_UV_STEP	3662
+#define TPS23881_MAX_UV		60000000
+#define TPS23881_NA_STEP	70190
+#define TPS23881_MAX_UA		1150000
+#define TPS23881_MW_STEP	500
+
 struct tps23881_port_desc {
 	u8 chan[2];
 	bool is_4p;
@@ -187,6 +199,167 @@ static int tps23881_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
 	return enabled;
 }
 
+static int tps23881_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
+{
+	struct tps23881_priv *priv = to_tps23881_priv(pcdev);
+	struct i2c_client *client = priv->client;
+	int ret, reg;
+	u8 chan;
+	u64 uV;
+
+	/* Read Voltage only at one of the 2-pair ports */
+	chan = priv->port[id].chan[0];
+	if (chan < 4)
+		/* Registers 0x32 0x36 0x3a 0x3e */
+		reg = TPS23881_REG_CHAN1_V + chan * 4;
+	else
+		/* Registers 0x33 0x37 0x3b 0x3f */
+		reg = TPS23881_REG_CHAN1_V + 1 + (chan % 4) * 4;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	uV = ret;
+	uV *= TPS23881_UV_STEP;
+	if (uV > TPS23881_MAX_UV) {
+		dev_err(&client->dev, "voltage read out of range\n");
+		return -ERANGE;
+	}
+
+	return (int)uV;
+}
+
+static int
+tps23881_pi_get_chan_current(struct tps23881_priv *priv, u8 chan)
+{
+	struct i2c_client *client = priv->client;
+	int reg, ret;
+	u64 tmp_64;
+
+	if (chan < 4)
+		/* Registers 0x30 0x34 0x38 0x3c */
+		reg = TPS23881_REG_CHAN1_A + chan * 4;
+	else
+		/* Registers 0x31 0x35 0x39 0x3d */
+		reg = TPS23881_REG_CHAN1_A + 1 + (chan % 4) * 4;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	tmp_64 = ret;
+	tmp_64 *= TPS23881_NA_STEP;
+	/* uA = nA / 1000 */
+	tmp_64 = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000);
+	if (tmp_64 > TPS23881_MAX_UA) {
+		dev_err(&client->dev, "current read out of range\n");
+		return -ERANGE;
+	}
+	return (int)tmp_64;
+}
+
+static int
+tps23881_pi_get_power(struct tps23881_priv *priv, unsigned long id)
+{
+	int ret, uV, uA;
+	u64 tmp_64;
+	u8 chan;
+
+	ret = tps23881_pi_get_voltage(&priv->pcdev, id);
+	if (ret < 0)
+		return ret;
+	uV = ret;
+
+	chan = priv->port[id].chan[0];
+	ret = tps23881_pi_get_chan_current(priv, chan);
+	if (ret < 0)
+		return ret;
+	uA = ret;
+
+	if (priv->port[id].is_4p) {
+		chan = priv->port[id].chan[1];
+		ret = tps23881_pi_get_chan_current(priv, chan);
+		if (ret < 0)
+			return ret;
+		uA += ret;
+	}
+
+	tmp_64 = uV;
+	tmp_64 *= uA;
+	/* mW = uV * uA / 1000000000 */
+	return DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
+}
+
+static int
+tps23881_pi_get_pw_limit_chan(struct tps23881_priv *priv, u8 chan)
+{
+	struct i2c_client *client = priv->client;
+	int ret, reg;
+	u16 val;
+
+	reg = TPS23881_REG_2PAIR_POL1 + (chan % 4);
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	val = tps23881_calc_val(ret, chan, 0, 0xff);
+	return val * TPS23881_MW_STEP;
+}
+
+static int tps23881_pi_get_pw_limit(struct tps23881_priv *priv, int id)
+{
+	int ret, mW;
+	u8 chan;
+
+	chan = priv->port[id].chan[0];
+	ret = tps23881_pi_get_pw_limit_chan(priv, chan);
+	if (ret < 0)
+		return ret;
+
+	mW = ret;
+	if (priv->port[id].is_4p) {
+		chan = priv->port[id].chan[1];
+		ret = tps23881_pi_get_pw_limit_chan(priv, chan);
+		if (ret < 0)
+			return ret;
+		mW += ret;
+	}
+
+	return mW;
+}
+
+static int tps23881_pi_get_max_pw_limit(struct tps23881_priv *priv, int id)
+{
+	int ret, uV;
+	u64 tmp_64;
+
+	ret = tps23881_pi_get_voltage(&priv->pcdev, id);
+	if (ret < 0)
+		return ret;
+	uV = ret;
+
+	tmp_64 = uV;
+	tmp_64 *= MAX_PI_CURRENT;
+	/* mW = uV * uA / 1000000000 */
+	return DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
+}
+
+static int tps23881_pi_get_class(struct tps23881_priv *priv, int id)
+{
+	struct i2c_client *client = priv->client;
+	int ret, reg;
+	u8 chan;
+
+	chan = priv->port[id].chan[0];
+	reg = TPS23881_REG_CHAN1_CLASS + (chan % 4);
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	return tps23881_calc_val(ret, chan, 4, 0xff);
+}
+
 static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
 				       unsigned long id,
 				       struct netlink_ext_ack *extack,
@@ -229,6 +402,35 @@ static int tps23881_ethtool_get_status(struct pse_controller_dev *pcdev,
 	else
 		status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
 
+	ret = tps23881_pi_get_power(priv, id);
+	if (ret < 0)
+		return ret;
+	status->c33_actual_pw = ret;
+
+	status->c33_pw_limit_ranges = kzalloc(sizeof(*status->c33_pw_limit_ranges),
+					      GFP_KERNEL);
+	if (!status->c33_pw_limit_ranges)
+		return -ENOMEM;
+
+	status->c33_actual_pw = ret;
+
+	ret = tps23881_pi_get_max_pw_limit(priv, id);
+	if (ret < 0)
+		return ret;
+	status->c33_pw_limit_nb_ranges = 1;
+	status->c33_pw_limit_ranges->min = 2000;
+	status->c33_pw_limit_ranges->max = ret;
+
+	ret = tps23881_pi_get_pw_limit(priv, id);
+	if (ret < 0)
+		return ret;
+	status->c33_avail_pw_limit = ret;
+
+	ret = tps23881_pi_get_class(priv, id);
+	if (ret < 0)
+		return ret;
+	status->c33_pw_class = ret;
+
 	return 0;
 }
 
@@ -645,12 +847,116 @@ static int tps23881_setup_pi_matrix(struct pse_controller_dev *pcdev)
 	return ret;
 }
 
+static int tps23881_pi_get_current_limit(struct pse_controller_dev *pcdev,
+					 int id)
+{
+	struct tps23881_priv *priv = to_tps23881_priv(pcdev);
+	int ret, mW, uV;
+	u64 tmp_64;
+
+	ret = tps23881_pi_get_pw_limit(priv, id);
+	if (ret < 0)
+		return ret;
+	mW = ret;
+
+	ret = tps23881_pi_get_voltage(pcdev, id);
+	if (ret < 0)
+		return ret;
+	uV = ret;
+
+	tmp_64 = mW;
+	tmp_64 *= 1000000000ull;
+	/* uA = mW * 1000000000 / uV */
+	return DIV_ROUND_CLOSEST_ULL(tmp_64, uV);
+}
+
+static int
+tps23881_pi_set_2p_pw_limit(struct tps23881_priv *priv, u8 chan, u8 pol)
+{
+	struct i2c_client *client = priv->client;
+	int ret, reg;
+	u16 val;
+
+	reg = TPS23881_REG_2PAIR_POL1 + (chan % 4);
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	if (chan < 4)
+		val = (ret & 0xff00) | pol;
+	else
+		val = (ret & 0xff) | (pol << 8);
+
+	return i2c_smbus_write_word_data(client, reg, val);
+}
+
+static int
+tps23881_pi_set_4p_pw_limit(struct tps23881_priv *priv, u8 chan, u8 pol)
+{
+	struct i2c_client *client = priv->client;
+	int ret, reg;
+	u16 val;
+
+	if ((chan % 4) < 2)
+		reg = TPS23881_REG_4PAIR_POL1;
+	else
+		reg = TPS23881_REG_4PAIR_POL1 + 1;
+
+	ret = i2c_smbus_read_word_data(client, reg);
+	if (ret < 0)
+		return ret;
+
+	if (chan < 4)
+		val = (ret & 0xff00) | pol;
+	else
+		val = (ret & 0xff) | (pol << 8);
+
+	return i2c_smbus_write_word_data(client, reg, val);
+}
+
+static int tps23881_pi_set_current_limit(struct pse_controller_dev *pcdev,
+					 int id, int max_uA)
+{
+	struct tps23881_priv *priv = to_tps23881_priv(pcdev);
+	u8 chan, pw_pol;
+	int ret, mW;
+	u64 tmp_64;
+
+	ret = tps23881_pi_get_voltage(pcdev, id);
+	if (ret < 0)
+		return ret;
+
+	tmp_64 = ret;
+	tmp_64 *= max_uA;
+	/* mW = uV * uA / 1000000000 */
+	mW = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
+	pw_pol = DIV_ROUND_CLOSEST_ULL(mW, TPS23881_MW_STEP);
+
+	if (priv->port[id].is_4p) {
+		chan = priv->port[id].chan[0];
+		/* One chan is enough to configure the PI power limit */
+		ret = tps23881_pi_set_4p_pw_limit(priv, chan, pw_pol);
+		if (ret < 0)
+			return ret;
+	} else {
+		chan = priv->port[id].chan[0];
+		ret = tps23881_pi_set_2p_pw_limit(priv, chan, pw_pol);
+		if (ret < 0)
+			return ret;
+	}
+
+	return 0;
+}
+
 static const struct pse_controller_ops tps23881_ops = {
 	.setup_pi_matrix = tps23881_setup_pi_matrix,
 	.pi_enable = tps23881_pi_enable,
 	.pi_disable = tps23881_pi_disable,
 	.pi_is_enabled = tps23881_pi_is_enabled,
 	.ethtool_get_status = tps23881_ethtool_get_status,
+	.pi_get_voltage = tps23881_pi_get_voltage,
+	.pi_get_current_limit = tps23881_pi_get_current_limit,
+	.pi_set_current_limit = tps23881_pi_set_current_limit,
 };
 
 static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin";

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (3 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:27   ` Oleksij Rempel
  2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Add support for a PSE device index to report the PSE controller index to
the user through ethtool. This will be useful for future support of power
domains and port priority management.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

changes in v2:
- new patch.
---
 drivers/net/pse-pd/pse_core.c | 23 ++++++++++++++++++-----
 include/linux/pse-pd/pse.h    |  4 ++++
 2 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 2906ce173f66..68297428f6b5 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -13,6 +13,7 @@
 
 static DEFINE_MUTEX(pse_list_mutex);
 static LIST_HEAD(pse_controller_list);
+static DEFINE_IDA(pse_ida);
 
 /**
  * struct pse_control - a PSE control
@@ -440,18 +441,22 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 
 	mutex_init(&pcdev->lock);
 	INIT_LIST_HEAD(&pcdev->pse_control_head);
+	ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);
+	if (ret < 0)
+		return ret;
+	pcdev->id = ret;
 
 	if (!pcdev->nr_lines)
 		pcdev->nr_lines = 1;
 
 	ret = of_load_pse_pis(pcdev);
 	if (ret)
-		return ret;
+		goto free_pse_ida;
 
 	if (pcdev->ops->setup_pi_matrix) {
 		ret = pcdev->ops->setup_pi_matrix(pcdev);
 		if (ret)
-			return ret;
+			goto free_pse_ida;
 	}
 
 	/* Each regulator name len is pcdev dev name + 7 char +
@@ -468,15 +473,17 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 			continue;
 
 		reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL);
-		if (!reg_name)
-			return -ENOMEM;
+		if (!reg_name) {
+			ret = -ENOMEM;
+			goto free_pse_ida;
+		}
 
 		snprintf(reg_name, reg_name_len, "pse-%s_pi%d",
 			 dev_name(pcdev->dev), i);
 
 		ret = devm_pse_pi_regulator_register(pcdev, reg_name, i);
 		if (ret)
-			return ret;
+			goto free_pse_ida;
 	}
 
 	mutex_lock(&pse_list_mutex);
@@ -484,6 +491,10 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 	mutex_unlock(&pse_list_mutex);
 
 	return 0;
+
+free_pse_ida:
+	ida_free(&pse_ida, pcdev->id);
+	return ret;
 }
 EXPORT_SYMBOL_GPL(pse_controller_register);
 
@@ -494,6 +505,7 @@ EXPORT_SYMBOL_GPL(pse_controller_register);
 void pse_controller_unregister(struct pse_controller_dev *pcdev)
 {
 	pse_release_pis(pcdev);
+	ida_free(&pse_ida, pcdev->id);
 	mutex_lock(&pse_list_mutex);
 	list_del(&pcdev->list);
 	mutex_unlock(&pse_list_mutex);
@@ -750,6 +762,7 @@ static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
 		return -EOPNOTSUPP;
 	}
 
+	status->pse_id = pcdev->id;
 	return ops->ethtool_get_status(pcdev, id, extack, status);
 }
 
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 85a08c349256..5312488cb3cf 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -31,6 +31,7 @@ struct pse_control_config {
 /**
  * struct pse_control_status - PSE control/channel status.
  *
+ * @pse_id: index number of the PSE. Set by PSE core.
  * @podl_admin_state: operational state of the PoDL PSE
  *	functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
  * @podl_pw_status: power detection status of the PoDL PSE.
@@ -52,6 +53,7 @@ struct pse_control_config {
  *	ranges
  */
 struct pse_control_status {
+	u32 pse_id;
 	enum ethtool_podl_pse_admin_state podl_admin_state;
 	enum ethtool_podl_pse_pw_d_status podl_pw_status;
 	enum ethtool_c33_pse_admin_state c33_admin_state;
@@ -150,6 +152,7 @@ struct pse_pi {
  * @types: types of the PSE controller
  * @pi: table of PSE PIs described in this controller device
  * @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
+ * @id: Index of the PSE
  */
 struct pse_controller_dev {
 	const struct pse_controller_ops *ops;
@@ -163,6 +166,7 @@ struct pse_controller_dev {
 	enum ethtool_pse_types types;
 	struct pse_pi *pi;
 	bool no_of_pse_pi;
+	int id;
 };
 
 #if IS_ENABLED(CONFIG_PSE_CONTROLLER)

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (4 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:28   ` Oleksij Rempel
                     ` (2 more replies)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function Kory Maincent
                   ` (11 subsequent siblings)
  17 siblings, 3 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Add functionality to report the newly introduced PSE device index to
the user, enabling better identification and management of PSE devices.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

changes in v2:
- new patch.
---
 Documentation/networking/ethtool-netlink.rst | 4 ++++
 include/uapi/linux/ethtool_netlink.h         | 1 +
 net/ethtool/pse-pd.c                         | 4 ++++
 3 files changed, 9 insertions(+)

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index b25926071ece..bd7173d1fa4d 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1766,6 +1766,7 @@ Kernel response contents:
                                                       limit of the PoE PSE.
   ``ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES``       nested  Supported power limit
                                                       configuration ranges.
+  ``ETHTOOL_A_PSE_ID``                           u32  Index of the PSE
   ==========================================  ======  =============================
 
 When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
@@ -1839,6 +1840,9 @@ identifies the C33 PSE power limit ranges through
 If the controller works with fixed classes, the min and max values will be
 equal.
 
+The ``ETHTOOL_A_PSE_ID`` attribute identifies the index of the PSE
+controller.
+
 PSE_SET
 =======
 
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 283305f6b063..9a4c293a9a82 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -970,6 +970,7 @@ enum {
 	ETHTOOL_A_C33_PSE_EXT_SUBSTATE,		/* u32 */
 	ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT,	/* u32 */
 	ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES,	/* nest - _C33_PSE_PW_LIMIT_* */
+	ETHTOOL_A_PSE_ID,			/* u32 */
 
 	/* add new constants above here */
 	__ETHTOOL_A_PSE_CNT,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index a0705edca22a..5edb8b0a669e 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -83,6 +83,7 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,
 	const struct pse_control_status *st = &data->status;
 	int len = 0;
 
+	len += nla_total_size(sizeof(u32)); /* _PSE_ID */
 	if (st->podl_admin_state > 0)
 		len += nla_total_size(sizeof(u32)); /* _PODL_PSE_ADMIN_STATE */
 	if (st->podl_pw_status > 0)
@@ -148,6 +149,9 @@ static int pse_fill_reply(struct sk_buff *skb,
 	const struct pse_reply_data *data = PSE_REPDATA(reply_base);
 	const struct pse_control_status *st = &data->status;
 
+	if (nla_put_u32(skb, ETHTOOL_A_PSE_ID, st->pse_id))
+		return -EMSGSIZE;
+
 	if (st->podl_admin_state > 0 &&
 	    nla_put_u32(skb, ETHTOOL_A_PODL_PSE_ADMIN_STATE,
 			st->podl_admin_state))

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (5 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31 21:44   ` Andrew Lunn
  2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Introduce support for the ethnl_info_init_ntf helper function to enable
initialization of ethtool notifications outside of the netlink.c file.
This change allows for more flexible notification handling.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

changes in v2:
- new patch.
---
 net/ethtool/netlink.c | 5 +++++
 net/ethtool/netlink.h | 2 ++
 2 files changed, 7 insertions(+)

diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
index e3f0ef6b851b..808cc8096f93 100644
--- a/net/ethtool/netlink.c
+++ b/net/ethtool/netlink.c
@@ -805,6 +805,11 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
 typedef void (*ethnl_notify_handler_t)(struct net_device *dev, unsigned int cmd,
 				       const void *data);
 
+void ethnl_info_init_ntf(struct genl_info *info, u8 cmd)
+{
+	genl_info_init_ntf(info, &ethtool_genl_family, cmd);
+}
+
 static const ethnl_notify_handler_t ethnl_notify_handlers[] = {
 	[ETHTOOL_MSG_LINKINFO_NTF]	= ethnl_default_notify,
 	[ETHTOOL_MSG_LINKMODES_NTF]	= ethnl_default_notify,
diff --git a/net/ethtool/netlink.h b/net/ethtool/netlink.h
index 203b08eb6c6f..d04a8e9d54db 100644
--- a/net/ethtool/netlink.h
+++ b/net/ethtool/netlink.h
@@ -322,6 +322,8 @@ struct ethnl_sock_priv {
 int ethnl_sock_priv_set(struct sk_buff *skb, struct net_device *dev, u32 portid,
 			enum ethnl_sock_type type);
 
+void ethnl_info_init_ntf(struct genl_info *info, u8 cmd);
+
 /**
  * struct ethnl_request_ops - unified handling of GET and SET requests
  * @request_cmd:      command id for request (GET)

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (6 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:34   ` Oleksij Rempel
                     ` (2 more replies)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 09/18] netlink: specs: Add support for PSE netlink notifications Kory Maincent
                   ` (9 subsequent siblings)
  17 siblings, 3 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Add support for devm_pse_irq_helper() to register PSE interrupts. This aims
to report events such as over-current or over-temperature conditions
similarly to how the regulator API handles them but using a specific PSE
ethtool netlink socket.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v2:
- Add support for PSE ethtool notification.
- Saved the attached phy_device in the pse_control structure to know which
  interface should have the notification.
- Rethink devm_pse_irq_helper() without devm_regulator_irq_helper() call.
---
 drivers/net/mdio/fwnode_mdio.c       |  26 ++++----
 drivers/net/pse-pd/pse_core.c        | 122 ++++++++++++++++++++++++++++++++++-
 include/linux/ethtool_netlink.h      |   9 +++
 include/linux/pse-pd/pse.h           |  16 ++++-
 include/uapi/linux/ethtool.h         |  11 ++++
 include/uapi/linux/ethtool_netlink.h |  11 ++++
 net/ethtool/pse-pd.c                 |  46 +++++++++++++
 7 files changed, 224 insertions(+), 17 deletions(-)

diff --git a/drivers/net/mdio/fwnode_mdio.c b/drivers/net/mdio/fwnode_mdio.c
index b156493d7084..7d571895a8eb 100644
--- a/drivers/net/mdio/fwnode_mdio.c
+++ b/drivers/net/mdio/fwnode_mdio.c
@@ -18,7 +18,8 @@ MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("FWNODE MDIO bus (Ethernet PHY) accessors");
 
 static struct pse_control *
-fwnode_find_pse_control(struct fwnode_handle *fwnode)
+fwnode_find_pse_control(struct fwnode_handle *fwnode,
+			struct phy_device *phydev)
 {
 	struct pse_control *psec;
 	struct device_node *np;
@@ -30,7 +31,7 @@ fwnode_find_pse_control(struct fwnode_handle *fwnode)
 	if (!np)
 		return NULL;
 
-	psec = of_pse_control_get(np);
+	psec = of_pse_control_get(np, phydev);
 	if (PTR_ERR(psec) == -ENOENT)
 		return NULL;
 
@@ -121,15 +122,9 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 	u32 phy_id;
 	int rc;
 
-	psec = fwnode_find_pse_control(child);
-	if (IS_ERR(psec))
-		return PTR_ERR(psec);
-
 	mii_ts = fwnode_find_mii_timestamper(child);
-	if (IS_ERR(mii_ts)) {
-		rc = PTR_ERR(mii_ts);
-		goto clean_pse;
-	}
+	if (IS_ERR(mii_ts))
+		return PTR_ERR(mii_ts);
 
 	is_c45 = fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45");
 	if (is_c45 || fwnode_get_phy_id(child, &phy_id))
@@ -162,6 +157,12 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 			goto clean_phy;
 	}
 
+	psec = fwnode_find_pse_control(child, phy);
+	if (IS_ERR(psec)) {
+		rc = PTR_ERR(psec);
+		goto unregister_phy;
+	}
+
 	phy->psec = psec;
 
 	/* phy->mii_ts may already be defined by the PHY driver. A
@@ -173,12 +174,13 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
 
 	return 0;
 
+unregister_phy:
+	if (is_acpi_node(child) || is_of_node(child))
+		phy_device_remove(phy);
 clean_phy:
 	phy_device_free(phy);
 clean_mii_ts:
 	unregister_mii_timestamper(mii_ts);
-clean_pse:
-	pse_control_put(psec);
 
 	return rc;
 }
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 68297428f6b5..712cb2d9c7c4 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -6,6 +6,7 @@
 //
 
 #include <linux/device.h>
+#include <linux/ethtool_netlink.h>
 #include <linux/of.h>
 #include <linux/pse-pd/pse.h>
 #include <linux/regulator/driver.h>
@@ -23,6 +24,7 @@ static DEFINE_IDA(pse_ida);
  * @list: list entry for the pcdev's PSE controller list
  * @id: ID of the PSE line in the PSE controller device
  * @refcnt: Number of gets of this pse_control
+ * @attached_phydev: PHY device pointer attached by the PSE control
  */
 struct pse_control {
 	struct pse_controller_dev *pcdev;
@@ -30,6 +32,7 @@ struct pse_control {
 	struct list_head list;
 	unsigned int id;
 	struct kref refcnt;
+	struct phy_device *attached_phydev;
 };
 
 static int of_load_single_pse_pi_pairset(struct device_node *node,
@@ -552,6 +555,116 @@ int devm_pse_controller_register(struct device *dev,
 }
 EXPORT_SYMBOL_GPL(devm_pse_controller_register);
 
+struct pse_irq {
+	struct pse_controller_dev *pcdev;
+	struct pse_irq_desc desc;
+	unsigned long *notifs;
+};
+
+static unsigned long pse_to_regulator_notifs(unsigned long notifs)
+{
+	switch (notifs) {
+	case ETHTOOL_C33_PSE_EVENT_OVER_CURRENT:
+		return REGULATOR_EVENT_OVER_CURRENT;
+	case ETHTOOL_C33_PSE_EVENT_OVER_TEMP:
+		return REGULATOR_EVENT_OVER_TEMP;
+	}
+	return 0;
+}
+
+static struct phy_device *
+pse_control_find_phy_by_id(struct pse_controller_dev *pcdev, int id)
+{
+	struct pse_control *psec;
+
+	mutex_lock(&pse_list_mutex);
+	list_for_each_entry(psec, &pcdev->pse_control_head, list) {
+		if (psec->id == id)
+			return psec->attached_phydev;
+	}
+	mutex_unlock(&pse_list_mutex);
+
+	return NULL;
+}
+
+static irqreturn_t pse_notifier_isr(int irq, void *data)
+{
+	struct netlink_ext_ack extack = {};
+	struct pse_controller_dev *pcdev;
+	unsigned long notifs_mask = 0;
+	struct pse_irq_desc *desc;
+	struct pse_irq *h = data;
+	int ret, i;
+
+	desc = &h->desc;
+	pcdev = h->pcdev;
+
+	/* Clear notifs mask */
+	memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
+	mutex_lock(&pcdev->lock);
+	ret = desc->map_event(irq, pcdev, h->notifs, &notifs_mask);
+	mutex_unlock(&pcdev->lock);
+	if (ret || !notifs_mask)
+		return IRQ_NONE;
+
+	for_each_set_bit(i, &notifs_mask, pcdev->nr_lines) {
+		struct phy_device *phydev;
+		unsigned long notifs, rnotifs;
+
+		/* Do nothing PI not described */
+		if (!pcdev->pi[i].rdev)
+			continue;
+
+		notifs = h->notifs[i];
+		dev_dbg(h->pcdev->dev,
+			"Sending PSE notification EVT 0x%lx\n", notifs);
+
+		phydev = pse_control_find_phy_by_id(pcdev, i);
+		if (phydev)
+			ethnl_pse_send_ntf(phydev, notifs, &extack);
+		rnotifs = pse_to_regulator_notifs(notifs);
+		regulator_notifier_call_chain(pcdev->pi[i].rdev, rnotifs,
+					      NULL);
+	}
+
+	return IRQ_HANDLED;
+}
+
+int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
+			int irq_flags, const struct pse_irq_desc *d)
+{
+	struct device *dev = pcdev->dev;
+	struct pse_irq *h;
+	int ret;
+
+	if (!d || !d->map_event || !d->name)
+		return -EINVAL;
+
+	h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
+	if (!h)
+		return -ENOMEM;
+
+	h->pcdev = pcdev;
+	h->desc = *d;
+	h->desc.name = devm_kstrdup(dev, d->name, GFP_KERNEL);
+	if (!h->desc.name)
+		return -ENOMEM;
+
+	h->notifs = devm_kcalloc(pcdev->dev, pcdev->nr_lines,
+				 sizeof(*h->notifs), GFP_KERNEL);
+	if (!h->notifs)
+		return -ENOMEM;
+
+	ret = devm_request_threaded_irq(dev, irq, NULL, pse_notifier_isr,
+					IRQF_ONESHOT | irq_flags,
+					h->desc.name, h);
+	if (ret)
+		dev_err(pcdev->dev, "Failed to request IRQ %d\n", irq);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(devm_pse_irq_helper);
+
 /* PSE control section */
 
 static void __pse_control_release(struct kref *kref)
@@ -594,7 +707,8 @@ void pse_control_put(struct pse_control *psec)
 EXPORT_SYMBOL_GPL(pse_control_put);
 
 static struct pse_control *
-pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
+pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index,
+			 struct phy_device *phydev)
 {
 	struct pse_control *psec;
 	int ret;
@@ -633,6 +747,7 @@ pse_control_get_internal(struct pse_controller_dev *pcdev, unsigned int index)
 	psec->pcdev = pcdev;
 	list_add(&psec->list, &pcdev->pse_control_head);
 	psec->id = index;
+	psec->attached_phydev = phydev;
 	kref_init(&psec->refcnt);
 
 	return psec;
@@ -688,7 +803,8 @@ static int psec_id_xlate(struct pse_controller_dev *pcdev,
 	return pse_spec->args[0];
 }
 
-struct pse_control *of_pse_control_get(struct device_node *node)
+struct pse_control *of_pse_control_get(struct device_node *node,
+				       struct phy_device *phydev)
 {
 	struct pse_controller_dev *r, *pcdev;
 	struct of_phandle_args args;
@@ -738,7 +854,7 @@ struct pse_control *of_pse_control_get(struct device_node *node)
 	}
 
 	/* pse_list_mutex also protects the pcdev's pse_control list */
-	psec = pse_control_get_internal(pcdev, psec_id);
+	psec = pse_control_get_internal(pcdev, psec_id, phydev);
 
 out:
 	mutex_unlock(&pse_list_mutex);
diff --git a/include/linux/ethtool_netlink.h b/include/linux/ethtool_netlink.h
index aba91335273a..0fa1d8f59cf2 100644
--- a/include/linux/ethtool_netlink.h
+++ b/include/linux/ethtool_netlink.h
@@ -43,6 +43,9 @@ void ethtool_aggregate_rmon_stats(struct net_device *dev,
 				  struct ethtool_rmon_stats *rmon_stats);
 bool ethtool_dev_mm_supported(struct net_device *dev);
 
+void ethnl_pse_send_ntf(struct phy_device *phydev, unsigned long notif,
+			struct netlink_ext_ack *extack);
+
 #else
 static inline int ethnl_cable_test_alloc(struct phy_device *phydev, u8 cmd)
 {
@@ -120,6 +123,12 @@ static inline bool ethtool_dev_mm_supported(struct net_device *dev)
 	return false;
 }
 
+static inline void ethnl_pse_send_ntf(struct phy_device *phydev,
+				      unsigned long notif,
+				      struct netlink_ext_ack *extack)
+{
+}
+
 #endif /* IS_ENABLED(CONFIG_ETHTOOL_NETLINK) */
 
 static inline int ethnl_cable_test_result(struct phy_device *phydev, u8 pair,
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 5312488cb3cf..ce8737c2219a 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -8,6 +8,7 @@
 #include <linux/ethtool.h>
 #include <linux/list.h>
 #include <uapi/linux/ethtool.h>
+#include <linux/regulator/driver.h>
 
 /* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
 #define MAX_PI_CURRENT 1920000
@@ -15,6 +16,13 @@
 struct phy_device;
 struct pse_controller_dev;
 
+struct pse_irq_desc {
+	const char *name;
+	int (*map_event)(int irq, struct pse_controller_dev *pcdev,
+			 unsigned long *notifs,
+			 unsigned long *notifs_mask);
+};
+
 /**
  * struct pse_control_config - PSE control/channel configuration.
  *
@@ -175,8 +183,11 @@ void pse_controller_unregister(struct pse_controller_dev *pcdev);
 struct device;
 int devm_pse_controller_register(struct device *dev,
 				 struct pse_controller_dev *pcdev);
+int devm_pse_irq_helper(struct pse_controller_dev *pcdev, int irq,
+			int irq_flags, const struct pse_irq_desc *d);
 
-struct pse_control *of_pse_control_get(struct device_node *node);
+struct pse_control *of_pse_control_get(struct device_node *node,
+				       struct phy_device *phydev);
 void pse_control_put(struct pse_control *psec);
 
 int pse_ethtool_get_status(struct pse_control *psec,
@@ -194,7 +205,8 @@ bool pse_has_c33(struct pse_control *psec);
 
 #else
 
-static inline struct pse_control *of_pse_control_get(struct device_node *node)
+static inline struct pse_control *of_pse_control_get(struct device_node *node,
+						     struct phy_device *phydev)
 {
 	return ERR_PTR(-ENOENT);
 }
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index c405ed63acfa..a1ad257b1ec1 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -998,6 +998,17 @@ enum ethtool_c33_pse_pw_d_status {
 	ETHTOOL_C33_PSE_PW_D_STATUS_OTHERFAULT,
 };
 
+/**
+ * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
+ * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
+ * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
+ */
+
+enum ethtool_c33_pse_events {
+	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
+	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
+};
+
 /**
  * enum ethtool_podl_pse_admin_state - operational state of the PoDL PSE
  *	functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 9a4c293a9a82..526b8b099c0e 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -114,6 +114,7 @@ enum {
 	ETHTOOL_MSG_MODULE_FW_FLASH_NTF,
 	ETHTOOL_MSG_PHY_GET_REPLY,
 	ETHTOOL_MSG_PHY_NTF,
+	ETHTOOL_MSG_PSE_NTF,
 
 	/* add new constants above here */
 	__ETHTOOL_MSG_KERNEL_CNT,
@@ -977,6 +978,16 @@ enum {
 	ETHTOOL_A_PSE_MAX = (__ETHTOOL_A_PSE_CNT - 1)
 };
 
+/* PSE NOTIFY */
+enum {
+	ETHTOOL_A_PSE_NTF_UNSPEC,
+	ETHTOOL_A_PSE_NTF_HEADER,	/* nest - ETHTOOL_A_HEADER_* */
+	ETHTOOL_A_C33_PSE_NTF_EVENTS,	/* u32 */
+
+	__ETHTOOL_A_PSE_NTF_CNT,
+	ETHTOOL_A_PSE_NTF_MAX = (__ETHTOOL_A_PSE_NTF_CNT - 1)
+};
+
 enum {
 	ETHTOOL_A_RSS_UNSPEC,
 	ETHTOOL_A_RSS_HEADER,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 5edb8b0a669e..52df956db0ba 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -319,3 +319,49 @@ const struct ethnl_request_ops ethnl_pse_request_ops = {
 	.set			= ethnl_set_pse,
 	/* PSE has no notification */
 };
+
+void ethnl_pse_send_ntf(struct phy_device *phydev, unsigned long notifs,
+			struct netlink_ext_ack *extack)
+{
+	struct net_device *netdev = phydev->attached_dev;
+	struct genl_info info;
+	void *reply_payload;
+	struct sk_buff *skb;
+	int reply_len;
+	int ret;
+
+	if (!netdev || !notifs)
+		return;
+
+	ethnl_info_init_ntf(&info, ETHTOOL_MSG_MM_NTF);
+	info.extack = extack;
+
+	reply_len = ethnl_reply_header_size();
+	/* _C33_PSE_NTF_EVENTS */
+	reply_len += nla_total_size(sizeof(u32));
+	skb = genlmsg_new(reply_len, GFP_KERNEL);
+	reply_payload = ethnl_bcastmsg_put(skb, ETHTOOL_MSG_MM_NTF);
+	if (!reply_payload)
+		goto err_skb;
+
+	ret = ethnl_fill_reply_header(skb, netdev,
+				      ETHTOOL_A_PSE_NTF_HEADER);
+	if (ret < 0)
+		goto err_skb;
+
+	ret = nla_put_u32(skb, ETHTOOL_A_C33_PSE_NTF_EVENTS, notifs);
+	if (ret) {
+		WARN_ONCE(ret == -EMSGSIZE,
+			  "calculated message payload length (%d) not sufficient\n",
+			  reply_len);
+		goto err_skb;
+	}
+
+	genlmsg_end(skb, reply_payload);
+	ethnl_multicast(skb, netdev);
+	return;
+
+err_skb:
+	nlmsg_free(skb);
+}
+EXPORT_SYMBOL_GPL(ethnl_pse_send_ntf);

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 09/18] netlink: specs: Add support for PSE netlink notifications
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (7 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 10/18] net: pse-pd: tps23881: Add support for PSE events and interrupts Kory Maincent
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Introduce support for PSE-specific netlink notifications, allowing for
the reporting of events related to c33 PSE (Power Sourcing Equipment).

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

changes in v2:
- new patch.
---
 Documentation/netlink/specs/ethtool.yaml | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 93369f0eb816..6983dea39976 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -1137,6 +1137,18 @@ attribute-sets:
       -
         name: downstream-sfp-name
         type: string
+  -
+    name: pse-ntf
+    attributes:
+      -
+        name: header
+        type: nest
+        nested-attributes: header
+      -
+        name: c33-pse-ntf-events
+        type: nest
+        nested-attributes: bitset
+        name-prefix: ethtool-a-
 
 operations:
   enum-model: directional
@@ -1960,3 +1972,13 @@ operations:
       name: phy-ntf
       doc: Notification for change in PHY devices.
       notify: phy-get
+    -
+      name: pse-ntf
+      doc: Notification for pse events.
+
+      attribute-set: pse-ntf
+
+      event:
+        attributes:
+          - header
+          - c33-pse-ntf-events

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 10/18] net: pse-pd: tps23881: Add support for PSE events and interrupts
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (8 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 09/18] netlink: specs: Add support for PSE netlink notifications Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description Kory Maincent
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Add support for PSE event reporting through interrupts. Set up the newly
introduced devm_pse_irq_helper helper to register the interrupt. Events are
reported for over-current and over-temperature conditions.

Reviewed-by: Kyle Swenson <kyle.swenson@est.tech>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v2:
- Remove support for OSS pin and TPC23881 specific port priority management
---
 drivers/net/pse-pd/tps23881.c | 90 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/drivers/net/pse-pd/tps23881.c b/drivers/net/pse-pd/tps23881.c
index 928d9844462c..3e15e2c97b24 100644
--- a/drivers/net/pse-pd/tps23881.c
+++ b/drivers/net/pse-pd/tps23881.c
@@ -17,6 +17,13 @@
 
 #define TPS23881_MAX_CHANS 8
 
+#define TPS23881_REG_IT		0x0
+#define TPS23881_REG_IT_MASK	0x1
+#define TPS23881_REG_IT_IFAULT	BIT(5)
+#define TPS23881_REG_IT_SUPF	BIT(7)
+#define TPS23881_REG_FAULT	0x7
+#define TPS23881_REG_SUPF_EVENT	0xb
+#define TPS23881_REG_TSD	BIT(7)
 #define TPS23881_REG_PW_STATUS	0x10
 #define TPS23881_REG_OP_MODE	0x12
 #define TPS23881_OP_MODE_SEMIAUTO	0xaaaa
@@ -24,6 +31,7 @@
 #define TPS23881_REG_DET_CLA_EN	0x14
 #define TPS23881_REG_GEN_MASK	0x17
 #define TPS23881_REG_NBITACC	BIT(5)
+#define TPS23881_REG_INTEN	BIT(7)
 #define TPS23881_REG_PW_EN	0x19
 #define TPS23881_REG_2PAIR_POL1	0x1e
 #define TPS23881_REG_PORT_MAP	0x26
@@ -1055,6 +1063,82 @@ static int tps23881_flash_sram_fw(struct i2c_client *client)
 	return 0;
 }
 
+static int tps23881_irq_handler(int irq, struct pse_controller_dev *pcdev,
+				unsigned long *notifs,
+				unsigned long *notifs_mask)
+{
+	struct tps23881_priv *priv = to_tps23881_priv(pcdev);
+	struct i2c_client *client = priv->client;
+	int ret, i;
+	u16 val;
+
+	ret = i2c_smbus_read_word_data(client, TPS23881_REG_IT);
+	if (ret < 0)
+		return ret;
+
+	val = (u16)ret;
+	/* The Supply event bit is repeated twice so we only need to read
+	 * the one from the first byte.
+	 */
+	if (val & TPS23881_REG_IT_SUPF) {
+		ret = i2c_smbus_read_word_data(client, TPS23881_REG_SUPF_EVENT);
+		if (ret < 0)
+			return ret;
+
+		if (ret & TPS23881_REG_TSD) {
+			for (i = 0; i < TPS23881_MAX_CHANS; i++) {
+				*notifs_mask |= 1 << i;
+				notifs[i] = ETHTOOL_C33_PSE_EVENT_OVER_TEMP;
+			}
+		}
+	}
+
+	if (val & (TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_IFAULT << 8)) {
+		ret = i2c_smbus_read_word_data(client, TPS23881_REG_FAULT);
+		if (ret < 0)
+			return ret;
+
+		/* Convert interrupt events located in 0xf0f to 0xff be
+		 * aligned with the port number.
+		 */
+		val = (u16)(((ret >> 4) & 0xf0) | (ret & 0x0f));
+
+		*notifs_mask |= val;
+		for_each_set_bit(i, notifs_mask, TPS23881_MAX_CHANS)
+			notifs[i] = ETHTOOL_C33_PSE_EVENT_OVER_CURRENT;
+	}
+
+	return 0;
+}
+
+static int tps23881_setup_irq(struct tps23881_priv *priv, int irq)
+{
+	struct i2c_client *client = priv->client;
+	struct pse_irq_desc irq_desc = {
+		.name = "tps23881-irq",
+		.map_event = tps23881_irq_handler,
+	};
+	int ret;
+	u16 val;
+
+	val = TPS23881_REG_IT_IFAULT | TPS23881_REG_IT_SUPF |
+	      TPS23881_REG_IT_IFAULT << 8 | TPS23881_REG_IT_SUPF << 8;
+	ret = i2c_smbus_write_word_data(client, TPS23881_REG_IT_MASK, val);
+	if (ret)
+		return ret;
+
+	ret = i2c_smbus_read_word_data(client, TPS23881_REG_GEN_MASK);
+	if (ret < 0)
+		return ret;
+
+	val = (u16)(ret | TPS23881_REG_INTEN | TPS23881_REG_INTEN << 8);
+	ret = i2c_smbus_write_word_data(client, TPS23881_REG_GEN_MASK, val);
+	if (ret < 0)
+		return ret;
+
+	return devm_pse_irq_helper(&priv->pcdev, irq, 0, &irq_desc);
+}
+
 static int tps23881_i2c_probe(struct i2c_client *client)
 {
 	struct device *dev = &client->dev;
@@ -1135,6 +1219,12 @@ static int tps23881_i2c_probe(struct i2c_client *client)
 				     "failed to register PSE controller\n");
 	}
 
+	if (client->irq) {
+		ret = tps23881_setup_irq(priv, client->irq);
+		if (ret)
+			return ret;
+	}
+
 	return ret;
 }
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (9 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 10/18] net: pse-pd: tps23881: Add support for PSE events and interrupts Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 17:03   ` Mark Brown
  2024-10-30 16:53 ` [PATCH RFC net-next v2 12/18] regulator: dt-bindings: Add regulator-power-budget property Kory Maincent
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

In preparation for future support of PSE port priority and power
management, we need the power budget value of the power supply.
This addition allows the regulator to track the available power
capacity, which will be essential for prioritizing ports when
making power allocation decisions.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Changes in v2:
- new patch.
---
 drivers/regulator/core.c           | 11 +++++++++++
 drivers/regulator/of_regulator.c   |  3 +++
 include/linux/regulator/consumer.h |  6 ++++++
 include/linux/regulator/machine.h  |  2 ++
 4 files changed, 22 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 1179766811f5..cd7b26f77a8e 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -4622,6 +4622,17 @@ int regulator_get_current_limit(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(regulator_get_current_limit);
 
+/**
+ * regulator_get_power_budget - get regulator total power budget
+ * @regulator: regulator source
+ *
+ * Return: Power budget of the regulator in mW.
+ */
+int regulator_get_power_budget(struct regulator *regulator)
+{
+	return regulator->rdev->constraints->pw_budget;
+}
+
 /**
  * regulator_set_mode - set regulator operating mode
  * @regulator: regulator source
diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c
index 3f490d81abc2..a8996e7597d4 100644
--- a/drivers/regulator/of_regulator.c
+++ b/drivers/regulator/of_regulator.c
@@ -125,6 +125,9 @@ static int of_get_regulation_constraints(struct device *dev,
 	if (constraints->min_uA != constraints->max_uA)
 		constraints->valid_ops_mask |= REGULATOR_CHANGE_CURRENT;
 
+	if (!of_property_read_u32(np, "regulator-power-budget", &pval))
+		constraints->pw_budget = pval;
+
 	constraints->boot_on = of_property_read_bool(np, "regulator-boot-on");
 	constraints->always_on = of_property_read_bool(np, "regulator-always-on");
 	if (!constraints->always_on) /* status change should be possible. */
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index b9ce521910a0..3e75d49d361f 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -235,6 +235,7 @@ int regulator_sync_voltage(struct regulator *regulator);
 int regulator_set_current_limit(struct regulator *regulator,
 			       int min_uA, int max_uA);
 int regulator_get_current_limit(struct regulator *regulator);
+int regulator_get_power_budget(struct regulator *regulator);
 
 int regulator_set_mode(struct regulator *regulator, unsigned int mode);
 unsigned int regulator_get_mode(struct regulator *regulator);
@@ -534,6 +535,11 @@ static inline int regulator_get_current_limit(struct regulator *regulator)
 	return 0;
 }
 
+static inline int regulator_get_power_budget(struct regulator *regulator)
+{
+	return 0;
+}
+
 static inline int regulator_set_mode(struct regulator *regulator,
 	unsigned int mode)
 {
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 0cd76d264727..3304cf8773b7 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -113,6 +113,7 @@ struct notification_limit {
  * @min_uA: Smallest current consumers may set.
  * @max_uA: Largest current consumers may set.
  * @ilim_uA: Maximum input current.
+ * @pw_budget: Power budget for the regulator in mW.
  * @system_load: Load that isn't captured by any consumer requests.
  *
  * @over_curr_limits:		Limits for acting on over current.
@@ -185,6 +186,7 @@ struct regulation_constraints {
 	int max_uA;
 	int ilim_uA;
 
+	int pw_budget;
 	int system_load;
 
 	/* used for coupled regulators */

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 12/18] regulator: dt-bindings: Add regulator-power-budget property
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (10 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 13/18] net: pse-pd: Add support for PSE power domains Kory Maincent
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Introduce a new property to describe the power budget of the regulator.
This property will allow power management support for regulator consumers
like PSE controllers, enabling them to make decisions based on the
available power capacity.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Changes in v2:
- new patch.
---
 Documentation/devicetree/bindings/regulator/regulator.yaml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/regulator.yaml b/Documentation/devicetree/bindings/regulator/regulator.yaml
index 1ef380d1515e..52a410b51769 100644
--- a/Documentation/devicetree/bindings/regulator/regulator.yaml
+++ b/Documentation/devicetree/bindings/regulator/regulator.yaml
@@ -34,6 +34,9 @@ properties:
   regulator-input-current-limit-microamp:
     description: maximum input current regulator allows
 
+  regulator-power-budget:
+    description: power budget of the regulator in mW
+
   regulator-always-on:
     description: boolean, regulator should never be disabled
     type: boolean

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 13/18] net: pse-pd: Add support for PSE power domains
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (11 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 12/18] regulator: dt-bindings: Add regulator-power-budget property Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 14/18] net: ethtool: Add support for new power domains index description Kory Maincent
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Introduce PSE power domain support in preparation for future port
priority features. Multiple PSE PIs are grouped under a PSE power
domain, which defines the available power budget. This setup allows
the system to check whether activating a port would exceed the
budget, helping prevent over-budget states.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Changes in v2:
- new patch.
---
 drivers/net/pse-pd/pse_core.c | 121 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/pse-pd/pse.h    |   2 +
 2 files changed, 123 insertions(+)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 712cb2d9c7c4..13f6ddcfca10 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -15,6 +15,7 @@
 static DEFINE_MUTEX(pse_list_mutex);
 static LIST_HEAD(pse_controller_list);
 static DEFINE_IDA(pse_ida);
+static DEFINE_XARRAY_ALLOC(pse_pw_d_map);
 
 /**
  * struct pse_control - a PSE control
@@ -35,6 +36,12 @@ struct pse_control {
 	struct phy_device *attached_phydev;
 };
 
+struct pse_power_domain {
+	int id;
+	struct regulator *supply;
+	int pw_budget;
+};
+
 static int of_load_single_pse_pi_pairset(struct device_node *node,
 					 struct pse_pi *pi,
 					 int pairset_num)
@@ -431,6 +438,115 @@ devm_pse_pi_regulator_register(struct pse_controller_dev *pcdev,
 	return 0;
 }
 
+static void pse_flush_pw_ds(struct pse_controller_dev *pcdev)
+{
+	struct pse_power_domain *pw_d;
+	int i;
+
+	for (i = 0; i < pcdev->nr_lines; i++) {
+		pw_d = xa_load(&pse_pw_d_map, pcdev->pi[i].pw_d->id);
+		if (pw_d) {
+			regulator_put(pw_d->supply);
+			xa_erase(&pse_pw_d_map, pw_d->id);
+		}
+	}
+}
+
+static struct pse_power_domain *devm_pse_alloc_pw_d(struct device *dev)
+{
+	struct pse_power_domain *pw_d;
+	int index, ret;
+
+	pw_d = devm_kzalloc(dev, sizeof(*pw_d), GFP_KERNEL);
+	if (!pw_d)
+		return ERR_PTR(-ENOMEM);
+
+	ret = xa_alloc(&pse_pw_d_map, &index, pw_d, xa_limit_31b, GFP_KERNEL);
+	if (ret)
+		return ERR_PTR(ret);
+
+	pw_d->id = index;
+	return pw_d;
+}
+
+static int pse_get_power_budget(struct regulator *supply)
+{
+	int ret, uV;
+	s64 tmp_64;
+
+	ret = regulator_get_voltage(supply);
+	if (ret < 0)
+		return ret;
+
+	uV = ret;
+	ret = regulator_get_power_budget(supply);
+	if (ret < 0)
+		return ret;
+
+	tmp_64 = ret;
+	tmp_64 *= uV;
+	/* mW = uV * uA / 1000000000 */
+	return DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);
+}
+
+static int pse_register_pw_ds(struct pse_controller_dev *pcdev)
+{
+	int i, ret;
+
+	for (i = 0; i < pcdev->nr_lines; i++) {
+		struct regulator_dev *rdev = pcdev->pi[i].rdev;
+		struct pse_power_domain *pw_d;
+		struct regulator *supply;
+		bool present = false;
+		unsigned long index;
+		int pw_budget;
+
+		/* No regulator or regulator parent supply registered.
+		 * We need a regulator parent to register a PSE power domain
+		 */
+		if (!rdev || !rdev->supply)
+			continue;
+
+		xa_for_each(&pse_pw_d_map, index, pw_d) {
+			/* Power supply already registered as a PSE power
+			 * domain.
+			 */
+			if (pw_d->supply == rdev->supply) {
+				present = true;
+				pcdev->pi[i].pw_d = pw_d;
+				break;
+			}
+		}
+		if (present)
+			break;
+
+		ret = pse_get_power_budget(rdev->supply);
+		if (ret < 0) {
+			dev_warn(pcdev->dev,
+				 "can't read power budget from PI %d, no power domain will be associated\n",
+				 i);
+			continue;
+		}
+		pw_budget = ret;
+
+		pw_d = devm_pse_alloc_pw_d(pcdev->dev);
+		if (IS_ERR_OR_NULL(pw_d))
+			return PTR_ERR(pw_d);
+
+		pw_d->pw_budget = pw_budget;
+		supply = regulator_get(pcdev->dev, rdev->supply_name);
+		if (IS_ERR(supply)) {
+			xa_erase(&pse_pw_d_map, pw_d->id);
+			return PTR_ERR(supply);
+		}
+
+		pw_d->supply = rdev->supply;
+		pcdev->pi[i].pw_d = pw_d;
+	}
+
+	return 0;
+}
+
 /**
  * pse_controller_register - register a PSE controller device
  * @pcdev: a pointer to the initialized PSE controller device
@@ -489,6 +605,10 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 			goto free_pse_ida;
 	}
 
+	ret = pse_register_pw_ds(pcdev);
+	if (ret)
+		goto free_pse_ida;
+
 	mutex_lock(&pse_list_mutex);
 	list_add(&pcdev->list, &pse_controller_list);
 	mutex_unlock(&pse_list_mutex);
@@ -508,6 +628,7 @@ EXPORT_SYMBOL_GPL(pse_controller_register);
 void pse_controller_unregister(struct pse_controller_dev *pcdev)
 {
 	pse_release_pis(pcdev);
+	pse_flush_pw_ds(pcdev);
 	ida_free(&pse_ida, pcdev->id);
 	mutex_lock(&pse_list_mutex);
 	list_del(&pcdev->list);
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index ce8737c2219a..3b35dc0f8dc3 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -138,12 +138,14 @@ struct pse_pi_pairset {
  * @np: device node pointer of the PSE PI node
  * @rdev: regulator represented by the PSE PI
  * @admin_state_enabled: PI enabled state
+ * @pw_d: Power domain of the PSE PI
  */
 struct pse_pi {
 	struct pse_pi_pairset pairset[2];
 	struct device_node *np;
 	struct regulator_dev *rdev;
 	bool admin_state_enabled;
+	struct pse_power_domain *pw_d;
 };
 
 /**

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 14/18] net: ethtool: Add support for new power domains index description
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (12 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 13/18] net: pse-pd: Add support for PSE power domains Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority Kory Maincent
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Report the index of the newly introduced PSE power domain to the user,
enabling improved management of the power budget for PSE devices.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Changes in v2:
- new patch.
---
 Documentation/networking/ethtool-netlink.rst | 4 ++++
 drivers/net/pse-pd/pse_core.c                | 1 +
 include/linux/pse-pd/pse.h                   | 2 ++
 include/uapi/linux/ethtool_netlink.h         | 1 +
 net/ethtool/pse-pd.c                         | 7 +++++++
 5 files changed, 15 insertions(+)

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index bd7173d1fa4d..3573543ae5ad 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1767,6 +1767,7 @@ Kernel response contents:
   ``ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES``       nested  Supported power limit
                                                       configuration ranges.
   ``ETHTOOL_A_PSE_ID``                           u32  Index of the PSE
+  ``ETHTOOL_A_PSE_PW_D_ID``                      u32  Index of the PSE power domain
   ==========================================  ======  =============================
 
 When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
@@ -1843,6 +1844,9 @@ equal.
 The ``ETHTOOL_A_PSE_ID`` attribute identifies the index of the PSE
 controller.
 
+The ``ETHTOOL_A_PSE_PW_D_ID`` attribute identifies the index of PSE power
+domain.
+
 PSE_SET
 =======
 
diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 13f6ddcfca10..29374b1ce378 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -1000,6 +1000,7 @@ static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
 	}
 
 	status->pse_id = pcdev->id;
+	status->pw_d_id = pcdev->pi[id].pw_d->id;
 	return ops->ethtool_get_status(pcdev, id, extack, status);
 }
 
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index 3b35dc0f8dc3..e275ef7e1eb0 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -40,6 +40,7 @@ struct pse_control_config {
  * struct pse_control_status - PSE control/channel status.
  *
  * @pse_id: index number of the PSE. Set by PSE core.
+ * @pw_d_id: PSE power domain index. Set by PSE core.
  * @podl_admin_state: operational state of the PoDL PSE
  *	functions. IEEE 802.3-2018 30.15.1.1.2 aPoDLPSEAdminState
  * @podl_pw_status: power detection status of the PoDL PSE.
@@ -62,6 +63,7 @@ struct pse_control_config {
  */
 struct pse_control_status {
 	u32 pse_id;
+	u32 pw_d_id;
 	enum ethtool_podl_pse_admin_state podl_admin_state;
 	enum ethtool_podl_pse_pw_d_status podl_pw_status;
 	enum ethtool_c33_pse_admin_state c33_admin_state;
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 526b8b099c0e..47784a165e8b 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -972,6 +972,7 @@ enum {
 	ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT,	/* u32 */
 	ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES,	/* nest - _C33_PSE_PW_LIMIT_* */
 	ETHTOOL_A_PSE_ID,			/* u32 */
+	ETHTOOL_A_PSE_PW_D_ID,			/* u32 */
 
 	/* add new constants above here */
 	__ETHTOOL_A_PSE_CNT,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 52df956db0ba..1288e8a2c3a7 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -84,6 +84,8 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,
 	int len = 0;
 
 	len += nla_total_size(sizeof(u32)); /* _PSE_ID */
+	if (st->pw_d_id > 0)
+		len += nla_total_size(sizeof(u32)); /* _PSE_PW_D_ID */
 	if (st->podl_admin_state > 0)
 		len += nla_total_size(sizeof(u32)); /* _PODL_PSE_ADMIN_STATE */
 	if (st->podl_pw_status > 0)
@@ -152,6 +154,11 @@ static int pse_fill_reply(struct sk_buff *skb,
 	if (nla_put_u32(skb, ETHTOOL_A_PSE_ID, st->pse_id))
 		return -EMSGSIZE;
 
+	if (st->pw_d_id > 0 &&
+	    nla_put_u32(skb, ETHTOOL_A_PSE_PW_D_ID,
+			st->pw_d_id))
+		return -EMSGSIZE;
+
 	if (st->podl_admin_state > 0 &&
 	    nla_put_u32(skb, ETHTOOL_A_PODL_PSE_ADMIN_STATE,
 			st->podl_admin_state))

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (13 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 14/18] net: ethtool: Add support for new power domains index description Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-31  6:54   ` Oleksij Rempel
  2024-10-30 16:53 ` [PATCH RFC net-next v2 16/18] net: ethtool: Add PSE new port priority support feature Kory Maincent
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

This patch introduces the ability to configure the PSE PI port priority.
Port priority is utilized by PSE controllers to determine which ports to
turn off first in scenarios such as power budget exceedance.

The pis_prio_max value is used to define the maximum priority level
supported by the controller. Both the current priority and the maximum
priority are exposed to the user through the pse_ethtool_get_status call.

This patch add support for two mode of port priority modes.
1. Static Method:

   This method involves distributing power based on PD classification.
   It’s straightforward and stable, the PSE core keeping track of the
   budget and subtracting the power requested by each PD’s class.

   Advantages: Every PD gets its promised power at any time, which
   guarantees reliability.

   Disadvantages: PD classification steps are large, meaning devices
   request much more power than they actually need. As a result, the power
   supply may only operate at, say, 50% capacity, which is inefficient and
   wastes money.

   Priority max value is matching the number of PSE PIs within the PSE.

2. Dynamic Method:

   To address the inefficiencies of the static method, vendors like
   Microchip have introduced dynamic power budgeting, as seen in the
   PD692x0 firmware. This method monitors the current consumption per port
   and subtracts it from the available power budget. When the budget is
   exceeded, lower-priority ports are shut down.

   Advantages: This method optimizes resource utilization, saving costs.

   Disadvantages: Low-priority devices may experience instability.

   Priority max value is set by the PSE controller driver.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v2:
- Rethink the port priority support.
---
 drivers/net/pse-pd/pse_core.c | 305 +++++++++++++++++++++++++++++++++++++++++-
 include/linux/pse-pd/pse.h    |  51 +++++++
 include/uapi/linux/ethtool.h  |  28 +++-
 3 files changed, 375 insertions(+), 9 deletions(-)

diff --git a/drivers/net/pse-pd/pse_core.c b/drivers/net/pse-pd/pse_core.c
index 29374b1ce378..25911083ff3b 100644
--- a/drivers/net/pse-pd/pse_core.c
+++ b/drivers/net/pse-pd/pse_core.c
@@ -229,6 +229,9 @@ static int pse_pi_is_enabled(struct regulator_dev *rdev)
 		return -EOPNOTSUPP;
 
 	id = rdev_get_id(rdev);
+	if (pcdev->port_prio_mode == ETHTOOL_PSE_PORT_PRIO_STATIC)
+		return pcdev->pi[id].pw_enabled;
+
 	mutex_lock(&pcdev->lock);
 	ret = ops->pi_is_enabled(pcdev, id);
 	mutex_unlock(&pcdev->lock);
@@ -248,6 +251,16 @@ static int pse_pi_enable(struct regulator_dev *rdev)
 
 	id = rdev_get_id(rdev);
 	mutex_lock(&pcdev->lock);
+	if (pcdev->port_prio_mode == ETHTOOL_PSE_PORT_PRIO_STATIC) {
+		/* Manage enabled status by software.
+		 * Real enable process will happen after a port connected
+		 * event.
+		 */
+		pcdev->pi[id].admin_state_enabled = 1;
+		mutex_unlock(&pcdev->lock);
+		return 0;
+	}
+
 	ret = ops->pi_enable(pcdev, id);
 	if (!ret)
 		pcdev->pi[id].admin_state_enabled = 1;
@@ -268,9 +281,12 @@ static int pse_pi_disable(struct regulator_dev *rdev)
 
 	id = rdev_get_id(rdev);
 	mutex_lock(&pcdev->lock);
+
 	ret = ops->pi_disable(pcdev, id);
-	if (!ret)
+	if (!ret) {
 		pcdev->pi[id].admin_state_enabled = 0;
+		pcdev->pi[id].pw_enabled = 0;
+	}
 	mutex_unlock(&pcdev->lock);
 
 	return ret;
@@ -564,6 +580,7 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
 	if (ret < 0)
 		return ret;
 	pcdev->id = ret;
+	pcdev->port_prio_supp_modes |= BIT(ETHTOOL_PSE_PORT_PRIO_DISABLED);
 
 	if (!pcdev->nr_lines)
 		pcdev->nr_lines = 1;
@@ -704,10 +721,166 @@ pse_control_find_phy_by_id(struct pse_controller_dev *pcdev, int id)
 			return psec->attached_phydev;
 	}
 	mutex_unlock(&pse_list_mutex);
-
 	return NULL;
 }
 
+static void pse_deallocate_pw_budget(struct pse_controller_dev *pcdev, int id)
+{
+	struct pse_power_domain *pw_d = pcdev->pi[id].pw_d;
+
+	if (!pw_d)
+		return;
+
+	pw_d->pw_budget += pcdev->pi[id].pw_allocated;
+}
+
+static int pse_pi_disable_isr(struct pse_controller_dev *pcdev, int id,
+			      struct netlink_ext_ack *extack)
+{
+	const struct pse_controller_ops *ops = pcdev->ops;
+	int ret;
+
+	if (!ops->pi_disable) {
+		NL_SET_ERR_MSG(extack, "PSE does not support disable control");
+		return -EOPNOTSUPP;
+	}
+
+	if (!pcdev->pi[id].admin_state_enabled ||
+	    !pcdev->pi[id].pw_enabled)
+		return 0;
+
+	ret = ops->pi_disable(pcdev, id);
+	if (ret) {
+		NL_SET_ERR_MSG_FMT(extack,
+				   "PI %d: disable error %d",
+				   id, ret);
+		return ret;
+	}
+
+	pse_deallocate_pw_budget(pcdev, id);
+	pcdev->pi[id].pw_enabled = 0;
+	return 0;
+}
+
+static int pse_disable_pis_prio(struct pse_controller_dev *pcdev, int prio)
+{
+	int i, ret;
+
+	for (i = 0; i < pcdev->nr_lines; i++) {
+		struct netlink_ext_ack extack = {};
+		struct phy_device *phydev;
+
+		if (pcdev->pi[i].prio != prio)
+			continue;
+
+		dev_dbg(pcdev->dev,
+			"Disabling PI %d to free power budget\n",
+			i);
+
+		NL_SET_ERR_MSG_FMT(&extack,
+				   "Disabling PI %d to free power budget",
+				   i);
+
+		ret = pse_pi_disable_isr(pcdev, i, &extack);
+		phydev = pse_control_find_phy_by_id(pcdev, i);
+		if (phydev)
+			ethnl_pse_send_ntf(phydev,
+					   ETHTOOL_C33_PSE_EVENT_DISCONNECTED,
+					   &extack);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int pse_allocate_pw_budget(struct pse_controller_dev *pcdev, int id,
+				  int pw_req, struct netlink_ext_ack *extack)
+{
+	struct pse_power_domain *pw_d = pcdev->pi[id].pw_d;
+	int ret, _prio;
+
+	if (!pw_d)
+		return 0;
+
+	_prio = pcdev->nr_lines;
+	while (pw_req > pw_d->pw_budget && _prio > pcdev->pi[id].prio) {
+		ret = pse_disable_pis_prio(pcdev, _prio--);
+		if (ret)
+			return ret;
+	}
+
+	if (pw_req > pw_d->pw_budget) {
+		NL_SET_ERR_MSG_FMT(extack,
+				   "PI %d: not enough power budget available",
+				   id);
+		return -ERANGE;
+	}
+
+	pw_d->pw_budget -= pw_req;
+	pcdev->pi[id].pw_allocated = pw_req;
+	return 0;
+}
+
+static int pse_pi_enable_isr(struct pse_controller_dev *pcdev, int id,
+			     struct netlink_ext_ack *extack)
+{
+	const struct pse_controller_ops *ops = pcdev->ops;
+	int ret, pw_req;
+
+	if (!ops->pi_enable || !ops->pi_get_pw_req) {
+		NL_SET_ERR_MSG(extack, "PSE does not support enable control");
+		return -EOPNOTSUPP;
+	}
+
+	if (!pcdev->pi[id].admin_state_enabled ||
+	    pcdev->pi[id].pw_enabled)
+		return 0;
+
+	ret = ops->pi_get_pw_req(pcdev, id);
+	if (ret < 0)
+		return ret;
+
+	pw_req = ret;
+	ret = pse_allocate_pw_budget(pcdev, id, pw_req, extack);
+	if (ret)
+		return ret;
+
+	ret = ops->pi_enable(pcdev, id);
+	if (ret) {
+		pse_deallocate_pw_budget(pcdev, id);
+		NL_SET_ERR_MSG_FMT(extack,
+				   "PI %d: enable error %d",
+				   id, ret);
+		return ret;
+	}
+
+	pcdev->pi[id].pw_enabled = 1;
+	return 0;
+}
+
+static int pse_set_config_isr(struct pse_controller_dev *pcdev, int id,
+			      unsigned long notifs,
+			      struct netlink_ext_ack *extack)
+{
+	int ret = 0;
+
+	if (notifs & ETHTOOL_C33_PSE_EVENT_CONNECTED &&
+	    notifs & ETHTOOL_C33_PSE_EVENT_DISCONNECTED) {
+		NL_SET_ERR_MSG_FMT(extack,
+				   "PI %d: error, connection and disconnection reported simultaneously",
+				   id);
+		return -EINVAL;
+	}
+
+	if (notifs & ETHTOOL_C33_PSE_EVENT_CONNECTED)
+		ret = pse_pi_enable_isr(pcdev, id, extack);
+	else if (notifs & ETHTOOL_C33_PSE_EVENT_DISCONNECTED)
+		ret = pse_pi_disable_isr(pcdev, id, extack);
+
+	return ret;
+}
+
 static irqreturn_t pse_notifier_isr(int irq, void *data)
 {
 	struct netlink_ext_ack extack = {};
@@ -724,7 +897,6 @@ static irqreturn_t pse_notifier_isr(int irq, void *data)
 	memset(h->notifs, 0, pcdev->nr_lines * sizeof(*h->notifs));
 	mutex_lock(&pcdev->lock);
 	ret = desc->map_event(irq, pcdev, h->notifs, &notifs_mask);
-	mutex_unlock(&pcdev->lock);
 	if (ret || !notifs_mask)
 		return IRQ_NONE;
 
@@ -737,6 +909,12 @@ static irqreturn_t pse_notifier_isr(int irq, void *data)
 			continue;
 
 		notifs = h->notifs[i];
+		if (pcdev->port_prio_mode == ETHTOOL_PSE_PORT_PRIO_STATIC) {
+			ret = pse_set_config_isr(pcdev, i, notifs, &extack);
+			if (ret)
+				notifs |= ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR;
+		}
+
 		dev_dbg(h->pcdev->dev,
 			"Sending PSE notification EVT 0x%lx\n", notifs);
 
@@ -748,6 +926,8 @@ static irqreturn_t pse_notifier_isr(int irq, void *data)
 					      NULL);
 	}
 
+	mutex_unlock(&pcdev->lock);
+
 	return IRQ_HANDLED;
 }
 
@@ -1001,6 +1181,20 @@ static int _pse_ethtool_get_status(struct pse_controller_dev *pcdev,
 
 	status->pse_id = pcdev->id;
 	status->pw_d_id = pcdev->pi[id].pw_d->id;
+	status->c33_prio_supp_modes = pcdev->port_prio_supp_modes;
+	status->c33_prio_mode = pcdev->port_prio_mode;
+	switch (pcdev->port_prio_mode) {
+	case ETHTOOL_PSE_PORT_PRIO_STATIC:
+		status->c33_prio_max = pcdev->nr_lines;
+		status->c33_prio = pcdev->pi[id].prio;
+		break;
+	case ETHTOOL_PSE_PORT_PRIO_DYNAMIC:
+		status->c33_prio_max = pcdev->pis_prio_max;
+		break;
+	default:
+		break;
+	}
+
 	return ops->ethtool_get_status(pcdev, id, extack, status);
 }
 
@@ -1038,11 +1232,12 @@ static int pse_ethtool_c33_set_config(struct pse_control *psec,
 	case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED:
 		/* We could have mismatch between admin_state_enabled and
 		 * state reported by regulator_is_enabled. This can occur when
-		 * the PI is forcibly turn off by the controller. Call
-		 * regulator_disable on that case to fix the counters state.
+		 * the PI is forcibly turn off by the controller or by the
+		 * interrupt context. Call regulator_disable on that case
+		 * to fix the counters state.
 		 */
-		if (psec->pcdev->pi[psec->id].admin_state_enabled &&
-		    !regulator_is_enabled(psec->ps)) {
+		if (!regulator_is_enabled(psec->ps) &&
+		    psec->pcdev->pi[psec->id].admin_state_enabled) {
 			err = regulator_disable(psec->ps);
 			if (err)
 				break;
@@ -1149,6 +1344,102 @@ int pse_ethtool_set_pw_limit(struct pse_control *psec,
 }
 EXPORT_SYMBOL_GPL(pse_ethtool_set_pw_limit);
 
+int pse_ethtool_set_prio(struct pse_control *psec,
+			 struct netlink_ext_ack *extack,
+			 unsigned int prio)
+{
+	struct pse_controller_dev *pcdev = psec->pcdev;
+	const struct pse_controller_ops *ops;
+	int ret = 0;
+
+	switch (pcdev->port_prio_mode) {
+	case ETHTOOL_PSE_PORT_PRIO_STATIC:
+		if (prio > pcdev->nr_lines) {
+			NL_SET_ERR_MSG_FMT(extack,
+					   "priority %d exceed priority max %d",
+					   prio, pcdev->nr_lines);
+			return -ERANGE;
+		}
+
+		/* We don't want priority change in the middle of an
+		 * enable/disable call
+		 */
+		mutex_lock(&pcdev->lock);
+		pcdev->pi[psec->id].prio = prio;
+		mutex_unlock(&pcdev->lock);
+		break;
+
+	case ETHTOOL_PSE_PORT_PRIO_DYNAMIC:
+		ops = psec->pcdev->ops;
+		if (!ops->pi_set_prio) {
+			NL_SET_ERR_MSG(extack,
+				       "pse driver does not support setting port priority");
+			return -EOPNOTSUPP;
+		}
+
+		if (prio > pcdev->pis_prio_max) {
+			NL_SET_ERR_MSG_FMT(extack,
+					   "priority %d exceed priority max %d",
+					   prio, pcdev->pis_prio_max);
+			return -ERANGE;
+		}
+
+		mutex_lock(&pcdev->lock);
+		ret = ops->pi_set_prio(pcdev, psec->id, prio);
+		mutex_unlock(&pcdev->lock);
+		break;
+
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pse_ethtool_set_prio);
+
+int pse_ethtool_set_prio_mode(struct pse_control *psec,
+			      struct netlink_ext_ack *extack,
+			      enum pse_port_prio_modes prio_mode)
+{
+	struct pse_controller_dev *pcdev = psec->pcdev;
+	const struct pse_controller_ops *ops;
+	int ret = 0, i;
+
+	if (!(BIT(prio_mode) & pcdev->port_prio_supp_modes)) {
+		NL_SET_ERR_MSG(extack, "priority mode not supported");
+		return -EOPNOTSUPP;
+	}
+
+	ops = psec->pcdev->ops;
+
+	/* We don't want priority mode change in the middle of an
+	 * enable/disable call
+	 */
+	mutex_lock(&pcdev->lock);
+	pcdev->port_prio_mode = prio_mode;
+
+	/* Reset all priorities */
+	for (i = 0; i < psec->pcdev->nr_lines; i++) {
+		/* PI not described */
+		if (!pcdev->pi[i].rdev)
+			continue;
+
+		pcdev->pi[i].prio = 0;
+
+		if (!ops->pi_set_prio)
+			continue;
+
+		if (pcdev->port_prio_supp_modes &
+		    BIT(ETHTOOL_PSE_PORT_PRIO_DYNAMIC))
+			ret = ops->pi_set_prio(pcdev, psec->id, 0);
+	}
+
+	mutex_unlock(&psec->pcdev->lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pse_ethtool_set_prio_mode);
+
 bool pse_has_podl(struct pse_control *psec)
 {
 	return psec->pcdev->types & ETHTOOL_PSE_PODL;
diff --git a/include/linux/pse-pd/pse.h b/include/linux/pse-pd/pse.h
index e275ef7e1eb0..653f9e3634bb 100644
--- a/include/linux/pse-pd/pse.h
+++ b/include/linux/pse-pd/pse.h
@@ -9,9 +9,12 @@
 #include <linux/list.h>
 #include <uapi/linux/ethtool.h>
 #include <linux/regulator/driver.h>
+#include <linux/workqueue.h>
 
 /* Maximum current in uA according to IEEE 802.3-2022 Table 145-1 */
 #define MAX_PI_CURRENT 1920000
+/* Maximum power in mW according to IEEE 802.3-2022 Table 145-16 */
+#define MAX_PI_PW 99900
 
 struct phy_device;
 struct pse_controller_dev;
@@ -60,6 +63,12 @@ struct pse_control_config {
  *	is in charge of the memory allocation.
  * @c33_pw_limit_nb_ranges: number of supported power limit configuration
  *	ranges
+ * @c33_prio_supp_modes: PSE port priority modes supported. Set by PSE core.
+ * @c33_prio_mode: PSE port priority mode selected. Set by PSE core.
+ * @c33_prio_max: max priority allowed for the c33_prio variable value. Set
+ *	by PSE core.
+ * @c33_prio: priority of the PSE. Set by PSE core in case of static port
+ *	priority mode.
  */
 struct pse_control_status {
 	u32 pse_id;
@@ -74,6 +83,10 @@ struct pse_control_status {
 	u32 c33_avail_pw_limit;
 	struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
 	u32 c33_pw_limit_nb_ranges;
+	u32 c33_prio_supp_modes;
+	enum pse_port_prio_modes c33_prio_mode;
+	u32 c33_prio_max;
+	u32 c33_prio;
 };
 
 /**
@@ -93,6 +106,8 @@ struct pse_control_status {
  *			  set_current_limit regulator callback.
  *			  Should not return an error in case of MAX_PI_CURRENT
  *			  current value set.
+ * @pi_set_prio: Configure the PSE PI priority.
+ * @pi_get_pw_req: Get the power requested by a PD before enabling the PSE PI
  */
 struct pse_controller_ops {
 	int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
@@ -107,6 +122,9 @@ struct pse_controller_ops {
 				    int id);
 	int (*pi_set_current_limit)(struct pse_controller_dev *pcdev,
 				    int id, int max_uA);
+	int (*pi_set_prio)(struct pse_controller_dev *pcdev, int id,
+			   unsigned int prio);
+	int (*pi_get_pw_req)(struct pse_controller_dev *pcdev, int id);
 };
 
 struct module;
@@ -141,6 +159,10 @@ struct pse_pi_pairset {
  * @rdev: regulator represented by the PSE PI
  * @admin_state_enabled: PI enabled state
  * @pw_d: Power domain of the PSE PI
+ * @prio: Priority of the PSE PI. Used in static port priority mode
+ * @pw_enabled: PSE PI power status in static port priority mode
+ * @pw_allocated: Power allocated to a PSE PI to manage power budget in
+ *	static port priority mode
  */
 struct pse_pi {
 	struct pse_pi_pairset pairset[2];
@@ -148,6 +170,9 @@ struct pse_pi {
 	struct regulator_dev *rdev;
 	bool admin_state_enabled;
 	struct pse_power_domain *pw_d;
+	int prio;
+	bool pw_enabled;
+	int pw_allocated;
 };
 
 /**
@@ -165,6 +190,9 @@ struct pse_pi {
  * @pi: table of PSE PIs described in this controller device
  * @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
  * @id: Index of the PSE
+ * @pis_prio_max: Maximum value allowed for the PSE PIs priority
+ * @port_prio_supp_modes: Bitfield of port priority mode supported by the PSE
+ * @port_prio_mode: Current port priority mode of the PSE
  */
 struct pse_controller_dev {
 	const struct pse_controller_ops *ops;
@@ -179,6 +207,9 @@ struct pse_controller_dev {
 	struct pse_pi *pi;
 	bool no_of_pse_pi;
 	int id;
+	unsigned int pis_prio_max;
+	u32 port_prio_supp_modes;
+	enum pse_port_prio_modes port_prio_mode;
 };
 
 #if IS_ENABLED(CONFIG_PSE_CONTROLLER)
@@ -203,6 +234,12 @@ int pse_ethtool_set_config(struct pse_control *psec,
 int pse_ethtool_set_pw_limit(struct pse_control *psec,
 			     struct netlink_ext_ack *extack,
 			     const unsigned int pw_limit);
+int pse_ethtool_set_prio(struct pse_control *psec,
+			 struct netlink_ext_ack *extack,
+			 unsigned int prio);
+int pse_ethtool_set_prio_mode(struct pse_control *psec,
+			      struct netlink_ext_ack *extack,
+			      enum pse_port_prio_modes prio_mode);
 
 bool pse_has_podl(struct pse_control *psec);
 bool pse_has_c33(struct pse_control *psec);
@@ -240,6 +277,20 @@ static inline int pse_ethtool_set_pw_limit(struct pse_control *psec,
 	return -EOPNOTSUPP;
 }
 
+static inline int pse_ethtool_set_prio(struct pse_control *psec,
+				       struct netlink_ext_ack *extack,
+				       unsigned int prio)
+{
+	return -EOPNOTSUPP;
+}
+
+static inline int pse_ethtool_set_prio_mode(struct pse_control *psec,
+					    struct netlink_ext_ack *extack,
+					    enum pse_port_prio_modes prio_mode)
+{
+	return -EOPNOTSUPP;
+}
+
 static inline bool pse_has_podl(struct pse_control *psec)
 {
 	return false;
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index a1ad257b1ec1..22664b1ea4a2 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1002,11 +1002,35 @@ enum ethtool_c33_pse_pw_d_status {
  * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
  * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
  * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
+ * @ETHTOOL_C33_PSE_EVENT_CONNECTED: PD detected on the PSE.
+ * @ETHTOOL_C33_PSE_EVENT_DISCONNECTED: PD has been disconnected on the PSE.
+ * @ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR: PSE faced an error in static
+ *	port priority management mode.
  */
 
 enum ethtool_c33_pse_events {
-	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
-	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
+	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =		1 << 0,
+	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =		1 << 1,
+	ETHTOOL_C33_PSE_EVENT_CONNECTED =		1 << 2,
+	ETHTOOL_C33_PSE_EVENT_DISCONNECTED =		1 << 3,
+	ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR =	1 << 4,
+};
+
+/**
+ * enum pse_port_prio_modes - PSE port priority modes.
+ * @ETHTOOL_PSE_PORT_PRIO_DISABLED: Port priority disabled.
+ * @ETHTOOL_PSE_PORT_PRIO_STATIC: PSE static port priority. Port priority
+ *	based on the power requested during PD classification. This mode
+ *	is managed by the PSE core.
+ * @ETHTOOL_PSE_PORT_PRIO_DYNAMIC: PSE dynamic port priority. Port priority
+ *	based on the current consumption per ports compared to the total
+ *	power budget. This mode is managed by the PSE controller.
+ */
+
+enum pse_port_prio_modes {
+	ETHTOOL_PSE_PORT_PRIO_DISABLED,
+	ETHTOOL_PSE_PORT_PRIO_STATIC,
+	ETHTOOL_PSE_PORT_PRIO_DYNAMIC,
 };
 
 /**

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 16/18] net: ethtool: Add PSE new port priority support feature
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (14 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 17/18] netlink: specs: Expand the PSE netlink command with newly supported features Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 18/18] net: pse-pd: pd692x0: Add support for PSE PI priority feature Kory Maincent
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

This patch expands the status information provided by ethtool for PSE c33
with current port priority and max port priority. It also adds a call to
pse_ethtool_set_prio() and pse_ethtool_set_prio_mode() to configure the PSE
port priority and its mode.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---

Change in v2:
- Improve port priority documentation.
- Add port priority modes.
---
 Documentation/networking/ethtool-netlink.rst | 63 ++++++++++++++++++++++++++++
 include/uapi/linux/ethtool_netlink.h         |  4 ++
 net/ethtool/pse-pd.c                         | 36 ++++++++++++++++
 3 files changed, 103 insertions(+)

diff --git a/Documentation/networking/ethtool-netlink.rst b/Documentation/networking/ethtool-netlink.rst
index 3573543ae5ad..5bb090455620 100644
--- a/Documentation/networking/ethtool-netlink.rst
+++ b/Documentation/networking/ethtool-netlink.rst
@@ -1768,6 +1768,13 @@ Kernel response contents:
                                                       configuration ranges.
   ``ETHTOOL_A_PSE_ID``                           u32  Index of the PSE
   ``ETHTOOL_A_PSE_PW_D_ID``                      u32  Index of the PSE power domain
+  ``ETHTOOL_A_C33_PSE_PRIO_SUPP_MODES``          u32  priority modes supported
+  ``ETHTOOL_A_C33_PSE_PRIO_MODE``                u32  priority mode of the PSE
+                                                      currently configured
+  ``ETHTOOL_A_C33_PSE_PRIO_MAX``                 u32  priority maximum configurable
+                                                      on the PoE PSE
+  ``ETHTOOL_A_C33_PSE_PRIO``                     u32  priority of the PoE PSE
+                                                      currently configured
   ==========================================  ======  =============================
 
 When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_STATE`` attribute identifies
@@ -1847,6 +1854,18 @@ controller.
 The ``ETHTOOL_A_PSE_PW_D_ID`` attribute identifies the index of PSE power
 domain.
 
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO_SUPP_MODES`` attribute
+identifies the priority mode supported by the C33 PSE.
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO_MODE`` attributes is used to
+identifies the currently configured C33 PSE priority mode.
+For a description of C33 PSE priority modes, see ``PSE_SET``.
+
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO_MAX`` attribute identifies
+the C33 PSE maximum priority value.
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO`` attributes is used to
+identifies the currently configured C33 PSE priority.
+For a description of C33 PSE priority attributes, see ``PSE_SET``.
+
 PSE_SET
 =======
 
@@ -1860,6 +1879,10 @@ Request contents:
   ``ETHTOOL_A_C33_PSE_ADMIN_CONTROL``        u32  Control PSE Admin state
   ``ETHTOOL_A_C33_PSE_AVAIL_PWR_LIMIT``      u32  Control PoE PSE available
                                                   power limit
+  ``ETHTOOL_A_C33_PSE_PRIO_MODE``            u32  Control priority mode of the
+                                                  PoE PSE
+  ``ETHTOOL_A_C33_PSE_PRIO``                 u32  Control priority of the
+                                                  PoE PSE
   ======================================  ======  =============================
 
 When set, the optional ``ETHTOOL_A_PODL_PSE_ADMIN_CONTROL`` attribute is used
@@ -1882,6 +1905,46 @@ various existing products that document power consumption in watts rather than
 classes. If power limit configuration based on classes is needed, the
 conversion can be done in user space, for example by ethtool.
 
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO_MODE`` attributes is used to
+control the C33 PSE priority mode. The available mode are:
+
+1. Static Method:
+
+   This method involves distributing power based on PD classification. It’s
+   straightforward and stable, with the PSE core keeping track of the budget
+   and subtracting the power requested by each PD’s class.
+
+   Advantages: Every PD gets its promised power at any time, which guarantees
+   reliability.
+
+   Disadvantages: PD classification steps are large, meaning devices request
+   much more power than they actually need. As a result, the power supply may
+   only operate at, say, 50% capacity, which is inefficient and wastes money.
+
+2. Dynamic Method:
+
+   This method monitors the current consumption per port and subtracts it from
+   the available power budget. When the budget is exceeded, lower-priority
+   ports are shut down. This method is managed by the PSE controller itself.
+
+   Advantages: This method optimizes resource utilization, saving costs.
+
+   Disadvantages: Low-priority devices may experience instability.
+
+When set, the optional ``ETHTOOL_A_C33_PSE_PRIO`` attributes is used to
+control the C33 PSE priority. Allowed priority value are between zero
+and the value of ``ETHTOOL_A_C33_PSE_PRIO_MAX`` attribute.
+
+A lower value indicates a higher priority, meaning that a priority value
+of 0 corresponds to the highest port priority.
+Port priority serves two functions:
+
+ - Power-up Order: After a reset, ports are powered up in order of their
+   priority from highest to lowest. Ports with higher priority
+   (lower values) power up first.
+ - Shutdown Order: When the power budget is exceeded, ports with lower
+   priority (higher values) are turned off first.
+
 RSS_GET
 =======
 
diff --git a/include/uapi/linux/ethtool_netlink.h b/include/uapi/linux/ethtool_netlink.h
index 47784a165e8b..aaeb8a6eecee 100644
--- a/include/uapi/linux/ethtool_netlink.h
+++ b/include/uapi/linux/ethtool_netlink.h
@@ -973,6 +973,10 @@ enum {
 	ETHTOOL_A_C33_PSE_PW_LIMIT_RANGES,	/* nest - _C33_PSE_PW_LIMIT_* */
 	ETHTOOL_A_PSE_ID,			/* u32 */
 	ETHTOOL_A_PSE_PW_D_ID,			/* u32 */
+	ETHTOOL_A_C33_PSE_PRIO_SUPP_MODES,	/* u32 */
+	ETHTOOL_A_C33_PSE_PRIO_MODE,		/* u32 */
+	ETHTOOL_A_C33_PSE_PRIO_MAX,		/* u32 */
+	ETHTOOL_A_C33_PSE_PRIO,			/* u32 */
 
 	/* add new constants above here */
 	__ETHTOOL_A_PSE_CNT,
diff --git a/net/ethtool/pse-pd.c b/net/ethtool/pse-pd.c
index 1288e8a2c3a7..13ba7534c833 100644
--- a/net/ethtool/pse-pd.c
+++ b/net/ethtool/pse-pd.c
@@ -112,6 +112,12 @@ static int pse_reply_size(const struct ethnl_req_info *req_base,
 		len += st->c33_pw_limit_nb_ranges *
 		       (nla_total_size(0) +
 			nla_total_size(sizeof(u32)) * 2);
+	if (st->c33_prio_mode)
+		/* _C33_PSE_PRIO_MODE */
+		len += nla_total_size(sizeof(u32));
+	if (st->c33_prio_max)
+		/* _C33_PSE_PRIO_MAX + _C33_PSE_PRIO */
+		len += nla_total_size(sizeof(u32)) * 2;
 
 	return len;
 }
@@ -209,6 +215,15 @@ static int pse_fill_reply(struct sk_buff *skb,
 	    pse_put_pw_limit_ranges(skb, st))
 		return -EMSGSIZE;
 
+	if (st->c33_prio_mode > 0 &&
+	    nla_put_u32(skb, ETHTOOL_A_C33_PSE_PRIO_MODE, st->c33_prio_mode))
+		return -EMSGSIZE;
+
+	if (st->c33_prio_max > 0 &&
+	    (nla_put_u32(skb, ETHTOOL_A_C33_PSE_PRIO_MAX, st->c33_prio_max) ||
+	     nla_put_u32(skb, ETHTOOL_A_C33_PSE_PRIO, st->c33_prio)))
+		return -EMSGSIZE;
+
 	return 0;
 }
 
@@ -230,6 +245,8 @@ const struct nla_policy ethnl_pse_set_policy[ETHTOOL_A_PSE_MAX + 1] = {
 		NLA_POLICY_RANGE(NLA_U32, ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED,
 				 ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED),
 	[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT] = { .type = NLA_U32 },
+	[ETHTOOL_A_C33_PSE_PRIO_MODE] = { .type = NLA_U32 },
+	[ETHTOOL_A_C33_PSE_PRIO] = { .type = NLA_U32 },
 };
 
 static int
@@ -278,6 +295,25 @@ ethnl_set_pse(struct ethnl_req_info *req_info, struct genl_info *info)
 	if (ret)
 		return ret;
 
+	if (tb[ETHTOOL_A_C33_PSE_PRIO_MODE]) {
+		unsigned int prio_mode;
+
+		prio_mode = nla_get_u32(tb[ETHTOOL_A_C33_PSE_PRIO_MODE]);
+		ret = pse_ethtool_set_prio_mode(phydev->psec, info->extack,
+						prio_mode);
+		if (ret)
+			return ret;
+	}
+
+	if (tb[ETHTOOL_A_C33_PSE_PRIO]) {
+		unsigned int prio;
+
+		prio = nla_get_u32(tb[ETHTOOL_A_C33_PSE_PRIO]);
+		ret = pse_ethtool_set_prio(phydev->psec, info->extack, prio);
+		if (ret)
+			return ret;
+	}
+
 	if (tb[ETHTOOL_A_C33_PSE_AVAIL_PW_LIMIT]) {
 		unsigned int pw_limit;
 

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 17/18] netlink: specs: Expand the PSE netlink command with newly supported features
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (15 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 16/18] net: ethtool: Add PSE new port priority support feature Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  2024-10-30 16:53 ` [PATCH RFC net-next v2 18/18] net: pse-pd: pd692x0: Add support for PSE PI priority feature Kory Maincent
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

Expand the c33 PSE attributes with PSE id, PSE power domain id, priority
and priority max to be able to set and get the PSE Power Interface
priority.

./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-get
             --json '{"header":{"dev-name":"eth1"}}'
{'c33-pse-actual-pw': 1700,
 'c33-pse-admin-state': 3,
 'c33-pse-avail-pw-limit': 97500,
 'c33-pse-prio': 2,
 'c33-pse-prio-max': 2,
 'c33-pse-pw-class': 4,
 'c33-pse-pw-d-status': 4,
 'c33-pse-pw-limit-ranges': [{'max': 18100, 'min': 15000},
                             {'max': 38000, 'min': 30000},
                             {'max': 65000, 'min': 60000},
                             {'max': 97500, 'min': 90000}],
 'header': {'dev-index': 5, 'dev-name': 'eth1'}}

./ynl/cli.py --spec netlink/specs/ethtool.yaml --no-schema --do pse-set
             --json '{"header":{"dev-name":"eth1"},
                      "c33-pse-prio":1}'
None

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 Documentation/netlink/specs/ethtool.yaml | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/Documentation/netlink/specs/ethtool.yaml b/Documentation/netlink/specs/ethtool.yaml
index 6983dea39976..5f5634acd24f 100644
--- a/Documentation/netlink/specs/ethtool.yaml
+++ b/Documentation/netlink/specs/ethtool.yaml
@@ -1025,6 +1025,30 @@ attribute-sets:
         type: nest
         multi-attr: true
         nested-attributes: c33-pse-pw-limit
+      -
+        name: pse-id
+        type: u32
+        name-prefix: ethtool-a-
+      -
+        name: pse-pw-d-id
+        type: u32
+        name-prefix: ethtool-a-
+      -
+        name: c33-pse-prio-supp-modes
+        type: u32
+        name-prefix: ethtool-a-
+      -
+        name: c33-pse-prio-mode
+        type: u32
+        name-prefix: ethtool-a-
+      -
+        name: c33-pse-prio-max
+        type: u32
+        name-prefix: ethtool-a-
+      -
+        name: c33-pse-prio
+        type: u32
+        name-prefix: ethtool-a-
   -
     name: rss
     attributes:
@@ -1793,6 +1817,12 @@ operations:
             - c33-pse-ext-substate
             - c33-pse-avail-pw-limit
             - c33-pse-pw-limit-ranges
+            - pse-id
+            - pse-pw-d-id
+            - c33-pse-prio-supp-modes
+            - c33-pse-prio-mode
+            - c33-pse-prio-max
+            - c33-pse-prio
       dump: *pse-get-op
     -
       name: pse-set
@@ -1807,6 +1837,7 @@ operations:
             - podl-pse-admin-control
             - c33-pse-admin-control
             - c33-pse-avail-pw-limit
+            - c33-pse-prio
     -
       name: rss-get
       doc: Get RSS params.

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* [PATCH RFC net-next v2 18/18] net: pse-pd: pd692x0: Add support for PSE PI priority feature
  2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
                   ` (16 preceding siblings ...)
  2024-10-30 16:53 ` [PATCH RFC net-next v2 17/18] netlink: specs: Expand the PSE netlink command with newly supported features Kory Maincent
@ 2024-10-30 16:53 ` Kory Maincent
  17 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 16:53 UTC (permalink / raw)
  To: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Mark Brown
  Cc: Thomas Petazzoni, linux-kernel, netdev, linux-doc, Kyle Swenson,
	Dent Project, kernel, Maxime Chevallier, Kory Maincent

From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>

This patch extends the PSE callbacks by adding support for the newly
introduced pi_set_prio() callback, enabling the configuration of PSE PI
priorities. The current port priority is now also included in the status
information returned to users.

Reviewed-by: Kyle Swenson <kyle.swenson@est.tech>
Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/pd692x0.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 0af7db80b2f8..018b6559049f 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -685,6 +685,8 @@ static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
 	if (ret < 0)
 		return ret;
 	status->c33_avail_pw_limit = ret;
+	/* PSE core priority start at 0 */
+	status->c33_prio = buf.data[2] - 1;
 
 	memset(&buf, 0, sizeof(buf));
 	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
@@ -1061,6 +1063,25 @@ static int pd692x0_pi_set_current_limit(struct pse_controller_dev *pcdev,
 	return pd692x0_sendrecv_msg(priv, &msg, &buf);
 }
 
+static int pd692x0_pi_set_prio(struct pse_controller_dev *pcdev, int id,
+			       unsigned int prio)
+{
+	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
+	struct pd692x0_msg msg, buf = {0};
+	int ret;
+
+	ret = pd692x0_fw_unavailable(priv);
+	if (ret)
+		return ret;
+
+	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
+	msg.sub[2] = id;
+	/* Controller priority from 1 to 3 */
+	msg.data[4] = prio + 1;
+
+	return pd692x0_sendrecv_msg(priv, &msg, &buf);
+}
+
 static const struct pse_controller_ops pd692x0_ops = {
 	.setup_pi_matrix = pd692x0_setup_pi_matrix,
 	.ethtool_get_status = pd692x0_ethtool_get_status,
@@ -1070,6 +1091,7 @@ static const struct pse_controller_ops pd692x0_ops = {
 	.pi_get_voltage = pd692x0_pi_get_voltage,
 	.pi_get_current_limit = pd692x0_pi_get_current_limit,
 	.pi_set_current_limit = pd692x0_pi_set_current_limit,
+	.pi_set_prio = pd692x0_pi_set_prio,
 };
 
 #define PD692X0_FW_LINE_MAX_SZ 0xff
@@ -1486,6 +1508,8 @@ static int pd692x0_i2c_probe(struct i2c_client *client)
 	priv->pcdev.ops = &pd692x0_ops;
 	priv->pcdev.dev = dev;
 	priv->pcdev.types = ETHTOOL_PSE_C33;
+	priv->pcdev.port_prio_supp_modes = BIT(ETHTOOL_PSE_PORT_PRIO_DYNAMIC);
+	priv->pcdev.pis_prio_max = 2;
 	ret = devm_pse_controller_register(dev, &priv->pcdev);
 	if (ret)
 		return dev_err_probe(dev, ret,

-- 
2.34.1


^ permalink raw reply related	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description
  2024-10-30 16:53 ` [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description Kory Maincent
@ 2024-10-30 17:03   ` Mark Brown
  2024-10-30 17:22     ` Kory Maincent
  0 siblings, 1 reply; 47+ messages in thread
From: Mark Brown @ 2024-10-30 17:03 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Thomas Petazzoni, linux-kernel,
	netdev, linux-doc, Kyle Swenson, Dent Project, kernel,
	Maxime Chevallier

[-- Attachment #1: Type: text/plain, Size: 674 bytes --]

On Wed, Oct 30, 2024 at 05:53:13PM +0100, Kory Maincent wrote:

> +/**
> + * regulator_get_power_budget - get regulator total power budget
> + * @regulator: regulator source
> + *
> + * Return: Power budget of the regulator in mW.
> + */
> +int regulator_get_power_budget(struct regulator *regulator)
> +{
> +	return regulator->rdev->constraints->pw_budget;
> +}

This is going to go badly with multiple consumers...

> +static inline int regulator_get_power_budget(struct regulator *regulator)
> +{
> +	return 0;
> +}

We should probably default to INT_MAX here and in the case where we do
have support, that way consumers will fail gracefully when no budget is
specified.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description
  2024-10-30 17:03   ` Mark Brown
@ 2024-10-30 17:22     ` Kory Maincent
  2024-10-30 17:31       ` Mark Brown
  0 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-10-30 17:22 UTC (permalink / raw)
  To: Mark Brown
  Cc: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Thomas Petazzoni, linux-kernel,
	netdev, linux-doc, Kyle Swenson, Dent Project, kernel,
	Maxime Chevallier

On Wed, 30 Oct 2024 17:03:06 +0000
Mark Brown <broonie@kernel.org> wrote:

> On Wed, Oct 30, 2024 at 05:53:13PM +0100, Kory Maincent wrote:
> 
> > +/**
> > + * regulator_get_power_budget - get regulator total power budget
> > + * @regulator: regulator source
> > + *
> > + * Return: Power budget of the regulator in mW.
> > + */
> > +int regulator_get_power_budget(struct regulator *regulator)
> > +{
> > +	return regulator->rdev->constraints->pw_budget;
> > +}  
> 
> This is going to go badly with multiple consumers...

On my series the available power budget of the PIs (which are consumers) is
managed in the PSE core in the PSE power domain (patch 13). We could move it
directly to regulator API.

> > +static inline int regulator_get_power_budget(struct regulator *regulator)
> > +{
> > +	return 0;
> > +}  
> 
> We should probably default to INT_MAX here and in the case where we do
> have support, that way consumers will fail gracefully when no budget is
> specified.

That's true. Thanks!

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description
  2024-10-30 17:22     ` Kory Maincent
@ 2024-10-30 17:31       ` Mark Brown
  0 siblings, 0 replies; 47+ messages in thread
From: Mark Brown @ 2024-10-30 17:31 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, Oleksij Rempel, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jonathan Corbet, Donald Hunter,
	Rob Herring, Andrew Lunn, Simon Horman, Heiner Kallweit,
	Russell King, Liam Girdwood, Thomas Petazzoni, linux-kernel,
	netdev, linux-doc, Kyle Swenson, Dent Project, kernel,
	Maxime Chevallier

[-- Attachment #1: Type: text/plain, Size: 636 bytes --]

On Wed, Oct 30, 2024 at 06:22:11PM +0100, Kory Maincent wrote:
> Mark Brown <broonie@kernel.org> wrote:
> > On Wed, Oct 30, 2024 at 05:53:13PM +0100, Kory Maincent wrote:

> > > +int regulator_get_power_budget(struct regulator *regulator)
> > > +{
> > > +	return regulator->rdev->constraints->pw_budget;
> > > +}  

> > This is going to go badly with multiple consumers...

> On my series the available power budget of the PIs (which are consumers) is
> managed in the PSE core in the PSE power domain (patch 13). We could move it
> directly to regulator API.

It feels like it's going to need joining up at some point.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
  2024-10-30 16:53 ` [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
@ 2024-10-31  6:18   ` Oleksij Rempel
  2024-10-31 21:11   ` Andrew Lunn
  1 sibling, 0 replies; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:18 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:05PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> This driver frequently follows a pattern where two registers are read or
> written in a single operation, followed by calculating the bit offset for
> a specific channel.
> 
> Introduce helpers to streamline this process and reduce code redundancy,
> making the codebase cleaner and more maintainable.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> ---

Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features
  2024-10-30 16:53 ` [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features Kory Maincent
@ 2024-10-31  6:20   ` Oleksij Rempel
  0 siblings, 0 replies; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:20 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:06PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Expand PSE callbacks to support the newly introduced
> pi_get/set_current_limit() and pi_get_voltage() functions. These callbacks
> allow for power limit configuration in the TPS23881 controller.
> 
> Additionally, the patch includes the detected class, the current power
> delivered and the power limit ranges in the status returned, providing more
> comprehensive PoE status reporting.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>

Acked-by: Oleksij Rempel <o.rempel@pengutronix.de>

Thank you!
-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index
  2024-10-30 16:53 ` [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index Kory Maincent
@ 2024-10-31  6:27   ` Oleksij Rempel
  2024-10-31 21:28     ` Andrew Lunn
  0 siblings, 1 reply; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:27 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:07PM +0100, Kory Maincent wrote:

...
>  /**
>   * struct pse_control - a PSE control
> @@ -440,18 +441,22 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
>  
>  	mutex_init(&pcdev->lock);
>  	INIT_LIST_HEAD(&pcdev->pse_control_head);
> +	ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);

s/INT_MAX/U32_MAX

...
>  struct pse_control_status {
> +	u32 pse_id;
>  	enum ethtool_podl_pse_admin_state podl_admin_state;
...
>  struct pse_controller_dev {
>  	const struct pse_controller_ops *ops;
> @@ -163,6 +166,7 @@ struct pse_controller_dev {
>  	enum ethtool_pse_types types;
>  	struct pse_pi *pi;
>  	bool no_of_pse_pi;
> +	int id;

        u32 id

It would be better to have one type for all variables.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description
  2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
@ 2024-10-31  6:28   ` Oleksij Rempel
  2024-10-31 21:29   ` Andrew Lunn
  2024-10-31 21:39   ` Andrew Lunn
  2 siblings, 0 replies; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:28 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:08PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Add functionality to report the newly introduced PSE device index to
> the user, enabling better identification and management of PSE devices.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>

Reviewed-by: Oleksij Rempel <o.rempel@pengutronix.de>

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
@ 2024-10-31  6:34   ` Oleksij Rempel
  2024-10-31 21:54   ` Andrew Lunn
  2024-10-31 22:00   ` Andrew Lunn
  2 siblings, 0 replies; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:34 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:10PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Add support for devm_pse_irq_helper() to register PSE interrupts. This aims
> to report events such as over-current or over-temperature conditions
> similarly to how the regulator API handles them but using a specific PSE
> ethtool netlink socket.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> ---
> 

> +/**
> + * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
> + * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
> + * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
> + */
> +
> +enum ethtool_c33_pse_events {
> +	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
> +	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
> +};
> +

> +/* PSE NOTIFY */
> +enum {
> +	ETHTOOL_A_PSE_NTF_UNSPEC,
> +	ETHTOOL_A_PSE_NTF_HEADER,	/* nest - ETHTOOL_A_HEADER_* */
> +	ETHTOOL_A_C33_PSE_NTF_EVENTS,	/* u32 */
> +
> +	__ETHTOOL_A_PSE_NTF_CNT,
> +	ETHTOOL_A_PSE_NTF_MAX = (__ETHTOOL_A_PSE_NTF_CNT - 1)
 

This types are not part of IEEE 802.3 - 2022 specification. It will be
better to remove C33 prefix.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-30 16:53 ` [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority Kory Maincent
@ 2024-10-31  6:54   ` Oleksij Rempel
  2024-10-31 11:11     ` Kory Maincent
  0 siblings, 1 reply; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31  6:54 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

>  struct pse_control_status {
>  	u32 pse_id;
> @@ -74,6 +83,10 @@ struct pse_control_status {
>  	u32 c33_avail_pw_limit;
>  	struct ethtool_c33_pse_pw_limit_range *c33_pw_limit_ranges;
>  	u32 c33_pw_limit_nb_ranges;
> +	u32 c33_prio_supp_modes;
> +	enum pse_port_prio_modes c33_prio_mode;
> +	u32 c33_prio_max;
> +	u32 c33_prio;
>  };
>  
>  /**
> @@ -93,6 +106,8 @@ struct pse_control_status {
>   *			  set_current_limit regulator callback.
>   *			  Should not return an error in case of MAX_PI_CURRENT
>   *			  current value set.
> + * @pi_set_prio: Configure the PSE PI priority.
> + * @pi_get_pw_req: Get the power requested by a PD before enabling the PSE PI
>   */
>  struct pse_controller_ops {
>  	int (*ethtool_get_status)(struct pse_controller_dev *pcdev,
> @@ -107,6 +122,9 @@ struct pse_controller_ops {
>  				    int id);
>  	int (*pi_set_current_limit)(struct pse_controller_dev *pcdev,
>  				    int id, int max_uA);
> +	int (*pi_set_prio)(struct pse_controller_dev *pcdev, int id,
> +			   unsigned int prio);
> +	int (*pi_get_pw_req)(struct pse_controller_dev *pcdev, int id);
>  };
>  
>  struct module;
> @@ -141,6 +159,10 @@ struct pse_pi_pairset {
>   * @rdev: regulator represented by the PSE PI
>   * @admin_state_enabled: PI enabled state
>   * @pw_d: Power domain of the PSE PI
> + * @prio: Priority of the PSE PI. Used in static port priority mode
> + * @pw_enabled: PSE PI power status in static port priority mode
> + * @pw_allocated: Power allocated to a PSE PI to manage power budget in
> + *	static port priority mode
>   */
>  struct pse_pi {
>  	struct pse_pi_pairset pairset[2];
> @@ -148,6 +170,9 @@ struct pse_pi {
>  	struct regulator_dev *rdev;
>  	bool admin_state_enabled;
>  	struct pse_power_domain *pw_d;
> +	int prio;
> +	bool pw_enabled;
> +	int pw_allocated;
>  };
>  
>  /**
> @@ -165,6 +190,9 @@ struct pse_pi {
>   * @pi: table of PSE PIs described in this controller device
>   * @no_of_pse_pi: flag set if the pse_pis devicetree node is not used
>   * @id: Index of the PSE
> + * @pis_prio_max: Maximum value allowed for the PSE PIs priority
> + * @port_prio_supp_modes: Bitfield of port priority mode supported by the PSE
> + * @port_prio_mode: Current port priority mode of the PSE
>   */
>  struct pse_controller_dev {
>  	const struct pse_controller_ops *ops;
> @@ -179,6 +207,9 @@ struct pse_controller_dev {
>  	struct pse_pi *pi;
>  	bool no_of_pse_pi;
>  	int id;
> +	unsigned int pis_prio_max;
> +	u32 port_prio_supp_modes;
> +	enum pse_port_prio_modes port_prio_mode;
>  };

> diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> index a1ad257b1ec1..22664b1ea4a2 100644
> --- a/include/uapi/linux/ethtool.h
> +++ b/include/uapi/linux/ethtool.h
> @@ -1002,11 +1002,35 @@ enum ethtool_c33_pse_pw_d_status {
>   * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
>   * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
>   * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
> + * @ETHTOOL_C33_PSE_EVENT_CONNECTED: PD detected on the PSE.
> + * @ETHTOOL_C33_PSE_EVENT_DISCONNECTED: PD has been disconnected on the PSE.
> + * @ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR: PSE faced an error in static
> + *	port priority management mode.
>   */
>  
>  enum ethtool_c33_pse_events {
> -	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
> -	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
> +	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =		1 << 0,
> +	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =		1 << 1,
> +	ETHTOOL_C33_PSE_EVENT_CONNECTED =		1 << 2,
> +	ETHTOOL_C33_PSE_EVENT_DISCONNECTED =		1 << 3,
> +	ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR =	1 << 4,
> +};

Same here, priority concept is not part of the spec, so the C33 prefix
should be removed.

> +
> +/**
> + * enum pse_port_prio_modes - PSE port priority modes.
> + * @ETHTOOL_PSE_PORT_PRIO_DISABLED: Port priority disabled.
> + * @ETHTOOL_PSE_PORT_PRIO_STATIC: PSE static port priority. Port priority
> + *	based on the power requested during PD classification. This mode
> + *	is managed by the PSE core.
> + * @ETHTOOL_PSE_PORT_PRIO_DYNAMIC: PSE dynamic port priority. Port priority
> + *	based on the current consumption per ports compared to the total
> + *	power budget. This mode is managed by the PSE controller.
> + */

This part will need some clarification about behavior with mixed port
configurations. Here is my proposal:

 * Expected behaviors in mixed port priority configurations:
 * - When ports are configured with a mix of disabled, static, and dynamic
 *   priority modes, the following behaviors are expected:
 *     - Ports with priority disabled (ETHTOOL_PSE_PORT_PRIO_DISABLED) are
 *       treated with lowest priority, receiving power only if the budget
 *       remains after static and dynamic ports have been served.
 *     - Static-priority ports are allocated power up to their requested
 *       levels during PD classification, provided the budget allows.
 *     - Dynamic-priority ports receive power based on real-time consumption,
 *       as monitored by the PSE controller, relative to the remaining budget
 *       after static ports.
 *
 * Handling scenarios where power budget is exceeded:
 * - Hot-plug behavior: If a new device is added that causes the total power
 *   demand to exceed the PSE budget, the newly added device is de-prioritized
 *   and shut down to maintain stability for previously connected devices.
 *   This behavior ensures that existing connections are not disrupted, though
 *   it may lead to inconsistent behavior if the device is disconnected and
 *   reconnected (hot-plugged).
 *
 * - Startup behavior (boot): When the system initializes with attached devices,
 *   the PSE allocates power based on a predefined order (e.g., by port index)
 *   until the budget is exhausted. Devices connected later in this order may
 *   not be enabled if they would exceed the power budget, resulting in consistent
 *   behavior during startup but potentially differing from runtime behavior
 *   (hot-plug).
 *
 * - Consistency challenge: These two scenarios—hot-plug vs. system boot—may lead
 *   to different handling of devices. During system boot, power is allocated
 *   sequentially, potentially leaving out high-priority devices added later due to
 *   a first-come-first-serve approach. In contrast, hot-plug behavior favors the
 *   status quo, maintaining stability for initially connected devices, which
 *   might not align with the system's prioritization policy.
 *

> +enum pse_port_prio_modes {
> +	ETHTOOL_PSE_PORT_PRIO_DISABLED,
> +	ETHTOOL_PSE_PORT_PRIO_STATIC,
> +	ETHTOOL_PSE_PORT_PRIO_DYNAMIC,
>  };
 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-31  6:54   ` Oleksij Rempel
@ 2024-10-31 11:11     ` Kory Maincent
  2024-10-31 17:32       ` Oleksij Rempel
  2024-11-01  8:31       ` Oleksij Rempel
  0 siblings, 2 replies; 47+ messages in thread
From: Kory Maincent @ 2024-10-31 11:11 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 07:54:08 +0100
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> > index a1ad257b1ec1..22664b1ea4a2 100644
> > --- a/include/uapi/linux/ethtool.h
> > +++ b/include/uapi/linux/ethtool.h
> > @@ -1002,11 +1002,35 @@ enum ethtool_c33_pse_pw_d_status {
> >   * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
> >   * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
> >   * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
> > + * @ETHTOOL_C33_PSE_EVENT_CONNECTED: PD detected on the PSE.
> > + * @ETHTOOL_C33_PSE_EVENT_DISCONNECTED: PD has been disconnected on the
> > PSE.
> > + * @ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR: PSE faced an error in
> > static
> > + *	port priority management mode.
> >   */
> >  
> >  enum ethtool_c33_pse_events {
> > -	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
> > -	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
> > +	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =		1 << 0,
> > +	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =		1 << 1,
> > +	ETHTOOL_C33_PSE_EVENT_CONNECTED =		1 << 2,
> > +	ETHTOOL_C33_PSE_EVENT_DISCONNECTED =		1 << 3,
> > +	ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR =	1 << 4,
> > +};  
> 
> Same here, priority concept is not part of the spec, so the C33 prefix
> should be removed.

Ack. So we assume PoDL could have the same interruption events.

> > +/**
> > + * enum pse_port_prio_modes - PSE port priority modes.
> > + * @ETHTOOL_PSE_PORT_PRIO_DISABLED: Port priority disabled.
> > + * @ETHTOOL_PSE_PORT_PRIO_STATIC: PSE static port priority. Port priority
> > + *	based on the power requested during PD classification. This mode
> > + *	is managed by the PSE core.
> > + * @ETHTOOL_PSE_PORT_PRIO_DYNAMIC: PSE dynamic port priority. Port priority
> > + *	based on the current consumption per ports compared to the total
> > + *	power budget. This mode is managed by the PSE controller.
> > + */  
> 
> This part will need some clarification about behavior with mixed port
> configurations. Here is my proposal:
> 
>  * Expected behaviors in mixed port priority configurations:
>  * - When ports are configured with a mix of disabled, static, and dynamic
>  *   priority modes, the following behaviors are expected:
>  *     - Ports with priority disabled (ETHTOOL_PSE_PORT_PRIO_DISABLED) are
>  *       treated with lowest priority, receiving power only if the budget
>  *       remains after static and dynamic ports have been served.
>  *     - Static-priority ports are allocated power up to their requested
>  *       levels during PD classification, provided the budget allows.
>  *     - Dynamic-priority ports receive power based on real-time consumption,
>  *       as monitored by the PSE controller, relative to the remaining budget
>  *       after static ports.

I was not thinking of supporting mixed configuration but indeed why not.
The thing is the Microchip PSE does not support static priority. I didn't find a
way to have only detection and classification enabled without auto activation.
Mixed priority could not be tested for now.

"Requested Power: The requested power of the logical port, related to the
requested class. In case of DSPD, it is the sum of the related class power for
each pair-set. The value is in steps of 0.1 W.
Assigned Class: The assigned classification depends on the requested class and
the available power. An 0xC value means that classification was not assigned
and power was not allocated to this port."

We could set the current limit to all unconnected ports if the budget limit goes
under 100W. This will add complexity as the PD692x0 can set current limit only
inside specific ranges. Maybe it is a bit too specific to Microchip.
Microchip PSE should only support dynamic mode.

>  *
>  * Handling scenarios where power budget is exceeded:
>  * - Hot-plug behavior: If a new device is added that causes the total power
>  *   demand to exceed the PSE budget, the newly added device is de-prioritized
>  *   and shut down to maintain stability for previously connected devices.
>  *   This behavior ensures that existing connections are not disrupted, though
>  *   it may lead to inconsistent behavior if the device is disconnected and
>  *   reconnected (hot-plugged).

Do we want this behavior even if the new device has an highest priority than
other previously connected devices?

>  * - Startup behavior (boot): When the system initializes with attached
> devices,
>  *   the PSE allocates power based on a predefined order (e.g., by port index)
>  *   until the budget is exhausted. Devices connected later in this order may
>  *   not be enabled if they would exceed the power budget, resulting in
> consistent
>  *   behavior during startup but potentially differing from runtime behavior
>  *   (hot-plug).
>  *
>  * - Consistency challenge: These two scenarios—hot-plug vs. system boot—may
> lead
>  *   to different handling of devices. During system boot, power is allocated
>  *   sequentially, potentially leaving out high-priority devices added later
> due to
>  *   a first-come-first-serve approach. In contrast, hot-plug behavior favors
> the
>  *   status quo, maintaining stability for initially connected devices, which
>  *   might not align with the system's prioritization policy.

This could be solve by the future support of persistent configuration. Indeed
the Microchip controller has a non-volatile memory to save the current
configuration (3.1.3) and we could hope future PSE controller could do
the same as there is indeed a consistency challenge.
This support will be added in a later patch series.

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-31 11:11     ` Kory Maincent
@ 2024-10-31 17:32       ` Oleksij Rempel
  2024-11-05 13:49         ` Kory Maincent
  2024-11-01  8:31       ` Oleksij Rempel
  1 sibling, 1 reply; 47+ messages in thread
From: Oleksij Rempel @ 2024-10-31 17:32 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, Oct 31, 2024 at 12:11:04PM +0100, Kory Maincent wrote:
> > This part will need some clarification about behavior with mixed port
> > configurations. Here is my proposal:
> > 
> >  * Expected behaviors in mixed port priority configurations:
> >  * - When ports are configured with a mix of disabled, static, and dynamic
> >  *   priority modes, the following behaviors are expected:
> >  *     - Ports with priority disabled (ETHTOOL_PSE_PORT_PRIO_DISABLED) are
> >  *       treated with lowest priority, receiving power only if the budget
> >  *       remains after static and dynamic ports have been served.
> >  *     - Static-priority ports are allocated power up to their requested
> >  *       levels during PD classification, provided the budget allows.
> >  *     - Dynamic-priority ports receive power based on real-time consumption,
> >  *       as monitored by the PSE controller, relative to the remaining budget
> >  *       after static ports.
> 
> I was not thinking of supporting mixed configuration but indeed why not.
> The thing is the Microchip PSE does not support static priority. I didn't find a
> way to have only detection and classification enabled without auto activation.
> Mixed priority could not be tested for now.

No, problem.

> "Requested Power: The requested power of the logical port, related to the
> requested class. In case of DSPD, it is the sum of the related class power for
> each pair-set. The value is in steps of 0.1 W.
> Assigned Class: The assigned classification depends on the requested class and
> the available power. An 0xC value means that classification was not assigned
> and power was not allocated to this port."
> 
> We could set the current limit to all unconnected ports if the budget limit goes
> under 100W. This will add complexity as the PD692x0 can set current limit only
> inside specific ranges. Maybe it is a bit too specific to Microchip.
> Microchip PSE should only support dynamic mode.

No need to fake it right now, you came up with nice idea to have
"configurable" method, wich in case of PD692x0 is only a single build in
method. Since user space will be ably to see available and used
prioritization methods - i'm happy with it.

> >  *
> >  * Handling scenarios where power budget is exceeded:
> >  * - Hot-plug behavior: If a new device is added that causes the total power
> >  *   demand to exceed the PSE budget, the newly added device is de-prioritized
> >  *   and shut down to maintain stability for previously connected devices.
> >  *   This behavior ensures that existing connections are not disrupted, though
> >  *   it may lead to inconsistent behavior if the device is disconnected and
> >  *   reconnected (hot-plugged).
> 
> Do we want this behavior even if the new device has an highest priority than
> other previously connected devices?

Huh... good question. I assume, if we go with policy in kernel, then it
is ok to implement just some one. But, I assume, we will need this kind of
interface soon or later: 

Warning! this is discussion, i'm in process of understanding :D

/**
 * enum pse_disconnection_policy - Disconnection strategies for same-priority
 *   devices when power budget is exceeded, tailored to specific priority modes.
 *
 * Each device can have multiple disconnection policies set as an array of
 * priorities. When the power budget is exceeded, the policies are executed
 * in the order defined by the user. This allows for a more nuanced and 
 * flexible approach to handling power constraints across a range of devices
 * with similar priorities or attributes.
 *
 * Example Usage:
 *   - Users can specify an ordered list of policies, such as starting with
 *     `PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST` to prioritize based on class,
 *     followed by `PSE_DISCON_LRC` to break ties based on connection time.
 *     This ordered execution ensures that power disconnections align closely
 *     with the system’s operational requirements and priorities.
 *
 * @PSE_DISCON_LRC: Disconnect least recently connected device.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: When multiple devices share the same priority level, the
 *     system disconnects the device that was most recently connected.
 *   - Rationale: This strategy favors stability for longer-standing connections,
 *     assuming that established devices may be more critical.
 *   - Use Case: Suitable for systems prioritizing stable power allocation for
 *     existing static-priority connections, making newer devices suitable
 *     candidates for disconnection if limits are exceeded.

 * @PSE_DISCON_ROUND_ROBIN_IDX_LOWEST_FIRST: Disconnect based on port index in a 
 *   round-robin manner, starting with the lowest index.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: Disconnects devices sequentially based on port index, starting
 *     with the lowest. If multiple disconnections are required, the process
 *     continues in ascending order.
 *   - Rationale: Provides a predictable, systematic approach for static-priority
 *     devices, making it clear which device will be disconnected next if power
 *     limits are reached.
 *   - Use Case: Appropriate for systems where static-priority devices are equal
 *     in role, and fairness in disconnections is prioritized.

 * @PSE_DISCON_ROUND_ROBIN_IDX_HIGHEST_FIRST: Disconnect based on port index in a 
 *   round-robin manner, starting with the highest index.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: Disconnects devices sequentially based on port index, starting
 *     with the highest. If multiple disconnections are required, the process
 *     continues in descending order.
 *   - Rationale: Provides a predictable, systematic approach for static-priority
 *     devices, prioritizing disconnection from the highest port number downwards.
 *   - Use Case: Suitable for scenarios where higher port numbers are less critical,
 *     or where devices connected to higher ports can be sacrificed first.

 * @PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST: Disconnect based on static allocation
 *   class, disconnecting higher-class devices first.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: Disconnects devices in order of their assigned power class,
 *     with higher-class devices being disconnected first.
 *   - Rationale: This strategy can be useful in scenarios where the goal is to
 *     preserve lower-class devices for minimal essential services, possibly
 *     sacrificing higher-class, power-intensive devices.
 *   - Use Case: Fits scenarios where power classes represent power-hungry or
 *     non-essential devices, allowing essential services to continue under
 *     constrained power conditions.

 * @PSE_DISCON_STATIC_CLASS_LOWEST_FIRST: Disconnect based on static allocation
 *   class, disconnecting lower-class devices first.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: Disconnects devices in order of their assigned power class,
 *     with lower-class devices being disconnected first.
 *   - Rationale: Ensures that higher-class, more critical devices retain power
 *     during constrained conditions.
 *   - Use Case: Fits scenarios where power classes represent priority, allowing
 *     the system to maintain higher-class static devices under constrained
 *     conditions.

 * @PSE_DISCON_STATIC_CLASS_BUDGET_MATCH: Disconnect based on static allocation
 *   class, targeting devices that release enough allocated power to meet the
 *   current power requirement.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
 *   - Behavior: Searches for the lowest-priority device that can release
 *     sufficient allocated power to meet the current budget requirement.
 *     Ensures that disconnection occurs only when enough power is freed.
 *   - Rationale: This strategy is useful when the goal is to balance power
 *     budget requirements while minimizing the number of disconnected devices.
 *     It ensures that the system does not needlessly disconnect multiple
 *     devices if a single disconnection is sufficient to meet the power needs.
 *   - Use Case: Ideal for systems where precise power budget management is
 *     necessary, and disconnections must be efficient in terms of freeing
 *     enough power with minimal impact on the system.

 * @PSE_DISCON_LOWEST_AVG_POWER: Disconnect device with the lowest average
 *   power draw, minimizing impact on dynamic power allocation.
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
 *   - Behavior: Among devices with the same priority level, the system
 *     disconnects the device with the lowest average power draw.
 *   - If multiple devices have the same average power draw and priority,
 *     further tie-breaking mechanisms can be applied, such as disconnecting
 *     the least recently connected device.
 *   - Rationale: Minimizes disruption across dynamic devices, keeping as many
 *     active as possible by removing the lowest-power ones.
 *   - Use Case: Suitable for dynamic-priority systems where maximizing the
 *     number of connected devices is more important than individual device
 *     power requirements.

 * @PSE_DISCON_LONGEST_IDLE: Disconnect device with the longest idle time
 *   (low or no recent active power usage).
 *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
 *   - Behavior: Disconnects the device with the longest period of inactivity,
 *     where "idle" is defined as low current draw or absence of recent data
 *     transmission.
 *   - If multiple devices have the same idle time and priority, a tie-breaking
 *     mechanism, such as round-robin based on port index, can be used.
 *   - Rationale: Optimizes resource allocation in dynamic-priority setups by
 *     maintaining active devices while deprioritizing those with minimal
 *     recent usage.
 *   - Use Case: Ideal for dynamic environments, like sensor networks, where
 *     devices may be intermittently active and can be deprioritized during
 *     idle periods.
 *
 * These disconnection policies provide flexibility in handling cases where
 * multiple devices with the same priority exceed the PSE budget, aligning
 * with either static or dynamic port priority modes:
 *   - `ETHTOOL_PSE_PORT_PRIO_STATIC` benefits from policies that maintain
 *     stable power allocation, favoring longer-standing or higher-class
 *     devices (e.g., `PSE_DISCON_LRC`, `PSE_DISCON_ROUND_ROBIN_IDX`,
 *     `PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST`, `PSE_DISCON_STATIC_CLASS_LOWEST_FIRST`,
 *     `PSE_DISCON_STATIC_CLASS_BUDGET_MATCH`).
 *   - `ETHTOOL_PSE_PORT_PRIO_DYNAMIC` supports policies that dynamically
 *     adjust based on real-time metrics (e.g., `PSE_DISCON_LOWEST_AVG_POWER`,
 *     `PSE_DISCON_LONGEST_IDLE`), ideal for setups where usage fluctuates
 *     frequently.
 *   - Users can define an ordered array of disconnection policies, allowing
 *     the system to apply each policy in sequence, providing nuanced control
 *     over how power disconnections are handled.
 */

PD692x0 seems to use @PSE_DISCON_ROUND_ROBIN_IDX_HIGHEST_FIRST disconnection
policy.

ETHTOOL_PSE_PORT_PRIO_DYNAMIC and ETHTOOL_PSE_PORT_PRIO_STATIC seems to be the
source of information which should be used to trigger the disconnection policy.
Correct?

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
  2024-10-30 16:53 ` [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
  2024-10-31  6:18   ` Oleksij Rempel
@ 2024-10-31 21:11   ` Andrew Lunn
  2024-11-07 10:47     ` Kory Maincent
  1 sibling, 1 reply; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:11 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

> +	val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
> +		val = tps23881_set_val(val, chan, 0, BIT(chan % 4),
> +				       BIT(chan % 4));
> +	val = tps23881_set_val(ret, chan, 4, BIT(chan % 4), BIT(chan % 4));
> +		val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
> +				       BIT(chan % 4));
> +	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> +		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> +	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> +	val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
> +		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> +		val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));

It looks like all the callers of this helper pass BIT(chan % 4) as the
last parameter. Maybe move that into the helper as well?

     Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index
  2024-10-31  6:27   ` Oleksij Rempel
@ 2024-10-31 21:28     ` Andrew Lunn
  2024-11-05  9:33       ` Kory Maincent
  0 siblings, 1 reply; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:28 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Kory Maincent, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, Oct 31, 2024 at 07:27:59AM +0100, Oleksij Rempel wrote:
> On Wed, Oct 30, 2024 at 05:53:07PM +0100, Kory Maincent wrote:
> 
> ...
> >  /**
> >   * struct pse_control - a PSE control
> > @@ -440,18 +441,22 @@ int pse_controller_register(struct pse_controller_dev *pcdev)
> >  
> >  	mutex_init(&pcdev->lock);
> >  	INIT_LIST_HEAD(&pcdev->pse_control_head);
> > +	ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);
> 
> s/INT_MAX/U32_MAX

 * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
 * or %-ENOSPC if there are no free IDs.

static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)

We need to be careful here, at least theoretically. Assuming a 32 bit
system, and you pass it U32_MAX, how does it return values in the
range S32_MAX..U32_MAX when it also needs to be able to return
negative numbers as errors?

I think the correct value to pass is S32_MAX, because it will always
fit in a u32, and there is space left for negative values for errors.

But this is probably theoretical, no real system should have that many
controllers.

	Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description
  2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
  2024-10-31  6:28   ` Oleksij Rempel
@ 2024-10-31 21:29   ` Andrew Lunn
  2024-10-31 21:39   ` Andrew Lunn
  2 siblings, 0 replies; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:29 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:08PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Add functionality to report the newly introduced PSE device index to
> the user, enabling better identification and management of PSE devices.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description
  2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
  2024-10-31  6:28   ` Oleksij Rempel
  2024-10-31 21:29   ` Andrew Lunn
@ 2024-10-31 21:39   ` Andrew Lunn
  2 siblings, 0 replies; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:39 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:08PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Add functionality to report the newly introduced PSE device index to
> the user, enabling better identification and management of PSE devices.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function
  2024-10-30 16:53 ` [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function Kory Maincent
@ 2024-10-31 21:44   ` Andrew Lunn
  2024-11-05  9:37     ` Kory Maincent
  0 siblings, 1 reply; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:44 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Wed, Oct 30, 2024 at 05:53:09PM +0100, Kory Maincent wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> Introduce support for the ethnl_info_init_ntf helper function to enable
> initialization of ethtool notifications outside of the netlink.c file.
> This change allows for more flexible notification handling.
> 
> Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> ---
> 
> changes in v2:
> - new patch.
> ---
>  net/ethtool/netlink.c | 5 +++++
>  net/ethtool/netlink.h | 2 ++
>  2 files changed, 7 insertions(+)
> 
> diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
> index e3f0ef6b851b..808cc8096f93 100644
> --- a/net/ethtool/netlink.c
> +++ b/net/ethtool/netlink.c
> @@ -805,6 +805,11 @@ static void ethnl_default_notify(struct net_device *dev, unsigned int cmd,
>  typedef void (*ethnl_notify_handler_t)(struct net_device *dev, unsigned int cmd,
>  				       const void *data);
>  
> +void ethnl_info_init_ntf(struct genl_info *info, u8 cmd)
> +{
> +	genl_info_init_ntf(info, &ethtool_genl_family, cmd);
> +}
> +

I've not looked at the users yet. Does this need EXPORT_SYMBOL_GPL()?

	Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
  2024-10-31  6:34   ` Oleksij Rempel
@ 2024-10-31 21:54   ` Andrew Lunn
  2024-11-05  9:48     ` Kory Maincent
  2024-10-31 22:00   ` Andrew Lunn
  2 siblings, 1 reply; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 21:54 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

> +static struct phy_device *
> +pse_control_find_phy_by_id(struct pse_controller_dev *pcdev, int id)
> +{
> +	struct pse_control *psec;
> +
> +	mutex_lock(&pse_list_mutex);
> +	list_for_each_entry(psec, &pcdev->pse_control_head, list) {
> +		if (psec->id == id)
> +			return psec->attached_phydev;

The mutex is still locked. I'm surprised your testing did not
deadlock, and that none of the automated tools have reported this.


    Andrew

---
pw-bot: cr

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
  2024-10-31  6:34   ` Oleksij Rempel
  2024-10-31 21:54   ` Andrew Lunn
@ 2024-10-31 22:00   ` Andrew Lunn
  2024-11-05  9:41     ` Kory Maincent
  2 siblings, 1 reply; 47+ messages in thread
From: Andrew Lunn @ 2024-10-31 22:00 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

> +static unsigned long pse_to_regulator_notifs(unsigned long notifs)
> +{
> +	switch (notifs) {
> +	case ETHTOOL_C33_PSE_EVENT_OVER_CURRENT:
> +		return REGULATOR_EVENT_OVER_CURRENT;
> +	case ETHTOOL_C33_PSE_EVENT_OVER_TEMP:
> +		return REGULATOR_EVENT_OVER_TEMP;
> +	}
> +	return 0;
> +}


https://elixir.bootlin.com/linux/v6.11.5/source/include/uapi/regulator/regulator.h#L36

 * NOTE: These events can be OR'ed together when passed into handler.

ETHTOOL_C33_PSE_EVENT_OVER_* are also bits which could be OR'ed
together, so is this function correct?

	Andrew

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-31 11:11     ` Kory Maincent
  2024-10-31 17:32       ` Oleksij Rempel
@ 2024-11-01  8:31       ` Oleksij Rempel
  2024-11-01 10:23         ` Oleksij Rempel
  1 sibling, 1 reply; 47+ messages in thread
From: Oleksij Rempel @ 2024-11-01  8:31 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, Oct 31, 2024 at 12:11:04PM +0100, Kory Maincent wrote:
> On Thu, 31 Oct 2024 07:54:08 +0100
> Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> 
> > > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> > > index a1ad257b1ec1..22664b1ea4a2 100644
> > > --- a/include/uapi/linux/ethtool.h
> > > +++ b/include/uapi/linux/ethtool.h
> > > @@ -1002,11 +1002,35 @@ enum ethtool_c33_pse_pw_d_status {
> > >   * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
> > >   * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
> > >   * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
> > > + * @ETHTOOL_C33_PSE_EVENT_CONNECTED: PD detected on the PSE.
> > > + * @ETHTOOL_C33_PSE_EVENT_DISCONNECTED: PD has been disconnected on the
> > > PSE.
> > > + * @ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR: PSE faced an error in
> > > static
> > > + *	port priority management mode.
> > >   */
> > >  
> > >  enum ethtool_c33_pse_events {
> > > -	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
> > > -	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
> > > +	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =		1 << 0,
> > > +	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =		1 << 1,
> > > +	ETHTOOL_C33_PSE_EVENT_CONNECTED =		1 << 2,
> > > +	ETHTOOL_C33_PSE_EVENT_DISCONNECTED =		1 << 3,
> > > +	ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR =	1 << 4,
> > > +};  
> > 
> > Same here, priority concept is not part of the spec, so the C33 prefix
> > should be removed.
> 
> Ack. So we assume PoDL could have the same interruption events.
> 
> > > +/**
> > > + * enum pse_port_prio_modes - PSE port priority modes.
> > > + * @ETHTOOL_PSE_PORT_PRIO_DISABLED: Port priority disabled.
> > > + * @ETHTOOL_PSE_PORT_PRIO_STATIC: PSE static port priority. Port priority
> > > + *	based on the power requested during PD classification. This mode
> > > + *	is managed by the PSE core.
> > > + * @ETHTOOL_PSE_PORT_PRIO_DYNAMIC: PSE dynamic port priority. Port priority
> > > + *	based on the current consumption per ports compared to the total
> > > + *	power budget. This mode is managed by the PSE controller.
> > > + */  

After thinking about it more overnight, I wanted to revisit the idea of having
a priority strategy per port. Right now, if one port is set to static or
dynamic mode, all disabled ports seem to have to follow it somehow too. This
makes it feel like we should have a strategy for the whole power domain, not
just for each port.

I'm having trouble imagining how a per-port priority strategy would work in
this setup.

Another point that came to mind is that we might have two different components
here, and we need to keep these two parts separate in follow-up discussions:

- **Budget Evaluation Strategy**: The static approach seems straightforward—if
a class requests more than available, appropriate actions are taken. However,
the dynamic approach has more complexity, such as determining the threshold,
how long violations can be tolerated, and whether a safety margin should be
maintained before exceeding maximum load.

- **Disconnection Policy**: Once a budget violation is detected, this decides
how to react, like which ports should be disconnected and in what order.

Would it make more sense to have a unified strategy for power domains, where we
apply the same budget evaluation mode (static or dynamic) and disconnection
policy to all ports in that domain? This could make the configuration simpler
and the power management more predictable.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-11-01  8:31       ` Oleksij Rempel
@ 2024-11-01 10:23         ` Oleksij Rempel
  2024-11-05 10:20           ` Kory Maincent
  0 siblings, 1 reply; 47+ messages in thread
From: Oleksij Rempel @ 2024-11-01 10:23 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Fri, Nov 01, 2024 at 09:31:43AM +0100, Oleksij Rempel wrote:
> On Thu, Oct 31, 2024 at 12:11:04PM +0100, Kory Maincent wrote:
> > On Thu, 31 Oct 2024 07:54:08 +0100
> > Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> > 
> > > > diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
> > > > index a1ad257b1ec1..22664b1ea4a2 100644
> > > > --- a/include/uapi/linux/ethtool.h
> > > > +++ b/include/uapi/linux/ethtool.h
> > > > @@ -1002,11 +1002,35 @@ enum ethtool_c33_pse_pw_d_status {
> > > >   * enum ethtool_c33_pse_events - event list of the C33 PSE controller.
> > > >   * @ETHTOOL_C33_PSE_EVENT_OVER_CURRENT: PSE output current is too high.
> > > >   * @ETHTOOL_C33_PSE_EVENT_OVER_TEMP: PSE in over temperature state.
> > > > + * @ETHTOOL_C33_PSE_EVENT_CONNECTED: PD detected on the PSE.
> > > > + * @ETHTOOL_C33_PSE_EVENT_DISCONNECTED: PD has been disconnected on the
> > > > PSE.
> > > > + * @ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR: PSE faced an error in
> > > > static
> > > > + *	port priority management mode.
> > > >   */
> > > >  
> > > >  enum ethtool_c33_pse_events {
> > > > -	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =	1 << 0,
> > > > -	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =	1 << 1,
> > > > +	ETHTOOL_C33_PSE_EVENT_OVER_CURRENT =		1 << 0,
> > > > +	ETHTOOL_C33_PSE_EVENT_OVER_TEMP =		1 << 1,
> > > > +	ETHTOOL_C33_PSE_EVENT_CONNECTED =		1 << 2,
> > > > +	ETHTOOL_C33_PSE_EVENT_DISCONNECTED =		1 << 3,
> > > > +	ETHTOOL_C33_PSE_EVENT_PORT_PRIO_STATIC_ERROR =	1 << 4,
> > > > +};  
> > > 
> > > Same here, priority concept is not part of the spec, so the C33 prefix
> > > should be removed.
> > 
> > Ack. So we assume PoDL could have the same interruption events.
> > 
> > > > +/**
> > > > + * enum pse_port_prio_modes - PSE port priority modes.
> > > > + * @ETHTOOL_PSE_PORT_PRIO_DISABLED: Port priority disabled.
> > > > + * @ETHTOOL_PSE_PORT_PRIO_STATIC: PSE static port priority. Port priority
> > > > + *	based on the power requested during PD classification. This mode
> > > > + *	is managed by the PSE core.
> > > > + * @ETHTOOL_PSE_PORT_PRIO_DYNAMIC: PSE dynamic port priority. Port priority
> > > > + *	based on the current consumption per ports compared to the total
> > > > + *	power budget. This mode is managed by the PSE controller.
> > > > + */  
> 
> After thinking about it more overnight, I wanted to revisit the idea of having
> a priority strategy per port. Right now, if one port is set to static or
> dynamic mode, all disabled ports seem to have to follow it somehow too. This
> makes it feel like we should have a strategy for the whole power domain, not
> just for each port.
> 
> I'm having trouble imagining how a per-port priority strategy would work in
> this setup.
> 
> Another point that came to mind is that we might have two different components
> here, and we need to keep these two parts separate in follow-up discussions:
> 
> - **Budget Evaluation Strategy**: The static approach seems straightforward—if
> a class requests more than available, appropriate actions are taken. However,
> the dynamic approach has more complexity, such as determining the threshold,
> how long violations can be tolerated, and whether a safety margin should be
> maintained before exceeding maximum load.
> 
> - **Disconnection Policy**: Once a budget violation is detected, this decides
> how to react, like which ports should be disconnected and in what order.
> 
> Would it make more sense to have a unified strategy for power domains, where we
> apply the same budget evaluation mode (static or dynamic) and disconnection
> policy to all ports in that domain? This could make the configuration simpler
> and the power management more predictable.

Except of user reports, do we have documented confirmation about dynamic
Budget Evaluation Strategy in PD692x0 firmware?

Do this configuration bits are what I called Budget Evaluation Strategy?
Version 3.55:
Bits [3..0]—BT port PM mode
0x0: The port power that is used for power management purposes is
     dynamic (Iport x Vmain).
0x1: The port power that is used for power management purposes is port
     TPPL_BT.
0x2: The port power that is used for power management purposes is
     dynamic for non LLDP/CDP/Autoclass ports and TPPL_BT for
     LLDP/CDP/Autoclass ports.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index
  2024-10-31 21:28     ` Andrew Lunn
@ 2024-11-05  9:33       ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-05  9:33 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 22:28:29 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> On Thu, Oct 31, 2024 at 07:27:59AM +0100, Oleksij Rempel wrote:
> > On Wed, Oct 30, 2024 at 05:53:07PM +0100, Kory Maincent wrote:
> > 
> > ...  
> > >  /**
> > >   * struct pse_control - a PSE control
> > > @@ -440,18 +441,22 @@ int pse_controller_register(struct
> > > pse_controller_dev *pcdev) 
> > >  	mutex_init(&pcdev->lock);
> > >  	INIT_LIST_HEAD(&pcdev->pse_control_head);
> > > +	ret = ida_alloc_max(&pse_ida, INT_MAX, GFP_KERNEL);  
> > 
> > s/INT_MAX/U32_MAX  
> 
>  * Return: The allocated ID, or %-ENOMEM if memory could not be allocated,
>  * or %-ENOSPC if there are no free IDs.
> 
> static inline int ida_alloc_max(struct ida *ida, unsigned int max, gfp_t gfp)
> 
> We need to be careful here, at least theoretically. Assuming a 32 bit
> system, and you pass it U32_MAX, how does it return values in the
> range S32_MAX..U32_MAX when it also needs to be able to return
> negative numbers as errors?
> 
> I think the correct value to pass is S32_MAX, because it will always
> fit in a u32, and there is space left for negative values for errors.
> 
> But this is probably theoretical, no real system should have that many
> controllers.

Indeed you are right we might have issue between S32_MAX and U32_MAX if we want
to return errors.
Small question, is S32_MAX better than INT_MAX? Is there a point to limit it to
32 bits?

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function
  2024-10-31 21:44   ` Andrew Lunn
@ 2024-11-05  9:37     ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-05  9:37 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 22:44:51 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> On Wed, Oct 30, 2024 at 05:53:09PM +0100, Kory Maincent wrote:
> > From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> > 
> > Introduce support for the ethnl_info_init_ntf helper function to enable
> > initialization of ethtool notifications outside of the netlink.c file.
> > This change allows for more flexible notification handling.
> > 
> > Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
> > ---
> > 
> > changes in v2:
> > - new patch.
> > ---
> >  net/ethtool/netlink.c | 5 +++++
> >  net/ethtool/netlink.h | 2 ++
> >  2 files changed, 7 insertions(+)
> > 
> > diff --git a/net/ethtool/netlink.c b/net/ethtool/netlink.c
> > index e3f0ef6b851b..808cc8096f93 100644
> > --- a/net/ethtool/netlink.c
> > +++ b/net/ethtool/netlink.c
> > @@ -805,6 +805,11 @@ static void ethnl_default_notify(struct net_device
> > *dev, unsigned int cmd, typedef void (*ethnl_notify_handler_t)(struct
> > net_device *dev, unsigned int cmd, const void *data);
> >  
> > +void ethnl_info_init_ntf(struct genl_info *info, u8 cmd)
> > +{
> > +	genl_info_init_ntf(info, &ethtool_genl_family, cmd);
> > +}
> > +  
> 
> I've not looked at the users yet. Does this need EXPORT_SYMBOL_GPL()?

No it doesn't as the user is net/ethtool/pse-pd.c

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-31 22:00   ` Andrew Lunn
@ 2024-11-05  9:41     ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-05  9:41 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 23:00:48 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> > +static unsigned long pse_to_regulator_notifs(unsigned long notifs)
> > +{
> > +	switch (notifs) {
> > +	case ETHTOOL_C33_PSE_EVENT_OVER_CURRENT:
> > +		return REGULATOR_EVENT_OVER_CURRENT;
> > +	case ETHTOOL_C33_PSE_EVENT_OVER_TEMP:
> > +		return REGULATOR_EVENT_OVER_TEMP;
> > +	}
> > +	return 0;
> > +}  
> 
> 
> https://elixir.bootlin.com/linux/v6.11.5/source/include/uapi/regulator/regulator.h#L36
> 
>  * NOTE: These events can be OR'ed together when passed into handler.
> 
> ETHTOOL_C33_PSE_EVENT_OVER_* are also bits which could be OR'ed
> together, so is this function correct?

You are right, thanks for seeing it.

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events
  2024-10-31 21:54   ` Andrew Lunn
@ 2024-11-05  9:48     ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-05  9:48 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 22:54:00 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> > +static struct phy_device *
> > +pse_control_find_phy_by_id(struct pse_controller_dev *pcdev, int id)
> > +{
> > +	struct pse_control *psec;
> > +
> > +	mutex_lock(&pse_list_mutex);
> > +	list_for_each_entry(psec, &pcdev->pse_control_head, list) {
> > +		if (psec->id == id)
> > +			return psec->attached_phydev;  
> 
> The mutex is still locked. I'm surprised your testing did not
> deadlock, and that none of the automated tools have reported this.

Ouch indeed! As explained in the cover letter, this v2 has not been fully
tested.
But I have built it with smatch and sparse. Weirdly they didn't find it. 
Thanks for seeing it.


> ---
> pw-bot: cr

Does RFC patch series pass through the netdev CI build test? 

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-11-01 10:23         ` Oleksij Rempel
@ 2024-11-05 10:20           ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-05 10:20 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Fri, 1 Nov 2024 11:23:06 +0100
Oleksij Rempel <o.rempel@pengutronix.de> wrote:

> On Fri, Nov 01, 2024 at 09:31:43AM +0100, Oleksij Rempel wrote:
> > On Thu, Oct 31, 2024 at 12:11:04PM +0100, Kory Maincent wrote:  
> > > On Thu, 31 Oct 2024 07:54:08 +0100
> > > Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> > >   
>  [...]  
>  [...]  
> > > 
> > > Ack. So we assume PoDL could have the same interruption events.
> > >   
>  [...]  
> > 
> > After thinking about it more overnight, I wanted to revisit the idea of
> > having a priority strategy per port. Right now, if one port is set to
> > static or dynamic mode, all disabled ports seem to have to follow it
> > somehow too. This makes it feel like we should have a strategy for the
> > whole power domain, not just for each port.
> > 
> > I'm having trouble imagining how a per-port priority strategy would work in
> > this setup.

Indeed you are right. I was first thinking of using the same port priority for
all the ports of a PSE but it seems indeed better to have it by Power domain.

> > Another point that came to mind is that we might have two different
> > components here, and we need to keep these two parts separate in follow-up
> > discussions:
> > 
> > - **Budget Evaluation Strategy**: The static approach seems
> > straightforward—if a class requests more than available, appropriate
> > actions are taken. However, the dynamic approach has more complexity, such
> > as determining the threshold, how long violations can be tolerated, and
> > whether a safety margin should be maintained before exceeding maximum load.
> > 
> > - **Disconnection Policy**: Once a budget violation is detected, this
> > decides how to react, like which ports should be disconnected and in what
> > order.
> > 
> > Would it make more sense to have a unified strategy for power domains,
> > where we apply the same budget evaluation mode (static or dynamic) and
> > disconnection policy to all ports in that domain? This could make the
> > configuration simpler and the power management more predictable.  

Yes, these policies and the port priority mode should be per power domains. 

> Except of user reports, do we have documented confirmation about dynamic
> Budget Evaluation Strategy in PD692x0 firmware?
> 
> Do this configuration bits are what I called Budget Evaluation Strategy?
> Version 3.55:
> Bits [3..0]—BT port PM mode
> 0x0: The port power that is used for power management purposes is
>      dynamic (Iport x Vmain).

Yes it seems so. I can't find any more configurations on the budget evaluation
strategy than the power limit.

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-10-31 17:32       ` Oleksij Rempel
@ 2024-11-05 13:49         ` Kory Maincent
  2024-11-05 14:36           ` Oleksij Rempel
  0 siblings, 1 reply; 47+ messages in thread
From: Kory Maincent @ 2024-11-05 13:49 UTC (permalink / raw)
  To: Oleksij Rempel
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 18:32:39 +0100
Oleksij Rempel <o.rempel@pengutronix.de> wrote:
 
> > >  *
> > >  * Handling scenarios where power budget is exceeded:
> > >  * - Hot-plug behavior: If a new device is added that causes the total
> > > power
> > >  *   demand to exceed the PSE budget, the newly added device is
> > > de-prioritized
> > >  *   and shut down to maintain stability for previously connected devices.
> > >  *   This behavior ensures that existing connections are not disrupted,
> > > though
> > >  *   it may lead to inconsistent behavior if the device is disconnected
> > > and
> > >  *   reconnected (hot-plugged).  
> > 
> > Do we want this behavior even if the new device has an highest priority than
> > other previously connected devices?  
> 
> Huh... good question. I assume, if we go with policy in kernel, then it
> is ok to implement just some one. But, I assume, we will need this kind of
> interface soon or later: 
> 
> Warning! this is discussion, i'm in process of understanding :D
> 
> /**
>  * enum pse_disconnection_policy - Disconnection strategies for same-priority
>  *   devices when power budget is exceeded, tailored to specific priority
> modes. *
>  * Each device can have multiple disconnection policies set as an array of
>  * priorities. When the power budget is exceeded, the policies are executed
>  * in the order defined by the user. This allows for a more nuanced and 
>  * flexible approach to handling power constraints across a range of devices
>  * with similar priorities or attributes.
>  *
>  * Example Usage:
>  *   - Users can specify an ordered list of policies, such as starting with
>  *     `PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST` to prioritize based on class,
>  *     followed by `PSE_DISCON_LRC` to break ties based on connection time.
>  *     This ordered execution ensures that power disconnections align closely
>  *     with the system’s operational requirements and priorities.
 
...

>  * @PSE_DISCON_STATIC_CLASS_BUDGET_MATCH: Disconnect based on static
> allocation
>  *   class, targeting devices that release enough allocated power to meet the
>  *   current power requirement.
>  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
>  *   - Behavior: Searches for the lowest-priority device that can release
>  *     sufficient allocated power to meet the current budget requirement.
>  *     Ensures that disconnection occurs only when enough power is freed.
>  *   - Rationale: This strategy is useful when the goal is to balance power
>  *     budget requirements while minimizing the number of disconnected
> devices.
>  *     It ensures that the system does not needlessly disconnect multiple
>  *     devices if a single disconnection is sufficient to meet the power
> needs.
>  *   - Use Case: Ideal for systems where precise power budget management is
>  *     necessary, and disconnections must be efficient in terms of freeing
>  *     enough power with minimal impact on the system.

Not sure about this one. PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST would be
sufficient for that case.
 
>  * @PSE_DISCON_LOWEST_AVG_POWER: Disconnect device with the lowest average
>  *   power draw, minimizing impact on dynamic power allocation.
>  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
>  *   - Behavior: Among devices with the same priority level, the system
>  *     disconnects the device with the lowest average power draw.
>  *   - If multiple devices have the same average power draw and priority,
>  *     further tie-breaking mechanisms can be applied, such as disconnecting
>  *     the least recently connected device.
>  *   - Rationale: Minimizes disruption across dynamic devices, keeping as many
>  *     active as possible by removing the lowest-power ones.
>  *   - Use Case: Suitable for dynamic-priority systems where maximizing the
>  *     number of connected devices is more important than individual device
>  *     power requirements.
> 
>  * @PSE_DISCON_LONGEST_IDLE: Disconnect device with the longest idle time
>  *   (low or no recent active power usage).
>  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
>  *   - Behavior: Disconnects the device with the longest period of inactivity,
>  *     where "idle" is defined as low current draw or absence of recent data
>  *     transmission.
>  *   - If multiple devices have the same idle time and priority, a
> tie-breaking
>  *     mechanism, such as round-robin based on port index, can be used.
>  *   - Rationale: Optimizes resource allocation in dynamic-priority setups by
>  *     maintaining active devices while deprioritizing those with minimal
>  *     recent usage.
>  *   - Use Case: Ideal for dynamic environments, like sensor networks, where
>  *     devices may be intermittently active and can be deprioritized during
>  *     idle periods.
>  *
>  * These disconnection policies provide flexibility in handling cases where
>  * multiple devices with the same priority exceed the PSE budget, aligning
>  * with either static or dynamic port priority modes:
>  *   - `ETHTOOL_PSE_PORT_PRIO_STATIC` benefits from policies that maintain
>  *     stable power allocation, favoring longer-standing or higher-class
>  *     devices (e.g., `PSE_DISCON_LRC`, `PSE_DISCON_ROUND_ROBIN_IDX`,
>  *     `PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST`,
> `PSE_DISCON_STATIC_CLASS_LOWEST_FIRST`,
>  *     `PSE_DISCON_STATIC_CLASS_BUDGET_MATCH`).
>  *   - `ETHTOOL_PSE_PORT_PRIO_DYNAMIC` supports policies that dynamically
>  *     adjust based on real-time metrics (e.g., `PSE_DISCON_LOWEST_AVG_POWER`,
>  *     `PSE_DISCON_LONGEST_IDLE`), ideal for setups where usage fluctuates
>  *     frequently.
>  *   - Users can define an ordered array of disconnection policies, allowing
>  *     the system to apply each policy in sequence, providing nuanced control
>  *     over how power disconnections are handled.
>  */

I think I can add support for one or two of these modes in this patch series.
Modes relevant for dynamic port priority can't be used for now as nothing
support them.
Do you think I should add this full enumeration in ethtool UAPI even if not all
of them are supported yet? 


> PD692x0 seems to use @PSE_DISCON_ROUND_ROBIN_IDX_HIGHEST_FIRST disconnection
> policy.

Yes.

> ETHTOOL_PSE_PORT_PRIO_DYNAMIC and ETHTOOL_PSE_PORT_PRIO_STATIC seems to be the
> source of information which should be used to trigger the disconnection
> policy. Correct?

Yes.
The management of disconnection in ETHTOOL_PSE_PORT_PRIO_DYNAMIC case is
managed directly by the PSE firmware on the PD692x0.

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority
  2024-11-05 13:49         ` Kory Maincent
@ 2024-11-05 14:36           ` Oleksij Rempel
  0 siblings, 0 replies; 47+ messages in thread
From: Oleksij Rempel @ 2024-11-05 14:36 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Tue, Nov 05, 2024 at 02:49:13PM +0100, Kory Maincent wrote:
> On Thu, 31 Oct 2024 18:32:39 +0100
> Oleksij Rempel <o.rempel@pengutronix.de> wrote:
> 
> >  * @PSE_DISCON_STATIC_CLASS_BUDGET_MATCH: Disconnect based on static
> > allocation
> >  *   class, targeting devices that release enough allocated power to meet the
> >  *   current power requirement.
> >  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_STATIC
> >  *   - Behavior: Searches for the lowest-priority device that can release
> >  *     sufficient allocated power to meet the current budget requirement.
> >  *     Ensures that disconnection occurs only when enough power is freed.
> >  *   - Rationale: This strategy is useful when the goal is to balance power
> >  *     budget requirements while minimizing the number of disconnected
> > devices.
> >  *     It ensures that the system does not needlessly disconnect multiple
> >  *     devices if a single disconnection is sufficient to meet the power
> > needs.
> >  *   - Use Case: Ideal for systems where precise power budget management is
> >  *     necessary, and disconnections must be efficient in terms of freeing
> >  *     enough power with minimal impact on the system.
> 
> Not sure about this one. PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST would be
> sufficient for that case.

ack

> >  * @PSE_DISCON_LOWEST_AVG_POWER: Disconnect device with the lowest average
> >  *   power draw, minimizing impact on dynamic power allocation.
> >  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
> >  *   - Behavior: Among devices with the same priority level, the system
> >  *     disconnects the device with the lowest average power draw.
> >  *   - If multiple devices have the same average power draw and priority,
> >  *     further tie-breaking mechanisms can be applied, such as disconnecting
> >  *     the least recently connected device.
> >  *   - Rationale: Minimizes disruption across dynamic devices, keeping as many
> >  *     active as possible by removing the lowest-power ones.
> >  *   - Use Case: Suitable for dynamic-priority systems where maximizing the
> >  *     number of connected devices is more important than individual device
> >  *     power requirements.
> > 
> >  * @PSE_DISCON_LONGEST_IDLE: Disconnect device with the longest idle time
> >  *   (low or no recent active power usage).
> >  *   - Relevant for: ETHTOOL_PSE_PORT_PRIO_DYNAMIC
> >  *   - Behavior: Disconnects the device with the longest period of inactivity,
> >  *     where "idle" is defined as low current draw or absence of recent data
> >  *     transmission.
> >  *   - If multiple devices have the same idle time and priority, a
> > tie-breaking
> >  *     mechanism, such as round-robin based on port index, can be used.
> >  *   - Rationale: Optimizes resource allocation in dynamic-priority setups by
> >  *     maintaining active devices while deprioritizing those with minimal
> >  *     recent usage.
> >  *   - Use Case: Ideal for dynamic environments, like sensor networks, where
> >  *     devices may be intermittently active and can be deprioritized during
> >  *     idle periods.
> >  *
> >  * These disconnection policies provide flexibility in handling cases where
> >  * multiple devices with the same priority exceed the PSE budget, aligning
> >  * with either static or dynamic port priority modes:
> >  *   - `ETHTOOL_PSE_PORT_PRIO_STATIC` benefits from policies that maintain
> >  *     stable power allocation, favoring longer-standing or higher-class
> >  *     devices (e.g., `PSE_DISCON_LRC`, `PSE_DISCON_ROUND_ROBIN_IDX`,
> >  *     `PSE_DISCON_STATIC_CLASS_HIGHEST_FIRST`,
> > `PSE_DISCON_STATIC_CLASS_LOWEST_FIRST`,
> >  *     `PSE_DISCON_STATIC_CLASS_BUDGET_MATCH`).
> >  *   - `ETHTOOL_PSE_PORT_PRIO_DYNAMIC` supports policies that dynamically
> >  *     adjust based on real-time metrics (e.g., `PSE_DISCON_LOWEST_AVG_POWER`,
> >  *     `PSE_DISCON_LONGEST_IDLE`), ideal for setups where usage fluctuates
> >  *     frequently.
> >  *   - Users can define an ordered array of disconnection policies, allowing
> >  *     the system to apply each policy in sequence, providing nuanced control
> >  *     over how power disconnections are handled.
> >  */
> 
> I think I can add support for one or two of these modes in this patch series.
> Modes relevant for dynamic port priority can't be used for now as nothing
> support them.

ack

> Do you think I should add this full enumeration in ethtool UAPI even if not all
> of them are supported yet? 

No, do not worry, it was just my brain dump. Care only about actually
used variants. If some one will need something different, we will
already know how to address it.

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 47+ messages in thread

* Re: [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel
  2024-10-31 21:11   ` Andrew Lunn
@ 2024-11-07 10:47     ` Kory Maincent
  0 siblings, 0 replies; 47+ messages in thread
From: Kory Maincent @ 2024-11-07 10:47 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Oleksij Rempel, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Jonathan Corbet, Donald Hunter, Rob Herring,
	Andrew Lunn, Simon Horman, Heiner Kallweit, Russell King,
	Liam Girdwood, Mark Brown, Thomas Petazzoni, linux-kernel, netdev,
	linux-doc, Kyle Swenson, Dent Project, kernel, Maxime Chevallier

On Thu, 31 Oct 2024 22:11:18 +0100
Andrew Lunn <andrew@lunn.ch> wrote:

> > +	val = tps23881_set_val(ret, chan, 0, BIT(chan % 4), BIT(chan % 4));
> > +		val = tps23881_set_val(val, chan, 0, BIT(chan % 4),
> > +				       BIT(chan % 4));
> > +	val = tps23881_set_val(ret, chan, 4, BIT(chan % 4), BIT(chan % 4));
> > +		val = tps23881_set_val(val, chan, 4, BIT(chan % 4),
> > +				       BIT(chan % 4));
> > +	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> > +		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> > +	val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> > +	val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));
> > +		val = tps23881_calc_val(ret, chan, 0, BIT(chan % 4));
> > +		val = tps23881_calc_val(ret, chan, 4, BIT(chan % 4));  
> 
> It looks like all the callers of this helper pass BIT(chan % 4) as the
> last parameter. Maybe move that into the helper as well?

There is different cases in the patch 4 of the series.

Regards,
-- 
Köry Maincent, Bootlin
Embedded Linux and kernel engineering
https://bootlin.com

^ permalink raw reply	[flat|nested] 47+ messages in thread

end of thread, other threads:[~2024-11-07 10:47 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-30 16:53 [PATCH RFC net-next v2 00/18] Add support for PSE port priority Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 01/18] net: pse-pd: Remove unused pse_ethtool_get_pw_limit function declaration Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 02/18] net: pse-pd: tps23881: Simplify function returns by removing redundant checks Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 03/18] net: pse-pd: tps23881: Use helpers to calculate bit offset for a channel Kory Maincent
2024-10-31  6:18   ` Oleksij Rempel
2024-10-31 21:11   ` Andrew Lunn
2024-11-07 10:47     ` Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 04/18] net: pse-pd: tps23881: Add support for power limit and measurement features Kory Maincent
2024-10-31  6:20   ` Oleksij Rempel
2024-10-30 16:53 ` [PATCH RFC net-next v2 05/18] net: pse-pd: Add support for PSE device index Kory Maincent
2024-10-31  6:27   ` Oleksij Rempel
2024-10-31 21:28     ` Andrew Lunn
2024-11-05  9:33       ` Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 06/18] net: ethtool: Add support for new PSE device index description Kory Maincent
2024-10-31  6:28   ` Oleksij Rempel
2024-10-31 21:29   ` Andrew Lunn
2024-10-31 21:39   ` Andrew Lunn
2024-10-30 16:53 ` [PATCH RFC net-next v2 07/18] net: ethtool: Add support for ethnl_info_init_ntf helper function Kory Maincent
2024-10-31 21:44   ` Andrew Lunn
2024-11-05  9:37     ` Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 08/18] net: pse-pd: Add support for reporting events Kory Maincent
2024-10-31  6:34   ` Oleksij Rempel
2024-10-31 21:54   ` Andrew Lunn
2024-11-05  9:48     ` Kory Maincent
2024-10-31 22:00   ` Andrew Lunn
2024-11-05  9:41     ` Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 09/18] netlink: specs: Add support for PSE netlink notifications Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 10/18] net: pse-pd: tps23881: Add support for PSE events and interrupts Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 11/18] regulator: Add support for power budget description Kory Maincent
2024-10-30 17:03   ` Mark Brown
2024-10-30 17:22     ` Kory Maincent
2024-10-30 17:31       ` Mark Brown
2024-10-30 16:53 ` [PATCH RFC net-next v2 12/18] regulator: dt-bindings: Add regulator-power-budget property Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 13/18] net: pse-pd: Add support for PSE power domains Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 14/18] net: ethtool: Add support for new power domains index description Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 15/18] net: pse-pd: Add support for getting and setting port priority Kory Maincent
2024-10-31  6:54   ` Oleksij Rempel
2024-10-31 11:11     ` Kory Maincent
2024-10-31 17:32       ` Oleksij Rempel
2024-11-05 13:49         ` Kory Maincent
2024-11-05 14:36           ` Oleksij Rempel
2024-11-01  8:31       ` Oleksij Rempel
2024-11-01 10:23         ` Oleksij Rempel
2024-11-05 10:20           ` Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 16/18] net: ethtool: Add PSE new port priority support feature Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 17/18] netlink: specs: Expand the PSE netlink command with newly supported features Kory Maincent
2024-10-30 16:53 ` [PATCH RFC net-next v2 18/18] net: pse-pd: pd692x0: Add support for PSE PI priority feature Kory Maincent

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).