Thread (35 messages) flat view 35 messages, 3 authors, 2016-06-06
STALE3722d

[PATCH net-next 2/9] net: dsa: Add support for parsing the old binding

From: Florian Fainelli <f.fainelli@gmail.com>
Date: 2016-06-04 00:05:50
Subsystem: networking [dsa], networking [general], the rest · Maintainers: Andrew Lunn, Vladimir Oltean, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

Extend dsa2.c to support parsing for the old binding, which mostly means
looking for more or less the same properties in different places.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 net/dsa/dsa2.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 126 insertions(+), 16 deletions(-)
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index b5640d8ffbae..23273fd984a8 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -408,21 +408,11 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
 	dst->applied = false;
 }
 
-static int dsa_cpu_parse(struct device_node *port, u32 index,
-			 struct dsa_switch_tree *dst,
-			 struct dsa_switch *ds)
+static int _dsa_cpu_parse(struct dsa_switch_tree *dst,
+			   struct dsa_switch *ds,
+			   struct net_device *ethernet_dev,
+			   u32 index)
 {
-	struct net_device *ethernet_dev;
-	struct device_node *ethernet;
-
-	ethernet = of_parse_phandle(port, "ethernet", 0);
-	if (!ethernet)
-		return -EINVAL;
-
-	ethernet_dev = of_find_net_device_by_node(ethernet);
-	if (!ethernet_dev)
-		return -EPROBE_DEFER;
-
 	if (!ds->master_netdev)
 		ds->master_netdev = ethernet_dev;
 
@@ -445,6 +435,24 @@ static int dsa_cpu_parse(struct device_node *port, u32 index,
 	return 0;
 }
 
+static int dsa_cpu_parse(struct device_node *port, u32 index,
+			 struct dsa_switch_tree *dst,
+			 struct dsa_switch *ds)
+{
+	struct net_device *ethernet_dev;
+	struct device_node *ethernet;
+
+	ethernet = of_parse_phandle(port, "ethernet", 0);
+	if (!ethernet)
+		return -EINVAL;
+
+	ethernet_dev = of_find_net_device_by_node(ethernet);
+	if (!ethernet_dev)
+		return -EPROBE_DEFER;
+
+	return _dsa_cpu_parse(dst, ds, ethernet_dev, index);
+}
+
 static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
 {
 	struct device_node *port;
@@ -552,6 +560,108 @@ static struct device_node *dsa_get_ports(struct dsa_switch *ds,
 	return ports;
 }
 
+static int _dsa_register_switch_legacy(struct dsa_switch *ds, struct device_node *np)
+{
+	const char *compat = of_get_property(np, "compatible", NULL);
+	struct device_node *dn, *ethernet;
+	struct net_device *ethernet_dev;
+	struct dsa_switch_tree *dst;
+	u32 tree = 0, index;
+	int err;
+
+	/* Tree is implied by how many devices are present in the DT with the
+	 * supported compatible strings from net/dsa/dsa.c
+	 */
+	for_each_compatible_node(dn, NULL, compat) {
+		if (dn != np)
+			tree++;
+	}
+
+	/* index is present in the "reg" property, second cell */
+	err = of_property_read_u32_index(np->child, "reg", 1, &index);
+	if (err)
+		return err;
+
+	if (index >= DSA_MAX_SWITCHES)
+		return -EINVAL;
+
+	err = dsa_parse_ports_dn(np->child, ds);
+	if (err)
+		return err;
+
+	dst = dsa_get_dst(tree);
+	if (!dst) {
+		dst = dsa_add_dst(tree);
+		if (!dst)
+			return -ENOMEM;
+	}
+
+	if (dst->ds[index]) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	ds->dst = dst;
+	ds->index = index;
+	dsa_dst_add_ds(dst, ds, index);
+
+	err = dsa_dst_complete(dst);
+	if (err < 0)
+		goto out;
+
+	if (err == 1) {
+		/* Not all switches registered yet */
+		err = 0;
+		goto out;
+	}
+
+	if (dst->applied) {
+		pr_info("DSA: Disjoint trees?\n");
+		err = -EINVAL;
+		goto out_del_dst;
+	}
+
+	ethernet = of_parse_phandle(np, "dsa,ethernet", 0);
+	if (!ethernet) {
+		err = -EINVAL;
+		goto out_del_dst;
+	}
+
+	ethernet_dev = of_find_net_device_by_node(ethernet);
+	if (!ethernet_dev) {
+		err = -EPROBE_DEFER;
+		goto out_del_dst;
+	}
+
+	err = _dsa_cpu_parse(dst, ds, ethernet_dev, index);
+	if (err)
+		goto out_del_dst;
+
+	if (!dst->master_netdev) {
+		pr_warn("Tree has no master device\n");
+		goto out_del_dst;
+	}
+
+	pr_info("DSA: tree %d parsed\n", dst->tree);
+
+	err = dsa_dst_apply(dst);
+	if (err) {
+		dsa_dst_unapply(dst);
+		goto out_del_dst;
+	}
+
+	dsa_put_dst(dst);
+
+	return 0;
+
+out_del_dst:
+	dsa_dst_del_ds(dst, ds, ds->index);
+out:
+	dsa_put_dst(dst);
+
+	return err;
+}
+
 static int __dsa_register_switch(struct dsa_switch *ds, struct device_node *np)
 {
 	struct device_node *ports = dsa_get_ports(ds, np);
@@ -626,8 +736,8 @@ static int _dsa_register_switch(struct dsa_switch *ds, struct device_node *np)
 {
 	struct device_node *ports = dsa_get_ports(ds, np);
 
-	if (IS_ERR(ports))
-		return PTR_ERR(ports);
+	if (IS_ERR(ports) && PTR_ERR(ports) == -EINVAL)
+		return _dsa_register_switch_legacy(ds, np);
 
 	return __dsa_register_switch(ds, np);
 }
-- 
2.7.4
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help