]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
net: team: Add new tx_enabled team port option
authorMarc Harvey <marcharvey@google.com>
Thu, 9 Apr 2026 02:59:31 +0000 (02:59 +0000)
committerPaolo Abeni <pabeni@redhat.com>
Mon, 13 Apr 2026 13:09:49 +0000 (15:09 +0200)
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>
drivers/net/team/team_core.c

index 67f77de4cf10f26f5a014d9b64b9c21074c2f533..0c87f99724577d8587e754dd611ff20e820f0ea2 100644 (file)
@@ -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,