Commit d82acd85 authored by Jiri Pirko's avatar Jiri Pirko Committed by Jakub Kicinski

net: dsa: move port_setup/teardown to be called outside devlink port registered area

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: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ae3bbc04
...@@ -472,12 +472,6 @@ static int dsa_port_setup(struct dsa_port *dp) ...@@ -472,12 +472,6 @@ static int dsa_port_setup(struct dsa_port *dp)
if (dp->setup) if (dp->setup)
return 0; return 0;
if (ds->ops->port_setup) {
err = ds->ops->port_setup(ds, dp->index);
if (err)
return err;
}
switch (dp->type) { switch (dp->type) {
case DSA_PORT_TYPE_UNUSED: case DSA_PORT_TYPE_UNUSED:
dsa_port_disable(dp); dsa_port_disable(dp);
...@@ -532,11 +526,8 @@ static int dsa_port_setup(struct dsa_port *dp) ...@@ -532,11 +526,8 @@ static int dsa_port_setup(struct dsa_port *dp)
dsa_port_disable(dp); dsa_port_disable(dp);
if (err && dsa_port_link_registered) if (err && dsa_port_link_registered)
dsa_shared_port_link_unregister_of(dp); dsa_shared_port_link_unregister_of(dp);
if (err) { if (err)
if (ds->ops->port_teardown)
ds->ops->port_teardown(ds, dp->index);
return err; return err;
}
dp->setup = true; dp->setup = true;
...@@ -549,17 +540,26 @@ static int dsa_port_devlink_setup(struct dsa_port *dp) ...@@ -549,17 +540,26 @@ static int dsa_port_devlink_setup(struct dsa_port *dp)
struct dsa_switch_tree *dst = dp->ds->dst; struct dsa_switch_tree *dst = dp->ds->dst;
struct devlink_port_attrs attrs = {}; struct devlink_port_attrs attrs = {};
struct devlink *dl = dp->ds->devlink; struct devlink *dl = dp->ds->devlink;
struct dsa_switch *ds = dp->ds;
const unsigned char *id; const unsigned char *id;
unsigned char len; unsigned char len;
int err; 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; id = (const unsigned char *)&dst->index;
len = sizeof(dst->index); len = sizeof(dst->index);
attrs.phys.port_number = dp->index; attrs.phys.port_number = dp->index;
memcpy(attrs.switch_id.id, id, len); memcpy(attrs.switch_id.id, id, len);
attrs.switch_id.id_len = len; attrs.switch_id.id_len = len;
memset(dlp, 0, sizeof(*dlp));
switch (dp->type) { switch (dp->type) {
case DSA_PORT_TYPE_UNUSED: case DSA_PORT_TYPE_UNUSED:
...@@ -578,24 +578,23 @@ static int dsa_port_devlink_setup(struct dsa_port *dp) ...@@ -578,24 +578,23 @@ static int dsa_port_devlink_setup(struct dsa_port *dp)
devlink_port_attrs_set(dlp, &attrs); devlink_port_attrs_set(dlp, &attrs);
err = devlink_port_register(dl, dlp, dp->index); 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) return 0;
dp->devlink_port_setup = true;
return err;
} }
static void dsa_port_teardown(struct dsa_port *dp) static void dsa_port_teardown(struct dsa_port *dp)
{ {
struct devlink_port *dlp = &dp->devlink_port; struct devlink_port *dlp = &dp->devlink_port;
struct dsa_switch *ds = dp->ds;
if (!dp->setup) if (!dp->setup)
return; return;
if (ds->ops->port_teardown)
ds->ops->port_teardown(ds, dp->index);
devlink_port_type_clear(dlp); devlink_port_type_clear(dlp);
switch (dp->type) { switch (dp->type) {
...@@ -625,40 +624,25 @@ static void dsa_port_teardown(struct dsa_port *dp) ...@@ -625,40 +624,25 @@ static void dsa_port_teardown(struct dsa_port *dp)
static void dsa_port_devlink_teardown(struct dsa_port *dp) static void dsa_port_devlink_teardown(struct dsa_port *dp)
{ {
struct devlink_port *dlp = &dp->devlink_port; 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); 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->devlink_port_setup = false;
} }
/* Destroy the current devlink port, and create a new one which has the UNUSED /* 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 * flavour.
* 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.
*/ */
static int dsa_port_reinit_as_unused(struct dsa_port *dp) static int dsa_port_reinit_as_unused(struct dsa_port *dp)
{ {
struct dsa_switch *ds = dp->ds;
int err;
dsa_port_devlink_teardown(dp); dsa_port_devlink_teardown(dp);
dp->type = DSA_PORT_TYPE_UNUSED; dp->type = DSA_PORT_TYPE_UNUSED;
err = dsa_port_devlink_setup(dp); return 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;
} }
static int dsa_devlink_info_get(struct devlink *dl, static int dsa_devlink_info_get(struct devlink *dl,
......
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