net: stmmac: Add the missing speeds that XGMAC supports
XGMAC supports following speeds: - 10G XGMII - 5G XGMII - 2.5G XGMII - 2.5G GMII - 1G GMII - 100M MII - 10M MII Add them to the stmmac driver. Signed-off-by: Jose Abreu <joabreu@synopsys.com> Cc: Joao Pinto <jpinto@synopsys.com> Cc: David S. Miller <davem@davemloft.net> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com> Cc: Alexandre Torgue <alexandre.torgue@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
900a81cc11
commit
5b0d7d7da6
4 changed files with 86 additions and 23 deletions
|
@ -392,8 +392,12 @@ struct mac_link {
|
||||||
u32 speed100;
|
u32 speed100;
|
||||||
u32 speed1000;
|
u32 speed1000;
|
||||||
u32 speed2500;
|
u32 speed2500;
|
||||||
u32 speed10000;
|
|
||||||
u32 duplex;
|
u32 duplex;
|
||||||
|
struct {
|
||||||
|
u32 speed2500;
|
||||||
|
u32 speed5000;
|
||||||
|
u32 speed10000;
|
||||||
|
} xgmii;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mii_regs {
|
struct mii_regs {
|
||||||
|
|
|
@ -15,10 +15,14 @@
|
||||||
/* MAC Registers */
|
/* MAC Registers */
|
||||||
#define XGMAC_TX_CONFIG 0x00000000
|
#define XGMAC_TX_CONFIG 0x00000000
|
||||||
#define XGMAC_CONFIG_SS_OFF 29
|
#define XGMAC_CONFIG_SS_OFF 29
|
||||||
#define XGMAC_CONFIG_SS_MASK GENMASK(30, 29)
|
#define XGMAC_CONFIG_SS_MASK GENMASK(31, 29)
|
||||||
#define XGMAC_CONFIG_SS_10000 (0x0 << XGMAC_CONFIG_SS_OFF)
|
#define XGMAC_CONFIG_SS_10000 (0x0 << XGMAC_CONFIG_SS_OFF)
|
||||||
#define XGMAC_CONFIG_SS_2500 (0x2 << XGMAC_CONFIG_SS_OFF)
|
#define XGMAC_CONFIG_SS_2500_GMII (0x2 << XGMAC_CONFIG_SS_OFF)
|
||||||
#define XGMAC_CONFIG_SS_1000 (0x3 << XGMAC_CONFIG_SS_OFF)
|
#define XGMAC_CONFIG_SS_1000_GMII (0x3 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_100_MII (0x4 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_5000 (0x5 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_2500 (0x6 << XGMAC_CONFIG_SS_OFF)
|
||||||
|
#define XGMAC_CONFIG_SS_10_MII (0x7 << XGMAC_CONFIG_SS_OFF)
|
||||||
#define XGMAC_CONFIG_SARC GENMASK(22, 20)
|
#define XGMAC_CONFIG_SARC GENMASK(22, 20)
|
||||||
#define XGMAC_CONFIG_SARC_SHIFT 20
|
#define XGMAC_CONFIG_SARC_SHIFT 20
|
||||||
#define XGMAC_CONFIG_JD BIT(16)
|
#define XGMAC_CONFIG_JD BIT(16)
|
||||||
|
|
|
@ -36,7 +36,7 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,
|
||||||
|
|
||||||
switch (hw->ps) {
|
switch (hw->ps) {
|
||||||
case SPEED_10000:
|
case SPEED_10000:
|
||||||
tx |= hw->link.speed10000;
|
tx |= hw->link.xgmii.speed10000;
|
||||||
break;
|
break;
|
||||||
case SPEED_2500:
|
case SPEED_2500:
|
||||||
tx |= hw->link.speed2500;
|
tx |= hw->link.speed2500;
|
||||||
|
@ -381,11 +381,13 @@ int dwxgmac2_setup(struct stmmac_priv *priv)
|
||||||
mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
|
mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
|
||||||
|
|
||||||
mac->link.duplex = 0;
|
mac->link.duplex = 0;
|
||||||
mac->link.speed10 = 0;
|
mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
|
||||||
mac->link.speed100 = 0;
|
mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
|
||||||
mac->link.speed1000 = XGMAC_CONFIG_SS_1000;
|
mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
|
||||||
mac->link.speed2500 = XGMAC_CONFIG_SS_2500;
|
mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
|
||||||
mac->link.speed10000 = XGMAC_CONFIG_SS_10000;
|
mac->link.xgmii.speed2500 = XGMAC_CONFIG_SS_2500;
|
||||||
|
mac->link.xgmii.speed5000 = XGMAC_CONFIG_SS_5000;
|
||||||
|
mac->link.xgmii.speed10000 = XGMAC_CONFIG_SS_10000;
|
||||||
mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
|
mac->link.speed_mask = XGMAC_CONFIG_SS_MASK;
|
||||||
|
|
||||||
mac->mii.addr = XGMAC_MDIO_ADDR;
|
mac->mii.addr = XGMAC_MDIO_ADDR;
|
||||||
|
|
|
@ -805,14 +805,43 @@ static void stmmac_validate(struct phylink_config *config,
|
||||||
struct phylink_link_state *state)
|
struct phylink_link_state *state)
|
||||||
{
|
{
|
||||||
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
|
struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev));
|
||||||
|
__ETHTOOL_DECLARE_LINK_MODE_MASK(mac_supported) = { 0, };
|
||||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||||
int tx_cnt = priv->plat->tx_queues_to_use;
|
int tx_cnt = priv->plat->tx_queues_to_use;
|
||||||
int max_speed = priv->plat->max_speed;
|
int max_speed = priv->plat->max_speed;
|
||||||
|
|
||||||
|
phylink_set(mac_supported, 10baseT_Half);
|
||||||
|
phylink_set(mac_supported, 10baseT_Full);
|
||||||
|
phylink_set(mac_supported, 100baseT_Half);
|
||||||
|
phylink_set(mac_supported, 100baseT_Full);
|
||||||
|
|
||||||
|
phylink_set(mac_supported, Autoneg);
|
||||||
|
phylink_set(mac_supported, Pause);
|
||||||
|
phylink_set(mac_supported, Asym_Pause);
|
||||||
|
phylink_set_port_modes(mac_supported);
|
||||||
|
|
||||||
|
if (priv->plat->has_gmac ||
|
||||||
|
priv->plat->has_gmac4 ||
|
||||||
|
priv->plat->has_xgmac) {
|
||||||
|
phylink_set(mac_supported, 1000baseT_Half);
|
||||||
|
phylink_set(mac_supported, 1000baseT_Full);
|
||||||
|
phylink_set(mac_supported, 1000baseKX_Full);
|
||||||
|
}
|
||||||
|
|
||||||
/* Cut down 1G if asked to */
|
/* Cut down 1G if asked to */
|
||||||
if ((max_speed > 0) && (max_speed < 1000)) {
|
if ((max_speed > 0) && (max_speed < 1000)) {
|
||||||
phylink_set(mask, 1000baseT_Full);
|
phylink_set(mask, 1000baseT_Full);
|
||||||
phylink_set(mask, 1000baseX_Full);
|
phylink_set(mask, 1000baseX_Full);
|
||||||
|
} else if (priv->plat->has_xgmac) {
|
||||||
|
phylink_set(mac_supported, 2500baseT_Full);
|
||||||
|
phylink_set(mac_supported, 5000baseT_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseSR_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseLR_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseER_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseLRM_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseT_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseKX4_Full);
|
||||||
|
phylink_set(mac_supported, 10000baseKR_Full);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Half-Duplex can only work with single queue */
|
/* Half-Duplex can only work with single queue */
|
||||||
|
@ -822,7 +851,12 @@ static void stmmac_validate(struct phylink_config *config,
|
||||||
phylink_set(mask, 1000baseT_Half);
|
phylink_set(mask, 1000baseT_Half);
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap_andnot(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
bitmap_and(supported, supported, mac_supported,
|
||||||
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||||
|
bitmap_andnot(supported, supported, mask,
|
||||||
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||||
|
bitmap_and(state->advertising, state->advertising, mac_supported,
|
||||||
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||||
bitmap_andnot(state->advertising, state->advertising, mask,
|
bitmap_andnot(state->advertising, state->advertising, mask,
|
||||||
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||||
}
|
}
|
||||||
|
@ -842,7 +876,25 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
|
||||||
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
ctrl = readl(priv->ioaddr + MAC_CTRL_REG);
|
||||||
ctrl &= ~priv->hw->link.speed_mask;
|
ctrl &= ~priv->hw->link.speed_mask;
|
||||||
|
|
||||||
|
if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
|
||||||
switch (state->speed) {
|
switch (state->speed) {
|
||||||
|
case SPEED_10000:
|
||||||
|
ctrl |= priv->hw->link.xgmii.speed10000;
|
||||||
|
break;
|
||||||
|
case SPEED_5000:
|
||||||
|
ctrl |= priv->hw->link.xgmii.speed5000;
|
||||||
|
break;
|
||||||
|
case SPEED_2500:
|
||||||
|
ctrl |= priv->hw->link.xgmii.speed2500;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (state->speed) {
|
||||||
|
case SPEED_2500:
|
||||||
|
ctrl |= priv->hw->link.speed2500;
|
||||||
|
break;
|
||||||
case SPEED_1000:
|
case SPEED_1000:
|
||||||
ctrl |= priv->hw->link.speed1000;
|
ctrl |= priv->hw->link.speed1000;
|
||||||
break;
|
break;
|
||||||
|
@ -855,6 +907,7 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
priv->speed = state->speed;
|
priv->speed = state->speed;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue