hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
....@@ -496,6 +496,7 @@
496496 reg |= XGBE_KR_TRAINING_ENABLE;
497497 reg |= XGBE_KR_TRAINING_START;
498498 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg);
499
+ pdata->kr_start_time = jiffies;
499500
500501 netif_dbg(pdata, link, pdata->netdev,
501502 "KR training initiated\n");
....@@ -631,6 +632,8 @@
631632 xgbe_an_disable(pdata);
632633
633634 xgbe_switch_mode(pdata);
635
+
636
+ pdata->an_result = XGBE_AN_READY;
634637
635638 xgbe_an_restart(pdata);
636639
....@@ -1275,9 +1278,30 @@
12751278 static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata)
12761279 {
12771280 unsigned long link_timeout;
1281
+ unsigned long kr_time;
1282
+ int wait;
12781283
12791284 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
12801285 if (time_after(jiffies, link_timeout)) {
1286
+ if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) &&
1287
+ pdata->phy.autoneg == AUTONEG_ENABLE) {
1288
+ /* AN restart should not happen while KR training is in progress.
1289
+ * The while loop ensures no AN restart during KR training,
1290
+ * waits up to 500ms and AN restart is triggered only if KR
1291
+ * training is failed.
1292
+ */
1293
+ wait = XGBE_KR_TRAINING_WAIT_ITER;
1294
+ while (wait--) {
1295
+ kr_time = pdata->kr_start_time +
1296
+ msecs_to_jiffies(XGBE_AN_MS_TIMEOUT);
1297
+ if (time_after(jiffies, kr_time))
1298
+ break;
1299
+ /* AN restart is not required, if AN result is COMPLETE */
1300
+ if (pdata->an_result == XGBE_AN_COMPLETE)
1301
+ return;
1302
+ usleep_range(10000, 11000);
1303
+ }
1304
+ }
12811305 netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
12821306 xgbe_phy_config_aneg(pdata);
12831307 }
....@@ -1288,7 +1312,7 @@
12881312 return pdata->phy_if.phy_impl.an_outcome(pdata);
12891313 }
12901314
1291
-static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
1315
+static bool xgbe_phy_status_result(struct xgbe_prv_data *pdata)
12921316 {
12931317 struct ethtool_link_ksettings *lks = &pdata->phy.lks;
12941318 enum xgbe_mode mode;
....@@ -1323,8 +1347,13 @@
13231347
13241348 pdata->phy.duplex = DUPLEX_FULL;
13251349
1326
- if (xgbe_set_mode(pdata, mode) && pdata->an_again)
1350
+ if (!xgbe_set_mode(pdata, mode))
1351
+ return false;
1352
+
1353
+ if (pdata->an_again)
13271354 xgbe_phy_reconfig_aneg(pdata);
1355
+
1356
+ return true;
13281357 }
13291358
13301359 static void xgbe_phy_status(struct xgbe_prv_data *pdata)
....@@ -1354,7 +1383,8 @@
13541383 return;
13551384 }
13561385
1357
- xgbe_phy_status_result(pdata);
1386
+ if (xgbe_phy_status_result(pdata))
1387
+ return;
13581388
13591389 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
13601390 clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
....@@ -1390,8 +1420,10 @@
13901420 /* Disable auto-negotiation */
13911421 xgbe_an_disable_all(pdata);
13921422
1393
- if (pdata->dev_irq != pdata->an_irq)
1423
+ if (pdata->dev_irq != pdata->an_irq) {
13941424 devm_free_irq(pdata->dev, pdata->an_irq, pdata);
1425
+ tasklet_kill(&pdata->tasklet_an);
1426
+ }
13951427
13961428 pdata->phy_if.phy_impl.stop(pdata);
13971429