Skip to content

Commit f1ae32a

Browse files
Russell King (Oracle)kuba-moo
authored andcommitted
net: phylink: force link down on major_config failure
If we fail to configure the MAC or PCS according to the desired mode, do not allow the network link to come up until we have successfully configured the MAC and PCS. This improves phylink's behaviour when an error occurs. Signed-off-by: Russell King (Oracle) <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent cc04ed5 commit f1ae32a

File tree

1 file changed

+34
-8
lines changed

1 file changed

+34
-8
lines changed

drivers/net/phy/phylink.c

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ struct phylink {
8181
unsigned int pcs_state;
8282

8383
bool link_failed;
84+
bool major_config_failed;
8485
bool mac_supports_eee_ops;
8586
bool mac_supports_eee;
8687
bool phy_enable_tx_lpi;
@@ -1216,12 +1217,16 @@ static void phylink_major_config(struct phylink *pl, bool restart,
12161217
phylink_an_mode_str(pl->req_link_an_mode),
12171218
phy_modes(state->interface));
12181219

1220+
pl->major_config_failed = false;
1221+
12191222
if (pl->mac_ops->mac_select_pcs) {
12201223
pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
12211224
if (IS_ERR(pcs)) {
12221225
phylink_err(pl,
12231226
"mac_select_pcs unexpectedly failed: %pe\n",
12241227
pcs);
1228+
1229+
pl->major_config_failed = true;
12251230
return;
12261231
}
12271232

@@ -1243,6 +1248,7 @@ static void phylink_major_config(struct phylink *pl, bool restart,
12431248
if (err < 0) {
12441249
phylink_err(pl, "mac_prepare failed: %pe\n",
12451250
ERR_PTR(err));
1251+
pl->major_config_failed = true;
12461252
return;
12471253
}
12481254
}
@@ -1266,36 +1272,50 @@ static void phylink_major_config(struct phylink *pl, bool restart,
12661272

12671273
phylink_mac_config(pl, state);
12681274

1269-
if (pl->pcs)
1270-
phylink_pcs_post_config(pl->pcs, state->interface);
1275+
if (pl->pcs) {
1276+
err = phylink_pcs_post_config(pl->pcs, state->interface);
1277+
if (err < 0) {
1278+
phylink_err(pl, "pcs_post_config failed: %pe\n",
1279+
ERR_PTR(err));
1280+
1281+
pl->major_config_failed = true;
1282+
}
1283+
}
12711284

12721285
if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed)
12731286
phylink_pcs_enable(pl->pcs);
12741287

12751288
err = phylink_pcs_config(pl->pcs, pl->pcs_neg_mode, state,
12761289
!!(pl->link_config.pause & MLO_PAUSE_AN));
1277-
if (err < 0)
1278-
phylink_err(pl, "pcs_config failed: %pe\n",
1279-
ERR_PTR(err));
1280-
else if (err > 0)
1290+
if (err < 0) {
1291+
phylink_err(pl, "pcs_config failed: %pe\n", ERR_PTR(err));
1292+
pl->major_config_failed = true;
1293+
} else if (err > 0) {
12811294
restart = true;
1295+
}
12821296

12831297
if (restart)
12841298
phylink_pcs_an_restart(pl);
12851299

12861300
if (pl->mac_ops->mac_finish) {
12871301
err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode,
12881302
state->interface);
1289-
if (err < 0)
1303+
if (err < 0) {
12901304
phylink_err(pl, "mac_finish failed: %pe\n",
12911305
ERR_PTR(err));
1306+
1307+
pl->major_config_failed = true;
1308+
}
12921309
}
12931310

12941311
if (pl->phydev && pl->phy_ib_mode) {
12951312
err = phy_config_inband(pl->phydev, pl->phy_ib_mode);
1296-
if (err < 0)
1313+
if (err < 0) {
12971314
phylink_err(pl, "phy_config_inband: %pe\n",
12981315
ERR_PTR(err));
1316+
1317+
pl->major_config_failed = true;
1318+
}
12991319
}
13001320

13011321
if (pl->sfp_bus) {
@@ -1639,6 +1659,12 @@ static void phylink_resolve(struct work_struct *w)
16391659
}
16401660
}
16411661

1662+
/* If configuration of the interface failed, force the link down
1663+
* until we get a successful configuration.
1664+
*/
1665+
if (pl->major_config_failed)
1666+
link_state.link = false;
1667+
16421668
if (link_state.link != cur_link_state) {
16431669
pl->old_link_state = link_state.link;
16441670
if (!link_state.link)

0 commit comments

Comments
 (0)