Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 877cd9ff authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 5a1c492b 79b139f4
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+0 −9
Original line number Diff line number Diff line
@@ -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);

+34 −46
Original line number Diff line number Diff line
@@ -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 @@ static int dsa_slave_switchdev_event(struct notifier_block *unused,
	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;