aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch459
1 files changed, 459 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch
new file mode 100644
index 00000000..2ec5d97c
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9051-amd-xgbe-Add-support-for-10Mbps.patch
@@ -0,0 +1,459 @@
+From f9c00a709f69bd4415a08b8cd84c0cf70e678287 Mon Sep 17 00:00:00 2001
+From: rgaridap <Ramesh.Garidapuri@amd.com>
+Date: Fri, 3 Jun 2022 13:15:26 +0530
+Subject: [PATCH 51/57] amd-xgbe: Add support for 10Mbps
+
+Adds the support for 10Mbps speed in SFP mode.
+Note: All the relevant changes for enabling 10Mbps in RJ45 are also
+included in the patch, however, the current changes only work for
+AIC2-phy not the onboard phy. The onboard AQR113 PHY fails to
+complete AN and linkup at 10Mbps.
+
+Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
+Change-Id: I0aff49cfe99b3b951b2b46259b28256ee0a19c81
+---
+ drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +
+ drivers/net/ethernet/amd/xgbe/xgbe-mdio.c | 25 +++++
+ drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 113 +++++++++++++++++---
+ drivers/net/ethernet/amd/xgbe/xgbe.h | 2 +
+ 4 files changed, 130 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+index d5fd49dd25f3..e5cc96bc70ad 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+@@ -807,6 +807,9 @@ static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed)
+ unsigned int ss;
+
+ switch (speed) {
++ case SPEED_10:
++ ss = 0x07;
++ break;
+ case SPEED_1000:
+ ss = 0x03;
+ break;
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+index 944271556e0c..d0b2179e9078 100755
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-mdio.c
+@@ -274,6 +274,15 @@ static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata)
+ pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
+ }
+
++static void xgbe_sgmii_10_mode(struct xgbe_prv_data *pdata)
++{
++ /* Set MAC to 10M speed */
++ pdata->hw_if.set_speed(pdata, SPEED_10);
++
++ /* Call PHY implementation support to complete rate change */
++ pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_10);
++}
++
+ static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
+ {
+ /* Set MAC to 1G speed */
+@@ -306,6 +315,9 @@ static void xgbe_change_mode(struct xgbe_prv_data *pdata,
+ case XGBE_MODE_KR:
+ xgbe_kr_mode(pdata);
+ break;
++ case XGBE_MODE_SGMII_10:
++ xgbe_sgmii_10_mode(pdata);
++ break;
+ case XGBE_MODE_SGMII_100:
+ xgbe_sgmii_100_mode(pdata);
+ break;
+@@ -1087,6 +1099,8 @@ static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
+ static const char *xgbe_phy_speed_string(int speed)
+ {
+ switch (speed) {
++ case SPEED_10:
++ return "10Mbps";
+ case SPEED_100:
+ return "100Mbps";
+ case SPEED_1000:
+@@ -1174,6 +1188,7 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
+ case XGBE_MODE_KX_1000:
+ case XGBE_MODE_KX_2500:
+ case XGBE_MODE_KR:
++ case XGBE_MODE_SGMII_10:
+ case XGBE_MODE_SGMII_100:
+ case XGBE_MODE_SGMII_1000:
+ case XGBE_MODE_X:
+@@ -1242,6 +1257,8 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode)
+ xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
+ } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
+ xgbe_set_mode(pdata, XGBE_MODE_SGMII_100);
++ } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_10)) {
++ xgbe_set_mode(pdata, XGBE_MODE_SGMII_10);
+ } else {
+ enable_irq(pdata->an_irq);
+ ret = -EINVAL;
+@@ -1331,6 +1348,9 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
+ if(pdata->an_mode != XGBE_AN_MODE_MDIO) {
+
+ switch (mode) {
++ case XGBE_MODE_SGMII_10:
++ pdata->phy.speed = SPEED_10;
++ break;
+ case XGBE_MODE_SGMII_100:
+ pdata->phy.speed = SPEED_100;
+ break;
+@@ -1470,6 +1490,7 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
+ /* Set initial mode - call the mode setting routines
+ * directly to insure we are properly configured
+ */
++
+ if (xgbe_use_mode(pdata, XGBE_MODE_KR)) {
+ xgbe_kr_mode(pdata);
+ } else if (xgbe_use_mode(pdata, XGBE_MODE_KX_2500)) {
+@@ -1484,6 +1505,8 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
+ xgbe_sgmii_1000_mode(pdata);
+ } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
+ xgbe_sgmii_100_mode(pdata);
++ } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_10)) {
++ xgbe_sgmii_10_mode(pdata);
+ } else {
+ ret = -EINVAL;
+ goto err_irq;
+@@ -1581,6 +1604,8 @@ static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
+ return SPEED_1000;
+ else if (XGBE_ADV(lks, 100baseT_Full))
+ return SPEED_100;
++ else if (XGBE_ADV(lks, 10baseT_Full))
++ return SPEED_10;
+
+ return SPEED_UNKNOWN;
+ }
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+index 2135c521f6e2..de53e636b049 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
++++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+@@ -124,6 +124,7 @@
+ #include "xgbe.h"
+ #include "xgbe-common.h"
+
++#define XGBE_PHY_PORT_SPEED_10 BIT(0)
+ #define XGBE_PHY_PORT_SPEED_100 BIT(1)
+ #define XGBE_PHY_PORT_SPEED_1000 BIT(2)
+ #define XGBE_PHY_PORT_SPEED_2500 BIT(3)
+@@ -763,6 +764,8 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
+ XGBE_SET_SUP(lks, Pause);
+ XGBE_SET_SUP(lks, Asym_Pause);
+ if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10)
++ XGBE_SET_SUP(lks, 10baseT_Full);
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
+ XGBE_SET_SUP(lks, 100baseT_Full);
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
+@@ -1561,6 +1564,17 @@ static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata)
+ xgbe_phy_phydev_flowctrl(pdata);
+
+ switch (pdata->an_status & XGBE_SGMII_AN_LINK_SPEED) {
++ case XGBE_SGMII_AN_LINK_SPEED_10:
++ if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) {
++ XGBE_SET_LP_ADV(lks, 10baseT_Full);
++ mode = XGBE_MODE_SGMII_10;
++ } else {
++ /* Half-duplex not supported */
++ XGBE_SET_LP_ADV(lks, 10baseT_Half);
++ mode = XGBE_MODE_UNKNOWN;
++ }
++ break;
++
+ case XGBE_SGMII_AN_LINK_SPEED_100:
+ if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) {
+ XGBE_SET_LP_ADV(lks, 100baseT_Full);
+@@ -1677,7 +1691,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
+ switch (phy_data->sfp_base) {
+ case XGBE_SFP_BASE_1000_T:
+ if (phy_data->phydev &&
+- (phy_data->phydev->speed == SPEED_100))
++ (phy_data->phydev->speed == SPEED_10))
++ mode = XGBE_MODE_SGMII_10;
++ else if (phy_data->phydev &&
++ (phy_data->phydev->speed == SPEED_100))
+ mode = XGBE_MODE_SGMII_100;
+ else
+ mode = XGBE_MODE_SGMII_1000;
+@@ -1692,7 +1709,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
+ break;
+ default:
+ if (phy_data->phydev &&
+- (phy_data->phydev->speed == SPEED_100))
++ (phy_data->phydev->speed == SPEED_10))
++ mode = XGBE_MODE_SGMII_10;
++ else if (phy_data->phydev &&
++ (phy_data->phydev->speed == SPEED_100))
+ mode = XGBE_MODE_SGMII_100;
+ else
+ mode = XGBE_MODE_SGMII_1000;
+@@ -1805,30 +1825,40 @@ static enum xgbe_mode xgbe_phy_mdio_an_outcome(struct xgbe_prv_data *pdata)
+ 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->phydev->speed == SPEED_10) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10)
++ mode = XGBE_MODE_SGMII_10;
++ }
++ else 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;
++ 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->phydev->speed == SPEED_10) {
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10)
++ mode = XGBE_MODE_SGMII_10;
++ }
++ else 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;
++ mode = XGBE_MODE_KX_2500;
+ }
+ break;
+ case PHY_INTERFACE_MODE_2500BASEX:
+@@ -1904,8 +1934,11 @@ static void xgbe_phy_an_advertising(struct xgbe_prv_data *pdata,
+ (phy_data->phydev->speed == SPEED_2500)) {
+ netif_dbg(pdata, link, pdata->netdev, "advertising 2.5G speed\n");
+ XGBE_SET_ADV(dlks, 2500baseX_Full);
+- }
+- else
++ } else if (phy_data->phydev &&
++ (phy_data->phydev->speed == SPEED_10)) {
++ netif_dbg(pdata, link, pdata->netdev, "advertising 10M speed\n");
++ XGBE_SET_ADV(dlks, 10baseT_Full);
++ } else
+ XGBE_SET_ADV(dlks, 1000baseKX_Full);
+ break;
+ case XGBE_PORT_MODE_10GBASE_R:
+@@ -1947,7 +1980,6 @@ static int xgbe_phy_an_config(struct xgbe_prv_data *pdata)
+ linkmode_and(phy_data->phydev->advertising,
+ phy_data->phydev->supported,
+ lks->link_modes.advertising);
+-
+ if (pdata->phy.autoneg != AUTONEG_ENABLE) {
+ phy_data->phydev->speed = pdata->phy.speed;
+ phy_data->phydev->duplex = pdata->phy.duplex;
+@@ -2332,6 +2364,20 @@ static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata)
+ netif_dbg(pdata, link, pdata->netdev, "100MbE SGMII mode set\n");
+ }
+
++static void xgbe_phy_sgmii_10_mode(struct xgbe_prv_data *pdata)
++{
++ struct xgbe_phy_data *phy_data = pdata->phy_data;
++
++ xgbe_phy_set_redrv_mode(pdata);
++
++ /* 10M/SGMII */
++ xgbe_phy_perform_ratechange(pdata, 1, 0);
++
++ phy_data->cur_mode = XGBE_MODE_SGMII_10;
++
++ netif_dbg(pdata, link, pdata->netdev, "10MbE SGMII mode set\n");
++}
++
+ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
+ {
+ struct xgbe_phy_data *phy_data = pdata->phy_data;
+@@ -2394,6 +2440,7 @@ static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata)
+ else if (phy_data->mdio_an_mode)
+ return XGBE_MODE_KR;
+ switch (xgbe_phy_cur_mode(pdata)) {
++ case XGBE_MODE_SGMII_10:
+ case XGBE_MODE_SGMII_100:
+ case XGBE_MODE_SGMII_1000:
+ case XGBE_MODE_KX_2500:
+@@ -2462,6 +2509,8 @@ static enum xgbe_mode xgbe_phy_get_baset_mode(struct xgbe_phy_data *phy_data,
+ int speed)
+ {
+ switch (speed) {
++ case SPEED_10:
++ return XGBE_MODE_SGMII_10;
+ case SPEED_100:
+ return XGBE_MODE_SGMII_100;
+ case SPEED_1000:
+@@ -2479,6 +2528,8 @@ static enum xgbe_mode xgbe_phy_get_sfp_mode(struct xgbe_phy_data *phy_data,
+ int speed)
+ {
+ switch (speed) {
++ case SPEED_10:
++ return XGBE_MODE_SGMII_10;
+ case SPEED_100:
+ return XGBE_MODE_SGMII_100;
+ case SPEED_1000:
+@@ -2553,6 +2604,9 @@ static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
+ case XGBE_MODE_KR:
+ xgbe_phy_kr_mode(pdata);
+ break;
++ case XGBE_MODE_SGMII_10:
++ xgbe_phy_sgmii_10_mode(pdata);
++ break;
+ case XGBE_MODE_SGMII_100:
+ xgbe_phy_sgmii_100_mode(pdata);
+ break;
+@@ -2609,6 +2663,9 @@ static bool xgbe_phy_use_baset_mode(struct xgbe_prv_data *pdata,
+ struct ethtool_link_ksettings *lks = &pdata->phy.lks;
+
+ switch (mode) {
++ case XGBE_MODE_SGMII_10:
++ return xgbe_phy_check_mode(pdata, mode,
++ XGBE_ADV(lks, 10baseT_Full));
+ case XGBE_MODE_SGMII_100:
+ return xgbe_phy_check_mode(pdata, mode,
+ XGBE_ADV(lks, 100baseT_Full));
+@@ -2638,6 +2695,11 @@ static bool xgbe_phy_use_sfp_mode(struct xgbe_prv_data *pdata,
+ return false;
+ return xgbe_phy_check_mode(pdata, mode,
+ XGBE_ADV(lks, 1000baseX_Full));
++ case XGBE_MODE_SGMII_10:
++ if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
++ return false;
++ return xgbe_phy_check_mode(pdata, mode,
++ XGBE_ADV(lks, 10baseT_Full));
+ case XGBE_MODE_SGMII_100:
+ if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
+ return false;
+@@ -2734,6 +2796,10 @@ static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data,
+ int speed)
+ {
+ switch (speed) {
++ case SPEED_10:
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10)
++ return true;
++ break;
+ case SPEED_100:
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
+ return true;
+@@ -2760,6 +2826,8 @@ static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_phy_data *phy_data,
+ int speed)
+ {
+ switch (speed) {
++ case SPEED_10:
++ return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000);
+ case SPEED_100:
+ return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000);
+ case SPEED_1000:
+@@ -3115,7 +3183,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
+ return false;
+ break;
+ case XGBE_PORT_MODE_1000BASE_T:
+- if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
++ if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) ||
++ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000))
+ return false;
+ break;
+@@ -3124,13 +3193,15 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
+ return false;
+ break;
+ case XGBE_PORT_MODE_NBASE_T:
+- if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
++ if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) ||
++ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500))
+ return false;
+ break;
+ case XGBE_PORT_MODE_10GBASE_T:
+- if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
++ if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) ||
++ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
+@@ -3141,7 +3212,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
+ return false;
+ break;
+ case XGBE_PORT_MODE_SFP:
+- if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
++ if ((phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) ||
++ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) ||
+ (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
+ return false;
+@@ -3537,6 +3609,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+ XGBE_SET_SUP(lks, Pause);
+ XGBE_SET_SUP(lks, Asym_Pause);
+ XGBE_SET_SUP(lks, TP);
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) {
++ dev_dbg(pdata->dev, "setting 10M support\n");
++ XGBE_SET_SUP(lks, 10baseT_Full);
++ phy_data->start_mode = XGBE_MODE_SGMII_10;
++ }
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
+ XGBE_SET_SUP(lks, 100baseT_Full);
+ phy_data->start_mode = XGBE_MODE_SGMII_100;
+@@ -3567,6 +3644,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+ XGBE_SET_SUP(lks, Pause);
+ XGBE_SET_SUP(lks, Asym_Pause);
+ XGBE_SET_SUP(lks, TP);
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) {
++ XGBE_SET_SUP(lks, 10baseT_Full);
++ phy_data->start_mode = XGBE_MODE_SGMII_10;
++ }
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
+ XGBE_SET_SUP(lks, 100baseT_Full);
+ phy_data->start_mode = XGBE_MODE_SGMII_100;
+@@ -3590,6 +3671,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+ XGBE_SET_SUP(lks, Pause);
+ XGBE_SET_SUP(lks, Asym_Pause);
+ XGBE_SET_SUP(lks, TP);
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10) {
++ XGBE_SET_SUP(lks, 10baseT_Full);
++ phy_data->start_mode = XGBE_MODE_SGMII_10;
++ }
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
+ XGBE_SET_SUP(lks, 100baseT_Full);
+ phy_data->start_mode = XGBE_MODE_SGMII_100;
+@@ -3638,6 +3723,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
+ XGBE_SET_SUP(lks, Asym_Pause);
+ XGBE_SET_SUP(lks, TP);
+ XGBE_SET_SUP(lks, FIBRE);
++ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10)
++ phy_data->start_mode = XGBE_MODE_SGMII_10;
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
+ phy_data->start_mode = XGBE_MODE_SGMII_100;
+ if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
+diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
+index b0e6a837d704..183289e094fb 100644
+--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
++++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
+@@ -292,6 +292,7 @@
+
+ #define XGBE_SGMII_AN_LINK_STATUS BIT(1)
+ #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
++#define XGBE_SGMII_AN_LINK_SPEED_10 0
+ #define XGBE_SGMII_AN_LINK_SPEED_100 0x04
+ #define XGBE_SGMII_AN_LINK_SPEED_1000 0x08
+ #define XGBE_SGMII_AN_LINK_DUPLEX BIT(4)
+@@ -594,6 +595,7 @@ enum xgbe_mode {
+ XGBE_MODE_KX_2500,
+ XGBE_MODE_KR,
+ XGBE_MODE_X,
++ XGBE_MODE_SGMII_10,
+ XGBE_MODE_SGMII_100,
+ XGBE_MODE_SGMII_1000,
+ XGBE_MODE_SFI,
+--
+2.37.3
+