linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
@ 2025-09-15 17:06 Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls Kory Maincent
                   ` (6 more replies)
  0 siblings, 7 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

This patch series introduces a new devlink-conf uAPI to manage device
configuration stored in non-volatile memory. This provides a standardized
interface for devices that need to persist configuration changes across
reboots. The uAPI is designed to be generic and can be used by any device
driver that manages persistent configuration storage.

The permanent configuration allows settings to persist across device
resets and power cycles, providing better control over PSE behavior
in production environments.

The new uAPI support is preceded by 3 patches that do house keeping.

Signed-off-by: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
---
Changes in v3:
- Move on from devlink param to new devlink conf uAPI. This new uAPI
  manage device configuration stored in non-volatile memory.
- Link to v2: https://lore.kernel.org/r/20250829-feature_poe_permanent_conf-v2-0-8bb6f073ec23@bootlin.com

Changes in v2:
- Move from sysfs interface to devlink interface for the permanent
  configuration support
- Remove the __free macro from pd692x0 driver following net policy.
- Link to v1: https://lore.kernel.org/r/20250822-feature_poe_permanent_conf-v1-0-dcd41290254d@bootlin.com

---
Kory Maincent (5):
      net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls
      net: pse-pd: pd692x0: Separate configuration parsing from hardware setup
      docs: devlink: Sort table of contents alphabetically
      devlink: Add devlink-conf uAPI for NV memory management
      net: pse-pd: pd692x0: Add devlink interface for configuration save/reset

 Documentation/netlink/specs/devlink.yaml          |  23 ++
 Documentation/networking/devlink/devlink-conf.rst |  22 ++
 Documentation/networking/devlink/index.rst        |  22 +-
 Documentation/networking/devlink/pd692x0.rst      |  24 ++
 MAINTAINERS                                       |   3 +
 drivers/net/pse-pd/pd692x0.c                      | 280 ++++++++++++++++++----
 include/net/devlink.h                             |  20 ++
 include/uapi/linux/devlink.h                      |   4 +
 net/devlink/Makefile                              |   3 +-
 net/devlink/conf.c                                |  31 +++
 net/devlink/netlink.c                             |   2 +-
 net/devlink/netlink_gen.c                         |  20 +-
 net/devlink/netlink_gen.h                         |   3 +-
 13 files changed, 400 insertions(+), 57 deletions(-)
---
base-commit: c237892eba83664b7265c46ffe3865a876e720ed
change-id: 20250813-feature_poe_permanent_conf-ec640dace1f2

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


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

* [PATCH net-next v3 1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
@ 2025-09-15 17:06 ` Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 2/5] net: pse-pd: pd692x0: Separate configuration parsing from hardware setup Kory Maincent
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

Replace __free(kfree) with explicit kfree() calls to follow the net
subsystem policy of avoiding automatic cleanup macros as described in
the documentation.

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

Changes in v2:
- New patch
---
 drivers/net/pse-pd/pd692x0.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index f4e91ba64a666..055e925c853ef 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -1200,9 +1200,9 @@ static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
 
 static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 {
-	struct pd692x0_manager *manager __free(kfree) = NULL;
 	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 	struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
+	struct pd692x0_manager *manager;
 	int ret, nmanagers;
 
 	/* Should we flash the port matrix */
@@ -1216,7 +1216,7 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 
 	ret = pd692x0_of_get_managers(priv, manager);
 	if (ret < 0)
-		return ret;
+		goto err_free_manager;
 
 	nmanagers = ret;
 	ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
@@ -1236,12 +1236,15 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 		goto err_managers_req_pw;
 
 	pd692x0_of_put_managers(priv, manager, nmanagers);
+	kfree(manager);
 	return 0;
 
 err_managers_req_pw:
 	pd692x0_managers_free_pw_budget(priv);
 err_of_managers:
 	pd692x0_of_put_managers(priv, manager, nmanagers);
+err_free_manager:
+	kfree(manager);
 	return ret;
 }
 

-- 
2.43.0


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

