b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | From d176f477fd2acded12356088c0f67dee059facb5 Mon Sep 17 00:00:00 2001 |
| 2 | From: Vladimir Oltean <vladimir.oltean@nxp.com> |
| 3 | Date: Sat, 9 Nov 2019 15:03:01 +0200 |
| 4 | Subject: [PATCH] net: mscc: ocelot: don't hardcode the number of the CPU port |
| 5 | |
| 6 | VSC7514 is a 10-port switch with 2 extra "CPU ports" (targets in the |
| 7 | queuing subsystem for terminating traffic locally). |
| 8 | |
| 9 | There are 2 issues with hardcoding the CPU port as #10: |
| 10 | - It is not clear which snippets of the code are configuring something |
| 11 | for one of the CPU ports, and which snippets are just doing something |
| 12 | related to the number of physical ports. |
| 13 | - Actually any physical port can act as a CPU port connected to an |
| 14 | external CPU (in addition to the local CPU). This is called NPI mode |
| 15 | (Node Processor Interface) and is the way that the 6-port VSC9959 |
| 16 | (Felix) switch is integrated inside NXP LS1028A (the "local management |
| 17 | CPU" functionality is not used there). |
| 18 | |
| 19 | This patch makes it clear that the ocelot_bridge_stp_state_set function |
| 20 | operates on the CPU port (by making it an implicit member of the |
| 21 | bridging domain), and at the same time adds logic for the NPI port (aka |
| 22 | a physical port) to play the role of a CPU port (it shouldn't be part of |
| 23 | bridge_fwd_mask, as it's not explicitly enslaved to a bridge). |
| 24 | |
| 25 | Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> |
| 26 | Signed-off-by: David S. Miller <davem@davemloft.net> |
| 27 | --- |
| 28 | drivers/net/ethernet/mscc/ocelot.c | 11 +++++++---- |
| 29 | 1 file changed, 7 insertions(+), 4 deletions(-) |
| 30 | |
| 31 | --- a/drivers/net/ethernet/mscc/ocelot.c |
| 32 | +++ b/drivers/net/ethernet/mscc/ocelot.c |
| 33 | @@ -1380,7 +1380,7 @@ static void ocelot_bridge_stp_state_set( |
| 34 | * a source for the other ports. |
| 35 | */ |
| 36 | for (p = 0; p < ocelot->num_phys_ports; p++) { |
| 37 | - if (ocelot->bridge_fwd_mask & BIT(p)) { |
| 38 | + if (p == ocelot->cpu || (ocelot->bridge_fwd_mask & BIT(p))) { |
| 39 | unsigned long mask = ocelot->bridge_fwd_mask & ~BIT(p); |
| 40 | |
| 41 | for (i = 0; i < ocelot->num_phys_ports; i++) { |
| 42 | @@ -1395,15 +1395,18 @@ static void ocelot_bridge_stp_state_set( |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | - ocelot_write_rix(ocelot, |
| 47 | - BIT(ocelot->num_phys_ports) | mask, |
| 48 | + /* Avoid the NPI port from looping back to itself */ |
| 49 | + if (p != ocelot->cpu) |
| 50 | + mask |= BIT(ocelot->cpu); |
| 51 | + |
| 52 | + ocelot_write_rix(ocelot, mask, |
| 53 | ANA_PGID_PGID, PGID_SRC + p); |
| 54 | } else { |
| 55 | /* Only the CPU port, this is compatible with link |
| 56 | * aggregation. |
| 57 | */ |
| 58 | ocelot_write_rix(ocelot, |
| 59 | - BIT(ocelot->num_phys_ports), |
| 60 | + BIT(ocelot->cpu), |
| 61 | ANA_PGID_PGID, PGID_SRC + p); |
| 62 | } |
| 63 | } |