]> git.ipfire.org Git - thirdparty/linux.git/blame - drivers/net/ethernet/mellanox/mlxsw/spectrum_switchdev.c
Merge tag 'drm-intel-fixes-2018-12-12-1' of git://anongit.freedesktop.org/drm/drm...
[thirdparty/linux.git] / drivers / net / ethernet / mellanox / mlxsw / spectrum_switchdev.c
CommitLineData
9948a064
JP
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
56ade8fe
JP
3
4#include <linux/kernel.h>
5#include <linux/types.h>
6#include <linux/netdevice.h>
7#include <linux/etherdevice.h>
8#include <linux/slab.h>
9#include <linux/device.h>
10#include <linux/skbuff.h>
11#include <linux/if_vlan.h>
12#include <linux/if_bridge.h>
13#include <linux/workqueue.h>
14#include <linux/jiffies.h>
4f2c6ae5 15#include <linux/rtnetlink.h>
9b63ef88 16#include <linux/netlink.h>
56ade8fe 17#include <net/switchdev.h>
1c30d183 18#include <net/vxlan.h>
56ade8fe 19
c520bc69 20#include "spectrum_span.h"
ea93c7b6 21#include "spectrum_switchdev.h"
56ade8fe
JP
22#include "spectrum.h"
23#include "core.h"
24#include "reg.h"
25
c57529e1
IS
26struct mlxsw_sp_bridge_ops;
27
5f6935c6
IS
28struct mlxsw_sp_bridge {
29 struct mlxsw_sp *mlxsw_sp;
30 struct {
31 struct delayed_work dw;
32#define MLXSW_SP_DEFAULT_LEARNING_INTERVAL 100
33 unsigned int interval; /* ms */
34 } fdb_notify;
35#define MLXSW_SP_MIN_AGEING_TIME 10
36#define MLXSW_SP_MAX_AGEING_TIME 1000000
37#define MLXSW_SP_DEFAULT_AGEING_TIME 300
38 u32 ageing_time;
c57529e1
IS
39 bool vlan_enabled_exists;
40 struct list_head bridges_list;
5f6935c6 41 DECLARE_BITMAP(mids_bitmap, MLXSW_SP_MID_MAX);
c57529e1
IS
42 const struct mlxsw_sp_bridge_ops *bridge_8021q_ops;
43 const struct mlxsw_sp_bridge_ops *bridge_8021d_ops;
44};
45
46struct mlxsw_sp_bridge_device {
47 struct net_device *dev;
48 struct list_head list;
49 struct list_head ports_list;
b80888a9 50 struct list_head mids_list;
c57529e1 51 u8 vlan_enabled:1,
593bc28a
YG
52 multicast_enabled:1,
53 mrouter:1;
c57529e1
IS
54 const struct mlxsw_sp_bridge_ops *ops;
55};
56
57struct mlxsw_sp_bridge_port {
58 struct net_device *dev;
59 struct mlxsw_sp_bridge_device *bridge_device;
60 struct list_head list;
61 struct list_head vlans_list;
62 unsigned int ref_count;
63 u8 stp_state;
64 unsigned long flags;
65 bool mrouter;
66 bool lagged;
67 union {
68 u16 lag_id;
69 u16 system_port;
70 };
71};
72
73struct mlxsw_sp_bridge_vlan {
74 struct list_head list;
75 struct list_head port_vlan_list;
76 u16 vid;
5f6935c6
IS
77};
78
c57529e1
IS
79struct mlxsw_sp_bridge_ops {
80 int (*port_join)(struct mlxsw_sp_bridge_device *bridge_device,
81 struct mlxsw_sp_bridge_port *bridge_port,
9b63ef88
IS
82 struct mlxsw_sp_port *mlxsw_sp_port,
83 struct netlink_ext_ack *extack);
c57529e1
IS
84 void (*port_leave)(struct mlxsw_sp_bridge_device *bridge_device,
85 struct mlxsw_sp_bridge_port *bridge_port,
86 struct mlxsw_sp_port *mlxsw_sp_port);
1c30d183
IS
87 int (*vxlan_join)(struct mlxsw_sp_bridge_device *bridge_device,
88 const struct net_device *vxlan_dev,
89 struct netlink_ext_ack *extack);
90 void (*vxlan_leave)(struct mlxsw_sp_bridge_device *bridge_device,
91 const struct net_device *vxlan_dev);
a1107487
IS
92 struct mlxsw_sp_fid *
93 (*fid_get)(struct mlxsw_sp_bridge_device *bridge_device,
94 u16 vid);
1231e04f
IS
95 struct mlxsw_sp_fid *
96 (*fid_lookup)(struct mlxsw_sp_bridge_device *bridge_device,
97 u16 vid);
98 u16 (*fid_vid)(struct mlxsw_sp_bridge_device *bridge_device,
99 const struct mlxsw_sp_fid *fid);
c57529e1
IS
100};
101
102static int
103mlxsw_sp_bridge_port_fdb_flush(struct mlxsw_sp *mlxsw_sp,
104 struct mlxsw_sp_bridge_port *bridge_port,
105 u16 fid_index);
106
bb5355b2
NF
107static void
108mlxsw_sp_bridge_port_mdb_flush(struct mlxsw_sp_port *mlxsw_sp_port,
109 struct mlxsw_sp_bridge_port *bridge_port);
110
2e3496cd
NF
111static void
112mlxsw_sp_bridge_mdb_mc_enable_sync(struct mlxsw_sp_port *mlxsw_sp_port,
113 struct mlxsw_sp_bridge_device
114 *bridge_device);
115
3ddda117
NF
116static void
117mlxsw_sp_port_mrouter_update_mdb(struct mlxsw_sp_port *mlxsw_sp_port,
118 struct mlxsw_sp_bridge_port *bridge_port,
119 bool add);
120
c57529e1
IS
121static struct mlxsw_sp_bridge_device *
122mlxsw_sp_bridge_device_find(const struct mlxsw_sp_bridge *bridge,
123 const struct net_device *br_dev)
5f6935c6 124{
c57529e1
IS
125 struct mlxsw_sp_bridge_device *bridge_device;
126
127 list_for_each_entry(bridge_device, &bridge->bridges_list, list)
128 if (bridge_device->dev == br_dev)
129 return bridge_device;
130
131 return NULL;
90045fc9
IS
132}
133
134bool mlxsw_sp_bridge_device_is_offloaded(const struct mlxsw_sp *mlxsw_sp,
135 const struct net_device *br_dev)
136{
137 return !!mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
5f6935c6
IS
138}
139
602b74ed
IS
140static int mlxsw_sp_bridge_device_upper_rif_destroy(struct net_device *dev,
141 void *data)
142{
143 struct mlxsw_sp *mlxsw_sp = data;
144
145 mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
146 return 0;
147}
148
149static void mlxsw_sp_bridge_device_rifs_destroy(struct mlxsw_sp *mlxsw_sp,
150 struct net_device *dev)
151{
152 mlxsw_sp_rif_destroy_by_dev(mlxsw_sp, dev);
153 netdev_walk_all_upper_dev_rcu(dev,
154 mlxsw_sp_bridge_device_upper_rif_destroy,
155 mlxsw_sp);
156}
157
c57529e1
IS
158static struct mlxsw_sp_bridge_device *
159mlxsw_sp_bridge_device_create(struct mlxsw_sp_bridge *bridge,
160 struct net_device *br_dev)
e4b6f693 161{
c57529e1
IS
162 struct device *dev = bridge->mlxsw_sp->bus_info->dev;
163 struct mlxsw_sp_bridge_device *bridge_device;
164 bool vlan_enabled = br_vlan_enabled(br_dev);
e4b6f693 165
c57529e1
IS
166 if (vlan_enabled && bridge->vlan_enabled_exists) {
167 dev_err(dev, "Only one VLAN-aware bridge is supported\n");
168 return ERR_PTR(-EINVAL);
169 }
e4b6f693 170
c57529e1
IS
171 bridge_device = kzalloc(sizeof(*bridge_device), GFP_KERNEL);
172 if (!bridge_device)
173 return ERR_PTR(-ENOMEM);
174
175 bridge_device->dev = br_dev;
176 bridge_device->vlan_enabled = vlan_enabled;
177 bridge_device->multicast_enabled = br_multicast_enabled(br_dev);
593bc28a 178 bridge_device->mrouter = br_multicast_router(br_dev);
c57529e1
IS
179 INIT_LIST_HEAD(&bridge_device->ports_list);
180 if (vlan_enabled) {
181 bridge->vlan_enabled_exists = true;
182 bridge_device->ops = bridge->bridge_8021q_ops;
183 } else {
184 bridge_device->ops = bridge->bridge_8021d_ops;
185 }
b80888a9 186 INIT_LIST_HEAD(&bridge_device->mids_list);
c57529e1 187 list_add(&bridge_device->list, &bridge->bridges_list);
e4b6f693 188
c57529e1 189 return bridge_device;
e4b6f693
ER
190}
191
c57529e1
IS
192static void
193mlxsw_sp_bridge_device_destroy(struct mlxsw_sp_bridge *bridge,
194 struct mlxsw_sp_bridge_device *bridge_device)
54a73201 195{
602b74ed
IS
196 mlxsw_sp_bridge_device_rifs_destroy(bridge->mlxsw_sp,
197 bridge_device->dev);
c57529e1
IS
198 list_del(&bridge_device->list);
199 if (bridge_device->vlan_enabled)
200 bridge->vlan_enabled_exists = false;
201 WARN_ON(!list_empty(&bridge_device->ports_list));
bb5355b2 202 WARN_ON(!list_empty(&bridge_device->mids_list));
c57529e1
IS
203 kfree(bridge_device);
204}
54a73201 205
c57529e1
IS
206static struct mlxsw_sp_bridge_device *
207mlxsw_sp_bridge_device_get(struct mlxsw_sp_bridge *bridge,
208 struct net_device *br_dev)
209{
210 struct mlxsw_sp_bridge_device *bridge_device;
211
212 bridge_device = mlxsw_sp_bridge_device_find(bridge, br_dev);
213 if (bridge_device)
214 return bridge_device;
215
216 return mlxsw_sp_bridge_device_create(bridge, br_dev);
217}
218
219static void
220mlxsw_sp_bridge_device_put(struct mlxsw_sp_bridge *bridge,
221 struct mlxsw_sp_bridge_device *bridge_device)
222{
223 if (list_empty(&bridge_device->ports_list))
224 mlxsw_sp_bridge_device_destroy(bridge, bridge_device);
225}
226
227static struct mlxsw_sp_bridge_port *
228__mlxsw_sp_bridge_port_find(const struct mlxsw_sp_bridge_device *bridge_device,
229 const struct net_device *brport_dev)
230{
231 struct mlxsw_sp_bridge_port *bridge_port;
232
233 list_for_each_entry(bridge_port, &bridge_device->ports_list, list) {
234 if (bridge_port->dev == brport_dev)
235 return bridge_port;
236 }
237
238 return NULL;
239}
240
ea93c7b6 241struct mlxsw_sp_bridge_port *
c57529e1
IS
242mlxsw_sp_bridge_port_find(struct mlxsw_sp_bridge *bridge,
243 struct net_device *brport_dev)
244{
245 struct net_device *br_dev = netdev_master_upper_dev_get(brport_dev);
246 struct mlxsw_sp_bridge_device *bridge_device;
247
248 if (!br_dev)
249 return NULL;
250
251 bridge_device = mlxsw_sp_bridge_device_find(bridge, br_dev);
252 if (!bridge_device)
253 return NULL;
254
255 return __mlxsw_sp_bridge_port_find(bridge_device, brport_dev);
256}
257
258static struct mlxsw_sp_bridge_port *
259mlxsw_sp_bridge_port_create(struct mlxsw_sp_bridge_device *bridge_device,
260 struct net_device *brport_dev)
261{
262 struct mlxsw_sp_bridge_port *bridge_port;
263 struct mlxsw_sp_port *mlxsw_sp_port;
264
265 bridge_port = kzalloc(sizeof(*bridge_port), GFP_KERNEL);
266 if (!bridge_port)
267 return NULL;
268
269 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(brport_dev);
270 bridge_port->lagged = mlxsw_sp_port->lagged;
271 if (bridge_port->lagged)
272 bridge_port->lag_id = mlxsw_sp_port->lag_id;
273 else
274 bridge_port->system_port = mlxsw_sp_port->local_port;
275 bridge_port->dev = brport_dev;
276 bridge_port->bridge_device = bridge_device;
277 bridge_port->stp_state = BR_STATE_DISABLED;
9dad51bd
NF
278 bridge_port->flags = BR_LEARNING | BR_FLOOD | BR_LEARNING_SYNC |
279 BR_MCAST_FLOOD;
c57529e1
IS
280 INIT_LIST_HEAD(&bridge_port->vlans_list);
281 list_add(&bridge_port->list, &bridge_device->ports_list);
282 bridge_port->ref_count = 1;
283
284 return bridge_port;
285}
286
287static void
288mlxsw_sp_bridge_port_destroy(struct mlxsw_sp_bridge_port *bridge_port)
289{
290 list_del(&bridge_port->list);
291 WARN_ON(!list_empty(&bridge_port->vlans_list));
292 kfree(bridge_port);
293}
294
295static bool
296mlxsw_sp_bridge_port_should_destroy(const struct mlxsw_sp_bridge_port *
297 bridge_port)
298{
993107fe
IS
299 struct net_device *dev = bridge_port->dev;
300 struct mlxsw_sp *mlxsw_sp;
301
302 if (is_vlan_dev(dev))
303 mlxsw_sp = mlxsw_sp_lower_get(vlan_dev_real_dev(dev));
304 else
305 mlxsw_sp = mlxsw_sp_lower_get(dev);
c57529e1
IS
306
307 /* In case ports were pulled from out of a bridged LAG, then
308 * it's possible the reference count isn't zero, yet the bridge
309 * port should be destroyed, as it's no longer an upper of ours.
310 */
311 if (!mlxsw_sp && list_empty(&bridge_port->vlans_list))
312 return true;
313 else if (bridge_port->ref_count == 0)
314 return true;
315 else
316 return false;
317}
318
319static struct mlxsw_sp_bridge_port *
320mlxsw_sp_bridge_port_get(struct mlxsw_sp_bridge *bridge,
321 struct net_device *brport_dev)
322{
323 struct net_device *br_dev = netdev_master_upper_dev_get(brport_dev);
324 struct mlxsw_sp_bridge_device *bridge_device;
325 struct mlxsw_sp_bridge_port *bridge_port;
326 int err;
327
328 bridge_port = mlxsw_sp_bridge_port_find(bridge, brport_dev);
329 if (bridge_port) {
330 bridge_port->ref_count++;
331 return bridge_port;
332 }
333
334 bridge_device = mlxsw_sp_bridge_device_get(bridge, br_dev);
335 if (IS_ERR(bridge_device))
336 return ERR_CAST(bridge_device);
337
338 bridge_port = mlxsw_sp_bridge_port_create(bridge_device, brport_dev);
339 if (!bridge_port) {
340 err = -ENOMEM;
341 goto err_bridge_port_create;
342 }
343
344 return bridge_port;
345
346err_bridge_port_create:
347 mlxsw_sp_bridge_device_put(bridge, bridge_device);
348 return ERR_PTR(err);
349}
350
351static void mlxsw_sp_bridge_port_put(struct mlxsw_sp_bridge *bridge,
352 struct mlxsw_sp_bridge_port *bridge_port)
353{
354 struct mlxsw_sp_bridge_device *bridge_device;
355
356 bridge_port->ref_count--;
357 if (!mlxsw_sp_bridge_port_should_destroy(bridge_port))
358 return;
359 bridge_device = bridge_port->bridge_device;
360 mlxsw_sp_bridge_port_destroy(bridge_port);
361 mlxsw_sp_bridge_device_put(bridge, bridge_device);
362}
363
364static struct mlxsw_sp_port_vlan *
365mlxsw_sp_port_vlan_find_by_bridge(struct mlxsw_sp_port *mlxsw_sp_port,
366 const struct mlxsw_sp_bridge_device *
367 bridge_device,
368 u16 vid)
369{
370 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
371
372 list_for_each_entry(mlxsw_sp_port_vlan, &mlxsw_sp_port->vlans_list,
373 list) {
374 if (!mlxsw_sp_port_vlan->bridge_port)
375 continue;
376 if (mlxsw_sp_port_vlan->bridge_port->bridge_device !=
377 bridge_device)
378 continue;
379 if (bridge_device->vlan_enabled &&
380 mlxsw_sp_port_vlan->vid != vid)
381 continue;
382 return mlxsw_sp_port_vlan;
1e5d9432
NF
383 }
384
c57529e1
IS
385 return NULL;
386}
387
388static struct mlxsw_sp_port_vlan*
389mlxsw_sp_port_vlan_find_by_fid(struct mlxsw_sp_port *mlxsw_sp_port,
390 u16 fid_index)
391{
392 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
393
394 list_for_each_entry(mlxsw_sp_port_vlan, &mlxsw_sp_port->vlans_list,
395 list) {
396 struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
397
a1107487 398 if (fid && mlxsw_sp_fid_index(fid) == fid_index)
c57529e1
IS
399 return mlxsw_sp_port_vlan;
400 }
401
402 return NULL;
403}
404
405static struct mlxsw_sp_bridge_vlan *
406mlxsw_sp_bridge_vlan_find(const struct mlxsw_sp_bridge_port *bridge_port,
407 u16 vid)
408{
409 struct mlxsw_sp_bridge_vlan *bridge_vlan;
410
411 list_for_each_entry(bridge_vlan, &bridge_port->vlans_list, list) {
412 if (bridge_vlan->vid == vid)
413 return bridge_vlan;
414 }
415
416 return NULL;
417}
418
419static struct mlxsw_sp_bridge_vlan *
420mlxsw_sp_bridge_vlan_create(struct mlxsw_sp_bridge_port *bridge_port, u16 vid)
421{
422 struct mlxsw_sp_bridge_vlan *bridge_vlan;
423
424 bridge_vlan = kzalloc(sizeof(*bridge_vlan), GFP_KERNEL);
425 if (!bridge_vlan)
426 return NULL;
427
428 INIT_LIST_HEAD(&bridge_vlan->port_vlan_list);
429 bridge_vlan->vid = vid;
430 list_add(&bridge_vlan->list, &bridge_port->vlans_list);
54a73201 431
c57529e1
IS
432 return bridge_vlan;
433}
434
435static void
436mlxsw_sp_bridge_vlan_destroy(struct mlxsw_sp_bridge_vlan *bridge_vlan)
437{
438 list_del(&bridge_vlan->list);
439 WARN_ON(!list_empty(&bridge_vlan->port_vlan_list));
440 kfree(bridge_vlan);
441}
442
443static struct mlxsw_sp_bridge_vlan *
444mlxsw_sp_bridge_vlan_get(struct mlxsw_sp_bridge_port *bridge_port, u16 vid)
445{
446 struct mlxsw_sp_bridge_vlan *bridge_vlan;
447
448 bridge_vlan = mlxsw_sp_bridge_vlan_find(bridge_port, vid);
449 if (bridge_vlan)
450 return bridge_vlan;
54a73201 451
c57529e1
IS
452 return mlxsw_sp_bridge_vlan_create(bridge_port, vid);
453}
454
455static void mlxsw_sp_bridge_vlan_put(struct mlxsw_sp_bridge_vlan *bridge_vlan)
456{
457 if (list_empty(&bridge_vlan->port_vlan_list))
458 mlxsw_sp_bridge_vlan_destroy(bridge_vlan);
459}
460
461static void mlxsw_sp_port_bridge_flags_get(struct mlxsw_sp_bridge *bridge,
462 struct net_device *dev,
463 unsigned long *brport_flags)
464{
465 struct mlxsw_sp_bridge_port *bridge_port;
466
467 bridge_port = mlxsw_sp_bridge_port_find(bridge, dev);
468 if (WARN_ON(!bridge_port))
469 return;
470
471 memcpy(brport_flags, &bridge_port->flags, sizeof(*brport_flags));
54a73201
IS
472}
473
56ade8fe
JP
474static int mlxsw_sp_port_attr_get(struct net_device *dev,
475 struct switchdev_attr *attr)
476{
477 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
478 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
479
480 switch (attr->id) {
481 case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
482 attr->u.ppid.id_len = sizeof(mlxsw_sp->base_mac);
483 memcpy(&attr->u.ppid.id, &mlxsw_sp->base_mac,
484 attr->u.ppid.id_len);
485 break;
486 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
c57529e1
IS
487 mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
488 &attr->u.brport_flags);
56ade8fe 489 break;
c7b566cd 490 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
9dad51bd
NF
491 attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD |
492 BR_MCAST_FLOOD;
c7b566cd 493 break;
56ade8fe
JP
494 default:
495 return -EOPNOTSUPP;
496 }
497
498 return 0;
499}
500
c57529e1
IS
501static int
502mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
503 struct mlxsw_sp_bridge_vlan *bridge_vlan,
504 u8 state)
505{
506 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
507
508 list_for_each_entry(mlxsw_sp_port_vlan, &bridge_vlan->port_vlan_list,
509 bridge_vlan_node) {
510 if (mlxsw_sp_port_vlan->mlxsw_sp_port != mlxsw_sp_port)
511 continue;
512 return mlxsw_sp_port_vid_stp_set(mlxsw_sp_port,
513 bridge_vlan->vid, state);
514 }
515
516 return 0;
517}
518
45bfe6b4
IS
519static int mlxsw_sp_port_attr_stp_state_set(struct mlxsw_sp_port *mlxsw_sp_port,
520 struct switchdev_trans *trans,
c57529e1 521 struct net_device *orig_dev,
45bfe6b4 522 u8 state)
56ade8fe 523{
c57529e1
IS
524 struct mlxsw_sp_bridge_port *bridge_port;
525 struct mlxsw_sp_bridge_vlan *bridge_vlan;
56ade8fe
JP
526 int err;
527
45bfe6b4
IS
528 if (switchdev_trans_ph_prepare(trans))
529 return 0;
54a73201 530
c57529e1
IS
531 /* It's possible we failed to enslave the port, yet this
532 * operation is executed due to it being deferred.
533 */
534 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
535 orig_dev);
536 if (!bridge_port)
56ade8fe
JP
537 return 0;
538
c57529e1
IS
539 list_for_each_entry(bridge_vlan, &bridge_port->vlans_list, list) {
540 err = mlxsw_sp_port_bridge_vlan_stp_set(mlxsw_sp_port,
541 bridge_vlan, state);
45bfe6b4 542 if (err)
c57529e1 543 goto err_port_bridge_vlan_stp_set;
45bfe6b4 544 }
c57529e1
IS
545
546 bridge_port->stp_state = state;
45bfe6b4
IS
547
548 return 0;
c57529e1
IS
549
550err_port_bridge_vlan_stp_set:
551 list_for_each_entry_continue_reverse(bridge_vlan,
552 &bridge_port->vlans_list, list)
553 mlxsw_sp_port_bridge_vlan_stp_set(mlxsw_sp_port, bridge_vlan,
554 bridge_port->stp_state);
555 return err;
56ade8fe
JP
556}
557
c57529e1
IS
558static int
559mlxsw_sp_port_bridge_vlan_flood_set(struct mlxsw_sp_port *mlxsw_sp_port,
560 struct mlxsw_sp_bridge_vlan *bridge_vlan,
a1107487 561 enum mlxsw_sp_flood_type packet_type,
c57529e1 562 bool member)
eaa7df3c 563{
c57529e1 564 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
0293038e 565
c57529e1
IS
566 list_for_each_entry(mlxsw_sp_port_vlan, &bridge_vlan->port_vlan_list,
567 bridge_vlan_node) {
568 if (mlxsw_sp_port_vlan->mlxsw_sp_port != mlxsw_sp_port)
569 continue;
a1107487
IS
570 return mlxsw_sp_fid_flood_set(mlxsw_sp_port_vlan->fid,
571 packet_type,
572 mlxsw_sp_port->local_port,
573 member);
c57529e1 574 }
aad8b6ba 575
eaa7df3c 576 return 0;
0293038e
IS
577}
578
c57529e1
IS
579static int
580mlxsw_sp_bridge_port_flood_table_set(struct mlxsw_sp_port *mlxsw_sp_port,
581 struct mlxsw_sp_bridge_port *bridge_port,
a1107487 582 enum mlxsw_sp_flood_type packet_type,
c57529e1 583 bool member)
0293038e 584{
c57529e1 585 struct mlxsw_sp_bridge_vlan *bridge_vlan;
0293038e
IS
586 int err;
587
c57529e1
IS
588 list_for_each_entry(bridge_vlan, &bridge_port->vlans_list, list) {
589 err = mlxsw_sp_port_bridge_vlan_flood_set(mlxsw_sp_port,
a1107487
IS
590 bridge_vlan,
591 packet_type,
c57529e1
IS
592 member);
593 if (err)
594 goto err_port_bridge_vlan_flood_set;
0293038e
IS
595 }
596
597 return 0;
598
c57529e1
IS
599err_port_bridge_vlan_flood_set:
600 list_for_each_entry_continue_reverse(bridge_vlan,
601 &bridge_port->vlans_list, list)
602 mlxsw_sp_port_bridge_vlan_flood_set(mlxsw_sp_port, bridge_vlan,
a1107487 603 packet_type, !member);
0293038e
IS
604 return err;
605}
606
c57529e1
IS
607static int
608mlxsw_sp_port_bridge_vlan_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
609 struct mlxsw_sp_bridge_vlan *bridge_vlan,
610 bool set)
90e0f0c1 611{
c57529e1
IS
612 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
613 u16 vid = bridge_vlan->vid;
90e0f0c1 614
c57529e1
IS
615 list_for_each_entry(mlxsw_sp_port_vlan, &bridge_vlan->port_vlan_list,
616 bridge_vlan_node) {
617 if (mlxsw_sp_port_vlan->mlxsw_sp_port != mlxsw_sp_port)
618 continue;
619 return mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, set);
90e0f0c1
NF
620 }
621
c57529e1 622 return 0;
7f71eb46
IS
623}
624
c57529e1
IS
625static int
626mlxsw_sp_bridge_port_learning_set(struct mlxsw_sp_port *mlxsw_sp_port,
627 struct mlxsw_sp_bridge_port *bridge_port,
628 bool set)
89b548f0 629{
c57529e1 630 struct mlxsw_sp_bridge_vlan *bridge_vlan;
89b548f0
IS
631 int err;
632
c57529e1
IS
633 list_for_each_entry(bridge_vlan, &bridge_port->vlans_list, list) {
634 err = mlxsw_sp_port_bridge_vlan_learning_set(mlxsw_sp_port,
635 bridge_vlan, set);
89b548f0 636 if (err)
c57529e1 637 goto err_port_bridge_vlan_learning_set;
89b548f0
IS
638 }
639
640 return 0;
641
c57529e1
IS
642err_port_bridge_vlan_learning_set:
643 list_for_each_entry_continue_reverse(bridge_vlan,
644 &bridge_port->vlans_list, list)
645 mlxsw_sp_port_bridge_vlan_learning_set(mlxsw_sp_port,
646 bridge_vlan, !set);
89b548f0
IS
647 return err;
648}
649
56ade8fe
JP
650static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
651 struct switchdev_trans *trans,
c57529e1 652 struct net_device *orig_dev,
56ade8fe
JP
653 unsigned long brport_flags)
654{
c57529e1 655 struct mlxsw_sp_bridge_port *bridge_port;
0293038e
IS
656 int err;
657
56ade8fe
JP
658 if (switchdev_trans_ph_prepare(trans))
659 return 0;
660
c57529e1
IS
661 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
662 orig_dev);
17b334a8
IS
663 if (!bridge_port)
664 return 0;
0293038e 665
c57529e1 666 err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
a1107487 667 MLXSW_SP_FLOOD_TYPE_UC,
c57529e1
IS
668 brport_flags & BR_FLOOD);
669 if (err)
670 return err;
89b548f0 671
c57529e1
IS
672 err = mlxsw_sp_bridge_port_learning_set(mlxsw_sp_port, bridge_port,
673 brport_flags & BR_LEARNING);
674 if (err)
675 return err;
0293038e 676
9dad51bd
NF
677 if (bridge_port->bridge_device->multicast_enabled)
678 goto out;
89b548f0 679
9dad51bd
NF
680 err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
681 MLXSW_SP_FLOOD_TYPE_MC,
682 brport_flags &
683 BR_MCAST_FLOOD);
684 if (err)
685 return err;
686
687out:
688 memcpy(&bridge_port->flags, &brport_flags, sizeof(brport_flags));
c57529e1 689 return 0;
56ade8fe
JP
690}
691
692static int mlxsw_sp_ageing_set(struct mlxsw_sp *mlxsw_sp, u32 ageing_time)
693{
694 char sfdat_pl[MLXSW_REG_SFDAT_LEN];
695 int err;
696
697 mlxsw_reg_sfdat_pack(sfdat_pl, ageing_time);
698 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdat), sfdat_pl);
699 if (err)
700 return err;
5f6935c6 701 mlxsw_sp->bridge->ageing_time = ageing_time;
56ade8fe
JP
702 return 0;
703}
704
705static int mlxsw_sp_port_attr_br_ageing_set(struct mlxsw_sp_port *mlxsw_sp_port,
706 struct switchdev_trans *trans,
135f9ece 707 unsigned long ageing_clock_t)
56ade8fe
JP
708{
709 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
135f9ece 710 unsigned long ageing_jiffies = clock_t_to_jiffies(ageing_clock_t);
56ade8fe
JP
711 u32 ageing_time = jiffies_to_msecs(ageing_jiffies) / 1000;
712
869f63a4
IS
713 if (switchdev_trans_ph_prepare(trans)) {
714 if (ageing_time < MLXSW_SP_MIN_AGEING_TIME ||
715 ageing_time > MLXSW_SP_MAX_AGEING_TIME)
716 return -ERANGE;
717 else
718 return 0;
719 }
56ade8fe
JP
720
721 return mlxsw_sp_ageing_set(mlxsw_sp, ageing_time);
722}
723
26a4ea0f
ER
724static int mlxsw_sp_port_attr_br_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port,
725 struct switchdev_trans *trans,
726 struct net_device *orig_dev,
727 bool vlan_enabled)
728{
729 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
c57529e1 730 struct mlxsw_sp_bridge_device *bridge_device;
26a4ea0f 731
c57529e1
IS
732 if (!switchdev_trans_ph_prepare(trans))
733 return 0;
734
735 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, orig_dev);
736 if (WARN_ON(!bridge_device))
26a4ea0f 737 return -EINVAL;
26a4ea0f 738
c57529e1
IS
739 if (bridge_device->vlan_enabled == vlan_enabled)
740 return 0;
741
742 netdev_err(bridge_device->dev, "VLAN filtering can't be changed for existing bridge\n");
743 return -EINVAL;
26a4ea0f
ER
744}
745
dff37b58
NF
746static int mlxsw_sp_port_attr_mrouter_set(struct mlxsw_sp_port *mlxsw_sp_port,
747 struct switchdev_trans *trans,
748 struct net_device *orig_dev,
749 bool is_port_mrouter)
8ecd4591 750{
c57529e1 751 struct mlxsw_sp_bridge_port *bridge_port;
4eb6a3bd 752 int err;
c57529e1
IS
753
754 if (switchdev_trans_ph_prepare(trans))
755 return 0;
756
757 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp_port->mlxsw_sp->bridge,
758 orig_dev);
17b334a8
IS
759 if (!bridge_port)
760 return 0;
c57529e1
IS
761
762 if (!bridge_port->bridge_device->multicast_enabled)
4eb6a3bd 763 goto out;
c57529e1 764
4eb6a3bd
NF
765 err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port, bridge_port,
766 MLXSW_SP_FLOOD_TYPE_MC,
dff37b58 767 is_port_mrouter);
4eb6a3bd
NF
768 if (err)
769 return err;
770
3ddda117
NF
771 mlxsw_sp_port_mrouter_update_mdb(mlxsw_sp_port, bridge_port,
772 is_port_mrouter);
4eb6a3bd 773out:
dff37b58 774 bridge_port->mrouter = is_port_mrouter;
4eb6a3bd 775 return 0;
c57529e1
IS
776}
777
218a8f8a
NF
778static bool mlxsw_sp_mc_flood(const struct mlxsw_sp_bridge_port *bridge_port)
779{
780 const struct mlxsw_sp_bridge_device *bridge_device;
781
782 bridge_device = bridge_port->bridge_device;
9dad51bd
NF
783 return bridge_device->multicast_enabled ? bridge_port->mrouter :
784 bridge_port->flags & BR_MCAST_FLOOD;
218a8f8a
NF
785}
786
c57529e1
IS
787static int mlxsw_sp_port_mc_disabled_set(struct mlxsw_sp_port *mlxsw_sp_port,
788 struct switchdev_trans *trans,
789 struct net_device *orig_dev,
790 bool mc_disabled)
791{
792 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
793 struct mlxsw_sp_bridge_device *bridge_device;
794 struct mlxsw_sp_bridge_port *bridge_port;
795 int err;
796
8ecd4591
NF
797 if (switchdev_trans_ph_prepare(trans))
798 return 0;
799
c57529e1
IS
800 /* It's possible we failed to enslave the port, yet this
801 * operation is executed due to it being deferred.
802 */
803 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, orig_dev);
804 if (!bridge_device)
805 return 0;
806
2e3496cd
NF
807 if (bridge_device->multicast_enabled != !mc_disabled) {
808 bridge_device->multicast_enabled = !mc_disabled;
809 mlxsw_sp_bridge_mdb_mc_enable_sync(mlxsw_sp_port,
810 bridge_device);
811 }
812
c57529e1 813 list_for_each_entry(bridge_port, &bridge_device->ports_list, list) {
a1107487 814 enum mlxsw_sp_flood_type packet_type = MLXSW_SP_FLOOD_TYPE_MC;
218a8f8a 815 bool member = mlxsw_sp_mc_flood(bridge_port);
c57529e1
IS
816
817 err = mlxsw_sp_bridge_port_flood_table_set(mlxsw_sp_port,
a1107487
IS
818 bridge_port,
819 packet_type, member);
c57529e1
IS
820 if (err)
821 return err;
822 }
823
824 bridge_device->multicast_enabled = !mc_disabled;
8ecd4591
NF
825
826 return 0;
827}
828
593bc28a
YG
829static int mlxsw_sp_smid_router_port_set(struct mlxsw_sp *mlxsw_sp,
830 u16 mid_idx, bool add)
831{
832 char *smid_pl;
833 int err;
834
835 smid_pl = kmalloc(MLXSW_REG_SMID_LEN, GFP_KERNEL);
836 if (!smid_pl)
837 return -ENOMEM;
838
839 mlxsw_reg_smid_pack(smid_pl, mid_idx,
840 mlxsw_sp_router_port(mlxsw_sp), add);
841 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smid), smid_pl);
842 kfree(smid_pl);
843 return err;
844}
845
846static void
847mlxsw_sp_bridge_mrouter_update_mdb(struct mlxsw_sp *mlxsw_sp,
848 struct mlxsw_sp_bridge_device *bridge_device,
849 bool add)
850{
851 struct mlxsw_sp_mid *mid;
852
853 list_for_each_entry(mid, &bridge_device->mids_list, list)
854 mlxsw_sp_smid_router_port_set(mlxsw_sp, mid->mid, add);
855}
856
857static int
858mlxsw_sp_port_attr_br_mrouter_set(struct mlxsw_sp_port *mlxsw_sp_port,
859 struct switchdev_trans *trans,
860 struct net_device *orig_dev,
861 bool is_mrouter)
862{
863 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
864 struct mlxsw_sp_bridge_device *bridge_device;
865
866 if (switchdev_trans_ph_prepare(trans))
867 return 0;
868
869 /* It's possible we failed to enslave the port, yet this
870 * operation is executed due to it being deferred.
871 */
872 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, orig_dev);
873 if (!bridge_device)
874 return 0;
875
876 if (bridge_device->mrouter != is_mrouter)
877 mlxsw_sp_bridge_mrouter_update_mdb(mlxsw_sp, bridge_device,
878 is_mrouter);
879 bridge_device->mrouter = is_mrouter;
880 return 0;
881}
882
56ade8fe
JP
883static int mlxsw_sp_port_attr_set(struct net_device *dev,
884 const struct switchdev_attr *attr,
885 struct switchdev_trans *trans)
886{
887 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
c57529e1 888 int err;
54a73201 889
56ade8fe
JP
890 switch (attr->id) {
891 case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
892 err = mlxsw_sp_port_attr_stp_state_set(mlxsw_sp_port, trans,
c57529e1 893 attr->orig_dev,
56ade8fe
JP
894 attr->u.stp_state);
895 break;
896 case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
897 err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port, trans,
c57529e1 898 attr->orig_dev,
56ade8fe
JP
899 attr->u.brport_flags);
900 break;
901 case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
902 err = mlxsw_sp_port_attr_br_ageing_set(mlxsw_sp_port, trans,
903 attr->u.ageing_time);
904 break;
26a4ea0f
ER
905 case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
906 err = mlxsw_sp_port_attr_br_vlan_set(mlxsw_sp_port, trans,
907 attr->orig_dev,
908 attr->u.vlan_filtering);
909 break;
8ecd4591 910 case SWITCHDEV_ATTR_ID_PORT_MROUTER:
dff37b58
NF
911 err = mlxsw_sp_port_attr_mrouter_set(mlxsw_sp_port, trans,
912 attr->orig_dev,
913 attr->u.mrouter);
8ecd4591 914 break;
90e0f0c1
NF
915 case SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED:
916 err = mlxsw_sp_port_mc_disabled_set(mlxsw_sp_port, trans,
c57529e1 917 attr->orig_dev,
90e0f0c1
NF
918 attr->u.mc_disabled);
919 break;
593bc28a
YG
920 case SWITCHDEV_ATTR_ID_BRIDGE_MROUTER:
921 err = mlxsw_sp_port_attr_br_mrouter_set(mlxsw_sp_port, trans,
922 attr->orig_dev,
923 attr->u.mrouter);
924 break;
56ade8fe
JP
925 default:
926 err = -EOPNOTSUPP;
927 break;
928 }
929
c520bc69
PM
930 if (switchdev_trans_ph_commit(trans))
931 mlxsw_sp_span_respin(mlxsw_sp_port->mlxsw_sp);
932
56ade8fe
JP
933 return err;
934}
935
c57529e1
IS
936static int
937mlxsw_sp_port_vlan_fid_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
938 struct mlxsw_sp_bridge_port *bridge_port)
14d39461 939{
c57529e1 940 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
a1107487
IS
941 struct mlxsw_sp_bridge_device *bridge_device;
942 u8 local_port = mlxsw_sp_port->local_port;
c57529e1
IS
943 u16 vid = mlxsw_sp_port_vlan->vid;
944 struct mlxsw_sp_fid *fid;
fe9ccc78 945 int err;
14d39461 946
a1107487
IS
947 bridge_device = bridge_port->bridge_device;
948 fid = bridge_device->ops->fid_get(bridge_device, vid);
c57529e1
IS
949 if (IS_ERR(fid))
950 return PTR_ERR(fid);
951
a1107487
IS
952 err = mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_UC, local_port,
953 bridge_port->flags & BR_FLOOD);
fe9ccc78 954 if (err)
a1107487 955 goto err_fid_uc_flood_set;
14d39461 956
a1107487
IS
957 err = mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_MC, local_port,
958 mlxsw_sp_mc_flood(bridge_port));
c57529e1 959 if (err)
a1107487 960 goto err_fid_mc_flood_set;
8ecd4591 961
a1107487
IS
962 err = mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_BC, local_port,
963 true);
14d39461 964 if (err)
a1107487 965 goto err_fid_bc_flood_set;
14d39461 966
a1107487 967 err = mlxsw_sp_fid_port_vid_map(fid, mlxsw_sp_port, vid);
fe9ccc78 968 if (err)
a1107487 969 goto err_fid_port_vid_map;
c57529e1
IS
970
971 mlxsw_sp_port_vlan->fid = fid;
14d39461
IS
972
973 return 0;
974
a1107487
IS
975err_fid_port_vid_map:
976 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_BC, local_port, false);
977err_fid_bc_flood_set:
978 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_MC, local_port, false);
979err_fid_mc_flood_set:
980 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_UC, local_port, false);
981err_fid_uc_flood_set:
982 mlxsw_sp_fid_put(fid);
14d39461
IS
983 return err;
984}
985
c57529e1
IS
986static void
987mlxsw_sp_port_vlan_fid_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
14d39461 988{
c57529e1 989 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
c57529e1 990 struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
a1107487 991 u8 local_port = mlxsw_sp_port->local_port;
c57529e1
IS
992 u16 vid = mlxsw_sp_port_vlan->vid;
993
994 mlxsw_sp_port_vlan->fid = NULL;
a1107487
IS
995 mlxsw_sp_fid_port_vid_unmap(fid, mlxsw_sp_port, vid);
996 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_BC, local_port, false);
997 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_MC, local_port, false);
998 mlxsw_sp_fid_flood_set(fid, MLXSW_SP_FLOOD_TYPE_UC, local_port, false);
999 mlxsw_sp_fid_put(fid);
14d39461
IS
1000}
1001
fe9ccc78
IS
1002static u16
1003mlxsw_sp_port_pvid_determine(const struct mlxsw_sp_port *mlxsw_sp_port,
1004 u16 vid, bool is_pvid)
584d73df 1005{
fe9ccc78
IS
1006 if (is_pvid)
1007 return vid;
1008 else if (mlxsw_sp_port->pvid == vid)
1009 return 0; /* Dis-allow untagged packets */
1010 else
1011 return mlxsw_sp_port->pvid;
584d73df
IS
1012}
1013
c57529e1
IS
1014static int
1015mlxsw_sp_port_vlan_bridge_join(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan,
1016 struct mlxsw_sp_bridge_port *bridge_port)
56ade8fe 1017{
c57529e1
IS
1018 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
1019 struct mlxsw_sp_bridge_vlan *bridge_vlan;
1020 u16 vid = mlxsw_sp_port_vlan->vid;
56ade8fe
JP
1021 int err;
1022
c57529e1 1023 /* No need to continue if only VLAN flags were changed */
9e25826f
PM
1024 if (mlxsw_sp_port_vlan->bridge_port) {
1025 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
c57529e1 1026 return 0;
9e25826f 1027 }
56ade8fe 1028
c57529e1 1029 err = mlxsw_sp_port_vlan_fid_join(mlxsw_sp_port_vlan, bridge_port);
fe9ccc78 1030 if (err)
c57529e1 1031 return err;
56ade8fe 1032
fe9ccc78 1033 err = mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid,
c57529e1 1034 bridge_port->flags & BR_LEARNING);
fe9ccc78 1035 if (err)
584d73df 1036 goto err_port_vid_learning_set;
584d73df 1037
fe9ccc78 1038 err = mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid,
c57529e1 1039 bridge_port->stp_state);
fe9ccc78
IS
1040 if (err)
1041 goto err_port_vid_stp_set;
56ade8fe 1042
c57529e1
IS
1043 bridge_vlan = mlxsw_sp_bridge_vlan_get(bridge_port, vid);
1044 if (!bridge_vlan) {
1045 err = -ENOMEM;
1046 goto err_bridge_vlan_get;
1047 }
1048
1049 list_add(&mlxsw_sp_port_vlan->bridge_vlan_node,
1050 &bridge_vlan->port_vlan_list);
1051
1052 mlxsw_sp_bridge_port_get(mlxsw_sp_port->mlxsw_sp->bridge,
1053 bridge_port->dev);
1054 mlxsw_sp_port_vlan->bridge_port = bridge_port;
b07a966c
IS
1055
1056 return 0;
1057
c57529e1
IS
1058err_bridge_vlan_get:
1059 mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid, BR_STATE_DISABLED);
fe9ccc78
IS
1060err_port_vid_stp_set:
1061 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, false);
584d73df 1062err_port_vid_learning_set:
c57529e1
IS
1063 mlxsw_sp_port_vlan_fid_leave(mlxsw_sp_port_vlan);
1064 return err;
1065}
1066
1067void
1068mlxsw_sp_port_vlan_bridge_leave(struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan)
1069{
1070 struct mlxsw_sp_port *mlxsw_sp_port = mlxsw_sp_port_vlan->mlxsw_sp_port;
1071 struct mlxsw_sp_fid *fid = mlxsw_sp_port_vlan->fid;
1072 struct mlxsw_sp_bridge_vlan *bridge_vlan;
1073 struct mlxsw_sp_bridge_port *bridge_port;
1074 u16 vid = mlxsw_sp_port_vlan->vid;
bb5355b2 1075 bool last_port, last_vlan;
c57529e1 1076
a1107487
IS
1077 if (WARN_ON(mlxsw_sp_fid_type(fid) != MLXSW_SP_FID_TYPE_8021Q &&
1078 mlxsw_sp_fid_type(fid) != MLXSW_SP_FID_TYPE_8021D))
1079 return;
1080
c57529e1 1081 bridge_port = mlxsw_sp_port_vlan->bridge_port;
bb5355b2 1082 last_vlan = list_is_singular(&bridge_port->vlans_list);
c57529e1 1083 bridge_vlan = mlxsw_sp_bridge_vlan_find(bridge_port, vid);
bb5355b2 1084 last_port = list_is_singular(&bridge_vlan->port_vlan_list);
c57529e1
IS
1085
1086 list_del(&mlxsw_sp_port_vlan->bridge_vlan_node);
1087 mlxsw_sp_bridge_vlan_put(bridge_vlan);
1088 mlxsw_sp_port_vid_stp_set(mlxsw_sp_port, vid, BR_STATE_DISABLED);
1089 mlxsw_sp_port_vid_learning_set(mlxsw_sp_port, vid, false);
bb5355b2 1090 if (last_port)
c57529e1 1091 mlxsw_sp_bridge_port_fdb_flush(mlxsw_sp_port->mlxsw_sp,
a1107487
IS
1092 bridge_port,
1093 mlxsw_sp_fid_index(fid));
bb5355b2
NF
1094 if (last_vlan)
1095 mlxsw_sp_bridge_port_mdb_flush(mlxsw_sp_port, bridge_port);
1096
c57529e1
IS
1097 mlxsw_sp_port_vlan_fid_leave(mlxsw_sp_port_vlan);
1098
1099 mlxsw_sp_bridge_port_put(mlxsw_sp_port->mlxsw_sp->bridge, bridge_port);
1100 mlxsw_sp_port_vlan->bridge_port = NULL;
1101}
1102
1103static int
1104mlxsw_sp_bridge_port_vlan_add(struct mlxsw_sp_port *mlxsw_sp_port,
1105 struct mlxsw_sp_bridge_port *bridge_port,
1106 u16 vid, bool is_untagged, bool is_pvid)
1107{
1108 u16 pvid = mlxsw_sp_port_pvid_determine(mlxsw_sp_port, vid, is_pvid);
1109 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
c57529e1
IS
1110 u16 old_pvid = mlxsw_sp_port->pvid;
1111 int err;
1112
1113 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_get(mlxsw_sp_port, vid);
1114 if (IS_ERR(mlxsw_sp_port_vlan))
1115 return PTR_ERR(mlxsw_sp_port_vlan);
1116
1117 err = mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, true,
1118 is_untagged);
1119 if (err)
1120 goto err_port_vlan_set;
1121
1122 err = mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid);
1123 if (err)
1124 goto err_port_pvid_set;
1125
1126 err = mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port);
1127 if (err)
1128 goto err_port_vlan_bridge_join;
1129
c57529e1
IS
1130 return 0;
1131
1132err_port_vlan_bridge_join:
fe9ccc78 1133 mlxsw_sp_port_pvid_set(mlxsw_sp_port, old_pvid);
b07a966c 1134err_port_pvid_set:
fe9ccc78
IS
1135 mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
1136err_port_vlan_set:
c57529e1 1137 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
b07a966c 1138 return err;
56ade8fe
JP
1139}
1140
567ad1a2
PM
1141static int
1142mlxsw_sp_br_ban_rif_pvid_change(struct mlxsw_sp *mlxsw_sp,
1143 const struct net_device *br_dev,
1144 const struct switchdev_obj_port_vlan *vlan)
1145{
1146 struct mlxsw_sp_rif *rif;
1147 struct mlxsw_sp_fid *fid;
1148 u16 pvid;
1149 u16 vid;
1150
1151 rif = mlxsw_sp_rif_find_by_dev(mlxsw_sp, br_dev);
1152 if (!rif)
1153 return 0;
1154 fid = mlxsw_sp_rif_fid(rif);
1155 pvid = mlxsw_sp_fid_8021q_vid(fid);
1156
1157 for (vid = vlan->vid_begin; vid <= vlan->vid_end; ++vid) {
1158 if (vlan->flags & BRIDGE_VLAN_INFO_PVID) {
1159 if (vid != pvid) {
1160 netdev_err(br_dev, "Can't change PVID, it's used by router interface\n");
1161 return -EBUSY;
1162 }
1163 } else {
1164 if (vid == pvid) {
1165 netdev_err(br_dev, "Can't remove PVID, it's used by router interface\n");
1166 return -EBUSY;
1167 }
1168 }
1169 }
1170
1171 return 0;
1172}
1173
56ade8fe
JP
1174static int mlxsw_sp_port_vlans_add(struct mlxsw_sp_port *mlxsw_sp_port,
1175 const struct switchdev_obj_port_vlan *vlan,
1176 struct switchdev_trans *trans)
1177{
e4a13055
ER
1178 bool flag_untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
1179 bool flag_pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
c57529e1
IS
1180 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1181 struct net_device *orig_dev = vlan->obj.orig_dev;
1182 struct mlxsw_sp_bridge_port *bridge_port;
fe9ccc78 1183 u16 vid;
56ade8fe 1184
567ad1a2
PM
1185 if (netif_is_bridge_master(orig_dev)) {
1186 int err = 0;
1187
1188 if ((vlan->flags & BRIDGE_VLAN_INFO_BRENTRY) &&
1189 br_vlan_enabled(orig_dev) &&
1190 switchdev_trans_ph_prepare(trans))
1191 err = mlxsw_sp_br_ban_rif_pvid_change(mlxsw_sp,
1192 orig_dev, vlan);
1193 if (!err)
1194 err = -EOPNOTSUPP;
1195 return err;
1196 }
ea472175 1197
56ade8fe
JP
1198 if (switchdev_trans_ph_prepare(trans))
1199 return 0;
1200
c57529e1
IS
1201 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
1202 if (WARN_ON(!bridge_port))
1203 return -EINVAL;
1204
1205 if (!bridge_port->bridge_device->vlan_enabled)
1206 return 0;
1207
fe9ccc78
IS
1208 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++) {
1209 int err;
1210
c57529e1
IS
1211 err = mlxsw_sp_bridge_port_vlan_add(mlxsw_sp_port, bridge_port,
1212 vid, flag_untagged,
1213 flag_pvid);
fe9ccc78
IS
1214 if (err)
1215 return err;
1216 }
1217
1218 return 0;
56ade8fe
JP
1219}
1220
c57529e1
IS
1221static enum mlxsw_reg_sfdf_flush_type mlxsw_sp_fdb_flush_type(bool lagged)
1222{
1223 return lagged ? MLXSW_REG_SFDF_FLUSH_PER_LAG_AND_FID :
1224 MLXSW_REG_SFDF_FLUSH_PER_PORT_AND_FID;
1225}
1226
1227static int
1228mlxsw_sp_bridge_port_fdb_flush(struct mlxsw_sp *mlxsw_sp,
1229 struct mlxsw_sp_bridge_port *bridge_port,
1230 u16 fid_index)
1231{
1232 bool lagged = bridge_port->lagged;
1233 char sfdf_pl[MLXSW_REG_SFDF_LEN];
1234 u16 system_port;
1235
1236 system_port = lagged ? bridge_port->lag_id : bridge_port->system_port;
1237 mlxsw_reg_sfdf_pack(sfdf_pl, mlxsw_sp_fdb_flush_type(lagged));
1238 mlxsw_reg_sfdf_fid_set(sfdf_pl, fid_index);
1239 mlxsw_reg_sfdf_port_fid_system_port_set(sfdf_pl, system_port);
1240
1241 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfdf), sfdf_pl);
1242}
1243
8a1ab5d7 1244static enum mlxsw_reg_sfd_rec_policy mlxsw_sp_sfd_rec_policy(bool dynamic)
56ade8fe 1245{
8a1ab5d7
JP
1246 return dynamic ? MLXSW_REG_SFD_REC_POLICY_DYNAMIC_ENTRY_INGRESS :
1247 MLXSW_REG_SFD_REC_POLICY_STATIC_ENTRY;
1248}
1249
1250static enum mlxsw_reg_sfd_op mlxsw_sp_sfd_op(bool adding)
1251{
1252 return adding ? MLXSW_REG_SFD_OP_WRITE_EDIT :
1253 MLXSW_REG_SFD_OP_WRITE_REMOVE;
1254}
1255
1231e04f
IS
1256static int mlxsw_sp_port_fdb_tunnel_uc_op(struct mlxsw_sp *mlxsw_sp,
1257 const char *mac, u16 fid,
1258 enum mlxsw_sp_l3proto proto,
1259 const union mlxsw_sp_l3addr *addr,
1260 bool adding, bool dynamic)
1261{
1262 enum mlxsw_reg_sfd_uc_tunnel_protocol sfd_proto;
1263 char *sfd_pl;
1264 u8 num_rec;
1265 u32 uip;
1266 int err;
1267
1268 switch (proto) {
1269 case MLXSW_SP_L3_PROTO_IPV4:
1270 uip = be32_to_cpu(addr->addr4);
1271 sfd_proto = MLXSW_REG_SFD_UC_TUNNEL_PROTOCOL_IPV4;
1272 break;
1273 case MLXSW_SP_L3_PROTO_IPV6: /* fall through */
1274 default:
1275 WARN_ON(1);
1276 return -EOPNOTSUPP;
1277 }
1278
1279 sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
1280 if (!sfd_pl)
1281 return -ENOMEM;
1282
1283 mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
1284 mlxsw_reg_sfd_uc_tunnel_pack(sfd_pl, 0,
1285 mlxsw_sp_sfd_rec_policy(dynamic), mac, fid,
1286 MLXSW_REG_SFD_REC_ACTION_NOP, uip,
1287 sfd_proto);
1288 num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
1289 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
1290 if (err)
1291 goto out;
1292
1293 if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
1294 err = -EBUSY;
1295
1296out:
1297 kfree(sfd_pl);
1298 return err;
1299}
1300
6e095fd4
IS
1301static int __mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
1302 const char *mac, u16 fid, bool adding,
1303 enum mlxsw_reg_sfd_rec_action action,
1304 bool dynamic)
8a1ab5d7 1305{
56ade8fe 1306 char *sfd_pl;
0a8a1bf1 1307 u8 num_rec;
56ade8fe
JP
1308 int err;
1309
56ade8fe
JP
1310 sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
1311 if (!sfd_pl)
1312 return -ENOMEM;
1313
8a1ab5d7
JP
1314 mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
1315 mlxsw_reg_sfd_uc_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
6e095fd4 1316 mac, fid, action, local_port);
0a8a1bf1 1317 num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
8a1ab5d7 1318 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
0a8a1bf1
ST
1319 if (err)
1320 goto out;
8a1ab5d7 1321
0a8a1bf1
ST
1322 if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
1323 err = -EBUSY;
1324
1325out:
1326 kfree(sfd_pl);
8a1ab5d7
JP
1327 return err;
1328}
1329
6e095fd4
IS
1330static int mlxsw_sp_port_fdb_uc_op(struct mlxsw_sp *mlxsw_sp, u8 local_port,
1331 const char *mac, u16 fid, bool adding,
1332 bool dynamic)
1333{
1334 return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid, adding,
1335 MLXSW_REG_SFD_REC_ACTION_NOP, dynamic);
1336}
1337
1338int mlxsw_sp_rif_fdb_op(struct mlxsw_sp *mlxsw_sp, const char *mac, u16 fid,
1339 bool adding)
1340{
1341 return __mlxsw_sp_port_fdb_uc_op(mlxsw_sp, 0, mac, fid, adding,
1342 MLXSW_REG_SFD_REC_ACTION_FORWARD_IP_ROUTER,
1343 false);
1344}
1345
8a1ab5d7 1346static int mlxsw_sp_port_fdb_uc_lag_op(struct mlxsw_sp *mlxsw_sp, u16 lag_id,
64771e31
IS
1347 const char *mac, u16 fid, u16 lag_vid,
1348 bool adding, bool dynamic)
8a1ab5d7
JP
1349{
1350 char *sfd_pl;
0a8a1bf1 1351 u8 num_rec;
8a1ab5d7
JP
1352 int err;
1353
1354 sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
1355 if (!sfd_pl)
1356 return -ENOMEM;
1357
1358 mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
1359 mlxsw_reg_sfd_uc_lag_pack(sfd_pl, 0, mlxsw_sp_sfd_rec_policy(dynamic),
64771e31
IS
1360 mac, fid, MLXSW_REG_SFD_REC_ACTION_NOP,
1361 lag_vid, lag_id);
0a8a1bf1 1362 num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
8a1ab5d7 1363 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
0a8a1bf1
ST
1364 if (err)
1365 goto out;
56ade8fe 1366
0a8a1bf1
ST
1367 if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
1368 err = -EBUSY;
1369
1370out:
1371 kfree(sfd_pl);
56ade8fe
JP
1372 return err;
1373}
1374
af061378
AS
1375static int
1376mlxsw_sp_port_fdb_set(struct mlxsw_sp_port *mlxsw_sp_port,
1377 struct switchdev_notifier_fdb_info *fdb_info, bool adding)
1378{
1379 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1380 struct net_device *orig_dev = fdb_info->info.dev;
1381 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1382 struct mlxsw_sp_bridge_device *bridge_device;
1383 struct mlxsw_sp_bridge_port *bridge_port;
1384 u16 fid_index, vid;
1385
1386 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
1387 if (!bridge_port)
1388 return -EINVAL;
1389
1390 bridge_device = bridge_port->bridge_device;
1391 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_bridge(mlxsw_sp_port,
1392 bridge_device,
1393 fdb_info->vid);
1394 if (!mlxsw_sp_port_vlan)
1395 return 0;
1396
1397 fid_index = mlxsw_sp_fid_index(mlxsw_sp_port_vlan->fid);
1398 vid = mlxsw_sp_port_vlan->vid;
1399
1400 if (!bridge_port->lagged)
1401 return mlxsw_sp_port_fdb_uc_op(mlxsw_sp,
1402 bridge_port->system_port,
1403 fdb_info->addr, fid_index,
1404 adding, false);
1405 else
1406 return mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp,
1407 bridge_port->lag_id,
1408 fdb_info->addr, fid_index,
1409 vid, adding, false);
1410}
1411
3a49b4fd 1412static int mlxsw_sp_port_mdb_op(struct mlxsw_sp *mlxsw_sp, const char *addr,
5f9abc59 1413 u16 fid, u16 mid_idx, bool adding)
3a49b4fd
ER
1414{
1415 char *sfd_pl;
0a8a1bf1 1416 u8 num_rec;
3a49b4fd
ER
1417 int err;
1418
1419 sfd_pl = kmalloc(MLXSW_REG_SFD_LEN, GFP_KERNEL);
1420 if (!sfd_pl)
1421 return -ENOMEM;
1422
1423 mlxsw_reg_sfd_pack(sfd_pl, mlxsw_sp_sfd_op(adding), 0);
1424 mlxsw_reg_sfd_mc_pack(sfd_pl, 0, addr, fid,
5f9abc59 1425 MLXSW_REG_SFD_REC_ACTION_NOP, mid_idx);
0a8a1bf1 1426 num_rec = mlxsw_reg_sfd_num_rec_get(sfd_pl);
3a49b4fd 1427 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(sfd), sfd_pl);
0a8a1bf1
ST
1428 if (err)
1429 goto out;
1430
1431 if (num_rec != mlxsw_reg_sfd_num_rec_get(sfd_pl))
1432 err = -EBUSY;
1433
1434out:
3a49b4fd
ER
1435 kfree(sfd_pl);
1436 return err;
1437}
1438
2e3496cd 1439static int mlxsw_sp_port_smid_full_entry(struct mlxsw_sp *mlxsw_sp, u16 mid_idx,
c4db953f
YG
1440 long *ports_bitmap,
1441 bool set_router_port)
3a49b4fd 1442{
3a49b4fd
ER
1443 char *smid_pl;
1444 int err, i;
1445
1446 smid_pl = kmalloc(MLXSW_REG_SMID_LEN, GFP_KERNEL);
1447 if (!smid_pl)
1448 return -ENOMEM;
1449
5f9abc59
NF
1450 mlxsw_reg_smid_pack(smid_pl, mid_idx, 0, false);
1451 for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++) {
1452 if (mlxsw_sp->ports[i])
1453 mlxsw_reg_smid_port_mask_set(smid_pl, i, 1);
3a49b4fd 1454 }
5f9abc59 1455
c4db953f
YG
1456 mlxsw_reg_smid_port_mask_set(smid_pl,
1457 mlxsw_sp_router_port(mlxsw_sp), 1);
1458
2e3496cd
NF
1459 for_each_set_bit(i, ports_bitmap, mlxsw_core_max_ports(mlxsw_sp->core))
1460 mlxsw_reg_smid_port_set(smid_pl, i, 1);
1461
c4db953f
YG
1462 mlxsw_reg_smid_port_set(smid_pl, mlxsw_sp_router_port(mlxsw_sp),
1463 set_router_port);
1464
5f9abc59
NF
1465 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smid), smid_pl);
1466 kfree(smid_pl);
1467 return err;
1468}
1469
1470static int mlxsw_sp_port_smid_set(struct mlxsw_sp_port *mlxsw_sp_port,
1471 u16 mid_idx, bool add)
1472{
1473 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1474 char *smid_pl;
1475 int err;
1476
1477 smid_pl = kmalloc(MLXSW_REG_SMID_LEN, GFP_KERNEL);
1478 if (!smid_pl)
1479 return -ENOMEM;
1480
1481 mlxsw_reg_smid_pack(smid_pl, mid_idx, mlxsw_sp_port->local_port, add);
3a49b4fd
ER
1482 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(smid), smid_pl);
1483 kfree(smid_pl);
1484 return err;
1485}
1486
b80888a9
NF
1487static struct
1488mlxsw_sp_mid *__mlxsw_sp_mc_get(struct mlxsw_sp_bridge_device *bridge_device,
1489 const unsigned char *addr,
1490 u16 fid)
3a49b4fd
ER
1491{
1492 struct mlxsw_sp_mid *mid;
1493
b80888a9 1494 list_for_each_entry(mid, &bridge_device->mids_list, list) {
46d0847c 1495 if (ether_addr_equal(mid->addr, addr) && mid->fid == fid)
3a49b4fd
ER
1496 return mid;
1497 }
1498 return NULL;
1499}
1500
3fba877c
NF
1501static void
1502mlxsw_sp_bridge_port_get_ports_bitmap(struct mlxsw_sp *mlxsw_sp,
1503 struct mlxsw_sp_bridge_port *bridge_port,
1504 unsigned long *ports_bitmap)
1505{
1506 struct mlxsw_sp_port *mlxsw_sp_port;
1507 u64 max_lag_members, i;
1508 int lag_id;
1509
1510 if (!bridge_port->lagged) {
1511 set_bit(bridge_port->system_port, ports_bitmap);
1512 } else {
1513 max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
1514 MAX_LAG_MEMBERS);
1515 lag_id = bridge_port->lag_id;
1516 for (i = 0; i < max_lag_members; i++) {
1517 mlxsw_sp_port = mlxsw_sp_port_lagged_get(mlxsw_sp,
1518 lag_id, i);
1519 if (mlxsw_sp_port)
1520 set_bit(mlxsw_sp_port->local_port,
1521 ports_bitmap);
1522 }
1523 }
1524}
1525
1526static void
1527mlxsw_sp_mc_get_mrouters_bitmap(unsigned long *flood_bitmap,
1528 struct mlxsw_sp_bridge_device *bridge_device,
1529 struct mlxsw_sp *mlxsw_sp)
1530{
1531 struct mlxsw_sp_bridge_port *bridge_port;
1532
1533 list_for_each_entry(bridge_port, &bridge_device->ports_list, list) {
1534 if (bridge_port->mrouter) {
1535 mlxsw_sp_bridge_port_get_ports_bitmap(mlxsw_sp,
1536 bridge_port,
1537 flood_bitmap);
1538 }
1539 }
1540}
1541
73b433e8
NF
1542static bool
1543mlxsw_sp_mc_write_mdb_entry(struct mlxsw_sp *mlxsw_sp,
3fba877c
NF
1544 struct mlxsw_sp_mid *mid,
1545 struct mlxsw_sp_bridge_device *bridge_device)
73b433e8 1546{
3fba877c
NF
1547 long *flood_bitmap;
1548 int num_of_ports;
1549 int alloc_size;
73b433e8
NF
1550 u16 mid_idx;
1551 int err;
1552
1553 mid_idx = find_first_zero_bit(mlxsw_sp->bridge->mids_bitmap,
1554 MLXSW_SP_MID_MAX);
1555 if (mid_idx == MLXSW_SP_MID_MAX)
1556 return false;
1557
3fba877c
NF
1558 num_of_ports = mlxsw_core_max_ports(mlxsw_sp->core);
1559 alloc_size = sizeof(long) * BITS_TO_LONGS(num_of_ports);
1560 flood_bitmap = kzalloc(alloc_size, GFP_KERNEL);
1561 if (!flood_bitmap)
1562 return false;
1563
1564 bitmap_copy(flood_bitmap, mid->ports_in_mid, num_of_ports);
1565 mlxsw_sp_mc_get_mrouters_bitmap(flood_bitmap, bridge_device, mlxsw_sp);
1566
73b433e8 1567 mid->mid = mid_idx;
c4db953f 1568 err = mlxsw_sp_port_smid_full_entry(mlxsw_sp, mid_idx, flood_bitmap,
593bc28a 1569 bridge_device->mrouter);
3fba877c 1570 kfree(flood_bitmap);
73b433e8
NF
1571 if (err)
1572 return false;
1573
1574 err = mlxsw_sp_port_mdb_op(mlxsw_sp, mid->addr, mid->fid, mid_idx,
1575 true);
1576 if (err)
1577 return false;
1578
1579 set_bit(mid_idx, mlxsw_sp->bridge->mids_bitmap);
1580 mid->in_hw = true;
1581 return true;
1582}
1583
1584static int mlxsw_sp_mc_remove_mdb_entry(struct mlxsw_sp *mlxsw_sp,
1585 struct mlxsw_sp_mid *mid)
1586{
846fd8a0
NF
1587 if (!mid->in_hw)
1588 return 0;
1589
73b433e8
NF
1590 clear_bit(mid->mid, mlxsw_sp->bridge->mids_bitmap);
1591 mid->in_hw = false;
1592 return mlxsw_sp_port_mdb_op(mlxsw_sp, mid->addr, mid->fid, mid->mid,
1593 false);
1594}
1595
b80888a9
NF
1596static struct
1597mlxsw_sp_mid *__mlxsw_sp_mc_alloc(struct mlxsw_sp *mlxsw_sp,
1598 struct mlxsw_sp_bridge_device *bridge_device,
1599 const unsigned char *addr,
1600 u16 fid)
3a49b4fd
ER
1601{
1602 struct mlxsw_sp_mid *mid;
4cdc35e4 1603 size_t alloc_size;
3a49b4fd
ER
1604
1605 mid = kzalloc(sizeof(*mid), GFP_KERNEL);
1606 if (!mid)
1607 return NULL;
1608
4cdc35e4
NF
1609 alloc_size = sizeof(unsigned long) *
1610 BITS_TO_LONGS(mlxsw_core_max_ports(mlxsw_sp->core));
73b433e8 1611
4cdc35e4 1612 mid->ports_in_mid = kzalloc(alloc_size, GFP_KERNEL);
73b433e8
NF
1613 if (!mid->ports_in_mid)
1614 goto err_ports_in_mid_alloc;
4cdc35e4 1615
3a49b4fd 1616 ether_addr_copy(mid->addr, addr);
46d0847c 1617 mid->fid = fid;
73b433e8 1618 mid->in_hw = false;
846fd8a0
NF
1619
1620 if (!bridge_device->multicast_enabled)
1621 goto out;
1622
3fba877c 1623 if (!mlxsw_sp_mc_write_mdb_entry(mlxsw_sp, mid, bridge_device))
73b433e8
NF
1624 goto err_write_mdb_entry;
1625
846fd8a0 1626out:
b80888a9 1627 list_add_tail(&mid->list, &bridge_device->mids_list);
3a49b4fd 1628 return mid;
73b433e8
NF
1629
1630err_write_mdb_entry:
1631 kfree(mid->ports_in_mid);
1632err_ports_in_mid_alloc:
1633 kfree(mid);
1634 return NULL;
3a49b4fd
ER
1635}
1636
0161b950
NF
1637static int mlxsw_sp_port_remove_from_mid(struct mlxsw_sp_port *mlxsw_sp_port,
1638 struct mlxsw_sp_mid *mid)
3a49b4fd 1639{
4cdc35e4 1640 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
73b433e8 1641 int err = 0;
4cdc35e4
NF
1642
1643 clear_bit(mlxsw_sp_port->local_port, mid->ports_in_mid);
0161b950
NF
1644 if (bitmap_empty(mid->ports_in_mid,
1645 mlxsw_core_max_ports(mlxsw_sp->core))) {
73b433e8 1646 err = mlxsw_sp_mc_remove_mdb_entry(mlxsw_sp, mid);
3a49b4fd 1647 list_del(&mid->list);
4cdc35e4 1648 kfree(mid->ports_in_mid);
3a49b4fd 1649 kfree(mid);
3a49b4fd 1650 }
73b433e8 1651 return err;
3a49b4fd
ER
1652}
1653
1654static int mlxsw_sp_port_mdb_add(struct mlxsw_sp_port *mlxsw_sp_port,
1655 const struct switchdev_obj_port_mdb *mdb,
1656 struct switchdev_trans *trans)
1657{
1658 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
c57529e1
IS
1659 struct net_device *orig_dev = mdb->obj.orig_dev;
1660 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
3a49b4fd 1661 struct net_device *dev = mlxsw_sp_port->dev;
c57529e1
IS
1662 struct mlxsw_sp_bridge_device *bridge_device;
1663 struct mlxsw_sp_bridge_port *bridge_port;
3a49b4fd 1664 struct mlxsw_sp_mid *mid;
c57529e1 1665 u16 fid_index;
3a49b4fd
ER
1666 int err = 0;
1667
1668 if (switchdev_trans_ph_prepare(trans))
1669 return 0;
1670
c57529e1 1671 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
17b334a8
IS
1672 if (!bridge_port)
1673 return 0;
c57529e1
IS
1674
1675 bridge_device = bridge_port->bridge_device;
1676 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_bridge(mlxsw_sp_port,
1677 bridge_device,
1678 mdb->vid);
17b334a8
IS
1679 if (!mlxsw_sp_port_vlan)
1680 return 0;
c57529e1 1681
a1107487 1682 fid_index = mlxsw_sp_fid_index(mlxsw_sp_port_vlan->fid);
c57529e1 1683
b80888a9 1684 mid = __mlxsw_sp_mc_get(bridge_device, mdb->addr, fid_index);
3a49b4fd 1685 if (!mid) {
b80888a9
NF
1686 mid = __mlxsw_sp_mc_alloc(mlxsw_sp, bridge_device, mdb->addr,
1687 fid_index);
3a49b4fd
ER
1688 if (!mid) {
1689 netdev_err(dev, "Unable to allocate MC group\n");
1690 return -ENOMEM;
1691 }
1692 }
4cdc35e4 1693 set_bit(mlxsw_sp_port->local_port, mid->ports_in_mid);
3a49b4fd 1694
846fd8a0
NF
1695 if (!bridge_device->multicast_enabled)
1696 return 0;
1697
ded711c8
NF
1698 if (bridge_port->mrouter)
1699 return 0;
1700
5f9abc59 1701 err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, true);
3a49b4fd
ER
1702 if (err) {
1703 netdev_err(dev, "Unable to set SMID\n");
1704 goto err_out;
1705 }
1706
3a49b4fd
ER
1707 return 0;
1708
1709err_out:
0161b950 1710 mlxsw_sp_port_remove_from_mid(mlxsw_sp_port, mid);
3a49b4fd
ER
1711 return err;
1712}
1713
2e3496cd
NF
1714static void
1715mlxsw_sp_bridge_mdb_mc_enable_sync(struct mlxsw_sp_port *mlxsw_sp_port,
1716 struct mlxsw_sp_bridge_device
1717 *bridge_device)
1718{
1719 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1720 struct mlxsw_sp_mid *mid;
1721 bool mc_enabled;
1722
1723 mc_enabled = bridge_device->multicast_enabled;
1724
1725 list_for_each_entry(mid, &bridge_device->mids_list, list) {
1726 if (mc_enabled)
3fba877c
NF
1727 mlxsw_sp_mc_write_mdb_entry(mlxsw_sp, mid,
1728 bridge_device);
2e3496cd
NF
1729 else
1730 mlxsw_sp_mc_remove_mdb_entry(mlxsw_sp, mid);
1731 }
1732}
1733
3ddda117
NF
1734static void
1735mlxsw_sp_port_mrouter_update_mdb(struct mlxsw_sp_port *mlxsw_sp_port,
1736 struct mlxsw_sp_bridge_port *bridge_port,
1737 bool add)
1738{
1739 struct mlxsw_sp_bridge_device *bridge_device;
1740 struct mlxsw_sp_mid *mid;
1741
1742 bridge_device = bridge_port->bridge_device;
1743
1744 list_for_each_entry(mid, &bridge_device->mids_list, list) {
1745 if (!test_bit(mlxsw_sp_port->local_port, mid->ports_in_mid))
1746 mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, add);
1747 }
1748}
1749
c520bc69
PM
1750struct mlxsw_sp_span_respin_work {
1751 struct work_struct work;
1752 struct mlxsw_sp *mlxsw_sp;
1753};
1754
1755static void mlxsw_sp_span_respin_work(struct work_struct *work)
1756{
1757 struct mlxsw_sp_span_respin_work *respin_work =
1758 container_of(work, struct mlxsw_sp_span_respin_work, work);
1759
1760 rtnl_lock();
1761 mlxsw_sp_span_respin(respin_work->mlxsw_sp);
1762 rtnl_unlock();
1763 kfree(respin_work);
1764}
1765
1766static void mlxsw_sp_span_respin_schedule(struct mlxsw_sp *mlxsw_sp)
1767{
1768 struct mlxsw_sp_span_respin_work *respin_work;
1769
1770 respin_work = kzalloc(sizeof(*respin_work), GFP_ATOMIC);
1771 if (!respin_work)
1772 return;
1773
1774 INIT_WORK(&respin_work->work, mlxsw_sp_span_respin_work);
1775 respin_work->mlxsw_sp = mlxsw_sp;
1776
1777 mlxsw_core_schedule_work(&respin_work->work);
1778}
1779
56ade8fe
JP
1780static int mlxsw_sp_port_obj_add(struct net_device *dev,
1781 const struct switchdev_obj *obj,
1782 struct switchdev_trans *trans)
1783{
1784 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
c520bc69 1785 const struct switchdev_obj_port_vlan *vlan;
56ade8fe
JP
1786 int err = 0;
1787
1788 switch (obj->id) {
1789 case SWITCHDEV_OBJ_ID_PORT_VLAN:
c520bc69
PM
1790 vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
1791 err = mlxsw_sp_port_vlans_add(mlxsw_sp_port, vlan, trans);
1792
7edcb8ec 1793 if (switchdev_trans_ph_prepare(trans)) {
c520bc69
PM
1794 /* The event is emitted before the changes are actually
1795 * applied to the bridge. Therefore schedule the respin
1796 * call for later, so that the respin logic sees the
1797 * updated bridge state.
1798 */
1799 mlxsw_sp_span_respin_schedule(mlxsw_sp_port->mlxsw_sp);
1800 }
56ade8fe 1801 break;
3a49b4fd
ER
1802 case SWITCHDEV_OBJ_ID_PORT_MDB:
1803 err = mlxsw_sp_port_mdb_add(mlxsw_sp_port,
1804 SWITCHDEV_OBJ_PORT_MDB(obj),
1805 trans);
1806 break;
56ade8fe
JP
1807 default:
1808 err = -EOPNOTSUPP;
1809 break;
1810 }
1811
1812 return err;
1813}
1814
c57529e1
IS
1815static void
1816mlxsw_sp_bridge_port_vlan_del(struct mlxsw_sp_port *mlxsw_sp_port,
1817 struct mlxsw_sp_bridge_port *bridge_port, u16 vid)
56ade8fe 1818{
fe9ccc78 1819 u16 pvid = mlxsw_sp_port->pvid == vid ? 0 : vid;
c57529e1 1820 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
fe9ccc78 1821
c57529e1
IS
1822 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
1823 if (WARN_ON(!mlxsw_sp_port_vlan))
1824 return;
1825
1826 mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
fe9ccc78
IS
1827 mlxsw_sp_port_pvid_set(mlxsw_sp_port, pvid);
1828 mlxsw_sp_port_vlan_set(mlxsw_sp_port, vid, vid, false, false);
c57529e1 1829 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
56ade8fe
JP
1830}
1831
1832static int mlxsw_sp_port_vlans_del(struct mlxsw_sp_port *mlxsw_sp_port,
1833 const struct switchdev_obj_port_vlan *vlan)
1834{
c57529e1
IS
1835 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
1836 struct net_device *orig_dev = vlan->obj.orig_dev;
1837 struct mlxsw_sp_bridge_port *bridge_port;
fe9ccc78
IS
1838 u16 vid;
1839
ea472175
PM
1840 if (netif_is_bridge_master(orig_dev))
1841 return -EOPNOTSUPP;
1842
c57529e1
IS
1843 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
1844 if (WARN_ON(!bridge_port))
1845 return -EINVAL;
fe9ccc78 1846
c57529e1
IS
1847 if (!bridge_port->bridge_device->vlan_enabled)
1848 return 0;
56ade8fe 1849
c57529e1
IS
1850 for (vid = vlan->vid_begin; vid <= vlan->vid_end; vid++)
1851 mlxsw_sp_bridge_port_vlan_del(mlxsw_sp_port, bridge_port, vid);
4dc236c3 1852
c57529e1 1853 return 0;
4dc236c3
IS
1854}
1855
061e55bf
NF
1856static int
1857__mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port,
1858 struct mlxsw_sp_bridge_port *bridge_port,
1859 struct mlxsw_sp_mid *mid)
1860{
1861 struct net_device *dev = mlxsw_sp_port->dev;
1862 int err;
1863
c7f46cca
IS
1864 if (bridge_port->bridge_device->multicast_enabled &&
1865 !bridge_port->mrouter) {
1866 err = mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, false);
1867 if (err)
1868 netdev_err(dev, "Unable to remove port from SMID\n");
846fd8a0 1869 }
061e55bf
NF
1870
1871 err = mlxsw_sp_port_remove_from_mid(mlxsw_sp_port, mid);
1872 if (err)
1873 netdev_err(dev, "Unable to remove MC SFD\n");
1874
1875 return err;
1876}
1877
3a49b4fd
ER
1878static int mlxsw_sp_port_mdb_del(struct mlxsw_sp_port *mlxsw_sp_port,
1879 const struct switchdev_obj_port_mdb *mdb)
1880{
1881 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
c57529e1
IS
1882 struct net_device *orig_dev = mdb->obj.orig_dev;
1883 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1884 struct mlxsw_sp_bridge_device *bridge_device;
3a49b4fd 1885 struct net_device *dev = mlxsw_sp_port->dev;
c57529e1 1886 struct mlxsw_sp_bridge_port *bridge_port;
3a49b4fd 1887 struct mlxsw_sp_mid *mid;
c57529e1 1888 u16 fid_index;
3a49b4fd 1889
c57529e1 1890 bridge_port = mlxsw_sp_bridge_port_find(mlxsw_sp->bridge, orig_dev);
17b334a8
IS
1891 if (!bridge_port)
1892 return 0;
c57529e1
IS
1893
1894 bridge_device = bridge_port->bridge_device;
1895 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_bridge(mlxsw_sp_port,
1896 bridge_device,
1897 mdb->vid);
17b334a8
IS
1898 if (!mlxsw_sp_port_vlan)
1899 return 0;
c57529e1 1900
a1107487 1901 fid_index = mlxsw_sp_fid_index(mlxsw_sp_port_vlan->fid);
c57529e1 1902
b80888a9 1903 mid = __mlxsw_sp_mc_get(bridge_device, mdb->addr, fid_index);
3a49b4fd
ER
1904 if (!mid) {
1905 netdev_err(dev, "Unable to remove port from MC DB\n");
1906 return -EINVAL;
1907 }
1908
061e55bf 1909 return __mlxsw_sp_port_mdb_del(mlxsw_sp_port, bridge_port, mid);
3a49b4fd
ER
1910}
1911
bb5355b2
NF
1912static void
1913mlxsw_sp_bridge_port_mdb_flush(struct mlxsw_sp_port *mlxsw_sp_port,
1914 struct mlxsw_sp_bridge_port *bridge_port)
1915{
1916 struct mlxsw_sp_bridge_device *bridge_device;
1917 struct mlxsw_sp_mid *mid, *tmp;
1918
1919 bridge_device = bridge_port->bridge_device;
1920
1921 list_for_each_entry_safe(mid, tmp, &bridge_device->mids_list, list) {
1922 if (test_bit(mlxsw_sp_port->local_port, mid->ports_in_mid)) {
1923 __mlxsw_sp_port_mdb_del(mlxsw_sp_port, bridge_port,
1924 mid);
01662777
NF
1925 } else if (bridge_device->multicast_enabled &&
1926 bridge_port->mrouter) {
1927 mlxsw_sp_port_smid_set(mlxsw_sp_port, mid->mid, false);
bb5355b2
NF
1928 }
1929 }
1930}
1931
56ade8fe
JP
1932static int mlxsw_sp_port_obj_del(struct net_device *dev,
1933 const struct switchdev_obj *obj)
1934{
1935 struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
1936 int err = 0;
1937
1938 switch (obj->id) {
1939 case SWITCHDEV_OBJ_ID_PORT_VLAN:
1940 err = mlxsw_sp_port_vlans_del(mlxsw_sp_port,
1941 SWITCHDEV_OBJ_PORT_VLAN(obj));
1942 break;
3a49b4fd
ER
1943 case SWITCHDEV_OBJ_ID_PORT_MDB:
1944 err = mlxsw_sp_port_mdb_del(mlxsw_sp_port,
1945 SWITCHDEV_OBJ_PORT_MDB(obj));
00ae40e7 1946 break;
56ade8fe
JP
1947 default:
1948 err = -EOPNOTSUPP;
1949 break;
1950 }
1951
f07ff014 1952 mlxsw_sp_span_respin_schedule(mlxsw_sp_port->mlxsw_sp);
c520bc69 1953
56ade8fe
JP
1954 return err;
1955}
1956
8a1ab5d7
JP
1957static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
1958 u16 lag_id)
1959{
1960 struct mlxsw_sp_port *mlxsw_sp_port;
c1a38311 1961 u64 max_lag_members;
8a1ab5d7
JP
1962 int i;
1963
c1a38311
JP
1964 max_lag_members = MLXSW_CORE_RES_GET(mlxsw_sp->core,
1965 MAX_LAG_MEMBERS);
1966 for (i = 0; i < max_lag_members; i++) {
8a1ab5d7
JP
1967 mlxsw_sp_port = mlxsw_sp_port_lagged_get(mlxsw_sp, lag_id, i);
1968 if (mlxsw_sp_port)
1969 return mlxsw_sp_port;
1970 }
1971 return NULL;
1972}
1973
c7070fc4 1974static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
56ade8fe
JP
1975 .switchdev_port_attr_get = mlxsw_sp_port_attr_get,
1976 .switchdev_port_attr_set = mlxsw_sp_port_attr_set,
1977 .switchdev_port_obj_add = mlxsw_sp_port_obj_add,
1978 .switchdev_port_obj_del = mlxsw_sp_port_obj_del,
56ade8fe
JP
1979};
1980
c57529e1
IS
1981static int
1982mlxsw_sp_bridge_8021q_port_join(struct mlxsw_sp_bridge_device *bridge_device,
1983 struct mlxsw_sp_bridge_port *bridge_port,
9b63ef88
IS
1984 struct mlxsw_sp_port *mlxsw_sp_port,
1985 struct netlink_ext_ack *extack)
c57529e1
IS
1986{
1987 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
1988
9b63ef88 1989 if (is_vlan_dev(bridge_port->dev)) {
6c677750 1990 NL_SET_ERR_MSG_MOD(extack, "Can not enslave a VLAN device to a VLAN-aware bridge");
c57529e1 1991 return -EINVAL;
9b63ef88 1992 }
c57529e1
IS
1993
1994 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, 1);
1995 if (WARN_ON(!mlxsw_sp_port_vlan))
1996 return -EINVAL;
1997
1998 /* Let VLAN-aware bridge take care of its own VLANs */
1999 mlxsw_sp_port_vlan_put(mlxsw_sp_port_vlan);
2000
2001 return 0;
2002}
2003
2004static void
2005mlxsw_sp_bridge_8021q_port_leave(struct mlxsw_sp_bridge_device *bridge_device,
2006 struct mlxsw_sp_bridge_port *bridge_port,
2007 struct mlxsw_sp_port *mlxsw_sp_port)
2008{
2009 mlxsw_sp_port_vlan_get(mlxsw_sp_port, 1);
2010 /* Make sure untagged frames are allowed to ingress */
2011 mlxsw_sp_port_pvid_set(mlxsw_sp_port, 1);
2012}
2013
1c30d183
IS
2014static int
2015mlxsw_sp_bridge_8021q_vxlan_join(struct mlxsw_sp_bridge_device *bridge_device,
2016 const struct net_device *vxlan_dev,
2017 struct netlink_ext_ack *extack)
2018{
2019 WARN_ON(1);
2020 return -EINVAL;
2021}
2022
2023static void
2024mlxsw_sp_bridge_8021q_vxlan_leave(struct mlxsw_sp_bridge_device *bridge_device,
2025 const struct net_device *vxlan_dev)
2026{
2027}
2028
a1107487
IS
2029static struct mlxsw_sp_fid *
2030mlxsw_sp_bridge_8021q_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
2031 u16 vid)
2032{
2033 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
2034
2035 return mlxsw_sp_fid_8021q_get(mlxsw_sp, vid);
2036}
2037
1231e04f
IS
2038static struct mlxsw_sp_fid *
2039mlxsw_sp_bridge_8021q_fid_lookup(struct mlxsw_sp_bridge_device *bridge_device,
2040 u16 vid)
2041{
2042 WARN_ON(1);
2043 return NULL;
2044}
2045
2046static u16
2047mlxsw_sp_bridge_8021q_fid_vid(struct mlxsw_sp_bridge_device *bridge_device,
2048 const struct mlxsw_sp_fid *fid)
2049{
2050 return mlxsw_sp_fid_8021q_vid(fid);
2051}
2052
c57529e1
IS
2053static const struct mlxsw_sp_bridge_ops mlxsw_sp_bridge_8021q_ops = {
2054 .port_join = mlxsw_sp_bridge_8021q_port_join,
2055 .port_leave = mlxsw_sp_bridge_8021q_port_leave,
1c30d183
IS
2056 .vxlan_join = mlxsw_sp_bridge_8021q_vxlan_join,
2057 .vxlan_leave = mlxsw_sp_bridge_8021q_vxlan_leave,
a1107487 2058 .fid_get = mlxsw_sp_bridge_8021q_fid_get,
1231e04f
IS
2059 .fid_lookup = mlxsw_sp_bridge_8021q_fid_lookup,
2060 .fid_vid = mlxsw_sp_bridge_8021q_fid_vid,
c57529e1
IS
2061};
2062
2063static bool
2064mlxsw_sp_port_is_br_member(const struct mlxsw_sp_port *mlxsw_sp_port,
2065 const struct net_device *br_dev)
2066{
2067 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
2068
2069 list_for_each_entry(mlxsw_sp_port_vlan, &mlxsw_sp_port->vlans_list,
2070 list) {
2071 if (mlxsw_sp_port_vlan->bridge_port &&
2072 mlxsw_sp_port_vlan->bridge_port->bridge_device->dev ==
2073 br_dev)
2074 return true;
2075 }
2076
2077 return false;
2078}
2079
2080static int
2081mlxsw_sp_bridge_8021d_port_join(struct mlxsw_sp_bridge_device *bridge_device,
2082 struct mlxsw_sp_bridge_port *bridge_port,
9b63ef88
IS
2083 struct mlxsw_sp_port *mlxsw_sp_port,
2084 struct netlink_ext_ack *extack)
c57529e1
IS
2085{
2086 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
65b53bfd 2087 struct net_device *dev = bridge_port->dev;
c57529e1
IS
2088 u16 vid;
2089
65b53bfd 2090 vid = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 1;
c57529e1
IS
2091 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
2092 if (WARN_ON(!mlxsw_sp_port_vlan))
2093 return -EINVAL;
c57529e1
IS
2094
2095 if (mlxsw_sp_port_is_br_member(mlxsw_sp_port, bridge_device->dev)) {
6c677750 2096 NL_SET_ERR_MSG_MOD(extack, "Can not bridge VLAN uppers of the same port");
c57529e1
IS
2097 return -EINVAL;
2098 }
2099
2100 /* Port is no longer usable as a router interface */
a1107487
IS
2101 if (mlxsw_sp_port_vlan->fid)
2102 mlxsw_sp_port_vlan_router_leave(mlxsw_sp_port_vlan);
c57529e1
IS
2103
2104 return mlxsw_sp_port_vlan_bridge_join(mlxsw_sp_port_vlan, bridge_port);
2105}
2106
2107static void
2108mlxsw_sp_bridge_8021d_port_leave(struct mlxsw_sp_bridge_device *bridge_device,
2109 struct mlxsw_sp_bridge_port *bridge_port,
2110 struct mlxsw_sp_port *mlxsw_sp_port)
2111{
2112 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
65b53bfd
IS
2113 struct net_device *dev = bridge_port->dev;
2114 u16 vid;
c57529e1 2115
65b53bfd 2116 vid = is_vlan_dev(dev) ? vlan_dev_vlan_id(dev) : 1;
c57529e1 2117 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_vid(mlxsw_sp_port, vid);
993107fe 2118 if (!mlxsw_sp_port_vlan)
c57529e1
IS
2119 return;
2120
2121 mlxsw_sp_port_vlan_bridge_leave(mlxsw_sp_port_vlan);
2122}
2123
1c30d183
IS
2124static int
2125mlxsw_sp_bridge_8021d_vxlan_join(struct mlxsw_sp_bridge_device *bridge_device,
2126 const struct net_device *vxlan_dev,
2127 struct netlink_ext_ack *extack)
2128{
2129 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
2130 struct vxlan_dev *vxlan = netdev_priv(vxlan_dev);
2131 struct mlxsw_sp_nve_params params = {
2132 .type = MLXSW_SP_NVE_TYPE_VXLAN,
2133 .vni = vxlan->cfg.vni,
2134 .dev = vxlan_dev,
2135 };
2136 struct mlxsw_sp_fid *fid;
2137 int err;
2138
2139 fid = mlxsw_sp_fid_8021d_lookup(mlxsw_sp, bridge_device->dev->ifindex);
2140 if (!fid)
2141 return -EINVAL;
2142
f58a83c2
IS
2143 if (mlxsw_sp_fid_vni_is_set(fid)) {
2144 err = -EINVAL;
2145 goto err_vni_exists;
2146 }
1c30d183
IS
2147
2148 err = mlxsw_sp_nve_fid_enable(mlxsw_sp, fid, &params, extack);
2149 if (err)
2150 goto err_nve_fid_enable;
2151
2152 /* The tunnel port does not hold a reference on the FID. Only
2153 * local ports and the router port
2154 */
2155 mlxsw_sp_fid_put(fid);
2156
2157 return 0;
2158
2159err_nve_fid_enable:
f58a83c2 2160err_vni_exists:
1c30d183
IS
2161 mlxsw_sp_fid_put(fid);
2162 return err;
2163}
2164
2165static void
2166mlxsw_sp_bridge_8021d_vxlan_leave(struct mlxsw_sp_bridge_device *bridge_device,
2167 const struct net_device *vxlan_dev)
2168{
2169 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
2170 struct mlxsw_sp_fid *fid;
2171
2172 fid = mlxsw_sp_fid_8021d_lookup(mlxsw_sp, bridge_device->dev->ifindex);
2173 if (WARN_ON(!fid))
2174 return;
2175
2176 /* If the VxLAN device is down, then the FID does not have a VNI */
2177 if (!mlxsw_sp_fid_vni_is_set(fid))
2178 goto out;
2179
2180 mlxsw_sp_nve_fid_disable(mlxsw_sp, fid);
2181out:
2182 mlxsw_sp_fid_put(fid);
2183}
2184
a1107487
IS
2185static struct mlxsw_sp_fid *
2186mlxsw_sp_bridge_8021d_fid_get(struct mlxsw_sp_bridge_device *bridge_device,
2187 u16 vid)
2188{
2189 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
1c30d183
IS
2190 struct net_device *vxlan_dev;
2191 struct mlxsw_sp_fid *fid;
2192 int err;
a1107487 2193
1c30d183
IS
2194 fid = mlxsw_sp_fid_8021d_get(mlxsw_sp, bridge_device->dev->ifindex);
2195 if (IS_ERR(fid))
2196 return fid;
2197
2198 if (mlxsw_sp_fid_vni_is_set(fid))
2199 return fid;
2200
2201 vxlan_dev = mlxsw_sp_bridge_vxlan_dev_find(bridge_device->dev);
2202 if (!vxlan_dev)
2203 return fid;
2204
2205 if (!netif_running(vxlan_dev))
2206 return fid;
2207
2208 err = mlxsw_sp_bridge_8021d_vxlan_join(bridge_device, vxlan_dev, NULL);
2209 if (err)
2210 goto err_vxlan_join;
2211
2212 return fid;
2213
2214err_vxlan_join:
2215 mlxsw_sp_fid_put(fid);
2216 return ERR_PTR(err);
a1107487
IS
2217}
2218
1231e04f
IS
2219static struct mlxsw_sp_fid *
2220mlxsw_sp_bridge_8021d_fid_lookup(struct mlxsw_sp_bridge_device *bridge_device,
2221 u16 vid)
2222{
2223 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_lower_get(bridge_device->dev);
2224
2225 /* The only valid VLAN for a VLAN-unaware bridge is 0 */
2226 if (vid)
2227 return NULL;
2228
2229 return mlxsw_sp_fid_8021d_lookup(mlxsw_sp, bridge_device->dev->ifindex);
2230}
2231
2232static u16
2233mlxsw_sp_bridge_8021d_fid_vid(struct mlxsw_sp_bridge_device *bridge_device,
2234 const struct mlxsw_sp_fid *fid)
2235{
2236 return 0;
2237}
2238
c57529e1
IS
2239static const struct mlxsw_sp_bridge_ops mlxsw_sp_bridge_8021d_ops = {
2240 .port_join = mlxsw_sp_bridge_8021d_port_join,
2241 .port_leave = mlxsw_sp_bridge_8021d_port_leave,
1c30d183
IS
2242 .vxlan_join = mlxsw_sp_bridge_8021d_vxlan_join,
2243 .vxlan_leave = mlxsw_sp_bridge_8021d_vxlan_leave,
a1107487 2244 .fid_get = mlxsw_sp_bridge_8021d_fid_get,
1231e04f
IS
2245 .fid_lookup = mlxsw_sp_bridge_8021d_fid_lookup,
2246 .fid_vid = mlxsw_sp_bridge_8021d_fid_vid,
c57529e1
IS
2247};
2248
2249int mlxsw_sp_port_bridge_join(struct mlxsw_sp_port *mlxsw_sp_port,
2250 struct net_device *brport_dev,
9b63ef88
IS
2251 struct net_device *br_dev,
2252 struct netlink_ext_ack *extack)
c57529e1
IS
2253{
2254 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2255 struct mlxsw_sp_bridge_device *bridge_device;
2256 struct mlxsw_sp_bridge_port *bridge_port;
2257 int err;
2258
2259 bridge_port = mlxsw_sp_bridge_port_get(mlxsw_sp->bridge, brport_dev);
2260 if (IS_ERR(bridge_port))
2261 return PTR_ERR(bridge_port);
2262 bridge_device = bridge_port->bridge_device;
2263
2264 err = bridge_device->ops->port_join(bridge_device, bridge_port,
9b63ef88 2265 mlxsw_sp_port, extack);
c57529e1
IS
2266 if (err)
2267 goto err_port_join;
2268
2269 return 0;
2270
2271err_port_join:
2272 mlxsw_sp_bridge_port_put(mlxsw_sp->bridge, bridge_port);
2273 return err;
2274}
2275
2276void mlxsw_sp_port_bridge_leave(struct mlxsw_sp_port *mlxsw_sp_port,
2277 struct net_device *brport_dev,
2278 struct net_device *br_dev)
2279{
2280 struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
2281 struct mlxsw_sp_bridge_device *bridge_device;
2282 struct mlxsw_sp_bridge_port *bridge_port;
2283
2284 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2285 if (!bridge_device)
2286 return;
2287 bridge_port = __mlxsw_sp_bridge_port_find(bridge_device, brport_dev);
2288 if (!bridge_port)
2289 return;
2290
2291 bridge_device->ops->port_leave(bridge_device, bridge_port,
2292 mlxsw_sp_port);
2293 mlxsw_sp_bridge_port_put(mlxsw_sp->bridge, bridge_port);
2294}
2295
1c30d183
IS
2296int mlxsw_sp_bridge_vxlan_join(struct mlxsw_sp *mlxsw_sp,
2297 const struct net_device *br_dev,
2298 const struct net_device *vxlan_dev,
2299 struct netlink_ext_ack *extack)
2300{
2301 struct mlxsw_sp_bridge_device *bridge_device;
2302
2303 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2304 if (WARN_ON(!bridge_device))
2305 return -EINVAL;
2306
2307 return bridge_device->ops->vxlan_join(bridge_device, vxlan_dev, extack);
2308}
2309
2310void mlxsw_sp_bridge_vxlan_leave(struct mlxsw_sp *mlxsw_sp,
2311 const struct net_device *br_dev,
2312 const struct net_device *vxlan_dev)
2313{
2314 struct mlxsw_sp_bridge_device *bridge_device;
2315
2316 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2317 if (WARN_ON(!bridge_device))
2318 return;
2319
2320 bridge_device->ops->vxlan_leave(bridge_device, vxlan_dev);
2321}
2322
1b40dc3d
AS
2323static void
2324mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
2325 const char *mac, u16 vid,
e9ba0fbc 2326 struct net_device *dev, bool offloaded)
8a1ab5d7
JP
2327{
2328 struct switchdev_notifier_fdb_info info;
8a1ab5d7 2329
a989cdb4
AS
2330 info.addr = mac;
2331 info.vid = vid;
e9ba0fbc 2332 info.offloaded = offloaded;
1b40dc3d 2333 call_switchdev_notifiers(type, dev, &info.info);
8a1ab5d7
JP
2334}
2335
56ade8fe
JP
2336static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
2337 char *sfn_pl, int rec_index,
2338 bool adding)
2339{
c57529e1
IS
2340 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
2341 struct mlxsw_sp_bridge_device *bridge_device;
2342 struct mlxsw_sp_bridge_port *bridge_port;
56ade8fe 2343 struct mlxsw_sp_port *mlxsw_sp_port;
1b40dc3d 2344 enum switchdev_notifier_type type;
56ade8fe
JP
2345 char mac[ETH_ALEN];
2346 u8 local_port;
9de6a80e 2347 u16 vid, fid;
12f1501e 2348 bool do_notification = true;
56ade8fe
JP
2349 int err;
2350
9de6a80e 2351 mlxsw_reg_sfn_mac_unpack(sfn_pl, rec_index, mac, &fid, &local_port);
56ade8fe
JP
2352 mlxsw_sp_port = mlxsw_sp->ports[local_port];
2353 if (!mlxsw_sp_port) {
2354 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect local port in FDB notification\n");
12f1501e 2355 goto just_remove;
56ade8fe
JP
2356 }
2357
c57529e1
IS
2358 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_fid(mlxsw_sp_port, fid);
2359 if (!mlxsw_sp_port_vlan) {
2360 netdev_err(mlxsw_sp_port->dev, "Failed to find a matching {Port, VID} following FDB notification\n");
2361 goto just_remove;
2362 }
aac78a44 2363
c57529e1
IS
2364 bridge_port = mlxsw_sp_port_vlan->bridge_port;
2365 if (!bridge_port) {
2366 netdev_err(mlxsw_sp_port->dev, "{Port, VID} not associated with a bridge\n");
2367 goto just_remove;
aac78a44
IS
2368 }
2369
c57529e1
IS
2370 bridge_device = bridge_port->bridge_device;
2371 vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0;
2372
12f1501e 2373do_fdb_op:
2fa9d45e 2374 err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid,
12f1501e 2375 adding, true);
56ade8fe 2376 if (err) {
c0e01eac 2377 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n");
56ade8fe
JP
2378 return;
2379 }
2380
12f1501e
JP
2381 if (!do_notification)
2382 return;
1b40dc3d 2383 type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE;
e9ba0fbc 2384 mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding);
a989cdb4 2385
12f1501e
JP
2386 return;
2387
2388just_remove:
2389 adding = false;
2390 do_notification = false;
2391 goto do_fdb_op;
8a1ab5d7 2392}
56ade8fe 2393
8a1ab5d7
JP
2394static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
2395 char *sfn_pl, int rec_index,
2396 bool adding)
2397{
c57529e1
IS
2398 struct mlxsw_sp_port_vlan *mlxsw_sp_port_vlan;
2399 struct mlxsw_sp_bridge_device *bridge_device;
2400 struct mlxsw_sp_bridge_port *bridge_port;
8a1ab5d7 2401 struct mlxsw_sp_port *mlxsw_sp_port;
1b40dc3d 2402 enum switchdev_notifier_type type;
8a1ab5d7 2403 char mac[ETH_ALEN];
64771e31 2404 u16 lag_vid = 0;
8a1ab5d7 2405 u16 lag_id;
9de6a80e 2406 u16 vid, fid;
12f1501e 2407 bool do_notification = true;
8a1ab5d7
JP
2408 int err;
2409
9de6a80e 2410 mlxsw_reg_sfn_mac_lag_unpack(sfn_pl, rec_index, mac, &fid, &lag_id);
8a1ab5d7
JP
2411 mlxsw_sp_port = mlxsw_sp_lag_rep_port(mlxsw_sp, lag_id);
2412 if (!mlxsw_sp_port) {
2413 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Cannot find port representor for LAG\n");
12f1501e 2414 goto just_remove;
56ade8fe 2415 }
8a1ab5d7 2416
c57529e1
IS
2417 mlxsw_sp_port_vlan = mlxsw_sp_port_vlan_find_by_fid(mlxsw_sp_port, fid);
2418 if (!mlxsw_sp_port_vlan) {
2419 netdev_err(mlxsw_sp_port->dev, "Failed to find a matching {Port, VID} following FDB notification\n");
2420 goto just_remove;
2421 }
aac78a44 2422
c57529e1
IS
2423 bridge_port = mlxsw_sp_port_vlan->bridge_port;
2424 if (!bridge_port) {
2425 netdev_err(mlxsw_sp_port->dev, "{Port, VID} not associated with a bridge\n");
2426 goto just_remove;
aac78a44
IS
2427 }
2428
c57529e1
IS
2429 bridge_device = bridge_port->bridge_device;
2430 vid = bridge_device->vlan_enabled ? mlxsw_sp_port_vlan->vid : 0;
2431 lag_vid = mlxsw_sp_port_vlan->vid;
2432
12f1501e 2433do_fdb_op:
64771e31 2434 err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
12f1501e 2435 adding, true);
8a1ab5d7 2436 if (err) {
c0e01eac 2437 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to set FDB entry\n");
8a1ab5d7
JP
2438 return;
2439 }
2440
12f1501e
JP
2441 if (!do_notification)
2442 return;
1b40dc3d 2443 type = adding ? SWITCHDEV_FDB_ADD_TO_BRIDGE : SWITCHDEV_FDB_DEL_TO_BRIDGE;
e9ba0fbc 2444 mlxsw_sp_fdb_call_notifiers(type, mac, vid, bridge_port->dev, adding);
a989cdb4 2445
12f1501e
JP
2446 return;
2447
2448just_remove:
2449 adding = false;
2450 do_notification = false;
2451 goto do_fdb_op;
56ade8fe
JP
2452}
2453
2454static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
2455 char *sfn_pl, int rec_index)
2456{
2457 switch (mlxsw_reg_sfn_rec_type_get(sfn_pl, rec_index)) {
2458 case MLXSW_REG_SFN_REC_TYPE_LEARNED_MAC:
2459 mlxsw_sp_fdb_notify_mac_process(mlxsw_sp, sfn_pl,
2460 rec_index, true);
2461 break;
2462 case MLXSW_REG_SFN_REC_TYPE_AGED_OUT_MAC:
2463 mlxsw_sp_fdb_notify_mac_process(mlxsw_sp, sfn_pl,
2464 rec_index, false);
2465 break;
8a1ab5d7
JP
2466 case MLXSW_REG_SFN_REC_TYPE_LEARNED_MAC_LAG:
2467 mlxsw_sp_fdb_notify_mac_lag_process(mlxsw_sp, sfn_pl,
2468 rec_index, true);
2469 break;
2470 case MLXSW_REG_SFN_REC_TYPE_AGED_OUT_MAC_LAG:
2471 mlxsw_sp_fdb_notify_mac_lag_process(mlxsw_sp, sfn_pl,
2472 rec_index, false);
2473 break;
56ade8fe
JP
2474 }
2475}
2476
2477static void mlxsw_sp_fdb_notify_work_schedule(struct mlxsw_sp *mlxsw_sp)
2478{
5f6935c6
IS
2479 struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
2480
2481 mlxsw_core_schedule_dw(&bridge->fdb_notify.dw,
2482 msecs_to_jiffies(bridge->fdb_notify.interval));
56ade8fe
JP
2483}
2484
2485static void mlxsw_sp_fdb_notify_work(struct work_struct *work)
2486{
5f6935c6 2487 struct mlxsw_sp_bridge *bridge;
56ade8fe
JP
2488 struct mlxsw_sp *mlxsw_sp;
2489 char *sfn_pl;
2490 u8 num_rec;
2491 int i;
2492 int err;
2493
2494 sfn_pl = kmalloc(MLXSW_REG_SFN_LEN, GFP_KERNEL);
2495 if (!sfn_pl)
2496 return;
2497
5f6935c6
IS
2498 bridge = container_of(work, struct mlxsw_sp_bridge, fdb_notify.dw.work);
2499 mlxsw_sp = bridge->mlxsw_sp;
56ade8fe 2500
4f2c6ae5 2501 rtnl_lock();
1803e0fb
IS
2502 mlxsw_reg_sfn_pack(sfn_pl);
2503 err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(sfn), sfn_pl);
2504 if (err) {
2505 dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get FDB notifications\n");
2506 goto out;
2507 }
2508 num_rec = mlxsw_reg_sfn_num_rec_get(sfn_pl);
2509 for (i = 0; i < num_rec; i++)
2510 mlxsw_sp_fdb_notify_rec_process(mlxsw_sp, sfn_pl, i);
56ade8fe 2511
1803e0fb 2512out:
4f2c6ae5 2513 rtnl_unlock();
56ade8fe
JP
2514 kfree(sfn_pl);
2515 mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
2516}
2517
af061378
AS
2518struct mlxsw_sp_switchdev_event_work {
2519 struct work_struct work;
1231e04f
IS
2520 union {
2521 struct switchdev_notifier_fdb_info fdb_info;
2522 struct switchdev_notifier_vxlan_fdb_info vxlan_fdb_info;
2523 };
af061378
AS
2524 struct net_device *dev;
2525 unsigned long event;
2526};
2527
1231e04f
IS
2528static void
2529mlxsw_sp_switchdev_vxlan_addr_convert(const union vxlan_addr *vxlan_addr,
2530 enum mlxsw_sp_l3proto *proto,
2531 union mlxsw_sp_l3addr *addr)
2532{
2533 if (vxlan_addr->sa.sa_family == AF_INET) {
2534 addr->addr4 = vxlan_addr->sin.sin_addr.s_addr;
2535 *proto = MLXSW_SP_L3_PROTO_IPV4;
2536 } else {
2537 addr->addr6 = vxlan_addr->sin6.sin6_addr;
2538 *proto = MLXSW_SP_L3_PROTO_IPV6;
2539 }
2540}
2541
2542static void
2543mlxsw_sp_switchdev_bridge_vxlan_fdb_event(struct mlxsw_sp *mlxsw_sp,
2544 struct mlxsw_sp_switchdev_event_work *
2545 switchdev_work,
2546 struct mlxsw_sp_fid *fid, __be32 vni)
2547{
2548 struct switchdev_notifier_vxlan_fdb_info vxlan_fdb_info;
2549 struct switchdev_notifier_fdb_info *fdb_info;
2550 struct net_device *dev = switchdev_work->dev;
2551 enum mlxsw_sp_l3proto proto;
2552 union mlxsw_sp_l3addr addr;
2553 int err;
2554
2555 fdb_info = &switchdev_work->fdb_info;
2556 err = vxlan_fdb_find_uc(dev, fdb_info->addr, vni, &vxlan_fdb_info);
2557 if (err)
2558 return;
2559
2560 mlxsw_sp_switchdev_vxlan_addr_convert(&vxlan_fdb_info.remote_ip,
2561 &proto, &addr);
2562
2563 switch (switchdev_work->event) {
2564 case SWITCHDEV_FDB_ADD_TO_DEVICE:
2565 err = mlxsw_sp_port_fdb_tunnel_uc_op(mlxsw_sp,
2566 vxlan_fdb_info.eth_addr,
2567 mlxsw_sp_fid_index(fid),
2568 proto, &addr, true, false);
2569 if (err)
2570 return;
2571 vxlan_fdb_info.offloaded = true;
2572 call_switchdev_notifiers(SWITCHDEV_VXLAN_FDB_OFFLOADED, dev,
2573 &vxlan_fdb_info.info);
2574 mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
2575 vxlan_fdb_info.eth_addr,
2576 fdb_info->vid, dev, true);
2577 break;
2578 case SWITCHDEV_FDB_DEL_TO_DEVICE:
2579 err = mlxsw_sp_port_fdb_tunnel_uc_op(mlxsw_sp,
2580 vxlan_fdb_info.eth_addr,
2581 mlxsw_sp_fid_index(fid),
2582 proto, &addr, false,
2583 false);
2584 vxlan_fdb_info.offloaded = false;
2585 call_switchdev_notifiers(SWITCHDEV_VXLAN_FDB_OFFLOADED, dev,
2586 &vxlan_fdb_info.info);
2587 break;
2588 }
2589}
2590
2591static void
2592mlxsw_sp_switchdev_bridge_nve_fdb_event(struct mlxsw_sp_switchdev_event_work *
2593 switchdev_work)
2594{
2595 struct mlxsw_sp_bridge_device *bridge_device;
2596 struct net_device *dev = switchdev_work->dev;
2597 struct net_device *br_dev;
2598 struct mlxsw_sp *mlxsw_sp;
2599 struct mlxsw_sp_fid *fid;
2600 __be32 vni;
2601 int err;
2602
2603 if (switchdev_work->event != SWITCHDEV_FDB_ADD_TO_DEVICE &&
2604 switchdev_work->event != SWITCHDEV_FDB_DEL_TO_DEVICE)
2605 return;
2606
2607 if (!switchdev_work->fdb_info.added_by_user)
2608 return;
2609
2610 if (!netif_running(dev))
2611 return;
2612 br_dev = netdev_master_upper_dev_get(dev);
2613 if (!br_dev)
2614 return;
2615 if (!netif_is_bridge_master(br_dev))
2616 return;
2617 mlxsw_sp = mlxsw_sp_lower_get(br_dev);
2618 if (!mlxsw_sp)
2619 return;
2620 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2621 if (!bridge_device)
2622 return;
2623
2624 fid = bridge_device->ops->fid_lookup(bridge_device,
2625 switchdev_work->fdb_info.vid);
2626 if (!fid)
2627 return;
2628
2629 err = mlxsw_sp_fid_vni(fid, &vni);
2630 if (err)
2631 goto out;
2632
2633 mlxsw_sp_switchdev_bridge_vxlan_fdb_event(mlxsw_sp, switchdev_work, fid,
2634 vni);
2635
2636out:
2637 mlxsw_sp_fid_put(fid);
2638}
2639
ab74c3a1 2640static void mlxsw_sp_switchdev_bridge_fdb_event_work(struct work_struct *work)
af061378
AS
2641{
2642 struct mlxsw_sp_switchdev_event_work *switchdev_work =
2643 container_of(work, struct mlxsw_sp_switchdev_event_work, work);
2644 struct net_device *dev = switchdev_work->dev;
2645 struct switchdev_notifier_fdb_info *fdb_info;
2646 struct mlxsw_sp_port *mlxsw_sp_port;
2647 int err;
2648
2649 rtnl_lock();
1231e04f
IS
2650 if (netif_is_vxlan(dev)) {
2651 mlxsw_sp_switchdev_bridge_nve_fdb_event(switchdev_work);
2652 goto out;
2653 }
2654
af061378
AS
2655 mlxsw_sp_port = mlxsw_sp_port_dev_lower_find(dev);
2656 if (!mlxsw_sp_port)
2657 goto out;
2658
2659 switch (switchdev_work->event) {
2660 case SWITCHDEV_FDB_ADD_TO_DEVICE:
2661 fdb_info = &switchdev_work->fdb_info;
816a3bed
PM
2662 if (!fdb_info->added_by_user)
2663 break;
af061378
AS
2664 err = mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, true);
2665 if (err)
2666 break;
2667 mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
2668 fdb_info->addr,
e9ba0fbc 2669 fdb_info->vid, dev, true);
af061378
AS
2670 break;
2671 case SWITCHDEV_FDB_DEL_TO_DEVICE:
2672 fdb_info = &switchdev_work->fdb_info;
2673 mlxsw_sp_port_fdb_set(mlxsw_sp_port, fdb_info, false);
2674 break;
c520bc69
PM
2675 case SWITCHDEV_FDB_ADD_TO_BRIDGE: /* fall through */
2676 case SWITCHDEV_FDB_DEL_TO_BRIDGE:
2677 /* These events are only used to potentially update an existing
2678 * SPAN mirror.
2679 */
2680 break;
af061378
AS
2681 }
2682
c520bc69
PM
2683 mlxsw_sp_span_respin(mlxsw_sp_port->mlxsw_sp);
2684
af061378
AS
2685out:
2686 rtnl_unlock();
2687 kfree(switchdev_work->fdb_info.addr);
2688 kfree(switchdev_work);
2689 dev_put(dev);
2690}
2691
1231e04f
IS
2692static void
2693mlxsw_sp_switchdev_vxlan_fdb_add(struct mlxsw_sp *mlxsw_sp,
2694 struct mlxsw_sp_switchdev_event_work *
2695 switchdev_work)
2696{
2697 struct switchdev_notifier_vxlan_fdb_info *vxlan_fdb_info;
2698 struct mlxsw_sp_bridge_device *bridge_device;
2699 struct net_device *dev = switchdev_work->dev;
2700 u8 all_zeros_mac[ETH_ALEN] = { 0 };
2701 enum mlxsw_sp_l3proto proto;
2702 union mlxsw_sp_l3addr addr;
2703 struct net_device *br_dev;
2704 struct mlxsw_sp_fid *fid;
2705 u16 vid;
2706 int err;
2707
2708 vxlan_fdb_info = &switchdev_work->vxlan_fdb_info;
2709 br_dev = netdev_master_upper_dev_get(dev);
2710
2711 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2712 if (!bridge_device)
2713 return;
2714
2715 fid = mlxsw_sp_fid_lookup_by_vni(mlxsw_sp, vxlan_fdb_info->vni);
2716 if (!fid)
2717 return;
2718
2719 mlxsw_sp_switchdev_vxlan_addr_convert(&vxlan_fdb_info->remote_ip,
2720 &proto, &addr);
2721
2722 if (ether_addr_equal(vxlan_fdb_info->eth_addr, all_zeros_mac)) {
2723 err = mlxsw_sp_nve_flood_ip_add(mlxsw_sp, fid, proto, &addr);
2724 if (err) {
2725 mlxsw_sp_fid_put(fid);
2726 return;
2727 }
2728 vxlan_fdb_info->offloaded = true;
2729 call_switchdev_notifiers(SWITCHDEV_VXLAN_FDB_OFFLOADED, dev,
2730 &vxlan_fdb_info->info);
2731 mlxsw_sp_fid_put(fid);
2732 return;
2733 }
2734
2735 /* The device has a single FDB table, whereas Linux has two - one
2736 * in the bridge driver and another in the VxLAN driver. We only
2737 * program an entry to the device if the MAC points to the VxLAN
2738 * device in the bridge's FDB table
2739 */
2740 vid = bridge_device->ops->fid_vid(bridge_device, fid);
2741 if (br_fdb_find_port(br_dev, vxlan_fdb_info->eth_addr, vid) != dev)
2742 goto err_br_fdb_find;
2743
2744 err = mlxsw_sp_port_fdb_tunnel_uc_op(mlxsw_sp, vxlan_fdb_info->eth_addr,
2745 mlxsw_sp_fid_index(fid), proto,
2746 &addr, true, false);
2747 if (err)
2748 goto err_fdb_tunnel_uc_op;
2749 vxlan_fdb_info->offloaded = true;
2750 call_switchdev_notifiers(SWITCHDEV_VXLAN_FDB_OFFLOADED, dev,
2751 &vxlan_fdb_info->info);
2752 mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
2753 vxlan_fdb_info->eth_addr, vid, dev, true);
2754
2755 mlxsw_sp_fid_put(fid);
2756
2757 return;
2758
2759err_fdb_tunnel_uc_op:
2760err_br_fdb_find:
2761 mlxsw_sp_fid_put(fid);
2762}
2763
2764static void
2765mlxsw_sp_switchdev_vxlan_fdb_del(struct mlxsw_sp *mlxsw_sp,
2766 struct mlxsw_sp_switchdev_event_work *
2767 switchdev_work)
2768{
2769 struct switchdev_notifier_vxlan_fdb_info *vxlan_fdb_info;
2770 struct mlxsw_sp_bridge_device *bridge_device;
2771 struct net_device *dev = switchdev_work->dev;
2772 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
2773 u8 all_zeros_mac[ETH_ALEN] = { 0 };
2774 enum mlxsw_sp_l3proto proto;
2775 union mlxsw_sp_l3addr addr;
2776 struct mlxsw_sp_fid *fid;
2777 u16 vid;
2778
2779 vxlan_fdb_info = &switchdev_work->vxlan_fdb_info;
2780
2781 bridge_device = mlxsw_sp_bridge_device_find(mlxsw_sp->bridge, br_dev);
2782 if (!bridge_device)
2783 return;
2784
2785 fid = mlxsw_sp_fid_lookup_by_vni(mlxsw_sp, vxlan_fdb_info->vni);
2786 if (!fid)
2787 return;
2788
2789 mlxsw_sp_switchdev_vxlan_addr_convert(&vxlan_fdb_info->remote_ip,
2790 &proto, &addr);
2791
2792 if (ether_addr_equal(vxlan_fdb_info->eth_addr, all_zeros_mac)) {
2793 mlxsw_sp_nve_flood_ip_del(mlxsw_sp, fid, proto, &addr);
2794 mlxsw_sp_fid_put(fid);
2795 return;
2796 }
2797
2798 mlxsw_sp_port_fdb_tunnel_uc_op(mlxsw_sp, vxlan_fdb_info->eth_addr,
2799 mlxsw_sp_fid_index(fid), proto, &addr,
2800 false, false);
2801 vid = bridge_device->ops->fid_vid(bridge_device, fid);
2802 mlxsw_sp_fdb_call_notifiers(SWITCHDEV_FDB_OFFLOADED,
2803 vxlan_fdb_info->eth_addr, vid, dev, false);
2804
2805 mlxsw_sp_fid_put(fid);
2806}
2807
2808static void mlxsw_sp_switchdev_vxlan_fdb_event_work(struct work_struct *work)
2809{
2810 struct mlxsw_sp_switchdev_event_work *switchdev_work =
2811 container_of(work, struct mlxsw_sp_switchdev_event_work, work);
2812 struct net_device *dev = switchdev_work->dev;
2813 struct mlxsw_sp *mlxsw_sp;
2814 struct net_device *br_dev;
2815
2816 rtnl_lock();
2817
2818 if (!netif_running(dev))
2819 goto out;
2820 br_dev = netdev_master_upper_dev_get(dev);
2821 if (!br_dev)
2822 goto out;
2823 if (!netif_is_bridge_master(br_dev))
2824 goto out;
2825 mlxsw_sp = mlxsw_sp_lower_get(br_dev);
2826 if (!mlxsw_sp)
2827 goto out;
2828
2829 switch (switchdev_work->event) {
2830 case SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE:
2831 mlxsw_sp_switchdev_vxlan_fdb_add(mlxsw_sp, switchdev_work);
2832 break;
2833 case SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE:
2834 mlxsw_sp_switchdev_vxlan_fdb_del(mlxsw_sp, switchdev_work);
2835 break;
2836 }
2837
2838out:
2839 rtnl_unlock();
2840 kfree(switchdev_work);
2841 dev_put(dev);
2842}
2843
2844static int
2845mlxsw_sp_switchdev_vxlan_work_prepare(struct mlxsw_sp_switchdev_event_work *
2846 switchdev_work,
2847 struct switchdev_notifier_info *info)
2848{
2849 struct vxlan_dev *vxlan = netdev_priv(switchdev_work->dev);
2850 struct switchdev_notifier_vxlan_fdb_info *vxlan_fdb_info;
2851 struct vxlan_config *cfg = &vxlan->cfg;
2852
2853 vxlan_fdb_info = container_of(info,
2854 struct switchdev_notifier_vxlan_fdb_info,
2855 info);
2856
2857 if (vxlan_fdb_info->remote_port != cfg->dst_port)
2858 return -EOPNOTSUPP;
2859 if (vxlan_fdb_info->remote_vni != cfg->vni)
2860 return -EOPNOTSUPP;
2861 if (vxlan_fdb_info->vni != cfg->vni)
2862 return -EOPNOTSUPP;
2863 if (vxlan_fdb_info->remote_ifindex)
2864 return -EOPNOTSUPP;
2865 if (is_multicast_ether_addr(vxlan_fdb_info->eth_addr))
2866 return -EOPNOTSUPP;
2867 if (vxlan_addr_multicast(&vxlan_fdb_info->remote_ip))
2868 return -EOPNOTSUPP;
2869
2870 switchdev_work->vxlan_fdb_info = *vxlan_fdb_info;
2871
2872 return 0;
2873}
2874
af061378
AS
2875/* Called under rcu_read_lock() */
2876static int mlxsw_sp_switchdev_event(struct notifier_block *unused,
2877 unsigned long event, void *ptr)
2878{
2879 struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
2880 struct mlxsw_sp_switchdev_event_work *switchdev_work;
9c73b1d1
IS
2881 struct switchdev_notifier_fdb_info *fdb_info;
2882 struct switchdev_notifier_info *info = ptr;
5050f6ae 2883 struct net_device *br_dev;
1231e04f 2884 int err;
af061378 2885
5050f6ae
IS
2886 /* Tunnel devices are not our uppers, so check their master instead */
2887 br_dev = netdev_master_upper_dev_get_rcu(dev);
2888 if (!br_dev)
2889 return NOTIFY_DONE;
2890 if (!netif_is_bridge_master(br_dev))
2891 return NOTIFY_DONE;
2892 if (!mlxsw_sp_port_dev_lower_find_rcu(br_dev))
af061378
AS
2893 return NOTIFY_DONE;
2894
2895 switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
2896 if (!switchdev_work)
2897 return NOTIFY_BAD;
2898
af061378
AS
2899 switchdev_work->dev = dev;
2900 switchdev_work->event = event;
2901
2902 switch (event) {
2903 case SWITCHDEV_FDB_ADD_TO_DEVICE: /* fall through */
c520bc69
PM
2904 case SWITCHDEV_FDB_DEL_TO_DEVICE: /* fall through */
2905 case SWITCHDEV_FDB_ADD_TO_BRIDGE: /* fall through */
2906 case SWITCHDEV_FDB_DEL_TO_BRIDGE:
9c73b1d1
IS
2907 fdb_info = container_of(info,
2908 struct switchdev_notifier_fdb_info,
2909 info);
ab74c3a1
IS
2910 INIT_WORK(&switchdev_work->work,
2911 mlxsw_sp_switchdev_bridge_fdb_event_work);
af061378
AS
2912 memcpy(&switchdev_work->fdb_info, ptr,
2913 sizeof(switchdev_work->fdb_info));
2914 switchdev_work->fdb_info.addr = kzalloc(ETH_ALEN, GFP_ATOMIC);
6f497930
IS
2915 if (!switchdev_work->fdb_info.addr)
2916 goto err_addr_alloc;
af061378
AS
2917 ether_addr_copy((u8 *)switchdev_work->fdb_info.addr,
2918 fdb_info->addr);
2919 /* Take a reference on the device. This can be either
2920 * upper device containig mlxsw_sp_port or just a
2921 * mlxsw_sp_port
2922 */
2923 dev_hold(dev);
2924 break;
1231e04f
IS
2925 case SWITCHDEV_VXLAN_FDB_ADD_TO_DEVICE: /* fall through */
2926 case SWITCHDEV_VXLAN_FDB_DEL_TO_DEVICE:
2927 INIT_WORK(&switchdev_work->work,
2928 mlxsw_sp_switchdev_vxlan_fdb_event_work);
2929 err = mlxsw_sp_switchdev_vxlan_work_prepare(switchdev_work,
2930 info);
2931 if (err)
2932 goto err_vxlan_work_prepare;
2933 dev_hold(dev);
2934 break;
af061378
AS
2935 default:
2936 kfree(switchdev_work);
2937 return NOTIFY_DONE;
2938 }
2939
2940 mlxsw_core_schedule_work(&switchdev_work->work);
2941
2942 return NOTIFY_DONE;
6f497930 2943
1231e04f 2944err_vxlan_work_prepare:
6f497930
IS
2945err_addr_alloc:
2946 kfree(switchdev_work);
2947 return NOTIFY_BAD;
af061378
AS
2948}
2949
2950static struct notifier_block mlxsw_sp_switchdev_notifier = {
2951 .notifier_call = mlxsw_sp_switchdev_event,
2952};
2953
ea93c7b6
PM
2954u8
2955mlxsw_sp_bridge_port_stp_state(struct mlxsw_sp_bridge_port *bridge_port)
2956{
2957 return bridge_port->stp_state;
2958}
2959
56ade8fe
JP
2960static int mlxsw_sp_fdb_init(struct mlxsw_sp *mlxsw_sp)
2961{
5f6935c6 2962 struct mlxsw_sp_bridge *bridge = mlxsw_sp->bridge;
56ade8fe
JP
2963 int err;
2964
2965 err = mlxsw_sp_ageing_set(mlxsw_sp, MLXSW_SP_DEFAULT_AGEING_TIME);
2966 if (err) {
2967 dev_err(mlxsw_sp->bus_info->dev, "Failed to set default ageing time\n");
2968 return err;
2969 }
af061378
AS
2970
2971 err = register_switchdev_notifier(&mlxsw_sp_switchdev_notifier);
2972 if (err) {
2973 dev_err(mlxsw_sp->bus_info->dev, "Failed to register switchdev notifier\n");
2974 return err;
2975 }
2976
5f6935c6
IS
2977 INIT_DELAYED_WORK(&bridge->fdb_notify.dw, mlxsw_sp_fdb_notify_work);
2978 bridge->fdb_notify.interval = MLXSW_SP_DEFAULT_LEARNING_INTERVAL;
56ade8fe
JP
2979 mlxsw_sp_fdb_notify_work_schedule(mlxsw_sp);
2980 return 0;
2981}
2982
2983static void mlxsw_sp_fdb_fini(struct mlxsw_sp *mlxsw_sp)
2984{
5f6935c6 2985 cancel_delayed_work_sync(&mlxsw_sp->bridge->fdb_notify.dw);
af061378
AS
2986 unregister_switchdev_notifier(&mlxsw_sp_switchdev_notifier);
2987
56ade8fe
JP
2988}
2989
56ade8fe
JP
2990int mlxsw_sp_switchdev_init(struct mlxsw_sp *mlxsw_sp)
2991{
5f6935c6
IS
2992 struct mlxsw_sp_bridge *bridge;
2993
2994 bridge = kzalloc(sizeof(*mlxsw_sp->bridge), GFP_KERNEL);
2995 if (!bridge)
2996 return -ENOMEM;
2997 mlxsw_sp->bridge = bridge;
2998 bridge->mlxsw_sp = mlxsw_sp;
2999
c57529e1 3000 INIT_LIST_HEAD(&mlxsw_sp->bridge->bridges_list);
5f6935c6 3001
c57529e1
IS
3002 bridge->bridge_8021q_ops = &mlxsw_sp_bridge_8021q_ops;
3003 bridge->bridge_8021d_ops = &mlxsw_sp_bridge_8021d_ops;
3004
56ade8fe
JP
3005 return mlxsw_sp_fdb_init(mlxsw_sp);
3006}
3007
3008void mlxsw_sp_switchdev_fini(struct mlxsw_sp *mlxsw_sp)
3009{
3010 mlxsw_sp_fdb_fini(mlxsw_sp);
c57529e1 3011 WARN_ON(!list_empty(&mlxsw_sp->bridge->bridges_list));
5f6935c6 3012 kfree(mlxsw_sp->bridge);
56ade8fe
JP
3013}
3014
56ade8fe
JP
3015void mlxsw_sp_port_switchdev_init(struct mlxsw_sp_port *mlxsw_sp_port)
3016{
3017 mlxsw_sp_port->dev->switchdev_ops = &mlxsw_sp_port_switchdev_ops;
3018}
3019
3020void mlxsw_sp_port_switchdev_fini(struct mlxsw_sp_port *mlxsw_sp_port)
3021{
3022}