* [PATCH net-next v3 2/5] net: pse-pd: pd692x0: Separate configuration parsing from hardware setup
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls Kory Maincent
@ 2025-09-15 17:06 ` Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 3/5] docs: devlink: Sort table of contents alphabetically Kory Maincent
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

Cache the port matrix configuration in driver private data to enable
PSE controller reconfiguration. This refactoring separates device tree
parsing from hardware configuration application, allowing settings to be
reapplied without reparsing the device tree.

This prepares for upcoming permanent configuration support where cached
settings can be restored after device resets or firmware updates.

Signed-off-by: Kory Maincent <kory.maincent@bootlin.com>
---
 drivers/net/pse-pd/pd692x0.c | 115 ++++++++++++++++++++++++++++---------------
 1 file changed, 76 insertions(+), 39 deletions(-)

diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 055e925c853ef..782b1abf94cb1 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -85,6 +85,11 @@ enum {
 	PD692X0_MSG_CNT
 };
 
+struct pd692x0_matrix {
+	u8 hw_port_a;
+	u8 hw_port_b;
+};
+
 struct pd692x0_priv {
 	struct i2c_client *client;
 	struct pse_controller_dev pcdev;
@@ -101,6 +106,8 @@ struct pd692x0_priv {
 	enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
 	struct regulator_dev *manager_reg[PD692X0_MAX_MANAGERS];
 	int manager_pw_budget[PD692X0_MAX_MANAGERS];
+	int nmanagers;
+	struct pd692x0_matrix *port_matrix;
 };
 
 /* Template list of communication messages. The non-null bytes defined here
@@ -809,11 +816,6 @@ struct pd692x0_manager {
 	int nports;
 };
 
-struct pd692x0_matrix {
-	u8 hw_port_a;
-	u8 hw_port_b;
-};
-
 static int
 pd692x0_of_get_ports_manager(struct pd692x0_priv *priv,
 			     struct pd692x0_manager *manager,
@@ -903,7 +905,8 @@ pd692x0_of_get_managers(struct pd692x0_priv *priv,
 	}
 
 	of_node_put(managers_node);
-	return nmanagers;
+	priv->nmanagers = nmanagers;
+	return 0;
 
 out:
 	for (i = 0; i < nmanagers; i++) {
@@ -963,8 +966,7 @@ pd692x0_register_manager_regulator(struct device *dev, char *reg_name,
 
 static int
 pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
-				    const struct pd692x0_manager *manager,
-				    int nmanagers)
+				    const struct pd692x0_manager *manager)
 {
 	struct device *dev = &priv->client->dev;
 	size_t reg_name_len;
@@ -975,7 +977,7 @@ pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
 	 */
 	reg_name_len = strlen(dev_name(dev)) + 23;
 
-	for (i = 0; i < nmanagers; i++) {
+	for (i = 0; i < priv->nmanagers; i++) {
 		static const char * const regulators[] = { "vaux5", "vaux3p3" };
 		struct regulator_dev *rdev;
 		char *reg_name;
@@ -1008,10 +1010,14 @@ pd692x0_register_managers_regulator(struct pd692x0_priv *priv,
 }
 
 static int
-pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id, int pw)
+pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id)
 {
 	struct pd692x0_msg msg, buf;
-	int ret, pw_mW = pw / 1000;
+	int ret, pw_mW;
+
+	pw_mW = priv->manager_pw_budget[id] / 1000;
+	if (!pw_mW)
+		return 0;
 
 	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_POWER_BANK];
 	msg.data[0] = id;
@@ -1032,11 +1038,11 @@ pd692x0_conf_manager_power_budget(struct pd692x0_priv *priv, int id, int pw)
 }
 
 static int
-pd692x0_configure_managers(struct pd692x0_priv *priv, int nmanagers)
+pd692x0_req_managers_pw_budget(struct pd692x0_priv *priv)
 {
 	int i, ret;
 
-	for (i = 0; i < nmanagers; i++) {
+	for (i = 0; i < priv->nmanagers; i++) {
 		struct regulator *supply = priv->manager_reg[i]->supply;
 		int pw_budget;
 
@@ -1053,7 +1059,18 @@ pd692x0_configure_managers(struct pd692x0_priv *priv, int nmanagers)
 			return ret;
 
 		priv->manager_pw_budget[i] = pw_budget;
-		ret = pd692x0_conf_manager_power_budget(priv, i, pw_budget);
+	}
+
+	return 0;
+}
+
+static int
+pd692x0_configure_managers(struct pd692x0_priv *priv)
+{
+	int i, ret;
+
+	for (i = 0; i < priv->nmanagers; i++) {
+		ret = pd692x0_conf_manager_power_budget(priv, i);
 		if (ret < 0)
 			return ret;
 	}
@@ -1101,10 +1118,9 @@ pd692x0_set_port_matrix(const struct pse_pi_pairset *pairset,
 
 static int
 pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
-			 const struct pd692x0_manager *manager,
-			 int nmanagers,
-			 struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
+			 const struct pd692x0_manager *manager)
 {
+	struct pd692x0_matrix *port_matrix = priv->port_matrix;
 	struct pse_controller_dev *pcdev = &priv->pcdev;
 	int i, ret;
 
@@ -1117,7 +1133,7 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
 	/* Update with values for every PSE PIs */
 	for (i = 0; i < pcdev->nr_lines; i++) {
 		ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0],
-					      manager, nmanagers,
+					      manager, priv->nmanagers,
 					      &port_matrix[i]);
 		if (ret) {
 			dev_err(&priv->client->dev,
@@ -1126,7 +1142,7 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
 		}
 
 		ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1],
-					      manager, nmanagers,
+					      manager, priv->nmanagers,
 					      &port_matrix[i]);
 		if (ret) {
 			dev_err(&priv->client->dev,
@@ -1139,9 +1155,9 @@ pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
 }
 
 static int
-pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
-			   const struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
+pd692x0_write_ports_matrix(struct pd692x0_priv *priv)
 {
+	struct pd692x0_matrix *port_matrix = priv->port_matrix;
 	struct pd692x0_msg msg, buf;
 	int ret, i;
 
@@ -1166,13 +1182,32 @@ pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
 	return 0;
 }
 
+static int pd692x0_hw_conf_init(struct pd692x0_priv *priv)
+{
+	int ret;
+
+	/* Is PD692x0 ready to be configured? */
+	if (priv->fw_state != PD692X0_FW_OK &&
+	    priv->fw_state != PD692X0_FW_COMPLETE)
+		return 0;
+
+	ret = pd692x0_configure_managers(priv);
+	if (ret)
+		return ret;
+
+	ret = pd692x0_write_ports_matrix(priv);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 static void pd692x0_of_put_managers(struct pd692x0_priv *priv,
-				    struct pd692x0_manager *manager,
-				    int nmanagers)
+				    struct pd692x0_manager *manager)
 {
 	int i, j;
 
-	for (i = 0; i < nmanagers; i++) {
+	for (i = 0; i < priv->nmanagers; i++) {
 		for (j = 0; j < manager[i].nports; j++)
 			of_node_put(manager[i].port_node[j]);
 		of_node_put(manager[i].node);
@@ -1201,48 +1236,50 @@ static void pd692x0_managers_free_pw_budget(struct pd692x0_priv *priv)
 static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 {
 	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
-	struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
+	struct pd692x0_matrix *port_matrix;
 	struct pd692x0_manager *manager;
-	int ret, nmanagers;
-
-	/* Should we flash the port matrix */
-	if (priv->fw_state != PD692X0_FW_OK &&
-	    priv->fw_state != PD692X0_FW_COMPLETE)
-		return 0;
+	int ret;
 
 	manager = kcalloc(PD692X0_MAX_MANAGERS, sizeof(*manager), GFP_KERNEL);
 	if (!manager)
 		return -ENOMEM;
 
+	port_matrix = devm_kcalloc(&priv->client->dev, PD692X0_MAX_PIS,
+				   sizeof(*port_matrix), GFP_KERNEL);
+	if (!port_matrix) {
+		ret = -ENOMEM;
+		goto err_free_manager;
+	}
+	priv->port_matrix = port_matrix;
+
 	ret = pd692x0_of_get_managers(priv, manager);
 	if (ret < 0)
 		goto err_free_manager;
 
-	nmanagers = ret;
-	ret = pd692x0_register_managers_regulator(priv, manager, nmanagers);
+	ret = pd692x0_register_managers_regulator(priv, manager);
 	if (ret)
 		goto err_of_managers;
 
-	ret = pd692x0_configure_managers(priv, nmanagers);
+	ret = pd692x0_req_managers_pw_budget(priv);
 	if (ret)
 		goto err_of_managers;
 
-	ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
+	ret = pd692x0_set_ports_matrix(priv, manager);
 	if (ret)
 		goto err_managers_req_pw;
 
-	ret = pd692x0_write_ports_matrix(priv, port_matrix);
+	ret = pd692x0_hw_conf_init(priv);
 	if (ret)
 		goto err_managers_req_pw;
 
-	pd692x0_of_put_managers(priv, manager, nmanagers);
+	pd692x0_of_put_managers(priv, manager);
 	kfree(manager);
 	return 0;
 
 err_managers_req_pw:
 	pd692x0_managers_free_pw_budget(priv);
 err_of_managers:
-	pd692x0_of_put_managers(priv, manager, nmanagers);
+	pd692x0_of_put_managers(priv, manager);
 err_free_manager:
 	kfree(manager);
 	return ret;
@@ -1647,7 +1684,7 @@ static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)
 		return FW_UPLOAD_ERR_FW_INVALID;
 	}
 
-	ret = pd692x0_setup_pi_matrix(&priv->pcdev);
+	ret = pd692x0_hw_conf_init(priv);
 	if (ret < 0) {
 		dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",
 			ERR_PTR(ret));

-- 
2.43.0


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

* [PATCH net-next v3 3/5] docs: devlink: Sort table of contents alphabetically
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 2/5] net: pse-pd: pd692x0: Separate configuration parsing from hardware setup Kory Maincent
@ 2025-09-15 17:06 ` Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 4/5] devlink: Add devlink-conf uAPI for NV memory management Kory Maincent
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

