Merge branch 'net-dsa-use-switchdev-attr-and-obj-handlers'
Vivien Didelot says: ==================== net: dsa: use switchdev attr and obj handlers This series reduces boilerplate in the handling of switchdev attribute and object operations by using the switchdev_handle_* helpers, which check the targeted devices and recurse into their lower devices. This also brings back the ability to inspect operations targeting the bridge device itself (where .orig_dev and .dev were originally the bridge device), even though that is of no use yet and skipped by this series. Changes in v2: Only VLAN and (non-host) MDB objects not directly targeting the slave device are unsupported at the moment, so only skip these cases. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
877cd9ffbc
|
@ -181,7 +181,7 @@ struct dsa_port {
|
|||
struct dsa_switch *ds;
|
||||
unsigned int index;
|
||||
const char *name;
|
||||
const struct dsa_port *cpu_dp;
|
||||
struct dsa_port *cpu_dp;
|
||||
const char *mac;
|
||||
struct device_node *dn;
|
||||
unsigned int ageing_time;
|
||||
|
|
|
@ -336,9 +336,6 @@ int dsa_port_vlan_add(struct dsa_port *dp,
|
|||
.vlan = vlan,
|
||||
};
|
||||
|
||||
/* Can be called from dsa_slave_port_obj_add() or
|
||||
* dsa_slave_vlan_rx_add_vid()
|
||||
*/
|
||||
if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
|
||||
return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info);
|
||||
|
||||
|
@ -354,12 +351,6 @@ int dsa_port_vlan_del(struct dsa_port *dp,
|
|||
.vlan = vlan,
|
||||
};
|
||||
|
||||
if (vlan->obj.orig_dev && netif_is_bridge_master(vlan->obj.orig_dev))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Can be called from dsa_slave_port_obj_del() or
|
||||
* dsa_slave_vlan_rx_kill_vid()
|
||||
*/
|
||||
if (!dp->bridge_dev || br_vlan_enabled(dp->bridge_dev))
|
||||
return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "dsa_priv.h"
|
||||
|
||||
static bool dsa_slave_dev_check(struct net_device *dev);
|
||||
static bool dsa_slave_dev_check(const struct net_device *dev);
|
||||
|
||||
/* slave mii_bus handling ***************************************************/
|
||||
static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
|
||||
|
@ -311,7 +311,8 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
|
|||
|
||||
static int dsa_slave_port_obj_add(struct net_device *dev,
|
||||
const struct switchdev_obj *obj,
|
||||
struct switchdev_trans *trans)
|
||||
struct switchdev_trans *trans,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
int err;
|
||||
|
@ -323,6 +324,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
|
|||
|
||||
switch (obj->id) {
|
||||
case SWITCHDEV_OBJ_ID_PORT_MDB:
|
||||
if (obj->orig_dev != dev)
|
||||
return -EOPNOTSUPP;
|
||||
err = dsa_port_mdb_add(dp, SWITCHDEV_OBJ_PORT_MDB(obj), trans);
|
||||
break;
|
||||
case SWITCHDEV_OBJ_ID_HOST_MDB:
|
||||
|
@ -333,6 +336,8 @@ static int dsa_slave_port_obj_add(struct net_device *dev,
|
|||
trans);
|
||||
break;
|
||||
case SWITCHDEV_OBJ_ID_PORT_VLAN:
|
||||
if (obj->orig_dev != dev)
|
||||
return -EOPNOTSUPP;
|
||||
err = dsa_port_vlan_add(dp, SWITCHDEV_OBJ_PORT_VLAN(obj),
|
||||
trans);
|
||||
break;
|
||||
|
@ -352,6 +357,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
|
|||
|
||||
switch (obj->id) {
|
||||
case SWITCHDEV_OBJ_ID_PORT_MDB:
|
||||
if (obj->orig_dev != dev)
|
||||
return -EOPNOTSUPP;
|
||||
err = dsa_port_mdb_del(dp, SWITCHDEV_OBJ_PORT_MDB(obj));
|
||||
break;
|
||||
case SWITCHDEV_OBJ_ID_HOST_MDB:
|
||||
|
@ -361,6 +368,8 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
|
|||
err = dsa_port_mdb_del(dp->cpu_dp, SWITCHDEV_OBJ_PORT_MDB(obj));
|
||||
break;
|
||||
case SWITCHDEV_OBJ_ID_PORT_VLAN:
|
||||
if (obj->orig_dev != dev)
|
||||
return -EOPNOTSUPP;
|
||||
err = dsa_port_vlan_del(dp, SWITCHDEV_OBJ_PORT_VLAN(obj));
|
||||
break;
|
||||
default:
|
||||
|
@ -1408,7 +1417,7 @@ void dsa_slave_destroy(struct net_device *slave_dev)
|
|||
free_netdev(slave_dev);
|
||||
}
|
||||
|
||||
static bool dsa_slave_dev_check(struct net_device *dev)
|
||||
static bool dsa_slave_dev_check(const struct net_device *dev)
|
||||
{
|
||||
return dev->netdev_ops == &dsa_slave_netdev_ops;
|
||||
}
|
||||
|
@ -1479,19 +1488,6 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
|
|||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int
|
||||
dsa_slave_switchdev_port_attr_set_event(struct net_device *netdev,
|
||||
struct switchdev_notifier_port_attr_info *port_attr_info)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = dsa_slave_port_attr_set(netdev, port_attr_info->attr,
|
||||
port_attr_info->trans);
|
||||
|
||||
port_attr_info->handled = true;
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
struct dsa_switchdev_event_work {
|
||||
struct work_struct work;
|
||||
struct switchdev_notifier_fdb_info fdb_info;
|
||||
|
@ -1566,13 +1562,18 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
|
|||
{
|
||||
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
||||
struct dsa_switchdev_event_work *switchdev_work;
|
||||
int err;
|
||||
|
||||
if (event == SWITCHDEV_PORT_ATTR_SET) {
|
||||
err = switchdev_handle_port_attr_set(dev, ptr,
|
||||
dsa_slave_dev_check,
|
||||
dsa_slave_port_attr_set);
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
if (!dsa_slave_dev_check(dev))
|
||||
return NOTIFY_DONE;
|
||||
|
||||
if (event == SWITCHDEV_PORT_ATTR_SET)
|
||||
return dsa_slave_switchdev_port_attr_set_event(dev, ptr);
|
||||
|
||||
switchdev_work = kzalloc(sizeof(*switchdev_work), GFP_ATOMIC);
|
||||
if (!switchdev_work)
|
||||
return NOTIFY_BAD;
|
||||
|
@ -1602,41 +1603,28 @@ err_fdb_work_init:
|
|||
return NOTIFY_BAD;
|
||||
}
|
||||
|
||||
static int
|
||||
dsa_slave_switchdev_port_obj_event(unsigned long event,
|
||||
struct net_device *netdev,
|
||||
struct switchdev_notifier_port_obj_info *port_obj_info)
|
||||
{
|
||||
int err = -EOPNOTSUPP;
|
||||
|
||||
switch (event) {
|
||||
case SWITCHDEV_PORT_OBJ_ADD:
|
||||
err = dsa_slave_port_obj_add(netdev, port_obj_info->obj,
|
||||
port_obj_info->trans);
|
||||
break;
|
||||
case SWITCHDEV_PORT_OBJ_DEL:
|
||||
err = dsa_slave_port_obj_del(netdev, port_obj_info->obj);
|
||||
break;
|
||||
}
|
||||
|
||||
port_obj_info->handled = true;
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
static int dsa_slave_switchdev_blocking_event(struct notifier_block *unused,
|
||||
unsigned long event, void *ptr)
|
||||
{
|
||||
struct net_device *dev = switchdev_notifier_info_to_dev(ptr);
|
||||
|
||||
if (!dsa_slave_dev_check(dev))
|
||||
return NOTIFY_DONE;
|
||||
int err;
|
||||
|
||||
switch (event) {
|
||||
case SWITCHDEV_PORT_OBJ_ADD: /* fall through */
|
||||
case SWITCHDEV_PORT_OBJ_ADD:
|
||||
err = switchdev_handle_port_obj_add(dev, ptr,
|
||||
dsa_slave_dev_check,
|
||||
dsa_slave_port_obj_add);
|
||||
return notifier_from_errno(err);
|
||||
case SWITCHDEV_PORT_OBJ_DEL:
|
||||
return dsa_slave_switchdev_port_obj_event(event, dev, ptr);
|
||||
err = switchdev_handle_port_obj_del(dev, ptr,
|
||||
dsa_slave_dev_check,
|
||||
dsa_slave_port_obj_del);
|
||||
return notifier_from_errno(err);
|
||||
case SWITCHDEV_PORT_ATTR_SET:
|
||||
return dsa_slave_switchdev_port_attr_set_event(dev, ptr);
|
||||
err = switchdev_handle_port_attr_set(dev, ptr,
|
||||
dsa_slave_dev_check,
|
||||
dsa_slave_port_attr_set);
|
||||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
|
|
Loading…
Reference in New Issue