Commit 87fa886e authored by Andrew Lunn's avatar Andrew Lunn Committed by David S. Miller

net: dsa: mv88e6xxx: Flood broadcast frames in hardware

By default, the switch does not flood broadcast frames. Instead the
broadcast address is unknown in the ATU, so the frame gets forwarded
out the cpu port. The software bridge then floods it back to the
individual switch ports which are members of the bridge.

Add an ATU entry in the switch so that it floods broadcast frames out
ports, rather than have the software bridge do it. Also, send a copy
out the cpu port and any dsa ports. Rely on the port vectors to
prevent broadcast frames leaking between bridges, and separated ports.

Additionally, when a VLAN is added, a new FID is allocated.  This
represents a new table of ATU entries. A broadcast entry is added to
the new FID.

With offload_fwd_mark being set, the software bridge will not flood
the frames it receives back to the switch.
Signed-off-by: default avatarAndrew Lunn <andrew@lunn.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a4c93ae1
...@@ -1252,6 +1252,29 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port, ...@@ -1252,6 +1252,29 @@ static int mv88e6xxx_port_db_load_purge(struct mv88e6xxx_chip *chip, int port,
return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry); return mv88e6xxx_g1_atu_loadpurge(chip, vlan.fid, &entry);
} }
static int mv88e6xxx_port_add_broadcast(struct mv88e6xxx_chip *chip, int port,
u16 vid)
{
const char broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
u8 state = MV88E6XXX_G1_ATU_DATA_STATE_MC_STATIC;
return mv88e6xxx_port_db_load_purge(chip, port, broadcast, vid, state);
}
static int mv88e6xxx_broadcast_setup(struct mv88e6xxx_chip *chip, u16 vid)
{
int port;
int err;
for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
err = mv88e6xxx_port_add_broadcast(chip, port, vid);
if (err)
return err;
}
return 0;
}
static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
u16 vid, u8 member) u16 vid, u8 member)
{ {
...@@ -1264,7 +1287,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port, ...@@ -1264,7 +1287,11 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
vlan.member[port] = member; vlan.member[port] = member;
return mv88e6xxx_vtu_loadpurge(chip, &vlan); err = mv88e6xxx_vtu_loadpurge(chip, &vlan);
if (err)
return err;
return mv88e6xxx_broadcast_setup(chip, vid);
} }
static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, static void mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port,
...@@ -2049,6 +2076,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) ...@@ -2049,6 +2076,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
if (err) if (err)
goto unlock; goto unlock;
err = mv88e6xxx_broadcast_setup(chip, 0);
if (err)
goto unlock;
err = mv88e6xxx_pot_setup(chip); err = mv88e6xxx_pot_setup(chip);
if (err) if (err)
goto unlock; goto unlock;
......
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