Sort devlink documentation table of contents alphabetically to improve
readability and make it easier to locate specific chapters.

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

Changes in v2:
- New patch
---
 Documentation/networking/devlink/index.rst | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index 270a65a014111..0c58e5c729d92 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -56,18 +56,18 @@ general.
    :maxdepth: 1
 
    devlink-dpipe
+   devlink-eswitch-attr
+   devlink-flash
    devlink-health
    devlink-info
-   devlink-flash
+   devlink-linecard
    devlink-params
    devlink-port
    devlink-region
-   devlink-resource
    devlink-reload
+   devlink-resource
    devlink-selftests
    devlink-trap
-   devlink-linecard
-   devlink-eswitch-attr
 
 Driver-specific documentation
 -----------------------------
@@ -78,12 +78,14 @@ parameters, info versions, and other features it supports.
 .. toctree::
    :maxdepth: 1
 
+   am65-nuss-cpsw-switch
    bnxt
    etas_es58x
    hns3
    i40e
-   ionic
    ice
+   ionic
+   iosm
    ixgbe
    kvaser_pciefd
    kvaser_usb
@@ -93,11 +95,9 @@ parameters, info versions, and other features it supports.
    mv88e6xxx
    netdevsim
    nfp
-   qed
-   ti-cpsw-switch
-   am65-nuss-cpsw-switch
-   prestera
-   iosm
    octeontx2
+   prestera
+   qed
    sfc
+   ti-cpsw-switch
    zl3073x

-- 
2.43.0


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

* [PATCH net-next v3 4/5] devlink: Add devlink-conf uAPI for NV memory management
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
                   ` (2 preceding siblings ...)
  2025-09-15 17:06 ` [PATCH net-next v3 3/5] docs: devlink: Sort table of contents alphabetically Kory Maincent
@ 2025-09-15 17:06 ` Kory Maincent
  2025-09-15 17:06 ` [PATCH net-next v3 5/5] net: pse-pd: pd692x0: Add devlink interface for configuration save/reset Kory Maincent
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

Introduce a new devlink-conf uAPI to manage device configuration stored
in non-volatile memory. This provides a standardized interface for
devices that need to persist configuration changes across reboots.

Add two new devlink operations:
- conf_save: Save current configuration to non-volatile memory
- conf_reset: Reset configuration in non-volatile memory to factory
	      defaults

The uAPI is designed to be generic and can be used by any device driver
that manages persistent configuration storage.

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

After two NAKs on sysfs and devlink-param design choices due to uAPI not
being appropriate, I moved to this new design approach.
Also, the choice of saving the configuration to NVM on every config change
seemed inappropriate as the save and the reset processes would be in two
different Kernel framework.
The new design intend to extend devlink uAPI with a devlink-conf interface.
This uAPI is designed to be generic. While currently only one driver
implements it, controllers that manage non-volatile memory to save
configuration are not uncommon.

Change in v3:
- New patch.
---
 Documentation/netlink/specs/devlink.yaml          | 23 +++++++++++++++++
 Documentation/networking/devlink/devlink-conf.rst | 22 ++++++++++++++++
 Documentation/networking/devlink/index.rst        |  1 +
 MAINTAINERS                                       |  2 ++
 include/net/devlink.h                             | 20 +++++++++++++++
 include/uapi/linux/devlink.h                      |  4 +++
 net/devlink/Makefile                              |  3 ++-
 net/devlink/conf.c                                | 31 +++++++++++++++++++++++
 net/devlink/netlink.c                             |  2 +-
 net/devlink/netlink_gen.c                         | 20 ++++++++++++++-
 net/devlink/netlink_gen.h                         |  3 ++-
 11 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
index 3db59c9658694..27db92457e886 100644
--- a/Documentation/netlink/specs/devlink.yaml
+++ b/Documentation/netlink/specs/devlink.yaml
@@ -857,6 +857,14 @@ attribute-sets:
         name: health-reporter-burst-period
         type: u64
         doc: Time (in msec) for recoveries before starting the grace period.
+      -
+        name: conf-save
+        type: flag
+        doc: Save device configuration to non-volatile memory.
+      -
+        name: conf-reset
+        type: flag
+        doc: Reset device configuration located in non-volatile memory.
   -
     name: dl-dev-stats
     subset-of: devlink
@@ -2325,3 +2333,18 @@ operations:
             - bus-name
             - dev-name
             - port-index
+    -
+      name: conf-set
+      doc: Manage device configuration.
+      attribute-set: devlink
+      dont-validate: [strict]
+      flags: [admin-perm]
+      do:
+        pre: devlink-nl-pre-doit
+        post: devlink-nl-post-doit
+        request:
+          attributes:
+            - bus-name
+            - dev-name
+            - conf-save
+            - conf-reset
diff --git a/Documentation/networking/devlink/devlink-conf.rst b/Documentation/networking/devlink/devlink-conf.rst
new file mode 100644
index 0000000000000..34f866f2f9594
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-conf.rst
@@ -0,0 +1,22 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+Devlink Conf
+============
+
+The ``devlink-conf`` API allows saving the device configuration as
+permanent writing it to a non-volatile memory.
+
+Drivers are expected to implement ``devlink-conf`` functionality through
+``conf_save`` and ``conf_reset`` devlink operations.
+
+example usage
+-------------
+
+.. code:: shell
+
+    $ devlink dev conf help
+    $ devlink dev conf DEV [ save | reset ]
+
+    # Run conf command for saving configuration to non-volatile memory:
+    $ devlink dev conf i2c/1-003c save
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index 0c58e5c729d92..ba381ecadc3dc 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -56,6 +56,7 @@ general.
    :maxdepth: 1
 
    devlink-dpipe
+   devlink-conf
    devlink-eswitch-attr
    devlink-flash
    devlink-health
diff --git a/MAINTAINERS b/MAINTAINERS
index b81595e9ea955..429303a9447f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20299,7 +20299,9 @@ M:	Kory Maincent <kory.maincent@bootlin.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/pse-pd/
+F:	Documentation/networking/devlink/devlink-conf.rst
 F:	drivers/net/pse-pd/
