diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch new file mode 100644 index 00000000..a4f4a06e --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch @@ -0,0 +1,365 @@ +From f820ae13017b4926cfadd644bfd2f1f31476d284 Mon Sep 17 00:00:00 2001 +From: Raju Rangoju <Raju.Rangoju@amd.com> +Date: Mon, 11 Apr 2022 19:01:46 +0530 +Subject: [PATCH 44/48] amd-xgbe: RX-Adaptation support for V3000 + +Change-Id: I2329b9414374ab335bc768c1b319ae1c0a55cefc +Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com> +Signed-off-by: rgaridap <Ramesh.Garidapuri@amd.com> +--- + drivers/net/ethernet/amd/xgbe/xgbe-common.h | 38 +++++ + drivers/net/ethernet/amd/xgbe/xgbe-pci.c | 1 + + drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 155 +++++++++++++++++++- + drivers/net/ethernet/amd/xgbe/xgbe.h | 5 + + 4 files changed, 191 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h +index 466273b22f0a..0b8b1e97d2f9 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h +@@ -1285,6 +1285,24 @@ + #define MDIO_PMA_RX_CTRL1 0x8051 + #endif + ++#ifndef MDIO_PMA_RX_LSTS ++#define MDIO_PMA_RX_LSTS 0x018020 ++#endif ++ ++#ifndef MDIO_PMA_RX_EQ_CTRL4 ++//#define MDIO_PMA_RX_EQ_CTRL4 0x003C ++#define MDIO_PMA_RX_EQ_CTRL4 0x0001805C ++#endif ++ ++#ifndef MDIO_PMA_MP_MISC_STS ++#define MDIO_PMA_MP_MISC_STS 0x0078 ++#endif ++ ++#ifndef MDIO_PMA_PHY_RX_EQ_CEU ++//#define MDIO_PMA_PHY_RX_EQ_CEU 0x800E ++#define MDIO_PMA_PHY_RX_EQ_CEU 0x1800E ++#endif ++ + #ifndef MDIO_PCS_DIG_CTRL + #define MDIO_PCS_DIG_CTRL 0x8000 + #endif +@@ -1395,6 +1413,26 @@ + #define XGBE_PMA_RX_RST_0_RESET_ON 0x10 + #define XGBE_PMA_RX_RST_0_RESET_OFF 0x00 + ++#define XGBE_PMA_RX_SIG_DET_0_MASK BIT(4) ++#define XGBE_PMA_RX_SIG_DET_0_ENABLE BIT(4) ++#define XGBE_PMA_RX_SIG_DET_0_DISABLE 0x0000 ++ ++#define XGBE_PMA_RX_VALID_0_MASK BIT(12) ++#define XGBE_PMA_RX_VALID_0_ENABLE BIT(12) ++#define XGBE_PMA_RX_VALID_0_DISABLE 0x0000 ++ ++#define XGBE_PMA_RX_AD_REQ_MASK BIT(12) ++#define XGBE_PMA_RX_AD_REQ_ENABLE BIT(12) ++#define XGBE_PMA_RX_AD_REQ_DISABLE 0x0000 ++ ++#define XGBE_PMA_RX_ADPT_ACK_MASK BIT(12) ++#define XGBE_PMA_RX_ADPT_ACK BIT(12) ++ ++#define XGBE_PMA_CFF_UPDTM1_VLD BIT(8) ++#define XGBE_PMA_CFF_UPDT0_VLD BIT(9) ++#define XGBE_PMA_CFF_UPDT1_VLD BIT(10) ++#define XGBE_PMA_CFF_UPDT_MASK (XGBE_PMA_CFF_UPDTM1_VLD | XGBE_PMA_CFF_UPDT0_VLD | XGBE_PMA_CFF_UPDT1_VLD) ++ + #define XGBE_PMA_PLL_CTRL_MASK BIT(15) + #define XGBE_PMA_PLL_CTRL_ENABLE BIT(15) + #define XGBE_PMA_PLL_CTRL_DISABLE 0x0000 +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c +index 4da4924e7254..0f2ac86ff904 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c +@@ -288,6 +288,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) + + /* Yellow Carp devices do not need rrc */ + pdata->vdata->enable_rrc = 0; ++ pdata->vdata->is_yc = 1; + dev_dbg(dev, "Disabling the RRC on Yellow carp devices\n"); + } else { + pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF; +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +index b66dae94bd54..f0cb4acbf231 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c ++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c +@@ -387,6 +387,10 @@ struct xgbe_phy_data { + static DEFINE_MUTEX(xgbe_phy_comm_lock); + + static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata); ++static void xgbe_phy_rrc(struct xgbe_prv_data *pdata); ++static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode); ++static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata); ++static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata); + + static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata, + struct xgbe_i2c_op *i2c_op) +@@ -2096,15 +2100,97 @@ static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable) + } + } + ++static void xgbe_phy_rx_adaptation(struct xgbe_prv_data *pdata) ++{ ++ /* ++ * step 1: Check for RX_VALID && LF_SIGDET ++ if (yes) { ++ step 2: force PCS to send RX_ADAPT Req to PHY ++ and then, ++ step 3: wait for RX_ADAPT ACK from the PHY ++ if (Yes) { ++ step4: Check for Block lock ++ if (yes) ++ return; ++ else ++ step 5: do mode set ++ } else ++ do mode set ++ } else ++ issue rrc ++ */ ++ ++ int reg; ++ pdata->count = 0; ++ ++rx_adapt_reinit: ++ reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_LSTS, ++ (XGBE_PMA_RX_SIG_DET_0_MASK | XGBE_PMA_RX_VALID_0_MASK)); ++ netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_RX_LSTS reg 0x%x\n", __func__, reg); ++ ++ /* step 1: Check for RX_VALID && LF_SIGDET */ ++ if ((reg & XGBE_PMA_RX_VALID_0_MASK) && (reg & XGBE_PMA_RX_SIG_DET_0_MASK)) { ++ reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, 0xffffffff); ++ netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_RX_EQ_CTRL4 current data 0x%x\n", ++ __func__, reg); ++ ++ /* step 2: force PCS to send RX_ADAPT Req to PHY */ ++ XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, ++ XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_ENABLE); ++ ++ msleep(200); ++ ++ /* step 3: wait for RX_ADAPT ACK from the PHY */ ++ reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_PHY_RX_EQ_CEU, 0xffffffff /*XGBE_PMA_CFF_UPDT_MASK*/); ++ ++ /* Clear the RX_AD_REQ bit */ ++ XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, ++ XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_DISABLE); ++ ++ netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_PHY_RX_EQ_CEU ACK is %s\n", ++ __func__, ((reg & XGBE_PMA_CFF_UPDT_MASK) == XGBE_PMA_CFF_UPDT_MASK) ? "SET" : "NOT_SET"); ++ ++ if ((reg & XGBE_PMA_CFF_UPDT_MASK) == XGBE_PMA_CFF_UPDT_MASK) ++ { ++ /*step 4: Check for Block lock */ ++ ++ /* Link status is latched low, so read once to clear ++ * and then read again to get current state ++ */ ++ reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); ++ reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); ++ if (reg & MDIO_STAT1_LSTATUS) { ++ /* If the block lock is found, declare the link up */ ++ netif_dbg(pdata, link, pdata->netdev, "%s block_lock done\n", __func__); ++ pdata->rx_adapt_done = 1; ++ pdata->mode_set = 0; ++ return; ++ } else { ++ struct xgbe_phy_data *phy_data = pdata->phy_data; ++ xgbe_phy_set_mode(pdata, phy_data->cur_mode); ++ } ++ } else { ++ struct xgbe_phy_data *phy_data = pdata->phy_data; ++ xgbe_phy_set_mode(pdata, phy_data->cur_mode); ++ } ++ } else { ++ netif_dbg(pdata, link, pdata->netdev, "%s either RX_VALID or LF_SIGDET is not set, issuing rrc\n",__func__); ++ xgbe_phy_rrc(pdata); ++ if (pdata->count++ >= 5) ++ return; ++ goto rx_adapt_reinit; ++ } ++} ++ + static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, + unsigned int cmd, unsigned int sub_cmd) + { + unsigned int s0 = 0; + unsigned int wait; ++ struct xgbe_phy_data *phy_data = pdata->phy_data; + + /* Disable PLL re-initialization during FW command processing */ + xgbe_phy_pll_ctrl(pdata, false); +- + /* Log if a previous command did not complete */ + if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) { + netif_dbg(pdata, link, pdata->netdev, +@@ -2125,7 +2211,7 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, + wait = XGBE_RATECHANGE_COUNT; + while (wait--) { + if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) +- goto reenable_pll; ++ goto do_rx_adaptation; + + usleep_range(1000, 2000); + } +@@ -2135,10 +2221,19 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata, + + /* Reset on error */ + xgbe_phy_rx_reset(pdata); ++ goto reenable_pll; ++ ++do_rx_adaptation: ++ dev_dbg(pdata->dev, "%s en_rx_adap %d sfp_cable %d\n", __func__, pdata->en_rx_adap, phy_data->sfp_cable); ++ if (pdata->en_rx_adap && (((cmd == 4) || (cmd == 3)) && (sub_cmd == 1))) { ++ netif_dbg(pdata, link, pdata->netdev, "%s Enabling RX adaptation\n", __func__); ++ pdata->mode_set = 1; ++ xgbe_phy_rx_adaptation(pdata); ++ } + + reenable_pll: + /* Enable PLL re-initialization, not needed for phy_poweroff (0,0) */ +- if (cmd != 0) ++ if ((cmd != 0) || (cmd != 5)) + xgbe_phy_pll_ctrl(pdata, true); + } + +@@ -2171,6 +2266,8 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata) + /* 10G/SFI */ + if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) { + xgbe_phy_perform_ratechange(pdata, 3, 0); ++ } else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) && (pdata->en_rx_adap)) { ++ xgbe_phy_perform_ratechange(pdata, 3, 1); + } else { + if (phy_data->sfp_cable_len <= 1) + xgbe_phy_perform_ratechange(pdata, 3, 1); +@@ -2178,8 +2275,8 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata) + xgbe_phy_perform_ratechange(pdata, 3, 2); + else + xgbe_phy_perform_ratechange(pdata, 3, 3); +- } + ++ } + phy_data->cur_mode = XGBE_MODE_SFI; + + netif_dbg(pdata, link, pdata->netdev, "10GbE SFI mode set\n"); +@@ -2234,7 +2331,10 @@ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata) + xgbe_phy_set_redrv_mode(pdata); + + /* 10G/KR */ +- xgbe_phy_perform_ratechange(pdata, 4, 0); ++ if (pdata->en_rx_adap) { ++ xgbe_phy_perform_ratechange(pdata, 4, 1); ++ } else ++ xgbe_phy_perform_ratechange(pdata, 4, 0); + + phy_data->cur_mode = XGBE_MODE_KR; + +@@ -2751,7 +2851,24 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart) + */ + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); + reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1); +- if (reg & MDIO_STAT1_LSTATUS) ++ ++ if (pdata->en_rx_adap) { ++ if (reg & MDIO_STAT1_LSTATUS) { ++ if (pdata->rx_adapt_done) ++ return 1; ++ else ++ xgbe_phy_rx_adaptation(pdata); ++ } else { ++ if (pdata->mode_set) ++ xgbe_phy_rx_adaptation(pdata); ++ else { ++ pdata->mode_set = 0; ++ pdata->rx_adapt_done = 0; ++ xgbe_phy_set_mode(pdata, phy_data->cur_mode); ++ } ++ } ++ ++ } else if (reg & MDIO_STAT1_LSTATUS) + return 1; + + if (pdata->phy.autoneg == AUTONEG_ENABLE && +@@ -3351,7 +3468,22 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) + /* Backplane support */ + case XGBE_PORT_MODE_BACKPLANE: + XGBE_SET_SUP(lks, Autoneg); +- fallthrough; ++ XGBE_SET_SUP(lks, Pause); ++ XGBE_SET_SUP(lks, Asym_Pause); ++ XGBE_SET_SUP(lks, Backplane); ++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) { ++ XGBE_SET_SUP(lks, 1000baseKX_Full); ++ phy_data->start_mode = XGBE_MODE_KX_1000; ++ } ++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { ++ XGBE_SET_SUP(lks, 10000baseKR_Full); ++ if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) ++ XGBE_SET_SUP(lks, 10000baseR_FEC); ++ phy_data->start_mode = XGBE_MODE_KR; ++ } ++ ++ phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; ++ break; + case XGBE_PORT_MODE_BACKPLANE_NO_AUTONEG: + XGBE_SET_SUP(lks, Pause); + XGBE_SET_SUP(lks, Asym_Pause); +@@ -3365,6 +3497,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) + if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE) + XGBE_SET_SUP(lks, 10000baseR_FEC); + phy_data->start_mode = XGBE_MODE_KR; ++ if (pdata->vdata->is_yc) ++ pdata->en_rx_adap = 1; + } + + phy_data->phydev_mode = XGBE_MDIO_MODE_NONE; +@@ -3454,6 +3588,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) + if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { + XGBE_SET_SUP(lks, 10000baseT_Full); + phy_data->start_mode = XGBE_MODE_KR; ++ if (pdata->vdata->is_yc) ++ pdata->en_rx_adap = 1; + } + + phy_data->phydev_mode = XGBE_MDIO_MODE_CL45; +@@ -3488,8 +3624,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) + phy_data->start_mode = XGBE_MODE_SGMII_100; + if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) + phy_data->start_mode = XGBE_MODE_SGMII_1000; +- if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) ++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) { + phy_data->start_mode = XGBE_MODE_SFI; ++ if (pdata->vdata->is_yc) ++ pdata->en_rx_adap = 1; ++ } + + phy_data->phydev_mode = XGBE_MDIO_MODE_CL22; + +diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h +index 8a5e0c68bc43..1ee48f3b9df5 100644 +--- a/drivers/net/ethernet/amd/xgbe/xgbe.h ++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h +@@ -1014,6 +1014,7 @@ struct xgbe_version_data { + unsigned int rx_desc_prefetch; + unsigned int an_cdr_workaround; + unsigned int enable_rrc; ++ unsigned int is_yc; + }; + + struct xgbe_prv_data { +@@ -1284,6 +1285,10 @@ struct xgbe_prv_data { + + bool debugfs_an_cdr_workaround; + bool debugfs_an_cdr_track_early; ++ bool en_rx_adap; ++ int count; ++ bool rx_adapt_done; ++ bool mode_set; + }; + + /* Function prototypes*/ +-- +2.27.0 + |