net: team: Add new tx_enabled team port option
This option allows independent control over tx enablement without affecting rx enablement. Like the rx_enabled option, this also implicitly affects the enabled option. If this option is not used, then the enabled option will continue to behave as it did before. Tested in a follow-up patch with a new selftest. Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Marc Harvey <marcharvey@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260409-teaming-driver-internal-v7-9-f47e7589685d@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>master
parent
0e47569a57
commit
bb9215a981
|
|
@ -978,6 +978,21 @@ static void __team_port_enable_tx(struct team *team,
|
|||
team_tx_port_index_hash(team, port->tx_index));
|
||||
}
|
||||
|
||||
static void team_port_enable_tx(struct team *team,
|
||||
struct team_port *port)
|
||||
{
|
||||
if (team_port_tx_enabled(port))
|
||||
return;
|
||||
|
||||
__team_port_enable_tx(team, port);
|
||||
team_adjust_ops(team);
|
||||
team_queue_override_port_add(team, port);
|
||||
|
||||
/* Don't rejoin multicast, since this port might not be receiving. */
|
||||
team_notify_peers(team);
|
||||
team_lower_state_changed(port);
|
||||
}
|
||||
|
||||
static void __reconstruct_port_hlist(struct team *team, int rm_index)
|
||||
{
|
||||
struct hlist_head *tx_port_index_hash;
|
||||
|
|
@ -1007,6 +1022,19 @@ static void __team_port_disable_tx(struct team *team,
|
|||
WRITE_ONCE(team->tx_en_port_count, team->tx_en_port_count - 1);
|
||||
}
|
||||
|
||||
static void team_port_disable_tx(struct team *team,
|
||||
struct team_port *port)
|
||||
{
|
||||
if (!team_port_tx_enabled(port))
|
||||
return;
|
||||
|
||||
__team_port_disable_tx(team, port);
|
||||
|
||||
team_queue_override_port_del(team, port);
|
||||
team_adjust_ops(team);
|
||||
team_lower_state_changed(port);
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable TX AND RX on the port.
|
||||
*/
|
||||
|
|
@ -1529,6 +1557,26 @@ static int team_port_rx_en_option_set(struct team *team,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void team_port_tx_en_option_get(struct team *team,
|
||||
struct team_gsetter_ctx *ctx)
|
||||
{
|
||||
struct team_port *port = ctx->info->port;
|
||||
|
||||
ctx->data.bool_val = team_port_tx_enabled(port);
|
||||
}
|
||||
|
||||
static int team_port_tx_en_option_set(struct team *team,
|
||||
struct team_gsetter_ctx *ctx)
|
||||
{
|
||||
struct team_port *port = ctx->info->port;
|
||||
|
||||
if (ctx->data.bool_val)
|
||||
team_port_enable_tx(team, port);
|
||||
else
|
||||
team_port_disable_tx(team, port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void team_user_linkup_option_get(struct team *team,
|
||||
struct team_gsetter_ctx *ctx)
|
||||
{
|
||||
|
|
@ -1657,6 +1705,13 @@ static const struct team_option team_options[] = {
|
|||
.getter = team_port_rx_en_option_get,
|
||||
.setter = team_port_rx_en_option_set,
|
||||
},
|
||||
{
|
||||
.name = "tx_enabled",
|
||||
.type = TEAM_OPTION_TYPE_BOOL,
|
||||
.per_port = true,
|
||||
.getter = team_port_tx_en_option_get,
|
||||
.setter = team_port_tx_en_option_set,
|
||||
},
|
||||
{
|
||||
.name = "user_linkup",
|
||||
.type = TEAM_OPTION_TYPE_BOOL,
|
||||
|
|
|
|||
Loading…
Reference in New Issue