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
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
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
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.
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>
30 drivers/net/phy/phylink.c | 60 ++++++++++++++++++++-------------------
31 1 file changed, 31 insertions(+), 29 deletions(-)
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);
45 @@ -1098,13 +1099,13 @@ static void phylink_mac_config(struct ph
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,
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);
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);
70 @@ -1142,7 +1143,7 @@ static void phylink_pcs_neg_mode(struct
72 unsigned int neg_mode, mode;
74 - mode = pl->cur_link_an_mode;
75 + mode = pl->req_link_an_mode;
78 case PHY_INTERFACE_MODE_SGMII:
79 @@ -1183,6 +1184,7 @@ static void phylink_pcs_neg_mode(struct
82 pl->pcs_neg_mode = neg_mode;
83 + pl->act_link_an_mode = mode;
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);
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,
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);
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;
105 @@ -1263,7 +1265,7 @@ static void phylink_major_config(struct
106 phylink_pcs_an_restart(pl);
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,
113 phylink_err(pl, "mac_finish failed: %pe\n",
114 @@ -1294,7 +1296,7 @@ static int phylink_change_inband_advert(
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);
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;
132 @@ -1368,7 +1370,7 @@ static void phylink_mac_initial_config(s
134 struct phylink_link_state link_state;
136 - switch (pl->cur_link_an_mode) {
137 + switch (pl->req_link_an_mode) {
139 link_state = pl->phy_state;
141 @@ -1442,14 +1444,14 @@ static void phylink_link_up(struct phyli
143 pl->cur_interface = link_state.interface;
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;
150 phylink_pcs_link_up(pl->pcs, neg_mode, pl->cur_interface, speed,
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);
158 @@ -1469,7 +1471,7 @@ static void phylink_link_down(struct phy
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,
165 phylink_info(pl, "Link is Down\n");
167 @@ -1495,10 +1497,10 @@ static void phylink_resolve(struct work_
168 } else if (pl->mac_link_dropped) {
169 link_state.link = false;
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;
180 @@ -1552,7 +1554,7 @@ static void phylink_resolve(struct work_
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);
189 @@ -1729,7 +1731,7 @@ struct phylink *phylink_create(struct ph
193 - pl->cur_link_an_mode = pl->cfg_link_an_mode;
194 + pl->req_link_an_mode = pl->cfg_link_an_mode;
196 ret = phylink_register_sfp(pl, fwnode);
198 @@ -2126,7 +2128,7 @@ void phylink_start(struct phylink *pl)
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));
206 /* Always set the carrier off */
207 @@ -2385,7 +2387,7 @@ int phylink_ethtool_ksettings_get(struct
209 linkmode_copy(kset->link_modes.supported, pl->supported);
211 - switch (pl->cur_link_an_mode) {
212 + switch (pl->act_link_an_mode) {
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.
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)
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.
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))
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);
243 @@ -2633,7 +2635,7 @@ int phylink_ethtool_set_pauseparam(struc
247 - if (pl->cur_link_an_mode == MLO_AN_FIXED)
248 + if (pl->req_link_an_mode == MLO_AN_FIXED)
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;
256 - switch (pl->cur_link_an_mode) {
257 + switch (pl->act_link_an_mode) {
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)
265 - switch (pl->cur_link_an_mode) {
266 + switch (pl->act_link_an_mode) {
270 @@ -3125,9 +3127,9 @@ static void phylink_sfp_set_config(struc
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;