All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/11] net: dsa: setup stage
@ 2017-11-06 21:11 Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port Vivien Didelot
                   ` (11 more replies)
  0 siblings, 12 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

When probing a DSA switch, there is basically two stages.

The first stage is the parsing of the switch device, from either device
tree or platform data. It fetches the DSA tree to which it belongs, and
validates its ports. The switch device is then added to the tree, and
the second stage is called if this was the last switch of the tree.

The second stage is the setup of the tree, which validates that the tree
is complete, sets up the routing tables, the default CPU port for user
ports, sets up the switch drivers and finally the master interfaces,
which makes the whole switch fabric functional.

This patch series covers the second setup stage. The setup and teardown
of a switch tree have been separated into logical steps, and the probing
of a switch now simply parses and adds a switch to a tree.

Vivien Didelot (11):
  net: dsa: constify cpu_dp member of dsa_port
  net: dsa: setup and teardown default CPU port
  net: dsa: setup and teardown master device
  net: dsa: setup and teardown tree
  net: dsa: setup and teardown switches
  net: dsa: setup and teardown ports
  net: dsa: add find port by node helper
  net: dsa: use of_for_each_phandle
  net: dsa: setup routing table
  net: dsa: setup a tree when adding a switch to it
  net: dsa: rename probe and remove switch functions

 include/net/dsa.h  |   4 +-
 net/dsa/dsa2.c     | 615 +++++++++++++++++++++++------------------------------
 net/dsa/dsa_priv.h |   4 +-
 net/dsa/legacy.c   |  20 +-
 net/dsa/master.c   |  30 ++-
 net/dsa/slave.c    |   2 +-
 6 files changed, 296 insertions(+), 379 deletions(-)

-- 
2.14.3

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-07  1:47   ` Florian Fainelli
  2017-11-06 21:11 ` [PATCH net-next 02/11] net: dsa: setup and teardown default CPU port Vivien Didelot
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

A DSA port has a dedicated CPU port assigned to it, stored in the cpu_dp
member. It is not meant to be modified by a port, thus make it const.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 include/net/dsa.h | 2 +-
 net/dsa/slave.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index e54332968417..2a8613b5a23d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -190,7 +190,7 @@ struct dsa_port {
 	struct dsa_switch	*ds;
 	unsigned int		index;
 	const char		*name;
-	struct dsa_port		*cpu_dp;
+	const struct dsa_port	*cpu_dp;
 	struct device_node	*dn;
 	unsigned int		ageing_time;
 	u8			stp_state;
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 814ced75a0cc..cc7fe47dd4bf 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1147,7 +1147,7 @@ static void dsa_slave_notify(struct net_device *dev, unsigned long val)
 
 int dsa_slave_create(struct dsa_port *port)
 {
-	struct dsa_port *cpu_dp = port->cpu_dp;
+	const struct dsa_port *cpu_dp = port->cpu_dp;
 	struct net_device *master = cpu_dp->master;
 	struct dsa_switch *ds = port->ds;
 	const char *name = port->name;
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 02/11] net: dsa: setup and teardown default CPU port
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 03/11] net: dsa: setup and teardown master device Vivien Didelot
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

The dsa_dst_parse function called just before dsa_dst_apply does not
parse the tree but does only one thing: it assigns the default CPU port
to dst->cpu_dp and to each user ports.

This patch simplifies this by calling a dsa_tree_setup_default_cpu
function at the beginning of dsa_dst_apply directly.

A dsa_port_is_user helper is added for convenience.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 153 +++++++++++++++++++++++++--------------------------------
 1 file changed, 68 insertions(+), 85 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 283104e5ca6a..0a63a2119cd0 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -112,6 +112,11 @@ static bool dsa_port_is_cpu(struct dsa_port *port)
 	return port->type == DSA_PORT_TYPE_CPU;
 }
 
+static bool dsa_port_is_user(struct dsa_port *dp)
+{
+	return dp->type == DSA_PORT_TYPE_USER;
+}
+
 static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
 				struct device_node *port)
 {
@@ -218,6 +223,64 @@ static int dsa_dst_complete(struct dsa_switch_tree *dst)
 	return 0;
 }
 
+static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
+{
+	struct dsa_switch *ds;
+	struct dsa_port *dp;
+	int device, port;
+
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
+		if (!ds)
+			continue;
+
+		for (port = 0; port < ds->num_ports; port++) {
+			dp = &ds->ports[port];
+
+			if (dsa_port_is_cpu(dp))
+				return dp;
+		}
+	}
+
+	return NULL;
+}
+
+static int dsa_tree_setup_default_cpu(struct dsa_switch_tree *dst)
+{
+	struct dsa_switch *ds;
+	struct dsa_port *dp;
+	int device, port;
+
+	/* DSA currently only supports a single CPU port */
+	dst->cpu_dp = dsa_tree_find_first_cpu(dst);
+	if (!dst->cpu_dp) {
+		pr_warn("Tree has no master device\n");
+		return -EINVAL;
+	}
+
+	/* Assign the default CPU port to all ports of the fabric */
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
+		if (!ds)
+			continue;
+
+		for (port = 0; port < ds->num_ports; port++) {
+			dp = &ds->ports[port];
+
+			if (dsa_port_is_user(dp))
+				dp->cpu_dp = dst->cpu_dp;
+		}
+	}
+
+	return 0;
+}
+
+static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
+{
+	/* DSA currently only supports a single CPU port */
+	dst->cpu_dp = NULL;
+}
+
 static int dsa_dsa_port_apply(struct dsa_port *port)
 {
 	struct dsa_switch *ds = port->ds;
@@ -412,6 +475,10 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
 	u32 index;
 	int err;
 
+	err = dsa_tree_setup_default_cpu(dst);
+	if (err)
+		return err;
+
 	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
 		ds = dst->ds[index];
 		if (!ds)
@@ -464,7 +531,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
 		dsa_ds_unapply(dst, ds);
 	}
 
-	dst->cpu_dp = NULL;
+	dsa_tree_teardown_default_cpu(dst);
 
 	pr_info("DSA: tree %d unapplied\n", dst->index);
 	dst->applied = false;
@@ -532,86 +599,6 @@ static int dsa_port_parse_cpu(struct dsa_port *dp, struct net_device *master)
 	return 0;
 }
 
-static int dsa_cpu_parse(struct dsa_port *port, u32 index,
-			 struct dsa_switch_tree *dst,
-			 struct dsa_switch *ds)
-{
-	if (!dst->cpu_dp)
-		dst->cpu_dp = port;
-
-	return 0;
-}
-
-static int dsa_ds_parse(struct dsa_switch_tree *dst, struct dsa_switch *ds)
-{
-	struct dsa_port *port;
-	u32 index;
-	int err;
-
-	for (index = 0; index < ds->num_ports; index++) {
-		port = &ds->ports[index];
-		if (!dsa_port_is_valid(port) ||
-		    dsa_port_is_dsa(port))
-			continue;
-
-		if (dsa_port_is_cpu(port)) {
-			err = dsa_cpu_parse(port, index, dst, ds);
-			if (err)
-				return err;
-		}
-
-	}
-
-	pr_info("DSA: switch %d %d parsed\n", dst->index, ds->index);
-
-	return 0;
-}
-
-static int dsa_dst_parse(struct dsa_switch_tree *dst)
-{
-	struct dsa_switch *ds;
-	struct dsa_port *dp;
-	u32 index;
-	int port;
-	int err;
-
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
-		if (!ds)
-			continue;
-
-		err = dsa_ds_parse(dst, ds);
-		if (err)
-			return err;
-	}
-
-	if (!dst->cpu_dp) {
-		pr_warn("Tree has no master device\n");
-		return -EINVAL;
-	}
-
-	/* Assign the default CPU port to all ports of the fabric */
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
-		if (!ds)
-			continue;
-
-		for (port = 0; port < ds->num_ports; port++) {
-			dp = &ds->ports[port];
-			if (!dsa_port_is_valid(dp) ||
-			    dsa_port_is_dsa(dp) ||
-			    dsa_port_is_cpu(dp))
-				continue;
-
-			dp->cpu_dp = dst->cpu_dp;
-		}
-	}
-
-	pr_info("DSA: tree %d parsed\n", dst->index);
-
-	return 0;
-}
-
 static int dsa_port_parse_of(struct dsa_port *dp, struct device_node *dn)
 {
 	struct device_node *ethernet = of_parse_phandle(dn, "ethernet", 0);
@@ -810,10 +797,6 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 		return -EINVAL;
 	}
 
-	err = dsa_dst_parse(dst);
-	if (err)
-		goto out_del_dst;
-
 	err = dsa_dst_apply(dst);
 	if (err) {
 		dsa_dst_unapply(dst);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 03/11] net: dsa: setup and teardown master device
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 02/11] net: dsa: setup and teardown default CPU port Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 04/11] net: dsa: setup and teardown tree Vivien Didelot
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Add DSA helpers to setup and teardown a master net device wired to its
CPU port. This centralizes the dsa_ptr assignment.

This also makes the master ethtool helpers static at the same time.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c     | 36 +++++++++++++++++++-----------------
 net/dsa/dsa_priv.h |  4 ++--
 net/dsa/legacy.c   | 20 ++------------------
 net/dsa/master.c   | 30 ++++++++++++++++++++++++++++--
 4 files changed, 51 insertions(+), 39 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 0a63a2119cd0..c9b50339fcac 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -469,6 +469,23 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
 
 }
 
+static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
+{
+	struct dsa_port *cpu_dp = dst->cpu_dp;
+	struct net_device *master = cpu_dp->master;
+
+	/* DSA currently supports a single pair of CPU port and master device */
+	return dsa_master_setup(master, cpu_dp);
+}
+
+static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
+{
+	struct dsa_port *cpu_dp = dst->cpu_dp;
+	struct net_device *master = cpu_dp->master;
+
+	return dsa_master_teardown(master);
+}
+
 static int dsa_dst_apply(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
@@ -489,14 +506,7 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
 			return err;
 	}
 
-	/* If we use a tagging format that doesn't have an ethertype
-	 * field, make sure that all packets from this point on get
-	 * sent to the tag format's receive function.
-	 */
-	wmb();
-	dst->cpu_dp->master->dsa_ptr = dst->cpu_dp;
-
-	err = dsa_master_ethtool_setup(dst->cpu_dp->master);
+	err = dsa_tree_setup_master(dst);
 	if (err)
 		return err;
 
@@ -513,15 +523,7 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
 	if (!dst->applied)
 		return;
 
-	dsa_master_ethtool_restore(dst->cpu_dp->master);
-
-	dst->cpu_dp->master->dsa_ptr = NULL;
-
-	/* If we used a tagging format that doesn't have an ethertype
-	 * field, make sure that all packets from this point get sent
-	 * without the tag and go through the regular receive path.
-	 */
-	wmb();
+	dsa_tree_teardown_master(dst);
 
 	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
 		ds = dst->ds[index];
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index 253a613c40cd..bb0218c1b570 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -108,8 +108,8 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
 		       const unsigned char *addr, u16 vid);
 
 /* master.c */
-int dsa_master_ethtool_setup(struct net_device *dev);
-void dsa_master_ethtool_restore(struct net_device *dev);
+int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp);
+void dsa_master_teardown(struct net_device *dev);
 
 static inline struct net_device *dsa_master_find_slave(struct net_device *dev,
 						       int device, int port)
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c
index 0511fe2feff7..4863e3e398b6 100644
--- a/net/dsa/legacy.c
+++ b/net/dsa/legacy.c
@@ -593,15 +593,7 @@ static int dsa_setup_dst(struct dsa_switch_tree *dst, struct net_device *dev,
 	if (!configured)
 		return -EPROBE_DEFER;
 
-	/*
-	 * If we use a tagging format that doesn't have an ethertype
-	 * field, make sure that all packets from this point on get
-	 * sent to the tag format's receive function.
-	 */
-	wmb();
-	dev->dsa_ptr = dst->cpu_dp;
-
-	return dsa_master_ethtool_setup(dst->cpu_dp->master);
+	return dsa_master_setup(dst->cpu_dp->master, dst->cpu_dp);
 }
 
 static int dsa_probe(struct platform_device *pdev)
@@ -666,15 +658,7 @@ static void dsa_remove_dst(struct dsa_switch_tree *dst)
 {
 	int i;
 
-	dsa_master_ethtool_restore(dst->cpu_dp->master);
-
-	dst->cpu_dp->master->dsa_ptr = NULL;
-
-	/* If we used a tagging format that doesn't have an ethertype
-	 * field, make sure that all packets from this point get sent
-	 * without the tag and go through the regular receive path.
-	 */
-	wmb();
+	dsa_master_teardown(dst->cpu_dp->master);
 
 	for (i = 0; i < dst->pd->nr_chips; i++) {
 		struct dsa_switch *ds = dst->ds[i];
diff --git a/net/dsa/master.c b/net/dsa/master.c
index 5f3f57e372e0..00589147f042 100644
--- a/net/dsa/master.c
+++ b/net/dsa/master.c
@@ -85,7 +85,7 @@ static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset,
 	}
 }
 
-int dsa_master_ethtool_setup(struct net_device *dev)
+static int dsa_master_ethtool_setup(struct net_device *dev)
 {
 	struct dsa_port *cpu_dp = dev->dsa_ptr;
 	struct dsa_switch *ds = cpu_dp->ds;
@@ -108,10 +108,36 @@ int dsa_master_ethtool_setup(struct net_device *dev)
 	return 0;
 }
 
-void dsa_master_ethtool_restore(struct net_device *dev)
+static void dsa_master_ethtool_teardown(struct net_device *dev)
 {
 	struct dsa_port *cpu_dp = dev->dsa_ptr;
 
 	dev->ethtool_ops = cpu_dp->orig_ethtool_ops;
 	cpu_dp->orig_ethtool_ops = NULL;
 }
+
+int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp)
+{
+	/* If we use a tagging format that doesn't have an ethertype
+	 * field, make sure that all packets from this point on get
+	 * sent to the tag format's receive function.
+	 */
+	wmb();
+
+	dev->dsa_ptr = cpu_dp;
+
+	return dsa_master_ethtool_setup(dev);
+}
+
+void dsa_master_teardown(struct net_device *dev)
+{
+	dsa_master_ethtool_teardown(dev);
+
+	dev->dsa_ptr = NULL;
+
+	/* If we used a tagging format that doesn't have an ethertype
+	 * field, make sure that all packets from this point get sent
+	 * without the tag and go through the regular receive path.
+	 */
+	wmb();
+}
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 04/11] net: dsa: setup and teardown tree
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (2 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 03/11] net: dsa: setup and teardown master device Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 05/11] net: dsa: setup and teardown switches Vivien Didelot
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

This commit provides better scope for the DSA tree setup and teardown
functions. It renames the "applied" bool to "setup" and print a message
when the tree is setup, as it is done during teardown.

At the same time, check dst->setup in dsa_tree_setup, where it is set to
true.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 include/net/dsa.h |  2 +-
 net/dsa/dsa2.c    | 32 ++++++++++++++++++--------------
 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 2a8613b5a23d..6c239257309b 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -122,7 +122,7 @@ struct dsa_switch_tree {
 	struct kref refcount;
 
 	/* Has this tree been applied to the hardware? */
-	bool applied;
+	bool setup;
 
 	/*
 	 * Configuration data for the platform device that owns
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index c9b50339fcac..1a8df0a177b5 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -486,12 +486,18 @@ static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
 	return dsa_master_teardown(master);
 }
 
-static int dsa_dst_apply(struct dsa_switch_tree *dst)
+static int dsa_tree_setup(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
 	u32 index;
 	int err;
 
+	if (dst->setup) {
+		pr_err("DSA: tree %d already setup! Disjoint trees?\n",
+		       dst->index);
+		return -EEXIST;
+	}
+
 	err = dsa_tree_setup_default_cpu(dst);
 	if (err)
 		return err;
@@ -510,17 +516,19 @@ static int dsa_dst_apply(struct dsa_switch_tree *dst)
 	if (err)
 		return err;
 
-	dst->applied = true;
+	dst->setup = true;
+
+	pr_info("DSA: tree %d setup\n", dst->index);
 
 	return 0;
 }
 
-static void dsa_dst_unapply(struct dsa_switch_tree *dst)
+static void dsa_tree_teardown(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
 	u32 index;
 
-	if (!dst->applied)
+	if (!dst->setup)
 		return;
 
 	dsa_tree_teardown_master(dst);
@@ -535,8 +543,9 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
 
 	dsa_tree_teardown_default_cpu(dst);
 
-	pr_info("DSA: tree %d unapplied\n", dst->index);
-	dst->applied = false;
+	pr_info("DSA: tree %d torn down\n", dst->index);
+
+	dst->setup = false;
 }
 
 static void dsa_tree_remove_switch(struct dsa_switch_tree *dst,
@@ -794,14 +803,9 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 	if (err == 1)
 		return 0;
 
-	if (dst->applied) {
-		pr_info("DSA: Disjoint trees?\n");
-		return -EINVAL;
-	}
-
-	err = dsa_dst_apply(dst);
+	err = dsa_tree_setup(dst);
 	if (err) {
-		dsa_dst_unapply(dst);
+		dsa_tree_teardown(dst);
 		goto out_del_dst;
 	}
 
@@ -852,7 +856,7 @@ static void _dsa_unregister_switch(struct dsa_switch *ds)
 	struct dsa_switch_tree *dst = ds->dst;
 	unsigned int index = ds->index;
 
-	dsa_dst_unapply(dst);
+	dsa_tree_teardown(dst);
 
 	dsa_tree_remove_switch(dst, index);
 }
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 05/11] net: dsa: setup and teardown switches
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (3 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 04/11] net: dsa: setup and teardown tree Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 06/11] net: dsa: setup and teardown ports Vivien Didelot
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

This patches brings no functional changes. It removes the unused dst
argument from the dsa_ds_apply and dsa_ds_unapply functions, rename them
to dsa_switch_setup and dsa_switch_teardown for a more explicit scope.

This clarifies the steps of the setup or teardown of a switch fabric.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 62 ++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 39 insertions(+), 23 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 1a8df0a177b5..2b3b2a86791d 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -362,7 +362,7 @@ static void dsa_user_port_unapply(struct dsa_port *port)
 	}
 }
 
-static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
+static int dsa_switch_setup(struct dsa_switch *ds)
 {
 	struct dsa_port *port;
 	u32 index;
@@ -433,7 +433,7 @@ static int dsa_ds_apply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
 	return 0;
 }
 
-static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
+static void dsa_switch_teardown(struct dsa_switch *ds)
 {
 	struct dsa_port *port;
 	u32 index;
@@ -469,6 +469,39 @@ static void dsa_ds_unapply(struct dsa_switch_tree *dst, struct dsa_switch *ds)
 
 }
 
+static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
+{
+	struct dsa_switch *ds;
+	int device;
+	int err;
+
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
+		if (!ds)
+			continue;
+
+		err = dsa_switch_setup(ds);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst)
+{
+	struct dsa_switch *ds;
+	int device;
+
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
+		if (!ds)
+			continue;
+
+		dsa_switch_teardown(ds);
+	}
+}
+
 static int dsa_tree_setup_master(struct dsa_switch_tree *dst)
 {
 	struct dsa_port *cpu_dp = dst->cpu_dp;
@@ -488,8 +521,6 @@ static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
 
 static int dsa_tree_setup(struct dsa_switch_tree *dst)
 {
-	struct dsa_switch *ds;
-	u32 index;
 	int err;
 
 	if (dst->setup) {
@@ -502,15 +533,9 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
 	if (err)
 		return err;
 
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
-		if (!ds)
-			continue;
-
-		err = dsa_ds_apply(dst, ds);
-		if (err)
-			return err;
-	}
+	err = dsa_tree_setup_switches(dst);
+	if (err)
+		return err;
 
 	err = dsa_tree_setup_master(dst);
 	if (err)
@@ -525,21 +550,12 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
 
 static void dsa_tree_teardown(struct dsa_switch_tree *dst)
 {
-	struct dsa_switch *ds;
-	u32 index;
-
 	if (!dst->setup)
 		return;
 
 	dsa_tree_teardown_master(dst);
 
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
-		if (!ds)
-			continue;
-
-		dsa_ds_unapply(dst, ds);
-	}
+	dsa_tree_teardown_switches(dst);
 
 	dsa_tree_teardown_default_cpu(dst);
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 06/11] net: dsa: setup and teardown ports
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (4 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 05/11] net: dsa: setup and teardown switches Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 07/11] net: dsa: add find port by node helper Vivien Didelot
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

The dsa_dsa_port_apply and dsa_cpu_port_apply functions do exactly the
same. The dsa_user_port_apply function does not try to register a fixed
link but try to create a slave.

This commit factorizes and scopes all that in two convenient
dsa_port_setup and dsa_port_teardown functions.

It won't hurt to register a devlink_port for unused port as well.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 175 ++++++++++++++++++++-------------------------------------
 1 file changed, 60 insertions(+), 115 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 2b3b2a86791d..676c0bc943dd 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -281,91 +281,65 @@ static void dsa_tree_teardown_default_cpu(struct dsa_switch_tree *dst)
 	dst->cpu_dp = NULL;
 }
 
-static int dsa_dsa_port_apply(struct dsa_port *port)
+static int dsa_port_setup(struct dsa_port *dp)
 {
-	struct dsa_switch *ds = port->ds;
+	struct dsa_switch *ds = dp->ds;
 	int err;
 
-	err = dsa_port_fixed_link_register_of(port);
-	if (err) {
-		dev_warn(ds->dev, "Failed to setup dsa port %d: %d\n",
-			 port->index, err);
-		return err;
-	}
+	memset(&dp->devlink_port, 0, sizeof(dp->devlink_port));
 
-	memset(&port->devlink_port, 0, sizeof(port->devlink_port));
-
-	return devlink_port_register(ds->devlink, &port->devlink_port,
-				     port->index);
-}
-
-static void dsa_dsa_port_unapply(struct dsa_port *port)
-{
-	devlink_port_unregister(&port->devlink_port);
-	dsa_port_fixed_link_unregister_of(port);
-}
-
-static int dsa_cpu_port_apply(struct dsa_port *port)
-{
-	struct dsa_switch *ds = port->ds;
-	int err;
-
-	err = dsa_port_fixed_link_register_of(port);
-	if (err) {
-		dev_warn(ds->dev, "Failed to setup cpu port %d: %d\n",
-			 port->index, err);
-		return err;
-	}
-
-	memset(&port->devlink_port, 0, sizeof(port->devlink_port));
-	err = devlink_port_register(ds->devlink, &port->devlink_port,
-				    port->index);
-	return err;
-}
-
-static void dsa_cpu_port_unapply(struct dsa_port *port)
-{
-	devlink_port_unregister(&port->devlink_port);
-	dsa_port_fixed_link_unregister_of(port);
-}
-
-static int dsa_user_port_apply(struct dsa_port *port)
-{
-	struct dsa_switch *ds = port->ds;
-	int err;
-
-	err = dsa_slave_create(port);
-	if (err) {
-		dev_warn(ds->dev, "Failed to create slave %d: %d\n",
-			 port->index, err);
-		port->slave = NULL;
-		return err;
-	}
-
-	memset(&port->devlink_port, 0, sizeof(port->devlink_port));
-	err = devlink_port_register(ds->devlink, &port->devlink_port,
-				    port->index);
+	err = devlink_port_register(ds->devlink, &dp->devlink_port, dp->index);
 	if (err)
 		return err;
 
-	devlink_port_type_eth_set(&port->devlink_port, port->slave);
+	switch (dp->type) {
+	case DSA_PORT_TYPE_UNUSED:
+		break;
+	case DSA_PORT_TYPE_CPU:
+	case DSA_PORT_TYPE_DSA:
+		err = dsa_port_fixed_link_register_of(dp);
+		if (err) {
+			dev_err(ds->dev, "failed to register fixed link for port %d.%d\n",
+				ds->index, dp->index);
+			return err;
+		}
+
+		break;
+	case DSA_PORT_TYPE_USER:
+		err = dsa_slave_create(dp);
+		if (err)
+			dev_err(ds->dev, "failed to create slave for port %d.%d\n",
+				ds->index, dp->index);
+		else
+			devlink_port_type_eth_set(&dp->devlink_port, dp->slave);
+		break;
+	}
 
 	return 0;
 }
 
-static void dsa_user_port_unapply(struct dsa_port *port)
+static void dsa_port_teardown(struct dsa_port *dp)
 {
-	devlink_port_unregister(&port->devlink_port);
-	if (port->slave) {
-		dsa_slave_destroy(port->slave);
-		port->slave = NULL;
+	devlink_port_unregister(&dp->devlink_port);
+
+	switch (dp->type) {
+	case DSA_PORT_TYPE_UNUSED:
+		break;
+	case DSA_PORT_TYPE_CPU:
+	case DSA_PORT_TYPE_DSA:
+		dsa_port_fixed_link_unregister_of(dp);
+		break;
+	case DSA_PORT_TYPE_USER:
+		if (dp->slave) {
+			dsa_slave_destroy(dp->slave);
+			dp->slave = NULL;
+		}
+		break;
 	}
 }
 
 static int dsa_switch_setup(struct dsa_switch *ds)
 {
-	struct dsa_port *port;
-	u32 index;
 	int err;
 
 	/* Initialize ds->phys_mii_mask before registering the slave MDIO bus
@@ -406,56 +380,11 @@ static int dsa_switch_setup(struct dsa_switch *ds)
 			return err;
 	}
 
-	for (index = 0; index < ds->num_ports; index++) {
-		port = &ds->ports[index];
-		if (!dsa_port_is_valid(port))
-			continue;
-
-		if (dsa_port_is_dsa(port)) {
-			err = dsa_dsa_port_apply(port);
-			if (err)
-				return err;
-			continue;
-		}
-
-		if (dsa_port_is_cpu(port)) {
-			err = dsa_cpu_port_apply(port);
-			if (err)
-				return err;
-			continue;
-		}
-
-		err = dsa_user_port_apply(port);
-		if (err)
-			continue;
-	}
-
 	return 0;
 }
 
 static void dsa_switch_teardown(struct dsa_switch *ds)
 {
-	struct dsa_port *port;
-	u32 index;
-
-	for (index = 0; index < ds->num_ports; index++) {
-		port = &ds->ports[index];
-		if (!dsa_port_is_valid(port))
-			continue;
-
-		if (dsa_port_is_dsa(port)) {
-			dsa_dsa_port_unapply(port);
-			continue;
-		}
-
-		if (dsa_port_is_cpu(port)) {
-			dsa_cpu_port_unapply(port);
-			continue;
-		}
-
-		dsa_user_port_unapply(port);
-	}
-
 	if (ds->slave_mii_bus && ds->ops->phy_read)
 		mdiobus_unregister(ds->slave_mii_bus);
 
@@ -472,7 +401,8 @@ static void dsa_switch_teardown(struct dsa_switch *ds)
 static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
-	int device;
+	struct dsa_port *dp;
+	int device, port;
 	int err;
 
 	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
@@ -483,6 +413,14 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
 		err = dsa_switch_setup(ds);
 		if (err)
 			return err;
+
+		for (port = 0; port < ds->num_ports; port++) {
+			dp = &ds->ports[port];
+
+			err = dsa_port_setup(dp);
+			if (err)
+				return err;
+		}
 	}
 
 	return 0;
@@ -491,13 +429,20 @@ static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
 static void dsa_tree_teardown_switches(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
-	int device;
+	struct dsa_port *dp;
+	int device, port;
 
 	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
 		ds = dst->ds[device];
 		if (!ds)
 			continue;
 
+		for (port = 0; port < ds->num_ports; port++) {
+			dp = &ds->ports[port];
+
+			dsa_port_teardown(dp);
+		}
+
 		dsa_switch_teardown(ds);
 	}
 }
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 07/11] net: dsa: add find port by node helper
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (5 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 06/11] net: dsa: setup and teardown ports Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 08/11] net: dsa: use of_for_each_phandle Vivien Didelot
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Instead of having two dsa_ds_find_port_dn (which returns a bool) and
dsa_dst_find_port_dn (which returns a switch) functions, provide a more
explicit dsa_tree_find_port_by_node function which returns a matching
port.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 37 +++++++++++++++++--------------------
 1 file changed, 17 insertions(+), 20 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 676c0bc943dd..0f6f8c1701f9 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -117,30 +117,24 @@ static bool dsa_port_is_user(struct dsa_port *dp)
 	return dp->type == DSA_PORT_TYPE_USER;
 }
 
-static bool dsa_ds_find_port_dn(struct dsa_switch *ds,
-				struct device_node *port)
-{
-	u32 index;
-
-	for (index = 0; index < ds->num_ports; index++)
-		if (ds->ports[index].dn == port)
-			return true;
-	return false;
-}
-
-static struct dsa_switch *dsa_dst_find_port_dn(struct dsa_switch_tree *dst,
-					       struct device_node *port)
+static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
+						   struct device_node *dn)
 {
 	struct dsa_switch *ds;
-	u32 index;
+	struct dsa_port *dp;
+	int device, port;
 
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
 		if (!ds)
 			continue;
 
-		if (dsa_ds_find_port_dn(ds, port))
-			return ds;
+		for (port = 0; port < ds->num_ports; port++) {
+			dp = &ds->ports[port];
+
+			if (dp->dn == dn)
+				return dp;
+		}
 	}
 
 	return NULL;
@@ -154,18 +148,21 @@ static int dsa_port_complete(struct dsa_switch_tree *dst,
 	struct device_node *link;
 	int index;
 	struct dsa_switch *dst_ds;
+	struct dsa_port *link_dp;
 
 	for (index = 0;; index++) {
 		link = of_parse_phandle(port->dn, "link", index);
 		if (!link)
 			break;
 
-		dst_ds = dsa_dst_find_port_dn(dst, link);
+		link_dp = dsa_tree_find_port_by_node(dst, link);
 		of_node_put(link);
 
-		if (!dst_ds)
+		if (!link_dp)
 			return 1;
 
+		dst_ds = link_dp->ds;
+
 		src_ds->rtable[dst_ds->index] = src_port;
 	}
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 08/11] net: dsa: use of_for_each_phandle
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (6 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 07/11] net: dsa: add find port by node helper Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 09/11] net: dsa: setup routing table Vivien Didelot
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

The OF code provides a of_for_each_phandle() helper to iterate over
phandles. Use it instead of arbitrary iterating ourselves over the list
of phandles hanging to the "link" property of the port's device node.

The of_phandle_iterator_next() helper calls of_node_put() itself on
it.node. Thus We must only do it ourselves if we break the loop.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 0f6f8c1701f9..25ed41262ead 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -145,21 +145,18 @@ static int dsa_port_complete(struct dsa_switch_tree *dst,
 			     struct dsa_port *port,
 			     u32 src_port)
 {
-	struct device_node *link;
-	int index;
+	struct device_node *dn = port->dn;
+	struct of_phandle_iterator it;
 	struct dsa_switch *dst_ds;
 	struct dsa_port *link_dp;
+	int err;
 
-	for (index = 0;; index++) {
-		link = of_parse_phandle(port->dn, "link", index);
-		if (!link)
-			break;
-
-		link_dp = dsa_tree_find_port_by_node(dst, link);
-		of_node_put(link);
-
-		if (!link_dp)
+	of_for_each_phandle(&it, err, dn, "link", NULL, 0) {
+		link_dp = dsa_tree_find_port_by_node(dst, it.node);
+		if (!link_dp) {
+			of_node_put(it.node);
 			return 1;
+		}
 
 		dst_ds = link_dp->ds;
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 09/11] net: dsa: setup routing table
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (7 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 08/11] net: dsa: use of_for_each_phandle Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 10/11] net: dsa: setup a tree when adding a switch to it Vivien Didelot
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

The *_complete() functions take too much arguments to do only one thing:
they try to fetch the dsa_port structures corresponding to device nodes
under the "link" list property of DSA ports, and use them to setup the
routing table of switches.

This patch simplifies them by providing instead simpler
dsa_{port,switch,tree}_setup_routing_table functions which return a
boolean value, true if the tree is complete.

dsa_tree_setup_routing_table is called inside dsa_tree_setup which
simplifies the switch registering function as well.

A switch's routing table is now initialized before its setup.

This also makes dsa_port_is_valid obsolete, remove it.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 108 ++++++++++++++++++++-------------------------------------
 1 file changed, 37 insertions(+), 71 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 25ed41262ead..44d26b5977cd 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -94,14 +94,6 @@ static void dsa_tree_put(struct dsa_switch_tree *dst)
 	kref_put(&dst->refcount, dsa_tree_release);
 }
 
-/* For platform data configurations, we need to have a valid name argument to
- * differentiate a disabled port from an enabled one
- */
-static bool dsa_port_is_valid(struct dsa_port *port)
-{
-	return port->type != DSA_PORT_TYPE_UNUSED;
-}
-
 static bool dsa_port_is_dsa(struct dsa_port *port)
 {
 	return port->type == DSA_PORT_TYPE_DSA;
@@ -140,14 +132,12 @@ static struct dsa_port *dsa_tree_find_port_by_node(struct dsa_switch_tree *dst,
 	return NULL;
 }
 
-static int dsa_port_complete(struct dsa_switch_tree *dst,
-			     struct dsa_switch *src_ds,
-			     struct dsa_port *port,
-			     u32 src_port)
+static bool dsa_port_setup_routing_table(struct dsa_port *dp)
 {
-	struct device_node *dn = port->dn;
+	struct dsa_switch *ds = dp->ds;
+	struct dsa_switch_tree *dst = ds->dst;
+	struct device_node *dn = dp->dn;
 	struct of_phandle_iterator it;
-	struct dsa_switch *dst_ds;
 	struct dsa_port *link_dp;
 	int err;
 
@@ -155,66 +145,54 @@ static int dsa_port_complete(struct dsa_switch_tree *dst,
 		link_dp = dsa_tree_find_port_by_node(dst, it.node);
 		if (!link_dp) {
 			of_node_put(it.node);
-			return 1;
+			return false;
 		}
 
-		dst_ds = link_dp->ds;
-
-		src_ds->rtable[dst_ds->index] = src_port;
+		ds->rtable[link_dp->ds->index] = dp->index;
 	}
 
-	return 0;
+	return true;
 }
 
-/* A switch is complete if all the DSA ports phandles point to ports
- * known in the tree. A return value of 1 means the tree is not
- * complete. This is not an error condition. A value of 0 is
- * success.
- */
-static int dsa_ds_complete(struct dsa_switch_tree *dst, struct dsa_switch *ds)
+static bool dsa_switch_setup_routing_table(struct dsa_switch *ds)
 {
-	struct dsa_port *port;
-	u32 index;
-	int err;
+	bool complete = true;
+	struct dsa_port *dp;
+	int i;
 
-	for (index = 0; index < ds->num_ports; index++) {
-		port = &ds->ports[index];
-		if (!dsa_port_is_valid(port))
-			continue;
+	for (i = 0; i < DSA_MAX_SWITCHES; i++)
+		ds->rtable[i] = DSA_RTABLE_NONE;
 
-		if (!dsa_port_is_dsa(port))
-			continue;
+	for (i = 0; i < ds->num_ports; i++) {
+		dp = &ds->ports[i];
 
-		err = dsa_port_complete(dst, ds, port, index);
-		if (err != 0)
-			return err;
+		if (dsa_port_is_dsa(dp)) {
+			complete = dsa_port_setup_routing_table(dp);
+			if (!complete)
+				break;
+		}
 	}
 
-	return 0;
+	return complete;
 }
 
-/* A tree is complete if all the DSA ports phandles point to ports
- * known in the tree. A return value of 1 means the tree is not
- * complete. This is not an error condition. A value of 0 is
- * success.
- */
-static int dsa_dst_complete(struct dsa_switch_tree *dst)
+static bool dsa_tree_setup_routing_table(struct dsa_switch_tree *dst)
 {
 	struct dsa_switch *ds;
-	u32 index;
-	int err;
+	bool complete = true;
+	int device;
 
-	for (index = 0; index < DSA_MAX_SWITCHES; index++) {
-		ds = dst->ds[index];
+	for (device = 0; device < DSA_MAX_SWITCHES; device++) {
+		ds = dst->ds[device];
 		if (!ds)
 			continue;
 
-		err = dsa_ds_complete(dst, ds);
-		if (err != 0)
-			return err;
+		complete = dsa_switch_setup_routing_table(ds);
+		if (!complete)
+			break;
 	}
 
-	return 0;
+	return complete;
 }
 
 static struct dsa_port *dsa_tree_find_first_cpu(struct dsa_switch_tree *dst)
@@ -460,6 +438,7 @@ static void dsa_tree_teardown_master(struct dsa_switch_tree *dst)
 
 static int dsa_tree_setup(struct dsa_switch_tree *dst)
 {
+	bool complete;
 	int err;
 
 	if (dst->setup) {
@@ -468,6 +447,10 @@ static int dsa_tree_setup(struct dsa_switch_tree *dst)
 		return -EEXIST;
 	}
 
+	complete = dsa_tree_setup_routing_table(dst);
+	if (!complete)
+		return 0;
+
 	err = dsa_tree_setup_default_cpu(dst);
 	if (err)
 		return err;
@@ -727,7 +710,7 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 	struct device_node *np = ds->dev->of_node;
 	struct dsa_switch_tree *dst;
 	unsigned int index;
-	int i, err;
+	int err;
 
 	if (np)
 		err = dsa_switch_parse_of(ds, np);
@@ -742,33 +725,16 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 	index = ds->index;
 	dst = ds->dst;
 
-	/* Initialize the routing table */
-	for (i = 0; i < DSA_MAX_SWITCHES; ++i)
-		ds->rtable[i] = DSA_RTABLE_NONE;
-
 	err = dsa_tree_add_switch(dst, ds);
 	if (err)
 		return err;
 
-	err = dsa_dst_complete(dst);
-	if (err < 0)
-		goto out_del_dst;
-
-	/* Not all switches registered yet */
-	if (err == 1)
-		return 0;
-
 	err = dsa_tree_setup(dst);
 	if (err) {
 		dsa_tree_teardown(dst);
-		goto out_del_dst;
+		dsa_tree_remove_switch(dst, index);
 	}
 
-	return 0;
-
-out_del_dst:
-	dsa_tree_remove_switch(dst, index);
-
 	return err;
 }
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 10/11] net: dsa: setup a tree when adding a switch to it
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (8 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 09/11] net: dsa: setup routing table Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-06 21:11 ` [PATCH net-next 11/11] net: dsa: rename probe and remove switch functions Vivien Didelot
  2017-11-09  0:29 ` [PATCH net-next 00/11] net: dsa: setup stage David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

Now that the tree setup is centralized, we can simplify the code a bit
more by setting up or tearing down the tree directly when adding or
removing a switch to/from it.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 35 ++++++++++++++++-------------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 44d26b5977cd..3db50e68640e 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -489,6 +489,8 @@ static void dsa_tree_teardown(struct dsa_switch_tree *dst)
 static void dsa_tree_remove_switch(struct dsa_switch_tree *dst,
 				   unsigned int index)
 {
+	dsa_tree_teardown(dst);
+
 	dst->ds[index] = NULL;
 	dsa_tree_put(dst);
 }
@@ -497,6 +499,7 @@ static int dsa_tree_add_switch(struct dsa_switch_tree *dst,
 			       struct dsa_switch *ds)
 {
 	unsigned int index = ds->index;
+	int err;
 
 	if (dst->ds[index])
 		return -EBUSY;
@@ -504,7 +507,11 @@ static int dsa_tree_add_switch(struct dsa_switch_tree *dst,
 	dsa_tree_get(dst);
 	dst->ds[index] = ds;
 
-	return 0;
+	err = dsa_tree_setup(dst);
+	if (err)
+		dsa_tree_remove_switch(dst, index);
+
+	return err;
 }
 
 static int dsa_port_parse_user(struct dsa_port *dp, const char *name)
@@ -704,12 +711,17 @@ static int dsa_switch_parse(struct dsa_switch *ds, struct dsa_chip_data *cd)
 	return dsa_switch_parse_ports(ds, cd);
 }
 
+static int dsa_switch_add(struct dsa_switch *ds)
+{
+	struct dsa_switch_tree *dst = ds->dst;
+
+	return dsa_tree_add_switch(dst, ds);
+}
+
 static int _dsa_register_switch(struct dsa_switch *ds)
 {
 	struct dsa_chip_data *pdata = ds->dev->platform_data;
 	struct device_node *np = ds->dev->of_node;
-	struct dsa_switch_tree *dst;
-	unsigned int index;
 	int err;
 
 	if (np)
@@ -722,20 +734,7 @@ static int _dsa_register_switch(struct dsa_switch *ds)
 	if (err)
 		return err;
 
-	index = ds->index;
-	dst = ds->dst;
-
-	err = dsa_tree_add_switch(dst, ds);
-	if (err)
-		return err;
-
-	err = dsa_tree_setup(dst);
-	if (err) {
-		dsa_tree_teardown(dst);
-		dsa_tree_remove_switch(dst, index);
-	}
-
-	return err;
+	return dsa_switch_add(ds);
 }
 
 struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n)
@@ -777,8 +776,6 @@ static void _dsa_unregister_switch(struct dsa_switch *ds)
 	struct dsa_switch_tree *dst = ds->dst;
 	unsigned int index = ds->index;
 
-	dsa_tree_teardown(dst);
-
 	dsa_tree_remove_switch(dst, index);
 }
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 11/11] net: dsa: rename probe and remove switch functions
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (9 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 10/11] net: dsa: setup a tree when adding a switch to it Vivien Didelot
@ 2017-11-06 21:11 ` Vivien Didelot
  2017-11-09  0:29 ` [PATCH net-next 00/11] net: dsa: setup stage David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: Vivien Didelot @ 2017-11-06 21:11 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
	Andrew Lunn, Vivien Didelot

This commit brings no functional changes. It gets rid of the underscore
prefixed _dsa_register_switch and _dsa_unregister_switch functions in
favor of dsa_switch_probe() which parses and adds a switch to a tree and
dsa_switch_remove() which removes a switch from a tree.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 net/dsa/dsa2.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 3db50e68640e..fd54a8e17986 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -718,7 +718,7 @@ static int dsa_switch_add(struct dsa_switch *ds)
 	return dsa_tree_add_switch(dst, ds);
 }
 
-static int _dsa_register_switch(struct dsa_switch *ds)
+static int dsa_switch_probe(struct dsa_switch *ds)
 {
 	struct dsa_chip_data *pdata = ds->dev->platform_data;
 	struct device_node *np = ds->dev->of_node;
@@ -764,14 +764,14 @@ int dsa_register_switch(struct dsa_switch *ds)
 	int err;
 
 	mutex_lock(&dsa2_mutex);
-	err = _dsa_register_switch(ds);
+	err = dsa_switch_probe(ds);
 	mutex_unlock(&dsa2_mutex);
 
 	return err;
 }
 EXPORT_SYMBOL_GPL(dsa_register_switch);
 
-static void _dsa_unregister_switch(struct dsa_switch *ds)
+static void dsa_switch_remove(struct dsa_switch *ds)
 {
 	struct dsa_switch_tree *dst = ds->dst;
 	unsigned int index = ds->index;
@@ -782,7 +782,7 @@ static void _dsa_unregister_switch(struct dsa_switch *ds)
 void dsa_unregister_switch(struct dsa_switch *ds)
 {
 	mutex_lock(&dsa2_mutex);
-	_dsa_unregister_switch(ds);
+	dsa_switch_remove(ds);
 	mutex_unlock(&dsa2_mutex);
 }
 EXPORT_SYMBOL_GPL(dsa_unregister_switch);
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port
  2017-11-06 21:11 ` [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port Vivien Didelot
@ 2017-11-07  1:47   ` Florian Fainelli
  0 siblings, 0 replies; 14+ messages in thread
From: Florian Fainelli @ 2017-11-07  1:47 UTC (permalink / raw)
  To: Vivien Didelot, netdev; +Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn

On 11/06/2017 01:11 PM, Vivien Didelot wrote:
> A DSA port has a dedicated CPU port assigned to it, stored in the cpu_dp
> member. It is not meant to be modified by a port, thus make it const.
> 
> Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 00/11] net: dsa: setup stage
  2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
                   ` (10 preceding siblings ...)
  2017-11-06 21:11 ` [PATCH net-next 11/11] net: dsa: rename probe and remove switch functions Vivien Didelot
@ 2017-11-09  0:29 ` David Miller
  11 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2017-11-09  0:29 UTC (permalink / raw)
  To: vivien.didelot; +Cc: netdev, linux-kernel, kernel, f.fainelli, andrew

From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Date: Mon,  6 Nov 2017 16:11:42 -0500

> When probing a DSA switch, there is basically two stages.
> 
> The first stage is the parsing of the switch device, from either device
> tree or platform data. It fetches the DSA tree to which it belongs, and
> validates its ports. The switch device is then added to the tree, and
> the second stage is called if this was the last switch of the tree.
> 
> The second stage is the setup of the tree, which validates that the tree
> is complete, sets up the routing tables, the default CPU port for user
> ports, sets up the switch drivers and finally the master interfaces,
> which makes the whole switch fabric functional.
> 
> This patch series covers the second setup stage. The setup and teardown
> of a switch tree have been separated into logical steps, and the probing
> of a switch now simply parses and adds a switch to a tree.

Series applied, thanks Vivien.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2017-11-09  0:29 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-06 21:11 [PATCH net-next 00/11] net: dsa: setup stage Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 01/11] net: dsa: constify cpu_dp member of dsa_port Vivien Didelot
2017-11-07  1:47   ` Florian Fainelli
2017-11-06 21:11 ` [PATCH net-next 02/11] net: dsa: setup and teardown default CPU port Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 03/11] net: dsa: setup and teardown master device Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 04/11] net: dsa: setup and teardown tree Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 05/11] net: dsa: setup and teardown switches Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 06/11] net: dsa: setup and teardown ports Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 07/11] net: dsa: add find port by node helper Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 08/11] net: dsa: use of_for_each_phandle Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 09/11] net: dsa: setup routing table Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 10/11] net: dsa: setup a tree when adding a switch to it Vivien Didelot
2017-11-06 21:11 ` [PATCH net-next 11/11] net: dsa: rename probe and remove switch functions Vivien Didelot
2017-11-09  0:29 ` [PATCH net-next 00/11] net: dsa: setup stage David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.