xref: /linux/drivers/net/ethernet/marvell/prestera/prestera_switchdev.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2019-2020 Marvell International Ltd. All rights reserved */
3 
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>
11 
12 #include "prestera.h"
13 #include "prestera_hw.h"
14 #include "prestera_switchdev.h"
15 
16 #define PRESTERA_VID_ALL (0xffff)
17 
18 #define PRESTERA_DEFAULT_AGEING_TIME_MS 300000
19 #define PRESTERA_MAX_AGEING_TIME_MS 1000000000
20 #define PRESTERA_MIN_AGEING_TIME_MS 32000
21 
22 struct prestera_fdb_event_work {
23 	struct work_struct work;
24 	struct switchdev_notifier_fdb_info fdb_info;
25 	struct net_device *dev;
26 	unsigned long event;
27 };
28 
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;
35 };
36 
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;
42 	struct list_head br_mdb_entry_list;
43 	bool mrouter_exist;
44 	bool vlan_enabled;
45 	bool multicast_enabled;
46 	u16 bridge_id;
47 };
48 
49 struct prestera_bridge_port {
50 	struct list_head head;
51 	struct net_device *dev;
52 	struct prestera_bridge *bridge;
53 	struct list_head vlan_list;
54 	struct list_head br_mdb_port_list;
55 	refcount_t ref_count;
56 	unsigned long flags;
57 	bool mrouter;
58 	u8 stp_state;
59 };
60 
61 struct prestera_bridge_vlan {
62 	struct list_head head;
63 	struct list_head port_vlan_list;
64 	u16 vid;
65 };
66 
67 struct prestera_port_vlan {
68 	struct list_head br_vlan_head;
69 	struct list_head port_head;
70 	struct prestera_port *port;
71 	struct prestera_bridge_port *br_port;
72 	u16 vid;
73 };
74 
75 struct prestera_br_mdb_port {
76 	struct prestera_bridge_port *br_port;
77 	struct list_head br_mdb_port_node;
78 };
79 
80 /* Software representation of MDB table. */
81 struct prestera_br_mdb_entry {
82 	struct prestera_bridge *bridge;
83 	struct prestera_mdb_entry *mdb;
84 	struct list_head br_mdb_port_list;
85 	struct list_head br_mdb_entry_node;
86 	bool enabled;
87 };
88 
89 static struct workqueue_struct *swdev_wq;
90 
91 static void prestera_bridge_port_put(struct prestera_bridge_port *br_port);
92 
93 static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
94 				     u8 state);
95 
96 static struct prestera_bridge *
prestera_bridge_find(const struct prestera_switch * sw,const struct net_device * br_dev)97 prestera_bridge_find(const struct prestera_switch *sw,
98 		     const struct net_device *br_dev)
99 {
100 	struct prestera_bridge *bridge;
101 
102 	list_for_each_entry(bridge, &sw->swdev->bridge_list, head)
103 		if (bridge->dev == br_dev)
104 			return bridge;
105 
106 	return NULL;
107 }
108 
109 static struct prestera_bridge_port *
__prestera_bridge_port_find(const struct prestera_bridge * bridge,const struct net_device * brport_dev)110 __prestera_bridge_port_find(const struct prestera_bridge *bridge,
111 			    const struct net_device *brport_dev)
112 {
113 	struct prestera_bridge_port *br_port;
114 
115 	list_for_each_entry(br_port, &bridge->port_list, head)
116 		if (br_port->dev == brport_dev)
117 			return br_port;
118 
119 	return NULL;
120 }
121 
122 static struct prestera_bridge_port *
prestera_bridge_port_find(struct prestera_switch * sw,struct net_device * brport_dev)123 prestera_bridge_port_find(struct prestera_switch *sw,
124 			  struct net_device *brport_dev)
125 {
126 	struct net_device *br_dev = netdev_master_upper_dev_get(brport_dev);
127 	struct prestera_bridge *bridge;
128 
129 	if (!br_dev)
130 		return NULL;
131 
132 	bridge = prestera_bridge_find(sw, br_dev);
133 	if (!bridge)
134 		return NULL;
135 
136 	return __prestera_bridge_port_find(bridge, brport_dev);
137 }
138 
139 static void
prestera_br_port_flags_reset(struct prestera_bridge_port * br_port,struct prestera_port * port)140 prestera_br_port_flags_reset(struct prestera_bridge_port *br_port,
141 			     struct prestera_port *port)
142 {
143 	prestera_port_uc_flood_set(port, false);
144 	prestera_port_mc_flood_set(port, false);
145 	prestera_port_learning_set(port, false);
146 	prestera_port_br_locked_set(port, false);
147 }
148 
prestera_br_port_flags_set(struct prestera_bridge_port * br_port,struct prestera_port * port)149 static int prestera_br_port_flags_set(struct prestera_bridge_port *br_port,
150 				      struct prestera_port *port)
151 {
152 	int err;
153 
154 	err = prestera_port_uc_flood_set(port, br_port->flags & BR_FLOOD);
155 	if (err)
156 		goto err_out;
157 
158 	err = prestera_port_mc_flood_set(port, br_port->flags & BR_MCAST_FLOOD);
159 	if (err)
160 		goto err_out;
161 
162 	err = prestera_port_learning_set(port, br_port->flags & BR_LEARNING);
163 	if (err)
164 		goto err_out;
165 
166 	err = prestera_port_br_locked_set(port,
167 					  br_port->flags & BR_PORT_LOCKED);
168 	if (err)
169 		goto err_out;
170 
171 	return 0;
172 
173 err_out:
174 	prestera_br_port_flags_reset(br_port, port);
175 	return err;
176 }
177 
178 static struct prestera_bridge_vlan *
prestera_bridge_vlan_create(struct prestera_bridge_port * br_port,u16 vid)179 prestera_bridge_vlan_create(struct prestera_bridge_port *br_port, u16 vid)
180 {
181 	struct prestera_bridge_vlan *br_vlan;
182 
183 	br_vlan = kzalloc(sizeof(*br_vlan), GFP_KERNEL);
184 	if (!br_vlan)
185 		return NULL;
186 
187 	INIT_LIST_HEAD(&br_vlan->port_vlan_list);
188 	br_vlan->vid = vid;
189 	list_add(&br_vlan->head, &br_port->vlan_list);
190 
191 	return br_vlan;
192 }
193 
prestera_bridge_vlan_destroy(struct prestera_bridge_vlan * br_vlan)194 static void prestera_bridge_vlan_destroy(struct prestera_bridge_vlan *br_vlan)
195 {
196 	list_del(&br_vlan->head);
197 	WARN_ON(!list_empty(&br_vlan->port_vlan_list));
198 	kfree(br_vlan);
199 }
200 
201 static struct prestera_bridge_vlan *
prestera_bridge_vlan_by_vid(struct prestera_bridge_port * br_port,u16 vid)202 prestera_bridge_vlan_by_vid(struct prestera_bridge_port *br_port, u16 vid)
203 {
204 	struct prestera_bridge_vlan *br_vlan;
205 
206 	list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
207 		if (br_vlan->vid == vid)
208 			return br_vlan;
209 	}
210 
211 	return NULL;
212 }
213 
prestera_bridge_vlan_port_count(struct prestera_bridge * bridge,u16 vid)214 static int prestera_bridge_vlan_port_count(struct prestera_bridge *bridge,
215 					   u16 vid)
216 {
217 	struct prestera_bridge_port *br_port;
218 	struct prestera_bridge_vlan *br_vlan;
219 	int count = 0;
220 
221 	list_for_each_entry(br_port, &bridge->port_list, head) {
222 		list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
223 			if (br_vlan->vid == vid) {
224 				count += 1;
225 				break;
226 			}
227 		}
228 	}
229 
230 	return count;
231 }
232 
prestera_bridge_vlan_put(struct prestera_bridge_vlan * br_vlan)233 static void prestera_bridge_vlan_put(struct prestera_bridge_vlan *br_vlan)
234 {
235 	if (list_empty(&br_vlan->port_vlan_list))
236 		prestera_bridge_vlan_destroy(br_vlan);
237 }
238 
239 static struct prestera_port_vlan *
prestera_port_vlan_by_vid(struct prestera_port * port,u16 vid)240 prestera_port_vlan_by_vid(struct prestera_port *port, u16 vid)
241 {
242 	struct prestera_port_vlan *port_vlan;
243 
244 	list_for_each_entry(port_vlan, &port->vlans_list, port_head) {
245 		if (port_vlan->vid == vid)
246 			return port_vlan;
247 	}
248 
249 	return NULL;
250 }
251 
252 static struct prestera_port_vlan *
prestera_port_vlan_create(struct prestera_port * port,u16 vid,bool untagged)253 prestera_port_vlan_create(struct prestera_port *port, u16 vid, bool untagged)
254 {
255 	struct prestera_port_vlan *port_vlan;
256 	int err;
257 
258 	port_vlan = prestera_port_vlan_by_vid(port, vid);
259 	if (port_vlan)
260 		return ERR_PTR(-EEXIST);
261 
262 	err = prestera_hw_vlan_port_set(port, vid, true, untagged);
263 	if (err)
264 		return ERR_PTR(err);
265 
266 	port_vlan = kzalloc(sizeof(*port_vlan), GFP_KERNEL);
267 	if (!port_vlan) {
268 		err = -ENOMEM;
269 		goto err_port_vlan_alloc;
270 	}
271 
272 	port_vlan->port = port;
273 	port_vlan->vid = vid;
274 
275 	list_add(&port_vlan->port_head, &port->vlans_list);
276 
277 	return port_vlan;
278 
279 err_port_vlan_alloc:
280 	prestera_hw_vlan_port_set(port, vid, false, false);
281 	return ERR_PTR(err);
282 }
283 
prestera_fdb_add(struct prestera_port * port,const unsigned char * mac,u16 vid,bool dynamic)284 static int prestera_fdb_add(struct prestera_port *port,
285 			    const unsigned char *mac, u16 vid, bool dynamic)
286 {
287 	if (prestera_port_is_lag_member(port))
288 		return prestera_hw_lag_fdb_add(port->sw, prestera_port_lag_id(port),
289 					      mac, vid, dynamic);
290 
291 	return prestera_hw_fdb_add(port, mac, vid, dynamic);
292 }
293 
prestera_fdb_del(struct prestera_port * port,const unsigned char * mac,u16 vid)294 static int prestera_fdb_del(struct prestera_port *port,
295 			    const unsigned char *mac, u16 vid)
296 {
297 	if (prestera_port_is_lag_member(port))
298 		return prestera_hw_lag_fdb_del(port->sw, prestera_port_lag_id(port),
299 					      mac, vid);
300 	else
301 		return prestera_hw_fdb_del(port, mac, vid);
302 }
303 
prestera_fdb_flush_port_vlan(struct prestera_port * port,u16 vid,u32 mode)304 static int prestera_fdb_flush_port_vlan(struct prestera_port *port, u16 vid,
305 					u32 mode)
306 {
307 	if (prestera_port_is_lag_member(port))
308 		return prestera_hw_fdb_flush_lag_vlan(port->sw, prestera_port_lag_id(port),
309 						      vid, mode);
310 	else
311 		return prestera_hw_fdb_flush_port_vlan(port, vid, mode);
312 }
313 
prestera_fdb_flush_port(struct prestera_port * port,u32 mode)314 static int prestera_fdb_flush_port(struct prestera_port *port, u32 mode)
315 {
316 	if (prestera_port_is_lag_member(port))
317 		return prestera_hw_fdb_flush_lag(port->sw, prestera_port_lag_id(port),
318 						 mode);
319 	else
320 		return prestera_hw_fdb_flush_port(port, mode);
321 }
322 
323 static void
prestera_mdb_port_del(struct prestera_mdb_entry * mdb,struct net_device * orig_dev)324 prestera_mdb_port_del(struct prestera_mdb_entry *mdb,
325 		      struct net_device *orig_dev)
326 {
327 	struct prestera_flood_domain *fl_domain = mdb->flood_domain;
328 	struct prestera_flood_domain_port *flood_domain_port;
329 
330 	flood_domain_port = prestera_flood_domain_port_find(fl_domain,
331 							    orig_dev,
332 							    mdb->vid);
333 	if (flood_domain_port)
334 		prestera_flood_domain_port_destroy(flood_domain_port);
335 }
336 
337 static void
prestera_br_mdb_entry_put(struct prestera_br_mdb_entry * br_mdb)338 prestera_br_mdb_entry_put(struct prestera_br_mdb_entry *br_mdb)
339 {
340 	struct prestera_bridge_port *br_port;
341 
342 	if (list_empty(&br_mdb->br_mdb_port_list)) {
343 		list_for_each_entry(br_port, &br_mdb->bridge->port_list, head)
344 			prestera_mdb_port_del(br_mdb->mdb, br_port->dev);
345 
346 		prestera_mdb_entry_destroy(br_mdb->mdb);
347 		list_del(&br_mdb->br_mdb_entry_node);
348 		kfree(br_mdb);
349 	}
350 }
351 
352 static void
prestera_br_mdb_port_del(struct prestera_br_mdb_entry * br_mdb,struct prestera_bridge_port * br_port)353 prestera_br_mdb_port_del(struct prestera_br_mdb_entry *br_mdb,
354 			 struct prestera_bridge_port *br_port)
355 {
356 	struct prestera_br_mdb_port *br_mdb_port, *tmp;
357 
358 	list_for_each_entry_safe(br_mdb_port, tmp, &br_mdb->br_mdb_port_list,
359 				 br_mdb_port_node) {
360 		if (br_mdb_port->br_port == br_port) {
361 			list_del(&br_mdb_port->br_mdb_port_node);
362 			kfree(br_mdb_port);
363 		}
364 	}
365 }
366 
367 static void
prestera_mdb_flush_bridge_port(struct prestera_bridge_port * br_port)368 prestera_mdb_flush_bridge_port(struct prestera_bridge_port *br_port)
369 {
370 	struct prestera_br_mdb_port *br_mdb_port, *tmp_port;
371 	struct prestera_br_mdb_entry *br_mdb, *br_mdb_tmp;
372 	struct prestera_bridge *br_dev = br_port->bridge;
373 
374 	list_for_each_entry_safe(br_mdb, br_mdb_tmp, &br_dev->br_mdb_entry_list,
375 				 br_mdb_entry_node) {
376 		list_for_each_entry_safe(br_mdb_port, tmp_port,
377 					 &br_mdb->br_mdb_port_list,
378 					 br_mdb_port_node) {
379 			prestera_mdb_port_del(br_mdb->mdb,
380 					      br_mdb_port->br_port->dev);
381 			prestera_br_mdb_port_del(br_mdb,  br_mdb_port->br_port);
382 		}
383 		prestera_br_mdb_entry_put(br_mdb);
384 	}
385 }
386 
387 static void
prestera_port_vlan_bridge_leave(struct prestera_port_vlan * port_vlan)388 prestera_port_vlan_bridge_leave(struct prestera_port_vlan *port_vlan)
389 {
390 	u32 fdb_flush_mode = PRESTERA_FDB_FLUSH_MODE_DYNAMIC;
391 	struct prestera_port *port = port_vlan->port;
392 	struct prestera_bridge_vlan *br_vlan;
393 	struct prestera_bridge_port *br_port;
394 	bool last_port, last_vlan;
395 	u16 vid = port_vlan->vid;
396 	int port_count;
397 
398 	br_port = port_vlan->br_port;
399 	port_count = prestera_bridge_vlan_port_count(br_port->bridge, vid);
400 	br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
401 
402 	last_vlan = list_is_singular(&br_port->vlan_list);
403 	last_port = port_count == 1;
404 
405 	if (last_vlan)
406 		prestera_fdb_flush_port(port, fdb_flush_mode);
407 	else if (last_port)
408 		prestera_hw_fdb_flush_vlan(port->sw, vid, fdb_flush_mode);
409 	else
410 		prestera_fdb_flush_port_vlan(port, vid, fdb_flush_mode);
411 
412 	prestera_mdb_flush_bridge_port(br_port);
413 
414 	list_del(&port_vlan->br_vlan_head);
415 	prestera_bridge_vlan_put(br_vlan);
416 	prestera_bridge_port_put(br_port);
417 	port_vlan->br_port = NULL;
418 }
419 
prestera_port_vlan_destroy(struct prestera_port_vlan * port_vlan)420 static void prestera_port_vlan_destroy(struct prestera_port_vlan *port_vlan)
421 {
422 	struct prestera_port *port = port_vlan->port;
423 	u16 vid = port_vlan->vid;
424 
425 	if (port_vlan->br_port)
426 		prestera_port_vlan_bridge_leave(port_vlan);
427 
428 	prestera_hw_vlan_port_set(port, vid, false, false);
429 	list_del(&port_vlan->port_head);
430 	kfree(port_vlan);
431 }
432 
433 static struct prestera_bridge *
prestera_bridge_create(struct prestera_switchdev * swdev,struct net_device * dev)434 prestera_bridge_create(struct prestera_switchdev *swdev, struct net_device *dev)
435 {
436 	bool vlan_enabled = br_vlan_enabled(dev);
437 	struct prestera_bridge *bridge;
438 	u16 bridge_id;
439 	int err;
440 
441 	if (vlan_enabled && swdev->bridge_8021q_exists) {
442 		netdev_err(dev, "Only one VLAN-aware bridge is supported\n");
443 		return ERR_PTR(-EINVAL);
444 	}
445 
446 	bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
447 	if (!bridge)
448 		return ERR_PTR(-ENOMEM);
449 
450 	if (vlan_enabled) {
451 		swdev->bridge_8021q_exists = true;
452 	} else {
453 		err = prestera_hw_bridge_create(swdev->sw, &bridge_id);
454 		if (err) {
455 			kfree(bridge);
456 			return ERR_PTR(err);
457 		}
458 
459 		bridge->bridge_id = bridge_id;
460 	}
461 
462 	bridge->vlan_enabled = vlan_enabled;
463 	bridge->swdev = swdev;
464 	bridge->dev = dev;
465 	bridge->multicast_enabled = br_multicast_enabled(dev);
466 
467 	INIT_LIST_HEAD(&bridge->port_list);
468 	INIT_LIST_HEAD(&bridge->br_mdb_entry_list);
469 
470 	list_add(&bridge->head, &swdev->bridge_list);
471 
472 	return bridge;
473 }
474 
prestera_bridge_destroy(struct prestera_bridge * bridge)475 static void prestera_bridge_destroy(struct prestera_bridge *bridge)
476 {
477 	struct prestera_switchdev *swdev = bridge->swdev;
478 
479 	list_del(&bridge->head);
480 
481 	if (bridge->vlan_enabled)
482 		swdev->bridge_8021q_exists = false;
483 	else
484 		prestera_hw_bridge_delete(swdev->sw, bridge->bridge_id);
485 
486 	WARN_ON(!list_empty(&bridge->br_mdb_entry_list));
487 	WARN_ON(!list_empty(&bridge->port_list));
488 	kfree(bridge);
489 }
490 
prestera_bridge_put(struct prestera_bridge * bridge)491 static void prestera_bridge_put(struct prestera_bridge *bridge)
492 {
493 	if (list_empty(&bridge->port_list))
494 		prestera_bridge_destroy(bridge);
495 }
496 
497 static
prestera_bridge_by_dev(struct prestera_switchdev * swdev,const struct net_device * dev)498 struct prestera_bridge *prestera_bridge_by_dev(struct prestera_switchdev *swdev,
499 					       const struct net_device *dev)
500 {
501 	struct prestera_bridge *bridge;
502 
503 	list_for_each_entry(bridge, &swdev->bridge_list, head)
504 		if (bridge->dev == dev)
505 			return bridge;
506 
507 	return NULL;
508 }
509 
510 static struct prestera_bridge_port *
__prestera_bridge_port_by_dev(struct prestera_bridge * bridge,struct net_device * dev)511 __prestera_bridge_port_by_dev(struct prestera_bridge *bridge,
512 			      struct net_device *dev)
513 {
514 	struct prestera_bridge_port *br_port;
515 
516 	list_for_each_entry(br_port, &bridge->port_list, head) {
517 		if (br_port->dev == dev)
518 			return br_port;
519 	}
520 
521 	return NULL;
522 }
523 
prestera_match_upper_bridge_dev(struct net_device * dev,struct netdev_nested_priv * priv)524 static int prestera_match_upper_bridge_dev(struct net_device *dev,
525 					   struct netdev_nested_priv *priv)
526 {
527 	if (netif_is_bridge_master(dev))
528 		priv->data = dev;
529 
530 	return 0;
531 }
532 
prestera_get_upper_bridge_dev(struct net_device * dev)533 static struct net_device *prestera_get_upper_bridge_dev(struct net_device *dev)
534 {
535 	struct netdev_nested_priv priv = { };
536 
537 	netdev_walk_all_upper_dev_rcu(dev, prestera_match_upper_bridge_dev,
538 				      &priv);
539 	return priv.data;
540 }
541 
542 static struct prestera_bridge_port *
prestera_bridge_port_by_dev(struct prestera_switchdev * swdev,struct net_device * dev)543 prestera_bridge_port_by_dev(struct prestera_switchdev *swdev,
544 			    struct net_device *dev)
545 {
546 	struct net_device *br_dev = prestera_get_upper_bridge_dev(dev);
547 	struct prestera_bridge *bridge;
548 
549 	if (!br_dev)
550 		return NULL;
551 
552 	bridge = prestera_bridge_by_dev(swdev, br_dev);
553 	if (!bridge)
554 		return NULL;
555 
556 	return __prestera_bridge_port_by_dev(bridge, dev);
557 }
558 
559 static struct prestera_bridge_port *
prestera_bridge_port_create(struct prestera_bridge * bridge,struct net_device * dev)560 prestera_bridge_port_create(struct prestera_bridge *bridge,
561 			    struct net_device *dev)
562 {
563 	struct prestera_bridge_port *br_port;
564 
565 	br_port = kzalloc(sizeof(*br_port), GFP_KERNEL);
566 	if (!br_port)
567 		return NULL;
568 
569 	br_port->flags = BR_LEARNING | BR_FLOOD | BR_LEARNING_SYNC |
570 				BR_MCAST_FLOOD;
571 	br_port->stp_state = BR_STATE_DISABLED;
572 	refcount_set(&br_port->ref_count, 1);
573 	br_port->bridge = bridge;
574 	br_port->dev = dev;
575 
576 	INIT_LIST_HEAD(&br_port->vlan_list);
577 	list_add(&br_port->head, &bridge->port_list);
578 	INIT_LIST_HEAD(&br_port->br_mdb_port_list);
579 
580 	return br_port;
581 }
582 
583 static void
prestera_bridge_port_destroy(struct prestera_bridge_port * br_port)584 prestera_bridge_port_destroy(struct prestera_bridge_port *br_port)
585 {
586 	list_del(&br_port->head);
587 	WARN_ON(!list_empty(&br_port->vlan_list));
588 	WARN_ON(!list_empty(&br_port->br_mdb_port_list));
589 	kfree(br_port);
590 }
591 
prestera_bridge_port_get(struct prestera_bridge_port * br_port)592 static void prestera_bridge_port_get(struct prestera_bridge_port *br_port)
593 {
594 	refcount_inc(&br_port->ref_count);
595 }
596 
prestera_bridge_port_put(struct prestera_bridge_port * br_port)597 static void prestera_bridge_port_put(struct prestera_bridge_port *br_port)
598 {
599 	struct prestera_bridge *bridge = br_port->bridge;
600 
601 	if (refcount_dec_and_test(&br_port->ref_count)) {
602 		prestera_bridge_port_destroy(br_port);
603 		prestera_bridge_put(bridge);
604 	}
605 }
606 
607 static struct prestera_bridge_port *
prestera_bridge_port_add(struct prestera_bridge * bridge,struct net_device * dev)608 prestera_bridge_port_add(struct prestera_bridge *bridge, struct net_device *dev)
609 {
610 	struct prestera_bridge_port *br_port;
611 
612 	br_port = __prestera_bridge_port_by_dev(bridge, dev);
613 	if (br_port) {
614 		prestera_bridge_port_get(br_port);
615 		return br_port;
616 	}
617 
618 	br_port = prestera_bridge_port_create(bridge, dev);
619 	if (!br_port)
620 		return ERR_PTR(-ENOMEM);
621 
622 	return br_port;
623 }
624 
625 static int
prestera_bridge_1d_port_join(struct prestera_bridge_port * br_port)626 prestera_bridge_1d_port_join(struct prestera_bridge_port *br_port)
627 {
628 	struct prestera_port *port = netdev_priv(br_port->dev);
629 	struct prestera_bridge *bridge = br_port->bridge;
630 	int err;
631 
632 	err = prestera_hw_bridge_port_add(port, bridge->bridge_id);
633 	if (err)
634 		return err;
635 
636 	err = prestera_br_port_flags_set(br_port, port);
637 	if (err)
638 		goto err_flags2port_set;
639 
640 	return 0;
641 
642 err_flags2port_set:
643 	prestera_hw_bridge_port_delete(port, bridge->bridge_id);
644 
645 	return err;
646 }
647 
prestera_bridge_port_join(struct net_device * br_dev,struct prestera_port * port,struct netlink_ext_ack * extack)648 int prestera_bridge_port_join(struct net_device *br_dev,
649 			      struct prestera_port *port,
650 			      struct netlink_ext_ack *extack)
651 {
652 	struct prestera_switchdev *swdev = port->sw->swdev;
653 	struct prestera_bridge_port *br_port;
654 	struct prestera_bridge *bridge;
655 	int err;
656 
657 	bridge = prestera_bridge_by_dev(swdev, br_dev);
658 	if (!bridge) {
659 		bridge = prestera_bridge_create(swdev, br_dev);
660 		if (IS_ERR(bridge))
661 			return PTR_ERR(bridge);
662 	}
663 
664 	br_port = prestera_bridge_port_add(bridge, port->dev);
665 	if (IS_ERR(br_port)) {
666 		prestera_bridge_put(bridge);
667 		return PTR_ERR(br_port);
668 	}
669 
670 	err = switchdev_bridge_port_offload(br_port->dev, port->dev, NULL,
671 					    NULL, NULL, false, extack);
672 	if (err)
673 		goto err_switchdev_offload;
674 
675 	if (bridge->vlan_enabled)
676 		return 0;
677 
678 	err = prestera_bridge_1d_port_join(br_port);
679 	if (err)
680 		goto err_port_join;
681 
682 	return 0;
683 
684 err_port_join:
685 	switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
686 err_switchdev_offload:
687 	prestera_bridge_port_put(br_port);
688 	return err;
689 }
690 
prestera_bridge_1q_port_leave(struct prestera_bridge_port * br_port)691 static void prestera_bridge_1q_port_leave(struct prestera_bridge_port *br_port)
692 {
693 	struct prestera_port *port = netdev_priv(br_port->dev);
694 
695 	prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
696 	prestera_port_pvid_set(port, PRESTERA_DEFAULT_VID);
697 }
698 
prestera_bridge_1d_port_leave(struct prestera_bridge_port * br_port)699 static void prestera_bridge_1d_port_leave(struct prestera_bridge_port *br_port)
700 {
701 	struct prestera_port *port = netdev_priv(br_port->dev);
702 
703 	prestera_hw_fdb_flush_port(port, PRESTERA_FDB_FLUSH_MODE_ALL);
704 	prestera_hw_bridge_port_delete(port, br_port->bridge->bridge_id);
705 }
706 
prestera_port_vid_stp_set(struct prestera_port * port,u16 vid,u8 state)707 static int prestera_port_vid_stp_set(struct prestera_port *port, u16 vid,
708 				     u8 state)
709 {
710 	u8 hw_state = state;
711 
712 	switch (state) {
713 	case BR_STATE_DISABLED:
714 		hw_state = PRESTERA_STP_DISABLED;
715 		break;
716 
717 	case BR_STATE_BLOCKING:
718 	case BR_STATE_LISTENING:
719 		hw_state = PRESTERA_STP_BLOCK_LISTEN;
720 		break;
721 
722 	case BR_STATE_LEARNING:
723 		hw_state = PRESTERA_STP_LEARN;
724 		break;
725 
726 	case BR_STATE_FORWARDING:
727 		hw_state = PRESTERA_STP_FORWARD;
728 		break;
729 
730 	default:
731 		return -EINVAL;
732 	}
733 
734 	return prestera_hw_vlan_port_stp_set(port, vid, hw_state);
735 }
736 
prestera_bridge_port_leave(struct net_device * br_dev,struct prestera_port * port)737 void prestera_bridge_port_leave(struct net_device *br_dev,
738 				struct prestera_port *port)
739 {
740 	struct prestera_switchdev *swdev = port->sw->swdev;
741 	struct prestera_bridge_port *br_port;
742 	struct prestera_bridge *bridge;
743 
744 	bridge = prestera_bridge_by_dev(swdev, br_dev);
745 	if (!bridge)
746 		return;
747 
748 	br_port = __prestera_bridge_port_by_dev(bridge, port->dev);
749 	if (!br_port)
750 		return;
751 
752 	bridge = br_port->bridge;
753 
754 	if (bridge->vlan_enabled)
755 		prestera_bridge_1q_port_leave(br_port);
756 	else
757 		prestera_bridge_1d_port_leave(br_port);
758 
759 	switchdev_bridge_port_unoffload(br_port->dev, NULL, NULL, NULL);
760 
761 	prestera_mdb_flush_bridge_port(br_port);
762 
763 	prestera_br_port_flags_reset(br_port, port);
764 	prestera_port_vid_stp_set(port, PRESTERA_VID_ALL, BR_STATE_FORWARDING);
765 	prestera_bridge_port_put(br_port);
766 }
767 
prestera_port_attr_br_flags_set(struct prestera_port * port,struct net_device * dev,struct switchdev_brport_flags flags)768 static int prestera_port_attr_br_flags_set(struct prestera_port *port,
769 					   struct net_device *dev,
770 					   struct switchdev_brport_flags flags)
771 {
772 	struct prestera_bridge_port *br_port;
773 
774 	br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
775 	if (!br_port)
776 		return 0;
777 
778 	br_port->flags &= ~flags.mask;
779 	br_port->flags |= flags.val & flags.mask;
780 	return prestera_br_port_flags_set(br_port, port);
781 }
782 
prestera_port_attr_br_ageing_set(struct prestera_port * port,unsigned long ageing_clock_t)783 static int prestera_port_attr_br_ageing_set(struct prestera_port *port,
784 					    unsigned long ageing_clock_t)
785 {
786 	unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
787 	u32 ageing_time_ms = jiffies_to_msecs(ageing_jiffies);
788 	struct prestera_switch *sw = port->sw;
789 
790 	if (ageing_time_ms < PRESTERA_MIN_AGEING_TIME_MS ||
791 	    ageing_time_ms > PRESTERA_MAX_AGEING_TIME_MS)
792 		return -ERANGE;
793 
794 	return prestera_hw_switch_ageing_set(sw, ageing_time_ms);
795 }
796 
prestera_port_attr_br_vlan_set(struct prestera_port * port,struct net_device * dev,bool vlan_enabled)797 static int prestera_port_attr_br_vlan_set(struct prestera_port *port,
798 					  struct net_device *dev,
799 					  bool vlan_enabled)
800 {
801 	struct prestera_switch *sw = port->sw;
802 	struct prestera_bridge *bridge;
803 
804 	bridge = prestera_bridge_by_dev(sw->swdev, dev);
805 	if (WARN_ON(!bridge))
806 		return -EINVAL;
807 
808 	if (bridge->vlan_enabled == vlan_enabled)
809 		return 0;
810 
811 	netdev_err(bridge->dev, "VLAN filtering can't be changed for existing bridge\n");
812 
813 	return -EINVAL;
814 }
815 
prestera_port_bridge_vlan_stp_set(struct prestera_port * port,struct prestera_bridge_vlan * br_vlan,u8 state)816 static int prestera_port_bridge_vlan_stp_set(struct prestera_port *port,
817 					     struct prestera_bridge_vlan *br_vlan,
818 					     u8 state)
819 {
820 	struct prestera_port_vlan *port_vlan;
821 
822 	list_for_each_entry(port_vlan, &br_vlan->port_vlan_list, br_vlan_head) {
823 		if (port_vlan->port != port)
824 			continue;
825 
826 		return prestera_port_vid_stp_set(port, br_vlan->vid, state);
827 	}
828 
829 	return 0;
830 }
831 
prestera_port_attr_stp_state_set(struct prestera_port * port,struct net_device * dev,u8 state)832 static int prestera_port_attr_stp_state_set(struct prestera_port *port,
833 					    struct net_device *dev,
834 					    u8 state)
835 {
836 	struct prestera_bridge_port *br_port;
837 	struct prestera_bridge_vlan *br_vlan;
838 	int err;
839 	u16 vid;
840 
841 	br_port = prestera_bridge_port_by_dev(port->sw->swdev, dev);
842 	if (!br_port)
843 		return 0;
844 
845 	if (!br_port->bridge->vlan_enabled) {
846 		vid = br_port->bridge->bridge_id;
847 		err = prestera_port_vid_stp_set(port, vid, state);
848 		if (err)
849 			goto err_port_stp_set;
850 	} else {
851 		list_for_each_entry(br_vlan, &br_port->vlan_list, head) {
852 			err = prestera_port_bridge_vlan_stp_set(port, br_vlan,
853 								state);
854 			if (err)
855 				goto err_port_vlan_stp_set;
856 		}
857 	}
858 
859 	br_port->stp_state = state;
860 
861 	return 0;
862 
863 err_port_vlan_stp_set:
864 	list_for_each_entry_continue_reverse(br_vlan, &br_port->vlan_list, head)
865 		prestera_port_bridge_vlan_stp_set(port, br_vlan, br_port->stp_state);
866 	return err;
867 
868 err_port_stp_set:
869 	prestera_port_vid_stp_set(port, vid, br_port->stp_state);
870 
871 	return err;
872 }
873 
874 static int
prestera_br_port_lag_mdb_mc_enable_sync(struct prestera_bridge_port * br_port,bool enabled)875 prestera_br_port_lag_mdb_mc_enable_sync(struct prestera_bridge_port *br_port,
876 					bool enabled)
877 {
878 	struct prestera_port *pr_port;
879 	struct prestera_switch *sw;
880 	u16 lag_id;
881 	int err;
882 
883 	pr_port = prestera_port_dev_lower_find(br_port->dev);
884 	if (!pr_port)
885 		return 0;
886 
887 	sw = pr_port->sw;
888 	err = prestera_lag_id(sw, br_port->dev, &lag_id);
889 	if (err)
890 		return err;
891 
892 	list_for_each_entry(pr_port, &sw->port_list, list) {
893 		if (pr_port->lag->lag_id == lag_id) {
894 			err = prestera_port_mc_flood_set(pr_port, enabled);
895 			if (err)
896 				return err;
897 		}
898 	}
899 
900 	return 0;
901 }
902 
prestera_br_mdb_mc_enable_sync(struct prestera_bridge * br_dev)903 static int prestera_br_mdb_mc_enable_sync(struct prestera_bridge *br_dev)
904 {
905 	struct prestera_bridge_port *br_port;
906 	struct prestera_port *port;
907 	bool enabled;
908 	int err;
909 
910 	/* if mrouter exists:
911 	 *  - make sure every mrouter receives unreg mcast traffic;
912 	 * if mrouter doesn't exists:
913 	 *  - make sure every port receives unreg mcast traffic;
914 	 */
915 	list_for_each_entry(br_port, &br_dev->port_list, head) {
916 		if (br_dev->multicast_enabled && br_dev->mrouter_exist)
917 			enabled = br_port->mrouter;
918 		else
919 			enabled = br_port->flags & BR_MCAST_FLOOD;
920 
921 		if (netif_is_lag_master(br_port->dev)) {
922 			err = prestera_br_port_lag_mdb_mc_enable_sync(br_port,
923 								      enabled);
924 			if (err)
925 				return err;
926 			continue;
927 		}
928 
929 		port = prestera_port_dev_lower_find(br_port->dev);
930 		if (!port)
931 			continue;
932 
933 		err = prestera_port_mc_flood_set(port, enabled);
934 		if (err)
935 			return err;
936 	}
937 
938 	return 0;
939 }
940 
941 static bool
prestera_br_mdb_port_is_member(struct prestera_br_mdb_entry * br_mdb,struct net_device * orig_dev)942 prestera_br_mdb_port_is_member(struct prestera_br_mdb_entry *br_mdb,
943 			       struct net_device *orig_dev)
944 {
945 	struct prestera_br_mdb_port *tmp_port;
946 
947 	list_for_each_entry(tmp_port, &br_mdb->br_mdb_port_list,
948 			    br_mdb_port_node)
949 		if (tmp_port->br_port->dev == orig_dev)
950 			return true;
951 
952 	return false;
953 }
954 
955 static int
prestera_mdb_port_add(struct prestera_mdb_entry * mdb,struct net_device * orig_dev,const unsigned char addr[ETH_ALEN],u16 vid)956 prestera_mdb_port_add(struct prestera_mdb_entry *mdb,
957 		      struct net_device *orig_dev,
958 		      const unsigned char addr[ETH_ALEN], u16 vid)
959 {
960 	struct prestera_flood_domain *flood_domain = mdb->flood_domain;
961 	int err;
962 
963 	if (!prestera_flood_domain_port_find(flood_domain,
964 					     orig_dev, vid)) {
965 		err = prestera_flood_domain_port_create(flood_domain, orig_dev,
966 							vid);
967 		if (err)
968 			return err;
969 	}
970 
971 	return 0;
972 }
973 
974 /* Sync bridge mdb (software table) with HW table (if MC is enabled). */
prestera_br_mdb_sync(struct prestera_bridge * br_dev)975 static int prestera_br_mdb_sync(struct prestera_bridge *br_dev)
976 {
977 	struct prestera_br_mdb_port *br_mdb_port;
978 	struct prestera_bridge_port *br_port;
979 	struct prestera_br_mdb_entry *br_mdb;
980 	struct prestera_mdb_entry *mdb;
981 	struct prestera_port *pr_port;
982 	int err = 0;
983 
984 	if (!br_dev->multicast_enabled)
985 		return 0;
986 
987 	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
988 			    br_mdb_entry_node) {
989 		mdb = br_mdb->mdb;
990 		/* Make sure every port that explicitly been added to the mdb
991 		 * joins the specified group.
992 		 */
993 		list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list,
994 				    br_mdb_port_node) {
995 			br_port = br_mdb_port->br_port;
996 			pr_port = prestera_port_dev_lower_find(br_port->dev);
997 
998 			/* Match only mdb and br_mdb ports that belong to the
999 			 * same broadcast domain.
1000 			 */
1001 			if (br_dev->vlan_enabled &&
1002 			    !prestera_port_vlan_by_vid(pr_port,
1003 						       mdb->vid))
1004 				continue;
1005 
1006 			/* If port is not in MDB or there's no Mrouter
1007 			 * clear HW mdb.
1008 			 */
1009 			if (prestera_br_mdb_port_is_member(br_mdb,
1010 							   br_mdb_port->br_port->dev) &&
1011 							   br_dev->mrouter_exist)
1012 				err = prestera_mdb_port_add(mdb, br_port->dev,
1013 							    mdb->addr,
1014 							    mdb->vid);
1015 			else
1016 				prestera_mdb_port_del(mdb, br_port->dev);
1017 
1018 			if (err)
1019 				return err;
1020 		}
1021 
1022 		/* Make sure that every mrouter port joins every MC group int
1023 		 * broadcast domain. If it's not an mrouter - it should leave
1024 		 */
1025 		list_for_each_entry(br_port, &br_dev->port_list, head) {
1026 			pr_port = prestera_port_dev_lower_find(br_port->dev);
1027 
1028 			/* Make sure mrouter woudln't receive traffci from
1029 			 * another broadcast domain (e.g. from a vlan, which
1030 			 * mrouter port is not a member of).
1031 			 */
1032 			if (br_dev->vlan_enabled &&
1033 			    !prestera_port_vlan_by_vid(pr_port,
1034 						       mdb->vid))
1035 				continue;
1036 
1037 			if (br_port->mrouter) {
1038 				err = prestera_mdb_port_add(mdb, br_port->dev,
1039 							    mdb->addr,
1040 							    mdb->vid);
1041 				if (err)
1042 					return err;
1043 			} else if (!br_port->mrouter &&
1044 				   !prestera_br_mdb_port_is_member
1045 				   (br_mdb, br_port->dev)) {
1046 				prestera_mdb_port_del(mdb, br_port->dev);
1047 			}
1048 		}
1049 	}
1050 
1051 	return 0;
1052 }
1053 
1054 static int
prestera_mdb_enable_set(struct prestera_br_mdb_entry * br_mdb,bool enable)1055 prestera_mdb_enable_set(struct prestera_br_mdb_entry *br_mdb, bool enable)
1056 {
1057 	int err;
1058 
1059 	if (enable != br_mdb->enabled) {
1060 		if (enable)
1061 			err = prestera_hw_mdb_create(br_mdb->mdb);
1062 		else
1063 			err = prestera_hw_mdb_destroy(br_mdb->mdb);
1064 
1065 		if (err)
1066 			return err;
1067 
1068 		br_mdb->enabled = enable;
1069 	}
1070 
1071 	return 0;
1072 }
1073 
1074 static int
prestera_br_mdb_enable_set(struct prestera_bridge * br_dev,bool enable)1075 prestera_br_mdb_enable_set(struct prestera_bridge *br_dev, bool enable)
1076 {
1077 	struct prestera_br_mdb_entry *br_mdb;
1078 	int err;
1079 
1080 	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
1081 			    br_mdb_entry_node) {
1082 		err = prestera_mdb_enable_set(br_mdb, enable);
1083 		if (err)
1084 			return err;
1085 	}
1086 
1087 	return 0;
1088 }
1089 
prestera_port_attr_br_mc_disabled_set(struct prestera_port * port,struct net_device * orig_dev,bool mc_disabled)1090 static int prestera_port_attr_br_mc_disabled_set(struct prestera_port *port,
1091 						 struct net_device *orig_dev,
1092 						 bool mc_disabled)
1093 {
1094 	struct prestera_switch *sw = port->sw;
1095 	struct prestera_bridge *br_dev;
1096 
1097 	br_dev = prestera_bridge_find(sw, orig_dev);
1098 	if (!br_dev)
1099 		return 0;
1100 
1101 	br_dev->multicast_enabled = !mc_disabled;
1102 
1103 	/* There's no point in enabling mdb back if router is missing. */
1104 	WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled &&
1105 					   br_dev->mrouter_exist));
1106 
1107 	WARN_ON(prestera_br_mdb_sync(br_dev));
1108 
1109 	WARN_ON(prestera_br_mdb_mc_enable_sync(br_dev));
1110 
1111 	return 0;
1112 }
1113 
1114 static bool
prestera_bridge_mdb_mc_mrouter_exists(struct prestera_bridge * br_dev)1115 prestera_bridge_mdb_mc_mrouter_exists(struct prestera_bridge *br_dev)
1116 {
1117 	struct prestera_bridge_port *br_port;
1118 
1119 	list_for_each_entry(br_port, &br_dev->port_list, head)
1120 		if (br_port->mrouter)
1121 			return true;
1122 
1123 	return false;
1124 }
1125 
1126 static int
prestera_port_attr_mrouter_set(struct prestera_port * port,struct net_device * orig_dev,bool is_port_mrouter)1127 prestera_port_attr_mrouter_set(struct prestera_port *port,
1128 			       struct net_device *orig_dev,
1129 			       bool is_port_mrouter)
1130 {
1131 	struct prestera_bridge_port *br_port;
1132 	struct prestera_bridge *br_dev;
1133 
1134 	br_port = prestera_bridge_port_find(port->sw, orig_dev);
1135 	if (!br_port)
1136 		return 0;
1137 
1138 	br_dev = br_port->bridge;
1139 	br_port->mrouter = is_port_mrouter;
1140 
1141 	br_dev->mrouter_exist = prestera_bridge_mdb_mc_mrouter_exists(br_dev);
1142 
1143 	/* Enable MDB processing if both mrouter exists and mc is enabled.
1144 	 * In case if MC enabled, but there is no mrouter, device would flood
1145 	 * all multicast traffic (even if MDB table is not empty) with the use
1146 	 * of bridge's flood capabilities (without the use of flood_domain).
1147 	 */
1148 	WARN_ON(prestera_br_mdb_enable_set(br_dev, br_dev->multicast_enabled &&
1149 					   br_dev->mrouter_exist));
1150 
1151 	WARN_ON(prestera_br_mdb_sync(br_dev));
1152 
1153 	WARN_ON(prestera_br_mdb_mc_enable_sync(br_dev));
1154 
1155 	return 0;
1156 }
1157 
prestera_port_obj_attr_set(struct net_device * dev,const void * ctx,const struct switchdev_attr * attr,struct netlink_ext_ack * extack)1158 static int prestera_port_obj_attr_set(struct net_device *dev, const void *ctx,
1159 				      const struct switchdev_attr *attr,
1160 				      struct netlink_ext_ack *extack)
1161 {
1162 	struct prestera_port *port = netdev_priv(dev);
1163 	int err = 0;
1164 
1165 	switch (attr->id) {
1166 	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
1167 		err = prestera_port_attr_stp_state_set(port, attr->orig_dev,
1168 						       attr->u.stp_state);
1169 		break;
1170 	case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
1171 		if (attr->u.brport_flags.mask &
1172 		    ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_PORT_LOCKED))
1173 			err = -EINVAL;
1174 		break;
1175 	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
1176 		err = prestera_port_attr_br_flags_set(port, attr->orig_dev,
1177 						      attr->u.brport_flags);
1178 		break;
1179 	case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
1180 		err = prestera_port_attr_br_ageing_set(port,
1181 						       attr->u.ageing_time);
1182 		break;
1183 	case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
1184 		err = prestera_port_attr_br_vlan_set(port, attr->orig_dev,
1185 						     attr->u.vlan_filtering);
1186 		break;
1187 	case SWITCHDEV_ATTR_ID_PORT_MROUTER:
1188 		err = prestera_port_attr_mrouter_set(port, attr->orig_dev,
1189 						     attr->u.mrouter);
1190 		break;
1191 	case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
1192 		err = prestera_port_attr_br_mc_disabled_set(port, attr->orig_dev,
1193 							    attr->u.mc_disabled);
1194 		break;
1195 	default:
1196 		err = -EOPNOTSUPP;
1197 	}
1198 
1199 	return err;
1200 }
1201 
1202 static void
prestera_fdb_offload_notify(struct prestera_port * port,struct switchdev_notifier_fdb_info * info)1203 prestera_fdb_offload_notify(struct prestera_port *port,
1204 			    struct switchdev_notifier_fdb_info *info)
1205 {
1206 	struct switchdev_notifier_fdb_info send_info = {};
1207 
1208 	send_info.addr = info->addr;
1209 	send_info.vid = info->vid;
1210 	send_info.offloaded = true;
1211 
1212 	call_switchdev_notifiers(SWITCHDEV_FDB_OFFLOADED, port->dev,
1213 				 &send_info.info, NULL);
1214 }
1215 
prestera_port_fdb_set(struct prestera_port * port,struct switchdev_notifier_fdb_info * fdb_info,bool adding)1216 static int prestera_port_fdb_set(struct prestera_port *port,
1217 				 struct switchdev_notifier_fdb_info *fdb_info,
1218 				 bool adding)
1219 {
1220 	struct prestera_switch *sw = port->sw;
1221 	struct prestera_bridge_port *br_port;
1222 	struct prestera_bridge *bridge;
1223 	int err;
1224 	u16 vid;
1225 
1226 	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1227 	if (!br_port)
1228 		return -EINVAL;
1229 
1230 	bridge = br_port->bridge;
1231 
1232 	if (bridge->vlan_enabled)
1233 		vid = fdb_info->vid;
1234 	else
1235 		vid = bridge->bridge_id;
1236 
1237 	if (adding)
1238 		err = prestera_fdb_add(port, fdb_info->addr, vid, false);
1239 	else
1240 		err = prestera_fdb_del(port, fdb_info->addr, vid);
1241 
1242 	return err;
1243 }
1244 
prestera_fdb_event_work(struct work_struct * work)1245 static void prestera_fdb_event_work(struct work_struct *work)
1246 {
1247 	struct switchdev_notifier_fdb_info *fdb_info;
1248 	struct prestera_fdb_event_work *swdev_work;
1249 	struct prestera_port *port;
1250 	struct net_device *dev;
1251 	int err;
1252 
1253 	swdev_work = container_of(work, struct prestera_fdb_event_work, work);
1254 	dev = swdev_work->dev;
1255 
1256 	rtnl_lock();
1257 
1258 	port = prestera_port_dev_lower_find(dev);
1259 	if (!port)
1260 		goto out_unlock;
1261 
1262 	switch (swdev_work->event) {
1263 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
1264 		fdb_info = &swdev_work->fdb_info;
1265 		if (!fdb_info->added_by_user || fdb_info->is_local)
1266 			break;
1267 
1268 		err = prestera_port_fdb_set(port, fdb_info, true);
1269 		if (err)
1270 			break;
1271 
1272 		prestera_fdb_offload_notify(port, fdb_info);
1273 		break;
1274 
1275 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
1276 		fdb_info = &swdev_work->fdb_info;
1277 		prestera_port_fdb_set(port, fdb_info, false);
1278 		break;
1279 	}
1280 
1281 out_unlock:
1282 	rtnl_unlock();
1283 
1284 	kfree(swdev_work->fdb_info.addr);
1285 	kfree(swdev_work);
1286 	dev_put(dev);
1287 }
1288 
prestera_switchdev_event(struct notifier_block * unused,unsigned long event,void * ptr)1289 static int prestera_switchdev_event(struct notifier_block *unused,
1290 				    unsigned long event, void *ptr)
1291 {
1292 	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1293 	struct switchdev_notifier_fdb_info *fdb_info;
1294 	struct switchdev_notifier_info *info = ptr;
1295 	struct prestera_fdb_event_work *swdev_work;
1296 	struct net_device *upper;
1297 	int err;
1298 
1299 	if (event == SWITCHDEV_PORT_ATTR_SET) {
1300 		err = switchdev_handle_port_attr_set(dev, ptr,
1301 						     prestera_netdev_check,
1302 						     prestera_port_obj_attr_set);
1303 		return notifier_from_errno(err);
1304 	}
1305 
1306 	if (!prestera_netdev_check(dev))
1307 		return NOTIFY_DONE;
1308 
1309 	upper = netdev_master_upper_dev_get_rcu(dev);
1310 	if (!upper)
1311 		return NOTIFY_DONE;
1312 
1313 	if (!netif_is_bridge_master(upper))
1314 		return NOTIFY_DONE;
1315 
1316 	swdev_work = kzalloc(sizeof(*swdev_work), GFP_ATOMIC);
1317 	if (!swdev_work)
1318 		return NOTIFY_BAD;
1319 
1320 	swdev_work->event = event;
1321 	swdev_work->dev = dev;
1322 
1323 	switch (event) {
1324 	case SWITCHDEV_FDB_ADD_TO_DEVICE:
1325 	case SWITCHDEV_FDB_DEL_TO_DEVICE:
1326 		fdb_info = container_of(info,
1327 					struct switchdev_notifier_fdb_info,
1328 					info);
1329 
1330 		INIT_WORK(&swdev_work->work, prestera_fdb_event_work);
1331 		memcpy(&swdev_work->fdb_info, ptr,
1332 		       sizeof(swdev_work->fdb_info));
1333 
1334 		swdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
1335 		if (!swdev_work->fdb_info.addr)
1336 			goto out_bad;
1337 
1338 		ether_addr_copy((u8 *)swdev_work->fdb_info.addr,
1339 				fdb_info->addr);
1340 		dev_hold(dev);
1341 		break;
1342 
1343 	default:
1344 		kfree(swdev_work);
1345 		return NOTIFY_DONE;
1346 	}
1347 
1348 	queue_work(swdev_wq, &swdev_work->work);
1349 	return NOTIFY_DONE;
1350 
1351 out_bad:
1352 	kfree(swdev_work);
1353 	return NOTIFY_BAD;
1354 }
1355 
1356 static int
prestera_port_vlan_bridge_join(struct prestera_port_vlan * port_vlan,struct prestera_bridge_port * br_port)1357 prestera_port_vlan_bridge_join(struct prestera_port_vlan *port_vlan,
1358 			       struct prestera_bridge_port *br_port)
1359 {
1360 	struct prestera_port *port = port_vlan->port;
1361 	struct prestera_bridge_vlan *br_vlan;
1362 	u16 vid = port_vlan->vid;
1363 	int err;
1364 
1365 	if (port_vlan->br_port)
1366 		return 0;
1367 
1368 	err = prestera_br_port_flags_set(br_port, port);
1369 	if (err)
1370 		goto err_flags2port_set;
1371 
1372 	err = prestera_port_vid_stp_set(port, vid, br_port->stp_state);
1373 	if (err)
1374 		goto err_port_vid_stp_set;
1375 
1376 	br_vlan = prestera_bridge_vlan_by_vid(br_port, vid);
1377 	if (!br_vlan) {
1378 		br_vlan = prestera_bridge_vlan_create(br_port, vid);
1379 		if (!br_vlan) {
1380 			err = -ENOMEM;
1381 			goto err_bridge_vlan_get;
1382 		}
1383 	}
1384 
1385 	list_add(&port_vlan->br_vlan_head, &br_vlan->port_vlan_list);
1386 
1387 	prestera_bridge_port_get(br_port);
1388 	port_vlan->br_port = br_port;
1389 
1390 	return 0;
1391 
1392 err_bridge_vlan_get:
1393 	prestera_port_vid_stp_set(port, vid, BR_STATE_FORWARDING);
1394 err_port_vid_stp_set:
1395 	prestera_br_port_flags_reset(br_port, port);
1396 err_flags2port_set:
1397 	return err;
1398 }
1399 
1400 static int
prestera_bridge_port_vlan_add(struct prestera_port * port,struct prestera_bridge_port * br_port,u16 vid,bool is_untagged,bool is_pvid,struct netlink_ext_ack * extack)1401 prestera_bridge_port_vlan_add(struct prestera_port *port,
1402 			      struct prestera_bridge_port *br_port,
1403 			      u16 vid, bool is_untagged, bool is_pvid,
1404 			      struct netlink_ext_ack *extack)
1405 {
1406 	struct prestera_port_vlan *port_vlan;
1407 	u16 old_pvid = port->pvid;
1408 	u16 pvid;
1409 	int err;
1410 
1411 	if (is_pvid)
1412 		pvid = vid;
1413 	else
1414 		pvid = port->pvid == vid ? 0 : port->pvid;
1415 
1416 	port_vlan = prestera_port_vlan_by_vid(port, vid);
1417 	if (port_vlan && port_vlan->br_port != br_port)
1418 		return -EEXIST;
1419 
1420 	if (!port_vlan) {
1421 		port_vlan = prestera_port_vlan_create(port, vid, is_untagged);
1422 		if (IS_ERR(port_vlan))
1423 			return PTR_ERR(port_vlan);
1424 	} else {
1425 		err = prestera_hw_vlan_port_set(port, vid, true, is_untagged);
1426 		if (err)
1427 			goto err_port_vlan_set;
1428 	}
1429 
1430 	err = prestera_port_pvid_set(port, pvid);
1431 	if (err)
1432 		goto err_port_pvid_set;
1433 
1434 	err = prestera_port_vlan_bridge_join(port_vlan, br_port);
1435 	if (err)
1436 		goto err_port_vlan_bridge_join;
1437 
1438 	return 0;
1439 
1440 err_port_vlan_bridge_join:
1441 	prestera_port_pvid_set(port, old_pvid);
1442 err_port_pvid_set:
1443 	prestera_hw_vlan_port_set(port, vid, false, false);
1444 err_port_vlan_set:
1445 	prestera_port_vlan_destroy(port_vlan);
1446 
1447 	return err;
1448 }
1449 
1450 static void
prestera_bridge_port_vlan_del(struct prestera_port * port,struct prestera_bridge_port * br_port,u16 vid)1451 prestera_bridge_port_vlan_del(struct prestera_port *port,
1452 			      struct prestera_bridge_port *br_port, u16 vid)
1453 {
1454 	u16 pvid = port->pvid == vid ? 0 : port->pvid;
1455 	struct prestera_port_vlan *port_vlan;
1456 
1457 	port_vlan = prestera_port_vlan_by_vid(port, vid);
1458 	if (WARN_ON(!port_vlan))
1459 		return;
1460 
1461 	prestera_port_vlan_bridge_leave(port_vlan);
1462 	prestera_port_pvid_set(port, pvid);
1463 	prestera_port_vlan_destroy(port_vlan);
1464 }
1465 
prestera_port_vlans_add(struct prestera_port * port,const struct switchdev_obj_port_vlan * vlan,struct netlink_ext_ack * extack)1466 static int prestera_port_vlans_add(struct prestera_port *port,
1467 				   const struct switchdev_obj_port_vlan *vlan,
1468 				   struct netlink_ext_ack *extack)
1469 {
1470 	bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1471 	bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
1472 	struct net_device *orig_dev = vlan->obj.orig_dev;
1473 	struct prestera_bridge_port *br_port;
1474 	struct prestera_switch *sw = port->sw;
1475 	struct prestera_bridge *bridge;
1476 
1477 	if (netif_is_bridge_master(orig_dev))
1478 		return 0;
1479 
1480 	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1481 	if (WARN_ON(!br_port))
1482 		return -EINVAL;
1483 
1484 	bridge = br_port->bridge;
1485 	if (!bridge->vlan_enabled)
1486 		return 0;
1487 
1488 	return prestera_bridge_port_vlan_add(port, br_port,
1489 					     vlan->vid, flag_untagged,
1490 					     flag_pvid, extack);
1491 }
1492 
1493 static struct prestera_br_mdb_entry *
prestera_br_mdb_entry_create(struct prestera_switch * sw,struct prestera_bridge * br_dev,const unsigned char * addr,u16 vid)1494 prestera_br_mdb_entry_create(struct prestera_switch *sw,
1495 			     struct prestera_bridge *br_dev,
1496 			     const unsigned char *addr, u16 vid)
1497 {
1498 	struct prestera_br_mdb_entry *br_mdb_entry;
1499 	struct prestera_mdb_entry *mdb_entry;
1500 
1501 	br_mdb_entry = kzalloc(sizeof(*br_mdb_entry), GFP_KERNEL);
1502 	if (!br_mdb_entry)
1503 		return NULL;
1504 
1505 	mdb_entry = prestera_mdb_entry_create(sw, addr, vid);
1506 	if (!mdb_entry)
1507 		goto err_mdb_alloc;
1508 
1509 	br_mdb_entry->mdb = mdb_entry;
1510 	br_mdb_entry->bridge = br_dev;
1511 	br_mdb_entry->enabled = true;
1512 	INIT_LIST_HEAD(&br_mdb_entry->br_mdb_port_list);
1513 
1514 	list_add(&br_mdb_entry->br_mdb_entry_node, &br_dev->br_mdb_entry_list);
1515 
1516 	return br_mdb_entry;
1517 
1518 err_mdb_alloc:
1519 	kfree(br_mdb_entry);
1520 	return NULL;
1521 }
1522 
prestera_br_mdb_port_add(struct prestera_br_mdb_entry * br_mdb,struct prestera_bridge_port * br_port)1523 static int prestera_br_mdb_port_add(struct prestera_br_mdb_entry *br_mdb,
1524 				    struct prestera_bridge_port *br_port)
1525 {
1526 	struct prestera_br_mdb_port *br_mdb_port;
1527 
1528 	list_for_each_entry(br_mdb_port, &br_mdb->br_mdb_port_list,
1529 			    br_mdb_port_node)
1530 		if (br_mdb_port->br_port == br_port)
1531 			return 0;
1532 
1533 	br_mdb_port = kzalloc(sizeof(*br_mdb_port), GFP_KERNEL);
1534 	if (!br_mdb_port)
1535 		return -ENOMEM;
1536 
1537 	br_mdb_port->br_port = br_port;
1538 	list_add(&br_mdb_port->br_mdb_port_node,
1539 		 &br_mdb->br_mdb_port_list);
1540 
1541 	return 0;
1542 }
1543 
1544 static struct prestera_br_mdb_entry *
prestera_br_mdb_entry_find(struct prestera_bridge * br_dev,const unsigned char * addr,u16 vid)1545 prestera_br_mdb_entry_find(struct prestera_bridge *br_dev,
1546 			   const unsigned char *addr, u16 vid)
1547 {
1548 	struct prestera_br_mdb_entry *br_mdb;
1549 
1550 	list_for_each_entry(br_mdb, &br_dev->br_mdb_entry_list,
1551 			    br_mdb_entry_node)
1552 		if (ether_addr_equal(&br_mdb->mdb->addr[0], addr) &&
1553 		    vid == br_mdb->mdb->vid)
1554 			return br_mdb;
1555 
1556 	return NULL;
1557 }
1558 
1559 static struct prestera_br_mdb_entry *
prestera_br_mdb_entry_get(struct prestera_switch * sw,struct prestera_bridge * br_dev,const unsigned char * addr,u16 vid)1560 prestera_br_mdb_entry_get(struct prestera_switch *sw,
1561 			  struct prestera_bridge *br_dev,
1562 			  const unsigned char *addr, u16 vid)
1563 {
1564 	struct prestera_br_mdb_entry *br_mdb;
1565 
1566 	br_mdb = prestera_br_mdb_entry_find(br_dev, addr, vid);
1567 	if (br_mdb)
1568 		return br_mdb;
1569 
1570 	return prestera_br_mdb_entry_create(sw, br_dev, addr, vid);
1571 }
1572 
1573 static int
prestera_mdb_port_addr_obj_add(const struct switchdev_obj_port_mdb * mdb)1574 prestera_mdb_port_addr_obj_add(const struct switchdev_obj_port_mdb *mdb)
1575 {
1576 	struct prestera_br_mdb_entry *br_mdb;
1577 	struct prestera_bridge_port *br_port;
1578 	struct prestera_bridge *br_dev;
1579 	struct prestera_switch *sw;
1580 	struct prestera_port *port;
1581 	int err;
1582 
1583 	sw = prestera_switch_get(mdb->obj.orig_dev);
1584 	port = prestera_port_dev_lower_find(mdb->obj.orig_dev);
1585 
1586 	br_port = prestera_bridge_port_find(sw, mdb->obj.orig_dev);
1587 	if (!br_port)
1588 		return 0;
1589 
1590 	br_dev = br_port->bridge;
1591 
1592 	if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid))
1593 		return 0;
1594 
1595 	if (mdb->vid)
1596 		br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0],
1597 						   mdb->vid);
1598 	else
1599 		br_mdb = prestera_br_mdb_entry_get(sw, br_dev, &mdb->addr[0],
1600 						   br_dev->bridge_id);
1601 
1602 	if (!br_mdb)
1603 		return -ENOMEM;
1604 
1605 	/* Make sure newly allocated MDB entry gets disabled if either MC is
1606 	 * disabled, or the mrouter does not exist.
1607 	 */
1608 	WARN_ON(prestera_mdb_enable_set(br_mdb, br_dev->multicast_enabled &&
1609 					br_dev->mrouter_exist));
1610 
1611 	err = prestera_br_mdb_port_add(br_mdb, br_port);
1612 	if (err) {
1613 		prestera_br_mdb_entry_put(br_mdb);
1614 		return err;
1615 	}
1616 
1617 	err = prestera_br_mdb_sync(br_dev);
1618 	if (err)
1619 		return err;
1620 
1621 	return 0;
1622 }
1623 
prestera_port_obj_add(struct net_device * dev,const void * ctx,const struct switchdev_obj * obj,struct netlink_ext_ack * extack)1624 static int prestera_port_obj_add(struct net_device *dev, const void *ctx,
1625 				 const struct switchdev_obj *obj,
1626 				 struct netlink_ext_ack *extack)
1627 {
1628 	struct prestera_port *port = netdev_priv(dev);
1629 	const struct switchdev_obj_port_vlan *vlan;
1630 	const struct switchdev_obj_port_mdb *mdb;
1631 	int err = 0;
1632 
1633 	switch (obj->id) {
1634 	case SWITCHDEV_OBJ_ID_PORT_VLAN:
1635 		vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
1636 		return prestera_port_vlans_add(port, vlan, extack);
1637 	case SWITCHDEV_OBJ_ID_PORT_MDB:
1638 		mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1639 		err = prestera_mdb_port_addr_obj_add(mdb);
1640 		break;
1641 	case SWITCHDEV_OBJ_ID_HOST_MDB:
1642 		fallthrough;
1643 	default:
1644 		err = -EOPNOTSUPP;
1645 		break;
1646 	}
1647 
1648 	return err;
1649 }
1650 
prestera_port_vlans_del(struct prestera_port * port,const struct switchdev_obj_port_vlan * vlan)1651 static int prestera_port_vlans_del(struct prestera_port *port,
1652 				   const struct switchdev_obj_port_vlan *vlan)
1653 {
1654 	struct net_device *orig_dev = vlan->obj.orig_dev;
1655 	struct prestera_bridge_port *br_port;
1656 	struct prestera_switch *sw = port->sw;
1657 
1658 	if (netif_is_bridge_master(orig_dev))
1659 		return -EOPNOTSUPP;
1660 
1661 	br_port = prestera_bridge_port_by_dev(sw->swdev, port->dev);
1662 	if (WARN_ON(!br_port))
1663 		return -EINVAL;
1664 
1665 	if (!br_port->bridge->vlan_enabled)
1666 		return 0;
1667 
1668 	prestera_bridge_port_vlan_del(port, br_port, vlan->vid);
1669 
1670 	return 0;
1671 }
1672 
1673 static int
prestera_mdb_port_addr_obj_del(struct prestera_port * port,const struct switchdev_obj_port_mdb * mdb)1674 prestera_mdb_port_addr_obj_del(struct prestera_port *port,
1675 			       const struct switchdev_obj_port_mdb *mdb)
1676 {
1677 	struct prestera_br_mdb_entry *br_mdb;
1678 	struct prestera_bridge_port *br_port;
1679 	struct prestera_bridge *br_dev;
1680 	int err;
1681 
1682 	/* Bridge port no longer exists - and so does this MDB entry */
1683 	br_port = prestera_bridge_port_find(port->sw, mdb->obj.orig_dev);
1684 	if (!br_port)
1685 		return 0;
1686 
1687 	/* Removing MDB with non-existing VLAN - not supported; */
1688 	if (mdb->vid && !prestera_port_vlan_by_vid(port, mdb->vid))
1689 		return 0;
1690 
1691 	br_dev = br_port->bridge;
1692 
1693 	if (br_port->bridge->vlan_enabled)
1694 		br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0],
1695 						    mdb->vid);
1696 	else
1697 		br_mdb = prestera_br_mdb_entry_find(br_dev, &mdb->addr[0],
1698 						    br_port->bridge->bridge_id);
1699 
1700 	if (!br_mdb)
1701 		return 0;
1702 
1703 	/* Since there might be a situation that this port was the last in the
1704 	 * MDB group, we have to both remove this port from software and HW MDB,
1705 	 * sync MDB table, and then destroy software MDB (if needed).
1706 	 */
1707 	prestera_br_mdb_port_del(br_mdb, br_port);
1708 
1709 	prestera_br_mdb_entry_put(br_mdb);
1710 
1711 	err = prestera_br_mdb_sync(br_dev);
1712 	if (err)
1713 		return err;
1714 
1715 	return 0;
1716 }
1717 
prestera_port_obj_del(struct net_device * dev,const void * ctx,const struct switchdev_obj * obj)1718 static int prestera_port_obj_del(struct net_device *dev, const void *ctx,
1719 				 const struct switchdev_obj *obj)
1720 {
1721 	struct prestera_port *port = netdev_priv(dev);
1722 	const struct switchdev_obj_port_mdb *mdb;
1723 	int err = 0;
1724 
1725 	switch (obj->id) {
1726 	case SWITCHDEV_OBJ_ID_PORT_VLAN:
1727 		return prestera_port_vlans_del(port, SWITCHDEV_OBJ_PORT_VLAN(obj));
1728 	case SWITCHDEV_OBJ_ID_PORT_MDB:
1729 		mdb = SWITCHDEV_OBJ_PORT_MDB(obj);
1730 		err = prestera_mdb_port_addr_obj_del(port, mdb);
1731 		break;
1732 	default:
1733 		err = -EOPNOTSUPP;
1734 		break;
1735 	}
1736 
1737 	return err;
1738 }
1739 
prestera_switchdev_blk_event(struct notifier_block * unused,unsigned long event,void * ptr)1740 static int prestera_switchdev_blk_event(struct notifier_block *unused,
1741 					unsigned long event, void *ptr)
1742 {
1743 	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
1744 	int err;
1745 
1746 	switch (event) {
1747 	case SWITCHDEV_PORT_OBJ_ADD:
1748 		err = switchdev_handle_port_obj_add(dev, ptr,
1749 						    prestera_netdev_check,
1750 						    prestera_port_obj_add);
1751 		break;
1752 	case SWITCHDEV_PORT_OBJ_DEL:
1753 		err = switchdev_handle_port_obj_del(dev, ptr,
1754 						    prestera_netdev_check,
1755 						    prestera_port_obj_del);
1756 		break;
1757 	case SWITCHDEV_PORT_ATTR_SET:
1758 		err = switchdev_handle_port_attr_set(dev, ptr,
1759 						     prestera_netdev_check,
1760 						     prestera_port_obj_attr_set);
1761 		break;
1762 	default:
1763 		return NOTIFY_DONE;
1764 	}
1765 
1766 	return notifier_from_errno(err);
1767 }
1768 
prestera_fdb_event(struct prestera_switch * sw,struct prestera_event * evt,void * arg)1769 static void prestera_fdb_event(struct prestera_switch *sw,
1770 			       struct prestera_event *evt, void *arg)
1771 {
1772 	struct switchdev_notifier_fdb_info info = {};
1773 	struct net_device *dev = NULL;
1774 	struct prestera_port *port;
1775 	struct prestera_lag *lag;
1776 
1777 	switch (evt->fdb_evt.type) {
1778 	case PRESTERA_FDB_ENTRY_TYPE_REG_PORT:
1779 		port = prestera_find_port(sw, evt->fdb_evt.dest.port_id);
1780 		if (port)
1781 			dev = port->dev;
1782 		break;
1783 	case PRESTERA_FDB_ENTRY_TYPE_LAG:
1784 		lag = prestera_lag_by_id(sw, evt->fdb_evt.dest.lag_id);
1785 		if (lag)
1786 			dev = lag->dev;
1787 		break;
1788 	default:
1789 		return;
1790 	}
1791 
1792 	if (!dev)
1793 		return;
1794 
1795 	info.addr = evt->fdb_evt.data.mac;
1796 	info.vid = evt->fdb_evt.vid;
1797 	info.offloaded = true;
1798 
1799 	rtnl_lock();
1800 
1801 	switch (evt->id) {
1802 	case PRESTERA_FDB_EVENT_LEARNED:
1803 		call_switchdev_notifiers(SWITCHDEV_FDB_ADD_TO_BRIDGE,
1804 					 dev, &info.info, NULL);
1805 		break;
1806 	case PRESTERA_FDB_EVENT_AGED:
1807 		call_switchdev_notifiers(SWITCHDEV_FDB_DEL_TO_BRIDGE,
1808 					 dev, &info.info, NULL);
1809 		break;
1810 	}
1811 
1812 	rtnl_unlock();
1813 }
1814 
prestera_fdb_init(struct prestera_switch * sw)1815 static int prestera_fdb_init(struct prestera_switch *sw)
1816 {
1817 	int err;
1818 
1819 	err = prestera_hw_event_handler_register(sw, PRESTERA_EVENT_TYPE_FDB,
1820 						 prestera_fdb_event, NULL);
1821 	if (err)
1822 		return err;
1823 
1824 	err = prestera_hw_switch_ageing_set(sw, PRESTERA_DEFAULT_AGEING_TIME_MS);
1825 	if (err)
1826 		goto err_ageing_set;
1827 
1828 	return 0;
1829 
1830 err_ageing_set:
1831 	prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1832 					     prestera_fdb_event);
1833 	return err;
1834 }
1835 
prestera_fdb_fini(struct prestera_switch * sw)1836 static void prestera_fdb_fini(struct prestera_switch *sw)
1837 {
1838 	prestera_hw_event_handler_unregister(sw, PRESTERA_EVENT_TYPE_FDB,
1839 					     prestera_fdb_event);
1840 }
1841 
prestera_switchdev_handler_init(struct prestera_switchdev * swdev)1842 static int prestera_switchdev_handler_init(struct prestera_switchdev *swdev)
1843 {
1844 	int err;
1845 
1846 	swdev->swdev_nb.notifier_call = prestera_switchdev_event;
1847 	err = register_switchdev_notifier(&swdev->swdev_nb);
1848 	if (err)
1849 		goto err_register_swdev_notifier;
1850 
1851 	swdev->swdev_nb_blk.notifier_call = prestera_switchdev_blk_event;
1852 	err = register_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1853 	if (err)
1854 		goto err_register_blk_swdev_notifier;
1855 
1856 	return 0;
1857 
1858 err_register_blk_swdev_notifier:
1859 	unregister_switchdev_notifier(&swdev->swdev_nb);
1860 err_register_swdev_notifier:
1861 	destroy_workqueue(swdev_wq);
1862 	return err;
1863 }
1864 
prestera_switchdev_handler_fini(struct prestera_switchdev * swdev)1865 static void prestera_switchdev_handler_fini(struct prestera_switchdev *swdev)
1866 {
1867 	unregister_switchdev_blocking_notifier(&swdev->swdev_nb_blk);
1868 	unregister_switchdev_notifier(&swdev->swdev_nb);
1869 }
1870 
prestera_switchdev_init(struct prestera_switch * sw)1871 int prestera_switchdev_init(struct prestera_switch *sw)
1872 {
1873 	struct prestera_switchdev *swdev;
1874 	int err;
1875 
1876 	swdev = kzalloc(sizeof(*swdev), GFP_KERNEL);
1877 	if (!swdev)
1878 		return -ENOMEM;
1879 
1880 	sw->swdev = swdev;
1881 	swdev->sw = sw;
1882 
1883 	INIT_LIST_HEAD(&swdev->bridge_list);
1884 
1885 	swdev_wq = alloc_ordered_workqueue("%s_ordered", 0, "prestera_br");
1886 	if (!swdev_wq) {
1887 		err = -ENOMEM;
1888 		goto err_alloc_wq;
1889 	}
1890 
1891 	err = prestera_switchdev_handler_init(swdev);
1892 	if (err)
1893 		goto err_swdev_init;
1894 
1895 	err = prestera_fdb_init(sw);
1896 	if (err)
1897 		goto err_fdb_init;
1898 
1899 	return 0;
1900 
1901 err_fdb_init:
1902 err_swdev_init:
1903 	destroy_workqueue(swdev_wq);
1904 err_alloc_wq:
1905 	kfree(swdev);
1906 
1907 	return err;
1908 }
1909 
prestera_switchdev_fini(struct prestera_switch * sw)1910 void prestera_switchdev_fini(struct prestera_switch *sw)
1911 {
1912 	struct prestera_switchdev *swdev = sw->swdev;
1913 
1914 	prestera_fdb_fini(sw);
1915 	prestera_switchdev_handler_fini(swdev);
1916 	destroy_workqueue(swdev_wq);
1917 	kfree(swdev);
1918 }
1919