fbb9c94ec1411661c588a8bd509a46c7eee41d75
[openwrt/staging/thess.git] /
1 From 1e3f407f3cacc5dcfe27166c412ed9bc263d82bf Mon Sep 17 00:00:00 2001
2 From: Vladimir Oltean <vladimir.oltean@nxp.com>
3 Date: Thu, 6 Jan 2022 01:11:16 +0200
4 Subject: [PATCH 5/6] net: dsa: first set up shared ports, then non-shared
5 ports
6
7 After commit a57d8c217aad ("net: dsa: flush switchdev workqueue before
8 tearing down CPU/DSA ports"), the port setup and teardown procedure
9 became asymmetric.
10
11 The fact of the matter is that user ports need the shared ports to be up
12 before they can be used for CPU-initiated termination. And since we
13 register net devices for the user ports, those won't be functional until
14 we also call the setup for the shared (CPU, DSA) ports. But we may do
15 that later, depending on the port numbering scheme of the hardware we
16 are dealing with.
17
18 It just makes sense that all shared ports are brought up before any user
19 port is. I can't pinpoint any issue due to the current behavior, but
20 let's change it nonetheless, for consistency's sake.
21
22 Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
23 Signed-off-by: David S. Miller <davem@davemloft.net>
24 ---
25 net/dsa/dsa2.c | 50 +++++++++++++++++++++++++++++++++++++-------------
26 1 file changed, 37 insertions(+), 13 deletions(-)
27
28 --- a/net/dsa/dsa2.c
29 +++ b/net/dsa/dsa2.c
30 @@ -1021,23 +1021,28 @@ static void dsa_tree_teardown_switches(s
31 dsa_switch_teardown(dp->ds);
32 }
33
34 -static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
35 +/* Bring shared ports up first, then non-shared ports */
36 +static int dsa_tree_setup_ports(struct dsa_switch_tree *dst)
37 {
38 struct dsa_port *dp;
39 - int err;
40 + int err = 0;
41
42 list_for_each_entry(dp, &dst->ports, list) {
43 - err = dsa_switch_setup(dp->ds);
44 - if (err)
45 - goto teardown;
46 + if (dsa_port_is_dsa(dp) || dsa_port_is_cpu(dp)) {
47 + err = dsa_port_setup(dp);
48 + if (err)
49 + goto teardown;
50 + }
51 }
52
53 list_for_each_entry(dp, &dst->ports, list) {
54 - err = dsa_port_setup(dp);
55 - if (err) {
56 - err = dsa_port_reinit_as_unused(dp);
57 - if (err)
58 - goto teardown;
59 + if (dsa_port_is_user(dp) || dsa_port_is_unused(dp)) {
60 + err = dsa_port_setup(dp);
61 + if (err) {
62 + err = dsa_port_reinit_as_unused(dp);
63 + if (err)
64 + goto teardown;
65 + }
66 }
67 }
68
69 @@ -1046,7 +1051,21 @@ static int dsa_tree_setup_switches(struc
70 teardown:
71 dsa_tree_teardown_ports(dst);
72
73 - dsa_tree_teardown_switches(dst);
74 + return err;
75 +}
76 +
77 +static int dsa_tree_setup_switches(struct dsa_switch_tree *dst)
78 +{
79 + struct dsa_port *dp;
80 + int err = 0;
81 +
82 + list_for_each_entry(dp, &dst->ports, list) {
83 + err = dsa_switch_setup(dp->ds);
84 + if (err) {
85 + dsa_tree_teardown_switches(dst);
86 + break;
87 + }
88 + }
89
90 return err;
91 }
92 @@ -1133,10 +1152,14 @@ static int dsa_tree_setup(struct dsa_swi
93 if (err)
94 goto teardown_cpu_ports;
95
96 - err = dsa_tree_setup_master(dst);
97 + err = dsa_tree_setup_ports(dst);
98 if (err)
99 goto teardown_switches;
100
101 + err = dsa_tree_setup_master(dst);
102 + if (err)
103 + goto teardown_ports;
104 +
105 err = dsa_tree_setup_lags(dst);
106 if (err)
107 goto teardown_master;
108 @@ -1149,8 +1172,9 @@ static int dsa_tree_setup(struct dsa_swi
109
110 teardown_master:
111 dsa_tree_teardown_master(dst);
112 -teardown_switches:
113 +teardown_ports:
114 dsa_tree_teardown_ports(dst);
115 +teardown_switches:
116 dsa_tree_teardown_switches(dst);
117 teardown_cpu_ports:
118 dsa_tree_teardown_cpu_ports(dst);