* [PATCH net-next 0/7] net: lan969x: add RGMII support
@ 2024-11-06 19:16 Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 1/7] net: sparx5: do some preparation work Daniel Machon
` (6 more replies)
0 siblings, 7 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
== Description:
This series is the fourth of a multi-part series, that prepares and adds
support for the new lan969x switch driver.
The upstreaming efforts is split into multiple series (might change a
bit as we go along):
1) Prepare the Sparx5 driver for lan969x (merged)
2) Add support for lan969x (same basic features as Sparx5
provides excl. FDMA and VCAP, merged).
3) Add lan969x VCAP functionality (merged).
--> 4) Add RGMII support.
5) Add FDMA support.
== RGMII support:
The lan969x switch device includes two RGMII interfaces (port 28 and 29)
supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.
Details are in the commit description of the patches.
== Patch breakdown:
Patch #1 does some preparation work.
Patch #2 adds new function: is_port_rgmii() to the match data ops.
Patch #3 uses the is_port_rgmii() in a number of places.
Patch #4 uses the phy_interface_mode_is_rgmii() in a number of places.
Patch #5 adds checks for RGMII PHY modes in sparx5_verify_speeds().
Patch #6 adds registers required to configure RGMII.
Patch #7 adds RGMII configuration function and uses it.
To: UNGLinuxDriver@microchip.com
To: Andrew Lunn <andrew+netdev@lunn.ch>
To: David S. Miller <davem@davemloft.net>
To: Eric Dumazet <edumazet@google.com>
To: Jakub Kicinski <kuba@kernel.org>
To: Paolo Abeni <pabeni@redhat.com>
To: Lars Povlsen <lars.povlsen@microchip.com>
To: Steen Hegelund <Steen.Hegelund@microchip.com>
To: Horatiu Vultur <horatiu.vultur@microchip.com>
To: Russell King <linux@armlinux.org.uk>
To: jacob.e.keller@intel.com
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
Daniel Machon (7):
net: sparx5: do some preparation work
net: sparx5: add function for RGMII port check
net: sparx5: use is_port_rgmii() throughout
net: sparx5: use phy_interface_mode_is_rgmii()
net: sparx5: verify RGMII speeds
net: lan969x: add RGMII registers
net: lan969x: add function for configuring RGMII port devices
drivers/net/ethernet/microchip/lan969x/lan969x.c | 109 ++++++++++++++++
drivers/net/ethernet/microchip/lan969x/lan969x.h | 5 +
.../net/ethernet/microchip/sparx5/sparx5_main.c | 29 +++--
.../net/ethernet/microchip/sparx5/sparx5_main.h | 6 +
.../ethernet/microchip/sparx5/sparx5_main_regs.h | 145 +++++++++++++++++++++
.../net/ethernet/microchip/sparx5/sparx5_phylink.c | 3 +
.../net/ethernet/microchip/sparx5/sparx5_port.c | 57 ++++----
.../net/ethernet/microchip/sparx5/sparx5_port.h | 5 +
8 files changed, 329 insertions(+), 30 deletions(-)
---
base-commit: 157a4881225bd0af5444aab9510e7b6da28f2469
change-id: 20241104-sparx5-lan969x-switch-driver-4-d59b7820485a
Best regards,
--
Daniel Machon <daniel.machon@microchip.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH net-next 1/7] net: sparx5: do some preparation work
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-08 11:18 ` Russell King (Oracle)
2024-11-06 19:16 ` [PATCH net-next 2/7] net: sparx5: add function for RGMII port check Daniel Machon
` (5 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
The sparx5_port_init() does initial configuration of a variety of
different features and options for each port. Some are shared for all
types of devices, some are not. As it is now, common configuration is
done after configuration of low-speed devices. This will not work when
adding RGMII support in a subsequent patch.
In preparation for lan969x RGMII support, move a block of code, that
configures 2g5 devices, down. This ensures that the configuration common
to all devices is done before configuration of 2g5, 5g, 10g and 25g
devices.
Also, expose the two symbols: SPX5_ETYPE_TAG_C and SPX5_ETYPE_TAG_S,
which will be needed by the lan969x RGMII configuration in a subsequent
patch.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../net/ethernet/microchip/sparx5/sparx5_main.h | 3 ++
.../net/ethernet/microchip/sparx5/sparx5_port.c | 39 ++++++++++------------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 146bdc938adc..91ae383a5555 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -134,6 +134,9 @@ enum sparx5_feature {
#define SPARX5_MAX_PTP_ID 512
+#define SPX5_ETYPE_TAG_C 0x8100
+#define SPX5_ETYPE_TAG_S 0x88a8
+
struct sparx5;
struct sparx5_calendar_data {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 1401761c6251..bb04c2ccf112 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -12,9 +12,6 @@
#include "sparx5_main.h"
#include "sparx5_port.h"
-#define SPX5_ETYPE_TAG_C 0x8100
-#define SPX5_ETYPE_TAG_S 0x88a8
-
#define SPX5_WAIT_US 1000
#define SPX5_WAIT_MAX_US 2000
@@ -1067,24 +1064,6 @@ int sparx5_port_init(struct sparx5 *sparx5,
if (err)
return err;
- /* Configure MAC vlan awareness */
- err = sparx5_port_max_tags_set(sparx5, port);
- if (err)
- return err;
-
- /* Set Max Length */
- spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
- DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
- sparx5,
- DEV2G5_MAC_MAXLEN_CFG(port->portno));
-
- /* 1G/2G5: Signal Detect configuration */
- spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
- DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
- DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
- sparx5,
- DEV2G5_PCS1G_SD_CFG(port->portno));
-
/* Set Pause WM hysteresis */
spx5_rmw(QSYS_PAUSE_CFG_PAUSE_START_SET(pause_start) |
QSYS_PAUSE_CFG_PAUSE_STOP_SET(pause_stop) |
@@ -1108,6 +1087,24 @@ int sparx5_port_init(struct sparx5 *sparx5,
ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
sparx5, ANA_CL_FILTER_CTRL(port->portno));
+ /* Configure MAC vlan awareness */
+ err = sparx5_port_max_tags_set(sparx5, port);
+ if (err)
+ return err;
+
+ /* Set Max Length */
+ spx5_rmw(DEV2G5_MAC_MAXLEN_CFG_MAX_LEN_SET(ETH_MAXLEN),
+ DEV2G5_MAC_MAXLEN_CFG_MAX_LEN,
+ sparx5,
+ DEV2G5_MAC_MAXLEN_CFG(port->portno));
+
+ /* 1G/2G5: Signal Detect configuration */
+ spx5_wr(DEV2G5_PCS1G_SD_CFG_SD_POL_SET(sd_pol) |
+ DEV2G5_PCS1G_SD_CFG_SD_SEL_SET(sd_sel) |
+ DEV2G5_PCS1G_SD_CFG_SD_ENA_SET(sd_ena),
+ sparx5,
+ DEV2G5_PCS1G_SD_CFG(port->portno));
+
if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
conf->portmode == PHY_INTERFACE_MODE_SGMII) {
err = sparx5_serdes_set(sparx5, port, conf);
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 2/7] net: sparx5: add function for RGMII port check
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 1/7] net: sparx5: do some preparation work Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout Daniel Machon
` (4 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
The lan969x device contains two RGMII interfaces, sitting at port 28 and
29. Add function: is_port_rgmii() to the match data ops, that checks if
a given port is an RGMII port or not. For Sparx5, this function always
returns false.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/lan969x/lan969x.c | 1 +
drivers/net/ethernet/microchip/lan969x/lan969x.h | 5 +++++
drivers/net/ethernet/microchip/sparx5/sparx5_main.c | 1 +
drivers/net/ethernet/microchip/sparx5/sparx5_main.h | 1 +
drivers/net/ethernet/microchip/sparx5/sparx5_port.h | 5 +++++
5 files changed, 13 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/lan969x/lan969x.c
index 79e5bcefbd73..8ac2652ef22c 100644
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
@@ -326,6 +326,7 @@ static const struct sparx5_ops lan969x_ops = {
.is_port_5g = &lan969x_port_is_5g,
.is_port_10g = &lan969x_port_is_10g,
.is_port_25g = &lan969x_port_is_25g,
+ .is_port_rgmii = &lan969x_port_is_rgmii,
.get_port_dev_index = &lan969x_port_dev_mapping,
.get_port_dev_bit = &lan969x_get_dev_mode_bit,
.get_hsch_max_group_rate = &lan969x_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.h b/drivers/net/ethernet/microchip/lan969x/lan969x.h
index 7ce047ad9ca4..47e2adce1bbb 100644
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.h
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.h
@@ -51,6 +51,11 @@ static inline bool lan969x_port_is_25g(int portno)
return false;
}
+static inline bool lan969x_port_is_rgmii(int portno)
+{
+ return portno == 28 || portno == 29;
+}
+
/* lan969x_calendar.c */
int lan969x_dsm_calendar_calc(struct sparx5 *sparx5, u32 taxi,
struct sparx5_calendar_data *data);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 4f2d5413a64f..1c12ea0e6fd3 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -1070,6 +1070,7 @@ static const struct sparx5_ops sparx5_ops = {
.is_port_5g = &sparx5_port_is_5g,
.is_port_10g = &sparx5_port_is_10g,
.is_port_25g = &sparx5_port_is_25g,
+ .is_port_rgmii = &sparx5_port_is_rgmii,
.get_port_dev_index = &sparx5_port_dev_mapping,
.get_port_dev_bit = &sparx5_port_dev_mapping,
.get_hsch_max_group_rate = &sparx5_get_hsch_max_group_rate,
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index 91ae383a5555..a622c01930e7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -313,6 +313,7 @@ struct sparx5_ops {
bool (*is_port_5g)(int portno);
bool (*is_port_10g)(int portno);
bool (*is_port_25g)(int portno);
+ bool (*is_port_rgmii)(int portno);
u32 (*get_port_dev_index)(struct sparx5 *sparx5, int port);
u32 (*get_port_dev_bit)(struct sparx5 *sparx5, int port);
u32 (*get_hsch_max_group_rate)(int grp);
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
index 9b9bcc6834bc..c8a37468a3d1 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.h
@@ -40,6 +40,11 @@ static inline bool sparx5_port_is_25g(int portno)
return portno >= 56 && portno <= 63;
}
+static inline bool sparx5_port_is_rgmii(int portno)
+{
+ return false;
+}
+
static inline u32 sparx5_to_high_dev(struct sparx5 *sparx5, int port)
{
const struct sparx5_ops *ops = sparx5->data->ops;
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 1/7] net: sparx5: do some preparation work Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 2/7] net: sparx5: add function for RGMII port check Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-07 22:39 ` Andrew Lunn
2024-11-06 19:16 ` [PATCH net-next 4/7] net: sparx5: use phy_interface_mode_is_rgmii() Daniel Machon
` (3 subsequent siblings)
6 siblings, 1 reply; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
Now that we can check if a given port is an RGMII port, use it in the
following cases:
- To set RGMII PHY modes for RGMII port devices.
- To avoid checking for a SerDes node in the devicetree, when the port
is an RGMII port.
- To bail out of sparx5_port_init() when the common configuration is
done.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
.../net/ethernet/microchip/sparx5/sparx5_main.c | 28 +++++++++++++++-------
.../net/ethernet/microchip/sparx5/sparx5_port.c | 3 +++
2 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
index 1c12ea0e6fd3..23bcef0970a4 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.c
@@ -311,10 +311,13 @@ static int sparx5_create_port(struct sparx5 *sparx5,
struct initial_port_config *config)
{
struct sparx5_port *spx5_port;
+ const struct sparx5_ops *ops;
struct net_device *ndev;
struct phylink *phylink;
int err;
+ ops = sparx5->data->ops;
+
ndev = sparx5_create_netdev(sparx5, config->portno);
if (IS_ERR(ndev)) {
dev_err(sparx5->dev, "Could not create net device: %02u\n",
@@ -355,6 +358,9 @@ static int sparx5_create_port(struct sparx5 *sparx5,
MAC_SYM_PAUSE | MAC_10 | MAC_100 | MAC_1000FD |
MAC_2500FD | MAC_5000FD | MAC_10000FD | MAC_25000FD;
+ if (ops->is_port_rgmii(spx5_port->portno))
+ phy_interface_set_rgmii(spx5_port->phylink_config.supported_interfaces);
+
__set_bit(PHY_INTERFACE_MODE_SGMII,
spx5_port->phylink_config.supported_interfaces);
__set_bit(PHY_INTERFACE_MODE_QSGMII,
@@ -831,6 +837,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
struct initial_port_config *configs, *config;
struct device_node *np = pdev->dev.of_node;
struct device_node *ports, *portnp;
+ const struct sparx5_ops *ops;
struct reset_control *reset;
struct sparx5 *sparx5;
int idx = 0, err = 0;
@@ -852,6 +859,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
return -EINVAL;
regs = sparx5->data->regs;
+ ops = sparx5->data->ops;
/* Do switch core reset if available */
reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");
@@ -881,7 +889,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
for_each_available_child_of_node(ports, portnp) {
struct sparx5_port_config *conf;
- struct phy *serdes;
+ struct phy *serdes = NULL;
u32 portno;
err = of_property_read_u32(portnp, "reg", &portno);
@@ -911,13 +919,17 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
conf->sd_sgpio = ~0;
else
sparx5->sd_sgpio_remapping = true;
- serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
- if (IS_ERR(serdes)) {
- err = dev_err_probe(sparx5->dev, PTR_ERR(serdes),
- "port %u: missing serdes\n",
- portno);
- of_node_put(portnp);
- goto cleanup_config;
+ /* There is no SerDes node for RGMII ports. */
+ if (!ops->is_port_rgmii(portno)) {
+ serdes = devm_of_phy_get(sparx5->dev, portnp, NULL);
+ if (IS_ERR(serdes)) {
+ err = dev_err_probe(sparx5->dev,
+ PTR_ERR(serdes),
+ "port %u: missing serdes\n",
+ portno);
+ of_node_put(portnp);
+ goto cleanup_config;
+ }
}
config->portno = portno;
config->node = portnp;
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index bb04c2ccf112..61e81b061268 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1087,6 +1087,9 @@ int sparx5_port_init(struct sparx5 *sparx5,
ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
sparx5, ANA_CL_FILTER_CTRL(port->portno));
+ if (ops->is_port_rgmii(port->portno))
+ return 0;
+
/* Configure MAC vlan awareness */
err = sparx5_port_max_tags_set(sparx5, port);
if (err)
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 4/7] net: sparx5: use phy_interface_mode_is_rgmii()
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
` (2 preceding siblings ...)
2024-11-06 19:16 ` [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 5/7] net: sparx5: verify RGMII speeds Daniel Machon
` (2 subsequent siblings)
6 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
Use the phy_interface_mode_is_rgmii() function to check if the PHY mode
is set to any of: RGMII, RGMII_ID, RGMII_RXID or RGMII_TXID in the
following places:
- When selecting the MAC PCS, make sure we return NULL in case the PHY
mode is RGMII (as there is no PCS to configure).
- When doing a port config, make sure we do not do the low-speed device
configuration, in case the PHY mode is RGMII.
Note that we could also have used is_port_rgmii() here, but it makes
more sense to me to use the phylink provided functions, as we are
called by phylink, and the RGMII modes have already been validated
against the supported interfaces of the ports.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c | 3 +++
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 3 ++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
index f8562c1a894d..cb55e05e5611 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_phylink.c
@@ -32,6 +32,9 @@ sparx5_phylink_mac_select_pcs(struct phylink_config *config,
{
struct sparx5_port *port = netdev_priv(to_net_dev(config->dev));
+ if (phy_interface_mode_is_rgmii(interface))
+ return NULL;
+
return &port->phylink_pcs;
}
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index 61e81b061268..fc1ca0cc4bb7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -991,6 +991,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
struct sparx5_port *port,
struct sparx5_port_config *conf)
{
+ bool rgmii = phy_interface_mode_is_rgmii(conf->phy_mode);
bool high_speed_dev = sparx5_is_baser(conf->portmode);
const struct sparx5_ops *ops = sparx5->data->ops;
int err, urgency, stop_wm;
@@ -1000,7 +1001,7 @@ int sparx5_port_config(struct sparx5 *sparx5,
return err;
/* high speed device is already configured */
- if (!high_speed_dev)
+ if (!rgmii && !high_speed_dev)
sparx5_port_config_low_set(sparx5, port, conf);
/* Configure flow control */
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 5/7] net: sparx5: verify RGMII speeds
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
` (3 preceding siblings ...)
2024-11-06 19:16 ` [PATCH net-next 4/7] net: sparx5: use phy_interface_mode_is_rgmii() Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 6/7] net: lan969x: add RGMII registers Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices Daniel Machon
6 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
When doing a port config, we verify the port speed against the PHY mode
and supported speeds of that PHY mode.
Add checks for the four RGMII phy modes: RGMII, RGMII_ID, RGMII_TXID and
RGMII_RXID.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/sparx5/sparx5_port.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index fc1ca0cc4bb7..bd1fa5da47d7 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -254,6 +254,15 @@ static int sparx5_port_verify_speed(struct sparx5 *sparx5,
conf->speed != SPEED_25000))
return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ case PHY_INTERFACE_MODE_RGMII_TXID:
+ case PHY_INTERFACE_MODE_RGMII_RXID:
+ if (conf->speed != SPEED_1000 &&
+ conf->speed != SPEED_100 &&
+ conf->speed != SPEED_10)
+ return sparx5_port_error(port, conf, SPX5_PERR_SPEED);
+ break;
default:
return sparx5_port_error(port, conf, SPX5_PERR_IFTYPE);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 6/7] net: lan969x: add RGMII registers
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
` (4 preceding siblings ...)
2024-11-06 19:16 ` [PATCH net-next 5/7] net: sparx5: verify RGMII speeds Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices Daniel Machon
6 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
Configuration of RGMII is done by configuring the GPIO and clock
settings in the HSIOWRAP target, and configuring the RGMII port devices
in the DEVRGMII target. Both targets contain registers replicated for
the number of RGMII port devices, which is two.
Add said targets and register macros required to configure RGMII.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/lan969x/lan969x.c | 3 +
.../ethernet/microchip/sparx5/sparx5_main_regs.h | 145 +++++++++++++++++++++
2 files changed, 148 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/lan969x/lan969x.c
index 8ac2652ef22c..cfd57eb42c04 100644
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
@@ -90,9 +90,12 @@ static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
{ TARGET_DEV2G5 + 27, 0x30d8000, 1 }, /* 0xe30d8000 */
{ TARGET_DEV10G + 9, 0x30dc000, 1 }, /* 0xe30dc000 */
{ TARGET_PCS10G_BR + 9, 0x30e0000, 1 }, /* 0xe30e0000 */
+ { TARGET_DEVRGMII, 0x30e4000, 1 }, /* 0xe30e4000 */
+ { TARGET_DEVRGMII + 1, 0x30e8000, 1 }, /* 0xe30e8000 */
{ TARGET_DSM, 0x30ec000, 1 }, /* 0xe30ec000 */
{ TARGET_PORT_CONF, 0x30f0000, 1 }, /* 0xe30f0000 */
{ TARGET_ASM, 0x3200000, 1 }, /* 0xe3200000 */
+ { TARGET_HSIO_WRAP, 0x3408000, 1 }, /* 0xe3408000 */
};
static struct sparx5_sdlb_group lan969x_sdlb_groups[LAN969X_SDLB_GRP_CNT] = {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
index 561344f19062..d9ef4ef137b8 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main_regs.h
@@ -37,6 +37,7 @@ enum sparx5_target {
TARGET_FDMA = 117,
TARGET_GCB = 118,
TARGET_HSCH = 119,
+ TARGET_HSIO_WRAP = 120,
TARGET_LRN = 122,
TARGET_PCEP = 129,
TARGET_PCS10G_BR = 132,
@@ -54,6 +55,7 @@ enum sparx5_target {
TARGET_VCAP_SUPER = 326,
TARGET_VOP = 327,
TARGET_XQS = 331,
+ TARGET_DEVRGMII = 392,
NUM_TARGETS = 517
};
@@ -5367,6 +5369,69 @@ extern const struct sparx5_regs *regs;
#define HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY_GET(x)\
FIELD_GET(HSCH_TAS_STATEMACHINE_CFG_REVISIT_DLY, x)
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:XMII_CFG */
+#define HSIO_WRAP_XMII_CFG(g) \
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 0, 0, 1, 4)
+
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG GENMASK(2, 1)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(x)\
+ FIELD_PREP(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+#define HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_GET(x)\
+ FIELD_GET(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:RGMII_CFG */
+#define HSIO_WRAP_RGMII_CFG(g) \
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 4, 0, 1, 4)
+
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG GENMASK(4, 2)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(x)\
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+#define HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_GET(x)\
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST BIT(1)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(x)\
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_GET(x)\
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_TX_RST, x)
+
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST BIT(0)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(x)\
+ FIELD_PREP(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+#define HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_GET(x)\
+ FIELD_GET(HSIO_WRAP_RGMII_CFG_RGMII_RX_RST, x)
+
+/* LAN969X ONLY */
+/* HSIOWRAP:XMII_CFG:DLL_CFG */
+#define HSIO_WRAP_DLL_CFG(g, r) \
+ __REG(TARGET_HSIO_WRAP, 0, 1, 116, g, 2, 20, 12, r, 2, 4)
+
+#define HSIO_WRAP_DLL_CFG_DLL_ENA BIT(19)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_SET(x)\
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_ENA_GET(x)\
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA BIT(18)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(x)\
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_GET(x)\
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_ENA, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL GENMASK(17, 15)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(x)\
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+#define HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_GET(x)\
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_CLK_SEL, x)
+
+#define HSIO_WRAP_DLL_CFG_DLL_RST BIT(0)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_SET(x)\
+ FIELD_PREP(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+#define HSIO_WRAP_DLL_CFG_DLL_RST_GET(x)\
+ FIELD_GET(HSIO_WRAP_DLL_CFG_DLL_RST, x)
+
/* LRN:COMMON:COMMON_ACCESS_CTRL */
#define LRN_COMMON_ACCESS_CTRL \
__REG(TARGET_LRN, 0, 1, 0, 0, 1, 72, 0, 0, 1, 4)
@@ -8110,4 +8175,84 @@ extern const struct sparx5_regs *regs;
#define XQS_CNT(g) \
__REG(TARGET_XQS, 0, 1, 0, g, 1024, 4, 0, 0, 1, 4)
+/* LAN969X ONLY */
+/* DEV1G:DEV_CFG_STATUS:DEV_RST_CTRL */
+#define DEVRGMII_DEV_RST_CTRL(t) \
+ __REG(TARGET_DEVRGMII, t, 2, 0, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL GENMASK(22, 20)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(x)\
+ FIELD_PREP(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+#define DEVRGMII_DEV_RST_CTRL_SPEED_SEL_GET(x)\
+ FIELD_GET(DEVRGMII_DEV_RST_CTRL_SPEED_SEL, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_ENA_CFG */
+#define DEVRGMII_MAC_ENA_CFG(t) \
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 0, 0, 1, 4)
+
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA BIT(4)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_RX_ENA_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_ENA_CFG_RX_ENA, x)
+
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA BIT(0)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+#define DEVRGMII_MAC_ENA_CFG_TX_ENA_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_ENA_CFG_TX_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_TAGS_CFG */
+#define DEVRGMII_MAC_TAGS_CFG(t) \
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 12, 0, 1, 4)
+
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID GENMASK(31, 16)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+#define DEVRGMII_MAC_TAGS_CFG_TAG_ID_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_TAG_ID, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA BIT(3)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA GENMASK(2, 1)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_PB_ENA_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_PB_ENA, x)
+
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA BIT(0)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+#define DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA, x)
+
+/* LAN969X ONLY */
+/* DEV1G:MAC_CFG_STATUS:MAC_IFG_CFG */
+#define DEVRGMII_MAC_IFG_CFG(t) \
+ __REG(TARGET_DEVRGMII, t, 2, 36, 0, 1, 36, 24, 0, 1, 4)
+
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG GENMASK(12, 8)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+#define DEVRGMII_MAC_IFG_CFG_TX_IFG_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_TX_IFG, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2 GENMASK(7, 4)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG2_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG2, x)
+
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1 GENMASK(3, 0)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(x)\
+ FIELD_PREP(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+#define DEVRGMII_MAC_IFG_CFG_RX_IFG1_GET(x)\
+ FIELD_GET(DEVRGMII_MAC_IFG_CFG_RX_IFG1, x)
+
#endif /* _SPARX5_MAIN_REGS_H_ */
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
` (5 preceding siblings ...)
2024-11-06 19:16 ` [PATCH net-next 6/7] net: lan969x: add RGMII registers Daniel Machon
@ 2024-11-06 19:16 ` Daniel Machon
2024-11-07 22:56 ` Andrew Lunn
6 siblings, 1 reply; 15+ messages in thread
From: Daniel Machon @ 2024-11-06 19:16 UTC (permalink / raw)
To: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller
Cc: netdev, linux-kernel, linux-arm-kernel
The lan969x switch device includes two RGMII interfaces (port 28 and 29)
supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.
Add new function: rgmii_config() to the match data ops, and use it to
configure RGMII port devices when doing a port config. On Sparx5, the
RGMII configuration will always be skipped, as the is_port_rgmii() will
return false.
Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
---
drivers/net/ethernet/microchip/lan969x/lan969x.c | 105 +++++++++++++++++++++
.../net/ethernet/microchip/sparx5/sparx5_main.h | 2 +
.../net/ethernet/microchip/sparx5/sparx5_port.c | 3 +
3 files changed, 110 insertions(+)
diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/lan969x/lan969x.c
index cfd57eb42c04..0681913a05d4 100644
--- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
+++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
@@ -9,6 +9,17 @@
#define LAN969X_SDLB_GRP_CNT 5
#define LAN969X_HSCH_LEAK_GRP_CNT 4
+#define LAN969X_RGMII_TX_CLK_DISABLE 0 /* Disable TX clock generation*/
+#define LAN969X_RGMII_TX_CLK_125MHZ 1 /* 1000Mbps */
+#define LAN969X_RGMII_TX_CLK_25MHZ 2 /* 100Mbps */
+#define LAN969X_RGMII_TX_CLK_2M5MHZ 3 /* 10Mbps */
+#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
+#define LAN969X_RGMII_PORT_RATE 2 /* 1000Mbps */
+#define LAN969X_RGMII_SHIFT_90DEG 3 /* Phase shift 90deg. (2 ns @ 125MHz) */
+#define LAN969X_RGMII_IFG_TX 4 /* TX Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX1 5 /* RX1 Inter Frame Gap value */
+#define LAN969X_RGMII_IFG_RX2 1 /* RX2 Inter Frame Gap value */
+
static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
{ TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
{ TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
@@ -293,6 +304,99 @@ static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
return IRQ_HANDLED;
}
+static int lan969x_port_config_rgmii(struct sparx5 *sparx5,
+ struct sparx5_port *port,
+ struct sparx5_port_config *conf)
+{
+ int tx_clk_freq, idx = port->portno - LAN969X_RGMII_PORT_START_IDX;
+ enum sparx5_port_max_tags max_tags = port->max_vlan_tags;
+ enum sparx5_vlan_port_type vlan_type = port->vlan_type;
+ bool dtag, dotag, tx_delay = false, rx_delay = false;
+ u32 etype;
+
+ tx_clk_freq = (conf->speed == SPEED_10 ? LAN969X_RGMII_TX_CLK_2M5MHZ :
+ conf->speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_25MHZ :
+ LAN969X_RGMII_TX_CLK_125MHZ);
+
+ etype = (vlan_type == SPX5_VLAN_PORT_TYPE_S_CUSTOM ?
+ port->custom_etype :
+ vlan_type == SPX5_VLAN_PORT_TYPE_C ?
+ SPX5_ETYPE_TAG_C : SPX5_ETYPE_TAG_S);
+
+ dtag = max_tags == SPX5_PORT_MAX_TAGS_TWO;
+ dotag = max_tags != SPX5_PORT_MAX_TAGS_NONE;
+
+ if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
+ conf->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
+ rx_delay = true;
+
+ if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
+ conf->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID)
+ tx_delay = true;
+
+ /* Take the RGMII clock domains out of reset and set tx clock
+ * frequency.
+ */
+ spx5_rmw(HSIO_WRAP_RGMII_CFG_TX_CLK_CFG_SET(tx_clk_freq) |
+ HSIO_WRAP_RGMII_CFG_RGMII_TX_RST_SET(0) |
+ HSIO_WRAP_RGMII_CFG_RGMII_RX_RST_SET(0),
+ HSIO_WRAP_RGMII_CFG_TX_CLK_CFG |
+ HSIO_WRAP_RGMII_CFG_RGMII_TX_RST |
+ HSIO_WRAP_RGMII_CFG_RGMII_RX_RST,
+ sparx5, HSIO_WRAP_RGMII_CFG(idx));
+
+ /* Enable the RGMII0 on the GPIOs */
+ spx5_wr(HSIO_WRAP_XMII_CFG_GPIO_XMII_CFG_SET(1),
+ sparx5, HSIO_WRAP_XMII_CFG(!idx));
+
+ /* Configure rx delay, the signal is shifted 90 degrees. */
+ spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+ HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(rx_delay) |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(LAN969X_RGMII_SHIFT_90DEG),
+ HSIO_WRAP_DLL_CFG_DLL_RST |
+ HSIO_WRAP_DLL_CFG_DLL_ENA |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+ sparx5, HSIO_WRAP_DLL_CFG(idx, 0));
+
+ /* Configure tx delay, the signal is shifted 90 degrees. */
+ spx5_rmw(HSIO_WRAP_DLL_CFG_DLL_RST_SET(0) |
+ HSIO_WRAP_DLL_CFG_DLL_ENA_SET(1) |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA_SET(tx_delay) |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL_SET(LAN969X_RGMII_SHIFT_90DEG),
+ HSIO_WRAP_DLL_CFG_DLL_RST |
+ HSIO_WRAP_DLL_CFG_DLL_ENA |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_ENA |
+ HSIO_WRAP_DLL_CFG_DLL_CLK_SEL,
+ sparx5, HSIO_WRAP_DLL_CFG(idx, 1));
+
+ /* Configure the port now */
+ spx5_wr(DEVRGMII_MAC_ENA_CFG_RX_ENA_SET(1) |
+ DEVRGMII_MAC_ENA_CFG_TX_ENA_SET(1),
+ sparx5, DEVRGMII_MAC_ENA_CFG(idx));
+
+ /* Configure the Inter Frame Gap */
+ spx5_wr(DEVRGMII_MAC_IFG_CFG_TX_IFG_SET(LAN969X_RGMII_IFG_TX) |
+ DEVRGMII_MAC_IFG_CFG_RX_IFG1_SET(LAN969X_RGMII_IFG_RX1) |
+ DEVRGMII_MAC_IFG_CFG_RX_IFG2_SET(LAN969X_RGMII_IFG_RX2),
+ sparx5, DEVRGMII_MAC_IFG_CFG(idx));
+
+ /* Configure port data rate */
+ spx5_wr(DEVRGMII_DEV_RST_CTRL_SPEED_SEL_SET(LAN969X_RGMII_PORT_RATE),
+ sparx5, DEVRGMII_DEV_RST_CTRL(idx));
+
+ /* Configure VLAN awareness */
+ spx5_wr(DEVRGMII_MAC_TAGS_CFG_TAG_ID_SET(etype) |
+ DEVRGMII_MAC_TAGS_CFG_PB_ENA_SET(dtag) |
+ DEVRGMII_MAC_TAGS_CFG_VLAN_AWR_ENA_SET(dotag) |
+ DEVRGMII_MAC_TAGS_CFG_VLAN_LEN_AWR_ENA_SET(dotag),
+ sparx5,
+ DEVRGMII_MAC_TAGS_CFG(idx));
+
+ return 0;
+}
+
static const struct sparx5_regs lan969x_regs = {
.tsize = lan969x_tsize,
.gaddr = lan969x_gaddr,
@@ -337,6 +441,7 @@ static const struct sparx5_ops lan969x_ops = {
.set_port_mux = &lan969x_port_mux_set,
.ptp_irq_handler = &lan969x_ptp_irq_handler,
.dsm_calendar_calc = &lan969x_dsm_calendar_calc,
+ .rgmii_config = &lan969x_port_config_rgmii,
};
const struct sparx5_match_data lan969x_desc = {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
index a622c01930e7..763c827c01f3 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_main.h
@@ -324,6 +324,8 @@ struct sparx5_ops {
irqreturn_t (*ptp_irq_handler)(int irq, void *args);
int (*dsm_calendar_calc)(struct sparx5 *sparx5, u32 taxi,
struct sparx5_calendar_data *data);
+ int (*rgmii_config)(struct sparx5 *sparx5, struct sparx5_port *port,
+ struct sparx5_port_config *conf);
};
struct sparx5_main_io_resource {
diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
index bd1fa5da47d7..ef61e8164e21 100644
--- a/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
+++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
@@ -1009,6 +1009,9 @@ int sparx5_port_config(struct sparx5 *sparx5,
if (err)
return err;
+ if (rgmii)
+ ops->rgmii_config(sparx5, port, conf);
+
/* high speed device is already configured */
if (!rgmii && !high_speed_dev)
sparx5_port_config_low_set(sparx5, port, conf);
--
2.34.1
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout
2024-11-06 19:16 ` [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout Daniel Machon
@ 2024-11-07 22:39 ` Andrew Lunn
2024-11-08 8:59 ` Daniel Machon
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Lunn @ 2024-11-07 22:39 UTC (permalink / raw)
To: Daniel Machon
Cc: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
> +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
> @@ -1087,6 +1087,9 @@ int sparx5_port_init(struct sparx5 *sparx5,
> ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
> sparx5, ANA_CL_FILTER_CTRL(port->portno));
>
> + if (ops->is_port_rgmii(port->portno))
> + return 0;
> +
> /* Configure MAC vlan awareness */
> err = sparx5_port_max_tags_set(sparx5, port);
> if (err)
That looks odd. What has RGMII to do with MAC VLAN awareness?
Maybe it just needs a comment?
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices
2024-11-06 19:16 ` [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices Daniel Machon
@ 2024-11-07 22:56 ` Andrew Lunn
2024-11-08 8:53 ` Daniel Machon
0 siblings, 1 reply; 15+ messages in thread
From: Andrew Lunn @ 2024-11-07 22:56 UTC (permalink / raw)
To: Daniel Machon
Cc: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
On Wed, Nov 06, 2024 at 08:16:45PM +0100, Daniel Machon wrote:
> The lan969x switch device includes two RGMII interfaces (port 28 and 29)
> supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.
>
> Add new function: rgmii_config() to the match data ops, and use it to
> configure RGMII port devices when doing a port config. On Sparx5, the
> RGMII configuration will always be skipped, as the is_port_rgmii() will
> return false.
>
> Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
> Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
> ---
> drivers/net/ethernet/microchip/lan969x/lan969x.c | 105 +++++++++++++++++++++
> .../net/ethernet/microchip/sparx5/sparx5_main.h | 2 +
> .../net/ethernet/microchip/sparx5/sparx5_port.c | 3 +
> 3 files changed, 110 insertions(+)
>
> diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/lan969x/lan969x.c
> index cfd57eb42c04..0681913a05d4 100644
> --- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
> +++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
> @@ -9,6 +9,17 @@
> #define LAN969X_SDLB_GRP_CNT 5
> #define LAN969X_HSCH_LEAK_GRP_CNT 4
>
> +#define LAN969X_RGMII_TX_CLK_DISABLE 0 /* Disable TX clock generation*/
> +#define LAN969X_RGMII_TX_CLK_125MHZ 1 /* 1000Mbps */
> +#define LAN969X_RGMII_TX_CLK_25MHZ 2 /* 100Mbps */
> +#define LAN969X_RGMII_TX_CLK_2M5MHZ 3 /* 10Mbps */
> +#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
> +#define LAN969X_RGMII_PORT_RATE 2 /* 1000Mbps */
> +#define LAN969X_RGMII_SHIFT_90DEG 3 /* Phase shift 90deg. (2 ns @ 125MHz) */
> +#define LAN969X_RGMII_IFG_TX 4 /* TX Inter Frame Gap value */
> +#define LAN969X_RGMII_IFG_RX1 5 /* RX1 Inter Frame Gap value */
> +#define LAN969X_RGMII_IFG_RX2 1 /* RX2 Inter Frame Gap value */
> +
> static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
> { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
> { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
> @@ -293,6 +304,99 @@ static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
> return IRQ_HANDLED;
> }
>
> +static int lan969x_port_config_rgmii(struct sparx5 *sparx5,
> + struct sparx5_port *port,
> + struct sparx5_port_config *conf)
> +{
> + int tx_clk_freq, idx = port->portno - LAN969X_RGMII_PORT_START_IDX;
> + enum sparx5_port_max_tags max_tags = port->max_vlan_tags;
> + enum sparx5_vlan_port_type vlan_type = port->vlan_type;
> + bool dtag, dotag, tx_delay = false, rx_delay = false;
> + u32 etype;
> +
> + tx_clk_freq = (conf->speed == SPEED_10 ? LAN969X_RGMII_TX_CLK_2M5MHZ :
> + conf->speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_25MHZ :
> + LAN969X_RGMII_TX_CLK_125MHZ);
https://www.spinics.net/lists/netdev/msg1040925.html
Once it is merged, i think this does what you want.
> + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
> + rx_delay = true;
> +
> + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID)
> + tx_delay = true;
O.K, now warning bells are ringing in this reviews head.
What i don't see is the value you pass to the PHY? You obviously need
to mask out what the MAC is doing when talking to the PHY, otherwise
both ends will add delays.
And in general in Linux, we have the PHY add the delays, not the
MAC. It is somewhat arbitrary, but the vast majority of systems do
that. The exception is systems where the PHY is too dumb/cheap to add
the delays and so the MAC has to do it. I'm don't know of any
Microchip PHYs which don't support RGMII delays.
Andrew
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices
2024-11-07 22:56 ` Andrew Lunn
@ 2024-11-08 8:53 ` Daniel Machon
2024-11-08 11:33 ` Russell King (Oracle)
0 siblings, 1 reply; 15+ messages in thread
From: Daniel Machon @ 2024-11-08 8:53 UTC (permalink / raw)
To: Andrew Lunn
Cc: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
Hi Andrew,
> > The lan969x switch device includes two RGMII interfaces (port 28 and 29)
> > supporting data speeds of 1 Gbps, 100 Mbps and 10 Mbps.
> >
> > Add new function: rgmii_config() to the match data ops, and use it to
> > configure RGMII port devices when doing a port config. On Sparx5, the
> > RGMII configuration will always be skipped, as the is_port_rgmii() will
> > return false.
> >
> > Reviewed-by: Steen Hegelund <Steen.Hegelund@microchip.com>
> > Reviewed-by: Horatiu Vultur <horatiu.vultur@microchip.com>
> > Signed-off-by: Daniel Machon <daniel.machon@microchip.com>
> > ---
> > drivers/net/ethernet/microchip/lan969x/lan969x.c | 105 +++++++++++++++++++++
> > .../net/ethernet/microchip/sparx5/sparx5_main.h | 2 +
> > .../net/ethernet/microchip/sparx5/sparx5_port.c | 3 +
> > 3 files changed, 110 insertions(+)
> >
> > diff --git a/drivers/net/ethernet/microchip/lan969x/lan969x.c b/drivers/net/ethernet/microchip/lan969x/lan969x.c
> > index cfd57eb42c04..0681913a05d4 100644
> > --- a/drivers/net/ethernet/microchip/lan969x/lan969x.c
> > +++ b/drivers/net/ethernet/microchip/lan969x/lan969x.c
> > @@ -9,6 +9,17 @@
> > #define LAN969X_SDLB_GRP_CNT 5
> > #define LAN969X_HSCH_LEAK_GRP_CNT 4
> >
> > +#define LAN969X_RGMII_TX_CLK_DISABLE 0 /* Disable TX clock generation*/
> > +#define LAN969X_RGMII_TX_CLK_125MHZ 1 /* 1000Mbps */
> > +#define LAN969X_RGMII_TX_CLK_25MHZ 2 /* 100Mbps */
> > +#define LAN969X_RGMII_TX_CLK_2M5MHZ 3 /* 10Mbps */
> > +#define LAN969X_RGMII_PORT_START_IDX 28 /* Index of the first RGMII port */
> > +#define LAN969X_RGMII_PORT_RATE 2 /* 1000Mbps */
> > +#define LAN969X_RGMII_SHIFT_90DEG 3 /* Phase shift 90deg. (2 ns @ 125MHz) */
> > +#define LAN969X_RGMII_IFG_TX 4 /* TX Inter Frame Gap value */
> > +#define LAN969X_RGMII_IFG_RX1 5 /* RX1 Inter Frame Gap value */
> > +#define LAN969X_RGMII_IFG_RX2 1 /* RX2 Inter Frame Gap value */
> > +
> > static const struct sparx5_main_io_resource lan969x_main_iomap[] = {
> > { TARGET_CPU, 0xc0000, 0 }, /* 0xe00c0000 */
> > { TARGET_FDMA, 0xc0400, 0 }, /* 0xe00c0400 */
> > @@ -293,6 +304,99 @@ static irqreturn_t lan969x_ptp_irq_handler(int irq, void *args)
> > return IRQ_HANDLED;
> > }
> >
> > +static int lan969x_port_config_rgmii(struct sparx5 *sparx5,
> > + struct sparx5_port *port,
> > + struct sparx5_port_config *conf)
> > +{
> > + int tx_clk_freq, idx = port->portno - LAN969X_RGMII_PORT_START_IDX;
> > + enum sparx5_port_max_tags max_tags = port->max_vlan_tags;
> > + enum sparx5_vlan_port_type vlan_type = port->vlan_type;
> > + bool dtag, dotag, tx_delay = false, rx_delay = false;
> > + u32 etype;
> > +
> > + tx_clk_freq = (conf->speed == SPEED_10 ? LAN969X_RGMII_TX_CLK_2M5MHZ :
> > + conf->speed == SPEED_100 ? LAN969X_RGMII_TX_CLK_25MHZ :
> > + LAN969X_RGMII_TX_CLK_125MHZ);
>
> https://www.spinics.net/lists/netdev/msg1040925.html
>
> Once it is merged, i think this does what you want.
>
Nice! Thanks for letting me know.
> > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
> > + rx_delay = true;
> > +
> > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID)
> > + tx_delay = true;
>
> O.K, now warning bells are ringing in this reviews head.
>
> What i don't see is the value you pass to the PHY? You obviously need
> to mask out what the MAC is doing when talking to the PHY, otherwise
> both ends will add delays.
>
What value should be passed to the PHY?
We (the MAC) add the delays based on the PHY modes - so does the PHY.
RGMII, we add both delays.
RGMII_ID, the PHY adds both delays.
RGMII_TXID, we add the rx delay, the PHY adds the tx delay.
RGMII_RXID, we add the tx delay, the PHY adds the rx delay.
Am I missing something here? :-)
> And in general in Linux, we have the PHY add the delays, not the
> MAC. It is somewhat arbitrary, but the vast majority of systems do
> that. The exception is systems where the PHY is too dumb/cheap to add
> the delays and so the MAC has to do it. I'm don't know of any
> Microchip PHYs which don't support RGMII delays.
Ack.
>
> Andrew
/Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout
2024-11-07 22:39 ` Andrew Lunn
@ 2024-11-08 8:59 ` Daniel Machon
0 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-08 8:59 UTC (permalink / raw)
To: Andrew Lunn
Cc: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, Russell King, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
Hi Andrew,
> > +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_port.c
> > @@ -1087,6 +1087,9 @@ int sparx5_port_init(struct sparx5 *sparx5,
> > ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
> > sparx5, ANA_CL_FILTER_CTRL(port->portno));
> >
> > + if (ops->is_port_rgmii(port->portno))
> > + return 0;
> > +
> > /* Configure MAC vlan awareness */
> > err = sparx5_port_max_tags_set(sparx5, port);
> > if (err)
>
> That looks odd. What has RGMII to do with MAC VLAN awareness?
> Maybe it just needs a comment?
The sparx5_port_init() function initializes the RGMII port device (and
the other types of devices too). After the common configuration is done,
we bail out, as we do not want to configure any 2g5, 5g, 10g or 25g
stuff.
I can add a comment, sure.
>
> Andrew
/Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 1/7] net: sparx5: do some preparation work
2024-11-06 19:16 ` [PATCH net-next 1/7] net: sparx5: do some preparation work Daniel Machon
@ 2024-11-08 11:18 ` Russell King (Oracle)
0 siblings, 0 replies; 15+ messages in thread
From: Russell King (Oracle) @ 2024-11-08 11:18 UTC (permalink / raw)
To: Daniel Machon
Cc: UNGLinuxDriver, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Lars Povlsen, Steen Hegelund,
Horatiu Vultur, jacob.e.keller, netdev, linux-kernel,
linux-arm-kernel
On Wed, Nov 06, 2024 at 08:16:39PM +0100, Daniel Machon wrote:
> @@ -134,6 +134,9 @@ enum sparx5_feature {
>
> #define SPARX5_MAX_PTP_ID 512
>
> +#define SPX5_ETYPE_TAG_C 0x8100
Maybe at some point consider using ETH_P_8021Q which is defined in
uapi/linux/if_ether.h ?
> +#define SPX5_ETYPE_TAG_S 0x88a8
Maybe also consider adding ETH_P_8021AD to uapi/linux/if_ether.h ?
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices
2024-11-08 8:53 ` Daniel Machon
@ 2024-11-08 11:33 ` Russell King (Oracle)
2024-11-12 10:26 ` Daniel Machon
0 siblings, 1 reply; 15+ messages in thread
From: Russell King (Oracle) @ 2024-11-08 11:33 UTC (permalink / raw)
To: Daniel Machon
Cc: Andrew Lunn, UNGLinuxDriver, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Lars Povlsen,
Steen Hegelund, Horatiu Vultur, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
On Fri, Nov 08, 2024 at 08:53:20AM +0000, Daniel Machon wrote:
> Hi Andrew,
>
> > > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
> > > + rx_delay = true;
> > > +
> > > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID)
> > > + tx_delay = true;
> >
> > O.K, now warning bells are ringing in this reviews head.
> >
> > What i don't see is the value you pass to the PHY? You obviously need
> > to mask out what the MAC is doing when talking to the PHY, otherwise
> > both ends will add delays.
> >
>
> What value should be passed to the PHY?
>
> We (the MAC) add the delays based on the PHY modes - so does the PHY.
>
> RGMII, we add both delays.
> RGMII_ID, the PHY adds both delays.
> RGMII_TXID, we add the rx delay, the PHY adds the tx delay.
> RGMII_RXID, we add the tx delay, the PHY adds the rx delay.
>
> Am I missing something here? :-)
What if the board routing adds the necessary delays?
From Documentation/networking/phy.rst:
"
* PHY_INTERFACE_MODE_RGMII: the PHY is not responsible for inserting any
internal delay by itself, it assumes that either the Ethernet MAC (if capable)
or the PCB traces insert the correct 1.5-2ns delay
...
For cases where the PHY is not capable of providing this delay, but the
Ethernet MAC driver is capable of doing so, the correct phy_interface_t value
should be PHY_INTERFACE_MODE_RGMII, and the Ethernet MAC driver should be
configured correctly in order to provide the required transmit and/or receive
side delay from the perspective of the PHY device. Conversely, if the Ethernet
MAC driver looks at the phy_interface_t value, for any other mode but
PHY_INTERFACE_MODE_RGMII, it should make sure that the MAC-level delays are
disabled."
The point here is that you have three entities that can deal with the
required delays - the PHY, the board, and the MAC.
PHY_INTERFACE_MODE_RGMII* passed to phylink/phylib tells the PHY how it
should program its delay capabilities.
We're then down to dealing with the MAC and board induced delays. Many
implementations use the rx-internal-delay-ps and tx-internal-delay-ps
properties defined in the ethernet-controller.yaml DT binding to
control the MAC delays.
However, there are a few which use PHY_INTERFACE_MODE_RGMII* on the MAC
end, but in this case, they always pass PHY_INTERFACE_MODE_RGMII to
phylib to stop the PHY adding any delays.
However, we don't have a way at present for DSA/phylink etc to handle a
MAC that wants to ddd its delays with the PHY set to
PHY_INTERFACE_MODE_RGMII.
Thanks.
--
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices
2024-11-08 11:33 ` Russell King (Oracle)
@ 2024-11-12 10:26 ` Daniel Machon
0 siblings, 0 replies; 15+ messages in thread
From: Daniel Machon @ 2024-11-12 10:26 UTC (permalink / raw)
To: Russell King (Oracle)
Cc: Andrew Lunn, UNGLinuxDriver, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Lars Povlsen,
Steen Hegelund, Horatiu Vultur, jacob.e.keller, netdev,
linux-kernel, linux-arm-kernel
Hi Russel,
> > Hi Andrew,
> >
> > > > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > > > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_TXID)
> > > > + rx_delay = true;
> > > > +
> > > > + if (conf->phy_mode == PHY_INTERFACE_MODE_RGMII ||
> > > > + conf->phy_mode == PHY_INTERFACE_MODE_RGMII_RXID)
> > > > + tx_delay = true;
> > >
> > > O.K, now warning bells are ringing in this reviews head.
> > >
> > > What i don't see is the value you pass to the PHY? You obviously need
> > > to mask out what the MAC is doing when talking to the PHY, otherwise
> > > both ends will add delays.
> > >
> >
> > What value should be passed to the PHY?
> >
> > We (the MAC) add the delays based on the PHY modes - so does the PHY.
> >
> > RGMII, we add both delays.
> > RGMII_ID, the PHY adds both delays.
> > RGMII_TXID, we add the rx delay, the PHY adds the tx delay.
> > RGMII_RXID, we add the tx delay, the PHY adds the rx delay.
> >
> > Am I missing something here? :-)
>
> What if the board routing adds the necessary delays?
>
> From Documentation/networking/phy.rst:
> "
> * PHY_INTERFACE_MODE_RGMII: the PHY is not responsible for inserting any
> internal delay by itself, it assumes that either the Ethernet MAC (if capable)
> or the PCB traces insert the correct 1.5-2ns delay
> ...
Ack. The case where the PCB traces add the delay is certainly not
handled with the current changes.
> For cases where the PHY is not capable of providing this delay, but the
> Ethernet MAC driver is capable of doing so, the correct phy_interface_t value
> should be PHY_INTERFACE_MODE_RGMII, and the Ethernet MAC driver should be
> configured correctly in order to provide the required transmit and/or receive
> side delay from the perspective of the PHY device. Conversely, if the Ethernet
> MAC driver looks at the phy_interface_t value, for any other mode but
> PHY_INTERFACE_MODE_RGMII, it should make sure that the MAC-level delays are
> disabled."
>
> The point here is that you have three entities that can deal with the
> required delays - the PHY, the board, and the MAC.
>
> PHY_INTERFACE_MODE_RGMII* passed to phylink/phylib tells the PHY how it
> should program its delay capabilities.
>
> We're then down to dealing with the MAC and board induced delays. Many
> implementations use the rx-internal-delay-ps and tx-internal-delay-ps
> properties defined in the ethernet-controller.yaml DT binding to
> control the MAC delays.
>
> However, there are a few which use PHY_INTERFACE_MODE_RGMII* on the MAC
> end, but in this case, they always pass PHY_INTERFACE_MODE_RGMII to
> phylib to stop the PHY adding any delays.
>
> However, we don't have a way at present for DSA/phylink etc to handle a
> MAC that wants to ddd its delays with the PHY set to
> PHY_INTERFACE_MODE_RGMII.
>
> Thanks.
Right, so using the {rx,tx}-internal-delay-ps allows me to configure the
MAC delays, or skip them entirely, in case the PCB adds them.
Thanks!
/Daniel
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-11-12 10:26 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-06 19:16 [PATCH net-next 0/7] net: lan969x: add RGMII support Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 1/7] net: sparx5: do some preparation work Daniel Machon
2024-11-08 11:18 ` Russell King (Oracle)
2024-11-06 19:16 ` [PATCH net-next 2/7] net: sparx5: add function for RGMII port check Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 3/7] net: sparx5: use is_port_rgmii() throughout Daniel Machon
2024-11-07 22:39 ` Andrew Lunn
2024-11-08 8:59 ` Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 4/7] net: sparx5: use phy_interface_mode_is_rgmii() Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 5/7] net: sparx5: verify RGMII speeds Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 6/7] net: lan969x: add RGMII registers Daniel Machon
2024-11-06 19:16 ` [PATCH net-next 7/7] net: lan969x: add function for configuring RGMII port devices Daniel Machon
2024-11-07 22:56 ` Andrew Lunn
2024-11-08 8:53 ` Daniel Machon
2024-11-08 11:33 ` Russell King (Oracle)
2024-11-12 10:26 ` Daniel Machon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).