Add progress notifications ability to user space while flashing modules' firmware by implementing the interface between the user space and the kernel. Signed-off-by: Danielle Ratson <danieller@xxxxxxxxxx> --- net/ethtool/module.c | 83 +++++++++++++++++++++++++++++++++++++++++ net/ethtool/module_fw.h | 10 +++++ 2 files changed, 93 insertions(+) create mode 100644 net/ethtool/module_fw.h diff --git a/net/ethtool/module.c b/net/ethtool/module.c index ceb575efc290..34e2f75c9e2d 100644 --- a/net/ethtool/module.c +++ b/net/ethtool/module.c @@ -5,6 +5,7 @@ #include "netlink.h" #include "common.h" #include "bitset.h" +#include "module_fw.h" struct module_req_info { struct ethnl_req_info base; @@ -158,3 +159,85 @@ const struct ethnl_request_ops ethnl_module_request_ops = { .set = ethnl_set_module, .set_ntf_cmd = ETHTOOL_MSG_MODULE_NTF, }; + +/* MODULE_FW_FLASH_NTF */ + +static void +ethnl_module_fw_flash_ntf(struct net_device *dev, + enum ethtool_module_fw_flash_status status, + const char *status_msg, u64 done, u64 total) +{ + struct sk_buff *skb; + void *hdr; + int ret; + + skb = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb) + return; + + hdr = ethnl_bcastmsg_put(skb, ETHTOOL_MSG_MODULE_FW_FLASH_NTF); + if (!hdr) + goto err_skb; + + ret = ethnl_fill_reply_header(skb, dev, + ETHTOOL_A_MODULE_FW_FLASH_HEADER); + if (ret < 0) + goto err_skb; + + if (nla_put_u8(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS, status)) + goto err_skb; + + if (status_msg && + nla_put_string(skb, ETHTOOL_A_MODULE_FW_FLASH_STATUS_MSG, + status_msg)) + goto err_skb; + + if (nla_put_u64_64bit(skb, ETHTOOL_A_MODULE_FW_FLASH_DONE, done, + ETHTOOL_A_MODULE_FW_FLASH_PAD)) + goto err_skb; + + if (nla_put_u64_64bit(skb, ETHTOOL_A_MODULE_FW_FLASH_TOTAL, + total, ETHTOOL_A_MODULE_FW_FLASH_PAD)) + goto err_skb; + + genlmsg_end(skb, hdr); + ethnl_multicast(skb, dev); + return; + +err_skb: + nlmsg_free(skb); +} + +void ethnl_module_fw_flash_ntf_err(struct net_device *dev, + char *err_msg, char *sub_err_msg) +{ + char status_msg[100]; + + if (sub_err_msg) + sprintf(status_msg, "%s, %s.", err_msg, sub_err_msg); + else + sprintf(status_msg, "%s.", err_msg); + + ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_ERROR, + status_msg, 0, 0); +} + +void ethnl_module_fw_flash_ntf_start(struct net_device *dev) +{ + ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_STARTED, + NULL, 0, 0); +} + +void ethnl_module_fw_flash_ntf_complete(struct net_device *dev) +{ + ethnl_module_fw_flash_ntf(dev, ETHTOOL_MODULE_FW_FLASH_STATUS_COMPLETED, + NULL, 0, 0); +} + +void ethnl_module_fw_flash_ntf_in_progress(struct net_device *dev, u64 done, + u64 total) +{ + ethnl_module_fw_flash_ntf(dev, + ETHTOOL_MODULE_FW_FLASH_STATUS_IN_PROGRESS, + NULL, done, total); +} diff --git a/net/ethtool/module_fw.h b/net/ethtool/module_fw.h new file mode 100644 index 000000000000..e40eae442741 --- /dev/null +++ b/net/ethtool/module_fw.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <uapi/linux/ethtool.h> + +void ethnl_module_fw_flash_ntf_err(struct net_device *dev, + char *err_msg, char *sub_err_msg); +void ethnl_module_fw_flash_ntf_start(struct net_device *dev); +void ethnl_module_fw_flash_ntf_complete(struct net_device *dev); +void ethnl_module_fw_flash_ntf_in_progress(struct net_device *dev, u64 done, + u64 total); -- 2.43.0