Skip to content

Commit 821de68

Browse files
macris-xiaodavem330
authored andcommitted
nfp: ethtool: fix the bug of setting unsupported port speed
Unsupported port speed can be set and cause error. Now fixing it and return an error if setting unsupported speed. This fix depends on the following, which was included in v6.2-rc1: commit a61474c ("nfp: ethtool: support reporting link modes"). Fixes: 7c69873 ("nfp: add support for .set_link_ksettings()") Signed-off-by: Yu Xiao <[email protected]> Signed-off-by: Simon Horman <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c11204c commit 821de68

File tree

2 files changed

+170
-36
lines changed

2 files changed

+170
-36
lines changed

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

Lines changed: 158 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -293,35 +293,131 @@ 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,
296+
static const struct nfp_eth_media_link_mode {
297+
u16 ethtool_link_mode;
298+
u16 speed;
299+
} nfp_eth_media_table[NFP_MEDIA_LINK_MODES_NUMBER] = {
300+
[NFP_MEDIA_1000BASE_CX] = {
301+
.ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
302+
.speed = NFP_SPEED_1G,
303+
},
304+
[NFP_MEDIA_1000BASE_KX] = {
305+
.ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
306+
.speed = NFP_SPEED_1G,
307+
},
308+
[NFP_MEDIA_10GBASE_KX4] = {
309+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
310+
.speed = NFP_SPEED_10G,
311+
},
312+
[NFP_MEDIA_10GBASE_KR] = {
313+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
314+
.speed = NFP_SPEED_10G,
315+
},
316+
[NFP_MEDIA_10GBASE_CX4] = {
317+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
318+
.speed = NFP_SPEED_10G,
319+
},
320+
[NFP_MEDIA_10GBASE_CR] = {
321+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
322+
.speed = NFP_SPEED_10G,
323+
},
324+
[NFP_MEDIA_10GBASE_SR] = {
325+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
326+
.speed = NFP_SPEED_10G,
327+
},
328+
[NFP_MEDIA_10GBASE_ER] = {
329+
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
330+
.speed = NFP_SPEED_10G,
331+
},
332+
[NFP_MEDIA_25GBASE_KR] = {
333+
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
334+
.speed = NFP_SPEED_25G,
335+
},
336+
[NFP_MEDIA_25GBASE_KR_S] = {
337+
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
338+
.speed = NFP_SPEED_25G,
339+
},
340+
[NFP_MEDIA_25GBASE_CR] = {
341+
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
342+
.speed = NFP_SPEED_25G,
343+
},
344+
[NFP_MEDIA_25GBASE_CR_S] = {
345+
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
346+
.speed = NFP_SPEED_25G,
347+
},
348+
[NFP_MEDIA_25GBASE_SR] = {
349+
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
350+
.speed = NFP_SPEED_25G,
351+
},
352+
[NFP_MEDIA_40GBASE_CR4] = {
353+
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
354+
.speed = NFP_SPEED_40G,
355+
},
356+
[NFP_MEDIA_40GBASE_KR4] = {
357+
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
358+
.speed = NFP_SPEED_40G,
359+
},
360+
[NFP_MEDIA_40GBASE_SR4] = {
361+
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
362+
.speed = NFP_SPEED_40G,
363+
},
364+
[NFP_MEDIA_40GBASE_LR4] = {
365+
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
366+
.speed = NFP_SPEED_40G,
367+
},
368+
[NFP_MEDIA_50GBASE_KR] = {
369+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
370+
.speed = NFP_SPEED_50G,
371+
},
372+
[NFP_MEDIA_50GBASE_SR] = {
373+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
374+
.speed = NFP_SPEED_50G,
375+
},
376+
[NFP_MEDIA_50GBASE_CR] = {
377+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
378+
.speed = NFP_SPEED_50G,
379+
},
380+
[NFP_MEDIA_50GBASE_LR] = {
381+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
382+
.speed = NFP_SPEED_50G,
383+
},
384+
[NFP_MEDIA_50GBASE_ER] = {
385+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
386+
.speed = NFP_SPEED_50G,
387+
},
388+
[NFP_MEDIA_50GBASE_FR] = {
389+
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
390+
.speed = NFP_SPEED_50G,
391+
},
392+
[NFP_MEDIA_100GBASE_KR4] = {
393+
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
394+
.speed = NFP_SPEED_100G,
395+
},
396+
[NFP_MEDIA_100GBASE_SR4] = {
397+
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
398+
.speed = NFP_SPEED_100G,
399+
},
400+
[NFP_MEDIA_100GBASE_CR4] = {
401+
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
402+
.speed = NFP_SPEED_100G,
403+
},
404+
[NFP_MEDIA_100GBASE_KP4] = {
405+
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
406+
.speed = NFP_SPEED_100G,
407+
},
408+
[NFP_MEDIA_100GBASE_CR10] = {
409+
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
410+
.speed = NFP_SPEED_100G,
411+
},
412+
};
413+
414+
static const unsigned int nfp_eth_speed_map[NFP_SUP_SPEED_NUMBER] = {
415+
[NFP_SPEED_1G] = SPEED_1000,
416+
[NFP_SPEED_10G] = SPEED_10000,
417+
[NFP_SPEED_25G] = SPEED_25000,
418+
[NFP_SPEED_40G] = SPEED_40000,
419+
[NFP_SPEED_50G] = SPEED_50000,
420+
[NFP_SPEED_100G] = SPEED_100000,
325421
};
326422

