Skip to content

Commit

Permalink
nfp: add support for .get_link_ksettings()
Browse files Browse the repository at this point in the history
Read link speed from the BAR.  This provides very basic information
and works for both PFs and VFs.

Signed-off-by: Jakub Kicinski <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
Jakub Kicinski authored and davem330 committed Apr 5, 2017
1 parent 18148f0 commit 265aeb5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
13 changes: 13 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,19 @@
#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0)
#define NFP_NET_CFG_STS 0x0034
#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */
/* Link rate */
#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1
#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF
#define NFP_NET_CFG_STS_LINK_RATE \
(NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_SHIFT)
#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0
#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1
#define NFP_NET_CFG_STS_LINK_RATE_1G 2
#define NFP_NET_CFG_STS_LINK_RATE_10G 3
#define NFP_NET_CFG_STS_LINK_RATE_25G 4
#define NFP_NET_CFG_STS_LINK_RATE_40G 5
#define NFP_NET_CFG_STS_LINK_RATE_50G 6
#define NFP_NET_CFG_STS_LINK_RATE_100G 7
#define NFP_NET_CFG_CAP 0x0038
#define NFP_NET_CFG_MAX_TXRINGS 0x003c
#define NFP_NET_CFG_MAX_RXRINGS 0x0040
Expand Down
49 changes: 49 additions & 0 deletions drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,54 @@ static void nfp_net_get_drvinfo(struct net_device *netdev,
drvinfo->regdump_len = NFP_NET_CFG_BAR_SZ;
}

/**
* nfp_net_get_link_ksettings - Get Link Speed settings
* @netdev: network interface device structure
* @cmd: ethtool command
*
* Reports speed settings based on info in the BAR provided by the fw.
*/
static int
nfp_net_get_link_ksettings(struct net_device *netdev,
struct ethtool_link_ksettings *cmd)
{
static const u32 ls_to_ethtool[] = {
[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0,
[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = SPEED_UNKNOWN,
[NFP_NET_CFG_STS_LINK_RATE_1G] = SPEED_1000,
[NFP_NET_CFG_STS_LINK_RATE_10G] = SPEED_10000,
[NFP_NET_CFG_STS_LINK_RATE_25G] = SPEED_25000,
[NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000,
[NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000,
[NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000,
};
struct nfp_net *nn = netdev_priv(netdev);
u32 sts, ls;

ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
cmd->base.port = PORT_OTHER;
cmd->base.speed = SPEED_UNKNOWN;
cmd->base.duplex = DUPLEX_UNKNOWN;

if (!netif_carrier_ok(netdev))
return 0;

sts = nn_readl(nn, NFP_NET_CFG_STS);

ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts);
if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED)
return -EOPNOTSUPP;

if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
ls >= ARRAY_SIZE(ls_to_ethtool))
return 0;

cmd->base.speed = ls_to_ethtool[sts];
cmd->base.duplex = DUPLEX_FULL;

return 0;
}

static void nfp_net_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
Expand Down Expand Up @@ -814,6 +862,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
.set_coalesce = nfp_net_set_coalesce,
.get_channels = nfp_net_get_channels,
.set_channels = nfp_net_set_channels,
.get_link_ksettings = nfp_net_get_link_ksettings,
};

void nfp_net_set_ethtool_ops(struct net_device *netdev)
Expand Down

0 comments on commit 265aeb5

Please sign in to comment.