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: Hans Schultz <schultz.hans+netdev@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Hans Schultz 2022-02-23 11:16:49 +01:00 committed by David S. Miller
parent b9e8b58fd2
commit 34ea415f92
3 changed files with 45 additions and 2 deletions

View file

@ -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);

View file

@ -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)
{

View file

@ -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);