int port = priv->chip_port;
int err = 0;
+ if (ctx && ctx != priv)
+ return 0;
+
switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
ocelot_port_attr_stp_state_set(ocelot, port, attr->u.stp_state);
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{
+ struct ocelot_port_private *priv = netdev_priv(dev);
int ret = 0;
+ if (ctx && ctx != priv)
+ return 0;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_VLAN:
ret = ocelot_port_obj_add_vlan(dev,
static int ocelot_port_obj_del(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj)
{
+ struct ocelot_port_private *priv = netdev_priv(dev);
int ret = 0;
+ if (ctx && ctx != priv)
+ return 0;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_VLAN:
ret = ocelot_vlan_vid_del(dev,
struct net_device *bridge_dev,
struct netlink_ext_ack *extack)
{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ struct ocelot_port_private *priv;
clock_t ageing_time;
u8 stp_state;
int err;
+ priv = container_of(ocelot_port, struct ocelot_port_private, port);
+
ocelot_inherit_brport_flags(ocelot, port, brport_dev);
stp_state = br_port_get_stp_state(brport_dev);
ageing_time = br_get_ageing_time(bridge_dev);
ocelot_port_attr_ageing_set(ocelot, port, ageing_time);
- err = br_mdb_replay(bridge_dev, brport_dev,
+ err = br_mdb_replay(bridge_dev, brport_dev, priv,
&ocelot_switchdev_blocking_nb, extack);
if (err && err != -EOPNOTSUPP)
return err;
- err = br_vlan_replay(bridge_dev, brport_dev,
+ err = br_vlan_replay(bridge_dev, brport_dev, priv,
&ocelot_switchdev_blocking_nb, extack);
if (err && err != -EOPNOTSUPP)
return err;
bool br_multicast_enabled(const struct net_device *dev);
bool br_multicast_router(const struct net_device *dev);
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb, struct netlink_ext_ack *extack);
+ const void *ctx, struct notifier_block *nb,
+ struct netlink_ext_ack *extack);
#else
static inline int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list)
return false;
}
static inline int br_mdb_replay(struct net_device *br_dev,
- struct net_device *dev,
+ struct net_device *dev, const void *ctx,
struct notifier_block *nb,
struct netlink_ext_ack *extack)
{
int br_vlan_get_info(const struct net_device *dev, u16 vid,
struct bridge_vlan_info *p_vinfo);
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb, struct netlink_ext_ack *extack);
+ const void *ctx, struct notifier_block *nb,
+ struct netlink_ext_ack *extack);
#else
static inline bool br_vlan_enabled(const struct net_device *dev)
{
}
static inline int br_vlan_replay(struct net_device *br_dev,
- struct net_device *dev,
+ struct net_device *dev, const void *ctx,
struct notifier_block *nb,
struct netlink_ext_ack *extack)
{
u8 br_port_get_stp_state(const struct net_device *dev);
clock_t br_get_ageing_time(struct net_device *br_dev);
int br_fdb_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb);
+ const void *ctx, struct notifier_block *nb);
#else
static inline struct net_device *
br_fdb_find_port(const struct net_device *br_dev,
}
static inline int br_fdb_replay(struct net_device *br_dev,
- struct net_device *dev,
+ struct net_device *dev, const void *ctx,
struct notifier_block *nb)
{
return -EOPNOTSUPP;
static int br_fdb_replay_one(struct notifier_block *nb,
struct net_bridge_fdb_entry *fdb,
- struct net_device *dev)
+ struct net_device *dev, const void *ctx)
{
struct switchdev_notifier_fdb_info item;
int err;
item.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags);
item.is_local = test_bit(BR_FDB_LOCAL, &fdb->flags);
item.info.dev = dev;
+ item.info.ctx = ctx;
err = nb->notifier_call(nb, SWITCHDEV_FDB_ADD_TO_DEVICE, &item);
return notifier_to_errno(err);
}
int br_fdb_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb)
+ const void *ctx, struct notifier_block *nb)
{
struct net_bridge_fdb_entry *fdb;
struct net_bridge *br;
if (dst_dev != br_dev && dst_dev != dev)
continue;
- err = br_fdb_replay_one(nb, fdb, dst_dev);
+ err = br_fdb_replay_one(nb, fdb, dst_dev, ctx);
if (err)
break;
}
static int br_mdb_replay_one(struct notifier_block *nb, struct net_device *dev,
struct switchdev_obj_port_mdb *mdb,
- struct netlink_ext_ack *extack)
+ const void *ctx, struct netlink_ext_ack *extack)
{
struct switchdev_notifier_port_obj_info obj_info = {
.info = {
.dev = dev,
.extack = extack,
+ .ctx = ctx,
},
.obj = &mdb->obj,
};
}
int br_mdb_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb, struct netlink_ext_ack *extack)
+ const void *ctx, struct notifier_block *nb,
+ struct netlink_ext_ack *extack)
{
struct net_bridge_mdb_entry *mp;
struct switchdev_obj *obj, *tmp;
list_for_each_entry(obj, &mdb_list, list) {
err = br_mdb_replay_one(nb, dev, SWITCHDEV_OBJ_PORT_MDB(obj),
- extack);
+ ctx, extack);
if (err)
goto out_free_mdb;
}
static int br_vlan_replay_one(struct notifier_block *nb,
struct net_device *dev,
struct switchdev_obj_port_vlan *vlan,
- struct netlink_ext_ack *extack)
+ const void *ctx, struct netlink_ext_ack *extack)
{
struct switchdev_notifier_port_obj_info obj_info = {
.info = {
.dev = dev,
.extack = extack,
+ .ctx = ctx,
},
.obj = &vlan->obj,
};
}
int br_vlan_replay(struct net_device *br_dev, struct net_device *dev,
- struct notifier_block *nb, struct netlink_ext_ack *extack)
+ const void *ctx, struct notifier_block *nb,
+ struct netlink_ext_ack *extack)
{
struct net_bridge_vlan_group *vg;
struct net_bridge_vlan *v;
if (!br_vlan_should_use(v))
continue;
- err = br_vlan_replay_one(nb, dev, &vlan, extack);
+ err = br_vlan_replay_one(nb, dev, &vlan, ctx, extack);
if (err)
return err;
}
if (err && err != -EOPNOTSUPP)
return err;
- err = br_mdb_replay(br, brport_dev,
+ err = br_mdb_replay(br, brport_dev, dp,
&dsa_slave_switchdev_blocking_notifier,
extack);
if (err && err != -EOPNOTSUPP)
return err;
- err = br_fdb_replay(br, brport_dev, &dsa_slave_switchdev_notifier);
+ err = br_fdb_replay(br, brport_dev, dp, &dsa_slave_switchdev_notifier);
if (err && err != -EOPNOTSUPP)
return err;
- err = br_vlan_replay(br, brport_dev,
+ err = br_vlan_replay(br, brport_dev, dp,
&dsa_slave_switchdev_blocking_notifier,
extack);
if (err && err != -EOPNOTSUPP)
struct dsa_port *dp = dsa_slave_to_port(dev);
int ret;
+ if (ctx && ctx != dp)
+ return 0;
+
switch (attr->id) {
case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
if (!dsa_port_offloads_bridge_port(dp, attr->orig_dev))
struct dsa_port *dp = dsa_slave_to_port(dev);
int err;
+ if (ctx && ctx != dp)
+ return 0;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_MDB:
if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))
struct dsa_port *dp = dsa_slave_to_port(dev);
int err;
+ if (ctx && ctx != dp)
+ return 0;
+
switch (obj->id) {
case SWITCHDEV_OBJ_ID_PORT_MDB:
if (!dsa_port_offloads_bridge_port(dp, obj->orig_dev))