Commit 5010ea59 authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-next'

Vivien Didelot says:

====================
net: dsa: push switchdev prepare phase in FDB ops

This patchset pushes the switchdev prepare phase for the FDB add and del
operations down to the DSA drivers. Currently only mv88e6xxx is affected.

Since the dump requires a bit of refactoring in the driver, it'll come in a
future patchset.

Changes in v2:
 * forward declare switchdev structs instead of fixing the dsa.h include.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6e86ac12 8057b3e7
...@@ -121,6 +121,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = { ...@@ -121,6 +121,7 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
.port_vlan_add = mv88e6xxx_port_vlan_add, .port_vlan_add = mv88e6xxx_port_vlan_add,
.port_vlan_del = mv88e6xxx_port_vlan_del, .port_vlan_del = mv88e6xxx_port_vlan_del,
.vlan_getnext = mv88e6xxx_vlan_getnext, .vlan_getnext = mv88e6xxx_vlan_getnext,
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
.port_fdb_add = mv88e6xxx_port_fdb_add, .port_fdb_add = mv88e6xxx_port_fdb_add,
.port_fdb_del = mv88e6xxx_port_fdb_del, .port_fdb_del = mv88e6xxx_port_fdb_del,
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext, .port_fdb_getnext = mv88e6xxx_port_fdb_getnext,
......
...@@ -348,6 +348,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = { ...@@ -348,6 +348,7 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
.port_vlan_add = mv88e6xxx_port_vlan_add, .port_vlan_add = mv88e6xxx_port_vlan_add,
.port_vlan_del = mv88e6xxx_port_vlan_del, .port_vlan_del = mv88e6xxx_port_vlan_del,
.vlan_getnext = mv88e6xxx_vlan_getnext, .vlan_getnext = mv88e6xxx_vlan_getnext,
.port_fdb_prepare = mv88e6xxx_port_fdb_prepare,
.port_fdb_add = mv88e6xxx_port_fdb_add, .port_fdb_add = mv88e6xxx_port_fdb_add,
.port_fdb_del = mv88e6xxx_port_fdb_del, .port_fdb_del = mv88e6xxx_port_fdb_del,
.port_fdb_getnext = mv88e6xxx_port_fdb_getnext, .port_fdb_getnext = mv88e6xxx_port_fdb_getnext,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/phy.h> #include <linux/phy.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <net/dsa.h> #include <net/dsa.h>
#include <net/switchdev.h>
#include "mv88e6xxx.h" #include "mv88e6xxx.h"
/* MDIO bus access can be nested in the case of PHYs connected to the /* MDIO bus access can be nested in the case of PHYs connected to the
...@@ -1841,30 +1842,41 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port, ...@@ -1841,30 +1842,41 @@ static int _mv88e6xxx_port_fdb_load(struct dsa_switch *ds, int port,
return _mv88e6xxx_atu_load(ds, &entry); 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, int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid) const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans)
{ {
int state = is_multicast_ether_addr(addr) ? int state = is_multicast_ether_addr(fdb->addr) ?
GLOBAL_ATU_DATA_STATE_MC_STATIC : GLOBAL_ATU_DATA_STATE_MC_STATIC :
GLOBAL_ATU_DATA_STATE_UC_STATIC; GLOBAL_ATU_DATA_STATE_UC_STATIC;
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret; int ret;
mutex_lock(&ps->smi_mutex); mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_fdb_load(ds, port, addr, vid, state); ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid, state);
mutex_unlock(&ps->smi_mutex); mutex_unlock(&ps->smi_mutex);
return ret; return ret;
} }
int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid) const struct switchdev_obj_port_fdb *fdb)
{ {
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret; int ret;
mutex_lock(&ps->smi_mutex); mutex_lock(&ps->smi_mutex);
ret = _mv88e6xxx_port_fdb_load(ds, port, addr, vid, ret = _mv88e6xxx_port_fdb_load(ds, port, fdb->addr, fdb->vid,
GLOBAL_ATU_DATA_STATE_UNUSED); GLOBAL_ATU_DATA_STATE_UNUSED);
mutex_unlock(&ps->smi_mutex); mutex_unlock(&ps->smi_mutex);
......
...@@ -474,10 +474,14 @@ int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid, ...@@ -474,10 +474,14 @@ 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_port_vlan_del(struct dsa_switch *ds, int port, u16 vid);
int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid, int mv88e6xxx_vlan_getnext(struct dsa_switch *ds, u16 *vid,
unsigned long *ports, unsigned long *untagged); 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, int mv88e6xxx_port_fdb_add(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid); const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans);
int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port, int mv88e6xxx_port_fdb_del(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid); const struct switchdev_obj_port_fdb *fdb);
int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port, int mv88e6xxx_port_fdb_getnext(struct dsa_switch *ds, int port,
unsigned char *addr, u16 *vid, bool *is_static); unsigned char *addr, u16 *vid, bool *is_static);
int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg); int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg);
......
...@@ -197,6 +197,9 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds) ...@@ -197,6 +197,9 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
return ds->pd->rtable[dst->cpu_switch]; return ds->pd->rtable[dst->cpu_switch];
} }
struct switchdev_trans;
struct switchdev_obj_port_fdb;
struct dsa_switch_driver { struct dsa_switch_driver {
struct list_head list; struct list_head list;
...@@ -316,10 +319,14 @@ struct dsa_switch_driver { ...@@ -316,10 +319,14 @@ struct dsa_switch_driver {
/* /*
* Forwarding database * 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, int (*port_fdb_add)(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid); const struct switchdev_obj_port_fdb *fdb,
struct switchdev_trans *trans);
int (*port_fdb_del)(struct dsa_switch *ds, int port, int (*port_fdb_del)(struct dsa_switch *ds, int port,
const unsigned char *addr, u16 vid); const struct switchdev_obj_port_fdb *fdb);
int (*port_fdb_getnext)(struct dsa_switch *ds, int port, int (*port_fdb_getnext)(struct dsa_switch *ds, int port,
unsigned char *addr, u16 *vid, unsigned char *addr, u16 *vid,
bool *is_static); bool *is_static);
......
...@@ -346,12 +346,15 @@ static int dsa_slave_port_fdb_add(struct net_device *dev, ...@@ -346,12 +346,15 @@ static int dsa_slave_port_fdb_add(struct net_device *dev,
{ {
struct dsa_slave_priv *p = netdev_priv(dev); struct dsa_slave_priv *p = netdev_priv(dev);
struct dsa_switch *ds = p->parent; 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)) 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 else
ret = ds->drv->port_fdb_add(ds, p->port, fdb->addr, fdb->vid); ret = ds->drv->port_fdb_add(ds, p->port, fdb, trans);
return ret; return ret;
} }
...@@ -364,7 +367,7 @@ static int dsa_slave_port_fdb_del(struct net_device *dev, ...@@ -364,7 +367,7 @@ static int dsa_slave_port_fdb_del(struct net_device *dev,
int ret = -EOPNOTSUPP; int ret = -EOPNOTSUPP;
if (ds->drv->port_fdb_del) if (ds->drv->port_fdb_del)
ret = ds->drv->port_fdb_del(ds, p->port, fdb->addr, fdb->vid); ret = ds->drv->port_fdb_del(ds, p->port, fdb);
return ret; return ret;
} }
......
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