Commit 34ea415f authored by Hans Schultz's avatar Hans Schultz Committed by David S. Miller
Browse files

net: dsa: mv88e6xxx: Add support for bridge port locked mode



Supporting bridge ports in locked mode using the drop on lock
feature in Marvell mv88e6xxx switchcores is described in the
'88E6096/88E6097/88E6097F Datasheet', sections 4.4.6, 4.4.7 and
5.1.2.1 (Drop on Lock).

This feature is implemented here facilitated by the locked port flag.

Signed-off-by: default avatarHans Schultz <schultz.hans+netdev@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b9e8b58f
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -6103,7 +6103,7 @@ static int mv88e6xxx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
	const struct mv88e6xxx_ops *ops;

	if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
			   BR_BCAST_FLOOD))
			   BR_BCAST_FLOOD | BR_PORT_LOCKED))
		return -EINVAL;

	ops = chip->info->ops;
@@ -6161,6 +6161,13 @@ static int mv88e6xxx_port_bridge_flags(struct dsa_switch *ds, int port,
			goto out;
	}

	if (flags.mask & BR_PORT_LOCKED) {
		bool locked = !!(flags.val & BR_PORT_LOCKED);

		err = mv88e6xxx_port_set_lock(chip, port, locked);
		if (err)
			goto out;
	}
out:
	mv88e6xxx_reg_unlock(chip);

+29 −0
Original line number Diff line number Diff line
@@ -1234,6 +1234,35 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
	return err;
}

int mv88e6xxx_port_set_lock(struct mv88e6xxx_chip *chip, int port,
			    bool locked)
{
	u16 reg;
	int err;

	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL0, &reg);
	if (err)
		return err;

	reg &= ~MV88E6XXX_PORT_CTL0_SA_FILT_MASK;
	if (locked)
		reg |= MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_LOCK;

	err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL0, reg);
	if (err)
		return err;

	err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, &reg);
	if (err)
		return err;

	reg &= ~MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;
	if (locked)
		reg |= MV88E6XXX_PORT_ASSOC_VECTOR_LOCKED_PORT;

	return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_ASSOC_VECTOR, reg);
}

int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
				  u16 mode)
{
+8 −1
Original line number Diff line number Diff line
@@ -147,7 +147,11 @@
/* Offset 0x04: Port Control Register */
#define MV88E6XXX_PORT_CTL0					0x04
#define MV88E6XXX_PORT_CTL0_USE_CORE_TAG			0x8000
#define MV88E6XXX_PORT_CTL0_DROP_ON_LOCK			0x4000
#define MV88E6XXX_PORT_CTL0_SA_FILT_MASK			0xc000
#define MV88E6XXX_PORT_CTL0_SA_FILT_DISABLED			0x0000
#define MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_LOCK		0x4000
#define MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_UNLOCK		0x8000
#define MV88E6XXX_PORT_CTL0_SA_FILT_DROP_ON_CPU		0xc000
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_MASK			0x3000
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNMODIFIED		0x0000
#define MV88E6XXX_PORT_CTL0_EGRESS_MODE_UNTAGGED		0x1000
@@ -370,6 +374,9 @@ int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid);
int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid);
int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid);

int mv88e6xxx_port_set_lock(struct mv88e6xxx_chip *chip, int port,
			    bool locked);

int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
				  u16 mode);
int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port);