Commit 4eceba17 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller
Browse files

ethtool: add compat for flash update



If driver does not support ethtool flash update operation
call into devlink.

Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 76726ccb
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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_ */
+30 −0
Original line number Diff line number Diff line
@@ -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);
+9 −3
Original line number Diff line number Diff line
@@ -2038,11 +2038,17 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev,

	if (copy_from_user(&efl, useraddr, sizeof(efl)))
		return -EFAULT;
	efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;

	if (!dev->ethtool_ops->flash_device)
		return -EOPNOTSUPP;
	if (!dev->ethtool_ops->flash_device) {
		int ret;

	efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
		rtnl_unlock();
		ret = devlink_compat_flash_update(dev, efl.data);
		rtnl_lock();

		return ret;
	}

	return dev->ethtool_ops->flash_device(dev, &efl);
}