Message ID | 20220513180030.3076793-1-horatiu.vultur@microchip.com (mailing list archive) |
---|---|
State | Accepted |
Commit | af8ca6eaa9b24a90484218e356f959a94bff22fa |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] net: lan966x: Fix assignment of the MAC address | expand |
Hello: This patch was applied to netdev/net.git (master) by Paolo Abeni <pabeni@redhat.com>: On Fri, 13 May 2022 20:00:30 +0200 you wrote: > The following two scenarios were failing for lan966x. > 1. If the port had the address X and then trying to assign the same > address, then the HW was just removing this address because first it > tries to learn new address and then delete the old one. As they are > the same the HW remove it. > 2. If the port eth0 was assigned the same address as one of the other > ports eth1 then when assigning back the address to eth0 then the HW > was deleting the address of eth1. > > [...] Here is the summary with links: - [net] net: lan966x: Fix assignment of the MAC address https://git.kernel.org/netdev/net/c/af8ca6eaa9b2 You are awesome, thank you!
diff --git a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c index 95830e3e2b1f..05f6dcc9dfd5 100644 --- a/drivers/net/ethernet/microchip/lan966x/lan966x_main.c +++ b/drivers/net/ethernet/microchip/lan966x/lan966x_main.c @@ -103,6 +103,24 @@ static int lan966x_create_targets(struct platform_device *pdev, return 0; } +static bool lan966x_port_unique_address(struct net_device *dev) +{ + struct lan966x_port *port = netdev_priv(dev); + struct lan966x *lan966x = port->lan966x; + int p; + + for (p = 0; p < lan966x->num_phys_ports; ++p) { + port = lan966x->ports[p]; + if (!port || port->dev == dev) + continue; + + if (ether_addr_equal(dev->dev_addr, port->dev->dev_addr)) + return false; + } + + return true; +} + static int lan966x_port_set_mac_address(struct net_device *dev, void *p) { struct lan966x_port *port = netdev_priv(dev); @@ -110,16 +128,26 @@ static int lan966x_port_set_mac_address(struct net_device *dev, void *p) const struct sockaddr *addr = p; int ret; + if (ether_addr_equal(addr->sa_data, dev->dev_addr)) + return 0; + /* Learn the new net device MAC address in the mac table. */ ret = lan966x_mac_cpu_learn(lan966x, addr->sa_data, HOST_PVID); if (ret) return ret; + /* If there is another port with the same address as the dev, then don't + * delete it from the MAC table + */ + if (!lan966x_port_unique_address(dev)) + goto out; + /* Then forget the previous one. */ ret = lan966x_mac_cpu_forget(lan966x, dev->dev_addr, HOST_PVID); if (ret) return ret; +out: eth_hw_addr_set(dev, addr->sa_data); return ret; }
The following two scenarios were failing for lan966x. 1. If the port had the address X and then trying to assign the same address, then the HW was just removing this address because first it tries to learn new address and then delete the old one. As they are the same the HW remove it. 2. If the port eth0 was assigned the same address as one of the other ports eth1 then when assigning back the address to eth0 then the HW was deleting the address of eth1. The case 1. is fixed by checking if the port has already the same address while case 2. is fixed by checking if the address is used by any other port. Fixes: e18aba8941b40b ("net: lan966x: add mactable support") Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> --- .../ethernet/microchip/lan966x/lan966x_main.c | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+)