Lines Matching +full:dp +full:- +full:port
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * net/dsa/dsa2.c - Hardware switch handling, binding version 2
4 * Copyright (c) 2008-2009 Marvell Semiconductor
27 struct dsa_port *dp; in dsa_switch_find() local
30 if (dst->index != tree_index) in dsa_switch_find()
33 list_for_each_entry(dp, &dst->ports, list) { in dsa_switch_find()
34 if (dp->ds->index != sw_index) in dsa_switch_find()
37 return dp->ds; in dsa_switch_find()
50 if (dst->index == index) in dsa_tree_find()
64 dst->index = index; in dsa_tree_alloc()
66 INIT_LIST_HEAD(&dst->rtable); in dsa_tree_alloc()
68 INIT_LIST_HEAD(&dst->ports); in dsa_tree_alloc()
70 INIT_LIST_HEAD(&dst->list); in dsa_tree_alloc()
71 list_add_tail(&dst->list, &dsa_tree_list); in dsa_tree_alloc()
73 kref_init(&dst->refcount); in dsa_tree_alloc()
80 list_del(&dst->list); in dsa_tree_free()
87 kref_get(&dst->refcount); in dsa_tree_get()
115 kref_put(&dst->refcount, dsa_tree_release); in dsa_tree_put()
118 static bool dsa_port_is_dsa(struct dsa_port *port) in dsa_port_is_dsa() argument
120 return port->type == DSA_PORT_TYPE_DSA; in dsa_port_is_dsa()
123 static bool dsa_port_is_cpu(struct dsa_port *port) in dsa_port_is_cpu() argument
125 return port->type == DSA_PORT_TYPE_CPU; in dsa_port_is_cpu()
128 static bool dsa_port_is_user(struct dsa_port *dp) in dsa_port_is_user() argument
130 return dp->type == DSA_PORT_TYPE_USER; in dsa_port_is_user()
136 struct dsa_port *dp; in dsa_tree_find_port_by_node() local
138 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_find_port_by_node()
139 if (dp->dn == dn) in dsa_tree_find_port_by_node()
140 return dp; in dsa_tree_find_port_by_node()
145 static struct dsa_link *dsa_link_touch(struct dsa_port *dp, in dsa_link_touch() argument
148 struct dsa_switch *ds = dp->ds; in dsa_link_touch()
152 dst = ds->dst; in dsa_link_touch()
154 list_for_each_entry(dl, &dst->rtable, list) in dsa_link_touch()
155 if (dl->dp == dp && dl->link_dp == link_dp) in dsa_link_touch()
162 dl->dp = dp; in dsa_link_touch()
163 dl->link_dp = link_dp; in dsa_link_touch()
165 INIT_LIST_HEAD(&dl->list); in dsa_link_touch()
166 list_add_tail(&dl->list, &dst->rtable); in dsa_link_touch()
171 static bool dsa_port_setup_routing_table(struct dsa_port *dp) in dsa_port_setup_routing_table() argument
173 struct dsa_switch *ds = dp->ds; in dsa_port_setup_routing_table()
174 struct dsa_switch_tree *dst = ds->dst; in dsa_port_setup_routing_table()
175 struct device_node *dn = dp->dn; in dsa_port_setup_routing_table()
188 dl = dsa_link_touch(dp, link_dp); in dsa_port_setup_routing_table()
201 struct dsa_port *dp; in dsa_tree_setup_routing_table() local
203 list_for_each_entry(dp, &dst->ports, list) { in dsa_tree_setup_routing_table()
204 if (dsa_port_is_dsa(dp)) { in dsa_tree_setup_routing_table()
205 complete = dsa_port_setup_routing_table(dp); in dsa_tree_setup_routing_table()
216 struct dsa_port *dp; in dsa_tree_find_first_cpu() local
218 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_find_first_cpu()
219 if (dsa_port_is_cpu(dp)) in dsa_tree_find_first_cpu()
220 return dp; in dsa_tree_find_first_cpu()
227 struct dsa_port *cpu_dp, *dp; in dsa_tree_setup_default_cpu() local
231 pr_err("DSA: tree %d has no CPU port\n", dst->index); in dsa_tree_setup_default_cpu()
232 return -EINVAL; in dsa_tree_setup_default_cpu()
235 /* Assign the default CPU port to all ports of the fabric */ in dsa_tree_setup_default_cpu()
236 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_setup_default_cpu()
237 if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp)) in dsa_tree_setup_default_cpu()
238 dp->cpu_dp = cpu_dp; in dsa_tree_setup_default_cpu()
245 struct dsa_port *dp; in dsa_tree_teardown_default_cpu() local
247 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_teardown_default_cpu()
248 if (dsa_port_is_user(dp) || dsa_port_is_dsa(dp)) in dsa_tree_teardown_default_cpu()
249 dp->cpu_dp = NULL; in dsa_tree_teardown_default_cpu()
252 static int dsa_port_setup(struct dsa_port *dp) in dsa_port_setup() argument
254 struct devlink_port *dlp = &dp->devlink_port; in dsa_port_setup()
259 if (dp->setup) in dsa_port_setup()
262 switch (dp->type) { in dsa_port_setup()
264 dsa_port_disable(dp); in dsa_port_setup()
267 err = dsa_port_link_register_of(dp); in dsa_port_setup()
272 err = dsa_port_enable(dp, NULL); in dsa_port_setup()
279 err = dsa_port_link_register_of(dp); in dsa_port_setup()
284 err = dsa_port_enable(dp, NULL); in dsa_port_setup()
291 dp->mac = of_get_mac_address(dp->dn); in dsa_port_setup()
292 err = dsa_slave_create(dp); in dsa_port_setup()
296 devlink_port_type_eth_set(dlp, dp->slave); in dsa_port_setup()
301 dsa_port_disable(dp); in dsa_port_setup()
303 dsa_port_link_unregister_of(dp); in dsa_port_setup()
307 dp->setup = true; in dsa_port_setup()
312 static int dsa_port_devlink_setup(struct dsa_port *dp) in dsa_port_devlink_setup() argument
314 struct devlink_port *dlp = &dp->devlink_port; in dsa_port_devlink_setup()
315 struct dsa_switch_tree *dst = dp->ds->dst; in dsa_port_devlink_setup()
317 struct devlink *dl = dp->ds->devlink; in dsa_port_devlink_setup()
322 id = (const unsigned char *)&dst->index; in dsa_port_devlink_setup()
323 len = sizeof(dst->index); in dsa_port_devlink_setup()
325 attrs.phys.port_number = dp->index; in dsa_port_devlink_setup()
330 switch (dp->type) { in dsa_port_devlink_setup()
346 err = devlink_port_register(dl, dlp, dp->index); in dsa_port_devlink_setup()
349 dp->devlink_port_setup = true; in dsa_port_devlink_setup()
354 static void dsa_port_teardown(struct dsa_port *dp) in dsa_port_teardown() argument
356 struct devlink_port *dlp = &dp->devlink_port; in dsa_port_teardown()
358 if (!dp->setup) in dsa_port_teardown()
363 switch (dp->type) { in dsa_port_teardown()
367 dsa_port_disable(dp); in dsa_port_teardown()
368 dsa_tag_driver_put(dp->tag_ops); in dsa_port_teardown()
369 dsa_port_link_unregister_of(dp); in dsa_port_teardown()
372 dsa_port_disable(dp); in dsa_port_teardown()
373 dsa_port_link_unregister_of(dp); in dsa_port_teardown()
376 if (dp->slave) { in dsa_port_teardown()
377 dsa_slave_destroy(dp->slave); in dsa_port_teardown()
378 dp->slave = NULL; in dsa_port_teardown()
383 dp->setup = false; in dsa_port_teardown()
386 static void dsa_port_devlink_teardown(struct dsa_port *dp) in dsa_port_devlink_teardown() argument
388 struct devlink_port *dlp = &dp->devlink_port; in dsa_port_devlink_teardown()
390 if (dp->devlink_port_setup) in dsa_port_devlink_teardown()
392 dp->devlink_port_setup = false; in dsa_port_devlink_teardown()
401 if (ds->ops->devlink_info_get) in dsa_devlink_info_get()
402 return ds->ops->devlink_info_get(ds, req, extack); in dsa_devlink_info_get()
404 return -EOPNOTSUPP; in dsa_devlink_info_get()
414 struct dsa_port *dp; in dsa_switch_setup() local
417 if (ds->setup) in dsa_switch_setup()
420 /* Initialize ds->phys_mii_mask before registering the slave MDIO bus in dsa_switch_setup()
421 * driver and before ops->setup() has run, since the switch drivers and in dsa_switch_setup()
425 ds->phys_mii_mask |= dsa_user_ports(ds); in dsa_switch_setup()
430 ds->devlink = devlink_alloc(&dsa_devlink_ops, sizeof(*dl_priv)); in dsa_switch_setup()
431 if (!ds->devlink) in dsa_switch_setup()
432 return -ENOMEM; in dsa_switch_setup()
433 dl_priv = devlink_priv(ds->devlink); in dsa_switch_setup()
434 dl_priv->ds = ds; in dsa_switch_setup()
436 err = devlink_register(ds->devlink, ds->dev); in dsa_switch_setup()
440 /* Setup devlink port instances now, so that the switch in dsa_switch_setup()
443 list_for_each_entry(dp, &ds->dst->ports, list) { in dsa_switch_setup()
444 if (dp->ds == ds) { in dsa_switch_setup()
445 err = dsa_port_devlink_setup(dp); in dsa_switch_setup()
455 err = ds->ops->setup(ds); in dsa_switch_setup()
459 devlink_params_publish(ds->devlink); in dsa_switch_setup()
461 if (!ds->slave_mii_bus && ds->ops->phy_read) { in dsa_switch_setup()
462 ds->slave_mii_bus = mdiobus_alloc(); in dsa_switch_setup()
463 if (!ds->slave_mii_bus) { in dsa_switch_setup()
464 err = -ENOMEM; in dsa_switch_setup()
470 err = mdiobus_register(ds->slave_mii_bus); in dsa_switch_setup()
475 ds->setup = true; in dsa_switch_setup()
480 if (ds->slave_mii_bus && ds->ops->phy_read) in dsa_switch_setup()
481 mdiobus_free(ds->slave_mii_bus); in dsa_switch_setup()
483 if (ds->ops->teardown) in dsa_switch_setup()
484 ds->ops->teardown(ds); in dsa_switch_setup()
488 list_for_each_entry(dp, &ds->dst->ports, list) in dsa_switch_setup()
489 if (dp->ds == ds) in dsa_switch_setup()
490 dsa_port_devlink_teardown(dp); in dsa_switch_setup()
491 devlink_unregister(ds->devlink); in dsa_switch_setup()
493 devlink_free(ds->devlink); in dsa_switch_setup()
494 ds->devlink = NULL; in dsa_switch_setup()
501 struct dsa_port *dp; in dsa_switch_teardown() local
503 if (!ds->setup) in dsa_switch_teardown()
506 if (ds->slave_mii_bus && ds->ops->phy_read) { in dsa_switch_teardown()
507 mdiobus_unregister(ds->slave_mii_bus); in dsa_switch_teardown()
508 mdiobus_free(ds->slave_mii_bus); in dsa_switch_teardown()
509 ds->slave_mii_bus = NULL; in dsa_switch_teardown()
514 if (ds->ops->teardown) in dsa_switch_teardown()
515 ds->ops->teardown(ds); in dsa_switch_teardown()
517 if (ds->devlink) { in dsa_switch_teardown()
518 list_for_each_entry(dp, &ds->dst->ports, list) in dsa_switch_teardown()
519 if (dp->ds == ds) in dsa_switch_teardown()
520 dsa_port_devlink_teardown(dp); in dsa_switch_teardown()
521 devlink_unregister(ds->devlink); in dsa_switch_teardown()
522 devlink_free(ds->devlink); in dsa_switch_teardown()
523 ds->devlink = NULL; in dsa_switch_teardown()
526 ds->setup = false; in dsa_switch_teardown()
531 struct dsa_port *dp; in dsa_tree_setup_switches() local
534 list_for_each_entry(dp, &dst->ports, list) { in dsa_tree_setup_switches()
535 err = dsa_switch_setup(dp->ds); in dsa_tree_setup_switches()
540 list_for_each_entry(dp, &dst->ports, list) { in dsa_tree_setup_switches()
541 err = dsa_port_setup(dp); in dsa_tree_setup_switches()
543 dsa_port_devlink_teardown(dp); in dsa_tree_setup_switches()
544 dp->type = DSA_PORT_TYPE_UNUSED; in dsa_tree_setup_switches()
545 err = dsa_port_devlink_setup(dp); in dsa_tree_setup_switches()
555 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_setup_switches()
556 dsa_port_teardown(dp); in dsa_tree_setup_switches()
558 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_setup_switches()
559 dsa_switch_teardown(dp->ds); in dsa_tree_setup_switches()
566 struct dsa_port *dp; in dsa_tree_teardown_switches() local
568 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_teardown_switches()
569 dsa_port_teardown(dp); in dsa_tree_teardown_switches()
571 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_teardown_switches()
572 dsa_switch_teardown(dp->ds); in dsa_tree_teardown_switches()
577 struct dsa_port *dp; in dsa_tree_setup_master() local
580 list_for_each_entry(dp, &dst->ports, list) { in dsa_tree_setup_master()
581 if (dsa_port_is_cpu(dp)) { in dsa_tree_setup_master()
582 err = dsa_master_setup(dp->master, dp); in dsa_tree_setup_master()
593 struct dsa_port *dp; in dsa_tree_teardown_master() local
595 list_for_each_entry(dp, &dst->ports, list) in dsa_tree_teardown_master()
596 if (dsa_port_is_cpu(dp)) in dsa_tree_teardown_master()
597 dsa_master_teardown(dp->master); in dsa_tree_teardown_master()
605 if (dst->setup) { in dsa_tree_setup()
607 dst->index); in dsa_tree_setup()
608 return -EEXIST; in dsa_tree_setup()
627 dst->setup = true; in dsa_tree_setup()
629 pr_info("DSA: tree %d setup\n", dst->index); in dsa_tree_setup()
645 if (!dst->setup) in dsa_tree_teardown()
654 list_for_each_entry_safe(dl, next, &dst->rtable, list) { in dsa_tree_teardown()
655 list_del(&dl->list); in dsa_tree_teardown()
659 pr_info("DSA: tree %d torn down\n", dst->index); in dsa_tree_teardown()
661 dst->setup = false; in dsa_tree_teardown()
666 struct dsa_switch_tree *dst = ds->dst; in dsa_port_touch()
667 struct dsa_port *dp; in dsa_port_touch() local
669 list_for_each_entry(dp, &dst->ports, list) in dsa_port_touch()
670 if (dp->ds == ds && dp->index == index) in dsa_port_touch()
671 return dp; in dsa_port_touch()
673 dp = kzalloc(sizeof(*dp), GFP_KERNEL); in dsa_port_touch()
674 if (!dp) in dsa_port_touch()
677 dp->ds = ds; in dsa_port_touch()
678 dp->index = index; in dsa_port_touch()
680 INIT_LIST_HEAD(&dp->list); in dsa_port_touch()
681 list_add_tail(&dp->list, &dst->ports); in dsa_port_touch()
683 return dp; in dsa_port_touch()
686 static int dsa_port_parse_user(struct dsa_port *dp, const char *name) in dsa_port_parse_user() argument
691 dp->type = DSA_PORT_TYPE_USER; in dsa_port_parse_user()
692 dp->name = name; in dsa_port_parse_user()
697 static int dsa_port_parse_dsa(struct dsa_port *dp) in dsa_port_parse_dsa() argument
699 dp->type = DSA_PORT_TYPE_DSA; in dsa_port_parse_dsa()
704 static enum dsa_tag_protocol dsa_get_tag_protocol(struct dsa_port *dp, in dsa_get_tag_protocol() argument
708 struct dsa_switch *mds, *ds = dp->ds; in dsa_get_tag_protocol()
718 mds = mdp->ds; in dsa_get_tag_protocol()
719 mdp_upstream = dsa_upstream_port(mds, mdp->index); in dsa_get_tag_protocol()
720 tag_protocol = mds->ops->get_tag_protocol(mds, mdp_upstream, in dsa_get_tag_protocol()
727 return ds->ops->get_tag_protocol(ds, dp->index, tag_protocol); in dsa_get_tag_protocol()
730 static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master) in dsa_port_parse_cpu() argument
732 struct dsa_switch *ds = dp->ds; in dsa_port_parse_cpu()
733 struct dsa_switch_tree *dst = ds->dst; in dsa_port_parse_cpu()
737 tag_protocol = dsa_get_tag_protocol(dp, master); in dsa_port_parse_cpu()
740 if (PTR_ERR(tag_ops) == -ENOPROTOOPT) in dsa_port_parse_cpu()
741 return -EPROBE_DEFER; in dsa_port_parse_cpu()
742 dev_warn(ds->dev, "No tagger for this switch\n"); in dsa_port_parse_cpu()
743 dp->master = NULL; in dsa_port_parse_cpu()
747 dp->master = master; in dsa_port_parse_cpu()
748 dp->type = DSA_PORT_TYPE_CPU; in dsa_port_parse_cpu()
749 dp->filter = tag_ops->filter; in dsa_port_parse_cpu()
750 dp->rcv = tag_ops->rcv; in dsa_port_parse_cpu()
751 dp->tag_ops = tag_ops; in dsa_port_parse_cpu()
752 dp->dst = dst; in dsa_port_parse_cpu()
757 static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn) in dsa_port_parse_of() argument
763 dp->dn = dn; in dsa_port_parse_of()
771 return -EPROBE_DEFER; in dsa_port_parse_of()
773 return dsa_port_parse_cpu(dp, master); in dsa_port_parse_of()
777 return dsa_port_parse_dsa(dp); in dsa_port_parse_of()
779 return dsa_port_parse_user(dp, name); in dsa_port_parse_of()
785 struct device_node *ports, *port; in dsa_switch_parse_ports_of() local
786 struct dsa_port *dp; in dsa_switch_parse_ports_of() local
792 /* The second possibility is "ethernet-ports" */ in dsa_switch_parse_ports_of()
793 ports = of_get_child_by_name(dn, "ethernet-ports"); in dsa_switch_parse_ports_of()
795 dev_err(ds->dev, "no ports child node found\n"); in dsa_switch_parse_ports_of()
796 return -EINVAL; in dsa_switch_parse_ports_of()
800 for_each_available_child_of_node(ports, port) { in dsa_switch_parse_ports_of()
801 err = of_property_read_u32(port, "reg", ®); in dsa_switch_parse_ports_of()
805 if (reg >= ds->num_ports) { in dsa_switch_parse_ports_of()
806 err = -EINVAL; in dsa_switch_parse_ports_of()
810 dp = dsa_to_port(ds, reg); in dsa_switch_parse_ports_of()
812 err = dsa_port_parse_of(dp, port); in dsa_switch_parse_ports_of()
830 if (sz < 0 && sz != -EINVAL) in dsa_switch_parse_member_of()
833 ds->index = m[1]; in dsa_switch_parse_member_of()
835 ds->dst = dsa_tree_touch(m[0]); in dsa_switch_parse_member_of()
836 if (!ds->dst) in dsa_switch_parse_member_of()
837 return -ENOMEM; in dsa_switch_parse_member_of()
844 struct dsa_port *dp; in dsa_switch_touch_ports() local
845 int port; in dsa_switch_touch_ports() local
847 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_touch_ports()
848 dp = dsa_port_touch(ds, port); in dsa_switch_touch_ports()
849 if (!dp) in dsa_switch_touch_ports()
850 return -ENOMEM; in dsa_switch_touch_ports()
871 static int dsa_port_parse(struct dsa_port *dp, const char *name, in dsa_port_parse() argument
879 return -EPROBE_DEFER; in dsa_port_parse()
883 return dsa_port_parse_cpu(dp, master); in dsa_port_parse()
887 return dsa_port_parse_dsa(dp); in dsa_port_parse()
889 return dsa_port_parse_user(dp, name); in dsa_port_parse()
896 struct dsa_port *dp; in dsa_switch_parse_ports() local
903 name = cd->port_names[i]; in dsa_switch_parse_ports()
904 dev = cd->netdev[i]; in dsa_switch_parse_ports()
905 dp = dsa_to_port(ds, i); in dsa_switch_parse_ports()
910 err = dsa_port_parse(dp, name, dev); in dsa_switch_parse_ports()
918 return -EINVAL; in dsa_switch_parse_ports()
927 ds->cd = cd; in dsa_switch_parse()
932 ds->index = 0; in dsa_switch_parse()
933 ds->dst = dsa_tree_touch(0); in dsa_switch_parse()
934 if (!ds->dst) in dsa_switch_parse()
935 return -ENOMEM; in dsa_switch_parse()
946 struct dsa_switch_tree *dst = ds->dst; in dsa_switch_release_ports()
947 struct dsa_port *dp, *next; in dsa_switch_release_ports() local
949 list_for_each_entry_safe(dp, next, &dst->ports, list) { in dsa_switch_release_ports()
950 if (dp->ds != ds) in dsa_switch_release_ports()
952 list_del(&dp->list); in dsa_switch_release_ports()
953 kfree(dp); in dsa_switch_release_ports()
964 if (!ds->dev) in dsa_switch_probe()
965 return -ENODEV; in dsa_switch_probe()
967 pdata = ds->dev->platform_data; in dsa_switch_probe()
968 np = ds->dev->of_node; in dsa_switch_probe()
970 if (!ds->num_ports) in dsa_switch_probe()
971 return -EINVAL; in dsa_switch_probe()
982 err = -ENODEV; in dsa_switch_probe()
988 dst = ds->dst; in dsa_switch_probe()
1005 dsa_tree_put(ds->dst); in dsa_register_switch()
1014 struct dsa_switch_tree *dst = ds->dst; in dsa_switch_remove()