Message ID | 20210404081433.1260889-2-danieller@nvidia.com |
---|---|
State | New |
Headers | show |
Series | Fix link_mode derived params functionality | expand |
> -----Original Message----- > From: Andrew Lunn <andrew@lunn.ch> > Sent: Sunday, April 4, 2021 7:33 PM > To: Danielle Ratson <danieller@nvidia.com> > Cc: netdev@vger.kernel.org; davem@davemloft.net; kuba@kernel.org; eric.dumazet@gmail.com; mkubecek@suse.cz; > f.fainelli@gmail.com; acardace@redhat.com; irusskikh@marvell.com; gustavo@embeddedor.com; magnus.karlsson@intel.com; > ecree@solarflare.com; Ido Schimmel <idosch@nvidia.com>; Jiri Pirko <jiri@nvidia.com>; mlxsw <mlxsw@nvidia.com> > Subject: Re: [PATCH net v2 1/2] ethtool: Add link_mode parameter capability bit to ethtool_ops > > > @@ -436,12 +436,16 @@ int __ethtool_get_link_ksettings(struct > > net_device *dev, > > > > memset(link_ksettings, 0, sizeof(*link_ksettings)); > > > > - link_ksettings->link_mode = -1; > > err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings); > > if (err) > > return err; > > > > - if (link_ksettings->link_mode != -1) { > > + if (dev->ethtool_ops->cap_link_mode_supported && > > + link_ksettings->link_mode != -1) { > > Is this -1 behaviour documented anywhere? It seems like you just changed its meaning. It used to mean, this field has not been set, > ignore it. Adding the cap_link_mode_supported it now means, we have field has been set, but we have no idea what link mode is > being used. > So you should probably add something to the documentation of struct ethtool_link_ksettings. > > I wonder if we should actually add ETHTOOL_LINK_MODE_UNKNOWN to enum ethtool_link_mode_bit_indices? > > > + if (WARN_ON_ONCE(link_ksettings->link_mode >= > > + __ETHTOOL_LINK_MODE_MASK_NBITS)) > > + return -EINVAL; > > + > > link_info = &link_mode_params[link_ksettings->link_mode]; > > link_ksettings->base.speed = link_info->speed; > > link_ksettings->lanes = link_info->lanes; > > If dev->ethtool_ops->cap_link_mode_supported && link_ksettings->link_mode == -1 should you be setting speed to > SPEED_UNKNOWN, and lanes to LANE_UNKNOWN? Or is that already the default? > > But over all, this API between the core and the driver seems messy. Why not just add a helper in common.c which translates link > mode to speed/duplex/lanes and call it in the driver. Then you don't need this capability flags, which i doubt any other driver will ever > use. And you don't need to worry about drivers returning random values. As far as i can see, the link_mode returned by the driver is > not used for anything other than for this translation. So i don't see a need for it outside of the driver. Or maybe i'm missing > something? > > Andrew Hi Andrew, Please see my patch here: https://github.com/daniellerts/linux_mlxsw/commit/72ca614951418843aa87323630c354691d9e50d4 Since a lack of time until the window closes, please see if that is what you meant and you are ok with it, before I am sending another version. Thanks, Danielle
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c index 0bd64169bf81..54f04c94210c 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ethtool.c @@ -1061,6 +1061,7 @@ mlxsw_sp_get_ts_info(struct net_device *netdev, struct ethtool_ts_info *info) const struct ethtool_ops mlxsw_sp_port_ethtool_ops = { .cap_link_lanes_supported = true, + .cap_link_mode_supported = true, .get_drvinfo = mlxsw_sp_port_get_drvinfo, .get_link = ethtool_op_get_link, .get_link_ext_state = mlxsw_sp_port_get_link_ext_state, diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index ec4cd3921c67..9e6eb6df375d 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -269,6 +269,8 @@ struct ethtool_pause_stats { * struct ethtool_ops - optional netdev operations * @cap_link_lanes_supported: indicates if the driver supports lanes * parameter. + * @cap_link_mode_supported: indicates if the driver supports link_mode + * parameter. * @supported_coalesce_params: supported types of interrupt coalescing. * @get_drvinfo: Report driver/device information. Should only set the * @driver, @version, @fw_version and @bus_info fields. If not @@ -424,7 +426,8 @@ struct ethtool_pause_stats { * of the generic netdev features interface. */ struct ethtool_ops { - u32 cap_link_lanes_supported:1; + u32 cap_link_lanes_supported:1, + cap_link_mode_supported:1; u32 supported_coalesce_params; void (*get_drvinfo)(struct net_device *, struct ethtool_drvinfo *); int (*get_regs_len)(struct net_device *); diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c index 24783b71c584..cebbf93b27a7 100644 --- a/net/ethtool/ioctl.c +++ b/net/ethtool/ioctl.c @@ -436,12 +436,16 @@ int __ethtool_get_link_ksettings(struct net_device *dev, memset(link_ksettings, 0, sizeof(*link_ksettings)); - link_ksettings->link_mode = -1; err = dev->ethtool_ops->get_link_ksettings(dev, link_ksettings); if (err) return err; - if (link_ksettings->link_mode != -1) { + if (dev->ethtool_ops->cap_link_mode_supported && + link_ksettings->link_mode != -1) { + if (WARN_ON_ONCE(link_ksettings->link_mode >= + __ETHTOOL_LINK_MODE_MASK_NBITS)) + return -EINVAL; + link_info = &link_mode_params[link_ksettings->link_mode]; link_ksettings->base.speed = link_info->speed; link_ksettings->lanes = link_info->lanes;