+F:	net/devlink/conf.c
 F:	net/ethtool/pse-pd.c
 
 PSTORE FILESYSTEM
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 5f44e702c25ca..04256d1973417 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1551,6 +1551,26 @@ struct devlink_ops {
 	enum devlink_selftest_status
 	(*selftest_run)(struct devlink *devlink, unsigned int id,
 			struct netlink_ext_ack *extack);
+
+	/**
+	 * conf_save - Save configuration to non-volatile memory
+	 * @devlink: Devlink instance
+	 * @extack: extack for reporting error messages
+	 *
+	 * Return: 0 on success, negative value otherwise.
+	 */
+	int (*conf_save)(struct devlink *devlink,
+			 struct netlink_ext_ack *extack);
+
+	/**
+	 * conf_reset - Reset configuration located in non-volatile memory
+	 * @devlink: Devlink instance
+	 * @extack: extack for reporting error messages
+	 *
+	 * Return: 0 on success, negative value otherwise.
+	 */
+	int (*conf_reset)(struct devlink *devlink,
+			  struct netlink_ext_ack *extack);
 };
 
 void *devlink_priv(struct devlink *devlink);
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index bcad11a787a55..ce9192e772d93 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -141,6 +141,8 @@ enum devlink_command {
 
 	DEVLINK_CMD_NOTIFY_FILTER_SET,
 
+	DEVLINK_CMD_CONF_SET,
+
 	/* add new commands above here */
 	__DEVLINK_CMD_MAX,
 	DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
@@ -638,6 +640,8 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_HEALTH_REPORTER_BURST_PERIOD,	/* u64 */
 
+	DEVLINK_ATTR_CONF_SAVE,			/* u8 */
+	DEVLINK_ATTR_CONF_RESET,		/* u8 */
 	/* Add new attributes above here, update the spec in
 	 * Documentation/netlink/specs/devlink.yaml and re-generate
 	 * net/devlink/netlink_gen.c.
diff --git a/net/devlink/Makefile b/net/devlink/Makefile
index 000da622116a3..e4ff40fc65ef2 100644
--- a/net/devlink/Makefile
+++ b/net/devlink/Makefile
@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0
 
 obj-y := core.o netlink.o netlink_gen.o dev.o port.o sb.o dpipe.o \
-	 resource.o param.o region.o health.o trap.o rate.o linecard.o
+	 resource.o param.o region.o health.o trap.o rate.o linecard.o \
+	 conf.o
diff --git a/net/devlink/conf.c b/net/devlink/conf.c
new file mode 100644
index 0000000000000..09cec798d5e48
--- /dev/null
+++ b/net/devlink/conf.c
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Bootlin, Kory Maincent <kory.maincent@bootlin.com>
+ */
+
+#include "devl_internal.h"
+
+int devlink_nl_conf_set_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct devlink *devlink = info->user_ptr[0];
+	struct nlattr **tb = info->attrs;
+	const struct devlink_ops *ops;
+
+	ops = devlink->ops;
+	if (!ops->conf_save || !ops->conf_reset)
+		return -EOPNOTSUPP;
+
+	if (tb[DEVLINK_ATTR_CONF_SAVE] && tb[DEVLINK_ATTR_CONF_RESET]) {
+		NL_SET_ERR_MSG_MOD(info->extack,
+				   "Can't save and reset the configuration simultaneously");
+		return -EINVAL;
+	}
+
+	if (tb[DEVLINK_ATTR_CONF_SAVE])
+		return ops->conf_save(devlink, info->extack);
+
+	if (tb[DEVLINK_ATTR_CONF_RESET])
+		return ops->conf_reset(devlink, info->extack);
+
+	return 0;
+}
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 593605c1b1ef4..e22f5bfaba931 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -367,7 +367,7 @@ struct genl_family devlink_nl_family __ro_after_init = {
 	.module		= THIS_MODULE,
 	.split_ops	= devlink_nl_ops,
 	.n_split_ops	= ARRAY_SIZE(devlink_nl_ops),
-	.resv_start_op	= DEVLINK_CMD_SELFTESTS_RUN + 1,
+	.resv_start_op	= DEVLINK_CMD_MAX + 1,
 	.mcgrps		= devlink_nl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
 	.sock_priv_size		= sizeof(struct devlink_nl_sock_priv),
diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c
index 9fd00977d59e3..51a1f55c7063d 100644
--- a/net/devlink/netlink_gen.c
+++ b/net/devlink/netlink_gen.c
@@ -602,8 +602,16 @@ static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_
 	[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
 };
 
+/* DEVLINK_CMD_CONF_SET - do */
+static const struct nla_policy devlink_conf_set_nl_policy[DEVLINK_ATTR_CONF_RESET + 1] = {
+	[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
+	[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+	[DEVLINK_ATTR_CONF_SAVE] = { .type = NLA_FLAG, },
+	[DEVLINK_ATTR_CONF_RESET] = { .type = NLA_FLAG, },
+};
+
 /* Ops table for devlink */
-const struct genl_split_ops devlink_nl_ops[74] = {
+const struct genl_split_ops devlink_nl_ops[75] = {
 	{
 		.cmd		= DEVLINK_CMD_GET,
 		.validate	= GENL_DONT_VALIDATE_STRICT,
@@ -1282,4 +1290,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
 		.maxattr	= DEVLINK_ATTR_PORT_INDEX,
 		.flags		= GENL_CMD_CAP_DO,
 	},
+	{
+		.cmd		= DEVLINK_CMD_CONF_SET,
+		.validate	= GENL_DONT_VALIDATE_STRICT,
+		.pre_doit	= devlink_nl_pre_doit,
+		.doit		= devlink_nl_conf_set_doit,
+		.post_doit	= devlink_nl_post_doit,
+		.policy		= devlink_conf_set_nl_policy,
+		.maxattr	= DEVLINK_ATTR_CONF_RESET,
+		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
+	},
 };
diff --git a/net/devlink/netlink_gen.h b/net/devlink/netlink_gen.h
index 09cc6f264ccfa..9e99528bd36c7 100644
--- a/net/devlink/netlink_gen.h
+++ b/net/devlink/netlink_gen.h
@@ -17,7 +17,7 @@ extern const struct nla_policy devlink_dl_rate_tc_bws_nl_policy[DEVLINK_RATE_TC_
 extern const struct nla_policy devlink_dl_selftest_id_nl_policy[DEVLINK_ATTR_SELFTEST_ID_FLASH + 1];
 
 /* Ops table for devlink */
-extern const struct genl_split_ops devlink_nl_ops[74];
+extern const struct genl_split_ops devlink_nl_ops[75];
 
 int devlink_nl_pre_doit(const struct genl_split_ops *ops, struct sk_buff *skb,
 			struct genl_info *info);
@@ -145,5 +145,6 @@ int devlink_nl_selftests_get_dumpit(struct sk_buff *skb,
 int devlink_nl_selftests_run_doit(struct sk_buff *skb, struct genl_info *info);
 int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
 				      struct genl_info *info);
+int devlink_nl_conf_set_doit(struct sk_buff *skb, struct genl_info *info);
 
 #endif /* _LINUX_DEVLINK_GEN_H */

-- 
2.43.0


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

* [PATCH net-next v3 5/5] net: pse-pd: pd692x0: Add devlink interface for configuration save/reset
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
                   ` (3 preceding siblings ...)
  2025-09-15 17:06 ` [PATCH net-next v3 4/5] devlink: Add devlink-conf uAPI for NV memory management Kory Maincent
@ 2025-09-15 17:06 ` Kory Maincent
  2025-09-16 23:54 ` [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Jakub Kicinski
  2025-09-17  0:20 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-15 17:06 UTC (permalink / raw)
  To: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Jiri Pirko, Simon Horman,
	Jonathan Corbet, Donald Hunter
  Cc: kernel, Dent Project, Thomas Petazzoni, netdev, linux-kernel,
	Maxime Chevallier, linux-doc, Kyle Swenson,
	Kory Maincent (Dent Project)

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

Add devlink conf_save and conf_reset ops to enable userspace management
of the PSE's permanent configuration stored in non-volatile memory.
The save_conf allows saving the current configuration to non-volatile
memory. The reset_conf attribute restores factory defaults configurations.

Skip hardware configuration initialization on probe when a saved
configuration is already present in non-volatile memory (detected via user
byte set to 42).

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

Changes in v2:
- Move on from sysfs to devlink param for userspace management.

Changes in v3:
- Move on from devlink param to new devlink conf uAPI.
---
 Documentation/networking/devlink/index.rst   |   1 +
 Documentation/networking/devlink/pd692x0.rst |  24 ++++
 MAINTAINERS                                  |   1 +
 drivers/net/pse-pd/pd692x0.c                 | 160 ++++++++++++++++++++++++++-
 4 files changed, 183 insertions(+), 3 deletions(-)

diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index ba381ecadc3dc..336b4cc00bd14 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -97,6 +97,7 @@ parameters, info versions, and other features it supports.
    netdevsim
    nfp
    octeontx2
+   pd692x0
    prestera
    qed
    sfc
diff --git a/Documentation/networking/devlink/pd692x0.rst b/Documentation/networking/devlink/pd692x0.rst
new file mode 100644
index 0000000000000..d7166f6f3ba91
--- /dev/null
+++ b/Documentation/networking/devlink/pd692x0.rst
@@ -0,0 +1,24 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================
+PSE PD692x0 devlink support
+===========================
+
+This document describes the devlink features implemented by the PSE
+``PD692x0`` device drivers.
+
+Operations
+==========
+
+The ``PD692x0`` drivers implement the following devlink operations.
+
+.. list-table:: Devlink ops implemented
+   :widths: 5 85
+
+   * - Name
+     - Description
+   * - ``conf_save``
+     - Save the current configuration to non-volatile memory.
+   * - ``conf_reset``
+     - Reset the current and saved configuration located the non-volatile
+       memory.
diff --git a/MAINTAINERS b/MAINTAINERS
index 429303a9447f3..cc6f7a8986b04 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -20300,6 +20300,7 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/devicetree/bindings/net/pse-pd/
 F:	Documentation/networking/devlink/devlink-conf.rst
+F:	Documentation/networking/devlink/pd692x0.rst
 F:	drivers/net/pse-pd/
 F:	net/devlink/conf.c
 F:	net/ethtool/pse-pd.c
diff --git a/drivers/net/pse-pd/pd692x0.c b/drivers/net/pse-pd/pd692x0.c
index 782b1abf94cb1..97f9c0648fdb6 100644
--- a/drivers/net/pse-pd/pd692x0.c
+++ b/drivers/net/pse-pd/pd692x0.c
@@ -14,6 +14,7 @@
 #include <linux/pse-pd/pse.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <net/devlink.h>
 
 #define PD692X0_PSE_NAME "pd692x0_pse"
 
@@ -30,6 +31,8 @@
 #define PD692X0_FW_MIN_VER	5
 #define PD692X0_FW_PATCH_VER	5
 
+#define PD692X0_USER_BYTE	42
+
 enum pd692x0_fw_state {
 	PD692X0_FW_UNKNOWN,
 	PD692X0_FW_OK,
@@ -80,6 +83,9 @@ enum {
 	PD692X0_MSG_GET_PORT_PARAM,
 	PD692X0_MSG_GET_POWER_BANK,
 	PD692X0_MSG_SET_POWER_BANK,
+	PD692X0_MSG_SET_USER_BYTE,
+	PD692X0_MSG_SAVE_SYS_SETTINGS,
+	PD692X0_MSG_RESTORE_FACTORY,
 
 	/* add new message above here */
 	PD692X0_MSG_CNT
@@ -103,11 +109,13 @@ struct pd692x0_priv {
 	bool last_cmd_key;
 	unsigned long last_cmd_key_time;
 
+	bool cfg_saved;
 	enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
 	struct regulator_dev *manager_reg[PD692X0_MAX_MANAGERS];
 	int manager_pw_budget[PD692X0_MAX_MANAGERS];
 	int nmanagers;
 	struct pd692x0_matrix *port_matrix;
+	struct devlink *dl;
 };
 
 /* Template list of communication messages. The non-null bytes defined here
@@ -193,6 +201,24 @@ static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
 		.key = PD692X0_KEY_CMD,
 		.sub = {0x07, 0x0b, 0x57},
 	},
+	[PD692X0_MSG_SET_USER_BYTE] = {
+		.key = PD692X0_KEY_PRG,
+		.sub = {0x41, PD692X0_USER_BYTE},
+		.data = {0x4e, 0x4e, 0x4e, 0x4e,
+			 0x4e, 0x4e, 0x4e, 0x4e},
+	},
+	[PD692X0_MSG_SAVE_SYS_SETTINGS] = {
+		.key = PD692X0_KEY_PRG,
+		.sub = {0x06, 0x0f},
+		.data = {0x4e, 0x4e, 0x4e, 0x4e,
+			 0x4e, 0x4e, 0x4e, 0x4e},
+	},
+	[PD692X0_MSG_RESTORE_FACTORY] = {
+		.key = PD692X0_KEY_PRG,
+		.sub = {0x2d, 0x4e},
+		.data = {0x4e, 0x4e, 0x4e, 0x4e,
+			 0x4e, 0x4e, 0x4e, 0x4e},
+	},
 };
 
 static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
@@ -1268,9 +1294,12 @@ static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 	if (ret)
 		goto err_managers_req_pw;
 
-	ret = pd692x0_hw_conf_init(priv);
-	if (ret)
-		goto err_managers_req_pw;
+	/* Do not init the conf if it is already saved */
+	if (!priv->cfg_saved) {
+		ret = pd692x0_hw_conf_init(priv);
+		if (ret)
+			goto err_managers_req_pw;
+	}
 
 	pd692x0_of_put_managers(priv, manager);
 	kfree(manager);
@@ -1727,14 +1756,118 @@ static const struct fw_upload_ops pd692x0_fw_ops = {
 	.cleanup = pd692x0_fw_cleanup,
 };
 
+/* Devlink Params APIs */
+enum pd692x0_devlink_param_id {
+	PD692X0_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+	PD692X0_DEVLINK_PARAM_ID_SAVE_CONF,
+	PD692X0_DEVLINK_PARAM_ID_RESET_CONF,
+};
+
+struct pd692x0_devlink {
+	struct pd692x0_priv *priv;
+};
+
+static int pd692x0_dl_conf_save(struct devlink *devlink,
+				struct netlink_ext_ack *extack)
+{
+	struct pd692x0_devlink *dl = devlink_priv(devlink);
+	struct pd692x0_priv *priv = dl->priv;
+	struct pd692x0_msg msg, buf = {0};
+	int ret;
+
+	mutex_lock(&priv->pcdev.lock);
+	ret = pd692x0_fw_unavailable(priv);
+	if (ret)
+		goto out;
+
+	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_USER_BYTE];
+	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
+	if (ret)
+		goto out;
+
+	msg = pd692x0_msg_template_list[PD692X0_MSG_SAVE_SYS_SETTINGS];
+	ret = pd692x0_send_msg(priv, &msg);
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Failed to save the configuration (%pe)\n",
+			ERR_PTR(ret));
+		goto out;
+	}
+
+	msleep(50); /* Sleep 50ms as described in the datasheet */
+
+	ret = i2c_master_recv(priv->client, (u8 *)&buf, sizeof(buf));
+	if (ret != sizeof(buf)) {
+		if (ret >= 0)
+			ret = -EIO;
+		goto out;
+	}
+
+	ret = 0;
+
+out:
+	mutex_unlock(&priv->pcdev.lock);
+	return ret;
+}
+
+static int pd692x0_dl_conf_reset(struct devlink *devlink,
+				 struct netlink_ext_ack *extack)
+{
+	struct pd692x0_devlink *dl = devlink_priv(devlink);
+	struct pd692x0_priv *priv = dl->priv;
+	struct pd692x0_msg msg, buf = {0};
+	int ret;
+
+	mutex_lock(&priv->pcdev.lock);
+	ret = pd692x0_fw_unavailable(priv);
+	if (ret)
+		goto out;
+
+	msg = pd692x0_msg_template_list[PD692X0_MSG_RESTORE_FACTORY];
+	ret = pd692x0_send_msg(priv, &msg);
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Failed to reset the configuration (%pe)\n",
+			ERR_PTR(ret));
+		goto out;
+	}
+
+	msleep(100); /* Sleep 100ms as described in the datasheet */
+
+	ret = i2c_master_recv(priv->client, (u8 *)&buf, sizeof(buf));
+	if (ret != sizeof(buf)) {
+		if (ret >= 0)
+			ret = -EIO;
+		goto out;
+	}
+
+	ret = pd692x0_hw_conf_init(priv);
+	if (ret) {
+		dev_err(&priv->client->dev,
+			"Error configuring ports matrix (%pe)\n",
+			ERR_PTR(ret));
+	}
+
+out:
+	mutex_unlock(&priv->pcdev.lock);
+	return ret;
+}
+
+static const struct devlink_ops pd692x0_dl_ops = {
+	.conf_save = pd692x0_dl_conf_save,
+	.conf_reset = pd692x0_dl_conf_reset,
+};
+
 static int pd692x0_i2c_probe(struct i2c_client *client)
 {
 	static const char * const regulators[] = { "vdd", "vdda" };
 	struct pd692x0_msg msg, buf = {0}, zero = {0};
+	struct pd692x0_devlink *pd692x0_dl;
 	struct device *dev = &client->dev;
 	struct pd692x0_msg_ver ver;
 	struct pd692x0_priv *priv;
 	struct fw_upload *fwl;
+	struct devlink *dl;
 	int ret;
 
 	ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators),
@@ -1793,6 +1926,9 @@ static int pd692x0_i2c_probe(struct i2c_client *client)
 		}
 	}
 
+	if (buf.data[2] == PD692X0_USER_BYTE)
+		priv->cfg_saved = true;
+
 	priv->np = dev->of_node;
 	priv->pcdev.nr_lines = PD692X0_MAX_PIS;
 	priv->pcdev.owner = THIS_MODULE;
@@ -1813,7 +1949,24 @@ static int pd692x0_i2c_probe(struct i2c_client *client)
 				     "failed to register to the Firmware Upload API\n");
 	priv->fwl = fwl;
 
