Commit 07445f3c authored by Raju Rangoju's avatar Raju Rangoju Committed by Paolo Abeni

amd-xgbe: Add support for 10 Mbps speed

Add the necessary changes to support 10 Mbps speed for BaseT and SFP
port modes. This is supported in MAC ver >= 30H.
Signed-off-by: default avatarRaju Rangoju <Raju.Rangoju@amd.com>
Link: https://lore.kernel.org/r/20230109101819.747572-1-Raju.Rangoju@amd.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent cbdbb58b
...@@ -807,6 +807,9 @@ static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed) ...@@ -807,6 +807,9 @@ static int xgbe_set_speed(struct xgbe_prv_data *pdata, int speed)
unsigned int ss; unsigned int ss;
switch (speed) { switch (speed) {
case SPEED_10:
ss = 0x07;
break;
case SPEED_1000: case SPEED_1000:
ss = 0x03; ss = 0x03;
break; break;
......
...@@ -274,6 +274,15 @@ static void xgbe_sgmii_1000_mode(struct xgbe_prv_data *pdata) ...@@ -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); 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) static void xgbe_sgmii_100_mode(struct xgbe_prv_data *pdata)
{ {
/* Set MAC to 1G speed */ /* Set MAC to 1G speed */
...@@ -306,6 +315,9 @@ static void xgbe_change_mode(struct xgbe_prv_data *pdata, ...@@ -306,6 +315,9 @@ static void xgbe_change_mode(struct xgbe_prv_data *pdata,
case XGBE_MODE_KR: case XGBE_MODE_KR:
xgbe_kr_mode(pdata); xgbe_kr_mode(pdata);
break; break;
case XGBE_MODE_SGMII_10:
xgbe_sgmii_10_mode(pdata);
break;
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
xgbe_sgmii_100_mode(pdata); xgbe_sgmii_100_mode(pdata);
break; break;
...@@ -1074,6 +1086,8 @@ static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata) ...@@ -1074,6 +1086,8 @@ static const char *xgbe_phy_fc_string(struct xgbe_prv_data *pdata)
static const char *xgbe_phy_speed_string(int speed) static const char *xgbe_phy_speed_string(int speed)
{ {
switch (speed) { switch (speed) {
case SPEED_10:
return "10Mbps";
case SPEED_100: case SPEED_100:
return "100Mbps"; return "100Mbps";
case SPEED_1000: case SPEED_1000:
...@@ -1161,6 +1175,7 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata) ...@@ -1161,6 +1175,7 @@ static int xgbe_phy_config_fixed(struct xgbe_prv_data *pdata)
case XGBE_MODE_KX_1000: case XGBE_MODE_KX_1000:
case XGBE_MODE_KX_2500: case XGBE_MODE_KX_2500:
case XGBE_MODE_KR: case XGBE_MODE_KR:
case XGBE_MODE_SGMII_10:
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
case XGBE_MODE_SGMII_1000: case XGBE_MODE_SGMII_1000:
case XGBE_MODE_X: case XGBE_MODE_X:
...@@ -1222,6 +1237,8 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode) ...@@ -1222,6 +1237,8 @@ static int __xgbe_phy_config_aneg(struct xgbe_prv_data *pdata, bool set_mode)
xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000); xgbe_set_mode(pdata, XGBE_MODE_SGMII_1000);
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) { } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
xgbe_set_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 { } else {
enable_irq(pdata->an_irq); enable_irq(pdata->an_irq);
ret = -EINVAL; ret = -EINVAL;
...@@ -1301,6 +1318,9 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata) ...@@ -1301,6 +1318,9 @@ static void xgbe_phy_status_result(struct xgbe_prv_data *pdata)
mode = xgbe_phy_status_aneg(pdata); mode = xgbe_phy_status_aneg(pdata);
switch (mode) { switch (mode) {
case XGBE_MODE_SGMII_10:
pdata->phy.speed = SPEED_10;
break;
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
pdata->phy.speed = SPEED_100; pdata->phy.speed = SPEED_100;
break; break;
...@@ -1443,6 +1463,8 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata) ...@@ -1443,6 +1463,8 @@ static int xgbe_phy_start(struct xgbe_prv_data *pdata)
xgbe_sgmii_1000_mode(pdata); xgbe_sgmii_1000_mode(pdata);
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) { } else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_100)) {
xgbe_sgmii_100_mode(pdata); xgbe_sgmii_100_mode(pdata);
} else if (xgbe_use_mode(pdata, XGBE_MODE_SGMII_10)) {
xgbe_sgmii_10_mode(pdata);
} else { } else {
ret = -EINVAL; ret = -EINVAL;
goto err_irq; goto err_irq;
...@@ -1540,6 +1562,8 @@ static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata) ...@@ -1540,6 +1562,8 @@ static int xgbe_phy_best_advertised_speed(struct xgbe_prv_data *pdata)
return SPEED_1000; return SPEED_1000;
else if (XGBE_ADV(lks, 100baseT_Full)) else if (XGBE_ADV(lks, 100baseT_Full))
return SPEED_100; return SPEED_100;
else if (XGBE_ADV(lks, 10baseT_Full))
return SPEED_10;
return SPEED_UNKNOWN; return SPEED_UNKNOWN;
} }
......
...@@ -124,6 +124,7 @@ ...@@ -124,6 +124,7 @@
#include "xgbe.h" #include "xgbe.h"
#include "xgbe-common.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_100 BIT(1)
#define XGBE_PHY_PORT_SPEED_1000 BIT(2) #define XGBE_PHY_PORT_SPEED_1000 BIT(2)
#define XGBE_PHY_PORT_SPEED_2500 BIT(3) #define XGBE_PHY_PORT_SPEED_2500 BIT(3)
...@@ -759,6 +760,8 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata) ...@@ -759,6 +760,8 @@ static void xgbe_phy_sfp_phy_settings(struct xgbe_prv_data *pdata)
XGBE_SET_SUP(lks, Pause); XGBE_SET_SUP(lks, Pause);
XGBE_SET_SUP(lks, Asym_Pause); XGBE_SET_SUP(lks, Asym_Pause);
if (phy_data->sfp_base == XGBE_SFP_BASE_1000_T) { 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) if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
XGBE_SET_SUP(lks, 100baseT_Full); XGBE_SET_SUP(lks, 100baseT_Full);
if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
...@@ -1542,6 +1545,16 @@ static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata) ...@@ -1542,6 +1545,16 @@ static enum xgbe_mode xgbe_phy_an37_sgmii_outcome(struct xgbe_prv_data *pdata)
xgbe_phy_phydev_flowctrl(pdata); xgbe_phy_phydev_flowctrl(pdata);
switch (pdata->an_status & XGBE_SGMII_AN_LINK_SPEED) { 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: case XGBE_SGMII_AN_LINK_SPEED_100:
if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) { if (pdata->an_status & XGBE_SGMII_AN_LINK_DUPLEX) {
XGBE_SET_LP_ADV(lks, 100baseT_Full); XGBE_SET_LP_ADV(lks, 100baseT_Full);
...@@ -1658,7 +1671,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata) ...@@ -1658,7 +1671,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
switch (phy_data->sfp_base) { switch (phy_data->sfp_base) {
case XGBE_SFP_BASE_1000_T: case XGBE_SFP_BASE_1000_T:
if (phy_data->phydev && 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; mode = XGBE_MODE_SGMII_100;
else else
mode = XGBE_MODE_SGMII_1000; mode = XGBE_MODE_SGMII_1000;
...@@ -1673,7 +1689,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata) ...@@ -1673,7 +1689,10 @@ static enum xgbe_mode xgbe_phy_an73_redrv_outcome(struct xgbe_prv_data *pdata)
break; break;
default: default:
if (phy_data->phydev && 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; mode = XGBE_MODE_SGMII_100;
else else
mode = XGBE_MODE_SGMII_1000; mode = XGBE_MODE_SGMII_1000;
...@@ -2127,6 +2146,20 @@ static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata) ...@@ -2127,6 +2146,20 @@ static void xgbe_phy_sgmii_100_mode(struct xgbe_prv_data *pdata)
netif_dbg(pdata, link, pdata->netdev, "100MbE SGMII mode set\n"); 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, XGBE_MB_CMD_SET_1G, XGBE_MB_SUBCMD_10MBITS);
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) static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
{ {
struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_phy_data *phy_data = pdata->phy_data;
...@@ -2185,6 +2218,7 @@ static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata) ...@@ -2185,6 +2218,7 @@ static enum xgbe_mode xgbe_phy_switch_baset_mode(struct xgbe_prv_data *pdata)
return xgbe_phy_cur_mode(pdata); return xgbe_phy_cur_mode(pdata);
switch (xgbe_phy_cur_mode(pdata)) { switch (xgbe_phy_cur_mode(pdata)) {
case XGBE_MODE_SGMII_10:
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
case XGBE_MODE_SGMII_1000: case XGBE_MODE_SGMII_1000:
return XGBE_MODE_KR; return XGBE_MODE_KR;
...@@ -2252,6 +2286,8 @@ static enum xgbe_mode xgbe_phy_get_baset_mode(struct xgbe_phy_data *phy_data, ...@@ -2252,6 +2286,8 @@ static enum xgbe_mode xgbe_phy_get_baset_mode(struct xgbe_phy_data *phy_data,
int speed) int speed)
{ {
switch (speed) { switch (speed) {
case SPEED_10:
return XGBE_MODE_SGMII_10;
case SPEED_100: case SPEED_100:
return XGBE_MODE_SGMII_100; return XGBE_MODE_SGMII_100;
case SPEED_1000: case SPEED_1000:
...@@ -2269,6 +2305,8 @@ static enum xgbe_mode xgbe_phy_get_sfp_mode(struct xgbe_phy_data *phy_data, ...@@ -2269,6 +2305,8 @@ static enum xgbe_mode xgbe_phy_get_sfp_mode(struct xgbe_phy_data *phy_data,
int speed) int speed)
{ {
switch (speed) { switch (speed) {
case SPEED_10:
return XGBE_MODE_SGMII_10;
case SPEED_100: case SPEED_100:
return XGBE_MODE_SGMII_100; return XGBE_MODE_SGMII_100;
case SPEED_1000: case SPEED_1000:
...@@ -2343,6 +2381,9 @@ static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode) ...@@ -2343,6 +2381,9 @@ static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode)
case XGBE_MODE_KR: case XGBE_MODE_KR:
xgbe_phy_kr_mode(pdata); xgbe_phy_kr_mode(pdata);
break; break;
case XGBE_MODE_SGMII_10:
xgbe_phy_sgmii_10_mode(pdata);
break;
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
xgbe_phy_sgmii_100_mode(pdata); xgbe_phy_sgmii_100_mode(pdata);
break; break;
...@@ -2399,6 +2440,9 @@ static bool xgbe_phy_use_baset_mode(struct xgbe_prv_data *pdata, ...@@ -2399,6 +2440,9 @@ static bool xgbe_phy_use_baset_mode(struct xgbe_prv_data *pdata,
struct ethtool_link_ksettings *lks = &pdata->phy.lks; struct ethtool_link_ksettings *lks = &pdata->phy.lks;
switch (mode) { switch (mode) {
case XGBE_MODE_SGMII_10:
return xgbe_phy_check_mode(pdata, mode,
XGBE_ADV(lks, 10baseT_Full));
case XGBE_MODE_SGMII_100: case XGBE_MODE_SGMII_100:
return xgbe_phy_check_mode(pdata, mode, return xgbe_phy_check_mode(pdata, mode,
XGBE_ADV(lks, 100baseT_Full)); XGBE_ADV(lks, 100baseT_Full));
...@@ -2428,6 +2472,11 @@ static bool xgbe_phy_use_sfp_mode(struct xgbe_prv_data *pdata, ...@@ -2428,6 +2472,11 @@ static bool xgbe_phy_use_sfp_mode(struct xgbe_prv_data *pdata,
return false; return false;
return xgbe_phy_check_mode(pdata, mode, return xgbe_phy_check_mode(pdata, mode,
XGBE_ADV(lks, 1000baseX_Full)); 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: case XGBE_MODE_SGMII_100:
if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T) if (phy_data->sfp_base != XGBE_SFP_BASE_1000_T)
return false; return false;
...@@ -2520,10 +2569,17 @@ static bool xgbe_phy_valid_speed_basex_mode(struct xgbe_phy_data *phy_data, ...@@ -2520,10 +2569,17 @@ static bool xgbe_phy_valid_speed_basex_mode(struct xgbe_phy_data *phy_data,
} }
} }
static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data, static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_prv_data *pdata,
int speed) int speed)
{ {
struct xgbe_phy_data *phy_data = pdata->phy_data;
unsigned int ver;
switch (speed) { switch (speed) {
case SPEED_10:
/* Supported in ver >= 30H */
ver = XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
return (ver >= 0x30) ? true : false;
case SPEED_100: case SPEED_100:
case SPEED_1000: case SPEED_1000:
return true; return true;
...@@ -2536,10 +2592,17 @@ static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data, ...@@ -2536,10 +2592,17 @@ static bool xgbe_phy_valid_speed_baset_mode(struct xgbe_phy_data *phy_data,
} }
} }
static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_phy_data *phy_data, static bool xgbe_phy_valid_speed_sfp_mode(struct xgbe_prv_data *pdata,
int speed) int speed)
{ {
struct xgbe_phy_data *phy_data = pdata->phy_data;
unsigned int ver;
switch (speed) { switch (speed) {
case SPEED_10:
/* Supported in ver >= 30H */
ver = XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
return (ver >= 0x30) && (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000);
case SPEED_100: case SPEED_100:
return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000); return (phy_data->sfp_speed == XGBE_SFP_SPEED_100_1000);
case SPEED_1000: case SPEED_1000:
...@@ -2586,12 +2649,12 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed) ...@@ -2586,12 +2649,12 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
case XGBE_PORT_MODE_1000BASE_T: case XGBE_PORT_MODE_1000BASE_T:
case XGBE_PORT_MODE_NBASE_T: case XGBE_PORT_MODE_NBASE_T:
case XGBE_PORT_MODE_10GBASE_T: case XGBE_PORT_MODE_10GBASE_T:
return xgbe_phy_valid_speed_baset_mode(phy_data, speed); return xgbe_phy_valid_speed_baset_mode(pdata, speed);
case XGBE_PORT_MODE_1000BASE_X: case XGBE_PORT_MODE_1000BASE_X:
case XGBE_PORT_MODE_10GBASE_R: case XGBE_PORT_MODE_10GBASE_R:
return xgbe_phy_valid_speed_basex_mode(phy_data, speed); return xgbe_phy_valid_speed_basex_mode(phy_data, speed);
case XGBE_PORT_MODE_SFP: case XGBE_PORT_MODE_SFP:
return xgbe_phy_valid_speed_sfp_mode(phy_data, speed); return xgbe_phy_valid_speed_sfp_mode(pdata, speed);
default: default:
return false; return false;
} }
...@@ -2862,6 +2925,12 @@ static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata) ...@@ -2862,6 +2925,12 @@ static int xgbe_phy_mdio_reset_setup(struct xgbe_prv_data *pdata)
static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata) static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
{ {
struct xgbe_phy_data *phy_data = pdata->phy_data; struct xgbe_phy_data *phy_data = pdata->phy_data;
unsigned int ver;
/* 10 Mbps speed is not supported in ver < 30H */
ver = XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER);
if (ver < 0x30 && (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10))
return true;
switch (phy_data->port_mode) { switch (phy_data->port_mode) {
case XGBE_PORT_MODE_BACKPLANE: case XGBE_PORT_MODE_BACKPLANE:
...@@ -2875,7 +2944,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata) ...@@ -2875,7 +2944,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
return false; return false;
break; break;
case XGBE_PORT_MODE_1000BASE_T: 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)) (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000))
return false; return false;
break; break;
...@@ -2884,13 +2954,15 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata) ...@@ -2884,13 +2954,15 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
return false; return false;
break; break;
case XGBE_PORT_MODE_NBASE_T: 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_1000) ||
(phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500)) (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_2500))
return false; return false;
break; break;
case XGBE_PORT_MODE_10GBASE_T: 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_1000) ||
(phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)) (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
return false; return false;
...@@ -2900,7 +2972,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata) ...@@ -2900,7 +2972,8 @@ static bool xgbe_phy_port_mode_mismatch(struct xgbe_prv_data *pdata)
return false; return false;
break; break;
case XGBE_PORT_MODE_SFP: 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_1000) ||
(phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)) (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000))
return false; return false;
...@@ -3269,6 +3342,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) ...@@ -3269,6 +3342,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
XGBE_SET_SUP(lks, Pause); XGBE_SET_SUP(lks, Pause);
XGBE_SET_SUP(lks, Asym_Pause); XGBE_SET_SUP(lks, Asym_Pause);
XGBE_SET_SUP(lks, TP); 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) { if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
XGBE_SET_SUP(lks, 100baseT_Full); XGBE_SET_SUP(lks, 100baseT_Full);
phy_data->start_mode = XGBE_MODE_SGMII_100; phy_data->start_mode = XGBE_MODE_SGMII_100;
...@@ -3299,6 +3376,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) ...@@ -3299,6 +3376,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
XGBE_SET_SUP(lks, Pause); XGBE_SET_SUP(lks, Pause);
XGBE_SET_SUP(lks, Asym_Pause); XGBE_SET_SUP(lks, Asym_Pause);
XGBE_SET_SUP(lks, TP); 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) { if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
XGBE_SET_SUP(lks, 100baseT_Full); XGBE_SET_SUP(lks, 100baseT_Full);
phy_data->start_mode = XGBE_MODE_SGMII_100; phy_data->start_mode = XGBE_MODE_SGMII_100;
...@@ -3321,6 +3402,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) ...@@ -3321,6 +3402,10 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
XGBE_SET_SUP(lks, Pause); XGBE_SET_SUP(lks, Pause);
XGBE_SET_SUP(lks, Asym_Pause); XGBE_SET_SUP(lks, Asym_Pause);
XGBE_SET_SUP(lks, TP); 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) { if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100) {
XGBE_SET_SUP(lks, 100baseT_Full); XGBE_SET_SUP(lks, 100baseT_Full);
phy_data->start_mode = XGBE_MODE_SGMII_100; phy_data->start_mode = XGBE_MODE_SGMII_100;
...@@ -3361,6 +3446,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata) ...@@ -3361,6 +3446,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
XGBE_SET_SUP(lks, Asym_Pause); XGBE_SET_SUP(lks, Asym_Pause);
XGBE_SET_SUP(lks, TP); XGBE_SET_SUP(lks, TP);
XGBE_SET_SUP(lks, FIBRE); 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) if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_100)
phy_data->start_mode = XGBE_MODE_SGMII_100; phy_data->start_mode = XGBE_MODE_SGMII_100;
if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
......
...@@ -293,6 +293,7 @@ ...@@ -293,6 +293,7 @@
#define XGBE_SGMII_AN_LINK_STATUS BIT(1) #define XGBE_SGMII_AN_LINK_STATUS BIT(1)
#define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3)) #define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
#define XGBE_SGMII_AN_LINK_SPEED_10 0x00
#define XGBE_SGMII_AN_LINK_SPEED_100 0x04 #define XGBE_SGMII_AN_LINK_SPEED_100 0x04
#define XGBE_SGMII_AN_LINK_SPEED_1000 0x08 #define XGBE_SGMII_AN_LINK_SPEED_1000 0x08
#define XGBE_SGMII_AN_LINK_DUPLEX BIT(4) #define XGBE_SGMII_AN_LINK_DUPLEX BIT(4)
...@@ -594,6 +595,7 @@ enum xgbe_mode { ...@@ -594,6 +595,7 @@ enum xgbe_mode {
XGBE_MODE_KX_2500, XGBE_MODE_KX_2500,
XGBE_MODE_KR, XGBE_MODE_KR,
XGBE_MODE_X, XGBE_MODE_X,
XGBE_MODE_SGMII_10,
XGBE_MODE_SGMII_100, XGBE_MODE_SGMII_100,
XGBE_MODE_SGMII_1000, XGBE_MODE_SGMII_1000,
XGBE_MODE_SFI, XGBE_MODE_SFI,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment