2021-04-05 18:10:31

by Sit, Michael Wei Hong

[permalink] [raw]
Subject: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

This patchset enables 2.5Gbps speed mode for stmmac.
Link speed mode is detected and configured at serdes power up sequence.
For 2.5G, we do not use SGMII in-band AN, we check the link speed mode
in the serdes and disable the in-band AN accordingly.

Changes:
v1 -> v2
patch 1/2
-Remove MAC supported link speed masking

patch 2/2
-Add supported link speed masking in the PCS

iperf3 and ping for 2.5Gbps and regression test on 10M/100M/1000Mbps
is done to prevent regresson issues.

10Mbps
host@EHL$ ethtool -s enp0s30f4 duplex full speed 10
[ 310.132264] intel-eth-pci 0000:00:1e.4 enp0s30f4: Link is Down
[ 312.438102] intel-eth-pci 0000:00:1e.4 enp0s30f4: Link is Up - 10Mbps/Full - flow control off
[ 312.447652] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s30f4: link becomes ready
host@EHL$ iperf3 -c 192.168.1.1
Connecting to host 192.168.1.1, port 5201
[ 5] local 192.168.1.2 port 60706 connected to 192.168.1.1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 1.26 MBytes 10.6 Mbits/sec 0 29.7 KBytes
[ 5] 1.00-2.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 2.00-3.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 3.00-4.00 sec 1.15 MBytes 9.68 Mbits/sec 0 29.7 KBytes
[ 5] 4.00-5.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 5.00-6.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 6.00-7.00 sec 1.15 MBytes 9.68 Mbits/sec 0 29.7 KBytes
[ 5] 7.00-8.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 8.00-9.00 sec 1.09 MBytes 9.17 Mbits/sec 0 29.7 KBytes
[ 5] 9.00-10.00 sec 1.15 MBytes 9.68 Mbits/sec 0 29.7 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 11.3 MBytes 9.47 Mbits/sec 0 sender
[ 5] 0.00-10.01 sec 11.1 MBytes 9.34 Mbits/sec receiver

iperf Done.
host@EHL$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.557 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.528 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.535 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.525 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=0.527 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=0.555 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=0.539 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=0.588 ms
64 bytes from 192.168.1.1: icmp_seq=9 ttl=64 time=0.570 ms
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=0.540 ms

--- 192.168.1.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9194ms
rtt min/avg/max/mdev = 0.525/0.546/0.588/0.019 ms
host@EHL$

100Mbps
host@EHL$ ethtool -s enp0s30f4 duplex full speed 100
[ 204.178572] intel-eth-pci 0000:00:1e.4 enp0s30f4: Link is Down
[ 207.990094] intel-eth-pci 0000:00:1e.4 enp0s30f4: Link is Up - 100Mbps/Full - flow control off
[ 207.999744] IPv6: ADDRCONF(NETDEV_CHANGE): enp0s30f4: link becomes ready
host@EHL$ iperf3 -c 192.168.1.1
Connecting to host 192.168.1.1, port 5201
[ 5] local 192.168.1.2 port 60702 connected to 192.168.1.1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 11.6 MBytes 97.0 Mbits/sec 1 102 KBytes
[ 5] 1.00-2.00 sec 10.9 MBytes 91.7 Mbits/sec 0 102 KBytes
[ 5] 2.00-3.00 sec 10.8 MBytes 90.5 Mbits/sec 0 102 KBytes
[ 5] 3.00-4.00 sec 11.0 MBytes 92.6 Mbits/sec 0 102 KBytes
[ 5] 4.00-5.00 sec 10.8 MBytes 90.6 Mbits/sec 0 102 KBytes
[ 5] 5.00-6.00 sec 11.0 MBytes 92.6 Mbits/sec 0 102 KBytes
[ 5] 6.00-7.00 sec 11.0 MBytes 92.6 Mbits/sec 0 102 KBytes
[ 5] 7.00-8.00 sec 10.8 MBytes 90.6 Mbits/sec 0 102 KBytes
[ 5] 8.00-9.00 sec 11.0 MBytes 92.6 Mbits/sec 0 102 KBytes
[ 5] 9.00-10.00 sec 11.0 MBytes 92.6 Mbits/sec 0 102 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 110 MBytes 92.3 Mbits/sec 1 sender
[ 5] 0.00-10.00 sec 109 MBytes 91.8 Mbits/sec receiver

iperf Done.
host@EHL$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.331 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.322 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.315 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.315 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=0.295 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=0.300 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=0.307 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=0.294 ms
64 bytes from 192.168.1.1: icmp_seq=9 ttl=64 time=0.292 ms
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=0.297 ms

--- 192.168.1.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9215ms
rtt min/avg/max/mdev = 0.292/0.306/0.331/0.012 ms

