mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
parent
74694002e6
commit
18f84f8aba
@ -946,6 +946,21 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MDI=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the medium dependent interface (MDI) mode for the interface. A MDI describes
|
||||
the interface from a physical layer implementation to the physical medium used to carry the
|
||||
transmission. Takes one of the following words: <literal>straight</literal> (or equivalently:
|
||||
<literal>mdi</literal>), <literal>crossover</literal> (or equivalently:
|
||||
<literal>mdi-x</literal>, <literal>mdix</literal>), and <literal>auto</literal>. When
|
||||
<literal>straight</literal>, the MDI straight through mode will be used. When
|
||||
<literal>crossover</literal>, the MDI crossover (MDI-X) mode will be used. When
|
||||
<literal>auto</literal>, the MDI status is automatically detected. Defaults to unset, and the
|
||||
kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SR-IOVVirtualFunctions=</varname></term>
|
||||
<listitem>
|
||||
|
@ -74,6 +74,15 @@ static const char* const port_table[] = {
|
||||
DEFINE_STRING_TABLE_LOOKUP(port, NetDevPort);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_port, port, NetDevPort, "Failed to parse Port setting");
|
||||
|
||||
static const char* const mdi_table[] = {
|
||||
[ETH_TP_MDI_INVALID] = "unknown",
|
||||
[ETH_TP_MDI] = "mdi",
|
||||
[ETH_TP_MDI_X] = "mdi-x",
|
||||
[ETH_TP_MDI_AUTO] = "auto",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(mdi, int);
|
||||
|
||||
static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
|
||||
[NET_DEV_FEAT_SG] = "tx-scatter-gather",
|
||||
[NET_DEV_FEAT_IP_CSUM] = "tx-checksum-ipv4",
|
||||
@ -835,6 +844,8 @@ static int get_gset(int fd, struct ifreq *ifr, struct ethtool_link_usettings **r
|
||||
.base.phy_address = ecmd.phy_address,
|
||||
.base.autoneg = ecmd.autoneg,
|
||||
.base.mdio_support = ecmd.mdio_support,
|
||||
.base.eth_tp_mdix = ecmd.eth_tp_mdix,
|
||||
.base.eth_tp_mdix_ctrl = ecmd.eth_tp_mdix_ctrl,
|
||||
|
||||
.link_modes.supported[0] = ecmd.supported,
|
||||
.link_modes.advertising[0] = ecmd.advertising,
|
||||
@ -914,7 +925,8 @@ int ethtool_set_glinksettings(
|
||||
const uint32_t advertise[static N_ADVERTISE],
|
||||
uint64_t speed,
|
||||
Duplex duplex,
|
||||
NetDevPort port) {
|
||||
NetDevPort port,
|
||||
uint8_t mdi) {
|
||||
|
||||
_cleanup_free_ struct ethtool_link_usettings *u = NULL;
|
||||
struct ifreq ifr = {};
|
||||
@ -926,7 +938,7 @@ int ethtool_set_glinksettings(
|
||||
assert(advertise);
|
||||
|
||||
if (autonegotiation < 0 && memeqzero(advertise, sizeof(uint32_t) * N_ADVERTISE) &&
|
||||
speed == 0 && duplex < 0 && port < 0)
|
||||
speed == 0 && duplex < 0 && port < 0 && mdi == ETH_TP_MDI_INVALID)
|
||||
return 0;
|
||||
|
||||
/* If autonegotiation is disabled, the speed and duplex represent the fixed link mode and are
|
||||
@ -957,7 +969,7 @@ int ethtool_set_glinksettings(
|
||||
if (r < 0) {
|
||||
r = get_gset(*fd, &ifr, &u);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "ethtool: Cannot get device settings for %s : %m", ifname);
|
||||
return log_debug_errno(r, "ethtool: Cannot get device settings for %s: %m", ifname);
|
||||
}
|
||||
|
||||
if (speed > 0)
|
||||
@ -984,6 +996,13 @@ int ethtool_set_glinksettings(
|
||||
ETHTOOL_LINK_MODE_MASK_MAX_KERNEL_NBYTES - sizeof(uint32_t) * N_ADVERTISE);
|
||||
}
|
||||
|
||||
if (mdi != ETH_TP_MDI_INVALID) {
|
||||
if (u->base.eth_tp_mdix_ctrl == ETH_TP_MDI_INVALID)
|
||||
log_debug("ethtool: setting MDI not supported for %s, ignoring.", ifname);
|
||||
else
|
||||
UPDATE(u->base.eth_tp_mdix_ctrl, mdi, changed);
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
return 0;
|
||||
|
||||
@ -1261,6 +1280,48 @@ int config_parse_advertise(
|
||||
}
|
||||
}
|
||||
|
||||
int config_parse_mdi(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
uint8_t *mdi = ASSERT_PTR(data);
|
||||
|
||||
assert(filename);
|
||||
assert(rvalue);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*mdi = ETH_TP_MDI_INVALID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(rvalue, "mdi", "straight")) {
|
||||
*mdi = ETH_TP_MDI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(rvalue, "mdi-x", "mdix", "crossover")) {
|
||||
*mdi = ETH_TP_MDI_X;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, "auto")) {
|
||||
*mdi = ETH_TP_MDI_AUTO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Failed to parse %s= setting, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_ring_buffer_or_channel(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
@ -168,9 +168,15 @@ int ethtool_get_permanent_hw_addr(int *ethtool_fd, const char *ifname, struct hw
|
||||
int ethtool_set_wol(int *ethtool_fd, const char *ifname, uint32_t wolopts, const uint8_t password[SOPASS_MAX]);
|
||||
int ethtool_set_nic_buffer_size(int *ethtool_fd, const char *ifname, const netdev_ring_param *ring);
|
||||
int ethtool_set_features(int *ethtool_fd, const char *ifname, const int features[static _NET_DEV_FEAT_MAX]);
|
||||
int ethtool_set_glinksettings(int *ethtool_fd, const char *ifname,
|
||||
int autonegotiation, const uint32_t advertise[static N_ADVERTISE],
|
||||
uint64_t speed, Duplex duplex, NetDevPort port);
|
||||
int ethtool_set_glinksettings(
|
||||
int *fd,
|
||||
const char *ifname,
|
||||
int autonegotiation,
|
||||
const uint32_t advertise[static N_ADVERTISE],
|
||||
uint64_t speed,
|
||||
Duplex duplex,
|
||||
NetDevPort port,
|
||||
uint8_t mdi);
|
||||
int ethtool_set_channels(int *ethtool_fd, const char *ifname, const netdev_channels *channels);
|
||||
int ethtool_set_flow_control(int *fd, const char *ifname, int rx, int tx, int autoneg);
|
||||
int ethtool_set_nic_coalesce_settings(int *ethtool_fd, const char *ifname, const netdev_coalesce_param *coalesce);
|
||||
@ -183,12 +189,15 @@ int wol_options_to_string_alloc(uint32_t opts, char **ret);
|
||||
const char *port_to_string(NetDevPort port) _const_;
|
||||
NetDevPort port_from_string(const char *port) _pure_;
|
||||
|
||||
const char *mdi_to_string(int mdi) _const_;
|
||||
|
||||
const char *ethtool_link_mode_bit_to_string(enum ethtool_link_mode_bit_indices val) _const_;
|
||||
enum ethtool_link_mode_bit_indices ethtool_link_mode_bit_from_string(const char *str) _pure_;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duplex);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_wol);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_port);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mdi);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_advertise);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ring_buffer_or_channel);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_coalesce_u32);
|
||||
|
@ -102,6 +102,7 @@ Link.RxMaxCoalescedHighFrames, config_parse_coalesce_u32,
|
||||
Link.TxCoalesceHighSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.tx_coalesce_usecs_high)
|
||||
Link.TxMaxCoalescedHighFrames, config_parse_coalesce_u32, 0, offsetof(LinkConfig, coalesce.tx_max_coalesced_frames_high)
|
||||
Link.CoalescePacketRateSampleIntervalSec, config_parse_coalesce_sec, 0, offsetof(LinkConfig, coalesce.rate_sample_interval)
|
||||
Link.MDI, config_parse_mdi, 0, offsetof(LinkConfig, mdi)
|
||||
Link.SR-IOVVirtualFunctions, config_parse_sr_iov_num_vfs, 0, offsetof(LinkConfig, sr_iov_num_vfs)
|
||||
SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, offsetof(LinkConfig, sr_iov_by_section)
|
||||
SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, offsetof(LinkConfig, sr_iov_by_section)
|
||||
|
@ -250,6 +250,7 @@ int link_load_one(LinkConfigContext *ctx, const char *filename) {
|
||||
.txqueuelen = UINT32_MAX,
|
||||
.coalesce.use_adaptive_rx_coalesce = -1,
|
||||
.coalesce.use_adaptive_tx_coalesce = -1,
|
||||
.mdi = ETH_TP_MDI_INVALID,
|
||||
.sr_iov_num_vfs = UINT32_MAX,
|
||||
};
|
||||
|
||||
@ -475,7 +476,7 @@ static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) {
|
||||
|
||||
r = ethtool_set_glinksettings(ethtool_fd, name,
|
||||
config->autonegotiation, config->advertise,
|
||||
config->speed, config->duplex, config->port);
|
||||
config->speed, config->duplex, config->port, config->mdi);
|
||||
if (r < 0) {
|
||||
if (config->autonegotiation >= 0)
|
||||
log_link_warning_errno(link, r, "Could not %s auto negotiation, ignoring: %m",
|
||||
@ -495,6 +496,10 @@ static int link_apply_ethtool_settings(Link *link, int *ethtool_fd) {
|
||||
if (config->port >= 0)
|
||||
log_link_warning_errno(link, r, "Could not set port to '%s', ignoring: %m",
|
||||
port_to_string(config->port));
|
||||
|
||||
if (config->mdi != ETH_TP_MDI_INVALID)
|
||||
log_link_warning_errno(link, r, "Could not set MDI-X to '%s', ignoring: %m",
|
||||
mdi_to_string(config->mdi));
|
||||
}
|
||||
|
||||
r = ethtool_set_wol(ethtool_fd, name, config->wol, config->wol_password);
|
||||
|
@ -76,6 +76,7 @@ struct LinkConfig {
|
||||
int tx_flow_control;
|
||||
int autoneg_flow_control;
|
||||
netdev_coalesce_param coalesce;
|
||||
uint8_t mdi;
|
||||
|
||||
uint32_t sr_iov_num_vfs;
|
||||
OrderedHashmap *sr_iov_by_section;
|
||||
|
@ -80,6 +80,7 @@ RxMaxCoalescedHighFrames=
|
||||
TxCoalesceHighSec=
|
||||
TxMaxCoalescedHighFrames=
|
||||
CoalescePacketRateSampleIntervalSec=
|
||||
MDI=
|
||||
SR-IOVVirtualFunctions=
|
||||
[SR-IOV]
|
||||
VirtualFunction=
|
||||
|
Loading…
Reference in New Issue
Block a user