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

Commit 2fb5ef09 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: extract single VLAN retrieval



Rename _mv88e6xxx_vlan_init in _mv88e6xxx_vtu_new, eventually called
from a new _mv88e6xxx_vtu_get function, which abstracts the VTU GetNext
VID-1 trick to retrieve a single entry.

Signed-off-by: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fb2dabad
Loading
Loading
Loading
Loading
+35 −20
Original line number Diff line number Diff line
@@ -1458,7 +1458,7 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds,
	return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_LOAD_PURGE);
}

static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
			      struct mv88e6xxx_vtu_stu_entry *entry)
{
	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
@@ -1509,6 +1509,35 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
	return 0;
}

static int _mv88e6xxx_vtu_get(struct dsa_switch *ds, u16 vid,
			      struct mv88e6xxx_vtu_stu_entry *entry, bool creat)
{
	int err;

	if (!vid)
		return -EINVAL;

	err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
	if (err)
		return err;

	err = _mv88e6xxx_vtu_getnext(ds, entry);
	if (err)
		return err;

	if (entry->vid != vid || !entry->valid) {
		if (!creat)
			return -EOPNOTSUPP;
		/* -ENOENT would've been more appropriate, but switchdev expects
		 * -EOPNOTSUPP to inform bridge about an eventual software VLAN.
		 */

		err = _mv88e6xxx_vtu_new(ds, vid, entry);
	}

	return err;
}

static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
					u16 vid_begin, u16 vid_end)
{
@@ -1593,20 +1622,10 @@ static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
	struct mv88e6xxx_vtu_stu_entry vlan;
	int err;

	err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
	err = _mv88e6xxx_vtu_get(ds, vid, &vlan, true);
	if (err)
		return err;

	err = _mv88e6xxx_vtu_getnext(ds, &vlan);
	if (err)
		return err;

	if (vlan.vid != vid || !vlan.valid) {
		err = _mv88e6xxx_vlan_init(ds, vid, &vlan);
		if (err)
			return err;
	}

	vlan.data[port] = untagged ?
		GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
		GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
@@ -1647,16 +1666,12 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
	struct mv88e6xxx_vtu_stu_entry vlan;
	int i, err;

	err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
	if (err)
		return err;

	err = _mv88e6xxx_vtu_getnext(ds, &vlan);
	err = _mv88e6xxx_vtu_get(ds, vid, &vlan, false);
	if (err)
		return err;

	if (vlan.vid != vid || !vlan.valid ||
	    vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
	/* Tell switchdev if this VLAN is handled in software */
	if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
		return -EOPNOTSUPP;

	vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;