Revert "Merge branch 'dsa-rtnl'"
[linux-2.6-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
e19cc13c
VO
98 err = ds->ops->port_bridge_join(ds, info->port, info->br);
99 if (err)
100 return err;
101 }
04d3a4c6 102
f66a6a69 103 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
e19cc13c
VO
104 ds->ops->crosschip_bridge_join) {
105 err = ds->ops->crosschip_bridge_join(ds, info->tree_index,
106 info->sw_index,
107 info->port, info->br);
108 if (err)
109 return err;
110 }
04d3a4c6 111
e19cc13c 112 return dsa_tag_8021q_bridge_join(ds, info);
04d3a4c6
VD
113}
114
115static int dsa_switch_bridge_leave(struct dsa_switch *ds,
116 struct dsa_notifier_bridge_info *info)
117{
f66a6a69 118 struct dsa_switch_tree *dst = ds->dst;
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
f66a6a69 125 if (dst->index == info->tree_index && ds->index == info->sw_index &&
bcb9928a 126 ds->ops->port_bridge_leave)
04d3a4c6
VD
127 ds->ops->port_bridge_leave(ds, info->port, info->br);
128
f66a6a69 129 if ((dst->index != info->tree_index || ds->index != info->sw_index) &&
bcb9928a 130 ds->ops->crosschip_bridge_leave)
f66a6a69
VO
131 ds->ops->crosschip_bridge_leave(ds, info->tree_index,
132 info->sw_index, info->port,
40ef2c93 133 info->br);
04d3a4c6 134
58adf9dc
VO
135 if (ds->needs_standalone_vlan_filtering && !br_vlan_enabled(info->br)) {
136 change_vlan_filtering = true;
137 vlan_filtering = true;
138 } else if (!ds->needs_standalone_vlan_filtering &&
139 br_vlan_enabled(info->br)) {
140 change_vlan_filtering = true;
141 vlan_filtering = false;
142 }
143
d371b7c9
VO
144 /* If the bridge was vlan_filtering, the bridge core doesn't trigger an
145 * event for changing vlan_filtering setting upon slave ports leaving
146 * it. That is a good thing, because that lets us handle it and also
147 * handle the case where the switch's vlan_filtering setting is global
148 * (not per port). When that happens, the correct moment to trigger the
479dc497
VO
149 * vlan_filtering callback is only when the last port leaves the last
150 * VLAN-aware bridge.
d371b7c9 151 */
58adf9dc 152 if (change_vlan_filtering && ds->vlan_filtering_is_global) {
d0004a02 153 dsa_switch_for_each_port(dp, ds) {
479dc497
VO
154 struct net_device *bridge_dev;
155
d0004a02 156 bridge_dev = dp->bridge_dev;
479dc497
VO
157
158 if (bridge_dev && br_vlan_enabled(bridge_dev)) {
58adf9dc 159 change_vlan_filtering = false;
d371b7c9
VO
160 break;
161 }
162 }
163 }
58adf9dc
VO
164
165 if (change_vlan_filtering) {
68bb8ea8 166 err = dsa_port_vlan_filtering(dsa_to_port(ds, info->port),
58adf9dc 167 vlan_filtering, &extack);
89153ed6
VO
168 if (extack._msg)
169 dev_err(ds->dev, "port %d: %s\n", info->port,
170 extack._msg);
43a4b4db 171 if (err && err != -EOPNOTSUPP)
d371b7c9
VO
172 return err;
173 }
e19cc13c
VO
174
175 return dsa_tag_8021q_bridge_leave(ds, info);
04d3a4c6
VD
176}
177
b8e997c4
VO
178/* Matches for all upstream-facing ports (the CPU port and all upstream-facing
179 * DSA links) that sit between the targeted port on which the notifier was
180 * emitted and its dedicated CPU port.
181 */
fac6abd5
VO
182static bool dsa_port_host_address_match(struct dsa_port *dp,
183 int info_sw_index, int info_port)
b8e997c4
VO
184{
185 struct dsa_port *targeted_dp, *cpu_dp;
186 struct dsa_switch *targeted_ds;
187
fac6abd5 188 targeted_ds = dsa_switch_find(dp->ds->dst->index, info_sw_index);
b8e997c4
VO
189 targeted_dp = dsa_to_port(targeted_ds, info_port);
190 cpu_dp = targeted_dp->cpu_dp;
191
fac6abd5
VO
192 if (dsa_switch_is_upstream_of(dp->ds, targeted_ds))
193 return dp->index == dsa_towards_port(dp->ds, cpu_dp->ds->index,
194 cpu_dp->index);
b8e997c4
VO
195
196 return false;
197}
198
161ca59d
VO
199static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
200 const unsigned char *addr,
201 u16 vid)
202{
203 struct dsa_mac_addr *a;
204
205 list_for_each_entry(a, addr_list, list)
206 if (ether_addr_equal(a->addr, addr) && a->vid == vid)
207 return a;
208
209 return NULL;
210}
211
fac6abd5
VO
212static int dsa_port_do_mdb_add(struct dsa_port *dp,
213 const struct switchdev_obj_port_mdb *mdb)
161ca59d 214{
fac6abd5 215 struct dsa_switch *ds = dp->ds;
161ca59d 216 struct dsa_mac_addr *a;
fac6abd5 217 int port = dp->index;
2d7e73f0 218 int err;
161ca59d
VO
219
220 /* No need to bother with refcounting for user ports */
221 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
222 return ds->ops->port_mdb_add(ds, port, mdb);
223
224 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
225 if (a) {
226 refcount_inc(&a->refcount);
2d7e73f0 227 return 0;
161ca59d
VO
228 }
229
230 a = kzalloc(sizeof(*a), GFP_KERNEL);
2d7e73f0
DM
231 if (!a)
232 return -ENOMEM;
161ca59d
VO
233
234 err = ds->ops->port_mdb_add(ds, port, mdb);
235 if (err) {
236 kfree(a);
2d7e73f0 237 return err;
161ca59d
VO
238 }
239
240 ether_addr_copy(a->addr, mdb->addr);
241 a->vid = mdb->vid;
242 refcount_set(&a->refcount, 1);
243 list_add_tail(&a->list, &dp->mdbs);
244
2d7e73f0 245 return 0;
161ca59d
VO
246}
247
fac6abd5
VO
248static int dsa_port_do_mdb_del(struct dsa_port *dp,
249 const struct switchdev_obj_port_mdb *mdb)
161ca59d 250{
fac6abd5 251 struct dsa_switch *ds = dp->ds;
161ca59d 252 struct dsa_mac_addr *a;
fac6abd5 253 int port = dp->index;
2d7e73f0 254 int err;
161ca59d
VO
255
256 /* No need to bother with refcounting for user ports */
257 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
258 return ds->ops->port_mdb_del(ds, port, mdb);
259
260 a = dsa_mac_addr_find(&dp->mdbs, mdb->addr, mdb->vid);
2d7e73f0
DM
261 if (!a)
262 return -ENOENT;
161ca59d
VO
263
264 if (!refcount_dec_and_test(&a->refcount))
2d7e73f0 265 return 0;
161ca59d
VO
266
267 err = ds->ops->port_mdb_del(ds, port, mdb);
268 if (err) {
269 refcount_inc(&a->refcount);
2d7e73f0 270 return err;
161ca59d
VO
271 }
272
273 list_del(&a->list);
274 kfree(a);
275
2d7e73f0 276 return 0;
161ca59d
VO
277}
278
fac6abd5
VO
279static int dsa_port_do_fdb_add(struct dsa_port *dp, const unsigned char *addr,
280 u16 vid)
3f6e32f9 281{
fac6abd5 282 struct dsa_switch *ds = dp->ds;
3f6e32f9 283 struct dsa_mac_addr *a;
fac6abd5 284 int port = dp->index;
2d7e73f0 285 int err;
3f6e32f9
VO
286
287 /* No need to bother with refcounting for user ports */
288 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
289 return ds->ops->port_fdb_add(ds, port, addr, vid);
290
291 a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
292 if (a) {
293 refcount_inc(&a->refcount);
2d7e73f0 294 return 0;
3f6e32f9
VO
295 }
296
297 a = kzalloc(sizeof(*a), GFP_KERNEL);
2d7e73f0
DM
298 if (!a)
299 return -ENOMEM;
3f6e32f9
VO
300
301 err = ds->ops->port_fdb_add(ds, port, addr, vid);
302 if (err) {
303 kfree(a);
2d7e73f0 304 return err;
3f6e32f9
VO
305 }
306
307 ether_addr_copy(a->addr, addr);
308 a->vid = vid;
309 refcount_set(&a->refcount, 1);
310 list_add_tail(&a->list, &dp->fdbs);
311
2d7e73f0 312 return 0;
3f6e32f9
VO
313}
314
fac6abd5
VO
315static int dsa_port_do_fdb_del(struct dsa_port *dp, const unsigned char *addr,
316 u16 vid)
3f6e32f9 317{
fac6abd5 318 struct dsa_switch *ds = dp->ds;
3f6e32f9 319 struct dsa_mac_addr *a;
fac6abd5 320 int port = dp->index;
2d7e73f0 321 int err;
3f6e32f9
VO
322
323 /* No need to bother with refcounting for user ports */
324 if (!(dsa_port_is_cpu(dp) || dsa_port_is_dsa(dp)))
325 return ds->ops->port_fdb_del(ds, port, addr, vid);
326
327 a = dsa_mac_addr_find(&dp->fdbs, addr, vid);
2d7e73f0
DM
328 if (!a)
329 return -ENOENT;
3f6e32f9
VO
330
331 if (!refcount_dec_and_test(&a->refcount))
2d7e73f0 332 return 0;
3f6e32f9
VO
333
334 err = ds->ops->port_fdb_del(ds, port, addr, vid);
335 if (err) {
336 refcount_inc(&a->refcount);
2d7e73f0 337 return err;
3f6e32f9
VO
338 }
339
340 list_del(&a->list);
341 kfree(a);
342
2d7e73f0 343 return 0;
3f6e32f9
VO
344}
345
3dc80afc
VO
346static int dsa_switch_host_fdb_add(struct dsa_switch *ds,
347 struct dsa_notifier_fdb_info *info)
348{
fac6abd5 349 struct dsa_port *dp;
3dc80afc 350 int err = 0;
3dc80afc
VO
351
352 if (!ds->ops->port_fdb_add)
353 return -EOPNOTSUPP;
354
fac6abd5
VO
355 dsa_switch_for_each_port(dp, ds) {
356 if (dsa_port_host_address_match(dp, info->sw_index,
357 info->port)) {
358 err = dsa_port_do_fdb_add(dp, info->addr, info->vid);
3dc80afc
VO
359 if (err)
360 break;
361 }
362 }
363
364 return err;
365}
366
367static int dsa_switch_host_fdb_del(struct dsa_switch *ds,
368 struct dsa_notifier_fdb_info *info)
369{
fac6abd5 370 struct dsa_port *dp;
3f6e32f9 371 int err = 0;
3f6e32f9 372
3dc80afc
VO
373 if (!ds->ops->port_fdb_del)
374 return -EOPNOTSUPP;
375
fac6abd5
VO
376 dsa_switch_for_each_port(dp, ds) {
377 if (dsa_port_host_address_match(dp, info->sw_index,
378 info->port)) {
379 err = dsa_port_do_fdb_del(dp, info->addr, info->vid);
3f6e32f9
VO
380 if (err)
381 break;
382 }
383 }
3dc80afc 384
3f6e32f9 385 return err;
3dc80afc
VO
386}
387
685fb6a4
VD
388static int dsa_switch_fdb_add(struct dsa_switch *ds,
389 struct dsa_notifier_fdb_info *info)
390{
3169241f 391 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 392 struct dsa_port *dp = dsa_to_port(ds, port);
685fb6a4 393
1b6dd556
AS
394 if (!ds->ops->port_fdb_add)
395 return -EOPNOTSUPP;
685fb6a4 396
fac6abd5 397 return dsa_port_do_fdb_add(dp, info->addr, info->vid);
685fb6a4
VD
398}
399
400static int dsa_switch_fdb_del(struct dsa_switch *ds,
401 struct dsa_notifier_fdb_info *info)
402{
3169241f 403 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 404 struct dsa_port *dp = dsa_to_port(ds, port);
685fb6a4
VD
405
406 if (!ds->ops->port_fdb_del)
407 return -EOPNOTSUPP;
408
fac6abd5 409 return dsa_port_do_fdb_del(dp, info->addr, info->vid);
685fb6a4
VD
410}
411
18596f50
GM
412static int dsa_switch_hsr_join(struct dsa_switch *ds,
413 struct dsa_notifier_hsr_info *info)
414{
415 if (ds->index == info->sw_index && ds->ops->port_hsr_join)
416 return ds->ops->port_hsr_join(ds, info->port, info->hsr);
417
418 return -EOPNOTSUPP;
419}
420
421static int dsa_switch_hsr_leave(struct dsa_switch *ds,
422 struct dsa_notifier_hsr_info *info)
423{
424 if (ds->index == info->sw_index && ds->ops->port_hsr_leave)
425 return ds->ops->port_hsr_leave(ds, info->port, info->hsr);
426
427 return -EOPNOTSUPP;
428}
429
058102a6
TW
430static int dsa_switch_lag_change(struct dsa_switch *ds,
431 struct dsa_notifier_lag_info *info)
432{
433 if (ds->index == info->sw_index && ds->ops->port_lag_change)
434 return ds->ops->port_lag_change(ds, info->port);
435
436 if (ds->index != info->sw_index && ds->ops->crosschip_lag_change)
437 return ds->ops->crosschip_lag_change(ds, info->sw_index,
438 info->port);
439
440 return 0;
441}
442
443static int dsa_switch_lag_join(struct dsa_switch *ds,
444 struct dsa_notifier_lag_info *info)
445{
446 if (ds->index == info->sw_index && ds->ops->port_lag_join)
447 return ds->ops->port_lag_join(ds, info->port, info->lag,
448 info->info);
449
450 if (ds->index != info->sw_index && ds->ops->crosschip_lag_join)
451 return ds->ops->crosschip_lag_join(ds, info->sw_index,
452 info->port, info->lag,
453 info->info);
454
b71d0987 455 return -EOPNOTSUPP;
058102a6
TW
456}
457
458static int dsa_switch_lag_leave(struct dsa_switch *ds,
459 struct dsa_notifier_lag_info *info)
460{
461 if (ds->index == info->sw_index && ds->ops->port_lag_leave)
462 return ds->ops->port_lag_leave(ds, info->port, info->lag);
463
464 if (ds->index != info->sw_index && ds->ops->crosschip_lag_leave)
465 return ds->ops->crosschip_lag_leave(ds, info->sw_index,
466 info->port, info->lag);
467
b71d0987 468 return -EOPNOTSUPP;
058102a6
TW
469}
470
ffb68fc5
VO
471static int dsa_switch_mdb_add(struct dsa_switch *ds,
472 struct dsa_notifier_mdb_info *info)
e6db98db 473{
abd49535 474 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 475 struct dsa_port *dp = dsa_to_port(ds, port);
e6db98db 476
a52b2da7 477 if (!ds->ops->port_mdb_add)
e6db98db
VD
478 return -EOPNOTSUPP;
479
fac6abd5 480 return dsa_port_do_mdb_add(dp, info->mdb);
8ae5bcdc
VD
481}
482
483static int dsa_switch_mdb_del(struct dsa_switch *ds,
484 struct dsa_notifier_mdb_info *info)
485{
161ca59d 486 int port = dsa_towards_port(ds, info->sw_index, info->port);
fac6abd5 487 struct dsa_port *dp = dsa_to_port(ds, port);
161ca59d 488
8ae5bcdc
VD
489 if (!ds->ops->port_mdb_del)
490 return -EOPNOTSUPP;
491
fac6abd5 492 return dsa_port_do_mdb_del(dp, info->mdb);
8ae5bcdc
VD
493}
494
b8e997c4
VO
495static int dsa_switch_host_mdb_add(struct dsa_switch *ds,
496 struct dsa_notifier_mdb_info *info)
497{
fac6abd5 498 struct dsa_port *dp;
b8e997c4 499 int err = 0;
b8e997c4
VO
500
501 if (!ds->ops->port_mdb_add)
502 return -EOPNOTSUPP;
503
fac6abd5
VO
504 dsa_switch_for_each_port(dp, ds) {
505 if (dsa_port_host_address_match(dp, info->sw_index,
506 info->port)) {
507 err = dsa_port_do_mdb_add(dp, info->mdb);
b8e997c4
VO
508 if (err)
509 break;
510 }
511 }
512
513 return err;
514}
515
516static int dsa_switch_host_mdb_del(struct dsa_switch *ds,
517 struct dsa_notifier_mdb_info *info)
518{
fac6abd5 519 struct dsa_port *dp;
161ca59d 520 int err = 0;
161ca59d 521
b8e997c4
VO
522 if (!ds->ops->port_mdb_del)
523 return -EOPNOTSUPP;
524
fac6abd5
VO
525 dsa_switch_for_each_port(dp, ds) {
526 if (dsa_port_host_address_match(dp, info->sw_index,
527 info->port)) {
528 err = dsa_port_do_mdb_del(dp, info->mdb);
161ca59d
VO
529 if (err)
530 break;
531 }
532 }
b8e997c4 533
161ca59d 534 return err;
b8e997c4
VO
535}
536
fac6abd5
VO
537static bool dsa_port_vlan_match(struct dsa_port *dp,
538 struct dsa_notifier_vlan_info *info)
e65d45cc 539{
fac6abd5 540 if (dp->ds->index == info->sw_index && dp->index == info->port)
e65d45cc
VD
541 return true;
542
fac6abd5 543 if (dsa_port_is_dsa(dp))
e65d45cc
VD
544 return true;
545
546 return false;
547}
548
ffb68fc5
VO
549static int dsa_switch_vlan_add(struct dsa_switch *ds,
550 struct dsa_notifier_vlan_info *info)
9c428c59 551{
fac6abd5
VO
552 struct dsa_port *dp;
553 int err;
9c428c59 554
1958d581 555 if (!ds->ops->port_vlan_add)
9c428c59
VD
556 return -EOPNOTSUPP;
557
fac6abd5
VO
558 dsa_switch_for_each_port(dp, ds) {
559 if (dsa_port_vlan_match(dp, info)) {
560 err = ds->ops->port_vlan_add(ds, dp->index, info->vlan,
31046a5f 561 info->extack);
e65d45cc
VD
562 if (err)
563 return err;
564 }
9c428c59
VD
565 }
566
d0c627b8
VD
567 return 0;
568}
569
570static int dsa_switch_vlan_del(struct dsa_switch *ds,
571 struct dsa_notifier_vlan_info *info)
572{
d0c627b8
VD
573 if (!ds->ops->port_vlan_del)
574 return -EOPNOTSUPP;
575
1ca4aa9c 576 if (ds->index == info->sw_index)
e65d45cc 577 return ds->ops->port_vlan_del(ds, info->port, info->vlan);
1ca4aa9c 578
7e1741b4
VD
579 /* Do not deprogram the DSA links as they may be used as conduit
580 * for other VLAN members in the fabric.
581 */
1ca4aa9c 582 return 0;
d0c627b8
VD
583}
584
53da0eba
VO
585static int dsa_switch_change_tag_proto(struct dsa_switch *ds,
586 struct dsa_notifier_tag_proto_info *info)
587{
588 const struct dsa_device_ops *tag_ops = info->tag_ops;
d0004a02
VO
589 struct dsa_port *dp, *cpu_dp;
590 int err;
53da0eba
VO
591
592 if (!ds->ops->change_tag_protocol)
593 return -EOPNOTSUPP;
594
595 ASSERT_RTNL();
596
d0004a02
VO
597 dsa_switch_for_each_cpu_port(cpu_dp, ds) {
598 err = ds->ops->change_tag_protocol(ds, cpu_dp->index,
599 tag_ops->proto);
21e0b508
TW
600 if (err)
601 return err;
602
d0004a02 603 dsa_port_set_tag_protocol(cpu_dp, tag_ops);
53da0eba
VO
604 }
605
606 /* Now that changing the tag protocol can no longer fail, let's update
607 * the remaining bits which are "duplicated for faster access", and the
608 * bits that depend on the tagger, such as the MTU.
609 */
d0004a02
VO
610 dsa_switch_for_each_user_port(dp, ds) {
611 struct net_device *slave = dp->slave;
53da0eba 612
d0004a02 613 dsa_slave_setup_tagger(slave);
53da0eba 614
d0004a02
VO
615 /* rtnl_mutex is held in dsa_tree_change_tag_proto */
616 dsa_slave_change_mtu(slave, slave->mtu);
53da0eba
VO
617 }
618
619 return 0;
620}
621
c595c433
HV
622static int dsa_switch_mrp_add(struct dsa_switch *ds,
623 struct dsa_notifier_mrp_info *info)
624{
c595c433
HV
625 if (!ds->ops->port_mrp_add)
626 return -EOPNOTSUPP;
627
f9bcdc36
VO
628 if (ds->index == info->sw_index)
629 return ds->ops->port_mrp_add(ds, info->port, info->mrp);
c595c433 630
f9bcdc36 631 return 0;
c595c433
HV
632}
633
634static int dsa_switch_mrp_del(struct dsa_switch *ds,
635 struct dsa_notifier_mrp_info *info)
636{
637 if (!ds->ops->port_mrp_del)
638 return -EOPNOTSUPP;
639
640 if (ds->index == info->sw_index)
641 return ds->ops->port_mrp_del(ds, info->port, info->mrp);
642
643 return 0;
644}
645
c595c433
HV
646static int
647dsa_switch_mrp_add_ring_role(struct dsa_switch *ds,
648 struct dsa_notifier_mrp_ring_role_info *info)
649{
c595c433
HV
650 if (!ds->ops->port_mrp_add)
651 return -EOPNOTSUPP;
652
f9bcdc36
VO
653 if (ds->index == info->sw_index)
654 return ds->ops->port_mrp_add_ring_role(ds, info->port,
655 info->mrp);
c595c433 656
f9bcdc36 657 return 0;
c595c433
HV
658}
659
660static int
661dsa_switch_mrp_del_ring_role(struct dsa_switch *ds,
662 struct dsa_notifier_mrp_ring_role_info *info)
663{
664 if (!ds->ops->port_mrp_del)
665 return -EOPNOTSUPP;
666
667 if (ds->index == info->sw_index)
668 return ds->ops->port_mrp_del_ring_role(ds, info->port,
669 info->mrp);
670
671 return 0;
672}
673
f515f192
VD
674static int dsa_switch_event(struct notifier_block *nb,
675 unsigned long event, void *info)
676{
677 struct dsa_switch *ds = container_of(nb, struct dsa_switch, nb);
678 int err;
679
680 switch (event) {
1faabf74
VD
681 case DSA_NOTIFIER_AGEING_TIME:
682 err = dsa_switch_ageing_time(ds, info);
683 break;
04d3a4c6
VD
684 case DSA_NOTIFIER_BRIDGE_JOIN:
685 err = dsa_switch_bridge_join(ds, info);
686 break;
687 case DSA_NOTIFIER_BRIDGE_LEAVE:
688 err = dsa_switch_bridge_leave(ds, info);
689 break;
685fb6a4
VD
690 case DSA_NOTIFIER_FDB_ADD:
691 err = dsa_switch_fdb_add(ds, info);
692 break;
693 case DSA_NOTIFIER_FDB_DEL:
694 err = dsa_switch_fdb_del(ds, info);
695 break;
3dc80afc
VO
696 case DSA_NOTIFIER_HOST_FDB_ADD:
697 err = dsa_switch_host_fdb_add(ds, info);
698 break;
699 case DSA_NOTIFIER_HOST_FDB_DEL:
700 err = dsa_switch_host_fdb_del(ds, info);
701 break;
18596f50
GM
702 case DSA_NOTIFIER_HSR_JOIN:
703 err = dsa_switch_hsr_join(ds, info);
704 break;
705 case DSA_NOTIFIER_HSR_LEAVE:
706 err = dsa_switch_hsr_leave(ds, info);
707 break;
058102a6
TW
708 case DSA_NOTIFIER_LAG_CHANGE:
709 err = dsa_switch_lag_change(ds, info);
710 break;
711 case DSA_NOTIFIER_LAG_JOIN:
712 err = dsa_switch_lag_join(ds, info);
713 break;
714 case DSA_NOTIFIER_LAG_LEAVE:
715 err = dsa_switch_lag_leave(ds, info);
716 break;
8ae5bcdc
VD
717 case DSA_NOTIFIER_MDB_ADD:
718 err = dsa_switch_mdb_add(ds, info);
719 break;
720 case DSA_NOTIFIER_MDB_DEL:
721 err = dsa_switch_mdb_del(ds, info);
722 break;
b8e997c4
VO
723 case DSA_NOTIFIER_HOST_MDB_ADD:
724 err = dsa_switch_host_mdb_add(ds, info);
725 break;
726 case DSA_NOTIFIER_HOST_MDB_DEL:
727 err = dsa_switch_host_mdb_del(ds, info);
728 break;
d0c627b8
VD
729 case DSA_NOTIFIER_VLAN_ADD:
730 err = dsa_switch_vlan_add(ds, info);
731 break;
732 case DSA_NOTIFIER_VLAN_DEL:
733 err = dsa_switch_vlan_del(ds, info);
734 break;
bfcb8132
VO
735 case DSA_NOTIFIER_MTU:
736 err = dsa_switch_mtu(ds, info);
737 break;
53da0eba
VO
738 case DSA_NOTIFIER_TAG_PROTO:
739 err = dsa_switch_change_tag_proto(ds, info);
740 break;
c595c433
HV
741 case DSA_NOTIFIER_MRP_ADD:
742 err = dsa_switch_mrp_add(ds, info);
743 break;
744 case DSA_NOTIFIER_MRP_DEL:
745 err = dsa_switch_mrp_del(ds, info);
746 break;
747 case DSA_NOTIFIER_MRP_ADD_RING_ROLE:
748 err = dsa_switch_mrp_add_ring_role(ds, info);
749 break;
750 case DSA_NOTIFIER_MRP_DEL_RING_ROLE:
751 err = dsa_switch_mrp_del_ring_role(ds, info);
752 break;
c64b9c05
VO
753 case DSA_NOTIFIER_TAG_8021Q_VLAN_ADD:
754 err = dsa_switch_tag_8021q_vlan_add(ds, info);
755 break;
756 case DSA_NOTIFIER_TAG_8021Q_VLAN_DEL:
757 err = dsa_switch_tag_8021q_vlan_del(ds, info);
758 break;
f515f192
VD
759 default:
760 err = -EOPNOTSUPP;
761 break;
762 }
763
f515f192
VD
764 if (err)
765 dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n",
766 event, err);
767
768 return notifier_from_errno(err);
769}
770
771int dsa_switch_register_notifier(struct dsa_switch *ds)
772{
773 ds->nb.notifier_call = dsa_switch_event;
774
775 return raw_notifier_chain_register(&ds->dst->nh, &ds->nb);
776}
777
778void dsa_switch_unregister_notifier(struct dsa_switch *ds)
779{
780 int err;
781
782 err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb);
783 if (err)
784 dev_err(ds->dev, "failed to unregister notifier (%d)\n", err);
785}