Skip to content

Commit 4f3b20b

Browse files
RajuRangojuPaolo Abeni
authored andcommitted
amd-xgbe: add support for rx-adaptation
The existing implementation for non-Autonegotiation 10G speed modes does not enable RX adaptation in the Driver and FW. The RX Equalization settings (AFE settings alone) are manually configured and the existing link-up sequence in the driver does not perform rx adaptation process as mentioned in the Synopsys databook. There's a customer request for 10G backplane mode without Auto-negotiation and for the DAC cables of more significant length that follow the non-Autonegotiation mode. These modes require PHY to perform RX Adaptation. The proposed logic adds the necessary changes to Yellow Carp devices to ensure seamless RX Adaptation for 10G-SFI (LONG DAC) and 10G-KR without AN (CL72 not present). The RX adaptation core algorithm is executed by firmware, however, to achieve that a new mailbox sub-command is required to be sent by the driver. Co-developed-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Shyam Sundar S K <Shyam-sundar.S-k@amd.com> Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 3ee217c commit 4f3b20b

File tree

3 files changed

+211
-4
lines changed

3 files changed

+211
-4
lines changed

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,6 +1285,22 @@
12851285
#define MDIO_PMA_RX_CTRL1 0x8051
12861286
#endif
12871287

1288+
#ifndef MDIO_PMA_RX_LSTS
1289+
#define MDIO_PMA_RX_LSTS 0x018020
1290+
#endif
1291+
1292+
#ifndef MDIO_PMA_RX_EQ_CTRL4
1293+
#define MDIO_PMA_RX_EQ_CTRL4 0x0001805C
1294+
#endif
1295+
1296+
#ifndef MDIO_PMA_MP_MISC_STS
1297+
#define MDIO_PMA_MP_MISC_STS 0x0078
1298+
#endif
1299+
1300+
#ifndef MDIO_PMA_PHY_RX_EQ_CEU
1301+
#define MDIO_PMA_PHY_RX_EQ_CEU 0x1800E
1302+
#endif
1303+
12881304
#ifndef MDIO_PCS_DIG_CTRL
12891305
#define MDIO_PCS_DIG_CTRL 0x8000
12901306
#endif
@@ -1395,6 +1411,28 @@
13951411
#define XGBE_PMA_RX_RST_0_RESET_ON 0x10
13961412
#define XGBE_PMA_RX_RST_0_RESET_OFF 0x00
13971413

1414+
#define XGBE_PMA_RX_SIG_DET_0_MASK BIT(4)
1415+
#define XGBE_PMA_RX_SIG_DET_0_ENABLE BIT(4)
1416+
#define XGBE_PMA_RX_SIG_DET_0_DISABLE 0x0000
1417+
1418+
#define XGBE_PMA_RX_VALID_0_MASK BIT(12)
1419+
#define XGBE_PMA_RX_VALID_0_ENABLE BIT(12)
1420+
#define XGBE_PMA_RX_VALID_0_DISABLE 0x0000
1421+
1422+
#define XGBE_PMA_RX_AD_REQ_MASK BIT(12)
1423+
#define XGBE_PMA_RX_AD_REQ_ENABLE BIT(12)
1424+
#define XGBE_PMA_RX_AD_REQ_DISABLE 0x0000
1425+
1426+
#define XGBE_PMA_RX_ADPT_ACK_MASK BIT(12)
1427+
#define XGBE_PMA_RX_ADPT_ACK BIT(12)
1428+
1429+
#define XGBE_PMA_CFF_UPDTM1_VLD BIT(8)
1430+
#define XGBE_PMA_CFF_UPDT0_VLD BIT(9)
1431+
#define XGBE_PMA_CFF_UPDT1_VLD BIT(10)
1432+
#define XGBE_PMA_CFF_UPDT_MASK (XGBE_PMA_CFF_UPDTM1_VLD |\
1433+
XGBE_PMA_CFF_UPDT0_VLD | \
1434+
XGBE_PMA_CFF_UPDT1_VLD)
1435+
13981436
#define XGBE_PMA_PLL_CTRL_MASK BIT(15)
13991437
#define XGBE_PMA_PLL_CTRL_ENABLE BIT(15)
14001438
#define XGBE_PMA_PLL_CTRL_DISABLE 0x0000

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

Lines changed: 168 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ struct xgbe_phy_data {
388388
static DEFINE_MUTEX(xgbe_phy_comm_lock);
389389

390390
static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata);
391+
static void xgbe_phy_rrc(struct xgbe_prv_data *pdata);
392+
static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
393+
unsigned int cmd, unsigned int sub_cmd);
391394

392395
static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata,
393396
struct xgbe_i2c_op *i2c_op)
@@ -2038,6 +2041,93 @@ static void xgbe_phy_set_redrv_mode(struct xgbe_prv_data *pdata)
20382041
xgbe_phy_put_comm_ownership(pdata);
20392042
}
20402043

