diff options
author | Vladimir Oltean <vladimir.oltean@nxp.com> | 2022-03-08 10:15:13 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2022-03-09 12:12:09 +0100 |
commit | e2d0576f0c009acdba63e1d763276743ff3788cc (patch) | |
tree | 4ac0a877228cca3b7b4ddf57eae1b0e47de1a200 /net/dsa | |
parent | net: dsa: felix: drop "bool change" from felix_set_tag_protocol (diff) | |
download | linux-e2d0576f0c009acdba63e1d763276743ff3788cc.tar.xz linux-e2d0576f0c009acdba63e1d763276743ff3788cc.zip |
net: dsa: be mostly no-op in dsa_slave_set_mac_address when down
Since the slave unicast address is synced to hardware and to the DSA
master during dsa_slave_open(), this means that a call to
dsa_slave_set_mac_address() while the slave interface is down will
result to a call to dsa_port_standalone_host_fdb_del() and to
dev_uc_del() for the MAC address while there was no previous
dsa_port_standalone_host_fdb_add() or dev_uc_add().
This is a partial revert of the blamed commit below, which was too
aggressive.
Fixes: 35aae5ab9121 ("net: dsa: remove workarounds for changing master promisc/allmulti only while up")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r-- | net/dsa/slave.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 42436ac6993b..a61a7c54af20 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -305,6 +305,12 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; + /* If the port is down, the address isn't synced yet to hardware or + * to the DSA master, so there is nothing to change. + */ + if (!(dev->flags & IFF_UP)) + goto out_change_dev_addr; + if (dsa_switch_supports_uc_filtering(ds)) { err = dsa_port_standalone_host_fdb_add(dp, addr->sa_data, 0); if (err) @@ -323,6 +329,7 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a) if (dsa_switch_supports_uc_filtering(ds)) dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); +out_change_dev_addr: eth_hw_addr_set(dev, addr->sa_data); return 0; |