Skip to content

Commit 3122433

Browse files
lunndavem330
authored andcommitted
net: dsa: Register devlink ports before calling DSA driver setup()
DSA drivers want to create regions on devlink ports as well as the devlink device instance, in order to export registers and other tables per port. To keep all this code together in the drivers, have the devlink ports registered early, so the setup() method can setup both device and port devlink regions. v3: Remove dp->setup Move common code out of switch statement. Fix wrong goto Signed-off-by: Andrew Lunn <[email protected]> Reviewed-by: Florian Fainelli <[email protected]> Reviewed-by: Vladimir Oltean <[email protected]> Tested-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f15ec13 commit 3122433

File tree

2 files changed

+73
-53
lines changed

2 files changed

+73
-53
lines changed

include/net/dsa.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ struct dsa_port {
215215
u8 stp_state;
216216
struct net_device *bridge_dev;
217217
struct devlink_port devlink_port;
218+
bool devlink_port_setup;
218219
struct phylink *pl;
219220
struct phylink_config pl_config;
220221

net/dsa/dsa2.c

Lines changed: 72 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -251,47 +251,19 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
251251

252252
static int dsa_port_setup(struct dsa_port *dp)
253253
{
254-
struct dsa_switch *ds = dp->ds;
255-
struct dsa_switch_tree *dst = ds->dst;
256-
const unsigned char *id = (const unsigned char *)&dst->index;
257-
const unsigned char len = sizeof(dst->index);
258254
struct devlink_port *dlp = &dp->devlink_port;
259255
bool dsa_port_link_registered = false;
260-
bool devlink_port_registered = false;
261-
struct devlink_port_attrs attrs = {};
262-
struct devlink *dl = ds->devlink;
263256
bool dsa_port_enabled = false;
264257
int err = 0;
265258

266-
attrs.phys.port_number = dp->index;
267-
memcpy(attrs.switch_id.id, id, len);
268-
attrs.switch_id.id_len = len;
269-
270259
if (dp->setup)
271260
return 0;
272261

273262
switch (dp->type) {
274263
case DSA_PORT_TYPE_UNUSED:
275-
memset(dlp, 0, sizeof(*dlp));
276-
attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
277-
devlink_port_attrs_set(dlp, &attrs);
278-
err = devlink_port_register(dl, dlp, dp->index);
279-
if (err)
280-
break;
281-
282-
devlink_port_registered = true;
283-
284264
dsa_port_disable(dp);
285265
break;
286266
case DSA_PORT_TYPE_CPU:
287-
memset(dlp, 0, sizeof(*dlp));
288-
attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
289-
devlink_port_attrs_set(dlp, &attrs);
290-
err = devlink_port_register(dl, dlp, dp->index);
291-
if (err)
292-
break;
293-
devlink_port_registered = true;
294-
295267
err = dsa_port_link_register_of(dp);
296268
if (err)
297269
break;
@@ -304,14 +276,6 @@ static int dsa_port_setup(struct dsa_port *dp)
304276

305277
break;
306278
case DSA_PORT_TYPE_DSA:
307-
memset(dlp, 0, sizeof(*dlp));
308-
attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
309-
devlink_port_attrs_set(dlp, &attrs);
310-
err = devlink_port_register(dl, dlp, dp->index);
311-
if (err)
312-
break;
313-
devlink_port_registered = true;
314-
315279
err = dsa_port_link_register_of(dp);
316280
if (err)
317281
break;
@@ -324,14 +288,6 @@ static int dsa_port_setup(struct dsa_port *dp)
324288

325289
break;
326290
case DSA_PORT_TYPE_USER:
327-
memset(dlp, 0, sizeof(*dlp));
328-
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
329-
devlink_port_attrs_set(dlp, &attrs);
330-
err = devlink_port_register(dl, dlp, dp->index);
331-
if (err)
332-
break;
333-
devlink_port_registered = true;
334-
335291
dp->mac = of_get_mac_address(dp->dn);
336292
err = dsa_slave_create(dp);
337293
if (err)
@@ -345,8 +301,6 @@ static int dsa_port_setup(struct dsa_port *dp)
345301
dsa_port_disable(dp);
346302
if (err && dsa_port_link_registered)
347303
dsa_port_link_unregister_of(dp);
348-
if (err && devlink_port_registered)
349-
devlink_port_unregister(dlp);
350304
if (err)
351305
return err;
352306

@@ -355,30 +309,66 @@ static int dsa_port_setup(struct dsa_port *dp)
355309
return 0;
356310
}
357311

358-
static void dsa_port_teardown(struct dsa_port *dp)
312+
static int dsa_port_devlink_setup(struct dsa_port *dp)
359313
{
360314
struct devlink_port *dlp = &dp->devlink_port;
315+
struct dsa_switch_tree *dst = dp->ds->dst;
316+
struct devlink_port_attrs attrs = {};
317+
struct devlink *dl = dp->ds->devlink;
318+
const unsigned char *id;
319+
unsigned char len;
320+
int err;
361321

322+
id = (const unsigned char *)&dst->index;
323+
len = sizeof(dst->index);
324+
325+
attrs.phys.port_number = dp->index;
326+
memcpy(attrs.switch_id.id, id, len);
327+
attrs.switch_id.id_len = len;
328+
memset(dlp, 0, sizeof(*dlp));
329+
330+
switch (dp->type) {
331+
case DSA_PORT_TYPE_UNUSED:
332+
attrs.flavour = DEVLINK_PORT_FLAVOUR_UNUSED;
333+
break;
334+
case DSA_PORT_TYPE_CPU:
335+
attrs.flavour = DEVLINK_PORT_FLAVOUR_CPU;
336+
break;
337+
case DSA_PORT_TYPE_DSA:
338+
attrs.flavour = DEVLINK_PORT_FLAVOUR_DSA;
339+
break;
340+
case DSA_PORT_TYPE_USER:
341+
attrs.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL;
342+
break;
343+
}
344+
345+
devlink_port_attrs_set(dlp, &attrs);
346+
err = devlink_port_register(dl, dlp, dp->index);
347+
348+
if (!err)
349+
dp->devlink_port_setup = true;
350+
351+
return err;
352+
}
353+
354+
static void dsa_port_teardown(struct dsa_port *dp)
355+
{
362356
if (!dp->setup)
363357
return;
364358

365359
switch (dp->type) {
366360
case DSA_PORT_TYPE_UNUSED:
367-
devlink_port_unregister(dlp);
368361
break;
369362
case DSA_PORT_TYPE_CPU:
370363
dsa_port_disable(dp);
371364
dsa_tag_driver_put(dp->tag_ops);
372-
devlink_port_unregister(dlp);
373365
dsa_port_link_unregister_of(dp);
374366
break;
375367
case DSA_PORT_TYPE_DSA:
376368
dsa_port_disable(dp);
377-
devlink_port_unregister(dlp);
378369
dsa_port_link_unregister_of(dp);
379370
break;
380371
case DSA_PORT_TYPE_USER:
381-
devlink_port_unregister(dlp);
382372
if (dp->slave) {
383373
dsa_slave_destroy(dp->slave);
384374
dp->slave = NULL;
@@ -389,6 +379,15 @@ static void dsa_port_teardown(struct dsa_port *dp)
389379
dp->setup = false;
390380
}
391381

382+
static void dsa_port_devlink_teardown(struct dsa_port *dp)
383+
{
384+
struct devlink_port *dlp = &dp->devlink_port;
385+
386+
if (dp->devlink_port_setup)
387+
devlink_port_unregister(dlp);
388+
dp->devlink_port_setup = false;
389+
}
390+
392391
static int dsa_devlink_info_get(struct devlink *dl,
393392
struct devlink_info_req *req,
394393
struct netlink_ext_ack *extack)
@@ -408,6 +407,7 @@ static const struct devlink_ops dsa_devlink_ops = {
408407
static int dsa_switch_setup(struct dsa_switch *ds)
409408
{
410409
struct dsa_devlink_priv *dl_priv;
410+
struct dsa_port *dp;
411411
int err;
412412

413413
if (ds->setup)
@@ -433,9 +433,20 @@ static int dsa_switch_setup(struct dsa_switch *ds)
433433
if (err)
434434
goto free_devlink;
435435

436+
/* Setup devlink port instances now, so that the switch
437+
* setup() can register regions etc, against the ports
438+
*/
439+
list_for_each_entry(dp, &ds->dst->ports, list) {
440+
if (dp->ds == ds) {
441+
err = dsa_port_devlink_setup(dp);
442+
if (err)
443+
goto unregister_devlink_ports;
444+
}
445+
}
446+
436447
err = dsa_switch_register_notifier(ds);
437448
if (err)
438-
goto unregister_devlink;
449+
goto unregister_devlink_ports;
439450

440451
err = ds->ops->setup(ds);
441452
if (err < 0)
@@ -463,7 +474,10 @@ static int dsa_switch_setup(struct dsa_switch *ds)
463474

464475
unregister_notifier:
465476
dsa_switch_unregister_notifier(ds);
466-
unregister_devlink:
477+
unregister_devlink_ports:
478+
list_for_each_entry(dp, &ds->dst->ports, list)
479+
if (dp->ds == ds)
480+
dsa_port_devlink_teardown(dp);
467481
devlink_unregister(ds->devlink);
468482
free_devlink:
469483
devlink_free(ds->devlink);
@@ -474,6 +488,8 @@ static int dsa_switch_setup(struct dsa_switch *ds)
474488

475489
static void dsa_switch_teardown(struct dsa_switch *ds)
476490
{
491+
struct dsa_port *dp;
492+
477493
if (!ds->setup)
478494
return;
479495

@@ -486,6 +502,9 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
486502
ds->ops->teardown(ds);
487503

488504
if (ds->devlink) {
505+
list_for_each_entry(dp, &ds->dst->ports, list)
506+
if (dp->ds == ds)
507+
dsa_port_devlink_teardown(dp);
489508
devlink_unregister(ds->devlink);
490509
devlink_free(ds->devlink);
491510
ds->devlink = NULL;

0 commit comments

Comments
 (0)