net: dsa: setup routing table

The *_complete() functions take too much arguments to do only one thing:
they try to fetch the dsa_port structures corresponding to device nodes
under the "link" list property of DSA ports, and use them to setup the
routing table of switches.

This patch simplifies them by providing instead simpler
dsa_{port,switch,tree}_setup_routing_table functions which return a
boolean value, true if the tree is complete.

dsa_tree_setup_routing_table is called inside dsa_tree_setup which
simplifies the switch registering function as well.

A switch's routing table is now initialized before its setup.

This also makes dsa_port_is_valid obsolete, remove it.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Vivien Didelot 2017-11-06 16:11:51 -05:00 committed by David S. Miller
parent c528666555
commit 34c09a8916
1 changed files with 37 additions and 71 deletions

View File

@ -94,14 +94,6 @@ static void dsa_tree_put(struct dsa_switch_tree *dst)
kref_put(&dst->refcount, dsa_tree_release);
}
/* For platform data configurations, we need to have a valid name argument to
* differentiate a disabled port from an enabled one
*/
static bool dsa_port_is_valid(struct dsa_port *port)
{
return port->type != DSA_PORT_TYPE_UNUSED;
}
static bool dsa_port_is_dsa(struct dsa_port *port)
{
return port->type == DSA_PORT_TYPE_DSA;
@ -140,14 +132,12 @@ static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
return NULL;
}
static int dsa_port_complete(struct dsa_switch_tree *dst,
struct dsa_switch *src_ds,
struct dsa_port *port,
u32 src_port)
static bool dsa_port_setup_routing_table(struct dsa_port *dp)
{
struct device_node *dn = port->dn;
struct dsa_switch *ds = dp->ds;
struct dsa_switch_tree *dst = ds->dst;
struct device_node *dn = dp->dn;
struct of_phandle_iterator it;
struct dsa_switch *dst_ds;
struct dsa_port *link_dp;
int err;
@ -155,66 +145,54 @@ static int dsa_port_complete(struct dsa_switch_tree *dst,
link_dp = dsa_tree_find_port_by_node(dst, it.node);
if (!link_dp) {
of_node_put(it.node);
return 1;
return false;
}
dst_ds = link_dp->ds;
src_ds->rtable[dst_ds->index] = src_port;
ds->rtable[link_dp->ds->index] = dp->index;
}
return 0;
return true;
}
/* A switch is complete if all the DSA ports phandles point to ports
* known in the tree. A return value of 1 means the tree is not
* complete. This is not an error condition. A value of 0 is
* success.
*/
static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
static bool dsa_switch_setup_routing_table(struct dsa_switch *ds)
{
struct dsa_port *port;
u32 index;
int err;
bool complete = true;
struct dsa_port *dp;
int i;
for (index = 0; index < ds->num_ports; index++) {
port = &ds->ports[index];
if (!dsa_port_is_valid(port))
continue;
for (i = 0; i < DSA_MAX_SWITCHES; i++)
ds->rtable[i] = DSA_RTABLE_NONE;
if (!dsa_port_is_dsa(port))
continue;
for (i = 0; i < ds->num_ports; i++) {
dp = &ds->ports[i];
err = dsa_port_complete(dst, ds, port, index);
if (err != 0)
return err;
if (dsa_port_is_dsa(dp)) {
complete = dsa_port_setup_routing_table(dp);
if (!complete)
break;
}
}
return 0;
return complete;
}
/* A tree is complete if all the DSA ports phandles point to ports
* known in the tree. A return value of 1 means the tree is not
* complete. This is not an error condition. A value of 0 is
* success.
*/
static int dsa_dst_complete(struct dsa_switch_tree *dst)
static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst)
{
struct dsa_switch *ds;
u32 index;
int err;
bool complete = true;
int device;
for (index = 0; index < DSA_MAX_SWITCHES; index++) {
ds = dst->ds[index];
for (device = 0; device < DSA_MAX_SWITCHES; device++) {
ds = dst->ds[device];
if (!ds)
continue;
err = dsa_ds_complete(dst, ds);
if (err != 0)
return err;
complete = dsa_switch_setup_routing_table(ds);
if (!complete)
break;
}
return 0;
return complete;
}
static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
@ -460,6 +438,7 @@ static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
static int dsa_tree_setup(struct dsa_switch_tree *dst)
{
bool complete;
int err;
if (dst->setup) {
@ -468,6 +447,10 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
return -EEXIST;
}
complete = dsa_tree_setup_routing_table(dst);
if (!complete)
return 0;
err = dsa_tree_setup_default_cpu(dst);
if (err)
return err;
@ -727,7 +710,7 @@ static int _dsa_register_switch(struct dsa_switch *ds)
struct device_node *np = ds->dev->of_node;
struct dsa_switch_tree *dst;
unsigned int index;
int i, err;
int err;
if (np)
err = dsa_switch_parse_of(ds, np);
@ -742,33 +725,16 @@ static int _dsa_register_switch(struct dsa_switch *ds)
index = ds->index;
dst = ds->dst;
/* Initialize the routing table */
for (i = 0; i < DSA_MAX_SWITCHES; ++i)
ds->rtable[i] = DSA_RTABLE_NONE;
err = dsa_tree_add_switch(dst, ds);
if (err)
return err;
err = dsa_dst_complete(dst);
if (err < 0)
goto out_del_dst;
/* Not all switches registered yet */
if (err == 1)
return 0;
err = dsa_tree_setup(dst);
if (err) {
dsa_tree_teardown(dst);
goto out_del_dst;
dsa_tree_remove_switch(dst, index);
}
return 0;
out_del_dst:
dsa_tree_remove_switch(dst, index);
return err;
}