2cc97dd7355a11b8f72dd334c7a34409d914820a
[openwrt/staging/xback.git] /
1 From 1f92ead7e15003f632b5f138e8138095e0997d3d Mon Sep 17 00:00:00 2001
2 From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
3 Date: Tue, 3 Dec 2024 15:30:52 +0000
4 Subject: [PATCH 02/13] net: phylink: split cur_link_an_mode into requested and
5 active
6
7 There is an interdependence between the current link_an_mode and
8 pcs_neg_mode that some drivers rely upon to know whether inband or PHY
9 mode will be used.
10
11 In order to support detection of PCS and PHY inband capabilities
12 resulting in automatic selection of inband or PHY mode, we need to
13 cater for this, and support changing the MAC link_an_mode. However, we
14 end up with an inter-dependency between the current link_an_mode and
15 pcs_neg_mode.
16
17 To solve this, split the current link_an_mode into the requested
18 link_an_mode and active link_an_mode. The requested link_an_mode will
19 always be passed to phylink_pcs_neg_mode(), and the active link_an_mode
20 will be used for everything else, and only updated during
21 phylink_major_config(). This will ensure that phylink_pcs_neg_mode()'s
22 link_an_mode will not depend on the active link_an_mode that will,
23 in a future patch, depend on pcs_neg_mode.
24
25 Reviewed-by: Andrew Lunn <andrew@lunn.ch>
26 Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
27 Link: https://patch.msgid.link/E1tIUrU-006ITn-Ai@rmk-PC.armlinux.org.uk
28 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
29 ---
30 drivers/net/phy/phylink.c | 60 ++++++++++++++++++++-------------------
31 1 file changed, 31 insertions(+), 29 deletions(-)
32
33 --- a/drivers/net/phy/phylink.c
34 +++ b/drivers/net/phy/phylink.c
35 @@ -56,7 +56,8 @@ struct phylink {
36 struct phy_device *phydev;
37 phy_interface_t link_interface; /* PHY_INTERFACE_xxx */
38 u8 cfg_link_an_mode; /* MLO_AN_xxx */
39 - u8 cur_link_an_mode;
40 + u8 req_link_an_mode; /* Requested MLO_AN_xxx mode */
41 + u8 act_link_an_mode; /* Active MLO_AN_xxx mode */
42 u8 link_port; /* The current non-phy ethtool port */
43 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
44
45 @@ -1098,13 +1099,13 @@ static void phylink_mac_config(struct ph
46
47 phylink_dbg(pl,
48 "%s: mode=%s/%s/%s adv=%*pb pause=%02x\n",
49 - __func__, phylink_an_mode_str(pl->cur_link_an_mode),
50 + __func__, phylink_an_mode_str(pl->act_link_an_mode),
51 phy_modes(st.interface),
52 phy_rate_matching_to_str(st.rate_matching),
53 __ETHTOOL_LINK_MODE_MASK_NBITS, st.advertising,
54 st.pause);
55
56 - pl->mac_ops->mac_config(pl->config, pl->cur_link_an_mode, &st);
57 + pl->mac_ops->mac_config(pl->config, pl->act_link_an_mode, &st);
58 }
59
60 static void phylink_pcs_an_restart(struct phylink *pl)
61 @@ -1112,7 +1113,7 @@ static void phylink_pcs_an_restart(struc
62 if (pl->pcs && linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
63 pl->link_config.advertising) &&
64 phy_interface_mode_is_8023z(pl->link_config.interface) &&
65 - phylink_autoneg_inband(pl->cur_link_an_mode))
66 + phylink_autoneg_inband(pl->act_link_an_mode))
67 pl->pcs->ops->pcs_an_restart(pl->pcs);
68 }
69
70 @@ -1142,7 +1143,7 @@ static void phylink_pcs_neg_mode(struct
71 {
72 unsigned int neg_mode, mode;
73
74 - mode = pl->cur_link_an_mode;
75 + mode = pl->req_link_an_mode;
76
77 switch (interface) {
78 case PHY_INTERFACE_MODE_SGMII:
79 @@ -1183,6 +1184,7 @@ static void phylink_pcs_neg_mode(struct
80 }
81
82 pl->pcs_neg_mode = neg_mode;
83 + pl->act_link_an_mode = mode;
84 }
85
86 static void phylink_major_config(struct phylink *pl, bool restart,
87 @@ -1213,7 +1215,7 @@ static void phylink_major_config(struct
88 phylink_pcs_poll_stop(pl);
89
90 if (pl->mac_ops->mac_prepare) {
91 - err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
92 + err = pl->mac_ops->mac_prepare(pl->config, pl->act_link_an_mode,
93 state->interface);
94 if (err < 0) {
95 phylink_err(pl, "mac_prepare failed: %pe\n",
96 @@ -1247,7 +1249,7 @@ static void phylink_major_config(struct
97 if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
98 phylink_pcs_enable(pl->pcs);
99
100 - neg_mode = pl->cur_link_an_mode;
101 + neg_mode = pl->act_link_an_mode;
102 if (pl->pcs && pl->pcs->neg_mode)
103 neg_mode = pl->pcs_neg_mode;
104
105 @@ -1263,7 +1265,7 @@ static void phylink_major_config(struct
106 phylink_pcs_an_restart(pl);
107
108 if (pl->mac_ops->mac_finish) {
109 - err = pl->mac_ops->mac_finish(pl->config, pl->cur_link_an_mode,
110 + err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode,
111 state->interface);
112 if (err < 0)
113 phylink_err(pl, "mac_finish failed: %pe\n",
114 @@ -1294,7 +1296,7 @@ static int phylink_change_inband_advert(
115 return 0;
116
117 phylink_dbg(pl, "%s: mode=%s/%s adv=%*pb pause=%02x\n", __func__,
118 - phylink_an_mode_str(pl->cur_link_an_mode),
119 + phylink_an_mode_str(pl->req_link_an_mode),
120 phy_modes(pl->link_config.interface),
121 __ETHTOOL_LINK_MODE_MASK_NBITS, pl->link_config.advertising,
122 pl->link_config.pause);
123 @@ -1303,7 +1305,7 @@ static int phylink_change_inband_advert(
124 phylink_pcs_neg_mode(pl, pl->pcs, pl->link_config.interface,
125 pl->link_config.advertising);
126
127 - neg_mode = pl->cur_link_an_mode;
128 + neg_mode = pl->act_link_an_mode;
129 if (pl->pcs->neg_mode)
130 neg_mode = pl->pcs_neg_mode;
131
132 @@ -1368,7 +1370,7 @@ static void phylink_mac_initial_config(s
133 {
134 struct phylink_link_state link_state;
135
136 - switch (pl->cur_link_an_mode) {
137 + switch (pl->req_link_an_mode) {
138 case MLO_AN_PHY:
139 link_state = pl->phy_state;
140 break;
141 @@ -1442,14 +1444,14 @@ static void phylink_link_up(struct phyli
142
143 pl->cur_interface = link_state.interface;
144
145 - neg_mode = pl->cur_link_an_mode;
146 + neg_mode = pl->act_link_an_mode;
147 if (pl->pcs && pl->pcs->neg_mode)
148 neg_mode = pl->pcs_neg_mode;
149
150 phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
151 duplex);
152
153 - pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->cur_link_an_mode,
154 + pl->mac_ops->mac_link_up(pl->config, pl->phydev, pl->act_link_an_mode,
155 pl->cur_interface, speed, duplex,
156 !!(link_state.pause & MLO_PAUSE_TX), rx_pause);
157
158 @@ -1469,7 +1471,7 @@ static void phylink_link_down(struct phy
159
160 if (ndev)
161 netif_carrier_off(ndev);
162 - pl->mac_ops->mac_link_down(pl->config, pl->cur_link_an_mode,
163 + pl->mac_ops->mac_link_down(pl->config, pl->act_link_an_mode,
164 pl->cur_interface);
165 phylink_info(pl, "Link is Down\n");
166 }
167 @@ -1495,10 +1497,10 @@ static void phylink_resolve(struct work_
168 } else if (pl->mac_link_dropped) {
169 link_state.link = false;
170 retrigger = true;
171 - } else if (pl->cur_link_an_mode == MLO_AN_FIXED) {
172 + } else if (pl->act_link_an_mode == MLO_AN_FIXED) {
173 phylink_get_fixed_state(pl, &link_state);
174 mac_config = link_state.link;
175 - } else if (pl->cur_link_an_mode == MLO_AN_PHY) {
176 + } else if (pl->act_link_an_mode == MLO_AN_PHY) {
177 link_state = pl->phy_state;
178 mac_config = link_state.link;
179 } else {
180 @@ -1552,7 +1554,7 @@ static void phylink_resolve(struct work_
181 }
182 }
183
184 - if (pl->cur_link_an_mode != MLO_AN_FIXED)
185 + if (pl->act_link_an_mode != MLO_AN_FIXED)
186 phylink_apply_manual_flow(pl, &link_state);
187
188 if (mac_config) {
189 @@ -1729,7 +1731,7 @@ struct phylink *phylink_create(struct ph
190 }
191 }
192
193 - pl->cur_link_an_mode = pl->cfg_link_an_mode;
194 + pl->req_link_an_mode = pl->cfg_link_an_mode;
195
196 ret = phylink_register_sfp(pl, fwnode);
197 if (ret < 0) {
198 @@ -2126,7 +2128,7 @@ void phylink_start(struct phylink *pl)
199 ASSERT_RTNL();
200
201 phylink_info(pl, "configuring for %s/%s link mode\n",
202 - phylink_an_mode_str(pl->cur_link_an_mode),
203 + phylink_an_mode_str(pl->req_link_an_mode),
204 phy_modes(pl->link_config.interface));
205
206 /* Always set the carrier off */
207 @@ -2385,7 +2387,7 @@ int phylink_ethtool_ksettings_get(struct
208
209 linkmode_copy(kset->link_modes.supported, pl->supported);
210
211 - switch (pl->cur_link_an_mode) {
212 + switch (pl->act_link_an_mode) {
213 case MLO_AN_FIXED:
214 /* We are using fixed settings. Report these as the
215 * current link settings - and note that these also
216 @@ -2477,7 +2479,7 @@ int phylink_ethtool_ksettings_set(struct
217 /* If we have a fixed link, refuse to change link parameters.
218 * If the link parameters match, accept them but do nothing.
219 */
220 - if (pl->cur_link_an_mode == MLO_AN_FIXED) {
221 + if (pl->req_link_an_mode == MLO_AN_FIXED) {
222 if (s->speed != pl->link_config.speed ||
223 s->duplex != pl->link_config.duplex)
224 return -EINVAL;
225 @@ -2493,7 +2495,7 @@ int phylink_ethtool_ksettings_set(struct
226 * is our default case) but do not allow the advertisement to
227 * be changed. If the advertisement matches, simply return.
228 */
229 - if (pl->cur_link_an_mode == MLO_AN_FIXED) {
230 + if (pl->req_link_an_mode == MLO_AN_FIXED) {
231 if (!linkmode_equal(config.advertising,
232 pl->link_config.advertising))
233 return -EINVAL;
234 @@ -2533,7 +2535,7 @@ int phylink_ethtool_ksettings_set(struct
235 linkmode_copy(support, pl->supported);
236 if (phylink_validate(pl, support, &config)) {
237 phylink_err(pl, "validation of %s/%s with support %*pb failed\n",
238 - phylink_an_mode_str(pl->cur_link_an_mode),
239 + phylink_an_mode_str(pl->req_link_an_mode),
240 phy_modes(config.interface),
241 __ETHTOOL_LINK_MODE_MASK_NBITS, support);
242 return -EINVAL;
243 @@ -2633,7 +2635,7 @@ int phylink_ethtool_set_pauseparam(struc
244
245 ASSERT_RTNL();
246
247 - if (pl->cur_link_an_mode == MLO_AN_FIXED)
248 + if (pl->req_link_an_mode == MLO_AN_FIXED)
249 return -EOPNOTSUPP;
250
251 if (!phylink_test(pl->supported, Pause) &&
252 @@ -2897,7 +2899,7 @@ static int phylink_mii_read(struct phyli
253 struct phylink_link_state state;
254 int val = 0xffff;
255
256 - switch (pl->cur_link_an_mode) {
257 + switch (pl->act_link_an_mode) {
258 case MLO_AN_FIXED:
259 if (phy_id == 0) {
260 phylink_get_fixed_state(pl, &state);
261 @@ -2922,7 +2924,7 @@ static int phylink_mii_read(struct phyli
262 static int phylink_mii_write(struct phylink *pl, unsigned int phy_id,
263 unsigned int reg, unsigned int val)
264 {
265 - switch (pl->cur_link_an_mode) {
266 + switch (pl->act_link_an_mode) {
267 case MLO_AN_FIXED:
268 break;
269
270 @@ -3125,9 +3127,9 @@ static void phylink_sfp_set_config(struc
271 changed = true;
272 }
273
274 - if (pl->cur_link_an_mode != mode ||
275 + if (pl->req_link_an_mode != mode ||
276 pl->link_config.interface != state->interface) {
277 - pl->cur_link_an_mode = mode;
278 + pl->req_link_an_mode = mode;
279 pl->link_config.interface = state->interface;
280
281 changed = true;