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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'amd-xgbe-rx-adaptation-and-phy-handling-fixes'

Raju Rangoju says:

====================
amd-xgbe: RX adaptation and PHY handling fixes

This series fixes several issues in the amd-xgbe driver related to RX
adaptation and PHY handling in 10GBASE-KR mode, particularly when
auto-negotiation is disabled.

Patch 1 fixes link status handling during RX adaptation by correctly
reading the latched link status bit so transient link drops are
detected without losing the current state.

Patch 2 prevents CRC errors that can occur when performing RX
adaptation with auto-negotiation turned off. The driver now stops
TX/RX before re-triggering RX adaptation and only re-enables traffic
once adaptation completes and the link is confirmed up, ensuring
packets are not corrupted during the adaptation window.

Patch 3 restores the intended ordering of PHY reset relative to
phy_start(), making sure PHY settings are reset before the PHY is
started instead of afterwards.
====================

Link: https://patch.msgid.link/20260306111629.1515676-1-Raju.Rangoju@amd.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+89 -16
+10 -9
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
··· 1271 1271 if (ret) 1272 1272 goto err_napi; 1273 1273 1274 + /* Reset the phy settings */ 1275 + ret = xgbe_phy_reset(pdata); 1276 + if (ret) 1277 + goto err_irqs; 1278 + 1279 + /* Start the phy */ 1274 1280 ret = phy_if->phy_start(pdata); 1275 1281 if (ret) 1276 1282 goto err_irqs; 1277 1283 1278 1284 hw_if->enable_tx(pdata); 1279 1285 hw_if->enable_rx(pdata); 1286 + /* Synchronize flag with hardware state after enabling TX/RX. 1287 + * This prevents stale state after device restart cycles. 1288 + */ 1289 + pdata->data_path_stopped = false; 1280 1290 1281 1291 udp_tunnel_nic_reset_ntf(netdev); 1282 - 1283 - /* Reset the phy settings */ 1284 - ret = xgbe_phy_reset(pdata); 1285 - if (ret) 1286 - goto err_txrx; 1287 1292 1288 1293 netif_tx_start_all_queues(netdev); 1289 1294 ··· 1298 1293 clear_bit(XGBE_STOPPED, &pdata->dev_state); 1299 1294 1300 1295 return 0; 1301 - 1302 - err_txrx: 1303 - hw_if->disable_rx(pdata); 1304 - hw_if->disable_tx(pdata); 1305 1296 1306 1297 err_irqs: 1307 1298 xgbe_free_irqs(pdata);
+75 -7
drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
··· 1942 1942 static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata) 1943 1943 { 1944 1944 struct xgbe_phy_data *phy_data = pdata->phy_data; 1945 - unsigned int reg; 1945 + int reg; 1946 1946 1947 1947 /* step 2: force PCS to send RX_ADAPT Req to PHY */ 1948 1948 XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, ··· 1964 1964 1965 1965 /* Step 4: Check for Block lock */ 1966 1966 1967 - /* Link status is latched low, so read once to clear 1968 - * and then read again to get current state 1967 + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1968 + if (reg < 0) 1969 + goto set_mode; 1970 + 1971 + /* Link status is latched low so that momentary link drops 1972 + * can be detected. If link was already down read again 1973 + * to get the latest state. 1969 1974 */ 1970 - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1971 - reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1975 + if (!pdata->phy.link && !(reg & MDIO_STAT1_LSTATUS)) { 1976 + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); 1977 + if (reg < 0) 1978 + goto set_mode; 1979 + } 1980 + 1972 1981 if (reg & MDIO_STAT1_LSTATUS) { 1973 1982 /* If the block lock is found, update the helpers 1974 1983 * and declare the link up ··· 2015 2006 2016 2007 /* perform rx adaptation */ 2017 2008 xgbe_rx_adaptation(pdata); 2009 + } 2010 + 2011 + /* 2012 + * xgbe_phy_stop_data_path - Stop TX/RX to prevent packet corruption 2013 + * @pdata: driver private data 2014 + * 2015 + * This function stops the data path (TX and RX) to prevent packet 2016 + * corruption during critical PHY operations like RX adaptation. 2017 + * Must be called before initiating RX adaptation when link goes down. 2018 + */ 2019 + static void xgbe_phy_stop_data_path(struct xgbe_prv_data *pdata) 2020 + { 2021 + if (pdata->data_path_stopped) 2022 + return; 2023 + 2024 + /* Stop TX/RX to prevent packet corruption during RX adaptation */ 2025 + pdata->hw_if.disable_tx(pdata); 2026 + pdata->hw_if.disable_rx(pdata); 2027 + pdata->data_path_stopped = true; 2028 + 2029 + netif_dbg(pdata, link, pdata->netdev, 2030 + "stopping data path for RX adaptation\n"); 2031 + } 2032 + 2033 + /* 2034 + * xgbe_phy_start_data_path - Re-enable TX/RX after RX adaptation 2035 + * @pdata: driver private data 2036 + * 2037 + * This function re-enables the data path (TX and RX) after RX adaptation 2038 + * has completed successfully. Only called when link is confirmed up. 2039 + */ 2040 + static void xgbe_phy_start_data_path(struct xgbe_prv_data *pdata) 2041 + { 2042 + if (!pdata->data_path_stopped) 2043 + return; 2044 + 2045 + pdata->hw_if.enable_rx(pdata); 2046 + pdata->hw_if.enable_tx(pdata); 2047 + pdata->data_path_stopped = false; 2048 + 2049 + netif_dbg(pdata, link, pdata->netdev, 2050 + "restarting data path after RX adaptation\n"); 2018 2051 } 2019 2052 2020 2053 static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata) ··· 2852 2801 if (pdata->en_rx_adap) { 2853 2802 /* if the link is available and adaptation is done, 2854 2803 * declare link up 2804 + * 2805 + * Note: When link is up and adaptation is done, we can 2806 + * safely re-enable the data path if it was stopped 2807 + * for adaptation. 2855 2808 */ 2856 - if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) 2809 + if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) { 2810 + xgbe_phy_start_data_path(pdata); 2857 2811 return 1; 2812 + } 2858 2813 /* If either link is not available or adaptation is not done, 2859 2814 * retrigger the adaptation logic. (if the mode is not set, 2860 2815 * then issue mailbox command first) 2861 2816 */ 2817 + 2818 + /* CRITICAL: Stop data path BEFORE triggering RX adaptation 2819 + * to prevent CRC errors from packets corrupted during 2820 + * the adaptation process. This is especially important 2821 + * when AN is OFF in 10G KR mode. 2822 + */ 2823 + xgbe_phy_stop_data_path(pdata); 2824 + 2862 2825 if (pdata->mode_set) { 2863 2826 xgbe_phy_rx_adaptation(pdata); 2864 2827 } else { ··· 2880 2815 xgbe_phy_set_mode(pdata, phy_data->cur_mode); 2881 2816 } 2882 2817 2883 - if (pdata->rx_adapt_done) 2818 + if (pdata->rx_adapt_done) { 2819 + /* Adaptation complete, safe to re-enable data path */ 2820 + xgbe_phy_start_data_path(pdata); 2884 2821 return 1; 2822 + } 2885 2823 } else if (reg & MDIO_STAT1_LSTATUS) 2886 2824 return 1; 2887 2825
+4
drivers/net/ethernet/amd/xgbe/xgbe.h
··· 1243 1243 bool en_rx_adap; 1244 1244 int rx_adapt_retries; 1245 1245 bool rx_adapt_done; 1246 + /* Flag to track if data path (TX/RX) was stopped for RX adaptation. 1247 + * This prevents packet corruption during the adaptation window. 1248 + */ 1249 + bool data_path_stopped; 1246 1250 bool mode_set; 1247 1251 bool sph; 1248 1252 };