Commit 77f75412 authored by Marek Behún's avatar Marek Behún Committed by David S. Miller

net: dsa: deduplicate code adding / deleting the port address to fdb

The sequence
  if (dsa_switch_supports_uc_filtering(ds))
    dsa_port_standalone_host_fdb_add(dp, addr, 0);
  if (!ether_addr_equal(addr, conduit->dev_addr))
    dev_uc_add(conduit, addr);
is executed both in dsa_user_open() and dsa_user_set_mac_addr().

Its reverse is executed both in dsa_user_close() and
dsa_user_set_mac_addr().

Refactor these sequences into new functions dsa_user_host_uc_install()
and dsa_user_host_uc_uninstall().
Signed-off-by: default avatarMarek Behún <kabel@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 395059c5
...@@ -355,60 +355,82 @@ static int dsa_user_get_iflink(const struct net_device *dev) ...@@ -355,60 +355,82 @@ static int dsa_user_get_iflink(const struct net_device *dev)
return READ_ONCE(dsa_user_to_conduit(dev)->ifindex); return READ_ONCE(dsa_user_to_conduit(dev)->ifindex);
} }
static int dsa_user_open(struct net_device *dev) static int dsa_user_host_uc_install(struct net_device *dev, const u8 *addr)
{ {
struct net_device *conduit = dsa_user_to_conduit(dev); struct net_device *conduit = dsa_user_to_conduit(dev);
struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_port *dp = dsa_user_to_port(dev);
struct dsa_switch *ds = dp->ds; struct dsa_switch *ds = dp->ds;
int err; int err;
err = dev_open(conduit, NULL);
if (err < 0) {
netdev_err(dev, "failed to open conduit %s\n", conduit->name);
goto out;
}
if (dsa_switch_supports_uc_filtering(ds)) { if (dsa_switch_supports_uc_filtering(ds)) {
err = dsa_port_standalone_host_fdb_add(dp, dev->dev_addr, 0); err = dsa_port_standalone_host_fdb_add(dp, addr, 0);
if (err) if (err)
goto out; goto out;
} }
if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) { if (!ether_addr_equal(addr, conduit->dev_addr)) {
err = dev_uc_add(conduit, dev->dev_addr); err = dev_uc_add(conduit, addr);
if (err < 0) if (err < 0)
goto del_host_addr; goto del_host_addr;
} }
err = dsa_port_enable_rt(dp, dev->phydev);
if (err)
goto del_unicast;
return 0; return 0;
del_unicast:
if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr))
dev_uc_del(conduit, dev->dev_addr);
del_host_addr: del_host_addr:
if (dsa_switch_supports_uc_filtering(ds)) if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); dsa_port_standalone_host_fdb_del(dp, addr, 0);
out: out:
return err; return err;
} }
static int dsa_user_close(struct net_device *dev) static void dsa_user_host_uc_uninstall(struct net_device *dev)
{ {
struct net_device *conduit = dsa_user_to_conduit(dev); struct net_device *conduit = dsa_user_to_conduit(dev);
struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_port *dp = dsa_user_to_port(dev);
struct dsa_switch *ds = dp->ds; struct dsa_switch *ds = dp->ds;
dsa_port_disable_rt(dp);
if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr))
dev_uc_del(conduit, dev->dev_addr); dev_uc_del(conduit, dev->dev_addr);
if (dsa_switch_supports_uc_filtering(ds)) if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
}
static int dsa_user_open(struct net_device *dev)
{
struct net_device *conduit = dsa_user_to_conduit(dev);
struct dsa_port *dp = dsa_user_to_port(dev);
int err;
err = dev_open(conduit, NULL);
if (err < 0) {
netdev_err(dev, "failed to open conduit %s\n", conduit->name);
goto out;
}
err = dsa_user_host_uc_install(dev, dev->dev_addr);
if (err)
goto out;
err = dsa_port_enable_rt(dp, dev->phydev);
if (err)
goto out_del_host_uc;
return 0;
out_del_host_uc:
dsa_user_host_uc_uninstall(dev);
out:
return err;
}
static int dsa_user_close(struct net_device *dev)
{
struct dsa_port *dp = dsa_user_to_port(dev);
dsa_port_disable_rt(dp);
dsa_user_host_uc_uninstall(dev);
return 0; return 0;
} }
...@@ -448,7 +470,6 @@ static void dsa_user_set_rx_mode(struct net_device *dev) ...@@ -448,7 +470,6 @@ static void dsa_user_set_rx_mode(struct net_device *dev)
static int dsa_user_set_mac_address(struct net_device *dev, void *a) static int dsa_user_set_mac_address(struct net_device *dev, void *a)
{ {
struct net_device *conduit = dsa_user_to_conduit(dev);
struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_port *dp = dsa_user_to_port(dev);
struct dsa_switch *ds = dp->ds; struct dsa_switch *ds = dp->ds;
struct sockaddr *addr = a; struct sockaddr *addr = a;
...@@ -470,34 +491,16 @@ static int dsa_user_set_mac_address(struct net_device *dev, void *a) ...@@ -470,34 +491,16 @@ static int dsa_user_set_mac_address(struct net_device *dev, void *a)
if (!(dev->flags & IFF_UP)) if (!(dev->flags & IFF_UP))
goto out_change_dev_addr; goto out_change_dev_addr;
if (dsa_switch_supports_uc_filtering(ds)) { err = dsa_user_host_uc_install(dev, addr->sa_data);
err = dsa_port_standalone_host_fdb_add(dp, addr->sa_data, 0);
if (err) if (err)
return err; return err;
}
if (!ether_addr_equal(addr->sa_data, conduit->dev_addr)) {
err = dev_uc_add(conduit, addr->sa_data);
if (err < 0)
goto del_unicast;
}
if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) dsa_user_host_uc_uninstall(dev);
dev_uc_del(conduit, dev->dev_addr);
if (dsa_switch_supports_uc_filtering(ds))
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
out_change_dev_addr: out_change_dev_addr:
eth_hw_addr_set(dev, addr->sa_data); eth_hw_addr_set(dev, addr->sa_data);
return 0; 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_user_dump_ctx { struct dsa_user_dump_ctx {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment