netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices
@ 2022-05-19 15:30 Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message Clément Léger
                   ` (12 more replies)
  0 siblings, 13 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

The Renesas RZ/N1 SoCs features an ethernet subsystem which contains
(most notably) a switch, two GMACs, and a MII converter [1]. This
series adds support for the switch and the MII converter.

The MII converter present on this SoC has been represented as a PCS
which sit between the MACs and the PHY. This PCS driver is probed from
the device-tree since it requires to be configured. Indeed the MII
converter also contains the registers that are handling the muxing of
ports (Switch, MAC, HSR, RTOS, etc) internally to the SoC.

The switch driver is based on DSA and exposes 4 ports + 1 CPU
management port. It include basic bridging support as well as FDB and
statistics support.

This series needs commits 14f11da778ff6421 ("soc: renesas: rzn1: Select
PM and PM_GENERIC_DOMAINS configs") and ed66b37f916ee23b ("ARM: dts:
r9a06g032: Add missing '#power-domain-cells'") which are available on
the renesas-devel tree in order to enable generic power domain on
RZ/N1.

Link: [1] https://www.renesas.com/us/en/document/mah/rzn1d-group-rzn1s-group-rzn1l-group-users-manual-r-engine-and-ethernet-peripherals

-----
Changes in V5:
- MAINTAINERS:
  - Add Florian Fainelli Reviewed-by
- Switch:
  - Switch Lookup table lock to a mutex instead of a spinlock
  - Only handle "ethernet-ports" property for switch ports
  - Handle RGMII_ID/RXID/TXID
  - Add check for pdata to be non null in remiove
  - Add missing of_node_put() for mdio and ports
  - Applied Florian Fainelli patch which makes stats description
    shorter
  - Add Kconfig dependency on ARCH_RZN1 to avoid Kconfig "unmet direct
    dependency"
- PCS:
  - Handle RGMII_ID/RXID/TXID
  - Use value instead of BIT() for speed/mode
- Tag driver:
  - Add Florian Fainelli Reviewed-by

Changes in V4:
- Add ETH_P_DSA_A5PSW in uapi/linux/if_ether.h
- PCS:
  - Use devm_pm_runtime_enable() instead of pm_runtime_enable()
- Switch:
  - Return -EOPNOTSUPP and set extack when multiple bdridge are created
  - Remove error messages in fdb_del if entry does not exists
  - Add compatibility with "ethernet-ports" device-tree property
- Tag driver:
  - Use ETH_ZLEN as padding len

Changes in V3:
- PCS:
  - Fixed reverse christmas tree declaration
  - Remove spurious pr_err
  - Use pm_runtime functions
- Tag driver:
  - Remove packed attribute from the tag struct
- Switch:
  - Fix missing spin_unlock in fdb_dump in case of error
  - Add static qualifier to dsa_switch_ops
  - Add missing documentation for hclk and clk members of struct a5psw
  - Changed types of fdb_entry to u16 to discard GCC note on char
    packed bitfields and add reserved field
- Added Reviewed-by tag from Florian Fainelli

Changes in V2:
- PCS:
  - Fix Reverse Christmas tree declaration
  - Removed stray newline
  - Add PCS remove function and disable clocks in them
  - Fix miic_validate function to return correct values
  - Split PCS CONV_MODE definition
  - Reordered phylink_pcs_ops in definition order
  - Remove interface setting in miic_link_up
  - Remove useless checks for invalid interface/speed and error prints
  - Replace phylink_pcs_to_miic_port macro by a static function
  - Add comment in miic_probe about platform_set_drvdata
- Bindings:
 - Fix wrong path for mdio.yaml $ref
 - Fix yamllint errors
- Tag driver:
  - Squashed commit that added tag value with tag driver
  - Add BUILD_BUG_ON for tag size
  - Split control_data2 in 2 16bits values
- Switch:
  - Use .phylink_get_caps instead of .phylink_validate and fill
    supported_interface correctly
  - Use fixed size (ETH_GSTRING_LEN) string for stats and use memcpy
  - Remove stats access locking since RTNL lock is used in upper layers
  - Check for non C45 addresses in mdio_read/write and return
    -EOPNOTSUPP
  - Add get_eth_mac_stats, get_eth_mac_ctrl_stat, get_rmon_stats
  - Fix a few indentation problems
  - Remove reset callback from MDIO bus operation
  - Add phy/mac/rmon stats
- Add get_rmon_stat to dsa_ops

Clément Léger (13):
  net: dsa: allow port_bridge_join() to override extack message
  net: dsa: add support for ethtool get_rmon_stats()
  net: dsa: add Renesas RZ/N1 switch tag driver
  dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter
  net: pcs: add Renesas MII converter driver
  dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port
    switch
  net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver
  net: dsa: rzn1-a5psw: add statistics support
  net: dsa: rzn1-a5psw: add FDB support
  ARM: dts: r9a06g032: describe MII converter
  ARM: dts: r9a06g032: describe GMAC2
  ARM: dts: r9a06g032: describe switch
  MAINTAINERS: add Renesas RZ/N1 switch related driver entry

 .../bindings/net/dsa/renesas,rzn1-a5psw.yaml  |  131 ++
 .../bindings/net/pcs/renesas,rzn1-miic.yaml   |  162 +++
 MAINTAINERS                                   |   11 +
 arch/arm/boot/dts/r9a06g032.dtsi              |   64 +
 drivers/net/dsa/Kconfig                       |    9 +
 drivers/net/dsa/Makefile                      |    1 +
 drivers/net/dsa/rzn1_a5psw.c                  | 1063 +++++++++++++++++
 drivers/net/dsa/rzn1_a5psw.h                  |  259 ++++
 drivers/net/pcs/Kconfig                       |    8 +
 drivers/net/pcs/Makefile                      |    1 +
 drivers/net/pcs/pcs-rzn1-miic.c               |  516 ++++++++
 include/dt-bindings/net/pcs-rzn1-miic.h       |   33 +
 include/linux/pcs-rzn1-miic.h                 |   18 +
 include/net/dsa.h                             |    5 +
 include/uapi/linux/if_ether.h                 |    1 +
 net/dsa/Kconfig                               |    7 +
 net/dsa/Makefile                              |    1 +
 net/dsa/slave.c                               |   18 +-
 net/dsa/tag_rzn1_a5psw.c                      |  113 ++
 19 files changed, 2419 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
 create mode 100644 Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
 create mode 100644 drivers/net/dsa/rzn1_a5psw.c
 create mode 100644 drivers/net/dsa/rzn1_a5psw.h
 create mode 100644 drivers/net/pcs/pcs-rzn1-miic.c
 create mode 100644 include/dt-bindings/net/pcs-rzn1-miic.h
 create mode 100644 include/linux/pcs-rzn1-miic.h
 create mode 100644 net/dsa/tag_rzn1_a5psw.c

-- 
2.36.0


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
@ 2022-05-19 15:30 ` Clément Léger
  2022-05-19 17:53   ` Vladimir Oltean
  2022-05-19 15:30 ` [PATCH net-next v5 02/13] net: dsa: add support for ethtool get_rmon_stats() Clément Léger
                   ` (11 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Some drivers might report that they are unable to bridge ports by
returning -EOPNOTSUPP, but still wants to override extack message.
In order to do so, in dsa_slave_changeupper(), if port_bridge_join()
returns -EOPNOTSUPP, check if extack message is set and if so, do not
override it.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 net/dsa/slave.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 801a5d445833..291197859cea 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -2460,8 +2460,9 @@ static int dsa_slave_changeupper(struct net_device *dev,
 			if (!err)
 				dsa_bridge_mtu_normalization(dp);
 			if (err == -EOPNOTSUPP) {
-				NL_SET_ERR_MSG_MOD(extack,
-						   "Offloading not supported");
+				if (!extack->_msg)
+					NL_SET_ERR_MSG_MOD(extack,
+							   "Offloading not supported");
 				err = 0;
 			}
 			err = notifier_from_errno(err);
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 02/13] net: dsa: add support for ethtool get_rmon_stats()
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message Clément Léger
@ 2022-05-19 15:30 ` Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 03/13] net: dsa: add Renesas RZ/N1 switch tag driver Clément Léger
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add support to allow dsa drivers to specify the .get_rmon_stats()
operation.

Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 include/net/dsa.h |  3 +++
 net/dsa/slave.c   | 13 +++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 14f07275852b..64da5ed27fdc 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -888,6 +888,9 @@ struct dsa_switch_ops {
 				     struct ethtool_eth_mac_stats *mac_stats);
 	void	(*get_eth_ctrl_stats)(struct dsa_switch *ds, int port,
 				      struct ethtool_eth_ctrl_stats *ctrl_stats);
+	void	(*get_rmon_stats)(struct dsa_switch *ds, int port,
+				  struct ethtool_rmon_stats *rmon_stats,
+				  const struct ethtool_rmon_hist_range **ranges);
 	void	(*get_stats64)(struct dsa_switch *ds, int port,
 				   struct rtnl_link_stats64 *s);
 	void	(*self_test)(struct dsa_switch *ds, int port,
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
index 291197859cea..6cfe07ce06d6 100644
--- a/net/dsa/slave.c
+++ b/net/dsa/slave.c
@@ -1002,6 +1002,18 @@ dsa_slave_get_eth_ctrl_stats(struct net_device *dev,
 		ds->ops->get_eth_ctrl_stats(ds, dp->index, ctrl_stats);
 }
 
+static void
+dsa_slave_get_rmon_stats(struct net_device *dev,
+			 struct ethtool_rmon_stats *rmon_stats,
+			 const struct ethtool_rmon_hist_range **ranges)
+{
+	struct dsa_port *dp = dsa_slave_to_port(dev);
+	struct dsa_switch *ds = dp->ds;
+
+	if (ds->ops->get_rmon_stats)
+		ds->ops->get_rmon_stats(ds, dp->index, rmon_stats, ranges);
+}
+
 static void dsa_slave_net_selftest(struct net_device *ndev,
 				   struct ethtool_test *etest, u64 *buf)
 {
@@ -2081,6 +2093,7 @@ static const struct ethtool_ops dsa_slave_ethtool_ops = {
 	.get_eth_phy_stats	= dsa_slave_get_eth_phy_stats,
 	.get_eth_mac_stats	= dsa_slave_get_eth_mac_stats,
 	.get_eth_ctrl_stats	= dsa_slave_get_eth_ctrl_stats,
+	.get_rmon_stats		= dsa_slave_get_rmon_stats,
 	.set_wol		= dsa_slave_set_wol,
 	.get_wol		= dsa_slave_get_wol,
 	.set_eee		= dsa_slave_set_eee,
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 03/13] net: dsa: add Renesas RZ/N1 switch tag driver
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 02/13] net: dsa: add support for ethtool get_rmon_stats() Clément Léger
@ 2022-05-19 15:30 ` Clément Léger
  2022-05-19 15:30 ` [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Clément Léger
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

The switch that is present on the Renesas RZ/N1 SoC uses a specific
VLAN value followed by 6 bytes which contains forwarding configuration.

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 include/net/dsa.h             |   2 +
 include/uapi/linux/if_ether.h |   1 +
 net/dsa/Kconfig               |   7 +++
 net/dsa/Makefile              |   1 +
 net/dsa/tag_rzn1_a5psw.c      | 113 ++++++++++++++++++++++++++++++++++
 5 files changed, 124 insertions(+)
 create mode 100644 net/dsa/tag_rzn1_a5psw.c

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 64da5ed27fdc..33283eeda697 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -53,6 +53,7 @@ struct phylink_link_state;
 #define DSA_TAG_PROTO_SJA1110_VALUE		23
 #define DSA_TAG_PROTO_RTL8_4_VALUE		24
 #define DSA_TAG_PROTO_RTL8_4T_VALUE		25
+#define DSA_TAG_PROTO_RZN1_A5PSW_VALUE		26
 
 enum dsa_tag_protocol {
 	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE,
@@ -81,6 +82,7 @@ enum dsa_tag_protocol {
 	DSA_TAG_PROTO_SJA1110		= DSA_TAG_PROTO_SJA1110_VALUE,
 	DSA_TAG_PROTO_RTL8_4		= DSA_TAG_PROTO_RTL8_4_VALUE,
 	DSA_TAG_PROTO_RTL8_4T		= DSA_TAG_PROTO_RTL8_4T_VALUE,
+	DSA_TAG_PROTO_RZN1_A5PSW	= DSA_TAG_PROTO_RZN1_A5PSW_VALUE,
 };
 
 struct dsa_switch;
diff --git a/include/uapi/linux/if_ether.h b/include/uapi/linux/if_ether.h
index 1d0bccc3fa54..d370165bc621 100644
--- a/include/uapi/linux/if_ether.h
+++ b/include/uapi/linux/if_ether.h
@@ -116,6 +116,7 @@
 #define ETH_P_QINQ3	0x9300		/* deprecated QinQ VLAN [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_EDSA	0xDADA		/* Ethertype DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_DSA_8021Q	0xDADB		/* Fake VLAN Header for DSA [ NOT AN OFFICIALLY REGISTERED ID ] */
+#define ETH_P_DSA_A5PSW	0xE001		/* A5PSW Tag Value [ NOT AN OFFICIALLY REGISTERED ID ] */
 #define ETH_P_IFE	0xED3E		/* ForCES inter-FE LFB type */
 #define ETH_P_AF_IUCV   0xFBFB		/* IBM af_iucv [ NOT AN OFFICIALLY REGISTERED ID ] */
 
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index 8cb87b5067ee..63853fff4e2f 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -132,6 +132,13 @@ config NET_DSA_TAG_RTL8_4
 	  Say Y or M if you want to enable support for tagging frames for Realtek
 	  switches with 8 byte protocol 4 tags, such as the Realtek RTL8365MB-VC.
 
+config NET_DSA_TAG_RZN1_A5PSW
+	tristate "Tag driver for Renesas RZ/N1 A5PSW switch"
+	help
+	  Say Y or M if you want to enable support for tagging frames for
+	  Renesas RZ/N1 embedded switch that uses an 8 byte tag located after
+	  destination MAC address.
+
 config NET_DSA_TAG_LAN9303
 	tristate "Tag driver for SMSC/Microchip LAN9303 family of switches"
 	help
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index 9f75820e7c98..af28c24ead18 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_NET_DSA_TAG_OCELOT_8021Q) += tag_ocelot_8021q.o
 obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
 obj-$(CONFIG_NET_DSA_TAG_RTL4_A) += tag_rtl4_a.o
 obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o
+obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) += tag_rzn1_a5psw.o
 obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
 obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
 obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o
diff --git a/net/dsa/tag_rzn1_a5psw.c b/net/dsa/tag_rzn1_a5psw.c
new file mode 100644
index 000000000000..e2a5ee6ae688
--- /dev/null
+++ b/net/dsa/tag_rzn1_a5psw.c
@@ -0,0 +1,113 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Schneider Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <net/dsa.h>
+
+#include "dsa_priv.h"
+
+/* To define the outgoing port and to discover the incoming port a TAG is
+ * inserted after Src MAC :
+ *
+ *       Dest MAC       Src MAC           TAG         Type
+ * ...| 1 2 3 4 5 6 | 1 2 3 4 5 6 | 1 2 3 4 5 6 7 8 | 1 2 |...
+ *                                |<--------------->|
+ *
+ * See struct a5psw_tag for layout
+ */
+
+#define ETH_P_DSA_A5PSW			0xE001
+#define A5PSW_TAG_LEN			8
+#define A5PSW_CTRL_DATA_FORCE_FORWARD	BIT(0)
+/* This is both used for xmit tag and rcv tagging */
+#define A5PSW_CTRL_DATA_PORT		GENMASK(3, 0)
+
+struct a5psw_tag {
+	__be16 ctrl_tag;
+	__be16 ctrl_data;
+	__be16 ctrl_data2_hi;
+	__be16 ctrl_data2_lo;
+};
+
+static struct sk_buff *a5psw_tag_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct dsa_port *dp = dsa_slave_to_port(dev);
+	struct a5psw_tag *ptag;
+	u32 data2_val;
+
+	BUILD_BUG_ON(sizeof(*ptag) != A5PSW_TAG_LEN);
+
+	/* The Ethernet switch we are interfaced with needs packets to be at
+	 * least 60 bytes otherwise they will be discarded when they enter the
+	 * switch port logic.
+	 */
+	if (__skb_put_padto(skb, ETH_ZLEN, false))
+		return NULL;
+
+	/* provide 'A5PSW_TAG_LEN' bytes additional space */
+	skb_push(skb, A5PSW_TAG_LEN);
+
+	/* make room between MACs and Ether-Type to insert tag */
+	dsa_alloc_etype_header(skb, A5PSW_TAG_LEN);
+
+	ptag = dsa_etype_header_pos_tx(skb);
+
+	data2_val = FIELD_PREP(A5PSW_CTRL_DATA_PORT, BIT(dp->index));
+	ptag->ctrl_tag = htons(ETH_P_DSA_A5PSW);
+	ptag->ctrl_data = htons(A5PSW_CTRL_DATA_FORCE_FORWARD);
+	ptag->ctrl_data2_lo = htons(data2_val);
+	ptag->ctrl_data2_hi = 0;
+
+	return skb;
+}
+
+static struct sk_buff *a5psw_tag_rcv(struct sk_buff *skb,
+				     struct net_device *dev)
+{
+	struct a5psw_tag *tag;
+	int port;
+
+	if (unlikely(!pskb_may_pull(skb, A5PSW_TAG_LEN))) {
+		dev_warn_ratelimited(&dev->dev,
+				     "Dropping packet, cannot pull\n");
+		return NULL;
+	}
+
+	tag = dsa_etype_header_pos_rx(skb);
+
+	if (tag->ctrl_tag != htons(ETH_P_DSA_A5PSW)) {
+		dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid TAG marker\n");
+		return NULL;
+	}
+
+	port = FIELD_GET(A5PSW_CTRL_DATA_PORT, ntohs(tag->ctrl_data));
+
+	skb->dev = dsa_master_find_slave(dev, 0, port);
+	if (!skb->dev)
+		return NULL;
+
+	skb_pull_rcsum(skb, A5PSW_TAG_LEN);
+	dsa_strip_etype_header(skb, A5PSW_TAG_LEN);
+
+	dsa_default_offload_fwd_mark(skb);
+
+	return skb;
+}
+
+static const struct dsa_device_ops a5psw_netdev_ops = {
+	.name	= "a5psw",
+	.proto	= DSA_TAG_PROTO_RZN1_A5PSW,
+	.xmit	= a5psw_tag_xmit,
+	.rcv	= a5psw_tag_rcv,
+	.needed_headroom = A5PSW_TAG_LEN,
+};
+
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_A5PSW);
+module_dsa_tag_driver(a5psw_netdev_ops);
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (2 preceding siblings ...)
  2022-05-19 15:30 ` [PATCH net-next v5 03/13] net: dsa: add Renesas RZ/N1 switch tag driver Clément Léger
@ 2022-05-19 15:30 ` Clément Léger
  2022-05-20  7:09   ` Geert Uytterhoeven
  2022-05-19 15:30 ` [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver Clément Léger
                   ` (8 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev, Rob Herring

This MII converter can be found on the RZ/N1 processor family. The MII
converter ports are declared as subnodes which are then referenced by
users of the PCS driver such as the switch.

Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 .../bindings/net/pcs/renesas,rzn1-miic.yaml   | 162 ++++++++++++++++++
 include/dt-bindings/net/pcs-rzn1-miic.h       |  33 ++++
 2 files changed, 195 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
 create mode 100644 include/dt-bindings/net/pcs-rzn1-miic.h

diff --git a/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml b/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
new file mode 100644
index 000000000000..81a2f7d414a6
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/renesas,rzn1-miic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/N1 MII converter
+
+maintainers:
+  - Clément Léger <clement.leger@bootlin.com>
+
+description: |
+  This MII converter is present on the Renesas RZ/N1 SoC family. It is
+  responsible to do MII passthrough or convert it to RMII/RGMII.
+
+properties:
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 0
+
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a06g032-miic
+      - const: renesas,rzn1-miic
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: MII reference clock
+      - description: RGMII reference clock
+      - description: RMII reference clock
+      - description: AHB clock used for the MII converter register interface
+
+  renesas,miic-switch-portin:
+    description: MII Switch PORTIN configuration. This value should use one of
+      the values defined in dt-bindings/net/pcs-rzn1-miic.h.
+    $ref: /schemas/types.yaml#/definitions/uint32
+    enum: [1, 2]
+
+  power-domains:
+    maxItems: 1
+
+patternProperties:
+  "^mii-conv@[0-5]$":
+    type: object
+    description: MII converter port
+
+    properties:
+      reg:
+        description: MII Converter port number.
+        enum: [1, 2, 3, 4, 5]
+
+      renesas,miic-input:
+        description: Converter input port configuration. This value should use
+          one of the values defined in dt-bindings/net/pcs-rzn1-miic.h.
+        $ref: /schemas/types.yaml#/definitions/uint32
+
+    required:
+      - reg
+      - renesas,miic-input
+
+    additionalProperties: false
+
+    allOf:
+      - if:
+          properties:
+            reg:
+              const: 1
+        then:
+          properties:
+            renesas,miic-input:
+              const: 0
+      - if:
+          properties:
+            reg:
+              const: 2
+        then:
+          properties:
+            renesas,miic-input:
+              enum: [1, 11]
+      - if:
+          properties:
+            reg:
+              const: 3
+        then:
+          properties:
+            renesas,miic-input:
+              enum: [7, 10]
+      - if:
+          properties:
+            reg:
+              const: 4
+        then:
+          properties:
+            renesas,miic-input:
+              enum: [4, 6, 9, 13]
+      - if:
+          properties:
+            reg:
+              const: 5
+        then:
+          properties:
+            renesas,miic-input:
+              enum: [3, 5, 8, 12]
+
+required:
+  - '#address-cells'
+  - '#size-cells'
+  - compatible
+  - reg
+  - clocks
+  - power-domains
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/net/pcs-rzn1-miic.h>
+    #include <dt-bindings/clock/r9a06g032-sysctrl.h>
+
+    eth-miic@44030000 {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      compatible = "renesas,r9a06g032-miic", "renesas,rzn1-miic";
+      reg = <0x44030000 0x10000>;
+      clocks = <&sysctrl R9A06G032_CLK_MII_REF>,
+              <&sysctrl R9A06G032_CLK_RGMII_REF>,
+              <&sysctrl R9A06G032_CLK_RMII_REF>,
+              <&sysctrl R9A06G032_HCLK_SWITCH_RG>;
+      renesas,miic-switch-portin = <MIIC_GMAC2_PORT>;
+      power-domains = <&sysctrl>;
+
+      mii_conv1: mii-conv@1 {
+        renesas,miic-input = <MIIC_GMAC1_PORT>;
+        reg = <1>;
+      };
+
+      mii_conv2: mii-conv@2 {
+        renesas,miic-input = <MIIC_SWITCH_PORTD>;
+        reg = <2>;
+      };
+
+      mii_conv3: mii-conv@3 {
+        renesas,miic-input = <MIIC_SWITCH_PORTC>;
+        reg = <3>;
+      };
+
+      mii_conv4: mii-conv@4 {
+        renesas,miic-input = <MIIC_SWITCH_PORTB>;
+        reg = <4>;
+      };
+
+      mii_conv5: mii-conv@5 {
+        renesas,miic-input = <MIIC_SWITCH_PORTA>;
+        reg = <5>;
+      };
+    };
diff --git a/include/dt-bindings/net/pcs-rzn1-miic.h b/include/dt-bindings/net/pcs-rzn1-miic.h
new file mode 100644
index 000000000000..784782eaec9e
--- /dev/null
+++ b/include/dt-bindings/net/pcs-rzn1-miic.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
+/*
+ * Copyright (C) 2022 Schneider-Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#ifndef _DT_BINDINGS_PCS_RZN1_MIIC
+#define _DT_BINDINGS_PCS_RZN1_MIIC
+
+/*
+ * Reefer to the datasheet [1] section 8.2.1, Internal Connection of Ethernet
+ * Ports to check the available combination
+ *
+ * [1] REN_r01uh0750ej0140-rzn1-introduction_MAT_20210228.pdf
+ */
+
+#define MIIC_GMAC1_PORT			0
+#define MIIC_GMAC2_PORT			1
+#define MIIC_RTOS_PORT			2
+#define MIIC_SERCOS_PORTA		3
+#define MIIC_SERCOS_PORTB		4
+#define MIIC_ETHERCAT_PORTA		5
+#define MIIC_ETHERCAT_PORTB		6
+#define MIIC_ETHERCAT_PORTC		7
+#define MIIC_SWITCH_PORTA		8
+#define MIIC_SWITCH_PORTB		9
+#define MIIC_SWITCH_PORTC		10
+#define MIIC_SWITCH_PORTD		11
+#define MIIC_HSR_PORTA			12
+#define MIIC_HSR_PORTB			13
+
+#endif
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (3 preceding siblings ...)
  2022-05-19 15:30 ` [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Clément Léger
@ 2022-05-19 15:30 ` Clément Léger
  2022-05-19 16:25   ` Russell King (Oracle)
  2022-05-19 15:31 ` [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
                   ` (7 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:30 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add a PCS driver for the MII converter that is present on the Renesas
RZ/N1 SoC. This MII converter is reponsible for converting MII to
RMII/RGMII or act as a MII pass-trough. Exposing it as a PCS allows to
reuse it in both the switch driver and the stmmac driver. Currently,
this driver only allows the PCS to be used by the dual Cortex-A7
subsystem since the register locking system is not used.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/pcs/Kconfig         |   8 +
 drivers/net/pcs/Makefile        |   1 +
 drivers/net/pcs/pcs-rzn1-miic.c | 516 ++++++++++++++++++++++++++++++++
 include/linux/pcs-rzn1-miic.h   |  18 ++
 4 files changed, 543 insertions(+)
 create mode 100644 drivers/net/pcs/pcs-rzn1-miic.c
 create mode 100644 include/linux/pcs-rzn1-miic.h

diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 22ba7b0b476d..6a500d30ca4c 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -18,4 +18,12 @@ config PCS_LYNX
 	  This module provides helpers to phylink for managing the Lynx PCS
 	  which is part of the Layerscape and QorIQ Ethernet SERDES.
 
+config PCS_RZN1_MIIC
+	tristate "Renesas RZ/N1 MII converter"
+	depends on ARCH_RZN1 || COMPILE_TEST
+	help
+	  This module provides a driver for the MII converter that is available
+	  on RZ/N1 SoCs. This PCS converts MII to RMII/RGMII or can be set in
+	  pass-through mode for MII.
+
 endmenu
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index 0603d469bd57..0ff5388fcdea 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -5,3 +5,4 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o
 
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
+obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c
new file mode 100644
index 000000000000..e8962058283c
--- /dev/null
+++ b/drivers/net/pcs/pcs-rzn1-miic.c
@@ -0,0 +1,516 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Schneider Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/pcs-rzn1-miic.h>
+#include <linux/phylink.h>
+#include <linux/pm_runtime.h>
+#include <dt-bindings/net/pcs-rzn1-miic.h>
+
+#define MIIC_PRCMD			0x0
+#define MIIC_ESID_CODE			0x4
+
+#define MIIC_MODCTRL			0x20
+#define MIIC_MODCTRL_SW_MODE		GENMASK(4, 0)
+
+#define MIIC_CONVCTRL(port)		(0x100 + (port) * 4)
+
+#define MIIC_CONVCTRL_CONV_SPEED	GENMASK(1, 0)
+#define CONV_MODE_10MBPS		0
+#define CONV_MODE_100MBPS		1
+#define CONV_MODE_1000MBPS		2
+
+#define MIIC_CONVCTRL_CONV_MODE		GENMASK(3, 2)
+#define CONV_MODE_MII			0
+#define CONV_MODE_RMII			1
+#define CONV_MODE_RGMII			2
+
+#define MIIC_CONVCTRL_FULLD		BIT(8)
+#define MIIC_CONVCTRL_RGMII_LINK	BIT(12)
+#define MIIC_CONVCTRL_RGMII_DUPLEX	BIT(13)
+#define MIIC_CONVCTRL_RGMII_SPEED	GENMASK(15, 14)
+
+#define MIIC_CONVRST			0x114
+#define MIIC_CONVRST_PHYIF_RST(port)	BIT(port)
+#define MIIC_CONVRST_PHYIF_RST_MASK	GENMASK(4, 0)
+
+#define MIIC_SWCTRL			0x304
+#define MIIC_SWDUPC			0x308
+
+#define MIIC_MAX_NR_PORTS		5
+
+#define MIIC_MODCTRL_CONF_CONV_NUM	6
+#define MIIC_MODCTRL_CONF_NONE		-1
+
+/**
+ * struct modctrl_match - Matching table entry for  convctrl configuration
+ *			  See section 8.2.1 of manual.
+ * @mode_cfg: Configuration value for convctrl
+ * @conv: Configuration of ethernet port muxes. First index is SWITCH_PORTIN,
+ *	  then index 1 - 5 are CONV1 - CONV5.
+ */
+struct modctrl_match {
+	u32 mode_cfg;
+	u8 conv[MIIC_MODCTRL_CONF_CONV_NUM];
+};
+
+static struct modctrl_match modctrl_match_table[] = {
+	{0x0, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_SERCOS_PORTB, MIIC_SERCOS_PORTA}},
+	{0x1, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0x2, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_ETHERCAT_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0x3, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_SWITCH_PORTB, MIIC_SWITCH_PORTA}},
+
+	{0x8, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_SERCOS_PORTB, MIIC_SERCOS_PORTA}},
+	{0x9, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0xA, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_ETHERCAT_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0xB, {MIIC_RTOS_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+	       MIIC_SWITCH_PORTC, MIIC_SWITCH_PORTB, MIIC_SWITCH_PORTA}},
+
+	{0x10, {MIIC_GMAC2_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+		MIIC_SWITCH_PORTC, MIIC_SERCOS_PORTB, MIIC_SERCOS_PORTA}},
+	{0x11, {MIIC_GMAC2_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+		MIIC_SWITCH_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0x12, {MIIC_GMAC2_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+		MIIC_ETHERCAT_PORTC, MIIC_ETHERCAT_PORTB, MIIC_ETHERCAT_PORTA}},
+	{0x13, {MIIC_GMAC2_PORT, MIIC_GMAC1_PORT, MIIC_SWITCH_PORTD,
+		MIIC_SWITCH_PORTC, MIIC_SWITCH_PORTB, MIIC_SWITCH_PORTA}}
+};
+
+static const char * const conf_to_string[] = {
+	[MIIC_GMAC1_PORT]	= "GMAC1_PORT",
+	[MIIC_GMAC2_PORT]	= "GMAC2_PORT",
+	[MIIC_RTOS_PORT]	= "RTOS_PORT",
+	[MIIC_SERCOS_PORTA]	= "SERCOS_PORTA",
+	[MIIC_SERCOS_PORTB]	= "SERCOS_PORTB",
+	[MIIC_ETHERCAT_PORTA]	= "ETHERCAT_PORTA",
+	[MIIC_ETHERCAT_PORTB]	= "ETHERCAT_PORTB",
+	[MIIC_ETHERCAT_PORTC]	= "ETHERCAT_PORTC",
+	[MIIC_SWITCH_PORTA]	= "SWITCH_PORTA",
+	[MIIC_SWITCH_PORTB]	= "SWITCH_PORTB",
+	[MIIC_SWITCH_PORTC]	= "SWITCH_PORTC",
+	[MIIC_SWITCH_PORTD]	= "SWITCH_PORTD",
+	[MIIC_HSR_PORTA]	= "HSR_PORTA",
+	[MIIC_HSR_PORTB]	= "HSR_PORTB",
+};
+
+static const char *index_to_string[MIIC_MODCTRL_CONF_CONV_NUM] = {
+	"SWITCH_PORTIN",
+	"CONV1",
+	"CONV2",
+	"CONV3",
+	"CONV4",
+	"CONV5",
+};
+
+/**
+ * struct miic - MII converter structure
+ * @base: base address of the MII converter
+ * @dev: Device associated to the MII converter
+ * @clks: Clocks used for this device
+ * @nclk: Number of clocks
+ * @lock: Lock used for read-modify-write access
+ */
+struct miic {
+	void __iomem *base;
+	struct device *dev;
+	struct clk_bulk_data *clks;
+	int nclk;
+	spinlock_t lock;
+};
+
+/**
+ * struct miic_port - Per port MII converter struct
+ * @miic: backiling to MII converter structure
+ * @pcs: PCS structure associated to the port
+ * @port: port number
+ */
+struct miic_port {
+	struct miic *miic;
+	struct phylink_pcs pcs;
+	int port;
+};
+
+static struct miic_port *phylink_pcs_to_miic_port(struct phylink_pcs *pcs)
+{
+	return container_of(pcs, struct miic_port, pcs);
+}
+
+static void miic_reg_writel(struct miic *miic, int offset, u32 value)
+{
+	writel(value, miic->base + offset);
+}
+
+static u32 miic_reg_readl(struct miic *miic, int offset)
+{
+	return readl(miic->base + offset);
+}
+
+static void miic_reg_rmw(struct miic *miic, int offset, u32 mask, u32 val)
+{
+	u32 reg;
+
+	spin_lock(&miic->lock);
+
+	reg = miic_reg_readl(miic, offset);
+	reg &= ~mask;
+	reg |= val;
+	miic_reg_writel(miic, offset, reg);
+
+	spin_unlock(&miic->lock);
+}
+
+static void miic_converter_enable(struct miic *miic, int port, int enable)
+{
+	u32 val = 0;
+
+	if (enable)
+		val = MIIC_CONVRST_PHYIF_RST(port);
+
+	miic_reg_rmw(miic, MIIC_CONVRST, MIIC_CONVRST_PHYIF_RST(port), val);
+}
+
+static int miic_config(struct phylink_pcs *pcs, unsigned int mode,
+		       phy_interface_t interface,
+		       const unsigned long *advertising, bool permit)
+{
+	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
+	struct miic *miic = miic_port->miic;
+	int port = miic_port->port;
+	u32 speed, conv_mode, val;
+
+	switch (interface) {
+	case PHY_INTERFACE_MODE_RMII:
+		conv_mode = CONV_MODE_RMII;
+		speed = CONV_MODE_100MBPS;
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		conv_mode = CONV_MODE_RGMII;
+		speed = CONV_MODE_1000MBPS;
+		break;
+	case PHY_INTERFACE_MODE_MII:
+		conv_mode = CONV_MODE_MII;
+		/* When in MII mode, speed should be set to 0 (which is actually
+		 * CONV_MODE_10MBPS)
+		 */
+		speed = CONV_MODE_10MBPS;
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+
+	val = FIELD_PREP(MIIC_CONVCTRL_CONV_MODE, conv_mode) |
+	      FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, speed);
+
+	miic_reg_rmw(miic, MIIC_CONVCTRL(port),
+		     MIIC_CONVCTRL_CONV_MODE | MIIC_CONVCTRL_CONV_SPEED, val);
+	miic_converter_enable(miic_port->miic, miic_port->port, 1);
+
+	return 0;
+}
+
+static void miic_link_up(struct phylink_pcs *pcs, unsigned int mode,
+			 phy_interface_t interface, int speed, int duplex)
+{
+	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
+	struct miic *miic = miic_port->miic;
+	u32 conv_speed = 0, val = 0;
+	int port = miic_port->port;
+
+	if (duplex == DUPLEX_FULL)
+		val |= MIIC_CONVCTRL_FULLD;
+
+	/* No speed in MII through-mode */
+	if (interface != PHY_INTERFACE_MODE_MII) {
+		switch (speed) {
+		case SPEED_1000:
+			conv_speed = CONV_MODE_1000MBPS;
+			break;
+		case SPEED_100:
+			conv_speed = CONV_MODE_100MBPS;
+			break;
+		case SPEED_10:
+			conv_speed = CONV_MODE_10MBPS;
+			break;
+		default:
+			return;
+		}
+	}
+
+	val |= FIELD_PREP(MIIC_CONVCTRL_CONV_SPEED, conv_speed);
+
+	miic_reg_rmw(miic, MIIC_CONVCTRL(port),
+		     (MIIC_CONVCTRL_CONV_SPEED | MIIC_CONVCTRL_FULLD), val);
+}
+
+static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
+			 const struct phylink_link_state *state)
+{
+	if (state->interface == PHY_INTERFACE_MODE_RGMII ||
+	    state->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+	    state->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
+	    state->interface == PHY_INTERFACE_MODE_RGMII_RXID ||
+	    state->interface == PHY_INTERFACE_MODE_RMII ||
+	    state->interface == PHY_INTERFACE_MODE_MII)
+		return 1;
+
+	return -EINVAL;
+}
+
+static const struct phylink_pcs_ops miic_phylink_ops = {
+	.pcs_validate = miic_validate,
+	.pcs_config = miic_config,
+	.pcs_link_up = miic_link_up,
+};
+
+struct phylink_pcs *miic_create(struct device_node *np)
+{
+	struct platform_device *pdev;
+	struct miic_port *miic_port;
+	struct device_node *pcs_np;
+	u32 port;
+
+	if (!of_device_is_available(np))
+		return ERR_PTR(-ENODEV);
+
+	if (of_property_read_u32(np, "reg", &port))
+		return ERR_PTR(-EINVAL);
+
+	if (port > MIIC_MAX_NR_PORTS || port < 1)
+		return ERR_PTR(-EINVAL);
+
+	/* The PCS pdev is attached to the parent node */
+	pcs_np = of_get_parent(np);
+	if (!pcs_np)
+		return ERR_PTR(-ENODEV);
+
+	if (!of_device_is_available(pcs_np))
+		return ERR_PTR(-ENODEV);
+
+	pdev = of_find_device_by_node(pcs_np);
+	if (!pdev || !platform_get_drvdata(pdev))
+		return ERR_PTR(-EPROBE_DEFER);
+
+	miic_port = kzalloc(sizeof(*miic_port), GFP_KERNEL);
+	if (!miic_port)
+		return ERR_PTR(-ENOMEM);
+
+	miic_port->miic = platform_get_drvdata(pdev);
+	miic_port->port = port - 1;
+	miic_port->pcs.ops = &miic_phylink_ops;
+
+	return &miic_port->pcs;
+}
+EXPORT_SYMBOL(miic_create);
+
+void miic_destroy(struct phylink_pcs *pcs)
+{
+	struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs);
+
+	miic_converter_enable(miic_port->miic, miic_port->port, 0);
+	kfree(miic_port);
+}
+EXPORT_SYMBOL(miic_destroy);
+
+static int miic_init_hw(struct miic *miic, u32 cfg_mode)
+{
+	int port;
+
+	/* Unlock write access to accessory registers (cf datasheet). If this
+	 * is going to be used in conjunction with the Cortex-M3, this sequence
+	 * will have to be moved in register write
+	 */
+	miic_reg_writel(miic, MIIC_PRCMD, 0x00A5);
+	miic_reg_writel(miic, MIIC_PRCMD, 0x0001);
+	miic_reg_writel(miic, MIIC_PRCMD, 0xFFFE);
+	miic_reg_writel(miic, MIIC_PRCMD, 0x0001);
+
+	miic_reg_writel(miic, MIIC_MODCTRL,
+			FIELD_PREP(MIIC_MODCTRL_SW_MODE, cfg_mode));
+
+	for (port = 0; port < MIIC_MAX_NR_PORTS; port++) {
+		miic_converter_enable(miic, port, 0);
+		/* Disable speed/duplex control from these registers, datasheet
+		 * says switch registers should be used to setup switch port
+		 * speed and duplex.
+		 */
+		miic_reg_writel(miic, MIIC_SWCTRL, 0x0);
+		miic_reg_writel(miic, MIIC_SWDUPC, 0x0);
+	}
+
+	return 0;
+}
+
+static bool miic_modctrl_match(s8 table_val[MIIC_MODCTRL_CONF_CONV_NUM],
+			       s8 dt_val[MIIC_MODCTRL_CONF_CONV_NUM])
+{
+	int i;
+
+	for (i = 0; i < MIIC_MODCTRL_CONF_CONV_NUM; i++) {
+		if (dt_val[i] == MIIC_MODCTRL_CONF_NONE)
+			continue;
+
+		if (dt_val[i] != table_val[i])
+			return false;
+	}
+
+	return true;
+}
+
+static void miic_dump_conf(struct device *dev,
+			   s8 conf[MIIC_MODCTRL_CONF_CONV_NUM])
+{
+	const char *conf_name;
+	int i;
+
+	for (i = 0; i < MIIC_MODCTRL_CONF_CONV_NUM; i++) {
+		if (conf[i] != MIIC_MODCTRL_CONF_NONE)
+			conf_name = conf_to_string[conf[i]];
+		else
+			conf_name = "NONE";
+
+		dev_err(dev, "%s: %s\n", index_to_string[i], conf_name);
+	}
+}
+
+static int miic_match_dt_conf(struct device *dev,
+			      s8 dt_val[MIIC_MODCTRL_CONF_CONV_NUM],
+			      u32 *mode_cfg)
+{
+	struct modctrl_match *table_entry;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(modctrl_match_table); i++) {
+		table_entry = &modctrl_match_table[i];
+
+		if (miic_modctrl_match(table_entry->conv, dt_val)) {
+			*mode_cfg = table_entry->mode_cfg;
+			return 0;
+		}
+	}
+
+	dev_err(dev, "Failed to apply requested configuration\n");
+	miic_dump_conf(dev, dt_val);
+
+	return -EINVAL;
+}
+
+static int miic_parse_dt(struct device *dev, u32 *mode_cfg)
+{
+	s8 dt_val[MIIC_MODCTRL_CONF_CONV_NUM];
+	struct device_node *np = dev->of_node;
+	struct device_node *conv;
+	u32 conf;
+	int port;
+
+	memset(dt_val, MIIC_MODCTRL_CONF_NONE, sizeof(dt_val));
+
+	of_property_read_u32(np, "renesas,miic-switch-portin", &conf);
+	dt_val[0] = conf;
+
+	for_each_child_of_node(np, conv) {
+		if (of_property_read_u32(conv, "reg", &port))
+			continue;
+
+		if (!of_device_is_available(conv))
+			continue;
+
+		if (of_property_read_u32(conv, "renesas,miic-input", &conf) == 0)
+			dt_val[port] = conf;
+
+		of_node_put(conv);
+	}
+
+	return miic_match_dt_conf(dev, dt_val, mode_cfg);
+}
+
+static int miic_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct miic *miic;
+	u32 mode_cfg;
+	int ret;
+
+	ret = miic_parse_dt(dev, &mode_cfg);
+	if (ret < 0)
+		return -EINVAL;
+
+	miic = devm_kzalloc(dev, sizeof(*miic), GFP_KERNEL);
+	if (!miic)
+		return -ENOMEM;
+
+	spin_lock_init(&miic->lock);
+	miic->dev = dev;
+	miic->base = devm_platform_ioremap_resource(pdev, 0);
+	if (!miic->base)
+		return -EINVAL;
+
+	ret = devm_pm_runtime_enable(dev);
+	if (ret < 0)
+		return ret;
+
+	ret = pm_runtime_resume_and_get(dev);
+	if (ret < 0)
+		return ret;
+
+	ret = miic_init_hw(miic, mode_cfg);
+	if (ret)
+		goto disable_runtime_pm;
+
+	/* miic_create() relies on that fact that data are attached to the
+	 * platform device to determine if the driver is ready so this needs to
+	 * be the last thing to be done after everything is initialized
+	 * properly.
+	 */
+	platform_set_drvdata(pdev, miic);
+
+	return 0;
+
+disable_runtime_pm:
+	pm_runtime_put(dev);
+
+	return ret;
+}
+
+static int miic_remove(struct platform_device *pdev)
+{
+	pm_runtime_put(&pdev->dev);
+
+	return 0;
+}
+
+static const struct of_device_id miic_of_mtable[] = {
+	{ .compatible = "renesas,rzn1-miic" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, miic_of_mtable);
+
+static struct platform_driver miic_driver = {
+	.driver = {
+		.name	 = "rzn1_miic",
+		.of_match_table = of_match_ptr(miic_of_mtable),
+	},
+	.probe = miic_probe,
+	.remove = miic_remove,
+};
+module_platform_driver(miic_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas MII converter PCS driver");
+MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");
diff --git a/include/linux/pcs-rzn1-miic.h b/include/linux/pcs-rzn1-miic.h
new file mode 100644
index 000000000000..7a303af57e40
--- /dev/null
+++ b/include/linux/pcs-rzn1-miic.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 Schneider Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#ifndef __LINUX_PCS_MIIC_H
+#define __LINUX_PCS_MIIC_H
+
+struct phylink;
+struct device_node;
+
+struct phylink_pcs *miic_create(struct device_node *np);
+
+void miic_destroy(struct phylink_pcs *pcs);
+
+#endif /* __LINUX_PCS_MIIC_H */
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (4 preceding siblings ...)
  2022-05-19 15:30 ` [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-20  7:13   ` Geert Uytterhoeven
  2022-05-24  2:34   ` Rob Herring
  2022-05-19 15:31 ` [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Clément Léger
                   ` (6 subsequent siblings)
  12 siblings, 2 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
This company does not exists anymore and has been bought by Synopsys.
Since this IP can't be find anymore in the Synospsy portfolio, lets use
Renesas as the vendor compatible for this IP.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 .../bindings/net/dsa/renesas,rzn1-a5psw.yaml  | 131 ++++++++++++++++++
 1 file changed, 131 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml

diff --git a/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
new file mode 100644
index 000000000000..e3ab1cf1575d
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Renesas RZ/N1 Advanced 5 ports ethernet switch
+
+maintainers:
+  - Clément Léger <clement.leger@bootlin.com>
+
+description: |
+  The advanced 5 ports switch is present on the Renesas RZ/N1 SoC family and
+  handles 4 ports + 1 CPU management port.
+
+allOf:
+  - $ref: dsa.yaml#
+
+properties:
+  compatible:
+    items:
+      - enum:
+          - renesas,r9a06g032-a5psw
+      - const: renesas,rzn1-a5psw
+
+  reg:
+    maxItems: 1
+
+  mdio:
+    $ref: /schemas/net/mdio.yaml#
+    unevaluatedProperties: false
+
+  clocks:
+    items:
+      - description: AHB clock used for the switch register interface
+      - description: Switch system clock
+
+  clock-names:
+    items:
+      - const: hclk
+      - const: clk
+
+  ethernet-ports:
+    type: object
+    properties:
+      '#address-cells':
+        const: 1
+      '#size-cells':
+        const: 0
+
+    patternProperties:
+      "^(ethernet-)?port@[0-4]$":
+        type: object
+        description: Ethernet switch ports
+
+        properties:
+          pcs-handle:
+            description:
+              phandle pointing to a PCS sub-node compatible with
+              renesas,rzn1-miic.yaml#
+            $ref: /schemas/types.yaml#/definitions/phandle
+
+unevaluatedProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/clock/r9a06g032-sysctrl.h>
+
+    switch@44050000 {
+        compatible = "renesas,r9a06g032-a5psw", "renesas,rzn1-a5psw";
+        reg = <0x44050000 0x10000>;
+        clocks = <&sysctrl R9A06G032_HCLK_SWITCH>, <&sysctrl R9A06G032_CLK_SWITCH>;
+        clock-names = "hclk", "clk";
+        pinctrl-names = "default";
+        pinctrl-0 = <&pins_mdio1>, <&pins_eth3>, <&pins_eth4>;
+
+        dsa,member = <0 0>;
+
+        ethernet-ports {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            port@0 {
+                reg = <0>;
+                label = "lan0";
+                phy-handle = <&switch0phy3>;
+                pcs-handle = <&mii_conv4>;
+            };
+
+            port@1 {
+                reg = <1>;
+                label = "lan1";
+                phy-handle = <&switch0phy1>;
+                pcs-handle = <&mii_conv3>;
+            };
+
+            port@4 {
+                reg = <4>;
+                ethernet = <&gmac1>;
+                label = "cpu";
+                fixed-link {
+                  speed = <1000>;
+                  full-duplex;
+                };
+            };
+        };
+
+        mdio {
+            #address-cells = <1>;
+            #size-cells = <0>;
+
+            reset-gpios = <&gpio0a 2 GPIO_ACTIVE_HIGH>;
+            reset-delay-us = <15>;
+            clock-frequency = <2500000>;
+
+            switch0phy1: ethernet-phy@1{
+                reg = <1>;
+            };
+
+            switch0phy3: ethernet-phy@3{
+                reg = <3>;
+            };
+        };
+    };
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (5 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-19 18:08   ` Vladimir Oltean
  2022-05-19 15:31 ` [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support Clément Léger
                   ` (5 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev, Jean-Pierre Geslin, Phil Edworthy

Add Renesas RZ/N1 advanced 5 port switch driver. This switch handles 5
ports including 1 CPU management port. A MDIO bus is also exposed by
this switch and allows to communicate with PHYs connected to the ports.
Each switch port (except for the CPU management ports) is connected to
the MII converter.

This driver includes basic bridging support, more support will be added
later (vlan, etc).

Suggested-by: Jean-Pierre Geslin <jean-pierre.geslin@non.se.com>
Suggested-by: Phil Edworthy <phil.edworthy@renesas.com>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/dsa/Kconfig      |   9 +
 drivers/net/dsa/Makefile     |   1 +
 drivers/net/dsa/rzn1_a5psw.c | 720 +++++++++++++++++++++++++++++++++++
 drivers/net/dsa/rzn1_a5psw.h | 198 ++++++++++
 4 files changed, 928 insertions(+)
 create mode 100644 drivers/net/dsa/rzn1_a5psw.c
 create mode 100644 drivers/net/dsa/rzn1_a5psw.h

diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig
index 37a3dabdce31..66ff3a4a3a98 100644
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -70,6 +70,15 @@ config NET_DSA_QCA8K
 
 source "drivers/net/dsa/realtek/Kconfig"
 
+config NET_DSA_RZN1_A5PSW
+	tristate "Renesas RZ/N1 A5PSW Ethernet switch support"
+	depends on ARCH_RZN1
+	select NET_DSA_TAG_RZN1_A5PSW
+	select PCS_RZN1_MIIC
+	help
+	  This driver supports the A5PSW switch, which is embedded in Renesas
+	  RZ/N1 SoC.
+
 config NET_DSA_SMSC_LAN9303
 	tristate
 	depends on VLAN_8021Q || VLAN_8021Q=n
diff --git a/drivers/net/dsa/Makefile b/drivers/net/dsa/Makefile
index e73838c12256..b32907afa702 100644
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
 obj-$(CONFIG_NET_DSA_MT7530)	+= mt7530.o
 obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
 obj-$(CONFIG_NET_DSA_QCA8K)	+= qca8k.o
+obj-$(CONFIG_NET_DSA_RZN1_A5PSW) += rzn1_a5psw.o
 obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
 obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o
 obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o
diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
new file mode 100644
index 000000000000..3c5e905e3a0f
--- /dev/null
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -0,0 +1,720 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2022 Schneider-Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/etherdevice.h>
+#include <linux/if_bridge.h>
+#include <linux/if_ether.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <net/dsa.h>
+
+#include "rzn1_a5psw.h"
+
+static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
+{
+	writel(value, a5psw->base + offset);
+}
+
+static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset)
+{
+	return readl(a5psw->base + offset);
+}
+
+static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)
+{
+	u32 reg;
+
+	spin_lock(&a5psw->reg_lock);
+
+	reg = a5psw_reg_readl(a5psw, offset);
+	reg &= ~mask;
+	reg |= val;
+	a5psw_reg_writel(a5psw, offset, reg);
+
+	spin_unlock(&a5psw->reg_lock);
+}
+
+static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds,
+						    int port,
+						    enum dsa_tag_protocol mp)
+{
+	return DSA_TAG_PROTO_RZN1_A5PSW;
+}
+
+static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern,
+				   bool enable)
+{
+	u32 rx_match = 0;
+
+	if (enable)
+		rx_match |= A5PSW_RXMATCH_CONFIG_PATTERN(pattern);
+
+	a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port),
+		      A5PSW_RXMATCH_CONFIG_PATTERN(pattern), rx_match);
+}
+
+static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable)
+{
+	/* Enable "management forward" pattern matching, this will forward
+	 * packets from this port only towards the management port and thus
+	 * isolate the port.
+	 */
+	a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable);
+}
+
+static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable)
+{
+	u32 port_ena = 0;
+
+	if (enable)
+		port_ena |= A5PSW_PORT_ENA_TX_RX(port);
+
+	a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port),
+		      port_ena);
+}
+
+static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl)
+{
+	int ret;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl);
+
+	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, *ctrl,
+				 !(*ctrl & A5PSW_LK_ADDR_CTRL_BUSY),
+				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
+	if (ret)
+		dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n");
+
+	return ret;
+}
+
+static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
+{
+	u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port);
+
+	spin_lock(&a5psw->lk_lock);
+	a5psw_lk_execute_ctrl(a5psw, &ctrl);
+	spin_unlock(&a5psw->lk_lock);
+}
+
+static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
+				     bool authorize)
+{
+	u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port));
+
+	if (authorize)
+		reg |= A5PSW_AUTH_PORT_AUTHORIZED;
+	else
+		reg &= ~A5PSW_AUTH_PORT_AUTHORIZED;
+
+	a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg);
+}
+
+static void a5psw_port_disable(struct dsa_switch *ds, int port)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	a5psw_port_authorize_set(a5psw, port, false);
+	a5psw_port_enable_set(a5psw, port, false);
+}
+
+static int a5psw_port_enable(struct dsa_switch *ds, int port,
+			     struct phy_device *phy)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	a5psw_port_authorize_set(a5psw, port, true);
+	a5psw_port_enable_set(a5psw, port, true);
+
+	return 0;
+}
+
+static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN;
+	a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
+
+	return 0;
+}
+
+static int a5psw_port_max_mtu(struct dsa_switch *ds, int port)
+{
+	return A5PSW_MAX_MTU;
+}
+
+static void a5psw_phylink_get_caps(struct dsa_switch *ds, int port,
+				   struct phylink_config *config)
+{
+	unsigned long *intf = config->supported_interfaces;
+
+	config->mac_capabilities = MAC_1000FD;
+
+	if (dsa_is_cpu_port(ds, port)) {
+		/* GMII is used internally and GMAC2 is connected to the switch
+		 * using 1000Mbps Full-Duplex mode only (cf ethernet manual)
+		 */
+		__set_bit(PHY_INTERFACE_MODE_GMII, intf);
+	} else {
+		config->mac_capabilities |= MAC_100 | MAC_10;
+		phy_interface_set_rgmii(intf);
+		__set_bit(PHY_INTERFACE_MODE_RMII, intf);
+		__set_bit(PHY_INTERFACE_MODE_MII, intf);
+	}
+}
+
+static struct phylink_pcs *
+a5psw_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
+			     phy_interface_t interface)
+{
+	struct dsa_port *dp = dsa_to_port(ds, port);
+	struct a5psw *a5psw = ds->priv;
+
+	if (!dsa_port_is_cpu(dp) && a5psw->pcs[port])
+		return a5psw->pcs[port];
+
+	return NULL;
+}
+
+static void a5psw_phylink_mac_link_down(struct dsa_switch *ds, int port,
+					unsigned int mode,
+					phy_interface_t interface)
+{
+	struct a5psw *a5psw = ds->priv;
+	u32 cmd_cfg;
+
+	cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port));
+	cmd_cfg &= ~(A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA);
+	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
+}
+
+static void a5psw_phylink_mac_link_up(struct dsa_switch *ds, int port,
+				      unsigned int mode,
+				      phy_interface_t interface,
+				      struct phy_device *phydev, int speed,
+				      int duplex, bool tx_pause, bool rx_pause)
+{
+	u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA |
+		      A5PSW_CMD_CFG_TX_CRC_APPEND;
+	struct a5psw *a5psw = ds->priv;
+
+	if (speed == SPEED_1000)
+		cmd_cfg |= A5PSW_CMD_CFG_ETH_SPEED;
+
+	if (duplex == DUPLEX_HALF)
+		cmd_cfg |= A5PSW_CMD_CFG_HD_ENA;
+
+	cmd_cfg |= A5PSW_CMD_CFG_CNTL_FRM_ENA;
+
+	if (!rx_pause)
+		cmd_cfg &= ~A5PSW_CMD_CFG_PAUSE_IGNORE;
+
+	a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
+}
+
+static int a5psw_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
+{
+	struct a5psw *a5psw = ds->priv;
+	unsigned long rate;
+	u64 max, tmp;
+	u32 agetime;
+
+	rate = clk_get_rate(a5psw->clk);
+	max = div64_ul(((u64)A5PSW_LK_AGETIME_MASK * A5PSW_TABLE_ENTRIES * 1024),
+		       rate) * 1000;
+	if (msecs > max)
+		return -EINVAL;
+
+	tmp = div_u64(rate, MSEC_PER_SEC);
+	agetime = div_u64(msecs * tmp, 1024 * A5PSW_TABLE_ENTRIES);
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime);
+
+	return 0;
+}
+
+static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port,
+					  bool set)
+{
+	u8 offsets[] = {A5PSW_UCAST_DEF_MASK, A5PSW_BCAST_DEF_MASK,
+			A5PSW_MCAST_DEF_MASK};
+	int i;
+
+	if (set)
+		a5psw->bridged_ports |= BIT(port);
+	else
+		a5psw->bridged_ports &= ~BIT(port);
+
+	for (i = 0; i < ARRAY_SIZE(offsets); i++)
+		a5psw_reg_writel(a5psw, offsets[i], a5psw->bridged_ports);
+}
+
+static int a5psw_port_bridge_join(struct dsa_switch *ds, int port,
+				  struct dsa_bridge bridge,
+				  bool *tx_fwd_offload,
+				  struct netlink_ext_ack *extack)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	/* We only support 1 bridge device */
+	if (a5psw->br_dev && bridge.dev != a5psw->br_dev) {
+		NL_SET_ERR_MSG_MOD(extack,
+				   "Forwarding offload supported for a single bridge");
+		return -EOPNOTSUPP;
+	}
+
+	a5psw->br_dev = bridge.dev;
+	a5psw_flooding_set_resolution(a5psw, port, true);
+	a5psw_port_mgmtfwd_set(a5psw, port, false);
+
+	return 0;
+}
+
+static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port,
+				    struct dsa_bridge bridge)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	a5psw_flooding_set_resolution(a5psw, port, false);
+	a5psw_port_mgmtfwd_set(a5psw, port, true);
+
+	/* No more ports bridged */
+	if (a5psw->bridged_ports == BIT(A5PSW_CPU_PORT))
+		a5psw->br_dev = NULL;
+}
+
+static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
+{
+	u32 mask = A5PSW_INPUT_LEARN_DIS(port) | A5PSW_INPUT_LEARN_BLOCK(port);
+	struct a5psw *a5psw = ds->priv;
+	u32 reg = 0;
+
+	switch (state) {
+	case BR_STATE_DISABLED:
+	case BR_STATE_BLOCKING:
+		reg |= A5PSW_INPUT_LEARN_DIS(port);
+		reg |= A5PSW_INPUT_LEARN_BLOCK(port);
+		break;
+	case BR_STATE_LISTENING:
+		reg |= A5PSW_INPUT_LEARN_DIS(port);
+		break;
+	case BR_STATE_LEARNING:
+		reg |= A5PSW_INPUT_LEARN_BLOCK(port);
+		break;
+	case BR_STATE_FORWARDING:
+	default:
+		break;
+	}
+
+	a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
+}
+
+static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
+{
+	struct a5psw *a5psw = ds->priv;
+
+	a5psw_port_fdb_flush(a5psw, port);
+}
+
+static int a5psw_setup(struct dsa_switch *ds)
+{
+	struct a5psw *a5psw = ds->priv;
+	int port, vlan, ret;
+	struct dsa_port *dp;
+	u32 reg;
+
+	/* Validate that there is only 1 CPU port with index A5PSW_CPU_PORT */
+	dsa_switch_for_each_cpu_port(dp, ds) {
+		if (dp->index != A5PSW_CPU_PORT) {
+			dev_err(a5psw->dev, "Invalid CPU port\n");
+			return -EINVAL;
+		}
+	}
+
+	/* Configure management port */
+	reg = A5PSW_CPU_PORT | A5PSW_MGMT_CFG_DISCARD;
+	a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg);
+
+	/* Set pattern 0 to forward all frame to mgmt port */
+	a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(A5PSW_PATTERN_MGMTFWD),
+			 A5PSW_PATTERN_CTRL_MGMTFWD);
+
+	/* Enable port tagging */
+	reg = FIELD_PREP(A5PSW_MGMT_TAG_CFG_TAGFIELD, ETH_P_DSA_A5PSW);
+	reg |= A5PSW_MGMT_TAG_CFG_ENABLE | A5PSW_MGMT_TAG_CFG_ALL_FRAMES;
+	a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg);
+
+	/* Enable normal switch operation */
+	reg = A5PSW_LK_ADDR_CTRL_BLOCKING | A5PSW_LK_ADDR_CTRL_LEARNING |
+	      A5PSW_LK_ADDR_CTRL_AGEING | A5PSW_LK_ADDR_CTRL_ALLOW_MIGR |
+	      A5PSW_LK_ADDR_CTRL_CLEAR_TABLE;
+	a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg);
+
+	ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, reg,
+				 !(reg & A5PSW_LK_ADDR_CTRL_CLEAR_TABLE),
+				 A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
+	if (ret) {
+		dev_err(a5psw->dev, "Failed to clear lookup table\n");
+		return ret;
+	}
+
+	/* Reset learn count to 0 */
+	reg = A5PSW_LK_LEARNCOUNT_MODE_SET;
+	a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
+
+	/* Clear VLAN resource table */
+	reg = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_WR_TAGMASK;
+	for (vlan = 0; vlan < A5PSW_VLAN_COUNT; vlan++)
+		a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg);
+
+	/* Reset all ports */
+	dsa_switch_for_each_port(dp, ds) {
+		port = dp->index;
+
+		/* Reset the port */
+		a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port),
+				 A5PSW_CMD_CFG_SW_RESET);
+
+		/* Enable only CPU port */
+		a5psw_port_enable_set(a5psw, port, dsa_port_is_cpu(dp));
+
+		if (dsa_port_is_unused(dp))
+			continue;
+
+		/* Enable egress flooding for CPU port */
+		if (dsa_port_is_cpu(dp))
+			a5psw_flooding_set_resolution(a5psw, port, true);
+
+		/* Enable management forward only for user ports */
+		if (dsa_port_is_user(dp))
+			a5psw_port_mgmtfwd_set(a5psw, port, true);
+	}
+
+	return 0;
+}
+
+static const struct dsa_switch_ops a5psw_switch_ops = {
+	.get_tag_protocol = a5psw_get_tag_protocol,
+	.setup = a5psw_setup,
+	.port_disable = a5psw_port_disable,
+	.port_enable = a5psw_port_enable,
+	.phylink_get_caps = a5psw_phylink_get_caps,
+	.phylink_mac_select_pcs = a5psw_phylink_mac_select_pcs,
+	.phylink_mac_link_down = a5psw_phylink_mac_link_down,
+	.phylink_mac_link_up = a5psw_phylink_mac_link_up,
+	.port_change_mtu = a5psw_port_change_mtu,
+	.port_max_mtu = a5psw_port_max_mtu,
+	.set_ageing_time = a5psw_set_ageing_time,
+	.port_bridge_join = a5psw_port_bridge_join,
+	.port_bridge_leave = a5psw_port_bridge_leave,
+	.port_stp_state_set = a5psw_port_stp_state_set,
+	.port_fast_age = a5psw_port_fast_age,
+};
+
+static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
+{
+	u32 status;
+	int err;
+
+	err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, status,
+				 !(status & A5PSW_MDIO_CFG_STATUS_BUSY), 10,
+				 1000 * USEC_PER_MSEC);
+	if (err)
+		dev_err(a5psw->dev, "MDIO command timeout\n");
+
+	return err;
+}
+
+static int a5psw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
+{
+	struct a5psw *a5psw = bus->priv;
+	u32 cmd, status;
+	int ret;
+
+	if (phy_reg & MII_ADDR_C45)
+		return -EOPNOTSUPP;
+
+	cmd = A5PSW_MDIO_COMMAND_READ;
+	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
+	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
+
+	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
+
+	ret = a5psw_mdio_wait_busy(a5psw);
+	if (ret)
+		return ret;
+
+	ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK;
+
+	status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS);
+	if (status & A5PSW_MDIO_CFG_STATUS_READERR)
+		return -EIO;
+
+	return ret;
+}
+
+static int a5psw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
+			    u16 phy_data)
+{
+	struct a5psw *a5psw = bus->priv;
+	u32 cmd;
+
+	if (phy_reg & MII_ADDR_C45)
+		return -EOPNOTSUPP;
+
+	cmd = FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
+	cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
+
+	a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
+	a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data);
+
+	return a5psw_mdio_wait_busy(a5psw);
+}
+
+static int a5psw_mdio_config(struct a5psw *a5psw, u32 mdio_freq)
+{
+	unsigned long rate;
+	unsigned long div;
+	u32 cfgstatus;
+
+	rate = clk_get_rate(a5psw->hclk);
+	div = ((rate / mdio_freq) / 2);
+	if (div > FIELD_MAX(A5PSW_MDIO_CFG_STATUS_CLKDIV) ||
+	    div < A5PSW_MDIO_CLK_DIV_MIN) {
+		dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div);
+		return -ERANGE;
+	}
+
+	cfgstatus = FIELD_PREP(A5PSW_MDIO_CFG_STATUS_CLKDIV, div);
+
+	a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus);
+
+	return 0;
+}
+
+static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)
+{
+	struct device *dev = a5psw->dev;
+	struct mii_bus *bus;
+	u32 mdio_freq;
+	int ret;
+
+	if (of_property_read_u32(node, "clock-frequency", &mdio_freq))
+		mdio_freq = A5PSW_MDIO_DEF_FREQ;
+
+	ret = a5psw_mdio_config(a5psw, mdio_freq);
+	if (ret)
+		return ret;
+
+	bus = devm_mdiobus_alloc(dev);
+	if (!bus)
+		return -ENOMEM;
+
+	bus->name = "a5psw_mdio";
+	bus->read = a5psw_mdio_read;
+	bus->write = a5psw_mdio_write;
+	bus->priv = a5psw;
+	bus->parent = dev;
+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
+
+	a5psw->mii_bus = bus;
+
+	return devm_of_mdiobus_register(dev, bus, node);
+}
+
+static void a5psw_pcs_free(struct a5psw *a5psw)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) {
+		if (a5psw->pcs[i])
+			miic_destroy(a5psw->pcs[i]);
+	}
+}
+
+static int a5psw_pcs_get(struct a5psw *a5psw)
+{
+	struct device_node *ports, *port, *pcs_node;
+	struct phylink_pcs *pcs;
+	int ret;
+	u32 reg;
+
+	ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
+	if (!ports)
+		return -EINVAL;
+
+	for_each_available_child_of_node(ports, port) {
+		pcs_node = of_parse_phandle(port, "pcs-handle", 0);
+		if (!pcs_node)
+			continue;
+
+		if (of_property_read_u32(port, "reg", &reg)) {
+			ret = -EINVAL;
+			goto free_pcs;
+		}
+
+		if (reg >= ARRAY_SIZE(a5psw->pcs)) {
+			ret = -ENODEV;
+			goto free_pcs;
+		}
+
+		pcs = miic_create(pcs_node);
+		if (IS_ERR(pcs)) {
+			dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
+				reg);
+			ret = PTR_ERR(pcs);
+			goto free_pcs;
+		}
+
+		a5psw->pcs[reg] = pcs;
+	}
+	of_node_put(ports);
+
+	return 0;
+
+free_pcs:
+	a5psw_pcs_free(a5psw);
+	of_node_put(ports);
+
+	return ret;
+}
+
+static int a5psw_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *mdio;
+	struct dsa_switch *ds;
+	struct a5psw *a5psw;
+	int ret;
+
+	a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL);
+	if (!a5psw)
+		return -ENOMEM;
+
+	a5psw->dev = dev;
+	spin_lock_init(&a5psw->lk_lock);
+	spin_lock_init(&a5psw->reg_lock);
+	a5psw->base = devm_platform_ioremap_resource(pdev, 0);
+	if (!a5psw->base)
+		return -EINVAL;
+
+	ret = a5psw_pcs_get(a5psw);
+	if (ret)
+		return ret;
+
+	a5psw->hclk = devm_clk_get(dev, "hclk");
+	if (IS_ERR(a5psw->hclk)) {
+		dev_err(dev, "failed get hclk clock\n");
+		ret = PTR_ERR(a5psw->hclk);
+		goto free_pcs;
+	}
+
+	a5psw->clk = devm_clk_get(dev, "clk");
+	if (IS_ERR(a5psw->clk)) {
+		dev_err(dev, "failed get clk_switch clock\n");
+		ret = PTR_ERR(a5psw->clk);
+		goto free_pcs;
+	}
+
+	ret = clk_prepare_enable(a5psw->clk);
+	if (ret)
+		goto free_pcs;
+
+	ret = clk_prepare_enable(a5psw->hclk);
+	if (ret)
+		goto clk_disable;
+
+	mdio = of_get_child_by_name(dev->of_node, "mdio");
+	if (of_device_is_available(mdio)) {
+		ret = a5psw_probe_mdio(a5psw, mdio);
+		if (ret) {
+			of_node_put(mdio);
+			dev_err(&pdev->dev, "Failed to register MDIO: %d\n",
+				ret);
+			goto hclk_disable;
+		}
+	}
+
+	of_node_put(mdio);
+
+	ds = &a5psw->ds;
+	ds->dev = &pdev->dev;
+	ds->num_ports = A5PSW_PORTS_NUM;
+	ds->ops = &a5psw_switch_ops;
+	ds->priv = a5psw;
+
+	ret = dsa_register_switch(ds);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to register DSA switch: %d\n", ret);
+		goto hclk_disable;
+	}
+
+	return 0;
+
+hclk_disable:
+	clk_disable_unprepare(a5psw->hclk);
+clk_disable:
+	clk_disable_unprepare(a5psw->clk);
+free_pcs:
+	a5psw_pcs_free(a5psw);
+
+	return ret;
+}
+
+static int a5psw_remove(struct platform_device *pdev)
+{
+	struct a5psw *a5psw = platform_get_drvdata(pdev);
+
+	if (!a5psw)
+		return 0;
+
+	dsa_unregister_switch(&a5psw->ds);
+	a5psw_pcs_free(a5psw);
+	clk_disable_unprepare(a5psw->hclk);
+	clk_disable_unprepare(a5psw->clk);
+
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static void a5psw_shutdown(struct platform_device *pdev)
+{
+	struct a5psw *a5psw = platform_get_drvdata(pdev);
+
+	if (!a5psw)
+		return;
+
+	dsa_switch_shutdown(&a5psw->ds);
+
+	platform_set_drvdata(pdev, NULL);
+}
+
+static const struct of_device_id a5psw_of_mtable[] = {
+	{ .compatible = "renesas,rzn1-a5psw", },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, a5psw_of_mtable);
+
+static struct platform_driver a5psw_driver = {
+	.driver = {
+		.name	 = "rzn1_a5psw",
+		.of_match_table = of_match_ptr(a5psw_of_mtable),
+	},
+	.probe = a5psw_probe,
+	.remove = a5psw_remove,
+	.shutdown = a5psw_shutdown,
+};
+module_platform_driver(a5psw_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Renesas RZ/N1 Advanced 5-port Switch driver");
+MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");
diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
new file mode 100644
index 000000000000..306cab55db24
--- /dev/null
+++ b/drivers/net/dsa/rzn1_a5psw.h
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2022 Schneider Electric
+ *
+ * Clément Léger <clement.leger@bootlin.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/platform_device.h>
+#include <linux/pcs-rzn1-miic.h>
+#include <net/dsa.h>
+
+#define A5PSW_REVISION			0x0
+#define A5PSW_PORT_OFFSET(port)		(0x400 * (port))
+
+#define A5PSW_PORT_ENA			0x8
+#define A5PSW_PORT_ENA_RX_SHIFT		16
+#define A5PSW_PORT_ENA_TX_RX(port)	(BIT((port) + A5PSW_PORT_ENA_RX_SHIFT) | \
+					 BIT(port))
+#define A5PSW_UCAST_DEF_MASK		0xC
+
+#define A5PSW_VLAN_VERIFY		0x10
+#define A5PSW_VLAN_VERI_SHIFT		0
+#define A5PSW_VLAN_DISC_SHIFT		16
+
+#define A5PSW_BCAST_DEF_MASK		0x14
+#define A5PSW_MCAST_DEF_MASK		0x18
+
+#define A5PSW_INPUT_LEARN		0x1C
+#define A5PSW_INPUT_LEARN_DIS(p)	BIT((p) + 16)
+#define A5PSW_INPUT_LEARN_BLOCK(p)	BIT(p)
+
+#define A5PSW_MGMT_CFG			0x20
+#define A5PSW_MGMT_CFG_DISCARD		BIT(7)
+
+#define A5PSW_MODE_CFG			0x24
+#define A5PSW_MODE_STATS_RESET		BIT(31)
+
+#define A5PSW_VLAN_IN_MODE		0x28
+#define A5PSW_VLAN_IN_MODE_PORT_SHIFT(port)	((port) * 2)
+#define A5PSW_VLAN_IN_MODE_PORT(port)		(GENMASK(1, 0) << \
+					A5PSW_VLAN_IN_MODE_PORT_SHIFT(port))
+#define A5PSW_VLAN_IN_MODE_SINGLE_PASSTHROUGH	0x0
+#define A5PSW_VLAN_IN_MODE_SINGLE_REPLACE	0x1
+#define A5PSW_VLAN_IN_MODE_TAG_ALWAYS		0x2
+
+#define A5PSW_VLAN_OUT_MODE		0x2C
+#define A5PSW_VLAN_OUT_MODE_PORT(port)	(GENMASK(1, 0) << ((port) * 2))
+#define A5PSW_VLAN_OUT_MODE_DIS		0x0
+#define A5PSW_VLAN_OUT_MODE_STRIP	0x1
+#define A5PSW_VLAN_OUT_MODE_TAG_THROUGH	0x2
+#define A5PSW_VLAN_OUT_MODE_TRANSPARENT	0x3
+
+#define A5PSW_VLAN_IN_MODE_ENA		0x30
+#define A5PSW_VLAN_TAG_ID		0x34
+
+#define A5PSW_SYSTEM_TAGINFO(port)	(0x200 + A5PSW_PORT_OFFSET(port))
+
+#define A5PSW_AUTH_PORT(port)		(0x240 + 4 * (port))
+#define A5PSW_AUTH_PORT_AUTHORIZED	BIT(0)
+
+#define A5PSW_VLAN_RES(entry)		(0x280 + 4 * (entry))
+#define A5PSW_VLAN_RES_WR_PORTMASK	BIT(30)
+#define A5PSW_VLAN_RES_WR_TAGMASK	BIT(29)
+#define A5PSW_VLAN_RES_RD_TAGMASK	BIT(28)
+#define A5PSW_VLAN_RES_ID		GENMASK(16, 5)
+#define A5PSW_VLAN_RES_PORTMASK		GENMASK(4, 0)
+
+#define A5PSW_RXMATCH_CONFIG(port)	(0x3e80 + 4 * (port))
+#define A5PSW_RXMATCH_CONFIG_PATTERN(p)	BIT(p)
+
+#define A5PSW_PATTERN_CTRL(p)		(0x3eb0 + 4  * (p))
+#define A5PSW_PATTERN_CTRL_MGMTFWD	BIT(1)
+
+#define A5PSW_LK_CTRL		0x400
+#define A5PSW_LK_ADDR_CTRL_BLOCKING	BIT(0)
+#define A5PSW_LK_ADDR_CTRL_LEARNING	BIT(1)
+#define A5PSW_LK_ADDR_CTRL_AGEING	BIT(2)
+#define A5PSW_LK_ADDR_CTRL_ALLOW_MIGR	BIT(3)
+#define A5PSW_LK_ADDR_CTRL_CLEAR_TABLE	BIT(6)
+
+#define A5PSW_LK_ADDR_CTRL		0x408
+#define A5PSW_LK_ADDR_CTRL_BUSY		BIT(31)
+#define A5PSW_LK_ADDR_CTRL_DELETE_PORT	BIT(30)
+#define A5PSW_LK_ADDR_CTRL_CLEAR	BIT(29)
+#define A5PSW_LK_ADDR_CTRL_LOOKUP	BIT(28)
+#define A5PSW_LK_ADDR_CTRL_WAIT		BIT(27)
+#define A5PSW_LK_ADDR_CTRL_READ		BIT(26)
+#define A5PSW_LK_ADDR_CTRL_WRITE	BIT(25)
+#define A5PSW_LK_ADDR_CTRL_ADDRESS	GENMASK(12, 0)
+
+#define A5PSW_LK_DATA_LO		0x40C
+#define A5PSW_LK_DATA_HI		0x410
+#define A5PSW_LK_DATA_HI_VALID		BIT(16)
+#define A5PSW_LK_DATA_HI_PORT		BIT(16)
+
+#define A5PSW_LK_LEARNCOUNT		0x418
+#define A5PSW_LK_LEARNCOUNT_COUNT	GENMASK(13, 0)
+#define A5PSW_LK_LEARNCOUNT_MODE	GENMASK(31, 30)
+#define A5PSW_LK_LEARNCOUNT_MODE_SET	0x0
+#define A5PSW_LK_LEARNCOUNT_MODE_INC	0x1
+#define A5PSW_LK_LEARNCOUNT_MODE_DEC	0x2
+
+#define A5PSW_MGMT_TAG_CFG		0x480
+#define A5PSW_MGMT_TAG_CFG_TAGFIELD	GENMASK(31, 16)
+#define A5PSW_MGMT_TAG_CFG_ALL_FRAMES	BIT(1)
+#define A5PSW_MGMT_TAG_CFG_ENABLE	BIT(0)
+
+#define A5PSW_LK_AGETIME		0x41C
+#define A5PSW_LK_AGETIME_MASK		GENMASK(23, 0)
+
+#define A5PSW_MDIO_CFG_STATUS		0x700
+#define A5PSW_MDIO_CFG_STATUS_CLKDIV	GENMASK(15, 7)
+#define A5PSW_MDIO_CFG_STATUS_READERR	BIT(1)
+#define A5PSW_MDIO_CFG_STATUS_BUSY	BIT(0)
+
+#define A5PSW_MDIO_COMMAND		0x704
+/* Register is named TRAININIT in datasheet and should be set when reading */
+#define A5PSW_MDIO_COMMAND_READ		BIT(15)
+#define A5PSW_MDIO_COMMAND_PHY_ADDR	GENMASK(9, 5)
+#define A5PSW_MDIO_COMMAND_REG_ADDR	GENMASK(4, 0)
+
+#define A5PSW_MDIO_DATA			0x708
+#define A5PSW_MDIO_DATA_MASK		GENMASK(15, 0)
+
+#define A5PSW_CMD_CFG(port)		(0x808 + A5PSW_PORT_OFFSET(port))
+#define A5PSW_CMD_CFG_CNTL_FRM_ENA	BIT(23)
+#define A5PSW_CMD_CFG_SW_RESET		BIT(13)
+#define A5PSW_CMD_CFG_TX_CRC_APPEND	BIT(11)
+#define A5PSW_CMD_CFG_HD_ENA		BIT(10)
+#define A5PSW_CMD_CFG_PAUSE_IGNORE	BIT(8)
+#define A5PSW_CMD_CFG_CRC_FWD		BIT(6)
+#define A5PSW_CMD_CFG_ETH_SPEED		BIT(3)
+#define A5PSW_CMD_CFG_RX_ENA		BIT(1)
+#define A5PSW_CMD_CFG_TX_ENA		BIT(0)
+
+#define A5PSW_FRM_LENGTH(port)		(0x814 + A5PSW_PORT_OFFSET(port))
+#define A5PSW_FRM_LENGTH_MASK		GENMASK(13, 0)
+
+#define A5PSW_STATUS(port)		(0x840 + A5PSW_PORT_OFFSET(port))
+
+#define A5PSW_STATS_HIWORD		0x900
+
+#define A5PSW_DUMMY_WORKAROUND		0x5000
+
+#define A5PSW_VLAN_TAG(prio, id)	(((prio) << 12) | (id))
+#define A5PSW_PORTS_NUM			5
+#define A5PSW_CPU_PORT			(A5PSW_PORTS_NUM - 1)
+#define A5PSW_MDIO_DEF_FREQ		2500000
+#define A5PSW_MDIO_TIMEOUT		100
+#define A5PSW_JUMBO_LEN			(10 * SZ_1K)
+#define A5PSW_MDIO_CLK_DIV_MIN		5
+#define A5PSW_TAG_LEN			8
+#define A5PSW_VLAN_COUNT		32
+
+/* Ensure enough space for 2 VLAN tags */
+#define A5PSW_EXTRA_MTU_LEN		(A5PSW_TAG_LEN + 8)
+#define A5PSW_MAX_MTU			(A5PSW_JUMBO_LEN - A5PSW_EXTRA_MTU_LEN)
+
+#define A5PSW_PATTERN_MGMTFWD		0
+
+#define A5PSW_LK_BUSY_USEC_POLL		10
+#define A5PSW_CTRL_TIMEOUT		1000
+#define A5PSW_TABLE_ENTRIES		8192
+
+/**
+ * struct a5psw - switch struct
+ * @base: Base address of the switch
+ * @hclk: hclk_switch clock
+ * @clk: clk_switch clock
+ * @dev: Device associated to the switch
+ * @mii_bus: MDIO bus struct
+ * @mdio_freq: MDIO bus frequency requested
+ * @pcs: Array of PCS connected to the switch ports (not for the CPU)
+ * @ds: DSA switch struct
+ * @lk_lock: Lock for the lookup table
+ * @reg_lock: Lock for register read-modify-write operation
+ * @bridged_ports: Mask of ports that are bridged and should be flooded
+ * @br_dev: Bridge net device
+ */
+struct a5psw {
+	void __iomem *base;
+	struct clk *hclk;
+	struct clk *clk;
+	struct device *dev;
+	struct mii_bus	*mii_bus;
+	struct phylink_pcs *pcs[A5PSW_PORTS_NUM - 1];
+	struct dsa_switch ds;
+	spinlock_t lk_lock;
+	spinlock_t reg_lock;
+	u32 bridged_ports;
+	struct net_device *br_dev;
+};
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (6 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-19 18:24   ` Vladimir Oltean
  2022-05-19 15:31 ` [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support Clément Léger
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add statistics support to the rzn1-a5psw driver by implementing the
following dsa_switch_ops callbacks:
- get_sset_count()
- get_strings()
- get_ethtool_stats()
- get_eth_mac_stats()
- get_eth_ctrl_stats()
- get_rmon_stats()

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/dsa/rzn1_a5psw.c | 174 +++++++++++++++++++++++++++++++++++
 drivers/net/dsa/rzn1_a5psw.h |  46 ++++++++-
 2 files changed, 219 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
index 3c5e905e3a0f..3ef68bf1c8c6 100644
--- a/drivers/net/dsa/rzn1_a5psw.c
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -17,6 +17,57 @@
 
 #include "rzn1_a5psw.h"
 
+struct a5psw_stats {
+	u16 offset;
+	const char name[ETH_GSTRING_LEN];
+};
+
+#define STAT_DESC(_offset) {	\
+	.offset = A5PSW_##_offset,	\
+	.name = __stringify(_offset),	\
+}
+
+static const struct a5psw_stats a5psw_stats[] = {
+	STAT_DESC(aFramesTransmittedOK),
+	STAT_DESC(aFramesReceivedOK),
+	STAT_DESC(aFrameCheckSequenceErrors),
+	STAT_DESC(aAlignmentErrors),
+	STAT_DESC(aOctetsTransmittedOK),
+	STAT_DESC(aOctetsReceivedOK),
+	STAT_DESC(aTxPAUSEMACCtrlFrames),
+	STAT_DESC(aRxPAUSEMACCtrlFrames),
+	STAT_DESC(ifInErrors),
+	STAT_DESC(ifOutErrors),
+	STAT_DESC(ifInUcastPkts),
+	STAT_DESC(ifInMulticastPkts),
+	STAT_DESC(ifInBroadcastPkts),
+	STAT_DESC(ifOutDiscards),
+	STAT_DESC(ifOutUcastPkts),
+	STAT_DESC(ifOutMulticastPkts),
+	STAT_DESC(ifOutBroadcastPkts),
+	STAT_DESC(etherStatsDropEvents),
+	STAT_DESC(etherStatsOctets),
+	STAT_DESC(etherStatsPkts),
+	STAT_DESC(etherStatsUndersizePkts),
+	STAT_DESC(etherStatsOversizePkts),
+	STAT_DESC(etherStatsPkts64Octets),
+	STAT_DESC(etherStatsPkts65to127Octets),
+	STAT_DESC(etherStatsPkts128to255Octets),
+	STAT_DESC(etherStatsPkts256to511Octets),
+	STAT_DESC(etherStatsPkts1024to1518Octets),
+	STAT_DESC(etherStatsPkts1519toXOctets),
+	STAT_DESC(etherStatsJabbers),
+	STAT_DESC(etherStatsFragments),
+	STAT_DESC(VLANReceived),
+	STAT_DESC(VLANTransmitted),
+	STAT_DESC(aDeferred),
+	STAT_DESC(aMultipleCollisions),
+	STAT_DESC(aSingleCollisions),
+	STAT_DESC(aLateCollisions),
+	STAT_DESC(aExcessiveCollisions),
+	STAT_DESC(aCarrierSenseErrors),
+};
+
 static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
 {
 	writel(value, a5psw->base + offset);
@@ -324,6 +375,123 @@ static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
 	a5psw_port_fdb_flush(a5psw, port);
 }
 
+static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
+{
+	u32 reg_lo, reg_hi;
+
+	reg_lo = a5psw_reg_readl(a5psw, offset + A5PSW_PORT_OFFSET(port));
+	/* A5PSW_STATS_HIWORD is latched on stat read */
+	reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD);
+
+	return ((u64)reg_hi << 32) | reg_lo;
+}
+
+static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset,
+			      uint8_t *data)
+{
+	unsigned int u;
+
+	if (stringset != ETH_SS_STATS)
+		return;
+
+	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++) {
+		memcpy(data + u * ETH_GSTRING_LEN, a5psw_stats[u].name,
+		       ETH_GSTRING_LEN);
+	}
+}
+
+static void a5psw_get_ethtool_stats(struct dsa_switch *ds, int port,
+				    uint64_t *data)
+{
+	struct a5psw *a5psw = ds->priv;
+	unsigned int u;
+
+	for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++)
+		data[u] = a5psw_read_stat(a5psw, a5psw_stats[u].offset, port);
+}
+
+static int a5psw_get_sset_count(struct dsa_switch *ds, int port, int sset)
+{
+	if (sset != ETH_SS_STATS)
+		return 0;
+
+	return ARRAY_SIZE(a5psw_stats);
+}
+
+static void a5psw_get_eth_mac_stats(struct dsa_switch *ds, int port,
+				    struct ethtool_eth_mac_stats *mac_stats)
+{
+	struct a5psw *a5psw = ds->priv;
+
+#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
+	mac_stats->FramesTransmittedOK = RD(aFramesTransmittedOK);
+	mac_stats->SingleCollisionFrames = RD(aSingleCollisions);
+	mac_stats->MultipleCollisionFrames = RD(aMultipleCollisions);
+	mac_stats->FramesReceivedOK = RD(aFramesReceivedOK);
+	mac_stats->FrameCheckSequenceErrors = RD(aFrameCheckSequenceErrors);
+	mac_stats->AlignmentErrors = RD(aAlignmentErrors);
+	mac_stats->OctetsTransmittedOK = RD(aOctetsTransmittedOK);
+	mac_stats->FramesWithDeferredXmissions = RD(aDeferred);
+	mac_stats->LateCollisions = RD(aLateCollisions);
+	mac_stats->FramesAbortedDueToXSColls = RD(aExcessiveCollisions);
+	mac_stats->FramesLostDueToIntMACXmitError = RD(ifOutErrors);
+	mac_stats->CarrierSenseErrors = RD(aCarrierSenseErrors);
+	mac_stats->OctetsReceivedOK = RD(aOctetsReceivedOK);
+	mac_stats->FramesLostDueToIntMACRcvError = RD(ifInErrors);
+	mac_stats->MulticastFramesXmittedOK = RD(ifOutMulticastPkts);
+	mac_stats->BroadcastFramesXmittedOK = RD(ifOutBroadcastPkts);
+	mac_stats->FramesWithExcessiveDeferral = RD(aDeferred);
+	mac_stats->MulticastFramesReceivedOK = RD(ifInMulticastPkts);
+	mac_stats->BroadcastFramesReceivedOK = RD(ifInBroadcastPkts);
+#undef RD
+}
+
+static const struct ethtool_rmon_hist_range a5psw_rmon_ranges[] = {
+	{ 0, 64 },
+	{ 65, 127 },
+	{ 128, 255 },
+	{ 256, 511 },
+	{ 512, 1023 },
+	{ 1024, 1518 },
+	{ 1519, A5PSW_MAX_MTU },
+	{}
+};
+
+static void a5psw_get_rmon_stats(struct dsa_switch *ds, int port,
+				 struct ethtool_rmon_stats *rmon_stats,
+				 const struct ethtool_rmon_hist_range **ranges)
+{
+	struct a5psw *a5psw = ds->priv;
+
+#define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
+	rmon_stats->undersize_pkts = RD(etherStatsUndersizePkts);
+	rmon_stats->oversize_pkts = RD(etherStatsOversizePkts);
+	rmon_stats->fragments = RD(etherStatsFragments);
+	rmon_stats->jabbers = RD(etherStatsJabbers);
+	rmon_stats->hist[0] = RD(etherStatsPkts64Octets);
+	rmon_stats->hist[1] = RD(etherStatsPkts65to127Octets);
+	rmon_stats->hist[2] = RD(etherStatsPkts128to255Octets);
+	rmon_stats->hist[3] = RD(etherStatsPkts256to511Octets);
+	rmon_stats->hist[4] = RD(etherStatsPkts512to1023Octets);
+	rmon_stats->hist[5] = RD(etherStatsPkts1024to1518Octets);
+	rmon_stats->hist[6] = RD(etherStatsPkts1519toXOctets);
+#undef RD
+
+	*ranges = a5psw_rmon_ranges;
+}
+
+static void a5psw_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
+				     struct ethtool_eth_ctrl_stats *ctrl_stats)
+{
+	struct a5psw *a5psw = ds->priv;
+	u64 stat;
+
+	stat = a5psw_read_stat(a5psw, A5PSW_aTxPAUSEMACCtrlFrames, port);
+	ctrl_stats->MACControlFramesTransmitted = stat;
+	stat = a5psw_read_stat(a5psw, A5PSW_aRxPAUSEMACCtrlFrames, port);
+	ctrl_stats->MACControlFramesReceived = stat;
+}
+
 static int a5psw_setup(struct dsa_switch *ds)
 {
 	struct a5psw *a5psw = ds->priv;
@@ -412,6 +580,12 @@ static const struct dsa_switch_ops a5psw_switch_ops = {
 	.phylink_mac_link_up = a5psw_phylink_mac_link_up,
 	.port_change_mtu = a5psw_port_change_mtu,
 	.port_max_mtu = a5psw_port_max_mtu,
+	.get_sset_count = a5psw_get_sset_count,
+	.get_strings = a5psw_get_strings,
+	.get_ethtool_stats = a5psw_get_ethtool_stats,
+	.get_eth_mac_stats = a5psw_get_eth_mac_stats,
+	.get_eth_ctrl_stats = a5psw_get_eth_ctrl_stats,
+	.get_rmon_stats = a5psw_get_rmon_stats,
 	.set_ageing_time = a5psw_set_ageing_time,
 	.port_bridge_join = a5psw_port_bridge_join,
 	.port_bridge_leave = a5psw_port_bridge_leave,
diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
index 306cab55db24..649165d37fde 100644
--- a/drivers/net/dsa/rzn1_a5psw.h
+++ b/drivers/net/dsa/rzn1_a5psw.h
@@ -146,7 +146,50 @@
 
 #define A5PSW_STATS_HIWORD		0x900
 
-#define A5PSW_DUMMY_WORKAROUND		0x5000
+/* Stats */
+#define A5PSW_aFramesTransmittedOK		0x868
+#define A5PSW_aFramesReceivedOK			0x86C
+#define A5PSW_aFrameCheckSequenceErrors		0x870
+#define A5PSW_aAlignmentErrors			0x874
+#define A5PSW_aOctetsTransmittedOK		0x878
+#define A5PSW_aOctetsReceivedOK			0x87C
+#define A5PSW_aTxPAUSEMACCtrlFrames		0x880
+#define A5PSW_aRxPAUSEMACCtrlFrames		0x884
+	/* If */
+#define A5PSW_ifInErrors			0x888
+#define A5PSW_ifOutErrors			0x88C
+#define A5PSW_ifInUcastPkts			0x890
+#define A5PSW_ifInMulticastPkts			0x894
+#define A5PSW_ifInBroadcastPkts			0x898
+#define A5PSW_ifOutDiscards			0x89C
+#define A5PSW_ifOutUcastPkts			0x8A0
+#define A5PSW_ifOutMulticastPkts		0x8A4
+#define A5PSW_ifOutBroadcastPkts		0x8A8
+	/* Ether */
+#define A5PSW_etherStatsDropEvents		0x8AC
+#define A5PSW_etherStatsOctets			0x8B0
+#define A5PSW_etherStatsPkts			0x8B4
+#define A5PSW_etherStatsUndersizePkts		0x8B8
+#define A5PSW_etherStatsOversizePkts		0x8BC
+#define A5PSW_etherStatsPkts64Octets		0x8C0
+#define A5PSW_etherStatsPkts65to127Octets	0x8C4
+#define A5PSW_etherStatsPkts128to255Octets	0x8C8
+#define A5PSW_etherStatsPkts256to511Octets	0x8CC
+#define A5PSW_etherStatsPkts512to1023Octets	0x8D0
+#define A5PSW_etherStatsPkts1024to1518Octets	0x8D4
+#define A5PSW_etherStatsPkts1519toXOctets	0x8D8
+#define A5PSW_etherStatsJabbers			0x8DC
+#define A5PSW_etherStatsFragments		0x8E0
+
+#define A5PSW_VLANReceived			0x8E8
+#define A5PSW_VLANTransmitted			0x8EC
+
+#define A5PSW_aDeferred				0x910
+#define A5PSW_aMultipleCollisions		0x914
+#define A5PSW_aSingleCollisions			0x918
+#define A5PSW_aLateCollisions			0x91C
+#define A5PSW_aExcessiveCollisions		0x920
+#define A5PSW_aCarrierSenseErrors		0x924
 
 #define A5PSW_VLAN_TAG(prio, id)	(((prio) << 12) | (id))
 #define A5PSW_PORTS_NUM			5
@@ -178,6 +221,7 @@
  * @mdio_freq: MDIO bus frequency requested
  * @pcs: Array of PCS connected to the switch ports (not for the CPU)
  * @ds: DSA switch struct
+ * @stats_lock: lock to access statistics (shared HI counter)
  * @lk_lock: Lock for the lookup table
  * @reg_lock: Lock for register read-modify-write operation
  * @bridged_ports: Mask of ports that are bridged and should be flooded
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (7 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-19 18:12   ` Vladimir Oltean
  2022-05-19 15:31 ` [PATCH net-next v5 10/13] ARM: dts: r9a06g032: describe MII converter Clément Léger
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

This commits add forwarding database support to the driver. It
implements fdb_add(), fdb_del() and fdb_dump().

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 drivers/net/dsa/rzn1_a5psw.c | 175 ++++++++++++++++++++++++++++++++++-
 drivers/net/dsa/rzn1_a5psw.h |  19 +++-
 2 files changed, 190 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/rzn1_a5psw.c b/drivers/net/dsa/rzn1_a5psw.c
index 3ef68bf1c8c6..125491d24c68 100644
--- a/drivers/net/dsa/rzn1_a5psw.c
+++ b/drivers/net/dsa/rzn1_a5psw.c
@@ -150,9 +150,9 @@ static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
 {
 	u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port);
 
-	spin_lock(&a5psw->lk_lock);
+	mutex_lock(&a5psw->lk_lock);
 	a5psw_lk_execute_ctrl(a5psw, &ctrl);
-	spin_unlock(&a5psw->lk_lock);
+	mutex_unlock(&a5psw->lk_lock);
 }
 
 static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
@@ -375,6 +375,172 @@ static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
 	a5psw_port_fdb_flush(a5psw, port);
 }
 
+static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
+				   u16 *entry)
+{
+	u32 ctrl;
+	int ret;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
+
+	ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP;
+	ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
+	if (ret)
+		return ret;
+
+	*entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS;
+
+	return 0;
+}
+
+static int a5psw_port_fdb_add(struct dsa_switch *ds, int port,
+			      const unsigned char *addr, u16 vid,
+			      struct dsa_db db)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data = {0};
+	bool inc_learncount = false;
+	int ret = 0;
+	u16 entry;
+	u32 reg;
+
+	ether_addr_copy(lk_data.entry.mac, addr);
+	lk_data.entry.port_mask = BIT(port);
+
+	mutex_lock(&a5psw->lk_lock);
+
+	/* Set the value to be written in the lookup table */
+	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
+	if (ret)
+		goto lk_unlock;
+
+	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+	if (!lk_data.entry.valid) {
+		inc_learncount = true;
+		/* port_mask set to 0x1f when entry is not valid, clear it */
+		lk_data.entry.port_mask = 0;
+		lk_data.entry.prio = 0;
+	}
+
+	lk_data.entry.port_mask |= BIT(port);
+	lk_data.entry.is_static = 1;
+	lk_data.entry.valid = 1;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
+
+	reg = A5PSW_LK_ADDR_CTRL_WRITE | entry;
+	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+	if (ret)
+		goto lk_unlock;
+
+	if (inc_learncount) {
+		reg = A5PSW_LK_LEARNCOUNT_MODE_INC;
+		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
+	}
+
+lk_unlock:
+	mutex_unlock(&a5psw->lk_lock);
+
+	return ret;
+}
+
+static int a5psw_port_fdb_del(struct dsa_switch *ds, int port,
+			      const unsigned char *addr, u16 vid,
+			      struct dsa_db db)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data = {0};
+	bool clear = false;
+	u16 entry;
+	u32 reg;
+	int ret;
+
+	ether_addr_copy(lk_data.entry.mac, addr);
+
+	mutex_lock(&a5psw->lk_lock);
+
+	ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
+	if (ret)
+		goto lk_unlock;
+
+	lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+
+	/* Our hardware does not associate any VID to the FDB entries so this
+	 * means that if two entries were added for the same mac but for
+	 * different VID, then, on the deletion of the first one, we would also
+	 * delete the second one. Since there is unfortunately nothing we can do
+	 * about that, do not return an error...
+	 */
+	if (!lk_data.entry.valid)
+		goto lk_unlock;
+
+	lk_data.entry.port_mask &= ~BIT(port);
+	/* If there is no more port in the mask, clear the entry */
+	if (lk_data.entry.port_mask == 0)
+		clear = true;
+
+	a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
+
+	reg = entry;
+	if (clear)
+		reg |= A5PSW_LK_ADDR_CTRL_CLEAR;
+	else
+		reg |= A5PSW_LK_ADDR_CTRL_WRITE;
+
+	ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+	if (ret)
+		goto lk_unlock;
+
+	/* Decrement LEARNCOUNT */
+	if (clear) {
+		reg = A5PSW_LK_LEARNCOUNT_MODE_DEC;
+		a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
+	}
+
+lk_unlock:
+	mutex_unlock(&a5psw->lk_lock);
+
+	return ret;
+}
+
+static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
+			       dsa_fdb_dump_cb_t *cb, void *data)
+{
+	struct a5psw *a5psw = ds->priv;
+	union lk_data lk_data;
+	int i = 0, ret;
+	u32 reg;
+
+	for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
+		reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
+		mutex_lock(&a5psw->lk_lock);
+
+		ret = a5psw_lk_execute_ctrl(a5psw, &reg);
+		if (ret) {
+			mutex_unlock(&a5psw->lk_lock);
+			return ret;
+		}
+
+		lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
+		/* If entry is not valid or does not contain the port, skip */
+		if (!lk_data.entry.valid ||
+		    !(lk_data.entry.port_mask & BIT(port))) {
+			mutex_unlock(&a5psw->lk_lock);
+			continue;
+		}
+
+		lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
+		mutex_unlock(&a5psw->lk_lock);
+
+		ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
 static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
 {
 	u32 reg_lo, reg_hi;
@@ -591,6 +757,9 @@ static const struct dsa_switch_ops a5psw_switch_ops = {
 	.port_bridge_leave = a5psw_port_bridge_leave,
 	.port_stp_state_set = a5psw_port_stp_state_set,
 	.port_fast_age = a5psw_port_fast_age,
+	.port_fdb_add = a5psw_port_fdb_add,
+	.port_fdb_del = a5psw_port_fdb_del,
+	.port_fdb_dump = a5psw_port_fdb_dump,
 };
 
 static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
@@ -774,7 +943,7 @@ static int a5psw_probe(struct platform_device *pdev)
 		return -ENOMEM;
 
 	a5psw->dev = dev;
-	spin_lock_init(&a5psw->lk_lock);
+	mutex_init(&a5psw->lk_lock);
 	spin_lock_init(&a5psw->reg_lock);
 	a5psw->base = devm_platform_ioremap_resource(pdev, 0);
 	if (!a5psw->base)
diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
index 649165d37fde..11fcea45b255 100644
--- a/drivers/net/dsa/rzn1_a5psw.h
+++ b/drivers/net/dsa/rzn1_a5psw.h
@@ -211,6 +211,23 @@
 #define A5PSW_CTRL_TIMEOUT		1000
 #define A5PSW_TABLE_ENTRIES		8192
 
+struct fdb_entry {
+	u8 mac[ETH_ALEN];
+	u16 valid:1;
+	u16 is_static:1;
+	u16 prio:3;
+	u16 port_mask:5;
+	u16 reserved:6;
+} __packed;
+
+union lk_data {
+	struct {
+		u32 lo;
+		u32 hi;
+	};
+	struct fdb_entry entry;
+};
+
 /**
  * struct a5psw - switch struct
  * @base: Base address of the switch
@@ -235,7 +252,7 @@ struct a5psw {
 	struct mii_bus	*mii_bus;
 	struct phylink_pcs *pcs[A5PSW_PORTS_NUM - 1];
 	struct dsa_switch ds;
-	spinlock_t lk_lock;
+	struct mutex lk_lock;
 	spinlock_t reg_lock;
 	u32 bridged_ports;
 	struct net_device *br_dev;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 10/13] ARM: dts: r9a06g032: describe MII converter
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (8 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-19 15:31 ` [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2 Clément Léger
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add the MII converter node which describes the MII converter that is
present on the RZ/N1 SoC.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 arch/arm/boot/dts/r9a06g032.dtsi | 38 ++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index 636a6ab31c58..0051fe9f44fd 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -200,6 +200,44 @@ nand_controller: nand-controller@40102000 {
 			status = "disabled";
 		};
 
+		eth_miic: eth-miic@44030000 {
+			compatible = "renesas,r9a06g032-miic", "renesas,rzn1-miic";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0x44030000 0x10000>;
+			clocks = <&sysctrl R9A06G032_CLK_MII_REF>,
+				 <&sysctrl R9A06G032_CLK_RGMII_REF>,
+				 <&sysctrl R9A06G032_CLK_RMII_REF>,
+				 <&sysctrl R9A06G032_HCLK_SWITCH_RG>;
+			power-domains = <&sysctrl>;
+			status = "disabled";
+
+			mii_conv1: mii-conv@1 {
+				reg = <1>;
+				status = "disabled";
+			};
+
+			mii_conv2: mii-conv@2 {
+				reg = <2>;
+				status = "disabled";
+			};
+
+			mii_conv3: mii-conv@3 {
+				reg = <3>;
+				status = "disabled";
+			};
+
+			mii_conv4: mii-conv@4 {
+				reg = <4>;
+				status = "disabled";
+			};
+
+			mii_conv5: mii-conv@5 {
+				reg = <5>;
+				status = "disabled";
+			};
+		};
+
 		gic: interrupt-controller@44101000 {
 			compatible = "arm,gic-400", "arm,cortex-a7-gic";
 			interrupt-controller;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (9 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 10/13] ARM: dts: r9a06g032: describe MII converter Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-20  7:18   ` Geert Uytterhoeven
  2022-05-19 15:31 ` [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch Clément Léger
  2022-05-19 15:31 ` [PATCH net-next v5 13/13] MAINTAINERS: add Renesas RZ/N1 switch related driver entry Clément Léger
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

RZ/N1 SoC includes two MAC named GMACx that are compatible with the
"snps,dwmac" driver. GMAC1 is connected directly to the MII converter
port 1. GMAC2 however can be used as the MAC for the switch CPU
management port or can be muxed to be connected directly to the MII
converter port 2. This commit add description for the GMAC2 which will
be used by the switch description.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 arch/arm/boot/dts/r9a06g032.dtsi | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index 0051fe9f44fd..31c4b2e2950a 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
 			status = "disabled";
 		};
 
+		gmac2: ethernet@44002000 {
+			compatible = "snps,dwmac";
+			reg = <0x44002000 0x2000>;
+			interrupt-parent = <&gic>;
+			interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+				     <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
+			interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
+			clock-names = "stmmaceth";
+			clocks = <&sysctrl R9A06G032_HCLK_GMAC1>;
+			snps,multicast-filter-bins = <256>;
+			snps,perfect-filter-entries = <128>;
+			tx-fifo-depth = <2048>;
+			rx-fifo-depth = <4096>;
+			status = "disabled";
+		};
+
 		eth_miic: eth-miic@44030000 {
 			compatible = "renesas,r9a06g032-miic", "renesas,rzn1-miic";
 			#address-cells = <1>;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (10 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2 Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  2022-05-19 18:28   ` Vladimir Oltean
  2022-05-19 15:31 ` [PATCH net-next v5 13/13] MAINTAINERS: add Renesas RZ/N1 switch related driver entry Clément Léger
  12 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Add description of the switch that is present on the RZ/N1 SoC.

Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 arch/arm/boot/dts/r9a06g032.dtsi | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
index 31c4b2e2950a..20d3dce632ce 100644
--- a/arch/arm/boot/dts/r9a06g032.dtsi
+++ b/arch/arm/boot/dts/r9a06g032.dtsi
@@ -255,6 +255,15 @@ mii_conv5: mii-conv@5 {
 			};
 		};
 
+		switch: switch@44050000 {
+			compatible = "renesas,r9a06g032-a5psw", "renesas,rzn1-a5psw";
+			reg = <0x44050000 0x10000>;
+			clocks = <&sysctrl R9A06G032_HCLK_SWITCH>,
+				 <&sysctrl R9A06G032_CLK_SWITCH>;
+			clock-names = "hclk", "clk";
+			status = "disabled";
+		};
+
 		gic: interrupt-controller@44101000 {
 			compatible = "arm,gic-400", "arm,cortex-a7-gic";
 			interrupt-controller;
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCH net-next v5 13/13] MAINTAINERS: add Renesas RZ/N1 switch related driver entry
  2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
                   ` (11 preceding siblings ...)
  2022-05-19 15:31 ` [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch Clément Léger
@ 2022-05-19 15:31 ` Clément Léger
  12 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-19 15:31 UTC (permalink / raw)
  To: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King
  Cc: Clément Léger, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

After contributing the drivers, volunteer for maintenance and add
myself as the maintainer for Renesas RZ/N1 switch related drivers.

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Clément Léger <clement.leger@bootlin.com>
---
 MAINTAINERS | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 69b597aa4bc7..9f03e4fba1a7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16889,6 +16889,17 @@ S:	Supported
 F:	Documentation/devicetree/bindings/iio/adc/renesas,rzg2l-adc.yaml
 F:	drivers/iio/adc/rzg2l_adc.c
 
+RENESAS RZ/N1 A5PSW SWITCH DRIVER
+M:	Clément Léger <clement.leger@bootlin.com>
+S:	Maintained
+F:	Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
+F:	Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
+F:	drivers/net/dsa/rzn1_a5psw*
+F:	drivers/net/pcs/pcs-rzn1-miic.c
+F:	include/dt-bindings/net/pcs-rzn1-miic.h
+F:	include/linux/pcs-rzn1-miic.h
+F:	net/dsa/tag_rzn1_a5psw.c
+
 RENESAS R-CAR GEN3 & RZ/N1 NAND CONTROLLER DRIVER
 M:	Miquel Raynal <miquel.raynal@bootlin.com>
 L:	linux-mtd@lists.infradead.org
-- 
2.36.0


^ permalink raw reply related	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-19 15:30 ` [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver Clément Léger
@ 2022-05-19 16:25   ` Russell King (Oracle)
  2022-05-20  7:52     ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Russell King (Oracle) @ 2022-05-19 16:25 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Hi,

On Thu, May 19, 2022 at 05:30:59PM +0200, Clément Léger wrote:
> Add a PCS driver for the MII converter that is present on the Renesas
> RZ/N1 SoC. This MII converter is reponsible for converting MII to
> RMII/RGMII or act as a MII pass-trough. Exposing it as a PCS allows to
> reuse it in both the switch driver and the stmmac driver. Currently,
> this driver only allows the PCS to be used by the dual Cortex-A7
> subsystem since the register locking system is not used.
> 
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>

Looks much better now, thanks. Only one thing I've spotted is:

> +static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
> +			 const struct phylink_link_state *state)
> +{
> +	if (state->interface == PHY_INTERFACE_MODE_RGMII ||
> +	    state->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> +	    state->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
> +	    state->interface == PHY_INTERFACE_MODE_RGMII_RXID ||

The above could use:

	if (phy_interface_mode_is_rgmii(state->interface) ||

Also, as a request to unbind this driver would be disasterous to users,
I think you should set ".suppress_bind_attrs = true" to prevent the
sysfs bind/unbind facility being available. This doesn't completely
solve the problem.

Thanks.

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

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message
  2022-05-19 15:30 ` [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message Clément Léger
@ 2022-05-19 17:53   ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-19 17:53 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Thu, May 19, 2022 at 05:30:55PM +0200, Clément Léger wrote:
> Some drivers might report that they are unable to bridge ports by
> returning -EOPNOTSUPP, but still wants to override extack message.
> In order to do so, in dsa_slave_changeupper(), if port_bridge_join()
> returns -EOPNOTSUPP, check if extack message is set and if so, do not
> override it.
> 
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> ---

Reviewed-by: Vladimir Oltean <olteanv@gmail.com>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver
  2022-05-19 15:31 ` [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Clément Léger
@ 2022-05-19 18:08   ` Vladimir Oltean
  2022-05-20  7:58     ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-19 18:08 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev, Jean-Pierre Geslin, Phil Edworthy

On Thu, May 19, 2022 at 05:31:01PM +0200, Clément Léger wrote:
> +static int a5psw_pcs_get(struct a5psw *a5psw)
> +{
> +	struct device_node *ports, *port, *pcs_node;
> +	struct phylink_pcs *pcs;
> +	int ret;
> +	u32 reg;
> +
> +	ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
> +	if (!ports)
> +		return -EINVAL;
> +
> +	for_each_available_child_of_node(ports, port) {
> +		pcs_node = of_parse_phandle(port, "pcs-handle", 0);
> +		if (!pcs_node)
> +			continue;
> +
> +		if (of_property_read_u32(port, "reg", &reg)) {
> +			ret = -EINVAL;
> +			goto free_pcs;

I think when you exit the for_each_available_child_of_node() loop you
need to manually call of_node_put(port).

> +		}
> +
> +		if (reg >= ARRAY_SIZE(a5psw->pcs)) {
> +			ret = -ENODEV;
> +			goto free_pcs;
> +		}
> +
> +		pcs = miic_create(pcs_node);
> +		if (IS_ERR(pcs)) {
> +			dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
> +				reg);
> +			ret = PTR_ERR(pcs);
> +			goto free_pcs;
> +		}
> +
> +		a5psw->pcs[reg] = pcs;
> +	}
> +	of_node_put(ports);
> +
> +	return 0;
> +
> +free_pcs:
> +	a5psw_pcs_free(a5psw);
> +	of_node_put(ports);
> +
> +	return ret;
> +}

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support
  2022-05-19 15:31 ` [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support Clément Léger
@ 2022-05-19 18:12   ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-19 18:12 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Thu, May 19, 2022 at 05:31:03PM +0200, Clément Léger wrote:
> +static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
> +			       dsa_fdb_dump_cb_t *cb, void *data)
> +{
> +	struct a5psw *a5psw = ds->priv;
> +	union lk_data lk_data;
> +	int i = 0, ret;
> +	u32 reg;
> +
> +	for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
> +		reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
> +		mutex_lock(&a5psw->lk_lock);

It might be more efficient to lock the lookup table only once, outside
the for loop, rather than 8192 times (plus the fact that when you run
plain "bridge fdb show", this gets repeated for each switch user port,
which is a nuisance of its own).

> +
> +		ret = a5psw_lk_execute_ctrl(a5psw, &reg);
> +		if (ret) {
> +			mutex_unlock(&a5psw->lk_lock);
> +			return ret;
> +		}
> +
> +		lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
> +		/* If entry is not valid or does not contain the port, skip */
> +		if (!lk_data.entry.valid ||
> +		    !(lk_data.entry.port_mask & BIT(port))) {
> +			mutex_unlock(&a5psw->lk_lock);
> +			continue;
> +		}
> +
> +		lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
> +		mutex_unlock(&a5psw->lk_lock);
> +
> +		ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
> +		if (ret)
> +			return ret;
> +	}
> +
> +	return 0;
> +}

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support
  2022-05-19 15:31 ` [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support Clément Léger
@ 2022-05-19 18:24   ` Vladimir Oltean
  0 siblings, 0 replies; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-19 18:24 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Thu, May 19, 2022 at 05:31:02PM +0200, Clément Léger wrote:
