@@ -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