All of lore.kernel.org
 help / color / mirror / Atom feed
* [net-next v4 0/5] devlink flash update overwrite mask
@ 2020-09-09 22:26 Jacob Keller
  2020-09-09 22:26 ` [net-next v4 1/5] devlink: check flash_update parameter support in net core Jacob Keller
                   ` (5 more replies)
  0 siblings, 6 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev
  Cc: Jacob Keller, Jiri Pirko, Jakub Kicinski, Jonathan Corbet,
	Michael Chan, Bin Luo, Saeed Mahameed, Leon Romanovsky,
	Ido Schimmel, Danielle Ratson

This series introduces support for a new attribute to the flash update
command: DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK.

This attribute is a bitfield which allows userspace to specify what set of
subfields to overwrite when performing a flash update for a device.

The intention is to support the ability to control the behavior of
overwriting the configuration and identifying fields in the Intel ice device
flash update process. This is necessary  as the firmware layout for the ice
device includes some settings and configuration within the same flash
section as the main firmware binary.

This series, and the accompanying iproute2 series, introduce support for the
attribute. Once applied, the overwrite support can be be invoked via
devlink:

  # overwrite settings
  devlink dev flash pci/0000:af:00.0 file firmware.bin overwrite settings

  # overwrite identifiers and settings
  devlink dev flash pci/0000:af:00.0 file firmware.bin overwrite settings overwrite identifiers

To aid in the safe addition of new parameters, first some refactoring is
done to the .flash_update function: its parameters are converted from a
series of function arguments into a structure. This makes it easier to add
the new parameter without changing the signature of the .flash_update
handler in the future. Additionally, a "supported_flash_update_params" field
is added to devlink_ops. This field is similar to the ethtool
"supported_coalesc_params" field. The devlink core will now check that the
DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT bit is set before forwarding the
component attribute. Similarly, the new overwrite attribute will also
require a supported bit.

Doing these refactors will aid in adding any other attributes in the future,
and creates a good pattern for other interfaces to use in the future. By
requiring drivers to opt-in, we reduce the risk of accidentally breaking
drivers when ever we add an additional parameter. We also reduce boiler
plate code in drivers which do not support the parameters.

Cc: Jiri Pirko <jiri@mellanox.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael Chan <michael.chan@broadcom.com>
Cc: Bin Luo <luobin9@huawei.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Ido Schimmel <idosch@mellanox.com>
Cc: Danielle Ratson <danieller@mellanox.com>

Changes since v3:
* split netdevsim changes to a new patch
* fixed a minor typo in the documentation
* sent iproute2 patches completely separately

Jacob Keller (5):
  devlink: check flash_update parameter support in net core
  devlink: convert flash_update to use params structure
  devlink: introduce flash update overwrite mask
  devlink: add support for overwrite mask to netdevsim
  ice: add support for flash update overwrite mask

 .../networking/devlink/devlink-flash.rst      | 28 +++++++++++++
 Documentation/networking/devlink/ice.rst      | 31 ++++++++++++++
 .../net/ethernet/broadcom/bnxt/bnxt_devlink.c | 19 ++++-----
 .../net/ethernet/huawei/hinic/hinic_devlink.c |  8 +---
 drivers/net/ethernet/intel/ice/ice_devlink.c  | 34 ++++++++++-----
 .../net/ethernet/intel/ice/ice_fw_update.c    | 16 ++++++-
 .../net/ethernet/intel/ice/ice_fw_update.h    |  2 +-
 .../net/ethernet/mellanox/mlx5/core/devlink.c |  8 +---
 drivers/net/ethernet/mellanox/mlxsw/core.c    |  6 +--
 drivers/net/ethernet/mellanox/mlxsw/core.h    |  2 +-
 .../net/ethernet/mellanox/mlxsw/spectrum.c    |  7 +---
 .../net/ethernet/netronome/nfp/nfp_devlink.c  |  9 ++--
 drivers/net/netdevsim/dev.c                   | 21 +++++++---
 drivers/net/netdevsim/netdevsim.h             |  1 +
 include/net/devlink.h                         | 35 +++++++++++++++-
 include/uapi/linux/devlink.h                  | 25 +++++++++++
 net/core/devlink.c                            | 42 +++++++++++++++----
 .../drivers/net/netdevsim/devlink.sh          | 21 ++++++++++
 18 files changed, 247 insertions(+), 68 deletions(-)


base-commit: b599a5b9e16698424bced2429e935bee056dcf88
-- 
2.28.0.218.ge27853923b9d.dirty


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

* [net-next v4 1/5] devlink: check flash_update parameter support in net core
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
@ 2020-09-09 22:26 ` Jacob Keller
  2020-09-10  0:53   ` Jakub Kicinski
  2020-09-09 22:26 ` [net-next v4 2/5] devlink: convert flash_update to use params structure Jacob Keller
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev
  Cc: Jacob Keller, Jiri Pirko, Jakub Kicinski, Jonathan Corbet,
	Michael Chan, Bin Luo, Saeed Mahameed, Leon Romanovsky,
	Ido Schimmel, Danielle Ratson

When implementing .flash_update, drivers which do not support
per-component update are manually checking the component parameter to
verify that it is NULL. Without this check, the driver might accept an
update request with a component specified even though it will not honor
such a request.

Instead of having each driver check this, move the logic into
net/core/devlink.c, and use a new `supported_flash_update_params` field
in the devlink_ops. Drivers which will support per-component update must
now specify this by setting DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT in
the supported_flash_update_params in their devlink_ops.

This helps ensure that drivers do not forget to check for a NULL
component if they do not support per-component update. This also enables
a slightly better error message by enabling the core stack to set the
netlink bad attribute message to indicate precisely the unsupported
attribute in the message.

Going forward, any new additional parameter to flash update will require
a bit in the supported_flash_update_params bitfield.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Jiri Pirko <jiri@mellanox.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael Chan <michael.chan@broadcom.com>
Cc: Bin Luo <luobin9@huawei.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Ido Schimmel <idosch@mellanox.com>
Cc: Danielle Ratson <danieller@mellanox.com>
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c | 12 +++---------
 drivers/net/ethernet/huawei/hinic/hinic_devlink.c |  3 ---
 drivers/net/ethernet/intel/ice/ice_devlink.c      |  9 ++-------
 drivers/net/ethernet/mellanox/mlx5/core/devlink.c |  3 ---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c    |  3 ---
 drivers/net/ethernet/netronome/nfp/nfp_devlink.c  |  2 --
 drivers/net/netdevsim/dev.c                       |  1 +
 include/net/devlink.h                             | 15 +++++++++++++++
 net/core/devlink.c                                | 15 +++++++++++++--
 9 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index 3a854195d5b0..a17764db1419 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -23,9 +23,6 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename,
 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
 	int rc;
 
-	if (region)
-		return -EOPNOTSUPP;
-
 	if (!BNXT_PF(bp)) {
 		NL_SET_ERR_MSG_MOD(extack,
 				   "flash update not supported from a VF");
@@ -33,15 +30,12 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename,
 	}
 
 	devlink_flash_update_begin_notify(dl);
-	devlink_flash_update_status_notify(dl, "Preparing to flash", region, 0,
-					   0);
+	devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
 	rc = bnxt_flash_package_from_file(bp->dev, filename, 0);
 	if (!rc)
-		devlink_flash_update_status_notify(dl, "Flashing done", region,
-						   0, 0);
+		devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
 	else
-		devlink_flash_update_status_notify(dl, "Flashing failed",
-						   region, 0, 0);
+		devlink_flash_update_status_notify(dl, "Flashing failed", NULL, 0, 0);
 	devlink_flash_update_end_notify(dl);
 	return rc;
 }
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
index 16bda7381ba0..662a27a514ae 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
@@ -289,9 +289,6 @@ static int hinic_devlink_flash_update(struct devlink *devlink,
 	const struct firmware *fw;
 	int err;
 
-	if (component)
-		return -EOPNOTSUPP;
-
 	err = request_firmware_direct(&fw, file_name,
 				      &priv->hwdev->hwif->pdev->dev);
 	if (err)
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
index 111d6bfe4222..6cdccd901637 100644
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -252,16 +252,12 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
 	const struct firmware *fw;
 	int err;
 
-	/* individual component update is not yet supported */
-	if (component)
-		return -EOPNOTSUPP;
-
 	if (!hw->dev_caps.common_cap.nvm_unified_update) {
 		NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update");
 		return -EOPNOTSUPP;
 	}
 
-	err = ice_check_for_pending_update(pf, component, extack);
+	err = ice_check_for_pending_update(pf, NULL, extack);
 	if (err)
 		return err;
 
@@ -272,8 +268,7 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
 	}
 
 	devlink_flash_update_begin_notify(devlink);
-	devlink_flash_update_status_notify(devlink, "Preparing to flash",
-					   component, 0, 0);
+	devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0);
 	err = ice_flash_pldm_image(pf, fw, extack);
 	devlink_flash_update_end_notify(devlink);
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index c709e9a385f6..fccae4b802b6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -16,9 +16,6 @@ static int mlx5_devlink_flash_update(struct devlink *devlink,
 	const struct firmware *fw;
 	int err;
 
-	if (component)
-		return -EOPNOTSUPP;
-
 	err = request_firmware_direct(&fw, file_name, &dev->pdev->dev);
 	if (err)
 		return err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 4186e29119c2..eaa82ef3bd68 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -425,9 +425,6 @@ static int mlxsw_sp_flash_update(struct mlxsw_core *mlxsw_core,
 	const struct firmware *firmware;
 	int err;
 
-	if (component)
-		return -EOPNOTSUPP;
-
 	err = request_firmware_direct(&firmware, file_name,
 				      mlxsw_sp->bus_info->dev);
 	if (err)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index be52510d446b..c93cb9a27e25 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -332,8 +332,6 @@ static int
 nfp_devlink_flash_update(struct devlink *devlink, const char *path,
 			 const char *component, struct netlink_ext_ack *extack)
 {
-	if (component)
-		return -EOPNOTSUPP;
 	return nfp_flash_update_common(devlink_priv(devlink), path, extack);
 }
 
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 32f339fedb21..1219637ab36e 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -875,6 +875,7 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
 }
 
 static const struct devlink_ops nsim_dev_devlink_ops = {
+	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
 	.reload_down = nsim_dev_reload_down,
 	.reload_up = nsim_dev_reload_up,
 	.info_get = nsim_dev_info_get,
diff --git a/include/net/devlink.h b/include/net/devlink.h
index eaec0a8cc5ef..15b32c9e6bfc 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -531,6 +531,8 @@ enum devlink_param_generic_id {
 /* Firmware bundle identifier */
 #define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID	"fw.bundle_id"
 
+#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT	BIT(0)
+
 struct devlink_region;
 struct devlink_info_req;
 
@@ -1011,6 +1013,12 @@ enum devlink_trap_group_generic_id {
 	}
 
 struct devlink_ops {
+	/**
+	 * @supported_flash_update_params:
+	 * mask of parameters supported by the driver's .flash_update
+	 * implemementation.
+	 */
+	u32 supported_flash_update_params;
 	int (*reload_down)(struct devlink *devlink, bool netns_change,
 			   struct netlink_ext_ack *extack);
 	int (*reload_up)(struct devlink *devlink,
@@ -1071,6 +1079,13 @@ struct devlink_ops {
 				      struct netlink_ext_ack *extack);
 	int (*info_get)(struct devlink *devlink, struct devlink_info_req *req,
 			struct netlink_ext_ack *extack);
+	/**
+	 * @flash_update: Device flash update function
+	 *
+	 * Used to perform a flash update for the device. The set of
+	 * parameters supported by the driver should be set in
+	 * supported_flash_update_params.
+	 */
 	int (*flash_update)(struct devlink *devlink, const char *file_name,
 			    const char *component,
 			    struct netlink_ext_ack *extack);
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 91c12612f2b7..7442194814db 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3125,18 +3125,29 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 				       struct genl_info *info)
 {
 	struct devlink *devlink = info->user_ptr[0];
-	const char *file_name, *component;
+	const char *file_name, *component = NULL;
 	struct nlattr *nla_component;
+	u32 supported_params;
 
 	if (!devlink->ops->flash_update)
 		return -EOPNOTSUPP;
 
 	if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
 		return -EINVAL;
+
+	supported_params = devlink->ops->supported_flash_update_params;
+
 	file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
 
 	nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
-	component = nla_component ? nla_data(nla_component) : NULL;
+	if (nla_component) {
+		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) {
+			NL_SET_ERR_MSG_ATTR(info->extack, nla_component,
+					    "component update is not supported");
+			return -EOPNOTSUPP;
+		}
+		component = nla_data(nla_component);
+	}
 
 	return devlink->ops->flash_update(devlink, file_name, component,
 					  info->extack);
-- 
2.28.0.218.ge27853923b9d.dirty


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

* [net-next v4 2/5] devlink: convert flash_update to use params structure
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
  2020-09-09 22:26 ` [net-next v4 1/5] devlink: check flash_update parameter support in net core Jacob Keller