2044+
#define MAX_RX_ADAPT_RETRIES 1
2045+
#define XGBE_PMA_RX_VAL_SIG_MASK (XGBE_PMA_RX_SIG_DET_0_MASK | \
2046+
XGBE_PMA_RX_VALID_0_MASK)
2047+
2048+
static void xgbe_set_rx_adap_mode(struct xgbe_prv_data *pdata,
2049+
enum xgbe_mode mode)
2050+
{
2051+
if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
2052+
pdata->rx_adapt_retries = 0;
2053+
return;
2054+
}
2055+
2056+
xgbe_phy_perform_ratechange(pdata,
2057+
mode == XGBE_MODE_KR ?
2058+
XGBE_MB_CMD_SET_10G_KR :
2059+
XGBE_MB_CMD_SET_10G_SFI,
2060+
XGBE_MB_SUBCMD_RX_ADAP);
2061+
}
2062+
2063+
static void xgbe_rx_adaptation(struct xgbe_prv_data *pdata)
2064+
{
2065+
struct xgbe_phy_data *phy_data = pdata->phy_data;
2066+
unsigned int reg;
2067+
2068+
/* step 2: force PCS to send RX_ADAPT Req to PHY */
2069+
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
2070+
XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_ENABLE);
2071+
2072+
/* Step 3: Wait for RX_ADAPT ACK from the PHY */
2073+
msleep(200);
2074+
2075+
/* Software polls for coefficient update command (given by local PHY) */
2076+
reg = XMDIO_READ(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_PHY_RX_EQ_CEU);
2077+
2078+
/* Clear the RX_AD_REQ bit */
2079+
XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
2080+
XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_DISABLE);
2081+
2082+
/* Check if coefficient update command is set */
2083+
if ((reg & XGBE_PMA_CFF_UPDT_MASK) != XGBE_PMA_CFF_UPDT_MASK)
2084+
goto set_mode;
2085+
2086+
/* Step 4: Check for Block lock */
2087+
2088+
/* Link status is latched low, so read once to clear
2089+
* and then read again to get current state
2090+
*/
2091+
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2092+
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2093+
if (reg & MDIO_STAT1_LSTATUS) {
2094+
/* If the block lock is found, update the helpers
2095+
* and declare the link up
2096+
*/
2097+
netif_dbg(pdata, link, pdata->netdev, "Block_lock done");
2098+
pdata->rx_adapt_done = true;
2099+
pdata->mode_set = false;
2100+
return;
2101+
}
2102+
2103+
set_mode:
2104+
xgbe_set_rx_adap_mode(pdata, phy_data->cur_mode);
2105+
}
2106+
2107+
static void xgbe_phy_rx_adaptation(struct xgbe_prv_data *pdata)
2108+
{
2109+
unsigned int reg;
2110+
2111+
rx_adapt_reinit:
2112+
reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_LSTS,
2113+
XGBE_PMA_RX_VAL_SIG_MASK);
2114+
2115+
/* step 1: Check for RX_VALID && LF_SIGDET */
2116+
if ((reg & XGBE_PMA_RX_VAL_SIG_MASK) != XGBE_PMA_RX_VAL_SIG_MASK) {
2117+
netif_dbg(pdata, link, pdata->netdev,
2118+
"RX_VALID or LF_SIGDET is unset, issue rrc");
2119+
xgbe_phy_rrc(pdata);
2120+
if (pdata->rx_adapt_retries++ >= MAX_RX_ADAPT_RETRIES) {
2121+
pdata->rx_adapt_retries = 0;
2122+
return;
2123+
}
2124+
goto rx_adapt_reinit;
2125+
}
2126+
2127+
/* perform rx adaptation */
2128+
xgbe_rx_adaptation(pdata);
2129+
}
2130+
20412131
static void xgbe_phy_rx_reset(struct xgbe_prv_data *pdata)
20422132
{
20432133
int reg;
@@ -2103,7 +2193,7 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
21032193
wait = XGBE_RATECHANGE_COUNT;
21042194
while (wait--) {
21052195
if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
2106-
goto reenable_pll;
2196+
goto do_rx_adaptation;
21072197

21082198
usleep_range(1000, 2000);
21092199
}
@@ -2113,6 +2203,20 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
21132203

21142204
/* Reset on error */
21152205
xgbe_phy_rx_reset(pdata);
2206+
goto reenable_pll;
2207+
2208+
do_rx_adaptation:
2209+
if (pdata->en_rx_adap && sub_cmd == XGBE_MB_SUBCMD_RX_ADAP &&
2210+
(cmd == XGBE_MB_CMD_SET_10G_KR || cmd == XGBE_MB_CMD_SET_10G_SFI)) {
2211+
netif_dbg(pdata, link, pdata->netdev,
2212+
"Enabling RX adaptation\n");
2213+
pdata->mode_set = true;
2214+
xgbe_phy_rx_adaptation(pdata);
2215+
/* return from here to avoid enabling PLL ctrl
2216+
* during adaptation phase
2217+
*/
2218+
return;
2219+
}
21162220

21172221
reenable_pll:
21182222
/* Enable PLL re-initialization, not needed for PHY Power Off and RRC cmds */
@@ -2141,6 +2245,31 @@ static void xgbe_phy_power_off(struct xgbe_prv_data *pdata)
21412245
netif_dbg(pdata, link, pdata->netdev, "phy powered off\n");
21422246
}
21432247

