Commit 7fbc7465 authored by Josua Mayer's avatar Josua Mayer

add support for dynamic serdes protocol switch between 10G & 25G

NXP has developed software support in the MC firmware, and Linux to
reconfigure serdes speed dynamically between 10G and 25G protocols
(USXGMII/CAUI).
Backport the provided patches to work with our LSDK-21.08 fork.
parent 89dd96c9
From 9133b5815fe59cad2d5227cb966c0b9549ed723d Mon Sep 17 00:00:00 2001
From: Steen Hegelund <steen.hegelund@microchip.com>
Date: Fri, 11 Jun 2021 14:54:50 +0200
Subject: [PATCH 51/61] dt-bindings: net: Add 25G BASE-R phy interface
Add 25gbase-r PHY interface mode.
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
Documentation/devicetree/bindings/net/ethernet-controller.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/ethernet-controller.yaml b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
index e615519f6a38..e2f8dd4b36ef 100644
--- a/Documentation/devicetree/bindings/net/ethernet-controller.yaml
+++ b/Documentation/devicetree/bindings/net/ethernet-controller.yaml
@@ -110,6 +110,8 @@ properties:
- 10gbase-kr
- usxgmii
+ - 25gbase-r
+
phy-mode:
$ref: "#/properties/phy-connection-type"
--
2.35.3
From a8ad6611735c73a3add9178685a06617ef818c84 Mon Sep 17 00:00:00 2001
From: Steen Hegelund <steen.hegelund@microchip.com>
Date: Fri, 11 Jun 2021 14:54:51 +0200
Subject: [PATCH 52/61] net: phy: Add 25G BASE-R interface mode
Add 25gbase-r phy interface mode
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
Documentation/networking/phy.rst | 6 ++++++
include/linux/phy.h | 4 ++++
2 files changed, 10 insertions(+)
diff --git a/Documentation/networking/phy.rst b/Documentation/networking/phy.rst
index b2f7ec794bc8..4884fc40e0ac 100644
--- a/Documentation/networking/phy.rst
+++ b/Documentation/networking/phy.rst
@@ -286,6 +286,12 @@ Some of the interface modes are described below:
Note: due to legacy usage, some 10GBASE-R usage incorrectly makes
use of this definition.
+``PHY_INTERFACE_MODE_25GBASER``
+ This is the IEEE 802.3 PCS Clause 107 defined 25GBASE-R protocol.
+ The PCS is identical to 10GBASE-R, i.e. 64B/66B encoded
+ running 2.5 as fast, giving a fixed bit rate of 25.78125 Gbaud.
+ Please refer to the IEEE standard for further information.
+
Pause frames / flow control
===========================
diff --git a/include/linux/phy.h b/include/linux/phy.h
index cb54401cdfb4..634b48cfb70d 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -109,6 +109,7 @@ extern const int phy_10gbit_features_array[1];
* @PHY_INTERFACE_MODE_RXAUI: Reduced XAUI
* @PHY_INTERFACE_MODE_XAUI: 10 Gigabit Attachment Unit Interface
* @PHY_INTERFACE_MODE_10GBASER: 10G BaseR
+ * @PHY_INTERFACE_MODE_25GBASER: 25G BaseR
* @PHY_INTERFACE_MODE_USXGMII: Universal Serial 10GE MII
* @PHY_INTERFACE_MODE_10GKR: 10GBASE-KR - with Clause 73 AN
* @PHY_INTERFACE_MODE_MAX: Book keeping
@@ -141,6 +142,7 @@ typedef enum {
PHY_INTERFACE_MODE_XAUI,
/* 10GBASE-R, XFI, SFI - single lane 10G Serdes */
PHY_INTERFACE_MODE_10GBASER,
+ PHY_INTERFACE_MODE_25GBASER,
PHY_INTERFACE_MODE_USXGMII,
/* 10GBASE-KR - with Clause 73 AN */
PHY_INTERFACE_MODE_10GKR,
@@ -248,6 +250,8 @@ static inline const char *phy_modes(phy_interface_t interface)
return "xaui";
case PHY_INTERFACE_MODE_10GBASER:
return "10gbase-r";
+ case PHY_INTERFACE_MODE_25GBASER:
+ return "25gbase-r";
case PHY_INTERFACE_MODE_USXGMII:
return "usxgmii";
case PHY_INTERFACE_MODE_10GKR:
--
2.35.3
From 5676c7a3d807e51fdd455ae20035343b80837b43 Mon Sep 17 00:00:00 2001
From: Steen Hegelund <steen.hegelund@microchip.com>
Date: Fri, 11 Jun 2021 14:54:52 +0200
Subject: [PATCH 53/61] net: sfp: add support for 25G BASE-R SFPs
Add support for 25gbase-r modules. This is needed for the Sparx5 switch.
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/sfp-bus.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c
index 4cf874fb5c5b..59f924d77443 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -381,6 +381,11 @@ EXPORT_SYMBOL_GPL(sfp_parse_support);
phy_interface_t sfp_select_interface(struct sfp_bus *bus,
unsigned long *link_modes)
{
+ if (phylink_test(link_modes, 25000baseCR_Full) ||
+ phylink_test(link_modes, 25000baseKR_Full) ||
+ phylink_test(link_modes, 25000baseSR_Full))
+ return PHY_INTERFACE_MODE_25GBASER;
+
if (phylink_test(link_modes, 10000baseCR_Full) ||
phylink_test(link_modes, 10000baseSR_Full) ||
phylink_test(link_modes, 10000baseLR_Full) ||
--
2.35.3
From a28487fff2de7bfcf6dec2f79ce5ce32c59baea9 Mon Sep 17 00:00:00 2001
From: Steen Hegelund <steen.hegelund@microchip.com>
Date: Fri, 11 Jun 2021 14:54:53 +0200
Subject: [PATCH 54/61] net: phylink: Add 25G BASE-R support
Add 25gbase-r interface type and speed to phylink.
This is needed for the Sparx5 switch.
Signed-off-by: Steen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: Bjarni Jonasson <bjarni.jonasson@microchip.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/phy/phylink.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 1d84bb849895..ba0148edd04f 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -307,6 +307,11 @@ static int phylink_parse_mode(struct phylink *pl, struct fwnode_handle *fwnode)
phylink_set(pl->supported, 2500baseX_Full);
break;
+ case PHY_INTERFACE_MODE_25GBASER:
+ phylink_set(pl->supported, 25000baseCR_Full);
+ phylink_set(pl->supported, 25000baseKR_Full);
+ phylink_set(pl->supported, 25000baseSR_Full);
+ fallthrough;
case PHY_INTERFACE_MODE_USXGMII:
case PHY_INTERFACE_MODE_10GKR:
case PHY_INTERFACE_MODE_10GBASER:
--
2.35.3
From d22414cf7e596d4dc2584c2e468d900e57a3eec7 Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Wed, 5 Apr 2023 15:33:13 +0300
Subject: [PATCH 55/61] net: phylink: extend phylink_mii_c45_pcs_get_state also
for PHY_INTERFACE_MODE_25GBASER
Extend the phylink_mii_c45_pcs_get_state() to also support
PHY_INTERFACE_MODE_25GBASER. The same C45 access to the
MMD_PCS:MDIO_STAT1 register is made to determine the link status.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/net/phy/phylink.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index ba0148edd04f..5fd81243beac 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2602,7 +2602,10 @@ void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
state->speed = SPEED_10000;
state->duplex = DUPLEX_FULL;
break;
-
+ case PHY_INTERFACE_MODE_25GBASER:
+ state->speed = SPEED_25000;
+ state->duplex = DUPLEX_FULL;
+ break;
default:
break;
}
--
2.35.3
From b95f4d73bf91780785f092b2ecf2ae41f4477a79 Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Wed, 5 Apr 2023 15:41:48 +0300
Subject: [PATCH 56/61] net: pcs: lynx: extend support to also handle
PHY_INTERFACE_MODE_25GBASER
Extend the Lynx PCS driver in order to be able to handle the
PHY_INTERFACE_MODE_25GBASER interface type.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/net/pcs/pcs-lynx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c
index af36cd647bf5..2916be7da089 100644
--- a/drivers/net/pcs/pcs-lynx.c
+++ b/drivers/net/pcs/pcs-lynx.c
@@ -96,6 +96,7 @@ static void lynx_pcs_get_state(struct phylink_pcs *pcs,
lynx_pcs_get_state_usxgmii(lynx->mdio, state);
break;
case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_25GBASER:
phylink_mii_c45_pcs_get_state(lynx->mdio, state);
break;
default:
@@ -204,6 +205,7 @@ static int lynx_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
case PHY_INTERFACE_MODE_USXGMII:
return lynx_pcs_config_usxgmii(lynx->mdio, mode, advertising);
case PHY_INTERFACE_MODE_10GBASER:
+ case PHY_INTERFACE_MODE_25GBASER:
/* Nothing to do here for 10GBASER */
break;
default:
--
2.35.3
From a9d89550d5dc789b575077e38e857e02a3b97a6c Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Wed, 5 Apr 2023 16:32:49 +0300
Subject: [PATCH 57/61] phy: lynx-28g: configure more equalization params for
10GBASER
We discovered that not all the equalization parameters for a lane were
configured upon an interface change. Configure the extra 2 registers
with the appropriate values for 10GBASE-R.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/phy/freescale/phy-fsl-lynx-28g.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index a2b060e9e284..08417c0098bd 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -325,6 +325,8 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id));
iowrite32(0x81000020, priv->base + LYNX_28G_LNaRECR2(lane->id));
iowrite32(0x00002000, priv->base + LYNX_28G_LNaRSCCR0(lane->id));
+ iowrite32(0x80000000, priv->base + LYNX_28G_LNaRCCR0(lane->id));
+ iowrite32(0x00408000, priv->base + LYNX_28G_LNaTTLCR0(lane->id));
}
static int lynx_28g_power_off(struct phy *phy)
--
2.35.3
From f34603353ef436ddd56e18f2a206ff9bd4550351 Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Wed, 5 Apr 2023 16:33:54 +0300
Subject: [PATCH 58/61] phy: lynx-28g: add support for 25GBASER
Add support for 25GBASE-R in the Lynx 28G SerDes PHY driver.
This mainly means being able to determine if a PLL is able to support
the new interface type, to determine at probe time if a lane is
configured from RCW with this interface and to be able to reconfigure a
lane.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/phy/freescale/phy-fsl-lynx-28g.c | 93 ++++++++++++++++++++++--
1 file changed, 87 insertions(+), 6 deletions(-)
diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index 08417c0098bd..2152066f2dbc 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -21,7 +21,12 @@
#define LYNX_28G_PCCC_USXGMII 0x1
#define LYNX_28G_PCCC_SXGMII_DIS 0x0
+#define LYNX_28G_PCCD 0x10b4
+#define LYNX_28G_PCCD_25GBASER 0x1
+#define LYNX_28G_PCCD_25GBASER_DIS 0x0
+
#define LYNX_28G_LNa_PCC_OFFSET(lane) (4 * (LYNX_28G_NUM_LANE - (lane->id) - 1))
+#define LYNX_28G_LNa_PCCD_OFFSET(lane) (4 * (lane->id))
/* Per PLL registers */
#define LYNX_28G_PLLnRSTCTL(pll) (0x400 + (pll) * 0x100 + 0x0)
@@ -41,6 +46,7 @@
#define LYNX_28G_PLLnCR1_FRATE_5G_10GVCO 0x0
#define LYNX_28G_PLLnCR1_FRATE_5G_25GVCO 0x10000000
#define LYNX_28G_PLLnCR1_FRATE_10G_20GVCO 0x6000000
+#define LYNX_28G_PLLnCR1_FRATE_12G_25GVCO 0x16000000
/* Per SerDes lane registers */
/* Lane a General Control Register */
@@ -48,9 +54,11 @@
#define LYNX_28G_LNaGCR0_PROTO_SEL_MSK GENMASK(7, 3)
#define LYNX_28G_LNaGCR0_PROTO_SEL_SGMII 0x8
#define LYNX_28G_LNaGCR0_PROTO_SEL_XFI 0x50
+#define LYNX_28G_LNaGCR0_PROTO_SEL_25G 0xD0
#define LYNX_28G_LNaGCR0_IF_WIDTH_MSK GENMASK(2, 0)
#define LYNX_28G_LNaGCR0_IF_WIDTH_10_BIT 0x0
#define LYNX_28G_LNaGCR0_IF_WIDTH_20_BIT 0x2
+#define LYNX_28G_LNaGCR0_IF_WIDTH_40_BIT 0x4
/* Lane a Tx Reset Control Register */
#define LYNX_28G_LNaTRSTCTL(lane) (0x800 + (lane) * 0x100 + 0x20)
@@ -66,6 +74,7 @@
#define LYNX_28G_LNaTGCR0_N_RATE_FULL 0x0
#define LYNX_28G_LNaTGCR0_N_RATE_HALF 0x1000000
#define LYNX_28G_LNaTGCR0_N_RATE_QUARTER 0x2000000
+#define LYNX_28G_LNaTGCR0_N_RATE_DOUBLE 0x3000000
#define LYNX_28G_LNaTGCR0_N_RATE_MSK GENMASK(26, 24)
#define LYNX_28G_LNaTECR0(lane) (0x800 + (lane) * 0x100 + 0x30)
@@ -86,6 +95,7 @@
#define LYNX_28G_LNaRGCR0_N_RATE_FULL 0x0
#define LYNX_28G_LNaRGCR0_N_RATE_HALF 0x1000000
#define LYNX_28G_LNaRGCR0_N_RATE_QUARTER 0x2000000
+#define LYNX_28G_LNaRGCR0_N_RATE_DOUBLE 0x3000000
#define LYNX_28G_LNaRGCR0_N_RATE_MSK GENMASK(26, 24)
#define LYNX_28G_LNaRGCR1(lane) (0x800 + (lane) * 0x100 + 0x48)
@@ -94,12 +104,17 @@
#define LYNX_28G_LNaRECR1(lane) (0x800 + (lane) * 0x100 + 0x54)
#define LYNX_28G_LNaRECR2(lane) (0x800 + (lane) * 0x100 + 0x58)
+#define LYNX_28G_LNaRCCR0(lane) (0x800 + (lane) * 0x100 + 0x68)
+
#define LYNX_28G_LNaRSCCR0(lane) (0x800 + (lane) * 0x100 + 0x74)
+#define LYNX_28G_LNaTTLCR0(lane) (0x800 + (lane) * 0x100 + 0x80)
+
#define LYNX_28G_LNaPSS(lane) (0x1000 + (lane) * 0x4)
#define LYNX_28G_LNaPSS_TYPE(pss) (((pss) & GENMASK(30, 24)) >> 24)
#define LYNX_28G_LNaPSS_TYPE_SGMII 0x4
#define LYNX_28G_LNaPSS_TYPE_XFI 0x28
+#define LYNX_28G_LNaPSS_TYPE_25G 0x68
#define LYNX_28G_SGMIIaCR1(lane) (0x1804 + (lane) * 0x10)
#define LYNX_28G_SGMIIaCR1_SGPCS_EN BIT(11)
@@ -215,6 +230,16 @@ static void lynx_28g_lane_set_nrate(struct lynx_28g_lane *lane,
break;
}
break;
+ case LYNX_28G_PLLnCR1_FRATE_12G_25GVCO:
+ switch (intf) {
+ case PHY_INTERFACE_MODE_25GBASER:
+ lynx_28g_lane_rmw(lane, LNaTGCR0, N_RATE_DOUBLE, N_RATE_MSK);
+ lynx_28g_lane_rmw(lane, LNaRGCR0, N_RATE_DOUBLE, N_RATE_MSK);
+ break;
+ default:
+ break;
+ }
+ break;
default:
break;
}
@@ -234,21 +259,35 @@ static void lynx_28g_lane_set_pll(struct lynx_28g_lane *lane,
static void lynx_28g_cleanup_lane(struct lynx_28g_lane *lane)
{
- u32 lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane);
struct lynx_28g_priv *priv = lane->priv;
+ u32 lane_offset;
- /* Cleanup the protocol configuration registers of the current protocol */
switch (lane->interface) {
case PHY_INTERFACE_MODE_10GBASER:
+ /* Cleanup the protocol configuration registers */
+ lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane);
lynx_28g_rmw(priv, LYNX_28G_PCCC,
LYNX_28G_PCCC_SXGMII_DIS << lane_offset,
GENMASK(3, 0) << lane_offset);
break;
case PHY_INTERFACE_MODE_SGMII:
case PHY_INTERFACE_MODE_1000BASEX:
+ /* Cleanup the protocol configuration registers */
+ lane_offset = LYNX_28G_LNa_PCC_OFFSET(lane);
lynx_28g_rmw(priv, LYNX_28G_PCC8,
LYNX_28G_PCC8_SGMII_DIS << lane_offset,
GENMASK(3, 0) << lane_offset);
+
+ /* Disable the SGMII PCS */
+ lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK);
+
+ break;
+ case PHY_INTERFACE_MODE_25GBASER:
+ /* Cleanup the protocol configuration registers */
+ lane_offset = LYNX_28G_LNa_PCCD_OFFSET(lane);
+ lynx_28g_rmw(priv, LYNX_28G_PCCD,
+ LYNX_28G_PCCD_25GBASER_DIS << lane_offset,
+ GENMASK(2, 0) << lane_offset);
break;
default:
break;
@@ -315,9 +354,6 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
/* Choose the portion of clock net to be used on this lane */
lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_10GBASER);
- /* Disable the SGMII PCS */
- lynx_28g_lane_rmw(lane, SGMIIaCR1, SGPCS_DIS, SGPCS_MSK);
-
/* Configure the appropriate equalization parameters for the protocol */
iowrite32(0x10808307, priv->base + LYNX_28G_LNaTECR0(lane->id));
iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id));
@@ -329,6 +365,41 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
iowrite32(0x00408000, priv->base + LYNX_28G_LNaTTLCR0(lane->id));
}
+static void lynx_28g_lane_set_25gbaser(struct lynx_28g_lane *lane)
+{
+ u32 lane_offset = LYNX_28G_LNa_PCCD_OFFSET(lane);
+ struct lynx_28g_priv *priv = lane->priv;
+ struct lynx_28g_pll *pll;
+
+ lynx_28g_cleanup_lane(lane);
+
+ /* Enable the E25G lane */
+ lynx_28g_rmw(priv, LYNX_28G_PCCD,
+ LYNX_28G_PCCD_25GBASER << lane_offset,
+ GENMASK(2, 0) << lane_offset);
+
+ /* Setup the protocol select and SerDes parallel interface width */
+ lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_25G, PROTO_SEL_MSK);
+ lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_40_BIT, IF_WIDTH_MSK);
+
+ /* Switch to the PLL that works with this interface type */
+ pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_25GBASER);
+ lynx_28g_lane_set_pll(lane, pll);
+
+ /* Choose the portion of clock net to be used on this lane */
+ lynx_28g_lane_set_nrate(lane, pll, PHY_INTERFACE_MODE_25GBASER);
+
+ /* Configure the appropriate equalization parameters for 25GBASE-R */
+ iowrite32(0x20828700, priv->base + LYNX_28G_LNaTECR0(lane->id));
+ iowrite32(0x10000000, priv->base + LYNX_28G_LNaRGCR1(lane->id));
+ iowrite32(0x00000085, priv->base + LYNX_28G_LNaRECR0(lane->id));
+ iowrite32(0x001f0000, priv->base + LYNX_28G_LNaRECR1(lane->id));
+ iowrite32(0xa1000023, priv->base + LYNX_28G_LNaRECR2(lane->id));
+ iowrite32(0x00002020, priv->base + LYNX_28G_LNaRSCCR0(lane->id));
+ iowrite32(0x8f000000, priv->base + LYNX_28G_LNaRCCR0(lane->id));
+ iowrite32(0x00008001, priv->base + LYNX_28G_LNaTTLCR0(lane->id));
+}
+
static int lynx_28g_power_off(struct phy *phy)
{
struct lynx_28g_lane *lane = phy_get_drvdata(phy);
@@ -407,6 +478,9 @@ static int lynx_28g_set_mode(struct phy *phy, enum phy_mode mode, int submode)
case PHY_INTERFACE_MODE_10GBASER:
lynx_28g_lane_set_10gbaser(lane);
break;
+ case PHY_INTERFACE_MODE_25GBASER:
+ lynx_28g_lane_set_25gbaser(lane);
+ break;
default:
err = -EOPNOTSUPP;
goto out;
@@ -491,8 +565,12 @@ static void lynx_28g_pll_read_configuration(struct lynx_28g_priv *priv)
/* 10.3125GHz clock net */
__set_bit(PHY_INTERFACE_MODE_10GBASER, pll->supported);
break;
+ case LYNX_28G_PLLnCR1_FRATE_12G_25GVCO:
+ /* 12.890625GHz clock net */
+ __set_bit(PHY_INTERFACE_MODE_25GBASER, pll->supported);
+ break;
default:
- /* 6GHz, 12.890625GHz, 8GHz */
+ /* 6GHz, 8GHz */
break;
}
}
@@ -541,6 +619,9 @@ static void lynx_28g_lane_read_configuration(struct lynx_28g_lane *lane)
case LYNX_28G_LNaPSS_TYPE_XFI:
lane->interface = PHY_INTERFACE_MODE_10GBASER;
break;
+ case LYNX_28G_LNaPSS_TYPE_25G:
+ lane->interface = PHY_INTERFACE_MODE_25GBASER;
+ break;
default:
lane->interface = PHY_INTERFACE_MODE_NA;
}
--
2.35.3
From b84b2a28a5347201b87239e00cd55a2c216b045d Mon Sep 17 00:00:00 2001
From: Ioana Ciornei <ioana.ciornei@nxp.com>
Date: Wed, 5 Apr 2023 15:36:39 +0300
Subject: [PATCH 59/61] net: dpaa2: add support for 25G interfaces
Add support in the dpaa2-eth driver so that it's able to also treat the
PHY_INTERFACE_MODE_25GBASER interface type.
Add MC_25000FD in the mac_capabilities field and add support so that the
driver is able to change from the MC known interface types to the Linux
known ones.
Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
---
drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index 4452a056b580..2302e9c11186 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -57,6 +57,9 @@ static int phy_mode(enum dpmac_eth_if eth_if, phy_interface_t *if_mode)
case DPMAC_ETH_IF_XFI:
*if_mode = PHY_INTERFACE_MODE_10GBASER;
break;
+ case DPMAC_ETH_IF_CAUI:
+ *if_mode = PHY_INTERFACE_MODE_25GBASER;
+ break;
default:
return -EINVAL;
}
@@ -92,6 +95,8 @@ static enum dpmac_eth_if dpmac_eth_if_mode(phy_interface_t if_mode)
return DPMAC_ETH_IF_XFI;
case PHY_INTERFACE_MODE_1000BASEX:
return DPMAC_ETH_IF_1000BASEX;
+ case PHY_INTERFACE_MODE_25GBASER:
+ return DPMAC_ETH_IF_CAUI;
default:
return DPMAC_ETH_IF_MII;
}
@@ -208,6 +213,13 @@ static void dpaa2_mac_validate(struct phylink_config *config,
switch (state->interface) {
case PHY_INTERFACE_MODE_NA:
+ case PHY_INTERFACE_MODE_25GBASER:
+ phylink_set(mask, 25000baseCR_Full);
+ phylink_set(mask, 25000baseKR_Full);
+ phylink_set(mask, 25000baseSR_Full);
+ if (state->interface == PHY_INTERFACE_MODE_25GBASER)
+ break;
+ fallthrough;
case PHY_INTERFACE_MODE_10GBASER:
case PHY_INTERFACE_MODE_USXGMII:
phylink_set(mask, 10000baseT_Full);
--
2.35.3
From 673e9c8f857169f226d3056e81726778c2bdd8b7 Mon Sep 17 00:00:00 2001
From: Josua Mayer <josua@solid-run.com>
Date: Wed, 23 Nov 2022 13:23:03 +0200
Subject: [PATCH 60/61] phy: add of_phy_get_by_index
Support getting a phy by index directly.
This is mostly useful for hardware specifying multiple similar
generic phys using the "phys" and "phy-names" properties.
Current user is dpaa2 driver that can have a phy object for each serdes
lane, and additionally 2 retimer channels (tx&rx).
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
drivers/phy/phy-core.c | 11 +++++++++--
include/linux/phy/phy.h | 6 ++++++
2 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
index 71cb10826326..7662c2cc02cd 100644
--- a/drivers/phy/phy-core.c
+++ b/drivers/phy/phy-core.c
@@ -546,12 +546,19 @@ static struct phy *_of_phy_get(struct device_node *np, int index)
*/
struct phy *of_phy_get(struct device_node *np, const char *con_id)
{
- struct phy *phy = NULL;
int index = 0;
if (con_id)
index = of_property_match_string(np, "phy-names", con_id);
+ return of_phy_get_by_index(np, index);
+}
+EXPORT_SYMBOL_GPL(of_phy_get);
+
+struct phy *of_phy_get_by_index(struct device_node *np, int index)
+{
+ struct phy *phy = NULL;
+
phy = _of_phy_get(np, index);
if (IS_ERR(phy))
return phy;
@@ -563,7 +570,7 @@ struct phy *of_phy_get(struct device_node *np, const char *con_id)
return phy;
}
-EXPORT_SYMBOL_GPL(of_phy_get);
+EXPORT_SYMBOL_GPL(of_phy_get_by_index);
/**
* of_phy_put() - release the PHY
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
index e435bdb0bab3..25038eb5aa8b 100644
--- a/include/linux/phy/phy.h
+++ b/include/linux/phy/phy.h
@@ -245,6 +245,7 @@ void of_phy_put(struct phy *phy);
void phy_put(struct device *dev, struct phy *phy);
void devm_phy_put(struct device *dev, struct phy *phy);
struct phy *of_phy_get(struct device_node *np, const char *con_id);
+struct phy *of_phy_get_by_index(struct device_node *np, int index);
struct phy *of_phy_simple_xlate(struct device *dev,
struct of_phandle_args *args);
struct phy *phy_create(struct device *dev, struct device_node *node,
@@ -444,6 +445,11 @@ static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
return ERR_PTR(-ENOSYS);
}
+static inline struct phy *of_phy_get_by_index(struct device_node *np, int index)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
static inline struct phy *of_phy_simple_xlate(struct device *dev,
struct of_phandle_args *args)
{
--
2.35.3
From 4f57e6a9e4b8a9b1e440459ce574a1f4921e1473 Mon Sep 17 00:00:00 2001
From: Josua Mayer <josua@solid-run.com>
Date: Sun, 16 Apr 2023 14:32:28 +0300
Subject: [PATCH] net: dpaa2: add support for retimer phys
To support network speeds greater than 10Gbps retimers may be connected
on tx & rx lines between the SoC and external phy.
Add support for dynamic configuration of retimers modeles as generic phy
ojects, and reconfigure them on interface type change.
In order to extract multiple different types of phy objects, i.e. serdes
& retimer, the existing code using of_phy_get is replaced by a loop
handling both serdes & retimer phys.
In the future to support 40G & 100G interface speeds, the number of
supported phys might need to be increased from the current maximum of
one serdes and 2 retimer phys.
Signed-off-by: Josua Mayer <josua@solid-run.com>
---
.../net/ethernet/freescale/dpaa2/dpaa2-mac.c | 63 +++++++++++++++----
.../net/ethernet/freescale/dpaa2/dpaa2-mac.h | 1 +
2 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
index 2302e9c11186..a4aad5431e82 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c
@@ -266,6 +266,7 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
struct dpaa2_mac *mac = phylink_to_dpaa2_mac(config);
struct dpmac_link_state *dpmac_state = &mac->state;
int err;
+ int i;
if (state->an_enabled)
dpmac_state->options |= DPMAC_LINK_OPT_AUTONEG;
@@ -290,6 +291,15 @@ static void dpaa2_mac_config(struct phylink_config *config, unsigned int mode,
err = phy_set_mode_ext(mac->serdes_phy, PHY_MODE_ETHERNET, state->interface);
if (err)
netdev_err(mac->net_dev, "phy_set_mode_ext() = %d\n", err);
+
+ for (i = 0; i < sizeof(mac->retimer_phys)/sizeof(mac->retimer_phys[0]); i++) {
+ if (!mac->retimer_phys[i])
+ continue;
+
+ err = phy_set_mode_ext(mac->retimer_phys[i], PHY_MODE_ETHERNET, state->interface);
+ if (err)
+ netdev_err(mac->net_dev, "phy_set_mode_ext() on retimer = %d\n", err);
+ }
}
static void dpaa2_mac_link_up(struct phylink_config *config,
@@ -419,9 +429,13 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
{
struct net_device *net_dev = mac->net_dev;
struct fwnode_handle *dpmac_node;
- struct phy *serdes_phy = NULL;
+ struct phy *phy = NULL;
struct phylink *phylink;
+ const char *phy_name;
int err;
+ int phy_count;
+ int retimer_phy_count = 0;
+ int i;
mac->if_link_type = mac->attr.link_type;
@@ -436,19 +450,42 @@ int dpaa2_mac_connect(struct dpaa2_mac *mac)
return -EINVAL;
mac->if_mode = err;
- if (mac->features & DPAA2_MAC_FEATURE_PROTOCOL_CHANGE &&
- !phy_interface_mode_is_rgmii(mac->if_mode) &&
- is_of_node(dpmac_node)) {
- serdes_phy = of_phy_get(to_of_node(dpmac_node), NULL);
-
- if (serdes_phy == ERR_PTR(-ENODEV))
- serdes_phy = NULL;
- else if (IS_ERR(serdes_phy))
- return PTR_ERR(serdes_phy);
- else
- phy_init(serdes_phy);
+ /* parse serdes & retimer phys, if any */
+ phy_count = of_count_phandle_with_args(to_of_node(dpmac_node), "phys", "#phy-cells");
+ if (phy_count >= 0) {
+ for (i = 0; i < phy_count; i++) {
+ phy = of_phy_get_by_index(to_of_node(dpmac_node), i);
+ if (IS_ERR(phy))
+ return PTR_ERR(phy);
+
+ err = of_property_read_string_index(to_of_node(dpmac_node), "phy-names", i, &phy_name);
+ if (err || !strcmp("serdes", phy_name)) {
+ if (!(mac->features & DPAA2_MAC_FEATURE_PROTOCOL_CHANGE)
+ || phy_interface_mode_is_rgmii(mac->if_mode)) {
+ printk("dpaa2_mac_connect: should maybe not enable serdes phy?\n");
+ continue;
+ }
+
+ if (mac->serdes_phy) {
+ netdev_warn(net_dev, "unsupported number of serdes phys\n");
+ continue;
+ }
+
+ phy_init(phy);
+ mac->serdes_phy = phy;
+ } else if (!strcmp("retimer", phy_name)) {
+ if (retimer_phy_count >= sizeof(mac->retimer_phys)/sizeof(mac->retimer_phys[0])) {
+ netdev_warn(net_dev, "unsupported number of retimer phys\n");
+ continue;
+ }
+
+ phy_init(phy);
+ mac->retimer_phys[retimer_phy_count++] = phy;
+ } else {
+ netdev_warn(net_dev, "unsupported phy \"%s\"\n", phy_name);
+ }
+ }
}
- mac->serdes_phy = serdes_phy;
/* The MAC does not have the capability to add RGMII delays so
* error out if the interface mode requests them and there is no PHY
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
index 09163dd210be..0bc767248f6c 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.h
@@ -29,6 +29,7 @@ struct dpaa2_mac {
struct lynx_pcs *pcs;
struct fwnode_handle *fw_node;
struct phy *serdes_phy;
+ struct phy *retimer_phys[2];
struct led_classdev *link_status_led;
};
--
2.35.3
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