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: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
ae3bbc04d4
commit
d82acd85cc
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue