Skip to content

Commit 265aeb5

Browse files
Jakub Kicinskidavem330
authored andcommitted
nfp: add support for .get_link_ksettings()
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]>
1 parent 18148f0 commit 265aeb5

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

drivers/net/ethernet/netronome/nfp/nfp_net_ctrl.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,19 @@
177177
#define NFP_NET_CFG_VERSION_MINOR(x) (((x) & 0xff) << 0)
178178
#define NFP_NET_CFG_STS 0x0034
179179
#define NFP_NET_CFG_STS_LINK (0x1 << 0) /* Link up or down */
180+
/* Link rate */
181+
#define NFP_NET_CFG_STS_LINK_RATE_SHIFT 1
182+
#define NFP_NET_CFG_STS_LINK_RATE_MASK 0xF
183+
#define NFP_NET_CFG_STS_LINK_RATE \
184+
(NFP_NET_CFG_STS_LINK_RATE_MASK << NFP_NET_CFG_STS_LINK_RATE_SHIFT)
185+
#define NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED 0
186+
#define NFP_NET_CFG_STS_LINK_RATE_UNKNOWN 1
187+
#define NFP_NET_CFG_STS_LINK_RATE_1G 2
188+
#define NFP_NET_CFG_STS_LINK_RATE_10G 3
189+
#define NFP_NET_CFG_STS_LINK_RATE_25G 4
190+
#define NFP_NET_CFG_STS_LINK_RATE_40G 5
191+
#define NFP_NET_CFG_STS_LINK_RATE_50G 6
192+
#define NFP_NET_CFG_STS_LINK_RATE_100G 7
180193
#define NFP_NET_CFG_CAP 0x0038
181194
#define NFP_NET_CFG_MAX_TXRINGS 0x003c
182195
#define NFP_NET_CFG_MAX_RXRINGS 0x0040

drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,54 @@ static void nfp_net_get_drvinfo(struct net_device *netdev,
173173
drvinfo->regdump_len = NFP_NET_CFG_BAR_SZ;
174174
}
175175

176+
/**
177+
* nfp_net_get_link_ksettings - Get Link Speed settings
178+
* @netdev: network interface device structure
179+
* @cmd: ethtool command
180+
*
181+
* Reports speed settings based on info in the BAR provided by the fw.
182+
*/
183+
static int
184+
nfp_net_get_link_ksettings(struct net_device *netdev,
185+
struct ethtool_link_ksettings *cmd)
186+
{
187+
static const u32 ls_to_ethtool[] = {
188+
[NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED] = 0,
189+
[NFP_NET_CFG_STS_LINK_RATE_UNKNOWN] = SPEED_UNKNOWN,
190+
[NFP_NET_CFG_STS_LINK_RATE_1G] = SPEED_1000,
191+
[NFP_NET_CFG_STS_LINK_RATE_10G] = SPEED_10000,
192+
[NFP_NET_CFG_STS_LINK_RATE_25G] = SPEED_25000,
193+
[NFP_NET_CFG_STS_LINK_RATE_40G] = SPEED_40000,
194+
[NFP_NET_CFG_STS_LINK_RATE_50G] = SPEED_50000,
195+
[NFP_NET_CFG_STS_LINK_RATE_100G] = SPEED_100000,
196+
};
197+
struct nfp_net *nn = netdev_priv(netdev);
198+
u32 sts, ls;
199+
200+
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
201+
cmd->base.port = PORT_OTHER;
202+
cmd->base.speed = SPEED_UNKNOWN;
203+
cmd->base.duplex = DUPLEX_UNKNOWN;
204+
205+
if (!netif_carrier_ok(netdev))
206+
return 0;
207+
208+
sts = nn_readl(nn, NFP_NET_CFG_STS);
209+
210+
ls = FIELD_GET(NFP_NET_CFG_STS_LINK_RATE, sts);
211+
if (ls == NFP_NET_CFG_STS_LINK_RATE_UNSUPPORTED)
212+
return -EOPNOTSUPP;
213+
214+
if (ls == NFP_NET_CFG_STS_LINK_RATE_UNKNOWN ||
215+
ls >= ARRAY_SIZE(ls_to_ethtool))
216+
return 0;
217+
218+
cmd->base.speed = ls_to_ethtool[sts];
219+
cmd->base.duplex = DUPLEX_FULL;
220+
221+
return 0;
222+
}
223+
176224
static void nfp_net_get_ringparam(struct net_device *netdev,
177225
struct ethtool_ringparam *ring)
178226
{
@@ -814,6 +862,7 @@ static const struct ethtool_ops nfp_net_ethtool_ops = {
814862
.set_coalesce = nfp_net_set_coalesce,
815863
.get_channels = nfp_net_get_channels,
816864
.set_channels = nfp_net_set_channels,
865+
.get_link_ksettings = nfp_net_get_link_ksettings,
817866
};
818867

819868
void nfp_net_set_ethtool_ops(struct net_device *netdev)

0 commit comments

Comments
 (0)