Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: 7c12aa08779c ("amd-xgbe: Move the PHY support into amd-xgbe")
Co-developed-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Acked-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Raju Rangoju and committed by
Jakub Kicinski
926446ae 579923d8

+26
+24
drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
··· 496 496 reg |= XGBE_KR_TRAINING_ENABLE; 497 497 reg |= XGBE_KR_TRAINING_START; 498 498 XMDIO_WRITE(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_10GBR_PMD_CTRL, reg); 499 + pdata->kr_start_time = jiffies; 499 500 500 501 netif_dbg(pdata, link, pdata->netdev, 501 502 "KR training initiated\n"); ··· 632 631 xgbe_an_disable(pdata); 633 632 634 633 xgbe_switch_mode(pdata); 634 + 635 + pdata->an_result = XGBE_AN_READY; 635 636 636 637 xgbe_an_restart(pdata); 637 638 ··· 1278 1275 static void xgbe_check_link_timeout(struct xgbe_prv_data *pdata) 1279 1276 { 1280 1277 unsigned long link_timeout; 1278 + unsigned long kr_time; 1279 + int wait; 1281 1280 1282 1281 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ); 1283 1282 if (time_after(jiffies, link_timeout)) { 1283 + if ((xgbe_cur_mode(pdata) == XGBE_MODE_KR) && 1284 + pdata->phy.autoneg == AUTONEG_ENABLE) { 1285 + /* AN restart should not happen while KR training is in progress. 1286 + * The while loop ensures no AN restart during KR training, 1287 + * waits up to 500ms and AN restart is triggered only if KR 1288 + * training is failed. 1289 + */ 1290 + wait = XGBE_KR_TRAINING_WAIT_ITER; 1291 + while (wait--) { 1292 + kr_time = pdata->kr_start_time + 1293 + msecs_to_jiffies(XGBE_AN_MS_TIMEOUT); 1294 + if (time_after(jiffies, kr_time)) 1295 + break; 1296 + /* AN restart is not required, if AN result is COMPLETE */ 1297 + if (pdata->an_result == XGBE_AN_COMPLETE) 1298 + return; 1299 + usleep_range(10000, 11000); 1300 + } 1301 + } 1284 1302 netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n"); 1285 1303 xgbe_phy_config_aneg(pdata); 1286 1304 }
+2
drivers/net/ethernet/amd/xgbe/xgbe.h
··· 290 290 /* Auto-negotiation */ 291 291 #define XGBE_AN_MS_TIMEOUT 500 292 292 #define XGBE_LINK_TIMEOUT 5 293 + #define XGBE_KR_TRAINING_WAIT_ITER 50 293 294 294 295 #define XGBE_SGMII_AN_LINK_STATUS BIT(1) 295 296 #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) ··· 1281 1280 unsigned int parallel_detect; 1282 1281 unsigned int fec_ability; 1283 1282 unsigned long an_start; 1283 + unsigned long kr_start_time; 1284 1284 enum xgbe_an_mode an_mode; 1285 1285 1286 1286 /* I2C support */