aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch
diff options
context:
space:
mode:
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.patch365
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
+