net: dsa: tag_8021q: replace the SVL bridging with VLAN-unaware IVL bridging
[linux-block.git] / net / dsa / switch.c
CommitLineData
2874c5fd 1// SPDX-License-Identifier: GPL-2.0-or-later
f515f192
VD
2/*
3 * Handling of a single switch chip, part of a switch fabric
4 *
4333d619
VD
5 * Copyright (c) 2017 Savoir-faire Linux Inc.
6 * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
f515f192
VD
7 */
8
d371b7c9 9#include <linux/if_bridge.h>
f515f192
VD
10#include <linux/netdevice.h>
11#include <linux/notifier.h>
061f6a50 12#include <linux/if_vlan.h>
1faabf74 13#include <net/switchdev.h>
ea5dd34b
VD
14
15#include "dsa_priv.h"
f515f192 16
1faabf74
VD
17static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
18 unsigned int ageing_time)
19{
d0004a02 20 struct dsa_port *dp;
1faabf74 21
d0004a02 22 dsa_switch_for_each_port(dp, ds)
1faabf74
VD
23 if (dp->ageing_time && dp->ageing_time < ageing_time)
24 ageing_time = dp->ageing_time;
1faabf74
VD
25
26 return ageing_time;
27}
28
29static int dsa_switch_ageing_time(struct dsa_switch *ds,
30 struct dsa_notifier_ageing_time_info *info)
31{
32 unsigned int ageing_time = info->ageing_time;
77b61365
VO
33
34 if (ds->ageing_time_min && ageing_time < ds->ageing_time_min)
35 return -ERANGE;
36
37 if (ds->ageing_time_max && ageing_time > ds->ageing_time_max)
38 return -ERANGE;
1faabf74
VD
39
40 /* Program the fastest ageing time in case of multiple bridges */
41 ageing_time = dsa_switch_fastest_ageing_time(ds, ageing_time);
42
43 if (ds->ops->set_ageing_time)
44 return ds->ops->set_ageing_time(ds, ageing_time);
45
46 return 0;
47}
48
fac6abd5
VO
49static bool dsa_port_mtu_match(struct dsa_port *dp,
50 struct dsa_notifier_mtu_info *info)
bfcb8132 51{
fac6abd5 52 if (dp->ds->index == info->sw_index && dp->index == info->port)
88faba20 53 return true;
bfcb8132 54
88faba20
VO
55 /* Do not propagate to other switches in the tree if the notifier was
56 * targeted for a single switch.
57 */
58 if (info->targeted_match)
bfcb8132
VO
59 return false;
60
fac6abd5 61 if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp))
bfcb8132
VO
62 return true;
63
64 return false;
65}
66
67static int dsa_switch_mtu(struct dsa_switch *ds,
68 struct dsa_notifier_mtu_info *info)
69{
fac6abd5
VO
70 struct dsa_port *dp;
71 int ret;
bfcb8132
VO
72
73 if (!ds->ops->port_change_mtu)
74 return -EOPNOTSUPP;
75
fac6abd5
VO
76 dsa_switch_for_each_port(dp, ds) {
77 if (dsa_port_mtu_match(dp, info)) {
78 ret = ds->ops->port_change_mtu(ds, dp->index,
79 info->mtu);
bfcb8132
VO
80 if (ret)
81 return ret;
82 }
83 }
84
85 return 0;
86}
87
04d3a4c6
VD
88static int dsa_switch_bridge_join(struct dsa_switch *ds,
89 struct dsa_notifier_bridge_info *info)
90{
f66a6a69 91 struct dsa_switch_tree *dst = ds->dst;
e19cc13c 92 int err;
f66a6a69 93
67b5fb5d
VO
94 if (dst->index == info->tree_index && ds->index == info->sw_index) {
95 if (!ds->ops->port_bridge_join)
96 return -EOPNOTSUPP;
97
b079922b
VO
98 err = ds->ops->port_bridge_join(ds, info->port, info->bridge,
99 &info->tx_fwd_offload);
e19cc13c
VO
100 if (err)
101 return err;
102 }
04d3a4c6 103
f66a6a69 104 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
e19cc13c
VO
105 ds->ops->crosschip_bridge_join) {
106 err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
107 info->sw_index,
d3eed0e5 108 info->port, info->bridge);
e19cc13c
VO
109 if (err)
110 return err;
111 }
04d3a4c6 112
91495f21 113 return 0;
04d3a4c6
VD
114}
115
381a7301
TW
116static int dsa_switch_sync_vlan_filtering(struct dsa_switch *ds,
117 struct dsa_notifier_bridge_info *info)
04d3a4c6 118{
89153ed6 119 struct netlink_ext_ack extack = {0};
58adf9dc
VO
120 bool change_vlan_filtering = false;
121 bool vlan_filtering;
d0004a02
VO
122 struct dsa_port *dp;
123 int err;
d371b7c9 124
d3eed0e5
VO
125 if (ds->needs_standalone_vlan_filtering &&
126 !br_vlan_enabled(info->bridge.dev)) {
58adf9dc
VO
127 change_vlan_filtering = true;
128 vlan_filtering = true;
129 } else if (!ds->needs_standalone_vlan_filtering &&
d3eed0e5 130 br_vlan_enabled(info->bridge.dev)) {
58adf9dc
VO
131 change_vlan_filtering = true;
132 vlan_filtering = false;
133 }
134
d371b7c9
VO
135 /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
136 * event for changing vlan_filtering setting upon slave ports leaving
137 * it. That is a good thing, because that lets us handle it and also
138 * handle the case where the switch's vlan_filtering setting is global
139 * (not per port). When that happens, the correct moment to trigger the
479dc497
VO
140 * vlan_filtering callback is only when the last port leaves the last
141 * VLAN-aware bridge.
d371b7c9 142 */
58adf9dc 143 if (change_vlan_filtering && ds->vlan_filtering_is_global) {
d0004a02 144 dsa_switch_for_each_port(dp, ds) {
36cbf39b 145 struct net_device *br = dsa_port_bridge_dev_get(dp);
479dc497 146
36cbf39b 147 if (br && br_vlan_enabled(br)) {
58adf9dc 148 change_vlan_filtering = false;
d371b7c9
VO
149 break;
150 }
151 }
152 }
58adf9dc
VO
153
154 if (change_vlan_filtering) {
68bb8ea8 155 err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
58adf9dc 156 vlan_filtering, &extack);
89153ed6
VO
157 if (extack._msg)
158 dev_err(ds->dev, "port %d: %s\n", info->port,
159 extack._msg);
43a4b4db 160 if (err && err != -EOPNOTSUPP)
d371b7c9
VO
161 return err;
162 }
e19cc13c 163
381a7301
TW
164 return 0;
165}
166
167static int dsa_switch_bridge_leave(struct dsa_switch *ds,
168 struct dsa_notifier_bridge_info *info)
169{
170 struct dsa_switch_tree *dst = ds->dst;
171 int err;
172
173 if (dst->index == info->tree_index && ds->index == info->sw_index &&
174 ds->ops->port_bridge_leave)
175 ds->ops->port_bridge_leave(ds, info->port, info->bridge);
176
177 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
178 ds->ops->crosschip_bridge_leave)
179 ds->ops->crosschip_bridge_leave(ds, info->tree_index,
180 info->sw_index, info->port,
181 info->bridge);
182
108dc874
TW
183 if (ds->dst->index == info->tree_index && ds->index == info->sw_index) {
184 err = dsa_switch_sync_vlan_filtering(ds, info);
185 if (err)
186 return err;
187 }
381a7301 188
91495f21 189 return 0;
04d3a4c6
VD
190}
191
b8e997c4
VO
192/* Matches for all upstream-facing ports (the CPU port and all upstream-facing
193 * DSA links) that sit between the targeted port on which the notifier was
194 * emitted and its dedicated CPU port.
195 */
fac6abd5
VO
196static bool dsa_port_host_address_match(struct dsa_port *dp,
197 int info_sw_index, int info_port)
b8e997c4
VO
198{
199 struct dsa_port *targeted_dp, *cpu_dp;
200 struct dsa_switch *targeted_ds;
201
fac6abd5 202 targeted_ds = dsa_switch_find(dp->ds->dst->index, info_sw_index);
b8e997c4
VO
203 targeted_dp = dsa_to_port(targeted_ds, info_port);
204 cpu_dp = targeted_dp->cpu_dp;
205
fac6abd5
VO
206 if (dsa_switch_is_upstream_of(dp->ds, targeted_ds))
207 return dp->index == dsa_towards_port(dp->ds, cpu_dp->ds->index,
208 cpu_dp->index);
b8e997c4
VO
209
210 return false;
211}
212
161ca59d
VO
213static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
214 const unsigned char *addr,
215 u16 vid)
216{
217 struct dsa_mac_addr *a;
218
219 list_for_each_entry(a, addr_list, list)
220 if (ether_addr_equal(a->addr, addr) && a->vid == vid)
221 return a;
222
223 return NULL;
224}
225
fac6abd5
VO
226static int dsa_port_do_mdb_add(struct dsa_port *dp,
227 const struct switchdev_obj_port_mdb *mdb)
161ca59d 228{
fac6abd5 229 struct dsa_switch *ds = dp->ds;
161ca59d 230 struct dsa_mac_addr *a;
fac6abd5 231 int port = dp->index;
338a3a47 232 int err = 0;
161ca59d
VO
233
234 /* No need to bother with refcounting for user ports */
235 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
236 return ds->ops->port_mdb_add(ds, port, mdb);
237
338a3a47
VO
238 mutex_lock(&dp->addr_lists_lock);
239
161ca59d
VO
240 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
241 if (a) {
242 refcount_inc(&a->refcount);
338a3a47 243 goto out;
161ca59d
VO
244 }
245
246 a = kzalloc(sizeof(*a), GFP_KERNEL);
338a3a47
VO
247 if (!a) {
248 err = -ENOMEM;
249 goto out;
250 }
161ca59d
VO
251
252 err = ds->ops->port_mdb_add(ds, port, mdb);
253 if (err) {
254 kfree(a);
338a3a47 255 goto out;
161ca59d
VO
256 }
257
258 ether_addr_copy(a->addr, mdb->addr);
259 a->vid = mdb->vid;
260 refcount_set(&a->refcount, 1);
261 list_add_tail(&a->list, &dp->mdbs);
262
338a3a47
VO
263out:
264 mutex_unlock(&dp->addr_lists_lock);
265
266 return err;
161ca59d
VO
267}
268
fac6abd5
VO
269static int dsa_port_do_mdb_del(struct dsa_port *dp,
270 const struct switchdev_obj_port_mdb *mdb)
161ca59d 271{
fac6abd5 272 struct dsa_switch *ds = dp->ds;
161ca59d 273 struct dsa_mac_addr *a;
fac6abd5 274 int port = dp->index;
338a3a47 275 int err = 0;
161ca59d
VO
276
277 /* No need to bother with refcounting for user ports */
278 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
279 return ds->ops->port_mdb_del(ds, port, mdb);
280
338a3a47
VO
281 mutex_lock(&dp->addr_lists_lock);
282
161ca59d 283 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
338a3a47
VO
284 if (!a) {
285 err = -ENOENT;
286 goto out;
287 }
161ca59d
VO
288
289 if (!refcount_dec_and_test(&a->refcount))
338a3a47 290 goto out;
161ca59d
VO
291
292 err = ds->ops->port_mdb_del(ds, port, mdb);
293 if (err) {
232deb3f 294 refcount_set(&a->refcount, 1);
338a3a47 295 goto out;
161ca59d
VO
296 }
297
298 list_del(&a->list);
299 kfree(a);
300
338a3a47
VO
301out:
302 mutex_unlock(&dp->addr_lists_lock);
303
304 return err;
161ca59d
VO
305}
306
fac6abd5
VO
307static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
308 u16 vid)
3f6e32f9 309{
fac6abd5 310 struct dsa_switch *ds = dp->ds;
3f6e32f9 311 struct dsa_mac_addr *a;
fac6abd5 312 int port = dp->index;
338a3a47 313 int err = 0;
3f6e32f9
VO
314
315 /* No need to bother with refcounting for user ports */
316 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
317 return ds->ops->port_fdb_add(ds, port, addr, vid);
318
338a3a47
VO
319 mutex_lock(&dp->addr_lists_lock);
320
3f6e32f9
VO
321 a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
322 if (a) {
323 refcount_inc(&a->refcount);
338a3a47 324 goto out;
3f6e32f9
VO
325 }
326
327 a = kzalloc(sizeof(*a), GFP_KERNEL);
338a3a47
VO
328 if (!a) {
329 err = -ENOMEM;
330 goto out;
331 }
3f6e32f9
VO
332
333 err = ds->ops->port_fdb_add(ds, port, addr, vid);
334 if (err) {
335 kfree(a);
338a3a47 336 goto out;
3f6e32f9
VO
337 }
338
339 ether_addr_copy(a->addr, addr);
340 a->vid = vid;
341 refcount_set(&a->refcount, 1);
342 list_add_tail(&a->list, &dp->fdbs);
343
338a3a47
VO
344out:
345 mutex_unlock(&dp->addr_lists_lock);
346
347 return err;
3f6e32f9
VO
348}
349
fac6abd5
VO
350static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
351 u16 vid)
3f6e32f9 352{
fac6abd5 353 struct dsa_switch *ds = dp->ds;
3f6e32f9 354 struct dsa_mac_addr *a;
fac6abd5 355 int port = dp->index;
338a3a47 356 int err = 0;
3f6e32f9
VO
357
358 /* No need to bother with refcounting for user ports */
359 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
360 return ds->ops->port_fdb_del(ds, port, addr, vid);
361
338a3a47
VO
362 mutex_lock(&dp->addr_lists_lock);
363
3f6e32f9 364 a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
338a3a47
VO
365 if (!a) {
366 err = -ENOENT;
367 goto out;
368 }
3f6e32f9
VO
369
370 if (!refcount_dec_and_test(&a->refcount))
338a3a47 371 goto out;
3f6e32f9
VO
372
373 err = ds->ops->port_fdb_del(ds, port, addr, vid);
374 if (err) {
232deb3f 375 refcount_set(&a->refcount, 1);
338a3a47 376 goto out;
3f6e32f9
VO
377 }
378
379 list_del(&a->list);
380 kfree(a);
381
338a3a47
VO
382out:
383 mutex_unlock(&dp->addr_lists_lock);
384
385 return err;
3f6e32f9
VO
386}
387
e212fa7c
VO
388static int dsa_switch_do_lag_fdb_add(struct dsa_switch *ds, struct dsa_lag *lag,
389 const unsigned char *addr, u16 vid)
390{
391 struct dsa_mac_addr *a;
392 int err = 0;
393
394 mutex_lock(&lag->fdb_lock);
395
396 a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
397 if (a) {
398 refcount_inc(&a->refcount);
399 goto out;
400 }
401
402 a = kzalloc(sizeof(*a), GFP_KERNEL);
403 if (!a) {
404 err = -ENOMEM;
405 goto out;
406 }
407
408 err = ds->ops->lag_fdb_add(ds, *lag, addr, vid);
409 if (err) {
410 kfree(a);
411 goto out;
412 }
413
414 ether_addr_copy(a->addr, addr);
415 a->vid = vid;
416 refcount_set(&a->refcount, 1);
417 list_add_tail(&a->list, &lag->fdbs);
418
419out:
420 mutex_unlock(&lag->fdb_lock);
421
422 return err;
423}
424
425static int dsa_switch_do_lag_fdb_del(struct dsa_switch *ds, struct dsa_lag *lag,
426 const unsigned char *addr, u16 vid)
427{
428 struct dsa_mac_addr *a;
429 int err = 0;
430
431 mutex_lock(&lag->fdb_lock);
432
433 a = dsa_mac_addr_find(&lag->fdbs, addr, vid);
434 if (!a) {
435 err = -ENOENT;
436 goto out;
437 }
438
439 if (!refcount_dec_and_test(&a->refcount))
440 goto out;
441
442 err = ds->ops->lag_fdb_del(ds, *lag, addr, vid);
443 if (err) {
444 refcount_set(&a->refcount, 1);
445 goto out;
446 }
447
448 list_del(&a->list);
449 kfree(a);
450
451out:
452 mutex_unlock(&lag->fdb_lock);
453
454 return err;
455}
456
3dc80afc
VO
457static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
458 struct dsa_notifier_fdb_info *info)
459{
fac6abd5 460 struct dsa_port *dp;
3dc80afc 461 int err = 0;
3dc80afc
VO
462
463 if (!ds->ops->port_fdb_add)
464 return -EOPNOTSUPP;
465
fac6abd5
VO
466 dsa_switch_for_each_port(dp, ds) {
467 if (dsa_port_host_address_match(dp, info->sw_index,
468 info->port)) {
469 err = dsa_port_do_fdb_add(dp, info->addr, info->vid);
3dc80afc
VO
470 if (err)
471 break;
472 }
473 }
474
475 return err;
476}
477
478static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
479 struct dsa_notifier_fdb_info *info)
480{
fac6abd5 481 struct dsa_port *dp;
3f6e32f9 482 int err = 0;
3f6e32f9 483
3dc80afc
VO
484 if (!ds->ops->port_fdb_del)
485 return -EOPNOTSUPP;
486
fac6abd5
VO
487 dsa_switch_for_each_port(dp, ds) {
488 if (dsa_port_host_address_match(dp, info->sw_index,
489 info->port)) {
490 err = dsa_port_do_fdb_del(dp, info->addr, info->vid);
3f6e32f9
VO
491 if (err)
492 break;
493 }
494 }
3dc80afc 495
3f6e32f9 496 return err;
3dc80afc
VO
497}
498
685fb6a4
VD
499static int dsa_switch_fdb_add(struct dsa_switch *ds,
500 struct dsa_notifier_fdb_info *info)
501{
3169241f 502 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 503 struct dsa_port *dp = dsa_to_port(ds, port);
685fb6a4 504
1b6dd556
AS
505 if (!ds->ops->port_fdb_add)
506 return -EOPNOTSUPP;
685fb6a4 507
fac6abd5 508 return dsa_port_do_fdb_add(dp, info->addr, info->vid);
685fb6a4
VD
509}
510
511static int dsa_switch_fdb_del(struct dsa_switch *ds,
512 struct dsa_notifier_fdb_info *info)
513{
3169241f 514 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 515 struct dsa_port *dp = dsa_to_port(ds, port);
685fb6a4
VD
516
517 if (!ds->ops->port_fdb_del)
518 return -EOPNOTSUPP;
519
fac6abd5 520 return dsa_port_do_fdb_del(dp, info->addr, info->vid);
685fb6a4
VD
521}
522
e212fa7c
VO
523static int dsa_switch_lag_fdb_add(struct dsa_switch *ds,
524 struct dsa_notifier_lag_fdb_info *info)
525{
526 struct dsa_port *dp;
527
528 if (!ds->ops->lag_fdb_add)
529 return -EOPNOTSUPP;
530
531 /* Notify switch only if it has a port in this LAG */
532 dsa_switch_for_each_port(dp, ds)
533 if (dsa_port_offloads_lag(dp, info->lag))
534 return dsa_switch_do_lag_fdb_add(ds, info->lag,
535 info->addr, info->vid);
536
537 return 0;
538}
539
540static int dsa_switch_lag_fdb_del(struct dsa_switch *ds,
541 struct dsa_notifier_lag_fdb_info *info)
542{
543 struct dsa_port *dp;
544
545 if (!ds->ops->lag_fdb_del)
546 return -EOPNOTSUPP;
547
548 /* Notify switch only if it has a port in this LAG */
549 dsa_switch_for_each_port(dp, ds)
550 if (dsa_port_offloads_lag(dp, info->lag))
551 return dsa_switch_do_lag_fdb_del(ds, info->lag,
552 info->addr, info->vid);
553
554 return 0;
555}
556
058102a6
TW
557static int dsa_switch_lag_change(struct dsa_switch *ds,
558 struct dsa_notifier_lag_info *info)
559{
560 if (ds->index == info->sw_index && ds->ops->port_lag_change)
561 return ds->ops->port_lag_change(ds, info->port);
562
563 if (ds->index != info->sw_index && ds->ops->crosschip_lag_change)
564 return ds->ops->crosschip_lag_change(ds, info->sw_index,
565 info->port);
566
567 return 0;
568}
569
570static int dsa_switch_lag_join(struct dsa_switch *ds,
571 struct dsa_notifier_lag_info *info)
572{
573 if (ds->index == info->sw_index && ds->ops->port_lag_join)
dedd6a00 574 return ds->ops->port_lag_join(ds, info->port, info->lag,
058102a6
TW
575 info->info);
576
577 if (ds->index != info->sw_index && ds->ops->crosschip_lag_join)
578 return ds->ops->crosschip_lag_join(ds, info->sw_index,
dedd6a00 579 info->port, info->lag,
058102a6
TW
580 info->info);
581
b71d0987 582 return -EOPNOTSUPP;
058102a6
TW
583}
584
585static int dsa_switch_lag_leave(struct dsa_switch *ds,
586 struct dsa_notifier_lag_info *info)
587{
588 if (ds->index == info->sw_index && ds->ops->port_lag_leave)
dedd6a00 589 return ds->ops->port_lag_leave(ds, info->port, info->lag);
058102a6
TW
590
591 if (ds->index != info->sw_index && ds->ops->crosschip_lag_leave)
592 return ds->ops->crosschip_lag_leave(ds, info->sw_index,
dedd6a00 593 info->port, info->lag);
058102a6 594
b71d0987 595 return -EOPNOTSUPP;
058102a6
TW
596}
597
ffb68fc5
VO
598static int dsa_switch_mdb_add(struct dsa_switch *ds,
599 struct dsa_notifier_mdb_info *info)
e6db98db 600{
abd49535 601 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 602 struct dsa_port *dp = dsa_to_port(ds, port);
e6db98db 603
a52b2da7 604 if (!ds->ops->port_mdb_add)
e6db98db
VD
605 return -EOPNOTSUPP;
606
fac6abd5 607 return dsa_port_do_mdb_add(dp, info->mdb);
8ae5bcdc
VD
608}
609
610static int dsa_switch_mdb_del(struct dsa_switch *ds,
611 struct dsa_notifier_mdb_info *info)
612{
161ca59d 613 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 614 struct dsa_port *dp = dsa_to_port(ds, port);
161ca59d 615
8ae5bcdc
VD
616 if (!ds->ops->port_mdb_del)
617 return -EOPNOTSUPP;
618
fac6abd5 619 return dsa_port_do_mdb_del(dp, info->mdb);
8ae5bcdc
VD
620}
621
b8e997c4
VO
622static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
623 struct dsa_notifier_mdb_info *info)
624{
fac6abd5 625 struct dsa_port *dp;
b8e997c4 626 int err = 0;
b8e997c4
VO
627
628 if (!ds->ops->port_mdb_add)
629 return -EOPNOTSUPP;
630
fac6abd5
VO
631 dsa_switch_for_each_port(dp, ds) {
632 if (dsa_port_host_address_match(dp, info->sw_index,
633 info->port)) {
634 err = dsa_port_do_mdb_add(dp, info->mdb);
b8e997c4
VO
635 if (err)
636 break;
637 }
638 }
639
640 return err;
641}
642
643static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
644 struct dsa_notifier_mdb_info *info)
645{
fac6abd5 646 struct dsa_port *dp;
161ca59d 647 int err = 0;
161ca59d 648
b8e997c4
VO
649 if (!ds->ops->port_mdb_del)
650 return -EOPNOTSUPP;
651
fac6abd5
VO
652 dsa_switch_for_each_port(dp, ds) {
653 if (dsa_port_host_address_match(dp, info->sw_index,
654 info->port)) {
655 err = dsa_port_do_mdb_del(dp, info->mdb);
161ca59d
VO
656 if (err)
657 break;
658 }
659 }
b8e997c4 660
161ca59d 661 return err;
b8e997c4
VO
662}
663
134ef238 664/* Port VLANs match on the targeted port and on all DSA ports */
fac6abd5
VO
665static bool dsa_port_vlan_match(struct dsa_port *dp,
666 struct dsa_notifier_vlan_info *info)
e65d45cc 667{
fac6abd5 668 if (dp->ds->index == info->sw_index && dp->index == info->port)
e65d45cc
VD
669 return true;
670
fac6abd5 671 if (dsa_port_is_dsa(dp))
e65d45cc
VD
672 return true;
673
674 return false;
675}
676
134ef238
VO
677/* Host VLANs match on the targeted port's CPU port, and on all DSA ports
678 * (upstream and downstream) of that switch and its upstream switches.
679 */
680static bool dsa_port_host_vlan_match(struct dsa_port *dp,
681 struct dsa_notifier_vlan_info *info)
682{
683 struct dsa_port *targeted_dp, *cpu_dp;
684 struct dsa_switch *targeted_ds;
685
686 targeted_ds = dsa_switch_find(dp->ds->dst->index, info->sw_index);
687 targeted_dp = dsa_to_port(targeted_ds, info->port);
688 cpu_dp = targeted_dp->cpu_dp;
689
690 if (dsa_switch_is_upstream_of(dp->ds, targeted_ds))
691 return dsa_port_is_dsa(dp) || dp == cpu_dp;
692
693 return false;
694}
695
696static struct dsa_vlan *dsa_vlan_find(struct list_head *vlan_list,
697 const struct switchdev_obj_port_vlan *vlan)
698{
699 struct dsa_vlan *v;
700
701 list_for_each_entry(v, vlan_list, list)
702 if (v->vid == vlan->vid)
703 return v;
704
705 return NULL;
706}
707
708static int dsa_port_do_vlan_add(struct dsa_port *dp,
709 const struct switchdev_obj_port_vlan *vlan,
710 struct netlink_ext_ack *extack)
711{
712 struct dsa_switch *ds = dp->ds;
713 int port = dp->index;
714 struct dsa_vlan *v;
715 int err = 0;
716
717 /* No need to bother with refcounting for user ports. */
718 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
719 return ds->ops->port_vlan_add(ds, port, vlan, extack);
720
721 /* No need to propagate on shared ports the existing VLANs that were
722 * re-notified after just the flags have changed. This would cause a
723 * refcount bump which we need to avoid, since it unbalances the
724 * additions with the deletions.
725 */
726 if (vlan->changed)
727 return 0;
728
729 mutex_lock(&dp->vlans_lock);
730
731 v = dsa_vlan_find(&dp->vlans, vlan);
732 if (v) {
733 refcount_inc(&v->refcount);
734 goto out;
735 }
736
737 v = kzalloc(sizeof(*v), GFP_KERNEL);
738 if (!v) {
739 err = -ENOMEM;
740 goto out;
741 }
742
743 err = ds->ops->port_vlan_add(ds, port, vlan, extack);
744 if (err) {
745 kfree(v);
746 goto out;
747 }
748
749 v->vid = vlan->vid;
750 refcount_set(&v->refcount, 1);
751 list_add_tail(&v->list, &dp->vlans);
752
753out:
754 mutex_unlock(&dp->vlans_lock);
755
756 return err;
757}
758
759static int dsa_port_do_vlan_del(struct dsa_port *dp,
760 const struct switchdev_obj_port_vlan *vlan)
761{
762 struct dsa_switch *ds = dp->ds;
763 int port = dp->index;
764 struct dsa_vlan *v;
765 int err = 0;
766
767 /* No need to bother with refcounting for user ports */
768 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
769 return ds->ops->port_vlan_del(ds, port, vlan);
770
771 mutex_lock(&dp->vlans_lock);
772
773 v = dsa_vlan_find(&dp->vlans, vlan);
774 if (!v) {
775 err = -ENOENT;
776 goto out;
777 }
778
779 if (!refcount_dec_and_test(&v->refcount))
780 goto out;
781
782 err = ds->ops->port_vlan_del(ds, port, vlan);
783 if (err) {
784 refcount_set(&v->refcount, 1);
785 goto out;
786 }
787
788 list_del(&v->list);
789 kfree(v);
790
791out:
792 mutex_unlock(&dp->vlans_lock);
793
794 return err;
795}
796
ffb68fc5
VO
797static int dsa_switch_vlan_add(struct dsa_switch *ds,
798 struct dsa_notifier_vlan_info *info)
9c428c59 799{
fac6abd5
VO
800 struct dsa_port *dp;
801 int err;
9c428c59 802
1958d581 803 if (!ds->ops->port_vlan_add)
9c428c59
VD
804 return -EOPNOTSUPP;
805
fac6abd5
VO
806 dsa_switch_for_each_port(dp, ds) {
807 if (dsa_port_vlan_match(dp, info)) {
134ef238
VO
808 err = dsa_port_do_vlan_add(dp, info->vlan,
809 info->extack);
e65d45cc
VD
810 if (err)
811 return err;
812 }
9c428c59
VD
813 }
814
d0c627b8
VD
815 return 0;
816}
817
818static int dsa_switch_vlan_del(struct dsa_switch *ds,
819 struct dsa_notifier_vlan_info *info)
820{
134ef238
VO
821 struct dsa_port *dp;
822 int err;
823
d0c627b8
VD
824 if (!ds->ops->port_vlan_del)
825 return -EOPNOTSUPP;
826
134ef238
VO
827 dsa_switch_for_each_port(dp, ds) {
828 if (dsa_port_vlan_match(dp, info)) {
829 err = dsa_port_do_vlan_del(dp, info->vlan);
830 if (err)
831 return err;
832 }
833 }
834
835 return 0;
836}
837
838static int dsa_switch_host_vlan_add(struct dsa_switch *ds,
839 struct dsa_notifier_vlan_info *info)
840{
841 struct dsa_port *dp;
842 int err;
843
844 if (!ds->ops->port_vlan_add)
845 return -EOPNOTSUPP;
846
847 dsa_switch_for_each_port(dp, ds) {
848 if (dsa_port_host_vlan_match(dp, info)) {
849 err = dsa_port_do_vlan_add(dp, info->vlan,
850 info->extack);
851 if (err)
852 return err;
853 }
854 }
855
856 return 0;
857}
858
859static int dsa_switch_host_vlan_del(struct dsa_switch *ds,
860 struct dsa_notifier_vlan_info *info)
861{
862 struct dsa_port *dp;
863 int err;
864
865 if (!ds->ops->port_vlan_del)
866 return -EOPNOTSUPP;
867
868 dsa_switch_for_each_port(dp, ds) {
869 if (dsa_port_host_vlan_match(dp, info)) {
870 err = dsa_port_do_vlan_del(dp, info->vlan);
871 if (err)
872 return err;
873 }
874 }
1ca4aa9c
VD
875
876 return 0;
d0c627b8
VD
877}
878
53da0eba
VO
879static int dsa_switch_change_tag_proto(struct dsa_switch *ds,
880 struct dsa_notifier_tag_proto_info *info)
881{
882 const struct dsa_device_ops *tag_ops = info->tag_ops;
d0004a02
VO
883 struct dsa_port *dp, *cpu_dp;
884 int err;
53da0eba
VO
885
886 if (!ds->ops->change_tag_protocol)
887 return -EOPNOTSUPP;
888
889 ASSERT_RTNL();
890
d0004a02
VO
891 dsa_switch_for_each_cpu_port(cpu_dp, ds) {
892 err = ds->ops->change_tag_protocol(ds, cpu_dp->index,
893 tag_ops->proto);
21e0b508
TW
894 if (err)
895 return err;
896
d0004a02 897 dsa_port_set_tag_protocol(cpu_dp, tag_ops);
53da0eba
VO
898 }
899
900 /* Now that changing the tag protocol can no longer fail, let's update
901 * the remaining bits which are "duplicated for faster access", and the
902 * bits that depend on the tagger, such as the MTU.
903 */
d0004a02
VO
904 dsa_switch_for_each_user_port(dp, ds) {
905 struct net_device *slave = dp->slave;
53da0eba 906
d0004a02 907 dsa_slave_setup_tagger(slave);
53da0eba 908
d0004a02
VO
909 /* rtnl_mutex is held in dsa_tree_change_tag_proto */
910 dsa_slave_change_mtu(slave, slave->mtu);
53da0eba
VO
911 }
912
913 return 0;
914}
915
7f297314
VO
916/* We use the same cross-chip notifiers to inform both the tagger side, as well
917 * as the switch side, of connection and disconnection events.
918 * Since ds->tagger_data is owned by the tagger, it isn't a hard error if the
919 * switch side doesn't support connecting to this tagger, and therefore, the
920 * fact that we don't disconnect the tagger side doesn't constitute a memory
921 * leak: the tagger will still operate with persistent per-switch memory, just
922 * with the switch side unconnected to it. What does constitute a hard error is
923 * when the switch side supports connecting but fails.
924 */
925static int
926dsa_switch_connect_tag_proto(struct dsa_switch *ds,
927 struct dsa_notifier_tag_proto_info *info)
dc452a47
VO
928{
929 const struct dsa_device_ops *tag_ops = info->tag_ops;
7f297314
VO
930 int err;
931
932 /* Notify the new tagger about the connection to this switch */
933 if (tag_ops->connect) {
934 err = tag_ops->connect(ds);
935 if (err)
936 return err;
937 }
dc452a47
VO
938
939 if (!ds->ops->connect_tag_protocol)
940 return -EOPNOTSUPP;
941
7f297314
VO
942 /* Notify the switch about the connection to the new tagger */
943 err = ds->ops->connect_tag_protocol(ds, tag_ops->proto);
944 if (err) {
945 /* Revert the new tagger's connection to this tree */
946 if (tag_ops->disconnect)
947 tag_ops->disconnect(ds);
948 return err;
949 }
950
951 return 0;
952}
953
954static int
955dsa_switch_disconnect_tag_proto(struct dsa_switch *ds,
956 struct dsa_notifier_tag_proto_info *info)
957{
958 const struct dsa_device_ops *tag_ops = info->tag_ops;
959
960 /* Notify the tagger about the disconnection from this switch */
961 if (tag_ops->disconnect && ds->tagger_data)
962 tag_ops->disconnect(ds);
963
964 /* No need to notify the switch, since it shouldn't have any
965 * resources to tear down
966 */
967 return 0;
dc452a47
VO
968}
969
295ab96f
VO
970static int
971dsa_switch_master_state_change(struct dsa_switch *ds,
972 struct dsa_notifier_master_state_info *info)
973{
974 if (!ds->ops->master_state_change)
975 return 0;
976
977 ds->ops->master_state_change(ds, info->master, info->operational);
978
979 return 0;
980}
981
f515f192
VD
982static int dsa_switch_event(struct notifier_block *nb,
983 unsigned long event, void *info)
984{
985 struct dsa_switch *ds = container_of(nb, struct dsa_switch, nb);
986 int err;
987
988 switch (event) {
1faabf74
VD
989 case DSA_NOTIFIER_AGEING_TIME:
990 err = dsa_switch_ageing_time(ds, info);
991 break;
04d3a4c6
VD
992 case DSA_NOTIFIER_BRIDGE_JOIN:
993 err = dsa_switch_bridge_join(ds, info);
994 break;
995 case DSA_NOTIFIER_BRIDGE_LEAVE:
996 err = dsa_switch_bridge_leave(ds, info);
997 break;
685fb6a4
VD
998 case DSA_NOTIFIER_FDB_ADD:
999 err = dsa_switch_fdb_add(ds, info);
1000 break;
1001 case DSA_NOTIFIER_FDB_DEL:
1002 err = dsa_switch_fdb_del(ds, info);
1003 break;
3dc80afc
VO
1004 case DSA_NOTIFIER_HOST_FDB_ADD:
1005 err = dsa_switch_host_fdb_add(ds, info);
1006 break;
1007 case DSA_NOTIFIER_HOST_FDB_DEL:
1008 err = dsa_switch_host_fdb_del(ds, info);
1009 break;
e212fa7c
VO
1010 case DSA_NOTIFIER_LAG_FDB_ADD:
1011 err = dsa_switch_lag_fdb_add(ds, info);
1012 break;
1013 case DSA_NOTIFIER_LAG_FDB_DEL:
1014 err = dsa_switch_lag_fdb_del(ds, info);
1015 break;
058102a6
TW
1016 case DSA_NOTIFIER_LAG_CHANGE:
1017 err = dsa_switch_lag_change(ds, info);
1018 break;
1019 case DSA_NOTIFIER_LAG_JOIN:
1020 err = dsa_switch_lag_join(ds, info);
1021 break;
1022 case DSA_NOTIFIER_LAG_LEAVE:
1023 err = dsa_switch_lag_leave(ds, info);
1024 break;
8ae5bcdc
VD
1025 case DSA_NOTIFIER_MDB_ADD:
1026 err = dsa_switch_mdb_add(ds, info);
1027 break;
1028 case DSA_NOTIFIER_MDB_DEL:
1029 err = dsa_switch_mdb_del(ds, info);
1030 break;
b8e997c4
VO
1031 case DSA_NOTIFIER_HOST_MDB_ADD:
1032 err = dsa_switch_host_mdb_add(ds, info);
1033 break;
1034 case DSA_NOTIFIER_HOST_MDB_DEL:
1035 err = dsa_switch_host_mdb_del(ds, info);
1036 break;
d0c627b8
VD
1037 case DSA_NOTIFIER_VLAN_ADD:
1038 err = dsa_switch_vlan_add(ds, info);
1039 break;
1040 case DSA_NOTIFIER_VLAN_DEL:
1041 err = dsa_switch_vlan_del(ds, info);
1042 break;
134ef238
VO
1043 case DSA_NOTIFIER_HOST_VLAN_ADD:
1044 err = dsa_switch_host_vlan_add(ds, info);
1045 break;
1046 case DSA_NOTIFIER_HOST_VLAN_DEL:
1047 err = dsa_switch_host_vlan_del(ds, info);
1048 break;
bfcb8132
VO
1049 case DSA_NOTIFIER_MTU:
1050 err = dsa_switch_mtu(ds, info);
1051 break;
53da0eba
VO
1052 case DSA_NOTIFIER_TAG_PROTO:
1053 err = dsa_switch_change_tag_proto(ds, info);
1054 break;
dc452a47
VO
1055 case DSA_NOTIFIER_TAG_PROTO_CONNECT:
1056 err = dsa_switch_connect_tag_proto(ds, info);
1057 break;
7f297314
VO
1058 case DSA_NOTIFIER_TAG_PROTO_DISCONNECT:
1059 err = dsa_switch_disconnect_tag_proto(ds, info);
1060 break;
c64b9c05
VO
1061 case DSA_NOTIFIER_TAG_8021Q_VLAN_ADD:
1062 err = dsa_switch_tag_8021q_vlan_add(ds, info);
1063 break;
1064 case DSA_NOTIFIER_TAG_8021Q_VLAN_DEL:
1065 err = dsa_switch_tag_8021q_vlan_del(ds, info);
1066 break;
295ab96f
VO
1067 case DSA_NOTIFIER_MASTER_STATE_CHANGE:
1068 err = dsa_switch_master_state_change(ds, info);
1069 break;
f515f192
VD
1070 default:
1071 err = -EOPNOTSUPP;
1072 break;
1073 }
1074
f515f192
VD
1075 if (err)
1076 dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n",
1077 event, err);
1078
1079 return notifier_from_errno(err);
1080}
1081
1082int dsa_switch_register_notifier(struct dsa_switch *ds)
1083{
1084 ds->nb.notifier_call = dsa_switch_event;
1085
1086 return raw_notifier_chain_register(&ds->dst->nh, &ds->nb);
1087}
1088
1089void dsa_switch_unregister_notifier(struct dsa_switch *ds)
1090{
1091 int err;
1092
1093 err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb);
1094 if (err)
1095 dev_err(ds->dev, "failed to unregister notifier (%d)\n", err);
1096}