2248+
static bool enable_rx_adap(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
2249+
{
2250+
struct xgbe_phy_data *phy_data = pdata->phy_data;
2251+
unsigned int ver;
2252+
2253+
/* Rx-Adaptation is not supported on older platforms(< 0x30H) */
2254+
ver = XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
2255+
if (ver < 0x30)
2256+
return false;
2257+
2258+
/* Re-driver models 4223 && 4227 do not support Rx-Adaptation */
2259+
if (phy_data->redrv &&
2260+
(phy_data->redrv_model == XGBE_PHY_REDRV_MODEL_4223 ||
2261+
phy_data->redrv_model == XGBE_PHY_REDRV_MODEL_4227))
2262+
return false;
2263+
2264+
/* 10G KR mode with AN does not support Rx-Adaptation */
2265+
if (mode == XGBE_MODE_KR &&
2266+
phy_data->port_mode != XGBE_PORT_MODE_BACKPLANE_NO_AUTONEG)
2267+
return false;
2268+
2269+
pdata->en_rx_adap = 1;
2270+
return true;
2271+
}
2272+
21442273
static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
21452274
{
21462275
struct xgbe_phy_data *phy_data = pdata->phy_data;
@@ -2149,7 +2278,12 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
21492278

21502279
/* 10G/SFI */
21512280
if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) {
2281+
pdata->en_rx_adap = 0;
21522282
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI, XGBE_MB_SUBCMD_ACTIVE);
2283+
} else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) &&
2284+
(enable_rx_adap(pdata, XGBE_MODE_SFI))) {
2285+
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI,
2286+
XGBE_MB_SUBCMD_RX_ADAP);
21532287
} else {
21542288
if (phy_data->sfp_cable_len <= 1)
21552289
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_SFI,
@@ -2230,7 +2364,12 @@ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
22302364
xgbe_phy_set_redrv_mode(pdata);
22312365

22322366
/* 10G/KR */
2233-
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_KR, XGBE_MB_SUBCMD_NONE);
2367+
if (enable_rx_adap(pdata, XGBE_MODE_KR))
2368+
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_KR,
2369+
XGBE_MB_SUBCMD_RX_ADAP);
2370+
else
2371+
xgbe_phy_perform_ratechange(pdata, XGBE_MB_CMD_SET_10G_KR,
2372+
XGBE_MB_SUBCMD_NONE);
22342373

22352374
phy_data->cur_mode = XGBE_MODE_KR;
22362375

@@ -2743,8 +2882,11 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
27432882
return 0;
27442883
}
27452884

2746-
if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los)
2885+
if (phy_data->sfp_mod_absent || phy_data->sfp_rx_los) {
2886+
if (pdata->en_rx_adap)
2887+
pdata->rx_adapt_done = false;
27472888
return 0;
2889+
}
27482890
}
27492891

27502892
if (phy_data->phydev) {
@@ -2766,7 +2908,29 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
27662908
*/
27672909
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
27682910
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2769-
if (reg & MDIO_STAT1_LSTATUS)
2911+
2912+
if (pdata->en_rx_adap) {
2913+
/* if the link is available and adaptation is done,
2914+
* declare link up
2915+
*/
2916+
if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
2917+
return 1;
2918+
/* If either link is not available or adaptation is not done,
2919+
* retrigger the adaptation logic. (if the mode is not set,
2920+
* then issue mailbox command first)
2921+
*/
2922+
if (pdata->mode_set) {
2923+
xgbe_phy_rx_adaptation(pdata);
2924+
} else {
2925+
pdata->rx_adapt_done = false;
2926+
xgbe_phy_set_mode(pdata, phy_data->cur_mode);
2927+
}
2928+
2929+
/* check again for the link and adaptation status */
2930+
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
2931+
if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
2932+
return 1;
2933+
} else if (reg & MDIO_STAT1_LSTATUS)
27702934
return 1;
27712935

27722936
if (pdata->phy.autoneg == AUTONEG_ENABLE &&

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ enum xgbe_mb_cmd {
625625

626626
enum xgbe_mb_subcmd {
627627
XGBE_MB_SUBCMD_NONE = 0,
628+
XGBE_MB_SUBCMD_RX_ADAP,
628629

629630
/* 10GbE SFP subcommands */
630631
XGBE_MB_SUBCMD_ACTIVE = 0,
@@ -1316,6 +1317,10 @@ struct xgbe_prv_data {
13161317

13171318
bool debugfs_an_cdr_workaround;
13181319
bool debugfs_an_cdr_track_early;
1320+
bool en_rx_adap;
1321+
int rx_adapt_retries;
1322+
bool rx_adapt_done;
1323+
bool mode_set;
13191324
};
13201325

13211326
/* Function prototypes*/

0 commit comments

Comments
 (0)