@ 2020-09-09 22:26 ` Jacob Keller
  2020-09-10  0:55   ` Jakub Kicinski
  2020-09-09 22:26 ` [net-next v4 3/5] devlink: introduce flash update overwrite mask Jacob Keller
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev
  Cc: Jacob Keller, Jiri Pirko, Jakub Kicinski, Jonathan Corbet,
	Michael Chan, Bin Luo, Saeed Mahameed, Leon Romanovsky,
	Ido Schimmel, Danielle Ratson

The devlink core recently gained support for checking whether the driver
supports a flash_update parameter, via `supported_flash_update_params`.
However, parameters are specified as function arguments. Adding a new
parameter still requires modifying the signature of the .flash_update
callback in all drivers.

Convert the .flash_update function to take a new `struct
devlink_flash_update_params` instead. By using this structure, and the
`supported_flash_update_params` bit field, a new parameter to
flash_update can be added without requiring modification to existing
drivers.

As before, all parameters except file_name will require driver opt-in.
Because file_name is a necessary field to for the flash_update to make
sense, no "SUPPORTED" bitflag is provided and it is always considered
valid. All future additional parameters will require a new bit in the
supported_flash_update_params bitfield.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Cc: Jiri Pirko <jiri@mellanox.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Michael Chan <michael.chan@broadcom.com>
Cc: Bin Luo <luobin9@huawei.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Ido Schimmel <idosch@mellanox.com>
Cc: Danielle Ratson <danieller@mellanox.com>
---
 .../net/ethernet/broadcom/bnxt/bnxt_devlink.c  |  7 ++++---
 .../net/ethernet/huawei/hinic/hinic_devlink.c  |  5 ++---
 drivers/net/ethernet/intel/ice/ice_devlink.c   | 10 +++++-----
 .../net/ethernet/mellanox/mlx5/core/devlink.c  |  5 ++---
 drivers/net/ethernet/mellanox/mlxsw/core.c     |  6 ++----
 drivers/net/ethernet/mellanox/mlxsw/core.h     |  2 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c |  4 ++--
 .../net/ethernet/netronome/nfp/nfp_devlink.c   |  7 ++++---
 drivers/net/netdevsim/dev.c                    | 12 ++++++------
 include/net/devlink.h                          | 18 ++++++++++++++++--
 net/core/devlink.c                             | 14 ++++++++------
 .../selftests/drivers/net/netdevsim/devlink.sh |  3 +++
 12 files changed, 55 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
index a17764db1419..d436134bdc40 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
@@ -17,8 +17,9 @@
 #include "bnxt_ethtool.h"
 
 static int
-bnxt_dl_flash_update(struct devlink *dl, const char *filename,
-		     const char *region, struct netlink_ext_ack *extack)
+bnxt_dl_flash_update(struct devlink *dl,
+		     struct devlink_flash_update_params *params,
+		     struct netlink_ext_ack *extack)
 {
 	struct bnxt *bp = bnxt_get_bp_from_dl(dl);
 	int rc;
@@ -31,7 +32,7 @@ bnxt_dl_flash_update(struct devlink *dl, const char *filename,
 
 	devlink_flash_update_begin_notify(dl);
 	devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
-	rc = bnxt_flash_package_from_file(bp->dev, filename, 0);
+	rc = bnxt_flash_package_from_file(bp->dev, params->file_name, 0);
 	if (!rc)
 		devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
 	else
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
index 662a27a514ae..2630d667f393 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c
@@ -281,15 +281,14 @@ static int hinic_firmware_update(struct hinic_devlink_priv *priv,
 }
 
 static int hinic_devlink_flash_update(struct devlink *devlink,
-				      const char *file_name,
-				      const char *component,
+				      struct devlink_flash_update_params *params,
 				      struct netlink_ext_ack *extack)
 {
 	struct hinic_devlink_priv *priv = devlink_priv(devlink);
 	const struct firmware *fw;
 	int err;
 
-	err = request_firmware_direct(&fw, file_name,
+	err = request_firmware_direct(&fw, params->file_name,
 				      &priv->hwdev->hwif->pdev->dev);
 	if (err)
 		return err;
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
index 6cdccd901637..4f8f9e229080 100644
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -233,8 +233,7 @@ static int ice_devlink_info_get(struct devlink *devlink,
 /**
  * ice_devlink_flash_update - Update firmware stored in flash on the device
  * @devlink: pointer to devlink associated with device to update
- * @path: the path of the firmware file to use via request_firmware
- * @component: name of the component to update, or NULL
+ * @params: flash update parameters
  * @extack: netlink extended ACK structure
  *
  * Perform a device flash update. The bulk of the update logic is contained
@@ -243,8 +242,9 @@ static int ice_devlink_info_get(struct devlink *devlink,
  * Returns: zero on success, or an error code on failure.
  */
 static int
-ice_devlink_flash_update(struct devlink *devlink, const char *path,
-			 const char *component, struct netlink_ext_ack *extack)
+ice_devlink_flash_update(struct devlink *devlink,
+			 struct devlink_flash_update_params *params,
+			 struct netlink_ext_ack *extack)
 {
 	struct ice_pf *pf = devlink_priv(devlink);
 	struct device *dev = &pf->pdev->dev;
@@ -261,7 +261,7 @@ ice_devlink_flash_update(struct devlink *devlink, const char *path,
 	if (err)
 		return err;
 
-	err = request_firmware(&fw, path, dev);
+	err = request_firmware(&fw, params->file_name, dev);
 	if (err) {
 		NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk");
 		return err;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
index fccae4b802b6..9b14e3f805a2 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/devlink.c
@@ -8,15 +8,14 @@
 #include "eswitch.h"
 
 static int mlx5_devlink_flash_update(struct devlink *devlink,
-				     const char *file_name,
-				     const char *component,
+				     struct devlink_flash_update_params *params,
 				     struct netlink_ext_ack *extack)
 {
 	struct mlx5_core_dev *dev = devlink_priv(devlink);
 	const struct firmware *fw;
 	int err;
 
-	err = request_firmware_direct(&fw, file_name, &dev->pdev->dev);
+	err = request_firmware_direct(&fw, params->file_name, &dev->pdev->dev);
 	if (err)
 		return err;
 
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index ec45a03140d7..efe39011cd94 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1138,8 +1138,7 @@ mlxsw_devlink_core_bus_device_reload_up(struct devlink *devlink,
 }
 
 static int mlxsw_devlink_flash_update(struct devlink *devlink,
-				      const char *file_name,
-				      const char *component,
+				      struct devlink_flash_update_params *params,
 				      struct netlink_ext_ack *extack)
 {
 	struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
@@ -1147,8 +1146,7 @@ static int mlxsw_devlink_flash_update(struct devlink *devlink,
 
 	if (!mlxsw_driver->flash_update)
 		return -EOPNOTSUPP;
-	return mlxsw_driver->flash_update(mlxsw_core, file_name,
-					  component, extack);
+	return mlxsw_driver->flash_update(mlxsw_core, params, extack);
 }
 
 static int mlxsw_devlink_trap_init(struct devlink *devlink,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index 11af3308f8cc..9630b2482b22 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -325,7 +325,7 @@ struct mlxsw_driver {
 				       enum devlink_sb_pool_type pool_type,
 				       u32 *p_cur, u32 *p_max);
 	int (*flash_update)(struct mlxsw_core *mlxsw_core,
-			    const char *file_name, const char *component,
+			    struct devlink_flash_update_params *params,
 			    struct netlink_ext_ack *extack);
 	int (*trap_init)(struct mlxsw_core *mlxsw_core,
 			 const struct devlink_trap *trap, void *trap_ctx);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index eaa82ef3bd68..da831e5a2aea 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -418,14 +418,14 @@ static int mlxsw_sp_fw_rev_validate(struct mlxsw_sp *mlxsw_sp)
 }
 
 static int mlxsw_sp_flash_update(struct mlxsw_core *mlxsw_core,
-				 const char *file_name, const char *component,
+				 struct devlink_flash_update_params *params,
 				 struct netlink_ext_ack *extack)
 {
 	struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
 	const struct firmware *firmware;
 	int err;
 
-	err = request_firmware_direct(&firmware, file_name,
+	err = request_firmware_direct(&firmware, params->file_name,
 				      mlxsw_sp->bus_info->dev);
 	if (err)
 		return err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
index c93cb9a27e25..97d2b03208de 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c
@@ -329,10 +329,11 @@ nfp_devlink_info_get(struct devlink *devlink, struct devlink_info_req *req,
 }
 
 static int
-nfp_devlink_flash_update(struct devlink *devlink, const char *path,
-			 const char *component, struct netlink_ext_ack *extack)
+nfp_devlink_flash_update(struct devlink *devlink,
+			 struct devlink_flash_update_params *params,
+			 struct netlink_ext_ack *extack)
 {
-	return nfp_flash_update_common(devlink_priv(devlink), path, extack);
+	return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack);
 }
 
 const struct devlink_ops nfp_devlink_ops = {
diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index 1219637ab36e..ebfc4a698809 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -740,8 +740,8 @@ static int nsim_dev_info_get(struct devlink *devlink,
 #define NSIM_DEV_FLASH_CHUNK_SIZE 1000
 #define NSIM_DEV_FLASH_CHUNK_TIME_MS 10
 
-static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
-				 const char *component,
+static int nsim_dev_flash_update(struct devlink *devlink,
+				 struct devlink_flash_update_params *params,
 				 struct netlink_ext_ack *extack)
 {
 	struct nsim_dev *nsim_dev = devlink_priv(devlink);
@@ -751,13 +751,13 @@ static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
 		devlink_flash_update_begin_notify(devlink);
 		devlink_flash_update_status_notify(devlink,
 						   "Preparing to flash",
-						   component, 0, 0);
+						   params->component, 0, 0);
 	}
 
 	for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) {
 		if (nsim_dev->fw_update_status)
 			devlink_flash_update_status_notify(devlink, "Flashing",
-							   component,
+							   params->component,
 							   i * NSIM_DEV_FLASH_CHUNK_SIZE,
 							   NSIM_DEV_FLASH_SIZE);
 		msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS);
@@ -765,11 +765,11 @@ static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name,
 
 	if (nsim_dev->fw_update_status) {
 		devlink_flash_update_status_notify(devlink, "Flashing",
-						   component,
+						   params->component,
 						   NSIM_DEV_FLASH_SIZE,
 						   NSIM_DEV_FLASH_SIZE);
 		devlink_flash_update_status_notify(devlink, "Flashing done",
-						   component, 0, 0);
+						   params->component, 0, 0);
 		devlink_flash_update_end_notify(devlink);
 	}
 
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 15b32c9e6bfc..3384e901bbf0 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -531,6 +531,20 @@ enum devlink_param_generic_id {
 /* Firmware bundle identifier */
 #define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID	"fw.bundle_id"
 
+/**
+ * struct devlink_flash_update_params - Flash Update parameters
+ * @file_name: the name of the flash firmware file to update from
+ * @component: the flash component to update
+ *
+ * With the exception of file_name, drivers must opt-in to parameters by
+ * setting the appropriate bit in the supported_flash_update_params field in
+ * their devlink_ops structure.
+ */
+struct devlink_flash_update_params {
+	const char *file_name;
+	const char *component;
+};
+
 #define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT	BIT(0)
 
 struct devlink_region;
@@ -1086,8 +1100,8 @@ struct devlink_ops {
 	 * parameters supported by the driver should be set in
 	 * supported_flash_update_params.
 	 */
-	int (*flash_update)(struct devlink *devlink, const char *file_name,
-			    const char *component,
+	int (*flash_update)(struct devlink *devlink,
+			    struct devlink_flash_update_params *params,
 			    struct netlink_ext_ack *extack);
 	/**
 	 * @trap_init: Trap initialization function.
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 7442194814db..c61f9c8205f6 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3124,8 +3124,8 @@ EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 				       struct genl_info *info)
 {
+	struct devlink_flash_update_params params = {};
 	struct devlink *devlink = info->user_ptr[0];
-	const char *file_name, *component = NULL;
 	struct nlattr *nla_component;
 	u32 supported_params;
 
@@ -3137,7 +3137,7 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 
 	supported_params = devlink->ops->supported_flash_update_params;
 
-	file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
+	params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
 
 	nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
 	if (nla_component) {
@@ -3146,11 +3146,10 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 					    "component update is not supported");
 			return -EOPNOTSUPP;
 		}
-		component = nla_data(nla_component);
+		params.component = nla_data(nla_component);
 	}
 
-	return devlink->ops->flash_update(devlink, file_name, component,
-					  info->extack);
+	return devlink->ops->flash_update(devlink, &params, info->extack);
 }
 
 static const struct devlink_param devlink_param_generic[] = {
@@ -9584,6 +9583,7 @@ void devlink_compat_running_version(struct net_device *dev,
 
 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
 {
+	struct devlink_flash_update_params params = {};
 	struct devlink *devlink;
 	int ret;
 
@@ -9596,8 +9596,10 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
 		goto out;
 	}
 
+	params.file_name = file_name;
+
 	mutex_lock(&devlink->lock);
-	ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
+	ret = devlink->ops->flash_update(devlink, &params, NULL);
 	mutex_unlock(&devlink->lock);
 
 out:
diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index de4b32fc4223..1e7541688978 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -23,6 +23,9 @@ fw_flash_test()
 	devlink dev flash $DL_HANDLE file dummy
 	check_err $? "Failed to flash with status updates on"
 
+	devlink dev flash $DL_HANDLE file dummy component fw.mgmt
+	check_err $? "Failed to flash with component attribute"
+
 	echo "n"> $DEBUGFS_DIR/fw_update_status
 	check_err $? "Failed to disable status updates"
 
-- 
2.28.0.218.ge27853923b9d.dirty


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

* [net-next v4 3/5] devlink: introduce flash update overwrite mask
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
  2020-09-09 22:26 ` [net-next v4 1/5] devlink: check flash_update parameter support in net core Jacob Keller
  2020-09-09 22:26 ` [net-next v4 2/5] devlink: convert flash_update to use params structure Jacob Keller
@ 2020-09-09 22:26 ` Jacob Keller
  2020-09-10  1:03   ` Jakub Kicinski
  2020-09-10 20:10   ` Jiri Pirko
  2020-09-09 22:26 ` [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim Jacob Keller
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev; +Cc: Jacob Keller

Sections of device flash may contain settings or device identifying
information. When performing a flash update, it is generally expected
that these settings and identifiers are not overwritten.

However, it may sometimes be useful to allow overwriting these fields
when performing a flash update. Some examples include, 1) customizing
the initial device config on first programming, such as overwriting
default device identifying information, or 2) reverting a device
configuration to known good state provided in the new firmware image, or
3) in case it is suspected that current firmware logic for managing the
preservation of fields during an update is broken.

Although some devices are able to completely separate these types of
settings and fields into separate components, this is not true for all
hardware.

To support controlling this behavior, a new
DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK is defined. This is an
nla_bitfield32 which will define what subset of fields in a component
should be overwritten during an update.

If no bits are specified, or of the overwrite mask is not provided, then
an update should not overwrite anything, and should maintain the
settings and identifiers as they are in the previous image.

If the overwrite mask has the DEVLINK_FLASH_OVERWRITE_SETTINGS bit set,
then the device should be configured to overwrite any of the settings in
the requested component with settings found in the provided image.

Similarly, if the DEVLINK_FLASH_OVERWRITE_IDENTIFIERS bit is set, the
device should be configured to overwrite any device identifiers in the
requested component with the identifiers from the image.

Multiple overwrite modes may be combined to indicate that a combination
of the set of fields that should be overwritten.

Drivers which support the new overwrite mask must set the
DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK in the
supported_flash_update_params field of their devlink_ops.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
Changes since v3
* split netdevsim driver changes to a new patch
* fixed a double-the typo in the documentation

 .../networking/devlink/devlink-flash.rst      | 28 +++++++++++++++++++
 include/net/devlink.h                         |  4 ++-
 include/uapi/linux/devlink.h                  | 25 +++++++++++++++++
 net/core/devlink.c                            | 17 ++++++++++-
 4 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/Documentation/networking/devlink/devlink-flash.rst b/Documentation/networking/devlink/devlink-flash.rst
index 40a87c0222cb..603e732f00cc 100644
--- a/Documentation/networking/devlink/devlink-flash.rst
+++ b/Documentation/networking/devlink/devlink-flash.rst
@@ -16,6 +16,34 @@ Note that the file name is a path relative to the firmware loading path
 (usually ``/lib/firmware/``). Drivers may send status updates to inform
 user space about the progress of the update operation.
 
+Overwrite Mask
+==============
+
+The ``devlink-flash`` command allows optionally specifying a mask indicating
+how the device should handle subsections of flash components when updating.
+This mask indicates the set of sections which are allowed to be overwritten.
+
+.. list-table:: List of overwrite mask bits
+   :widths: 5 95
+
+   * - Name
+     - Description
+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
+     - Indicates that the device should overwrite settings in the components
+       being updated with the settings found in the provided image.
+   * - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
+     - Indicates that the device should overwrite identifiers in the
+       components being updated with the identifiers found in the provided
+       image. This includes MAC addresses, serial IDs, and similar device
+       identifiers.
+
+Multiple overwrite bits may be combined and requested together. If no bits
+are provided, it is expected that the device only update firmware binaries
+in the components being updated. Settings and identifiers are expected to be
+preserved across the update. A device may not support every combination and
+the driver for such a device must reject any combination which cannot be
+faithfully implemented.
+
 Firmware Loading
 ================
 
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 3384e901bbf0..ff4638f7e547 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -543,9 +543,11 @@ enum devlink_param_generic_id {
 struct devlink_flash_update_params {
 	const char *file_name;
 	const char *component;
+	u32 overwrite_mask;
 };
 
-#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT	BIT(0)
+#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT		BIT(0)
+#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK	BIT(1)
 
 struct devlink_region;
 struct devlink_info_req;
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 40d35145c879..19a573566359 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -228,6 +228,28 @@ enum {
 	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
 };
 
+/* Specify what sections of a flash component can be overwritten when
+ * performing an update. Overwriting of firmware binary sections is always
+ * implicitly assumed to be allowed.
+ *
+ * Each section must be documented in
+ * Documentation/networking/devlink/devlink-flash.rst
+ *
+ */
+enum {
+	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
+	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
+
+	__DEVLINK_FLASH_OVERWRITE_MAX_BIT,
+	DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
+};
+
+#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
+#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
+
+#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
+	(BIT(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
+
 /**
  * enum devlink_trap_action - Packet trap action.
  * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
@@ -460,6 +482,9 @@ enum devlink_attr {
 
 	DEVLINK_ATTR_PORT_EXTERNAL,		/* u8 */
 	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,	/* u32 */
+
+	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,	/* bitfield32 */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
diff --git a/net/core/devlink.c b/net/core/devlink.c
index c61f9c8205f6..d0d38ca17ea8 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -3125,8 +3125,8 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 				       struct genl_info *info)
 {
 	struct devlink_flash_update_params params = {};
+	struct nlattr *nla_component, *nla_overwrite;
 	struct devlink *devlink = info->user_ptr[0];
-	struct nlattr *nla_component;
 	u32 supported_params;
 
 	if (!devlink->ops->flash_update)
@@ -3149,6 +3149,19 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
 		params.component = nla_data(nla_component);
 	}
 
+	nla_overwrite = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
+	if (nla_overwrite) {
+		struct nla_bitfield32 sections;
+
+		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
+			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite,
+					    "overwrite is not supported");
+			return -EOPNOTSUPP;
+		}
+		sections = nla_get_bitfield32(nla_overwrite);
+		params.overwrite_mask = sections.value & sections.selector;
+	}
+
 	return devlink->ops->flash_update(devlink, &params, info->extack);
 }
 
@@ -7046,6 +7059,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
 	[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
 	[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
+	[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
+		NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
 	[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
 	[DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
 	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
-- 
2.28.0.218.ge27853923b9d.dirty


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

* [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
                   ` (2 preceding siblings ...)
  2020-09-09 22:26 ` [net-next v4 3/5] devlink: introduce flash update overwrite mask Jacob Keller
@ 2020-09-09 22:26 ` Jacob Keller
  2020-09-10  1:05   ` Jakub Kicinski
  2020-09-09 22:26 ` [net-next v4 5/5] ice: add support for flash update overwrite mask Jacob Keller
  2020-09-10 20:13 ` [net-next v4 0/5] devlink " David Miller
  5 siblings, 1 reply; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev; +Cc: Jacob Keller

The devlink interface recently gained support for a new "overwrite mask"
parameter that allows specifying how various sub-sections of a flash
component are modified when updating.

Add support for this to netdevsim, to enable easily testing the
interface. Make the allowed overwrite mask values controllable via
a debugfs parameter. This enables testing a flow where the driver
rejects an unsupportable overwrite mask.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
This patch is new in v4

 drivers/net/netdevsim/dev.c                    | 10 +++++++++-
 drivers/net/netdevsim/netdevsim.h              |  1 +
 .../selftests/drivers/net/netdevsim/devlink.sh | 18 ++++++++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/netdevsim/dev.c b/drivers/net/netdevsim/dev.c
index ebfc4a698809..74a869fbaa67 100644
--- a/drivers/net/netdevsim/dev.c
+++ b/drivers/net/netdevsim/dev.c
@@ -201,6 +201,8 @@ static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 		return PTR_ERR(nsim_dev->ports_ddir);
 	debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
 			    &nsim_dev->fw_update_status);
+	debugfs_create_u32("fw_update_overwrite_mask", 0600, nsim_dev->ddir,
+			    &nsim_dev->fw_update_overwrite_mask);
 	debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
 			   &nsim_dev->max_macs);
 	debugfs_create_bool("test1", 0600, nsim_dev->ddir,
@@ -747,6 +749,9 @@ static int nsim_dev_flash_update(struct devlink *devlink,
 	struct nsim_dev *nsim_dev = devlink_priv(devlink);
 	int i;
 
+	if ((params->overwrite_mask & ~nsim_dev->fw_update_overwrite_mask) != 0)
+		return -EOPNOTSUPP;
+
 	if (nsim_dev->fw_update_status) {
 		devlink_flash_update_begin_notify(devlink);
 		devlink_flash_update_status_notify(devlink,
@@ -875,7 +880,8 @@ nsim_dev_devlink_trap_policer_counter_get(struct devlink *devlink,
 }
 
 static const struct devlink_ops nsim_dev_devlink_ops = {
-	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT,
+	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT |
+					 DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
 	.reload_down = nsim_dev_reload_down,
 	.reload_up = nsim_dev_reload_up,
 	.info_get = nsim_dev_info_get,
@@ -990,6 +996,7 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
 	INIT_LIST_HEAD(&nsim_dev->port_list);
 	mutex_init(&nsim_dev->port_list_lock);
 	nsim_dev->fw_update_status = true;
+	nsim_dev->fw_update_overwrite_mask = 0;
 
 	nsim_dev->fib_data = nsim_fib_create(devlink, extack);
 	if (IS_ERR(nsim_dev->fib_data))
@@ -1048,6 +1055,7 @@ int nsim_dev_probe(struct nsim_bus_dev *nsim_bus_dev)
 	INIT_LIST_HEAD(&nsim_dev->port_list);
 	mutex_init(&nsim_dev->port_list_lock);
 	nsim_dev->fw_update_status = true;
+	nsim_dev->fw_update_overwrite_mask = 0;
 	nsim_dev->max_macs = NSIM_DEV_MAX_MACS_DEFAULT;
 	nsim_dev->test1 = NSIM_DEV_TEST1_DEFAULT;
 	spin_lock_init(&nsim_dev->fa_cookie_lock);
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 284f7092241d..48ba33501450 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -185,6 +185,7 @@ struct nsim_dev {
 	struct list_head port_list;
 	struct mutex port_list_lock; /* protects port list */
 	bool fw_update_status;
+	u32 fw_update_overwrite_mask;
 	u32 max_macs;
 	bool test1;
 	bool dont_allow_reload;
diff --git a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
index 1e7541688978..40909c254365 100755
--- a/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
+++ b/tools/testing/selftests/drivers/net/netdevsim/devlink.sh
@@ -26,6 +26,24 @@ fw_flash_test()
 	devlink dev flash $DL_HANDLE file dummy component fw.mgmt
 	check_err $? "Failed to flash with component attribute"
 
+	devlink dev flash $DL_HANDLE file dummy overwrite settings
+	check_fail $? "Flash with overwrite settings should be rejected"
+
+	echo "1"> $DEBUGFS_DIR/fw_update_overwrite_mask
+	check_err $? "Failed to change allowed overwrite mask"
+
+	devlink dev flash $DL_HANDLE file dummy overwrite settings
+	check_err $? "Failed to flash with settings overwrite enabled"
+
+	devlink dev flash $DL_HANDLE file dummy overwrite identifiers
+	check_fail $? "Flash with overwrite settings should be identifiers"
+
+	echo "3"> $DEBUGFS_DIR/fw_update_overwrite_mask
+	check_err $? "Failed to change allowed overwrite mask"
+
+	devlink dev flash $DL_HANDLE file dummy overwrite identifiers overwrite settings
+	check_err $? "Failed to flash with settings and identifiers overwrite enabled"
+
 	echo "n"> $DEBUGFS_DIR/fw_update_status
 	check_err $? "Failed to disable status updates"
 
-- 
2.28.0.218.ge27853923b9d.dirty


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

* [net-next v4 5/5] ice: add support for flash update overwrite mask
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
                   ` (3 preceding siblings ...)
  2020-09-09 22:26 ` [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim Jacob Keller
@ 2020-09-09 22:26 ` Jacob Keller
  2020-09-10  1:06   ` Jakub Kicinski
  2020-09-10 20:13 ` [net-next v4 0/5] devlink " David Miller
  5 siblings, 1 reply; 20+ messages in thread
