diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-02-03 13:20:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-02-06 16:53:29 -0500 |
commit | f515f192ab4f45bb695146b82432d63d98775787 (patch) | |
tree | 5a6fddcbb34e28e6850e63d3023504b46e5ea9c3 /net/dsa/switch.c | |
parent | c5d35cb32cffa6e4c2db1cbd9a544e10a8d6fda9 (diff) |
net: dsa: add switch notifier
Add a notifier block per DSA switch, registered against a notifier head
in the switch fabric they belong to.
This infrastructure will allow to propagate fabric-wide events such as
port bridging, VLAN configuration, etc. If a DSA switch driver cares
about cross-chip configuration, such events can be caught.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dsa/switch.c')
-rw-r--r-- | net/dsa/switch.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/net/dsa/switch.c b/net/dsa/switch.c new file mode 100644 index 000000000000..e22fa7633d03 --- /dev/null +++ b/net/dsa/switch.c | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Handling of a single switch chip, part of a switch fabric | ||
3 | * | ||
4 | * Copyright (c) 2017 Vivien Didelot <vivien.didelot@savoirfairelinux.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/netdevice.h> | ||
13 | #include <linux/notifier.h> | ||
14 | #include <net/dsa.h> | ||
15 | |||
16 | static int dsa_switch_event(struct notifier_block *nb, | ||
17 | unsigned long event, void *info) | ||
18 | { | ||
19 | struct dsa_switch *ds = container_of(nb, struct dsa_switch, nb); | ||
20 | int err; | ||
21 | |||
22 | switch (event) { | ||
23 | default: | ||
24 | err = -EOPNOTSUPP; | ||
25 | break; | ||
26 | } | ||
27 | |||
28 | /* Non-switchdev operations cannot be rolled back. If a DSA driver | ||
29 | * returns an error during the chained call, switch chips may be in an | ||
30 | * inconsistent state. | ||
31 | */ | ||
32 | if (err) | ||
33 | dev_dbg(ds->dev, "breaking chain for DSA event %lu (%d)\n", | ||
34 | event, err); | ||
35 | |||
36 | return notifier_from_errno(err); | ||
37 | } | ||
38 | |||
39 | int dsa_switch_register_notifier(struct dsa_switch *ds) | ||
40 | { | ||
41 | ds->nb.notifier_call = dsa_switch_event; | ||
42 | |||
43 | return raw_notifier_chain_register(&ds->dst->nh, &ds->nb); | ||
44 | } | ||
45 | |||
46 | void dsa_switch_unregister_notifier(struct dsa_switch *ds) | ||
47 | { | ||
48 | int err; | ||
49 | |||
50 | err = raw_notifier_chain_unregister(&ds->dst->nh, &ds->nb); | ||
51 | if (err) | ||
52 | dev_err(ds->dev, "failed to unregister notifier (%d)\n", err); | ||
53 | } | ||