Commit 1e3f407f authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: dsa: first set up shared ports, then non-shared ports

After commit a57d8c21 ("net: dsa: flush switchdev workqueue before
tearing down CPU/DSA ports"), the port setup and teardown procedure
became asymmetric.

The fact of the matter is that user ports need the shared ports to be up
before they can be used for CPU-initiated termination. And since we
register net devices for the user ports, those won't be functional until
we also call the setup for the shared (CPU, DSA) ports. But we may do
that later, depending on the port numbering scheme of the hardware we
are dealing with.

It just makes sense that all shared ports are brought up before any user
port is. I can't pinpoint any issue due to the current behavior, but
let's change it nonetheless, for consistency's sake.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c146f9bc
...@@ -1003,23 +1003,28 @@ static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst) ...@@ -1003,23 +1003,28 @@ static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst)
dsa_switch_teardown(dp->ds); dsa_switch_teardown(dp->ds);
} }
static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) /* Bring shared ports up first, then non-shared ports */
static int dsa_tree_setup_ports(struct dsa_switch_tree *dst)
{ {
struct dsa_port *dp; struct dsa_port *dp;
int err; int err = 0;
list_for_each_entry(dp, &dst->ports, list) { list_for_each_entry(dp, &dst->ports, list) {
err = dsa_switch_setup(dp->ds); if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp)) {
if (err) err = dsa_port_setup(dp);
goto teardown; if (err)
goto teardown;
}
} }
list_for_each_entry(dp, &dst->ports, list) { list_for_each_entry(dp, &dst->ports, list) {
err = dsa_port_setup(dp); if (dsa_port_is_user(dp) || dsa_port_is_unused(dp)) {
if (err) { err = dsa_port_setup(dp);
err = dsa_port_reinit_as_unused(dp); if (err) {
if (err) err = dsa_port_reinit_as_unused(dp);
goto teardown; if (err)
goto teardown;
}
} }
} }
...@@ -1028,7 +1033,21 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) ...@@ -1028,7 +1033,21 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
teardown: teardown:
dsa_tree_teardown_ports(dst); dsa_tree_teardown_ports(dst);
dsa_tree_teardown_switches(dst); return err;
}
static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
{
struct dsa_port *dp;
int err = 0;
list_for_each_entry(dp, &dst->ports, list) {
err = dsa_switch_setup(dp->ds);
if (err) {
dsa_tree_teardown_switches(dst);
break;
}
}
return err; return err;
} }
...@@ -1115,10 +1134,14 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst) ...@@ -1115,10 +1134,14 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
if (err) if (err)
goto teardown_cpu_ports; goto teardown_cpu_ports;
err = dsa_tree_setup_master(dst); err = dsa_tree_setup_ports(dst);
if (err) if (err)
goto teardown_switches; goto teardown_switches;
err = dsa_tree_setup_master(dst);
if (err)
goto teardown_ports;
err = dsa_tree_setup_lags(dst); err = dsa_tree_setup_lags(dst);
if (err) if (err)
goto teardown_master; goto teardown_master;
...@@ -1131,8 +1154,9 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst) ...@@ -1131,8 +1154,9 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
teardown_master: teardown_master:
dsa_tree_teardown_master(dst); dsa_tree_teardown_master(dst);
teardown_switches: teardown_ports:
dsa_tree_teardown_ports(dst); dsa_tree_teardown_ports(dst);
teardown_switches:
dsa_tree_teardown_switches(dst); dsa_tree_teardown_switches(dst);
teardown_cpu_ports: teardown_cpu_ports:
dsa_tree_teardown_cpu_ports(dst); dsa_tree_teardown_cpu_ports(dst);
......
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