+	dl = devlink_alloc(&pd692x0_dl_ops, sizeof(*pd692x0_dl), dev);
+	if (!dl) {
+		dev_err(dev, "devlink_alloc failed\n");
+		ret = -ENOMEM;
+		goto err_unregister_fw;
+	}
+
+	pd692x0_dl = devlink_priv(dl);
+	pd692x0_dl->priv = priv;
+	priv->dl = dl;
+	devlink_register(dl);
+
 	return 0;
+
+err_unregister_fw:
+	firmware_upload_unregister(priv->fwl);
+
+	return ret;
 }
 
 static void pd692x0_i2c_remove(struct i2c_client *client)
@@ -1821,6 +1974,7 @@ static void pd692x0_i2c_remove(struct i2c_client *client)
 	struct pd692x0_priv *priv = i2c_get_clientdata(client);
 
 	pd692x0_managers_free_pw_budget(priv);
+	devlink_unregister(priv->dl);
 	firmware_upload_unregister(priv->fwl);
 }
 

-- 
2.43.0


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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
                   ` (4 preceding siblings ...)
  2025-09-15 17:06 ` [PATCH net-next v3 5/5] net: pse-pd: pd692x0: Add devlink interface for configuration save/reset Kory Maincent
@ 2025-09-16 23:54 ` Jakub Kicinski
  2025-09-17  9:46   ` Kory Maincent
  2025-09-17  0:20 ` patchwork-bot+netdevbpf
  6 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2025-09-16 23:54 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson

On Mon, 15 Sep 2025 19:06:25 +0200 Kory Maincent wrote:
> This patch series introduces a new devlink-conf uAPI to manage device
> configuration stored in non-volatile memory. This provides a standardized
> interface for devices that need to persist configuration changes across
> reboots. The uAPI is designed to be generic and can be used by any device
> driver that manages persistent configuration storage.
> 
> The permanent configuration allows settings to persist across device
> resets and power cycles, providing better control over PSE behavior
> in production environments.

I'm still unclear on the technical justification for this.
"There's a tool in another project which does it this way"
is not usually sufficient upstream. For better or worse we
like to re-implement things from first principles.

Could you succinctly explain why "saving config" can't be implemented
by some user space dumping out ethtool configuration, saving it under
/etc, and using that config after reboot. A'la iptables-save /
iptables-restore?

(I'll apply patch 3 now, looks like a nice cleanup)

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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
                   ` (5 preceding siblings ...)
  2025-09-16 23:54 ` [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Jakub Kicinski
@ 2025-09-17  0:20 ` patchwork-bot+netdevbpf
  6 siblings, 0 replies; 13+ messages in thread
