diff options
author | Thomas Haller <thaller@redhat.com> | 2021-08-30 23:43:03 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-09-06 10:07:16 +0200 |
commit | bd92df3e563277bb04cee663420c739c3f0d999d (patch) | |
tree | 1986c23107a30c54328130c2a784b7c8b533353a | |
parent | d5f062cecd0495273d7e18dd9cf1843909d8167a (diff) | |
download | NetworkManager-bd92df3e563277bb04cee663420c739c3f0d999d.tar.gz |
platform: also set advertised modes when disabling ethernet autoneg
Disabling autoneg is not supported for Gigabit ethernet. But it seems that
ixgbe also doesn't honor
ethtool -s enp5s0f0 speed 100 duplex full autoneg off
As a workaround, when we disable autoneg then always set the advertised
modes too. I think (hope) that should not have a bad effect otherwise,
but seems most sensible for ixgbe.
-rw-r--r-- | src/libnm-platform/nm-platform-utils.c | 73 |
1 files changed, 44 insertions, 29 deletions
diff --git a/src/libnm-platform/nm-platform-utils.c b/src/libnm-platform/nm-platform-utils.c index 7557d327c8..bcb2e6bfe4 100644 --- a/src/libnm-platform/nm-platform-utils.c +++ b/src/libnm-platform/nm-platform-utils.c @@ -1508,13 +1508,12 @@ set_link_settings_new(SocketHandle * shandle, /* then change the needed ones */ edata->cmd = ETHTOOL_SLINKSETTINGS; - if (autoneg) { + + { const guint32 *v_map_supported = &edata->link_mode_masks[0]; guint32 * v_map_advertising = &edata->link_mode_masks[nwords]; guint32 * v_map_lp_advertising = &edata->link_mode_masks[2 * nwords]; - edata->autoneg = AUTONEG_ENABLE; - memcpy(v_map_advertising, v_map_supported, sizeof(guint32) * nwords); (void) v_map_lp_advertising; @@ -1524,6 +1523,8 @@ set_link_settings_new(SocketHandle * shandle, mode = get_baset_mode(speed, duplex); if (mode == ADVERTISED_INVALID) { + if (!autoneg) + goto set_autoneg; nm_log_trace(LOGD_PLATFORM, "ethtool[%d]: %uBASE-T %s duplex mode cannot be advertised", shandle->ifindex, @@ -1533,6 +1534,8 @@ set_link_settings_new(SocketHandle * shandle, } if (!(v_map_supported[0] & mode)) { + if (!autoneg) + goto set_autoneg; nm_log_trace(LOGD_PLATFORM, "ethtool[%d]: device does not support %uBASE-T %s duplex mode", shandle->ifindex, @@ -1545,7 +1548,12 @@ set_link_settings_new(SocketHandle * shandle, v_map_advertising[i] &= ~_nmp_link_mode_all_advertised_modes[i]; v_map_advertising[0] |= mode; } - } else { + } + +set_autoneg: + if (autoneg) + edata->autoneg = AUTONEG_ENABLE; + else { edata->autoneg = AUTONEG_DISABLE; if (speed) @@ -1593,34 +1601,41 @@ nmp_utils_ethtool_set_link_settings(int ifindex, /* then change the needed ones */ edata.cmd = ETHTOOL_SSET; - if (autoneg) { - edata.autoneg = AUTONEG_ENABLE; - edata.advertising = edata.supported; - if (speed != 0) { - guint32 mode; - mode = get_baset_mode(speed, duplex); + edata.advertising = edata.supported; + if (speed != 0) { + guint32 mode; - if (mode == ADVERTISED_INVALID) { - nm_log_trace(LOGD_PLATFORM, - "ethtool[%d]: %uBASE-T %s duplex mode cannot be advertised", - ifindex, - speed, - nm_platform_link_duplex_type_to_string(duplex)); - return FALSE; - } - if (!(edata.supported & mode)) { - nm_log_trace(LOGD_PLATFORM, - "ethtool[%d]: device does not support %uBASE-T %s duplex mode", - ifindex, - speed, - nm_platform_link_duplex_type_to_string(duplex)); - return FALSE; - } - edata.advertising &= ~_nmp_link_mode_all_advertised_modes[0]; - edata.advertising |= mode; + mode = get_baset_mode(speed, duplex); + + if (mode == ADVERTISED_INVALID) { + if (!autoneg) + goto set_autoneg; + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: %uBASE-T %s duplex mode cannot be advertised", + ifindex, + speed, + nm_platform_link_duplex_type_to_string(duplex)); + return FALSE; } - } else { + if (!(edata.supported & mode)) { + if (!autoneg) + goto set_autoneg; + nm_log_trace(LOGD_PLATFORM, + "ethtool[%d]: device does not support %uBASE-T %s duplex mode", + ifindex, + speed, + nm_platform_link_duplex_type_to_string(duplex)); + return FALSE; + } + edata.advertising &= ~_nmp_link_mode_all_advertised_modes[0]; + edata.advertising |= mode; + } + +set_autoneg: + if (autoneg) + edata.autoneg = AUTONEG_ENABLE; + else { edata.autoneg = AUTONEG_DISABLE; if (speed) |