All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit 34a79f63 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: support switchdev ageing time attr

Add a new function for DSA drivers to handle the switchdev
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME attribute.

The ageing time is passed as milliseconds.

Also because we can have multiple logical bridges on top of a physical
switch and ageing time are switch-wide, call the driver function with
the fastest ageing time in use on the chip instead of the requested one.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8ec61c7f
......@@ -141,6 +141,7 @@ struct dsa_switch_tree {
struct dsa_port {
struct net_device *netdev;
struct device_node *dn;
unsigned int ageing_time;
};
struct dsa_switch {
......@@ -329,6 +330,7 @@ struct dsa_switch_driver {
/*
* Bridge integration
*/
int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct net_device *bridge);
void (*port_bridge_leave)(struct dsa_switch *ds, int port);
......
......@@ -333,6 +333,44 @@ static int dsa_slave_vlan_filtering(struct net_device *dev,
return 0;
}
static int dsa_fastest_ageing_time(struct dsa_switch *ds,
unsigned int ageing_time)
{
int i;
for (i = 0; i < DSA_MAX_PORTS; ++i) {
struct dsa_port *dp = &ds->ports[i];
if (dp && dp->ageing_time && dp->ageing_time < ageing_time)
ageing_time = dp->ageing_time;
}
return ageing_time;
}
static int dsa_slave_ageing_time(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans)
{
struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent;
unsigned long ageing_jiffies = clock_t_to_jiffies(attr->u.ageing_time);
unsigned int ageing_time = jiffies_to_msecs(ageing_jiffies);
/* bridge skips -EOPNOTSUPP, so skip the prepare phase */
if (switchdev_trans_ph_prepare(trans))
return 0;
/* Keep the fastest ageing time in case of multiple bridges */
ds->ports[p->port].ageing_time = ageing_time;
ageing_time = dsa_fastest_ageing_time(ds, ageing_time);
if (ds->drv->set_ageing_time)
return ds->drv->set_ageing_time(ds, ageing_time);
return 0;
}
static int dsa_slave_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr,
struct switchdev_trans *trans)
......@@ -346,6 +384,9 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
case SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING:
ret = dsa_slave_vlan_filtering(dev, attr, trans);
break;
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
ret = dsa_slave_ageing_time(dev, attr, trans);
break;
default:
ret = -EOPNOTSUPP;
break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment