summaryrefslogtreecommitdiff
path: root/net/dsa/switch.c
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2022-11-22 20:41:57 -0800
committerJakub Kicinski <kuba@kernel.org>2022-11-22 20:41:59 -0800
commit8263ee81f659ff773e5ee0a6f2adb9c6b5b4b0cc (patch)
treed86eeff9ffd9ca54719cb6d983db3270265f0004 /net/dsa/switch.c
parent815bc3ac75e9e34727f8ca78380266f34a3b6c66 (diff)
parent5917bfe688672a6afc816ad472a274eb16c9bb7a (diff)
Merge branch 'remove-dsa_priv-h'
Vladimir Oltean says: ==================== Remove dsa_priv.h After working on the "Autoload DSA tagging driver when dynamically changing protocol" series: https://patchwork.kernel.org/project/netdevbpf/cover/20221115011847.2843127-1-vladimir.oltean@nxp.com/ it became clear to me that the situation with DSA headers is a bit messy, and I put the tagging protocol driver macros in a pretty random temporary spot in dsa_priv.h. Now is the time to make the net/dsa/ folder a bit more organized, and to make tagging protocol driver modules include just headers they're going to use. Another thing is the merging and cleanup of dsa.c and dsa2.c. Before, dsa.c had 589 lines and dsa2.c had 1817 lines. Now, the combined dsa.c has 1749 lines, the rest went to some other places. Sorry for the set size, I know the rules, but since this is basically code movement for the most part, I thought more patches are better. ==================== Link: https://lore.kernel.org/r/20221121135555.1227271-1-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/dsa/switch.c')
-rw-r--r--net/dsa/switch.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/net/dsa/switch.c b/net/dsa/switch.c
index ce56acdba2031..d5bc4bb7310dc 100644
--- a/net/dsa/switch.c
+++ b/net/dsa/switch.c
@@ -12,7 +12,12 @@
#include <linux/if_vlan.h>
#include <net/switchdev.h>
-#include "dsa_priv.h"
+#include "dsa.h"
+#include "netlink.h"
+#include "port.h"
+#include "slave.h"
+#include "switch.h"
+#include "tag_8021q.h"
static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds,
unsigned int ageing_time)
@@ -1013,6 +1018,52 @@ static int dsa_switch_event(struct notifier_block *nb,
return notifier_from_errno(err);
}
+/**
+ * dsa_tree_notify - Execute code for all switches in a DSA switch tree.
+ * @dst: collection of struct dsa_switch devices to notify.
+ * @e: event, must be of type DSA_NOTIFIER_*
+ * @v: event-specific value.
+ *
+ * Given a struct dsa_switch_tree, this can be used to run a function once for
+ * each member DSA switch. The other alternative of traversing the tree is only
+ * through its ports list, which does not uniquely list the switches.
+ */
+int dsa_tree_notify(struct dsa_switch_tree *dst, unsigned long e, void *v)
+{
+ struct raw_notifier_head *nh = &dst->nh;
+ int err;
+
+ err = raw_notifier_call_chain(nh, e, v);
+
+ return notifier_to_errno(err);
+}
+
+/**
+ * dsa_broadcast - Notify all DSA trees in the system.
+ * @e: event, must be of type DSA_NOTIFIER_*
+ * @v: event-specific value.
+ *
+ * Can be used to notify the switching fabric of events such as cross-chip
+ * bridging between disjoint trees (such as islands of tagger-compatible
+ * switches bridged by an incompatible middle switch).
+ *
+ * WARNING: this function is not reliable during probe time, because probing
+ * between trees is asynchronous and not all DSA trees might have probed.
+ */
+int dsa_broadcast(unsigned long e, void *v)
+{
+ struct dsa_switch_tree *dst;
+ int err = 0;
+
+ list_for_each_entry(dst, &dsa_tree_list, list) {
+ err = dsa_tree_notify(dst, e, v);
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
int dsa_switch_register_notifier(struct dsa_switch *ds)
{
ds->nb.notifier_call = dsa_switch_event;