summaryrefslogtreecommitdiffstats
path: root/net/dsa/dsa2.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/dsa/dsa2.c')
-rw-r--r--net/dsa/dsa2.c176
1 files changed, 82 insertions, 94 deletions
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 6f555b1bb483..747c0364fb0f 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -461,6 +461,74 @@ static void dsa_tree_teardown_cpu_ports(struct dsa_switch_tree *dst)
dp->cpu_dp = NULL;
}
+static int dsa_port_devlink_setup(struct dsa_port *dp)
+{
+ struct devlink_port *dlp = &dp->devlink_port;
+ struct dsa_switch_tree *dst = dp->ds->dst;
+ struct devlink_port_attrs attrs = {};
+ struct devlink *dl = dp->ds->devlink;
+ struct dsa_switch *ds = dp->ds;
+ const unsigned char *id;
+ unsigned char len;
+ int err;
+
+ memset(dlp, 0, sizeof(*dlp));
+ devlink_port_init(dl, dlp);
+
+ if (ds->ops->port_setup) {
+ err = ds->ops->port_setup(ds, dp->index);
+ if (err)
+ return err;
+ }
+
+ id = (const unsigned char *)&dst->index;
+ len = sizeof(dst->index);
+
+ attrs.phys.port_number = dp->index;
+ memcpy(attrs.switch_id.id, id, len);
+ attrs.switch_id.id_len = len;
+
+ switch (dp->type) {
+ case DSA_PORT_TYPE_UNUSED:
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
+ break;
+ case DSA_PORT_TYPE_CPU:
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
+ break;
+ case DSA_PORT_TYPE_DSA:
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
+ break;
+ case DSA_PORT_TYPE_USER:
+ attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
+ break;
+ }
+
+ devlink_port_attrs_set(dlp, &attrs);
+ err = devlink_port_register(dl, dlp, dp->index);
+ if (err) {
+ if (ds->ops->port_teardown)
+ ds->ops->port_teardown(ds, dp->index);
+ return err;
+ }
+ dp->devlink_port_setup = true;
+
+ return 0;
+}
+
+static void dsa_port_devlink_teardown(struct dsa_port *dp)
+{
+ struct devlink_port *dlp = &dp->devlink_port;
+ struct dsa_switch *ds = dp->ds;
+
+ if (dp->devlink_port_setup) {
+ devlink_port_unregister(dlp);
+ if (ds->ops->port_teardown)
+ ds->ops->port_teardown(ds, dp->index);
+ devlink_port_fini(dlp);
+ }
+ dp->devlink_port_setup = false;
+}
+
static int dsa_port_setup(struct dsa_port *dp)
{
struct devlink_port *dlp = &dp->devlink_port;
@@ -472,6 +540,10 @@ static int dsa_port_setup(struct dsa_port *dp)
if (dp->setup)
return 0;
+ err = dsa_port_devlink_setup(dp);
+ if (err)
+ return err;
+
switch (dp->type) {
case DSA_PORT_TYPE_UNUSED:
dsa_port_disable(dp);
@@ -526,64 +598,12 @@ static int dsa_port_setup(struct dsa_port *dp)
dsa_port_disable(dp);
if (err && dsa_port_link_registered)
dsa_shared_port_link_unregister_of(dp);
- if (err)
- return err;
-
- dp->setup = true;
-
- return 0;
-}
-
-static int dsa_port_devlink_setup(struct dsa_port *dp)
-{
- struct devlink_port *dlp = &dp->devlink_port;
- struct dsa_switch_tree *dst = dp->ds->dst;
- struct devlink_port_attrs attrs = {};
- struct devlink *dl = dp->ds->devlink;
- struct dsa_switch *ds = dp->ds;
- const unsigned char *id;
- unsigned char len;
- int err;
-
- memset(dlp, 0, sizeof(*dlp));
- devlink_port_init(dl, dlp);
-
- if (ds->ops->port_setup) {
- err = ds->ops->port_setup(ds, dp->index);
- if (err)
- return err;
- }
-
- id = (const unsigned char *)&dst->index;
- len = sizeof(dst->index);
-
- attrs.phys.port_number = dp->index;
- memcpy(attrs.switch_id.id, id, len);
- attrs.switch_id.id_len = len;
-
- switch (dp->type) {
- case DSA_PORT_TYPE_UNUSED:
- attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
- break;
- case DSA_PORT_TYPE_CPU:
- attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
- break;
- case DSA_PORT_TYPE_DSA:
- attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
- break;
- case DSA_PORT_TYPE_USER:
- attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
- break;
- }
-
- devlink_port_attrs_set(dlp, &attrs);
- err = devlink_port_register(dl, dlp, dp->index);
if (err) {
- if (ds->ops->port_teardown)
- ds->ops->port_teardown(ds, dp->index);
+ dsa_port_devlink_teardown(dp);
return err;
}
- dp->devlink_port_setup = true;
+
+ dp->setup = true;
return 0;
}
@@ -618,31 +638,15 @@ static void dsa_port_teardown(struct dsa_port *dp)
break;
}
- dp->setup = false;
-}
-
-static void dsa_port_devlink_teardown(struct dsa_port *dp)
-{
- struct devlink_port *dlp = &dp->devlink_port;
- struct dsa_switch *ds = dp->ds;
+ dsa_port_devlink_teardown(dp);
- if (dp->devlink_port_setup) {
- devlink_port_unregister(dlp);
- if (ds->ops->port_teardown)
- ds->ops->port_teardown(ds, dp->index);
- devlink_port_fini(dlp);
- }
- dp->devlink_port_setup = false;
+ dp->setup = false;
}
-/* Destroy the current devlink port, and create a new one which has the UNUSED
- * flavour.
- */
-static int dsa_port_reinit_as_unused(struct dsa_port *dp)
+static int dsa_port_setup_as_unused(struct dsa_port *dp)
{
- dsa_port_devlink_teardown(dp);
dp->type = DSA_PORT_TYPE_UNUSED;
- return dsa_port_devlink_setup(dp);
+ return dsa_port_setup(dp);
}
static int dsa_devlink_info_get(struct devlink *dl,
@@ -866,7 +870,6 @@ static int dsa_switch_setup(struct dsa_switch *ds)
{
struct dsa_devlink_priv *dl_priv;
struct device_node *dn;
- struct dsa_port *dp;
int err;
if (ds->setup)
@@ -889,18 +892,9 @@ static int dsa_switch_setup(struct dsa_switch *ds)
dl_priv = devlink_priv(ds->devlink);
dl_priv->ds = ds;
- /* Setup devlink port instances now, so that the switch
- * setup() can register regions etc, against the ports
- */
- dsa_switch_for_each_port(dp, ds) {
- err = dsa_port_devlink_setup(dp);
- if (err)
- goto unregister_devlink_ports;
- }
-
err = dsa_switch_register_notifier(ds);
if (err)
- goto unregister_devlink_ports;
+ goto devlink_free;
ds->configure_vlan_while_not_filtering = true;
@@ -941,9 +935,7 @@ teardown:
ds->ops->teardown(ds);
unregister_notifier:
dsa_switch_unregister_notifier(ds);
-unregister_devlink_ports:
- dsa_switch_for_each_port(dp, ds)
- dsa_port_devlink_teardown(dp);
+devlink_free:
devlink_free(ds->devlink);
ds->devlink = NULL;
return err;
@@ -951,8 +943,6 @@ unregister_devlink_ports:
static void dsa_switch_teardown(struct dsa_switch *ds)
{
- struct dsa_port *dp;
-
if (!ds->setup)
return;
@@ -971,8 +961,6 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
dsa_switch_unregister_notifier(ds);
if (ds->devlink) {
- dsa_switch_for_each_port(dp, ds)
- dsa_port_devlink_teardown(dp);
devlink_free(ds->devlink);
ds->devlink = NULL;
}
@@ -1025,7 +1013,7 @@ static int dsa_tree_setup_ports(struct dsa_switch_tree *dst)
if (dsa_port_is_user(dp) || dsa_port_is_unused(dp)) {
err = dsa_port_setup(dp);
if (err) {
- err = dsa_port_reinit_as_unused(dp);
+ err = dsa_port_setup_as_unused(dp);
if (err)
goto teardown;
}