> diff --git a/drivers/net/dsa/rzn1_a5psw.h b/drivers/net/dsa/rzn1_a5psw.h
> index 306cab55db24..649165d37fde 100644
> --- a/drivers/net/dsa/rzn1_a5psw.h
> +++ b/drivers/net/dsa/rzn1_a5psw.h
> @@ -146,7 +146,50 @@
>  
>  #define A5PSW_STATS_HIWORD		0x900
>  
> -#define A5PSW_DUMMY_WORKAROUND		0x5000
> +/* Stats */
> +#define A5PSW_aFramesTransmittedOK		0x868
> +#define A5PSW_aFramesReceivedOK			0x86C
> +#define A5PSW_aFrameCheckSequenceErrors		0x870
> +#define A5PSW_aAlignmentErrors			0x874
> +#define A5PSW_aOctetsTransmittedOK		0x878
> +#define A5PSW_aOctetsReceivedOK			0x87C
> +#define A5PSW_aTxPAUSEMACCtrlFrames		0x880
> +#define A5PSW_aRxPAUSEMACCtrlFrames		0x884
> +	/* If */

It would probably be good to keep the same alignment for all comments here.

> +#define A5PSW_ifInErrors			0x888
> +#define A5PSW_ifOutErrors			0x88C
> +#define A5PSW_ifInUcastPkts			0x890
> +#define A5PSW_ifInMulticastPkts			0x894
> +#define A5PSW_ifInBroadcastPkts			0x898
> +#define A5PSW_ifOutDiscards			0x89C
> +#define A5PSW_ifOutUcastPkts			0x8A0
> +#define A5PSW_ifOutMulticastPkts		0x8A4
> +#define A5PSW_ifOutBroadcastPkts		0x8A8
> +	/* Ether */
> +#define A5PSW_etherStatsDropEvents		0x8AC
> +#define A5PSW_etherStatsOctets			0x8B0
> +#define A5PSW_etherStatsPkts			0x8B4
> +#define A5PSW_etherStatsUndersizePkts		0x8B8
> +#define A5PSW_etherStatsOversizePkts		0x8BC
> +#define A5PSW_etherStatsPkts64Octets		0x8C0
> +#define A5PSW_etherStatsPkts65to127Octets	0x8C4
> +#define A5PSW_etherStatsPkts128to255Octets	0x8C8
> +#define A5PSW_etherStatsPkts256to511Octets	0x8CC
> +#define A5PSW_etherStatsPkts512to1023Octets	0x8D0
> +#define A5PSW_etherStatsPkts1024to1518Octets	0x8D4
> +#define A5PSW_etherStatsPkts1519toXOctets	0x8D8
> +#define A5PSW_etherStatsJabbers			0x8DC
> +#define A5PSW_etherStatsFragments		0x8E0
> +
> +#define A5PSW_VLANReceived			0x8E8
> +#define A5PSW_VLANTransmitted			0x8EC
> +
> +#define A5PSW_aDeferred				0x910
> +#define A5PSW_aMultipleCollisions		0x914
> +#define A5PSW_aSingleCollisions			0x918
> +#define A5PSW_aLateCollisions			0x91C
> +#define A5PSW_aExcessiveCollisions		0x920
> +#define A5PSW_aCarrierSenseErrors		0x924

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch
  2022-05-19 15:31 ` [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch Clément Léger
@ 2022-05-19 18:28   ` Vladimir Oltean
  2022-05-20  8:18     ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-19 18:28 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Thu, May 19, 2022 at 05:31:06PM +0200, Clément Léger wrote:
