From patchwork Wed Aug 19 00:28:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Keller X-Patchwork-Id: 1347352 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BWTD02Djbz9sPC for ; Wed, 19 Aug 2020 10:28:48 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726923AbgHSA2p (ORCPT ); Tue, 18 Aug 2020 20:28:45 -0400 Received: from mga05.intel.com ([192.55.52.43]:48087 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726835AbgHSA2k (ORCPT ); Tue, 18 Aug 2020 20:28:40 -0400 IronPort-SDR: JGg7meSk3ovBY2jUNNkQKVSZ5rMoEkDEyWAJ03inZ/O0otLc6FItK6Nhy4co6UCeR2WQ/2OrSh oIWogCr5coPg== X-IronPort-AV: E=McAfee;i="6000,8403,9717"; a="239856124" X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="239856124" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 17:28:37 -0700 IronPort-SDR: oqOL1NiKyhM+ebjD2P/pIPDk++xMqq82tjb052pUTMjDEcTP3g1bMW6280qFPGi/VCK3R7a34V BtsTSFJWHepg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="320283556" Received: from jekeller-desk.amr.corp.intel.com ([10.166.241.33]) by fmsmga004.fm.intel.com with ESMTP; 18 Aug 2020 17:28:37 -0700 From: Jacob Keller To: netdev@vger.kernel.org Cc: Jacob Keller , Jiri Pirko , Jakub Kicinski , Jonathan Corbet , Michael Chan , Bin Luo , Saeed Mahameed , Leon Romanovsky , Ido Schimmel , Danielle Ratson Subject: [net-next v3 1/4] devlink: check flash_update parameter support in net core Date: Tue, 18 Aug 2020 17:28:15 -0700 Message-Id: <20200819002821.2657515-2-jacob.e.keller@intel.com> X-Mailer: git-send-email 2.28.0.218.ge27853923b9d.dirty In-Reply-To: <20200819002821.2657515-1-jacob.e.keller@intel.com> References: <20200819002821.2657515-1-jacob.e.keller@intel.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Cc: Jiri Pirko Cc: Jakub Kicinski Cc: Jonathan Corbet Cc: Michael Chan Cc: Bin Luo Cc: Saeed Mahameed Cc: Leon Romanovsky Cc: Ido Schimmel Cc: Danielle Ratson --- Changes since v2: * split this to its own patch, now with just the conversion to supported_flash_update_params, as suggested by Jiri. 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 fdf9aa8314b2..95ddc1212d0e 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 8f3c8a443238..1ef4b832f37b 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -511,6 +511,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; @@ -991,6 +993,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, @@ -1051,6 +1059,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 e5feb87beca7..b596b45c8fd8 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3120,18 +3120,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); From patchwork Wed Aug 19 00:28:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Keller X-Patchwork-Id: 1347357 X-Patchwork-Delegate: dsahern@gmail.com Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BWTDB027mz9sPC for ; Wed, 19 Aug 2020 10:28:58 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727047AbgHSA25 (ORCPT ); Tue, 18 Aug 2020 20:28:57 -0400 Received: from mga05.intel.com ([192.55.52.43]:48102 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726950AbgHSA2z (ORCPT ); Tue, 18 Aug 2020 20:28:55 -0400 IronPort-SDR: jAUTr/8eRJ4VWkrBZplyD+CorPMIYkSV4wpamSMxxf0MSlZvdzoRX8EtwmLiWpLoJqYWeTgVzQ gR8pBVIBTbsQ== X-IronPort-AV: E=McAfee;i="6000,8403,9717"; a="239856135" X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="239856135" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 17:28:39 -0700 IronPort-SDR: 4ALApbepyX5CnbBTJA0wvxRbkgsw/Yr8VqovZ8TNdULkeD4hiLKO9ZP79/gRGKfnhx79p7zyXr iiD9xfx657ig== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="320283592" Received: from jekeller-desk.amr.corp.intel.com ([10.166.241.33]) by fmsmga004.fm.intel.com with ESMTP; 18 Aug 2020 17:28:39 -0700 From: Jacob Keller To: netdev@vger.kernel.org Cc: Jacob Keller Subject: [iproute2-next v3 2/2] devlink: support setting the overwrite mask Date: Tue, 18 Aug 2020 17:28:21 -0700 Message-Id: <20200819002821.2657515-8-jacob.e.keller@intel.com> X-Mailer: git-send-email 2.28.0.218.ge27853923b9d.dirty In-Reply-To: <20200819002821.2657515-1-jacob.e.keller@intel.com> References: <20200819002821.2657515-1-jacob.e.keller@intel.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add support for specifying the overwrite sections to allow in the flash update command. This is done by adding a new "overwrite" option which can take either "settings" or "identifiers" passing the overwrite mode multiple times will combine the fields using bitwise-OR. Signed-off-by: Jacob Keller --- devlink/devlink.c | 48 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/devlink/devlink.c b/devlink/devlink.c index 8ec96c01fbcf..1dc9096781f7 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -302,6 +302,7 @@ static void ifname_map_free(struct ifname_map *ifname_map) #define DL_OPT_TRAP_POLICER_BURST BIT(36) #define DL_OPT_HEALTH_REPORTER_AUTO_DUMP BIT(37) #define DL_OPT_PORT_FUNCTION_HW_ADDR BIT(38) +#define DL_OPT_FLASH_OVERWRITE BIT(39) struct dl_opts { uint64_t present; /* flags of present items */ @@ -349,6 +350,7 @@ struct dl_opts { uint64_t trap_policer_burst; char port_function_hw_addr[MAX_ADDR_LEN]; uint32_t port_function_hw_addr_len; + uint32_t overwrite_mask; }; struct dl { @@ -1285,6 +1287,19 @@ eswitch_encap_mode_get(const char *typestr, return 0; } +static int flash_overwrite_section_get(const char *sectionstr, uint32_t *mask) +{ + if (strcmp(sectionstr, "settings") == 0) { + *mask |= DEVLINK_FLASH_OVERWRITE_SETTINGS; + } else if (strcmp(sectionstr, "identifiers") == 0) { + *mask |= DEVLINK_FLASH_OVERWRITE_IDENTIFIERS; + } else { + pr_err("Unknown overwrite section \"%s\"\n", sectionstr); + return -EINVAL; + } + return 0; +} + static int param_cmode_get(const char *cmodestr, enum devlink_param_cmode *cmode) { @@ -1627,6 +1642,21 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required, if (err) return err; o_found |= DL_OPT_FLASH_COMPONENT; + + } else if (dl_argv_match(dl, "overwrite") && + (o_all & DL_OPT_FLASH_OVERWRITE)) { + const char *sectionstr; + + dl_arg_inc(dl); + err = dl_argv_str(dl, §ionstr); + if(err) + return err; + err = flash_overwrite_section_get(sectionstr, + &opts->overwrite_mask); + if (err) + return err; + o_found |= DL_OPT_FLASH_OVERWRITE; + } else if (dl_argv_match(dl, "reporter") && (o_all & DL_OPT_HEALTH_REPORTER_NAME)) { dl_arg_inc(dl); @@ -1767,6 +1797,18 @@ dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts) mnl_attr_nest_end(nlh, nest); } +static void +dl_flash_update_overwrite_put(struct nlmsghdr *nlh, const struct dl_opts *opts) +{ + struct nla_bitfield32 overwrite_mask; + + overwrite_mask.selector = DEVLINK_SUPPORTED_FLASH_OVERWRITE_SECTIONS; + overwrite_mask.value = opts->overwrite_mask; + + mnl_attr_put(nlh, DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK, + sizeof(overwrite_mask), &overwrite_mask); +} + static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) { struct dl_opts *opts = &dl->opts; @@ -1854,6 +1896,8 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) if (opts->present & DL_OPT_FLASH_COMPONENT) mnl_attr_put_strz(nlh, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, opts->flash_component); + if (opts->present & DL_OPT_FLASH_OVERWRITE) + dl_flash_update_overwrite_put(nlh, opts); if (opts->present & DL_OPT_HEALTH_REPORTER_NAME) mnl_attr_put_strz(nlh, DEVLINK_ATTR_HEALTH_REPORTER_NAME, opts->reporter_name); @@ -1954,7 +1998,7 @@ static void cmd_dev_help(void) pr_err(" devlink dev param show [DEV name PARAMETER]\n"); pr_err(" devlink dev reload DEV [ netns { PID | NAME | ID } ]\n"); pr_err(" devlink dev info [ DEV ]\n"); - pr_err(" devlink dev flash DEV file PATH [ component NAME ]\n"); + pr_err(" devlink dev flash DEV file PATH [ component NAME ] [ overwrite SECTION ]\n"); } static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name, @@ -3219,7 +3263,7 @@ static int cmd_dev_flash(struct dl *dl) NLM_F_REQUEST | NLM_F_ACK); err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | DL_OPT_FLASH_FILE_NAME, - DL_OPT_FLASH_COMPONENT); + DL_OPT_FLASH_COMPONENT | DL_OPT_FLASH_OVERWRITE); if (err) return err; From patchwork Wed Aug 19 00:28:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Keller X-Patchwork-Id: 1347353 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BWTD32hNWz9sPC for ; Wed, 19 Aug 2020 10:28:51 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726983AbgHSA2u (ORCPT ); Tue, 18 Aug 2020 20:28:50 -0400 Received: from mga05.intel.com ([192.55.52.43]:48087 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726410AbgHSA2p (ORCPT ); Tue, 18 Aug 2020 20:28:45 -0400 IronPort-SDR: DHvpE5ChTSCDKZzPqdSggdYYl/Ft1zafgMopAXNBPh7hU65KI2o6PQuYGcQBCwywoT7FFte8n8 tQWRkOFpQHtQ== X-IronPort-AV: E=McAfee;i="6000,8403,9717"; a="239856128" X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="239856128" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 17:28:38 -0700 IronPort-SDR: I5xkQuAhIKpApTE0fQ2kAiVbzi9ZiM25RIFzbBksONSK2o3k6G2Xds/cDI0mdgMxm5bLShQC26 psk7qOOnvxnQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="320283570" Received: from jekeller-desk.amr.corp.intel.com ([10.166.241.33]) by fmsmga004.fm.intel.com with ESMTP; 18 Aug 2020 17:28:38 -0700 From: Jacob Keller To: netdev@vger.kernel.org Cc: Jacob Keller Subject: [net-next v3 3/4] devlink: introduce flash update overwrite mask Date: Tue, 18 Aug 2020 17:28:17 -0700 Message-Id: <20200819002821.2657515-4-jacob.e.keller@intel.com> X-Mailer: git-send-email 2.28.0.218.ge27853923b9d.dirty In-Reply-To: <20200819002821.2657515-1-jacob.e.keller@intel.com> References: <20200819002821.2657515-1-jacob.e.keller@intel.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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. To provide some simple tests of the interface, modify the netdevsim driver to enable support for this parameter and add a few self tests used to make sure the attribute works. A new debugfs hook is used to control what set of overwrite mask values the netdevsim driver will accept. Signed-off-by: Jacob Keller --- Changes since v2: * re-wrote commit message, including additional clarification on the concept and reasoning. * removed use of GENMASK in the uapi header. We can do a simple BIT()-1 calculation instead, simplifying use in the devlink userspace program, and other programs which may not wish to pull in linux headers for GENMASK support. * converted the overwrite mask to an nla_bitfield32. Both the selector and value bits must be set in order to be honored, as the bitmask sent to the driver is the bitwise AND of the two. .../networking/devlink/devlink-flash.rst | 29 +++++++++++++++++++ drivers/net/netdevsim/dev.c | 10 ++++++- drivers/net/netdevsim/netdevsim.h | 1 + include/net/devlink.h | 4 ++- include/uapi/linux/devlink.h | 24 +++++++++++++++ net/core/devlink.c | 17 ++++++++++- .../drivers/net/netdevsim/devlink.sh | 18 ++++++++++++ 7 files changed, 100 insertions(+), 3 deletions(-) diff --git a/Documentation/networking/devlink/devlink-flash.rst b/Documentation/networking/devlink/devlink-flash.rst index 40a87c0222cb..bf97f5c8d4bd 100644 --- a/Documentation/networking/devlink/devlink-flash.rst +++ b/Documentation/networking/devlink/devlink-flash.rst @@ -16,6 +16,35 @@ 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 +the 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/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/include/net/devlink.h b/include/net/devlink.h index a9aab735aef2..39fa60e127d9 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -523,9 +523,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 cfef4245ea5a..1d8bbe9c1ae1 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 @@ -458,6 +480,8 @@ enum devlink_attr { DEVLINK_ATTR_PORT_LANES, /* u32 */ DEVLINK_ATTR_PORT_SPLITTABLE, /* u8 */ + 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 dd6567775b24..cf74bd6468a3 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -3120,8 +3120,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) @@ -3144,6 +3144,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, ¶ms, info->extack); } @@ -7038,6 +7051,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 }, 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" From patchwork Wed Aug 19 00:28:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacob Keller X-Patchwork-Id: 1347354 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 4BWTD4647nz9sPC for ; Wed, 19 Aug 2020 10:28:52 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726745AbgHSA2u (ORCPT ); Tue, 18 Aug 2020 20:28:50 -0400 Received: from mga05.intel.com ([192.55.52.43]:48102 "EHLO mga05.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726731AbgHSA2p (ORCPT ); Tue, 18 Aug 2020 20:28:45 -0400 IronPort-SDR: wxa48L06lziWER7c04UKf/RkJXipuaJE8ak1pUGlN0pWBvbjaz8g7VK4DxLhAkLPGw0glShCX5 vIbEQj5TP9wQ== X-IronPort-AV: E=McAfee;i="6000,8403,9717"; a="239856131" X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="239856131" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga105.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Aug 2020 17:28:38 -0700 IronPort-SDR: IsOPmNPPIkdloP7aixovx5fZVOlsAckE/vsBvv+DTMxOtB5+H1kE5FyFhDkd+S55BdVKzX6tjq yEZNjYntpm4A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,329,1592895600"; d="scan'208";a="320283576" Received: from jekeller-desk.amr.corp.intel.com ([10.166.241.33]) by fmsmga004.fm.intel.com with ESMTP; 18 Aug 2020 17:28:38 -0700 From: Jacob Keller To: netdev@vger.kernel.org Cc: Jacob Keller Subject: [net-next v3 4/4] ice: add support for flash update overwrite mask Date: Tue, 18 Aug 2020 17:28:18 -0700 Message-Id: <20200819002821.2657515-5-jacob.e.keller@intel.com> X-Mailer: git-send-email 2.28.0.218.ge27853923b9d.dirty In-Reply-To: <20200819002821.2657515-1-jacob.e.keller@intel.com> References: <20200819002821.2657515-1-jacob.e.keller@intel.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 --- Changes since v2: * Rewrote the commit message slightly 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);