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: commita61474c41e
("nfp: ethtool: support reporting link modes"). Fixes:7c69873727
("nfp: add support for .set_link_ksettings()") Signed-off-by: Yu Xiao <yu.xiao@corigine.com> Signed-off-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
c11204c78d
Коммит
821de68c1f
|
@ -293,35 +293,131 @@ nfp_net_set_fec_link_mode(struct nfp_eth_table_port *eth_port,
|
|||
}
|
||||
}
|
||||
|
||||
static const u16 nfp_eth_media_table[] = {
|
||||
[NFP_MEDIA_1000BASE_CX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
|
||||
[NFP_MEDIA_1000BASE_KX] = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_KX4] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_KR] = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_CX4] = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_CR] = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_SR] = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
|
||||
[NFP_MEDIA_10GBASE_ER] = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
|
||||
[NFP_MEDIA_25GBASE_KR] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
|
||||
[NFP_MEDIA_25GBASE_KR_S] = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
|
||||
[NFP_MEDIA_25GBASE_CR] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
|
||||
[NFP_MEDIA_25GBASE_CR_S] = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
|
||||
[NFP_MEDIA_25GBASE_SR] = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
|
||||
[NFP_MEDIA_40GBASE_CR4] = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
|
||||
[NFP_MEDIA_40GBASE_KR4] = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
|
||||
[NFP_MEDIA_40GBASE_SR4] = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
|
||||
[NFP_MEDIA_40GBASE_LR4] = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_KR] = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_SR] = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_CR] = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_LR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_ER] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
[NFP_MEDIA_50GBASE_FR] = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
[NFP_MEDIA_100GBASE_KR4] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
|
||||
[NFP_MEDIA_100GBASE_SR4] = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
|
||||
[NFP_MEDIA_100GBASE_CR4] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
|
||||
[NFP_MEDIA_100GBASE_KP4] = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
|
||||
[NFP_MEDIA_100GBASE_CR10] = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
|
||||
static const struct nfp_eth_media_link_mode {
|
||||
u16 ethtool_link_mode;
|
||||
u16 speed;
|
||||
} nfp_eth_media_table[NFP_MEDIA_LINK_MODES_NUMBER] = {
|
||||
[NFP_MEDIA_1000BASE_CX] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
|
||||
.speed = NFP_SPEED_1G,
|
||||
},
|
||||
[NFP_MEDIA_1000BASE_KX] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
|
||||
.speed = NFP_SPEED_1G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_KX4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_KR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_CX4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_CR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseCR_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_SR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseSR_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_10GBASE_ER] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_10000baseER_Full_BIT,
|
||||
.speed = NFP_SPEED_10G,
|
||||
},
|
||||
[NFP_MEDIA_25GBASE_KR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
|
||||
.speed = NFP_SPEED_25G,
|
||||
},
|
||||
[NFP_MEDIA_25GBASE_KR_S] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT,
|
||||
.speed = NFP_SPEED_25G,
|
||||
},
|
||||
[NFP_MEDIA_25GBASE_CR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
|
||||
.speed = NFP_SPEED_25G,
|
||||
},
|
||||
[NFP_MEDIA_25GBASE_CR_S] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT,
|
||||
.speed = NFP_SPEED_25G,
|
||||
},
|
||||
[NFP_MEDIA_25GBASE_SR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_25000baseSR_Full_BIT,
|
||||
.speed = NFP_SPEED_25G,
|
||||
},
|
||||
[NFP_MEDIA_40GBASE_CR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT,
|
||||
.speed = NFP_SPEED_40G,
|
||||
},
|
||||
[NFP_MEDIA_40GBASE_KR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT,
|
||||
.speed = NFP_SPEED_40G,
|
||||
},
|
||||
[NFP_MEDIA_40GBASE_SR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT,
|
||||
.speed = NFP_SPEED_40G,
|
||||
},
|
||||
[NFP_MEDIA_40GBASE_LR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT,
|
||||
.speed = NFP_SPEED_40G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_KR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseKR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_SR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseSR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_CR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseCR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_LR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_ER] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_50GBASE_FR] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
|
||||
.speed = NFP_SPEED_50G,
|
||||
},
|
||||
[NFP_MEDIA_100GBASE_KR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
|
||||
.speed = NFP_SPEED_100G,
|
||||
},
|
||||
[NFP_MEDIA_100GBASE_SR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT,
|
||||
.speed = NFP_SPEED_100G,
|
||||
},
|
||||
[NFP_MEDIA_100GBASE_CR4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
|
||||
.speed = NFP_SPEED_100G,
|
||||
},
|
||||
[NFP_MEDIA_100GBASE_KP4] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT,
|
||||
.speed = NFP_SPEED_100G,
|
||||
},
|
||||
[NFP_MEDIA_100GBASE_CR10] = {
|
||||
.ethtool_link_mode = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT,
|
||||
.speed = NFP_SPEED_100G,
|
||||
},
|
||||
};
|
||||
|
||||
static const unsigned int nfp_eth_speed_map[NFP_SUP_SPEED_NUMBER] = {
|
||||
[NFP_SPEED_1G] = SPEED_1000,
|
||||
[NFP_SPEED_10G] = SPEED_10000,
|
||||
[NFP_SPEED_25G] = SPEED_25000,
|
||||
[NFP_SPEED_40G] = SPEED_40000,
|
||||
[NFP_SPEED_50G] = SPEED_50000,
|
||||
[NFP_SPEED_100G] = SPEED_100000,
|
||||
};
|
||||
|
||||
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,
|
|||
};
|
||||
struct nfp_cpp *cpp = port->app->cpp;
|
||||
|
||||
if (nfp_eth_read_media(cpp, ðm))
|
||||
if (nfp_eth_read_media(cpp, ðm)) {
|
||||
bitmap_fill(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
|
||||
return;
|
||||
}
|
||||
|
||||
bitmap_zero(port->speed_bitmap, NFP_SUP_SPEED_NUMBER);
|
||||
|
||||
for (u32 i = 0; i < 2; i++) {
|
||||
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,
|
|||
|
||||
for (u32 i = 0; i < NFP_MEDIA_LINK_MODES_NUMBER; i++) {
|
||||
if (i < 64) {
|
||||
if (supported_modes[0] & BIT_ULL(i))
|
||||
__set_bit(nfp_eth_media_table[i],
|
||||
if (supported_modes[0] & BIT_ULL(i)) {
|
||||
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
|
||||
cmd->link_modes.supported);
|
||||
__set_bit(nfp_eth_media_table[i].speed,
|
||||
port->speed_bitmap);
|
||||
}
|
||||
|
||||
if (advertised_modes[0] & BIT_ULL(i))
|
||||
__set_bit(nfp_eth_media_table[i],
|
||||
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
|
||||
cmd->link_modes.advertising);
|
||||
} else {
|
||||
if (supported_modes[1] & BIT_ULL(i - 64))
|
||||
__set_bit(nfp_eth_media_table[i],
|
||||
if (supported_modes[1] & BIT_ULL(i - 64)) {
|
||||
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
|
||||
cmd->link_modes.supported);
|
||||
__set_bit(nfp_eth_media_table[i].speed,
|
||||
port->speed_bitmap);
|
||||
}
|
||||
|
||||
if (advertised_modes[1] & BIT_ULL(i - 64))
|
||||
__set_bit(nfp_eth_media_table[i],
|
||||
__set_bit(nfp_eth_media_table[i].ethtool_link_mode,
|
||||
cmd->link_modes.advertising);
|
||||
}
|
||||
}
|
||||
|
@ -468,6 +574,22 @@ nfp_net_set_link_ksettings(struct net_device *netdev,
|
|||
|
||||
if (cmd->base.speed != SPEED_UNKNOWN) {
|
||||
u32 speed = cmd->base.speed / eth_port->lanes;
|
||||
bool is_supported = false;
|
||||
|
||||
for (u32 i = 0; i < NFP_SUP_SPEED_NUMBER; i++) {
|
||||
if (cmd->base.speed == nfp_eth_speed_map[i] &&
|
||||
test_bit(i, port->speed_bitmap)) {
|
||||
is_supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_supported) {
|
||||
netdev_err(netdev, "Speed %u is not supported.\n",
|
||||
cmd->base.speed);
|
||||
err = -EINVAL;
|
||||
goto err_bad_set;
|
||||
}
|
||||
|
||||
if (req_aneg) {
|
||||
netdev_err(netdev, "Speed changing is not allowed when working on autoneg mode.\n");
|
||||
|
|
|
@ -38,6 +38,16 @@ enum nfp_port_flags {
|
|||
NFP_PORT_CHANGED = 0,
|
||||
};
|
||||
|
||||
enum {
|
||||
NFP_SPEED_1G,
|
||||
NFP_SPEED_10G,
|
||||
NFP_SPEED_25G,
|
||||
NFP_SPEED_40G,
|
||||
NFP_SPEED_50G,
|
||||
NFP_SPEED_100G,
|
||||
NFP_SUP_SPEED_NUMBER
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nfp_port - structure representing NFP port
|
||||
* @netdev: backpointer to associated netdev
|
||||
|
@ -52,6 +62,7 @@ enum nfp_port_flags {
|
|||
* @eth_forced: for %NFP_PORT_PHYS_PORT port is forced UP or DOWN, don't change
|
||||
* @eth_port: for %NFP_PORT_PHYS_PORT translated ETH Table port entry
|
||||
* @eth_stats: for %NFP_PORT_PHYS_PORT MAC stats if available
|
||||
* @speed_bitmap: for %NFP_PORT_PHYS_PORT supported speed bitmap
|
||||
* @pf_id: for %NFP_PORT_PF_PORT, %NFP_PORT_VF_PORT ID of the PCI PF (0-3)
|
||||
* @vf_id: for %NFP_PORT_VF_PORT ID of the PCI VF within @pf_id
|
||||
* @pf_split: for %NFP_PORT_PF_PORT %true if PCI PF has more than one vNIC
|
||||
|
@ -78,6 +89,7 @@ struct nfp_port {
|
|||
bool eth_forced;
|
||||
struct nfp_eth_table_port *eth_port;
|
||||
u8 __iomem *eth_stats;
|
||||
DECLARE_BITMAP(speed_bitmap, NFP_SUP_SPEED_NUMBER);
|
||||
};
|
||||
/* NFP_PORT_PF_PORT, NFP_PORT_VF_PORT */
|
||||
struct {
|
||||
|
|
Загрузка…
Ссылка в новой задаче