diff options
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.patch | 248 |
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 + |