From: Jacob Keller @ 2020-09-09 22:26 UTC (permalink / raw)
  To: netdev; +Cc: Jacob Keller

Support the recently added DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK
parameter in the ice flash update handler. Convert the overwrite mask
bitfield into the appropriate preservation level used by the firmware
when updating.

Because there is no equivalent preservation level for overwriting only
identifiers, this combination is rejected by the driver as not supported
with an appropriate extended ACK message.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
---
 Documentation/networking/devlink/ice.rst      | 31 +++++++++++++++++++
 drivers/net/ethernet/intel/ice/ice_devlink.c  | 19 +++++++++++-
 .../net/ethernet/intel/ice/ice_fw_update.c    | 16 ++++++++--
 .../net/ethernet/intel/ice/ice_fw_update.h    |  2 +-
 4 files changed, 64 insertions(+), 4 deletions(-)

diff --git a/Documentation/networking/devlink/ice.rst b/Documentation/networking/devlink/ice.rst
index 237848d56f9b..8eb50ba41f1a 100644
--- a/Documentation/networking/devlink/ice.rst
+++ b/Documentation/networking/devlink/ice.rst
@@ -81,6 +81,37 @@ The ``ice`` driver reports the following versions
       - 0xee16ced7
       - The first 4 bytes of the hash of the netlist module contents.
 
