diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-11-06 16:11:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-11-08 19:26:49 -0500 |
commit | f070464cf000131928b2c3fd592efd1946610eea (patch) | |
tree | c7367e2105eeee1c71a3744dae6c22c581f19d50 /net/dsa | |
parent | 24a9332a58b7f41a0d36c35a2c6897242bffdbc0 (diff) |
net: dsa: setup and teardown default CPU port
The dsa_dst_parse function called just before dsa_dst_apply does not
parse the tree but does only one thing: it assigns the default CPU port
to dst->cpu_dp and to each user ports.
This patch simplifies this by calling a dsa_tree_setup_default_cpu
function at the beginning of dsa_dst_apply directly.
A dsa_port_is_user helper is added for convenience.
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 | 153 |
1 files changed, 68 insertions, 85 deletions
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 283104e5ca6a..0a63a2119cd0 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c | |||
@@ -112,6 +112,11 @@ static bool dsa_port_is_cpu(struct dsa_port *port) | |||
112 | return port->type == DSA_PORT_TYPE_CPU; | 112 | return port->type == DSA_PORT_TYPE_CPU; |
113 | } | 113 | } |
114 | 114 | ||
115 | static bool dsa_port_is_user(struct dsa_port *dp) | ||
116 | { | ||
117 | return dp->type == DSA_PORT_TYPE_USER; | ||
118 | } | ||
119 | |||
115 | static bool dsa_ds_find_port_dn(struct dsa_switch *ds, | 120 | static bool dsa_ds_find_port_dn(struct dsa_switch *ds, |
116 | struct device_node *port) | 121 | struct device_node *port) |
117 | { | 122 | { |
@@ -218,6 +223,64 @@ static int dsa_dst_complete(struct dsa_switch_tree *dst) | |||
218 | return 0; | 223 | return 0; |
219 | } | 224 | } |
220 | 225 | ||
226 | static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst) | ||
227 | { | ||
228 | struct dsa_switch *ds; | ||
229 | struct dsa_port *dp; | ||
230 | int device, port; | ||
231 | |||
232 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { | ||
233 | ds = dst->ds[device]; | ||
234 | if (!ds) | ||
235 | continue; | ||
236 | |||
237 | for (port = 0; port < ds->num_ports; port++) { | ||
238 | dp = &ds->ports[port]; | ||
239 | |||
240 | if (dsa_port_is_cpu(dp)) | ||
241 | return dp; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | return NULL; | ||
246 | } | ||
247 | |||
248 | static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst) | ||
249 | { | ||
250 | struct dsa_switch *ds; | ||
251 | struct dsa_port *dp; | ||
252 | int device, port; | ||
253 | |||
254 | /* DSA currently only supports a single CPU port */ | ||
255 | dst->cpu_dp = dsa_tree_find_first_cpu(dst); | ||
256 | if (!dst->cpu_dp) { | ||
257 | pr_warn("Tree has no master device\n"); | ||
258 | return -EINVAL; | ||
259 | } | ||
260 | |||
261 | /* Assign the default CPU port to all ports of the fabric */ | ||
262 | for (device = 0; device < DSA_MAX_SWITCHES; device++) { | ||
263 | ds = dst->ds[device]; | ||
264 | if (!ds) | ||
265 | continue; | ||
266 | |||
267 | for (port = 0; port < ds->num_ports; port++) { | ||
268 | dp = &ds->ports[port]; | ||
269 | |||
270 | if (dsa_port_is_user(dp)) | ||
271 | dp->cpu_dp = dst->cpu_dp; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst) | ||
279 | { | ||
280 | /* DSA currently only supports a single CPU port */ | ||
281 | dst->cpu_dp = NULL; | ||
282 | } | ||
283 | |||
221 | static int dsa_dsa_port_apply(struct dsa_port *port) | 284 | static int dsa_dsa_port_apply(struct dsa_port *port) |
222 | { | 285 | { |
223 | struct dsa_switch *ds = port->ds; | 286 | struct dsa_switch *ds = port->ds; |
@@ -412,6 +475,10 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst) | |||
412 | u32 index; | 475 | u32 index; |
413 | int err; | 476 | int err; |
414 | 477 | ||
478 | err = dsa_tree_setup_default_cpu(dst); | ||
479 | if (err) | ||
480 | return err; | ||
481 | |||
415 | for (index = 0; index < DSA_MAX_SWITCHES; index++) { | 482 | for (index = 0; index < DSA_MAX_SWITCHES; index++) { |
416 | ds = dst->ds[index]; | 483 | ds = dst->ds[index]; |
417 | if (!ds) | 484 | if (!ds) |
@@ -464,7 +531,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) | |||
464 | dsa_ds_unapply(dst, ds); | 531 | dsa_ds_unapply(dst, ds); |
465 | } | 532 | } |
466 | 533 | ||
467 | dst->cpu_dp = NULL; | 534 | dsa_tree_teardown_default_cpu(dst); |
468 | 535 | ||
469 | pr_info("DSA: tree %d unapplied\n", dst->index); | 536 | pr_info("DSA: tree %d unapplied\n", dst->index); |
470 | dst->applied = false; | 537 | dst->applied = false; |
@@ -532,86 +599,6 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) | |||
532 | return 0; | 599 | return 0; |
533 | } | 600 | } |
534 | 601 | ||
535 | static int dsa_cpu_parse(struct dsa_port *port, u32 index, | ||
536 | struct dsa_switch_tree *dst, | ||
537 | struct dsa_switch *ds) | ||
538 | { | ||
539 | if (!dst->cpu_dp) | ||
540 | dst->cpu_dp = port; | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds) | ||
546 | { | ||
547 | struct dsa_port *port; | ||
548 | u32 index; | ||
549 | int err; | ||
550 | |||
551 | for (index = 0; index < ds->num_ports; index++) { | ||
552 | port = &ds->ports[index]; | ||
553 | if (!dsa_port_is_valid(port) || | ||
554 | dsa_port_is_dsa(port)) | ||
555 | continue; | ||
556 | |||
557 | if (dsa_port_is_cpu(port)) { | ||
558 | err = dsa_cpu_parse(port, index, dst, ds); | ||
559 | if (err) | ||
560 | return err; | ||
561 | } | ||
562 | |||
563 | } | ||
564 | |||
565 | pr_info("DSA: switch %d %d parsed\n", dst->index, ds->index); | ||
566 | |||
567 | return 0; | ||
568 | } | ||
569 | |||
570 | static int dsa_dst_parse(struct dsa_switch_tree *dst) | ||
571 | { | ||
572 | struct dsa_switch *ds; | ||
573 | struct dsa_port *dp; | ||
574 | u32 index; | ||
575 | int port; | ||
576 | int err; | ||
577 | |||
578 | for (index = 0; index < DSA_MAX_SWITCHES; index++) { | ||
579 | ds = dst->ds[index]; | ||
580 | if (!ds) | ||
581 | continue; | ||
582 | |||
583 | err = dsa_ds_parse(dst, ds); | ||
584 | if (err) | ||
585 | return err; | ||
586 | } | ||
587 | |||
588 | if (!dst->cpu_dp) { | ||
589 | pr_warn("Tree has no master device\n"); | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | |||
593 | /* Assign the default CPU port to all ports of the fabric */ | ||
594 | for (index = 0; index < DSA_MAX_SWITCHES; index++) { | ||
595 | ds = dst->ds[index]; | ||
596 | if (!ds) | ||
597 | continue; | ||
598 | |||
599 | for (port = 0; port < ds->num_ports; port++) { | ||
600 | dp = &ds->ports[port]; | ||
601 | if (!dsa_port_is_valid(dp) || | ||
602 | dsa_port_is_dsa(dp) || | ||
603 | dsa_port_is_cpu(dp)) | ||
604 | continue; | ||
605 | |||
606 | dp->cpu_dp = dst->cpu_dp; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | pr_info("DSA: tree %d parsed\n", dst->index); | ||
611 | |||
612 | return 0; | ||
613 | } | ||
614 | |||
615 | static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) | 602 | static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) |
616 | { | 603 | { |
617 | struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); | 604 | struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0); |
@@ -810,10 +797,6 @@ static int _dsa_register_switch(struct dsa_switch *ds) | |||
810 | return -EINVAL; | 797 | return -EINVAL; |
811 | } | 798 | } |
812 | 799 | ||
813 | err = dsa_dst_parse(dst); | ||
814 | if (err) | ||
815 | goto out_del_dst; | ||
816 | |||
817 | err = dsa_dst_apply(dst); | 800 | err = dsa_dst_apply(dst); |
818 | if (err) { | 801 | if (err) { |
819 | dsa_dst_unapply(dst); | 802 | dsa_dst_unapply(dst); |