net: dsa: move port_setup/teardown to be called outside devlink port registered area
authorJiri Pirko <jiri@nvidia.com>
Thu, 29 Sep 2022 07:28:59 +0000 (09:28 +0200)
committerJakub Kicinski <kuba@kernel.org>
Sat, 1 Oct 2022 01:17:16 +0000 (18:17 -0700)
Move port_setup() op to be called before devlink_port_register() and
port_teardown() after devlink_port_unregister().

Note it makes sense to move this alongside the rest of the devlink port
code, the reinit() function also gets much nicer, as clearly the fact that
port_setup()->devlink_port_region_create() was called in dsa_port_setup
did not fit the flow.

Signed-off-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/dsa/dsa2.c

index 7024e2120de1baf1c189d6fd39cfa631500deb20..6f555b1bb483c2818590622454617fd46d8cdde6 100644 (file)
@@ -472,12 +472,6 @@ static int dsa_port_setup(struct dsa_port *dp)
        if (dp->setup)
                return 0;
 
-       if (ds->ops->port_setup) {
-               err = ds->ops->port_setup(ds, dp->index);
-               if (err)
-                       return err;
-       }
-
        switch (dp->type) {
        case DSA_PORT_TYPE_UNUSED:
                dsa_port_disable(dp);
@@ -532,11 +526,8 @@ 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) {
-               if (ds->ops->port_teardown)
-                       ds->ops->port_teardown(ds, dp->index);
+       if (err)
                return err;
-       }
 
        dp->setup = true;
 
@@ -549,17 +540,26 @@ static int dsa_port_devlink_setup(struct dsa_port *dp)
        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;
-       memset(dlp, 0, sizeof(*dlp));
 
        switch (dp->type) {
        case DSA_PORT_TYPE_UNUSED:
@@ -578,24 +578,23 @@ static int dsa_port_devlink_setup(struct dsa_port *dp)
 
        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;
 
-       if (!err)
-               dp->devlink_port_setup = true;
-
-       return err;
+       return 0;
 }
 
 static void dsa_port_teardown(struct dsa_port *dp)
 {
        struct devlink_port *dlp = &dp->devlink_port;
-       struct dsa_switch *ds = dp->ds;
 
        if (!dp->setup)
                return;
 
-       if (ds->ops->port_teardown)
-               ds->ops->port_teardown(ds, dp->index);
-
        devlink_port_type_clear(dlp);
 
        switch (dp->type) {
@@ -625,40 +624,25 @@ static void dsa_port_teardown(struct dsa_port *dp)
 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)
+       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;
 }
 
 /* Destroy the current devlink port, and create a new one which has the UNUSED
- * flavour. At this point, any call to ds->ops->port_setup has been already
- * balanced out by a call to ds->ops->port_teardown, so we know that any
- * devlink port regions the driver had are now unregistered. We then call its
- * ds->ops->port_setup again, in order for the driver to re-create them on the
- * new devlink port.
+ * flavour.
  */
 static int dsa_port_reinit_as_unused(struct dsa_port *dp)
 {
-       struct dsa_switch *ds = dp->ds;
-       int err;
-
        dsa_port_devlink_teardown(dp);
        dp->type = DSA_PORT_TYPE_UNUSED;
-       err = dsa_port_devlink_setup(dp);
-       if (err)
-               return err;
-
-       if (ds->ops->port_setup) {
-               /* On error, leave the devlink port registered,
-                * dsa_switch_teardown will clean it up later.
-                */
-               err = ds->ops->port_setup(ds, dp->index);
-               if (err)
-                       return err;
-       }
-
-       return 0;
+       return dsa_port_devlink_setup(dp);
 }
 
 static int dsa_devlink_info_get(struct devlink *dl,