aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch248
1 files changed, 248 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch
new file mode 100644
index 00000000..22a74950
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9041-amd-xgbe-10G-RJ45-support-on-Fox-platform-with-AN-su.patch
@@ -0,0 +1,248 @@
+From 1fb36bba84ceada142324306c29ff5e158f257cb Mon Sep 17 00:00:00 2001
+From: Sudheesh Mavila <sudheesh.mavila@amd.com>
+Date: Mon, 25 Apr 2022 12:40:58 +0530
+Subject: [PATCH 41/48] amd-xgbe: 10G RJ45 support on Fox platform with AN
+ support using MDIO
+
+Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com>
+Signed-off-by: rgaridap <Ramesh.Garidapuri@amd.com>
+Change-Id: If19412f51805064b14d9cfd71d9fbeb8ea365bb0
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 10 ++
+ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 110 ++++++++++++++++++--
+ drivers/net/ethernet/amd/xgbe/xgbe.h | 1 +
+ 3 files changed, 114 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index c370a8027ce3..bc8172c19082 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -1282,6 +1282,12 @@ static int xgbe_phy_reconfig_aneg(struct xgbe_prv_data *pdata)
+
+ static bool xgbe_phy_aneg_done(struct xgbe_prv_data *pdata)
+ {
++ if (pdata->an_mode == XGBE_AN_MODE_MDIO) {
++ if(pdata->phy.link)
++ pdata->an_result = XGBE_AN_COMPLETE;
++ else
++ pdata->an_result = XGBE_AN_NO_LINK;
++ }
+ return (pdata->an_result == XGBE_AN_COMPLETE);
+ }
+
+@@ -1313,6 +1319,8 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
+ else
+ mode = xgbe_phy_status_aneg(pdata);
+
++ if(pdata->an_mode != XGBE_AN_MODE_MDIO) {
++
+ switch (mode) {
+ case XGBE_MODE_SGMII_100:
+ pdata->phy.speed = SPEED_100;
+@@ -1334,6 +1342,8 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
+ pdata->phy.speed = SPEED_UNKNOWN;
+ }
+
++
++ }
+ pdata->phy.duplex = DUPLEX_FULL;
+
+ if (xgbe_set_mode(pdata, mode) && pdata->an_again)
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 1a56a52e0079..8b464b268165 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -380,6 +380,7 @@ struct xgbe_phy_data {
+ /* KR AN support */
+ unsigned int phy_cdr_notrack;
+ unsigned int phy_cdr_delay;
++ unsigned int mdio_an_mode;
+ };
+
+ /* I2C, MDIO and GPIO lines are muxed, so only one device at a time */
+@@ -1764,6 +1765,82 @@ static enum xgbe_mode xgbe_phy_an73_outcome(struct xgbe_prv_data *pdata)
+ return mode;
+ }
+
++static enum xgbe_mode xgbe_phy_mdio_an_outcome(struct xgbe_prv_data *pdata)
++{
++ struct ethtool_link_ksettings *lks = &pdata->phy.lks;
++ enum xgbe_mode mode = XGBE_MODE_UNKNOWN;
++ unsigned int ad_reg, lp_reg;
++ struct xgbe_phy_data *phy_data = pdata->phy_data;
++ if(phy_data->phydev) {
++
++ /* Compare Advertisement and Link Partner register 1 */
++ ad_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_ADVERTISE);
++ lp_reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_LPA);
++ if (lp_reg & 0x400)
++ XGBE_SET_LP_ADV(lks, Pause);
++ if (lp_reg & 0x800)
++ XGBE_SET_LP_ADV(lks, Asym_Pause);
++
++ if (pdata->phy.pause_autoneg) {
++ /* Set flow control based on auto-negotiation result */
++ pdata->phy.tx_pause = 0;
++ pdata->phy.rx_pause = 0;
++
++ if (ad_reg & lp_reg & 0x400) {
++ pdata->phy.tx_pause = 1;
++ pdata->phy.rx_pause = 1;
++ } else if (ad_reg & lp_reg & 0x800) {
++ if (ad_reg & 0x400)
++ pdata->phy.rx_pause = 1;
++ else if (lp_reg & 0x400)
++ pdata->phy.tx_pause = 1;
++ }
++ }
++
++ switch (phy_data->phydev->interface) {
++ case PHY_INTERFACE_MODE_10GKR:
++ if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) && (phy_data->phydev->speed == SPEED_10000))
++ mode = XGBE_MODE_KR;
++ if(phy_data->phydev->speed == SPEED_100) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
++ mode = XGBE_MODE_SGMII_100;
++ } else if (phy_data->phydev->speed == SPEED_1000){
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
++ mode = XGBE_MODE_SGMII_1000;
++ } else if (phy_data->phydev->speed == SPEED_1000) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)
++ mode =XGBE_MODE_KX_2500;
++ }
++ break;
++ case PHY_INTERFACE_MODE_10GBASER:
++ mode = XGBE_MODE_KR;
++ break;
++ case PHY_INTERFACE_MODE_SGMII:
++ if(phy_data->phydev->speed == SPEED_100) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
++ mode = XGBE_MODE_SGMII_100;
++ } else if (phy_data->phydev->speed == SPEED_1000){
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
++ mode = XGBE_MODE_SGMII_1000;
++ } else if (phy_data->phydev->speed == SPEED_1000) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)
++ mode = XGBE_MODE_KX_2500;
++ }
++ break;
++ case PHY_INTERFACE_MODE_2500BASEX:
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)
++ mode = XGBE_MODE_KX_2500;
++ break;
++ default:
++ mode = XGBE_MODE_KR;
++ break;
++ }
++ }
++ pdata->phy.speed = phy_data->phydev->speed;
++ return mode;
++}
++
++
+ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
+ {
+ switch (pdata->an_mode) {
+@@ -1775,6 +1852,8 @@ static enum xgbe_mode xgbe_phy_an_outcome(struct xgbe_prv_data *pdata)
+ return xgbe_phy_an37_outcome(pdata);
+ case XGBE_AN_MODE_CL37_SGMII:
+ return xgbe_phy_an37_sgmii_outcome(pdata);
++ case XGBE_AN_MODE_MDIO:
++ return xgbe_phy_mdio_an_outcome(pdata);
+ default:
+ return XGBE_MODE_UNKNOWN;
+ }
+@@ -1910,7 +1989,10 @@ static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata)
+ case XGBE_PORT_MODE_NBASE_T:
+ return XGBE_AN_MODE_CL37_SGMII;
+ case XGBE_PORT_MODE_10GBASE_T:
+- return XGBE_AN_MODE_CL73;
++ if(phy_data->mdio_an_mode)
++ return XGBE_AN_MODE_MDIO;
++ else
++ return XGBE_AN_MODE_CL73;
+ case XGBE_PORT_MODE_10GBASE_R:
+ return XGBE_AN_MODE_NONE;
+ case XGBE_PORT_MODE_SFP:
+@@ -2201,7 +2283,8 @@ static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata)
+ /* No switching if not 10GBase-T */
+ if (phy_data->port_mode != XGBE_PORT_MODE_10GBASE_T)
+ return xgbe_phy_cur_mode(pdata);
+-
++ else if (phy_data->mdio_an_mode)
++ return XGBE_MODE_KR;
+ switch (xgbe_phy_cur_mode(pdata)) {
+ case XGBE_MODE_SGMII_100:
+ case XGBE_MODE_SGMII_1000:
+@@ -2544,16 +2627,26 @@ static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data,
+ {
+ switch (speed) {
+ case SPEED_100:
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
++ return true;
++ break;
+ case SPEED_1000:
+- return true;
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
++ return true;
++ break;
+ case SPEED_2500:
+- return ((phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T) ||
+- (phy_data->port_mode == XGBE_PORT_MODE_NBASE_T));
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)
++ return ((phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T) ||
++ (phy_data->port_mode == XGBE_PORT_MODE_NBASE_T));
++ break;
+ case SPEED_10000:
+- return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T);
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)
++ return (phy_data->port_mode == XGBE_PORT_MODE_10GBASE_T);
++ break;
+ default:
+ return false;
+ }
++ return false;
+ }
+
+ static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_phy_data *phy_data,
+@@ -2650,6 +2743,8 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
+
+ if (!phy_data->phydev->link)
+ return 0;
++ if (pdata->an_mode == XGBE_AN_MODE_MDIO)
++ return 1;
+ }
+
+ /* Link status is latched low, so read once to clear
+@@ -3339,7 +3434,7 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+
+ /* 10GBase-T support */
+ case XGBE_PORT_MODE_10GBASE_T:
+- //XGBE_SET_SUP(lks, Autoneg);
++ XGBE_SET_SUP(lks, Autoneg);
+ dev_dbg(pdata->dev, "port mode: 10GBase-T\n");
+ XGBE_SET_SUP(lks, Pause);
+ XGBE_SET_SUP(lks, Asym_Pause);
+@@ -3363,6 +3458,7 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+ }
+
+ phy_data->phydev_mode = XGBE_MDIO_MODE_CL45;
++ phy_data->mdio_an_mode = 1;
+ break;
+
+ /* 10GBase-R support */
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index 3305979a9f7c..bd883f00fad0 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -569,6 +569,7 @@ enum xgbe_an_mode {
+ XGBE_AN_MODE_CL73_REDRV,
+ XGBE_AN_MODE_CL37,
+ XGBE_AN_MODE_CL37_SGMII,
++ XGBE_AN_MODE_MDIO,
+ XGBE_AN_MODE_NONE,
+ };
+
+--
+2.37.3
+