diff options
author | George McCollister <george.mccollister@gmail.com> | 2021-06-16 04:39:03 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-06-16 22:17:03 +0300 |
commit | a4fc566543c0dede64b85ca907f34a5d19636292 (patch) | |
tree | 4a8a3beb101a6702a93933eb9070bd16ef9e770d /drivers | |
parent | d917c35a451e4ebba5c12a51c92cbddce958c91e (diff) | |
download | linux-a4fc566543c0dede64b85ca907f34a5d19636292.tar.xz |
net: dsa: xrs700x: forward HSR supervision frames
Forward supervision frames between redunant HSR ports. This was broken
in the last commit.
Fixes: 1a42624aecba ("net: dsa: xrs700x: allow HSR/PRP supervision dupes for node_table")
Signed-off-by: George McCollister <george.mccollister@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/dsa/xrs700x/xrs700x.c | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c index a79066174a77..130abb0f1438 100644 --- a/drivers/net/dsa/xrs700x/xrs700x.c +++ b/drivers/net/dsa/xrs700x/xrs700x.c @@ -337,7 +337,8 @@ static int xrs700x_port_add_bpdu_ipf(struct dsa_switch *ds, int port) * This is required to correctly populate the HSR/PRP node_table. * Leave the policy disabled, it will be enabled as needed. */ -static int xrs700x_port_add_hsrsup_ipf(struct dsa_switch *ds, int port) +static int xrs700x_port_add_hsrsup_ipf(struct dsa_switch *ds, int port, + int fwdport) { struct xrs700x *priv = ds->priv; unsigned int val = 0; @@ -368,6 +369,9 @@ static int xrs700x_port_add_hsrsup_ipf(struct dsa_switch *ds, int port) if (ret) return ret; + if (fwdport >= 0) + val |= BIT(fwdport); + /* Allow must be set prevent duplicate discard */ ret = regmap_write(priv->regmap, XRS_ETH_ADDR_FWD_ALLOW(port, 1), val); if (ret) @@ -405,10 +409,6 @@ static int xrs700x_port_setup(struct dsa_switch *ds, int port) ret = xrs700x_port_add_bpdu_ipf(ds, port); if (ret) return ret; - - ret = xrs700x_port_add_hsrsup_ipf(ds, port); - if (ret) - return ret; } return 0; @@ -562,6 +562,7 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, struct net_device *slave; int ret, i, hsr_pair[2]; enum hsr_version ver; + bool fwd = false; ret = hsr_get_version(hsr, &ver); if (ret) @@ -607,6 +608,7 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, if (ver == HSR_V1) { val &= ~BIT(partner->index); val &= ~BIT(port); + fwd = true; } val &= ~BIT(dsa_upstream_port(ds, port)); regmap_write(priv->regmap, XRS_PORT_FWD_MASK(partner->index), val); @@ -616,10 +618,19 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, XRS_PORT_FORWARDING); regmap_fields_write(priv->ps_forward, port, XRS_PORT_FORWARDING); - /* Enable inbound policy added by xrs700x_port_add_hsrsup_ipf() - * which allows HSR/PRP supervision forwarding to the CPU port without - * discarding duplicates. + /* Enable inbound policy which allows HSR/PRP supervision forwarding + * to the CPU port without discarding duplicates. Continue to + * forward to redundant ports when in HSR mode while discarding + * duplicates. */ + ret = xrs700x_port_add_hsrsup_ipf(ds, partner->index, fwd ? port : -1); + if (ret) + return ret; + + ret = xrs700x_port_add_hsrsup_ipf(ds, port, fwd ? partner->index : -1); + if (ret) + return ret; + regmap_update_bits(priv->regmap, XRS_ETH_ADDR_CFG(partner->index, 1), 1, 1); regmap_update_bits(priv->regmap, XRS_ETH_ADDR_CFG(port, 1), 1, 1); |