The MAC address we use is based on a suggestion in the USB4 Inter-domain spec but it is not really used in the USB4NET protocol. It is more targeted for the upper layers of the network stack. There is no reason why it should not be changed by the userspace for example if needed for bonding. Reported-by: Ian MacDonald Closes: https://lore.kernel.org/netdev/CAFJzfF9N4Hak23sc-zh0jMobbkjK7rg4odhic1DQ1cC+=MoQoA@mail.gmail.com/ Signed-off-by: Mika Westerberg --- drivers/net/thunderbolt/main.c | 4 ++++ 1 file changed, 4 insertions(+) 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) -- 2.50.1 In some cases it is useful to be able to use different MTU than the default one. Especially when dealing against non-Linux networking stack. For this reason add possibility to change the MTU of the device. Signed-off-by: Mika Westerberg --- drivers/net/thunderbolt/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c index 57b226afeb84..20bac55a3e20 100644 --- a/drivers/net/thunderbolt/main.c +++ b/drivers/net/thunderbolt/main.c @@ -1257,12 +1257,23 @@ static void tbnet_get_stats64(struct net_device *dev, stats->rx_missed_errors = net->stats.rx_missed_errors; } +static int tbnet_change_mtu(struct net_device *dev, int new_mtu) +{ + /* Keep the MTU within supported range */ + if (new_mtu < 68 || new_mtu > (TBNET_MAX_MTU - ETH_HLEN)) + return -EINVAL; + + dev->mtu = new_mtu; + return 0; +} + 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, + .ndo_change_mtu = tbnet_change_mtu, }; static void tbnet_generate_mac(struct net_device *dev) -- 2.50.1 USB4 v2 link used in peer-to-peer networking is symmetric 80 Gbps so in order to support reading this link speed, add it to ethtool. Signed-off-by: Mika Westerberg --- include/uapi/linux/ethtool.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h index eb7ff2602fbb..181243a2d700 100644 --- a/include/uapi/linux/ethtool.h +++ b/include/uapi/linux/ethtool.h @@ -2190,6 +2190,7 @@ enum ethtool_link_mode_bit_indices { #define SPEED_40000 40000 #define SPEED_50000 50000 #define SPEED_56000 56000 +#define SPEED_80000 80000 #define SPEED_100000 100000 #define SPEED_200000 200000 #define SPEED_400000 400000 -- 2.50.1 Add support for ethtool SPEED_80000. This is needed to allow Thunderbolt/USB4 networking driver to be used with the bonding driver. Signed-off-by: Mika Westerberg --- drivers/net/bonding/bond_3ad.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 1a8de2bf8655..e5e9c7207309 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -72,6 +72,7 @@ enum ad_link_speed_type { AD_LINK_SPEED_40000MBPS, AD_LINK_SPEED_50000MBPS, AD_LINK_SPEED_56000MBPS, + AD_LINK_SPEED_80000MBPS, AD_LINK_SPEED_100000MBPS, AD_LINK_SPEED_200000MBPS, AD_LINK_SPEED_400000MBPS, @@ -297,6 +298,7 @@ static inline int __check_agg_selection_timer(struct port *port) * %AD_LINK_SPEED_40000MBPS * %AD_LINK_SPEED_50000MBPS * %AD_LINK_SPEED_56000MBPS + * %AD_LINK_SPEED_80000MBPS * %AD_LINK_SPEED_100000MBPS * %AD_LINK_SPEED_200000MBPS * %AD_LINK_SPEED_400000MBPS @@ -365,6 +367,10 @@ static u16 __get_link_speed(struct port *port) speed = AD_LINK_SPEED_56000MBPS; break; + case SPEED_80000: + speed = AD_LINK_SPEED_80000MBPS; + break; + case SPEED_100000: speed = AD_LINK_SPEED_100000MBPS; break; -- 2.50.1 From: Ian MacDonald In order to use Thunderbolt networking as part of bonding device it needs to support ->get_link_ksettings() ethtool operation, so that the bonding driver can read the link speed and the related attributes. Add support for this to the driver. Signed-off-by: Ian MacDonald Signed-off-by: Mika Westerberg --- drivers/net/thunderbolt/main.c | 49 ++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c index 20bac55a3e20..74160d14cf46 100644 --- a/drivers/net/thunderbolt/main.c +++ b/drivers/net/thunderbolt/main.c @@ -10,6 +10,7 @@ */ #include +#include #include #include #include @@ -1276,6 +1277,53 @@ static const struct net_device_ops tbnet_netdev_ops = { .ndo_change_mtu = tbnet_change_mtu, }; +static int tbnet_get_link_ksettings(struct net_device *dev, + struct ethtool_link_ksettings *cmd) +{ + const struct tbnet *net = netdev_priv(dev); + const struct tb_xdomain *xd = net->xd; + int speed; + + ethtool_link_ksettings_zero_link_mode(cmd, supported); + ethtool_link_ksettings_zero_link_mode(cmd, advertising); + + /* Figure out the current link speed and width */ + switch (xd->link_speed) { + case 40: + speed = SPEED_80000; + break; + + case 20: + if (xd->link_width == 2) + speed = SPEED_40000; + else + speed = SPEED_20000; + break; + + case 10: + if (xd->link_width == 2) { + speed = SPEED_20000; + break; + } + fallthrough; + + default: + speed = SPEED_10000; + break; + } + + cmd->base.speed = speed; + cmd->base.duplex = DUPLEX_FULL; + cmd->base.autoneg = AUTONEG_DISABLE; + cmd->base.port = PORT_OTHER; + + return 0; +} + +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); @@ -1326,6 +1374,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.50.1