net/ethtool: Introduce link_ksettings API for virtual network devices

With the ethtool_virtdev_set_link_ksettings function in core/ethtool.c,
ibmveth, netvsc, and virtio now use the core's helper function.

Funtionality changes that pertain to ibmveth driver include:

  1. Changed the initial hardcoded link speed to 1GB.

  2. Added support for allowing a user to change the reported link
  speed via ethtool.

Functionality changes to the netvsc driver include:

  1. When netvsc_get_link_ksettings is called, it will defer to the VF
  device if it exists to pull accelerated networking values, otherwise
  pull default or user-defined values.

  2. Similarly, if netvsc_set_link_ksettings called and a VF device
  exists, the real values of speed and duplex are changed.

Signed-off-by: Cris Forno <cforno12@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Cris Forno
2020-02-28 14:12:05 -06:00
committed by David S. Miller
parent 70ae1e127b
commit 9aedc6e2f1
4 changed files with 51 additions and 85 deletions

View File

@@ -712,29 +712,36 @@ static int ibmveth_close(struct net_device *netdev)
return 0;
}
static int netdev_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
static int ibmveth_set_link_ksettings(struct net_device *dev,
const struct ethtool_link_ksettings *cmd)
{
u32 supported, advertising;
struct ibmveth_adapter *adapter = netdev_priv(dev);
supported = (SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
SUPPORTED_FIBRE);
advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
ADVERTISED_FIBRE);
cmd->base.speed = SPEED_1000;
cmd->base.duplex = DUPLEX_FULL;
cmd->base.port = PORT_FIBRE;
cmd->base.phy_address = 0;
cmd->base.autoneg = AUTONEG_ENABLE;
return ethtool_virtdev_set_link_ksettings(dev, cmd,
&adapter->speed,
&adapter->duplex);
}
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.supported,
supported);
ethtool_convert_legacy_u32_to_link_mode(cmd->link_modes.advertising,
advertising);
static int ibmveth_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *cmd)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
cmd->base.speed = adapter->speed;
cmd->base.duplex = adapter->duplex;
cmd->base.port = PORT_OTHER;
return 0;
}
static void ibmveth_init_link_settings(struct net_device *dev)
{
struct ibmveth_adapter *adapter = netdev_priv(dev);
adapter->speed = SPEED_1000;
adapter->duplex = DUPLEX_FULL;
}
static void netdev_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
@@ -965,12 +972,13 @@ static void ibmveth_get_ethtool_stats(struct net_device *dev,
}
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_strings = ibmveth_get_strings,
.get_sset_count = ibmveth_get_sset_count,
.get_ethtool_stats = ibmveth_get_ethtool_stats,
.get_link_ksettings = netdev_get_link_ksettings,
.get_drvinfo = netdev_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_strings = ibmveth_get_strings,
.get_sset_count = ibmveth_get_sset_count,
.get_ethtool_stats = ibmveth_get_ethtool_stats,
.get_link_ksettings = ibmveth_get_link_ksettings,
.set_link_ksettings = ibmveth_set_link_ksettings,
};
static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1674,6 +1682,7 @@ static int ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
adapter->netdev = netdev;
adapter->mcastFilterSize = be32_to_cpu(*mcastFilterSize_p);
adapter->pool_config = 0;
ibmveth_init_link_settings(netdev);
netif_napi_add(netdev, &adapter->napi, ibmveth_poll, 16);