327423
static void nfp_add_media_link_mode(struct nfp_port *port,
@@ -334,8 +430,12 @@ static void nfp_add_media_link_mode(struct nfp_port *port,
334430
};
335431
struct nfp_cpp *cpp = port->app->cpp;
336432

337-
if (nfp_eth_read_media(cpp, &ethm))
433+
if (nfp_eth_read_media(cpp, &ethm)) {
434+
bitmap_fill(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
338435
return;
436+
}
437+
438+
bitmap_zero(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
339439

340440
for (u32 i = 0; i < 2; i++) {
341441
supported_modes[i] = le64_to_cpu(ethm.supported_modes[i]);
@@ -344,20 +444,26 @@ static void nfp_add_media_link_mode(struct nfp_port *port,
344444

345445
for (u32 i = 0; i < NFP_MEDIA_LINK_MODES_NUMBER; i++) {
346446
if (i < 64) {
347-
if (supported_modes[0] & BIT_ULL(i))
348-
__set_bit(nfp_eth_media_table[i],
447+
if (supported_modes[0] & BIT_ULL(i)) {
448+
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
349449
cmd->link_modes.supported);
450+
__set_bit(nfp_eth_media_table[i].speed,
451+
port->speed_bitmap);
452+
}
350453

351454
if (advertised_modes[0] & BIT_ULL(i))
352-
__set_bit(nfp_eth_media_table[i],
455+
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
353456
cmd->link_modes.advertising);
354457
} else {
355-
if (supported_modes[1] & BIT_ULL(i - 64))
356-
__set_bit(nfp_eth_media_table[i],
458+
if (supported_modes[1] & BIT_ULL(i - 64)) {
459+
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
357460
cmd->link_modes.supported);
461+
__set_bit(nfp_eth_media_table[i].speed,
462+
port->speed_bitmap);
463+
}
358464

359465
if (advertised_modes[1] & BIT_ULL(i - 64))
360-
__set_bit(nfp_eth_media_table[i],
466+
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
361467
cmd->link_modes.advertising);
362468
}
363469
}
@@ -468,6 +574,22 @@ nfp_net_set_link_ksettings(struct net_device *netdev,
468574

469575
if (cmd->base.speed != SPEED_UNKNOWN) {
470576
u32 speed = cmd->base.speed / eth_port->lanes;
577+
bool is_supported = false;
578+
579+
for (u32 i = 0; i < NFP_SUP_SPEED_NUMBER; i++) {
580+
if (cmd->base.speed == nfp_eth_speed_map[i] &&
581+
test_bit(i, port->speed_bitmap)) {
582+
is_supported = true;
583+
break;
584+
}
585+
}
586+
587+
if (!is_supported) {
588+
netdev_err(netdev, "Speed %u is not supported.\n",
589+
cmd->base.speed);
590+
err = -EINVAL;
591+
goto err_bad_set;
592+
}
471593

472594
if (req_aneg) {
473595
netdev_err(netdev, "Speed changing is not allowed when working on autoneg mode.\n");

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ enum nfp_port_flags {
3838
NFP_PORT_CHANGED = 0,
3939
};
4040

41+
enum {
42+
NFP_SPEED_1G,
43+
NFP_SPEED_10G,
44+
NFP_SPEED_25G,
45+
NFP_SPEED_40G,
46+
NFP_SPEED_50G,
47+
NFP_SPEED_100G,
48+
NFP_SUP_SPEED_NUMBER
49+
};
50+
4151
/**
4252
* struct nfp_port - structure representing NFP port
4353
* @netdev: backpointer to associated netdev
@@ -52,6 +62,7 @@ enum nfp_port_flags {
5262
* @eth_forced: for %NFP_PORT_PHYS_PORT port is forced UP or DOWN, don't change
5363
* @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry
5464
* @eth_stats: for %NFP_PORT_PHYS_PORT MAC stats if available
65+
* @speed_bitmap: for %NFP_PORT_PHYS_PORT supported speed bitmap
5566
* @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3)
5667
* @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id
5768
* @pf_split: for %NFP_PORT_PF_PORT %true if PCI PF has more than one vNIC
@@ -78,6 +89,7 @@ struct nfp_port {
7889
bool eth_forced;
7990
struct nfp_eth_table_port *eth_port;
8091
u8 __iomem *eth_stats;
92+
DECLARE_BITMAP(speed_bitmap, NFP_SUP_SPEED_NUMBER);
8193
};
8294
/* NFP_PORT_PF_PORT, NFP_PORT_VF_PORT */
8395
struct {

0 commit comments

Comments
 (0)