1G speed
host@EHL$ iperf3 -c 192.168.1.1
Connecting to host 192.168.1.1, port 5201
[ 5] local 192.168.1.2 port 60698 connected to 192.168.1.1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 114 MBytes 954 Mbits/sec 0 533 KBytes
[ 5] 1.00-2.00 sec 112 MBytes 942 Mbits/sec 0 591 KBytes
[ 5] 2.00-3.00 sec 113 MBytes 945 Mbits/sec 0 621 KBytes
[ 5] 3.00-4.00 sec 112 MBytes 941 Mbits/sec 0 621 KBytes
[ 5] 4.00-5.00 sec 112 MBytes 942 Mbits/sec 0 764 KBytes
[ 5] 5.00-6.00 sec 112 MBytes 944 Mbits/sec 0 764 KBytes
[ 5] 6.00-7.00 sec 111 MBytes 933 Mbits/sec 0 803 KBytes
[ 5] 7.00-8.00 sec 112 MBytes 944 Mbits/sec 0 803 KBytes
[ 5] 8.00-9.00 sec 112 MBytes 944 Mbits/sec 0 843 KBytes
[ 5] 9.00-10.00 sec 112 MBytes 944 Mbits/sec 0 843 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 1.10 GBytes 943 Mbits/sec 0 sender
[ 5] 0.00-10.00 sec 1.09 GBytes 940 Mbits/sec receiver

iperf Done.
host@EHL$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.299 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.277 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.277 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.286 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=0.330 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=0.276 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=0.296 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=0.272 ms
64 bytes from 192.168.1.1: icmp_seq=9 ttl=64 time=0.276 ms
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=0.274 ms

--- 192.168.1.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9196ms
rtt min/avg/max/mdev = 0.272/0.286/0.330/0.017 ms

2.5G speed
host@EHL$ iperf3 -c 192.168.1.1
Connecting to host 192.168.1.1, port 5201
[ 5] local 192.168.1.2 port 55160 connected to 192.168.1.1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 175 MBytes 1.47 Gbits/sec 17 683 KBytes
[ 5] 1.00-2.00 sec 202 MBytes 1.70 Gbits/sec 0 707 KBytes
[ 5] 2.00-3.00 sec 204 MBytes 1.71 Gbits/sec 0 751 KBytes
[ 5] 3.00-4.00 sec 204 MBytes 1.71 Gbits/sec 0 773 KBytes
[ 5] 4.00-5.00 sec 202 MBytes 1.70 Gbits/sec 0 773 KBytes
[ 5] 5.00-6.00 sec 204 MBytes 1.71 Gbits/sec 0 798 KBytes
[ 5] 6.00-7.00 sec 204 MBytes 1.71 Gbits/sec 0 807 KBytes
[ 5] 7.00-8.00 sec 204 MBytes 1.71 Gbits/sec 0 807 KBytes
[ 5] 8.00-9.00 sec 204 MBytes 1.71 Gbits/sec 0 807 KBytes
[ 5] 9.00-10.00 sec 202 MBytes 1.70 Gbits/sec 0 807 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 1.96 GBytes 1.68 Gbits/sec 17 sender
[ 5] 0.00-10.00 sec 1.96 GBytes 1.68 Gbits/sec receiver

iperf Done.
host@EHL$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.671 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.300 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.300 ms
64 bytes from 192.168.1.1: icmp_seq=4 ttl=64 time=0.291 ms
64 bytes from 192.168.1.1: icmp_seq=5 ttl=64 time=0.296 ms
64 bytes from 192.168.1.1: icmp_seq=6 ttl=64 time=0.301 ms
64 bytes from 192.168.1.1: icmp_seq=7 ttl=64 time=0.328 ms
64 bytes from 192.168.1.1: icmp_seq=8 ttl=64 time=0.306 ms
64 bytes from 192.168.1.1: icmp_seq=9 ttl=64 time=0.299 ms
64 bytes from 192.168.1.1: icmp_seq=10 ttl=64 time=0.293 ms

--- 192.168.1.1 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9251ms
rtt min/avg/max/mdev = 0.291/0.338/0.671/0.111 ms

Voon Weifeng (2):
net: stmmac: enable 2.5Gbps link speed
net: pcs: configure xpcs 2.5G speed mode

.../net/ethernet/stmicro/stmmac/dwmac-intel.c | 44 ++++++++++++++++++-
.../net/ethernet/stmicro/stmmac/dwmac-intel.h | 13 ++++++
.../net/ethernet/stmicro/stmmac/dwmac4_core.c | 1 +
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 20 ++++++++-
drivers/net/pcs/pcs-xpcs.c | 39 ++++++++++++++++
include/linux/pcs/pcs-xpcs.h | 1 +
include/linux/stmmac.h | 2 +
7 files changed, 117 insertions(+), 3 deletions(-)

--
2.17.1


