mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-29 09:10:10 +01:00
merge: branch 'bg/ethtool-channels'
Add ethtool channels support https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1754
This commit is contained in:
commit
2d956f4d51
19 changed files with 398 additions and 57 deletions
|
|
@ -303,6 +303,7 @@ typedef struct {
|
|||
NMEthtoolCoalesceState *coalesce;
|
||||
NMEthtoolRingState *ring;
|
||||
NMEthtoolPauseState *pause;
|
||||
NMEthtoolChannelsState *channels;
|
||||
} EthtoolState;
|
||||
|
||||
typedef enum {
|
||||
|
|
@ -2385,6 +2386,8 @@ _ethtool_features_reset(NMDevice *self, NMPlatform *platform, EthtoolState *etht
|
|||
gs_free NMEthtoolFeatureStates *features = NULL;
|
||||
|
||||
features = g_steal_pointer(ðtool_state->features);
|
||||
if (!features)
|
||||
return;
|
||||
|
||||
if (!nm_platform_ethtool_set_features(platform,
|
||||
ethtool_state->ifindex,
|
||||
|
|
@ -2404,8 +2407,7 @@ _ethtool_features_set(NMDevice *self,
|
|||
{
|
||||
gs_free NMEthtoolFeatureStates *features = NULL;
|
||||
|
||||
if (ethtool_state->features)
|
||||
_ethtool_features_reset(self, platform, ethtool_state);
|
||||
_ethtool_features_reset(self, platform, ethtool_state);
|
||||
|
||||
if (nm_setting_ethtool_init_features(s_ethtool, ethtool_state->requested) == 0)
|
||||
return;
|
||||
|
|
@ -2602,6 +2604,104 @@ _ethtool_ring_set(NMDevice *self,
|
|||
_LOGD(LOGD_DEVICE, "ethtool: ring settings successfully set");
|
||||
}
|
||||
|
||||
static void
|
||||
_ethtool_channels_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state)
|
||||
{
|
||||
gs_free NMEthtoolChannelsState *channels = NULL;
|
||||
|
||||
nm_assert(NM_IS_DEVICE(self));
|
||||
nm_assert(NM_IS_PLATFORM(platform));
|
||||
nm_assert(ethtool_state);
|
||||
|
||||
channels = g_steal_pointer(ðtool_state->channels);
|
||||
if (!channels)
|
||||
return;
|
||||
|
||||
if (!nm_platform_ethtool_set_channels(platform, ethtool_state->ifindex, channels))
|
||||
_LOGW(LOGD_DEVICE, "ethtool: failure resetting one or more channels settings");
|
||||
else
|
||||
_LOGD(LOGD_DEVICE, "ethtool: channels settings successfully reset");
|
||||
}
|
||||
|
||||
static void
|
||||
_ethtool_channels_set(NMDevice *self,
|
||||
NMPlatform *platform,
|
||||
EthtoolState *ethtool_state,
|
||||
NMSettingEthtool *s_ethtool)
|
||||
{
|
||||
NMEthtoolChannelsState channels_old;
|
||||
NMEthtoolChannelsState channels_new;
|
||||
GHashTable *hash;
|
||||
GHashTableIter iter;
|
||||
const char *name;
|
||||
GVariant *variant;
|
||||
gboolean has_old = FALSE;
|
||||
|
||||
nm_assert(NM_IS_DEVICE(self));
|
||||
nm_assert(NM_IS_PLATFORM(platform));
|
||||
nm_assert(NM_IS_SETTING_ETHTOOL(s_ethtool));
|
||||
nm_assert(ethtool_state);
|
||||
nm_assert(!ethtool_state->channels);
|
||||
|
||||
hash = _nm_setting_option_hash(NM_SETTING(s_ethtool), FALSE);
|
||||
if (!hash)
|
||||
return;
|
||||
|
||||
g_hash_table_iter_init(&iter, hash);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer *) &name, (gpointer *) &variant)) {
|
||||
NMEthtoolID ethtool_id = nm_ethtool_id_get_by_name(name);
|
||||
guint32 u32;
|
||||
|
||||
if (!nm_ethtool_id_is_channels(ethtool_id))
|
||||
continue;
|
||||
|
||||
nm_assert(g_variant_is_of_type(variant, G_VARIANT_TYPE_UINT32));
|
||||
|
||||
if (!has_old) {
|
||||
if (!nm_platform_ethtool_get_link_channels(platform,
|
||||
ethtool_state->ifindex,
|
||||
&channels_old)) {
|
||||
_LOGW(LOGD_DEVICE,
|
||||
"ethtool: failure setting channels options (cannot read existing setting)");
|
||||
return;
|
||||
}
|
||||
has_old = TRUE;
|
||||
channels_new = channels_old;
|
||||
}
|
||||
|
||||
u32 = g_variant_get_uint32(variant);
|
||||
|
||||
switch (ethtool_id) {
|
||||
case NM_ETHTOOL_ID_CHANNELS_RX:
|
||||
channels_new.rx = u32;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_CHANNELS_TX:
|
||||
channels_new.tx = u32;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_CHANNELS_OTHER:
|
||||
channels_new.other = u32;
|
||||
break;
|
||||
case NM_ETHTOOL_ID_CHANNELS_COMBINED:
|
||||
channels_new.combined = u32;
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
if (!has_old)
|
||||
return;
|
||||
|
||||
ethtool_state->channels = nm_memdup(&channels_old, sizeof(channels_old));
|
||||
|
||||
if (!nm_platform_ethtool_set_channels(platform, ethtool_state->ifindex, &channels_new)) {
|
||||
_LOGW(LOGD_DEVICE, "ethtool: failure setting channels settings");
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGD(LOGD_DEVICE, "ethtool: channels settings successfully set");
|
||||
}
|
||||
|
||||
static void
|
||||
_ethtool_pause_reset(NMDevice *self, NMPlatform *platform, EthtoolState *ethtool_state)
|
||||
{
|
||||
|
|
@ -2719,14 +2819,11 @@ _ethtool_state_reset(NMDevice *self)
|
|||
if (!ethtool_state)
|
||||
return;
|
||||
|
||||
if (ethtool_state->features)
|
||||
_ethtool_features_reset(self, platform, ethtool_state);
|
||||
if (ethtool_state->coalesce)
|
||||
_ethtool_coalesce_reset(self, platform, ethtool_state);
|
||||
if (ethtool_state->ring)
|
||||
_ethtool_ring_reset(self, platform, ethtool_state);
|
||||
if (ethtool_state->pause)
|
||||
_ethtool_pause_reset(self, platform, ethtool_state);
|
||||
_ethtool_features_reset(self, platform, ethtool_state);
|
||||
_ethtool_coalesce_reset(self, platform, ethtool_state);
|
||||
_ethtool_ring_reset(self, platform, ethtool_state);
|
||||
_ethtool_pause_reset(self, platform, ethtool_state);
|
||||
_ethtool_channels_reset(self, platform, ethtool_state);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2761,9 +2858,10 @@ _ethtool_state_set(NMDevice *self)
|
|||
_ethtool_coalesce_set(self, platform, ethtool_state, s_ethtool);
|
||||
_ethtool_ring_set(self, platform, ethtool_state, s_ethtool);
|
||||
_ethtool_pause_set(self, platform, ethtool_state, s_ethtool);
|
||||
_ethtool_channels_set(self, platform, ethtool_state, s_ethtool);
|
||||
|
||||
if (ethtool_state->features || ethtool_state->coalesce || ethtool_state->ring
|
||||
|| ethtool_state->pause)
|
||||
|| ethtool_state->pause || ethtool_state->channels)
|
||||
priv->ethtool_state = g_steal_pointer(ðtool_state);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1346,6 +1346,7 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error
|
|||
guint32 u32;
|
||||
gboolean b;
|
||||
gboolean any_option = FALSE;
|
||||
char prop_name[300];
|
||||
|
||||
s_con = nm_connection_get_setting_connection(connection);
|
||||
if (s_con) {
|
||||
|
|
@ -1426,6 +1427,18 @@ write_ethtool_setting(NMConnection *connection, shvarFile *ifcfg, GError **error
|
|||
any_option = TRUE;
|
||||
}
|
||||
|
||||
is_first = TRUE;
|
||||
for (ethtool_id = _NM_ETHTOOL_ID_CHANNELS_FIRST; ethtool_id <= _NM_ETHTOOL_ID_CHANNELS_LAST;
|
||||
ethtool_id++) {
|
||||
if (nm_setting_option_get_uint32(NM_SETTING(s_ethtool),
|
||||
nm_ethtool_data[ethtool_id]->optname,
|
||||
&u32)) {
|
||||
nm_sprintf_buf(prop_name, "ethtool.%s", nm_ethtool_data[ethtool_id]->optname);
|
||||
set_error_unsupported(error, connection, prop_name, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_option) {
|
||||
/* Write an empty dummy "-A" option without arguments. This is to
|
||||
* ensure that the reader will create an (all default) NMSettingEthtool.
|
||||
|
|
|
|||
|
|
@ -3623,6 +3623,11 @@ test_roundtrip_ethtool(void)
|
|||
optname = nm_ethtool_data[ethtool_id]->optname;
|
||||
vtype = nm_ethtool_id_get_variant_type(ethtool_id);
|
||||
|
||||
if (nm_ethtool_optname_is_channels(optname)) {
|
||||
/* Not supported */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NM_IN_SET(ethtool_id,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX)) {
|
||||
|
|
|
|||
|
|
@ -124,14 +124,23 @@ typedef enum {
|
|||
NM_ETHTOOL_ID_RING_TX,
|
||||
_NM_ETHTOOL_ID_RING_LAST = NM_ETHTOOL_ID_RING_TX,
|
||||
|
||||
_NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_RING_LAST,
|
||||
_NM_ETHTOOL_ID_CHANNELS_FIRST = _NM_ETHTOOL_ID_RING_LAST + 1,
|
||||
NM_ETHTOOL_ID_CHANNELS_RX = _NM_ETHTOOL_ID_CHANNELS_FIRST,
|
||||
NM_ETHTOOL_ID_CHANNELS_TX,
|
||||
NM_ETHTOOL_ID_CHANNELS_OTHER,
|
||||
NM_ETHTOOL_ID_CHANNELS_COMBINED,
|
||||
_NM_ETHTOOL_ID_CHANNELS_LAST = NM_ETHTOOL_ID_CHANNELS_COMBINED,
|
||||
|
||||
_NM_ETHTOOL_ID_LAST = _NM_ETHTOOL_ID_CHANNELS_LAST,
|
||||
|
||||
_NM_ETHTOOL_ID_COALESCE_NUM =
|
||||
(_NM_ETHTOOL_ID_COALESCE_LAST - _NM_ETHTOOL_ID_COALESCE_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_FEATURE_NUM = (_NM_ETHTOOL_ID_FEATURE_LAST - _NM_ETHTOOL_ID_FEATURE_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_RING_NUM = (_NM_ETHTOOL_ID_RING_LAST - _NM_ETHTOOL_ID_RING_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_PAUSE_NUM = (_NM_ETHTOOL_ID_PAUSE_LAST - _NM_ETHTOOL_ID_PAUSE_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_CHANNELS_NUM =
|
||||
(_NM_ETHTOOL_ID_CHANNELS_LAST - _NM_ETHTOOL_ID_CHANNELS_FIRST + 1),
|
||||
_NM_ETHTOOL_ID_NUM = (_NM_ETHTOOL_ID_LAST - _NM_ETHTOOL_ID_FIRST + 1),
|
||||
} NMEthtoolID;
|
||||
|
||||
#define _NM_ETHTOOL_ID_FEATURE_AS_IDX(ethtool_id) ((ethtool_id) -_NM_ETHTOOL_ID_FEATURE_FIRST)
|
||||
|
|
@ -143,6 +152,7 @@ typedef enum {
|
|||
NM_ETHTOOL_TYPE_FEATURE,
|
||||
NM_ETHTOOL_TYPE_RING,
|
||||
NM_ETHTOOL_TYPE_PAUSE,
|
||||
NM_ETHTOOL_TYPE_CHANNELS,
|
||||
} NMEthtoolType;
|
||||
|
||||
/****************************************************************************/
|
||||
|
|
@ -171,6 +181,12 @@ nm_ethtool_id_is_pause(NMEthtoolID id)
|
|||
return id >= _NM_ETHTOOL_ID_PAUSE_FIRST && id <= _NM_ETHTOOL_ID_PAUSE_LAST;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
nm_ethtool_id_is_channels(NMEthtoolID id)
|
||||
{
|
||||
return id >= _NM_ETHTOOL_ID_CHANNELS_FIRST && id <= _NM_ETHTOOL_ID_CHANNELS_LAST;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -106,11 +106,19 @@ const NMEthtoolData *const nm_ethtool_data[_NM_ETHTOOL_ID_NUM + 1] = {
|
|||
ETHT_DATA(RING_RX_JUMBO),
|
||||
ETHT_DATA(RING_RX_MINI),
|
||||
ETHT_DATA(RING_TX),
|
||||
ETHT_DATA(CHANNELS_RX),
|
||||
ETHT_DATA(CHANNELS_TX),
|
||||
ETHT_DATA(CHANNELS_OTHER),
|
||||
ETHT_DATA(CHANNELS_COMBINED),
|
||||
[_NM_ETHTOOL_ID_NUM] = NULL,
|
||||
};
|
||||
|
||||
static const guint8 _by_name[_NM_ETHTOOL_ID_NUM] = {
|
||||
/* sorted by optname. */
|
||||
NM_ETHTOOL_ID_CHANNELS_COMBINED,
|
||||
NM_ETHTOOL_ID_CHANNELS_OTHER,
|
||||
NM_ETHTOOL_ID_CHANNELS_RX,
|
||||
NM_ETHTOOL_ID_CHANNELS_TX,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_RX,
|
||||
NM_ETHTOOL_ID_COALESCE_ADAPTIVE_TX,
|
||||
NM_ETHTOOL_ID_COALESCE_PKT_RATE_HIGH,
|
||||
|
|
@ -291,6 +299,8 @@ nm_ethtool_id_to_type(NMEthtoolID id)
|
|||
return NM_ETHTOOL_TYPE_RING;
|
||||
if (nm_ethtool_id_is_pause(id))
|
||||
return NM_ETHTOOL_TYPE_PAUSE;
|
||||
if (nm_ethtool_id_is_channels(id))
|
||||
return NM_ETHTOOL_TYPE_CHANNELS;
|
||||
|
||||
return NM_ETHTOOL_TYPE_UNKNOWN;
|
||||
}
|
||||
|
|
@ -298,11 +308,17 @@ nm_ethtool_id_to_type(NMEthtoolID id)
|
|||
const GVariantType *
|
||||
nm_ethtool_id_get_variant_type(NMEthtoolID ethtool_id)
|
||||
{
|
||||
if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id))
|
||||
switch (nm_ethtool_id_to_type(ethtool_id)) {
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
case NM_ETHTOOL_TYPE_PAUSE:
|
||||
return G_VARIANT_TYPE_BOOLEAN;
|
||||
|
||||
if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id))
|
||||
case NM_ETHTOOL_TYPE_CHANNELS:
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
return G_VARIANT_TYPE_UINT32;
|
||||
|
||||
return NULL;
|
||||
case NM_ETHTOOL_TYPE_UNKNOWN:
|
||||
nm_assert(ethtool_id == NM_ETHTOOL_ID_UNKNOWN);
|
||||
return NULL;
|
||||
}
|
||||
return nm_assert_unreachable_val(NULL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,6 +104,11 @@ G_BEGIN_DECLS
|
|||
#define NM_ETHTOOL_OPTNAME_PAUSE_RX "pause-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_PAUSE_TX "pause-tx"
|
||||
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_RX "channels-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_TX "channels-tx"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -1947,4 +1947,5 @@ global:
|
|||
libnm_1_46_0 {
|
||||
global:
|
||||
nm_access_point_get_bandwidth;
|
||||
nm_ethtool_optname_is_channels;
|
||||
} libnm_1_44_0;
|
||||
|
|
|
|||
|
|
@ -104,6 +104,11 @@ G_BEGIN_DECLS
|
|||
#define NM_ETHTOOL_OPTNAME_PAUSE_RX "pause-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_PAUSE_TX "pause-tx"
|
||||
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_RX "channels-rx"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_TX "channels-tx"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_OTHER "channels-other"
|
||||
#define NM_ETHTOOL_OPTNAME_CHANNELS_COMBINED "channels-combined"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
|
|
@ -1292,6 +1292,22 @@
|
|||
dbus-type="u"
|
||||
is-setting-option="1"
|
||||
/>
|
||||
<property name="channels-rx"
|
||||
dbus-type="u"
|
||||
is-setting-option="1"
|
||||
/>
|
||||
<property name="channels-tx"
|
||||
dbus-type="u"
|
||||
is-setting-option="1"
|
||||
/>
|
||||
<property name="channels-other"
|
||||
dbus-type="u"
|
||||
is-setting-option="1"
|
||||
/>
|
||||
<property name="channels-combined"
|
||||
dbus-type="u"
|
||||
is-setting-option="1"
|
||||
/>
|
||||
</setting>
|
||||
<setting name="generic"
|
||||
gtype="NMSettingGeneric"
|
||||
|
|
|
|||
|
|
@ -75,6 +75,22 @@ nm_ethtool_optname_is_ring(const char *optname)
|
|||
return optname && nm_ethtool_id_is_ring(nm_ethtool_id_get_by_name(optname));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_ethtool_optname_is_channels:
|
||||
* @optname: (nullable): the option name to check
|
||||
*
|
||||
* Checks whether @optname is a valid option name for a channels setting.
|
||||
*
|
||||
* Returns: %TRUE, if @optname is valid
|
||||
*
|
||||
* Since: 1.46
|
||||
*/
|
||||
gboolean
|
||||
nm_ethtool_optname_is_channels(const char *optname)
|
||||
{
|
||||
return optname && nm_ethtool_id_is_channels(nm_ethtool_id_get_by_name(optname));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_ethtool_optname_is_pause:
|
||||
* @optname: (nullable): the option name to check
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ gboolean nm_ethtool_optname_is_ring(const char *optname);
|
|||
NM_AVAILABLE_IN_1_32
|
||||
gboolean nm_ethtool_optname_is_pause(const char *optname);
|
||||
|
||||
NM_AVAILABLE_IN_1_46
|
||||
gboolean nm_ethtool_optname_is_channels(const char *optname);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define NM_TYPE_SETTING_ETHTOOL (nm_setting_ethtool_get_type())
|
||||
|
|
|
|||
|
|
@ -1067,6 +1067,69 @@ nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_get_channels(int ifindex, NMEthtoolChannelsState *channels)
|
||||
{
|
||||
struct ethtool_channels eth_data;
|
||||
|
||||
g_return_val_if_fail(ifindex > 0, FALSE);
|
||||
g_return_val_if_fail(channels, FALSE);
|
||||
|
||||
eth_data.cmd = ETHTOOL_GCHANNELS;
|
||||
|
||||
if (_ethtool_call_once(ifindex, ð_data, sizeof(eth_data)) < 0) {
|
||||
nm_log_trace(LOGD_PLATFORM,
|
||||
"ethtool[%d]: %s: failure getting channels settings",
|
||||
ifindex,
|
||||
"get-channels");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*channels = (NMEthtoolChannelsState){
|
||||
.rx = eth_data.rx_count,
|
||||
.tx = eth_data.tx_count,
|
||||
.other = eth_data.other_count,
|
||||
.combined = eth_data.combined_count,
|
||||
};
|
||||
|
||||
nm_log_trace(LOGD_PLATFORM,
|
||||
"ethtool[%d]: %s: retrieved kernel channels settings",
|
||||
ifindex,
|
||||
"get-channels");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_set_channels(int ifindex, const NMEthtoolChannelsState *channels)
|
||||
{
|
||||
struct ethtool_channels eth_data;
|
||||
|
||||
g_return_val_if_fail(ifindex > 0, FALSE);
|
||||
g_return_val_if_fail(channels, FALSE);
|
||||
|
||||
eth_data = (struct ethtool_channels){
|
||||
.cmd = ETHTOOL_SCHANNELS,
|
||||
.rx_count = channels->rx,
|
||||
.tx_count = channels->tx,
|
||||
.other_count = channels->other,
|
||||
.combined_count = channels->combined,
|
||||
};
|
||||
|
||||
if (_ethtool_call_once(ifindex, ð_data, sizeof(eth_data)) < 0) {
|
||||
nm_log_trace(LOGD_PLATFORM,
|
||||
"ethtool[%d]: %s: failure setting channels settings",
|
||||
ifindex,
|
||||
"set-channels");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
nm_log_trace(LOGD_PLATFORM,
|
||||
"ethtool[%d]: %s: set kernel channels settings",
|
||||
ifindex,
|
||||
"set-channels");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_utils_ethtool_get_pause(int ifindex, NMEthtoolPauseState *pause)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ gboolean nmp_utils_ethtool_get_ring(int ifindex, NMEthtoolRingState *ring);
|
|||
|
||||
gboolean nmp_utils_ethtool_set_ring(int ifindex, const NMEthtoolRingState *ring);
|
||||
|
||||
gboolean nmp_utils_ethtool_get_channels(int ifindex, NMEthtoolChannelsState *channels);
|
||||
|
||||
gboolean nmp_utils_ethtool_set_channels(int ifindex, const NMEthtoolChannelsState *channels);
|
||||
|
||||
gboolean nmp_utils_ethtool_get_pause(int ifindex, NMEthtoolPauseState *pause);
|
||||
|
||||
gboolean nmp_utils_ethtool_set_pause(int ifindex, const NMEthtoolPauseState *pause);
|
||||
|
|
|
|||
|
|
@ -3580,6 +3580,31 @@ nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingS
|
|||
return nmp_utils_ethtool_set_ring(ifindex, ring);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_get_link_channels(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolChannelsState *channels)
|
||||
{
|
||||
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail(ifindex > 0, FALSE);
|
||||
g_return_val_if_fail(channels, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_get_channels(ifindex, channels);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_set_channels(NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolChannelsState *channels)
|
||||
{
|
||||
_CHECK_SELF_NETNS(self, klass, netns, FALSE);
|
||||
|
||||
g_return_val_if_fail(ifindex > 0, FALSE);
|
||||
|
||||
return nmp_utils_ethtool_set_channels(ifindex, channels);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2567,6 +2567,14 @@ gboolean nm_platform_ethtool_get_link_ring(NMPlatform *self, int ifindex, NMEtht
|
|||
gboolean
|
||||
nm_platform_ethtool_set_ring(NMPlatform *self, int ifindex, const NMEthtoolRingState *ring);
|
||||
|
||||
gboolean nm_platform_ethtool_get_link_channels(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMEthtoolChannelsState *channels);
|
||||
|
||||
gboolean nm_platform_ethtool_set_channels(NMPlatform *self,
|
||||
int ifindex,
|
||||
const NMEthtoolChannelsState *channels);
|
||||
|
||||
gboolean
|
||||
nm_platform_ethtool_get_link_pause(NMPlatform *self, int ifindex, NMEthtoolPauseState *pause);
|
||||
|
||||
|
|
|
|||
|
|
@ -93,16 +93,12 @@ typedef struct {
|
|||
const NMEthtoolFeatureState states_list[];
|
||||
} NMEthtoolFeatureStates;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
guint32
|
||||
s[_NM_ETHTOOL_ID_COALESCE_NUM /* indexed by (NMEthtoolID - _NM_ETHTOOL_ID_COALESCE_FIRST) */
|
||||
];
|
||||
} NMEthtoolCoalesceState;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
guint32 rx_pending;
|
||||
guint32 rx_mini_pending;
|
||||
|
|
@ -116,6 +112,13 @@ typedef struct {
|
|||
bool tx : 1;
|
||||
} NMEthtoolPauseState;
|
||||
|
||||
typedef struct {
|
||||
guint32 rx;
|
||||
guint32 tx;
|
||||
guint32 other;
|
||||
guint32 combined;
|
||||
} NMEthtoolChannelsState;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMPNetns NMPNetns;
|
||||
|
|
|
|||
|
|
@ -4421,26 +4421,32 @@ _get_fcn_ethtool(ARGS_GET_FCN)
|
|||
|
||||
RETURN_UNSUPPORTED_GET_TYPE();
|
||||
|
||||
if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) {
|
||||
switch (nm_ethtool_id_to_type(ethtool_id)) {
|
||||
case NM_ETHTOOL_TYPE_CHANNELS:
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
if (!nm_setting_option_get_uint32(setting, nm_ethtool_data[ethtool_id]->optname, &u32)) {
|
||||
NM_SET_OUT(out_is_default, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RETURN_STR_TO_FREE(nm_strdup_int(u32));
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
case NM_ETHTOOL_TYPE_PAUSE:
|
||||
if (!nm_setting_option_get_boolean(setting, nm_ethtool_data[ethtool_id]->optname, &b)) {
|
||||
NM_SET_OUT(out_is_default, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = b ? N_("on") : N_("off");
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
|
||||
s = gettext(s);
|
||||
return s;
|
||||
case NM_ETHTOOL_TYPE_UNKNOWN:
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
nm_assert(nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id));
|
||||
|
||||
if (!nm_setting_option_get_boolean(setting, nm_ethtool_data[ethtool_id]->optname, &b)) {
|
||||
NM_SET_OUT(out_is_default, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = b ? N_("on") : N_("off");
|
||||
if (get_type == NM_META_ACCESSOR_GET_TYPE_PRETTY)
|
||||
s = gettext(s);
|
||||
return s;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -4453,7 +4459,10 @@ _set_fcn_ethtool(ARGS_SET_FCN)
|
|||
if (_SET_FCN_DO_RESET_DEFAULT(property_info, modifier, value))
|
||||
goto do_unset;
|
||||
|
||||
if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id)) {
|
||||
switch (nm_ethtool_id_to_type(ethtool_id)) {
|
||||
case NM_ETHTOOL_TYPE_CHANNELS:
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
i64 = _nm_utils_ascii_str_to_int64(value, 10, 0, G_MAXUINT32, -1);
|
||||
if (i64 == -1) {
|
||||
nm_utils_error_set(
|
||||
|
|
@ -4468,25 +4477,27 @@ _set_fcn_ethtool(ARGS_SET_FCN)
|
|||
|
||||
nm_setting_option_set_uint32(setting, nm_ethtool_data[ethtool_id]->optname, i64);
|
||||
return TRUE;
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
case NM_ETHTOOL_TYPE_PAUSE:
|
||||
if (!nmc_string_to_ternary_full(value,
|
||||
NMC_STRING_TO_TERNARY_FLAGS_IGNORE_FOR_DEFAULT,
|
||||
&t,
|
||||
NULL)) {
|
||||
nm_utils_error_set(error,
|
||||
NM_UTILS_ERROR_INVALID_ARGUMENT,
|
||||
_("'%s' is not valid; use 'on', 'off', or 'ignore'"),
|
||||
value);
|
||||
return FALSE;
|
||||
}
|
||||
if (t == NM_TERNARY_DEFAULT)
|
||||
goto do_unset;
|
||||
|
||||
nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, !!t);
|
||||
return TRUE;
|
||||
case NM_ETHTOOL_TYPE_UNKNOWN:
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
nm_assert(nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id));
|
||||
|
||||
if (!nmc_string_to_ternary_full(value,
|
||||
NMC_STRING_TO_TERNARY_FLAGS_IGNORE_FOR_DEFAULT,
|
||||
&t,
|
||||
NULL)) {
|
||||
nm_utils_error_set(error,
|
||||
NM_UTILS_ERROR_INVALID_ARGUMENT,
|
||||
_("'%s' is not valid; use 'on', 'off', or 'ignore'"),
|
||||
value);
|
||||
return FALSE;
|
||||
}
|
||||
if (t == NM_TERNARY_DEFAULT)
|
||||
goto do_unset;
|
||||
|
||||
nm_setting_option_set_boolean(setting, nm_ethtool_data[ethtool_id]->optname, !!t);
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
|
||||
do_unset:
|
||||
nm_setting_option_set(setting, nm_ethtool_data[ethtool_id]->optname, NULL);
|
||||
|
|
@ -5919,6 +5930,10 @@ static const NMMetaPropertyInfo *const property_infos_ETHTOOL[] = {
|
|||
PROPERTY_INFO_ETHTOOL (RING_RX_JUMBO),
|
||||
PROPERTY_INFO_ETHTOOL (RING_RX_MINI),
|
||||
PROPERTY_INFO_ETHTOOL (RING_TX),
|
||||
PROPERTY_INFO_ETHTOOL (CHANNELS_RX),
|
||||
PROPERTY_INFO_ETHTOOL (CHANNELS_TX),
|
||||
PROPERTY_INFO_ETHTOOL (CHANNELS_OTHER),
|
||||
PROPERTY_INFO_ETHTOOL (CHANNELS_COMBINED),
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -111,10 +111,18 @@ get_ethtool_format(const NMMetaPropertyInfo *prop_info)
|
|||
|
||||
ethtool_id = prop_info->property_typ_data->subtype.ethtool.ethtool_id;
|
||||
|
||||
if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id))
|
||||
switch (nm_ethtool_id_to_type(ethtool_id)) {
|
||||
case NM_ETHTOOL_TYPE_CHANNELS:
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
return g_strdup("integer");
|
||||
else if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id))
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
case NM_ETHTOOL_TYPE_PAUSE:
|
||||
return g_strdup("ternary");
|
||||
case NM_ETHTOOL_TYPE_UNKNOWN:
|
||||
nm_assert_not_reached();
|
||||
};
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -301,10 +309,19 @@ append_ethtool_valid_values(const NMMetaPropertyInfo *prop_info, GPtrArray *vali
|
|||
|
||||
ethtool_id = prop_info->property_typ_data->subtype.ethtool.ethtool_id;
|
||||
|
||||
if (nm_ethtool_id_is_coalesce(ethtool_id) || nm_ethtool_id_is_ring(ethtool_id))
|
||||
switch (nm_ethtool_id_to_type(ethtool_id)) {
|
||||
case NM_ETHTOOL_TYPE_CHANNELS:
|
||||
case NM_ETHTOOL_TYPE_COALESCE:
|
||||
case NM_ETHTOOL_TYPE_RING:
|
||||
g_ptr_array_add(valid_values, g_strdup_printf("0 - %u", G_MAXUINT32));
|
||||
else if (nm_ethtool_id_is_feature(ethtool_id) || nm_ethtool_id_is_pause(ethtool_id))
|
||||
break;
|
||||
case NM_ETHTOOL_TYPE_FEATURE:
|
||||
case NM_ETHTOOL_TYPE_PAUSE:
|
||||
append_vals(valid_values, "on", "off", "ignore");
|
||||
break;
|
||||
case NM_ETHTOOL_TYPE_UNKNOWN:
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
|||
|
|
@ -1040,6 +1040,18 @@
|
|||
<property name="ring-tx"
|
||||
format="integer"
|
||||
values="0 - 4294967295" />
|
||||
<property name="channels-rx"
|
||||
format="integer"
|
||||
values="0 - 4294967295" />
|
||||
<property name="channels-tx"
|
||||
format="integer"
|
||||
values="0 - 4294967295" />
|
||||
<property name="channels-other"
|
||||
format="integer"
|
||||
values="0 - 4294967295" />
|
||||
<property name="channels-combined"
|
||||
format="integer"
|
||||
values="0 - 4294967295" />
|
||||
</setting>
|
||||
<setting name="generic" >
|
||||
</setting>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue