net: dsa: add port_fdb_prepare
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Thu, 8 Oct 2015 15:35:12 +0000 (11:35 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 11 Oct 2015 12:28:49 +0000 (05:28 -0700)
Push the prepare phase for FDB operations down to the DSA drivers, with
a new port_fdb_prepare function. Currently only mv88e6xxx is affected.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6171.c
drivers/net/dsa/mv88e6352.c
drivers/net/dsa/mv88e6xxx.c
drivers/net/dsa/mv88e6xxx.h
include/net/dsa.h
net/dsa/slave.c

index c95cfab56a4f3560aad93612e6eba0fc5c1c14ed..ca3330aec7402759e08eb6162392f387cfc8b609 100644 (file)
@@ -121,6 +121,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
        .port_vlan_add          = mv88e6xxx_port_vlan_add,
        .port_vlan_del          = mv88e6xxx_port_vlan_del,
        .vlan_getnext           = mv88e6xxx_vlan_getnext,
+       .port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
        .port_fdb_add           = mv88e6xxx_port_fdb_add,
        .port_fdb_del           = mv88e6xxx_port_fdb_del,
        .port_fdb_getnext       = mv88e6xxx_port_fdb_getnext,
index 37367060676f1881a0603527d0954ef16a6d76f7..078a358c1b8322c9e67199bcefe45ebfd2935061 100644 (file)
@@ -348,6 +348,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
        .port_vlan_add          = mv88e6xxx_port_vlan_add,
        .port_vlan_del          = mv88e6xxx_port_vlan_del,
        .vlan_getnext           = mv88e6xxx_vlan_getnext,
+       .port_fdb_prepare       = mv88e6xxx_port_fdb_prepare,
        .port_fdb_add           = mv88e6xxx_port_fdb_add,
        .port_fdb_del           = mv88e6xxx_port_fdb_del,
        .port_fdb_getnext       = mv88e6xxx_port_fdb_getnext,
index 8e088e35583436fc111cfe3ca96a130828822c7a..0da865171798a99e0c2dba1a1b079cb16f5359bd 100644 (file)
@@ -1841,6 +1841,16 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
        return _mv88e6xxx_atu_load(ds, &entry);
 }
 
+int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
+                              const struct switchdev_obj_port_fdb *fdb,
+                              struct switchdev_trans *trans)
+{
+       /* We don't need any dynamic resource from the kernel (yet),
+        * so skip the prepare phase.
+        */
+       return 0;
+}
+
 int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
                           const unsigned char *addr, u16 vid)
 {
index d8ec48710b80e11669d51c296f6f4ae7c5178bf2..3042869246426d5a744d55884923b2c38f65cc27 100644 (file)
@@ -474,6 +474,9 @@ int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
 int mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid);
 int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
                           unsigned long *ports, unsigned long *untagged);
+int mv88e6xxx_port_fdb_prepare(struct dsa_switch *ds, int port,
+                              const struct switchdev_obj_port_fdb *fdb,
+                              struct switchdev_trans *trans);
 int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
                           const unsigned char *addr, u16 vid);
 int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
index b34d812bc5d056d47b7d39181668572cde4f53ca..4f66f8411583fa0fc4ae9607a5003864782d1f8d 100644 (file)
@@ -197,6 +197,9 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
                return ds->pd->rtable[dst->cpu_switch];
 }
 
+struct switchdev_trans;
+struct switchdev_obj_port_fdb;
+
 struct dsa_switch_driver {
        struct list_head        list;
 
@@ -316,6 +319,9 @@ struct dsa_switch_driver {
        /*
         * Forwarding database
         */
+       int     (*port_fdb_prepare)(struct dsa_switch *ds, int port,
+                                   const struct switchdev_obj_port_fdb *fdb,
+                                   struct switchdev_trans *trans);
        int     (*port_fdb_add)(struct dsa_switch *ds, int port,
                                const unsigned char *addr, u16 vid);
        int     (*port_fdb_del)(struct dsa_switch *ds, int port,
index 4f607bc2a8451cd5edc286480004e6dd68c1c8a5..48e8c15a2611bfc3c8cefa387832ca76380b1260 100644 (file)
@@ -346,10 +346,13 @@ static int dsa_slave_port_fdb_add(struct net_device *dev,
 {
        struct dsa_slave_priv *p = netdev_priv(dev);
        struct dsa_switch *ds = p->parent;
-       int ret = -EOPNOTSUPP;
+       int ret;
+
+       if (!ds->drv->port_fdb_prepare || !ds->drv->port_fdb_add)
+               return -EOPNOTSUPP;
 
        if (switchdev_trans_ph_prepare(trans))
-               ret = ds->drv->port_fdb_add ? 0 : -EOPNOTSUPP;
+               ret = ds->drv->port_fdb_prepare(ds, p->port, fdb, trans);
        else
                ret = ds->drv->port_fdb_add(ds, p->port, fdb->addr, fdb->vid);