+Flash Update
+============
+
+The ``ice`` driver implements support for flash update using the
+``devlink-flash`` interface. It supports updating the device flash using a
+combined flash image that contains the ``fw.mgmt``, ``fw.undi``, and
+``fw.netlist`` components.
+
+.. list-table:: List of supported overwrite modes
+   :widths: 5 95
+
+   * - Bits
+     - Behavior
+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
+     - Do not preserve settings stored in the flash components being
+       updated. This includes overwriting the port configuration that
+       determines the number of physical functions the device will
+       initialize with.
+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS`` and ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
+     - Do not preserve either settings or identifiers. Overwrite everything
+       in the flash with the contents from the provided image, without
+       performing any preservation. This includes overwriting device
+       identifying fields such as the MAC address, VPD area, and device
+       serial number. It is expected that this combination be used with an
+       image customized for the specific device.
+
+The ice hardware does not support overwriting only identifiers while
+preserving settings, and thus ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS`` on its
+own will be rejected. If no overwrite mask is provided, the firmware will be
+instructed to preserve all settings and identifying fields when updating.
+
 Regions
 =======
 
diff --git a/drivers/net/ethernet/intel/ice/ice_devlink.c b/drivers/net/ethernet/intel/ice/ice_devlink.c
index 4f8f9e229080..c2726932b2d1 100644
--- a/drivers/net/ethernet/intel/ice/ice_devlink.c
+++ b/drivers/net/ethernet/intel/ice/ice_devlink.c
@@ -250,8 +250,24 @@ ice_devlink_flash_update(struct devlink *devlink,
 	struct device *dev = &pf->pdev->dev;
 	struct ice_hw *hw = &pf->hw;
 	const struct firmware *fw;
+	u8 preservation;
 	int err;
 
+	if (!params->overwrite_mask) {
+		/* preserve all settings and identifiers */
+		preservation = ICE_AQC_NVM_PRESERVE_ALL;
+	} else if (params->overwrite_mask == DEVLINK_FLASH_OVERWRITE_SETTINGS) {
+		/* overwrite settings, but preserve the vital device identifiers */
+		preservation = ICE_AQC_NVM_PRESERVE_SELECTED;
+	} else if (params->overwrite_mask == (DEVLINK_FLASH_OVERWRITE_SETTINGS |
+					      DEVLINK_FLASH_OVERWRITE_IDENTIFIERS)) {
+		/* overwrite both settings and identifiers, preserve nothing */
+		preservation = ICE_AQC_NVM_NO_PRESERVATION;
+	} else {
+		NL_SET_ERR_MSG_MOD(extack, "Requested overwrite mask is not supported");
+		return -EOPNOTSUPP;
+	}
+
 	if (!hw->dev_caps.common_cap.nvm_unified_update) {
 		NL_SET_ERR_MSG_MOD(extack, "Current firmware does not support unified update");
 		return -EOPNOTSUPP;
@@ -269,7 +285,7 @@ ice_devlink_flash_update(struct devlink *devlink,
 
 	devlink_flash_update_begin_notify(devlink);
 	devlink_flash_update_status_notify(devlink, "Preparing to flash", NULL, 0, 0);
-	err = ice_flash_pldm_image(pf, fw, extack);
+	err = ice_flash_pldm_image(pf, fw, preservation, extack);
 	devlink_flash_update_end_notify(devlink);
 
 	release_firmware(fw);
@@ -278,6 +294,7 @@ ice_devlink_flash_update(struct devlink *devlink,
 }
 
 static const struct devlink_ops ice_devlink_ops = {
+	.supported_flash_update_params = DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK,
 	.info_get = ice_devlink_info_get,
 	.flash_update = ice_devlink_flash_update,
 };
diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.c b/drivers/net/ethernet/intel/ice/ice_fw_update.c
index deaefe00c9c0..c81273000d88 100644
--- a/drivers/net/ethernet/intel/ice/ice_fw_update.c
+++ b/drivers/net/ethernet/intel/ice/ice_fw_update.c
@@ -630,6 +630,7 @@ static const struct pldmfw_ops ice_fwu_ops = {
  * ice_flash_pldm_image - Write a PLDM-formatted firmware image to the device
  * @pf: private device driver structure
  * @fw: firmware object pointing to the relevant firmware file
+ * @preservation: preservation level to request from firmware
  * @extack: netlink extended ACK structure
  *
  * Parse the data for a given firmware file, verifying that it is a valid PLDM
@@ -643,7 +644,7 @@ static const struct pldmfw_ops ice_fwu_ops = {
  * Returns: zero on success or a negative error code on failure.
  */
 int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
-			 struct netlink_ext_ack *extack)
+			 u8 preservation, struct netlink_ext_ack *extack)
 {
 	struct device *dev = ice_pf_to_dev(pf);
 	struct ice_hw *hw = &pf->hw;
@@ -651,13 +652,24 @@ int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
 	enum ice_status status;
 	int err;
 
+	switch (preservation) {
+	case ICE_AQC_NVM_PRESERVE_ALL:
+	case ICE_AQC_NVM_PRESERVE_SELECTED:
+	case ICE_AQC_NVM_NO_PRESERVATION:
+	case ICE_AQC_NVM_FACTORY_DEFAULT:
+		break;
+	default:
+		WARN(1, "Unexpected preservation level request %u", preservation);
+		return -EINVAL;
+	}
+
 	memset(&priv, 0, sizeof(priv));
 
 	priv.context.ops = &ice_fwu_ops;
 	priv.context.dev = dev;
 	priv.extack = extack;
 	priv.pf = pf;
-	priv.activate_flags = ICE_AQC_NVM_PRESERVE_ALL;
+	priv.activate_flags = preservation;
 
 	status = ice_acquire_nvm(hw, ICE_RES_WRITE);
 	if (status) {
diff --git a/drivers/net/ethernet/intel/ice/ice_fw_update.h b/drivers/net/ethernet/intel/ice/ice_fw_update.h
index 79472cc618b4..c6390f6851ff 100644
--- a/drivers/net/ethernet/intel/ice/ice_fw_update.h
+++ b/drivers/net/ethernet/intel/ice/ice_fw_update.h
@@ -5,7 +5,7 @@
 #define _ICE_FW_UPDATE_H_
 
 int ice_flash_pldm_image(struct ice_pf *pf, const struct firmware *fw,
-			 struct netlink_ext_ack *extack);
+			 u8 preservation, struct netlink_ext_ack *extack);
 int ice_check_for_pending_update(struct ice_pf *pf, const char *component,
 				 struct netlink_ext_ack *extack);
 
-- 
2.28.0.218.ge27853923b9d.dirty


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

* Re: [net-next v4 1/5] devlink: check flash_update parameter support in net core
  2020-09-09 22:26 ` [net-next v4 1/5] devlink: check flash_update parameter support in net core Jacob Keller
@ 2020-09-10  0:53   ` Jakub Kicinski
  0 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10  0:53 UTC (permalink / raw)
  To: Jacob Keller
  Cc: netdev, Jiri Pirko, Jonathan Corbet, Michael Chan, Bin Luo,
	Saeed Mahameed, Leon Romanovsky, Ido Schimmel, Danielle Ratson

On Wed,  9 Sep 2020 15:26:49 -0700 Jacob Keller wrote:
> +		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT)) {
> +			NL_SET_ERR_MSG_ATTR(info->extack, nla_component,
> +					    "component update is not supported");

If you need to respin for other reasons - ".. for this device"?

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

* Re: [net-next v4 2/5] devlink: convert flash_update to use params structure
  2020-09-09 22:26 ` [net-next v4 2/5] devlink: convert flash_update to use params structure Jacob Keller
@ 2020-09-10  0:55   ` Jakub Kicinski
  2020-09-10 20:59     ` Jacob Keller
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10  0:55 UTC (permalink / raw)
  To: Jacob Keller
  Cc: netdev, Jiri Pirko, Jonathan Corbet, Michael Chan, Bin Luo,
	Saeed Mahameed, Leon Romanovsky, Ido Schimmel, Danielle Ratson

On Wed,  9 Sep 2020 15:26:50 -0700 Jacob Keller wrote:
> The devlink core recently gained support for checking whether the driver
> supports a flash_update parameter, via `supported_flash_update_params`.
> However, parameters are specified as function arguments. Adding a new
> parameter still requires modifying the signature of the .flash_update
> callback in all drivers.
> 
> Convert the .flash_update function to take a new `struct
> devlink_flash_update_params` instead. By using this structure, and the
> `supported_flash_update_params` bit field, a new parameter to
> flash_update can be added without requiring modification to existing
> drivers.
> 
> As before, all parameters except file_name will require driver opt-in.
> Because file_name is a necessary field to for the flash_update to make
> sense, no "SUPPORTED" bitflag is provided and it is always considered
> valid. All future additional parameters will require a new bit in the
> supported_flash_update_params bitfield.

I keep thinking we should also make the core do the
request_firmware_direct(). What else is the driver gonna do with the file name..

But I don't want to drag your series out so:

Reviewed-by: Jakub Kicinski <kuba@kernel.org>

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

* Re: [net-next v4 3/5] devlink: introduce flash update overwrite mask
  2020-09-09 22:26 ` [net-next v4 3/5] devlink: introduce flash update overwrite mask Jacob Keller
@ 2020-09-10  1:03   ` Jakub Kicinski
  2020-09-10 21:01     ` Jacob Keller
  2020-09-10 20:10   ` Jiri Pirko
  1 sibling, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10  1:03 UTC (permalink / raw)
  To: Jacob Keller; +Cc: netdev

On Wed,  9 Sep 2020 15:26:51 -0700 Jacob Keller wrote:
> diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
> index 40d35145c879..19a573566359 100644
> --- a/include/uapi/linux/devlink.h
> +++ b/include/uapi/linux/devlink.h
> @@ -228,6 +228,28 @@ enum {
>  	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
>  };
>  
> +/* Specify what sections of a flash component can be overwritten when
> + * performing an update. Overwriting of firmware binary sections is always
> + * implicitly assumed to be allowed.
> + *
> + * Each section must be documented in
> + * Documentation/networking/devlink/devlink-flash.rst
> + *
> + */
> +enum {
> +	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
> +	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
> +
> +	__DEVLINK_FLASH_OVERWRITE_MAX_BIT,
> +	DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
> +};
> +
> +#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
> +#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
> +
> +#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
> +	(BIT(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)

I don't think you can use BIT() in uAPI headers :(

>  /**
>   * enum devlink_trap_action - Packet trap action.
>   * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
> @@ -460,6 +482,9 @@ enum devlink_attr {
>  
>  	DEVLINK_ATTR_PORT_EXTERNAL,		/* u8 */
>  	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,	/* u32 */
> +
> +	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,	/* bitfield32 */
> +
>  	/* add new attributes above here, update the policy in devlink.c */
>  
>  	__DEVLINK_ATTR_MAX,
> diff --git a/net/core/devlink.c b/net/core/devlink.c
> index c61f9c8205f6..d0d38ca17ea8 100644
> --- a/net/core/devlink.c
> +++ b/net/core/devlink.c
> @@ -3125,8 +3125,8 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>  				       struct genl_info *info)
>  {
>  	struct devlink_flash_update_params params = {};
> +	struct nlattr *nla_component, *nla_overwrite;
>  	struct devlink *devlink = info->user_ptr[0];
> -	struct nlattr *nla_component;
>  	u32 supported_params;
>  
>  	if (!devlink->ops->flash_update)
> @@ -3149,6 +3149,19 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>  		params.component = nla_data(nla_component);
>  	}
>  
> +	nla_overwrite = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
> +	if (nla_overwrite) {
> +		struct nla_bitfield32 sections;
> +
> +		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
> +			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite,
> +					    "overwrite is not supported");

settings ... by this device ?

> +			return -EOPNOTSUPP;
> +		}
> +		sections = nla_get_bitfield32(nla_overwrite);
> +		params.overwrite_mask = sections.value & sections.selector;
 

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

* Re: [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim
  2020-09-09 22:26 ` [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim Jacob Keller
@ 2020-09-10  1:05   ` Jakub Kicinski
  2020-09-10 21:02     ` Jacob Keller
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10  1:05 UTC (permalink / raw)
  To: Jacob Keller; +Cc: netdev

On Wed,  9 Sep 2020 15:26:52 -0700 Jacob Keller wrote:
> The devlink interface recently gained support for a new "overwrite mask"
> parameter that allows specifying how various sub-sections of a flash
> component are modified when updating.
> 
> Add support for this to netdevsim, to enable easily testing the
> interface. Make the allowed overwrite mask values controllable via
> a debugfs parameter. This enables testing a flow where the driver
> rejects an unsupportable overwrite mask.
> 
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>

nit: subject should be prefixed with netdevsim: not devlink:

Reviewed-by: Jakub Kicinski <kuba@kernel.org>

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

* Re: [net-next v4 5/5] ice: add support for flash update overwrite mask
  2020-09-09 22:26 ` [net-next v4 5/5] ice: add support for flash update overwrite mask Jacob Keller
@ 2020-09-10  1:06   ` Jakub Kicinski
  0 siblings, 0 replies; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10  1:06 UTC (permalink / raw)
  To: Jacob Keller; +Cc: netdev

On Wed,  9 Sep 2020 15:26:53 -0700 Jacob Keller wrote:
> Support the recently added DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK
> parameter in the ice flash update handler. Convert the overwrite mask
> bitfield into the appropriate preservation level used by the firmware
> when updating.
> 
> Because there is no equivalent preservation level for overwriting only
> identifiers, this combination is rejected by the driver as not supported
> with an appropriate extended ACK message.
> 
> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>

Reviewed-by: Jakub Kicinski <kuba@kernel.org>

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

* Re: [net-next v4 3/5] devlink: introduce flash update overwrite mask
  2020-09-09 22:26 ` [net-next v4 3/5] devlink: introduce flash update overwrite mask Jacob Keller
  2020-09-10  1:03   ` Jakub Kicinski
@ 2020-09-10 20:10   ` Jiri Pirko
  2020-09-10 21:10     ` Jacob Keller
  1 sibling, 1 reply; 20+ messages in thread
From: Jiri Pirko @ 2020-09-10 20:10 UTC (permalink / raw)
  To: Jacob Keller; +Cc: netdev

Thu, Sep 10, 2020 at 12:26:51AM CEST, jacob.e.keller@intel.com wrote:
>Sections of device flash may contain settings or device identifying
>information. When performing a flash update, it is generally expected
>that these settings and identifiers are not overwritten.
>
>However, it may sometimes be useful to allow overwriting these fields
>when performing a flash update. Some examples include, 1) customizing
>the initial device config on first programming, such as overwriting
>default device identifying information, or 2) reverting a device
>configuration to known good state provided in the new firmware image, or
>3) in case it is suspected that current firmware logic for managing the
>preservation of fields during an update is broken.
>
>Although some devices are able to completely separate these types of
>settings and fields into separate components, this is not true for all
>hardware.
>
>To support controlling this behavior, a new
>DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK is defined. This is an
>nla_bitfield32 which will define what subset of fields in a component
>should be overwritten during an update.
>
>If no bits are specified, or of the overwrite mask is not provided, then
>an update should not overwrite anything, and should maintain the
>settings and identifiers as they are in the previous image.
>
>If the overwrite mask has the DEVLINK_FLASH_OVERWRITE_SETTINGS bit set,
>then the device should be configured to overwrite any of the settings in
>the requested component with settings found in the provided image.
>
>Similarly, if the DEVLINK_FLASH_OVERWRITE_IDENTIFIERS bit is set, the
>device should be configured to overwrite any device identifiers in the
>requested component with the identifiers from the image.
>
>Multiple overwrite modes may be combined to indicate that a combination
>of the set of fields that should be overwritten.
>
>Drivers which support the new overwrite mask must set the
>DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK in the
>supported_flash_update_params field of their devlink_ops.
>
>Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>---
>Changes since v3
>* split netdevsim driver changes to a new patch
>* fixed a double-the typo in the documentation
>
> .../networking/devlink/devlink-flash.rst      | 28 +++++++++++++++++++
> include/net/devlink.h                         |  4 ++-
> include/uapi/linux/devlink.h                  | 25 +++++++++++++++++
> net/core/devlink.c                            | 17 ++++++++++-
> 4 files changed, 72 insertions(+), 2 deletions(-)
>
>diff --git a/Documentation/networking/devlink/devlink-flash.rst b/Documentation/networking/devlink/devlink-flash.rst
>index 40a87c0222cb..603e732f00cc 100644
>--- a/Documentation/networking/devlink/devlink-flash.rst
>+++ b/Documentation/networking/devlink/devlink-flash.rst
>@@ -16,6 +16,34 @@ Note that the file name is a path relative to the firmware loading path
> (usually ``/lib/firmware/``). Drivers may send status updates to inform
> user space about the progress of the update operation.
> 
>+Overwrite Mask
>+==============
>+
>+The ``devlink-flash`` command allows optionally specifying a mask indicating
>+how the device should handle subsections of flash components when updating.
>+This mask indicates the set of sections which are allowed to be overwritten.
>+
>+.. list-table:: List of overwrite mask bits
>+   :widths: 5 95
>+
>+   * - Name
>+     - Description
>+   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
>+     - Indicates that the device should overwrite settings in the components
>+       being updated with the settings found in the provided image.
>+   * - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
>+     - Indicates that the device should overwrite identifiers in the
>+       components being updated with the identifiers found in the provided
>+       image. This includes MAC addresses, serial IDs, and similar device
>+       identifiers.
>+
>+Multiple overwrite bits may be combined and requested together. If no bits
>+are provided, it is expected that the device only update firmware binaries
>+in the components being updated. Settings and identifiers are expected to be
>+preserved across the update. A device may not support every combination and
>+the driver for such a device must reject any combination which cannot be
>+faithfully implemented.
>+
> Firmware Loading
> ================
> 
>diff --git a/include/net/devlink.h b/include/net/devlink.h
>index 3384e901bbf0..ff4638f7e547 100644
>--- a/include/net/devlink.h
>+++ b/include/net/devlink.h
>@@ -543,9 +543,11 @@ enum devlink_param_generic_id {
> struct devlink_flash_update_params {
> 	const char *file_name;
> 	const char *component;
>+	u32 overwrite_mask;
> };
> 
>-#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT	BIT(0)
>+#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT		BIT(0)
>+#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK	BIT(1)
> 
> struct devlink_region;
> struct devlink_info_req;
>diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
>index 40d35145c879..19a573566359 100644
>--- a/include/uapi/linux/devlink.h
>+++ b/include/uapi/linux/devlink.h
>@@ -228,6 +228,28 @@ enum {
> 	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
> };
> 
>+/* Specify what sections of a flash component can be overwritten when
>+ * performing an update. Overwriting of firmware binary sections is always
>+ * implicitly assumed to be allowed.
>+ *
>+ * Each section must be documented in
>+ * Documentation/networking/devlink/devlink-flash.rst
>+ *
>+ */
>+enum {
>+	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
>+	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
>+
>+	__DEVLINK_FLASH_OVERWRITE_MAX_BIT,
>+	DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
>+};
>+
>+#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
>+#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
>+
>+#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
>+	(BIT(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
>+
> /**
>  * enum devlink_trap_action - Packet trap action.
>  * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
>@@ -460,6 +482,9 @@ enum devlink_attr {
> 
> 	DEVLINK_ATTR_PORT_EXTERNAL,		/* u8 */
> 	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,	/* u32 */
>+
>+	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,	/* bitfield32 */
>+
> 	/* add new attributes above here, update the policy in devlink.c */
> 
> 	__DEVLINK_ATTR_MAX,
>diff --git a/net/core/devlink.c b/net/core/devlink.c
>index c61f9c8205f6..d0d38ca17ea8 100644
>--- a/net/core/devlink.c
>+++ b/net/core/devlink.c
>@@ -3125,8 +3125,8 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
> 				       struct genl_info *info)
> {
> 	struct devlink_flash_update_params params = {};
>+	struct nlattr *nla_component, *nla_overwrite;
> 	struct devlink *devlink = info->user_ptr[0];
>-	struct nlattr *nla_component;
> 	u32 supported_params;
> 
> 	if (!devlink->ops->flash_update)
>@@ -3149,6 +3149,19 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
> 		params.component = nla_data(nla_component);
> 	}
> 
>+	nla_overwrite = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];

Just a nitpick, better to name this "nla_overwrite_mask" to follow the
name of the netlink attr.

Otherwise (extept the uapi BIT as Jakub pointed out) this looks fine to
me.


>+	if (nla_overwrite) {
>+		struct nla_bitfield32 sections;
>+
>+		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
>+			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite,
>+					    "overwrite is not supported");
>+			return -EOPNOTSUPP;
>+		}
>+		sections = nla_get_bitfield32(nla_overwrite);
>+		params.overwrite_mask = sections.value & sections.selector;
>+	}
>+
> 	return devlink->ops->flash_update(devlink, &params, info->extack);
> }
> 
>@@ -7046,6 +7059,8 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
> 	[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
> 	[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
> 	[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
>+	[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] =
>+		NLA_POLICY_BITFIELD32(DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS),
> 	[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING },
> 	[DEVLINK_ATTR_TRAP_ACTION] = { .type = NLA_U8 },
> 	[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING },
>-- 
>2.28.0.218.ge27853923b9d.dirty
>

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

* Re: [net-next v4 0/5] devlink flash update overwrite mask
  2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
                   ` (4 preceding siblings ...)
  2020-09-09 22:26 ` [net-next v4 5/5] ice: add support for flash update overwrite mask Jacob Keller
@ 2020-09-10 20:13 ` David Miller
  2020-09-10 21:03   ` Jacob Keller
  5 siblings, 1 reply; 20+ messages in thread
From: David Miller @ 2020-09-10 20:13 UTC (permalink / raw)
  To: jacob.e.keller
  Cc: netdev, jiri, kuba, corbet, michael.chan, luobin9, saeedm, leon,
	idosch, danieller

From: Jacob Keller <jacob.e.keller@intel.com>
Date: Wed,  9 Sep 2020 15:26:48 -0700

> This series introduces support for a new attribute to the flash update
> command: DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK.

I think you really need to get rid of BIT() usage in the UAPI
header as Jakub mentioned.

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

* Re: [net-next v4 2/5] devlink: convert flash_update to use params structure
  2020-09-10  0:55   ` Jakub Kicinski
@ 2020-09-10 20:59     ` Jacob Keller
  2020-09-10 21:23       ` Jakub Kicinski
  0 siblings, 1 reply; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 20:59 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, Jiri Pirko, Jonathan Corbet, Michael Chan, Bin Luo,
	Saeed Mahameed, Leon Romanovsky, Ido Schimmel, Danielle Ratson



On 9/9/2020 5:55 PM, Jakub Kicinski wrote:
> On Wed,  9 Sep 2020 15:26:50 -0700 Jacob Keller wrote:
>> The devlink core recently gained support for checking whether the driver
>> supports a flash_update parameter, via `supported_flash_update_params`.
>> However, parameters are specified as function arguments. Adding a new
>> parameter still requires modifying the signature of the .flash_update
>> callback in all drivers.
>>
>> Convert the .flash_update function to take a new `struct
>> devlink_flash_update_params` instead. By using this structure, and the
>> `supported_flash_update_params` bit field, a new parameter to
>> flash_update can be added without requiring modification to existing
>> drivers.
>>
>> As before, all parameters except file_name will require driver opt-in.
>> Because file_name is a necessary field to for the flash_update to make
>> sense, no "SUPPORTED" bitflag is provided and it is always considered
>> valid. All future additional parameters will require a new bit in the
>> supported_flash_update_params bitfield.
> 
> I keep thinking we should also make the core do the
> request_firmware_direct(). What else is the driver gonna do with the file name..
> 
> But I don't want to drag your series out so:
> 
> Reviewed-by: Jakub Kicinski <kuba@kernel.org>
> 

Hmm. What does _direct do? I guess it means it won't fall back to the
userspace helper if it can't find the firmware? It looks like MLX
drivers use it, but others seem to just stick to regular request_firmware.

This seems like an improvement that we can handle in a follow up series
either way. Thanks for the review!

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

* Re: [net-next v4 3/5] devlink: introduce flash update overwrite mask
  2020-09-10  1:03   ` Jakub Kicinski
@ 2020-09-10 21:01     ` Jacob Keller
  0 siblings, 0 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 21:01 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev



On 9/9/2020 6:03 PM, Jakub Kicinski wrote:
> On Wed,  9 Sep 2020 15:26:51 -0700 Jacob Keller wrote:
>> diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
>> index 40d35145c879..19a573566359 100644
>> --- a/include/uapi/linux/devlink.h
>> +++ b/include/uapi/linux/devlink.h
>> @@ -228,6 +228,28 @@ enum {
>>  	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
>>  };
>>  
>> +/* Specify what sections of a flash component can be overwritten when
>> + * performing an update. Overwriting of firmware binary sections is always
>> + * implicitly assumed to be allowed.
>> + *
>> + * Each section must be documented in
>> + * Documentation/networking/devlink/devlink-flash.rst
>> + *
>> + */
>> +enum {
>> +	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
>> +	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
>> +
>> +	__DEVLINK_FLASH_OVERWRITE_MAX_BIT,
>> +	DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
>> +};
>> +
>> +#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
>> +#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
>> +
>> +#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
>> +	(BIT(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
> 
> I don't think you can use BIT() in uAPI headers :(
> 


Hmmm.. There are exactly 2 other uses I found by searching for 'BIT('
that already exists. We can chance this to just do the bit shift directly.

>>  /**
>>   * enum devlink_trap_action - Packet trap action.
>>   * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
>> @@ -460,6 +482,9 @@ enum devlink_attr {
>>  
>>  	DEVLINK_ATTR_PORT_EXTERNAL,		/* u8 */
>>  	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,	/* u32 */
>> +
>> +	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,	/* bitfield32 */
>> +
>>  	/* add new attributes above here, update the policy in devlink.c */
>>  
>>  	__DEVLINK_ATTR_MAX,
>> diff --git a/net/core/devlink.c b/net/core/devlink.c
>> index c61f9c8205f6..d0d38ca17ea8 100644
>> --- a/net/core/devlink.c
>> +++ b/net/core/devlink.c
>> @@ -3125,8 +3125,8 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>>  				       struct genl_info *info)
>>  {
>>  	struct devlink_flash_update_params params = {};
>> +	struct nlattr *nla_component, *nla_overwrite;
>>  	struct devlink *devlink = info->user_ptr[0];
>> -	struct nlattr *nla_component;
>>  	u32 supported_params;
>>  
>>  	if (!devlink->ops->flash_update)
>> @@ -3149,6 +3149,19 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>>  		params.component = nla_data(nla_component);
>>  	}
>>  
>> +	nla_overwrite = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
>> +	if (nla_overwrite) {
>> +		struct nla_bitfield32 sections;
>> +
>> +		if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
>> +			NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite,
>> +					    "overwrite is not supported");
> 
> settings ... by this device ?

Sure I can fix this along with the other location either as a follow up
or a respin if this still needs it.

Thanks,
Jake

> 
>> +			return -EOPNOTSUPP;
>> +		}
>> +		sections = nla_get_bitfield32(nla_overwrite);
>> +		params.overwrite_mask = sections.value & sections.selector;
>  
> 

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

* Re: [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim
  2020-09-10  1:05   ` Jakub Kicinski
@ 2020-09-10 21:02     ` Jacob Keller
  0 siblings, 0 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 21:02 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: netdev



On 9/9/2020 6:05 PM, Jakub Kicinski wrote:
> On Wed,  9 Sep 2020 15:26:52 -0700 Jacob Keller wrote:
>> The devlink interface recently gained support for a new "overwrite mask"
>> parameter that allows specifying how various sub-sections of a flash
>> component are modified when updating.
>>
>> Add support for this to netdevsim, to enable easily testing the
>> interface. Make the allowed overwrite mask values controllable via
>> a debugfs parameter. This enables testing a flow where the driver
>> rejects an unsupportable overwrite mask.
>>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
> 
> nit: subject should be prefixed with netdevsim: not devlink:
> 
> Reviewed-by: Jakub Kicinski <kuba@kernel.org>
> 

Yep. when I split the patch apart, I had copied and edited the commit
message but forgot to change the subject.

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

* Re: [net-next v4 0/5] devlink flash update overwrite mask
  2020-09-10 20:13 ` [net-next v4 0/5] devlink " David Miller
@ 2020-09-10 21:03   ` Jacob Keller
  0 siblings, 0 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 21:03 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, jiri, kuba, corbet, michael.chan, luobin9, saeedm, leon,
	idosch, danieller



On 9/10/2020 1:13 PM, David Miller wrote:
> From: Jacob Keller <jacob.e.keller@intel.com>
> Date: Wed,  9 Sep 2020 15:26:48 -0700
> 
>> This series introduces support for a new attribute to the flash update
>> command: DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK.
> 
> I think you really need to get rid of BIT() usage in the UAPI
> header as Jakub mentioned.
> 

Yep. I'll send a v5 with that and the 3 minor nits fixed up.

Thanks!

-Jake

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

* Re: [net-next v4 3/5] devlink: introduce flash update overwrite mask
  2020-09-10 20:10   ` Jiri Pirko
@ 2020-09-10 21:10     ` Jacob Keller
  0 siblings, 0 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 21:10 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: netdev



On 9/10/2020 1:10 PM, Jiri Pirko wrote:
> Thu, Sep 10, 2020 at 12:26:51AM CEST, jacob.e.keller@intel.com wrote:
>> Sections of device flash may contain settings or device identifying
>> information. When performing a flash update, it is generally expected
>> that these settings and identifiers are not overwritten.
>>
>> However, it may sometimes be useful to allow overwriting these fields
>> when performing a flash update. Some examples include, 1) customizing
>> the initial device config on first programming, such as overwriting
>> default device identifying information, or 2) reverting a device
>> configuration to known good state provided in the new firmware image, or
>> 3) in case it is suspected that current firmware logic for managing the
>> preservation of fields during an update is broken.
>>
>> Although some devices are able to completely separate these types of
>> settings and fields into separate components, this is not true for all
>> hardware.
>>
>> To support controlling this behavior, a new
>> DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK is defined. This is an
>> nla_bitfield32 which will define what subset of fields in a component
>> should be overwritten during an update.
>>
>> If no bits are specified, or of the overwrite mask is not provided, then
>> an update should not overwrite anything, and should maintain the
>> settings and identifiers as they are in the previous image.
>>
>> If the overwrite mask has the DEVLINK_FLASH_OVERWRITE_SETTINGS bit set,
>> then the device should be configured to overwrite any of the settings in
>> the requested component with settings found in the provided image.
>>
>> Similarly, if the DEVLINK_FLASH_OVERWRITE_IDENTIFIERS bit is set, the
>> device should be configured to overwrite any device identifiers in the
>> requested component with the identifiers from the image.
>>
>> Multiple overwrite modes may be combined to indicate that a combination
>> of the set of fields that should be overwritten.
>>
>> Drivers which support the new overwrite mask must set the
>> DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK in the
>> supported_flash_update_params field of their devlink_ops.
>>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> ---
>> Changes since v3
>> * split netdevsim driver changes to a new patch
>> * fixed a double-the typo in the documentation
>>
>> .../networking/devlink/devlink-flash.rst      | 28 +++++++++++++++++++
>> include/net/devlink.h                         |  4 ++-
>> include/uapi/linux/devlink.h                  | 25 +++++++++++++++++
>> net/core/devlink.c                            | 17 ++++++++++-
>> 4 files changed, 72 insertions(+), 2 deletions(-)
>>
>> diff --git a/Documentation/networking/devlink/devlink-flash.rst b/Documentation/networking/devlink/devlink-flash.rst
>> index 40a87c0222cb..603e732f00cc 100644
>> --- a/Documentation/networking/devlink/devlink-flash.rst
>> +++ b/Documentation/networking/devlink/devlink-flash.rst
>> @@ -16,6 +16,34 @@ Note that the file name is a path relative to the firmware loading path
>> (usually ``/lib/firmware/``). Drivers may send status updates to inform
>> user space about the progress of the update operation.
>>
>> +Overwrite Mask
>> +==============
>> +
>> +The ``devlink-flash`` command allows optionally specifying a mask indicating
>> +how the device should handle subsections of flash components when updating.
>> +This mask indicates the set of sections which are allowed to be overwritten.
>> +
>> +.. list-table:: List of overwrite mask bits
>> +   :widths: 5 95
>> +
>> +   * - Name
>> +     - Description
>> +   * - ``DEVLINK_FLASH_OVERWRITE_SETTINGS``
>> +     - Indicates that the device should overwrite settings in the components
>> +       being updated with the settings found in the provided image.
>> +   * - ``DEVLINK_FLASH_OVERWRITE_IDENTIFIERS``
>> +     - Indicates that the device should overwrite identifiers in the
>> +       components being updated with the identifiers found in the provided
>> +       image. This includes MAC addresses, serial IDs, and similar device
>> +       identifiers.
>> +
>> +Multiple overwrite bits may be combined and requested together. If no bits
>> +are provided, it is expected that the device only update firmware binaries
>> +in the components being updated. Settings and identifiers are expected to be
>> +preserved across the update. A device may not support every combination and
>> +the driver for such a device must reject any combination which cannot be
>> +faithfully implemented.
>> +
>> Firmware Loading
>> ================
>>
>> diff --git a/include/net/devlink.h b/include/net/devlink.h
>> index 3384e901bbf0..ff4638f7e547 100644
>> --- a/include/net/devlink.h
>> +++ b/include/net/devlink.h
>> @@ -543,9 +543,11 @@ enum devlink_param_generic_id {
>> struct devlink_flash_update_params {
>> 	const char *file_name;
>> 	const char *component;
>> +	u32 overwrite_mask;
>> };
>>
>> -#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT	BIT(0)
>> +#define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT		BIT(0)
>> +#define DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK	BIT(1)
>>
>> struct devlink_region;
>> struct devlink_info_req;
>> diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
>> index 40d35145c879..19a573566359 100644
>> --- a/include/uapi/linux/devlink.h
>> +++ b/include/uapi/linux/devlink.h
>> @@ -228,6 +228,28 @@ enum {
>> 	DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
>> };
>>
>> +/* Specify what sections of a flash component can be overwritten when
>> + * performing an update. Overwriting of firmware binary sections is always
>> + * implicitly assumed to be allowed.
>> + *
>> + * Each section must be documented in
>> + * Documentation/networking/devlink/devlink-flash.rst
>> + *
>> + */
>> +enum {
>> +	DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT,
>> +	DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT,
>> +
>> +	__DEVLINK_FLASH_OVERWRITE_MAX_BIT,
>> +	DEVLINK_FLASH_OVERWRITE_MAX_BIT = __DEVLINK_FLASH_OVERWRITE_MAX_BIT - 1
>> +};
>> +
>> +#define DEVLINK_FLASH_OVERWRITE_SETTINGS BIT(DEVLINK_FLASH_OVERWRITE_SETTINGS_BIT)
>> +#define DEVLINK_FLASH_OVERWRITE_IDENTIFIERS BIT(DEVLINK_FLASH_OVERWRITE_IDENTIFIERS_BIT)
>> +
>> +#define DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS \
>> +	(BIT(__DEVLINK_FLASH_OVERWRITE_MAX_BIT) - 1)
>> +
>> /**
>>  * enum devlink_trap_action - Packet trap action.
>>  * @DEVLINK_TRAP_ACTION_DROP: Packet is dropped by the device and a copy is not
>> @@ -460,6 +482,9 @@ enum devlink_attr {
>>
>> 	DEVLINK_ATTR_PORT_EXTERNAL,		/* u8 */
>> 	DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,	/* u32 */
>> +
>> +	DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,	/* bitfield32 */
>> +
>> 	/* add new attributes above here, update the policy in devlink.c */
>>
>> 	__DEVLINK_ATTR_MAX,
>> diff --git a/net/core/devlink.c b/net/core/devlink.c
>> index c61f9c8205f6..d0d38ca17ea8 100644
>> --- a/net/core/devlink.c
>> +++ b/net/core/devlink.c
>> @@ -3125,8 +3125,8 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>> 				       struct genl_info *info)
>> {
>> 	struct devlink_flash_update_params params = {};
>> +	struct nlattr *nla_component, *nla_overwrite;
>> 	struct devlink *devlink = info->user_ptr[0];
>> -	struct nlattr *nla_component;
>> 	u32 supported_params;
>>
>> 	if (!devlink->ops->flash_update)
>> @@ -3149,6 +3149,19 @@ static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
>> 		params.component = nla_data(nla_component);
>> 	}
>>
>> +	nla_overwrite = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
> 
> Just a nitpick, better to name this "nla_overwrite_mask" to follow the
> name of the netlink attr.
> 
> Otherwise (extept the uapi BIT as Jakub pointed out) this looks fine to
> me.
> 

Sure, seems reasonable. Will fix in v5

Thanks,
Jake

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

* Re: [net-next v4 2/5] devlink: convert flash_update to use params structure
  2020-09-10 20:59     ` Jacob Keller
@ 2020-09-10 21:23       ` Jakub Kicinski
  2020-09-10 21:33         ` Jacob Keller
  0 siblings, 1 reply; 20+ messages in thread
From: Jakub Kicinski @ 2020-09-10 21:23 UTC (permalink / raw)
  To: Jacob Keller
  Cc: netdev, Jiri Pirko, Jonathan Corbet, Michael Chan, Bin Luo,
	Saeed Mahameed, Leon Romanovsky, Ido Schimmel, Danielle Ratson

On Thu, 10 Sep 2020 13:59:07 -0700 Jacob Keller wrote:
> On 9/9/2020 5:55 PM, Jakub Kicinski wrote:
> > On Wed,  9 Sep 2020 15:26:50 -0700 Jacob Keller wrote:  
> >> The devlink core recently gained support for checking whether the driver
> >> supports a flash_update parameter, via `supported_flash_update_params`.
> >> However, parameters are specified as function arguments. Adding a new
> >> parameter still requires modifying the signature of the .flash_update
> >> callback in all drivers.
> >>
> >> Convert the .flash_update function to take a new `struct
> >> devlink_flash_update_params` instead. By using this structure, and the
> >> `supported_flash_update_params` bit field, a new parameter to
> >> flash_update can be added without requiring modification to existing
> >> drivers.
> >>
> >> As before, all parameters except file_name will require driver opt-in.
> >> Because file_name is a necessary field to for the flash_update to make
> >> sense, no "SUPPORTED" bitflag is provided and it is always considered
> >> valid. All future additional parameters will require a new bit in the
> >> supported_flash_update_params bitfield.  
> > 
> > I keep thinking we should also make the core do the
> > request_firmware_direct(). What else is the driver gonna do with the file name..
> > 
> > But I don't want to drag your series out so:
> > 
> > Reviewed-by: Jakub Kicinski <kuba@kernel.org>
> 
> Hmm. What does _direct do? I guess it means it won't fall back to the
> userspace helper if it can't find the firmware? It looks like MLX
> drivers use it, but others seem to just stick to regular request_firmware.

FWIW _direct() is pretty much meaningless today, I think the kernel
support for non-direct is mostly dropped. Systemd doesn't support it
either.

> This seems like an improvement that we can handle in a follow up series
> either way. Thanks for the review!

Agreed. Too many pending patches for this area already :S

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

* Re: [net-next v4 2/5] devlink: convert flash_update to use params structure
  2020-09-10 21:23       ` Jakub Kicinski
@ 2020-09-10 21:33         ` Jacob Keller
  0 siblings, 0 replies; 20+ messages in thread
From: Jacob Keller @ 2020-09-10 21:33 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: netdev, Jiri Pirko, Jonathan Corbet, Michael Chan, Bin Luo,
	Saeed Mahameed, Leon Romanovsky, Ido Schimmel, Danielle Ratson



On 9/10/2020 2:23 PM, Jakub Kicinski wrote:
> On Thu, 10 Sep 2020 13:59:07 -0700 Jacob Keller wrote:
>> On 9/9/2020 5:55 PM, Jakub Kicinski wrote:
>>> On Wed,  9 Sep 2020 15:26:50 -0700 Jacob Keller wrote:  
>>>> The devlink core recently gained support for checking whether the driver
>>>> supports a flash_update parameter, via `supported_flash_update_params`.
>>>> However, parameters are specified as function arguments. Adding a new
>>>> parameter still requires modifying the signature of the .flash_update
>>>> callback in all drivers.
>>>>
>>>> Convert the .flash_update function to take a new `struct
>>>> devlink_flash_update_params` instead. By using this structure, and the
>>>> `supported_flash_update_params` bit field, a new parameter to
>>>> flash_update can be added without requiring modification to existing
>>>> drivers.
>>>>
>>>> As before, all parameters except file_name will require driver opt-in.
>>>> Because file_name is a necessary field to for the flash_update to make
>>>> sense, no "SUPPORTED" bitflag is provided and it is always considered
>>>> valid. All future additional parameters will require a new bit in the
>>>> supported_flash_update_params bitfield.  
>>>
>>> I keep thinking we should also make the core do the
>>> request_firmware_direct(). What else is the driver gonna do with the file name..
>>>
>>> But I don't want to drag your series out so:
>>>
>>> Reviewed-by: Jakub Kicinski <kuba@kernel.org>
>>
>> Hmm. What does _direct do? I guess it means it won't fall back to the
>> userspace helper if it can't find the firmware? It looks like MLX
>> drivers use it, but others seem to just stick to regular request_firmware.
> 
> FWIW _direct() is pretty much meaningless today, I think the kernel
> support for non-direct is mostly dropped. Systemd doesn't support it
> either.
> 

Ah, I see. So basically using either doesn't really impact anything
because everything will just do the direct method and fail otherwise? Ok.

>> This seems like an improvement that we can handle in a follow up series
>> either way. Thanks for the review!
> 
> Agreed. Too many pending patches for this area already :S
> 
Yea. I'm happy to wait a bit for this to settle and then look at it
again in a few weeks.

Thanks,
Jake

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

end of thread, other threads:[~2020-09-10 21:33 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-09 22:26 [net-next v4 0/5] devlink flash update overwrite mask Jacob Keller
2020-09-09 22:26 ` [net-next v4 1/5] devlink: check flash_update parameter support in net core Jacob Keller
2020-09-10  0:53   ` Jakub Kicinski
2020-09-09 22:26 ` [net-next v4 2/5] devlink: convert flash_update to use params structure Jacob Keller
2020-09-10  0:55   ` Jakub Kicinski
2020-09-10 20:59     ` Jacob Keller
2020-09-10 21:23       ` Jakub Kicinski
2020-09-10 21:33         ` Jacob Keller
2020-09-09 22:26 ` [net-next v4 3/5] devlink: introduce flash update overwrite mask Jacob Keller
2020-09-10  1:03   ` Jakub Kicinski
2020-09-10 21:01     ` Jacob Keller
2020-09-10 20:10   ` Jiri Pirko
2020-09-10 21:10     ` Jacob Keller
2020-09-09 22:26 ` [net-next v4 4/5] devlink: add support for overwrite mask to netdevsim Jacob Keller
2020-09-10  1:05   ` Jakub Kicinski
2020-09-10 21:02     ` Jacob Keller
2020-09-09 22:26 ` [net-next v4 5/5] ice: add support for flash update overwrite mask Jacob Keller
2020-09-10  1:06   ` Jakub Kicinski
2020-09-10 20:13 ` [net-next v4 0/5] devlink " David Miller
2020-09-10 21:03   ` Jacob Keller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.