[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20251127053336.GI323117@black.igk.intel.com>
Date: Thu, 27 Nov 2025 06:33:36 +0100
From: Mika Westerberg <mika.westerberg@...ux.intel.com>
To: Ian MacDonald <ian@...statz.com>
Cc: Mika Westerberg <westeri@...nel.org>,
Yehezkel Bernat <YehezkelShB@...il.com>, netdev@...r.kernel.org,
linux-kernel@...r.kernel.org, 1121032@...s.debian.org
Subject: Re: net: thunderbolt: missing ndo_set_mac_address breaks 802.3ad
bonding
Hi,
On Wed, Nov 26, 2025 at 06:39:50PM -0500, Ian MacDonald wrote:
> Hi Mika,
>
> Following up on the previous discussion, your patch enabling MAC address
> changes allowed bonding to enslave thunderbolt_net devices, but 802.3ad
> still could not form an aggregator because the driver does not report
> link speed or duplex via ethtool. Bonding logs:
>
> bond0: (slave thunderbolt0): failed to get link speed/duplex
Okay thanks for checking.
> Bonding (802.3ad) requires non-zero speed/duplex values for LACP port
> key calculation.
>
> The patch below adds a minimal get_link_ksettings() implementation and
> registers ethtool_ops. It reports a fixed 10Gbps full-duplex link,
> which is sufficient for LACP and seems consistent with ThunderboltIP
> host-to-host bandwidth with the USB4v1/TB3 hardware I am using.
I see. Yeah for speed we need to do something more than use the hard-coded
values because it varies depending on whether we have lane bonding (not the
same bonding you are doing) enabled and also how the link trained.
Let me come up with a patch based on yours that does that.
> With this change, 802.3ad bonding comes up correctly on my USB4/TB
> host-to-host setup. I also added link mode bitmaps, though they are not
> strictly required for LACP/802.3ad.
>
> Signed-off-by: Ian MacDonald <ian@...statz.com>
>
> ---
> drivers/net/thunderbolt/main.c | 29 +++++++++++++++++++++++++++++
> 1 file changed, 29 insertions(+)
>
> diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c
> index 4f4694db6..b9e276693 100644
> --- a/drivers/net/thunderbolt/main.c
> +++ b/drivers/net/thunderbolt/main.c
> @@ -15,6 +15,7 @@
> #include <linux/jhash.h>
> #include <linux/module.h>
> #include <linux/etherdevice.h>
> +#include <linux/ethtool.h>
> #include <linux/rtnetlink.h>
> #include <linux/sizes.h>
> #include <linux/thunderbolt.h>
> @@ -1257,6 +1258,28 @@ static void tbnet_get_stats64(struct net_device *dev,
> stats->rx_missed_errors = net->stats.rx_missed_errors;
> }
>
> +static int tbnet_get_link_ksettings(struct net_device *dev,
> + struct ethtool_link_ksettings *cmd)
> +{
> + /* ThunderboltIP is a software-only full-duplex network tunnel.
> + * We report fixed link settings to satisfy bonding (802.3ad)
> + * requirements for LACP port key calculation. Speed is set to
> + * 10Gbps as a conservative baseline.
> + */
> + ethtool_link_ksettings_zero_link_mode(cmd, supported);
> + ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full);
> +
> + ethtool_link_ksettings_zero_link_mode(cmd, advertising);
> + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full);
> +
> + cmd->base.speed = SPEED_10000;
> + cmd->base.duplex = DUPLEX_FULL;
> + cmd->base.autoneg = AUTONEG_DISABLE;
> + cmd->base.port = PORT_NONE;
> +
> + return 0;
> +}
> +
> static const struct net_device_ops tbnet_netdev_ops = {
> .ndo_open = tbnet_open,
> .ndo_stop = tbnet_stop,
> @@ -1265,6 +1288,10 @@ static const struct net_device_ops tbnet_netdev_ops = {
> .ndo_get_stats64 = tbnet_get_stats64,
> };
>
> +static const struct ethtool_ops tbnet_ethtool_ops = {
> + .get_link_ksettings = tbnet_get_link_ksettings,
> +};
> +
> static void tbnet_generate_mac(struct net_device *dev)
> {
> const struct tbnet *net = netdev_priv(dev);
> @@ -1315,6 +1342,7 @@ static int tbnet_probe(struct tb_service *svc,
> const struct tb_service_id *id)
>
> strcpy(dev->name, "thunderbolt%d");
> dev->netdev_ops = &tbnet_netdev_ops;
> + dev->ethtool_ops = &tbnet_ethtool_ops;
>
> /* ThunderboltIP takes advantage of TSO packets but instead of
> * segmenting them we just split the packet into Thunderbolt
> --
> 2.47.3
>
>
>
> > On Fri, Nov 21, 2025 at 3:11 AM Mika Westerberg
> > <mika.westerberg@...ux.intel.com> wrote:
> > > The below allows me to change it using "ip link set" command. I wonder if
> > > you could try it with the bonding case and see it that makes any
> > > difference?
> > >
> > > diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c
> > > index dcaa62377808..57b226afeb84 100644
> > > --- a/drivers/net/thunderbolt/main.c
> > > +++ b/drivers/net/thunderbolt/main.c
> > > @@ -1261,6 +1261,7 @@ static const struct net_device_ops tbnet_netdev_ops = {
> > > .ndo_open = tbnet_open,
> > > .ndo_stop = tbnet_stop,
> > > .ndo_start_xmit = tbnet_start_xmit,
> > > + .ndo_set_mac_address = eth_mac_addr,
> > > .ndo_get_stats64 = tbnet_get_stats64,
> > > };
> > >
> > > @@ -1281,6 +1282,9 @@ static void tbnet_generate_mac(struct net_device *dev)
> > > hash = jhash2((u32 *)xd->local_uuid, 4, hash);
> > > addr[5] = hash & 0xff;
> > > eth_hw_addr_set(dev, addr);
> > > +
> > > + /* Allow changing it if needed */
> > > + dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
> > > }
> > >
> > > static int tbnet_probe(struct tb_service *svc, const struct tb_service_id *id)
>
> Basic testing below on Debian with kernel 6.17.8 shows aggregate
> speeds within the expected range.
>
> - - - - - - - - - - - - - - - - - - - - - - - - -
> [ ID][Role] Interval Transfer Bitrate Retr
> [ 5][TX-C] 0.00-10.07 sec 5.58 GBytes 4.76 Gbits/sec 0
> sender
> [ 5][TX-C] 0.00-10.07 sec 5.58 GBytes 4.76 Gbits/sec
> receiver
> [ 7][TX-C] 0.00-10.07 sec 5.58 GBytes 4.76 Gbits/sec 0
> sender
> [ 7][TX-C] 0.00-10.07 sec 5.58 GBytes 4.76 Gbits/sec
> receiver
> [ 9][TX-C] 0.00-10.07 sec 5.59 GBytes 4.77 Gbits/sec 0
> sender
> [ 9][TX-C] 0.00-10.07 sec 5.59 GBytes 4.77 Gbits/sec
> receiver
> [ 11][TX-C] 0.00-10.07 sec 5.59 GBytes 4.77 Gbits/sec 0
> sender
> [ 11][TX-C] 0.00-10.07 sec 5.59 GBytes 4.77 Gbits/sec
> receiver
> [SUM][TX-C] 0.00-10.07 sec 22.3 GBytes 19.1 Gbits/sec 0
> sender
> [SUM][TX-C] 0.00-10.07 sec 22.3 GBytes 19.1 Gbits/sec
> receiver
> [ 13][RX-C] 0.00-10.07 sec 3.72 GBytes 3.18 Gbits/sec 1
> sender
> [ 13][RX-C] 0.00-10.07 sec 3.72 GBytes 3.17 Gbits/sec
> receiver
> [ 15][RX-C] 0.00-10.07 sec 11.1 GBytes 9.50 Gbits/sec 4
> sender
> [ 15][RX-C] 0.00-10.07 sec 11.1 GBytes 9.50 Gbits/sec
> receiver
> [ 17][RX-C] 0.00-10.07 sec 3.72 GBytes 3.18 Gbits/sec 1
> sender
> [ 17][RX-C] 0.00-10.07 sec 3.72 GBytes 3.17 Gbits/sec
> receiver
> [ 19][RX-C] 0.00-10.07 sec 3.73 GBytes 3.18 Gbits/sec 1
> sender
> [ 19][RX-C] 0.00-10.07 sec 3.73 GBytes 3.18 Gbits/sec
> receiver
> [SUM][RX-C] 0.00-10.07 sec 22.3 GBytes 19.0 Gbits/sec 7
> sender
> [SUM][RX-C] 0.00-10.07 sec 22.3 GBytes 19.0 Gbits/sec
> receiver
>
> iperf Done.
> ai2:~# iperf3 --bidir -c 10.10.13.1 -P 4 -t 10
>
> ai2:~# networkctl status bond0
> ● 3: bond0
> NetDev File: /etc/systemd/network/50-bond0.netdev
> Link File: /usr/lib/systemd/network/99-default.link
> Network File: /etc/systemd/network/53-bond0.network
> State: routable (configured)
> Online state: online
> Type: bond
> Kind: bond
> Driver: bonding
> Hardware Address: 82:36:12:ad:a1:c0
> MTU: 1500 (min: 68, max: 65535)
> QDisc: noqueue
> IPv6 Address Generation Mode: eui64
> Mode: 802.3ad
> Miimon: 500ms
> Updelay: 0
> Downdelay: 0
> Number of Queues (Tx/Rx): 16/16
> Auto negotiation: no
> Speed: 20Gbps
> Duplex: full
> Address: 10.10.13.2
> fe80::8036:12ff:fead:a1c0
> Activation Policy: up
> Required For Online: yes
> DHCPv6 Client DUID: DUID-EN/Vendor:0000ab111c6e5c59896f0172
>
> Nov 26 22:46:11 ai2 systemd-networkd[641]: bond0: netdev ready
> Nov 26 22:46:11 ai2 systemd-networkd[641]: bond0: Configuring with
> /etc/systemd/network/53-bond0.network.
> Nov 26 22:46:11 ai2 systemd-networkd[641]: bond0: Link UP
> Nov 26 17:46:52 ai2 systemd-networkd[641]: bond0: Gained carrier
> Nov 26 17:46:53 ai2 systemd-networkd[641]: bond0: Gained IPv6LL
>
> ai2:~# ethtool thunderbolt0
> Settings for thunderbolt0:
> Supported ports: [ ]
> Supported link modes: 10000baseT/Full
> Supported pause frame use: No
> Supports auto-negotiation: No
> Supported FEC modes: Not reported
> Advertised link modes: 10000baseT/Full
> Advertised pause frame use: No
> Advertised auto-negotiation: No
> Advertised FEC modes: Not reported
> Speed: 10000Mb/s
> Duplex: Full
> Auto-negotiation: off
> Port: None
> PHYAD: 0
> Transceiver: internal
Powered by blists - more mailing lists