Commit 2930942e authored by David S. Miller's avatar David S. Miller

Merge branch 'ethtool-drop-get_settings-and-set_settings-ops'

Michal Kubecek says:

====================
ethtool: drop get_settings and set_settings ops

As Andrew Lunn pointed out in recent discussion, there is only one in tree
driver left which still defines deprecated callbacks get_settings() and
set_settings() in ethtool_ops. First patch converts this driver to
get_link_ksettings() and set_link_ksettings(). Second patch then removes
the deprecated callbacks from struct ethtool_ops and ethtool code which
falls back to them.

This doesn't break old versions of ethtool or any other userspace code
using ETHTOOL_{G,S}SET. We still implement both (old) ETHTOOL_{G,S}SET and
(new) ETHTOOL_{G,S}LINKSETTINGS ioctl commands but after this series both
will be implemented only using {g,s}et_link_ksettings(). The only affected
code would be out of tree NIC drivers which have not been converted yet.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7e3af593 9b300495
...@@ -117,7 +117,7 @@ Description: ...@@ -117,7 +117,7 @@ Description:
full: full duplex full: full duplex
Note: This attribute is only valid for interfaces that implement Note: This attribute is only valid for interfaces that implement
the ethtool get_settings method (mostly Ethernet). the ethtool get_link_ksettings method (mostly Ethernet).
What: /sys/class/net/<iface>/flags What: /sys/class/net/<iface>/flags
Date: April 2005 Date: April 2005
...@@ -224,7 +224,7 @@ Description: ...@@ -224,7 +224,7 @@ Description:
an integer representing the link speed in Mbits/sec. an integer representing the link speed in Mbits/sec.
Note: this attribute is only valid for interfaces that implement Note: this attribute is only valid for interfaces that implement
the ethtool get_settings method (mostly Ethernet ). the ethtool get_link_ksettings method (mostly Ethernet).
What: /sys/class/net/<iface>/tx_queue_len What: /sys/class/net/<iface>/tx_queue_len
Date: April 2005 Date: April 2005
......
...@@ -564,26 +564,29 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i ...@@ -564,26 +564,29 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
sizeof(info->bus_info)); sizeof(info->bus_info));
} }
static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int etherh_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{ {
cmd->supported = etherh_priv(dev)->supported; ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
ethtool_cmd_speed_set(cmd, SPEED_10); etherh_priv(dev)->supported);
cmd->duplex = DUPLEX_HALF; cmd->base.speed = SPEED_10;
cmd->port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC; cmd->base.duplex = DUPLEX_HALF;
cmd->autoneg = (dev->flags & IFF_AUTOMEDIA ? cmd->base.port = dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
AUTONEG_ENABLE : AUTONEG_DISABLE); cmd->base.autoneg = (dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE :
AUTONEG_DISABLE);
return 0; return 0;
} }
static int etherh_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) static int etherh_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{ {
switch (cmd->autoneg) { switch (cmd->base.autoneg) {
case AUTONEG_ENABLE: case AUTONEG_ENABLE:
dev->flags |= IFF_AUTOMEDIA; dev->flags |= IFF_AUTOMEDIA;
break; break;
case AUTONEG_DISABLE: case AUTONEG_DISABLE:
switch (cmd->port) { switch (cmd->base.port) {
case PORT_TP: case PORT_TP:
dev->if_port = IF_PORT_10BASET; dev->if_port = IF_PORT_10BASET;
break; break;
...@@ -622,12 +625,12 @@ static void etherh_set_msglevel(struct net_device *dev, u32 v) ...@@ -622,12 +625,12 @@ static void etherh_set_msglevel(struct net_device *dev, u32 v)
} }
static const struct ethtool_ops etherh_ethtool_ops = { static const struct ethtool_ops etherh_ethtool_ops = {
.get_settings = etherh_get_settings,
.set_settings = etherh_set_settings,
.get_drvinfo = etherh_get_drvinfo, .get_drvinfo = etherh_get_drvinfo,
.get_ts_info = ethtool_op_get_ts_info, .get_ts_info = ethtool_op_get_ts_info,
.get_msglevel = etherh_get_msglevel, .get_msglevel = etherh_get_msglevel,
.set_msglevel = etherh_set_msglevel, .set_msglevel = etherh_set_msglevel,
.get_link_ksettings = etherh_get_link_ksettings,
.set_link_ksettings = etherh_set_link_ksettings,
}; };
static const struct net_device_ops etherh_netdev_ops = { static const struct net_device_ops etherh_netdev_ops = {
......
...@@ -183,14 +183,6 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, ...@@ -183,14 +183,6 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
/** /**
* struct ethtool_ops - optional netdev operations * struct ethtool_ops - optional netdev operations
* @get_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
* API. Get various device settings including Ethernet link
* settings. The @cmd parameter is expected to have been cleared
* before get_settings is called. Returns a negative error code
* or zero.
* @set_settings: DEPRECATED, use %get_link_ksettings/%set_link_ksettings
* API. Set various device settings including Ethernet link
* settings. Returns a negative error code or zero.
* @get_drvinfo: Report driver/device information. Should only set the * @get_drvinfo: Report driver/device information. Should only set the
* @driver, @version, @fw_version and @bus_info fields. If not * @driver, @version, @fw_version and @bus_info fields. If not
* implemented, the @driver and @bus_info fields will be filled in * implemented, the @driver and @bus_info fields will be filled in
...@@ -297,19 +289,16 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, ...@@ -297,19 +289,16 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
* a TX queue has this number, return -EINVAL. If only a RX queue or a TX * a TX queue has this number, return -EINVAL. If only a RX queue or a TX
* queue has this number, ignore the inapplicable fields. * queue has this number, ignore the inapplicable fields.
* Returns a negative error code or zero. * Returns a negative error code or zero.
* @get_link_ksettings: When defined, takes precedence over the * @get_link_ksettings: Get various device settings including Ethernet link
* %get_settings method. Get various device settings * settings. The %cmd and %link_mode_masks_nwords fields should be
* including Ethernet link settings. The %cmd and * ignored (use %__ETHTOOL_LINK_MODE_MASK_NBITS instead of the latter),
* %link_mode_masks_nwords fields should be ignored (use * any change to them will be overwritten by kernel. Returns a negative
* %__ETHTOOL_LINK_MODE_MASK_NBITS instead of the latter), any * error code or zero.
* change to them will be overwritten by kernel. Returns a * @set_link_ksettings: Set various device settings including Ethernet link
* negative error code or zero. * settings. The %cmd and %link_mode_masks_nwords fields should be
* @set_link_ksettings: When defined, takes precedence over the * ignored (use %__ETHTOOL_LINK_MODE_MASK_NBITS instead of the latter),
* %set_settings method. Set various device settings including * any change to them will be overwritten by kernel. Returns a negative
* Ethernet link settings. The %cmd and %link_mode_masks_nwords * error code or zero.
* fields should be ignored (use %__ETHTOOL_LINK_MODE_MASK_NBITS
* instead of the latter), any change to them will be overwritten
* by kernel. Returns a negative error code or zero.
* @get_fecparam: Get the network device Forward Error Correction parameters. * @get_fecparam: Get the network device Forward Error Correction parameters.
* @set_fecparam: Set the network device Forward Error Correction parameters. * @set_fecparam: Set the network device Forward Error Correction parameters.
* @get_ethtool_phy_stats: Return extended statistics about the PHY device. * @get_ethtool_phy_stats: Return extended statistics about the PHY device.
...@@ -329,8 +318,6 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32, ...@@ -329,8 +318,6 @@ bool ethtool_convert_link_mode_to_legacy_u32(u32 *legacy_u32,
* of the generic netdev features interface. * of the generic netdev features interface.
*/ */
struct ethtool_ops { struct ethtool_ops {
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
int (*set_settings)(struct net_device *, struct ethtool_cmd *);
void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *);
int (*get_regs_len)(struct net_device *); int (*get_regs_len)(struct net_device *);
void (*get_regs)(struct net_device *, struct ethtool_regs *, void *); void (*get_regs)(struct net_device *, struct ethtool_regs *, void *);
......
...@@ -91,10 +91,6 @@ ...@@ -91,10 +91,6 @@
* %ETHTOOL_GSET to get the current values before making specific * %ETHTOOL_GSET to get the current values before making specific
* changes and then applying them with %ETHTOOL_SSET. * changes and then applying them with %ETHTOOL_SSET.
* *
* Drivers that implement set_settings() should validate all fields
* other than @cmd that are not described as read-only or deprecated,
* and must ignore all fields described as read-only.
*
* Deprecated fields should be ignored by both users and drivers. * Deprecated fields should be ignored by both users and drivers.
*/ */
struct ethtool_cmd { struct ethtool_cmd {
...@@ -1800,14 +1796,9 @@ enum ethtool_reset_flags { ...@@ -1800,14 +1796,9 @@ enum ethtool_reset_flags {
* rejected. * rejected.
* *
* Deprecated %ethtool_cmd fields transceiver, maxtxpkt and maxrxpkt * Deprecated %ethtool_cmd fields transceiver, maxtxpkt and maxrxpkt
* are not available in %ethtool_link_settings. Until all drivers are * are not available in %ethtool_link_settings. These fields will be
* converted to ignore them or to the new %ethtool_link_settings API, * always set to zero in %ETHTOOL_GSET reply and %ETHTOOL_SSET will
* for both queries and changes, users should always try * fail if any of them is set to non-zero value.
* %ETHTOOL_GLINKSETTINGS first, and if it fails with -ENOTSUPP stick
* only to %ETHTOOL_GSET and %ETHTOOL_SSET consistently. If it
* succeeds, then users should stick to %ETHTOOL_GLINKSETTINGS and
* %ETHTOOL_SLINKSETTINGS (which would support drivers implementing
* either %ethtool_cmd or %ethtool_link_settings).
* *
* Users should assume that all fields not marked read-only are * Users should assume that all fields not marked read-only are
* writable and subject to validation by the driver. They should use * writable and subject to validation by the driver. They should use
......
...@@ -539,47 +539,17 @@ struct ethtool_link_usettings { ...@@ -539,47 +539,17 @@ struct ethtool_link_usettings {
} link_modes; } link_modes;
}; };
/* Internal kernel helper to query a device ethtool_link_settings. /* Internal kernel helper to query a device ethtool_link_settings. */
*
* Backward compatibility note: for compatibility with legacy drivers
* that implement only the ethtool_cmd API, this has to work with both
* drivers implementing get_link_ksettings API and drivers
* implementing get_settings API. When drivers implement get_settings
* and report ethtool_cmd deprecated fields
* (transceiver/maxrxpkt/maxtxpkt), these fields are silently ignored
* because the resulting struct ethtool_link_settings does not report them.
*/
int __ethtool_get_link_ksettings(struct net_device *dev, int __ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *link_ksettings) struct ethtool_link_ksettings *link_ksettings)
{ {
int err;
struct ethtool_cmd cmd;
ASSERT_RTNL(); ASSERT_RTNL();
if (dev->ethtool_ops->get_link_ksettings) { if (!dev->ethtool_ops->get_link_ksettings)
memset(link_ksettings, 0, sizeof(*link_ksettings));
return dev->ethtool_ops->get_link_ksettings(dev,
link_ksettings);
}
/* driver doesn't support %ethtool_link_ksettings API. revert to
* legacy %ethtool_cmd API, unless it's not supported either.
* TODO: remove when ethtool_ops::get_settings disappears internally
*/
if (!dev->ethtool_ops->get_settings)
return -EOPNOTSUPP; return -EOPNOTSUPP;
memset(&cmd, 0, sizeof(cmd)); memset(link_ksettings, 0, sizeof(*link_ksettings));
cmd.cmd = ETHTOOL_GSET; return dev->ethtool_ops->get_link_ksettings(dev, link_ksettings);
err = dev->ethtool_ops->get_settings(dev, &cmd);
if (err < 0)
return err;
/* we ignore deprecated fields transceiver/maxrxpkt/maxtxpkt
*/
convert_legacy_settings_to_link_ksettings(link_ksettings, &cmd);
return err;
} }
EXPORT_SYMBOL(__ethtool_get_link_ksettings); EXPORT_SYMBOL(__ethtool_get_link_ksettings);
...@@ -635,16 +605,7 @@ store_link_ksettings_for_user(void __user *to, ...@@ -635,16 +605,7 @@ store_link_ksettings_for_user(void __user *to,
return 0; return 0;
} }
/* Query device for its ethtool_link_settings. /* Query device for its ethtool_link_settings. */
*
* Backward compatibility note: this function must fail when driver
* does not implement ethtool::get_link_ksettings, even if legacy
* ethtool_ops::get_settings is implemented. This tells new versions
* of ethtool that they should use the legacy API %ETHTOOL_GSET for
* this driver, so that they can correctly access the ethtool_cmd
* deprecated fields (transceiver/maxrxpkt/maxtxpkt), until no driver
* implements ethtool_ops::get_settings anymore.
*/
static int ethtool_get_link_ksettings(struct net_device *dev, static int ethtool_get_link_ksettings(struct net_device *dev,
void __user *useraddr) void __user *useraddr)
{ {
...@@ -652,7 +613,6 @@ static int ethtool_get_link_ksettings(struct net_device *dev, ...@@ -652,7 +613,6 @@ static int ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings link_ksettings; struct ethtool_link_ksettings link_ksettings;
ASSERT_RTNL(); ASSERT_RTNL();
if (!dev->ethtool_ops->get_link_ksettings) if (!dev->ethtool_ops->get_link_ksettings)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -699,16 +659,7 @@ static int ethtool_get_link_ksettings(struct net_device *dev, ...@@ -699,16 +659,7 @@ static int ethtool_get_link_ksettings(struct net_device *dev,
return store_link_ksettings_for_user(useraddr, &link_ksettings); return store_link_ksettings_for_user(useraddr, &link_ksettings);
} }
/* Update device ethtool_link_settings. /* Update device ethtool_link_settings. */
*
* Backward compatibility note: this function must fail when driver
* does not implement ethtool::set_link_ksettings, even if legacy
* ethtool_ops::set_settings is implemented. This tells new versions
* of ethtool that they should use the legacy API %ETHTOOL_SSET for
* this driver, so that they can correctly update the ethtool_cmd
* deprecated fields (transceiver/maxrxpkt/maxtxpkt), until no driver
* implements ethtool_ops::get_settings anymore.
*/
static int ethtool_set_link_ksettings(struct net_device *dev, static int ethtool_set_link_ksettings(struct net_device *dev,
void __user *useraddr) void __user *useraddr)
{ {
...@@ -746,51 +697,31 @@ static int ethtool_set_link_ksettings(struct net_device *dev, ...@@ -746,51 +697,31 @@ static int ethtool_set_link_ksettings(struct net_device *dev,
/* Query device for its ethtool_cmd settings. /* Query device for its ethtool_cmd settings.
* *
* Backward compatibility note: for compatibility with legacy ethtool, * Backward compatibility note: for compatibility with legacy ethtool, this is
* this has to work with both drivers implementing get_link_ksettings * now implemented via get_link_ksettings. When driver reports higher link mode
* API and drivers implementing get_settings API. When drivers * bits, a kernel warning is logged once (with name of 1st driver/device) to
* implement get_link_ksettings and report higher link mode bits, a * recommend user to upgrade ethtool, but the command is successful (only the
* kernel warning is logged once (with name of 1st driver/device) to * lower link mode bits reported back to user). Deprecated fields from
* recommend user to upgrade ethtool, but the command is successful * ethtool_cmd (transceiver/maxrxpkt/maxtxpkt) are always set to zero.
* (only the lower link mode bits reported back to user).
*/ */
static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_link_ksettings link_ksettings;
struct ethtool_cmd cmd; struct ethtool_cmd cmd;
int err;
ASSERT_RTNL(); ASSERT_RTNL();
if (!dev->ethtool_ops->get_link_ksettings)
if (dev->ethtool_ops->get_link_ksettings) { return -EOPNOTSUPP;
/* First, use link_ksettings API if it is supported */
int err;
struct ethtool_link_ksettings link_ksettings;
memset(&link_ksettings, 0, sizeof(link_ksettings)); memset(&link_ksettings, 0, sizeof(link_ksettings));
err = dev->ethtool_ops->get_link_ksettings(dev, err = dev->ethtool_ops->get_link_ksettings(dev, &link_ksettings);
&link_ksettings);
if (err < 0) if (err < 0)
return err; return err;
convert_link_ksettings_to_legacy_settings(&cmd, convert_link_ksettings_to_legacy_settings(&cmd, &link_ksettings);
&link_ksettings);
/* send a sensible cmd tag back to user */ /* send a sensible cmd tag back to user */
cmd.cmd = ETHTOOL_GSET; cmd.cmd = ETHTOOL_GSET;
} else {
/* driver doesn't support %ethtool_link_ksettings
* API. revert to legacy %ethtool_cmd API, unless it's
* not supported either.
*/
int err;
if (!dev->ethtool_ops->get_settings)
return -EOPNOTSUPP;
memset(&cmd, 0, sizeof(cmd));
cmd.cmd = ETHTOOL_GSET;
err = dev->ethtool_ops->get_settings(dev, &cmd);
if (err < 0)
return err;
}
if (copy_to_user(useraddr, &cmd, sizeof(cmd))) if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
return -EFAULT; return -EFAULT;
...@@ -800,48 +731,29 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) ...@@ -800,48 +731,29 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
/* Update device link settings with given ethtool_cmd. /* Update device link settings with given ethtool_cmd.
* *
* Backward compatibility note: for compatibility with legacy ethtool, * Backward compatibility note: for compatibility with legacy ethtool, this is
* this has to work with both drivers implementing set_link_ksettings * now always implemented via set_link_settings. When user's request updates
* API and drivers implementing set_settings API. When drivers * deprecated ethtool_cmd fields (transceiver/maxrxpkt/maxtxpkt), a kernel
* implement set_link_ksettings and user's request updates deprecated * warning is logged once (with name of 1st driver/device) to recommend user to
* ethtool_cmd fields (transceiver/maxrxpkt/maxtxpkt), a kernel * upgrade ethtool, and the request is rejected.
* warning is logged once (with name of 1st driver/device) to
* recommend user to upgrade ethtool, and the request is rejected.
*/ */
static int ethtool_set_settings(struct net_device *dev, void __user *useraddr) static int ethtool_set_settings(struct net_device *dev, void __user *useraddr)
{ {
struct ethtool_link_ksettings link_ksettings;
struct ethtool_cmd cmd; struct ethtool_cmd cmd;
ASSERT_RTNL(); ASSERT_RTNL();
if (copy_from_user(&cmd, useraddr, sizeof(cmd))) if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
return -EFAULT; return -EFAULT;
if (!dev->ethtool_ops->set_link_ksettings)
/* first, try new %ethtool_link_ksettings API. */
if (dev->ethtool_ops->set_link_ksettings) {
struct ethtool_link_ksettings link_ksettings;
if (!convert_legacy_settings_to_link_ksettings(&link_ksettings,
&cmd))
return -EINVAL;
link_ksettings.base.cmd = ETHTOOL_SLINKSETTINGS;
link_ksettings.base.link_mode_masks_nwords
= __ETHTOOL_LINK_MODE_MASK_NU32;
return dev->ethtool_ops->set_link_ksettings(dev,
&link_ksettings);
}
/* legacy %ethtool_cmd API */
/* TODO: return -EOPNOTSUPP when ethtool_ops::get_settings
* disappears internally
*/
if (!dev->ethtool_ops->set_settings)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return dev->ethtool_ops->set_settings(dev, &cmd); if (!convert_legacy_settings_to_link_ksettings(&link_ksettings, &cmd))
return -EINVAL;
link_ksettings.base.link_mode_masks_nwords =
__ETHTOOL_LINK_MODE_MASK_NU32;
return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings);
} }
static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment