Skip to content

Commit d626367

Browse files
Edwin Peerdavem330
authored andcommitted
bnxt_en: support lane configuration via ethtool
Recent kernels support changing the number of link lanes via ethtool. This is useful for determining the appropriate signal mode to use when a given link speed can be achieved using different lane configurations. Accept the ethtool lanes parameter when configuring forced speed. If there is no lanes parameter, select a default. Signed-off-by: Edwin Peer <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ecdad2a commit d626367

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,13 +2019,15 @@ static int bnxt_get_link_ksettings(struct net_device *dev,
20192019
return 0;
20202020
}
20212021

2022-
static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed)
2022+
static int
2023+
bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed, u32 lanes)
20232024
{
20242025
struct bnxt *bp = netdev_priv(dev);
20252026
struct bnxt_link_info *link_info = &bp->link_info;
20262027
u16 support_pam4_spds = link_info->support_pam4_speeds;
20272028
u16 support_spds = link_info->support_speeds;
20282029
u8 sig_mode = BNXT_SIG_MODE_NRZ;
2030+
u32 lanes_needed = 1;
20292031
u16 fw_speed = 0;
20302032

20312033
switch (ethtool_speed) {
@@ -2046,37 +2048,46 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed)
20462048
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_10GB;
20472049
break;
20482050
case SPEED_20000:
2049-
if (support_spds & BNXT_LINK_SPEED_MSK_20GB)
2051+
if (support_spds & BNXT_LINK_SPEED_MSK_20GB) {
20502052
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_20GB;
2053+
lanes_needed = 2;
2054+
}
20512055
break;
20522056
case SPEED_25000:
20532057
if (support_spds & BNXT_LINK_SPEED_MSK_25GB)
20542058
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_25GB;
20552059
break;
20562060
case SPEED_40000:
2057-
if (support_spds & BNXT_LINK_SPEED_MSK_40GB)
2061+
if (support_spds & BNXT_LINK_SPEED_MSK_40GB) {
20582062
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_40GB;
2063+
lanes_needed = 4;
2064+
}
20592065
break;
20602066
case SPEED_50000:
2061-
if (support_spds & BNXT_LINK_SPEED_MSK_50GB) {
2067+
if ((support_spds & BNXT_LINK_SPEED_MSK_50GB) && lanes != 1) {
20622068
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_50GB;
2069+
lanes_needed = 2;
20632070
} else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_50GB) {
20642071
fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_50GB;
20652072
sig_mode = BNXT_SIG_MODE_PAM4;
20662073
}
20672074
break;
20682075
case SPEED_100000:
2069-
if (support_spds & BNXT_LINK_SPEED_MSK_100GB) {
2076+
if ((support_spds & BNXT_LINK_SPEED_MSK_100GB) &&
2077+
lanes != 2 && lanes != 1) {
20702078
fw_speed = PORT_PHY_CFG_REQ_FORCE_LINK_SPEED_100GB;
2079+
lanes_needed = 4;
20712080
} else if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_100GB) {
20722081
fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_100GB;
20732082
sig_mode = BNXT_SIG_MODE_PAM4;
2083+
lanes_needed = 2;
20742084
}
20752085
break;
20762086
case SPEED_200000:
20772087
if (support_pam4_spds & BNXT_LINK_PAM4_SPEED_MSK_200GB) {
20782088
fw_speed = PORT_PHY_CFG_REQ_FORCE_PAM4_LINK_SPEED_200GB;
20792089
sig_mode = BNXT_SIG_MODE_PAM4;
2090+
lanes_needed = 4;
20802091
}
20812092
break;
20822093
}
@@ -2086,6 +2097,11 @@ static int bnxt_force_link_speed(struct net_device *dev, u32 ethtool_speed)
20862097
return -EINVAL;
20872098
}
20882099

2100+
if (lanes && lanes != lanes_needed) {
2101+
netdev_err(dev, "unsupported number of lanes for speed\n");
2102+
return -EINVAL;
2103+
}
2104+
20892105
if (link_info->req_link_speed == fw_speed &&
20902106
link_info->req_signal_mode == sig_mode &&
20912107
link_info->autoneg == 0)
@@ -2130,7 +2146,7 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
21302146
struct bnxt_link_info *link_info = &bp->link_info;
21312147
const struct ethtool_link_settings *base = &lk_ksettings->base;
21322148
bool set_pause = false;
2133-
u32 speed;
2149+
u32 speed, lanes = 0;
21342150
int rc = 0;
21352151

21362152
if (!BNXT_PHY_CFG_ABLE(bp))
@@ -2171,7 +2187,8 @@ static int bnxt_set_link_ksettings(struct net_device *dev,
21712187
goto set_setting_exit;
21722188
}
21732189
speed = base->speed;
2174-
rc = bnxt_force_link_speed(dev, speed);
2190+
lanes = lk_ksettings->lanes;
2191+
rc = bnxt_force_link_speed(dev, speed, lanes);
21752192
if (rc) {
21762193
if (rc == -EALREADY)
21772194
rc = 0;
@@ -4377,6 +4394,7 @@ void bnxt_ethtool_free(struct bnxt *bp)
43774394
}
43784395

43794396
const struct ethtool_ops bnxt_ethtool_ops = {
4397+
.cap_link_lanes_supported = 1,
43804398
.supported_coalesce_params = ETHTOOL_COALESCE_USECS |
43814399
ETHTOOL_COALESCE_MAX_FRAMES |
43824400
ETHTOOL_COALESCE_USECS_IRQ |

0 commit comments

Comments
 (0)