diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2019-05-06 00:25:09 +0200 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-07 10:34:45 -0700 |
commit | 4581348199ca189b1943a7c5fc3950003310fa37 (patch) | |
tree | 9ccc05d6eb8ce54019a31d6766bf9c426654ebd1 /drivers/net/dsa/lantiq_gswip.c | |
parent | 9bbb1c053bdcfba075ffb703c4b865297c3fee02 (diff) | |
download | linux-stable-4581348199ca189b1943a7c5fc3950003310fa37.tar.gz linux-stable-4581348199ca189b1943a7c5fc3950003310fa37.tar.bz2 linux-stable-4581348199ca189b1943a7c5fc3950003310fa37.zip |
net: dsa: lantiq: Add fast age function
Fast aging per port is not supported directly by the hardware, it is
only possible to configure a global aging time.
Do the fast aging by iterating over the MAC forwarding table and remove
all dynamic entries for a given port.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/lantiq_gswip.c')
-rw-r--r-- | drivers/net/dsa/lantiq_gswip.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index c62d923377e3..80afd3b9fd80 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c @@ -213,6 +213,8 @@ #define GSWIP_TABLE_ACTIVE_VLAN 0x01 #define GSWIP_TABLE_VLAN_MAPPING 0x02 +#define GSWIP_TABLE_MAC_BRIDGE 0x0b +#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */ #define XRX200_GPHY_FW_ALIGN (16 * 1024) @@ -1220,6 +1222,43 @@ static int gswip_port_vlan_del(struct dsa_switch *ds, int port, return 0; } +static void gswip_port_fast_age(struct dsa_switch *ds, int port) +{ + struct gswip_priv *priv = ds->priv; + struct gswip_pce_table_entry mac_bridge = {0,}; + int i; + int err; + + for (i = 0; i < 2048; i++) { + mac_bridge.table = GSWIP_TABLE_MAC_BRIDGE; + mac_bridge.index = i; + + err = gswip_pce_table_entry_read(priv, &mac_bridge); + if (err) { + dev_err(priv->dev, "failed to read mac brigde: %d\n", + err); + return; + } + + if (!mac_bridge.valid) + continue; + + if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC) + continue; + + if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port) + continue; + + mac_bridge.valid = false; + err = gswip_pce_table_entry_write(priv, &mac_bridge); + if (err) { + dev_err(priv->dev, "failed to write mac brigde: %d\n", + err); + return; + } + } +} + static void gswip_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) { struct gswip_priv *priv = ds->priv; @@ -1460,6 +1499,7 @@ static const struct dsa_switch_ops gswip_switch_ops = { .port_disable = gswip_port_disable, .port_bridge_join = gswip_port_bridge_join, .port_bridge_leave = gswip_port_bridge_leave, + .port_fast_age = gswip_port_fast_age, .port_vlan_filtering = gswip_port_vlan_filtering, .port_vlan_prepare = gswip_port_vlan_prepare, .port_vlan_add = gswip_port_vlan_add, |