diff options
author | Peter Zijlstra <peterz@infradead.org> | 2022-05-11 17:27:06 +0300 |
---|---|---|
committer | Peter Zijlstra <peterz@infradead.org> | 2022-05-11 17:27:06 +0300 |
commit | 47319846a9e2ab1c4d22108e891818d003615bd8 (patch) | |
tree | 919dbed5c01d3ad4db009bd38bb12cfd3d038246 /drivers/net/dsa/ocelot/felix.c | |
parent | 3d47083b9ff46863e8374ad3bb5edb5e464c75f8 (diff) | |
parent | 672c0c5173427e6b3e2a9bbb7be51ceeec78093a (diff) |
Merge branch 'v5.18-rc5'
Obtain the new INTEL_FAM6 stuff required.
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Diffstat (limited to 'drivers/net/dsa/ocelot/felix.c')
-rw-r--r-- | drivers/net/dsa/ocelot/felix.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 413b0006e9a2..9e28219b223d 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -670,6 +670,8 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu, struct ocelot *ocelot = ds->priv; struct felix *felix = ocelot_to_felix(ocelot); enum dsa_tag_protocol old_proto = felix->tag_proto; + bool cpu_port_active = false; + struct dsa_port *dp; int err; if (proto != DSA_TAG_PROTO_SEVILLE && @@ -677,6 +679,27 @@ static int felix_change_tag_protocol(struct dsa_switch *ds, int cpu, proto != DSA_TAG_PROTO_OCELOT_8021Q) return -EPROTONOSUPPORT; + /* We don't support multiple CPU ports, yet the DT blob may have + * multiple CPU ports defined. The first CPU port is the active one, + * the others are inactive. In this case, DSA will call + * ->change_tag_protocol() multiple times, once per CPU port. + * Since we implement the tagging protocol change towards "ocelot" or + * "seville" as effectively initializing the NPI port, what we are + * doing is effectively changing who the NPI port is to the last @cpu + * argument passed, which is an unused DSA CPU port and not the one + * that should actively pass traffic. + * Suppress DSA's calls on CPU ports that are inactive. + */ + dsa_switch_for_each_user_port(dp, ds) { + if (dp->cpu_dp->index == cpu) { + cpu_port_active = true; + break; + } + } + + if (!cpu_port_active) + return 0; + felix_del_tag_protocol(ds, cpu, old_proto); err = felix_set_tag_protocol(ds, cpu, proto); |