972ec164f123b0a3c76a28eec399ee665f0ffb18
[openwrt/staging/ldir.git] /
1 From 93a32fc4f43ae40a2140acd9258faada11a98ec0 Mon Sep 17 00:00:00 2001
2 From: Vladimir Oltean <vladimir.oltean@nxp.com>
3 Date: Mon, 18 Nov 2019 20:16:57 +0200
4 Subject: [PATCH] net: dsa: felix: Fix CPU port assignment when not last port
5
6 On the NXP LS1028A, there are 2 Ethernet links between the Felix switch
7 and the ENETC:
8 - eno2 <-> swp4, at 2.5G
9 - eno3 <-> swp5, at 1G
10
11 Only one of the above Ethernet port pairs can act as a DSA link for
12 tagging.
13
14 When adding initial support for the driver, it was tested only on the 1G
15 eno3 <-> swp5 interface, due to the necessity of using PHYLIB initially
16 (which treats fixed-link interfaces as emulated C22 PHYs, so it doesn't
17 support fixed-link speeds higher than 1G).
18
19 After making PHYLINK work, it appears that swp4 still can't act as CPU
20 port. So it looks like ocelot_set_cpu_port was being called for swp4,
21 but then it was called again for swp5, overwriting the CPU port assigned
22 in the DT.
23
24 It appears that when you call dsa_upstream_port for a port that is not
25 defined in the device tree (such as swp5 when using swp4 as CPU port),
26 its dp->cpu_dp pointer is not initialized by dsa_tree_setup_default_cpu,
27 and this trips up the following condition in dsa_upstream_port:
28
29 if (!cpu_dp)
30 return port;
31
32 So the moral of the story is: don't call dsa_upstream_port for a port
33 that is not defined in the device tree, and therefore its dsa_port
34 structure is not completely initialized (ds->num_ports is still 6).
35
36 Fixes: 56051948773e ("net: dsa: ocelot: add driver for Felix switch family")
37 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
38 Signed-off-by: David S. Miller <davem@davemloft.net>
39 ---
40 drivers/net/dsa/ocelot/felix.c | 2 +-
41 1 file changed, 1 insertion(+), 1 deletion(-)
42
43 --- a/drivers/net/dsa/ocelot/felix.c
44 +++ b/drivers/net/dsa/ocelot/felix.c
45 @@ -286,7 +286,7 @@ static int felix_setup(struct dsa_switch
46 for (port = 0; port < ds->num_ports; port++) {
47 ocelot_init_port(ocelot, port);
48
49 - if (port == dsa_upstream_port(ds, port))
50 + if (dsa_is_cpu_port(ds, port))
51 ocelot_set_cpu_port(ocelot, port,
52 OCELOT_TAG_PREFIX_NONE,
53 OCELOT_TAG_PREFIX_LONG);