blob: 7ddc5753f6496408555c87cf31a4bd2ac575c440 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From d176f477fd2acded12356088c0f67dee059facb5 Mon Sep 17 00:00:00 2001
2From: Vladimir Oltean <vladimir.oltean@nxp.com>
3Date: Sat, 9 Nov 2019 15:03:01 +0200
4Subject: [PATCH] net: mscc: ocelot: don't hardcode the number of the CPU port
5
6VSC7514 is a 10-port switch with 2 extra "CPU ports" (targets in the
7queuing subsystem for terminating traffic locally).
8
9There 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
19This patch makes it clear that the ocelot_bridge_stp_state_set function
20operates on the CPU port (by making it an implicit member of the
21bridging domain), and at the same time adds logic for the NPI port (aka
22a physical port) to play the role of a CPU port (it shouldn't be part of
23bridge_fwd_mask, as it's not explicitly enslaved to a bridge).
24
25Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
26Signed-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 }