Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1389657 > unrolled thread
| Started by | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| First post | 2016-04-28 00:40 +0200 |
| Last post | 2016-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.
[RFC 17/20] net: dsa: mv88e6xxx: factorize port bridge change Vivien Didelot <vivien.didelot@savoirfairelinux.com> - 2016-04-28 00:40 +0200
| From | Vivien Didelot <vivien.didelot@savoirfairelinux.com> |
|---|---|
| Date | 2016-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
Back to top | Article view | linux.kernel
csiph-web