Commit 7c698737 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

nfp: add support for .set_link_ksettings()

Support setting link speed and autonegotiation through
set_link_ksettings() ethtool op.  If the port is reconfigured
in incompatible way and reboot is required the netdev will get
unregistered and not come back until user reboots the system.
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarSimon Horman <simon.horman@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5a560832
...@@ -237,6 +237,51 @@ nfp_net_get_link_ksettings(struct net_device *netdev, ...@@ -237,6 +237,51 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
return 0; return 0;
} }
static int
nfp_net_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *cmd)
{
struct nfp_net *nn = netdev_priv(netdev);
struct nfp_nsp *nsp;
int err;
if (!nn->eth_port)
return -EOPNOTSUPP;
if (netif_running(netdev)) {
nn_warn(nn, "Changing settings not allowed on an active interface. It may cause the port to be disabled until reboot.\n");
return -EBUSY;
}
nsp = nfp_eth_config_start(nn->cpp, nn->eth_port->index);
if (IS_ERR(nsp))
return PTR_ERR(nsp);
err = __nfp_eth_set_aneg(nsp, cmd->base.autoneg == AUTONEG_ENABLE ?
NFP_ANEG_AUTO : NFP_ANEG_DISABLED);
if (err)
goto err_bad_set;
if (cmd->base.speed != SPEED_UNKNOWN) {
u32 speed = cmd->base.speed / nn->eth_port->lanes;
err = __nfp_eth_set_speed(nsp, speed);
if (err)
goto err_bad_set;
}
err = nfp_eth_config_commit_end(nsp);
if (err > 0)
return 0; /* no change */
nfp_net_refresh_port_config(nn);
return err;
err_bad_set:
nfp_eth_config_cleanup_end(nsp);
return err;
}
static void nfp_net_get_ringparam(struct net_device *netdev, static void nfp_net_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
...@@ -879,6 +924,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = { ...@@ -879,6 +924,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
.get_channels = nfp_net_get_channels, .get_channels = nfp_net_get_channels,
.set_channels = nfp_net_set_channels, .set_channels = nfp_net_set_channels,
.get_link_ksettings = nfp_net_get_link_ksettings, .get_link_ksettings = nfp_net_get_link_ksettings,
.set_link_ksettings = nfp_net_set_link_ksettings,
}; };
void nfp_net_set_ethtool_ops(struct net_device *netdev) void nfp_net_set_ethtool_ops(struct net_device *netdev)
......
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