Lines Matching +full:a +full:- +full:facing
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Handling of a single switch chip, part of a switch fabric
5 * Copyright (c) 2017 Savoir-faire Linux Inc.
22 for (i = 0; i < ds->num_ports; ++i) { in dsa_switch_fastest_ageing_time()
25 if (dp->ageing_time && dp->ageing_time < ageing_time) in dsa_switch_fastest_ageing_time()
26 ageing_time = dp->ageing_time; in dsa_switch_fastest_ageing_time()
35 unsigned int ageing_time = info->ageing_time; in dsa_switch_ageing_time()
37 if (ds->ageing_time_min && ageing_time < ds->ageing_time_min) in dsa_switch_ageing_time()
38 return -ERANGE; in dsa_switch_ageing_time()
40 if (ds->ageing_time_max && ageing_time > ds->ageing_time_max) in dsa_switch_ageing_time()
41 return -ERANGE; in dsa_switch_ageing_time()
46 if (ds->ops->set_ageing_time) in dsa_switch_ageing_time()
47 return ds->ops->set_ageing_time(ds, ageing_time); in dsa_switch_ageing_time()
55 if (ds->index == info->sw_index && port == info->port) in dsa_switch_mtu_match()
59 * targeted for a single switch. in dsa_switch_mtu_match()
61 if (info->targeted_match) in dsa_switch_mtu_match()
75 if (!ds->ops->port_change_mtu) in dsa_switch_mtu()
76 return -EOPNOTSUPP; in dsa_switch_mtu()
78 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_mtu()
80 ret = ds->ops->port_change_mtu(ds, port, info->mtu); in dsa_switch_mtu()
92 struct dsa_switch_tree *dst = ds->dst; in dsa_switch_bridge_join()
95 if (dst->index == info->tree_index && ds->index == info->sw_index) { in dsa_switch_bridge_join()
96 if (!ds->ops->port_bridge_join) in dsa_switch_bridge_join()
97 return -EOPNOTSUPP; in dsa_switch_bridge_join()
99 err = ds->ops->port_bridge_join(ds, info->port, info->br); in dsa_switch_bridge_join()
104 if ((dst->index != info->tree_index || ds->index != info->sw_index) && in dsa_switch_bridge_join()
105 ds->ops->crosschip_bridge_join) { in dsa_switch_bridge_join()
106 err = ds->ops->crosschip_bridge_join(ds, info->tree_index, in dsa_switch_bridge_join()
107 info->sw_index, in dsa_switch_bridge_join()
108 info->port, info->br); in dsa_switch_bridge_join()
119 struct dsa_switch_tree *dst = ds->dst; in dsa_switch_bridge_leave()
125 if (dst->index == info->tree_index && ds->index == info->sw_index && in dsa_switch_bridge_leave()
126 ds->ops->port_bridge_leave) in dsa_switch_bridge_leave()
127 ds->ops->port_bridge_leave(ds, info->port, info->br); in dsa_switch_bridge_leave()
129 if ((dst->index != info->tree_index || ds->index != info->sw_index) && in dsa_switch_bridge_leave()
130 ds->ops->crosschip_bridge_leave) in dsa_switch_bridge_leave()
131 ds->ops->crosschip_bridge_leave(ds, info->tree_index, in dsa_switch_bridge_leave()
132 info->sw_index, info->port, in dsa_switch_bridge_leave()
133 info->br); in dsa_switch_bridge_leave()
135 if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) { in dsa_switch_bridge_leave()
138 } else if (!ds->needs_standalone_vlan_filtering && in dsa_switch_bridge_leave()
139 br_vlan_enabled(info->br)) { in dsa_switch_bridge_leave()
146 * it. That is a good thing, because that lets us handle it and also in dsa_switch_bridge_leave()
150 * VLAN-aware bridge. in dsa_switch_bridge_leave()
152 if (change_vlan_filtering && ds->vlan_filtering_is_global) { in dsa_switch_bridge_leave()
153 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_bridge_leave()
156 bridge_dev = dsa_to_port(ds, port)->bridge_dev; in dsa_switch_bridge_leave()
166 err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port), in dsa_switch_bridge_leave()
169 dev_err(ds->dev, "port %d: %s\n", info->port, in dsa_switch_bridge_leave()
171 if (err && err != -EOPNOTSUPP) in dsa_switch_bridge_leave()
178 /* Matches for all upstream-facing ports (the CPU port and all upstream-facing
188 targeted_ds = dsa_switch_find(ds->dst->index, info_sw_index); in dsa_switch_host_address_match()
190 cpu_dp = targeted_dp->cpu_dp; in dsa_switch_host_address_match()
193 return port == dsa_towards_port(ds, cpu_dp->ds->index, in dsa_switch_host_address_match()
194 cpu_dp->index); in dsa_switch_host_address_match()
203 struct dsa_mac_addr *a; in dsa_mac_addr_find() local
205 list_for_each_entry(a, addr_list, list) in dsa_mac_addr_find()
206 if (ether_addr_equal(a->addr, addr) && a->vid == vid) in dsa_mac_addr_find()
207 return a; in dsa_mac_addr_find()
216 struct dsa_mac_addr *a; in dsa_switch_do_mdb_add() local
221 return ds->ops->port_mdb_add(ds, port, mdb); in dsa_switch_do_mdb_add()
223 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid); in dsa_switch_do_mdb_add()
224 if (a) { in dsa_switch_do_mdb_add()
225 refcount_inc(&a->refcount); in dsa_switch_do_mdb_add()
229 a = kzalloc(sizeof(*a), GFP_KERNEL); in dsa_switch_do_mdb_add()
230 if (!a) in dsa_switch_do_mdb_add()
231 return -ENOMEM; in dsa_switch_do_mdb_add()
233 err = ds->ops->port_mdb_add(ds, port, mdb); in dsa_switch_do_mdb_add()
235 kfree(a); in dsa_switch_do_mdb_add()
239 ether_addr_copy(a->addr, mdb->addr); in dsa_switch_do_mdb_add()
240 a->vid = mdb->vid; in dsa_switch_do_mdb_add()
241 refcount_set(&a->refcount, 1); in dsa_switch_do_mdb_add()
242 list_add_tail(&a->list, &dp->mdbs); in dsa_switch_do_mdb_add()
251 struct dsa_mac_addr *a; in dsa_switch_do_mdb_del() local
256 return ds->ops->port_mdb_del(ds, port, mdb); in dsa_switch_do_mdb_del()
258 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid); in dsa_switch_do_mdb_del()
259 if (!a) in dsa_switch_do_mdb_del()
260 return -ENOENT; in dsa_switch_do_mdb_del()
262 if (!refcount_dec_and_test(&a->refcount)) in dsa_switch_do_mdb_del()
265 err = ds->ops->port_mdb_del(ds, port, mdb); in dsa_switch_do_mdb_del()
267 refcount_inc(&a->refcount); in dsa_switch_do_mdb_del()
271 list_del(&a->list); in dsa_switch_do_mdb_del()
272 kfree(a); in dsa_switch_do_mdb_del()
281 struct dsa_mac_addr *a; in dsa_switch_do_fdb_add() local
286 return ds->ops->port_fdb_add(ds, port, addr, vid); in dsa_switch_do_fdb_add()
288 a = dsa_mac_addr_find(&dp->fdbs, addr, vid); in dsa_switch_do_fdb_add()
289 if (a) { in dsa_switch_do_fdb_add()
290 refcount_inc(&a->refcount); in dsa_switch_do_fdb_add()
294 a = kzalloc(sizeof(*a), GFP_KERNEL); in dsa_switch_do_fdb_add()
295 if (!a) in dsa_switch_do_fdb_add()
296 return -ENOMEM; in dsa_switch_do_fdb_add()
298 err = ds->ops->port_fdb_add(ds, port, addr, vid); in dsa_switch_do_fdb_add()
300 kfree(a); in dsa_switch_do_fdb_add()
304 ether_addr_copy(a->addr, addr); in dsa_switch_do_fdb_add()
305 a->vid = vid; in dsa_switch_do_fdb_add()
306 refcount_set(&a->refcount, 1); in dsa_switch_do_fdb_add()
307 list_add_tail(&a->list, &dp->fdbs); in dsa_switch_do_fdb_add()
316 struct dsa_mac_addr *a; in dsa_switch_do_fdb_del() local
321 return ds->ops->port_fdb_del(ds, port, addr, vid); in dsa_switch_do_fdb_del()
323 a = dsa_mac_addr_find(&dp->fdbs, addr, vid); in dsa_switch_do_fdb_del()
324 if (!a) in dsa_switch_do_fdb_del()
325 return -ENOENT; in dsa_switch_do_fdb_del()
327 if (!refcount_dec_and_test(&a->refcount)) in dsa_switch_do_fdb_del()
330 err = ds->ops->port_fdb_del(ds, port, addr, vid); in dsa_switch_do_fdb_del()
332 refcount_inc(&a->refcount); in dsa_switch_do_fdb_del()
336 list_del(&a->list); in dsa_switch_do_fdb_del()
337 kfree(a); in dsa_switch_do_fdb_del()
348 if (!ds->ops->port_fdb_add) in dsa_switch_host_fdb_add()
349 return -EOPNOTSUPP; in dsa_switch_host_fdb_add()
351 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_host_fdb_add()
352 if (dsa_switch_host_address_match(ds, port, info->sw_index, in dsa_switch_host_fdb_add()
353 info->port)) { in dsa_switch_host_fdb_add()
354 err = dsa_switch_do_fdb_add(ds, port, info->addr, in dsa_switch_host_fdb_add()
355 info->vid); in dsa_switch_host_fdb_add()
370 if (!ds->ops->port_fdb_del) in dsa_switch_host_fdb_del()
371 return -EOPNOTSUPP; in dsa_switch_host_fdb_del()
373 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_host_fdb_del()
374 if (dsa_switch_host_address_match(ds, port, info->sw_index, in dsa_switch_host_fdb_del()
375 info->port)) { in dsa_switch_host_fdb_del()
376 err = dsa_switch_do_fdb_del(ds, port, info->addr, in dsa_switch_host_fdb_del()
377 info->vid); in dsa_switch_host_fdb_del()
389 int port = dsa_towards_port(ds, info->sw_index, info->port); in dsa_switch_fdb_add()
391 if (!ds->ops->port_fdb_add) in dsa_switch_fdb_add()
392 return -EOPNOTSUPP; in dsa_switch_fdb_add()
394 return dsa_switch_do_fdb_add(ds, port, info->addr, info->vid); in dsa_switch_fdb_add()
400 int port = dsa_towards_port(ds, info->sw_index, info->port); in dsa_switch_fdb_del()
402 if (!ds->ops->port_fdb_del) in dsa_switch_fdb_del()
403 return -EOPNOTSUPP; in dsa_switch_fdb_del()
405 return dsa_switch_do_fdb_del(ds, port, info->addr, info->vid); in dsa_switch_fdb_del()
411 if (ds->index == info->sw_index && ds->ops->port_hsr_join) in dsa_switch_hsr_join()
412 return ds->ops->port_hsr_join(ds, info->port, info->hsr); in dsa_switch_hsr_join()
414 return -EOPNOTSUPP; in dsa_switch_hsr_join()
420 if (ds->index == info->sw_index && ds->ops->port_hsr_leave) in dsa_switch_hsr_leave()
421 return ds->ops->port_hsr_leave(ds, info->port, info->hsr); in dsa_switch_hsr_leave()
423 return -EOPNOTSUPP; in dsa_switch_hsr_leave()
429 if (ds->index == info->sw_index && ds->ops->port_lag_change) in dsa_switch_lag_change()
430 return ds->ops->port_lag_change(ds, info->port); in dsa_switch_lag_change()
432 if (ds->index != info->sw_index && ds->ops->crosschip_lag_change) in dsa_switch_lag_change()
433 return ds->ops->crosschip_lag_change(ds, info->sw_index, in dsa_switch_lag_change()
434 info->port); in dsa_switch_lag_change()
442 if (ds->index == info->sw_index && ds->ops->port_lag_join) in dsa_switch_lag_join()
443 return ds->ops->port_lag_join(ds, info->port, info->lag, in dsa_switch_lag_join()
444 info->info); in dsa_switch_lag_join()
446 if (ds->index != info->sw_index && ds->ops->crosschip_lag_join) in dsa_switch_lag_join()
447 return ds->ops->crosschip_lag_join(ds, info->sw_index, in dsa_switch_lag_join()
448 info->port, info->lag, in dsa_switch_lag_join()
449 info->info); in dsa_switch_lag_join()
451 return -EOPNOTSUPP; in dsa_switch_lag_join()
457 if (ds->index == info->sw_index && ds->ops->port_lag_leave) in dsa_switch_lag_leave()
458 return ds->ops->port_lag_leave(ds, info->port, info->lag); in dsa_switch_lag_leave()
460 if (ds->index != info->sw_index && ds->ops->crosschip_lag_leave) in dsa_switch_lag_leave()
461 return ds->ops->crosschip_lag_leave(ds, info->sw_index, in dsa_switch_lag_leave()
462 info->port, info->lag); in dsa_switch_lag_leave()
464 return -EOPNOTSUPP; in dsa_switch_lag_leave()
470 int port = dsa_towards_port(ds, info->sw_index, info->port); in dsa_switch_mdb_add()
472 if (!ds->ops->port_mdb_add) in dsa_switch_mdb_add()
473 return -EOPNOTSUPP; in dsa_switch_mdb_add()
475 return dsa_switch_do_mdb_add(ds, port, info->mdb); in dsa_switch_mdb_add()
481 int port = dsa_towards_port(ds, info->sw_index, info->port); in dsa_switch_mdb_del()
483 if (!ds->ops->port_mdb_del) in dsa_switch_mdb_del()
484 return -EOPNOTSUPP; in dsa_switch_mdb_del()
486 return dsa_switch_do_mdb_del(ds, port, info->mdb); in dsa_switch_mdb_del()
495 if (!ds->ops->port_mdb_add) in dsa_switch_host_mdb_add()
496 return -EOPNOTSUPP; in dsa_switch_host_mdb_add()
498 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_host_mdb_add()
499 if (dsa_switch_host_address_match(ds, port, info->sw_index, in dsa_switch_host_mdb_add()
500 info->port)) { in dsa_switch_host_mdb_add()
501 err = dsa_switch_do_mdb_add(ds, port, info->mdb); in dsa_switch_host_mdb_add()
516 if (!ds->ops->port_mdb_del) in dsa_switch_host_mdb_del()
517 return -EOPNOTSUPP; in dsa_switch_host_mdb_del()
519 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_host_mdb_del()
520 if (dsa_switch_host_address_match(ds, port, info->sw_index, in dsa_switch_host_mdb_del()
521 info->port)) { in dsa_switch_host_mdb_del()
522 err = dsa_switch_do_mdb_del(ds, port, info->mdb); in dsa_switch_host_mdb_del()
534 if (ds->index == info->sw_index && port == info->port) in dsa_switch_vlan_match()
548 if (!ds->ops->port_vlan_add) in dsa_switch_vlan_add()
549 return -EOPNOTSUPP; in dsa_switch_vlan_add()
551 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_vlan_add()
553 err = ds->ops->port_vlan_add(ds, port, info->vlan, in dsa_switch_vlan_add()
554 info->extack); in dsa_switch_vlan_add()
566 if (!ds->ops->port_vlan_del) in dsa_switch_vlan_del()
567 return -EOPNOTSUPP; in dsa_switch_vlan_del()
569 if (ds->index == info->sw_index) in dsa_switch_vlan_del()
570 return ds->ops->port_vlan_del(ds, info->port, info->vlan); in dsa_switch_vlan_del()
581 const struct dsa_device_ops *tag_ops = info->tag_ops; in dsa_switch_change_tag_proto()
584 if (!ds->ops->change_tag_protocol) in dsa_switch_change_tag_proto()
585 return -EOPNOTSUPP; in dsa_switch_change_tag_proto()
589 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_change_tag_proto()
593 err = ds->ops->change_tag_protocol(ds, port, tag_ops->proto); in dsa_switch_change_tag_proto()
604 for (port = 0; port < ds->num_ports; port++) { in dsa_switch_change_tag_proto()
608 slave = dsa_to_port(ds, port)->slave; in dsa_switch_change_tag_proto()
612 dsa_slave_change_mtu(slave, slave->mtu); in dsa_switch_change_tag_proto()
622 if (!ds->ops->port_mrp_add) in dsa_switch_mrp_add()
623 return -EOPNOTSUPP; in dsa_switch_mrp_add()
625 if (ds->index == info->sw_index) in dsa_switch_mrp_add()
626 return ds->ops->port_mrp_add(ds, info->port, info->mrp); in dsa_switch_mrp_add()
634 if (!ds->ops->port_mrp_del) in dsa_switch_mrp_del()
635 return -EOPNOTSUPP; in dsa_switch_mrp_del()
637 if (ds->index == info->sw_index) in dsa_switch_mrp_del()
638 return ds->ops->port_mrp_del(ds, info->port, info->mrp); in dsa_switch_mrp_del()
647 if (!ds->ops->port_mrp_add) in dsa_switch_mrp_add_ring_role()
648 return -EOPNOTSUPP; in dsa_switch_mrp_add_ring_role()
650 if (ds->index == info->sw_index) in dsa_switch_mrp_add_ring_role()
651 return ds->ops->port_mrp_add_ring_role(ds, info->port, in dsa_switch_mrp_add_ring_role()
652 info->mrp); in dsa_switch_mrp_add_ring_role()
661 if (!ds->ops->port_mrp_del) in dsa_switch_mrp_del_ring_role()
662 return -EOPNOTSUPP; in dsa_switch_mrp_del_ring_role()
664 if (ds->index == info->sw_index) in dsa_switch_mrp_del_ring_role()
665 return ds->ops->port_mrp_del_ring_role(ds, info->port, in dsa_switch_mrp_del_ring_role()
666 info->mrp); in dsa_switch_mrp_del_ring_role()
757 err = -EOPNOTSUPP; in dsa_switch_event()
762 dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n", in dsa_switch_event()
770 ds->nb.notifier_call = dsa_switch_event; in dsa_switch_register_notifier()
772 return raw_notifier_chain_register(&ds->dst->nh, &ds->nb); in dsa_switch_register_notifier()
779 err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb); in dsa_switch_unregister_notifier()
781 dev_err(ds->dev, "failed to unregister notifier (%d)\n", err); in dsa_switch_unregister_notifier()