Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

devlink: convert flash_update to use params structure

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>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
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>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jacob Keller and committed by
David S. Miller
bc75c054 22ec3d23

+57 -40
+4 -3
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
··· 17 17 #include "bnxt_ethtool.h" 18 18 19 19 static int 20 - bnxt_dl_flash_update(struct devlink *dl, const char *filename, 21 - const char *region, struct netlink_ext_ack *extack) 20 + bnxt_dl_flash_update(struct devlink *dl, 21 + struct devlink_flash_update_params *params, 22 + struct netlink_ext_ack *extack) 22 23 { 23 24 struct bnxt *bp = bnxt_get_bp_from_dl(dl); 24 25 int rc; ··· 32 31 33 32 devlink_flash_update_begin_notify(dl); 34 33 devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0); 35 - rc = bnxt_flash_package_from_file(bp->dev, filename, 0); 34 + rc = bnxt_flash_package_from_file(bp->dev, params->file_name, 0); 36 35 if (!rc) 37 36 devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0); 38 37 else
+2 -3
drivers/net/ethernet/huawei/hinic/hinic_devlink.c
··· 281 281 } 282 282 283 283 static int hinic_devlink_flash_update(struct devlink *devlink, 284 - const char *file_name, 285 - const char *component, 284 + struct devlink_flash_update_params *params, 286 285 struct netlink_ext_ack *extack) 287 286 { 288 287 struct hinic_devlink_priv *priv = devlink_priv(devlink); 289 288 const struct firmware *fw; 290 289 int err; 291 290 292 - err = request_firmware_direct(&fw, file_name, 291 + err = request_firmware_direct(&fw, params->file_name, 293 292 &priv->hwdev->hwif->pdev->dev); 294 293 if (err) 295 294 return err;
+5 -5
drivers/net/ethernet/intel/ice/ice_devlink.c
··· 233 233 /** 234 234 * ice_devlink_flash_update - Update firmware stored in flash on the device 235 235 * @devlink: pointer to devlink associated with device to update 236 - * @path: the path of the firmware file to use via request_firmware 237 - * @component: name of the component to update, or NULL 236 + * @params: flash update parameters 238 237 * @extack: netlink extended ACK structure 239 238 * 240 239 * Perform a device flash update. The bulk of the update logic is contained ··· 242 243 * Returns: zero on success, or an error code on failure. 243 244 */ 244 245 static int 245 - ice_devlink_flash_update(struct devlink *devlink, const char *path, 246 - const char *component, struct netlink_ext_ack *extack) 246 + ice_devlink_flash_update(struct devlink *devlink, 247 + struct devlink_flash_update_params *params, 248 + struct netlink_ext_ack *extack) 247 249 { 248 250 struct ice_pf *pf = devlink_priv(devlink); 249 251 struct device *dev = &pf->pdev->dev; ··· 261 261 if (err) 262 262 return err; 263 263 264 - err = request_firmware(&fw, path, dev); 264 + err = request_firmware(&fw, params->file_name, dev); 265 265 if (err) { 266 266 NL_SET_ERR_MSG_MOD(extack, "Unable to read file from disk"); 267 267 return err;
+2 -3
drivers/net/ethernet/mellanox/mlx5/core/devlink.c
··· 8 8 #include "eswitch.h" 9 9 10 10 static int mlx5_devlink_flash_update(struct devlink *devlink, 11 - const char *file_name, 12 - const char *component, 11 + struct devlink_flash_update_params *params, 13 12 struct netlink_ext_ack *extack) 14 13 { 15 14 struct mlx5_core_dev *dev = devlink_priv(devlink); 16 15 const struct firmware *fw; 17 16 int err; 18 17 19 - err = request_firmware_direct(&fw, file_name, &dev->pdev->dev); 18 + err = request_firmware_direct(&fw, params->file_name, &dev->pdev->dev); 20 19 if (err) 21 20 return err; 22 21
+4 -5
drivers/net/ethernet/mellanox/mlxsw/core.c
··· 1102 1102 } 1103 1103 1104 1104 static int mlxsw_core_fw_flash_update(struct mlxsw_core *mlxsw_core, 1105 - const char *file_name, const char *component, 1105 + struct devlink_flash_update_params *params, 1106 1106 struct netlink_ext_ack *extack) 1107 1107 { 1108 1108 const struct firmware *firmware; 1109 1109 int err; 1110 1110 1111 - err = request_firmware_direct(&firmware, file_name, mlxsw_core->bus_info->dev); 1111 + err = request_firmware_direct(&firmware, params->file_name, mlxsw_core->bus_info->dev); 1112 1112 if (err) 1113 1113 return err; 1114 1114 err = mlxsw_core_fw_flash(mlxsw_core, firmware, extack); ··· 1431 1431 } 1432 1432 1433 1433 static int mlxsw_devlink_flash_update(struct devlink *devlink, 1434 - const char *file_name, 1435 - const char *component, 1434 + struct devlink_flash_update_params *params, 1436 1435 struct netlink_ext_ack *extack) 1437 1436 { 1438 1437 struct mlxsw_core *mlxsw_core = devlink_priv(devlink); 1439 1438 1440 - return mlxsw_core_fw_flash_update(mlxsw_core, file_name, component, extack); 1439 + return mlxsw_core_fw_flash_update(mlxsw_core, params, extack); 1441 1440 } 1442 1441 1443 1442 static int mlxsw_devlink_trap_init(struct devlink *devlink,
+4 -3
drivers/net/ethernet/netronome/nfp/nfp_devlink.c
··· 329 329 } 330 330 331 331 static int 332 - nfp_devlink_flash_update(struct devlink *devlink, const char *path, 333 - const char *component, struct netlink_ext_ack *extack) 332 + nfp_devlink_flash_update(struct devlink *devlink, 333 + struct devlink_flash_update_params *params, 334 + struct netlink_ext_ack *extack) 334 335 { 335 - return nfp_flash_update_common(devlink_priv(devlink), path, extack); 336 + return nfp_flash_update_common(devlink_priv(devlink), params->file_name, extack); 336 337 } 337 338 338 339 const struct devlink_ops nfp_devlink_ops = {
+2 -3
drivers/net/ethernet/pensando/ionic/ionic_devlink.c
··· 10 10 #include "ionic_devlink.h" 11 11 12 12 static int ionic_dl_flash_update(struct devlink *dl, 13 - const char *fwname, 14 - const char *component, 13 + struct devlink_flash_update_params *params, 15 14 struct netlink_ext_ack *extack) 16 15 { 17 16 struct ionic *ionic = devlink_priv(dl); 18 17 19 - return ionic_firmware_update(ionic->lif, fwname, extack); 18 + return ionic_firmware_update(ionic->lif, params->file_name, extack); 20 19 } 21 20 22 21 static int ionic_dl_info_get(struct devlink *dl, struct devlink_info_req *req,
+7 -7
drivers/net/netdevsim/dev.c
··· 742 742 #define NSIM_DEV_FLASH_CHUNK_SIZE 1000 743 743 #define NSIM_DEV_FLASH_CHUNK_TIME_MS 10 744 744 745 - static int nsim_dev_flash_update(struct devlink *devlink, const char *file_name, 746 - const char *component, 745 + static int nsim_dev_flash_update(struct devlink *devlink, 746 + struct devlink_flash_update_params *params, 747 747 struct netlink_ext_ack *extack) 748 748 { 749 749 struct nsim_dev *nsim_dev = devlink_priv(devlink); ··· 753 753 devlink_flash_update_begin_notify(devlink); 754 754 devlink_flash_update_status_notify(devlink, 755 755 "Preparing to flash", 756 - component, 0, 0); 756 + params->component, 0, 0); 757 757 } 758 758 759 759 for (i = 0; i < NSIM_DEV_FLASH_SIZE / NSIM_DEV_FLASH_CHUNK_SIZE; i++) { 760 760 if (nsim_dev->fw_update_status) 761 761 devlink_flash_update_status_notify(devlink, "Flashing", 762 - component, 762 + params->component, 763 763 i * NSIM_DEV_FLASH_CHUNK_SIZE, 764 764 NSIM_DEV_FLASH_SIZE); 765 765 msleep(NSIM_DEV_FLASH_CHUNK_TIME_MS); ··· 767 767 768 768 if (nsim_dev->fw_update_status) { 769 769 devlink_flash_update_status_notify(devlink, "Flashing", 770 - component, 770 + params->component, 771 771 NSIM_DEV_FLASH_SIZE, 772 772 NSIM_DEV_FLASH_SIZE); 773 773 devlink_flash_update_timeout_notify(devlink, "Flash select", 774 - component, 81); 774 + params->component, 81); 775 775 devlink_flash_update_status_notify(devlink, "Flashing done", 776 - component, 0, 0); 776 + params->component, 0, 0); 777 777 devlink_flash_update_end_notify(devlink); 778 778 } 779 779
+16 -2
include/net/devlink.h
··· 550 550 /* Firmware bundle identifier */ 551 551 #define DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID "fw.bundle_id" 552 552 553 + /** 554 + * struct devlink_flash_update_params - Flash Update parameters 555 + * @file_name: the name of the flash firmware file to update from 556 + * @component: the flash component to update 557 + * 558 + * With the exception of file_name, drivers must opt-in to parameters by 559 + * setting the appropriate bit in the supported_flash_update_params field in 560 + * their devlink_ops structure. 561 + */ 562 + struct devlink_flash_update_params { 563 + const char *file_name; 564 + const char *component; 565 + }; 566 + 553 567 #define DEVLINK_SUPPORT_FLASH_UPDATE_COMPONENT BIT(0) 554 568 555 569 struct devlink_region; ··· 1126 1112 * parameters supported by the driver should be set in 1127 1113 * supported_flash_update_params. 1128 1114 */ 1129 - int (*flash_update)(struct devlink *devlink, const char *file_name, 1130 - const char *component, 1115 + int (*flash_update)(struct devlink *devlink, 1116 + struct devlink_flash_update_params *params, 1131 1117 struct netlink_ext_ack *extack); 1132 1118 /** 1133 1119 * @trap_init: Trap initialization function.
+8 -6
net/core/devlink.c
··· 3147 3147 static int devlink_nl_cmd_flash_update(struct sk_buff *skb, 3148 3148 struct genl_info *info) 3149 3149 { 3150 + struct devlink_flash_update_params params = {}; 3150 3151 struct devlink *devlink = info->user_ptr[0]; 3151 - const char *file_name, *component = NULL; 3152 3152 struct nlattr *nla_component; 3153 3153 u32 supported_params; 3154 3154 ··· 3160 3160 3161 3161 supported_params = devlink->ops->supported_flash_update_params; 3162 3162 3163 - file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); 3163 + params.file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]); 3164 3164 3165 3165 nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT]; 3166 3166 if (nla_component) { ··· 3169 3169 "component update is not supported by this device"); 3170 3170 return -EOPNOTSUPP; 3171 3171 } 3172 - component = nla_data(nla_component); 3172 + params.component = nla_data(nla_component); 3173 3173 } 3174 3174 3175 - return devlink->ops->flash_update(devlink, file_name, component, 3176 - info->extack); 3175 + return devlink->ops->flash_update(devlink, &params, info->extack); 3177 3176 } 3178 3177 3179 3178 static const struct devlink_param devlink_param_generic[] = { ··· 9650 9651 9651 9652 int devlink_compat_flash_update(struct net_device *dev, const char *file_name) 9652 9653 { 9654 + struct devlink_flash_update_params params = {}; 9653 9655 struct devlink *devlink; 9654 9656 int ret; 9655 9657 ··· 9663 9663 goto out; 9664 9664 } 9665 9665 9666 + params.file_name = file_name; 9667 + 9666 9668 mutex_lock(&devlink->lock); 9667 - ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL); 9669 + ret = devlink->ops->flash_update(devlink, &params, NULL); 9668 9670 mutex_unlock(&devlink->lock); 9669 9671 9670 9672 out:
+3
tools/testing/selftests/drivers/net/netdevsim/devlink.sh
··· 23 23 devlink dev flash $DL_HANDLE file dummy 24 24 check_err $? "Failed to flash with status updates on" 25 25 26 + devlink dev flash $DL_HANDLE file dummy component fw.mgmt 27 + check_err $? "Failed to flash with component attribute" 28 + 26 29 echo "n"> $DEBUGFS_DIR/fw_update_status 27 30 check_err $? "Failed to disable status updates" 28 31