Commit 5a7921f4 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: mv88e6xxx: add port vlan map setter

Add a port function to access the Port Based VLAN Map register.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e28def33
...@@ -1218,16 +1218,13 @@ static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid, ...@@ -1218,16 +1218,13 @@ static int _mv88e6xxx_atu_remove(struct mv88e6xxx_chip *chip, u16 fid,
static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
{ {
struct net_device *bridge = chip->ports[port].bridge_dev; struct net_device *bridge = chip->ports[port].bridge_dev;
const u16 mask = (1 << mv88e6xxx_num_ports(chip)) - 1;
struct dsa_switch *ds = chip->ds; struct dsa_switch *ds = chip->ds;
u16 output_ports = 0; u16 output_ports = 0;
u16 reg;
int err;
int i; int i;
/* allow CPU port or DSA link(s) to send frames to every port */ /* allow CPU port or DSA link(s) to send frames to every port */
if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) {
output_ports = mask; output_ports = ~0;
} else { } else {
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
/* allow sending frames to every group member */ /* allow sending frames to every group member */
...@@ -1243,14 +1240,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) ...@@ -1243,14 +1240,7 @@ static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port)
/* prevent frames from going back out of the port they came in on */ /* prevent frames from going back out of the port they came in on */
output_ports &= ~BIT(port); output_ports &= ~BIT(port);
err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); return mv88e6xxx_port_set_vlan_map(chip, port, output_ports);
if (err)
return err;
reg &= ~mask;
reg |= output_ports & mask;
return mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
} }
static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
......
...@@ -60,3 +60,28 @@ int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) ...@@ -60,3 +60,28 @@ int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
return 0; return 0;
} }
/* Offset 0x06: Port Based VLAN Map */
int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map)
{
const u16 mask = GENMASK(mv88e6xxx_num_ports(chip) - 1, 0);
u16 reg;
int err;
err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg);
if (err)
return err;
reg &= ~mask;
reg |= map & mask;
err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg);
if (err)
return err;
netdev_dbg(chip->ds->ports[port].netdev, "VLANTable set to %.3x\n",
map);
return 0;
}
...@@ -23,4 +23,6 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, ...@@ -23,4 +23,6 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state); int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state);
int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map);
#endif /* _MV88E6XXX_PORT_H */ #endif /* _MV88E6XXX_PORT_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment