| From d176f477fd2acded12356088c0f67dee059facb5 Mon Sep 17 00:00:00 2001 |
| From: Vladimir Oltean <vladimir.oltean@nxp.com> |
| Date: Sat, 9 Nov 2019 15:03:01 +0200 |
| Subject: [PATCH] net: mscc: ocelot: don't hardcode the number of the CPU port |
| |
| VSC7514 is a 10-port switch with 2 extra "CPU ports" (targets in the |
| queuing subsystem for terminating traffic locally). |
| |
| There are 2 issues with hardcoding the CPU port as #10: |
| - It is not clear which snippets of the code are configuring something |
| for one of the CPU ports, and which snippets are just doing something |
| related to the number of physical ports. |
| - Actually any physical port can act as a CPU port connected to an |
| external CPU (in addition to the local CPU). This is called NPI mode |
| (Node Processor Interface) and is the way that the 6-port VSC9959 |
| (Felix) switch is integrated inside NXP LS1028A (the "local management |
| CPU" functionality is not used there). |
| |
| This patch makes it clear that the ocelot_bridge_stp_state_set function |
| operates on the CPU port (by making it an implicit member of the |
| bridging domain), and at the same time adds logic for the NPI port (aka |
| a physical port) to play the role of a CPU port (it shouldn't be part of |
| bridge_fwd_mask, as it's not explicitly enslaved to a bridge). |
| |
| Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| --- |
| drivers/net/ethernet/mscc/ocelot.c | 11 +++++++---- |
| 1 file changed, 7 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/net/ethernet/mscc/ocelot.c |
| +++ b/drivers/net/ethernet/mscc/ocelot.c |
| @@ -1380,7 +1380,7 @@ static void ocelot_bridge_stp_state_set( |
| * a source for the other ports. |
| */ |
| for (p = 0; p < ocelot->num_phys_ports; p++) { |
| - if (ocelot->bridge_fwd_mask & BIT(p)) { |
| + if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) { |
| unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p); |
| |
| for (i = 0; i < ocelot->num_phys_ports; i++) { |
| @@ -1395,15 +1395,18 @@ static void ocelot_bridge_stp_state_set( |
| } |
| } |
| |
| - ocelot_write_rix(ocelot, |
| - BIT(ocelot->num_phys_ports) | mask, |
| + /* Avoid the NPI port from looping back to itself */ |
| + if (p != ocelot->cpu) |
| + mask |= BIT(ocelot->cpu); |
| + |
| + ocelot_write_rix(ocelot, mask, |
| ANA_PGID_PGID, PGID_SRC + p); |
| } else { |
| /* Only the CPU port, this is compatible with link |
| * aggregation. |
| */ |
| ocelot_write_rix(ocelot, |
| - BIT(ocelot->num_phys_ports), |
| + BIT(ocelot->cpu), |
| ANA_PGID_PGID, PGID_SRC + p); |
| } |
| } |