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