Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1389657 > unrolled thread

[RFC 17/20] net: dsa: mv88e6xxx: factorize port bridge change

Started byVivien Didelot <vivien.didelot@savoirfairelinux.com>
First post2016-04-28 00:40 +0200
Last post2016-04-28 00:40 +0200
Articles 1 — 1 participant

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [RFC 17/20] net: dsa: mv88e6xxx: factorize port bridge change Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-04-28 00:40 +0200

#1389657 — [RFC 17/20] net: dsa: mv88e6xxx: factorize port bridge change

FromVivien Didelot <vivien.didelot@savoirfairelinux.com>
Date2016-04-28 00:40 +0200
Subject[RFC 17/20] net: dsa: mv88e6xxx: factorize port bridge change
Message-ID<rsGhJ-P8-37@gated-at.bofh.it>
Implement a mv88e6xxx_port_bridge_change function to factorize the
configuration needed when a port joins or leaves a bridge group.

This will simplify the implementation of cross-chip bridging.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx.c | 67 +++++++++++++++++++++++++++------------------
 1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 8004d00..25852ee 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -1150,6 +1150,24 @@ static int _mv88e6xxx_port_map_vlantable(struct dsa_switch *ds,
 	return _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_BASE_VLAN, reg);
 }
 
+static int _mv88e6xxx_remap_vlantable(struct dsa_switch *ds,
+				      struct net_device *bridge)
+{
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+	struct dsa_port *intp;
+	int err;
+
+	dsa_switch_for_each_port(ds, intp, ps->info->num_ports) {
+		if (intp->br == bridge) {
+			err = _mv88e6xxx_port_map_vlantable(ds, intp);
+			if (err)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
 void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -2229,51 +2247,46 @@ unlock:
 	return err;
 }
 
-int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, struct dsa_port *dp,
-			       struct net_device *bridge)
+int mv88e6xxx_port_bridge_change(struct dsa_switch *ds, struct dsa_port *dp,
+				 struct net_device *bridge)
 {
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	struct dsa_port *intp;
 	int err;
 
-	if (dsa_port_is_external(dp, ds))
-		return -EOPNOTSUPP;
-
 	mutex_lock(&ps->smi_mutex);
 
-	/* Remap each port's VLANTable */
-	dsa_switch_for_each_port(ds, intp, ps->info->num_ports) {
-		if (intp->br == bridge) {
-			err = _mv88e6xxx_port_map_vlantable(ds, intp);
+	if (dsa_port_is_external(dp, ds)) {
+		err = -EOPNOTSUPP;
+	} else {
+		/* Remap VLANTable of concerned in-chip ports */
+		if (!dp->br) {
+			err = _mv88e6xxx_port_map_vlantable(ds, dp);
 			if (err)
-				break;
+				goto unlock;
 		}
+
+		err = _mv88e6xxx_remap_vlantable(ds, bridge);
+		if (err)
+			goto unlock;
 	}
 
+unlock:
 	mutex_unlock(&ps->smi_mutex);
 
 	return err;
 }
 
+int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, struct dsa_port *dp,
+			       struct net_device *bridge)
+{
+	return mv88e6xxx_port_bridge_change(ds, dp, bridge);
+}
+
 void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, struct dsa_port *dp,
 				 struct net_device *bridge)
 {
-	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
-	struct dsa_port *intp;
-
-	if (dsa_port_is_external(dp, ds))
-		return;
-
-	mutex_lock(&ps->smi_mutex);
-
-	/* Remap each port's VLANTable */
-	dsa_switch_for_each_port(ds, intp, ps->info->num_ports)
-		if (intp == dp || intp->br == bridge)
-			if (_mv88e6xxx_port_map_vlantable(ds, intp))
-				netdev_warn(ds->ports[intp->port],
-					    "failed to remap\n");
-
-	mutex_unlock(&ps->smi_mutex);
+	if (mv88e6xxx_port_bridge_change(ds, dp, bridge))
+		netdev_err(ds->ports[dp->port], "failed to unbridge\n");
 }
 
 static void mv88e6xxx_bridge_work(struct work_struct *work)
-- 
2.8.0

[toc] | [standalone]


Back to top | Article view | linux.kernel


csiph-web