Lines Matching +full:bridge +full:- +full:enable

1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
52 struct prestera_bridge *bridge; member
82 struct prestera_bridge *bridge; member
100 struct prestera_bridge *bridge; in prestera_bridge_find() local
102 list_for_each_entry(bridge, &sw->swdev->bridge_list, head) in prestera_bridge_find()
103 if (bridge->dev == br_dev) in prestera_bridge_find()
104 return bridge; in prestera_bridge_find()
110 __prestera_bridge_port_find(const struct prestera_bridge *bridge, in __prestera_bridge_port_find() argument
115 list_for_each_entry(br_port, &bridge->port_list, head) in __prestera_bridge_port_find()
116 if (br_port->dev == brport_dev) in __prestera_bridge_port_find()
127 struct prestera_bridge *bridge; in prestera_bridge_port_find() local
132 bridge = prestera_bridge_find(sw, br_dev); in prestera_bridge_port_find()
133 if (!bridge) in prestera_bridge_port_find()
136 return __prestera_bridge_port_find(bridge, brport_dev); in prestera_bridge_port_find()
154 err = prestera_port_uc_flood_set(port, br_port->flags & BR_FLOOD); in prestera_br_port_flags_set()
158 err = prestera_port_mc_flood_set(port, br_port->flags & BR_MCAST_FLOOD); in prestera_br_port_flags_set()
162 err = prestera_port_learning_set(port, br_port->flags & BR_LEARNING); in prestera_br_port_flags_set()
167 br_port->flags & BR_PORT_LOCKED); in prestera_br_port_flags_set()
187 INIT_LIST_HEAD(&br_vlan->port_vlan_list); in prestera_bridge_vlan_create()
188 br_vlan->vid = vid; in prestera_bridge_vlan_create()
189 list_add(&br_vlan->head, &br_port->vlan_list); in prestera_bridge_vlan_create()
196 list_del(&br_vlan->head); in prestera_bridge_vlan_destroy()
197 WARN_ON(!list_empty(&br_vlan->port_vlan_list)); in prestera_bridge_vlan_destroy()
206 list_for_each_entry(br_vlan, &br_port->vlan_list, head) { in prestera_bridge_vlan_by_vid()
207 if (br_vlan->vid == vid) in prestera_bridge_vlan_by_vid()
214 static int prestera_bridge_vlan_port_count(struct prestera_bridge *bridge, in prestera_bridge_vlan_port_count() argument
221 list_for_each_entry(br_port, &bridge->port_list, head) { in prestera_bridge_vlan_port_count()
222 list_for_each_entry(br_vlan, &br_port->vlan_list, head) { in prestera_bridge_vlan_port_count()
223 if (br_vlan->vid == vid) { in prestera_bridge_vlan_port_count()
235 if (list_empty(&br_vlan->port_vlan_list)) in prestera_bridge_vlan_put()
244 list_for_each_entry(port_vlan, &port->vlans_list, port_head) { in prestera_port_vlan_by_vid()
245 if (port_vlan->vid == vid) in prestera_port_vlan_by_vid()
260 return ERR_PTR(-EEXIST); in prestera_port_vlan_create()
268 err = -ENOMEM; in prestera_port_vlan_create()
272 port_vlan->port = port; in prestera_port_vlan_create()
273 port_vlan->vid = vid; in prestera_port_vlan_create()
275 list_add(&port_vlan->port_head, &port->vlans_list); in prestera_port_vlan_create()
288 return prestera_hw_lag_fdb_add(port->sw, prestera_port_lag_id(port), in prestera_fdb_add()
298 return prestera_hw_lag_fdb_del(port->sw, prestera_port_lag_id(port), in prestera_fdb_del()
308 return prestera_hw_fdb_flush_lag_vlan(port->sw, prestera_port_lag_id(port), in prestera_fdb_flush_port_vlan()
317 return prestera_hw_fdb_flush_lag(port->sw, prestera_port_lag_id(port), in prestera_fdb_flush_port()
327 struct prestera_flood_domain *fl_domain = mdb->flood_domain; in prestera_mdb_port_del()
332 mdb->vid); in prestera_mdb_port_del()
342 if (list_empty(&br_mdb->br_mdb_port_list)) { in prestera_br_mdb_entry_put()
343 list_for_each_entry(br_port, &br_mdb->bridge->port_list, head) in prestera_br_mdb_entry_put()
344 prestera_mdb_port_del(br_mdb->mdb, br_port->dev); in prestera_br_mdb_entry_put()
346 prestera_mdb_entry_destroy(br_mdb->mdb); in prestera_br_mdb_entry_put()
347 list_del(&br_mdb->br_mdb_entry_node); in prestera_br_mdb_entry_put()
358 list_for_each_entry_safe(br_mdb_port, tmp, &br_mdb->br_mdb_port_list, in prestera_br_mdb_port_del()
360 if (br_mdb_port->br_port == br_port) { in prestera_br_mdb_port_del()
361 list_del(&br_mdb_port->br_mdb_port_node); in prestera_br_mdb_port_del()
372 struct prestera_bridge *br_dev = br_port->bridge; in prestera_mdb_flush_bridge_port()
374 list_for_each_entry_safe(br_mdb, br_mdb_tmp, &br_dev->br_mdb_entry_list, in prestera_mdb_flush_bridge_port()
377 &br_mdb->br_mdb_port_list, in prestera_mdb_flush_bridge_port()
379 prestera_mdb_port_del(br_mdb->mdb, in prestera_mdb_flush_bridge_port()
380 br_mdb_port->br_port->dev); in prestera_mdb_flush_bridge_port()
381 prestera_br_mdb_port_del(br_mdb, br_mdb_port->br_port); in prestera_mdb_flush_bridge_port()
391 struct prestera_port *port = port_vlan->port; in prestera_port_vlan_bridge_leave()
395 u16 vid = port_vlan->vid; in prestera_port_vlan_bridge_leave()
398 br_port = port_vlan->br_port; in prestera_port_vlan_bridge_leave()
399 port_count = prestera_bridge_vlan_port_count(br_port->bridge, vid); in prestera_port_vlan_bridge_leave()
402 last_vlan = list_is_singular(&br_port->vlan_list); in prestera_port_vlan_bridge_leave()
408 prestera_hw_fdb_flush_vlan(port->sw, vid, fdb_flush_mode); in prestera_port_vlan_bridge_leave()
414 list_del(&port_vlan->br_vlan_head); in prestera_port_vlan_bridge_leave()
417 port_vlan->br_port = NULL; in prestera_port_vlan_bridge_leave()
422 struct prestera_port *port = port_vlan->port; in prestera_port_vlan_destroy()
423 u16 vid = port_vlan->vid; in prestera_port_vlan_destroy()
425 if (port_vlan->br_port) in prestera_port_vlan_destroy()
429 list_del(&port_vlan->port_head); in prestera_port_vlan_destroy()
437 struct prestera_bridge *bridge; in prestera_bridge_create() local
441 if (vlan_enabled && swdev->bridge_8021q_exists) { in prestera_bridge_create()
442 netdev_err(dev, "Only one VLAN-aware bridge is supported\n"); in prestera_bridge_create()
443 return ERR_PTR(-EINVAL); in prestera_bridge_create()
446 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); in prestera_bridge_create()
447 if (!bridge) in prestera_bridge_create()
448 return ERR_PTR(-ENOMEM); in prestera_bridge_create()
451 swdev->bridge_8021q_exists = true; in prestera_bridge_create()
453 err = prestera_hw_bridge_create(swdev->sw, &bridge_id); in prestera_bridge_create()
455 kfree(bridge); in prestera_bridge_create()
459 bridge->bridge_id = bridge_id; in prestera_bridge_create()
462 bridge->vlan_enabled = vlan_enabled; in prestera_bridge_create()
463 bridge->swdev = swdev; in prestera_bridge_create()
464 bridge->dev = dev; in prestera_bridge_create()
465 bridge->multicast_enabled = br_multicast_enabled(dev); in prestera_bridge_create()
467 INIT_LIST_HEAD(&bridge->port_list); in prestera_bridge_create()
468 INIT_LIST_HEAD(&bridge->br_mdb_entry_list); in prestera_bridge_create()
470 list_add(&bridge->head, &swdev->bridge_list); in prestera_bridge_create()
472 return bridge; in prestera_bridge_create()
475 static void prestera_bridge_destroy(struct prestera_bridge *bridge) in prestera_bridge_destroy() argument
477 struct prestera_switchdev *swdev = bridge->swdev; in prestera_bridge_destroy()
479 list_del(&bridge->head); in prestera_bridge_destroy()
481 if (bridge->vlan_enabled) in prestera_bridge_destroy()
482 swdev->bridge_8021q_exists = false; in prestera_bridge_destroy()
484 prestera_hw_bridge_delete(swdev->sw, bridge->bridge_id); in prestera_bridge_destroy()
486 WARN_ON(!list_empty(&bridge->br_mdb_entry_list)); in prestera_bridge_destroy()
487 WARN_ON(!list_empty(&bridge->port_list)); in prestera_bridge_destroy()
488 kfree(bridge); in prestera_bridge_destroy()
491 static void prestera_bridge_put(struct prestera_bridge *bridge) in prestera_bridge_put() argument
493 if (list_empty(&bridge->port_list)) in prestera_bridge_put()
494 prestera_bridge_destroy(bridge); in prestera_bridge_put()
501 struct prestera_bridge *bridge; in prestera_bridge_by_dev() local
503 list_for_each_entry(bridge, &swdev->bridge_list, head) in prestera_bridge_by_dev()
504 if (bridge->dev == dev) in prestera_bridge_by_dev()
505 return bridge; in prestera_bridge_by_dev()
511 __prestera_bridge_port_by_dev(struct prestera_bridge *bridge, in __prestera_bridge_port_by_dev() argument
516 list_for_each_entry(br_port, &bridge->port_list, head) { in __prestera_bridge_port_by_dev()
517 if (br_port->dev == dev) in __prestera_bridge_port_by_dev()
528 priv->data = dev; in prestera_match_upper_bridge_dev()
547 struct prestera_bridge *bridge; in prestera_bridge_port_by_dev() local
552 bridge = prestera_bridge_by_dev(swdev, br_dev); in prestera_bridge_port_by_dev()
553 if (!bridge) in prestera_bridge_port_by_dev()
556 return __prestera_bridge_port_by_dev(bridge, dev); in prestera_bridge_port_by_dev()
560 prestera_bridge_port_create(struct prestera_bridge *bridge, in prestera_bridge_port_create() argument
569 br_port->flags = BR_LEARNING | BR_FLOOD | BR_LEARNING_SYNC | in prestera_bridge_port_create()
571 br_port->stp_state = BR_STATE_DISABLED; in prestera_bridge_port_create()
572 refcount_set(&br_port->ref_count, 1); in prestera_bridge_port_create()
573 br_port->bridge = bridge; in prestera_bridge_port_create()
574 br_port->dev = dev; in prestera_bridge_port_create()
576 INIT_LIST_HEAD(&br_port->vlan_list); in prestera_bridge_port_create()
577 list_add(&br_port->head, &bridge->port_list); in prestera_bridge_port_create()
578 INIT_LIST_HEAD(&br_port->br_mdb_port_list); in prestera_bridge_port_create()
586 list_del(&br_port->head); in prestera_bridge_port_destroy()
587 WARN_ON(!list_empty(&br_port->vlan_list)); in prestera_bridge_port_destroy()
588 WARN_ON(!list_empty(&br_port->br_mdb_port_list)); in prestera_bridge_port_destroy()
594 refcount_inc(&br_port->ref_count); in prestera_bridge_port_get()
599 struct prestera_bridge *bridge = br_port->bridge; in prestera_bridge_port_put() local
601 if (refcount_dec_and_test(&br_port->ref_count)) { in prestera_bridge_port_put()
603 prestera_bridge_put(bridge); in prestera_bridge_port_put()
608 prestera_bridge_port_add(struct prestera_bridge *bridge, struct net_device *dev) in prestera_bridge_port_add() argument
612 br_port = __prestera_bridge_port_by_dev(bridge, dev); in prestera_bridge_port_add()
618 br_port = prestera_bridge_port_create(bridge, dev); in prestera_bridge_port_add()
620 return ERR_PTR(-ENOMEM); in prestera_bridge_port_add()
628 struct prestera_port *port = netdev_priv(br_port->dev); in prestera_bridge_1d_port_join()
629 struct prestera_bridge *bridge = br_port->bridge; in prestera_bridge_1d_port_join() local
632 err = prestera_hw_bridge_port_add(port, bridge->bridge_id); in prestera_bridge_1d_port_join()
643 prestera_hw_bridge_port_delete(port, bridge->bridge_id); in prestera_bridge_1d_port_join()
652 struct prestera_switchdev *swdev = port->sw->swdev; in prestera_bridge_port_join()
654 struct prestera_bridge *bridge; in prestera_bridge_port_join() local
657 bridge = prestera_bridge_by_dev(swdev, br_dev); in prestera_bridge_port_join()
658 if (!bridge) { in prestera_bridge_port_join()
659 bridge = prestera_bridge_create(swdev, br_dev); in prestera_bridge_port_join()
660 if (IS_ERR(bridge)) in prestera_bridge_port_join()
661 return PTR_ERR(bridge); in prestera_bridge_port_join()
664 br_port = prestera_bridge_port_add(bridge, port->dev); in prestera_bridge_port_join()
666 prestera_bridge_put(bridge); in prestera_bridge_port_join()
670 err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL, in prestera_bridge_port_join()
675 if (bridge->vlan_enabled) in prestera_bridge_port_join()
685 switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL); in prestera_bridge_port_join()
693 struct prestera_port *port = netdev_priv(br_port->dev); in prestera_bridge_1q_port_leave()
701 struct prestera_port *port = netdev_priv(br_port->dev); in prestera_bridge_1d_port_leave()
704 prestera_hw_bridge_port_delete(port, br_port->bridge->bridge_id); in prestera_bridge_1d_port_leave()
731 return -EINVAL; in prestera_port_vid_stp_set()
740 struct prestera_switchdev *swdev = port->sw->swdev; in prestera_bridge_port_leave()
742 struct prestera_bridge *bridge; in prestera_bridge_port_leave() local
744 bridge = prestera_bridge_by_dev(swdev, br_dev); in prestera_bridge_port_leave()
745 if (!bridge) in prestera_bridge_port_leave()
748 br_port = __prestera_bridge_port_by_dev(bridge, port->dev); in prestera_bridge_port_leave()
752 bridge = br_port->bridge; in prestera_bridge_port_leave()
754 if (bridge->vlan_enabled) in prestera_bridge_port_leave()
759 switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL); in prestera_bridge_port_leave()
774 br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev); in prestera_port_attr_br_flags_set()
778 br_port->flags &= ~flags.mask; in prestera_port_attr_br_flags_set()
779 br_port->flags |= flags.val & flags.mask; in prestera_port_attr_br_flags_set()
788 struct prestera_switch *sw = port->sw; in prestera_port_attr_br_ageing_set()
792 return -ERANGE; in prestera_port_attr_br_ageing_set()
801 struct prestera_switch *sw = port->sw; in prestera_port_attr_br_vlan_set()
802 struct prestera_bridge *bridge; in prestera_port_attr_br_vlan_set() local
804 bridge = prestera_bridge_by_dev(sw->swdev, dev); in prestera_port_attr_br_vlan_set()
805 if (WARN_ON(!bridge)) in prestera_port_attr_br_vlan_set()
806 return -EINVAL; in prestera_port_attr_br_vlan_set()
808 if (bridge->vlan_enabled == vlan_enabled) in prestera_port_attr_br_vlan_set()
811 netdev_err(bridge->dev, "VLAN filtering can't be changed for existing bridge\n"); in prestera_port_attr_br_vlan_set()
813 return -EINVAL; in prestera_port_attr_br_vlan_set()
822 list_for_each_entry(port_vlan, &br_vlan->port_vlan_list, br_vlan_head) { in prestera_port_bridge_vlan_stp_set()
823 if (port_vlan->port != port) in prestera_port_bridge_vlan_stp_set()
826 return prestera_port_vid_stp_set(port, br_vlan->vid, state); in prestera_port_bridge_vlan_stp_set()
841 br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev); in prestera_port_attr_stp_state_set()
845 if (!br_port->bridge->vlan_enabled) { in prestera_port_attr_stp_state_set()
846 vid = br_port->bridge->bridge_id; in prestera_port_attr_stp_state_set()
851 list_for_each_entry(br_vlan, &br_port->vlan_list, head) { in prestera_port_attr_stp_state_set()
859 br_port->stp_state = state; in prestera_port_attr_stp_state_set()
864 list_for_each_entry_continue_reverse(br_vlan, &br_port->vlan_list, head) in prestera_port_attr_stp_state_set()
865 prestera_port_bridge_vlan_stp_set(port, br_vlan, br_port->stp_state); in prestera_port_attr_stp_state_set()
869 prestera_port_vid_stp_set(port, vid, br_port->stp_state); in prestera_port_attr_stp_state_set()
883 pr_port = prestera_port_dev_lower_find(br_port->dev); in prestera_br_port_lag_mdb_mc_enable_sync()
887 sw = pr_port->sw; in prestera_br_port_lag_mdb_mc_enable_sync()
888 err = prestera_lag_id(sw, br_port->dev, &lag_id); in prestera_br_port_lag_mdb_mc_enable_sync()
892 list_for_each_entry(pr_port, &sw->port_list, list) { in prestera_br_port_lag_mdb_mc_enable_sync()
893 if (pr_port->lag->lag_id == lag_id) { in prestera_br_port_lag_mdb_mc_enable_sync()
911 * - make sure every mrouter receives unreg mcast traffic; in prestera_br_mdb_mc_enable_sync()
913 * - make sure every port receives unreg mcast traffic; in prestera_br_mdb_mc_enable_sync()
915 list_for_each_entry(br_port, &br_dev->port_list, head) { in prestera_br_mdb_mc_enable_sync()
916 if (br_dev->multicast_enabled && br_dev->mrouter_exist) in prestera_br_mdb_mc_enable_sync()
917 enabled = br_port->mrouter; in prestera_br_mdb_mc_enable_sync()
919 enabled = br_port->flags & BR_MCAST_FLOOD; in prestera_br_mdb_mc_enable_sync()
921 if (netif_is_lag_master(br_port->dev)) { in prestera_br_mdb_mc_enable_sync()
929 port = prestera_port_dev_lower_find(br_port->dev); in prestera_br_mdb_mc_enable_sync()
947 list_for_each_entry(tmp_port, &br_mdb->br_mdb_port_list, in prestera_br_mdb_port_is_member()
949 if (tmp_port->br_port->dev == orig_dev) in prestera_br_mdb_port_is_member()
960 struct prestera_flood_domain *flood_domain = mdb->flood_domain; in prestera_mdb_port_add()
974 /* Sync bridge mdb (software table) with HW table (if MC is enabled). */
984 if (!br_dev->multicast_enabled) in prestera_br_mdb_sync()
987 list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list, in prestera_br_mdb_sync()
989 mdb = br_mdb->mdb; in prestera_br_mdb_sync()
993 list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list, in prestera_br_mdb_sync()
995 br_port = br_mdb_port->br_port; in prestera_br_mdb_sync()
996 pr_port = prestera_port_dev_lower_find(br_port->dev); in prestera_br_mdb_sync()
1001 if (br_dev->vlan_enabled && in prestera_br_mdb_sync()
1003 mdb->vid)) in prestera_br_mdb_sync()
1010 br_mdb_port->br_port->dev) && in prestera_br_mdb_sync()
1011 br_dev->mrouter_exist) in prestera_br_mdb_sync()
1012 err = prestera_mdb_port_add(mdb, br_port->dev, in prestera_br_mdb_sync()
1013 mdb->addr, in prestera_br_mdb_sync()
1014 mdb->vid); in prestera_br_mdb_sync()
1016 prestera_mdb_port_del(mdb, br_port->dev); in prestera_br_mdb_sync()
1023 * broadcast domain. If it's not an mrouter - it should leave in prestera_br_mdb_sync()
1025 list_for_each_entry(br_port, &br_dev->port_list, head) { in prestera_br_mdb_sync()
1026 pr_port = prestera_port_dev_lower_find(br_port->dev); in prestera_br_mdb_sync()
1032 if (br_dev->vlan_enabled && in prestera_br_mdb_sync()
1034 mdb->vid)) in prestera_br_mdb_sync()
1037 if (br_port->mrouter) { in prestera_br_mdb_sync()
1038 err = prestera_mdb_port_add(mdb, br_port->dev, in prestera_br_mdb_sync()
1039 mdb->addr, in prestera_br_mdb_sync()
1040 mdb->vid); in prestera_br_mdb_sync()
1043 } else if (!br_port->mrouter && in prestera_br_mdb_sync()
1045 (br_mdb, br_port->dev)) { in prestera_br_mdb_sync()
1046 prestera_mdb_port_del(mdb, br_port->dev); in prestera_br_mdb_sync()
1055 prestera_mdb_enable_set(struct prestera_br_mdb_entry *br_mdb, bool enable) in prestera_mdb_enable_set() argument
1059 if (enable != br_mdb->enabled) { in prestera_mdb_enable_set()
1060 if (enable) in prestera_mdb_enable_set()
1061 err = prestera_hw_mdb_create(br_mdb->mdb); in prestera_mdb_enable_set()
1063 err = prestera_hw_mdb_destroy(br_mdb->mdb); in prestera_mdb_enable_set()
1068 br_mdb->enabled = enable; in prestera_mdb_enable_set()
1075 prestera_br_mdb_enable_set(struct prestera_bridge *br_dev, bool enable) in prestera_br_mdb_enable_set() argument
1080 list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list, in prestera_br_mdb_enable_set()
1082 err = prestera_mdb_enable_set(br_mdb, enable); in prestera_br_mdb_enable_set()
1094 struct prestera_switch *sw = port->sw; in prestera_port_attr_br_mc_disabled_set()
1101 br_dev->multicast_enabled = !mc_disabled; in prestera_port_attr_br_mc_disabled_set()
1104 WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled && in prestera_port_attr_br_mc_disabled_set()
1105 br_dev->mrouter_exist)); in prestera_port_attr_br_mc_disabled_set()
1119 list_for_each_entry(br_port, &br_dev->port_list, head) in prestera_bridge_mdb_mc_mrouter_exists()
1120 if (br_port->mrouter) in prestera_bridge_mdb_mc_mrouter_exists()
1134 br_port = prestera_bridge_port_find(port->sw, orig_dev); in prestera_port_attr_mrouter_set()
1138 br_dev = br_port->bridge; in prestera_port_attr_mrouter_set()
1139 br_port->mrouter = is_port_mrouter; in prestera_port_attr_mrouter_set()
1141 br_dev->mrouter_exist = prestera_bridge_mdb_mc_mrouter_exists(br_dev); in prestera_port_attr_mrouter_set()
1143 /* Enable MDB processing if both mrouter exists and mc is enabled. in prestera_port_attr_mrouter_set()
1146 * of bridge's flood capabilities (without the use of flood_domain). in prestera_port_attr_mrouter_set()
1148 WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled && in prestera_port_attr_mrouter_set()
1149 br_dev->mrouter_exist)); in prestera_port_attr_mrouter_set()
1165 switch (attr->id) { in prestera_port_obj_attr_set()
1167 err = prestera_port_attr_stp_state_set(port, attr->orig_dev, in prestera_port_obj_attr_set()
1168 attr->u.stp_state); in prestera_port_obj_attr_set()
1171 if (attr->u.brport_flags.mask & in prestera_port_obj_attr_set()
1173 err = -EINVAL; in prestera_port_obj_attr_set()
1176 err = prestera_port_attr_br_flags_set(port, attr->orig_dev, in prestera_port_obj_attr_set()
1177 attr->u.brport_flags); in prestera_port_obj_attr_set()
1181 attr->u.ageing_time); in prestera_port_obj_attr_set()
1184 err = prestera_port_attr_br_vlan_set(port, attr->orig_dev, in prestera_port_obj_attr_set()
1185 attr->u.vlan_filtering); in prestera_port_obj_attr_set()
1188 err = prestera_port_attr_mrouter_set(port, attr->orig_dev, in prestera_port_obj_attr_set()
1189 attr->u.mrouter); in prestera_port_obj_attr_set()
1192 err = prestera_port_attr_br_mc_disabled_set(port, attr->orig_dev, in prestera_port_obj_attr_set()
1193 attr->u.mc_disabled); in prestera_port_obj_attr_set()
1196 err = -EOPNOTSUPP; in prestera_port_obj_attr_set()
1208 send_info.addr = info->addr; in prestera_fdb_offload_notify()
1209 send_info.vid = info->vid; in prestera_fdb_offload_notify()
1212 call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, port->dev, in prestera_fdb_offload_notify()
1220 struct prestera_switch *sw = port->sw; in prestera_port_fdb_set()
1222 struct prestera_bridge *bridge; in prestera_port_fdb_set() local
1226 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev); in prestera_port_fdb_set()
1228 return -EINVAL; in prestera_port_fdb_set()
1230 bridge = br_port->bridge; in prestera_port_fdb_set()
1232 if (bridge->vlan_enabled) in prestera_port_fdb_set()
1233 vid = fdb_info->vid; in prestera_port_fdb_set()
1235 vid = bridge->bridge_id; in prestera_port_fdb_set()
1238 err = prestera_fdb_add(port, fdb_info->addr, vid, false); in prestera_port_fdb_set()
1240 err = prestera_fdb_del(port, fdb_info->addr, vid); in prestera_port_fdb_set()
1254 dev = swdev_work->dev; in prestera_fdb_event_work()
1262 switch (swdev_work->event) { in prestera_fdb_event_work()
1264 fdb_info = &swdev_work->fdb_info; in prestera_fdb_event_work()
1265 if (!fdb_info->added_by_user || fdb_info->is_local) in prestera_fdb_event_work()
1276 fdb_info = &swdev_work->fdb_info; in prestera_fdb_event_work()
1284 kfree(swdev_work->fdb_info.addr); in prestera_fdb_event_work()
1320 swdev_work->event = event; in prestera_switchdev_event()
1321 swdev_work->dev = dev; in prestera_switchdev_event()
1330 INIT_WORK(&swdev_work->work, prestera_fdb_event_work); in prestera_switchdev_event()
1331 memcpy(&swdev_work->fdb_info, ptr, in prestera_switchdev_event()
1332 sizeof(swdev_work->fdb_info)); in prestera_switchdev_event()
1334 swdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC); in prestera_switchdev_event()
1335 if (!swdev_work->fdb_info.addr) in prestera_switchdev_event()
1338 ether_addr_copy((u8 *)swdev_work->fdb_info.addr, in prestera_switchdev_event()
1339 fdb_info->addr); in prestera_switchdev_event()
1348 queue_work(swdev_wq, &swdev_work->work); in prestera_switchdev_event()
1360 struct prestera_port *port = port_vlan->port; in prestera_port_vlan_bridge_join()
1362 u16 vid = port_vlan->vid; in prestera_port_vlan_bridge_join()
1365 if (port_vlan->br_port) in prestera_port_vlan_bridge_join()
1372 err = prestera_port_vid_stp_set(port, vid, br_port->stp_state); in prestera_port_vlan_bridge_join()
1380 err = -ENOMEM; in prestera_port_vlan_bridge_join()
1385 list_add(&port_vlan->br_vlan_head, &br_vlan->port_vlan_list); in prestera_port_vlan_bridge_join()
1388 port_vlan->br_port = br_port; in prestera_port_vlan_bridge_join()
1407 u16 old_pvid = port->pvid; in prestera_bridge_port_vlan_add()
1414 pvid = port->pvid == vid ? 0 : port->pvid; in prestera_bridge_port_vlan_add()
1417 if (port_vlan && port_vlan->br_port != br_port) in prestera_bridge_port_vlan_add()
1418 return -EEXIST; in prestera_bridge_port_vlan_add()
1454 u16 pvid = port->pvid == vid ? 0 : port->pvid; in prestera_bridge_port_vlan_del()
1470 bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; in prestera_port_vlans_add()
1471 bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; in prestera_port_vlans_add()
1472 struct net_device *orig_dev = vlan->obj.orig_dev; in prestera_port_vlans_add()
1474 struct prestera_switch *sw = port->sw; in prestera_port_vlans_add()
1475 struct prestera_bridge *bridge; in prestera_port_vlans_add() local
1480 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev); in prestera_port_vlans_add()
1482 return -EINVAL; in prestera_port_vlans_add()
1484 bridge = br_port->bridge; in prestera_port_vlans_add()
1485 if (!bridge->vlan_enabled) in prestera_port_vlans_add()
1489 vlan->vid, flag_untagged, in prestera_port_vlans_add()
1509 br_mdb_entry->mdb = mdb_entry; in prestera_br_mdb_entry_create()
1510 br_mdb_entry->bridge = br_dev; in prestera_br_mdb_entry_create()
1511 br_mdb_entry->enabled = true; in prestera_br_mdb_entry_create()
1512 INIT_LIST_HEAD(&br_mdb_entry->br_mdb_port_list); in prestera_br_mdb_entry_create()
1514 list_add(&br_mdb_entry->br_mdb_entry_node, &br_dev->br_mdb_entry_list); in prestera_br_mdb_entry_create()
1528 list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list, in prestera_br_mdb_port_add()
1530 if (br_mdb_port->br_port == br_port) in prestera_br_mdb_port_add()
1535 return -ENOMEM; in prestera_br_mdb_port_add()
1537 br_mdb_port->br_port = br_port; in prestera_br_mdb_port_add()
1538 list_add(&br_mdb_port->br_mdb_port_node, in prestera_br_mdb_port_add()
1539 &br_mdb->br_mdb_port_list); in prestera_br_mdb_port_add()
1550 list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list, in prestera_br_mdb_entry_find()
1552 if (ether_addr_equal(&br_mdb->mdb->addr[0], addr) && in prestera_br_mdb_entry_find()
1553 vid == br_mdb->mdb->vid) in prestera_br_mdb_entry_find()
1583 sw = prestera_switch_get(mdb->obj.orig_dev); in prestera_mdb_port_addr_obj_add()
1584 port = prestera_port_dev_lower_find(mdb->obj.orig_dev); in prestera_mdb_port_addr_obj_add()
1586 br_port = prestera_bridge_port_find(sw, mdb->obj.orig_dev); in prestera_mdb_port_addr_obj_add()
1590 br_dev = br_port->bridge; in prestera_mdb_port_addr_obj_add()
1592 if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid)) in prestera_mdb_port_addr_obj_add()
1595 if (mdb->vid) in prestera_mdb_port_addr_obj_add()
1596 br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0], in prestera_mdb_port_addr_obj_add()
1597 mdb->vid); in prestera_mdb_port_addr_obj_add()
1599 br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0], in prestera_mdb_port_addr_obj_add()
1600 br_dev->bridge_id); in prestera_mdb_port_addr_obj_add()
1603 return -ENOMEM; in prestera_mdb_port_addr_obj_add()
1608 WARN_ON(prestera_mdb_enable_set(br_mdb, br_dev->multicast_enabled && in prestera_mdb_port_addr_obj_add()
1609 br_dev->mrouter_exist)); in prestera_mdb_port_addr_obj_add()
1633 switch (obj->id) { in prestera_port_obj_add()
1644 err = -EOPNOTSUPP; in prestera_port_obj_add()
1654 struct net_device *orig_dev = vlan->obj.orig_dev; in prestera_port_vlans_del()
1656 struct prestera_switch *sw = port->sw; in prestera_port_vlans_del()
1659 return -EOPNOTSUPP; in prestera_port_vlans_del()
1661 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev); in prestera_port_vlans_del()
1663 return -EINVAL; in prestera_port_vlans_del()
1665 if (!br_port->bridge->vlan_enabled) in prestera_port_vlans_del()
1668 prestera_bridge_port_vlan_del(port, br_port, vlan->vid); in prestera_port_vlans_del()
1682 /* Bridge port no longer exists - and so does this MDB entry */ in prestera_mdb_port_addr_obj_del()
1683 br_port = prestera_bridge_port_find(port->sw, mdb->obj.orig_dev); in prestera_mdb_port_addr_obj_del()
1687 /* Removing MDB with non-existing VLAN - not supported; */ in prestera_mdb_port_addr_obj_del()
1688 if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid)) in prestera_mdb_port_addr_obj_del()
1691 br_dev = br_port->bridge; in prestera_mdb_port_addr_obj_del()
1693 if (br_port->bridge->vlan_enabled) in prestera_mdb_port_addr_obj_del()
1694 br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0], in prestera_mdb_port_addr_obj_del()
1695 mdb->vid); in prestera_mdb_port_addr_obj_del()
1697 br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0], in prestera_mdb_port_addr_obj_del()
1698 br_port->bridge->bridge_id); in prestera_mdb_port_addr_obj_del()
1725 switch (obj->id) { in prestera_port_obj_del()
1733 err = -EOPNOTSUPP; in prestera_port_obj_del()
1777 switch (evt->fdb_evt.type) { in prestera_fdb_event()
1779 port = prestera_find_port(sw, evt->fdb_evt.dest.port_id); in prestera_fdb_event()
1781 dev = port->dev; in prestera_fdb_event()
1784 lag = prestera_lag_by_id(sw, evt->fdb_evt.dest.lag_id); in prestera_fdb_event()
1786 dev = lag->dev; in prestera_fdb_event()
1795 info.addr = evt->fdb_evt.data.mac; in prestera_fdb_event()
1796 info.vid = evt->fdb_evt.vid; in prestera_fdb_event()
1801 switch (evt->id) { in prestera_fdb_event()
1846 swdev->swdev_nb.notifier_call = prestera_switchdev_event; in prestera_switchdev_handler_init()
1847 err = register_switchdev_notifier(&swdev->swdev_nb); in prestera_switchdev_handler_init()
1851 swdev->swdev_nb_blk.notifier_call = prestera_switchdev_blk_event; in prestera_switchdev_handler_init()
1852 err = register_switchdev_blocking_notifier(&swdev->swdev_nb_blk); in prestera_switchdev_handler_init()
1859 unregister_switchdev_notifier(&swdev->swdev_nb); in prestera_switchdev_handler_init()
1867 unregister_switchdev_blocking_notifier(&swdev->swdev_nb_blk); in prestera_switchdev_handler_fini()
1868 unregister_switchdev_notifier(&swdev->swdev_nb); in prestera_switchdev_handler_fini()
1878 return -ENOMEM; in prestera_switchdev_init()
1880 sw->swdev = swdev; in prestera_switchdev_init()
1881 swdev->sw = sw; in prestera_switchdev_init()
1883 INIT_LIST_HEAD(&swdev->bridge_list); in prestera_switchdev_init()
1887 err = -ENOMEM; in prestera_switchdev_init()
1912 struct prestera_switchdev *swdev = sw->swdev; in prestera_switchdev_fini()