diff options
Diffstat (limited to 'target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch')
-rw-r--r-- | target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch new file mode 100644 index 0000000000..a5553a3e96 --- /dev/null +++ b/target/linux/mvebu/patches-5.4/531-net-mvneta-Add-support-for-2500Mbps-SGMII.patch @@ -0,0 +1,104 @@ +From da58a931f248f423f917c3a0b3c94303aa30a738 Mon Sep 17 00:00:00 2001 +From: Maxime Chevallier <maxime.chevallier@bootlin.com> +Date: Tue, 25 Sep 2018 15:59:39 +0200 +Subject: [PATCH] net: mvneta: Add support for 2500Mbps SGMII + +The mvneta controller can handle speeds up to 2500Mbps on the SGMII +interface. This relies on serdes configuration, the lane must be +configured at 3.125Gbps and we can't use in-band autoneg at that speed. + +The main issue when supporting that speed on this particular controller +is that the link partner can send ethernet frames with a shortened +preamble, which if not explicitly enabled in the controller will cause +unexpected behaviours. + +This was tested on Armada 385, with the comphy configuration done in +bootloader. + +Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/marvell/mvneta.c | 27 +++++++++++++++++++++++---- + 1 file changed, 23 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -221,6 +221,8 @@ + #define MVNETA_GMAC_AN_FLOW_CTRL_EN BIT(11) + #define MVNETA_GMAC_CONFIG_FULL_DUPLEX BIT(12) + #define MVNETA_GMAC_AN_DUPLEX_EN BIT(13) ++#define MVNETA_GMAC_CTRL_4 0x2c90 ++#define MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE BIT(1) + #define MVNETA_MIB_COUNTERS_BASE 0x3000 + #define MVNETA_MIB_LATE_COLLISION 0x7c + #define MVNETA_DA_FILT_SPEC_MCAST 0x3400 +@@ -3359,6 +3361,7 @@ static void mvneta_validate(struct net_d + if (state->interface != PHY_INTERFACE_MODE_NA && + state->interface != PHY_INTERFACE_MODE_QSGMII && + state->interface != PHY_INTERFACE_MODE_SGMII && ++ state->interface != PHY_INTERFACE_MODE_2500BASEX && + !phy_interface_mode_is_8023z(state->interface) && + !phy_interface_mode_is_rgmii(state->interface)) { + bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS); +@@ -3371,9 +3374,15 @@ static void mvneta_validate(struct net_d + + /* Asymmetric pause is unsupported */ + phylink_set(mask, Pause); +- /* Half-duplex at speeds higher than 100Mbit is unsupported */ +- phylink_set(mask, 1000baseT_Full); +- phylink_set(mask, 1000baseX_Full); ++ ++ /* We cannot use 1Gbps when using the 2.5G interface. */ ++ if (state->interface == PHY_INTERFACE_MODE_2500BASEX) { ++ phylink_set(mask, 2500baseT_Full); ++ phylink_set(mask, 2500baseX_Full); ++ } else { ++ phylink_set(mask, 1000baseT_Full); ++ phylink_set(mask, 1000baseX_Full); ++ } + + if (!phy_interface_mode_is_8023z(state->interface)) { + /* 10M and 100M are only supported in non-802.3z mode */ +@@ -3434,12 +3443,14 @@ static void mvneta_mac_config(struct net + struct mvneta_port *pp = netdev_priv(ndev); + u32 new_ctrl0, gmac_ctrl0 = mvreg_read(pp, MVNETA_GMAC_CTRL_0); + u32 new_ctrl2, gmac_ctrl2 = mvreg_read(pp, MVNETA_GMAC_CTRL_2); ++ u32 new_ctrl4, gmac_ctrl4 = mvreg_read(pp, MVNETA_GMAC_CTRL_4); + u32 new_clk, gmac_clk = mvreg_read(pp, MVNETA_GMAC_CLOCK_DIVIDER); + u32 new_an, gmac_an = mvreg_read(pp, MVNETA_GMAC_AUTONEG_CONFIG); + + new_ctrl0 = gmac_ctrl0 & ~MVNETA_GMAC0_PORT_1000BASE_X; + new_ctrl2 = gmac_ctrl2 & ~(MVNETA_GMAC2_INBAND_AN_ENABLE | + MVNETA_GMAC2_PORT_RESET); ++ new_ctrl4 = gmac_ctrl4 & ~(MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE); + new_clk = gmac_clk & ~MVNETA_GMAC_1MS_CLOCK_ENABLE; + new_an = gmac_an & ~(MVNETA_GMAC_INBAND_AN_ENABLE | + MVNETA_GMAC_INBAND_RESTART_AN | +@@ -3472,7 +3483,7 @@ static void mvneta_mac_config(struct net + if (state->duplex) + new_an |= MVNETA_GMAC_CONFIG_FULL_DUPLEX; + +- if (state->speed == SPEED_1000) ++ if (state->speed == SPEED_1000 || state->speed == SPEED_2500) + new_an |= MVNETA_GMAC_CONFIG_GMII_SPEED; + else if (state->speed == SPEED_100) + new_an |= MVNETA_GMAC_CONFIG_MII_SPEED; +@@ -3511,10 +3522,18 @@ static void mvneta_mac_config(struct net + MVNETA_GMAC_FORCE_LINK_DOWN); + } + ++ /* When at 2.5G, the link partner can send frames with shortened ++ * preambles. ++ */ ++ if (state->speed == SPEED_2500) ++ new_ctrl4 |= MVNETA_GMAC4_SHORT_PREAMBLE_ENABLE; ++ + if (new_ctrl0 != gmac_ctrl0) + mvreg_write(pp, MVNETA_GMAC_CTRL_0, new_ctrl0); + if (new_ctrl2 != gmac_ctrl2) + mvreg_write(pp, MVNETA_GMAC_CTRL_2, new_ctrl2); ++ if (new_ctrl4 != gmac_ctrl4) ++ mvreg_write(pp, MVNETA_GMAC_CTRL_4, new_ctrl4); + if (new_clk != gmac_clk) + mvreg_write(pp, MVNETA_GMAC_CLOCK_DIVIDER, new_clk); + if (new_an != gmac_an) |