Skip to content

Commit

Permalink
net: dsa: install the primary unicast MAC address as standalone port …
Browse files Browse the repository at this point in the history
…host FDB

To be able to safely turn off CPU flooding for standalone ports, we need
to ensure that the dev_addr of each DSA slave interface is installed as
a standalone host FDB entry for compatible switches.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vladimir Oltean authored and David S. Miller committed Mar 3, 2022
1 parent 5e8a1e0 commit 499aa9e
Showing 1 changed file with 33 additions and 2 deletions.
35 changes: 33 additions & 2 deletions net/dsa/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ static int dsa_slave_open(struct net_device *dev)
{
struct net_device *master = dsa_slave_to_master(dev);
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_switch *ds = dp->ds;
int err;

err = dev_open(master, NULL);
Expand All @@ -183,10 +184,16 @@ static int dsa_slave_open(struct net_device *dev)
goto out;
}

if (dsa_switch_supports_uc_filtering(ds)) {
err = dsa_port_standalone_host_fdb_add(dp, dev->dev_addr, 0);
if (err)
goto out;
}

if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
err = dev_uc_add(master, dev->dev_addr);
if (err < 0)
goto out;
goto del_host_addr;
}

err = dsa_port_enable_rt(dp, dev->phydev);
Expand All @@ -198,6 +205,9 @@ static int dsa_slave_open(struct net_device *dev)
del_unicast:
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
dev_uc_del(master, dev->dev_addr);
del_host_addr:
if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
out:
return err;
}
Expand All @@ -206,12 +216,16 @@ static int dsa_slave_close(struct net_device *dev)
{
struct net_device *master = dsa_slave_to_master(dev);
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_switch *ds = dp->ds;

dsa_port_disable_rt(dp);

if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
dev_uc_del(master, dev->dev_addr);

if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);

return 0;
}

Expand Down Expand Up @@ -244,24 +258,41 @@ static void dsa_slave_set_rx_mode(struct net_device *dev)
static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
{
struct net_device *master = dsa_slave_to_master(dev);
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_switch *ds = dp->ds;
struct sockaddr *addr = a;
int err;

if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;

if (dsa_switch_supports_uc_filtering(ds)) {
err = dsa_port_standalone_host_fdb_add(dp, addr->sa_data, 0);
if (err)
return err;
}

if (!ether_addr_equal(addr->sa_data, master->dev_addr)) {
err = dev_uc_add(master, addr->sa_data);
if (err < 0)
return err;
goto del_unicast;
}

if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
dev_uc_del(master, dev->dev_addr);

if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);

eth_hw_addr_set(dev, addr->sa_data);

return 0;

del_unicast:
if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, addr->sa_data, 0);

return err;
}

struct dsa_slave_dump_ctx {
Expand Down

0 comments on commit 499aa9e

Please sign in to comment.