Skip to content

Commit 3228835

Browse files
author
Paolo Abeni
committed
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>
2 parents 7d86aa4 + a8ba129 commit 3228835

3 files changed

Lines changed: 89 additions & 16 deletions

File tree

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,20 +1271,25 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
12711271
if (ret)
12721272
goto err_napi;
12731273

1274+
/* Reset the phy settings */
1275+
ret = xgbe_phy_reset(pdata);
1276+
if (ret)
1277+
goto err_irqs;
1278+
1279+
/* Start the phy */
12741280
ret = phy_if->phy_start(pdata);
12751281
if (ret)
12761282
goto err_irqs;
12771283

12781284
hw_if->enable_tx(pdata);
12791285
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;
12801290

12811291
udp_tunnel_nic_reset_ntf(netdev);
12821292

1283-
/* Reset the phy settings */
1284-
ret = xgbe_phy_reset(pdata);
1285-
if (ret)
1286-
goto err_txrx;
1287-
12881293
netif_tx_start_all_queues(netdev);
12891294

12901295
xgbe_start_timers(pdata);
@@ -1294,10 +1299,6 @@ static int xgbe_start(struct xgbe_prv_data *pdata)
12941299

12951300
return 0;
12961301

1297-
err_txrx:
1298-
hw_if->disable_rx(pdata);
1299-
hw_if->disable_tx(pdata);
1300-
13011302
err_irqs:
13021303
xgbe_free_irqs(pdata);
13031304

drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,7 +1942,7 @@ static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata,
19421942
static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata)
19431943
{
19441944
struct xgbe_phy_data *phy_data = pdata->phy_data;
1945-
unsigned int reg;
1945+
int reg;
19461946

19471947
/* step 2: force PCS to send RX_ADAPT Req to PHY */
19481948
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
@@ -1964,11 +1964,20 @@ static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata)
19641964

19651965
/* Step 4: Check for Block lock */
19661966

1967-
/* Link status is latched low, so read once to clear
1968-
* and then read again to get current state
1969-
*/
1970-
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
19711967
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.
1974+
*/
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+
19721981
if (reg & MDIO_STAT1_LSTATUS) {
19731982
/* If the block lock is found, update the helpers
19741983
* and declare the link up
@@ -2008,6 +2017,48 @@ static void xgbe_phy_rx_adaptation(struct xgbe_prv_data *pdata)
20082017
xgbe_rx_adaptation(pdata);
20092018
}
20102019

2020+
/*
2021+
* xgbe_phy_stop_data_path - Stop TX/RX to prevent packet corruption
2022+
* @pdata: driver private data
2023+
*
2024+
* This function stops the data path (TX and RX) to prevent packet
2025+
* corruption during critical PHY operations like RX adaptation.
2026+
* Must be called before initiating RX adaptation when link goes down.
2027+
*/
2028+
static void xgbe_phy_stop_data_path(struct xgbe_prv_data *pdata)
2029+
{
2030+
if (pdata->data_path_stopped)
2031+
return;
2032+
2033+
/* Stop TX/RX to prevent packet corruption during RX adaptation */
2034+
pdata->hw_if.disable_tx(pdata);
2035+
pdata->hw_if.disable_rx(pdata);
2036+
pdata->data_path_stopped = true;
2037+
2038+
netif_dbg(pdata, link, pdata->netdev,
2039+
"stopping data path for RX adaptation\n");
2040+
}
2041+
2042+
/*
2043+
* xgbe_phy_start_data_path - Re-enable TX/RX after RX adaptation
2044+
* @pdata: driver private data
2045+
*
2046+
* This function re-enables the data path (TX and RX) after RX adaptation
2047+
* has completed successfully. Only called when link is confirmed up.
2048+
*/
2049+
static void xgbe_phy_start_data_path(struct xgbe_prv_data *pdata)
2050+
{
2051+
if (!pdata->data_path_stopped)
2052+
return;
2053+
2054+
pdata->hw_if.enable_rx(pdata);
2055+
pdata->hw_if.enable_tx(pdata);
2056+
pdata->data_path_stopped = false;
2057+
2058+
netif_dbg(pdata, link, pdata->netdev,
2059+
"restarting data path after RX adaptation\n");
2060+
}
2061+
20112062
static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata)
20122063
{
20132064
int reg;
@@ -2801,22 +2852,39 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
28012852
if (pdata->en_rx_adap) {
28022853
/* if the link is available and adaptation is done,
28032854
* declare link up
2855+
*
2856+
* Note: When link is up and adaptation is done, we can
2857+
* safely re-enable the data path if it was stopped
2858+
* for adaptation.
28042859
*/
2805-
if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
2860+
if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done) {
2861+
xgbe_phy_start_data_path(pdata);
28062862
return 1;
2863+
}
28072864
/* If either link is not available or adaptation is not done,
28082865
* retrigger the adaptation logic. (if the mode is not set,
28092866
* then issue mailbox command first)
28102867
*/
2868+
2869+
/* CRITICAL: Stop data path BEFORE triggering RX adaptation
2870+
* to prevent CRC errors from packets corrupted during
2871+
* the adaptation process. This is especially important
2872+
* when AN is OFF in 10G KR mode.
2873+
*/
2874+
xgbe_phy_stop_data_path(pdata);
2875+
28112876
if (pdata->mode_set) {
28122877
xgbe_phy_rx_adaptation(pdata);
28132878
} else {
28142879
pdata->rx_adapt_done = false;
28152880
xgbe_phy_set_mode(pdata, phy_data->cur_mode);
28162881
}
28172882

2818-
if (pdata->rx_adapt_done)
2883+
if (pdata->rx_adapt_done) {
2884+
/* Adaptation complete, safe to re-enable data path */
2885+
xgbe_phy_start_data_path(pdata);
28192886
return 1;
2887+
}
28202888
} else if (reg & MDIO_STAT1_LSTATUS)
28212889
return 1;
28222890

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,10 @@ struct xgbe_prv_data {
12431243
bool en_rx_adap;
12441244
int rx_adapt_retries;
12451245
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;
12461250
bool mode_set;
12471251
bool sph;
12481252
};

0 commit comments

Comments
 (0)