Commit d89ef4b8 authored by Tobias Waldekranz's avatar Tobias Waldekranz Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: Provide generic VTU iterator



Move the intricacies of correctly iterating over the VTU to a common
implementation.

Signed-off-by: default avatarTobias Waldekranz <tobias@waldekranz.com>
Reviewed-by: default avatarAndrew Lunn <andrew@lunn.ch>
Reviewed-by: default avatarVladimir Oltean <olteanv@gmail.com>
Reviewed-by: default avatarFlorian Fainelli <f.fainelli@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ffcec3f2
Loading
Loading
Loading
Loading
+64 −36
Original line number Diff line number Diff line
@@ -1511,6 +1511,37 @@ static int mv88e6xxx_vtu_getnext(struct mv88e6xxx_chip *chip,
	return chip->info->ops->vtu_getnext(chip, entry);
}

static int mv88e6xxx_vtu_walk(struct mv88e6xxx_chip *chip,
			      int (*cb)(struct mv88e6xxx_chip *chip,
					const struct mv88e6xxx_vtu_entry *entry,
					void *priv),
			      void *priv)
{
	struct mv88e6xxx_vtu_entry entry = {
		.vid = mv88e6xxx_max_vid(chip),
		.valid = false,
	};
	int err;

	if (!chip->info->ops->vtu_getnext)
		return -EOPNOTSUPP;

	do {
		err = chip->info->ops->vtu_getnext(chip, &entry);
		if (err)
			return err;

		if (!entry.valid)
			break;

		err = cb(chip, &entry, priv);
		if (err)
			return err;
	} while (entry.vid < mv88e6xxx_max_vid(chip));

	return 0;
}

static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
				   struct mv88e6xxx_vtu_entry *entry)
{
@@ -1520,9 +1551,18 @@ static int mv88e6xxx_vtu_loadpurge(struct mv88e6xxx_chip *chip,
	return chip->info->ops->vtu_loadpurge(chip, entry);
}

static int mv88e6xxx_fid_map_vlan(struct mv88e6xxx_chip *chip,
				  const struct mv88e6xxx_vtu_entry *entry,
				  void *_fid_bitmap)
{
	unsigned long *fid_bitmap = _fid_bitmap;

	set_bit(entry->fid, fid_bitmap);
	return 0;
}

int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
{
	struct mv88e6xxx_vtu_entry vlan;
	int i, err;
	u16 fid;

@@ -1538,21 +1578,7 @@ int mv88e6xxx_fid_map(struct mv88e6xxx_chip *chip, unsigned long *fid_bitmap)
	}

	/* Set every FID bit used by the VLAN entries */
	vlan.vid = mv88e6xxx_max_vid(chip);
	vlan.valid = false;

	do {
		err = mv88e6xxx_vtu_getnext(chip, &vlan);
		if (err)
			return err;

		if (!vlan.valid)
			break;

		set_bit(vlan.fid, fid_bitmap);
	} while (vlan.vid < mv88e6xxx_max_vid(chip));

	return 0;
	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_fid_map_vlan, fid_bitmap);
}

static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
@@ -2198,10 +2224,30 @@ static int mv88e6xxx_port_db_dump_fid(struct mv88e6xxx_chip *chip,
	return err;
}

struct mv88e6xxx_port_db_dump_vlan_ctx {
	int port;
	dsa_fdb_dump_cb_t *cb;
	void *data;
};

static int mv88e6xxx_port_db_dump_vlan(struct mv88e6xxx_chip *chip,
				       const struct mv88e6xxx_vtu_entry *entry,
				       void *_data)
{
	struct mv88e6xxx_port_db_dump_vlan_ctx *ctx = _data;

	return mv88e6xxx_port_db_dump_fid(chip, entry->fid, entry->vid,
					  ctx->port, ctx->cb, ctx->data);
}

static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
				  dsa_fdb_dump_cb_t *cb, void *data)
{
	struct mv88e6xxx_vtu_entry vlan;
	struct mv88e6xxx_port_db_dump_vlan_ctx ctx = {
		.port = port,
		.cb = cb,
		.data = data,
	};
	u16 fid;
	int err;

@@ -2214,25 +2260,7 @@ static int mv88e6xxx_port_db_dump(struct mv88e6xxx_chip *chip, int port,
	if (err)
		return err;

	/* Dump VLANs' Filtering Information Databases */
	vlan.vid = mv88e6xxx_max_vid(chip);
	vlan.valid = false;

	do {
		err = mv88e6xxx_vtu_getnext(chip, &vlan);
		if (err)
			return err;

		if (!vlan.valid)
			break;

		err = mv88e6xxx_port_db_dump_fid(chip, vlan.fid, vlan.vid, port,
						 cb, data);
		if (err)
			return err;
	} while (vlan.vid < mv88e6xxx_max_vid(chip));

	return err;
	return mv88e6xxx_vtu_walk(chip, mv88e6xxx_port_db_dump_vlan, &ctx);
}

static int mv88e6xxx_port_fdb_dump(struct dsa_switch *ds, int port,