2021-04-05 18:10:32

by Sit, Michael Wei Hong

[permalink] [raw]
Subject: [PATCH net-next v2 2/2] net: pcs: configure xpcs 2.5G speed mode

From: Voon Weifeng <[email protected]>

Besides setting 2.5G configuration, this patch will also disable
automatic speed mode change. This is due to the 2.5G mode is
using the same functionality as 1G mode except the clock rate is
2.5 times the original rate. Hence, auto-negotiation is disabled
to make sure it will only be in 2.5G mode.

Signed-off-by: Voon Weifeng <[email protected]>
Signed-off-by: Michael Sit Wei Hong <[email protected]>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 1 +
drivers/net/pcs/pcs-xpcs.c | 39 +++++++++++++++++++
include/linux/pcs/pcs-xpcs.h | 1 +
3 files changed, 41 insertions(+)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 7def80c6347e..97545cce3430 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -5828,6 +5828,7 @@ int stmmac_dvr_probe(struct device *device,
if (priv->plat->speed_mode_2500) {
priv->plat->speed_2500_en = priv->plat->speed_mode_2500(ndev,
priv->plat->bsp_priv);
+ priv->hw->xpcs_args.speed_2500_en = priv->plat->speed_2500_en;
}

ret = stmmac_phy_setup(priv);
diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c
index 944ba105cac1..bd651299d75f 100644
--- a/drivers/net/pcs/pcs-xpcs.c
+++ b/drivers/net/pcs/pcs-xpcs.c
@@ -60,10 +60,14 @@

/* Clause 37 Defines */
/* VR MII MMD registers offsets */
+#define DW_VR_MII_MMD_CTRL 0x0000
#define DW_VR_MII_DIG_CTRL1 0x8000
#define DW_VR_MII_AN_CTRL 0x8001
#define DW_VR_MII_AN_INTR_STS 0x8002

+/* Enable 2.5G Mode */
+#define DW_VR_MII_DIG_CTRL1_2G5_EN BIT(2)
+
/* VR_MII_DIG_CTRL1 */
#define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9)

@@ -86,6 +90,11 @@
#define DW_VR_MII_C37_ANSGM_SP_1000 0x2
#define DW_VR_MII_C37_ANSGM_SP_LNKSTS BIT(4)

+/* SR MII MMD Control defines */
+#define AN_CL37_EN BIT(12) /* Enable Clause 37 auto-nego */
+#define SGMII_SPEED_SS13 BIT(13) /* SGMII speed along with SS6 */
+#define SGMII_SPEED_SS6 BIT(6) /* SGMII speed along with SS13 */
+
static const int xpcs_usxgmii_features[] = {
ETHTOOL_LINK_MODE_Pause_BIT,
ETHTOOL_LINK_MODE_Asym_Pause_BIT,
@@ -141,6 +150,7 @@ static const int xpcs_sgmii_features[] = {
ETHTOOL_LINK_MODE_100baseT_Full_BIT,
ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
+ ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
__ETHTOOL_LINK_MODE_MASK_NBITS,
};

@@ -645,6 +655,16 @@ static int xpcs_validate(struct mdio_xpcs_args *xpcs,
unsigned long *supported,
struct phylink_link_state *state)
{
+ if (xpcs->speed_2500_en) {
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+ phylink_set(mask, 10baseT_Half);
+ phylink_set(mask, 10baseT_Full);
+ phylink_set(mask, 100baseT_Half);
+ phylink_set(mask, 100baseT_Full);
+ phylink_set(mask, 1000baseT_Half);
+ phylink_set(mask, 1000baseT_Full);
+ linkmode_andnot(xpcs->supported, xpcs->supported, mask);
+ }
linkmode_and(supported, supported, xpcs->supported);
linkmode_and(state->advertising, state->advertising, xpcs->supported);
return 0;
@@ -654,6 +674,25 @@ static int xpcs_config_aneg_c37_sgmii(struct mdio_xpcs_args *xpcs)
{
int ret;

+ if (xpcs->speed_2500_en) {
+ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
+ if (ret < 0)
+ return ret;
+ ret |= DW_VR_MII_DIG_CTRL1_2G5_EN;
+ ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
+ ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
+ if (ret < 0)
+ return ret;
+
+ ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
+ if (ret < 0)
+ return ret;
+ ret &= ~AN_CL37_EN;
+ ret |= SGMII_SPEED_SS6;
+ ret &= ~SGMII_SPEED_SS13;
+ return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
+ }
+
/* For AN for C37 SGMII mode, the settings are :-
* 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
* 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
diff --git a/include/linux/pcs/pcs-xpcs.h b/include/linux/pcs/pcs-xpcs.h
index 2cb5188a7ef1..6b94b2a48e0c 100644
--- a/include/linux/pcs/pcs-xpcs.h
+++ b/include/linux/pcs/pcs-xpcs.h
@@ -19,6 +19,7 @@ struct mdio_xpcs_args {
struct mii_bus *bus;
int addr;
int an_mode;
+ bool speed_2500_en;
};

struct mdio_xpcs_ops {
--
2.17.1

2021-04-05 18:10:33

by Sit, Michael Wei Hong

[permalink] [raw]
Subject: [PATCH net-next v2 1/2] net: stmmac: enable 2.5Gbps link speed

From: Voon Weifeng <[email protected]>

The MAC support 2.5G mode when the PCS is in 1000BASE-T mode. The
2.5G mode of operation is functionally same as 1000BASE-T mode,
except that the clock rate is 2.5 times the original rate.
In this mode, the serdes/PHY operates at a serial baud rate of
3.125 Gbps and the PCS data path and GMII interface of the MAC
operate at 312.5 MHz instead of 125 MHz.

The MAC running in 10M/100M/1G mode or 2.5G mode depends on
the link speed mode in the serdes.

Signed-off-by: Voon Weifeng <[email protected]>
Signed-off-by: Michael Sit Wei Hong <[email protected]>
---
.../net/ethernet/stmicro/stmmac/dwmac-intel.c | 44 ++++++++++++++++++-
.../net/ethernet/stmicro/stmmac/dwmac-intel.h | 13 ++++++
.../net/ethernet/stmicro/stmmac/dwmac4_core.c | 1 +
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 19 +++++++-
include/linux/stmmac.h | 2 +
5 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
index 3d9a57043af2..4f70a12b42f9 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c
@@ -102,6 +102,22 @@ static int intel_serdes_powerup(struct net_device *ndev, void *priv_data)

serdes_phy_addr = intel_priv->mdio_adhoc_addr;

+ /* Set the serdes rate and the PCLK rate */
+ data = mdiobus_read(priv->mii, serdes_phy_addr,
+ SERDES_GCR0);
+
+ data &= ~SERDES_RATE_MASK;
+ data &= ~SERDES_PCLK_MASK;
+
+ if (priv->plat->speed_2500_en)
+ data |= SERDES_RATE_PCIE_GEN2 << SERDES_RATE_PCIE_SHIFT |
+ SERDES_PCLK_37p5MHZ << SERDES_PCLK_SHIFT;
+ else
+ data |= SERDES_RATE_PCIE_GEN1 << SERDES_RATE_PCIE_SHIFT |
+ SERDES_PCLK_70MHZ << SERDES_PCLK_SHIFT;
+
+ mdiobus_write(priv->mii, serdes_phy_addr, SERDES_GCR0, data);
+
/* assert clk_req */
data = mdiobus_read(priv->mii, serdes_phy_addr, SERDES_GCR0);
data |= SERDES_PLL_CLK;
@@ -220,6 +236,28 @@ static void intel_serdes_powerdown(struct net_device *ndev, void *intel_data)
}
}

+static bool intel_speed_mode_2500(struct net_device *ndev, void *intel_data)
+{
+ struct intel_priv_data *intel_priv = intel_data;
+ struct stmmac_priv *priv = netdev_priv(ndev);
+ int serdes_phy_addr = 0;
+ u32 data = 0;
+
+ serdes_phy_addr = intel_priv->mdio_adhoc_addr;
+
+ /* Determine the link speed mode: 2.5Gbps/1Gbps */
+ data = mdiobus_read(priv->mii, serdes_phy_addr,
+ SERDES_GCR);
+
+ if (((data & SERDES_LINK_MODE_MASK) >> SERDES_LINK_MODE_SHIFT) ==
+ SERDES_LINK_MODE_2G5) {
+ dev_info(priv->device, "Link Speed Mode: 2.5Gbps\n");
+ return true;
+ } else {
+ return false;
+ }
+}
+
/* Program PTP Clock Frequency for different variant of
* Intel mGBE that has slightly different GPO mapping
*/
@@ -540,7 +578,7 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
{
plat->bus_id = 1;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
-
+ plat->speed_mode_2500 = intel_speed_mode_2500;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;

@@ -593,6 +631,7 @@ static int ehl_pse0_sgmii1g_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+ plat->speed_mode_2500 = intel_speed_mode_2500;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;
return ehl_pse0_common_data(pdev, plat);
@@ -631,6 +670,7 @@ static int ehl_pse1_sgmii1g_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+ plat->speed_mode_2500 = intel_speed_mode_2500;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;
return ehl_pse1_common_data(pdev, plat);
@@ -655,6 +695,7 @@ static int tgl_sgmii_phy0_data(struct pci_dev *pdev,
{
plat->bus_id = 1;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+ plat->speed_mode_2500 = intel_speed_mode_2500;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;
return tgl_common_data(pdev, plat);
@@ -669,6 +710,7 @@ static int tgl_sgmii_phy1_data(struct pci_dev *pdev,
{
plat->bus_id = 2;
plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+ plat->speed_mode_2500 = intel_speed_mode_2500;
plat->serdes_powerup = intel_serdes_powerup;
plat->serdes_powerdown = intel_serdes_powerdown;
return tgl_common_data(pdev, plat);
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
index e723096c0b15..021a5c178d97 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.h
@@ -9,6 +9,7 @@
#define POLL_DELAY_US 8

/* SERDES Register */
+#define SERDES_GCR 0x0 /* Global Conguration */
#define SERDES_GSR0 0x5 /* Global Status Reg0 */
#define SERDES_GCR0 0xb /* Global Configuration Reg0 */

@@ -16,8 +17,20 @@
#define SERDES_PLL_CLK BIT(0) /* PLL clk valid signal */
#define SERDES_RST BIT(2) /* Serdes Reset */
#define SERDES_PWR_ST_MASK GENMASK(6, 4) /* Serdes Power state*/
+#define SERDES_RATE_MASK GENMASK(9, 8)
+#define SERDES_PCLK_MASK GENMASK(14, 12) /* PCLK rate to PHY */
+#define SERDES_LINK_MODE_MASK GENMASK(2, 1)
+#define SERDES_LINK_MODE_SHIFT 1
#define SERDES_PWR_ST_SHIFT 4
#define SERDES_PWR_ST_P0 0x0
#define SERDES_PWR_ST_P3 0x3
+#define SERDES_LINK_MODE_2G5 0x3
+#define SERSED_LINK_MODE_1G 0x2
+#define SERDES_PCLK_37p5MHZ 0x0
+#define SERDES_PCLK_70MHZ 0x1
+#define SERDES_RATE_PCIE_GEN1 0x0
+#define SERDES_RATE_PCIE_GEN2 0x1
+#define SERDES_RATE_PCIE_SHIFT 8
+#define SERDES_PCLK_SHIFT 12

#endif /* __DWMAC_INTEL_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 95864f014ffa..4c3f27a9e8b2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -1357,6 +1357,7 @@ int dwmac4_setup(struct stmmac_priv *priv)
mac->link.speed10 = GMAC_CONFIG_PS;
mac->link.speed100 = GMAC_CONFIG_FES | GMAC_CONFIG_PS;
mac->link.speed1000 = 0;
+ mac->link.speed2500 = GMAC_CONFIG_FES;
mac->link.speed_mask = GMAC_CONFIG_FES | GMAC_CONFIG_PS;
mac->mii.addr = GMAC_MDIO_ADDR;
mac->mii.data = GMAC_MDIO_DATA;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d34388b1ffcc..7def80c6347e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -882,6 +882,11 @@ static void stmmac_validate(struct phylink_config *config,
phylink_set(mac_supported, Asym_Pause);
phylink_set_port_modes(mac_supported);

+ /* 2.5G mode only support 2500baseT full duplex only */
+ if (priv->plat->has_gmac4 && priv->plat->speed_2500_en) {
+ phylink_set(mac_supported, 2500baseT_Full);
+ }
+
/* Cut down 1G if asked to */
if ((max_speed > 0) && (max_speed < 1000)) {
phylink_set(mask, 1000baseT_Full);
@@ -1192,8 +1197,13 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
priv->phylink_config.dev = &priv->dev->dev;
priv->phylink_config.type = PHYLINK_NETDEV;
priv->phylink_config.pcs_poll = true;
- priv->phylink_config.ovr_an_inband =
- priv->plat->mdio_bus_data->xpcs_an_inband;
+ /* For 2.5G, we do not use SGMII in-band AN */
+ if (priv->plat->speed_2500_en) {
+ priv->phylink_config.ovr_an_inband = false;
+ } else {
+ priv->phylink_config.ovr_an_inband =
+ priv->plat->mdio_bus_data->xpcs_an_inband;
+ }

if (!fwnode)
fwnode = dev_fwnode(priv->device);
@@ -5815,6 +5825,11 @@ int stmmac_dvr_probe(struct device *device,
}
}

+ if (priv->plat->speed_mode_2500) {
+ priv->plat->speed_2500_en = priv->plat->speed_mode_2500(ndev,
+ priv->plat->bsp_priv);
+ }
+
ret = stmmac_phy_setup(priv);
if (ret) {
netdev_err(ndev, "failed to setup phy (%d)\n", ret);
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index e338ef7abc00..a43ce24d2a42 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -209,6 +209,7 @@ struct plat_stmmacenet_data {
void (*fix_mac_speed)(void *priv, unsigned int speed);
int (*serdes_powerup)(struct net_device *ndev, void *priv);
void (*serdes_powerdown)(struct net_device *ndev, void *priv);
+ bool (*speed_mode_2500)(struct net_device *ndev, void *priv);
void (*ptp_clk_freq_config)(void *priv);
int (*init)(struct platform_device *pdev, void *priv);
void (*exit)(struct platform_device *pdev, void *priv);
@@ -234,6 +235,7 @@ struct plat_stmmacenet_data {
int has_xgmac;
bool vlan_fail_q_en;
u8 vlan_fail_q;
+ bool speed_2500_en;
unsigned int eee_usecs_rate;
struct pci_dev *pdev;
bool has_crossts;
--
2.17.1

2021-04-05 20:44:37

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

On Mon, Apr 05, 2021 at 07:29:51PM +0800, Michael Sit Wei Hong wrote:
> This patchset enables 2.5Gbps speed mode for stmmac.
> Link speed mode is detected and configured at serdes power up sequence.
> For 2.5G, we do not use SGMII in-band AN, we check the link speed mode
> in the serdes and disable the in-band AN accordingly.
>
> Changes:
> v1 -> v2
> patch 1/2
> -Remove MAC supported link speed masking
>
> patch 2/2
> -Add supported link speed masking in the PCS

So there still some confusion here.

------------ --------
|MAC - PCS |---serdes---| PHY |--- copper
------------ --------


You have a MAC and an PCS in the stmmac IP block. That then has some
sort of SERDES interface, running 1000BaseX, SGMII, SGMII overclocked
at 2.5G or 25000BaseX. Connected to the SERDES you have a PHY which
converts to copper, giving you 2500BaseT.

You said earlier, that the PHY can only do 2500BaseT. So it should be
the PHY driver which sets supported to 2500BaseT and no other speeds.

You should think about when somebody uses this MAC with a different
PHY, one that can do the full range of 10/half through to 2.5G
full. What generally happens is that the PHY performs auto-neg to
determine the link speed. For 10M-1G speeds the PHY will configure its
SERDES interface to SGMII and phylink will ask the PCS to also be
configured to SGMII. If the PHY negotiates 2500BaseT, it will
configure its side of the SERDES to 2500BaseX or SGMII overclocked at
2.5G. Again, phylink will ask the PCS to match what the PHY is doing.

So, where exactly is the limitation in your hardware? PCS or PHY?

Andrew

2021-04-05 22:06:14

by Sit, Michael Wei Hong

[permalink] [raw]
Subject: RE: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac



> -----Original Message-----
> From: Andrew Lunn <[email protected]>
> Sent: Monday, 5 April, 2021 9:11 PM
> To: Sit, Michael Wei Hong <[email protected]>
> Cc: [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; Voon, Weifeng
> <[email protected]>; Ong, Boon Leong
> <[email protected]>; [email protected]; Wong,
> Vee Khee <[email protected]>; [email protected];
> Chuah, Kim Tatt <[email protected]>;
> [email protected]; linux-stm32@st-md-
> mailman.stormreply.com; [email protected];
> [email protected]; [email protected]
> Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for
> stmmac
>
> On Mon, Apr 05, 2021 at 07:29:51PM +0800, Michael Sit Wei Hong
> wrote:
> > This patchset enables 2.5Gbps speed mode for stmmac.
> > Link speed mode is detected and configured at serdes power
> up sequence.
> > For 2.5G, we do not use SGMII in-band AN, we check the link
> speed mode
> > in the serdes and disable the in-band AN accordingly.
> >
> > Changes:
> > v1 -> v2
> > patch 1/2
> > -Remove MAC supported link speed masking
> >
> > patch 2/2
> > -Add supported link speed masking in the PCS
>
> So there still some confusion here.
>
> ------------ --------
> |MAC - PCS |---serdes---| PHY |--- copper
> ------------ --------
>
>
> You have a MAC and an PCS in the stmmac IP block. That then has
> some
> sort of SERDES interface, running 1000BaseX, SGMII, SGMII
> overclocked
> at 2.5G or 25000BaseX. Connected to the SERDES you have a PHY
> which
> converts to copper, giving you 2500BaseT.
>
> You said earlier, that the PHY can only do 2500BaseT. So it should
> be
> the PHY driver which sets supported to 2500BaseT and no other
> speeds.
>
> You should think about when somebody uses this MAC with a
> different
> PHY, one that can do the full range of 10/half through to 2.5G
> full. What generally happens is that the PHY performs auto-neg to
> determine the link speed. For 10M-1G speeds the PHY will
> configure its
> SERDES interface to SGMII and phylink will ask the PCS to also be
> configured to SGMII. If the PHY negotiates 2500BaseT, it will
> configure its side of the SERDES to 2500BaseX or SGMII
> overclocked at
> 2.5G. Again, phylink will ask the PCS to match what the PHY is
> doing.
>
> So, where exactly is the limitation in your hardware? PCS or PHY?
The limitation in the hardware is at the PCS side where it is either running
in SGMII 2.5G or SGMII 1G speeds.
When running on SGMII 2.5G speeds, we disable the in-band AN and use 2.5G speed only
>
> Andrew

2021-04-05 22:12:46

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

> > You have a MAC and an PCS in the stmmac IP block. That then has
> > some
> > sort of SERDES interface, running 1000BaseX, SGMII, SGMII
> > overclocked
> > at 2.5G or 25000BaseX. Connected to the SERDES you have a PHY
> > which
> > converts to copper, giving you 2500BaseT.
> >
> > You said earlier, that the PHY can only do 2500BaseT. So it should
> > be
> > the PHY driver which sets supported to 2500BaseT and no other
> > speeds.
> >
> > You should think about when somebody uses this MAC with a
> > different
> > PHY, one that can do the full range of 10/half through to 2.5G
> > full. What generally happens is that the PHY performs auto-neg to
> > determine the link speed. For 10M-1G speeds the PHY will
> > configure its
> > SERDES interface to SGMII and phylink will ask the PCS to also be
> > configured to SGMII. If the PHY negotiates 2500BaseT, it will
> > configure its side of the SERDES to 2500BaseX or SGMII
> > overclocked at
> > 2.5G. Again, phylink will ask the PCS to match what the PHY is
> > doing.
> >
> > So, where exactly is the limitation in your hardware? PCS or PHY?
> The limitation in the hardware is at the PCS side where it is either running
> in SGMII 2.5G or SGMII 1G speeds.
> When running on SGMII 2.5G speeds, we disable the in-band AN and use 2.5G speed only

So there is no actual limitation! The MAC should indicate it can do
10Half through to 2500BaseT. And you need to listen to PHYLINK and
swap the PCS between SGMII to overclocked SGMII when it requests.

PHYLINK will call stmmac_mac_config() and use state->interface to
decide how to configure the PCS to match what the PHY is doing.

Andrew

2021-04-06 18:14:47

by Voon, Weifeng

[permalink] [raw]
Subject: RE: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

> > > You have a MAC and an PCS in the stmmac IP block. That then has some
> > > sort of SERDES interface, running 1000BaseX, SGMII, SGMII
> > > overclocked at 2.5G or 25000BaseX. Connected to the SERDES you have
> > > a PHY which converts to copper, giving you 2500BaseT.
> > >
> > > You said earlier, that the PHY can only do 2500BaseT. So it should
> > > be the PHY driver which sets supported to 2500BaseT and no other
> > > speeds.
> > >
> > > You should think about when somebody uses this MAC with a different
> > > PHY, one that can do the full range of 10/half through to 2.5G full.
> > > What generally happens is that the PHY performs auto-neg to
> > > determine the link speed. For 10M-1G speeds the PHY will configure
> > > its SERDES interface to SGMII and phylink will ask the PCS to also
> > > be configured to SGMII. If the PHY negotiates 2500BaseT, it will
> > > configure its side of the SERDES to 2500BaseX or SGMII overclocked
> > > at 2.5G. Again, phylink will ask the PCS to match what the PHY is
> > > doing.
> > >
> > > So, where exactly is the limitation in your hardware? PCS or PHY?
> > The limitation in the hardware is at the PCS side where it is either
> > running in SGMII 2.5G or SGMII 1G speeds.
> > When running on SGMII 2.5G speeds, we disable the in-band AN and use
> > 2.5G speed only
>
> So there is no actual limitation! The MAC should indicate it can do 10Half
> through to 2500BaseT. And you need to listen to PHYLINK and swap the PCS
> between SGMII to overclocked SGMII when it requests.
>
> PHYLINK will call stmmac_mac_config() and use state->interface to decide
> how to configure the PCS to match what the PHY is doing.
>
> Andrew

The limitation is not on the MAC, PCS or the PHY. For Intel mgbe, the
overclocking of 2.5 times clock rate to support 2.5G is only able to be
configured in the BIOS during boot time. Kernel driver has no access to
modify the clock rate for 1Gbps/2.5G mode. The way to determined the
current 1G/2.5G mode is by reading a dedicated adhoc register through mdio bus.
In short, after the system boot up, it is either in 1G mode or 2.5G mode
which not able to be changed on the fly.

Since the stmmac MAC can pair with any PCS and PHY, I still prefer that we tie
this platform specific limitation with the of MAC. As stmmac does handle platform
specific config/limitation.

What is your thoughts?

Weifeng

2021-04-07 08:28:49

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

> The limitation is not on the MAC, PCS or the PHY. For Intel mgbe, the
> overclocking of 2.5 times clock rate to support 2.5G is only able to be
> configured in the BIOS during boot time. Kernel driver has no access to
> modify the clock rate for 1Gbps/2.5G mode. The way to determined the
> current 1G/2.5G mode is by reading a dedicated adhoc register through mdio bus.
> In short, after the system boot up, it is either in 1G mode or 2.5G mode
> which not able to be changed on the fly.

Right. It would of been a lot easier if this was in the commit message
from the beginning. Please ensure the next version does say this.

> Since the stmmac MAC can pair with any PCS and PHY, I still prefer that we tie
> this platform specific limitation with the of MAC. As stmmac does handle platform
> specific config/limitation.

So yes, this needs to be somewhere in the intel specific stmmac code,
with a nice comment explaining what is going on.

What PHY are you using? The Aquantia/Marvell multi-gige phy can do
rate adaptation. So you could fix the MAC-PHY link to 2500BaseX, and
let the PHY internally handle the different line speeds.

Andrew

2021-04-07 17:06:54

by Voon, Weifeng

[permalink] [raw]
Subject: RE: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

> > The limitation is not on the MAC, PCS or the PHY. For Intel mgbe, the
> > overclocking of 2.5 times clock rate to support 2.5G is only able to
> > be configured in the BIOS during boot time. Kernel driver has no
> > access to modify the clock rate for 1Gbps/2.5G mode. The way to
> > determined the current 1G/2.5G mode is by reading a dedicated adhoc
> register through mdio bus.
> > In short, after the system boot up, it is either in 1G mode or 2.5G
> > mode which not able to be changed on the fly.
>
> Right. It would of been a lot easier if this was in the commit message
> from the beginning. Please ensure the next version does say this.
>
> > Since the stmmac MAC can pair with any PCS and PHY, I still prefer
> > that we tie this platform specific limitation with the of MAC. As
> > stmmac does handle platform specific config/limitation.
>
> So yes, this needs to be somewhere in the intel specific stmmac code,
> with a nice comment explaining what is going on.
>
> What PHY are you using? The Aquantia/Marvell multi-gige phy can do rate
> adaptation. So you could fix the MAC-PHY link to 2500BaseX, and let the
> PHY internally handle the different line speeds.
>
Intel mgbe is flexible to pair with any PHY. Only Aquantia/Marvell
multi-gige PHY can do rate adaption right? Hence, we still need to take
care of others PHYs.

Thanks for all the comments, will include them in v3.

Weifeng

2021-04-07 20:59:30

by Russell King (Oracle)

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

On Wed, Apr 07, 2021 at 02:44:39PM +0200, Andrew Lunn wrote:
> > Intel mgbe is flexible to pair with any PHY. Only Aquantia/Marvell
> > multi-gige PHY can do rate adaption right?
>
> The Marvell/Marvell multi-gige PHY can also do rate
> adaptation. Marvell buying Aquantia made naming messy :-(
> I should probably use part numbers.
>
> > Hence, we still need to take care of others PHYs.
>
> Yes, it just makes working around the broken design harder if you want
> to get the most out of the hardware.

FYI, we really need to come up with a good solution to the rate
adaption issue. What we have today really is not good.

For example, take a MAC that supports only 2500base-X connected to a
PHY that does rate adaption from 2500base-X to media speed.

So, the PHY could be capable of 10, 100, 1G and 2.5G media speeds,
and would advertise those in its supported mask. The MAC however
would only report (via the validate callback) support for 2.5G speed
because that's all that 2500base-X supports.

What we really want when a rate adapting capable PHY is connected is
to ignore what ethtool link modes the MAC supports beyond "does it
support this interface type" and just use the PHY supported mask.
However, that's another property of the PHY that we need to know from
phylib, and it's not clear when that property should be made available.
As we know from Marvell PHYs, it depends on the configurable MAC_TYPE
setting, so could only be available once we've selected an interface
mode for the PHY. On the other hand, we might need to know what
interface mode(s) are available from the PHY and MAC to select an
appropriate mode.

This is not easy problems to overcome; I have had some patches for some
time which allow some combination of MAC and PHY to advertise which
interface mode(s) they support but I haven't been entirely happy with
them to push them upstream - and it would be another phylink API change
which means having to maintain the new and old code until everything
has been updated (thereby making stuff a lot more complex.) After the
last round of phylink API updates and the hostility from people over
that, this is a big demotivating factor.

--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 40Mbps down 10Mbps up. Decent connectivity at last!

2021-04-07 21:00:41

by Andrew Lunn

[permalink] [raw]
Subject: Re: [PATCH net-next v2 0/2] Enable 2.5Gbps speed for stmmac

> Intel mgbe is flexible to pair with any PHY. Only Aquantia/Marvell
> multi-gige PHY can do rate adaption right?

The Marvell/Marvell multi-gige PHY can also do rate
adaptation. Marvell buying Aquantia made naming messy :-(
I should probably use part numbers.

> Hence, we still need to take care of others PHYs.

Yes, it just makes working around the broken design harder if you want
to get the most out of the hardware.

Andrew