From: patchwork-bot+netdevbpf @ 2025-09-17  0:20 UTC (permalink / raw)
  To: Kory Maincent
  Cc: o.rempel, andrew+netdev, davem, edumazet, kuba, pabeni, jiri,
	horms, corbet, donald.hunter, kernel, dentproject,
	thomas.petazzoni, netdev, linux-kernel, maxime.chevallier,
	linux-doc, kyle.swenson

Hello:

This series was applied to netdev/net-next.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Mon, 15 Sep 2025 19:06:25 +0200 you wrote:
> From: Kory Maincent (Dent Project) <kory.maincent@bootlin.com>
> 
> This patch series introduces a new devlink-conf uAPI to manage device
> configuration stored in non-volatile memory. This provides a standardized
> interface for devices that need to persist configuration changes across
> reboots. The uAPI is designed to be generic and can be used by any device
> driver that manages persistent configuration storage.
> 
> [...]

Here is the summary with links:
  - [net-next,v3,1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls
    (no matching commit)
  - [net-next,v3,2/5] net: pse-pd: pd692x0: Separate configuration parsing from hardware setup
    (no matching commit)
  - [net-next,v3,3/5] docs: devlink: Sort table of contents alphabetically
    https://git.kernel.org/netdev/net-next/c/7cfbe1c3397c
  - [net-next,v3,4/5] devlink: Add devlink-conf uAPI for NV memory management
    (no matching commit)
  - [net-next,v3,5/5] net: pse-pd: pd692x0: Add devlink interface for configuration save/reset
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-16 23:54 ` [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Jakub Kicinski
@ 2025-09-17  9:46   ` Kory Maincent
  2025-09-17 21:19     ` Jakub Kicinski
  0 siblings, 1 reply; 13+ messages in thread
From: Kory Maincent @ 2025-09-17  9:46 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson

On Tue, 16 Sep 2025 16:54:40 -0700
Jakub Kicinski <kuba@kernel.org> wrote:

> On Mon, 15 Sep 2025 19:06:25 +0200 Kory Maincent wrote:
> > This patch series introduces a new devlink-conf uAPI to manage device
> > configuration stored in non-volatile memory. This provides a standardized
> > interface for devices that need to persist configuration changes across
> > reboots. The uAPI is designed to be generic and can be used by any device
> > driver that manages persistent configuration storage.
> > 
> > The permanent configuration allows settings to persist across device
> > resets and power cycles, providing better control over PSE behavior
> > in production environments.  
> 
> I'm still unclear on the technical justification for this.
> "There's a tool in another project which does it this way"
> is not usually sufficient upstream. For better or worse we
> like to re-implement things from first principles.
> 
> Could you succinctly explain why "saving config" can't be implemented
> by some user space dumping out ethtool configuration, saving it under
> /etc, and using that config after reboot. A'la iptables-save /
> iptables-restore?

I think the only reason to save the config in the NVM instead of the userspace
is to improve boot time. As Oleksij described:
> I can confirm a field case from industrial/medical gear. Closed system,
> several modules on SPE, PoDL for power. Requirement: power the PDs as
> early as possible, even before Linux. The box boots faster if power-up
> and Linux init run in parallel. In this setup the power-on state is
> pre-designed by the product team and should not be changed by Linux at
> runtime.

He told me that he also had added support for switches in Barebox for the
same reason, the boot time. I don't know if it is a reasonable reason to add it
in Linux.

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

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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-17  9:46   ` Kory Maincent
@ 2025-09-17 21:19     ` Jakub Kicinski
  2025-09-22 16:20       ` Kory Maincent
  0 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2025-09-17 21:19 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson

On Wed, 17 Sep 2025 11:46:55 +0200 Kory Maincent wrote:
> > On Mon, 15 Sep 2025 19:06:25 +0200 Kory Maincent wrote:  
> > > This patch series introduces a new devlink-conf uAPI to manage device
> > > configuration stored in non-volatile memory. This provides a standardized
> > > interface for devices that need to persist configuration changes across
> > > reboots. The uAPI is designed to be generic and can be used by any device
> > > driver that manages persistent configuration storage.
> > > 
> > > The permanent configuration allows settings to persist across device
> > > resets and power cycles, providing better control over PSE behavior
> > > in production environments.    
> > 
> > I'm still unclear on the technical justification for this.
> > "There's a tool in another project which does it this way"
> > is not usually sufficient upstream. For better or worse we
> > like to re-implement things from first principles.
> > 
> > Could you succinctly explain why "saving config" can't be implemented
> > by some user space dumping out ethtool configuration, saving it under
> > /etc, and using that config after reboot. A'la iptables-save /
> > iptables-restore?  
> 
> I think the only reason to save the config in the NVM instead of the userspace
> is to improve boot time. As Oleksij described:
> > I can confirm a field case from industrial/medical gear. Closed system,
> > several modules on SPE, PoDL for power. Requirement: power the PDs as
> > early as possible, even before Linux. The box boots faster if power-up
> > and Linux init run in parallel. In this setup the power-on state is
> > pre-designed by the product team and should not be changed by Linux at
> > runtime.  
> 
> He told me that he also had added support for switches in Barebox for the
> same reason, the boot time. I don't know if it is a reasonable reason to add it
> in Linux.

Right, subjectively I focused on the last sentence of Oleksij's reply.
I vote we leave it out for now.

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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-17 21:19     ` Jakub Kicinski
@ 2025-09-22 16:20       ` Kory Maincent
  2025-09-22 18:02         ` Jakub Kicinski
  0 siblings, 1 reply; 13+ messages in thread
From: Kory Maincent @ 2025-09-22 16:20 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson,
	Luka Perkov, Robert Marko, Sridhar Rao

Hello Jakub,

On Wed, 17 Sep 2025 14:19:12 -0700
Jakub Kicinski <kuba@kernel.org> wrote:

> On Wed, 17 Sep 2025 11:46:55 +0200 Kory Maincent wrote:
> > > On Mon, 15 Sep 2025 19:06:25 +0200 Kory Maincent wrote:    
>  [...]  
> > > 
> > > I'm still unclear on the technical justification for this.
> > > "There's a tool in another project which does it this way"
> > > is not usually sufficient upstream. For better or worse we
> > > like to re-implement things from first principles.
> > > 
> > > Could you succinctly explain why "saving config" can't be implemented
> > > by some user space dumping out ethtool configuration, saving it under
> > > /etc, and using that config after reboot. A'la iptables-save /
> > > iptables-restore?    
> > 
> > I think the only reason to save the config in the NVM instead of the
> > userspace is to improve boot time. As Oleksij described:  
> > > I can confirm a field case from industrial/medical gear. Closed system,
> > > several modules on SPE, PoDL for power. Requirement: power the PDs as
> > > early as possible, even before Linux. The box boots faster if power-up
> > > and Linux init run in parallel. In this setup the power-on state is
> > > pre-designed by the product team and should not be changed by Linux at
> > > runtime.    
> > 
> > He told me that he also had added support for switches in Barebox for the
> > same reason, the boot time. I don't know if it is a reasonable reason to
> > add it in Linux.  
> 
> Right, subjectively I focused on the last sentence of Oleksij's reply.
> I vote we leave it out for now.

I would like to restart the discussion as I have one more argument besides the
boot time optimization coming from Luka Perkov in CC.

According to him, not having this feature supported also brings an issue across
reboot:
"When a network switch reboots, any devices receiving Power over
Ethernet (PoE) from that switch will lose power unless the PoE
configuration is persisted across the reboot cycle. This creates a
significant operational impact: WiFi access points and other
PoE-powered devices will experience an unplanned hard power loss,
forcing them offline without any opportunity for graceful shutdown.

The critical issue is not the impact on the switch itself, but rather
the cascading effect on all dependent infrastructure. Without
kernel-level persistence of PoE settings, a simple switch reboot
(whether for maintenance, updates, or recovery) forces all connected
PoE devices into an abrupt power cycle. This results in extended
downtime as these devices must complete their full boot sequence once
power is restored, rather than remaining operational throughout the
switch's reboot process."

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

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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-22 16:20       ` Kory Maincent
@ 2025-09-22 18:02         ` Jakub Kicinski
  2025-09-23  9:04           ` Kory Maincent
  0 siblings, 1 reply; 13+ messages in thread
From: Jakub Kicinski @ 2025-09-22 18:02 UTC (permalink / raw)
  To: Kory Maincent
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson,
	Luka Perkov, Robert Marko, Sridhar Rao

On Mon, 22 Sep 2025 18:20:02 +0200 Kory Maincent wrote:
> > > I think the only reason to save the config in the NVM instead of the
> > > userspace is to improve boot time. As Oleksij described:    
> > > 
> > > He told me that he also had added support for switches in Barebox for the
> > > same reason, the boot time. I don't know if it is a reasonable reason to
> > > add it in Linux.    
> > 
> > Right, subjectively I focused on the last sentence of Oleksij's reply.
> > I vote we leave it out for now.  
> 
> I would like to restart the discussion as I have one more argument besides the
> boot time optimization coming from Luka Perkov in CC.
> 
> According to him, not having this feature supported also brings an issue across
> reboot:
> "When a network switch reboots, any devices receiving Power over
> Ethernet (PoE) from that switch will lose power unless the PoE
> configuration is persisted across the reboot cycle. This creates a
> significant operational impact: WiFi access points and other
> PoE-powered devices will experience an unplanned hard power loss,
> forcing them offline without any opportunity for graceful shutdown.
> 
> The critical issue is not the impact on the switch itself, but rather
> the cascading effect on all dependent infrastructure. Without
> kernel-level persistence of PoE settings, a simple switch reboot
> (whether for maintenance, updates, or recovery) forces all connected
> PoE devices into an abrupt power cycle. This results in extended
> downtime as these devices must complete their full boot sequence once
> power is restored, rather than remaining operational throughout the
> switch's reboot process."

Any sort of hot reset that maintains the pre-existing configuration 
and doesn't issue resets is orthogonal to storing the configuration
into the flash.

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

* Re: [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support
  2025-09-22 18:02         ` Jakub Kicinski
@ 2025-09-23  9:04           ` Kory Maincent
  0 siblings, 0 replies; 13+ messages in thread
From: Kory Maincent @ 2025-09-23  9:04 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Oleksij Rempel, Andrew Lunn, David S. Miller, Eric Dumazet,
	Paolo Abeni, Jiri Pirko, Simon Horman, Jonathan Corbet,
	Donald Hunter, kernel, Dent Project, Thomas Petazzoni, netdev,
	linux-kernel, Maxime Chevallier, linux-doc, Kyle Swenson,
	Luka Perkov, Robert Marko, Sridhar Rao

On Mon, 22 Sep 2025 11:02:20 -0700
Jakub Kicinski <kuba@kernel.org> wrote:

> On Mon, 22 Sep 2025 18:20:02 +0200 Kory Maincent wrote:
>  [...]  
> > > 
> > > Right, subjectively I focused on the last sentence of Oleksij's reply.
> > > I vote we leave it out for now.    
> > 
> > I would like to restart the discussion as I have one more argument besides
> > the boot time optimization coming from Luka Perkov in CC.
> > 
> > According to him, not having this feature supported also brings an issue
> > across reboot:
> > "When a network switch reboots, any devices receiving Power over
> > Ethernet (PoE) from that switch will lose power unless the PoE
> > configuration is persisted across the reboot cycle. This creates a
> > significant operational impact: WiFi access points and other
> > PoE-powered devices will experience an unplanned hard power loss,
> > forcing them offline without any opportunity for graceful shutdown.
> > 
> > The critical issue is not the impact on the switch itself, but rather
> > the cascading effect on all dependent infrastructure. Without
> > kernel-level persistence of PoE settings, a simple switch reboot
> > (whether for maintenance, updates, or recovery) forces all connected
> > PoE devices into an abrupt power cycle. This results in extended
> > downtime as these devices must complete their full boot sequence once
> > power is restored, rather than remaining operational throughout the
> > switch's reboot process."  
> 
> Any sort of hot reset that maintains the pre-existing configuration 
> and doesn't issue resets is orthogonal to storing the configuration
> into the flash.

Indeed if the switch reboot and the PSE lose its power supply, the devices will
in any cases face a power loss. While if the PSE does not lose its power the
configuration won't be reset whether there is a permanent configuration or
not. We just need to detect during the boot if the port matrix has already
been flashed to not reconfigure all the ports.  
This argument is indeed not relevant.

Luka any other arguments in favor of permanent configuration support?

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

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

end of thread, other threads:[~2025-09-23  9:05 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-15 17:06 [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Kory Maincent
2025-09-15 17:06 ` [PATCH net-next v3 1/5] net: pse-pd: pd692x0: Replace __free macro with explicit kfree calls Kory Maincent
2025-09-15 17:06 ` [PATCH net-next v3 2/5] net: pse-pd: pd692x0: Separate configuration parsing from hardware setup Kory Maincent
2025-09-15 17:06 ` [PATCH net-next v3 3/5] docs: devlink: Sort table of contents alphabetically Kory Maincent
2025-09-15 17:06 ` [PATCH net-next v3 4/5] devlink: Add devlink-conf uAPI for NV memory management Kory Maincent
2025-09-15 17:06 ` [PATCH net-next v3 5/5] net: pse-pd: pd692x0: Add devlink interface for configuration save/reset Kory Maincent
2025-09-16 23:54 ` [PATCH net-next v3 0/5] net: pse-pd: pd692x0: Add permanent configuration management support Jakub Kicinski
2025-09-17  9:46   ` Kory Maincent
2025-09-17 21:19     ` Jakub Kicinski
2025-09-22 16:20       ` Kory Maincent
2025-09-22 18:02         ` Jakub Kicinski
2025-09-23  9:04           ` Kory Maincent
2025-09-17  0:20 ` patchwork-bot+netdevbpf

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).