@@ -81,6 +81,7 @@ struct phylink {
81
81
unsigned int pcs_state ;
82
82
83
83
bool link_failed ;
84
+ bool major_config_failed ;
84
85
bool mac_supports_eee_ops ;
85
86
bool mac_supports_eee ;
86
87
bool phy_enable_tx_lpi ;
@@ -1216,12 +1217,16 @@ static void phylink_major_config(struct phylink *pl, bool restart,
1216
1217
phylink_an_mode_str (pl -> req_link_an_mode ),
1217
1218
phy_modes (state -> interface ));
1218
1219
1220
+ pl -> major_config_failed = false;
1221
+
1219
1222
if (pl -> mac_ops -> mac_select_pcs ) {
1220
1223
pcs = pl -> mac_ops -> mac_select_pcs (pl -> config , state -> interface );
1221
1224
if (IS_ERR (pcs )) {
1222
1225
phylink_err (pl ,
1223
1226
"mac_select_pcs unexpectedly failed: %pe\n" ,
1224
1227
pcs );
1228
+
1229
+ pl -> major_config_failed = true;
1225
1230
return ;
1226
1231
}
1227
1232
@@ -1243,6 +1248,7 @@ static void phylink_major_config(struct phylink *pl, bool restart,
1243
1248
if (err < 0 ) {
1244
1249
phylink_err (pl , "mac_prepare failed: %pe\n" ,
1245
1250
ERR_PTR (err ));
1251
+ pl -> major_config_failed = true;
1246
1252
return ;
1247
1253
}
1248
1254
}
@@ -1266,36 +1272,50 @@ static void phylink_major_config(struct phylink *pl, bool restart,
1266
1272
1267
1273
phylink_mac_config (pl , state );
1268
1274
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
+ }
1271
1284
1272
1285
if (pl -> pcs_state == PCS_STATE_STARTING || pcs_changed )
1273
1286
phylink_pcs_enable (pl -> pcs );
1274
1287
1275
1288
err = phylink_pcs_config (pl -> pcs , pl -> pcs_neg_mode , state ,
1276
1289
!!(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 ) {
1281
1294
restart = true;
1295
+ }
1282
1296
1283
1297
if (restart )
1284
1298
phylink_pcs_an_restart (pl );
1285
1299
1286
1300
if (pl -> mac_ops -> mac_finish ) {
1287
1301
err = pl -> mac_ops -> mac_finish (pl -> config , pl -> act_link_an_mode ,
1288
1302
state -> interface );
1289
- if (err < 0 )
1303
+ if (err < 0 ) {
1290
1304
phylink_err (pl , "mac_finish failed: %pe\n" ,
1291
1305
ERR_PTR (err ));
1306
+
1307
+ pl -> major_config_failed = true;
1308
+ }
1292
1309
}
1293
1310
1294
1311
if (pl -> phydev && pl -> phy_ib_mode ) {
1295
1312
err = phy_config_inband (pl -> phydev , pl -> phy_ib_mode );
1296
- if (err < 0 )
1313
+ if (err < 0 ) {
1297
1314
phylink_err (pl , "phy_config_inband: %pe\n" ,
1298
1315
ERR_PTR (err ));
1316
+
1317
+ pl -> major_config_failed = true;
1318
+ }
1299
1319
}
1300
1320
1301
1321
if (pl -> sfp_bus ) {
@@ -1639,6 +1659,12 @@ static void phylink_resolve(struct work_struct *w)
1639
1659
}
1640
1660
}
1641
1661
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
+
1642
1668
if (link_state .link != cur_link_state ) {
1643
1669
pl -> old_link_state = link_state .link ;
1644
1670
if (!link_state .link )
0 commit comments