1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
4 #include <linux/if_bridge.h>
5 #include <linux/if_vlan.h>
6 #include <linux/kernel.h>
7 #include <linux/module.h>
8 #include <linux/notifier.h>
9 #include <net/netevent.h>
10 #include <net/switchdev.h>
13 #include "prestera_hw.h"
14 #include "prestera_switchdev.h"
16 #define PRESTERA_VID_ALL (0xffff)
18 #define PRESTERA_DEFAULT_AGEING_TIME_MS 300000
19 #define PRESTERA_MAX_AGEING_TIME_MS 1000000000
20 #define PRESTERA_MIN_AGEING_TIME_MS 32000
22 struct prestera_fdb_event_work {
23 struct work_struct work;
24 struct switchdev_notifier_fdb_info fdb_info;
25 struct net_device *dev;
29 struct prestera_switchdev {
30 struct prestera_switch *sw;
31 struct list_head bridge_list;
32 bool bridge_8021q_exists;
33 struct notifier_block swdev_nb_blk;
34 struct notifier_block swdev_nb;
37 struct prestera_bridge {
38 struct list_head head;
39 struct net_device *dev;
40 struct prestera_switchdev *swdev;
41 struct list_head port_list;
46 struct prestera_bridge_port {
47 struct list_head head;
48 struct net_device *dev;
49 struct prestera_bridge *bridge;
50 struct list_head vlan_list;
56 struct prestera_bridge_vlan {
57 struct list_head head;
58 struct list_head port_vlan_list;
62 struct prestera_port_vlan {
63 struct list_head br_vlan_head;
64 struct list_head port_head;
65 struct prestera_port *port;
66 struct prestera_bridge_port *br_port;
70 static struct workqueue_struct *swdev_wq;
72 static void prestera_bridge_port_put(struct prestera_bridge_port *br_port);
74 static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
77 static struct prestera_bridge_vlan *
78 prestera_bridge_vlan_create(struct prestera_bridge_port *br_port, u16 vid)
80 struct prestera_bridge_vlan *br_vlan;
82 br_vlan = kzalloc(sizeof(*br_vlan), GFP_KERNEL);
86 INIT_LIST_HEAD(&br_vlan->port_vlan_list);
88 list_add(&br_vlan->head, &br_port->vlan_list);
93 static void prestera_bridge_vlan_destroy(struct prestera_bridge_vlan *br_vlan)
95 list_del(&br_vlan->head);
96 WARN_ON(!list_empty(&br_vlan->port_vlan_list));
100 static struct prestera_bridge_vlan *
101 prestera_bridge_vlan_by_vid(struct prestera_bridge_port *br_port, u16 vid)
103 struct prestera_bridge_vlan *br_vlan;
105 list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
106 if (br_vlan->vid == vid)
113 static int prestera_bridge_vlan_port_count(struct prestera_bridge *bridge,
116 struct prestera_bridge_port *br_port;
117 struct prestera_bridge_vlan *br_vlan;
120 list_for_each_entry(br_port, &bridge->port_list, head) {
121 list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
122 if (br_vlan->vid == vid) {
132 static void prestera_bridge_vlan_put(struct prestera_bridge_vlan *br_vlan)
134 if (list_empty(&br_vlan->port_vlan_list))
135 prestera_bridge_vlan_destroy(br_vlan);
138 static struct prestera_port_vlan *
139 prestera_port_vlan_by_vid(struct prestera_port *port, u16 vid)
141 struct prestera_port_vlan *port_vlan;
143 list_for_each_entry(port_vlan, &port->vlans_list, port_head) {
144 if (port_vlan->vid == vid)
151 static struct prestera_port_vlan *
152 prestera_port_vlan_create(struct prestera_port *port, u16 vid, bool untagged)
154 struct prestera_port_vlan *port_vlan;
157 port_vlan = prestera_port_vlan_by_vid(port, vid);
159 return ERR_PTR(-EEXIST);
161 err = prestera_hw_vlan_port_set(port, vid, true, untagged);
165 port_vlan = kzalloc(sizeof(*port_vlan), GFP_KERNEL);
168 goto err_port_vlan_alloc;
171 port_vlan->port = port;
172 port_vlan->vid = vid;
174 list_add(&port_vlan->port_head, &port->vlans_list);
179 prestera_hw_vlan_port_set(port, vid, false, false);
183 static int prestera_fdb_add(struct prestera_port *port,
184 const unsigned char *mac, u16 vid, bool dynamic)
186 if (prestera_port_is_lag_member(port))
187 return prestera_hw_lag_fdb_add(port->sw, prestera_port_lag_id(port),
190 return prestera_hw_fdb_add(port, mac, vid, dynamic);
193 static int prestera_fdb_del(struct prestera_port *port,
194 const unsigned char *mac, u16 vid)
196 if (prestera_port_is_lag_member(port))
197 return prestera_hw_lag_fdb_del(port->sw, prestera_port_lag_id(port),
200 return prestera_hw_fdb_del(port, mac, vid);
203 static int prestera_fdb_flush_port_vlan(struct prestera_port *port, u16 vid,
206 if (prestera_port_is_lag_member(port))
207 return prestera_hw_fdb_flush_lag_vlan(port->sw, prestera_port_lag_id(port),
210 return prestera_hw_fdb_flush_port_vlan(port, vid, mode);
213 static int prestera_fdb_flush_port(struct prestera_port *port, u32 mode)
215 if (prestera_port_is_lag_member(port))
216 return prestera_hw_fdb_flush_lag(port->sw, prestera_port_lag_id(port),
219 return prestera_hw_fdb_flush_port(port, mode);
223 prestera_port_vlan_bridge_leave(struct prestera_port_vlan *port_vlan)
225 u32 fdb_flush_mode = PRESTERA_FDB_FLUSH_MODE_DYNAMIC;
226 struct prestera_port *port = port_vlan->port;
227 struct prestera_bridge_vlan *br_vlan;
228 struct prestera_bridge_port *br_port;
229 bool last_port, last_vlan;
230 u16 vid = port_vlan->vid;
233 br_port = port_vlan->br_port;
234 port_count = prestera_bridge_vlan_port_count(br_port->bridge, vid);
235 br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
237 last_vlan = list_is_singular(&br_port->vlan_list);
238 last_port = port_count == 1;
241 prestera_fdb_flush_port(port, fdb_flush_mode);
243 prestera_hw_fdb_flush_vlan(port->sw, vid, fdb_flush_mode);
245 prestera_fdb_flush_port_vlan(port, vid, fdb_flush_mode);
247 list_del(&port_vlan->br_vlan_head);
248 prestera_bridge_vlan_put(br_vlan);
249 prestera_bridge_port_put(br_port);
250 port_vlan->br_port = NULL;
253 static void prestera_port_vlan_destroy(struct prestera_port_vlan *port_vlan)
255 struct prestera_port *port = port_vlan->port;
256 u16 vid = port_vlan->vid;
258 if (port_vlan->br_port)
259 prestera_port_vlan_bridge_leave(port_vlan);
261 prestera_hw_vlan_port_set(port, vid, false, false);
262 list_del(&port_vlan->port_head);
266 static struct prestera_bridge *
267 prestera_bridge_create(struct prestera_switchdev *swdev, struct net_device *dev)
269 bool vlan_enabled = br_vlan_enabled(dev);
270 struct prestera_bridge *bridge;
274 if (vlan_enabled && swdev->bridge_8021q_exists) {
275 netdev_err(dev, "Only one VLAN-aware bridge is supported\n");
276 return ERR_PTR(-EINVAL);
279 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
281 return ERR_PTR(-ENOMEM);
284 swdev->bridge_8021q_exists = true;
286 err = prestera_hw_bridge_create(swdev->sw, &bridge_id);
292 bridge->bridge_id = bridge_id;
295 bridge->vlan_enabled = vlan_enabled;
296 bridge->swdev = swdev;
299 INIT_LIST_HEAD(&bridge->port_list);
301 list_add(&bridge->head, &swdev->bridge_list);
306 static void prestera_bridge_destroy(struct prestera_bridge *bridge)
308 struct prestera_switchdev *swdev = bridge->swdev;
310 list_del(&bridge->head);
312 if (bridge->vlan_enabled)
313 swdev->bridge_8021q_exists = false;
315 prestera_hw_bridge_delete(swdev->sw, bridge->bridge_id);
317 WARN_ON(!list_empty(&bridge->port_list));
321 static void prestera_bridge_put(struct prestera_bridge *bridge)
323 if (list_empty(&bridge->port_list))
324 prestera_bridge_destroy(bridge);
328 struct prestera_bridge *prestera_bridge_by_dev(struct prestera_switchdev *swdev,
329 const struct net_device *dev)
331 struct prestera_bridge *bridge;
333 list_for_each_entry(bridge, &swdev->bridge_list, head)
334 if (bridge->dev == dev)
340 static struct prestera_bridge_port *
341 __prestera_bridge_port_by_dev(struct prestera_bridge *bridge,
342 struct net_device *dev)
344 struct prestera_bridge_port *br_port;
346 list_for_each_entry(br_port, &bridge->port_list, head) {
347 if (br_port->dev == dev)
354 static int prestera_match_upper_bridge_dev(struct net_device *dev,
355 struct netdev_nested_priv *priv)
357 if (netif_is_bridge_master(dev))
363 static struct net_device *prestera_get_upper_bridge_dev(struct net_device *dev)
365 struct netdev_nested_priv priv = { };
367 netdev_walk_all_upper_dev_rcu(dev, prestera_match_upper_bridge_dev,
372 static struct prestera_bridge_port *
373 prestera_bridge_port_by_dev(struct prestera_switchdev *swdev,
374 struct net_device *dev)
376 struct net_device *br_dev = prestera_get_upper_bridge_dev(dev);
377 struct prestera_bridge *bridge;
382 bridge = prestera_bridge_by_dev(swdev, br_dev);
386 return __prestera_bridge_port_by_dev(bridge, dev);
389 static struct prestera_bridge_port *
390 prestera_bridge_port_create(struct prestera_bridge *bridge,
391 struct net_device *dev)
393 struct prestera_bridge_port *br_port;
395 br_port = kzalloc(sizeof(*br_port), GFP_KERNEL);
399 br_port->flags = BR_LEARNING | BR_FLOOD | BR_LEARNING_SYNC |
401 br_port->stp_state = BR_STATE_DISABLED;
402 refcount_set(&br_port->ref_count, 1);
403 br_port->bridge = bridge;
406 INIT_LIST_HEAD(&br_port->vlan_list);
407 list_add(&br_port->head, &bridge->port_list);
413 prestera_bridge_port_destroy(struct prestera_bridge_port *br_port)
415 list_del(&br_port->head);
416 WARN_ON(!list_empty(&br_port->vlan_list));
420 static void prestera_bridge_port_get(struct prestera_bridge_port *br_port)
422 refcount_inc(&br_port->ref_count);
425 static void prestera_bridge_port_put(struct prestera_bridge_port *br_port)
427 struct prestera_bridge *bridge = br_port->bridge;
429 if (refcount_dec_and_test(&br_port->ref_count)) {
430 prestera_bridge_port_destroy(br_port);
431 prestera_bridge_put(bridge);
435 static struct prestera_bridge_port *
436 prestera_bridge_port_add(struct prestera_bridge *bridge, struct net_device *dev)
438 struct prestera_bridge_port *br_port;
440 br_port = __prestera_bridge_port_by_dev(bridge, dev);
442 prestera_bridge_port_get(br_port);
446 br_port = prestera_bridge_port_create(bridge, dev);
448 return ERR_PTR(-ENOMEM);
454 prestera_bridge_1d_port_join(struct prestera_bridge_port *br_port)
456 struct prestera_port *port = netdev_priv(br_port->dev);
457 struct prestera_bridge *bridge = br_port->bridge;
460 err = prestera_hw_bridge_port_add(port, bridge->bridge_id);
464 err = prestera_hw_port_flood_set(port, BR_FLOOD | BR_MCAST_FLOOD,
467 goto err_port_flood_set;
469 err = prestera_hw_port_learning_set(port, br_port->flags & BR_LEARNING);
471 goto err_port_learning_set;
475 err_port_learning_set:
477 prestera_hw_bridge_port_delete(port, bridge->bridge_id);
482 int prestera_bridge_port_join(struct net_device *br_dev,
483 struct prestera_port *port,
484 struct netlink_ext_ack *extack)
486 struct prestera_switchdev *swdev = port->sw->swdev;
487 struct prestera_bridge_port *br_port;
488 struct prestera_bridge *bridge;
491 bridge = prestera_bridge_by_dev(swdev, br_dev);
493 bridge = prestera_bridge_create(swdev, br_dev);
495 return PTR_ERR(bridge);
498 br_port = prestera_bridge_port_add(bridge, port->dev);
499 if (IS_ERR(br_port)) {
500 err = PTR_ERR(br_port);
501 goto err_brport_create;
504 err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL,
505 NULL, NULL, false, extack);
507 goto err_switchdev_offload;
509 if (bridge->vlan_enabled)
512 err = prestera_bridge_1d_port_join(br_port);
519 switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
520 err_switchdev_offload:
521 prestera_bridge_port_put(br_port);
523 prestera_bridge_put(bridge);
527 static void prestera_bridge_1q_port_leave(struct prestera_bridge_port *br_port)
529 struct prestera_port *port = netdev_priv(br_port->dev);
531 prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
532 prestera_port_pvid_set(port, PRESTERA_DEFAULT_VID);
535 static void prestera_bridge_1d_port_leave(struct prestera_bridge_port *br_port)
537 struct prestera_port *port = netdev_priv(br_port->dev);
539 prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
540 prestera_hw_bridge_port_delete(port, br_port->bridge->bridge_id);
543 static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
549 case BR_STATE_DISABLED:
550 hw_state = PRESTERA_STP_DISABLED;
553 case BR_STATE_BLOCKING:
554 case BR_STATE_LISTENING:
555 hw_state = PRESTERA_STP_BLOCK_LISTEN;
558 case BR_STATE_LEARNING:
559 hw_state = PRESTERA_STP_LEARN;
562 case BR_STATE_FORWARDING:
563 hw_state = PRESTERA_STP_FORWARD;
570 return prestera_hw_vlan_port_stp_set(port, vid, hw_state);
573 void prestera_bridge_port_leave(struct net_device *br_dev,
574 struct prestera_port *port)
576 struct prestera_switchdev *swdev = port->sw->swdev;
577 struct prestera_bridge_port *br_port;
578 struct prestera_bridge *bridge;
580 bridge = prestera_bridge_by_dev(swdev, br_dev);
584 br_port = __prestera_bridge_port_by_dev(bridge, port->dev);
588 bridge = br_port->bridge;
590 if (bridge->vlan_enabled)
591 prestera_bridge_1q_port_leave(br_port);
593 prestera_bridge_1d_port_leave(br_port);
595 switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
597 prestera_hw_port_learning_set(port, false);
598 prestera_hw_port_flood_set(port, BR_FLOOD | BR_MCAST_FLOOD, 0);
599 prestera_port_vid_stp_set(port, PRESTERA_VID_ALL, BR_STATE_FORWARDING);
600 prestera_bridge_port_put(br_port);
603 static int prestera_port_attr_br_flags_set(struct prestera_port *port,
604 struct net_device *dev,
605 struct switchdev_brport_flags flags)
607 struct prestera_bridge_port *br_port;
610 br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
614 err = prestera_hw_port_flood_set(port, flags.mask, flags.val);
618 if (flags.mask & BR_LEARNING) {
619 err = prestera_hw_port_learning_set(port,
620 flags.val & BR_LEARNING);
625 memcpy(&br_port->flags, &flags.val, sizeof(flags.val));
630 static int prestera_port_attr_br_ageing_set(struct prestera_port *port,
631 unsigned long ageing_clock_t)
633 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
634 u32 ageing_time_ms = jiffies_to_msecs(ageing_jiffies);
635 struct prestera_switch *sw = port->sw;
637 if (ageing_time_ms < PRESTERA_MIN_AGEING_TIME_MS ||
638 ageing_time_ms > PRESTERA_MAX_AGEING_TIME_MS)
641 return prestera_hw_switch_ageing_set(sw, ageing_time_ms);
644 static int prestera_port_attr_br_vlan_set(struct prestera_port *port,
645 struct net_device *dev,
648 struct prestera_switch *sw = port->sw;
649 struct prestera_bridge *bridge;
651 bridge = prestera_bridge_by_dev(sw->swdev, dev);
652 if (WARN_ON(!bridge))
655 if (bridge->vlan_enabled == vlan_enabled)
658 netdev_err(bridge->dev, "VLAN filtering can't be changed for existing bridge\n");
663 static int prestera_port_bridge_vlan_stp_set(struct prestera_port *port,
664 struct prestera_bridge_vlan *br_vlan,
667 struct prestera_port_vlan *port_vlan;
669 list_for_each_entry(port_vlan, &br_vlan->port_vlan_list, br_vlan_head) {
670 if (port_vlan->port != port)
673 return prestera_port_vid_stp_set(port, br_vlan->vid, state);
679 static int prestera_port_attr_stp_state_set(struct prestera_port *port,
680 struct net_device *dev,
683 struct prestera_bridge_port *br_port;
684 struct prestera_bridge_vlan *br_vlan;
688 br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
692 if (!br_port->bridge->vlan_enabled) {
693 vid = br_port->bridge->bridge_id;
694 err = prestera_port_vid_stp_set(port, vid, state);
696 goto err_port_stp_set;
698 list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
699 err = prestera_port_bridge_vlan_stp_set(port, br_vlan,
702 goto err_port_vlan_stp_set;
706 br_port->stp_state = state;
710 err_port_vlan_stp_set:
711 list_for_each_entry_continue_reverse(br_vlan, &br_port->vlan_list, head)
712 prestera_port_bridge_vlan_stp_set(port, br_vlan, br_port->stp_state);
716 prestera_port_vid_stp_set(port, vid, br_port->stp_state);
721 static int prestera_port_obj_attr_set(struct net_device *dev, const void *ctx,
722 const struct switchdev_attr *attr,
723 struct netlink_ext_ack *extack)
725 struct prestera_port *port = netdev_priv(dev);
729 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
730 err = prestera_port_attr_stp_state_set(port, attr->orig_dev,
733 case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
734 if (attr->u.brport_flags.mask &
735 ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD))
738 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
739 err = prestera_port_attr_br_flags_set(port, attr->orig_dev,
740 attr->u.brport_flags);
742 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
743 err = prestera_port_attr_br_ageing_set(port,
744 attr->u.ageing_time);
746 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
747 err = prestera_port_attr_br_vlan_set(port, attr->orig_dev,
748 attr->u.vlan_filtering);
758 prestera_fdb_offload_notify(struct prestera_port *port,
759 struct switchdev_notifier_fdb_info *info)
761 struct switchdev_notifier_fdb_info send_info = {};
763 send_info.addr = info->addr;
764 send_info.vid = info->vid;
765 send_info.offloaded = true;
767 call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, port->dev,
768 &send_info.info, NULL);
771 static int prestera_port_fdb_set(struct prestera_port *port,
772 struct switchdev_notifier_fdb_info *fdb_info,
775 struct prestera_switch *sw = port->sw;
776 struct prestera_bridge_port *br_port;
777 struct prestera_bridge *bridge;
781 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
785 bridge = br_port->bridge;
787 if (bridge->vlan_enabled)
790 vid = bridge->bridge_id;
793 err = prestera_fdb_add(port, fdb_info->addr, vid, false);
795 err = prestera_fdb_del(port, fdb_info->addr, vid);
800 static void prestera_fdb_event_work(struct work_struct *work)
802 struct switchdev_notifier_fdb_info *fdb_info;
803 struct prestera_fdb_event_work *swdev_work;
804 struct prestera_port *port;
805 struct net_device *dev;
808 swdev_work = container_of(work, struct prestera_fdb_event_work, work);
809 dev = swdev_work->dev;
813 port = prestera_port_dev_lower_find(dev);
817 switch (swdev_work->event) {
818 case SWITCHDEV_FDB_ADD_TO_DEVICE:
819 fdb_info = &swdev_work->fdb_info;
820 if (!fdb_info->added_by_user || fdb_info->is_local)
823 err = prestera_port_fdb_set(port, fdb_info, true);
827 prestera_fdb_offload_notify(port, fdb_info);
830 case SWITCHDEV_FDB_DEL_TO_DEVICE:
831 fdb_info = &swdev_work->fdb_info;
832 prestera_port_fdb_set(port, fdb_info, false);
839 kfree(swdev_work->fdb_info.addr);
844 static int prestera_switchdev_event(struct notifier_block *unused,
845 unsigned long event, void *ptr)
847 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
848 struct switchdev_notifier_fdb_info *fdb_info;
849 struct switchdev_notifier_info *info = ptr;
850 struct prestera_fdb_event_work *swdev_work;
851 struct net_device *upper;
854 if (event == SWITCHDEV_PORT_ATTR_SET) {
855 err = switchdev_handle_port_attr_set(dev, ptr,
856 prestera_netdev_check,
857 prestera_port_obj_attr_set);
858 return notifier_from_errno(err);
861 if (!prestera_netdev_check(dev))
864 upper = netdev_master_upper_dev_get_rcu(dev);
868 if (!netif_is_bridge_master(upper))
871 swdev_work = kzalloc(sizeof(*swdev_work), GFP_ATOMIC);
875 swdev_work->event = event;
876 swdev_work->dev = dev;
879 case SWITCHDEV_FDB_ADD_TO_DEVICE:
880 case SWITCHDEV_FDB_DEL_TO_DEVICE:
881 fdb_info = container_of(info,
882 struct switchdev_notifier_fdb_info,
885 INIT_WORK(&swdev_work->work, prestera_fdb_event_work);
886 memcpy(&swdev_work->fdb_info, ptr,
887 sizeof(swdev_work->fdb_info));
889 swdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
890 if (!swdev_work->fdb_info.addr)
893 ether_addr_copy((u8 *)swdev_work->fdb_info.addr,
903 queue_work(swdev_wq, &swdev_work->work);
912 prestera_port_vlan_bridge_join(struct prestera_port_vlan *port_vlan,
913 struct prestera_bridge_port *br_port)
915 struct prestera_port *port = port_vlan->port;
916 struct prestera_bridge_vlan *br_vlan;
917 u16 vid = port_vlan->vid;
920 if (port_vlan->br_port)
923 err = prestera_hw_port_flood_set(port, BR_FLOOD | BR_MCAST_FLOOD,
928 err = prestera_hw_port_learning_set(port, br_port->flags & BR_LEARNING);
930 goto err_port_learning_set;
932 err = prestera_port_vid_stp_set(port, vid, br_port->stp_state);
934 goto err_port_vid_stp_set;
936 br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
938 br_vlan = prestera_bridge_vlan_create(br_port, vid);
941 goto err_bridge_vlan_get;
945 list_add(&port_vlan->br_vlan_head, &br_vlan->port_vlan_list);
947 prestera_bridge_port_get(br_port);
948 port_vlan->br_port = br_port;
953 prestera_port_vid_stp_set(port, vid, BR_STATE_FORWARDING);
954 err_port_vid_stp_set:
955 prestera_hw_port_learning_set(port, false);
956 err_port_learning_set:
961 prestera_bridge_port_vlan_add(struct prestera_port *port,
962 struct prestera_bridge_port *br_port,
963 u16 vid, bool is_untagged, bool is_pvid,
964 struct netlink_ext_ack *extack)
966 struct prestera_port_vlan *port_vlan;
967 u16 old_pvid = port->pvid;
974 pvid = port->pvid == vid ? 0 : port->pvid;
976 port_vlan = prestera_port_vlan_by_vid(port, vid);
977 if (port_vlan && port_vlan->br_port != br_port)
981 port_vlan = prestera_port_vlan_create(port, vid, is_untagged);
982 if (IS_ERR(port_vlan))
983 return PTR_ERR(port_vlan);
985 err = prestera_hw_vlan_port_set(port, vid, true, is_untagged);
987 goto err_port_vlan_set;
990 err = prestera_port_pvid_set(port, pvid);
992 goto err_port_pvid_set;
994 err = prestera_port_vlan_bridge_join(port_vlan, br_port);
996 goto err_port_vlan_bridge_join;
1000 err_port_vlan_bridge_join:
1001 prestera_port_pvid_set(port, old_pvid);
1003 prestera_hw_vlan_port_set(port, vid, false, false);
1005 prestera_port_vlan_destroy(port_vlan);
1011 prestera_bridge_port_vlan_del(struct prestera_port *port,
1012 struct prestera_bridge_port *br_port, u16 vid)
1014 u16 pvid = port->pvid == vid ? 0 : port->pvid;
1015 struct prestera_port_vlan *port_vlan;
1017 port_vlan = prestera_port_vlan_by_vid(port, vid);
1018 if (WARN_ON(!port_vlan))
1021 prestera_port_vlan_bridge_leave(port_vlan);
1022 prestera_port_pvid_set(port, pvid);
1023 prestera_port_vlan_destroy(port_vlan);
1026 static int prestera_port_vlans_add(struct prestera_port *port,
1027 const struct switchdev_obj_port_vlan *vlan,
1028 struct netlink_ext_ack *extack)
1030 bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1031 bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1032 struct net_device *orig_dev = vlan->obj.orig_dev;
1033 struct prestera_bridge_port *br_port;
1034 struct prestera_switch *sw = port->sw;
1035 struct prestera_bridge *bridge;
1037 if (netif_is_bridge_master(orig_dev))
1040 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1041 if (WARN_ON(!br_port))
1044 bridge = br_port->bridge;
1045 if (!bridge->vlan_enabled)
1048 return prestera_bridge_port_vlan_add(port, br_port,
1049 vlan->vid, flag_untagged,
1053 static int prestera_port_obj_add(struct net_device *dev, const void *ctx,
1054 const struct switchdev_obj *obj,
1055 struct netlink_ext_ack *extack)
1057 struct prestera_port *port = netdev_priv(dev);
1058 const struct switchdev_obj_port_vlan *vlan;
1061 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1062 vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
1063 return prestera_port_vlans_add(port, vlan, extack);
1069 static int prestera_port_vlans_del(struct prestera_port *port,
1070 const struct switchdev_obj_port_vlan *vlan)
1072 struct net_device *orig_dev = vlan->obj.orig_dev;
1073 struct prestera_bridge_port *br_port;
1074 struct prestera_switch *sw = port->sw;
1076 if (netif_is_bridge_master(orig_dev))
1079 br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1080 if (WARN_ON(!br_port))
1083 if (!br_port->bridge->vlan_enabled)
1086 prestera_bridge_port_vlan_del(port, br_port, vlan->vid);
1091 static int prestera_port_obj_del(struct net_device *dev, const void *ctx,
1092 const struct switchdev_obj *obj)
1094 struct prestera_port *port = netdev_priv(dev);
1097 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1098 return prestera_port_vlans_del(port, SWITCHDEV_OBJ_PORT_VLAN(obj));
1104 static int prestera_switchdev_blk_event(struct notifier_block *unused,
1105 unsigned long event, void *ptr)
1107 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1111 case SWITCHDEV_PORT_OBJ_ADD:
1112 err = switchdev_handle_port_obj_add(dev, ptr,
1113 prestera_netdev_check,
1114 prestera_port_obj_add);
1116 case SWITCHDEV_PORT_OBJ_DEL:
1117 err = switchdev_handle_port_obj_del(dev, ptr,
1118 prestera_netdev_check,
1119 prestera_port_obj_del);
1121 case SWITCHDEV_PORT_ATTR_SET:
1122 err = switchdev_handle_port_attr_set(dev, ptr,
1123 prestera_netdev_check,
1124 prestera_port_obj_attr_set);
1130 return notifier_from_errno(err);
1133 static void prestera_fdb_event(struct prestera_switch *sw,
1134 struct prestera_event *evt, void *arg)
1136 struct switchdev_notifier_fdb_info info = {};
1137 struct net_device *dev = NULL;
1138 struct prestera_port *port;
1139 struct prestera_lag *lag;
1141 switch (evt->fdb_evt.type) {
1142 case PRESTERA_FDB_ENTRY_TYPE_REG_PORT:
1143 port = prestera_find_port(sw, evt->fdb_evt.dest.port_id);
1147 case PRESTERA_FDB_ENTRY_TYPE_LAG:
1148 lag = prestera_lag_by_id(sw, evt->fdb_evt.dest.lag_id);
1159 info.addr = evt->fdb_evt.data.mac;
1160 info.vid = evt->fdb_evt.vid;
1161 info.offloaded = true;
1166 case PRESTERA_FDB_EVENT_LEARNED:
1167 call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
1168 dev, &info.info, NULL);
1170 case PRESTERA_FDB_EVENT_AGED:
1171 call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
1172 dev, &info.info, NULL);
1179 static int prestera_fdb_init(struct prestera_switch *sw)
1183 err = prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_FDB,
1184 prestera_fdb_event, NULL);
1188 err = prestera_hw_switch_ageing_set(sw, PRESTERA_DEFAULT_AGEING_TIME_MS);
1190 goto err_ageing_set;
1195 prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1196 prestera_fdb_event);
1200 static void prestera_fdb_fini(struct prestera_switch *sw)
1202 prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1203 prestera_fdb_event);
1206 static int prestera_switchdev_handler_init(struct prestera_switchdev *swdev)
1210 swdev->swdev_nb.notifier_call = prestera_switchdev_event;
1211 err = register_switchdev_notifier(&swdev->swdev_nb);
1213 goto err_register_swdev_notifier;
1215 swdev->swdev_nb_blk.notifier_call = prestera_switchdev_blk_event;
1216 err = register_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1218 goto err_register_blk_swdev_notifier;
1222 err_register_blk_swdev_notifier:
1223 unregister_switchdev_notifier(&swdev->swdev_nb);
1224 err_register_swdev_notifier:
1225 destroy_workqueue(swdev_wq);
1229 static void prestera_switchdev_handler_fini(struct prestera_switchdev *swdev)
1231 unregister_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1232 unregister_switchdev_notifier(&swdev->swdev_nb);
1235 int prestera_switchdev_init(struct prestera_switch *sw)
1237 struct prestera_switchdev *swdev;
1240 swdev = kzalloc(sizeof(*swdev), GFP_KERNEL);
1247 INIT_LIST_HEAD(&swdev->bridge_list);
1249 swdev_wq = alloc_ordered_workqueue("%s_ordered", 0, "prestera_br");
1255 err = prestera_switchdev_handler_init(swdev);
1257 goto err_swdev_init;
1259 err = prestera_fdb_init(sw);
1267 destroy_workqueue(swdev_wq);
1274 void prestera_switchdev_fini(struct prestera_switch *sw)
1276 struct prestera_switchdev *swdev = sw->swdev;
1278 prestera_fdb_fini(sw);
1279 prestera_switchdev_handler_fini(swdev);
1280 destroy_workqueue(swdev_wq);