mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
net: dsa: vsc73xx: start treating the BR_LEARNING flag
This patch implements .port_pre_bridge_flags() and .port_bridge_flags(), which are required for properly treating the BR_LEARNING flag. Also, .port_stp_state_set() is tweaked and now disables learning for standalone ports. Disabling learning for standalone ports is required to avoid situations where one port sees traffic originating from another, which could cause packet drops. Signed-off-by: Pawel Dembicki <paweldembicki@gmail.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Link: https://patch.msgid.link/20240713211620.1125910-13-paweldembicki@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
6dfaaa2763
commit
259a7061c2
@ -1622,6 +1622,31 @@ static int vsc73xx_tag_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid)
|
||||
return vsc73xx_update_vlan_table(vsc, port, vid, false);
|
||||
}
|
||||
|
||||
static int vsc73xx_port_pre_bridge_flags(struct dsa_switch *ds, int port,
|
||||
struct switchdev_brport_flags flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & ~BR_LEARNING)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vsc73xx_port_bridge_flags(struct dsa_switch *ds, int port,
|
||||
struct switchdev_brport_flags flags,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (flags.mask & BR_LEARNING) {
|
||||
u32 val = flags.val & BR_LEARNING ? BIT(port) : 0;
|
||||
struct vsc73xx *vsc = ds->priv;
|
||||
|
||||
return vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_LEARNMASK, BIT(port), val);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state)
|
||||
{
|
||||
struct dsa_port *other_dp, *dp = dsa_to_port(ds, port);
|
||||
@ -1682,19 +1707,21 @@ static void vsc73xx_refresh_fwd_map(struct dsa_switch *ds, int port, u8 state)
|
||||
static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port,
|
||||
u8 state)
|
||||
{
|
||||
struct dsa_port *dp = dsa_to_port(ds, port);
|
||||
struct vsc73xx *vsc = ds->priv;
|
||||
u32 val;
|
||||
u32 val = 0;
|
||||
|
||||
if (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING)
|
||||
val = dp->learning ? BIT(port) : 0;
|
||||
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_LEARNMASK, BIT(port), val);
|
||||
|
||||
val = (state == BR_STATE_BLOCKING || state == BR_STATE_DISABLED) ?
|
||||
0 : BIT(port);
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_RECVMASK, BIT(port), val);
|
||||
|
||||
val = (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) ?
|
||||
BIT(port) : 0;
|
||||
vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0,
|
||||
VSC73XX_LEARNMASK, BIT(port), val);
|
||||
|
||||
/* CPU Port should always forward packets when user ports are forwarding
|
||||
* so let's configure it from other ports only.
|
||||
*/
|
||||
@ -1719,6 +1746,8 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = {
|
||||
.get_sset_count = vsc73xx_get_sset_count,
|
||||
.port_enable = vsc73xx_port_enable,
|
||||
.port_disable = vsc73xx_port_disable,
|
||||
.port_pre_bridge_flags = vsc73xx_port_pre_bridge_flags,
|
||||
.port_bridge_flags = vsc73xx_port_bridge_flags,
|
||||
.port_bridge_join = dsa_tag_8021q_bridge_join,
|
||||
.port_bridge_leave = dsa_tag_8021q_bridge_leave,
|
||||
.port_change_mtu = vsc73xx_change_mtu,
|
||||
|
Loading…
Reference in New Issue
Block a user