7ddc5753f6496408555c87cf31a4bd2ac575c440
[openwrt/openwrt.git] /
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 }