Skip to content
This repository was archived by the owner on Oct 3, 2024. It is now read-only.

Commit af8ca6e

Browse files
HoratiuVulturPaolo Abeni
authored and
Paolo Abeni
committed
net: lan966x: Fix assignment of the MAC address
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: e18aba8 ("net: lan966x: add mactable support") Signed-off-by: Horatiu Vultur <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent da2172a commit af8ca6e

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/net/ethernet/microchip/lan966x/lan966x_main.c

+28
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,51 @@ static int lan966x_create_targets(struct platform_device *pdev,
103103
return 0;
104104
}
105105

106+
static bool lan966x_port_unique_address(struct net_device *dev)
107+
{
108+
struct lan966x_port *port = netdev_priv(dev);
109+
struct lan966x *lan966x = port->lan966x;
110+
int p;
111+
112+
for (p = 0; p < lan966x->num_phys_ports; ++p) {
113+
port = lan966x->ports[p];
114+
if (!port || port->dev == dev)
115+
continue;
116+
117+
if (ether_addr_equal(dev->dev_addr, port->dev->dev_addr))
118+
return false;
119+
}
120+
121+
return true;
122+
}
123+
106124
static int lan966x_port_set_mac_address(struct net_device *dev, void *p)
107125
{
108126
struct lan966x_port *port = netdev_priv(dev);
109127
struct lan966x *lan966x = port->lan966x;
110128
const struct sockaddr *addr = p;
111129
int ret;
112130

131+
if (ether_addr_equal(addr->sa_data, dev->dev_addr))
132+
return 0;
133+
113134
/* Learn the new net device MAC address in the mac table. */
114135
ret = lan966x_mac_cpu_learn(lan966x, addr->sa_data, HOST_PVID);
115136
if (ret)
116137
return ret;
117138

139+
/* If there is another port with the same address as the dev, then don't
140+
* delete it from the MAC table
141+
*/
142+
if (!lan966x_port_unique_address(dev))
143+
goto out;
144+
118145
/* Then forget the previous one. */
119146
ret = lan966x_mac_cpu_forget(lan966x, dev->dev_addr, HOST_PVID);
120147
if (ret)
121148
return ret;
122149

150+
out:
123151
eth_hw_addr_set(dev, addr->sa_data);
124152
return ret;
125153
}

0 commit comments

Comments
 (0)