Skip to content

Commit

Permalink
Merge branch 'dsa-cross-chip'
Browse files Browse the repository at this point in the history
Vladimir Oltean says:

====================
Improvement for DSA cross-chip setups

This series improves some aspects in multi-switch DSA tree topologies:
- better device tree validation
- better handling of MTU changes
- better handling of multicast addresses
- removal of some unused code
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jun 21, 2021
2 parents 41505d3 + f9bcdc3 commit 6ff5f81
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 103 deletions.
15 changes: 15 additions & 0 deletions include/net/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,21 @@ static inline struct dsa_port *dsa_to_port(struct dsa_switch *ds, int p)
return NULL;
}

static inline bool dsa_port_is_dsa(struct dsa_port *port)
{
return port->type == DSA_PORT_TYPE_DSA;
}

static inline bool dsa_port_is_cpu(struct dsa_port *port)
{
return port->type == DSA_PORT_TYPE_CPU;
}

static inline bool dsa_port_is_user(struct dsa_port *dp)
{
return dp->type == DSA_PORT_TYPE_USER;
}

static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
{
return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
Expand Down
22 changes: 7 additions & 15 deletions net/dsa/dsa2.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,21 +219,6 @@ static void dsa_tree_put(struct dsa_switch_tree *dst)
kref_put(&dst->refcount, dsa_tree_release);
}

static bool dsa_port_is_dsa(struct dsa_port *port)
{
return port->type == DSA_PORT_TYPE_DSA;
}

static bool dsa_port_is_cpu(struct dsa_port *port)
{
return port->type == DSA_PORT_TYPE_CPU;
}

static bool dsa_port_is_user(struct dsa_port *dp)
{
return dp->type == DSA_PORT_TYPE_USER;
}

static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
struct device_node *dn)
{
Expand Down Expand Up @@ -1259,6 +1244,13 @@ static int dsa_switch_parse_member_of(struct dsa_switch *ds,
if (!ds->dst)
return -ENOMEM;

if (dsa_switch_find(ds->dst->index, ds->index)) {
dev_err(ds->dev,
"A DSA switch with index %d already exists in tree %d\n",
ds->index, ds->dst->index);
return -EEXIST;
}

return 0;
}

Expand Down
4 changes: 2 additions & 2 deletions net/dsa/dsa_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct dsa_notifier_vlan_info {

/* DSA_NOTIFIER_MTU */
struct dsa_notifier_mtu_info {
bool propagate_upstream;
bool targeted_match;
int sw_index;
int port;
int mtu;
Expand Down Expand Up @@ -200,7 +200,7 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
bool dsa_port_skip_vlan_configuration(struct dsa_port *dp);
int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock);
int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu,
bool propagate_upstream);
bool targeted_match);
int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
u16 vid);
int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr,
Expand Down
4 changes: 2 additions & 2 deletions net/dsa/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,11 +567,11 @@ int dsa_port_mrouter(struct dsa_port *dp, bool mrouter,
}

int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu,
bool propagate_upstream)
bool targeted_match)
{
struct dsa_notifier_mtu_info info = {
.sw_index = dp->ds->index,
.propagate_upstream = propagate_upstream,
.targeted_match = targeted_match,
.port = dp->index,
.mtu = new_mtu,
};
Expand Down
22 changes: 12 additions & 10 deletions net/dsa/slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -1528,38 +1528,39 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
struct dsa_port *dp = dsa_slave_to_port(dev);
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->dp->ds;
struct dsa_port *dp_iter;
struct dsa_port *cpu_dp;
int port = p->dp->index;
int largest_mtu = 0;
int new_master_mtu;
int old_master_mtu;
int mtu_limit;
int cpu_mtu;
int err, i;
int err;

if (!ds->ops->port_change_mtu)
return -EOPNOTSUPP;

for (i = 0; i < ds->num_ports; i++) {
list_for_each_entry(dp_iter, &ds->dst->ports, list) {
int slave_mtu;

if (!dsa_is_user_port(ds, i))
if (!dsa_port_is_user(dp_iter))
continue;

/* During probe, this function will be called for each slave
* device, while not all of them have been allocated. That's
* ok, it doesn't change what the maximum is, so ignore it.
*/
if (!dsa_to_port(ds, i)->slave)
if (!dp_iter->slave)
continue;

/* Pretend that we already applied the setting, which we
* actually haven't (still haven't done all integrity checks)
*/
if (i == port)
if (dp_iter == dp)
slave_mtu = new_mtu;
else
slave_mtu = dsa_to_port(ds, i)->slave->mtu;
slave_mtu = dp_iter->slave->mtu;

if (largest_mtu < slave_mtu)
largest_mtu = slave_mtu;
Expand All @@ -1585,14 +1586,15 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
goto out_master_failed;

/* We only need to propagate the MTU of the CPU port to
* upstream switches.
* upstream switches, so create a non-targeted notifier which
* updates all switches.
*/
err = dsa_port_mtu_change(cpu_dp, cpu_mtu, true);
err = dsa_port_mtu_change(cpu_dp, cpu_mtu, false);
if (err)
goto out_cpu_failed;
}

err = dsa_port_mtu_change(dp, new_mtu, false);
err = dsa_port_mtu_change(dp, new_mtu, true);
if (err)
goto out_port_failed;

Expand All @@ -1606,7 +1608,7 @@ int dsa_slave_change_mtu(struct net_device *dev, int new_mtu)
if (new_master_mtu != old_master_mtu)
dsa_port_mtu_change(cpu_dp, old_master_mtu -
dsa_tag_protocol_overhead(cpu_dp->tag_ops),
true);
false);
out_cpu_failed:
if (new_master_mtu != old_master_mtu)
dev_set_mtu(master, old_master_mtu);
Expand Down
89 changes: 15 additions & 74 deletions net/dsa/switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,13 @@ static int dsa_switch_ageing_time(struct dsa_switch *ds,
static bool dsa_switch_mtu_match(struct dsa_switch *ds, int port,
struct dsa_notifier_mtu_info *info)
{
if (ds->index == info->sw_index)
return (port == info->port) || dsa_is_dsa_port(ds, port);
if (ds->index == info->sw_index && port == info->port)
return true;

if (!info->propagate_upstream)
/* Do not propagate to other switches in the tree if the notifier was
* targeted for a single switch.
*/
if (info->targeted_match)
return false;

if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port))
Expand Down Expand Up @@ -232,36 +235,15 @@ static int dsa_switch_lag_leave(struct dsa_switch *ds,
return 0;
}

static bool dsa_switch_mdb_match(struct dsa_switch *ds, int port,
struct dsa_notifier_mdb_info *info)
{
if (ds->index == info->sw_index && port == info->port)
return true;

if (dsa_is_dsa_port(ds, port))
return true;

return false;
}

static int dsa_switch_mdb_add(struct dsa_switch *ds,
struct dsa_notifier_mdb_info *info)
{
int err = 0;
int port;
int port = dsa_towards_port(ds, info->sw_index, info->port);

if (!ds->ops->port_mdb_add)
return -EOPNOTSUPP;

for (port = 0; port < ds->num_ports; port++) {
if (dsa_switch_mdb_match(ds, port, info)) {
err = ds->ops->port_mdb_add(ds, port, info->mdb);
if (err)
break;
}
}

return err;
return ds->ops->port_mdb_add(ds, port, info->mdb);
}

static int dsa_switch_mdb_del(struct dsa_switch *ds,
Expand Down Expand Up @@ -364,36 +346,16 @@ static int dsa_switch_change_tag_proto(struct dsa_switch *ds,
return 0;
}

static bool dsa_switch_mrp_match(struct dsa_switch *ds, int port,
struct dsa_notifier_mrp_info *info)
{
if (ds->index == info->sw_index && port == info->port)
return true;

if (dsa_is_dsa_port(ds, port))
return true;

return false;
}

static int dsa_switch_mrp_add(struct dsa_switch *ds,
struct dsa_notifier_mrp_info *info)
{
int err = 0;
int port;

if (!ds->ops->port_mrp_add)
return -EOPNOTSUPP;

for (port = 0; port < ds->num_ports; port++) {
if (dsa_switch_mrp_match(ds, port, info)) {
err = ds->ops->port_mrp_add(ds, port, info->mrp);
if (err)
break;
}
}
if (ds->index == info->sw_index)
return ds->ops->port_mrp_add(ds, info->port, info->mrp);

return err;
return 0;
}

static int dsa_switch_mrp_del(struct dsa_switch *ds,
Expand All @@ -408,39 +370,18 @@ static int dsa_switch_mrp_del(struct dsa_switch *ds,
return 0;
}

static bool
dsa_switch_mrp_ring_role_match(struct dsa_switch *ds, int port,
struct dsa_notifier_mrp_ring_role_info *info)
{
if (ds->index == info->sw_index && port == info->port)
return true;

if (dsa_is_dsa_port(ds, port))
return true;

return false;
}

static int
dsa_switch_mrp_add_ring_role(struct dsa_switch *ds,
struct dsa_notifier_mrp_ring_role_info *info)
{
int err = 0;
int port;

if (!ds->ops->port_mrp_add)
return -EOPNOTSUPP;

for (port = 0; port < ds->num_ports; port++) {
if (dsa_switch_mrp_ring_role_match(ds, port, info)) {
err = ds->ops->port_mrp_add_ring_role(ds, port,
info->mrp);
if (err)
break;
}
}
if (ds->index == info->sw_index)
return ds->ops->port_mrp_add_ring_role(ds, info->port,
info->mrp);

return err;
return 0;
}

static int
Expand Down

0 comments on commit 6ff5f81

Please sign in to comment.