Skip to content

Commit 926446a

Browse files
RajuRangojukuba-moo
authored andcommitted
amd-xgbe: Delay AN timeout during KR training
AN restart triggered during KR training not only aborts the KR training process but also move the HW to unstable state. Driver has to wait upto 500ms or until the KR training is completed before restarting AN cycle. Fixes: 7c12aa0 ("amd-xgbe: Move the PHY support into amd-xgbe") Co-developed-by: Sudheesh Mavila <[email protected]> Signed-off-by: Sudheesh Mavila <[email protected]> Signed-off-by: Raju Rangoju <[email protected]> Acked-by: Shyam Sundar S K <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 579923d commit 926446a

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

drivers/net/ethernet/amd/xgbe/xgbe-mdio.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,7 @@ static enum xgbe_an xgbe_an73_tx_training(struct xgbe_prv_data *pdata,
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");
@@ -632,6 +633,8 @@ static enum xgbe_an xgbe_an73_incompat_link(struct xgbe_prv_data *pdata)
632633

633634
xgbe_switch_mode(pdata);
634635

636+
pdata->an_result = XGBE_AN_READY;
637+
635638
xgbe_an_restart(pdata);
636639

637640
return XGBE_AN_INCOMPAT_LINK;
@@ -1275,9 +1278,30 @@ static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
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
}

drivers/net/ethernet/amd/xgbe/xgbe.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@
290290
/* Auto-negotiation */
291291
#define XGBE_AN_MS_TIMEOUT 500
292292
#define XGBE_LINK_TIMEOUT 5
293+
#define XGBE_KR_TRAINING_WAIT_ITER 50
293294

294295
#define XGBE_SGMII_AN_LINK_STATUS BIT(1)
295296
#define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
@@ -1280,6 +1281,7 @@ struct xgbe_prv_data {
12801281
unsigned int parallel_detect;
12811282
unsigned int fec_ability;
12821283
unsigned long an_start;
1284+
unsigned long kr_start_time;
12831285
enum xgbe_an_mode an_mode;
12841286

12851287
/* I2C support */

0 commit comments

Comments
 (0)