From 4eceba17200c03a2678edbdcff5d800aded607be Mon Sep 17 00:00:00 2001 From: Jakub Kicinski Date: Thu, 14 Feb 2019 13:40:45 -0800 Subject: [PATCH] ethtool: add compat for flash update If driver does not support ethtool flash update operation call into devlink. Signed-off-by: Jakub Kicinski Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- include/net/devlink.h | 7 +++++++ net/core/devlink.c | 30 ++++++++++++++++++++++++++++++ net/core/ethtool.c | 14 ++++++++++---- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/include/net/devlink.h b/include/net/devlink.h index 18d7a051f412..a2da49dd9147 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -1195,11 +1195,18 @@ devlink_health_report(struct devlink_health_reporter *reporter, #if IS_REACHABLE(CONFIG_NET_DEVLINK) void devlink_compat_running_version(struct net_device *dev, char *buf, size_t len); +int devlink_compat_flash_update(struct net_device *dev, const char *file_name); #else static inline void devlink_compat_running_version(struct net_device *dev, char *buf, size_t len) { } + +static inline int +devlink_compat_flash_update(struct net_device *dev, const char *file_name) +{ + return -EOPNOTSUPP; +} #endif #endif /* _NET_DEVLINK_H_ */ diff --git a/net/core/devlink.c b/net/core/devlink.c index 4a1ad0b13e52..04d98550c78c 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -6450,6 +6450,36 @@ out: mutex_unlock(&devlink_mutex); } +int devlink_compat_flash_update(struct net_device *dev, const char *file_name) +{ + struct devlink_port *devlink_port; + struct devlink *devlink; + + mutex_lock(&devlink_mutex); + list_for_each_entry(devlink, &devlink_list, list) { + mutex_lock(&devlink->lock); + list_for_each_entry(devlink_port, &devlink->port_list, list) { + int ret = -EOPNOTSUPP; + + if (devlink_port->type != DEVLINK_PORT_TYPE_ETH || + devlink_port->type_dev != dev) + continue; + + mutex_unlock(&devlink_mutex); + if (devlink->ops->flash_update) + ret = devlink->ops->flash_update(devlink, + file_name, + NULL, NULL); + mutex_unlock(&devlink->lock); + return ret; + } + mutex_unlock(&devlink->lock); + } + mutex_unlock(&devlink_mutex); + + return -EOPNOTSUPP; +} + static int __init devlink_module_init(void) { return genl_register_family(&devlink_nl_family); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index d2c47cdf25da..1320e8dce559 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -2038,12 +2038,18 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev, if (copy_from_user(&efl, useraddr, sizeof(efl))) return -EFAULT; - - if (!dev->ethtool_ops->flash_device) - return -EOPNOTSUPP; - efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0; + if (!dev->ethtool_ops->flash_device) { + int ret; + + rtnl_unlock(); + ret = devlink_compat_flash_update(dev, efl.data); + rtnl_lock(); + + return ret; + } + return dev->ethtool_ops->flash_device(dev, &efl); }