platform: allow to force the advertised auto-negotiation link value
This will only work for network devices supporting the BASE-T specification.
This commit is contained in:
@@ -384,6 +384,40 @@ nmp_utils_ethtool_get_link_settings (int ifindex,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ADVERTISED_INVALID 0
|
||||||
|
#define BASET_ALL_MODES ( ADVERTISED_10baseT_Half \
|
||||||
|
| ADVERTISED_10baseT_Full \
|
||||||
|
| ADVERTISED_100baseT_Half \
|
||||||
|
| ADVERTISED_100baseT_Full \
|
||||||
|
| ADVERTISED_1000baseT_Half \
|
||||||
|
| ADVERTISED_1000baseT_Full \
|
||||||
|
| ADVERTISED_10000baseT_Full )
|
||||||
|
|
||||||
|
static inline guint32
|
||||||
|
get_baset_mode (guint32 speed, NMPlatformLinkDuplexType duplex)
|
||||||
|
{
|
||||||
|
if (duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN)
|
||||||
|
return ADVERTISED_INVALID;
|
||||||
|
|
||||||
|
if (duplex == NM_PLATFORM_LINK_DUPLEX_HALF) {
|
||||||
|
switch (speed) {
|
||||||
|
case 10: return ADVERTISED_10baseT_Half;
|
||||||
|
case 100: return ADVERTISED_100baseT_Half;
|
||||||
|
case 1000: return ADVERTISED_1000baseT_Half;
|
||||||
|
default: return ADVERTISED_INVALID;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (speed) {
|
||||||
|
case 10: return ADVERTISED_10baseT_Full;
|
||||||
|
case 100: return ADVERTISED_100baseT_Full;
|
||||||
|
case 1000: return ADVERTISED_1000baseT_Full;
|
||||||
|
case 10000: return ADVERTISED_10000baseT_Full;
|
||||||
|
default: return ADVERTISED_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nmp_utils_ethtool_set_link_settings (int ifindex,
|
nmp_utils_ethtool_set_link_settings (int ifindex,
|
||||||
gboolean autoneg,
|
gboolean autoneg,
|
||||||
@@ -395,6 +429,8 @@ nmp_utils_ethtool_set_link_settings (int ifindex,
|
|||||||
};
|
};
|
||||||
|
|
||||||
g_return_val_if_fail (ifindex > 0, FALSE);
|
g_return_val_if_fail (ifindex > 0, FALSE);
|
||||||
|
g_return_val_if_fail ( (speed && duplex != NM_PLATFORM_LINK_DUPLEX_UNKNOWN)
|
||||||
|
|| (!speed && duplex == NM_PLATFORM_LINK_DUPLEX_UNKNOWN), FALSE);
|
||||||
|
|
||||||
/* retrieve first current settings */
|
/* retrieve first current settings */
|
||||||
if (!ethtool_get (ifindex, &edata))
|
if (!ethtool_get (ifindex, &edata))
|
||||||
@@ -404,7 +440,31 @@ nmp_utils_ethtool_set_link_settings (int ifindex,
|
|||||||
edata.cmd = ETHTOOL_SSET;
|
edata.cmd = ETHTOOL_SSET;
|
||||||
if (autoneg) {
|
if (autoneg) {
|
||||||
edata.autoneg = AUTONEG_ENABLE;
|
edata.autoneg = AUTONEG_ENABLE;
|
||||||
edata.advertising = edata.supported;
|
if (!speed)
|
||||||
|
edata.advertising = edata.supported;
|
||||||
|
else {
|
||||||
|
guint32 mode;
|
||||||
|
|
||||||
|
mode = get_baset_mode (speed, duplex);
|
||||||
|
|
||||||
|
if (!mode) {
|
||||||
|
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 = (edata.supported & ~BASET_ALL_MODES) | mode;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
edata.autoneg = AUTONEG_DISABLE;
|
edata.autoneg = AUTONEG_DISABLE;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user