Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b0d7d7d authored by Jose Abreu's avatar Jose Abreu Committed by David S. Miller
Browse files

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: default avatarJose 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: default avatarDavid S. Miller <davem@davemloft.net>
parent 900a81cc
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -392,8 +392,12 @@ struct mac_link {
	u32 speed100;
	u32 speed1000;
	u32 speed2500;
	u32 speed10000;
	u32 duplex;
	struct {
		u32 speed2500;
		u32 speed5000;
		u32 speed10000;
	} xgmii;
};

struct mii_regs {
+7 −3
Original line number Diff line number Diff line
@@ -15,10 +15,14 @@
/* MAC Registers */
#define XGMAC_TX_CONFIG			0x00000000
#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_2500		(0x2 << XGMAC_CONFIG_SS_OFF)
#define XGMAC_CONFIG_SS_1000		(0x3 << XGMAC_CONFIG_SS_OFF)
#define XGMAC_CONFIG_SS_2500_GMII	(0x2 << 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_SHIFT		20
#define XGMAC_CONFIG_JD			BIT(16)
+8 −6
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ static void dwxgmac2_core_init(struct mac_device_info *hw,

		switch (hw->ps) {
		case SPEED_10000:
			tx |= hw->link.speed10000;
			tx |= hw->link.xgmii.speed10000;
			break;
		case SPEED_2500:
			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->link.duplex = 0;
	mac->link.speed10 = 0;
	mac->link.speed100 = 0;
	mac->link.speed1000 = XGMAC_CONFIG_SS_1000;
	mac->link.speed2500 = XGMAC_CONFIG_SS_2500;
	mac->link.speed10000 = XGMAC_CONFIG_SS_10000;
	mac->link.speed10 = XGMAC_CONFIG_SS_10_MII;
	mac->link.speed100 = XGMAC_CONFIG_SS_100_MII;
	mac->link.speed1000 = XGMAC_CONFIG_SS_1000_GMII;
	mac->link.speed2500 = XGMAC_CONFIG_SS_2500_GMII;
	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->mii.addr = XGMAC_MDIO_ADDR;
+66 −13
Original line number Diff line number Diff line
@@ -805,14 +805,43 @@ static void stmmac_validate(struct phylink_config *config,
			    struct phylink_link_state *state)
{
	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, };
	int tx_cnt = priv->plat->tx_queues_to_use;
	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 */
	if ((max_speed > 0) && (max_speed < 1000)) {
		phylink_set(mask, 1000baseT_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 */
@@ -822,7 +851,12 @@ static void stmmac_validate(struct phylink_config *config,
		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,
		      __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 &= ~priv->hw->link.speed_mask;

	if (state->interface == PHY_INTERFACE_MODE_USXGMII) {
		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:
			ctrl |= priv->hw->link.speed1000;
			break;
@@ -855,6 +907,7 @@ static void stmmac_mac_config(struct phylink_config *config, unsigned int mode,
		default:
			return;
		}
	}

	priv->speed = state->speed;