Skip to content

Commit a61474c

Browse files
macris-xiaoPaolo Abeni
authored andcommitted
nfp: ethtool: support reporting link modes
Add support for reporting link modes, including `Supported link modes` and `Advertised link modes`, via ethtool $DEV. A new command `SPCODE_READ_MEDIA` is added to read info from management firmware. Also, the mapping table `nfp_eth_media_table` associates the link modes between NFP and kernel. Both of them help to support this ability. Signed-off-by: Yu Xiao <yu.xiao@corigine.com> Reviewed-by: Louis Peens <louis.peens@corigine.com> Signed-off-by: Simon Horman <simon.horman@corigine.com> Reviewed-by: Alexander Lobakin <alexandr.lobakin@intel.com> Link: https://lore.kernel.org/r/20221125113030.141642-1-simon.horman@corigine.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 7666dbe commit a61474c

File tree

5 files changed

+173
-0
lines changed

5 files changed

+173
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ struct nfp_hwinfo;
2727
struct nfp_mip;
2828
struct nfp_net;
2929
struct nfp_nsp_identify;
30+
struct nfp_eth_media_buf;
3031
struct nfp_port;
3132
struct nfp_rtsym;
3233
struct nfp_rtsym_table;

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,76 @@ nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
293293
}
294294
}
295295

296+
static const u16 nfp_eth_media_table[] = {
297+
[NFP_MEDIA_1000BASE_CX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
298+
[NFP_MEDIA_1000BASE_KX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
299+
[NFP_MEDIA_10GBASE_KX4] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
300+
[NFP_MEDIA_10GBASE_KR] = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
301+
[NFP_MEDIA_10GBASE_CX4] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
302+
[NFP_MEDIA_10GBASE_CR] = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
303+
[NFP_MEDIA_10GBASE_SR] = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
304+
[NFP_MEDIA_10GBASE_ER] = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
305+
[NFP_MEDIA_25GBASE_KR] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
306+
[NFP_MEDIA_25GBASE_KR_S] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
307+
[NFP_MEDIA_25GBASE_CR] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
308+
[NFP_MEDIA_25GBASE_CR_S] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
309+
[NFP_MEDIA_25GBASE_SR] = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
310+
[NFP_MEDIA_40GBASE_CR4] = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
311+
[NFP_MEDIA_40GBASE_KR4] = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
312+
[NFP_MEDIA_40GBASE_SR4] = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
313+
[NFP_MEDIA_40GBASE_LR4] = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
314+
[NFP_MEDIA_50GBASE_KR] = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
315+
[NFP_MEDIA_50GBASE_SR] = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
316+
[NFP_MEDIA_50GBASE_CR] = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
317+
[NFP_MEDIA_50GBASE_LR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
318+
[NFP_MEDIA_50GBASE_ER] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
319+
[NFP_MEDIA_50GBASE_FR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
320+
[NFP_MEDIA_100GBASE_KR4] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
321+
[NFP_MEDIA_100GBASE_SR4] = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
322+
[NFP_MEDIA_100GBASE_CR4] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
323+
[NFP_MEDIA_100GBASE_KP4] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
324+
[NFP_MEDIA_100GBASE_CR10] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
325+
};
326+
327+
static void nfp_add_media_link_mode(struct nfp_port *port,
328+
struct nfp_eth_table_port *eth_port,
329+
struct ethtool_link_ksettings *cmd)
330+
{
331+
u64 supported_modes[2], advertised_modes[2];
332+
struct nfp_eth_media_buf ethm = {
333+
.eth_index = eth_port->eth_index,
334+
};
335+
struct nfp_cpp *cpp = port->app->cpp;
336+
337+
if (nfp_eth_read_media(cpp, &ethm))
338+
return;
339+
340+
for (u32 i = 0; i < 2; i++) {
341+
supported_modes[i] = le64_to_cpu(ethm.supported_modes[i]);
342+
advertised_modes[i] = le64_to_cpu(ethm.advertised_modes[i]);
343+
}
344+
345+
for (u32 i = 0; i < NFP_MEDIA_LINK_MODES_NUMBER; i++) {
346+
if (i < 64) {
347+
if (supported_modes[0] & BIT_ULL(i))
348+
__set_bit(nfp_eth_media_table[i],
349+
cmd->link_modes.supported);
350+
351+
if (advertised_modes[0] & BIT_ULL(i))
352+
__set_bit(nfp_eth_media_table[i],
353+
cmd->link_modes.advertising);
354+
} else {
355+
if (supported_modes[1] & BIT_ULL(i - 64))
356+
__set_bit(nfp_eth_media_table[i],
357+
cmd->link_modes.supported);
358+
359+
if (advertised_modes[1] & BIT_ULL(i - 64))
360+
__set_bit(nfp_eth_media_table[i],
361+
cmd->link_modes.advertising);
362+
}
363+
}
364+
}
365+
296366
/**
297367
* nfp_net_get_link_ksettings - Get Link Speed settings
298368
* @netdev: network interface device structure
@@ -311,6 +381,8 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
311381
u16 sts;
312382

313383
/* Init to unknowns */
384+
ethtool_link_ksettings_zero_link_mode(cmd, supported);
385+
ethtool_link_ksettings_zero_link_mode(cmd, advertising);
314386
ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE);
315387
cmd->base.port = PORT_OTHER;
316388
cmd->base.speed = SPEED_UNKNOWN;
@@ -321,6 +393,7 @@ nfp_net_get_link_ksettings(struct net_device *netdev,
321393
if (eth_port) {
322394
ethtool_link_ksettings_add_link_mode(cmd, supported, Pause);
323395
ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause);
396+
nfp_add_media_link_mode(port, eth_port, cmd);
324397
if (eth_port->supp_aneg) {
325398
ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg);
326399
if (eth_port->aneg == NFP_ANEG_AUTO) {

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ enum nfp_nsp_cmd {
100100
SPCODE_FW_LOADED = 19, /* Is application firmware loaded */
101101
SPCODE_VERSIONS = 21, /* Report FW versions */
102102
SPCODE_READ_SFF_EEPROM = 22, /* Read module EEPROM */
103+
SPCODE_READ_MEDIA = 23, /* Get either the supported or advertised media for a port */
103104
};
104105

105106
struct nfp_nsp_dma_buf {
@@ -1100,4 +1101,20 @@ int nfp_nsp_read_module_eeprom(struct nfp_nsp *state, int eth_index,
11001101
kfree(buf);
11011102

11021103
return ret;
1104+
};
1105+
1106+
int nfp_nsp_read_media(struct nfp_nsp *state, void *buf, unsigned int size)
1107+
{
1108+
struct nfp_nsp_command_buf_arg media = {
1109+
{
1110+
.code = SPCODE_READ_MEDIA,
1111+
.option = size,
1112+
},
1113+
.in_buf = buf,
1114+
.in_size = size,
1115+
.out_buf = buf,
1116+
.out_size = size,
1117+
};
1118+
1119+
return nfp_nsp_command_buf(state, &media);
11031120
}

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ static inline bool nfp_nsp_has_read_module_eeprom(struct nfp_nsp *state)
6565
return nfp_nsp_get_abi_ver_minor(state) > 28;
6666
}
6767

68+
static inline bool nfp_nsp_has_read_media(struct nfp_nsp *state)
69+
{
70+
return nfp_nsp_get_abi_ver_minor(state) > 33;
71+
}
72+
6873
enum nfp_eth_interface {
6974
NFP_INTERFACE_NONE = 0,
7075
NFP_INTERFACE_SFP = 1,
@@ -97,6 +102,47 @@ enum nfp_eth_fec {
97102
NFP_FEC_DISABLED_BIT,
98103
};
99104

105+
/* link modes about RJ45 haven't been used, so there's no mapping to them */
106+
enum nfp_ethtool_link_mode_list {
107+
NFP_MEDIA_W0_RJ45_10M,
108+
NFP_MEDIA_W0_RJ45_10M_HD,
109+
NFP_MEDIA_W0_RJ45_100M,
110+
NFP_MEDIA_W0_RJ45_100M_HD,
111+
NFP_MEDIA_W0_RJ45_1G,
112+
NFP_MEDIA_W0_RJ45_2P5G,
113+
NFP_MEDIA_W0_RJ45_5G,
114+
NFP_MEDIA_W0_RJ45_10G,
115+
NFP_MEDIA_1000BASE_CX,
116+
NFP_MEDIA_1000BASE_KX,
117+
NFP_MEDIA_10GBASE_KX4,
118+
NFP_MEDIA_10GBASE_KR,
119+
NFP_MEDIA_10GBASE_CX4,
120+
NFP_MEDIA_10GBASE_CR,
121+
NFP_MEDIA_10GBASE_SR,
122+
NFP_MEDIA_10GBASE_ER,
123+
NFP_MEDIA_25GBASE_KR,
124+
NFP_MEDIA_25GBASE_KR_S,
125+
NFP_MEDIA_25GBASE_CR,
126+
NFP_MEDIA_25GBASE_CR_S,
127+
NFP_MEDIA_25GBASE_SR,
128+
NFP_MEDIA_40GBASE_CR4,
129+
NFP_MEDIA_40GBASE_KR4,
130+
NFP_MEDIA_40GBASE_SR4,
131+
NFP_MEDIA_40GBASE_LR4,
132+
NFP_MEDIA_50GBASE_KR,
133+
NFP_MEDIA_50GBASE_SR,
134+
NFP_MEDIA_50GBASE_CR,
135+
NFP_MEDIA_50GBASE_LR,
136+
NFP_MEDIA_50GBASE_ER,
137+
NFP_MEDIA_50GBASE_FR,
138+
NFP_MEDIA_100GBASE_KR4,
139+
NFP_MEDIA_100GBASE_SR4,
140+
NFP_MEDIA_100GBASE_CR4,
141+
NFP_MEDIA_100GBASE_KP4,
142+
NFP_MEDIA_100GBASE_CR10,
143+
NFP_MEDIA_LINK_MODES_NUMBER
144+
};
145+
100146
#define NFP_FEC_AUTO BIT(NFP_FEC_AUTO_BIT)
101147
#define NFP_FEC_BASER BIT(NFP_FEC_BASER_BIT)
102148
#define NFP_FEC_REED_SOLOMON BIT(NFP_FEC_REED_SOLOMON_BIT)
@@ -256,6 +302,16 @@ enum nfp_nsp_sensor_id {
256302
int nfp_hwmon_read_sensor(struct nfp_cpp *cpp, enum nfp_nsp_sensor_id id,
257303
long *val);
258304

305+
struct nfp_eth_media_buf {
306+
u8 eth_index;
307+
u8 reserved[7];
308+
__le64 supported_modes[2];
309+
__le64 advertised_modes[2];
310+
};
311+
312+
int nfp_nsp_read_media(struct nfp_nsp *state, void *buf, unsigned int size);
313+
int nfp_eth_read_media(struct nfp_cpp *cpp, struct nfp_eth_media_buf *ethm);
314+
259315
#define NFP_NSP_VERSION_BUFSZ 1024 /* reasonable size, not in the ABI */
260316

261317
enum nfp_nsp_versions {

drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,3 +647,29 @@ int __nfp_eth_set_split(struct nfp_nsp *nsp, unsigned int lanes)
647647
return NFP_ETH_SET_BIT_CONFIG(nsp, NSP_ETH_RAW_PORT, NSP_ETH_PORT_LANES,
648648
lanes, NSP_ETH_CTRL_SET_LANES);
649649
}
650+
651+
int nfp_eth_read_media(struct nfp_cpp *cpp, struct nfp_eth_media_buf *ethm)
652+
{
653+
struct nfp_nsp *nsp;
654+
int ret;
655+
656+
nsp = nfp_nsp_open(cpp);
657+
if (IS_ERR(nsp)) {
658+
nfp_err(cpp, "Failed to access the NSP: %pe\n", nsp);
659+
return PTR_ERR(nsp);
660+
}
661+
662+
if (!nfp_nsp_has_read_media(nsp)) {
663+
nfp_warn(cpp, "Reading media link modes not supported. Please update flash\n");
664+
ret = -EOPNOTSUPP;
665+
goto exit_close_nsp;
666+
}
667+
668+
ret = nfp_nsp_read_media(nsp, ethm, sizeof(*ethm));
669+
if (ret)
670+
nfp_err(cpp, "Reading media link modes failed: %pe\n", ERR_PTR(ret));
671+
672+
exit_close_nsp:
673+
nfp_nsp_close(nsp);
674+
return ret;
675+
}

0 commit comments

Comments
 (0)