> Add description of the switch that is present on the RZ/N1 SoC.
> 
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> ---
>  arch/arm/boot/dts/r9a06g032.dtsi | 9 +++++++++
>  1 file changed, 9 insertions(+)
> 
> diff --git a/arch/arm/boot/dts/r9a06g032.dtsi b/arch/arm/boot/dts/r9a06g032.dtsi
> index 31c4b2e2950a..20d3dce632ce 100644
> --- a/arch/arm/boot/dts/r9a06g032.dtsi
> +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> @@ -255,6 +255,15 @@ mii_conv5: mii-conv@5 {
>  			};
>  		};
>  
> +		switch: switch@44050000 {
> +			compatible = "renesas,r9a06g032-a5psw", "renesas,rzn1-a5psw";
> +			reg = <0x44050000 0x10000>;
> +			clocks = <&sysctrl R9A06G032_HCLK_SWITCH>,
> +				 <&sysctrl R9A06G032_CLK_SWITCH>;
> +			clock-names = "hclk", "clk";
> +			status = "disabled";

Does the switch port count depend on anything? If it doesn't, maybe you
could add the "ethernet-ports" node and all the ports here, with status
= "disabled", so that board files don't need to spell them out each time?
I'm also thinking you could define the fixed-link and phy-mode = "internal"
property of the CPU port with this occasion. That surely isn't a
per-board thing.

> +		};
> +
>  		gic: interrupt-controller@44101000 {
>  			compatible = "arm,gic-400", "arm,cortex-a7-gic";
>  			interrupt-controller;
> -- 
> 2.36.0
> 

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter
  2022-05-19 15:30 ` [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Clément Léger
@ 2022-05-20  7:09   ` Geert Uytterhoeven
  0 siblings, 0 replies; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  7:09 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Magnus Damm, Heiner Kallweit,
	Russell King, Thomas Petazzoni, Herve Codina, Miquèl Raynal,
	Milan Stevanovic, Jimmy Lalande, Pascal Eberhard,
	Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev, Rob Herring

Hi Clément,

On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> This MII converter can be found on the RZ/N1 processor family. The MII
> converter ports are declared as subnodes which are then referenced by
> users of the PCS driver such as the switch.
>
> Reviewed-by: Rob Herring <robh@kernel.org>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>

Thanks for your patch!

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/renesas,rzn1-miic.yaml
> @@ -0,0 +1,162 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/renesas,rzn1-miic.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/N1 MII converter
> +
> +maintainers:
> +  - Clément Léger <clement.leger@bootlin.com>
> +
> +description: |
> +  This MII converter is present on the Renesas RZ/N1 SoC family. It is
> +  responsible to do MII passthrough or convert it to RMII/RGMII.
> +
> +properties:
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +  compatible:
> +    items:
> +      - enum:
> +          - renesas,r9a06g032-miic
> +      - const: renesas,rzn1-miic
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: MII reference clock
> +      - description: RGMII reference clock
> +      - description: RMII reference clock
> +      - description: AHB clock used for the MII converter register interface

Please add clock-names (and make it required), as there are multiple clocks.

The rest LGTM (from an SoC integration PoV), so
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-19 15:31 ` [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
@ 2022-05-20  7:13   ` Geert Uytterhoeven
  2022-05-20  7:57     ` Clément Léger
  2022-05-24  2:34   ` Rob Herring
  1 sibling, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  7:13 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Hi Clément,

On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
> present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
> This company does not exists anymore and has been bought by Synopsys.
> Since this IP can't be find anymore in the Synospsy portfolio, lets use
> Renesas as the vendor compatible for this IP.
>
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>

Thanks for your patch!

> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
> @@ -0,0 +1,131 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Renesas RZ/N1 Advanced 5 ports ethernet switch
> +
> +maintainers:
> +  - Clément Léger <clement.leger@bootlin.com>
> +
> +description: |
> +  The advanced 5 ports switch is present on the Renesas RZ/N1 SoC family and
> +  handles 4 ports + 1 CPU management port.
> +
> +allOf:
> +  - $ref: dsa.yaml#
> +
> +properties:
> +  compatible:
> +    items:
> +      - enum:
> +          - renesas,r9a06g032-a5psw
> +      - const: renesas,rzn1-a5psw
> +
> +  reg:
> +    maxItems: 1
> +
> +  mdio:
> +    $ref: /schemas/net/mdio.yaml#
> +    unevaluatedProperties: false
> +
> +  clocks:
> +    items:
> +      - description: AHB clock used for the switch register interface
> +      - description: Switch system clock
> +
> +  clock-names:
> +    items:
> +      - const: hclk
> +      - const: clk

(Good, "clock-names" is present ;-)

Missing "power-domains" property.

> +examples:
> +  - |
> +    #include <dt-bindings/gpio/gpio.h>
> +    #include <dt-bindings/clock/r9a06g032-sysctrl.h>
> +
> +    switch@44050000 {
> +        compatible = "renesas,r9a06g032-a5psw", "renesas,rzn1-a5psw";
> +        reg = <0x44050000 0x10000>;
> +        clocks = <&sysctrl R9A06G032_HCLK_SWITCH>, <&sysctrl R9A06G032_CLK_SWITCH>;
> +        clock-names = "hclk", "clk";
> +        pinctrl-names = "default";
> +        pinctrl-0 = <&pins_mdio1>, <&pins_eth3>, <&pins_eth4>;

Usually we don't list pinctrl-* properties in examples.

The rest LGTM (from an SoC integration PoV), so with the above fixed
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-19 15:31 ` [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2 Clément Léger
@ 2022-05-20  7:18   ` Geert Uytterhoeven
  2022-05-20  8:13     ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  7:18 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Hi Clément

On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> RZ/N1 SoC includes two MAC named GMACx that are compatible with the
> "snps,dwmac" driver. GMAC1 is connected directly to the MII converter
> port 1. GMAC2 however can be used as the MAC for the switch CPU
> management port or can be muxed to be connected directly to the MII
> converter port 2. This commit add description for the GMAC2 which will
> be used by the switch description.
>
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>

Thanks for your patch!

> --- a/arch/arm/boot/dts/r9a06g032.dtsi
> +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
>                         status = "disabled";
>                 };
>
> +               gmac2: ethernet@44002000 {
> +                       compatible = "snps,dwmac";

Does this need an SoC-specific compatible value?

> +                       reg = <0x44002000 0x2000>;
> +                       interrupt-parent = <&gic>;
> +                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>,
> +                                    <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
> +                                    <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
> +                       interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
> +                       clock-names = "stmmaceth";
> +                       clocks = <&sysctrl R9A06G032_HCLK_GMAC1>;

Missing "power-domains", also in the DT bindings.
The driver already uses Runtime PM.

> +                       snps,multicast-filter-bins = <256>;
> +                       snps,perfect-filter-entries = <128>;
> +                       tx-fifo-depth = <2048>;
> +                       rx-fifo-depth = <4096>;
> +                       status = "disabled";
> +               };
> +
>                 eth_miic: eth-miic@44030000 {
>                         compatible = "renesas,r9a06g032-miic", "renesas,rzn1-miic";
>                         #address-cells = <1>;

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-19 16:25   ` Russell King (Oracle)
@ 2022-05-20  7:52     ` Clément Léger
  2022-05-20  8:49       ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20  7:52 UTC (permalink / raw)
  To: Russell King (Oracle)
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Le Thu, 19 May 2022 17:25:10 +0100,
"Russell King (Oracle)" <linux@armlinux.org.uk> a écrit :

> Hi,
> 
> On Thu, May 19, 2022 at 05:30:59PM +0200, Clément Léger wrote:
> > Add a PCS driver for the MII converter that is present on the Renesas
> > RZ/N1 SoC. This MII converter is reponsible for converting MII to
> > RMII/RGMII or act as a MII pass-trough. Exposing it as a PCS allows to
> > reuse it in both the switch driver and the stmmac driver. Currently,
> > this driver only allows the PCS to be used by the dual Cortex-A7
> > subsystem since the register locking system is not used.
> > 
> > Signed-off-by: Clément Léger <clement.leger@bootlin.com>  
> 
> Looks much better now, thanks. Only one thing I've spotted is:
> 
> > +static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported,
> > +			 const struct phylink_link_state *state)
> > +{
> > +	if (state->interface == PHY_INTERFACE_MODE_RGMII ||
> > +	    state->interface == PHY_INTERFACE_MODE_RGMII_ID ||
> > +	    state->interface == PHY_INTERFACE_MODE_RGMII_TXID ||
> > +	    state->interface == PHY_INTERFACE_MODE_RGMII_RXID ||  
> 
> The above could use:
> 
> 	if (phy_interface_mode_is_rgmii(state->interface) ||

Thanks, I did found the one to set the bit for phylink part but not
this one.

> 
> Also, as a request to unbind this driver would be disasterous to users,
> I think you should set ".suppress_bind_attrs = true" to prevent the
> sysfs bind/unbind facility being available. This doesn't completely
> solve the problem.

Acked. What should I do to make it more robust ? Should I use a
refcount per pdev and check that in the remove() callback to avoid
removing the pdev if used ?

Thanks,

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-20  7:13   ` Geert Uytterhoeven
@ 2022-05-20  7:57     ` Clément Léger
  2022-05-20  8:01       ` Geert Uytterhoeven
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20  7:57 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Le Fri, 20 May 2022 09:13:23 +0200,
Geert Uytterhoeven <geert@linux-m68k.org> a écrit :

> Hi Clément,
> 
> On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> > Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
> > present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
> > This company does not exists anymore and has been bought by Synopsys.
> > Since this IP can't be find anymore in the Synospsy portfolio, lets use
> > Renesas as the vendor compatible for this IP.
> >
> > Signed-off-by: Clément Léger <clement.leger@bootlin.com>  
> 
> Thanks for your patch!
> 
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
> > @@ -0,0 +1,131 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Renesas RZ/N1 Advanced 5 ports ethernet switch
> > +
> > +maintainers:
> > +  - Clément Léger <clement.leger@bootlin.com>
> > +
> > +description: |
> > +  The advanced 5 ports switch is present on the Renesas RZ/N1 SoC family and
> > +  handles 4 ports + 1 CPU management port.
> > +
> > +allOf:
> > +  - $ref: dsa.yaml#
> > +
> > +properties:
> > +  compatible:
> > +    items:
> > +      - enum:
> > +          - renesas,r9a06g032-a5psw
> > +      - const: renesas,rzn1-a5psw
> > +
> > +  reg:
> > +    maxItems: 1
> > +
> > +  mdio:
> > +    $ref: /schemas/net/mdio.yaml#
> > +    unevaluatedProperties: false
> > +
> > +  clocks:
> > +    items:
> > +      - description: AHB clock used for the switch register interface
> > +      - description: Switch system clock
> > +
> > +  clock-names:
> > +    items:
> > +      - const: hclk
> > +      - const: clk  
> 
> (Good, "clock-names" is present ;-)
> 
> Missing "power-domains" property.
> 

I do not use pm_runtime* in the switch driver. I should probably do that
right ?

> > +examples:
> > +  - |
> > +    #include <dt-bindings/gpio/gpio.h>
> > +    #include <dt-bindings/clock/r9a06g032-sysctrl.h>
> > +
> > +    switch@44050000 {
> > +        compatible = "renesas,r9a06g032-a5psw", "renesas,rzn1-a5psw";
> > +        reg = <0x44050000 0x10000>;
> > +        clocks = <&sysctrl R9A06G032_HCLK_SWITCH>, <&sysctrl R9A06G032_CLK_SWITCH>;
> > +        clock-names = "hclk", "clk";
> > +        pinctrl-names = "default";
> > +        pinctrl-0 = <&pins_mdio1>, <&pins_eth3>, <&pins_eth4>;  
> 
> Usually we don't list pinctrl-* properties in examples.
> 

Acked, I'll remove that.

> The rest LGTM (from an SoC integration PoV), so with the above fixed
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver
  2022-05-19 18:08   ` Vladimir Oltean
@ 2022-05-20  7:58     ` Clément Léger
  0 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-20  7:58 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev, Jean-Pierre Geslin, Phil Edworthy

Le Thu, 19 May 2022 21:08:51 +0300,
Vladimir Oltean <olteanv@gmail.com> a écrit :

> I think when you exit the for_each_available_child_of_node() loop you
> need to manually call of_node_put(port).

Yes you are right on that point. I'll fix that.

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-20  7:57     ` Clément Léger
@ 2022-05-20  8:01       ` Geert Uytterhoeven
  2022-05-20  8:16         ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  8:01 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Hi Clément,

On Fri, May 20, 2022 at 9:58 AM Clément Léger <clement.leger@bootlin.com> wrote:
> Le Fri, 20 May 2022 09:13:23 +0200,
> Geert Uytterhoeven <geert@linux-m68k.org> a écrit :
> > On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> > > Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
> > > present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
> > > This company does not exists anymore and has been bought by Synopsys.
> > > Since this IP can't be find anymore in the Synospsy portfolio, lets use
> > > Renesas as the vendor compatible for this IP.
> > >
> > > Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml

> > Missing "power-domains" property.
>
> I do not use pm_runtime* in the switch driver. I should probably do that
> right ?

For now you don't have to.  But I think it is a good idea, and it helps if the
IP block is ever reused in an SoC with real power areas.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-20  7:18   ` Geert Uytterhoeven
@ 2022-05-20  8:13     ` Clément Léger
  2022-05-20  8:25       ` Geert Uytterhoeven
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20  8:13 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Le Fri, 20 May 2022 09:18:58 +0200,
Geert Uytterhoeven <geert@linux-m68k.org> a écrit :

> Hi Clément
> 
> On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> > RZ/N1 SoC includes two MAC named GMACx that are compatible with the
> > "snps,dwmac" driver. GMAC1 is connected directly to the MII converter
> > port 1. GMAC2 however can be used as the MAC for the switch CPU
> > management port or can be muxed to be connected directly to the MII
> > converter port 2. This commit add description for the GMAC2 which will
> > be used by the switch description.
> >
> > Signed-off-by: Clément Léger <clement.leger@bootlin.com>  
> 
> Thanks for your patch!
> 
> > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
> >                         status = "disabled";
> >                 };
> >
> > +               gmac2: ethernet@44002000 {
> > +                       compatible = "snps,dwmac";  
> 
> Does this need an SoC-specific compatible value?

Indeed, it might be useful to introduce a specific SoC compatible since
in a near future, there might be some specific support for that gmac.
Here is an overview of the gmac connection on the SoC:

                                          ┌─────────┐   ┌──────────┐
                                          │         │   │          │
                                          │  GMAC2  │   │  GMAC1   │
                                          │         │   │          │
                                          └───┬─────┘   └─────┬────┘
                                              │               │
                                              │               │
                                              │               │
                                         ┌────▼──────┐        │
                                         │           │        │
            ┌────────────────────────────┤  SWITCH   │        │
            │                            │           │        │
            │          ┌─────────────────┴─┬────┬────┘        │
            │          │            ┌──────┘    │             │
            │          │            │           │             │
       ┌────▼──────────▼────────────▼───────────▼─────────────▼────┐
       │                      MII Converter                        │
       │                                                           │
       │                                                           │
       │ port 1      port 2       port 3      port 4       port 5  │
       └───────────────────────────────────────────────────────────┘

As you can see, the GMAC1 is directly connected to MIIC converter and
thus will need a "pcs-handle" property to point on the MII converter
port whereas the GMAC2 is directly connected to the switch in GMII.

Is "renesas,r9a06g032-gmac2", "renesas,rzn1-switch-gmac2" looks ok for
you for this one ?

Thanks,

Clément

> 
> > +                       reg = <0x44002000 0x2000>;
> > +                       interrupt-parent = <&gic>;
> > +                       interrupts = <GIC_SPI 37
> > IRQ_TYPE_LEVEL_HIGH>,
> > +                                    <GIC_SPI 39
> > IRQ_TYPE_LEVEL_HIGH>,
> > +                                    <GIC_SPI 38
> > IRQ_TYPE_LEVEL_HIGH>;
> > +                       interrupt-names = "macirq", "eth_wake_irq",
> > "eth_lpi";
> > +                       clock-names = "stmmaceth";
> > +                       clocks = <&sysctrl R9A06G032_HCLK_GMAC1>;  
> 
> Missing "power-domains", also in the DT bindings.
> The driver already uses Runtime PM.

Ok,I'll add that to the DT and modify the DWMAC bindings.

> 
> > +                       snps,multicast-filter-bins = <256>;
> > +                       snps,perfect-filter-entries = <128>;
> > +                       tx-fifo-depth = <2048>;
> > +                       rx-fifo-depth = <4096>;
> > +                       status = "disabled";
> > +               };
> > +
> >                 eth_miic: eth-miic@44030000 {
> >                         compatible = "renesas,r9a06g032-miic",
> > "renesas,rzn1-miic"; #address-cells = <1>;  
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 --
> geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a
> hacker. But when I'm talking to journalists I just say "programmer"
> or something like that. -- Linus Torvalds



-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-20  8:01       ` Geert Uytterhoeven
@ 2022-05-20  8:16         ` Clément Léger
  0 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-20  8:16 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Le Fri, 20 May 2022 10:01:32 +0200,
Geert Uytterhoeven <geert@linux-m68k.org> a écrit :

> Hi Clément,
> 
> On Fri, May 20, 2022 at 9:58 AM Clément Léger <clement.leger@bootlin.com> wrote:
> > Le Fri, 20 May 2022 09:13:23 +0200,
> > Geert Uytterhoeven <geert@linux-m68k.org> a écrit :  
> > > On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:  
> > > > Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
> > > > present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
> > > > This company does not exists anymore and has been bought by Synopsys.
> > > > Since this IP can't be find anymore in the Synospsy portfolio, lets use
> > > > Renesas as the vendor compatible for this IP.
> > > >
> > > > Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml  
> 
> > > Missing "power-domains" property.  
> >
> > I do not use pm_runtime* in the switch driver. I should probably do that
> > right ?  
> 
> For now you don't have to.  But I think it is a good idea, and it helps if the
> IP block is ever reused in an SoC with real power areas.

Ok, sounds good, I'll probably also set that as required to be
compatible with these potentials modifications without breaking the
bindings.

Thanks,

> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds


-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch
  2022-05-19 18:28   ` Vladimir Oltean
@ 2022-05-20  8:18     ` Clément Léger
  0 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-20  8:18 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Russell King, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Le Thu, 19 May 2022 21:28:12 +0300,
Vladimir Oltean <olteanv@gmail.com> a écrit :

> Does the switch port count depend on anything? If it doesn't, maybe you
> could add the "ethernet-ports" node and all the ports here, with status
> = "disabled", so that board files don't need to spell them out each time?

Port count does not depends on anything, it's always fixed so indeed, it
would be a good idea to provide all the ports as disabled.

> I'm also thinking you could define the fixed-link and phy-mode = "internal"
> property of the CPU port with this occasion. That surely isn't a
> per-board thing.

Totally.

Thanks,

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-20  8:13     ` Clément Léger
@ 2022-05-20  8:25       ` Geert Uytterhoeven
  2022-05-20  8:31         ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  8:25 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Hi Clément,

On Fri, May 20, 2022 at 10:14 AM Clément Léger
<clement.leger@bootlin.com> wrote:
> Le Fri, 20 May 2022 09:18:58 +0200,
> Geert Uytterhoeven <geert@linux-m68k.org> a écrit :
> > On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> > > RZ/N1 SoC includes two MAC named GMACx that are compatible with the
> > > "snps,dwmac" driver. GMAC1 is connected directly to the MII converter
> > > port 1. GMAC2 however can be used as the MAC for the switch CPU
> > > management port or can be muxed to be connected directly to the MII
> > > converter port 2. This commit add description for the GMAC2 which will
> > > be used by the switch description.
> > >
> > > Signed-off-by: Clément Léger <clement.leger@bootlin.com>

> > > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > > @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
> > >                         status = "disabled";
> > >                 };
> > >
> > > +               gmac2: ethernet@44002000 {
> > > +                       compatible = "snps,dwmac";
> >
> > Does this need an SoC-specific compatible value?
>
> Indeed, it might be useful to introduce a specific SoC compatible since
> in a near future, there might be some specific support for that gmac.
> Here is an overview of the gmac connection on the SoC:
>
>                                           ┌─────────┐   ┌──────────┐
>                                           │         │   │          │
>                                           │  GMAC2  │   │  GMAC1   │
>                                           │         │   │          │
>                                           └───┬─────┘   └─────┬────┘
>                                               │               │
>                                               │               │
>                                               │               │
>                                          ┌────▼──────┐        │
>                                          │           │        │
>             ┌────────────────────────────┤  SWITCH   │        │
>             │                            │           │        │
>             │          ┌─────────────────┴─┬────┬────┘        │
>             │          │            ┌──────┘    │             │
>             │          │            │           │             │
>        ┌────▼──────────▼────────────▼───────────▼─────────────▼────┐
>        │                      MII Converter                        │
>        │                                                           │
>        │                                                           │
>        │ port 1      port 2       port 3      port 4       port 5  │
>        └───────────────────────────────────────────────────────────┘
>
> As you can see, the GMAC1 is directly connected to MIIC converter and
> thus will need a "pcs-handle" property to point on the MII converter
> port whereas the GMAC2 is directly connected to the switch in GMII.
>
> Is "renesas,r9a06g032-gmac2", "renesas,rzn1-switch-gmac2" looks ok for
> you for this one ?

Why "switch" in the family-specific value, but not in the SoC-specific
value?

Are GMAC1 and GMAC2 really different, or are they identical, and is
the only difference in the wiring, which can be detected at run-time
using this "pcs-handle" property? If they're identical, they should
use the same compatible value.

Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-20  8:25       ` Geert Uytterhoeven
@ 2022-05-20  8:31         ` Clément Léger
  2022-05-20  8:48           ` Geert Uytterhoeven
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20  8:31 UTC (permalink / raw)
  To: Geert Uytterhoeven
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Le Fri, 20 May 2022 10:25:37 +0200,
Geert Uytterhoeven <geert@linux-m68k.org> a écrit :

> Hi Clément,
> 
> On Fri, May 20, 2022 at 10:14 AM Clément Léger
> <clement.leger@bootlin.com> wrote:
> > Le Fri, 20 May 2022 09:18:58 +0200,
> > Geert Uytterhoeven <geert@linux-m68k.org> a écrit :  
> > > On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:  
> > > > RZ/N1 SoC includes two MAC named GMACx that are compatible with the
> > > > "snps,dwmac" driver. GMAC1 is connected directly to the MII converter
> > > > port 1. GMAC2 however can be used as the MAC for the switch CPU
> > > > management port or can be muxed to be connected directly to the MII
> > > > converter port 2. This commit add description for the GMAC2 which will
> > > > be used by the switch description.
> > > >
> > > > Signed-off-by: Clément Léger <clement.leger@bootlin.com>  
> 
> > > > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > > > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > > > @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
> > > >                         status = "disabled";
> > > >                 };
> > > >
> > > > +               gmac2: ethernet@44002000 {
> > > > +                       compatible = "snps,dwmac";  
> > >
> > > Does this need an SoC-specific compatible value?  
> >
> > Indeed, it might be useful to introduce a specific SoC compatible since
> > in a near future, there might be some specific support for that gmac.
> > Here is an overview of the gmac connection on the SoC:
> >
> >                                           ┌─────────┐   ┌──────────┐
> >                                           │         │   │          │
> >                                           │  GMAC2  │   │  GMAC1   │
> >                                           │         │   │          │
> >                                           └───┬─────┘   └─────┬────┘
> >                                               │               │
> >                                               │               │
> >                                               │               │
> >                                          ┌────▼──────┐        │
> >                                          │           │        │
> >             ┌────────────────────────────┤  SWITCH   │        │
> >             │                            │           │        │
> >             │          ┌─────────────────┴─┬────┬────┘        │
> >             │          │            ┌──────┘    │             │
> >             │          │            │           │             │
> >        ┌────▼──────────▼────────────▼───────────▼─────────────▼────┐
> >        │                      MII Converter                        │
> >        │                                                           │
> >        │                                                           │
> >        │ port 1      port 2       port 3      port 4       port 5  │
> >        └───────────────────────────────────────────────────────────┘
> >
> > As you can see, the GMAC1 is directly connected to MIIC converter and
> > thus will need a "pcs-handle" property to point on the MII converter
> > port whereas the GMAC2 is directly connected to the switch in GMII.
> >
> > Is "renesas,r9a06g032-gmac2", "renesas,rzn1-switch-gmac2" looks ok
> > for you for this one ?  
> 
> Why "switch" in the family-specific value, but not in the SoC-specific
> value?

That's a typo, switch should be removed.

> 
> Are GMAC1 and GMAC2 really different, or are they identical, and is
> the only difference in the wiring, which can be detected at run-time
> using this "pcs-handle" property? If they're identical, they should
> use the same compatible value.

They are actually identical except the requirement for a "pcs-handle"
for gmac1. I thought about using different compatible to enforce this by
making it "required" with the "renesas,r9a06g032-gmac1" compatible but
not the "renesas,r9a06g032-gmac2" one. If it's ok for you to let it
optional and use a single compatible, I'm ok with that !


Thanks !

> 
> Thanks!
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                 -- Linus Torvalds



-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2
  2022-05-20  8:31         ` Clément Léger
@ 2022-05-20  8:48           ` Geert Uytterhoeven
  0 siblings, 0 replies; 40+ messages in thread
From: Geert Uytterhoeven @ 2022-05-20  8:48 UTC (permalink / raw)
  To: Clément Léger
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, Vladimir Oltean,
	David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Geert Uytterhoeven,
	Magnus Damm, Heiner Kallweit, Russell King, Thomas Petazzoni,
	Herve Codina, Miquèl Raynal, Milan Stevanovic,
	Jimmy Lalande, Pascal Eberhard, Linux Kernel Mailing List,
	open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
	Linux-Renesas, netdev

Hi Clément,

On Fri, May 20, 2022 at 10:33 AM Clément Léger
<clement.leger@bootlin.com> wrote:
> Le Fri, 20 May 2022 10:25:37 +0200,
> Geert Uytterhoeven <geert@linux-m68k.org> a écrit :
> > On Fri, May 20, 2022 at 10:14 AM Clément Léger
> > <clement.leger@bootlin.com> wrote:
> > > Le Fri, 20 May 2022 09:18:58 +0200,
> > > Geert Uytterhoeven <geert@linux-m68k.org> a écrit :
> > > > On Thu, May 19, 2022 at 5:32 PM Clément Léger <clement.leger@bootlin.com> wrote:
> > > > > RZ/N1 SoC includes two MAC named GMACx that are compatible with the
> > > > > "snps,dwmac" driver. GMAC1 is connected directly to the MII converter
> > > > > port 1. GMAC2 however can be used as the MAC for the switch CPU
> > > > > management port or can be muxed to be connected directly to the MII
> > > > > converter port 2. This commit add description for the GMAC2 which will
> > > > > be used by the switch description.
> > > > >
> > > > > Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> >
> > > > > --- a/arch/arm/boot/dts/r9a06g032.dtsi
> > > > > +++ b/arch/arm/boot/dts/r9a06g032.dtsi
> > > > > @@ -200,6 +200,23 @@ nand_controller: nand-controller@40102000 {
> > > > >                         status = "disabled";
> > > > >                 };
> > > > >
> > > > > +               gmac2: ethernet@44002000 {
> > > > > +                       compatible = "snps,dwmac";
> > > >
> > > > Does this need an SoC-specific compatible value?
> > >
> > > Indeed, it might be useful to introduce a specific SoC compatible since
> > > in a near future, there might be some specific support for that gmac.
> > > Here is an overview of the gmac connection on the SoC:
> > >
> > >                                           ┌─────────┐   ┌──────────┐
> > >                                           │         │   │          │
> > >                                           │  GMAC2  │   │  GMAC1   │
> > >                                           │         │   │          │
> > >                                           └───┬─────┘   └─────┬────┘
> > >                                               │               │
> > >                                               │               │
> > >                                               │               │
> > >                                          ┌────▼──────┐        │
> > >                                          │           │        │
> > >             ┌────────────────────────────┤  SWITCH   │        │
> > >             │                            │           │        │
> > >             │          ┌─────────────────┴─┬────┬────┘        │
> > >             │          │            ┌──────┘    │             │
> > >             │          │            │           │             │
> > >        ┌────▼──────────▼────────────▼───────────▼─────────────▼────┐
> > >        │                      MII Converter                        │
> > >        │                                                           │
> > >        │                                                           │
> > >        │ port 1      port 2       port 3      port 4       port 5  │
> > >        └───────────────────────────────────────────────────────────┘
> > >
> > > As you can see, the GMAC1 is directly connected to MIIC converter and
> > > thus will need a "pcs-handle" property to point on the MII converter
> > > port whereas the GMAC2 is directly connected to the switch in GMII.
> > >
> > > Is "renesas,r9a06g032-gmac2", "renesas,rzn1-switch-gmac2" looks ok
> > > for you for this one ?
> >
> > Why "switch" in the family-specific value, but not in the SoC-specific
> > value?
>
> That's a typo, switch should be removed.

OK.

> > Are GMAC1 and GMAC2 really different, or are they identical, and is
> > the only difference in the wiring, which can be detected at run-time
> > using this "pcs-handle" property? If they're identical, they should
> > use the same compatible value.
>
> They are actually identical except the requirement for a "pcs-handle"
> for gmac1. I thought about using different compatible to enforce this by
> making it "required" with the "renesas,r9a06g032-gmac1" compatible but
> not the "renesas,r9a06g032-gmac2" one. If it's ok for you to let it
> optional and use a single compatible, I'm ok with that !

OK to make it optional. Thanks!

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20  7:52     ` Clément Léger
@ 2022-05-20  8:49       ` Vladimir Oltean
  2022-05-20 15:22         ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-20  8:49 UTC (permalink / raw)
  To: Clément Léger
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:
> > Also, as a request to unbind this driver would be disasterous to users,
> > I think you should set ".suppress_bind_attrs = true" to prevent the
> > sysfs bind/unbind facility being available. This doesn't completely
> > solve the problem.
> 
> Acked. What should I do to make it more robust ? Should I use a
> refcount per pdev and check that in the remove() callback to avoid
> removing the pdev if used ?

I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
wouldn't that be enough to auto-unbind the DSA driver when the MII
converter driver unbinds?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20  8:49       ` Vladimir Oltean
@ 2022-05-20 15:22         ` Clément Léger
  2022-05-20 15:44           ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20 15:22 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Le Fri, 20 May 2022 11:49:14 +0300,
Vladimir Oltean <olteanv@gmail.com> a écrit :

> On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:
> > > Also, as a request to unbind this driver would be disasterous to users,
> > > I think you should set ".suppress_bind_attrs = true" to prevent the
> > > sysfs bind/unbind facility being available. This doesn't completely
> > > solve the problem.  
> > 
> > Acked. What should I do to make it more robust ? Should I use a
> > refcount per pdev and check that in the remove() callback to avoid
> > removing the pdev if used ?  
> 
> I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
> wouldn't that be enough to auto-unbind the DSA driver when the MII
> converter driver unbinds?

I looiked at that a bit and I'm not sure how to achieve that cleanly. If
I need to create this link, then I need to do it once for the dsa switch
device. However, currently, the way I get the references to the MII
converter are via the pcs-handle properties which are for each port.

So, I'm not sure creating the link multiple times in miic_create() would
be ok and also, I'm not sure how to create the link once without adding
a specific property which points on the MII converter node and use that
to create the link by adding miic_device_add_link() for instance.

Do you have any preference ?

Thanks,

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20 15:22         ` Clément Léger
@ 2022-05-20 15:44           ` Vladimir Oltean
  2022-05-20 15:49             ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-20 15:44 UTC (permalink / raw)
  To: Clément Léger
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Fri, May 20, 2022 at 05:22:44PM +0200, Clément Léger wrote:
> Le Fri, 20 May 2022 11:49:14 +0300,
> Vladimir Oltean <olteanv@gmail.com> a écrit :
>
> > On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:
> > > > Also, as a request to unbind this driver would be disasterous to users,
> > > > I think you should set ".suppress_bind_attrs = true" to prevent the
> > > > sysfs bind/unbind facility being available. This doesn't completely
> > > > solve the problem.
> > >
> > > Acked. What should I do to make it more robust ? Should I use a
> > > refcount per pdev and check that in the remove() callback to avoid
> > > removing the pdev if used ?
> >
> > I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
> > wouldn't that be enough to auto-unbind the DSA driver when the MII
> > converter driver unbinds?
>
> I looiked at that a bit and I'm not sure how to achieve that cleanly. If
> I need to create this link, then I need to do it once for the dsa switch
> device. However, currently, the way I get the references to the MII
> converter are via the pcs-handle properties which are for each port.
>
> So, I'm not sure creating the link multiple times in miic_create() would
> be ok and also, I'm not sure how to create the link once without adding
> a specific property which points on the MII converter node and use that
> to create the link by adding miic_device_add_link() for instance.
>
> Do you have any preference ?

The simplest (although not the most elegant) way would probably be to
pass the ds->dev as a second argument to miic_create(), and call
device_link_add() multiple times, letting all but the first call fail,
and ignoring the resulting NULL return code. Maybe others have a better idea.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20 15:44           ` Vladimir Oltean
@ 2022-05-20 15:49             ` Clément Léger
  2022-05-20 15:58               ` Vladimir Oltean
  0 siblings, 1 reply; 40+ messages in thread
From: Clément Léger @ 2022-05-20 15:49 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Le Fri, 20 May 2022 18:44:40 +0300,
Vladimir Oltean <olteanv@gmail.com> a écrit :

> On Fri, May 20, 2022 at 05:22:44PM +0200, Clément Léger wrote:
> > Le Fri, 20 May 2022 11:49:14 +0300,
> > Vladimir Oltean <olteanv@gmail.com> a écrit :
> >  
> > > On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:  
> > > > > Also, as a request to unbind this driver would be disasterous to users,
> > > > > I think you should set ".suppress_bind_attrs = true" to prevent the
> > > > > sysfs bind/unbind facility being available. This doesn't completely
> > > > > solve the problem.  
> > > >
> > > > Acked. What should I do to make it more robust ? Should I use a
> > > > refcount per pdev and check that in the remove() callback to avoid
> > > > removing the pdev if used ?  
> > >
> > > I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
> > > wouldn't that be enough to auto-unbind the DSA driver when the MII
> > > converter driver unbinds?  
> >
> > I looiked at that a bit and I'm not sure how to achieve that cleanly. If
> > I need to create this link, then I need to do it once for the dsa switch
> > device. However, currently, the way I get the references to the MII
> > converter are via the pcs-handle properties which are for each port.
> >
> > So, I'm not sure creating the link multiple times in miic_create() would
> > be ok and also, I'm not sure how to create the link once without adding
> > a specific property which points on the MII converter node and use that
> > to create the link by adding miic_device_add_link() for instance.
> >
> > Do you have any preference ?  
> 
> The simplest (although not the most elegant) way would probably be to
> pass the ds->dev as a second argument to miic_create(), and call
> device_link_add() multiple times, letting all but the first call fail,
> and ignoring the resulting NULL return code. Maybe others have a better idea.

That's indeed what I started to do although it's nasty to say the
least... Moreover, the device_link_del() calls in miic_destroy() would
have to be carefully made after all miic ports have been
destroyed. Not sure this is going to be cleaner ! I'll try to think
about it a bit more.

Thanks,

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20 15:49             ` Clément Léger
@ 2022-05-20 15:58               ` Vladimir Oltean
  2022-05-20 16:22                 ` Clément Léger
  0 siblings, 1 reply; 40+ messages in thread
From: Vladimir Oltean @ 2022-05-20 15:58 UTC (permalink / raw)
  To: Clément Léger
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

On Fri, May 20, 2022 at 05:49:34PM +0200, Clément Léger wrote:
> Le Fri, 20 May 2022 18:44:40 +0300,
> Vladimir Oltean <olteanv@gmail.com> a écrit :
> 
> > On Fri, May 20, 2022 at 05:22:44PM +0200, Clément Léger wrote:
> > > Le Fri, 20 May 2022 11:49:14 +0300,
> > > Vladimir Oltean <olteanv@gmail.com> a écrit :
> > >  
> > > > On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:  
> > > > > > Also, as a request to unbind this driver would be disasterous to users,
> > > > > > I think you should set ".suppress_bind_attrs = true" to prevent the
> > > > > > sysfs bind/unbind facility being available. This doesn't completely
> > > > > > solve the problem.  
> > > > >
> > > > > Acked. What should I do to make it more robust ? Should I use a
> > > > > refcount per pdev and check that in the remove() callback to avoid
> > > > > removing the pdev if used ?  
> > > >
> > > > I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
> > > > wouldn't that be enough to auto-unbind the DSA driver when the MII
> > > > converter driver unbinds?  
> > >
> > > I looiked at that a bit and I'm not sure how to achieve that cleanly. If
> > > I need to create this link, then I need to do it once for the dsa switch
> > > device. However, currently, the way I get the references to the MII
> > > converter are via the pcs-handle properties which are for each port.
> > >
> > > So, I'm not sure creating the link multiple times in miic_create() would
> > > be ok and also, I'm not sure how to create the link once without adding
> > > a specific property which points on the MII converter node and use that
> > > to create the link by adding miic_device_add_link() for instance.
> > >
> > > Do you have any preference ?  
> > 
> > The simplest (although not the most elegant) way would probably be to
> > pass the ds->dev as a second argument to miic_create(), and call
> > device_link_add() multiple times, letting all but the first call fail,
> > and ignoring the resulting NULL return code. Maybe others have a better idea.
> 
> That's indeed what I started to do although it's nasty to say the
> least... Moreover, the device_link_del() calls in miic_destroy() would
> have to be carefully made after all miic ports have been
> destroyed. Not sure this is going to be cleaner ! I'll try to think
> about it a bit more.

Wait... the whole idea with AUTOREMOVE_CONSUMER is that you _don't_
remove the device link.. you let it sit there such that the device core
knows there are other consumers it needs to remove when this driver
unbinds from the device.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver
  2022-05-20 15:58               ` Vladimir Oltean
@ 2022-05-20 16:22                 ` Clément Léger
  0 siblings, 0 replies; 40+ messages in thread
From: Clément Léger @ 2022-05-20 16:22 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Russell King (Oracle),
	Andrew Lunn, Vivien Didelot, Florian Fainelli, David S . Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Geert Uytterhoeven, Magnus Damm,
	Heiner Kallweit, Thomas Petazzoni, Herve Codina,
	Miquèl Raynal, Milan Stevanovic, Jimmy Lalande,
	Pascal Eberhard, linux-kernel, devicetree, linux-renesas-soc,
	netdev

Le Fri, 20 May 2022 18:58:15 +0300,
Vladimir Oltean <olteanv@gmail.com> a écrit :

> On Fri, May 20, 2022 at 05:49:34PM +0200, Clément Léger wrote:
> > Le Fri, 20 May 2022 18:44:40 +0300,
> > Vladimir Oltean <olteanv@gmail.com> a écrit :
> >   
> > > On Fri, May 20, 2022 at 05:22:44PM +0200, Clément Léger wrote:  
> > > > Le Fri, 20 May 2022 11:49:14 +0300,
> > > > Vladimir Oltean <olteanv@gmail.com> a écrit :
> > > >    
> > > > > On Fri, May 20, 2022 at 09:52:41AM +0200, Clément Léger wrote:    
> > > > > > > Also, as a request to unbind this driver would be disasterous to users,
> > > > > > > I think you should set ".suppress_bind_attrs = true" to prevent the
> > > > > > > sysfs bind/unbind facility being available. This doesn't completely
> > > > > > > solve the problem.    
> > > > > >
> > > > > > Acked. What should I do to make it more robust ? Should I use a
> > > > > > refcount per pdev and check that in the remove() callback to avoid
> > > > > > removing the pdev if used ?    
> > > > >
> > > > > I wonder, if you call device_link_add(ds->dev, miic->dev, DL_FLAG_AUTOREMOVE_CONSUMER),
> > > > > wouldn't that be enough to auto-unbind the DSA driver when the MII
> > > > > converter driver unbinds?    
> > > >
> > > > I looiked at that a bit and I'm not sure how to achieve that cleanly. If
> > > > I need to create this link, then I need to do it once for the dsa switch
> > > > device. However, currently, the way I get the references to the MII
> > > > converter are via the pcs-handle properties which are for each port.
> > > >
> > > > So, I'm not sure creating the link multiple times in miic_create() would
> > > > be ok and also, I'm not sure how to create the link once without adding
> > > > a specific property which points on the MII converter node and use that
> > > > to create the link by adding miic_device_add_link() for instance.
> > > >
> > > > Do you have any preference ?    
> > > 
> > > The simplest (although not the most elegant) way would probably be to
> > > pass the ds->dev as a second argument to miic_create(), and call
> > > device_link_add() multiple times, letting all but the first call fail,
> > > and ignoring the resulting NULL return code. Maybe others have a better idea.  
> > 
> > That's indeed what I started to do although it's nasty to say the
> > least... Moreover, the device_link_del() calls in miic_destroy() would
> > have to be carefully made after all miic ports have been
> > destroyed. Not sure this is going to be cleaner ! I'll try to think
> > about it a bit more.  
> 
> Wait... the whole idea with AUTOREMOVE_CONSUMER is that you _don't_
> remove the device link.. you let it sit there such that the device core
> knows there are other consumers it needs to remove when this driver
> unbinds from the device.

Hum ok, got it, so let's try this solution.

-- 
Clément Léger,
Embedded Linux and Kernel engineer at Bootlin
https://bootlin.com

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch
  2022-05-19 15:31 ` [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
  2022-05-20  7:13   ` Geert Uytterhoeven
@ 2022-05-24  2:34   ` Rob Herring
  1 sibling, 0 replies; 40+ messages in thread
From: Rob Herring @ 2022-05-24  2:34 UTC (permalink / raw)
  To: Clément Léger
  Cc: Jimmy Lalande, Russell King, David S . Miller, Magnus Damm,
	netdev, Krzysztof Kozlowski, Milan Stevanovic, Eric Dumazet,
	Geert Uytterhoeven, Herve Codina, Pascal Eberhard, linux-kernel,
	devicetree, Miquèl Raynal, Thomas Petazzoni,
	Heiner Kallweit, Jakub Kicinski, Florian Fainelli,
	linux-renesas-soc, Paolo Abeni, Andrew Lunn, Rob Herring,
	Vivien Didelot, Vladimir Oltean

On Thu, 19 May 2022 17:31:00 +0200, Clément Léger wrote:
> Add bindings for Renesas RZ/N1 Advanced 5 port switch. This switch is
> present on Renesas RZ/N1 SoC and was probably provided by MoreThanIP.
> This company does not exists anymore and has been bought by Synopsys.
> Since this IP can't be find anymore in the Synospsy portfolio, lets use
> Renesas as the vendor compatible for this IP.
> 
> Signed-off-by: Clément Léger <clement.leger@bootlin.com>
> ---
>  .../bindings/net/dsa/renesas,rzn1-a5psw.yaml  | 131 ++++++++++++++++++
>  1 file changed, 131 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/dsa/renesas,rzn1-a5psw.yaml
> 

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2022-05-24  2:34 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-19 15:30 [PATCH net-next v5 00/13] add support for Renesas RZ/N1 ethernet subsystem devices Clément Léger
2022-05-19 15:30 ` [PATCH net-next v5 01/13] net: dsa: allow port_bridge_join() to override extack message Clément Léger
2022-05-19 17:53   ` Vladimir Oltean
2022-05-19 15:30 ` [PATCH net-next v5 02/13] net: dsa: add support for ethtool get_rmon_stats() Clément Léger
2022-05-19 15:30 ` [PATCH net-next v5 03/13] net: dsa: add Renesas RZ/N1 switch tag driver Clément Léger
2022-05-19 15:30 ` [PATCH net-next v5 04/13] dt-bindings: net: pcs: add bindings for Renesas RZ/N1 MII converter Clément Léger
2022-05-20  7:09   ` Geert Uytterhoeven
2022-05-19 15:30 ` [PATCH net-next v5 05/13] net: pcs: add Renesas MII converter driver Clément Léger
2022-05-19 16:25   ` Russell King (Oracle)
2022-05-20  7:52     ` Clément Léger
2022-05-20  8:49       ` Vladimir Oltean
2022-05-20 15:22         ` Clément Léger
2022-05-20 15:44           ` Vladimir Oltean
2022-05-20 15:49             ` Clément Léger
2022-05-20 15:58               ` Vladimir Oltean
2022-05-20 16:22                 ` Clément Léger
2022-05-19 15:31 ` [PATCH net-next v5 06/13] dt-bindings: net: dsa: add bindings for Renesas RZ/N1 Advanced 5 port switch Clément Léger
2022-05-20  7:13   ` Geert Uytterhoeven
2022-05-20  7:57     ` Clément Léger
2022-05-20  8:01       ` Geert Uytterhoeven
2022-05-20  8:16         ` Clément Léger
2022-05-24  2:34   ` Rob Herring
2022-05-19 15:31 ` [PATCH net-next v5 07/13] net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port switch driver Clément Léger
2022-05-19 18:08   ` Vladimir Oltean
2022-05-20  7:58     ` Clément Léger
2022-05-19 15:31 ` [PATCH net-next v5 08/13] net: dsa: rzn1-a5psw: add statistics support Clément Léger
2022-05-19 18:24   ` Vladimir Oltean
2022-05-19 15:31 ` [PATCH net-next v5 09/13] net: dsa: rzn1-a5psw: add FDB support Clément Léger
2022-05-19 18:12   ` Vladimir Oltean
2022-05-19 15:31 ` [PATCH net-next v5 10/13] ARM: dts: r9a06g032: describe MII converter Clément Léger
2022-05-19 15:31 ` [PATCH net-next v5 11/13] ARM: dts: r9a06g032: describe GMAC2 Clément Léger
2022-05-20  7:18   ` Geert Uytterhoeven
2022-05-20  8:13     ` Clément Léger
2022-05-20  8:25       ` Geert Uytterhoeven
2022-05-20  8:31         ` Clément Léger
2022-05-20  8:48           ` Geert Uytterhoeven
2022-05-19 15:31 ` [PATCH net-next v5 12/13] ARM: dts: r9a06g032: describe switch Clément Léger
2022-05-19 18:28   ` Vladimir Oltean
2022-05-20  8:18     ` Clément Léger
2022-05-19 15:31 ` [PATCH net-next v5 13/13] MAINTAINERS: add Renesas RZ/N1 switch related driver entry Clément Léger

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).