OSDN Git Service

net: dsa: lantiq: Add fast age function
authorHauke Mehrtens <hauke@hauke-m.de>
Sun, 5 May 2019 22:25:09 +0000 (00:25 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 7 May 2019 17:34:45 +0000 (10:34 -0700)
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>
drivers/net/dsa/lantiq_gswip.c

index c62d923..80afd3b 100644 (file)
 
 #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,