From 1faabf7440f17999f41973e91878c13ad9f080b2 Mon Sep 17 00:00:00 2001 From: Vivien Didelot Date: Fri, 19 May 2017 17:00:52 -0400 Subject: net: dsa: add notifier for ageing time This patch keeps the port-wide ageing time handling code in dsa_port_ageing_time, pushes the requested ageing time value in a new switch fabric notification, and moves the switch-wide ageing time handling code in dsa_switch_ageing_time. This has the effect that now not only the switch that the target port belongs to can be programmed, but all switches composing the switch fabric. For the moment, keep the current behavior and ignore other switches. Signed-off-by: Vivien Didelot Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- net/dsa/switch.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'net/dsa/switch.c') diff --git a/net/dsa/switch.c b/net/dsa/switch.c index f477053308d2..540770ecc8b0 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -12,9 +12,52 @@ #include #include +#include #include "dsa_priv.h" +static unsigned int dsa_switch_fastest_ageing_time(struct dsa_switch *ds, + unsigned int ageing_time) +{ + int i; + + for (i = 0; i < ds->num_ports; ++i) { + struct dsa_port *dp = &ds->ports[i]; + + if (dp->ageing_time && dp->ageing_time < ageing_time) + ageing_time = dp->ageing_time; + } + + return ageing_time; +} + +static int dsa_switch_ageing_time(struct dsa_switch *ds, + struct dsa_notifier_ageing_time_info *info) +{ + unsigned int ageing_time = info->ageing_time; + struct switchdev_trans *trans = info->trans; + + /* Do not care yet about other switch chips of the fabric */ + if (ds->index != info->sw_index) + return 0; + + if (switchdev_trans_ph_prepare(trans)) { + if (ds->ageing_time_min && ageing_time < ds->ageing_time_min) + return -ERANGE; + if (ds->ageing_time_max && ageing_time > ds->ageing_time_max) + return -ERANGE; + return 0; + } + + /* Program the fastest ageing time in case of multiple bridges */ + ageing_time = dsa_switch_fastest_ageing_time(ds, ageing_time); + + if (ds->ops->set_ageing_time) + return ds->ops->set_ageing_time(ds, ageing_time); + + return 0; +} + static int dsa_switch_bridge_join(struct dsa_switch *ds, struct dsa_notifier_bridge_info *info) { @@ -48,6 +91,9 @@ static int dsa_switch_event(struct notifier_block *nb, int err; switch (event) { + case DSA_NOTIFIER_AGEING_TIME: + err = dsa_switch_ageing_time(ds, info); + break; case DSA_NOTIFIER_BRIDGE_JOIN: err = dsa_switch_bridge_join(ds, info); break; -- cgit v1.2.3