Message ID | 20190226202014.23626-1-jakub.kicinski@netronome.com |
---|---|
State | Accepted |
Delegated to: | David Ahern |
Headers | show |
Series | [iproute2-next] devlink: add support for updating device flash | expand |
Tue, Feb 26, 2019 at 09:20:14PM CET, jakub.kicinski@netronome.com wrote: >Add new command for updating flash of devices via devlink API. >Example: > >$ cp flash-boot.bin /lib/firmware/ >$ devlink dev flash pci/0000:05:00.0 file flash-boot.bin > >Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Thanks! >--- > devlink/devlink.c | 54 ++++++++++++++++++++++++++++++++++++++++++ > man/man8/devlink-dev.8 | 32 +++++++++++++++++++++++++ > 2 files changed, 86 insertions(+) > >diff --git a/devlink/devlink.c b/devlink/devlink.c >index 960cdda99b5b..5c6cac1f76dd 100644 >--- a/devlink/devlink.c >+++ b/devlink/devlink.c >@@ -199,6 +199,8 @@ static void ifname_map_free(struct ifname_map *ifname_map) > #define DL_OPT_REGION_SNAPSHOT_ID BIT(22) > #define DL_OPT_REGION_ADDRESS BIT(23) > #define DL_OPT_REGION_LENGTH BIT(24) >+#define DL_OPT_FLASH_FILE_NAME BIT(25) >+#define DL_OPT_FLASH_COMPONENT BIT(26) > > struct dl_opts { > uint32_t present; /* flags of present items */ >@@ -230,6 +232,8 @@ struct dl_opts { > uint32_t region_snapshot_id; > uint64_t region_address; > uint64_t region_length; >+ const char *flash_file_name; >+ const char *flash_component; > }; > > struct dl { >@@ -1185,6 +1189,20 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, > if (err) > return err; > o_found |= DL_OPT_REGION_LENGTH; >+ } else if (dl_argv_match(dl, "file") && >+ (o_all & DL_OPT_FLASH_FILE_NAME)) { >+ dl_arg_inc(dl); >+ err = dl_argv_str(dl, &opts->flash_file_name); >+ if (err) >+ return err; >+ o_found |= DL_OPT_FLASH_FILE_NAME; >+ } else if (dl_argv_match(dl, "component") && >+ (o_all & DL_OPT_FLASH_COMPONENT)) { >+ dl_arg_inc(dl); >+ err = dl_argv_str(dl, &opts->flash_component); >+ if (err) >+ return err; >+ o_found |= DL_OPT_FLASH_COMPONENT; > } else { > pr_err("Unknown option \"%s\"\n", dl_argv(dl)); > return -EINVAL; >@@ -1389,6 +1407,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) > if (opts->present & DL_OPT_REGION_LENGTH) > mnl_attr_put_u64(nlh, DEVLINK_ATTR_REGION_CHUNK_LEN, > opts->region_length); >+ if (opts->present & DL_OPT_FLASH_FILE_NAME) >+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME, >+ opts->flash_file_name); >+ if (opts->present & DL_OPT_FLASH_COMPONENT) >+ mnl_attr_put_strz(nlh, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, >+ opts->flash_component); > } > > static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, >@@ -1451,6 +1475,7 @@ static void cmd_dev_help(void) > pr_err(" devlink dev param show [DEV name PARAMETER]\n"); > pr_err(" devlink dev reload DEV\n"); > pr_err(" devlink dev info [ DEV ]\n"); >+ pr_err(" devlink dev flash DEV file PATH [ component NAME ]\n"); > } > > static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name, >@@ -2583,6 +2608,32 @@ static int cmd_dev_info(struct dl *dl) > return err; > } > >+static void cmd_dev_flash_help(void) >+{ >+ pr_err("Usage: devlink dev flash DEV file PATH [ component NAME ]\n"); >+} >+ >+static int cmd_dev_flash(struct dl *dl) >+{ >+ struct nlmsghdr *nlh; >+ int err; >+ >+ if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { >+ cmd_dev_flash_help(); >+ return 0; >+ } >+ >+ nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_FLASH_UPDATE, >+ 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); >+ if (err) >+ return err; >+ >+ return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); >+} >+ > static int cmd_dev(struct dl *dl) > { > if (dl_argv_match(dl, "help")) { >@@ -2604,6 +2655,9 @@ static int cmd_dev(struct dl *dl) > } else if (dl_argv_match(dl, "info")) { > dl_arg_inc(dl); > return cmd_dev_info(dl); >+ } else if (dl_argv_match(dl, "flash")) { >+ dl_arg_inc(dl); >+ return cmd_dev_flash(dl); > } > pr_err("Command \"%s\" not found\n", dl_argv(dl)); > return -ENOENT; >diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 >index 47838371fecd..1804463b2321 100644 >--- a/man/man8/devlink-dev.8 >+++ b/man/man8/devlink-dev.8 >@@ -69,6 +69,16 @@ devlink-dev \- devlink device configuration > .IR DEV > .RI "]" > >+.ti -8 >+.BR "devlink dev flash" >+.IR DEV >+.BR file >+.IR PATH >+.RI "[" >+.BR target >+.IR ID >+.RI "]" >+ > .SH "DESCRIPTION" > .SS devlink dev show - display devlink device attributes > >@@ -177,6 +187,28 @@ versions may differ after flash has been updated, but before reboot. > - specifies the devlink device to show. > If this argument is omitted all devices are listed. > >+.SS devlink dev flash - write device's non-volatile memory. >+ >+.PP >+.I "DEV" >+- specifies the devlink device to write to. >+ >+.BR file >+.I PATH >+- Path to the file which will be written into device's flash. The path needs >+to be relative to one of the directories searched by the kernel firmware loaded, >+such as /lib/firmware. >+ >+.BR component >+.I NAME >+- If device stores multiple firmware images in non-volatile memory, this >+parameter may be used to indicate which firmware image should be written. >+The value of >+.I NAME >+should match the component names from >+.B "devlink dev info" >+and may be driver-dependent. >+ > .SH "EXAMPLES" > .PP > devlink dev show >-- >2.19.2 >
On 2/26/19 1:20 PM, Jakub Kicinski wrote: > Add new command for updating flash of devices via devlink API. > Example: > > $ cp flash-boot.bin /lib/firmware/ > $ devlink dev flash pci/0000:05:00.0 file flash-boot.bin > > Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> > --- > devlink/devlink.c | 54 ++++++++++++++++++++++++++++++++++++++++++ > man/man8/devlink-dev.8 | 32 +++++++++++++++++++++++++ > 2 files changed, 86 insertions(+) > applied to iproute2-next after updating the headers. Thanks
diff --git a/devlink/devlink.c b/devlink/devlink.c index 960cdda99b5b..5c6cac1f76dd 100644 --- a/devlink/devlink.c +++ b/devlink/devlink.c @@ -199,6 +199,8 @@ static void ifname_map_free(struct ifname_map *ifname_map) #define DL_OPT_REGION_SNAPSHOT_ID BIT(22) #define DL_OPT_REGION_ADDRESS BIT(23) #define DL_OPT_REGION_LENGTH BIT(24) +#define DL_OPT_FLASH_FILE_NAME BIT(25) +#define DL_OPT_FLASH_COMPONENT BIT(26) struct dl_opts { uint32_t present; /* flags of present items */ @@ -230,6 +232,8 @@ struct dl_opts { uint32_t region_snapshot_id; uint64_t region_address; uint64_t region_length; + const char *flash_file_name; + const char *flash_component; }; struct dl { @@ -1185,6 +1189,20 @@ static int dl_argv_parse(struct dl *dl, uint32_t o_required, if (err) return err; o_found |= DL_OPT_REGION_LENGTH; + } else if (dl_argv_match(dl, "file") && + (o_all & DL_OPT_FLASH_FILE_NAME)) { + dl_arg_inc(dl); + err = dl_argv_str(dl, &opts->flash_file_name); + if (err) + return err; + o_found |= DL_OPT_FLASH_FILE_NAME; + } else if (dl_argv_match(dl, "component") && + (o_all & DL_OPT_FLASH_COMPONENT)) { + dl_arg_inc(dl); + err = dl_argv_str(dl, &opts->flash_component); + if (err) + return err; + o_found |= DL_OPT_FLASH_COMPONENT; } else { pr_err("Unknown option \"%s\"\n", dl_argv(dl)); return -EINVAL; @@ -1389,6 +1407,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl) if (opts->present & DL_OPT_REGION_LENGTH) mnl_attr_put_u64(nlh, DEVLINK_ATTR_REGION_CHUNK_LEN, opts->region_length); + if (opts->present & DL_OPT_FLASH_FILE_NAME) + mnl_attr_put_strz(nlh, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME, + opts->flash_file_name); + if (opts->present & DL_OPT_FLASH_COMPONENT) + mnl_attr_put_strz(nlh, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT, + opts->flash_component); } static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl, @@ -1451,6 +1475,7 @@ static void cmd_dev_help(void) pr_err(" devlink dev param show [DEV name PARAMETER]\n"); pr_err(" devlink dev reload DEV\n"); pr_err(" devlink dev info [ DEV ]\n"); + pr_err(" devlink dev flash DEV file PATH [ component NAME ]\n"); } static bool cmp_arr_last_handle(struct dl *dl, const char *bus_name, @@ -2583,6 +2608,32 @@ static int cmd_dev_info(struct dl *dl) return err; } +static void cmd_dev_flash_help(void) +{ + pr_err("Usage: devlink dev flash DEV file PATH [ component NAME ]\n"); +} + +static int cmd_dev_flash(struct dl *dl) +{ + struct nlmsghdr *nlh; + int err; + + if (dl_argv_match(dl, "help") || dl_no_arg(dl)) { + cmd_dev_flash_help(); + return 0; + } + + nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_FLASH_UPDATE, + 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); + if (err) + return err; + + return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL); +} + static int cmd_dev(struct dl *dl) { if (dl_argv_match(dl, "help")) { @@ -2604,6 +2655,9 @@ static int cmd_dev(struct dl *dl) } else if (dl_argv_match(dl, "info")) { dl_arg_inc(dl); return cmd_dev_info(dl); + } else if (dl_argv_match(dl, "flash")) { + dl_arg_inc(dl); + return cmd_dev_flash(dl); } pr_err("Command \"%s\" not found\n", dl_argv(dl)); return -ENOENT; diff --git a/man/man8/devlink-dev.8 b/man/man8/devlink-dev.8 index 47838371fecd..1804463b2321 100644 --- a/man/man8/devlink-dev.8 +++ b/man/man8/devlink-dev.8 @@ -69,6 +69,16 @@ devlink-dev \- devlink device configuration .IR DEV .RI "]" +.ti -8 +.BR "devlink dev flash" +.IR DEV +.BR file +.IR PATH +.RI "[" +.BR target +.IR ID +.RI "]" + .SH "DESCRIPTION" .SS devlink dev show - display devlink device attributes @@ -177,6 +187,28 @@ versions may differ after flash has been updated, but before reboot. - specifies the devlink device to show. If this argument is omitted all devices are listed. +.SS devlink dev flash - write device's non-volatile memory. + +.PP +.I "DEV" +- specifies the devlink device to write to. + +.BR file +.I PATH +- Path to the file which will be written into device's flash. The path needs +to be relative to one of the directories searched by the kernel firmware loaded, +such as /lib/firmware. + +.BR component +.I NAME +- If device stores multiple firmware images in non-volatile memory, this +parameter may be used to indicate which firmware image should be written. +The value of +.I NAME +should match the component names from +.B "devlink dev info" +and may be driver-dependent. + .SH "EXAMPLES" .PP devlink dev show
Add new command for updating flash of devices via devlink API. Example: $ cp flash-boot.bin /lib/firmware/ $ devlink dev flash pci/0000:05:00.0 file flash-boot.bin Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> --- devlink/devlink.c | 54 ++++++++++++++++++++++++++++++++++++++++++ man/man8/devlink-dev.8 | 32 +++++++++++++++++++++++++ 2 files changed, 86 insertions(+)