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

Commit 0944d6b5 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller
Browse files

bridge: try switchdev op first in __vlan_vid_add/del



Some drivers need to implement both switchdev vlan ops and
vid_add/kill ndos. For that to work in bridge code, we need to try
switchdev op first when adding/deleting vlan id.

Signed-off-by: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarIdo Schimmel <idosch@mellanox.com>
Acked-by: default avatarScott Feldman <sfeldma@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3703ebe4
Loading
Loading
Loading
Loading
+22 −36
Original line number Diff line number Diff line
@@ -72,28 +72,20 @@ static void __vlan_add_flags(struct net_bridge_vlan *v, u16 flags)
static int __vlan_vid_add(struct net_device *dev, struct net_bridge *br,
			  u16 vid, u16 flags)
{
	const struct net_device_ops *ops = dev->netdev_ops;
	int err;

	/* If driver uses VLAN ndo ops, use 8021q to install vid
	 * on device, otherwise try switchdev ops to install vid.
	 */

	if (ops->ndo_vlan_rx_add_vid) {
		err = vlan_vid_add(dev, br->vlan_proto, vid);
	} else {
	struct switchdev_obj_port_vlan v = {
		.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
		.flags = flags,
		.vid_begin = vid,
		.vid_end = vid,
	};
	int err;

	/* Try switchdev op first. In case it is not supported, fallback to
	 * 8021q add.
	 */
	err = switchdev_port_obj_add(dev, &v.obj);
	if (err == -EOPNOTSUPP)
			err = 0;
	}

		return vlan_vid_add(dev, br->vlan_proto, vid);
	return err;
}

@@ -122,27 +114,21 @@ static void __vlan_del_list(struct net_bridge_vlan *v)
static int __vlan_vid_del(struct net_device *dev, struct net_bridge *br,
			  u16 vid)
{
	const struct net_device_ops *ops = dev->netdev_ops;
	int err = 0;

	/* If driver uses VLAN ndo ops, use 8021q to delete vid
	 * on device, otherwise try switchdev ops to delete vid.
	 */

	if (ops->ndo_vlan_rx_kill_vid) {
		vlan_vid_del(dev, br->vlan_proto, vid);
	} else {
	struct switchdev_obj_port_vlan v = {
		.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
		.vid_begin = vid,
		.vid_end = vid,
	};
	int err;

	/* Try switchdev op first. In case it is not supported, fallback to
	 * 8021q del.
	 */
	err = switchdev_port_obj_del(dev, &v.obj);
		if (err == -EOPNOTSUPP)
			err = 0;
	if (err == -EOPNOTSUPP) {
		vlan_vid_del(dev, br->vlan_proto, vid);
		return 0;
	}

	return err;
}