* [PATCH net-next 1/4] net: dsa: add port STP state helper
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
@ 2016-09-22 20:49 ` Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 2/4] net: dsa: add port fast ageing Vivien Didelot
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vivien Didelot @ 2016-09-22 20:49 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, John Crispin, Vivien Didelot
Add a void helper to set the STP state of a port, checking first if the
required routine is provided by the driver.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
net/dsa/slave.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 9ecbe78..fd78d4c 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -69,6 +69,12 @@ static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
return !!p->bridge_dev;
}
+static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
+{
+ if (ds->ops->port_stp_state_set)
+ ds->ops->port_stp_state_set(ds, port, state);
+}
+
static int dsa_slave_open(struct net_device *dev)
{
struct dsa_slave_priv *p = netdev_priv(dev);
@@ -104,8 +110,7 @@ static int dsa_slave_open(struct net_device *dev)
goto clear_promisc;
}
- if (ds->ops->port_stp_state_set)
- ds->ops->port_stp_state_set(ds, p->port, stp_state);
+ dsa_port_set_stp_state(ds, p->port, stp_state);
if (p->phy)
phy_start(p->phy);
@@ -147,8 +152,7 @@ static int dsa_slave_close(struct net_device *dev)
if (ds->ops->port_disable)
ds->ops->port_disable(ds, p->port, p->phy);
- if (ds->ops->port_stp_state_set)
- ds->ops->port_stp_state_set(ds, p->port, BR_STATE_DISABLED);
+ dsa_port_set_stp_state(ds, p->port, BR_STATE_DISABLED);
return 0;
}
@@ -354,7 +358,7 @@ static int dsa_slave_stp_state_set(struct net_device *dev,
if (switchdev_trans_ph_prepare(trans))
return ds->ops->port_stp_state_set ? 0 : -EOPNOTSUPP;
- ds->ops->port_stp_state_set(ds, p->port, attr->u.stp_state);
+ dsa_port_set_stp_state(ds, p->port, attr->u.stp_state);
return 0;
}
@@ -556,8 +560,7 @@ static void dsa_slave_bridge_port_leave(struct net_device *dev)
/* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer,
* so allow it to be in BR_STATE_FORWARDING to be kept functional
*/
- if (ds->ops->port_stp_state_set)
- ds->ops->port_stp_state_set(ds, p->port, BR_STATE_FORWARDING);
+ dsa_port_set_stp_state(ds, p->port, BR_STATE_FORWARDING);
}
static int dsa_slave_port_attr_get(struct net_device *dev,
--
2.10.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next 2/4] net: dsa: add port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 1/4] net: dsa: add port STP state helper Vivien Didelot
@ 2016-09-22 20:49 ` Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 3/4] net: dsa: b53: implement DSA " Vivien Didelot
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vivien Didelot @ 2016-09-22 20:49 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, John Crispin, Vivien Didelot
Today the DSA drivers are in charge of flushing the MAC addresses
associated to a port when its STP state changes from Learning or
Forwarding, to Disabled or Blocking or Listening.
This makes the drivers more complex and hides the generic switch logic.
Introduce a new optional port_fast_age operation to dsa_switch_ops, to
move this logic to the DSA layer and keep drivers simple.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
include/net/dsa.h | 2 ++
net/dsa/slave.c | 18 ++++++++++++++++++
2 files changed, 20 insertions(+)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7556646..b122196 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -143,6 +143,7 @@ struct dsa_port {
struct net_device *netdev;
struct device_node *dn;
unsigned int ageing_time;
+ u8 stp_state;
};
struct dsa_switch {
@@ -339,6 +340,7 @@ struct dsa_switch_ops {
void (*port_bridge_leave)(struct dsa_switch *ds, int port);
void (*port_stp_state_set)(struct dsa_switch *ds, int port,
u8 state);
+ void (*port_fast_age)(struct dsa_switch *ds, int port);
/*
* VLAN support
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index fd78d4c..6b1282c 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -71,8 +71,26 @@ static inline bool dsa_port_is_bridged(struct dsa_slave_priv *p)
static void dsa_port_set_stp_state(struct dsa_switch *ds, int port, u8 state)
{
+ struct dsa_port *dp = &ds->ports[port];
+
if (ds->ops->port_stp_state_set)
ds->ops->port_stp_state_set(ds, port, state);
+
+ if (ds->ops->port_fast_age) {
+ /* Fast age FDB entries or flush appropriate forwarding database
+ * for the given port, if we are moving it from Learning or
+ * Forwarding state, to Disabled or Blocking or Listening state.
+ */
+
+ if ((dp->stp_state == BR_STATE_LEARNING ||
+ dp->stp_state == BR_STATE_FORWARDING) &&
+ (state == BR_STATE_DISABLED ||
+ state == BR_STATE_BLOCKING ||
+ state == BR_STATE_LISTENING))
+ ds->ops->port_fast_age(ds, port);
+ }
+
+ dp->stp_state = state;
}
static int dsa_slave_open(struct net_device *dev)
--
2.10.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next 3/4] net: dsa: b53: implement DSA port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 1/4] net: dsa: add port STP state helper Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 2/4] net: dsa: add port fast ageing Vivien Didelot
@ 2016-09-22 20:49 ` Vivien Didelot
2016-09-22 20:49 ` [PATCH net-next 4/4] net: dsa: mv88e6xxx: " Vivien Didelot
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vivien Didelot @ 2016-09-22 20:49 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, John Crispin, Vivien Didelot
Remove the fast ageing logic from b53_br_set_stp_state and implement the
new DSA switch port_fast_age operation instead.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/b53/b53_common.c | 31 +++++++++++--------------------
1 file changed, 11 insertions(+), 20 deletions(-)
diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 1a492c0..64be66d 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1402,16 +1402,12 @@ static void b53_br_leave(struct dsa_switch *ds, int port)
}
}
-static void b53_br_set_stp_state(struct dsa_switch *ds, int port,
- u8 state)
+static void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state)
{
struct b53_device *dev = ds->priv;
- u8 hw_state, cur_hw_state;
+ u8 hw_state;
u8 reg;
- b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®);
- cur_hw_state = reg & PORT_CTRL_STP_STATE_MASK;
-
switch (state) {
case BR_STATE_DISABLED:
hw_state = PORT_CTRL_DIS_STATE;
@@ -1433,26 +1429,20 @@ static void b53_br_set_stp_state(struct dsa_switch *ds, int port,
return;
}
- /* Fast-age ARL entries if we are moving a port from Learning or
- * Forwarding (cur_hw_state) state to Disabled, Blocking or Listening
- * state (hw_state)
- */
- if (cur_hw_state != hw_state) {
- if (cur_hw_state >= PORT_CTRL_LEARN_STATE &&
- hw_state <= PORT_CTRL_LISTEN_STATE) {
- if (b53_fast_age_port(dev, port)) {
- dev_err(ds->dev, "fast ageing failed\n");
- return;
- }
- }
- }
-
b53_read8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), ®);
reg &= ~PORT_CTRL_STP_STATE_MASK;
reg |= hw_state;
b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg);
}
+static void b53_br_fast_age(struct dsa_switch *ds, int port, u8 state)
+{
+ struct b53_device *dev = ds->priv;
+
+ if (b53_fast_age_port(dev, port))
+ dev_err(ds->dev, "fast ageing failed\n");
+}
+
static enum dsa_tag_protocol b53_get_tag_protocol(struct dsa_switch *ds)
{
return DSA_TAG_PROTO_NONE;
@@ -1472,6 +1462,7 @@ static struct dsa_switch_ops b53_switch_ops = {
.port_bridge_join = b53_br_join,
.port_bridge_leave = b53_br_leave,
.port_stp_state_set = b53_br_set_stp_state,
+ .port_fast_age = b53_br_fast_age,
.port_vlan_filtering = b53_vlan_filtering,
.port_vlan_prepare = b53_vlan_prepare,
.port_vlan_add = b53_vlan_add,
--
2.10.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* [PATCH net-next 4/4] net: dsa: mv88e6xxx: implement DSA port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
` (2 preceding siblings ...)
2016-09-22 20:49 ` [PATCH net-next 3/4] net: dsa: b53: implement DSA " Vivien Didelot
@ 2016-09-22 20:49 ` Vivien Didelot
2016-09-22 23:43 ` [PATCH net-next 0/4] net: dsa: add " Andrew Lunn
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Vivien Didelot @ 2016-09-22 20:49 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, kernel, David S. Miller, Florian Fainelli,
Andrew Lunn, John Crispin, Vivien Didelot
Now that the DSA layer handles port fast ageing on correct STP change,
simplify _mv88e6xxx_port_state and implement mv88e6xxx_port_fast_age.
Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 45 ++++++++++++++++++++--------------------
1 file changed, 23 insertions(+), 22 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 25bd3fa..122876c 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1133,31 +1133,18 @@ static int _mv88e6xxx_port_state(struct mv88e6xxx_chip *chip, int port,
oldstate = reg & PORT_CONTROL_STATE_MASK;
- if (oldstate != state) {
- /* Flush forwarding database if we're moving a port
- * from Learning or Forwarding state to Disabled or
- * Blocking or Listening state.
- */
- if ((oldstate == PORT_CONTROL_STATE_LEARNING ||
- oldstate == PORT_CONTROL_STATE_FORWARDING) &&
- (state == PORT_CONTROL_STATE_DISABLED ||
- state == PORT_CONTROL_STATE_BLOCKING)) {
- err = _mv88e6xxx_atu_remove(chip, 0, port, false);
- if (err)
- return err;
- }
+ reg &= ~PORT_CONTROL_STATE_MASK;
+ reg |= state;
- reg = (reg & ~PORT_CONTROL_STATE_MASK) | state;
- err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
- if (err)
- return err;
+ err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+ if (err)
+ return err;
- netdev_dbg(ds->ports[port].netdev, "PortState %s (was %s)\n",
- mv88e6xxx_port_state_names[state],
- mv88e6xxx_port_state_names[oldstate]);
- }
+ netdev_dbg(ds->ports[port].netdev, "PortState %s (was %s)\n",
+ mv88e6xxx_port_state_names[state],
+ mv88e6xxx_port_state_names[oldstate]);
- return err;
+ return 0;
}
static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
@@ -1232,6 +1219,19 @@ static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
mv88e6xxx_port_state_names[stp_state]);
}
+static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+ int err;
+
+ mutex_lock(&chip->reg_lock);
+ err = _mv88e6xxx_atu_remove(chip, 0, port, false);
+ mutex_unlock(&chip->reg_lock);
+
+ if (err)
+ netdev_err(ds->ports[port].netdev, "failed to flush ATU\n");
+}
+
static int _mv88e6xxx_port_pvid(struct mv88e6xxx_chip *chip, int port,
u16 *new, u16 *old)
{
@@ -3684,6 +3684,7 @@ static struct dsa_switch_ops mv88e6xxx_switch_ops = {
.port_bridge_join = mv88e6xxx_port_bridge_join,
.port_bridge_leave = mv88e6xxx_port_bridge_leave,
.port_stp_state_set = mv88e6xxx_port_stp_state_set,
+ .port_fast_age = mv88e6xxx_port_fast_age,
.port_vlan_filtering = mv88e6xxx_port_vlan_filtering,
.port_vlan_prepare = mv88e6xxx_port_vlan_prepare,
.port_vlan_add = mv88e6xxx_port_vlan_add,
--
2.10.0
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH net-next 0/4] net: dsa: add port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
` (3 preceding siblings ...)
2016-09-22 20:49 ` [PATCH net-next 4/4] net: dsa: mv88e6xxx: " Vivien Didelot
@ 2016-09-22 23:43 ` Andrew Lunn
2016-09-23 5:36 ` Florian Fainelli
2016-09-23 12:01 ` David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2016-09-22 23:43 UTC (permalink / raw)
To: Vivien Didelot
Cc: netdev, linux-kernel, kernel, David S. Miller, Florian Fainelli,
John Crispin
On Thu, Sep 22, 2016 at 04:49:20PM -0400, Vivien Didelot wrote:
> Today the DSA drivers are in charge of flushing the MAC addresses
> associated to a port when its STP state changes from Learning or
> Forwarding, to Disabled or Blocking or Listening.
>
> This makes the drivers more complex and hides this generic switch logic.
>
> This patchset introduces a new optional port_fast_age operation to
> dsa_switch_ops, to move this logic to the DSA layer and keep drivers
> simple. b53 and mv88e6xxx are updated accordingly.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Andrew
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next 0/4] net: dsa: add port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
` (4 preceding siblings ...)
2016-09-22 23:43 ` [PATCH net-next 0/4] net: dsa: add " Andrew Lunn
@ 2016-09-23 5:36 ` Florian Fainelli
2016-09-23 12:01 ` David Miller
6 siblings, 0 replies; 8+ messages in thread
From: Florian Fainelli @ 2016-09-23 5:36 UTC (permalink / raw)
To: Vivien Didelot, netdev
Cc: linux-kernel, kernel, David S. Miller, Andrew Lunn, John Crispin
On 09/22/2016 01:49 PM, Vivien Didelot wrote:
> Today the DSA drivers are in charge of flushing the MAC addresses
> associated to a port when its STP state changes from Learning or
> Forwarding, to Disabled or Blocking or Listening.
>
> This makes the drivers more complex and hides this generic switch logic.
>
> This patchset introduces a new optional port_fast_age operation to
> dsa_switch_ops, to move this logic to the DSA layer and keep drivers
> simple. b53 and mv88e6xxx are updated accordingly.
This looks good, just one minor thing, both the b53 and mv88e6xxx can
actually return an error from fast ageing a port, should we account for
that? Not that we would be doing something about it though...
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Vivien Didelot (4):
> net: dsa: add port STP state helper
> net: dsa: add port fast ageing
> net: dsa: b53: implement DSA port fast ageing
> net: dsa: mv88e6xxx: implement DSA port fast ageing
>
> drivers/net/dsa/b53/b53_common.c | 31 ++++++++++-----------------
> drivers/net/dsa/mv88e6xxx/chip.c | 45 ++++++++++++++++++++--------------------
> include/net/dsa.h | 2 ++
> net/dsa/slave.c | 35 ++++++++++++++++++++++++-------
> 4 files changed, 64 insertions(+), 49 deletions(-)
>
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH net-next 0/4] net: dsa: add port fast ageing
2016-09-22 20:49 [PATCH net-next 0/4] net: dsa: add port fast ageing Vivien Didelot
` (5 preceding siblings ...)
2016-09-23 5:36 ` Florian Fainelli
@ 2016-09-23 12:01 ` David Miller
6 siblings, 0 replies; 8+ messages in thread
From: David Miller @ 2016-09-23 12:01 UTC (permalink / raw)
To: vivien.didelot; +Cc: netdev, linux-kernel, kernel, f.fainelli, andrew, john
From: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Date: Thu, 22 Sep 2016 16:49:20 -0400
> Today the DSA drivers are in charge of flushing the MAC addresses
> associated to a port when its STP state changes from Learning or
> Forwarding, to Disabled or Blocking or Listening.
>
> This makes the drivers more complex and hides this generic switch logic.
>
> This patchset introduces a new optional port_fast_age operation to
> dsa_switch_ops, to move this logic to the DSA layer and keep drivers
> simple. b53 and mv88e6xxx are updated accordingly.
Series applied, thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread