diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-11-06 16:11:48 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-08 19:26:49 -0500 |
commit | 1d27732f411d57f0168af30be2adb504b8b7749d (patch) | |
tree | 4d27342910325b453e82f0889d61fc7c4a4b514f /net/dsa | |
parent | 1f08f9e9cbc63d92c246f40ae4221cba86ef8ec6 (diff) |
net: dsa: setup and teardown ports
The dsa_dsa_port_apply and dsa_cpu_port_apply functions do exactly the
same. The dsa_user_port_apply function does not try to register a fixed
link but try to create a slave.
This commit factorizes and scopes all that in two convenient
dsa_port_setup and dsa_port_teardown functions.
It won't hurt to register a devlink_port for unused port as well.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa')
-rw-r--r-- | net/dsa/dsa2.c | 173 |
1 files changed, 59 insertions, 114 deletions
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 2b3b2a86791d..676c0bc943dd 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c | |||
@@ -281,91 +281,65 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) | |||
281 | dst->cpu_dp = NULL; | 281 | dst->cpu_dp = NULL; |
282 | } | 282 | } |
283 | 283 | ||
284 | static int dsa_dsa_port_apply(struct dsa_port *port) | 284 | static int dsa_port_setup(struct dsa_port *dp) |
285 | { | 285 | { |
286 | struct dsa_switch *ds = port->ds; | 286 | struct dsa_switch *ds = dp->ds; |
287 | int err; | 287 | int err; |
288 | 288 | ||
289 | err = dsa_port_fixed_link_register_of(port); | 289 | memset(&dp->devlink_port, 0, sizeof(dp->devlink_port)); |
290 | if (err) { | ||
291 | dev_warn(ds->dev, "Failed to setup dsa port %d: %d\n", | ||
292 | port->index, err); | ||
293 | return err; | ||
294 | } | ||
295 | |||
296 | memset(&port->devlink_port, 0, sizeof(port->devlink_port)); | ||
297 | |||
298 | return devlink_port_register(ds->devlink, &port->devlink_port, | ||
299 | port->index); | ||
300 | } | ||
301 | |||
302 | static void dsa_dsa_port_unapply(struct dsa_port *port) | ||
303 | { | ||
304 | devlink_port_unregister(&port->devlink_port); | ||
305 | dsa_port_fixed_link_unregister_of(port); | ||
306 | } | ||
307 | |||
308 | static int dsa_cpu_port_apply(struct dsa_port *port) | ||
309 | { | ||
310 | struct dsa_switch *ds = port->ds; | ||
311 | int err; | ||
312 | 290 | ||
313 | err = dsa_port_fixed_link_register_of(port); | 291 | err = devlink_port_register(ds->devlink, &dp->devlink_port, dp->index); |
314 | if (err) { | 292 | if (err) |
315 | dev_warn(ds->dev, "Failed to setup cpu port %d: %d\n", | ||
316 | port->index, err); | ||
317 | return err; | 293 | return err; |
318 | } | ||
319 | |||
320 | memset(&port->devlink_port, 0, sizeof(port->devlink_port)); | ||
321 | err = devlink_port_register(ds->devlink, &port->devlink_port, | ||
322 | port->index); | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | static void dsa_cpu_port_unapply(struct dsa_port *port) | ||
327 | { | ||
328 | devlink_port_unregister(&port->devlink_port); | ||
329 | dsa_port_fixed_link_unregister_of(port); | ||
330 | } | ||
331 | 294 | ||
332 | static int dsa_user_port_apply(struct dsa_port *port) | 295 | switch (dp->type) { |
333 | { | 296 | case DSA_PORT_TYPE_UNUSED: |
334 | struct dsa_switch *ds = port->ds; | 297 | break; |
335 | int err; | 298 | case DSA_PORT_TYPE_CPU: |
299 | case DSA_PORT_TYPE_DSA: | ||
300 | err = dsa_port_fixed_link_register_of(dp); | ||
301 | if (err) { | ||
302 | dev_err(ds->dev, "failed to register fixed link for port %d.%d\n", | ||
303 | ds->index, dp->index); | ||
304 | return err; | ||
305 | } | ||
336 | 306 | ||
337 | err = dsa_slave_create(port); | 307 | break; |
338 | if (err) { | 308 | case DSA_PORT_TYPE_USER: |
339 | dev_warn(ds->dev, "Failed to create slave %d: %d\n", | 309 | err = dsa_slave_create(dp); |
340 | port->index, err); | 310 | if (err) |
341 | port->slave = NULL; | 311 | dev_err(ds->dev, "failed to create slave for port %d.%d\n", |
342 | return err; | 312 | ds->index, dp->index); |
313 | else | ||
314 | devlink_port_type_eth_set(&dp->devlink_port, dp->slave); | ||
315 | break; | ||
343 | } | 316 | } |
344 | 317 | ||
345 | memset(&port->devlink_port, 0, sizeof(port->devlink_port)); | ||
346 | err = devlink_port_register(ds->devlink, &port->devlink_port, | ||
347 | port->index); | ||
348 | if (err) | ||
349 | return err; | ||
350 | |||
351 | devlink_port_type_eth_set(&port->devlink_port, port->slave); | ||
352 | |||
353 | return 0; | 318 | return 0; |
354 | } | 319 | } |
355 | 320 | ||
356 | static void dsa_user_port_unapply(struct dsa_port *port) | 321 | static void dsa_port_teardown(struct dsa_port *dp) |
357 | { | 322 | { |
358 | devlink_port_unregister(&port->devlink_port); | 323 | devlink_port_unregister(&dp->devlink_port); |
359 | if (port->slave) { | 324 | |
360 | dsa_slave_destroy(port->slave); | 325 | switch (dp->type) { |
361 | port->slave = NULL; | 326 | case DSA_PORT_TYPE_UNUSED: |
327 | break; | ||
328 | case DSA_PORT_TYPE_CPU: | ||
329 | case DSA_PORT_TYPE_DSA: | ||
330 | dsa_port_fixed_link_unregister_of(dp); | ||
331 | break; | ||
332 | case DSA_PORT_TYPE_USER: | ||
333 | if (dp->slave) { | ||
334 | dsa_slave_destroy(dp->slave); | ||
335 | dp->slave = NULL; | ||
336 | } | ||
337 | break; | ||
362 | } | 338 | } |
363 | } | 339 | } |
364 | 340 | ||
365 | static int dsa_switch_setup(struct dsa_switch *ds) | 341 | static int dsa_switch_setup(struct dsa_switch *ds) |
366 | { | 342 | { |
367 | struct dsa_port *port; | ||
368 | u32 index; | ||
369 | int err; | 343 | int err; |
370 | 344 | ||
371 | /* Initialize ds->phys_mii_mask before registering the slave MDIO bus | 345 | /* Initialize ds->phys_mii_mask before registering the slave MDIO bus |
@@ -406,56 +380,11 @@ static int dsa_switch_setup(struct dsa_switch *ds) | |||
406 | return err; | 380 | return err; |
407 | } | 381 | } |
408 | 382 | ||
409 | for (index = 0; index < ds->num_ports; index++) { | ||
410 | port = &ds->ports[index]; | ||
411 | if (!dsa_port_is_valid(port)) | ||
412 | continue; | ||
413 | |||
414 | if (dsa_port_is_dsa(port)) { | ||
415 | err = dsa_dsa_port_apply(port); | ||
416 | if (err) | ||
417 | return err; | ||
418 | continue; | ||
419 | } | ||
420 | |||
421 | if (dsa_port_is_cpu(port)) { | ||
422 | err = dsa_cpu_port_apply(port); | ||
423 | if (err) | ||
424 | return err; | ||
425 | continue; | ||
426 | } | ||
427 | |||
428 | err = dsa_user_port_apply(port); | ||
429 | if (err) | ||
430 | continue; | ||
431 | } | ||
432 | |||
433 | return 0; | 383 | return 0; |
434 | } | 384 | } |
435 | 385 | ||
436 | static void dsa_switch_teardown(struct dsa_switch *ds) | 386 | static void dsa_switch_teardown(struct dsa_switch *ds) |
437 | { | 387 | { |
438 | struct dsa_port *port; | ||
439 | u32 index; | ||
440 | |||
441 | for (index = 0; index < ds->num_ports; index++) { | ||
442 | port = &ds->ports[index]; | ||
443 | if (!dsa_port_is_valid(port)) | ||
444 | continue; | ||
445 | |||
446 | if (dsa_port_is_dsa(port)) { | ||
447 | dsa_dsa_port_unapply(port); | ||
448 | continue; | ||
449 | } | ||
450 | |||
451 | if (dsa_port_is_cpu(port)) { | ||
452 | dsa_cpu_port_unapply(port); | ||
453 | continue; | ||
454 | } | ||
455 | |||
456 | dsa_user_port_unapply(port); | ||
457 | } | ||
458 | |||
459 | if (ds->slave_mii_bus && ds->ops->phy_read) | 388 | if (ds->slave_mii_bus && ds->ops->phy_read) |
460 | mdiobus_unregister(ds->slave_mii_bus); | 389 | mdiobus_unregister(ds->slave_mii_bus); |
461 | 390 | ||
@@ -472,7 +401,8 @@ static void dsa_switch_teardown(struct dsa_switch *ds) | |||
472 | static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) | 401 | static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) |
473 | { | 402 | { |
474 | struct dsa_switch *ds; | 403 | struct dsa_switch *ds; |
475 | int device; | 404 | struct dsa_port *dp; |
405 | int device, port; | ||
476 | int err; | 406 | int err; |
477 | 407 | ||
478 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { | 408 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { |
@@ -483,6 +413,14 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) | |||
483 | err = dsa_switch_setup(ds); | 413 | err = dsa_switch_setup(ds); |
484 | if (err) | 414 | if (err) |
485 | return err; | 415 | return err; |
416 | |||
417 | for (port = 0; port < ds->num_ports; port++) { | ||
418 | dp = &ds->ports[port]; | ||
419 | |||
420 | err = dsa_port_setup(dp); | ||
421 | if (err) | ||
422 | return err; | ||
423 | } | ||
486 | } | 424 | } |
487 | 425 | ||
488 | return 0; | 426 | return 0; |
@@ -491,13 +429,20 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst) | |||
491 | static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst) | 429 | static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst) |
492 | { | 430 | { |
493 | struct dsa_switch *ds; | 431 | struct dsa_switch *ds; |
494 | int device; | 432 | struct dsa_port *dp; |
433 | int device, port; | ||
495 | 434 | ||
496 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { | 435 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { |
497 | ds = dst->ds[device]; | 436 | ds = dst->ds[device]; |
498 | if (!ds) | 437 | if (!ds) |
499 | continue; | 438 | continue; |
500 | 439 | ||
440 | for (port = 0; port < ds->num_ports; port++) { | ||
441 | dp = &ds->ports[port]; | ||
442 | |||
443 | dsa_port_teardown(dp); | ||
444 | } | ||
445 | |||
501 | dsa_switch_teardown(ds); | 446 | dsa_switch_teardown(ds); |
502 | } | 447 | } |
503 | } | 448 | } |