Commit 34c09a89 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

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: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c5286665
...@@ -94,14 +94,6 @@ static void dsa_tree_put(struct dsa_switch_tree *dst) ...@@ -94,14 +94,6 @@ static void dsa_tree_put(struct dsa_switch_tree *dst)
kref_put(&dst->refcount, dsa_tree_release); 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) static bool dsa_port_is_dsa(struct dsa_port *port)
{ {
return port->type == DSA_PORT_TYPE_DSA; 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, ...@@ -140,14 +132,12 @@ static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
return NULL; return NULL;
} }
static int dsa_port_complete(struct dsa_switch_tree *dst, static bool dsa_port_setup_routing_table(struct dsa_port *dp)
struct dsa_switch *src_ds,
struct dsa_port *port,
u32 src_port)
{ {
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 of_phandle_iterator it;
struct dsa_switch *dst_ds;
struct dsa_port *link_dp; struct dsa_port *link_dp;
int err; int err;
...@@ -155,66 +145,54 @@ static int dsa_port_complete(struct dsa_switch_tree *dst, ...@@ -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); link_dp = dsa_tree_find_port_by_node(dst, it.node);
if (!link_dp) { if (!link_dp) {
of_node_put(it.node); of_node_put(it.node);
return 1; return false;
} }
dst_ds = link_dp->ds; ds->rtable[link_dp->ds->index] = dp->index;
src_ds->rtable[dst_ds->index] = src_port;
} }
return 0; return true;
} }
/* A switch is complete if all the DSA ports phandles point to ports static bool dsa_switch_setup_routing_table(struct dsa_switch *ds)
* 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)
{ {
struct dsa_port *port; bool complete = true;
u32 index; struct dsa_port *dp;
int err; int i;
for (index = 0; index < ds->num_ports; index++) { for (i = 0; i < DSA_MAX_SWITCHES; i++)
port = &ds->ports[index]; ds->rtable[i] = DSA_RTABLE_NONE;
if (!dsa_port_is_valid(port))
continue;
if (!dsa_port_is_dsa(port)) for (i = 0; i < ds->num_ports; i++) {
continue; dp = &ds->ports[i];
err = dsa_port_complete(dst, ds, port, index); if (dsa_port_is_dsa(dp)) {
if (err != 0) complete = dsa_port_setup_routing_table(dp);
return err; if (!complete)
break;
}
} }
return 0; return complete;
} }
/* A tree is complete if all the DSA ports phandles point to ports static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst)
* 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)
{ {
struct dsa_switch *ds; struct dsa_switch *ds;
u32 index; bool complete = true;
int err; int device;
for (index = 0; index < DSA_MAX_SWITCHES; index++) { for (device = 0; device < DSA_MAX_SWITCHES; device++) {
ds = dst->ds[index]; ds = dst->ds[device];
if (!ds) if (!ds)
continue; continue;
err = dsa_ds_complete(dst, ds); complete = dsa_switch_setup_routing_table(ds);
if (err != 0) if (!complete)
return err; break;
} }
return 0; return complete;
} }
static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst) 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) ...@@ -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) static int dsa_tree_setup(struct dsa_switch_tree *dst)
{ {
bool complete;
int err; int err;
if (dst->setup) { if (dst->setup) {
...@@ -468,6 +447,10 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst) ...@@ -468,6 +447,10 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
return -EEXIST; return -EEXIST;
} }
complete = dsa_tree_setup_routing_table(dst);
if (!complete)
return 0;
err = dsa_tree_setup_default_cpu(dst); err = dsa_tree_setup_default_cpu(dst);
if (err) if (err)
return err; return err;
...@@ -727,7 +710,7 @@ static int _dsa_register_switch(struct dsa_switch *ds) ...@@ -727,7 +710,7 @@ static int _dsa_register_switch(struct dsa_switch *ds)
struct device_node *np = ds->dev->of_node; struct device_node *np = ds->dev->of_node;
struct dsa_switch_tree *dst; struct dsa_switch_tree *dst;
unsigned int index; unsigned int index;
int i, err; int err;
if (np) if (np)
err = dsa_switch_parse_of(ds, np); err = dsa_switch_parse_of(ds, np);
...@@ -742,33 +725,16 @@ static int _dsa_register_switch(struct dsa_switch *ds) ...@@ -742,33 +725,16 @@ static int _dsa_register_switch(struct dsa_switch *ds)
index = ds->index; index = ds->index;
dst = ds->dst; 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); err = dsa_tree_add_switch(dst, ds);
if (err) if (err)
return 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); err = dsa_tree_setup(dst);
if (err) { if (err) {
dsa_tree_teardown(dst); 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; return err;
} }
......
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