All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module
@ 2023-12-20  4:24 Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops Luiz Angelo Daros de Luca
                   ` (7 more replies)
  0 siblings, 8 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

The current driver consists of two interface modules (SMI and MDIO) and two family/variant modules (RTL8365MB and RTL8366RB). The SMI and MDIO modules serve as the platform and MDIO drivers, respectively, calling functions from the variant modules. In this setup, one interface module can be loaded independently of the other, but both variants must be loaded (if not disabled at build time) for any type of interface. This approach doesn't scale well, especially with the addition of more switch variants (e.g., RTL8366B), leading to loaded but unused modules. Additionally, this also seems to be upside down, as the specific driver code normally depends on the more generic functions and not the other way around.

The series begins by removing an unused function pointer at realtek_ops->cleanup.

Each variant module was converted into real drivers, serving as both a platform driver (for switches connected using the SMI interface) and an MDIO driver (for MDIO-connected switches). The relationship between the variant and interface modules is reversed, with the variant module now calling both interface functions (if not disabled at build time). While in most devices only one interface is likely used, the interface code is significantly smaller than a variant module, consuming fewer resources than the previous code. With variant modules now functioning as real drivers, compatible strings are published only in a single variant module, preventing conflicts.

The patch series introduces a new common module for functions shared by both variants. This module also absorbs the two previous interface modules, as they would always be loaded anyway.

The series relocates the user MII driver from realtek-smi to common. It is now used by MDIO-connected switches instead of the generic DSA driver. There's a change in how this driver locates the MDIO node. It now searches for either a child named "mdio" (compatible with realtek-mdio and binding docs) or a child with the compatible string (compatible with realtek-smi).

The dsa_switch in realtek_priv->ds is now embedded in the struct. It is always in use and avoids dynamic memory allocation.

Testing has been performed with an RTL8367S (rtl8365mb) using MDIO interface and an RTL8366RB (rtl8366) with SMI interface.

Luiz

---

Changes:

v1-v2:
1) Renamed realtek_common module to realtek-dsa.
2) Removed the warning when the MDIO node is not named "mdio."
3) ds->user_mii_bus is only assigned if all user ports do not have a phy-handle.
4) of_node_put is now back to the driver remove method.
5) Renamed realtek_common_probe_{pre,post} to realtek_common_{probe,register_switch}.
6) Added some comments for realtek_common_{probe,register_switch}.
7) Using dev_err_probe whenever possible.
8) Embedded priv->ds into realtek_priv, removing its dynamic allocation.
9) Fixed realtek-common.h macros.
10) Save and check the return value in functions, even when it is the last one.
11) Added the #if expression as a comment to #else and #endif in header files.
12) Unregister the platform and the MDIO driver in the reverse order they are registered.
13) Unregister the first driver if the second one failed to register.
14) Added the revert patch for "net: dsa: OF-ware slave_mii_bus."



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

* [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20 13:57   ` Alvin Šipraga
  2023-12-20  4:24 ` [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers Luiz Angelo Daros de Luca
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

It was never used and never referenced.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
---
 drivers/net/dsa/realtek/realtek.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index 790488e9c667..e9ee778665b2 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -91,7 +91,6 @@ struct realtek_ops {
 	int	(*detect)(struct realtek_priv *priv);
 	int	(*reset_chip)(struct realtek_priv *priv);
 	int	(*setup)(struct realtek_priv *priv);
-	void	(*cleanup)(struct realtek_priv *priv);
 	int	(*get_mib_counter)(struct realtek_priv *priv,
 				   int port,
 				   struct rtl8366_mib_counter *mib,
-- 
2.43.0


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

* [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-21 17:08   ` Vladimir Oltean
  2023-12-20  4:24 ` [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module Luiz Angelo Daros de Luca
                   ` (5 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

Previously, the interface modules realtek-smi and realtek-mdio served as
a platform and an MDIO driver, respectively. Each interface module
redundantly specified the same compatible strings for both variants and
referenced symbols from the variants.

Now, each variant module has been transformed into a unified driver
serving both as a platform and an MDIO driver. This modification
reverses the relationship between the interface and variant modules,
with the variant module now utilizing symbols from the interface
modules.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/Kconfig        | 20 +++-------
 drivers/net/dsa/realtek/realtek-mdio.c | 33 ++++------------
 drivers/net/dsa/realtek/realtek-mdio.h | 48 +++++++++++++++++++++++
 drivers/net/dsa/realtek/realtek-smi.c  | 38 ++++--------------
 drivers/net/dsa/realtek/realtek-smi.h  | 48 +++++++++++++++++++++++
 drivers/net/dsa/realtek/rtl8365mb.c    | 54 +++++++++++++++++++++++++-
 drivers/net/dsa/realtek/rtl8366rb.c    | 54 +++++++++++++++++++++++++-
 7 files changed, 222 insertions(+), 73 deletions(-)
 create mode 100644 drivers/net/dsa/realtek/realtek-mdio.h
 create mode 100644 drivers/net/dsa/realtek/realtek-smi.h

diff --git a/drivers/net/dsa/realtek/Kconfig b/drivers/net/dsa/realtek/Kconfig
index 060165a85fb7..9d182fde11b4 100644
--- a/drivers/net/dsa/realtek/Kconfig
+++ b/drivers/net/dsa/realtek/Kconfig
@@ -16,37 +16,29 @@ menuconfig NET_DSA_REALTEK
 if NET_DSA_REALTEK
 
 config NET_DSA_REALTEK_MDIO
-	tristate "Realtek MDIO interface driver"
+	tristate "Realtek MDIO interface support"
 	depends on OF
-	depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
-	depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
-	depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
 	help
 	  Select to enable support for registering switches configured
 	  through MDIO.
 
 config NET_DSA_REALTEK_SMI
-	tristate "Realtek SMI interface driver"
+	tristate "Realtek SMI interface support"
 	depends on OF
-	depends on NET_DSA_REALTEK_RTL8365MB || NET_DSA_REALTEK_RTL8366RB
-	depends on NET_DSA_REALTEK_RTL8365MB || !NET_DSA_REALTEK_RTL8365MB
-	depends on NET_DSA_REALTEK_RTL8366RB || !NET_DSA_REALTEK_RTL8366RB
 	help
 	  Select to enable support for registering switches connected
 	  through SMI.
 
 config NET_DSA_REALTEK_RTL8365MB
-	tristate "Realtek RTL8365MB switch subdriver"
-	imply NET_DSA_REALTEK_SMI
-	imply NET_DSA_REALTEK_MDIO
+	tristate "Realtek RTL8365MB switch driver"
+	depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
 	select NET_DSA_TAG_RTL8_4
 	help
 	  Select to enable support for Realtek RTL8365MB-VC and RTL8367S.
 
 config NET_DSA_REALTEK_RTL8366RB
-	tristate "Realtek RTL8366RB switch subdriver"
-	imply NET_DSA_REALTEK_SMI
-	imply NET_DSA_REALTEK_MDIO
+	tristate "Realtek RTL8366RB switch driver"
+	depends on NET_DSA_REALTEK_SMI || NET_DSA_REALTEK_MDIO
 	select NET_DSA_TAG_RTL4_A
 	help
 	  Select to enable support for Realtek RTL8366RB.
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 292e6d087e8b..58966d0625c8 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -25,6 +25,7 @@
 #include <linux/regmap.h>
 
 #include "realtek.h"
+#include "realtek-mdio.h"
 
 /* Read/write via mdiobus */
 #define REALTEK_MDIO_CTRL0_REG		31
@@ -140,7 +141,7 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
 	.disable_locking = true,
 };
 
-static int realtek_mdio_probe(struct mdio_device *mdiodev)
+int realtek_mdio_probe(struct mdio_device *mdiodev)
 {
 	struct realtek_priv *priv;
 	struct device *dev = &mdiodev->dev;
@@ -235,8 +236,9 @@ static int realtek_mdio_probe(struct mdio_device *mdiodev)
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(realtek_mdio_probe);
 
-static void realtek_mdio_remove(struct mdio_device *mdiodev)
+void realtek_mdio_remove(struct mdio_device *mdiodev)
 {
 	struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
 
@@ -249,8 +251,9 @@ static void realtek_mdio_remove(struct mdio_device *mdiodev)
 	if (priv->reset)
 		gpiod_set_value(priv->reset, 1);
 }
+EXPORT_SYMBOL_GPL(realtek_mdio_remove);
 
-static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
+void realtek_mdio_shutdown(struct mdio_device *mdiodev)
 {
 	struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
 
@@ -261,29 +264,7 @@ static void realtek_mdio_shutdown(struct mdio_device *mdiodev)
 
 	dev_set_drvdata(&mdiodev->dev, NULL);
 }
-
-static const struct of_device_id realtek_mdio_of_match[] = {
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
-	{ .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
-	{ .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
-#endif
-	{ /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, realtek_mdio_of_match);
-
-static struct mdio_driver realtek_mdio_driver = {
-	.mdiodrv.driver = {
-		.name = "realtek-mdio",
-		.of_match_table = realtek_mdio_of_match,
-	},
-	.probe  = realtek_mdio_probe,
-	.remove = realtek_mdio_remove,
-	.shutdown = realtek_mdio_shutdown,
-};
-
-mdio_module_driver(realtek_mdio_driver);
+EXPORT_SYMBOL_GPL(realtek_mdio_shutdown);
 
 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
 MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
diff --git a/drivers/net/dsa/realtek/realtek-mdio.h b/drivers/net/dsa/realtek/realtek-mdio.h
new file mode 100644
index 000000000000..ee70f6a5b8ff
--- /dev/null
+++ b/drivers/net/dsa/realtek/realtek-mdio.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _REALTEK_MDIO_H
+#define _REALTEK_MDIO_H
+
+#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO)
+
+static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
+{
+	return mdio_driver_register(drv);
+}
+
+static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
+{
+	mdio_driver_unregister(drv);
+}
+
+int realtek_mdio_probe(struct mdio_device *mdiodev);
+void realtek_mdio_remove(struct mdio_device *mdiodev);
+void realtek_mdio_shutdown(struct mdio_device *mdiodev);
+
+#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
+
+static inline int realtek_mdio_driver_register(struct mdio_driver *drv)
+{
+	return 0;
+}
+
+static inline void realtek_mdio_driver_unregister(struct mdio_driver *drv)
+{
+}
+
+static inline int realtek_mdio_probe(struct mdio_device *mdiodev)
+{
+	return -ENOENT;
+}
+
+static inline void realtek_mdio_remove(struct mdio_device *mdiodev)
+{
+}
+
+static inline void realtek_mdio_shutdown(struct mdio_device *mdiodev)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_MDIO) */
+
+#endif /* _REALTEK_MDIO_H */
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index 755546ed8db6..31ac409acfd0 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -40,6 +40,7 @@
 #include <linux/if_bridge.h>
 
 #include "realtek.h"
+#include "realtek-smi.h"
 
 #define REALTEK_SMI_ACK_RETRY_COUNT		5
 
@@ -408,7 +409,7 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
 	return ret;
 }
 
-static int realtek_smi_probe(struct platform_device *pdev)
+int realtek_smi_probe(struct platform_device *pdev)
 {
 	const struct realtek_variant *var;
 	struct device *dev = &pdev->dev;
@@ -505,8 +506,9 @@ static int realtek_smi_probe(struct platform_device *pdev)
 	}
 	return 0;
 }
+EXPORT_SYMBOL_GPL(realtek_smi_probe);
 
-static void realtek_smi_remove(struct platform_device *pdev)
+void realtek_smi_remove(struct platform_device *pdev)
 {
 	struct realtek_priv *priv = platform_get_drvdata(pdev);
 
@@ -521,8 +523,9 @@ static void realtek_smi_remove(struct platform_device *pdev)
 	if (priv->reset)
 		gpiod_set_value(priv->reset, 1);
 }
+EXPORT_SYMBOL_GPL(realtek_smi_remove);
 
-static void realtek_smi_shutdown(struct platform_device *pdev)
+void realtek_smi_shutdown(struct platform_device *pdev)
 {
 	struct realtek_priv *priv = platform_get_drvdata(pdev);
 
@@ -533,34 +536,7 @@ static void realtek_smi_shutdown(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, NULL);
 }
-
-static const struct of_device_id realtek_smi_of_match[] = {
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8366RB)
-	{
-		.compatible = "realtek,rtl8366rb",
-		.data = &rtl8366rb_variant,
-	},
-#endif
-#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_RTL8365MB)
-	{
-		.compatible = "realtek,rtl8365mb",
-		.data = &rtl8365mb_variant,
-	},
-#endif
-	{ /* sentinel */ },
-};
-MODULE_DEVICE_TABLE(of, realtek_smi_of_match);
-
-static struct platform_driver realtek_smi_driver = {
-	.driver = {
-		.name = "realtek-smi",
-		.of_match_table = realtek_smi_of_match,
-	},
-	.probe  = realtek_smi_probe,
-	.remove_new = realtek_smi_remove,
-	.shutdown = realtek_smi_shutdown,
-};
-module_platform_driver(realtek_smi_driver);
+EXPORT_SYMBOL_GPL(realtek_smi_shutdown);
 
 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
diff --git a/drivers/net/dsa/realtek/realtek-smi.h b/drivers/net/dsa/realtek/realtek-smi.h
new file mode 100644
index 000000000000..ea49a2edd3c8
--- /dev/null
+++ b/drivers/net/dsa/realtek/realtek-smi.h
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _REALTEK_SMI_H
+#define _REALTEK_SMI_H
+
+#if IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI)
+
+static inline int realtek_smi_driver_register(struct platform_driver *drv)
+{
+	return platform_driver_register(drv);
+}
+
+static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
+{
+	platform_driver_unregister(drv);
+}
+
+int realtek_smi_probe(struct platform_device *pdev);
+void realtek_smi_remove(struct platform_device *pdev);
+void realtek_smi_shutdown(struct platform_device *pdev);
+
+#else /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
+
+static inline int realtek_smi_driver_register(struct platform_driver *drv)
+{
+	return 0;
+}
+
+static inline void realtek_smi_driver_unregister(struct platform_driver *drv)
+{
+}
+
+static inline int realtek_smi_probe(struct platform_device *pdev)
+{
+	return -ENOENT;
+}
+
+static inline void realtek_smi_remove(struct platform_device *pdev)
+{
+}
+
+static inline void realtek_smi_shutdown(struct platform_device *pdev)
+{
+}
+
+#endif /* IS_ENABLED(CONFIG_NET_DSA_REALTEK_SMI) */
+
+#endif  /* _REALTEK_SMI_H */
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index 0875e4fc9f57..1ace2239934a 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -101,6 +101,8 @@
 #include <linux/if_vlan.h>
 
 #include "realtek.h"
+#include "realtek-smi.h"
+#include "realtek-mdio.h"
 
 /* Family-specific data and limits */
 #define RTL8365MB_PHYADDRMAX		7
@@ -2172,7 +2174,57 @@ const struct realtek_variant rtl8365mb_variant = {
 	.cmd_write = 0xb8,
 	.chip_data_sz = sizeof(struct rtl8365mb),
 };
-EXPORT_SYMBOL_GPL(rtl8365mb_variant);
+
+static const struct of_device_id rtl8365mb_of_match[] = {
+	{ .compatible = "realtek,rtl8365mb", .data = &rtl8365mb_variant, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, rtl8365mb_of_match);
+
+static struct platform_driver rtl8365mb_smi_driver = {
+	.driver = {
+		.name = "rtl8365mb-smi",
+		.of_match_table = rtl8365mb_of_match,
+	},
+	.probe  = realtek_smi_probe,
+	.remove_new = realtek_smi_remove,
+	.shutdown = realtek_smi_shutdown,
+};
+
+static struct mdio_driver rtl8365mb_mdio_driver = {
+	.mdiodrv.driver = {
+		.name = "rtl8365mb-mdio",
+		.of_match_table = rtl8365mb_of_match,
+	},
+	.probe  = realtek_mdio_probe,
+	.remove = realtek_mdio_remove,
+	.shutdown = realtek_mdio_shutdown,
+};
+
+static int rtl8365mb_init(void)
+{
+	int ret;
+
+	ret = realtek_mdio_driver_register(&rtl8365mb_mdio_driver);
+	if (ret)
+		return ret;
+
+	ret = platform_driver_register(&rtl8365mb_smi_driver);
+	if (ret) {
+		realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
+		return ret;
+	}
+
+	return 0;
+}
+module_init(rtl8365mb_init);
+
+static void __exit rtl8365mb_exit(void)
+{
+	platform_driver_unregister(&rtl8365mb_smi_driver);
+	realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
+}
+module_exit(rtl8365mb_exit);
 
 MODULE_AUTHOR("Alvin Šipraga <alsi@bang-olufsen.dk>");
 MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch");
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index b39b719a5b8f..cc2fd636ec23 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -22,6 +22,8 @@
 #include <linux/regmap.h>
 
 #include "realtek.h"
+#include "realtek-smi.h"
+#include "realtek-mdio.h"
 
 #define RTL8366RB_PORT_NUM_CPU		5
 #define RTL8366RB_NUM_PORTS		6
@@ -1920,7 +1922,57 @@ const struct realtek_variant rtl8366rb_variant = {
 	.cmd_write = 0xa8,
 	.chip_data_sz = sizeof(struct rtl8366rb),
 };
-EXPORT_SYMBOL_GPL(rtl8366rb_variant);
+
+static const struct of_device_id rtl8366rb_of_match[] = {
+	{ .compatible = "realtek,rtl8366rb", .data = &rtl8366rb_variant, },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, rtl8366rb_of_match);
+
+static struct platform_driver rtl8366rb_smi_driver = {
+	.driver = {
+		.name = "rtl8366rb-smi",
+		.of_match_table = rtl8366rb_of_match,
+	},
+	.probe  = realtek_smi_probe,
+	.remove_new = realtek_smi_remove,
+	.shutdown = realtek_smi_shutdown,
+};
+
+static struct mdio_driver rtl8366rb_mdio_driver = {
+	.mdiodrv.driver = {
+		.name = "rtl8366rb-mdio",
+		.of_match_table = rtl8366rb_of_match,
+	},
+	.probe  = realtek_mdio_probe,
+	.remove = realtek_mdio_remove,
+	.shutdown = realtek_mdio_shutdown,
+};
+
+static int rtl8366rb_init(void)
+{
+	int ret;
+
+	ret = realtek_mdio_driver_register(&rtl8366rb_mdio_driver);
+	if (ret)
+		return ret;
+
+	ret = realtek_smi_driver_register(&rtl8366rb_smi_driver);
+	if (ret) {
+		realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
+		return ret;
+	}
+
+	return 0;
+}
+module_init(rtl8366rb_init);
+
+static void __exit rtl8366rb_exit(void)
+{
+	realtek_smi_driver_unregister(&rtl8366rb_smi_driver);
+	realtek_mdio_driver_unregister(&rtl8366rb_mdio_driver);
+}
+module_exit(rtl8366rb_exit);
 
 MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 MODULE_DESCRIPTION("Driver for RTL8366RB ethernet switch");
-- 
2.43.0


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

* [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20 10:40   ` Alvin Šipraga
  2023-12-20  4:24 ` [PATCH net-next v2 4/7] net: dsa: realtek: merge common and interface modules into realtek-dsa Luiz Angelo Daros de Luca
                   ` (4 subsequent siblings)
  7 siblings, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

Some code can be shared between both interface modules (MDIO and SMI)
and among variants. These interface functions migrated to a common
module:

- realtek_common_lock
- realtek_common_unlock
- realtek_common_probe
- realtek_common_register_switch
- realtek_common_remove

The reset during probe was moved to the end of the common probe. This way,
we avoid a reset if anything else fails.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/Makefile         |   2 +
 drivers/net/dsa/realtek/realtek-common.c | 137 +++++++++++++++++++++++
 drivers/net/dsa/realtek/realtek-common.h |  16 +++
 drivers/net/dsa/realtek/realtek-mdio.c   | 114 +++----------------
 drivers/net/dsa/realtek/realtek-smi.c    | 117 +++----------------
 drivers/net/dsa/realtek/realtek.h        |   6 +-
 drivers/net/dsa/realtek/rtl8365mb.c      |   9 +-
 drivers/net/dsa/realtek/rtl8366rb.c      |   9 +-
 8 files changed, 199 insertions(+), 211 deletions(-)
 create mode 100644 drivers/net/dsa/realtek/realtek-common.c
 create mode 100644 drivers/net/dsa/realtek/realtek-common.h

diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
index 0aab57252a7c..f4f9c6340d5f 100644
--- a/drivers/net/dsa/realtek/Makefile
+++ b/drivers/net/dsa/realtek/Makefile
@@ -1,4 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
+obj-$(CONFIG_NET_DSA_REALTEK)		+= realtek-dsa.o
+realtek-dsa-objs			:= realtek-common.o
 obj-$(CONFIG_NET_DSA_REALTEK_MDIO) 	+= realtek-mdio.o
 obj-$(CONFIG_NET_DSA_REALTEK_SMI) 	+= realtek-smi.o
 obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
new file mode 100644
index 000000000000..c7507b6cdcdd
--- /dev/null
+++ b/drivers/net/dsa/realtek/realtek-common.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/module.h>
+
+#include "realtek.h"
+#include "realtek-common.h"
+
+void realtek_common_lock(void *ctx)
+{
+	struct realtek_priv *priv = ctx;
+
+	mutex_lock(&priv->map_lock);
+}
+EXPORT_SYMBOL_GPL(realtek_common_lock);
+
+void realtek_common_unlock(void *ctx)
+{
+	struct realtek_priv *priv = ctx;
+
+	mutex_unlock(&priv->map_lock);
+}
+EXPORT_SYMBOL_GPL(realtek_common_unlock);
+
+/* sets up driver private data struct, sets up regmaps, parse common device-tree
+ * properties and finally issues a hardware reset.
+ */
+struct realtek_priv *
+realtek_common_probe(struct device *dev, struct regmap_config rc,
+		     struct regmap_config rc_nolock)
+{
+	const struct realtek_variant *var;
+	struct realtek_priv *priv;
+	int ret;
+
+	var = of_device_get_match_data(dev);
+	if (!var)
+		return ERR_PTR(-EINVAL);
+
+	priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
+			    GFP_KERNEL);
+	if (!priv)
+		return ERR_PTR(-ENOMEM);
+
+	mutex_init(&priv->map_lock);
+
+	rc.lock_arg = priv;
+	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
+	if (IS_ERR(priv->map)) {
+		ret = PTR_ERR(priv->map);
+		dev_err(dev, "regmap init failed: %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
+	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc_nolock);
+	if (IS_ERR(priv->map_nolock)) {
+		ret = PTR_ERR(priv->map_nolock);
+		dev_err(dev, "regmap init failed: %d\n", ret);
+		return ERR_PTR(ret);
+	}
+
+	/* Link forward and backward */
+	priv->dev = dev;
+	priv->variant = var;
+	priv->ops = var->ops;
+	priv->chip_data = (void *)priv + sizeof(*priv);
+
+	dev_set_drvdata(dev, priv);
+	spin_lock_init(&priv->lock);
+
+	priv->leds_disabled = of_property_read_bool(dev->of_node,
+						    "realtek,disable-leds");
+
+	/* TODO: if power is software controlled, set up any regulators here */
+
+	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
+	if (IS_ERR(priv->reset)) {
+		dev_err(dev, "failed to get RESET GPIO\n");
+		return ERR_CAST(priv->reset);
+	}
+	if (priv->reset) {
+		gpiod_set_value(priv->reset, 1);
+		dev_dbg(dev, "asserted RESET\n");
+		msleep(REALTEK_HW_STOP_DELAY);
+		gpiod_set_value(priv->reset, 0);
+		msleep(REALTEK_HW_START_DELAY);
+		dev_dbg(dev, "deasserted RESET\n");
+	}
+
+	return priv;
+}
+EXPORT_SYMBOL(realtek_common_probe);
+
+/* Detects the realtek switch id/version and registers the dsa switch.
+ */
+int realtek_common_register_switch(struct realtek_priv *priv)
+{
+	int ret;
+
+	ret = priv->ops->detect(priv);
+	if (ret) {
+		dev_err_probe(priv->dev, ret, "unable to detect switch\n");
+		return ret;
+	}
+
+	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
+	if (!priv->ds)
+		return -ENOMEM;
+
+	priv->ds->priv = priv;
+	priv->ds->dev = priv->dev;
+	priv->ds->ops = priv->ds_ops;
+	priv->ds->num_ports = priv->num_ports;
+
+	ret = dsa_register_switch(priv->ds);
+	if (ret) {
+		dev_err_probe(priv->dev, ret, "unable to register switch\n");
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(realtek_common_register_switch);
+
+void realtek_common_remove(struct realtek_priv *priv)
+{
+	if (!priv)
+		return;
+
+	/* leave the device reset asserted */
+	if (priv->reset)
+		gpiod_set_value(priv->reset, 1);
+}
+EXPORT_SYMBOL(realtek_common_remove);
+
+MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
+MODULE_DESCRIPTION("Realtek DSA switches common module");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
new file mode 100644
index 000000000000..518d091ff496
--- /dev/null
+++ b/drivers/net/dsa/realtek/realtek-common.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _REALTEK_COMMON_H
+#define _REALTEK_COMMON_H
+
+#include <linux/regmap.h>
+
+void realtek_common_lock(void *ctx);
+void realtek_common_unlock(void *ctx);
+struct realtek_priv *
+realtek_common_probe(struct device *dev, struct regmap_config rc,
+		     struct regmap_config rc_nolock);
+int realtek_common_register_switch(struct realtek_priv *priv);
+void realtek_common_remove(struct realtek_priv *priv);
+
+#endif /* _REALTEK_COMMON_H */
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 58966d0625c8..1eed09ab3aa1 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -26,6 +26,7 @@
 
 #include "realtek.h"
 #include "realtek-mdio.h"
+#include "realtek-common.h"
 
 /* Read/write via mdiobus */
 #define REALTEK_MDIO_CTRL0_REG		31
@@ -100,20 +101,6 @@ static int realtek_mdio_read(void *ctx, u32 reg, u32 *val)
 	return ret;
 }
 
-static void realtek_mdio_lock(void *ctx)
-{
-	struct realtek_priv *priv = ctx;
-
-	mutex_lock(&priv->map_lock);
-}
-
-static void realtek_mdio_unlock(void *ctx)
-{
-	struct realtek_priv *priv = ctx;
-
-	mutex_unlock(&priv->map_lock);
-}
-
 static const struct regmap_config realtek_mdio_regmap_config = {
 	.reg_bits = 10, /* A4..A0 R4..R0 */
 	.val_bits = 16,
@@ -124,8 +111,8 @@ static const struct regmap_config realtek_mdio_regmap_config = {
 	.reg_read = realtek_mdio_read,
 	.reg_write = realtek_mdio_write,
 	.cache_type = REGCACHE_NONE,
-	.lock = realtek_mdio_lock,
-	.unlock = realtek_mdio_unlock,
+	.lock = realtek_common_lock,
+	.unlock = realtek_common_unlock,
 };
 
 static const struct regmap_config realtek_mdio_nolock_regmap_config = {
@@ -143,96 +130,23 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
 
 int realtek_mdio_probe(struct mdio_device *mdiodev)
 {
-	struct realtek_priv *priv;
 	struct device *dev = &mdiodev->dev;
-	const struct realtek_variant *var;
-	struct regmap_config rc;
-	struct device_node *np;
+	struct realtek_priv *priv;
 	int ret;
 
-	var = of_device_get_match_data(dev);
-	if (!var)
-		return -EINVAL;
-
-	priv = devm_kzalloc(&mdiodev->dev,
-			    size_add(sizeof(*priv), var->chip_data_sz),
-			    GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-
-	mutex_init(&priv->map_lock);
+	priv = realtek_common_probe(dev, realtek_mdio_regmap_config,
+				    realtek_mdio_nolock_regmap_config);
+	if (IS_ERR(priv))
+		return PTR_ERR(priv);
 
-	rc = realtek_mdio_regmap_config;
-	rc.lock_arg = priv;
-	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
-	if (IS_ERR(priv->map)) {
-		ret = PTR_ERR(priv->map);
-		dev_err(dev, "regmap init failed: %d\n", ret);
-		return ret;
-	}
-
-	rc = realtek_mdio_nolock_regmap_config;
-	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
-	if (IS_ERR(priv->map_nolock)) {
-		ret = PTR_ERR(priv->map_nolock);
-		dev_err(dev, "regmap init failed: %d\n", ret);
-		return ret;
-	}
-
-	priv->mdio_addr = mdiodev->addr;
 	priv->bus = mdiodev->bus;
-	priv->dev = &mdiodev->dev;
-	priv->chip_data = (void *)priv + sizeof(*priv);
-
-	priv->clk_delay = var->clk_delay;
-	priv->cmd_read = var->cmd_read;
-	priv->cmd_write = var->cmd_write;
-	priv->ops = var->ops;
-
+	priv->mdio_addr = mdiodev->addr;
 	priv->write_reg_noack = realtek_mdio_write;
+	priv->ds_ops = priv->variant->ds_ops_mdio;
 
-	np = dev->of_node;
-
-	dev_set_drvdata(dev, priv);
-
-	/* TODO: if power is software controlled, set up any regulators here */
-	priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
-
-	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(priv->reset)) {
-		dev_err(dev, "failed to get RESET GPIO\n");
-		return PTR_ERR(priv->reset);
-	}
-
-	if (priv->reset) {
-		gpiod_set_value(priv->reset, 1);
-		dev_dbg(dev, "asserted RESET\n");
-		msleep(REALTEK_HW_STOP_DELAY);
-		gpiod_set_value(priv->reset, 0);
-		msleep(REALTEK_HW_START_DELAY);
-		dev_dbg(dev, "deasserted RESET\n");
-	}
-
-	ret = priv->ops->detect(priv);
-	if (ret) {
-		dev_err(dev, "unable to detect switch\n");
-		return ret;
-	}
-
-	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
-	if (!priv->ds)
-		return -ENOMEM;
-
-	priv->ds->dev = dev;
-	priv->ds->num_ports = priv->num_ports;
-	priv->ds->priv = priv;
-	priv->ds->ops = var->ds_ops_mdio;
-
-	ret = dsa_register_switch(priv->ds);
-	if (ret) {
-		dev_err(priv->dev, "unable to register switch ret = %d\n", ret);
+	ret = realtek_common_register_switch(priv);
+	if (ret)
 		return ret;
-	}
 
 	return 0;
 }
@@ -247,9 +161,7 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
 
 	dsa_unregister_switch(priv->ds);
 
-	/* leave the device reset asserted */
-	if (priv->reset)
-		gpiod_set_value(priv->reset, 1);
+	realtek_common_remove(priv);
 }
 EXPORT_SYMBOL_GPL(realtek_mdio_remove);
 
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index 31ac409acfd0..fc54190839cf 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -41,12 +41,13 @@
 
 #include "realtek.h"
 #include "realtek-smi.h"
+#include "realtek-common.h"
 
 #define REALTEK_SMI_ACK_RETRY_COUNT		5
 
 static inline void realtek_smi_clk_delay(struct realtek_priv *priv)
 {
-	ndelay(priv->clk_delay);
+	ndelay(priv->variant->clk_delay);
 }
 
 static void realtek_smi_start(struct realtek_priv *priv)
@@ -209,7 +210,7 @@ static int realtek_smi_read_reg(struct realtek_priv *priv, u32 addr, u32 *data)
 	realtek_smi_start(priv);
 
 	/* Send READ command */
-	ret = realtek_smi_write_byte(priv, priv->cmd_read);
+	ret = realtek_smi_write_byte(priv, priv->variant->cmd_read);
 	if (ret)
 		goto out;
 
@@ -250,7 +251,7 @@ static int realtek_smi_write_reg(struct realtek_priv *priv,
 	realtek_smi_start(priv);
 
 	/* Send WRITE command */
-	ret = realtek_smi_write_byte(priv, priv->cmd_write);
+	ret = realtek_smi_write_byte(priv, priv->variant->cmd_write);
 	if (ret)
 		goto out;
 
@@ -311,20 +312,6 @@ static int realtek_smi_read(void *ctx, u32 reg, u32 *val)
 	return realtek_smi_read_reg(priv, reg, val);
 }
 
-static void realtek_smi_lock(void *ctx)
-{
-	struct realtek_priv *priv = ctx;
-
-	mutex_lock(&priv->map_lock);
-}
-
-static void realtek_smi_unlock(void *ctx)
-{
-	struct realtek_priv *priv = ctx;
-
-	mutex_unlock(&priv->map_lock);
-}
-
 static const struct regmap_config realtek_smi_regmap_config = {
 	.reg_bits = 10, /* A4..A0 R4..R0 */
 	.val_bits = 16,
@@ -335,8 +322,8 @@ static const struct regmap_config realtek_smi_regmap_config = {
 	.reg_read = realtek_smi_read,
 	.reg_write = realtek_smi_write,
 	.cache_type = REGCACHE_NONE,
-	.lock = realtek_smi_lock,
-	.unlock = realtek_smi_unlock,
+	.lock = realtek_common_lock,
+	.unlock = realtek_common_unlock,
 };
 
 static const struct regmap_config realtek_smi_nolock_regmap_config = {
@@ -411,99 +398,32 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
 
 int realtek_smi_probe(struct platform_device *pdev)
 {
-	const struct realtek_variant *var;
 	struct device *dev = &pdev->dev;
 	struct realtek_priv *priv;
-	struct regmap_config rc;
-	struct device_node *np;
 	int ret;
 
-	var = of_device_get_match_data(dev);
-	np = dev->of_node;
-
-	priv = devm_kzalloc(dev, sizeof(*priv) + var->chip_data_sz, GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	priv->chip_data = (void *)priv + sizeof(*priv);
-
-	mutex_init(&priv->map_lock);
-
-	rc = realtek_smi_regmap_config;
-	rc.lock_arg = priv;
-	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
-	if (IS_ERR(priv->map)) {
-		ret = PTR_ERR(priv->map);
-		dev_err(dev, "regmap init failed: %d\n", ret);
-		return ret;
-	}
-
-	rc = realtek_smi_nolock_regmap_config;
-	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
-	if (IS_ERR(priv->map_nolock)) {
-		ret = PTR_ERR(priv->map_nolock);
-		dev_err(dev, "regmap init failed: %d\n", ret);
-		return ret;
-	}
-
-	/* Link forward and backward */
-	priv->dev = dev;
-	priv->clk_delay = var->clk_delay;
-	priv->cmd_read = var->cmd_read;
-	priv->cmd_write = var->cmd_write;
-	priv->ops = var->ops;
-
-	priv->setup_interface = realtek_smi_setup_mdio;
-	priv->write_reg_noack = realtek_smi_write_reg_noack;
-
-	dev_set_drvdata(dev, priv);
-	spin_lock_init(&priv->lock);
-
-	/* TODO: if power is software controlled, set up any regulators here */
-
-	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
-	if (IS_ERR(priv->reset)) {
-		dev_err(dev, "failed to get RESET GPIO\n");
-		return PTR_ERR(priv->reset);
-	}
-	if (priv->reset) {
-		gpiod_set_value(priv->reset, 1);
-		dev_dbg(dev, "asserted RESET\n");
-		msleep(REALTEK_HW_STOP_DELAY);
-		gpiod_set_value(priv->reset, 0);
-		msleep(REALTEK_HW_START_DELAY);
-		dev_dbg(dev, "deasserted RESET\n");
-	}
+	priv = realtek_common_probe(dev, realtek_smi_regmap_config,
+				    realtek_smi_nolock_regmap_config);
+	if (IS_ERR(priv))
+		return PTR_ERR(priv);
 
 	/* Fetch MDIO pins */
 	priv->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW);
 	if (IS_ERR(priv->mdc))
 		return PTR_ERR(priv->mdc);
+
 	priv->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW);
 	if (IS_ERR(priv->mdio))
 		return PTR_ERR(priv->mdio);
 
-	priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
+	priv->write_reg_noack = realtek_smi_write_reg_noack;
+	priv->setup_interface = realtek_smi_setup_mdio;
+	priv->ds_ops = priv->variant->ds_ops_smi;
 
-	ret = priv->ops->detect(priv);
-	if (ret) {
-		dev_err(dev, "unable to detect switch\n");
+	ret = realtek_common_register_switch(priv);
+	if (ret)
 		return ret;
-	}
-
-	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
-	if (!priv->ds)
-		return -ENOMEM;
 
-	priv->ds->dev = dev;
-	priv->ds->num_ports = priv->num_ports;
-	priv->ds->priv = priv;
-
-	priv->ds->ops = var->ds_ops_smi;
-	ret = dsa_register_switch(priv->ds);
-	if (ret) {
-		dev_err_probe(dev, ret, "unable to register switch\n");
-		return ret;
-	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(realtek_smi_probe);
@@ -516,12 +436,11 @@ void realtek_smi_remove(struct platform_device *pdev)
 		return;
 
 	dsa_unregister_switch(priv->ds);
+
 	if (priv->user_mii_bus)
 		of_node_put(priv->user_mii_bus->dev.of_node);
 
-	/* leave the device reset asserted */
-	if (priv->reset)
-		gpiod_set_value(priv->reset, 1);
+	realtek_common_remove(priv);
 }
 EXPORT_SYMBOL_GPL(realtek_smi_remove);
 
diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index e9ee778665b2..fbd0616c1df3 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -58,11 +58,9 @@ struct realtek_priv {
 	struct mii_bus		*bus;
 	int			mdio_addr;
 
-	unsigned int		clk_delay;
-	u8			cmd_read;
-	u8			cmd_write;
 	spinlock_t		lock; /* Locks around command writes */
 	struct dsa_switch	*ds;
+	const struct dsa_switch_ops *ds_ops;
 	struct irq_domain	*irqdomain;
 	bool			leds_disabled;
 
@@ -79,6 +77,8 @@ struct realtek_priv {
 	int			vlan_enabled;
 	int			vlan4k_enabled;
 
+	const struct realtek_variant *variant;
+
 	char			buf[4096];
 	void			*chip_data; /* Per-chip extra variant data */
 };
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index 1ace2239934a..58ec057b6c32 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -103,6 +103,7 @@
 #include "realtek.h"
 #include "realtek-smi.h"
 #include "realtek-mdio.h"
+#include "realtek-common.h"
 
 /* Family-specific data and limits */
 #define RTL8365MB_PHYADDRMAX		7
@@ -691,7 +692,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
 	u32 val;
 	int ret;
 
-	mutex_lock(&priv->map_lock);
+	realtek_common_lock(priv);
 
 	ret = rtl8365mb_phy_poll_busy(priv);
 	if (ret)
@@ -724,7 +725,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
 	*data = val & 0xFFFF;
 
 out:
-	mutex_unlock(&priv->map_lock);
+	realtek_common_unlock(priv);
 
 	return ret;
 }
@@ -735,7 +736,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
 	u32 val;
 	int ret;
 
-	mutex_lock(&priv->map_lock);
+	realtek_common_lock(priv);
 
 	ret = rtl8365mb_phy_poll_busy(priv);
 	if (ret)
@@ -766,7 +767,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
 		goto out;
 
 out:
-	mutex_unlock(&priv->map_lock);
+	realtek_common_unlock(priv);
 
 	return 0;
 }
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index cc2fd636ec23..e60a0a81d426 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -24,6 +24,7 @@
 #include "realtek.h"
 #include "realtek-smi.h"
 #include "realtek-mdio.h"
+#include "realtek-common.h"
 
 #define RTL8366RB_PORT_NUM_CPU		5
 #define RTL8366RB_NUM_PORTS		6
@@ -1707,7 +1708,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
 	if (phy > RTL8366RB_PHY_NO_MAX)
 		return -EINVAL;
 
-	mutex_lock(&priv->map_lock);
+	realtek_common_lock(priv);
 
 	ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
 			   RTL8366RB_PHY_CTRL_READ);
@@ -1735,7 +1736,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
 		phy, regnum, reg, val);
 
 out:
-	mutex_unlock(&priv->map_lock);
+	realtek_common_unlock(priv);
 
 	return ret;
 }
@@ -1749,7 +1750,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
 	if (phy > RTL8366RB_PHY_NO_MAX)
 		return -EINVAL;
 
-	mutex_lock(&priv->map_lock);
+	realtek_common_lock(priv);
 
 	ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
 			   RTL8366RB_PHY_CTRL_WRITE);
@@ -1766,7 +1767,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
 		goto out;
 
 out:
-	mutex_unlock(&priv->map_lock);
+	realtek_common_unlock(priv);
 
 	return ret;
 }
-- 
2.43.0


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

* [PATCH net-next v2 4/7] net: dsa: realtek: merge common and interface modules into realtek-dsa
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
                   ` (2 preceding siblings ...)
  2023-12-20  4:24 ` [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa Luiz Angelo Daros de Luca
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

Since realtek-common and realtek-{smi,mdio} are always loaded together,
we can optimize resource usage by consolidating them into a single
module.

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/Kconfig          | 4 ++--
 drivers/net/dsa/realtek/Makefile         | 7 ++++---
 drivers/net/dsa/realtek/realtek-common.c | 1 +
 drivers/net/dsa/realtek/realtek-mdio.c   | 4 ----
 drivers/net/dsa/realtek/realtek-smi.c    | 4 ----
 5 files changed, 7 insertions(+), 13 deletions(-)

diff --git a/drivers/net/dsa/realtek/Kconfig b/drivers/net/dsa/realtek/Kconfig
index 9d182fde11b4..6989972eebc3 100644
--- a/drivers/net/dsa/realtek/Kconfig
+++ b/drivers/net/dsa/realtek/Kconfig
@@ -16,14 +16,14 @@ menuconfig NET_DSA_REALTEK
 if NET_DSA_REALTEK
 
 config NET_DSA_REALTEK_MDIO
-	tristate "Realtek MDIO interface support"
+	bool "Realtek MDIO interface support"
 	depends on OF
 	help
 	  Select to enable support for registering switches configured
 	  through MDIO.
 
 config NET_DSA_REALTEK_SMI
-	tristate "Realtek SMI interface support"
+	bool "Realtek SMI interface support"
 	depends on OF
 	help
 	  Select to enable support for registering switches connected
diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
index f4f9c6340d5f..cea0e761d20f 100644
--- a/drivers/net/dsa/realtek/Makefile
+++ b/drivers/net/dsa/realtek/Makefile
@@ -1,8 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_NET_DSA_REALTEK)		+= realtek-dsa.o
-realtek-dsa-objs			:= realtek-common.o
-obj-$(CONFIG_NET_DSA_REALTEK_MDIO) 	+= realtek-mdio.o
-obj-$(CONFIG_NET_DSA_REALTEK_SMI) 	+= realtek-smi.o
+realtek-dsa-objs-y			:= realtek-common.o
+realtek-dsa-objs-$(CONFIG_NET_DSA_REALTEK_MDIO) += realtek-mdio.o
+realtek-dsa-objs-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
+realtek-dsa-objs			:= $(realtek-dsa-objs-y)
 obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
 rtl8366-objs 				:= rtl8366-core.o rtl8366rb.o
 obj-$(CONFIG_NET_DSA_REALTEK_RTL8365MB) += rtl8365mb.o
diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
index c7507b6cdcdd..bf3933a99072 100644
--- a/drivers/net/dsa/realtek/realtek-common.c
+++ b/drivers/net/dsa/realtek/realtek-common.c
@@ -133,5 +133,6 @@ void realtek_common_remove(struct realtek_priv *priv)
 EXPORT_SYMBOL(realtek_common_remove);
 
 MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
+MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
 MODULE_DESCRIPTION("Realtek DSA switches common module");
 MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 1eed09ab3aa1..967f6c1e8df0 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -177,7 +177,3 @@ void realtek_mdio_shutdown(struct mdio_device *mdiodev)
 	dev_set_drvdata(&mdiodev->dev, NULL);
 }
 EXPORT_SYMBOL_GPL(realtek_mdio_shutdown);
-
-MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
-MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via MDIO interface");
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index fc54190839cf..2b2c6e34bae5 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -456,7 +456,3 @@ void realtek_smi_shutdown(struct platform_device *pdev)
 	platform_set_drvdata(pdev, NULL);
 }
 EXPORT_SYMBOL_GPL(realtek_smi_shutdown);
-
-MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");
-MODULE_DESCRIPTION("Driver for Realtek ethernet switch connected via SMI interface");
-MODULE_LICENSE("GPL");
-- 
2.43.0


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

* [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
                   ` (3 preceding siblings ...)
  2023-12-20  4:24 ` [PATCH net-next v2 4/7] net: dsa: realtek: merge common and interface modules into realtek-dsa Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20  4:51   ` Luiz Angelo Daros de Luca
  2023-12-20 13:17   ` Alvin Šipraga
  2023-12-20  4:24 ` [PATCH net-next v2 6/7] net: dsa: realtek: embed dsa_switch into realtek_priv Luiz Angelo Daros de Luca
                   ` (2 subsequent siblings)
  7 siblings, 2 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

In the user MDIO driver, despite numerous references to SMI, including
its compatible string, there's nothing inherently specific about the SMI
interface in the user MDIO bus. Consequently, the code has been migrated
to the common module. All references to SMI have been eliminated, with
the exception of the compatible string, which will continue to function
as before.

The realtek-mdio will now use this driver instead of the generic DSA
driver ("dsa user smi"), which should not be used with OF[1].

There was a change in how the driver looks for the MDIO node in the
device tree. Now, it first checks for a child node named "mdio," which
is required by both interfaces in binding docs but used previously only
by realtek-mdio. If the node is not found, it will also look for a
compatible string, required only by SMI-connected devices in binding
docs and compatible with the old realtek-smi behavior.

The line assigning dev.of_node in mdio_bus has been removed since the
subsequent of_mdiobus_register will always overwrite it.

ds->user_mii_bus is only defined if all user ports do not declare a
phy-handle, providing a warning about the erroneous device tree[2].

With a single ds_ops for both interfaces, the ds_ops in realtek_priv is
no longer necessary. Now, the realtek_variant.ds_ops can be used
directly.

The realtek_priv.setup_interface() has been removed as we can directly
call the new common function.

The switch unregistration and the MDIO node decrement in refcount were
moved into realtek_common_remove() as both interfaces now need to put
the MDIO node.

[1] https://lkml.kernel.org/netdev/20220630200423.tieprdu5fpabflj7@bang-olufsen.dk/T/
[2] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/realtek-common.c | 87 +++++++++++++++++++++++-
 drivers/net/dsa/realtek/realtek-common.h |  1 +
 drivers/net/dsa/realtek/realtek-mdio.c   |  6 --
 drivers/net/dsa/realtek/realtek-smi.c    | 68 ------------------
 drivers/net/dsa/realtek/realtek.h        |  5 +-
 drivers/net/dsa/realtek/rtl8365mb.c      | 49 ++-----------
 drivers/net/dsa/realtek/rtl8366rb.c      | 52 ++------------
 7 files changed, 100 insertions(+), 168 deletions(-)

diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
index bf3933a99072..b1f0095d5bce 100644
--- a/drivers/net/dsa/realtek/realtek-common.c
+++ b/drivers/net/dsa/realtek/realtek-common.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0+
 
 #include <linux/module.h>
+#include <linux/of_mdio.h>
 
 #include "realtek.h"
 #include "realtek-common.h"
@@ -21,6 +22,85 @@ void realtek_common_unlock(void *ctx)
 }
 EXPORT_SYMBOL_GPL(realtek_common_unlock);
 
+static int realtek_common_user_mdio_read(struct mii_bus *bus, int addr,
+					 int regnum)
+{
+	struct realtek_priv *priv = bus->priv;
+
+	return priv->ops->phy_read(priv, addr, regnum);
+}
+
+static int realtek_common_user_mdio_write(struct mii_bus *bus, int addr,
+					  int regnum, u16 val)
+{
+	struct realtek_priv *priv = bus->priv;
+
+	return priv->ops->phy_write(priv, addr, regnum, val);
+}
+
+int realtek_common_setup_user_mdio(struct dsa_switch *ds)
+{
+	const char *compatible = "realtek,smi-mdio";
+	struct realtek_priv *priv =  ds->priv;
+	struct device_node *phy_node;
+	struct device_node *mdio_np;
+	struct dsa_port *dp;
+	int ret;
+
+	mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
+	if (!mdio_np) {
+		mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
+		if (!mdio_np) {
+			dev_err(priv->dev, "no MDIO bus node\n");
+			return -ENODEV;
+		}
+	}
+
+	priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
+	if (!priv->user_mii_bus) {
+		ret = -ENOMEM;
+		goto err_put_node;
+	}
+	priv->user_mii_bus->priv = priv;
+	priv->user_mii_bus->name = "Realtek user MII";
+	priv->user_mii_bus->read = realtek_common_user_mdio_read;
+	priv->user_mii_bus->write = realtek_common_user_mdio_write;
+	snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
+		 ds->index);
+	priv->user_mii_bus->parent = priv->dev;
+
+	/* When OF describes the MDIO, connecting ports with phy-handle,
+	 * ds->user_mii_bus should not be used *
+	 */
+	dsa_switch_for_each_user_port(dp, ds) {
+		phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
+		of_node_put(phy_node);
+		if (phy_node)
+			continue;
+
+		dev_warn(priv->dev,
+			 "DS user_mii_bus in use as '%s' is missing phy-handle",
+			 dp->name);
+		ds->user_mii_bus = priv->user_mii_bus;
+		break;
+	}
+
+	ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
+	if (ret) {
+		dev_err(priv->dev, "unable to register MDIO bus %s\n",
+			priv->user_mii_bus->id);
+		goto err_put_node;
+	}
+
+	return 0;
+
+err_put_node:
+	of_node_put(mdio_np);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(realtek_common_setup_user_mdio);
+
 /* sets up driver private data struct, sets up regmaps, parse common device-tree
  * properties and finally issues a hardware reset.
  */
@@ -108,7 +188,7 @@ int realtek_common_register_switch(struct realtek_priv *priv)
 
 	priv->ds->priv = priv;
 	priv->ds->dev = priv->dev;
-	priv->ds->ops = priv->ds_ops;
+	priv->ds->ops = priv->variant->ds_ops;
 	priv->ds->num_ports = priv->num_ports;
 
 	ret = dsa_register_switch(priv->ds);
@@ -126,6 +206,11 @@ void realtek_common_remove(struct realtek_priv *priv)
 	if (!priv)
 		return;
 
+	dsa_unregister_switch(priv->ds);
+
+	if (priv->user_mii_bus)
+		of_node_put(priv->user_mii_bus->dev.of_node);
+
 	/* leave the device reset asserted */
 	if (priv->reset)
 		gpiod_set_value(priv->reset, 1);
diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
index 518d091ff496..b1c2a50d85cd 100644
--- a/drivers/net/dsa/realtek/realtek-common.h
+++ b/drivers/net/dsa/realtek/realtek-common.h
@@ -7,6 +7,7 @@
 
 void realtek_common_lock(void *ctx);
 void realtek_common_unlock(void *ctx);
+int realtek_common_setup_user_mdio(struct dsa_switch *ds);
 struct realtek_priv *
 realtek_common_probe(struct device *dev, struct regmap_config rc,
 		     struct regmap_config rc_nolock);
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index 967f6c1e8df0..e2b5432eeb26 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -142,7 +142,6 @@ int realtek_mdio_probe(struct mdio_device *mdiodev)
 	priv->bus = mdiodev->bus;
 	priv->mdio_addr = mdiodev->addr;
 	priv->write_reg_noack = realtek_mdio_write;
-	priv->ds_ops = priv->variant->ds_ops_mdio;
 
 	ret = realtek_common_register_switch(priv);
 	if (ret)
@@ -156,11 +155,6 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
 {
 	struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
 
-	if (!priv)
-		return;
-
-	dsa_unregister_switch(priv->ds);
-
 	realtek_common_remove(priv);
 }
 EXPORT_SYMBOL_GPL(realtek_mdio_remove);
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index 2b2c6e34bae5..383689163057 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -31,7 +31,6 @@
 #include <linux/spinlock.h>
 #include <linux/skbuff.h>
 #include <linux/of.h>
-#include <linux/of_mdio.h>
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/platform_device.h>
@@ -339,63 +338,6 @@ static const struct regmap_config realtek_smi_nolock_regmap_config = {
 	.disable_locking = true,
 };
 
-static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
-{
-	struct realtek_priv *priv = bus->priv;
-
-	return priv->ops->phy_read(priv, addr, regnum);
-}
-
-static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
-				  u16 val)
-{
-	struct realtek_priv *priv = bus->priv;
-
-	return priv->ops->phy_write(priv, addr, regnum, val);
-}
-
-static int realtek_smi_setup_mdio(struct dsa_switch *ds)
-{
-	struct realtek_priv *priv =  ds->priv;
-	struct device_node *mdio_np;
-	int ret;
-
-	mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio");
-	if (!mdio_np) {
-		dev_err(priv->dev, "no MDIO bus node\n");
-		return -ENODEV;
-	}
-
-	priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
-	if (!priv->user_mii_bus) {
-		ret = -ENOMEM;
-		goto err_put_node;
-	}
-	priv->user_mii_bus->priv = priv;
-	priv->user_mii_bus->name = "SMI user MII";
-	priv->user_mii_bus->read = realtek_smi_mdio_read;
-	priv->user_mii_bus->write = realtek_smi_mdio_write;
-	snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
-		 ds->index);
-	priv->user_mii_bus->dev.of_node = mdio_np;
-	priv->user_mii_bus->parent = priv->dev;
-	ds->user_mii_bus = priv->user_mii_bus;
-
-	ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
-	if (ret) {
-		dev_err(priv->dev, "unable to register MDIO bus %s\n",
-			priv->user_mii_bus->id);
-		goto err_put_node;
-	}
-
-	return 0;
-
-err_put_node:
-	of_node_put(mdio_np);
-
-	return ret;
-}
-
 int realtek_smi_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -417,8 +359,6 @@ int realtek_smi_probe(struct platform_device *pdev)
 		return PTR_ERR(priv->mdio);
 
 	priv->write_reg_noack = realtek_smi_write_reg_noack;
-	priv->setup_interface = realtek_smi_setup_mdio;
-	priv->ds_ops = priv->variant->ds_ops_smi;
 
 	ret = realtek_common_register_switch(priv);
 	if (ret)
@@ -432,14 +372,6 @@ void realtek_smi_remove(struct platform_device *pdev)
 {
 	struct realtek_priv *priv = platform_get_drvdata(pdev);
 
-	if (!priv)
-		return;
-
-	dsa_unregister_switch(priv->ds);
-
-	if (priv->user_mii_bus)
-		of_node_put(priv->user_mii_bus->dev.of_node);
-
 	realtek_common_remove(priv);
 }
 EXPORT_SYMBOL_GPL(realtek_smi_remove);
diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index fbd0616c1df3..7af6dcc1bb24 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -60,7 +60,6 @@ struct realtek_priv {
 
 	spinlock_t		lock; /* Locks around command writes */
 	struct dsa_switch	*ds;
-	const struct dsa_switch_ops *ds_ops;
 	struct irq_domain	*irqdomain;
 	bool			leds_disabled;
 
@@ -71,7 +70,6 @@ struct realtek_priv {
 	struct rtl8366_mib_counter *mib_counters;
 
 	const struct realtek_ops *ops;
-	int			(*setup_interface)(struct dsa_switch *ds);
 	int			(*write_reg_noack)(void *ctx, u32 addr, u32 data);
 
 	int			vlan_enabled;
@@ -115,8 +113,7 @@ struct realtek_ops {
 };
 
 struct realtek_variant {
-	const struct dsa_switch_ops *ds_ops_smi;
-	const struct dsa_switch_ops *ds_ops_mdio;
+	const struct dsa_switch_ops *ds_ops;
 	const struct realtek_ops *ops;
 	unsigned int clk_delay;
 	u8 cmd_read;
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index 58ec057b6c32..e890ad113ba3 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -828,17 +828,6 @@ static int rtl8365mb_phy_write(struct realtek_priv *priv, int phy, int regnum,
 	return 0;
 }
 
-static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
-{
-	return rtl8365mb_phy_read(ds->priv, phy, regnum);
-}
-
-static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
-				   u16 val)
-{
-	return rtl8365mb_phy_write(ds->priv, phy, regnum, val);
-}
-
 static const struct rtl8365mb_extint *
 rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)
 {
@@ -2017,12 +2006,10 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 	if (ret)
 		goto out_teardown_irq;
 
-	if (priv->setup_interface) {
-		ret = priv->setup_interface(ds);
-		if (ret) {
-			dev_err(priv->dev, "could not set up MDIO bus\n");
-			goto out_teardown_irq;
-		}
+	ret = realtek_common_setup_user_mdio(ds);
+	if (ret) {
+		dev_err(priv->dev, "could not set up MDIO bus\n");
+		goto out_teardown_irq;
 	}
 
 	/* Start statistics counter polling */
@@ -2116,28 +2103,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
 	return 0;
 }
 
-static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
-	.get_tag_protocol = rtl8365mb_get_tag_protocol,
-	.change_tag_protocol = rtl8365mb_change_tag_protocol,
-	.setup = rtl8365mb_setup,
-	.teardown = rtl8365mb_teardown,
-	.phylink_get_caps = rtl8365mb_phylink_get_caps,
-	.phylink_mac_config = rtl8365mb_phylink_mac_config,
-	.phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
-	.phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
-	.port_stp_state_set = rtl8365mb_port_stp_state_set,
-	.get_strings = rtl8365mb_get_strings,
-	.get_ethtool_stats = rtl8365mb_get_ethtool_stats,
-	.get_sset_count = rtl8365mb_get_sset_count,
-	.get_eth_phy_stats = rtl8365mb_get_phy_stats,
-	.get_eth_mac_stats = rtl8365mb_get_mac_stats,
-	.get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
-	.get_stats64 = rtl8365mb_get_stats64,
-	.port_change_mtu = rtl8365mb_port_change_mtu,
-	.port_max_mtu = rtl8365mb_port_max_mtu,
-};
-
-static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
+static const struct dsa_switch_ops rtl8365mb_switch_ops = {
 	.get_tag_protocol = rtl8365mb_get_tag_protocol,
 	.change_tag_protocol = rtl8365mb_change_tag_protocol,
 	.setup = rtl8365mb_setup,
@@ -2146,8 +2112,6 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
 	.phylink_mac_config = rtl8365mb_phylink_mac_config,
 	.phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
 	.phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
-	.phy_read = rtl8365mb_dsa_phy_read,
-	.phy_write = rtl8365mb_dsa_phy_write,
 	.port_stp_state_set = rtl8365mb_port_stp_state_set,
 	.get_strings = rtl8365mb_get_strings,
 	.get_ethtool_stats = rtl8365mb_get_ethtool_stats,
@@ -2167,8 +2131,7 @@ static const struct realtek_ops rtl8365mb_ops = {
 };
 
 const struct realtek_variant rtl8365mb_variant = {
-	.ds_ops_smi = &rtl8365mb_switch_ops_smi,
-	.ds_ops_mdio = &rtl8365mb_switch_ops_mdio,
+	.ds_ops = &rtl8365mb_switch_ops,
 	.ops = &rtl8365mb_ops,
 	.clk_delay = 10,
 	.cmd_read = 0xb9,
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index e60a0a81d426..56619aa592ec 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -1027,12 +1027,10 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
 	if (ret)
 		dev_info(priv->dev, "no interrupt support\n");
 
-	if (priv->setup_interface) {
-		ret = priv->setup_interface(ds);
-		if (ret) {
-			dev_err(priv->dev, "could not set up MDIO bus\n");
-			return -ENODEV;
-		}
+	ret = realtek_common_setup_user_mdio(ds);
+	if (ret) {
+		dev_err(priv->dev, "could not set up MDIO bus\n");
+		return -ENODEV;
 	}
 
 	return 0;
@@ -1772,17 +1770,6 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
 	return ret;
 }
 
-static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
-{
-	return rtl8366rb_phy_read(ds->priv, phy, regnum);
-}
-
-static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
-				   u16 val)
-{
-	return rtl8366rb_phy_write(ds->priv, phy, regnum, val);
-}
-
 static int rtl8366rb_reset_chip(struct realtek_priv *priv)
 {
 	int timeout = 10;
@@ -1848,35 +1835,9 @@ static int rtl8366rb_detect(struct realtek_priv *priv)
 	return 0;
 }
 
-static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = {
-	.get_tag_protocol = rtl8366_get_tag_protocol,
-	.setup = rtl8366rb_setup,
-	.phylink_get_caps = rtl8366rb_phylink_get_caps,
-	.phylink_mac_link_up = rtl8366rb_mac_link_up,
-	.phylink_mac_link_down = rtl8366rb_mac_link_down,
-	.get_strings = rtl8366_get_strings,
-	.get_ethtool_stats = rtl8366_get_ethtool_stats,
-	.get_sset_count = rtl8366_get_sset_count,
-	.port_bridge_join = rtl8366rb_port_bridge_join,
-	.port_bridge_leave = rtl8366rb_port_bridge_leave,
-	.port_vlan_filtering = rtl8366rb_vlan_filtering,
-	.port_vlan_add = rtl8366_vlan_add,
-	.port_vlan_del = rtl8366_vlan_del,
-	.port_enable = rtl8366rb_port_enable,
-	.port_disable = rtl8366rb_port_disable,
-	.port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
-	.port_bridge_flags = rtl8366rb_port_bridge_flags,
-	.port_stp_state_set = rtl8366rb_port_stp_state_set,
-	.port_fast_age = rtl8366rb_port_fast_age,
-	.port_change_mtu = rtl8366rb_change_mtu,
-	.port_max_mtu = rtl8366rb_max_mtu,
-};
-
-static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = {
+static const struct dsa_switch_ops rtl8366rb_switch_ops = {
 	.get_tag_protocol = rtl8366_get_tag_protocol,
 	.setup = rtl8366rb_setup,
-	.phy_read = rtl8366rb_dsa_phy_read,
-	.phy_write = rtl8366rb_dsa_phy_write,
 	.phylink_get_caps = rtl8366rb_phylink_get_caps,
 	.phylink_mac_link_up = rtl8366rb_mac_link_up,
 	.phylink_mac_link_down = rtl8366rb_mac_link_down,
@@ -1915,8 +1876,7 @@ static const struct realtek_ops rtl8366rb_ops = {
 };
 
 const struct realtek_variant rtl8366rb_variant = {
-	.ds_ops_smi = &rtl8366rb_switch_ops_smi,
-	.ds_ops_mdio = &rtl8366rb_switch_ops_mdio,
+	.ds_ops = &rtl8366rb_switch_ops,
 	.ops = &rtl8366rb_ops,
 	.clk_delay = 10,
 	.cmd_read = 0xa9,
-- 
2.43.0


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

* [PATCH net-next v2 6/7] net: dsa: realtek: embed dsa_switch into realtek_priv
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
                   ` (4 preceding siblings ...)
  2023-12-20  4:24 ` [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20  4:24 ` [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus" Luiz Angelo Daros de Luca
  2023-12-21 15:21 ` [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Vladimir Oltean
  7 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

To eliminate the need for a second memory allocation for dsa_switch, it
has been embedded within realtek_priv.

Suggested-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 drivers/net/dsa/realtek/realtek-common.c | 16 ++++++----------
 drivers/net/dsa/realtek/realtek-mdio.c   |  2 +-
 drivers/net/dsa/realtek/realtek-smi.c    |  2 +-
 drivers/net/dsa/realtek/realtek.h        |  2 +-
 drivers/net/dsa/realtek/rtl8365mb.c      | 12 ++++++------
 drivers/net/dsa/realtek/rtl8366rb.c      |  2 +-
 6 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
index b1f0095d5bce..5c3efbcd6449 100644
--- a/drivers/net/dsa/realtek/realtek-common.c
+++ b/drivers/net/dsa/realtek/realtek-common.c
@@ -182,16 +182,12 @@ int realtek_common_register_switch(struct realtek_priv *priv)
 		return ret;
 	}
 
-	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
-	if (!priv->ds)
-		return -ENOMEM;
+	priv->ds.priv = priv;
+	priv->ds.dev = priv->dev;
+	priv->ds.ops = priv->variant->ds_ops;
+	priv->ds.num_ports = priv->num_ports;
 
-	priv->ds->priv = priv;
-	priv->ds->dev = priv->dev;
-	priv->ds->ops = priv->variant->ds_ops;
-	priv->ds->num_ports = priv->num_ports;
-
-	ret = dsa_register_switch(priv->ds);
+	ret = dsa_register_switch(&priv->ds);
 	if (ret) {
 		dev_err_probe(priv->dev, ret, "unable to register switch\n");
 		return ret;
@@ -206,7 +202,7 @@ void realtek_common_remove(struct realtek_priv *priv)
 	if (!priv)
 		return;
 
-	dsa_unregister_switch(priv->ds);
+	dsa_unregister_switch(&priv->ds);
 
 	if (priv->user_mii_bus)
 		of_node_put(priv->user_mii_bus->dev.of_node);
diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
index e2b5432eeb26..0305b2f69b41 100644
--- a/drivers/net/dsa/realtek/realtek-mdio.c
+++ b/drivers/net/dsa/realtek/realtek-mdio.c
@@ -166,7 +166,7 @@ void realtek_mdio_shutdown(struct mdio_device *mdiodev)
 	if (!priv)
 		return;
 
-	dsa_switch_shutdown(priv->ds);
+	dsa_switch_shutdown(&priv->ds);
 
 	dev_set_drvdata(&mdiodev->dev, NULL);
 }
diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
index 383689163057..fa5a4c5e4210 100644
--- a/drivers/net/dsa/realtek/realtek-smi.c
+++ b/drivers/net/dsa/realtek/realtek-smi.c
@@ -383,7 +383,7 @@ void realtek_smi_shutdown(struct platform_device *pdev)
 	if (!priv)
 		return;
 
-	dsa_switch_shutdown(priv->ds);
+	dsa_switch_shutdown(&priv->ds);
 
 	platform_set_drvdata(pdev, NULL);
 }
diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
index 7af6dcc1bb24..0217b8032c01 100644
--- a/drivers/net/dsa/realtek/realtek.h
+++ b/drivers/net/dsa/realtek/realtek.h
@@ -59,7 +59,7 @@ struct realtek_priv {
 	int			mdio_addr;
 
 	spinlock_t		lock; /* Locks around command writes */
-	struct dsa_switch	*ds;
+	struct dsa_switch	ds;
 	struct irq_domain	*irqdomain;
 	bool			leds_disabled;
 
diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
index e890ad113ba3..b05cf6fb56c0 100644
--- a/drivers/net/dsa/realtek/rtl8365mb.c
+++ b/drivers/net/dsa/realtek/rtl8365mb.c
@@ -880,7 +880,7 @@ static int rtl8365mb_ext_config_rgmii(struct realtek_priv *priv, int port,
 	if (!extint)
 		return -ENODEV;
 
-	dp = dsa_to_port(priv->ds, port);
+	dp = dsa_to_port(&priv->ds, port);
 	dn = dp->dn;
 
 	/* Set the RGMII TX/RX delay
@@ -1543,7 +1543,7 @@ static void rtl8365mb_stats_setup(struct realtek_priv *priv)
 	for (i = 0; i < priv->num_ports; i++) {
 		struct rtl8365mb_port *p = &mb->ports[i];
 
-		if (dsa_is_unused_port(priv->ds, i))
+		if (dsa_is_unused_port(&priv->ds, i))
 			continue;
 
 		/* Per-port spinlock to protect the stats64 data */
@@ -1564,7 +1564,7 @@ static void rtl8365mb_stats_teardown(struct realtek_priv *priv)
 	for (i = 0; i < priv->num_ports; i++) {
 		struct rtl8365mb_port *p = &mb->ports[i];
 
-		if (dsa_is_unused_port(priv->ds, i))
+		if (dsa_is_unused_port(&priv->ds, i))
 			continue;
 
 		cancel_delayed_work_sync(&p->mib_work);
@@ -1963,7 +1963,7 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 		dev_info(priv->dev, "no interrupt support\n");
 
 	/* Configure CPU tagging */
-	dsa_switch_for_each_cpu_port(cpu_dp, priv->ds) {
+	dsa_switch_for_each_cpu_port(cpu_dp, &priv->ds) {
 		cpu->mask |= BIT(cpu_dp->index);
 
 		if (cpu->trap_port == RTL8365MB_MAX_NUM_PORTS)
@@ -1978,7 +1978,7 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 	for (i = 0; i < priv->num_ports; i++) {
 		struct rtl8365mb_port *p = &mb->ports[i];
 
-		if (dsa_is_unused_port(priv->ds, i))
+		if (dsa_is_unused_port(&priv->ds, i))
 			continue;
 
 		/* Forward only to the CPU */
@@ -1995,7 +1995,7 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
 		 * ports will still forward frames to the CPU despite being
 		 * administratively down by default.
 		 */
-		rtl8365mb_port_stp_state_set(priv->ds, i, BR_STATE_DISABLED);
+		rtl8365mb_port_stp_state_set(&priv->ds, i, BR_STATE_DISABLED);
 
 		/* Set up per-port private data */
 		p->priv = priv;
diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
index 56619aa592ec..f5b32c77db7f 100644
--- a/drivers/net/dsa/realtek/rtl8366rb.c
+++ b/drivers/net/dsa/realtek/rtl8366rb.c
@@ -1662,7 +1662,7 @@ static int rtl8366rb_set_mc_index(struct realtek_priv *priv, int port, int index
 	 * not drop any untagged or C-tagged frames. Make sure to update the
 	 * filtering setting.
 	 */
-	if (dsa_port_is_vlan_filtering(dsa_to_port(priv->ds, port)))
+	if (dsa_port_is_vlan_filtering(dsa_to_port(&priv->ds, port)))
 		ret = rtl8366rb_drop_untagged(priv, port, !pvid_enabled);
 
 	return ret;
-- 
2.43.0


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

* [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus"
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
                   ` (5 preceding siblings ...)
  2023-12-20  4:24 ` [PATCH net-next v2 6/7] net: dsa: realtek: embed dsa_switch into realtek_priv Luiz Angelo Daros de Luca
@ 2023-12-20  4:24 ` Luiz Angelo Daros de Luca
  2023-12-20 13:19   ` Alvin Šipraga
  2023-12-21  0:41   ` kernel test robot
  2023-12-21 15:21 ` [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Vladimir Oltean
  7 siblings, 2 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:24 UTC (permalink / raw)
  To: netdev
  Cc: linus.walleij, alsi, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal, Luiz Angelo Daros de Luca

This reverts commit fe7324b932222574a0721b80e72c6c5fe57960d1.

The use of user_mii_bus is inappropriate when the hardware is described
with a device-tree [1].

Since all drivers currently implementing ds_switch_ops.phy_{read,write}
were not updated to utilize the MDIO information from OF with the
generic "dsa user mii", they might not be affected by this change.

[1] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u

Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
---
 net/dsa/dsa.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index ac7be864e80d..cea364c81b70 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -15,7 +15,6 @@
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/of.h>
-#include <linux/of_mdio.h>
 #include <linux/of_net.h>
 #include <net/dsa_stubs.h>
 #include <net/sch_generic.h>
@@ -626,7 +625,6 @@ static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds)
 
 static int dsa_switch_setup(struct dsa_switch *ds)
 {
-	struct device_node *dn;
 	int err;
 
 	if (ds->setup)
@@ -666,10 +664,7 @@ static int dsa_switch_setup(struct dsa_switch *ds)
 
 		dsa_user_mii_bus_init(ds);
 
-		dn = of_get_child_by_name(ds->dev->of_node, "mdio");
-
-		err = of_mdiobus_register(ds->user_mii_bus, dn);
-		of_node_put(dn);
+		err = mdiobus_register(ds->user_mii_bus, dn);
 		if (err < 0)
 			goto free_user_mii_bus;
 	}
-- 
2.43.0


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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-20  4:24 ` [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa Luiz Angelo Daros de Luca
@ 2023-12-20  4:51   ` Luiz Angelo Daros de Luca
  2023-12-21 17:47     ` Vladimir Oltean
  2023-12-20 13:17   ` Alvin Šipraga
  1 sibling, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-20  4:51 UTC (permalink / raw)
  To: olteanv
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev, arinc.unal

Hello Vladimir,

I'm sorry to bother you again but I would like your attention for two
points that I'm not completely sure about.

> In the user MDIO driver, despite numerous references to SMI, including
> its compatible string, there's nothing inherently specific about the SMI
> interface in the user MDIO bus. Consequently, the code has been migrated
> to the common module. All references to SMI have been eliminated, with
> the exception of the compatible string, which will continue to function
> as before.
>
> The realtek-mdio will now use this driver instead of the generic DSA
> driver ("dsa user smi"), which should not be used with OF[1].
>
> There was a change in how the driver looks for the MDIO node in the
> device tree. Now, it first checks for a child node named "mdio," which
> is required by both interfaces in binding docs but used previously only
> by realtek-mdio. If the node is not found, it will also look for a
> compatible string, required only by SMI-connected devices in binding
> docs and compatible with the old realtek-smi behavior.
>
> The line assigning dev.of_node in mdio_bus has been removed since the
> subsequent of_mdiobus_register will always overwrite it.
>
> ds->user_mii_bus is only defined if all user ports do not declare a
> phy-handle, providing a warning about the erroneous device tree[2].
>
> With a single ds_ops for both interfaces, the ds_ops in realtek_priv is
> no longer necessary. Now, the realtek_variant.ds_ops can be used
> directly.
>
> The realtek_priv.setup_interface() has been removed as we can directly
> call the new common function.
>
> The switch unregistration and the MDIO node decrement in refcount were
> moved into realtek_common_remove() as both interfaces now need to put
> the MDIO node.
>
> [1] https://lkml.kernel.org/netdev/20220630200423.tieprdu5fpabflj7@bang-olufsen.dk/T/
> [2] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
>
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> ---
>  drivers/net/dsa/realtek/realtek-common.c | 87 +++++++++++++++++++++++-
>  drivers/net/dsa/realtek/realtek-common.h |  1 +
>  drivers/net/dsa/realtek/realtek-mdio.c   |  6 --
>  drivers/net/dsa/realtek/realtek-smi.c    | 68 ------------------
>  drivers/net/dsa/realtek/realtek.h        |  5 +-
>  drivers/net/dsa/realtek/rtl8365mb.c      | 49 ++-----------
>  drivers/net/dsa/realtek/rtl8366rb.c      | 52 ++------------
>  7 files changed, 100 insertions(+), 168 deletions(-)
>
> diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
> index bf3933a99072..b1f0095d5bce 100644
> --- a/drivers/net/dsa/realtek/realtek-common.c
> +++ b/drivers/net/dsa/realtek/realtek-common.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0+
>
>  #include <linux/module.h>
> +#include <linux/of_mdio.h>
>
>  #include "realtek.h"
>  #include "realtek-common.h"
> @@ -21,6 +22,85 @@ void realtek_common_unlock(void *ctx)
>  }
>  EXPORT_SYMBOL_GPL(realtek_common_unlock);
>
> +static int realtek_common_user_mdio_read(struct mii_bus *bus, int addr,
> +                                        int regnum)
> +{
> +       struct realtek_priv *priv = bus->priv;
> +
> +       return priv->ops->phy_read(priv, addr, regnum);
> +}
> +
> +static int realtek_common_user_mdio_write(struct mii_bus *bus, int addr,
> +                                         int regnum, u16 val)
> +{
> +       struct realtek_priv *priv = bus->priv;
> +
> +       return priv->ops->phy_write(priv, addr, regnum, val);
> +}
> +
> +int realtek_common_setup_user_mdio(struct dsa_switch *ds)
> +{
> +       const char *compatible = "realtek,smi-mdio";
> +       struct realtek_priv *priv =  ds->priv;
> +       struct device_node *phy_node;
> +       struct device_node *mdio_np;
> +       struct dsa_port *dp;
> +       int ret;
> +
> +       mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
> +       if (!mdio_np) {
> +               mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
> +               if (!mdio_np) {
> +                       dev_err(priv->dev, "no MDIO bus node\n");
> +                       return -ENODEV;
> +               }
> +       }

I just kept the code compatible with both realtek-smi and realtek-mdio
(that was using the generic "DSA user mii"), even when it might
violate the binding docs (for SMI with a node not named "mdio").

You suggested using two new compatible strings for this driver
("realtek,rtl8365mb-mdio" and "realtek,rtl8366rb-mdio"). However, it
might still not be a good name as it is similar to the MDIO-connected
subdriver of each variant. Anyway, if possible, I would like to keep
it out of this series as it would first require a change in the
bindings before any real code change and it might add some more path
cycles.

> +       priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> +       if (!priv->user_mii_bus) {
> +               ret = -ENOMEM;
> +               goto err_put_node;
> +       }
> +       priv->user_mii_bus->priv = priv;
> +       priv->user_mii_bus->name = "Realtek user MII";
> +       priv->user_mii_bus->read = realtek_common_user_mdio_read;
> +       priv->user_mii_bus->write = realtek_common_user_mdio_write;
> +       snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
> +                ds->index);
> +       priv->user_mii_bus->parent = priv->dev;
> +
> +       /* When OF describes the MDIO, connecting ports with phy-handle,
> +        * ds->user_mii_bus should not be used *
> +        */
> +       dsa_switch_for_each_user_port(dp, ds) {
> +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> +               of_node_put(phy_node);
> +               if (phy_node)
> +                       continue;
> +
> +               dev_warn(priv->dev,
> +                        "DS user_mii_bus in use as '%s' is missing phy-handle",
> +                        dp->name);
> +               ds->user_mii_bus = priv->user_mii_bus;
> +               break;
> +       }

Does this check align with how should ds->user_mii_bus be used (in a
first step for phasing it out, at least for this driver)?

> +
> +       ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
> +       if (ret) {
> +               dev_err(priv->dev, "unable to register MDIO bus %s\n",
> +                       priv->user_mii_bus->id);
> +               goto err_put_node;
> +       }
> +
> +       return 0;
> +
> +err_put_node:
> +       of_node_put(mdio_np);
> +
> +       return ret;
> +}
> +EXPORT_SYMBOL_GPL(realtek_common_setup_user_mdio);
> +
>  /* sets up driver private data struct, sets up regmaps, parse common device-tree
>   * properties and finally issues a hardware reset.
>   */
> @@ -108,7 +188,7 @@ int realtek_common_register_switch(struct realtek_priv *priv)
>
>         priv->ds->priv = priv;
>         priv->ds->dev = priv->dev;
> -       priv->ds->ops = priv->ds_ops;
> +       priv->ds->ops = priv->variant->ds_ops;
>         priv->ds->num_ports = priv->num_ports;
>
>         ret = dsa_register_switch(priv->ds);
> @@ -126,6 +206,11 @@ void realtek_common_remove(struct realtek_priv *priv)
>         if (!priv)
>                 return;
>
> +       dsa_unregister_switch(priv->ds);
> +
> +       if (priv->user_mii_bus)
> +               of_node_put(priv->user_mii_bus->dev.of_node);
> +
>         /* leave the device reset asserted */
>         if (priv->reset)
>                 gpiod_set_value(priv->reset, 1);
> diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
> index 518d091ff496..b1c2a50d85cd 100644
> --- a/drivers/net/dsa/realtek/realtek-common.h
> +++ b/drivers/net/dsa/realtek/realtek-common.h
> @@ -7,6 +7,7 @@
>
>  void realtek_common_lock(void *ctx);
>  void realtek_common_unlock(void *ctx);
> +int realtek_common_setup_user_mdio(struct dsa_switch *ds);
>  struct realtek_priv *
>  realtek_common_probe(struct device *dev, struct regmap_config rc,
>                      struct regmap_config rc_nolock);
> diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
> index 967f6c1e8df0..e2b5432eeb26 100644
> --- a/drivers/net/dsa/realtek/realtek-mdio.c
> +++ b/drivers/net/dsa/realtek/realtek-mdio.c
> @@ -142,7 +142,6 @@ int realtek_mdio_probe(struct mdio_device *mdiodev)
>         priv->bus = mdiodev->bus;
>         priv->mdio_addr = mdiodev->addr;
>         priv->write_reg_noack = realtek_mdio_write;
> -       priv->ds_ops = priv->variant->ds_ops_mdio;
>
>         ret = realtek_common_register_switch(priv);
>         if (ret)
> @@ -156,11 +155,6 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
>  {
>         struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
>
> -       if (!priv)
> -               return;
> -
> -       dsa_unregister_switch(priv->ds);
> -
>         realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_mdio_remove);
> diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
> index 2b2c6e34bae5..383689163057 100644
> --- a/drivers/net/dsa/realtek/realtek-smi.c
> +++ b/drivers/net/dsa/realtek/realtek-smi.c
> @@ -31,7 +31,6 @@
>  #include <linux/spinlock.h>
>  #include <linux/skbuff.h>
>  #include <linux/of.h>
> -#include <linux/of_mdio.h>
>  #include <linux/delay.h>
>  #include <linux/gpio/consumer.h>
>  #include <linux/platform_device.h>
> @@ -339,63 +338,6 @@ static const struct regmap_config realtek_smi_nolock_regmap_config = {
>         .disable_locking = true,
>  };
>
> -static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
> -{
> -       struct realtek_priv *priv = bus->priv;
> -
> -       return priv->ops->phy_read(priv, addr, regnum);
> -}
> -
> -static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
> -                                 u16 val)
> -{
> -       struct realtek_priv *priv = bus->priv;
> -
> -       return priv->ops->phy_write(priv, addr, regnum, val);
> -}
> -
> -static int realtek_smi_setup_mdio(struct dsa_switch *ds)
> -{
> -       struct realtek_priv *priv =  ds->priv;
> -       struct device_node *mdio_np;
> -       int ret;
> -
> -       mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio");
> -       if (!mdio_np) {
> -               dev_err(priv->dev, "no MDIO bus node\n");
> -               return -ENODEV;
> -       }
> -
> -       priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> -       if (!priv->user_mii_bus) {
> -               ret = -ENOMEM;
> -               goto err_put_node;
> -       }
> -       priv->user_mii_bus->priv = priv;
> -       priv->user_mii_bus->name = "SMI user MII";
> -       priv->user_mii_bus->read = realtek_smi_mdio_read;
> -       priv->user_mii_bus->write = realtek_smi_mdio_write;
> -       snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
> -                ds->index);
> -       priv->user_mii_bus->dev.of_node = mdio_np;
> -       priv->user_mii_bus->parent = priv->dev;
> -       ds->user_mii_bus = priv->user_mii_bus;
> -
> -       ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
> -       if (ret) {
> -               dev_err(priv->dev, "unable to register MDIO bus %s\n",
> -                       priv->user_mii_bus->id);
> -               goto err_put_node;
> -       }
> -
> -       return 0;
> -
> -err_put_node:
> -       of_node_put(mdio_np);
> -
> -       return ret;
> -}
> -
>  int realtek_smi_probe(struct platform_device *pdev)
>  {
>         struct device *dev = &pdev->dev;
> @@ -417,8 +359,6 @@ int realtek_smi_probe(struct platform_device *pdev)
>                 return PTR_ERR(priv->mdio);
>
>         priv->write_reg_noack = realtek_smi_write_reg_noack;
> -       priv->setup_interface = realtek_smi_setup_mdio;
> -       priv->ds_ops = priv->variant->ds_ops_smi;
>
>         ret = realtek_common_register_switch(priv);
>         if (ret)
> @@ -432,14 +372,6 @@ void realtek_smi_remove(struct platform_device *pdev)
>  {
>         struct realtek_priv *priv = platform_get_drvdata(pdev);
>
> -       if (!priv)
> -               return;
> -
> -       dsa_unregister_switch(priv->ds);
> -
> -       if (priv->user_mii_bus)
> -               of_node_put(priv->user_mii_bus->dev.of_node);
> -
>         realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_smi_remove);
> diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> index fbd0616c1df3..7af6dcc1bb24 100644
> --- a/drivers/net/dsa/realtek/realtek.h
> +++ b/drivers/net/dsa/realtek/realtek.h
> @@ -60,7 +60,6 @@ struct realtek_priv {
>
>         spinlock_t              lock; /* Locks around command writes */
>         struct dsa_switch       *ds;
> -       const struct dsa_switch_ops *ds_ops;
>         struct irq_domain       *irqdomain;
>         bool                    leds_disabled;
>
> @@ -71,7 +70,6 @@ struct realtek_priv {
>         struct rtl8366_mib_counter *mib_counters;
>
>         const struct realtek_ops *ops;
> -       int                     (*setup_interface)(struct dsa_switch *ds);
>         int                     (*write_reg_noack)(void *ctx, u32 addr, u32 data);
>
>         int                     vlan_enabled;
> @@ -115,8 +113,7 @@ struct realtek_ops {
>  };
>
>  struct realtek_variant {
> -       const struct dsa_switch_ops *ds_ops_smi;
> -       const struct dsa_switch_ops *ds_ops_mdio;
> +       const struct dsa_switch_ops *ds_ops;
>         const struct realtek_ops *ops;
>         unsigned int clk_delay;
>         u8 cmd_read;
> diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> index 58ec057b6c32..e890ad113ba3 100644
> --- a/drivers/net/dsa/realtek/rtl8365mb.c
> +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> @@ -828,17 +828,6 @@ static int rtl8365mb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>         return 0;
>  }
>
> -static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> -{
> -       return rtl8365mb_phy_read(ds->priv, phy, regnum);
> -}
> -
> -static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> -                                  u16 val)
> -{
> -       return rtl8365mb_phy_write(ds->priv, phy, regnum, val);
> -}
> -
>  static const struct rtl8365mb_extint *
>  rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)
>  {
> @@ -2017,12 +2006,10 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
>         if (ret)
>                 goto out_teardown_irq;
>
> -       if (priv->setup_interface) {
> -               ret = priv->setup_interface(ds);
> -               if (ret) {
> -                       dev_err(priv->dev, "could not set up MDIO bus\n");
> -                       goto out_teardown_irq;
> -               }
> +       ret = realtek_common_setup_user_mdio(ds);
> +       if (ret) {
> +               dev_err(priv->dev, "could not set up MDIO bus\n");
> +               goto out_teardown_irq;
>         }
>
>         /* Start statistics counter polling */
> @@ -2116,28 +2103,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
>         return 0;
>  }
>
> -static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
> -       .get_tag_protocol = rtl8365mb_get_tag_protocol,
> -       .change_tag_protocol = rtl8365mb_change_tag_protocol,
> -       .setup = rtl8365mb_setup,
> -       .teardown = rtl8365mb_teardown,
> -       .phylink_get_caps = rtl8365mb_phylink_get_caps,
> -       .phylink_mac_config = rtl8365mb_phylink_mac_config,
> -       .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
> -       .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> -       .port_stp_state_set = rtl8365mb_port_stp_state_set,
> -       .get_strings = rtl8365mb_get_strings,
> -       .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> -       .get_sset_count = rtl8365mb_get_sset_count,
> -       .get_eth_phy_stats = rtl8365mb_get_phy_stats,
> -       .get_eth_mac_stats = rtl8365mb_get_mac_stats,
> -       .get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
> -       .get_stats64 = rtl8365mb_get_stats64,
> -       .port_change_mtu = rtl8365mb_port_change_mtu,
> -       .port_max_mtu = rtl8365mb_port_max_mtu,
> -};
> -
> -static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
> +static const struct dsa_switch_ops rtl8365mb_switch_ops = {
>         .get_tag_protocol = rtl8365mb_get_tag_protocol,
>         .change_tag_protocol = rtl8365mb_change_tag_protocol,
>         .setup = rtl8365mb_setup,
> @@ -2146,8 +2112,6 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
>         .phylink_mac_config = rtl8365mb_phylink_mac_config,
>         .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
>         .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> -       .phy_read = rtl8365mb_dsa_phy_read,
> -       .phy_write = rtl8365mb_dsa_phy_write,
>         .port_stp_state_set = rtl8365mb_port_stp_state_set,
>         .get_strings = rtl8365mb_get_strings,
>         .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> @@ -2167,8 +2131,7 @@ static const struct realtek_ops rtl8365mb_ops = {
>  };
>
>  const struct realtek_variant rtl8365mb_variant = {
> -       .ds_ops_smi = &rtl8365mb_switch_ops_smi,
> -       .ds_ops_mdio = &rtl8365mb_switch_ops_mdio,
> +       .ds_ops = &rtl8365mb_switch_ops,
>         .ops = &rtl8365mb_ops,
>         .clk_delay = 10,
>         .cmd_read = 0xb9,
> diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
> index e60a0a81d426..56619aa592ec 100644
> --- a/drivers/net/dsa/realtek/rtl8366rb.c
> +++ b/drivers/net/dsa/realtek/rtl8366rb.c
> @@ -1027,12 +1027,10 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
>         if (ret)
>                 dev_info(priv->dev, "no interrupt support\n");
>
> -       if (priv->setup_interface) {
> -               ret = priv->setup_interface(ds);
> -               if (ret) {
> -                       dev_err(priv->dev, "could not set up MDIO bus\n");
> -                       return -ENODEV;
> -               }
> +       ret = realtek_common_setup_user_mdio(ds);
> +       if (ret) {
> +               dev_err(priv->dev, "could not set up MDIO bus\n");
> +               return -ENODEV;
>         }
>
>         return 0;
> @@ -1772,17 +1770,6 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>         return ret;
>  }
>
> -static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> -{
> -       return rtl8366rb_phy_read(ds->priv, phy, regnum);
> -}
> -
> -static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> -                                  u16 val)
> -{
> -       return rtl8366rb_phy_write(ds->priv, phy, regnum, val);
> -}
> -
>  static int rtl8366rb_reset_chip(struct realtek_priv *priv)
>  {
>         int timeout = 10;
> @@ -1848,35 +1835,9 @@ static int rtl8366rb_detect(struct realtek_priv *priv)
>         return 0;
>  }
>
> -static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = {
> -       .get_tag_protocol = rtl8366_get_tag_protocol,
> -       .setup = rtl8366rb_setup,
> -       .phylink_get_caps = rtl8366rb_phylink_get_caps,
> -       .phylink_mac_link_up = rtl8366rb_mac_link_up,
> -       .phylink_mac_link_down = rtl8366rb_mac_link_down,
> -       .get_strings = rtl8366_get_strings,
> -       .get_ethtool_stats = rtl8366_get_ethtool_stats,
> -       .get_sset_count = rtl8366_get_sset_count,
> -       .port_bridge_join = rtl8366rb_port_bridge_join,
> -       .port_bridge_leave = rtl8366rb_port_bridge_leave,
> -       .port_vlan_filtering = rtl8366rb_vlan_filtering,
> -       .port_vlan_add = rtl8366_vlan_add,
> -       .port_vlan_del = rtl8366_vlan_del,
> -       .port_enable = rtl8366rb_port_enable,
> -       .port_disable = rtl8366rb_port_disable,
> -       .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
> -       .port_bridge_flags = rtl8366rb_port_bridge_flags,
> -       .port_stp_state_set = rtl8366rb_port_stp_state_set,
> -       .port_fast_age = rtl8366rb_port_fast_age,
> -       .port_change_mtu = rtl8366rb_change_mtu,
> -       .port_max_mtu = rtl8366rb_max_mtu,
> -};
> -
> -static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = {
> +static const struct dsa_switch_ops rtl8366rb_switch_ops = {
>         .get_tag_protocol = rtl8366_get_tag_protocol,
>         .setup = rtl8366rb_setup,
> -       .phy_read = rtl8366rb_dsa_phy_read,
> -       .phy_write = rtl8366rb_dsa_phy_write,
>         .phylink_get_caps = rtl8366rb_phylink_get_caps,
>         .phylink_mac_link_up = rtl8366rb_mac_link_up,
>         .phylink_mac_link_down = rtl8366rb_mac_link_down,
> @@ -1915,8 +1876,7 @@ static const struct realtek_ops rtl8366rb_ops = {
>  };
>
>  const struct realtek_variant rtl8366rb_variant = {
> -       .ds_ops_smi = &rtl8366rb_switch_ops_smi,
> -       .ds_ops_mdio = &rtl8366rb_switch_ops_mdio,
> +       .ds_ops = &rtl8366rb_switch_ops,
>         .ops = &rtl8366rb_ops,
>         .clk_delay = 10,
>         .cmd_read = 0xa9,
> --
> 2.43.0
>

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

* Re: [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module
  2023-12-20  4:24 ` [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module Luiz Angelo Daros de Luca
@ 2023-12-20 10:40   ` Alvin Šipraga
  2023-12-20 15:50     ` Alvin Šipraga
  2023-12-21  3:11     ` Luiz Angelo Daros de Luca
  0 siblings, 2 replies; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-20 10:40 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:26AM -0300, Luiz Angelo Daros de Luca wrote:
> Some code can be shared between both interface modules (MDIO and SMI)
> and among variants. These interface functions migrated to a common
> module:
> 
> - realtek_common_lock
> - realtek_common_unlock
> - realtek_common_probe
> - realtek_common_register_switch
> - realtek_common_remove
> 
> The reset during probe was moved to the end of the common probe. This way,
> we avoid a reset if anything else fails.
> 
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> ---
>  drivers/net/dsa/realtek/Makefile         |   2 +
>  drivers/net/dsa/realtek/realtek-common.c | 137 +++++++++++++++++++++++
>  drivers/net/dsa/realtek/realtek-common.h |  16 +++
>  drivers/net/dsa/realtek/realtek-mdio.c   | 114 +++----------------
>  drivers/net/dsa/realtek/realtek-smi.c    | 117 +++----------------
>  drivers/net/dsa/realtek/realtek.h        |   6 +-
>  drivers/net/dsa/realtek/rtl8365mb.c      |   9 +-
>  drivers/net/dsa/realtek/rtl8366rb.c      |   9 +-
>  8 files changed, 199 insertions(+), 211 deletions(-)
>  create mode 100644 drivers/net/dsa/realtek/realtek-common.c
>  create mode 100644 drivers/net/dsa/realtek/realtek-common.h
> 
> diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
> index 0aab57252a7c..f4f9c6340d5f 100644
> --- a/drivers/net/dsa/realtek/Makefile
> +++ b/drivers/net/dsa/realtek/Makefile
> @@ -1,4 +1,6 @@
>  # SPDX-License-Identifier: GPL-2.0
> +obj-$(CONFIG_NET_DSA_REALTEK)		+= realtek-dsa.o
> +realtek-dsa-objs			:= realtek-common.o
>  obj-$(CONFIG_NET_DSA_REALTEK_MDIO) 	+= realtek-mdio.o
>  obj-$(CONFIG_NET_DSA_REALTEK_SMI) 	+= realtek-smi.o
>  obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
> diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
> new file mode 100644
> index 000000000000..c7507b6cdcdd
> --- /dev/null
> +++ b/drivers/net/dsa/realtek/realtek-common.c
> @@ -0,0 +1,137 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <linux/module.h>
> +
> +#include "realtek.h"
> +#include "realtek-common.h"
> +
> +void realtek_common_lock(void *ctx)
> +{
> +	struct realtek_priv *priv = ctx;
> +
> +	mutex_lock(&priv->map_lock);
> +}
> +EXPORT_SYMBOL_GPL(realtek_common_lock);
> +
> +void realtek_common_unlock(void *ctx)
> +{
> +	struct realtek_priv *priv = ctx;
> +
> +	mutex_unlock(&priv->map_lock);
> +}
> +EXPORT_SYMBOL_GPL(realtek_common_unlock);
> +
> +/* sets up driver private data struct, sets up regmaps, parse common device-tree
> + * properties and finally issues a hardware reset.
> + */

Please use kdoc format if you add such comments. But I think we agreed
that the name is quite informative now, so you can also just drop it.

> +struct realtek_priv *
> +realtek_common_probe(struct device *dev, struct regmap_config rc,
> +		     struct regmap_config rc_nolock)
> +{
> +	const struct realtek_variant *var;
> +	struct realtek_priv *priv;
> +	int ret;
> +
> +	var = of_device_get_match_data(dev);
> +	if (!var)
> +		return ERR_PTR(-EINVAL);
> +
> +	priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
> +			    GFP_KERNEL);
> +	if (!priv)
> +		return ERR_PTR(-ENOMEM);
> +
> +	mutex_init(&priv->map_lock);
> +
> +	rc.lock_arg = priv;
> +	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> +	if (IS_ERR(priv->map)) {
> +		ret = PTR_ERR(priv->map);
> +		dev_err(dev, "regmap init failed: %d\n", ret);
> +		return ERR_PTR(ret);
> +	}
> +
> +	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc_nolock);
> +	if (IS_ERR(priv->map_nolock)) {
> +		ret = PTR_ERR(priv->map_nolock);
> +		dev_err(dev, "regmap init failed: %d\n", ret);
> +		return ERR_PTR(ret);
> +	}
> +
> +	/* Link forward and backward */
> +	priv->dev = dev;
> +	priv->variant = var;
> +	priv->ops = var->ops;
> +	priv->chip_data = (void *)priv + sizeof(*priv);
> +
> +	dev_set_drvdata(dev, priv);
> +	spin_lock_init(&priv->lock);
> +
> +	priv->leds_disabled = of_property_read_bool(dev->of_node,
> +						    "realtek,disable-leds");
> +
> +	/* TODO: if power is software controlled, set up any regulators here */
> +
> +	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> +	if (IS_ERR(priv->reset)) {
> +		dev_err(dev, "failed to get RESET GPIO\n");
> +		return ERR_CAST(priv->reset);
> +	}
> +	if (priv->reset) {
> +		gpiod_set_value(priv->reset, 1);
> +		dev_dbg(dev, "asserted RESET\n");
> +		msleep(REALTEK_HW_STOP_DELAY);
> +		gpiod_set_value(priv->reset, 0);
> +		msleep(REALTEK_HW_START_DELAY);
> +		dev_dbg(dev, "deasserted RESET\n");
> +	}

I simply cannot understand why you insist on moving this part despite
our earlier discussion on it where I pointed out that it makes no
sense to move it. Is chip hardware reset not the discipline of the chip
variant driver?

Why don't you just keep it in its original place? It will make your
patch smaller, which is what you seemed to care about the last time I
raised this.

Sorry, but I cannot give my Reviewed-by on this patch with this part
moved around.

> +
> +	return priv;
> +}
> +EXPORT_SYMBOL(realtek_common_probe);
> +
> +/* Detects the realtek switch id/version and registers the dsa switch.
> + */
> +int realtek_common_register_switch(struct realtek_priv *priv)
> +{
> +	int ret;
> +
> +	ret = priv->ops->detect(priv);
> +	if (ret) {
> +		dev_err_probe(priv->dev, ret, "unable to detect switch\n");
> +		return ret;
> +	}
> +
> +	priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
> +	if (!priv->ds)
> +		return -ENOMEM;
> +
> +	priv->ds->priv = priv;
> +	priv->ds->dev = priv->dev;
> +	priv->ds->ops = priv->ds_ops;
> +	priv->ds->num_ports = priv->num_ports;
> +
> +	ret = dsa_register_switch(priv->ds);
> +	if (ret) {
> +		dev_err_probe(priv->dev, ret, "unable to register switch\n");
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(realtek_common_register_switch);
> +
> +void realtek_common_remove(struct realtek_priv *priv)
> +{
> +	if (!priv)
> +		return;

This check is not really necessary.

> +
> +	/* leave the device reset asserted */
> +	if (priv->reset)
> +		gpiod_set_value(priv->reset, 1);
> +}
> +EXPORT_SYMBOL(realtek_common_remove);
> +
> +MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
> +MODULE_DESCRIPTION("Realtek DSA switches common module");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
> new file mode 100644
> index 000000000000..518d091ff496
> --- /dev/null
> +++ b/drivers/net/dsa/realtek/realtek-common.h
> @@ -0,0 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +
> +#ifndef _REALTEK_COMMON_H
> +#define _REALTEK_COMMON_H
> +
> +#include <linux/regmap.h>
> +
> +void realtek_common_lock(void *ctx);
> +void realtek_common_unlock(void *ctx);
> +struct realtek_priv *
> +realtek_common_probe(struct device *dev, struct regmap_config rc,
> +		     struct regmap_config rc_nolock);
> +int realtek_common_register_switch(struct realtek_priv *priv);
> +void realtek_common_remove(struct realtek_priv *priv);
> +
> +#endif /* _REALTEK_COMMON_H */
> diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
> index 58966d0625c8..1eed09ab3aa1 100644
> --- a/drivers/net/dsa/realtek/realtek-mdio.c
> +++ b/drivers/net/dsa/realtek/realtek-mdio.c
> @@ -26,6 +26,7 @@
>  
>  #include "realtek.h"
>  #include "realtek-mdio.h"
> +#include "realtek-common.h"
>  
>  /* Read/write via mdiobus */
>  #define REALTEK_MDIO_CTRL0_REG		31
> @@ -100,20 +101,6 @@ static int realtek_mdio_read(void *ctx, u32 reg, u32 *val)
>  	return ret;
>  }
>  
> -static void realtek_mdio_lock(void *ctx)
> -{
> -	struct realtek_priv *priv = ctx;
> -
> -	mutex_lock(&priv->map_lock);
> -}
> -
> -static void realtek_mdio_unlock(void *ctx)
> -{
> -	struct realtek_priv *priv = ctx;
> -
> -	mutex_unlock(&priv->map_lock);
> -}
> -
>  static const struct regmap_config realtek_mdio_regmap_config = {
>  	.reg_bits = 10, /* A4..A0 R4..R0 */
>  	.val_bits = 16,
> @@ -124,8 +111,8 @@ static const struct regmap_config realtek_mdio_regmap_config = {
>  	.reg_read = realtek_mdio_read,
>  	.reg_write = realtek_mdio_write,
>  	.cache_type = REGCACHE_NONE,
> -	.lock = realtek_mdio_lock,
> -	.unlock = realtek_mdio_unlock,
> +	.lock = realtek_common_lock,
> +	.unlock = realtek_common_unlock,
>  };
>  
>  static const struct regmap_config realtek_mdio_nolock_regmap_config = {
> @@ -143,96 +130,23 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
>  
>  int realtek_mdio_probe(struct mdio_device *mdiodev)
>  {
> -	struct realtek_priv *priv;
>  	struct device *dev = &mdiodev->dev;
> -	const struct realtek_variant *var;
> -	struct regmap_config rc;
> -	struct device_node *np;
> +	struct realtek_priv *priv;
>  	int ret;
>  
> -	var = of_device_get_match_data(dev);
> -	if (!var)
> -		return -EINVAL;
> -
> -	priv = devm_kzalloc(&mdiodev->dev,
> -			    size_add(sizeof(*priv), var->chip_data_sz),
> -			    GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -
> -	mutex_init(&priv->map_lock);
> +	priv = realtek_common_probe(dev, realtek_mdio_regmap_config,
> +				    realtek_mdio_nolock_regmap_config);
> +	if (IS_ERR(priv))
> +		return PTR_ERR(priv);
>  
> -	rc = realtek_mdio_regmap_config;
> -	rc.lock_arg = priv;
> -	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> -	if (IS_ERR(priv->map)) {
> -		ret = PTR_ERR(priv->map);
> -		dev_err(dev, "regmap init failed: %d\n", ret);
> -		return ret;
> -	}
> -
> -	rc = realtek_mdio_nolock_regmap_config;
> -	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
> -	if (IS_ERR(priv->map_nolock)) {
> -		ret = PTR_ERR(priv->map_nolock);
> -		dev_err(dev, "regmap init failed: %d\n", ret);
> -		return ret;
> -	}
> -
> -	priv->mdio_addr = mdiodev->addr;
>  	priv->bus = mdiodev->bus;
> -	priv->dev = &mdiodev->dev;
> -	priv->chip_data = (void *)priv + sizeof(*priv);
> -
> -	priv->clk_delay = var->clk_delay;
> -	priv->cmd_read = var->cmd_read;
> -	priv->cmd_write = var->cmd_write;
> -	priv->ops = var->ops;
> -
> +	priv->mdio_addr = mdiodev->addr;
>  	priv->write_reg_noack = realtek_mdio_write;
> +	priv->ds_ops = priv->variant->ds_ops_mdio;
>  
> -	np = dev->of_node;
> -
> -	dev_set_drvdata(dev, priv);
> -
> -	/* TODO: if power is software controlled, set up any regulators here */
> -	priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
> -
> -	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> -	if (IS_ERR(priv->reset)) {
> -		dev_err(dev, "failed to get RESET GPIO\n");
> -		return PTR_ERR(priv->reset);
> -	}
> -
> -	if (priv->reset) {
> -		gpiod_set_value(priv->reset, 1);
> -		dev_dbg(dev, "asserted RESET\n");
> -		msleep(REALTEK_HW_STOP_DELAY);
> -		gpiod_set_value(priv->reset, 0);
> -		msleep(REALTEK_HW_START_DELAY);
> -		dev_dbg(dev, "deasserted RESET\n");
> -	}
> -
> -	ret = priv->ops->detect(priv);
> -	if (ret) {
> -		dev_err(dev, "unable to detect switch\n");
> -		return ret;
> -	}
> -
> -	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
> -	if (!priv->ds)
> -		return -ENOMEM;
> -
> -	priv->ds->dev = dev;
> -	priv->ds->num_ports = priv->num_ports;
> -	priv->ds->priv = priv;
> -	priv->ds->ops = var->ds_ops_mdio;
> -
> -	ret = dsa_register_switch(priv->ds);
> -	if (ret) {
> -		dev_err(priv->dev, "unable to register switch ret = %d\n", ret);
> +	ret = realtek_common_register_switch(priv);
> +	if (ret)
>  		return ret;
> -	}
>  
>  	return 0;
>  }
> @@ -247,9 +161,7 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
>  
>  	dsa_unregister_switch(priv->ds);
>  
> -	/* leave the device reset asserted */
> -	if (priv->reset)
> -		gpiod_set_value(priv->reset, 1);
> +	realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_mdio_remove);
>  
> diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
> index 31ac409acfd0..fc54190839cf 100644
> --- a/drivers/net/dsa/realtek/realtek-smi.c
> +++ b/drivers/net/dsa/realtek/realtek-smi.c
> @@ -41,12 +41,13 @@
>  
>  #include "realtek.h"
>  #include "realtek-smi.h"
> +#include "realtek-common.h"
>  
>  #define REALTEK_SMI_ACK_RETRY_COUNT		5
>  
>  static inline void realtek_smi_clk_delay(struct realtek_priv *priv)
>  {
> -	ndelay(priv->clk_delay);
> +	ndelay(priv->variant->clk_delay);
>  }
>  
>  static void realtek_smi_start(struct realtek_priv *priv)
> @@ -209,7 +210,7 @@ static int realtek_smi_read_reg(struct realtek_priv *priv, u32 addr, u32 *data)
>  	realtek_smi_start(priv);
>  
>  	/* Send READ command */
> -	ret = realtek_smi_write_byte(priv, priv->cmd_read);
> +	ret = realtek_smi_write_byte(priv, priv->variant->cmd_read);
>  	if (ret)
>  		goto out;
>  
> @@ -250,7 +251,7 @@ static int realtek_smi_write_reg(struct realtek_priv *priv,
>  	realtek_smi_start(priv);
>  
>  	/* Send WRITE command */
> -	ret = realtek_smi_write_byte(priv, priv->cmd_write);
> +	ret = realtek_smi_write_byte(priv, priv->variant->cmd_write);
>  	if (ret)
>  		goto out;
>  
> @@ -311,20 +312,6 @@ static int realtek_smi_read(void *ctx, u32 reg, u32 *val)
>  	return realtek_smi_read_reg(priv, reg, val);
>  }
>  
> -static void realtek_smi_lock(void *ctx)
> -{
> -	struct realtek_priv *priv = ctx;
> -
> -	mutex_lock(&priv->map_lock);
> -}
> -
> -static void realtek_smi_unlock(void *ctx)
> -{
> -	struct realtek_priv *priv = ctx;
> -
> -	mutex_unlock(&priv->map_lock);
> -}
> -
>  static const struct regmap_config realtek_smi_regmap_config = {
>  	.reg_bits = 10, /* A4..A0 R4..R0 */
>  	.val_bits = 16,
> @@ -335,8 +322,8 @@ static const struct regmap_config realtek_smi_regmap_config = {
>  	.reg_read = realtek_smi_read,
>  	.reg_write = realtek_smi_write,
>  	.cache_type = REGCACHE_NONE,
> -	.lock = realtek_smi_lock,
> -	.unlock = realtek_smi_unlock,
> +	.lock = realtek_common_lock,
> +	.unlock = realtek_common_unlock,
>  };
>  
>  static const struct regmap_config realtek_smi_nolock_regmap_config = {
> @@ -411,99 +398,32 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
>  
>  int realtek_smi_probe(struct platform_device *pdev)
>  {
> -	const struct realtek_variant *var;
>  	struct device *dev = &pdev->dev;
>  	struct realtek_priv *priv;
> -	struct regmap_config rc;
> -	struct device_node *np;
>  	int ret;
>  
> -	var = of_device_get_match_data(dev);
> -	np = dev->of_node;
> -
> -	priv = devm_kzalloc(dev, sizeof(*priv) + var->chip_data_sz, GFP_KERNEL);
> -	if (!priv)
> -		return -ENOMEM;
> -	priv->chip_data = (void *)priv + sizeof(*priv);
> -
> -	mutex_init(&priv->map_lock);
> -
> -	rc = realtek_smi_regmap_config;
> -	rc.lock_arg = priv;
> -	priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> -	if (IS_ERR(priv->map)) {
> -		ret = PTR_ERR(priv->map);
> -		dev_err(dev, "regmap init failed: %d\n", ret);
> -		return ret;
> -	}
> -
> -	rc = realtek_smi_nolock_regmap_config;
> -	priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
> -	if (IS_ERR(priv->map_nolock)) {
> -		ret = PTR_ERR(priv->map_nolock);
> -		dev_err(dev, "regmap init failed: %d\n", ret);
> -		return ret;
> -	}
> -
> -	/* Link forward and backward */
> -	priv->dev = dev;
> -	priv->clk_delay = var->clk_delay;
> -	priv->cmd_read = var->cmd_read;
> -	priv->cmd_write = var->cmd_write;

You don't mention these parts in your commit message. Could be a patch
in its own right too.

> -	priv->ops = var->ops;
> -
> -	priv->setup_interface = realtek_smi_setup_mdio;
> -	priv->write_reg_noack = realtek_smi_write_reg_noack;
> -
> -	dev_set_drvdata(dev, priv);
> -	spin_lock_init(&priv->lock);
> -
> -	/* TODO: if power is software controlled, set up any regulators here */
> -
> -	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> -	if (IS_ERR(priv->reset)) {
> -		dev_err(dev, "failed to get RESET GPIO\n");
> -		return PTR_ERR(priv->reset);
> -	}
> -	if (priv->reset) {
> -		gpiod_set_value(priv->reset, 1);
> -		dev_dbg(dev, "asserted RESET\n");
> -		msleep(REALTEK_HW_STOP_DELAY);
> -		gpiod_set_value(priv->reset, 0);
> -		msleep(REALTEK_HW_START_DELAY);
> -		dev_dbg(dev, "deasserted RESET\n");
> -	}
> +	priv = realtek_common_probe(dev, realtek_smi_regmap_config,
> +				    realtek_smi_nolock_regmap_config);
> +	if (IS_ERR(priv))
> +		return PTR_ERR(priv);
>  
>  	/* Fetch MDIO pins */
>  	priv->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW);
>  	if (IS_ERR(priv->mdc))
>  		return PTR_ERR(priv->mdc);
> +
>  	priv->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW);
>  	if (IS_ERR(priv->mdio))
>  		return PTR_ERR(priv->mdio);
>  
> -	priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
> +	priv->write_reg_noack = realtek_smi_write_reg_noack;
> +	priv->setup_interface = realtek_smi_setup_mdio;
> +	priv->ds_ops = priv->variant->ds_ops_smi;
>  
> -	ret = priv->ops->detect(priv);
> -	if (ret) {
> -		dev_err(dev, "unable to detect switch\n");
> +	ret = realtek_common_register_switch(priv);
> +	if (ret)
>  		return ret;
> -	}
> -
> -	priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
> -	if (!priv->ds)
> -		return -ENOMEM;
>  
> -	priv->ds->dev = dev;
> -	priv->ds->num_ports = priv->num_ports;
> -	priv->ds->priv = priv;
> -
> -	priv->ds->ops = var->ds_ops_smi;
> -	ret = dsa_register_switch(priv->ds);
> -	if (ret) {
> -		dev_err_probe(dev, ret, "unable to register switch\n");
> -		return ret;
> -	}
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(realtek_smi_probe);
> @@ -516,12 +436,11 @@ void realtek_smi_remove(struct platform_device *pdev)
>  		return;
>  
>  	dsa_unregister_switch(priv->ds);
> +
>  	if (priv->user_mii_bus)
>  		of_node_put(priv->user_mii_bus->dev.of_node);
>  
> -	/* leave the device reset asserted */
> -	if (priv->reset)
> -		gpiod_set_value(priv->reset, 1);
> +	realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_smi_remove);
>  
> diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> index e9ee778665b2..fbd0616c1df3 100644
> --- a/drivers/net/dsa/realtek/realtek.h
> +++ b/drivers/net/dsa/realtek/realtek.h
> @@ -58,11 +58,9 @@ struct realtek_priv {
>  	struct mii_bus		*bus;
>  	int			mdio_addr;
>  
> -	unsigned int		clk_delay;
> -	u8			cmd_read;
> -	u8			cmd_write;
>  	spinlock_t		lock; /* Locks around command writes */
>  	struct dsa_switch	*ds;
> +	const struct dsa_switch_ops *ds_ops;
>  	struct irq_domain	*irqdomain;
>  	bool			leds_disabled;
>  
> @@ -79,6 +77,8 @@ struct realtek_priv {
>  	int			vlan_enabled;
>  	int			vlan4k_enabled;
>  
> +	const struct realtek_variant *variant;
> +
>  	char			buf[4096];
>  	void			*chip_data; /* Per-chip extra variant data */
>  };
> diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> index 1ace2239934a..58ec057b6c32 100644
> --- a/drivers/net/dsa/realtek/rtl8365mb.c
> +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> @@ -103,6 +103,7 @@
>  #include "realtek.h"
>  #include "realtek-smi.h"
>  #include "realtek-mdio.h"
> +#include "realtek-common.h"
>  
>  /* Family-specific data and limits */
>  #define RTL8365MB_PHYADDRMAX		7
> @@ -691,7 +692,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
>  	u32 val;
>  	int ret;
>  
> -	mutex_lock(&priv->map_lock);
> +	realtek_common_lock(priv);
>  
>  	ret = rtl8365mb_phy_poll_busy(priv);
>  	if (ret)
> @@ -724,7 +725,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
>  	*data = val & 0xFFFF;
>  
>  out:
> -	mutex_unlock(&priv->map_lock);
> +	realtek_common_unlock(priv);
>  
>  	return ret;
>  }
> @@ -735,7 +736,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
>  	u32 val;
>  	int ret;
>  
> -	mutex_lock(&priv->map_lock);
> +	realtek_common_lock(priv);
>  
>  	ret = rtl8365mb_phy_poll_busy(priv);
>  	if (ret)
> @@ -766,7 +767,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
>  		goto out;
>  
>  out:
> -	mutex_unlock(&priv->map_lock);
> +	realtek_common_unlock(priv);
>  
>  	return 0;
>  }
> diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
> index cc2fd636ec23..e60a0a81d426 100644
> --- a/drivers/net/dsa/realtek/rtl8366rb.c
> +++ b/drivers/net/dsa/realtek/rtl8366rb.c
> @@ -24,6 +24,7 @@
>  #include "realtek.h"
>  #include "realtek-smi.h"
>  #include "realtek-mdio.h"
> +#include "realtek-common.h"
>  
>  #define RTL8366RB_PORT_NUM_CPU		5
>  #define RTL8366RB_NUM_PORTS		6
> @@ -1707,7 +1708,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
>  	if (phy > RTL8366RB_PHY_NO_MAX)
>  		return -EINVAL;
>  
> -	mutex_lock(&priv->map_lock);
> +	realtek_common_lock(priv);
>  
>  	ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
>  			   RTL8366RB_PHY_CTRL_READ);
> @@ -1735,7 +1736,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
>  		phy, regnum, reg, val);
>  
>  out:
> -	mutex_unlock(&priv->map_lock);
> +	realtek_common_unlock(priv);
>  
>  	return ret;
>  }
> @@ -1749,7 +1750,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>  	if (phy > RTL8366RB_PHY_NO_MAX)
>  		return -EINVAL;
>  
> -	mutex_lock(&priv->map_lock);
> +	realtek_common_lock(priv);
>  
>  	ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
>  			   RTL8366RB_PHY_CTRL_WRITE);
> @@ -1766,7 +1767,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>  		goto out;
>  
>  out:
> -	mutex_unlock(&priv->map_lock);
> +	realtek_common_unlock(priv);
>  
>  	return ret;
>  }
> -- 
> 2.43.0
>

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-20  4:24 ` [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa Luiz Angelo Daros de Luca
  2023-12-20  4:51   ` Luiz Angelo Daros de Luca
@ 2023-12-20 13:17   ` Alvin Šipraga
  2023-12-21  3:03     ` Luiz Angelo Daros de Luca
  1 sibling, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-20 13:17 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:28AM -0300, Luiz Angelo Daros de Luca wrote:
> In the user MDIO driver, despite numerous references to SMI, including
> its compatible string, there's nothing inherently specific about the SMI
> interface in the user MDIO bus. Consequently, the code has been migrated
> to the common module. All references to SMI have been eliminated, with
> the exception of the compatible string, which will continue to function
> as before.
> 
> The realtek-mdio will now use this driver instead of the generic DSA
> driver ("dsa user smi"), which should not be used with OF[1].
> 
> There was a change in how the driver looks for the MDIO node in the
> device tree. Now, it first checks for a child node named "mdio," which
> is required by both interfaces in binding docs but used previously only
> by realtek-mdio. If the node is not found, it will also look for a
> compatible string, required only by SMI-connected devices in binding
> docs and compatible with the old realtek-smi behavior.
> 
> The line assigning dev.of_node in mdio_bus has been removed since the
> subsequent of_mdiobus_register will always overwrite it.
> 
> ds->user_mii_bus is only defined if all user ports do not declare a
> phy-handle, providing a warning about the erroneous device tree[2].
> 
> With a single ds_ops for both interfaces, the ds_ops in realtek_priv is
> no longer necessary. Now, the realtek_variant.ds_ops can be used
> directly.
> 
> The realtek_priv.setup_interface() has been removed as we can directly
> call the new common function.
> 
> The switch unregistration and the MDIO node decrement in refcount were
> moved into realtek_common_remove() as both interfaces now need to put
> the MDIO node.
> 
> [1] https://lkml.kernel.org/netdev/20220630200423.tieprdu5fpabflj7@bang-olufsen.dk/T/
> [2] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
> 
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> ---
>  drivers/net/dsa/realtek/realtek-common.c | 87 +++++++++++++++++++++++-
>  drivers/net/dsa/realtek/realtek-common.h |  1 +
>  drivers/net/dsa/realtek/realtek-mdio.c   |  6 --
>  drivers/net/dsa/realtek/realtek-smi.c    | 68 ------------------
>  drivers/net/dsa/realtek/realtek.h        |  5 +-
>  drivers/net/dsa/realtek/rtl8365mb.c      | 49 ++-----------
>  drivers/net/dsa/realtek/rtl8366rb.c      | 52 ++------------
>  7 files changed, 100 insertions(+), 168 deletions(-)
> 
> diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
> index bf3933a99072..b1f0095d5bce 100644
> --- a/drivers/net/dsa/realtek/realtek-common.c
> +++ b/drivers/net/dsa/realtek/realtek-common.c
> @@ -1,6 +1,7 @@
>  // SPDX-License-Identifier: GPL-2.0+
>  
>  #include <linux/module.h>
> +#include <linux/of_mdio.h>
>  
>  #include "realtek.h"
>  #include "realtek-common.h"
> @@ -21,6 +22,85 @@ void realtek_common_unlock(void *ctx)
>  }
>  EXPORT_SYMBOL_GPL(realtek_common_unlock);
>  
> +static int realtek_common_user_mdio_read(struct mii_bus *bus, int addr,
> +					 int regnum)
> +{
> +	struct realtek_priv *priv = bus->priv;
> +
> +	return priv->ops->phy_read(priv, addr, regnum);
> +}
> +
> +static int realtek_common_user_mdio_write(struct mii_bus *bus, int addr,
> +					  int regnum, u16 val)
> +{
> +	struct realtek_priv *priv = bus->priv;
> +
> +	return priv->ops->phy_write(priv, addr, regnum, val);
> +}
> +
> +int realtek_common_setup_user_mdio(struct dsa_switch *ds)
> +{
> +	const char *compatible = "realtek,smi-mdio";

No need to put this in its own variable, it makes the code harder to read.

> +	struct realtek_priv *priv =  ds->priv;
> +	struct device_node *phy_node;
> +	struct device_node *mdio_np;
> +	struct dsa_port *dp;
> +	int ret;
> +
> +	mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
> +	if (!mdio_np) {
> +		mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
> +		if (!mdio_np) {
> +			dev_err(priv->dev, "no MDIO bus node\n");
> +			return -ENODEV;
> +		}
> +	}
> +
> +	priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> +	if (!priv->user_mii_bus) {
> +		ret = -ENOMEM;
> +		goto err_put_node;
> +	}
> +	priv->user_mii_bus->priv = priv;
> +	priv->user_mii_bus->name = "Realtek user MII";
> +	priv->user_mii_bus->read = realtek_common_user_mdio_read;
> +	priv->user_mii_bus->write = realtek_common_user_mdio_write;
> +	snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
> +		 ds->index);
> +	priv->user_mii_bus->parent = priv->dev;
> +
> +	/* When OF describes the MDIO, connecting ports with phy-handle,
> +	 * ds->user_mii_bus should not be used *

Stray *, put a full stop.

> +	 */
> +	dsa_switch_for_each_user_port(dp, ds) {
> +		phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> +		of_node_put(phy_node);
> +		if (phy_node)
> +			continue;
> +
> +		dev_warn(priv->dev,
> +			 "DS user_mii_bus in use as '%s' is missing phy-handle",
> +			 dp->name);

"DS user_mii_bus in use" is a very cryptic warning, can you not just
warn about a missing phy-handle, since that is what is expected?

> +		ds->user_mii_bus = priv->user_mii_bus;
> +		break;
> +	}
> +
> +	ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);

You use devres here, but this means the mdiobus will outlive the switch
after dsa_switch_teardown(). I don't really know if this can cause any
unwanted runtime behaviour, but the code feels unbalanced.

> +	if (ret) {
> +		dev_err(priv->dev, "unable to register MDIO bus %s\n",
> +			priv->user_mii_bus->id);
> +		goto err_put_node;
> +	}
> +
> +	return 0;
> +
> +err_put_node:
> +	of_node_put(mdio_np);
> +
> +	return ret;
> +}
> +EXPORT_SYMBOL_GPL(realtek_common_setup_user_mdio);
> +
>  /* sets up driver private data struct, sets up regmaps, parse common device-tree
>   * properties and finally issues a hardware reset.
>   */
> @@ -108,7 +188,7 @@ int realtek_common_register_switch(struct realtek_priv *priv)
>  
>  	priv->ds->priv = priv;
>  	priv->ds->dev = priv->dev;
> -	priv->ds->ops = priv->ds_ops;
> +	priv->ds->ops = priv->variant->ds_ops;
>  	priv->ds->num_ports = priv->num_ports;
>  
>  	ret = dsa_register_switch(priv->ds);
> @@ -126,6 +206,11 @@ void realtek_common_remove(struct realtek_priv *priv)
>  	if (!priv)
>  		return;
>  
> +	dsa_unregister_switch(priv->ds);

Wait, wasn't this supposed to belong in the previous patch that added
realtek_common_remove? Why is it being put here in this patch?

Regarding the series as a whole, I still think all you really need is
something like this:

  - realtek_common_probe
  - realtek_common_remove (if there is actually anything to do?)
  - realtek_common_setup_user_mdio
  - realtek_common_teardown_user_mdio

The chip variant drivers can then do:

  /* Interface-agnostic chip driver code */

  rtl836xxx_setup() {
    // ...
    realtek_common_setup_user_mdio();
    // ...
  }

  rtl836xxx_teardown() {
    // ...
    realtek_common_teardown_user_mdio();
    // ...
  }

  rtl836xxx_probe() {
    // assert
    // enable regulators
    // deassert reset
    // do what was in detect() before
    dsa_register_switch(priv->ds);
  }

  rtl836xxx_remove() {
    dsa_unregister_switch();
    // assert reset again
  }

  /* SMI boilerplate */

  rtl836xxx_smi_probe() {
    priv = realtek_smi_probe();
    return rtl836xxx_probe(priv);
  }
  
  rtl836xxx_smi_remove() {
    rtl836xxx_remove();
    realtek_smi_remove(); // if needed
  }

  /* MDIO boilerplate */

  rtl836xxx_mdio_probe() {
    priv = realtek_mdio_probe();
    return rtl836xxx_probe(priv);
  }

  rtl836xxx_mdio_remove() {
    rtl836xxx_remove();
    realtek_mdio_remove(); // if needed
  }

And your interface probe functions:

  realtek_smi_probe() {
    priv = realtek_common_probe();
    // SMI specific setup
    return priv;
  }

  realtek_mdio_probe() {
    priv = realtek_common_probe();
    // MDIO specific setup
    return priv;
  }

Am I missing something? I'm open to other suggestions but I can't help
but feel that the current proposal is half-baked.

As a side note: I also think this will make it a bit easier to reason
about the ownership of variables in struct realtek_priv. Ultimately its
contents ought all to belong to the code which ends up in the
realtek-dsa IMO. With a little effort, the rest can be moved into the
variant-specific private data structs. And cases like
realtek_priv::num_ports can be removed completely. But that cleanup is
for another time.

> +
> +	if (priv->user_mii_bus)
> +		of_node_put(priv->user_mii_bus->dev.of_node);

I think you should undo your work in the corresponding undo
function. You set up priv->user_mii_bus in ds_ops::setup, so you should
undo any such stuff in ds_ops::teardown as well.

> +
>  	/* leave the device reset asserted */
>  	if (priv->reset)
>  		gpiod_set_value(priv->reset, 1);
> diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
> index 518d091ff496..b1c2a50d85cd 100644
> --- a/drivers/net/dsa/realtek/realtek-common.h
> +++ b/drivers/net/dsa/realtek/realtek-common.h
> @@ -7,6 +7,7 @@
>  
>  void realtek_common_lock(void *ctx);
>  void realtek_common_unlock(void *ctx);
> +int realtek_common_setup_user_mdio(struct dsa_switch *ds);
>  struct realtek_priv *
>  realtek_common_probe(struct device *dev, struct regmap_config rc,
>  		     struct regmap_config rc_nolock);
> diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
> index 967f6c1e8df0..e2b5432eeb26 100644
> --- a/drivers/net/dsa/realtek/realtek-mdio.c
> +++ b/drivers/net/dsa/realtek/realtek-mdio.c
> @@ -142,7 +142,6 @@ int realtek_mdio_probe(struct mdio_device *mdiodev)
>  	priv->bus = mdiodev->bus;
>  	priv->mdio_addr = mdiodev->addr;
>  	priv->write_reg_noack = realtek_mdio_write;
> -	priv->ds_ops = priv->variant->ds_ops_mdio;
>  
>  	ret = realtek_common_register_switch(priv);
>  	if (ret)
> @@ -156,11 +155,6 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
>  {
>  	struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
>  
> -	if (!priv)
> -		return;
> -
> -	dsa_unregister_switch(priv->ds);
> -
>  	realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_mdio_remove);
> diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
> index 2b2c6e34bae5..383689163057 100644
> --- a/drivers/net/dsa/realtek/realtek-smi.c
> +++ b/drivers/net/dsa/realtek/realtek-smi.c
> @@ -31,7 +31,6 @@
>  #include <linux/spinlock.h>
>  #include <linux/skbuff.h>
>  #include <linux/of.h>
> -#include <linux/of_mdio.h>
>  #include <linux/delay.h>
>  #include <linux/gpio/consumer.h>
>  #include <linux/platform_device.h>
> @@ -339,63 +338,6 @@ static const struct regmap_config realtek_smi_nolock_regmap_config = {
>  	.disable_locking = true,
>  };
>  
> -static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
> -{
> -	struct realtek_priv *priv = bus->priv;
> -
> -	return priv->ops->phy_read(priv, addr, regnum);
> -}
> -
> -static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
> -				  u16 val)
> -{
> -	struct realtek_priv *priv = bus->priv;
> -
> -	return priv->ops->phy_write(priv, addr, regnum, val);
> -}
> -
> -static int realtek_smi_setup_mdio(struct dsa_switch *ds)
> -{
> -	struct realtek_priv *priv =  ds->priv;
> -	struct device_node *mdio_np;
> -	int ret;
> -
> -	mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio");
> -	if (!mdio_np) {
> -		dev_err(priv->dev, "no MDIO bus node\n");
> -		return -ENODEV;
> -	}
> -
> -	priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> -	if (!priv->user_mii_bus) {
> -		ret = -ENOMEM;
> -		goto err_put_node;
> -	}
> -	priv->user_mii_bus->priv = priv;
> -	priv->user_mii_bus->name = "SMI user MII";
> -	priv->user_mii_bus->read = realtek_smi_mdio_read;
> -	priv->user_mii_bus->write = realtek_smi_mdio_write;
> -	snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
> -		 ds->index);
> -	priv->user_mii_bus->dev.of_node = mdio_np;
> -	priv->user_mii_bus->parent = priv->dev;
> -	ds->user_mii_bus = priv->user_mii_bus;
> -
> -	ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
> -	if (ret) {
> -		dev_err(priv->dev, "unable to register MDIO bus %s\n",
> -			priv->user_mii_bus->id);
> -		goto err_put_node;
> -	}
> -
> -	return 0;
> -
> -err_put_node:
> -	of_node_put(mdio_np);
> -
> -	return ret;
> -}
> -
>  int realtek_smi_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> @@ -417,8 +359,6 @@ int realtek_smi_probe(struct platform_device *pdev)
>  		return PTR_ERR(priv->mdio);
>  
>  	priv->write_reg_noack = realtek_smi_write_reg_noack;
> -	priv->setup_interface = realtek_smi_setup_mdio;
> -	priv->ds_ops = priv->variant->ds_ops_smi;
>  
>  	ret = realtek_common_register_switch(priv);
>  	if (ret)
> @@ -432,14 +372,6 @@ void realtek_smi_remove(struct platform_device *pdev)
>  {
>  	struct realtek_priv *priv = platform_get_drvdata(pdev);
>  
> -	if (!priv)
> -		return;
> -
> -	dsa_unregister_switch(priv->ds);
> -
> -	if (priv->user_mii_bus)
> -		of_node_put(priv->user_mii_bus->dev.of_node);
> -
>  	realtek_common_remove(priv);
>  }
>  EXPORT_SYMBOL_GPL(realtek_smi_remove);
> diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> index fbd0616c1df3..7af6dcc1bb24 100644
> --- a/drivers/net/dsa/realtek/realtek.h
> +++ b/drivers/net/dsa/realtek/realtek.h
> @@ -60,7 +60,6 @@ struct realtek_priv {
>  
>  	spinlock_t		lock; /* Locks around command writes */
>  	struct dsa_switch	*ds;
> -	const struct dsa_switch_ops *ds_ops;
>  	struct irq_domain	*irqdomain;
>  	bool			leds_disabled;
>  
> @@ -71,7 +70,6 @@ struct realtek_priv {
>  	struct rtl8366_mib_counter *mib_counters;
>  
>  	const struct realtek_ops *ops;
> -	int			(*setup_interface)(struct dsa_switch *ds);
>  	int			(*write_reg_noack)(void *ctx, u32 addr, u32 data);
>  
>  	int			vlan_enabled;
> @@ -115,8 +113,7 @@ struct realtek_ops {
>  };
>  
>  struct realtek_variant {
> -	const struct dsa_switch_ops *ds_ops_smi;
> -	const struct dsa_switch_ops *ds_ops_mdio;
> +	const struct dsa_switch_ops *ds_ops;
>  	const struct realtek_ops *ops;
>  	unsigned int clk_delay;
>  	u8 cmd_read;
> diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> index 58ec057b6c32..e890ad113ba3 100644
> --- a/drivers/net/dsa/realtek/rtl8365mb.c
> +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> @@ -828,17 +828,6 @@ static int rtl8365mb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>  	return 0;
>  }
>  
> -static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> -{
> -	return rtl8365mb_phy_read(ds->priv, phy, regnum);
> -}
> -
> -static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> -				   u16 val)
> -{
> -	return rtl8365mb_phy_write(ds->priv, phy, regnum, val);
> -}
> -
>  static const struct rtl8365mb_extint *
>  rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)
>  {
> @@ -2017,12 +2006,10 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
>  	if (ret)
>  		goto out_teardown_irq;
>  
> -	if (priv->setup_interface) {
> -		ret = priv->setup_interface(ds);
> -		if (ret) {
> -			dev_err(priv->dev, "could not set up MDIO bus\n");
> -			goto out_teardown_irq;
> -		}
> +	ret = realtek_common_setup_user_mdio(ds);
> +	if (ret) {
> +		dev_err(priv->dev, "could not set up MDIO bus\n");
> +		goto out_teardown_irq;
>  	}
>  
>  	/* Start statistics counter polling */
> @@ -2116,28 +2103,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
>  	return 0;
>  }
>  
> -static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
> -	.get_tag_protocol = rtl8365mb_get_tag_protocol,
> -	.change_tag_protocol = rtl8365mb_change_tag_protocol,
> -	.setup = rtl8365mb_setup,
> -	.teardown = rtl8365mb_teardown,
> -	.phylink_get_caps = rtl8365mb_phylink_get_caps,
> -	.phylink_mac_config = rtl8365mb_phylink_mac_config,
> -	.phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
> -	.phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> -	.port_stp_state_set = rtl8365mb_port_stp_state_set,
> -	.get_strings = rtl8365mb_get_strings,
> -	.get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> -	.get_sset_count = rtl8365mb_get_sset_count,
> -	.get_eth_phy_stats = rtl8365mb_get_phy_stats,
> -	.get_eth_mac_stats = rtl8365mb_get_mac_stats,
> -	.get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
> -	.get_stats64 = rtl8365mb_get_stats64,
> -	.port_change_mtu = rtl8365mb_port_change_mtu,
> -	.port_max_mtu = rtl8365mb_port_max_mtu,
> -};
> -
> -static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
> +static const struct dsa_switch_ops rtl8365mb_switch_ops = {
>  	.get_tag_protocol = rtl8365mb_get_tag_protocol,
>  	.change_tag_protocol = rtl8365mb_change_tag_protocol,
>  	.setup = rtl8365mb_setup,
> @@ -2146,8 +2112,6 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
>  	.phylink_mac_config = rtl8365mb_phylink_mac_config,
>  	.phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
>  	.phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> -	.phy_read = rtl8365mb_dsa_phy_read,
> -	.phy_write = rtl8365mb_dsa_phy_write,
>  	.port_stp_state_set = rtl8365mb_port_stp_state_set,
>  	.get_strings = rtl8365mb_get_strings,
>  	.get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> @@ -2167,8 +2131,7 @@ static const struct realtek_ops rtl8365mb_ops = {
>  };
>  
>  const struct realtek_variant rtl8365mb_variant = {
> -	.ds_ops_smi = &rtl8365mb_switch_ops_smi,
> -	.ds_ops_mdio = &rtl8365mb_switch_ops_mdio,
> +	.ds_ops = &rtl8365mb_switch_ops,
>  	.ops = &rtl8365mb_ops,
>  	.clk_delay = 10,
>  	.cmd_read = 0xb9,
> diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
> index e60a0a81d426..56619aa592ec 100644
> --- a/drivers/net/dsa/realtek/rtl8366rb.c
> +++ b/drivers/net/dsa/realtek/rtl8366rb.c
> @@ -1027,12 +1027,10 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
>  	if (ret)
>  		dev_info(priv->dev, "no interrupt support\n");
>  
> -	if (priv->setup_interface) {
> -		ret = priv->setup_interface(ds);
> -		if (ret) {
> -			dev_err(priv->dev, "could not set up MDIO bus\n");
> -			return -ENODEV;
> -		}
> +	ret = realtek_common_setup_user_mdio(ds);
> +	if (ret) {
> +		dev_err(priv->dev, "could not set up MDIO bus\n");
> +		return -ENODEV;
>  	}
>  
>  	return 0;
> @@ -1772,17 +1770,6 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
>  	return ret;
>  }
>  
> -static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> -{
> -	return rtl8366rb_phy_read(ds->priv, phy, regnum);
> -}
> -
> -static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> -				   u16 val)
> -{
> -	return rtl8366rb_phy_write(ds->priv, phy, regnum, val);
> -}
> -
>  static int rtl8366rb_reset_chip(struct realtek_priv *priv)
>  {
>  	int timeout = 10;
> @@ -1848,35 +1835,9 @@ static int rtl8366rb_detect(struct realtek_priv *priv)
>  	return 0;
>  }
>  
> -static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = {
> -	.get_tag_protocol = rtl8366_get_tag_protocol,
> -	.setup = rtl8366rb_setup,
> -	.phylink_get_caps = rtl8366rb_phylink_get_caps,
> -	.phylink_mac_link_up = rtl8366rb_mac_link_up,
> -	.phylink_mac_link_down = rtl8366rb_mac_link_down,
> -	.get_strings = rtl8366_get_strings,
> -	.get_ethtool_stats = rtl8366_get_ethtool_stats,
> -	.get_sset_count = rtl8366_get_sset_count,
> -	.port_bridge_join = rtl8366rb_port_bridge_join,
> -	.port_bridge_leave = rtl8366rb_port_bridge_leave,
> -	.port_vlan_filtering = rtl8366rb_vlan_filtering,
> -	.port_vlan_add = rtl8366_vlan_add,
> -	.port_vlan_del = rtl8366_vlan_del,
> -	.port_enable = rtl8366rb_port_enable,
> -	.port_disable = rtl8366rb_port_disable,
> -	.port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
> -	.port_bridge_flags = rtl8366rb_port_bridge_flags,
> -	.port_stp_state_set = rtl8366rb_port_stp_state_set,
> -	.port_fast_age = rtl8366rb_port_fast_age,
> -	.port_change_mtu = rtl8366rb_change_mtu,
> -	.port_max_mtu = rtl8366rb_max_mtu,
> -};
> -
> -static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = {
> +static const struct dsa_switch_ops rtl8366rb_switch_ops = {
>  	.get_tag_protocol = rtl8366_get_tag_protocol,
>  	.setup = rtl8366rb_setup,
> -	.phy_read = rtl8366rb_dsa_phy_read,
> -	.phy_write = rtl8366rb_dsa_phy_write,
>  	.phylink_get_caps = rtl8366rb_phylink_get_caps,
>  	.phylink_mac_link_up = rtl8366rb_mac_link_up,
>  	.phylink_mac_link_down = rtl8366rb_mac_link_down,
> @@ -1915,8 +1876,7 @@ static const struct realtek_ops rtl8366rb_ops = {
>  };
>  
>  const struct realtek_variant rtl8366rb_variant = {
> -	.ds_ops_smi = &rtl8366rb_switch_ops_smi,
> -	.ds_ops_mdio = &rtl8366rb_switch_ops_mdio,
> +	.ds_ops = &rtl8366rb_switch_ops,
>  	.ops = &rtl8366rb_ops,
>  	.clk_delay = 10,
>  	.cmd_read = 0xa9,
> -- 
> 2.43.0
>

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

* Re: [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus"
  2023-12-20  4:24 ` [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus" Luiz Angelo Daros de Luca
@ 2023-12-20 13:19   ` Alvin Šipraga
  2023-12-21  3:45     ` Luiz Angelo Daros de Luca
  2023-12-21  0:41   ` kernel test robot
  1 sibling, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-20 13:19 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:30AM -0300, Luiz Angelo Daros de Luca wrote:
> This reverts commit fe7324b932222574a0721b80e72c6c5fe57960d1.
> 
> The use of user_mii_bus is inappropriate when the hardware is described
> with a device-tree [1].
> 
> Since all drivers currently implementing ds_switch_ops.phy_{read,write}
> were not updated to utilize the MDIO information from OF with the
> generic "dsa user mii", they might not be affected by this change.

/might/ not? I think this paragraph could be more precisely worded.

> 
> [1] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
> 
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> ---
>  net/dsa/dsa.c | 7 +------
>  1 file changed, 1 insertion(+), 6 deletions(-)
> 
> diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> index ac7be864e80d..cea364c81b70 100644
> --- a/net/dsa/dsa.c
> +++ b/net/dsa/dsa.c
> @@ -15,7 +15,6 @@
>  #include <linux/slab.h>
>  #include <linux/rtnetlink.h>
>  #include <linux/of.h>
> -#include <linux/of_mdio.h>
>  #include <linux/of_net.h>
>  #include <net/dsa_stubs.h>
>  #include <net/sch_generic.h>
> @@ -626,7 +625,6 @@ static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds)
>  
>  static int dsa_switch_setup(struct dsa_switch *ds)
>  {
> -	struct device_node *dn;
>  	int err;
>  
>  	if (ds->setup)
> @@ -666,10 +664,7 @@ static int dsa_switch_setup(struct dsa_switch *ds)
>  
>  		dsa_user_mii_bus_init(ds);
>  
> -		dn = of_get_child_by_name(ds->dev->of_node, "mdio");
> -
> -		err = of_mdiobus_register(ds->user_mii_bus, dn);
> -		of_node_put(dn);
> +		err = mdiobus_register(ds->user_mii_bus, dn);
>  		if (err < 0)
>  			goto free_user_mii_bus;
>  	}
> -- 
> 2.43.0
>

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

* Re: [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops
  2023-12-20  4:24 ` [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops Luiz Angelo Daros de Luca
@ 2023-12-20 13:57   ` Alvin Šipraga
  2023-12-21 17:04     ` Vladimir Oltean
  0 siblings, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-20 13:57 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:24AM -0300, Luiz Angelo Daros de Luca wrote:
> It was never used and never referenced.
> 
> Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>

You should always put your Signed-off-by last when sending patches.

> ---
>  drivers/net/dsa/realtek/realtek.h | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> index 790488e9c667..e9ee778665b2 100644
> --- a/drivers/net/dsa/realtek/realtek.h
> +++ b/drivers/net/dsa/realtek/realtek.h
> @@ -91,7 +91,6 @@ struct realtek_ops {
>  	int	(*detect)(struct realtek_priv *priv);
>  	int	(*reset_chip)(struct realtek_priv *priv);
>  	int	(*setup)(struct realtek_priv *priv);
> -	void	(*cleanup)(struct realtek_priv *priv);
>  	int	(*get_mib_counter)(struct realtek_priv *priv,
>  				   int port,
>  				   struct rtl8366_mib_counter *mib,
> -- 
> 2.43.0
>

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

* Re: [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module
  2023-12-20 10:40   ` Alvin Šipraga
@ 2023-12-20 15:50     ` Alvin Šipraga
  2023-12-21  3:25       ` Luiz Angelo Daros de Luca
  2023-12-21  3:11     ` Luiz Angelo Daros de Luca
  1 sibling, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-20 15:50 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 10:40:25AM +0000, Alvin Šipraga wrote:
> On Wed, Dec 20, 2023 at 01:24:26AM -0300, Luiz Angelo Daros de Luca wrote:
> > +	/* TODO: if power is software controlled, set up any regulators here */
> > +
> > +	priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > +	if (IS_ERR(priv->reset)) {
> > +		dev_err(dev, "failed to get RESET GPIO\n");
> > +		return ERR_CAST(priv->reset);
> > +	}
> > +	if (priv->reset) {
> > +		gpiod_set_value(priv->reset, 1);
> > +		dev_dbg(dev, "asserted RESET\n");
> > +		msleep(REALTEK_HW_STOP_DELAY);
> > +		gpiod_set_value(priv->reset, 0);
> > +		msleep(REALTEK_HW_START_DELAY);
> > +		dev_dbg(dev, "deasserted RESET\n");
> > +	}
> 
> I simply cannot understand why you insist on moving this part despite
> our earlier discussion on it where I pointed out that it makes no
> sense to move it. Is chip hardware reset not the discipline of the chip
> variant driver?
> 
> Why don't you just keep it in its original place? It will make your
> patch smaller, which is what you seemed to care about the last time I
> raised this.
> 
> Sorry, but I cannot give my Reviewed-by on this patch with this part
> moved around.

Well, to be fair, your original goal was to add support for reset
controllers. And Vladimir pointed out that you end up with a lot of
duplicated code when doing that. And he has a point.

So on reflection, I think this part is OK for now. Then you can then get
unblocked and put your reset controller patch on top when you get around
to it, without the code duplication. I think code can be adapted to
support regulators without too much churn. I'm sorry for the overly
negative feedback.

But please have a look at my comments in patch 5, since they apply more
broadly to your series.

Kind regards,
Alvin

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

* Re: [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus"
  2023-12-20  4:24 ` [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus" Luiz Angelo Daros de Luca
  2023-12-20 13:19   ` Alvin Šipraga
@ 2023-12-21  0:41   ` kernel test robot
  1 sibling, 0 replies; 38+ messages in thread
From: kernel test robot @ 2023-12-21  0:41 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca, netdev
  Cc: oe-kbuild-all, linus.walleij, alsi, andrew, f.fainelli, olteanv,
	davem, edumazet, kuba, pabeni, arinc.unal,
	Luiz Angelo Daros de Luca

Hi Luiz,

kernel test robot noticed the following build errors:

[auto build test ERROR on net-next/main]

url:    https://github.com/intel-lab-lkp/linux/commits/Luiz-Angelo-Daros-de-Luca/net-dsa-realtek-drop-cleanup-from-realtek_ops/20231220-122907
base:   net-next/main
patch link:    https://lore.kernel.org/r/20231220042632.26825-8-luizluca%40gmail.com
patch subject: [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus"
config: arm64-defconfig (https://download.01.org/0day-ci/archive/20231221/202312210853.t6DhuvdS-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231221/202312210853.t6DhuvdS-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202312210853.t6DhuvdS-lkp@intel.com/

All errors (new ones prefixed by >>):

   net/dsa/dsa.c: In function 'dsa_switch_setup':
>> net/dsa/dsa.c:667:60: error: macro "mdiobus_register" passed 2 arguments, but takes just 1
     667 |                 err = mdiobus_register(ds->user_mii_bus, dn);
         |                                                            ^
   In file included from include/linux/of_net.h:9,
                    from net/dsa/dsa.c:18:
   include/linux/phy.h:456: note: macro "mdiobus_register" defined here
     456 | #define mdiobus_register(bus) __mdiobus_register(bus, THIS_MODULE)
         | 
>> net/dsa/dsa.c:667:23: error: 'mdiobus_register' undeclared (first use in this function); did you mean 'mdiobus_unregister'?
     667 |                 err = mdiobus_register(ds->user_mii_bus, dn);
         |                       ^~~~~~~~~~~~~~~~
         |                       mdiobus_unregister
   net/dsa/dsa.c:667:23: note: each undeclared identifier is reported only once for each function it appears in


vim +/mdiobus_register +667 net/dsa/dsa.c

   625	
   626	static int dsa_switch_setup(struct dsa_switch *ds)
   627	{
   628		int err;
   629	
   630		if (ds->setup)
   631			return 0;
   632	
   633		/* Initialize ds->phys_mii_mask before registering the user MDIO bus
   634		 * driver and before ops->setup() has run, since the switch drivers and
   635		 * the user MDIO bus driver rely on these values for probing PHY
   636		 * devices or not
   637		 */
   638		ds->phys_mii_mask |= dsa_user_ports(ds);
   639	
   640		err = dsa_switch_devlink_alloc(ds);
   641		if (err)
   642			return err;
   643	
   644		err = dsa_switch_register_notifier(ds);
   645		if (err)
   646			goto devlink_free;
   647	
   648		ds->configure_vlan_while_not_filtering = true;
   649	
   650		err = ds->ops->setup(ds);
   651		if (err < 0)
   652			goto unregister_notifier;
   653	
   654		err = dsa_switch_setup_tag_protocol(ds);
   655		if (err)
   656			goto teardown;
   657	
   658		if (!ds->user_mii_bus && ds->ops->phy_read) {
   659			ds->user_mii_bus = mdiobus_alloc();
   660			if (!ds->user_mii_bus) {
   661				err = -ENOMEM;
   662				goto teardown;
   663			}
   664	
   665			dsa_user_mii_bus_init(ds);
   666	
 > 667			err = mdiobus_register(ds->user_mii_bus, dn);
   668			if (err < 0)
   669				goto free_user_mii_bus;
   670		}
   671	
   672		dsa_switch_devlink_register(ds);
   673	
   674		ds->setup = true;
   675		return 0;
   676	
   677	free_user_mii_bus:
   678		if (ds->user_mii_bus && ds->ops->phy_read)
   679			mdiobus_free(ds->user_mii_bus);
   680	teardown:
   681		if (ds->ops->teardown)
   682			ds->ops->teardown(ds);
   683	unregister_notifier:
   684		dsa_switch_unregister_notifier(ds);
   685	devlink_free:
   686		dsa_switch_devlink_free(ds);
   687		return err;
   688	}
   689	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-20 13:17   ` Alvin Šipraga
@ 2023-12-21  3:03     ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-21  3:03 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

> On Wed, Dec 20, 2023 at 01:24:28AM -0300, Luiz Angelo Daros de Luca wrote:
> > In the user MDIO driver, despite numerous references to SMI, including
> > its compatible string, there's nothing inherently specific about the SMI
> > interface in the user MDIO bus. Consequently, the code has been migrated
> > to the common module. All references to SMI have been eliminated, with
> > the exception of the compatible string, which will continue to function
> > as before.
> >
> > The realtek-mdio will now use this driver instead of the generic DSA
> > driver ("dsa user smi"), which should not be used with OF[1].
> >
> > There was a change in how the driver looks for the MDIO node in the
> > device tree. Now, it first checks for a child node named "mdio," which
> > is required by both interfaces in binding docs but used previously only
> > by realtek-mdio. If the node is not found, it will also look for a
> > compatible string, required only by SMI-connected devices in binding
> > docs and compatible with the old realtek-smi behavior.
> >
> > The line assigning dev.of_node in mdio_bus has been removed since the
> > subsequent of_mdiobus_register will always overwrite it.
> >
> > ds->user_mii_bus is only defined if all user ports do not declare a
> > phy-handle, providing a warning about the erroneous device tree[2].
> >
> > With a single ds_ops for both interfaces, the ds_ops in realtek_priv is
> > no longer necessary. Now, the realtek_variant.ds_ops can be used
> > directly.
> >
> > The realtek_priv.setup_interface() has been removed as we can directly
> > call the new common function.
> >
> > The switch unregistration and the MDIO node decrement in refcount were
> > moved into realtek_common_remove() as both interfaces now need to put
> > the MDIO node.
> >
> > [1] https://lkml.kernel.org/netdev/20220630200423.tieprdu5fpabflj7@bang-olufsen.dk/T/
> > [2] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
> >
> > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > ---
> >  drivers/net/dsa/realtek/realtek-common.c | 87 +++++++++++++++++++++++-
> >  drivers/net/dsa/realtek/realtek-common.h |  1 +
> >  drivers/net/dsa/realtek/realtek-mdio.c   |  6 --
> >  drivers/net/dsa/realtek/realtek-smi.c    | 68 ------------------
> >  drivers/net/dsa/realtek/realtek.h        |  5 +-
> >  drivers/net/dsa/realtek/rtl8365mb.c      | 49 ++-----------
> >  drivers/net/dsa/realtek/rtl8366rb.c      | 52 ++------------
> >  7 files changed, 100 insertions(+), 168 deletions(-)
> >
> > diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
> > index bf3933a99072..b1f0095d5bce 100644
> > --- a/drivers/net/dsa/realtek/realtek-common.c
> > +++ b/drivers/net/dsa/realtek/realtek-common.c
> > @@ -1,6 +1,7 @@
> >  // SPDX-License-Identifier: GPL-2.0+
> >
> >  #include <linux/module.h>
> > +#include <linux/of_mdio.h>
> >
> >  #include "realtek.h"
> >  #include "realtek-common.h"
> > @@ -21,6 +22,85 @@ void realtek_common_unlock(void *ctx)
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_common_unlock);
> >
> > +static int realtek_common_user_mdio_read(struct mii_bus *bus, int addr,
> > +                                      int regnum)
> > +{
> > +     struct realtek_priv *priv = bus->priv;
> > +
> > +     return priv->ops->phy_read(priv, addr, regnum);
> > +}
> > +
> > +static int realtek_common_user_mdio_write(struct mii_bus *bus, int addr,
> > +                                       int regnum, u16 val)
> > +{
> > +     struct realtek_priv *priv = bus->priv;
> > +
> > +     return priv->ops->phy_write(priv, addr, regnum, val);
> > +}
> > +
> > +int realtek_common_setup_user_mdio(struct dsa_switch *ds)
> > +{
> > +     const char *compatible = "realtek,smi-mdio";
>
> No need to put this in its own variable, it makes the code harder to read.

OK. Without a warning message that would use it again, it is better to
simply use the literal.

> > +     struct realtek_priv *priv =  ds->priv;
> > +     struct device_node *phy_node;
> > +     struct device_node *mdio_np;
> > +     struct dsa_port *dp;
> > +     int ret;
> > +
> > +     mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
> > +     if (!mdio_np) {
> > +             mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
> > +             if (!mdio_np) {
> > +                     dev_err(priv->dev, "no MDIO bus node\n");
> > +                     return -ENODEV;
> > +             }
> > +     }
> > +
> > +     priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> > +     if (!priv->user_mii_bus) {
> > +             ret = -ENOMEM;
> > +             goto err_put_node;
> > +     }
> > +     priv->user_mii_bus->priv = priv;
> > +     priv->user_mii_bus->name = "Realtek user MII";
> > +     priv->user_mii_bus->read = realtek_common_user_mdio_read;
> > +     priv->user_mii_bus->write = realtek_common_user_mdio_write;
> > +     snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
> > +              ds->index);
> > +     priv->user_mii_bus->parent = priv->dev;
> > +
> > +     /* When OF describes the MDIO, connecting ports with phy-handle,
> > +      * ds->user_mii_bus should not be used *
>
> Stray *, put a full stop.

OK

>
> > +      */
> > +     dsa_switch_for_each_user_port(dp, ds) {
> > +             phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +             of_node_put(phy_node);
> > +             if (phy_node)
> > +                     continue;
> > +
> > +             dev_warn(priv->dev,
> > +                      "DS user_mii_bus in use as '%s' is missing phy-handle",
> > +                      dp->name);
>
> "DS user_mii_bus in use" is a very cryptic warning, can you not just
> warn about a missing phy-handle, since that is what is expected?

I was struggling to fit an informative message in the 80 cols limit.
However, kernel messages are not the place for whys, just whats.
I'll change to:

                dev_warn(priv->dev, "'%s' should have a phy-handle",
                        dp->name);

> > +             ds->user_mii_bus = priv->user_mii_bus;
> > +             break;
> > +     }
> > +
> > +     ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
>
> You use devres here, but this means the mdiobus will outlive the switch
> after dsa_switch_teardown(). I don't really know if this can cause any
> unwanted runtime behaviour, but the code feels unbalanced.

devm_* functions prepare objects to be destroyed/unregistered/removed
when a parent device is gone. So, if you use devm_* anywhere but in
the probe function, it might look like it is unbalanced because the
unwinding process happens automatically, outside the driver control.
So, technically, it will always be at least a little bit unbalanced.
However, the guarantee it will be cleaned and in the correct order is
worth it.

Vladimir suggested that new drivers should split the MDIO bus driver
from the DSA driver. I believe it is expected that mdiobus will
outlive the switch and it could also be registered before the switch
is registered or even allocated. We just need it to be registered
before ports are ready (dsa_tree_setup_ports?). The switch setup is
just the last opportunity we have to register an MDIO bus. Would it be
better if we move the realtek_common_setup_user_mdio call from
variants to just before the switch is registered in
realtek_common_register_switch? I didn't test it but it should work.

> > +     if (ret) {
> > +             dev_err(priv->dev, "unable to register MDIO bus %s\n",
> > +                     priv->user_mii_bus->id);
> > +             goto err_put_node;
> > +     }
> > +
> > +     return 0;
> > +
> > +err_put_node:
> > +     of_node_put(mdio_np);
> > +
> > +     return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(realtek_common_setup_user_mdio);
> > +
> >  /* sets up driver private data struct, sets up regmaps, parse common device-tree
> >   * properties and finally issues a hardware reset.
> >   */
> > @@ -108,7 +188,7 @@ int realtek_common_register_switch(struct realtek_priv *priv)
> >
> >       priv->ds->priv = priv;
> >       priv->ds->dev = priv->dev;
> > -     priv->ds->ops = priv->ds_ops;
> > +     priv->ds->ops = priv->variant->ds_ops;
> >       priv->ds->num_ports = priv->num_ports;
> >
> >       ret = dsa_register_switch(priv->ds);
> > @@ -126,6 +206,11 @@ void realtek_common_remove(struct realtek_priv *priv)
> >       if (!priv)
> >               return;
> >
> > +     dsa_unregister_switch(priv->ds);
>
> Wait, wasn't this supposed to belong in the previous patch that added
> realtek_common_remove? Why is it being put here in this patch?

It wasn't. The of_node_put, before this patch, is only used by
realtek-smi. So, for realtek-smi, I need to add the put between the
dsa_unregister_switch() and the realtek_common_remove(), when we lose
the mdiobus reference. I thought it wasn't worth it to create a
realtek_common_unregister() that simply calls dsa_unregister_switch().
That's why I left the dsa_unregister_switch (both) and the of_node_put
(realtek-smi) on each interface code. With this commit, realtek-mdio
will also need to put the node, so it makes sense to move the common
code to the realtek_common_remove().

If we could put the node just after the registration (another patch I
sent to OF MDIO API), we wouldn't even need to think about the mdio
bus during removal. It would just go in peace.

> Regarding the series as a whole, I still think all you really need is
> something like this:
>
>   - realtek_common_probe
>   - realtek_common_remove (if there is actually anything to do?)
>   - realtek_common_setup_user_mdio
>   - realtek_common_teardown_user_mdio
>
> The chip variant drivers can then do:
>
>   /* Interface-agnostic chip driver code */
>
>   rtl836xxx_setup() {
>     // ...
>     realtek_common_setup_user_mdio();
>     // ...
>   }
>
>   rtl836xxx_teardown() {
>     // ...
>     realtek_common_teardown_user_mdio();
>     // ...
>   }
>
>   rtl836xxx_probe() {
>     // assert
>     // enable regulators
>     // deassert reset
>     // do what was in detect() before
>     dsa_register_switch(priv->ds);
>   }
>
>   rtl836xxx_remove() {
>     dsa_unregister_switch();
>     // assert reset again
>   }
>
>   /* SMI boilerplate */
>
>   rtl836xxx_smi_probe() {
>     priv = realtek_smi_probe();
>     return rtl836xxx_probe(priv);
>   }
>
>   rtl836xxx_smi_remove() {
>     rtl836xxx_remove();
>     realtek_smi_remove(); // if needed
>   }
>
>   /* MDIO boilerplate */
>
>   rtl836xxx_mdio_probe() {
>     priv = realtek_mdio_probe();
>     return rtl836xxx_probe(priv);
>   }
>
>   rtl836xxx_mdio_remove() {
>     rtl836xxx_remove();
>     realtek_mdio_remove(); // if needed
>   }
>
> And your interface probe functions:
>
>   realtek_smi_probe() {
>     priv = realtek_common_probe();
>     // SMI specific setup
>     return priv;
>   }
>
>   realtek_mdio_probe() {
>     priv = realtek_common_probe();
>     // MDIO specific setup
>     return priv;
>   }
>
> Am I missing something? I'm open to other suggestions but I can't help
> but feel that the current proposal is half-baked.

Until we have some specific code for probe/remove that is both
interface and variant specific, it just creates some new functions
that have the same code. Up to this point, the detect is responsible
for the variant-specific logic. We could rename it to match a broader
role, like resetting the device before detecting it. However, it will
introduce another unbalance as the "detect" will reset the switch but,
without an "undetect-like" function, the common remove will leave it
asserted. I'm OK with that as resetting and leaving the device reset
asserted, although using the same tools, have different objectives.
But we can discuss that in the 3/7 patch.

While we use devm, there is not much need for tearing down the MDIO
(except, for now, putting the node). I don't think we should put the
node during switch teardown. At this point, all user ports are down
and the mdiobus might not be reachable but, maybe, something might
still interact with the mdio bus (sysfs? a queued syscall?).

Even during driver removal, mdiobus will still be registered and
allocated and it is still odd for me to put a node still referenced in
a registered mdio bus device. At least, it is the closest point we
have before mdiobus_unregister. The correct place to put it would be
between mdiobus_unregister and mdiobus_free, both called by devm on
device destruction and out of our control. There is no
devm_of_put_node and creating a new devm callback to put the node just
looks hacky.

All this just reinforces my belief that of_mdiobus_register should get
the node (and mdio_unregister put it), especially with devm where the
unregister happens out of the driver control. I just don't know if I
did that right.

> As a side note: I also think this will make it a bit easier to reason
> about the ownership of variables in struct realtek_priv. Ultimately its
> contents ought all to belong to the code which ends up in the
> realtek-dsa IMO. With a little effort, the rest can be moved into the
> variant-specific private data structs. And cases like
> realtek_priv::num_ports can be removed completely. But that cleanup is
> for another time.

Please, keep it for another time. I wish I don't end up reimplementing
all the driver just to add a reset control. The driver might need more
love than I'm giving but it would be easier after this series gets in.

> > +
> > +     if (priv->user_mii_bus)
> > +             of_node_put(priv->user_mii_bus->dev.of_node);
>
> I think you should undo your work in the corresponding undo
> function. You set up priv->user_mii_bus in ds_ops::setup, so you should
> undo any such stuff in ds_ops::teardown as well.

As I said, priv->user_mii_bus could (or should?) be set outside dsa
setup and priv->user_mii_bus->dev.of_node should actually be put
between mdiobus_unregister and mdiobus_free, that all called by devm
and out of our control. Here is just the closest we have before devm
does its job.

>
> > +
> >       /* leave the device reset asserted */
> >       if (priv->reset)
> >               gpiod_set_value(priv->reset, 1);
> > diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
> > index 518d091ff496..b1c2a50d85cd 100644
> > --- a/drivers/net/dsa/realtek/realtek-common.h
> > +++ b/drivers/net/dsa/realtek/realtek-common.h
> > @@ -7,6 +7,7 @@
> >
> >  void realtek_common_lock(void *ctx);
> >  void realtek_common_unlock(void *ctx);
> > +int realtek_common_setup_user_mdio(struct dsa_switch *ds);
> >  struct realtek_priv *
> >  realtek_common_probe(struct device *dev, struct regmap_config rc,
> >                    struct regmap_config rc_nolock);
> > diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
> > index 967f6c1e8df0..e2b5432eeb26 100644
> > --- a/drivers/net/dsa/realtek/realtek-mdio.c
> > +++ b/drivers/net/dsa/realtek/realtek-mdio.c
> > @@ -142,7 +142,6 @@ int realtek_mdio_probe(struct mdio_device *mdiodev)
> >       priv->bus = mdiodev->bus;
> >       priv->mdio_addr = mdiodev->addr;
> >       priv->write_reg_noack = realtek_mdio_write;
> > -     priv->ds_ops = priv->variant->ds_ops_mdio;
> >
> >       ret = realtek_common_register_switch(priv);
> >       if (ret)
> > @@ -156,11 +155,6 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
> >  {
> >       struct realtek_priv *priv = dev_get_drvdata(&mdiodev->dev);
> >
> > -     if (!priv)
> > -             return;
> > -
> > -     dsa_unregister_switch(priv->ds);
> > -
> >       realtek_common_remove(priv);
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_mdio_remove);
> > diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
> > index 2b2c6e34bae5..383689163057 100644
> > --- a/drivers/net/dsa/realtek/realtek-smi.c
> > +++ b/drivers/net/dsa/realtek/realtek-smi.c
> > @@ -31,7 +31,6 @@
> >  #include <linux/spinlock.h>
> >  #include <linux/skbuff.h>
> >  #include <linux/of.h>
> > -#include <linux/of_mdio.h>
> >  #include <linux/delay.h>
> >  #include <linux/gpio/consumer.h>
> >  #include <linux/platform_device.h>
> > @@ -339,63 +338,6 @@ static const struct regmap_config realtek_smi_nolock_regmap_config = {
> >       .disable_locking = true,
> >  };
> >
> > -static int realtek_smi_mdio_read(struct mii_bus *bus, int addr, int regnum)
> > -{
> > -     struct realtek_priv *priv = bus->priv;
> > -
> > -     return priv->ops->phy_read(priv, addr, regnum);
> > -}
> > -
> > -static int realtek_smi_mdio_write(struct mii_bus *bus, int addr, int regnum,
> > -                               u16 val)
> > -{
> > -     struct realtek_priv *priv = bus->priv;
> > -
> > -     return priv->ops->phy_write(priv, addr, regnum, val);
> > -}
> > -
> > -static int realtek_smi_setup_mdio(struct dsa_switch *ds)
> > -{
> > -     struct realtek_priv *priv =  ds->priv;
> > -     struct device_node *mdio_np;
> > -     int ret;
> > -
> > -     mdio_np = of_get_compatible_child(priv->dev->of_node, "realtek,smi-mdio");
> > -     if (!mdio_np) {
> > -             dev_err(priv->dev, "no MDIO bus node\n");
> > -             return -ENODEV;
> > -     }
> > -
> > -     priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> > -     if (!priv->user_mii_bus) {
> > -             ret = -ENOMEM;
> > -             goto err_put_node;
> > -     }
> > -     priv->user_mii_bus->priv = priv;
> > -     priv->user_mii_bus->name = "SMI user MII";
> > -     priv->user_mii_bus->read = realtek_smi_mdio_read;
> > -     priv->user_mii_bus->write = realtek_smi_mdio_write;
> > -     snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "SMI-%d",
> > -              ds->index);
> > -     priv->user_mii_bus->dev.of_node = mdio_np;
> > -     priv->user_mii_bus->parent = priv->dev;
> > -     ds->user_mii_bus = priv->user_mii_bus;
> > -
> > -     ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
> > -     if (ret) {
> > -             dev_err(priv->dev, "unable to register MDIO bus %s\n",
> > -                     priv->user_mii_bus->id);
> > -             goto err_put_node;
> > -     }
> > -
> > -     return 0;
> > -
> > -err_put_node:
> > -     of_node_put(mdio_np);
> > -
> > -     return ret;
> > -}
> > -
> >  int realtek_smi_probe(struct platform_device *pdev)
> >  {
> >       struct device *dev = &pdev->dev;
> > @@ -417,8 +359,6 @@ int realtek_smi_probe(struct platform_device *pdev)
> >               return PTR_ERR(priv->mdio);
> >
> >       priv->write_reg_noack = realtek_smi_write_reg_noack;
> > -     priv->setup_interface = realtek_smi_setup_mdio;
> > -     priv->ds_ops = priv->variant->ds_ops_smi;
> >
> >       ret = realtek_common_register_switch(priv);
> >       if (ret)
> > @@ -432,14 +372,6 @@ void realtek_smi_remove(struct platform_device *pdev)
> >  {
> >       struct realtek_priv *priv = platform_get_drvdata(pdev);
> >
> > -     if (!priv)
> > -             return;
> > -
> > -     dsa_unregister_switch(priv->ds);
> > -
> > -     if (priv->user_mii_bus)
> > -             of_node_put(priv->user_mii_bus->dev.of_node);
> > -
> >       realtek_common_remove(priv);
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_smi_remove);
> > diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> > index fbd0616c1df3..7af6dcc1bb24 100644
> > --- a/drivers/net/dsa/realtek/realtek.h
> > +++ b/drivers/net/dsa/realtek/realtek.h
> > @@ -60,7 +60,6 @@ struct realtek_priv {
> >
> >       spinlock_t              lock; /* Locks around command writes */
> >       struct dsa_switch       *ds;
> > -     const struct dsa_switch_ops *ds_ops;
> >       struct irq_domain       *irqdomain;
> >       bool                    leds_disabled;
> >
> > @@ -71,7 +70,6 @@ struct realtek_priv {
> >       struct rtl8366_mib_counter *mib_counters;
> >
> >       const struct realtek_ops *ops;
> > -     int                     (*setup_interface)(struct dsa_switch *ds);
> >       int                     (*write_reg_noack)(void *ctx, u32 addr, u32 data);
> >
> >       int                     vlan_enabled;
> > @@ -115,8 +113,7 @@ struct realtek_ops {
> >  };
> >
> >  struct realtek_variant {
> > -     const struct dsa_switch_ops *ds_ops_smi;
> > -     const struct dsa_switch_ops *ds_ops_mdio;
> > +     const struct dsa_switch_ops *ds_ops;
> >       const struct realtek_ops *ops;
> >       unsigned int clk_delay;
> >       u8 cmd_read;
> > diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> > index 58ec057b6c32..e890ad113ba3 100644
> > --- a/drivers/net/dsa/realtek/rtl8365mb.c
> > +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> > @@ -828,17 +828,6 @@ static int rtl8365mb_phy_write(struct realtek_priv *priv, int phy, int regnum,
> >       return 0;
> >  }
> >
> > -static int rtl8365mb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> > -{
> > -     return rtl8365mb_phy_read(ds->priv, phy, regnum);
> > -}
> > -
> > -static int rtl8365mb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> > -                                u16 val)
> > -{
> > -     return rtl8365mb_phy_write(ds->priv, phy, regnum, val);
> > -}
> > -
> >  static const struct rtl8365mb_extint *
> >  rtl8365mb_get_port_extint(struct realtek_priv *priv, int port)
> >  {
> > @@ -2017,12 +2006,10 @@ static int rtl8365mb_setup(struct dsa_switch *ds)
> >       if (ret)
> >               goto out_teardown_irq;
> >
> > -     if (priv->setup_interface) {
> > -             ret = priv->setup_interface(ds);
> > -             if (ret) {
> > -                     dev_err(priv->dev, "could not set up MDIO bus\n");
> > -                     goto out_teardown_irq;
> > -             }
> > +     ret = realtek_common_setup_user_mdio(ds);
> > +     if (ret) {
> > +             dev_err(priv->dev, "could not set up MDIO bus\n");
> > +             goto out_teardown_irq;
> >       }
> >
> >       /* Start statistics counter polling */
> > @@ -2116,28 +2103,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv)
> >       return 0;
> >  }
> >
> > -static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = {
> > -     .get_tag_protocol = rtl8365mb_get_tag_protocol,
> > -     .change_tag_protocol = rtl8365mb_change_tag_protocol,
> > -     .setup = rtl8365mb_setup,
> > -     .teardown = rtl8365mb_teardown,
> > -     .phylink_get_caps = rtl8365mb_phylink_get_caps,
> > -     .phylink_mac_config = rtl8365mb_phylink_mac_config,
> > -     .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
> > -     .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> > -     .port_stp_state_set = rtl8365mb_port_stp_state_set,
> > -     .get_strings = rtl8365mb_get_strings,
> > -     .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> > -     .get_sset_count = rtl8365mb_get_sset_count,
> > -     .get_eth_phy_stats = rtl8365mb_get_phy_stats,
> > -     .get_eth_mac_stats = rtl8365mb_get_mac_stats,
> > -     .get_eth_ctrl_stats = rtl8365mb_get_ctrl_stats,
> > -     .get_stats64 = rtl8365mb_get_stats64,
> > -     .port_change_mtu = rtl8365mb_port_change_mtu,
> > -     .port_max_mtu = rtl8365mb_port_max_mtu,
> > -};
> > -
> > -static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
> > +static const struct dsa_switch_ops rtl8365mb_switch_ops = {
> >       .get_tag_protocol = rtl8365mb_get_tag_protocol,
> >       .change_tag_protocol = rtl8365mb_change_tag_protocol,
> >       .setup = rtl8365mb_setup,
> > @@ -2146,8 +2112,6 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = {
> >       .phylink_mac_config = rtl8365mb_phylink_mac_config,
> >       .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down,
> >       .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up,
> > -     .phy_read = rtl8365mb_dsa_phy_read,
> > -     .phy_write = rtl8365mb_dsa_phy_write,
> >       .port_stp_state_set = rtl8365mb_port_stp_state_set,
> >       .get_strings = rtl8365mb_get_strings,
> >       .get_ethtool_stats = rtl8365mb_get_ethtool_stats,
> > @@ -2167,8 +2131,7 @@ static const struct realtek_ops rtl8365mb_ops = {
> >  };
> >
> >  const struct realtek_variant rtl8365mb_variant = {
> > -     .ds_ops_smi = &rtl8365mb_switch_ops_smi,
> > -     .ds_ops_mdio = &rtl8365mb_switch_ops_mdio,
> > +     .ds_ops = &rtl8365mb_switch_ops,
> >       .ops = &rtl8365mb_ops,
> >       .clk_delay = 10,
> >       .cmd_read = 0xb9,
> > diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
> > index e60a0a81d426..56619aa592ec 100644
> > --- a/drivers/net/dsa/realtek/rtl8366rb.c
> > +++ b/drivers/net/dsa/realtek/rtl8366rb.c
> > @@ -1027,12 +1027,10 @@ static int rtl8366rb_setup(struct dsa_switch *ds)
> >       if (ret)
> >               dev_info(priv->dev, "no interrupt support\n");
> >
> > -     if (priv->setup_interface) {
> > -             ret = priv->setup_interface(ds);
> > -             if (ret) {
> > -                     dev_err(priv->dev, "could not set up MDIO bus\n");
> > -                     return -ENODEV;
> > -             }
> > +     ret = realtek_common_setup_user_mdio(ds);
> > +     if (ret) {
> > +             dev_err(priv->dev, "could not set up MDIO bus\n");
> > +             return -ENODEV;
> >       }
> >
> >       return 0;
> > @@ -1772,17 +1770,6 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
> >       return ret;
> >  }
> >
> > -static int rtl8366rb_dsa_phy_read(struct dsa_switch *ds, int phy, int regnum)
> > -{
> > -     return rtl8366rb_phy_read(ds->priv, phy, regnum);
> > -}
> > -
> > -static int rtl8366rb_dsa_phy_write(struct dsa_switch *ds, int phy, int regnum,
> > -                                u16 val)
> > -{
> > -     return rtl8366rb_phy_write(ds->priv, phy, regnum, val);
> > -}
> > -
> >  static int rtl8366rb_reset_chip(struct realtek_priv *priv)
> >  {
> >       int timeout = 10;
> > @@ -1848,35 +1835,9 @@ static int rtl8366rb_detect(struct realtek_priv *priv)
> >       return 0;
> >  }
> >
> > -static const struct dsa_switch_ops rtl8366rb_switch_ops_smi = {
> > -     .get_tag_protocol = rtl8366_get_tag_protocol,
> > -     .setup = rtl8366rb_setup,
> > -     .phylink_get_caps = rtl8366rb_phylink_get_caps,
> > -     .phylink_mac_link_up = rtl8366rb_mac_link_up,
> > -     .phylink_mac_link_down = rtl8366rb_mac_link_down,
> > -     .get_strings = rtl8366_get_strings,
> > -     .get_ethtool_stats = rtl8366_get_ethtool_stats,
> > -     .get_sset_count = rtl8366_get_sset_count,
> > -     .port_bridge_join = rtl8366rb_port_bridge_join,
> > -     .port_bridge_leave = rtl8366rb_port_bridge_leave,
> > -     .port_vlan_filtering = rtl8366rb_vlan_filtering,
> > -     .port_vlan_add = rtl8366_vlan_add,
> > -     .port_vlan_del = rtl8366_vlan_del,
> > -     .port_enable = rtl8366rb_port_enable,
> > -     .port_disable = rtl8366rb_port_disable,
> > -     .port_pre_bridge_flags = rtl8366rb_port_pre_bridge_flags,
> > -     .port_bridge_flags = rtl8366rb_port_bridge_flags,
> > -     .port_stp_state_set = rtl8366rb_port_stp_state_set,
> > -     .port_fast_age = rtl8366rb_port_fast_age,
> > -     .port_change_mtu = rtl8366rb_change_mtu,
> > -     .port_max_mtu = rtl8366rb_max_mtu,
> > -};
> > -
> > -static const struct dsa_switch_ops rtl8366rb_switch_ops_mdio = {
> > +static const struct dsa_switch_ops rtl8366rb_switch_ops = {
> >       .get_tag_protocol = rtl8366_get_tag_protocol,
> >       .setup = rtl8366rb_setup,
> > -     .phy_read = rtl8366rb_dsa_phy_read,
> > -     .phy_write = rtl8366rb_dsa_phy_write,
> >       .phylink_get_caps = rtl8366rb_phylink_get_caps,
> >       .phylink_mac_link_up = rtl8366rb_mac_link_up,
> >       .phylink_mac_link_down = rtl8366rb_mac_link_down,
> > @@ -1915,8 +1876,7 @@ static const struct realtek_ops rtl8366rb_ops = {
> >  };
> >
> >  const struct realtek_variant rtl8366rb_variant = {
> > -     .ds_ops_smi = &rtl8366rb_switch_ops_smi,
> > -     .ds_ops_mdio = &rtl8366rb_switch_ops_mdio,
> > +     .ds_ops = &rtl8366rb_switch_ops,
> >       .ops = &rtl8366rb_ops,
> >       .clk_delay = 10,
> >       .cmd_read = 0xa9,
> > --
> > 2.43.0
> >

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

* Re: [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module
  2023-12-20 10:40   ` Alvin Šipraga
  2023-12-20 15:50     ` Alvin Šipraga
@ 2023-12-21  3:11     ` Luiz Angelo Daros de Luca
  1 sibling, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-21  3:11 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

> On Wed, Dec 20, 2023 at 01:24:26AM -0300, Luiz Angelo Daros de Luca wrote:
> > Some code can be shared between both interface modules (MDIO and SMI)
> > and among variants. These interface functions migrated to a common
> > module:
> >
> > - realtek_common_lock
> > - realtek_common_unlock
> > - realtek_common_probe
> > - realtek_common_register_switch
> > - realtek_common_remove
> >
> > The reset during probe was moved to the end of the common probe. This way,
> > we avoid a reset if anything else fails.
> >
> > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > ---
> >  drivers/net/dsa/realtek/Makefile         |   2 +
> >  drivers/net/dsa/realtek/realtek-common.c | 137 +++++++++++++++++++++++
> >  drivers/net/dsa/realtek/realtek-common.h |  16 +++
> >  drivers/net/dsa/realtek/realtek-mdio.c   | 114 +++----------------
> >  drivers/net/dsa/realtek/realtek-smi.c    | 117 +++----------------
> >  drivers/net/dsa/realtek/realtek.h        |   6 +-
> >  drivers/net/dsa/realtek/rtl8365mb.c      |   9 +-
> >  drivers/net/dsa/realtek/rtl8366rb.c      |   9 +-
> >  8 files changed, 199 insertions(+), 211 deletions(-)
> >  create mode 100644 drivers/net/dsa/realtek/realtek-common.c
> >  create mode 100644 drivers/net/dsa/realtek/realtek-common.h
> >
> > diff --git a/drivers/net/dsa/realtek/Makefile b/drivers/net/dsa/realtek/Makefile
> > index 0aab57252a7c..f4f9c6340d5f 100644
> > --- a/drivers/net/dsa/realtek/Makefile
> > +++ b/drivers/net/dsa/realtek/Makefile
> > @@ -1,4 +1,6 @@
> >  # SPDX-License-Identifier: GPL-2.0
> > +obj-$(CONFIG_NET_DSA_REALTEK)                += realtek-dsa.o
> > +realtek-dsa-objs                     := realtek-common.o
> >  obj-$(CONFIG_NET_DSA_REALTEK_MDIO)   += realtek-mdio.o
> >  obj-$(CONFIG_NET_DSA_REALTEK_SMI)    += realtek-smi.o
> >  obj-$(CONFIG_NET_DSA_REALTEK_RTL8366RB) += rtl8366.o
> > diff --git a/drivers/net/dsa/realtek/realtek-common.c b/drivers/net/dsa/realtek/realtek-common.c
> > new file mode 100644
> > index 000000000000..c7507b6cdcdd
> > --- /dev/null
> > +++ b/drivers/net/dsa/realtek/realtek-common.c
> > @@ -0,0 +1,137 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +
> > +#include <linux/module.h>
> > +
> > +#include "realtek.h"
> > +#include "realtek-common.h"
> > +
> > +void realtek_common_lock(void *ctx)
> > +{
> > +     struct realtek_priv *priv = ctx;
> > +
> > +     mutex_lock(&priv->map_lock);
> > +}
> > +EXPORT_SYMBOL_GPL(realtek_common_lock);
> > +
> > +void realtek_common_unlock(void *ctx)
> > +{
> > +     struct realtek_priv *priv = ctx;
> > +
> > +     mutex_unlock(&priv->map_lock);
> > +}
> > +EXPORT_SYMBOL_GPL(realtek_common_unlock);
> > +
> > +/* sets up driver private data struct, sets up regmaps, parse common device-tree
> > + * properties and finally issues a hardware reset.
> > + */
>
> Please use kdoc format if you add such comments. But I think we agreed
> that the name is quite informative now, so you can also just drop it.

OK

>
> > +struct realtek_priv *
> > +realtek_common_probe(struct device *dev, struct regmap_config rc,
> > +                  struct regmap_config rc_nolock)
> > +{
> > +     const struct realtek_variant *var;
> > +     struct realtek_priv *priv;
> > +     int ret;
> > +
> > +     var = of_device_get_match_data(dev);
> > +     if (!var)
> > +             return ERR_PTR(-EINVAL);
> > +
> > +     priv = devm_kzalloc(dev, size_add(sizeof(*priv), var->chip_data_sz),
> > +                         GFP_KERNEL);
> > +     if (!priv)
> > +             return ERR_PTR(-ENOMEM);
> > +
> > +     mutex_init(&priv->map_lock);
> > +
> > +     rc.lock_arg = priv;
> > +     priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> > +     if (IS_ERR(priv->map)) {
> > +             ret = PTR_ERR(priv->map);
> > +             dev_err(dev, "regmap init failed: %d\n", ret);
> > +             return ERR_PTR(ret);
> > +     }
> > +
> > +     priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc_nolock);
> > +     if (IS_ERR(priv->map_nolock)) {
> > +             ret = PTR_ERR(priv->map_nolock);
> > +             dev_err(dev, "regmap init failed: %d\n", ret);
> > +             return ERR_PTR(ret);
> > +     }
> > +
> > +     /* Link forward and backward */
> > +     priv->dev = dev;
> > +     priv->variant = var;
> > +     priv->ops = var->ops;
> > +     priv->chip_data = (void *)priv + sizeof(*priv);
> > +
> > +     dev_set_drvdata(dev, priv);
> > +     spin_lock_init(&priv->lock);
> > +
> > +     priv->leds_disabled = of_property_read_bool(dev->of_node,
> > +                                                 "realtek,disable-leds");
> > +
> > +     /* TODO: if power is software controlled, set up any regulators here */
> > +
> > +     priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > +     if (IS_ERR(priv->reset)) {
> > +             dev_err(dev, "failed to get RESET GPIO\n");
> > +             return ERR_CAST(priv->reset);
> > +     }
> > +     if (priv->reset) {
> > +             gpiod_set_value(priv->reset, 1);
> > +             dev_dbg(dev, "asserted RESET\n");
> > +             msleep(REALTEK_HW_STOP_DELAY);
> > +             gpiod_set_value(priv->reset, 0);
> > +             msleep(REALTEK_HW_START_DELAY);
> > +             dev_dbg(dev, "deasserted RESET\n");
> > +     }
>
> I simply cannot understand why you insist on moving this part despite
> our earlier discussion on it where I pointed out that it makes no
> sense to move it. Is chip hardware reset not the discipline of the chip
> variant driver?
>
> Why don't you just keep it in its original place? It will make your
> patch smaller, which is what you seemed to care about the last time I
> raised this.

If I keep where it was, it will be in the interface code, not the
variant one. The only variant specific code during probe is the
detect. We could explode each probe for each interface and each
variant and drop the realtek_ops->detect callback but it now saves a
lot of duplications.

> Sorry, but I cannot give my Reviewed-by on this patch with this part
> moved around.

Should I add a new realtek_common_hwreset() with the reset code and
add a call to it at the beginning of each variant detect?

> > +
> > +     return priv;
> > +}
> > +EXPORT_SYMBOL(realtek_common_probe);
> > +
> > +/* Detects the realtek switch id/version and registers the dsa switch.
> > + */
> > +int realtek_common_register_switch(struct realtek_priv *priv)
> > +{
> > +     int ret;
> > +
> > +     ret = priv->ops->detect(priv);
> > +     if (ret) {
> > +             dev_err_probe(priv->dev, ret, "unable to detect switch\n");
> > +             return ret;
> > +     }
> > +
> > +     priv->ds = devm_kzalloc(priv->dev, sizeof(*priv->ds), GFP_KERNEL);
> > +     if (!priv->ds)
> > +             return -ENOMEM;
> > +
> > +     priv->ds->priv = priv;
> > +     priv->ds->dev = priv->dev;
> > +     priv->ds->ops = priv->ds_ops;
> > +     priv->ds->num_ports = priv->num_ports;
> > +
> > +     ret = dsa_register_switch(priv->ds);
> > +     if (ret) {
> > +             dev_err_probe(priv->dev, ret, "unable to register switch\n");
> > +             return ret;
> > +     }
> > +
> > +     return 0;
> > +}
> > +EXPORT_SYMBOL(realtek_common_register_switch);
> > +
> > +void realtek_common_remove(struct realtek_priv *priv)
> > +{
> > +     if (!priv)
> > +             return;
>
> This check is not really necessary.
>
> > +
> > +     /* leave the device reset asserted */
> > +     if (priv->reset)
> > +             gpiod_set_value(priv->reset, 1);
> > +}
> > +EXPORT_SYMBOL(realtek_common_remove);
> > +
> > +MODULE_AUTHOR("Luiz Angelo Daros de Luca <luizluca@gmail.com>");
> > +MODULE_DESCRIPTION("Realtek DSA switches common module");
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/net/dsa/realtek/realtek-common.h b/drivers/net/dsa/realtek/realtek-common.h
> > new file mode 100644
> > index 000000000000..518d091ff496
> > --- /dev/null
> > +++ b/drivers/net/dsa/realtek/realtek-common.h
> > @@ -0,0 +1,16 @@
> > +/* SPDX-License-Identifier: GPL-2.0+ */
> > +
> > +#ifndef _REALTEK_COMMON_H
> > +#define _REALTEK_COMMON_H
> > +
> > +#include <linux/regmap.h>
> > +
> > +void realtek_common_lock(void *ctx);
> > +void realtek_common_unlock(void *ctx);
> > +struct realtek_priv *
> > +realtek_common_probe(struct device *dev, struct regmap_config rc,
> > +                  struct regmap_config rc_nolock);
> > +int realtek_common_register_switch(struct realtek_priv *priv);
> > +void realtek_common_remove(struct realtek_priv *priv);
> > +
> > +#endif /* _REALTEK_COMMON_H */
> > diff --git a/drivers/net/dsa/realtek/realtek-mdio.c b/drivers/net/dsa/realtek/realtek-mdio.c
> > index 58966d0625c8..1eed09ab3aa1 100644
> > --- a/drivers/net/dsa/realtek/realtek-mdio.c
> > +++ b/drivers/net/dsa/realtek/realtek-mdio.c
> > @@ -26,6 +26,7 @@
> >
> >  #include "realtek.h"
> >  #include "realtek-mdio.h"
> > +#include "realtek-common.h"
> >
> >  /* Read/write via mdiobus */
> >  #define REALTEK_MDIO_CTRL0_REG               31
> > @@ -100,20 +101,6 @@ static int realtek_mdio_read(void *ctx, u32 reg, u32 *val)
> >       return ret;
> >  }
> >
> > -static void realtek_mdio_lock(void *ctx)
> > -{
> > -     struct realtek_priv *priv = ctx;
> > -
> > -     mutex_lock(&priv->map_lock);
> > -}
> > -
> > -static void realtek_mdio_unlock(void *ctx)
> > -{
> > -     struct realtek_priv *priv = ctx;
> > -
> > -     mutex_unlock(&priv->map_lock);
> > -}
> > -
> >  static const struct regmap_config realtek_mdio_regmap_config = {
> >       .reg_bits = 10, /* A4..A0 R4..R0 */
> >       .val_bits = 16,
> > @@ -124,8 +111,8 @@ static const struct regmap_config realtek_mdio_regmap_config = {
> >       .reg_read = realtek_mdio_read,
> >       .reg_write = realtek_mdio_write,
> >       .cache_type = REGCACHE_NONE,
> > -     .lock = realtek_mdio_lock,
> > -     .unlock = realtek_mdio_unlock,
> > +     .lock = realtek_common_lock,
> > +     .unlock = realtek_common_unlock,
> >  };
> >
> >  static const struct regmap_config realtek_mdio_nolock_regmap_config = {
> > @@ -143,96 +130,23 @@ static const struct regmap_config realtek_mdio_nolock_regmap_config = {
> >
> >  int realtek_mdio_probe(struct mdio_device *mdiodev)
> >  {
> > -     struct realtek_priv *priv;
> >       struct device *dev = &mdiodev->dev;
> > -     const struct realtek_variant *var;
> > -     struct regmap_config rc;
> > -     struct device_node *np;
> > +     struct realtek_priv *priv;
> >       int ret;
> >
> > -     var = of_device_get_match_data(dev);
> > -     if (!var)
> > -             return -EINVAL;
> > -
> > -     priv = devm_kzalloc(&mdiodev->dev,
> > -                         size_add(sizeof(*priv), var->chip_data_sz),
> > -                         GFP_KERNEL);
> > -     if (!priv)
> > -             return -ENOMEM;
> > -
> > -     mutex_init(&priv->map_lock);
> > +     priv = realtek_common_probe(dev, realtek_mdio_regmap_config,
> > +                                 realtek_mdio_nolock_regmap_config);
> > +     if (IS_ERR(priv))
> > +             return PTR_ERR(priv);
> >
> > -     rc = realtek_mdio_regmap_config;
> > -     rc.lock_arg = priv;
> > -     priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> > -     if (IS_ERR(priv->map)) {
> > -             ret = PTR_ERR(priv->map);
> > -             dev_err(dev, "regmap init failed: %d\n", ret);
> > -             return ret;
> > -     }
> > -
> > -     rc = realtek_mdio_nolock_regmap_config;
> > -     priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
> > -     if (IS_ERR(priv->map_nolock)) {
> > -             ret = PTR_ERR(priv->map_nolock);
> > -             dev_err(dev, "regmap init failed: %d\n", ret);
> > -             return ret;
> > -     }
> > -
> > -     priv->mdio_addr = mdiodev->addr;
> >       priv->bus = mdiodev->bus;
> > -     priv->dev = &mdiodev->dev;
> > -     priv->chip_data = (void *)priv + sizeof(*priv);
> > -
> > -     priv->clk_delay = var->clk_delay;
> > -     priv->cmd_read = var->cmd_read;
> > -     priv->cmd_write = var->cmd_write;
> > -     priv->ops = var->ops;
> > -
> > +     priv->mdio_addr = mdiodev->addr;
> >       priv->write_reg_noack = realtek_mdio_write;
> > +     priv->ds_ops = priv->variant->ds_ops_mdio;
> >
> > -     np = dev->of_node;
> > -
> > -     dev_set_drvdata(dev, priv);
> > -
> > -     /* TODO: if power is software controlled, set up any regulators here */
> > -     priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
> > -
> > -     priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > -     if (IS_ERR(priv->reset)) {
> > -             dev_err(dev, "failed to get RESET GPIO\n");
> > -             return PTR_ERR(priv->reset);
> > -     }
> > -
> > -     if (priv->reset) {
> > -             gpiod_set_value(priv->reset, 1);
> > -             dev_dbg(dev, "asserted RESET\n");
> > -             msleep(REALTEK_HW_STOP_DELAY);
> > -             gpiod_set_value(priv->reset, 0);
> > -             msleep(REALTEK_HW_START_DELAY);
> > -             dev_dbg(dev, "deasserted RESET\n");
> > -     }
> > -
> > -     ret = priv->ops->detect(priv);
> > -     if (ret) {
> > -             dev_err(dev, "unable to detect switch\n");
> > -             return ret;
> > -     }
> > -
> > -     priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
> > -     if (!priv->ds)
> > -             return -ENOMEM;
> > -
> > -     priv->ds->dev = dev;
> > -     priv->ds->num_ports = priv->num_ports;
> > -     priv->ds->priv = priv;
> > -     priv->ds->ops = var->ds_ops_mdio;
> > -
> > -     ret = dsa_register_switch(priv->ds);
> > -     if (ret) {
> > -             dev_err(priv->dev, "unable to register switch ret = %d\n", ret);
> > +     ret = realtek_common_register_switch(priv);
> > +     if (ret)
> >               return ret;
> > -     }
> >
> >       return 0;
> >  }
> > @@ -247,9 +161,7 @@ void realtek_mdio_remove(struct mdio_device *mdiodev)
> >
> >       dsa_unregister_switch(priv->ds);
> >
> > -     /* leave the device reset asserted */
> > -     if (priv->reset)
> > -             gpiod_set_value(priv->reset, 1);
> > +     realtek_common_remove(priv);
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_mdio_remove);
> >
> > diff --git a/drivers/net/dsa/realtek/realtek-smi.c b/drivers/net/dsa/realtek/realtek-smi.c
> > index 31ac409acfd0..fc54190839cf 100644
> > --- a/drivers/net/dsa/realtek/realtek-smi.c
> > +++ b/drivers/net/dsa/realtek/realtek-smi.c
> > @@ -41,12 +41,13 @@
> >
> >  #include "realtek.h"
> >  #include "realtek-smi.h"
> > +#include "realtek-common.h"
> >
> >  #define REALTEK_SMI_ACK_RETRY_COUNT          5
> >
> >  static inline void realtek_smi_clk_delay(struct realtek_priv *priv)
> >  {
> > -     ndelay(priv->clk_delay);
> > +     ndelay(priv->variant->clk_delay);
> >  }
> >
> >  static void realtek_smi_start(struct realtek_priv *priv)
> > @@ -209,7 +210,7 @@ static int realtek_smi_read_reg(struct realtek_priv *priv, u32 addr, u32 *data)
> >       realtek_smi_start(priv);
> >
> >       /* Send READ command */
> > -     ret = realtek_smi_write_byte(priv, priv->cmd_read);
> > +     ret = realtek_smi_write_byte(priv, priv->variant->cmd_read);
> >       if (ret)
> >               goto out;
> >
> > @@ -250,7 +251,7 @@ static int realtek_smi_write_reg(struct realtek_priv *priv,
> >       realtek_smi_start(priv);
> >
> >       /* Send WRITE command */
> > -     ret = realtek_smi_write_byte(priv, priv->cmd_write);
> > +     ret = realtek_smi_write_byte(priv, priv->variant->cmd_write);
> >       if (ret)
> >               goto out;
> >
> > @@ -311,20 +312,6 @@ static int realtek_smi_read(void *ctx, u32 reg, u32 *val)
> >       return realtek_smi_read_reg(priv, reg, val);
> >  }
> >
> > -static void realtek_smi_lock(void *ctx)
> > -{
> > -     struct realtek_priv *priv = ctx;
> > -
> > -     mutex_lock(&priv->map_lock);
> > -}
> > -
> > -static void realtek_smi_unlock(void *ctx)
> > -{
> > -     struct realtek_priv *priv = ctx;
> > -
> > -     mutex_unlock(&priv->map_lock);
> > -}
> > -
> >  static const struct regmap_config realtek_smi_regmap_config = {
> >       .reg_bits = 10, /* A4..A0 R4..R0 */
> >       .val_bits = 16,
> > @@ -335,8 +322,8 @@ static const struct regmap_config realtek_smi_regmap_config = {
> >       .reg_read = realtek_smi_read,
> >       .reg_write = realtek_smi_write,
> >       .cache_type = REGCACHE_NONE,
> > -     .lock = realtek_smi_lock,
> > -     .unlock = realtek_smi_unlock,
> > +     .lock = realtek_common_lock,
> > +     .unlock = realtek_common_unlock,
> >  };
> >
> >  static const struct regmap_config realtek_smi_nolock_regmap_config = {
> > @@ -411,99 +398,32 @@ static int realtek_smi_setup_mdio(struct dsa_switch *ds)
> >
> >  int realtek_smi_probe(struct platform_device *pdev)
> >  {
> > -     const struct realtek_variant *var;
> >       struct device *dev = &pdev->dev;
> >       struct realtek_priv *priv;
> > -     struct regmap_config rc;
> > -     struct device_node *np;
> >       int ret;
> >
> > -     var = of_device_get_match_data(dev);
> > -     np = dev->of_node;
> > -
> > -     priv = devm_kzalloc(dev, sizeof(*priv) + var->chip_data_sz, GFP_KERNEL);
> > -     if (!priv)
> > -             return -ENOMEM;
> > -     priv->chip_data = (void *)priv + sizeof(*priv);
> > -
> > -     mutex_init(&priv->map_lock);
> > -
> > -     rc = realtek_smi_regmap_config;
> > -     rc.lock_arg = priv;
> > -     priv->map = devm_regmap_init(dev, NULL, priv, &rc);
> > -     if (IS_ERR(priv->map)) {
> > -             ret = PTR_ERR(priv->map);
> > -             dev_err(dev, "regmap init failed: %d\n", ret);
> > -             return ret;
> > -     }
> > -
> > -     rc = realtek_smi_nolock_regmap_config;
> > -     priv->map_nolock = devm_regmap_init(dev, NULL, priv, &rc);
> > -     if (IS_ERR(priv->map_nolock)) {
> > -             ret = PTR_ERR(priv->map_nolock);
> > -             dev_err(dev, "regmap init failed: %d\n", ret);
> > -             return ret;
> > -     }
> > -
> > -     /* Link forward and backward */
> > -     priv->dev = dev;
> > -     priv->clk_delay = var->clk_delay;
> > -     priv->cmd_read = var->cmd_read;
> > -     priv->cmd_write = var->cmd_write;
>
> You don't mention these parts in your commit message. Could be a patch
> in its own right too.
>
> > -     priv->ops = var->ops;
> > -
> > -     priv->setup_interface = realtek_smi_setup_mdio;
> > -     priv->write_reg_noack = realtek_smi_write_reg_noack;
> > -
> > -     dev_set_drvdata(dev, priv);
> > -     spin_lock_init(&priv->lock);
> > -
> > -     /* TODO: if power is software controlled, set up any regulators here */
> > -
> > -     priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > -     if (IS_ERR(priv->reset)) {
> > -             dev_err(dev, "failed to get RESET GPIO\n");
> > -             return PTR_ERR(priv->reset);
> > -     }
> > -     if (priv->reset) {
> > -             gpiod_set_value(priv->reset, 1);
> > -             dev_dbg(dev, "asserted RESET\n");
> > -             msleep(REALTEK_HW_STOP_DELAY);
> > -             gpiod_set_value(priv->reset, 0);
> > -             msleep(REALTEK_HW_START_DELAY);
> > -             dev_dbg(dev, "deasserted RESET\n");
> > -     }
> > +     priv = realtek_common_probe(dev, realtek_smi_regmap_config,
> > +                                 realtek_smi_nolock_regmap_config);
> > +     if (IS_ERR(priv))
> > +             return PTR_ERR(priv);
> >
> >       /* Fetch MDIO pins */
> >       priv->mdc = devm_gpiod_get_optional(dev, "mdc", GPIOD_OUT_LOW);
> >       if (IS_ERR(priv->mdc))
> >               return PTR_ERR(priv->mdc);
> > +
> >       priv->mdio = devm_gpiod_get_optional(dev, "mdio", GPIOD_OUT_LOW);
> >       if (IS_ERR(priv->mdio))
> >               return PTR_ERR(priv->mdio);
> >
> > -     priv->leds_disabled = of_property_read_bool(np, "realtek,disable-leds");
> > +     priv->write_reg_noack = realtek_smi_write_reg_noack;
> > +     priv->setup_interface = realtek_smi_setup_mdio;
> > +     priv->ds_ops = priv->variant->ds_ops_smi;
> >
> > -     ret = priv->ops->detect(priv);
> > -     if (ret) {
> > -             dev_err(dev, "unable to detect switch\n");
> > +     ret = realtek_common_register_switch(priv);
> > +     if (ret)
> >               return ret;
> > -     }
> > -
> > -     priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
> > -     if (!priv->ds)
> > -             return -ENOMEM;
> >
> > -     priv->ds->dev = dev;
> > -     priv->ds->num_ports = priv->num_ports;
> > -     priv->ds->priv = priv;
> > -
> > -     priv->ds->ops = var->ds_ops_smi;
> > -     ret = dsa_register_switch(priv->ds);
> > -     if (ret) {
> > -             dev_err_probe(dev, ret, "unable to register switch\n");
> > -             return ret;
> > -     }
> >       return 0;
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_smi_probe);
> > @@ -516,12 +436,11 @@ void realtek_smi_remove(struct platform_device *pdev)
> >               return;
> >
> >       dsa_unregister_switch(priv->ds);
> > +
> >       if (priv->user_mii_bus)
> >               of_node_put(priv->user_mii_bus->dev.of_node);
> >
> > -     /* leave the device reset asserted */
> > -     if (priv->reset)
> > -             gpiod_set_value(priv->reset, 1);
> > +     realtek_common_remove(priv);
> >  }
> >  EXPORT_SYMBOL_GPL(realtek_smi_remove);
> >
> > diff --git a/drivers/net/dsa/realtek/realtek.h b/drivers/net/dsa/realtek/realtek.h
> > index e9ee778665b2..fbd0616c1df3 100644
> > --- a/drivers/net/dsa/realtek/realtek.h
> > +++ b/drivers/net/dsa/realtek/realtek.h
> > @@ -58,11 +58,9 @@ struct realtek_priv {
> >       struct mii_bus          *bus;
> >       int                     mdio_addr;
> >
> > -     unsigned int            clk_delay;
> > -     u8                      cmd_read;
> > -     u8                      cmd_write;
> >       spinlock_t              lock; /* Locks around command writes */
> >       struct dsa_switch       *ds;
> > +     const struct dsa_switch_ops *ds_ops;
> >       struct irq_domain       *irqdomain;
> >       bool                    leds_disabled;
> >
> > @@ -79,6 +77,8 @@ struct realtek_priv {
> >       int                     vlan_enabled;
> >       int                     vlan4k_enabled;
> >
> > +     const struct realtek_variant *variant;
> > +
> >       char                    buf[4096];
> >       void                    *chip_data; /* Per-chip extra variant data */
> >  };
> > diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c
> > index 1ace2239934a..58ec057b6c32 100644
> > --- a/drivers/net/dsa/realtek/rtl8365mb.c
> > +++ b/drivers/net/dsa/realtek/rtl8365mb.c
> > @@ -103,6 +103,7 @@
> >  #include "realtek.h"
> >  #include "realtek-smi.h"
> >  #include "realtek-mdio.h"
> > +#include "realtek-common.h"
> >
> >  /* Family-specific data and limits */
> >  #define RTL8365MB_PHYADDRMAX         7
> > @@ -691,7 +692,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
> >       u32 val;
> >       int ret;
> >
> > -     mutex_lock(&priv->map_lock);
> > +     realtek_common_lock(priv);
> >
> >       ret = rtl8365mb_phy_poll_busy(priv);
> >       if (ret)
> > @@ -724,7 +725,7 @@ static int rtl8365mb_phy_ocp_read(struct realtek_priv *priv, int phy,
> >       *data = val & 0xFFFF;
> >
> >  out:
> > -     mutex_unlock(&priv->map_lock);
> > +     realtek_common_unlock(priv);
> >
> >       return ret;
> >  }
> > @@ -735,7 +736,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
> >       u32 val;
> >       int ret;
> >
> > -     mutex_lock(&priv->map_lock);
> > +     realtek_common_lock(priv);
> >
> >       ret = rtl8365mb_phy_poll_busy(priv);
> >       if (ret)
> > @@ -766,7 +767,7 @@ static int rtl8365mb_phy_ocp_write(struct realtek_priv *priv, int phy,
> >               goto out;
> >
> >  out:
> > -     mutex_unlock(&priv->map_lock);
> > +     realtek_common_unlock(priv);
> >
> >       return 0;
> >  }
> > diff --git a/drivers/net/dsa/realtek/rtl8366rb.c b/drivers/net/dsa/realtek/rtl8366rb.c
> > index cc2fd636ec23..e60a0a81d426 100644
> > --- a/drivers/net/dsa/realtek/rtl8366rb.c
> > +++ b/drivers/net/dsa/realtek/rtl8366rb.c
> > @@ -24,6 +24,7 @@
> >  #include "realtek.h"
> >  #include "realtek-smi.h"
> >  #include "realtek-mdio.h"
> > +#include "realtek-common.h"
> >
> >  #define RTL8366RB_PORT_NUM_CPU               5
> >  #define RTL8366RB_NUM_PORTS          6
> > @@ -1707,7 +1708,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
> >       if (phy > RTL8366RB_PHY_NO_MAX)
> >               return -EINVAL;
> >
> > -     mutex_lock(&priv->map_lock);
> > +     realtek_common_lock(priv);
> >
> >       ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
> >                          RTL8366RB_PHY_CTRL_READ);
> > @@ -1735,7 +1736,7 @@ static int rtl8366rb_phy_read(struct realtek_priv *priv, int phy, int regnum)
> >               phy, regnum, reg, val);
> >
> >  out:
> > -     mutex_unlock(&priv->map_lock);
> > +     realtek_common_unlock(priv);
> >
> >       return ret;
> >  }
> > @@ -1749,7 +1750,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
> >       if (phy > RTL8366RB_PHY_NO_MAX)
> >               return -EINVAL;
> >
> > -     mutex_lock(&priv->map_lock);
> > +     realtek_common_lock(priv);
> >
> >       ret = regmap_write(priv->map_nolock, RTL8366RB_PHY_ACCESS_CTRL_REG,
> >                          RTL8366RB_PHY_CTRL_WRITE);
> > @@ -1766,7 +1767,7 @@ static int rtl8366rb_phy_write(struct realtek_priv *priv, int phy, int regnum,
> >               goto out;
> >
> >  out:
> > -     mutex_unlock(&priv->map_lock);
> > +     realtek_common_unlock(priv);
> >
> >       return ret;
> >  }
> > --
> > 2.43.0
> >

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

* Re: [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module
  2023-12-20 15:50     ` Alvin Šipraga
@ 2023-12-21  3:25       ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-21  3:25 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

> > > +   /* TODO: if power is software controlled, set up any regulators here */
> > > +
> > > +   priv->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
> > > +   if (IS_ERR(priv->reset)) {
> > > +           dev_err(dev, "failed to get RESET GPIO\n");
> > > +           return ERR_CAST(priv->reset);
> > > +   }
> > > +   if (priv->reset) {
> > > +           gpiod_set_value(priv->reset, 1);
> > > +           dev_dbg(dev, "asserted RESET\n");
> > > +           msleep(REALTEK_HW_STOP_DELAY);
> > > +           gpiod_set_value(priv->reset, 0);
> > > +           msleep(REALTEK_HW_START_DELAY);
> > > +           dev_dbg(dev, "deasserted RESET\n");
> > > +   }
> >
> > I simply cannot understand why you insist on moving this part despite
> > our earlier discussion on it where I pointed out that it makes no
> > sense to move it. Is chip hardware reset not the discipline of the chip
> > variant driver?
> >
> > Why don't you just keep it in its original place? It will make your
> > patch smaller, which is what you seemed to care about the last time I
> > raised this.
> >
> > Sorry, but I cannot give my Reviewed-by on this patch with this part
> > moved around.
>
> Well, to be fair, your original goal was to add support for reset
> controllers. And Vladimir pointed out that you end up with a lot of
> duplicated code when doing that. And he has a point.

Yes, it ended up bringing many more issues, like the driver dependency
direction, duplicated compatibles, and so on. Even issues with the OF
MDIO API and other drivers. However, at some point, we need to stop
adding stuff to the series or I might start to sign-of-by as Sisyphus.

And I still want to take a look at the LED code, which is not working at all.

> So on reflection, I think this part is OK for now. Then you can then get
> unblocked and put your reset controller patch on top when you get around
> to it, without the code duplication. I think code can be adapted to
> support regulators without too much churn. I'm sorry for the overly
> negative feedback.

It's OK. You are just reviewing the code considering what you want to
do on top of it but we need to focus on what makes sense as it is now.

Your reviews are always fruitful. Thank you, Alvin.

> But please have a look at my comments in patch 5, since they apply more
> broadly to your series.

I already did. :-)

> Kind regards,
> Alvin

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

* Re: [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus"
  2023-12-20 13:19   ` Alvin Šipraga
@ 2023-12-21  3:45     ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-21  3:45 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: netdev, linus.walleij, andrew, f.fainelli, olteanv, davem,
	edumazet, kuba, pabeni, arinc.unal

> > This reverts commit fe7324b932222574a0721b80e72c6c5fe57960d1.
> >
> > The use of user_mii_bus is inappropriate when the hardware is described
> > with a device-tree [1].
> >
> > Since all drivers currently implementing ds_switch_ops.phy_{read,write}
> > were not updated to utilize the MDIO information from OF with the
> > generic "dsa user mii", they might not be affected by this change.
>
> /might/ not? I think this paragraph could be more precisely worded.

Yes, it should be "should". That's what I get from working instead of
sleeping. I checked all changes that have happened since that commit
touching drivers with the ds_switch_ops.phy_{read,write}. How about:

  The generic "dsa user mii" driver will only be utilized by drivers
implementing ds_switch_ops.phy_{read,write} and leaving
ds.user_mii_bus unallocated. For these drivers, no commits have been
made since the one being reverted that altered the usage of
ds.user_mii_bus. Consequently, these drivers should not be affected by
this change.

> > [1] https://lkml.kernel.org/netdev/20231213120656.x46fyad6ls7sqyzv@skbuf/T/#u
> >
> > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > ---
> >  net/dsa/dsa.c | 7 +------
> >  1 file changed, 1 insertion(+), 6 deletions(-)
> >
> > diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
> > index ac7be864e80d..cea364c81b70 100644
> > --- a/net/dsa/dsa.c
> > +++ b/net/dsa/dsa.c
> > @@ -15,7 +15,6 @@
> >  #include <linux/slab.h>
> >  #include <linux/rtnetlink.h>
> >  #include <linux/of.h>
> > -#include <linux/of_mdio.h>
> >  #include <linux/of_net.h>
> >  #include <net/dsa_stubs.h>
> >  #include <net/sch_generic.h>
> > @@ -626,7 +625,6 @@ static void dsa_switch_teardown_tag_protocol(struct dsa_switch *ds)
> >
> >  static int dsa_switch_setup(struct dsa_switch *ds)
> >  {
> > -     struct device_node *dn;
> >       int err;
> >
> >       if (ds->setup)
> > @@ -666,10 +664,7 @@ static int dsa_switch_setup(struct dsa_switch *ds)
> >
> >               dsa_user_mii_bus_init(ds);
> >
> > -             dn = of_get_child_by_name(ds->dev->of_node, "mdio");
> > -
> > -             err = of_mdiobus_register(ds->user_mii_bus, dn);
> > -             of_node_put(dn);
> > +             err = mdiobus_register(ds->user_mii_bus, dn);

This patch also has an obvious compile error that I didn't catch
during my builds. I might have built just a subtree and during each
step in a rebase, missing the last one. Sorry. It should be

            err = mdiobus_register(ds->user_mii_bus);

> >               if (err < 0)
> >                       goto free_user_mii_bus;
> >       }
> > --
> > 2.43.0
> >

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

* Re: [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module
  2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
                   ` (6 preceding siblings ...)
  2023-12-20  4:24 ` [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus" Luiz Angelo Daros de Luca
@ 2023-12-21 15:21 ` Vladimir Oltean
  2023-12-22 21:32   ` Luiz Angelo Daros de Luca
  7 siblings, 1 reply; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-21 15:21 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, alsi, andrew, f.fainelli, davem, edumazet,
	kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:23AM -0300, Luiz Angelo Daros de Luca wrote:
> The current driver consists of two interface modules (SMI and MDIO) and two family/variant modules (RTL8365MB and RTL8366RB). The SMI and MDIO modules serve as the platform and MDIO drivers, respectively, calling functions from the variant modules. In this setup, one interface module can be loaded independently of the other, but both variants must be loaded (if not disabled at build time) for any type of interface. This approach doesn't scale well, especially with the addition of more switch variants (e.g., RTL8366B), leading to loaded but unused modules. Additionally, this also seems to be upside down, as the specific driver code normally depends on the more generic functions and not the other way around.
> 
> The series begins by removing an unused function pointer at realtek_ops->cleanup.
> 
> Each variant module was converted into real drivers, serving as both a platform driver (for switches connected using the SMI interface) and an MDIO driver (for MDIO-connected switches). The relationship between the variant and interface modules is reversed, with the variant module now calling both interface functions (if not disabled at build time). While in most devices only one interface is likely used, the interface code is significantly smaller than a variant module, consuming fewer resources than the previous code. With variant modules now functioning as real drivers, compatible strings are published only in a single variant module, preventing conflicts.
> 
> The patch series introduces a new common module for functions shared by both variants. This module also absorbs the two previous interface modules, as they would always be loaded anyway.
> 
> The series relocates the user MII driver from realtek-smi to common. It is now used by MDIO-connected switches instead of the generic DSA driver. There's a change in how this driver locates the MDIO node. It now searches for either a child named "mdio" (compatible with realtek-mdio and binding docs) or a child with the compatible string (compatible with realtek-smi).
> 
> The dsa_switch in realtek_priv->ds is now embedded in the struct. It is always in use and avoids dynamic memory allocation.
> 
> Testing has been performed with an RTL8367S (rtl8365mb) using MDIO interface and an RTL8366RB (rtl8366) with SMI interface.

Could you please do word wrapping at around 80 characters per line,
so that the cover letter doesn't look horrible when used as the message
for the merge commit? Thanks.

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

* Re: [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops
  2023-12-20 13:57   ` Alvin Šipraga
@ 2023-12-21 17:04     ` Vladimir Oltean
  2023-12-21 20:05       ` Alvin Šipraga
  0 siblings, 1 reply; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-21 17:04 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: Luiz Angelo Daros de Luca, netdev, linus.walleij, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:57:41PM +0000, Alvin Šipraga wrote:
> On Wed, Dec 20, 2023 at 01:24:24AM -0300, Luiz Angelo Daros de Luca wrote:
> > It was never used and never referenced.
> > 
> > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
> 
> You should always put your Signed-off-by last when sending patches.

I'm not so sure about that.

When you send a patch, it gets reviewed and then accepted all in the
same version, the Reviewed-by tag will be after your sign off. It makes
more sense to me that if you send a patch with a review tag carried
over, you put it in the same place where it would sit if it was received
on the final patch version. Idk, not too big of a deal.

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

* Re: [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers
  2023-12-20  4:24 ` [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers Luiz Angelo Daros de Luca
@ 2023-12-21 17:08   ` Vladimir Oltean
  0 siblings, 0 replies; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-21 17:08 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: netdev, linus.walleij, alsi, andrew, f.fainelli, davem, edumazet,
	kuba, pabeni, arinc.unal

On Wed, Dec 20, 2023 at 01:24:25AM -0300, Luiz Angelo Daros de Luca wrote:
> +static int rtl8365mb_init(void)
> +{
> +	int ret;
> +
> +	ret = realtek_mdio_driver_register(&rtl8365mb_mdio_driver);
> +	if (ret)
> +		return ret;
> +
> +	ret = platform_driver_register(&rtl8365mb_smi_driver);

I guess this was supposed to be a call to realtek_smi_driver_register().

> +	if (ret) {
> +		realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +module_init(rtl8365mb_init);
> +
> +static void __exit rtl8365mb_exit(void)
> +{
> +	platform_driver_unregister(&rtl8365mb_smi_driver);

And this to realtek_smi_driver_unregister().

> +	realtek_mdio_driver_unregister(&rtl8365mb_mdio_driver);
> +}
> +module_exit(rtl8365mb_exit);

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-20  4:51   ` Luiz Angelo Daros de Luca
@ 2023-12-21 17:47     ` Vladimir Oltean
  2023-12-21 18:34       ` Arınç ÜNAL
  2023-12-22 20:03       ` Luiz Angelo Daros de Luca
  0 siblings, 2 replies; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-21 17:47 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev, arinc.unal

On Wed, Dec 20, 2023 at 01:51:01AM -0300, Luiz Angelo Daros de Luca wrote:
> Hello Vladimir,
> 
> I'm sorry to bother you again but I would like your attention for two
> points that I'm not completely sure about.

Ok. Please trim the quoted text from your replies to just what's relevant.
It's easy to scroll past the new bits.

> > +int realtek_common_setup_user_mdio(struct dsa_switch *ds)
> > +{
> > +       const char *compatible = "realtek,smi-mdio";
> > +       struct realtek_priv *priv =  ds->priv;
> > +       struct device_node *phy_node;
> > +       struct device_node *mdio_np;
> > +       struct dsa_port *dp;
> > +       int ret;
> > +
> > +       mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
> > +       if (!mdio_np) {
> > +               mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
> > +               if (!mdio_np) {
> > +                       dev_err(priv->dev, "no MDIO bus node\n");
> > +                       return -ENODEV;
> > +               }
> > +       }
> 
> I just kept the code compatible with both realtek-smi and realtek-mdio
> (that was using the generic "DSA user mii"), even when it might
> violate the binding docs (for SMI with a node not named "mdio").
> 
> You suggested using two new compatible strings for this driver
> ("realtek,rtl8365mb-mdio" and "realtek,rtl8366rb-mdio"). However, it
> might still not be a good name as it is similar to the MDIO-connected
> subdriver of each variant. Anyway, if possible, I would like to keep
> it out of this series as it would first require a change in the
> bindings before any real code change and it might add some more path
> cycles.

I suppose what you don't want is to make the code inadvertently accept
an MDIO bus named "realtek,smi-mdio" on MDIO-controlled switches.

I think it's safe to write a separate commit which just exercises a part
of the dt-binding that the Linux driver hasn't used thus far: that the
node name must be "mdio". You don't need to fall back to the search by
compatible string if there is nothing broken to support, and it's all
just theoretical (and even then, the theory is not supported by the DT
binding).

> > +       priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> > +       if (!priv->user_mii_bus) {
> > +               ret = -ENOMEM;
> > +               goto err_put_node;
> > +       }
> > +       priv->user_mii_bus->priv = priv;
> > +       priv->user_mii_bus->name = "Realtek user MII";
> > +       priv->user_mii_bus->read = realtek_common_user_mdio_read;
> > +       priv->user_mii_bus->write = realtek_common_user_mdio_write;
> > +       snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
> > +                ds->index);
> > +       priv->user_mii_bus->parent = priv->dev;
> > +
> > +       /* When OF describes the MDIO, connecting ports with phy-handle,
> > +        * ds->user_mii_bus should not be used *
> > +        */
> > +       dsa_switch_for_each_user_port(dp, ds) {
> > +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +               of_node_put(phy_node);
> > +               if (phy_node)
> > +                       continue;
> > +
> > +               dev_warn(priv->dev,
> > +                        "DS user_mii_bus in use as '%s' is missing phy-handle",
> > +                        dp->name);
> > +               ds->user_mii_bus = priv->user_mii_bus;
> > +               break;
> > +       }
> 
> Does this check align with how should ds->user_mii_bus be used (in a
> first step for phasing it out, at least for this driver)?

No. Thanks for asking.

What I would like to see is a commit which removes the line assigning
ds->user_mii_bus completely, with the following justification:

ds->user_mii_bus helps when
(1) the switch probes with platform_data (not on OF), or
(2) the switch probes on OF but its MDIO bus is not described in OF

Case (1) is eliminated because this driver uses of_device_get_match_data()
and fails to probe if that returns NULL (which it will, with platform_data).
So this switch driver only probes on OF.

Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
assignment is only ever executed when the bus has an OF node, aka when
it is not useful.

Having the MDIO bus described in OF, but no phy-handle to its children
is a semantically broken device tree, we should make no effort whatsoever
to support it.

Thus, because the dsa_user_phy_connect() behavior given by the DSA core
through ds->user_mii_bus does not help in any valid circumstance, let's
deactivate that possible code path and simplify the interaction between
the driver and DSA.

And then go on with the driver cleanup as if ds->user_mii_bus didn't exist.

Makes sense? Parsing "phy-handle" is just absurdly complicated.

> > +
> > +       ret = devm_of_mdiobus_register(priv->dev, priv->user_mii_bus, mdio_np);
> > +       if (ret) {
> > +               dev_err(priv->dev, "unable to register MDIO bus %s\n",
> > +                       priv->user_mii_bus->id);
> > +               goto err_put_node;
> > +       }
> > +
> > +       return 0;
> > +
> > +err_put_node:
> > +       of_node_put(mdio_np);
> > +
> > +       return ret;
> > +}
> > +EXPORT_SYMBOL_GPL(realtek_common_setup_user_mdio);

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-21 17:47     ` Vladimir Oltean
@ 2023-12-21 18:34       ` Arınç ÜNAL
  2023-12-22 10:48         ` Vladimir Oltean
  2023-12-22 20:03       ` Luiz Angelo Daros de Luca
  1 sibling, 1 reply; 38+ messages in thread
From: Arınç ÜNAL @ 2023-12-21 18:34 UTC (permalink / raw)
  To: Vladimir Oltean, Luiz Angelo Daros de Luca
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev

On 21.12.2023 20:47, Vladimir Oltean wrote:
> On Wed, Dec 20, 2023 at 01:51:01AM -0300, Luiz Angelo Daros de Luca wrote:
>>> +       priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
>>> +       if (!priv->user_mii_bus) {
>>> +               ret = -ENOMEM;
>>> +               goto err_put_node;
>>> +       }
>>> +       priv->user_mii_bus->priv = priv;
>>> +       priv->user_mii_bus->name = "Realtek user MII";
>>> +       priv->user_mii_bus->read = realtek_common_user_mdio_read;
>>> +       priv->user_mii_bus->write = realtek_common_user_mdio_write;
>>> +       snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
>>> +                ds->index);
>>> +       priv->user_mii_bus->parent = priv->dev;
>>> +
>>> +       /* When OF describes the MDIO, connecting ports with phy-handle,
>>> +        * ds->user_mii_bus should not be used *
>>> +        */
>>> +       dsa_switch_for_each_user_port(dp, ds) {
>>> +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
>>> +               of_node_put(phy_node);
>>> +               if (phy_node)
>>> +                       continue;
>>> +
>>> +               dev_warn(priv->dev,
>>> +                        "DS user_mii_bus in use as '%s' is missing phy-handle",
>>> +                        dp->name);
>>> +               ds->user_mii_bus = priv->user_mii_bus;
>>> +               break;
>>> +       }
>>
>> Does this check align with how should ds->user_mii_bus be used (in a
>> first step for phasing it out, at least for this driver)?
> 
> No. Thanks for asking.
> 
> What I would like to see is a commit which removes the line assigning
> ds->user_mii_bus completely, with the following justification:
> 
> ds->user_mii_bus helps when
> (1) the switch probes with platform_data (not on OF), or
> (2) the switch probes on OF but its MDIO bus is not described in OF
> 
> Case (1) is eliminated because this driver uses of_device_get_match_data()
> and fails to probe if that returns NULL (which it will, with platform_data).
> So this switch driver only probes on OF.
> 
> Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
> if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
> assignment is only ever executed when the bus has an OF node, aka when
> it is not useful.
> 
> Having the MDIO bus described in OF, but no phy-handle to its children
> is a semantically broken device tree, we should make no effort whatsoever
> to support it.
> 
> Thus, because the dsa_user_phy_connect() behavior given by the DSA core
> through ds->user_mii_bus does not help in any valid circumstance, let's
> deactivate that possible code path and simplify the interaction between
> the driver and DSA.
> 
> And then go on with the driver cleanup as if ds->user_mii_bus didn't exist.
> 
> Makes sense? Parsing "phy-handle" is just absurdly complicated.

I don't like the fact that the driver bails out if it doesn't find the
"mdio" child node. This basically forces the hardware design to use the
MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
the switch are perfectly valid.

It looks to me that, to make all types of hardware designs work, we must
not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
cases of the ethernet controller lacking link definitions in OF so we
should enforce link definitions on ethernet controllers. This way, we make
sure all types of hardware designs work and are described in OF properly.

Arınç

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

* Re: [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops
  2023-12-21 17:04     ` Vladimir Oltean
@ 2023-12-21 20:05       ` Alvin Šipraga
  2023-12-22 22:32         ` Luiz Angelo Daros de Luca
  0 siblings, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-21 20:05 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Luiz Angelo Daros de Luca, netdev, linus.walleij, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, arinc.unal

On Thu, Dec 21, 2023 at 07:04:18PM +0200, Vladimir Oltean wrote:
> On Wed, Dec 20, 2023 at 01:57:41PM +0000, Alvin Šipraga wrote:
> > On Wed, Dec 20, 2023 at 01:24:24AM -0300, Luiz Angelo Daros de Luca wrote:
> > > It was never used and never referenced.
> > > 
> > > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > > Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
> > 
> > You should always put your Signed-off-by last when sending patches.
> 
> I'm not so sure about that.
> 
> When you send a patch, it gets reviewed and then accepted all in the
> same version, the Reviewed-by tag will be after your sign off. It makes
> more sense to me that if you send a patch with a review tag carried
> over, you put it in the same place where it would sit if it was received
> on the final patch version. Idk, not too big of a deal.

It's what I see most of the time, and Andrew recently pointed out the
same [1]. Still there does not seem to be a consensus... [2] [3] [4]

But yea, not a big deal!

[1] https://lore.kernel.org/all/8d2dd95b-13f7-41d8-997f-d5c2953dcb06@lunn.ch/
[2] https://lore.kernel.org/all/20200408073603.GA948@gerhold.net/
[3] https://lore.kernel.org/all/20190627083443.4f4918a7@lwn.net/
[4] https://lore.kernel.org/all/87a7zzd47q.fsf@intel.com/

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-21 18:34       ` Arınç ÜNAL
@ 2023-12-22 10:48         ` Vladimir Oltean
  2023-12-22 11:13           ` Alvin Šipraga
  2023-12-22 16:56           ` Arınç ÜNAL
  0 siblings, 2 replies; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-22 10:48 UTC (permalink / raw)
  To: Arınç ÜNAL
  Cc: Luiz Angelo Daros de Luca, linus.walleij, alsi, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

On Thu, Dec 21, 2023 at 09:34:52PM +0300, Arınç ÜNAL wrote:
> On 21.12.2023 20:47, Vladimir Oltean wrote:
> > ds->user_mii_bus helps when
> > (1) the switch probes with platform_data (not on OF), or
> > (2) the switch probes on OF but its MDIO bus is not described in OF
> > 
> > Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
> > if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
> > assignment is only ever executed when the bus has an OF node, aka when
> > it is not useful.
> 
> I don't like the fact that the driver bails out if it doesn't find the
> "mdio" child node. This basically forces the hardware design to use the
> MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
> the switch are perfectly valid.
> 
> It looks to me that, to make all types of hardware designs work, we must
> not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
> cases of the ethernet controller lacking link definitions in OF so we
> should enforce link definitions on ethernet controllers. This way, we make
> sure all types of hardware designs work and are described in OF properly.
> 
> Arınç

The bindings for the realtek switches can be extended in compatible ways,
e.g. by making the 'mdio' node optional. If we want that to mean "there
is no internal PHY that needs to be used", there is no better time than
now to drop the driver's linkage to ds->user_mii_bus, while its bindings
still strictly require an 'mdio' node.

If we don't drop that linkage _before_ making 'mdio' optional, there
is no way to disprove the existence of device trees which lack a link
description on user ports (which is now possible). So the driver will
always have to pay the penalty of mdiobus_register(ds->user_mii_bus),
which will always enumerate the internal PHYs even if they will end up
unused, as you say should be possible. Listing the MDIO bus in OF
deactivates bus scanning, which speeds up probing and booting in most
cases.

There are other ways to reduce that PHY enumeration pain, like manually
setting the bus->phy_mask and moving code around such that it gets
executed only once in the presence of -EPROBE_DEFER. This is what Klaus
Kudielka had to go through with mv88e6xxx, all because the Turris Omnia
device tree lacks phy-handle to the internal PHYs, his boot time shot up
by a wide margin.
https://lore.kernel.org/lkml/449bde236c08d5ab5e54abd73b645d8b29955894.camel@gmail.com/
commit 2c7e46edbd03 ("net: dsa: mv88e6xxx: mask apparently non-existing phys during probing")
commit 2cb0658d4f88 ("net: dsa: mv88e6xxx: move call to mv88e6xxx_mdios_register()")

We support device trees with 'hidden' switch internal MDIO buses and it
would be unwise to break them. But they are a self-inflicted pain and it
would be even more unwise for me to go on record not discouraging their use.
Honestly, I don't want any more of them.

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 10:48         ` Vladimir Oltean
@ 2023-12-22 11:13           ` Alvin Šipraga
  2023-12-22 17:04             ` Arınç ÜNAL
  2023-12-22 16:56           ` Arınç ÜNAL
  1 sibling, 1 reply; 38+ messages in thread
From: Alvin Šipraga @ 2023-12-22 11:13 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Arınç ÜNAL, Luiz Angelo Daros de Luca,
	linus.walleij, andrew, f.fainelli, davem, edumazet, kuba, pabeni,
	netdev

On Fri, Dec 22, 2023 at 12:48:31PM +0200, Vladimir Oltean wrote:
> On Thu, Dec 21, 2023 at 09:34:52PM +0300, Arınç ÜNAL wrote:
> > On 21.12.2023 20:47, Vladimir Oltean wrote:
> > > ds->user_mii_bus helps when
> > > (1) the switch probes with platform_data (not on OF), or
> > > (2) the switch probes on OF but its MDIO bus is not described in OF
> > > 
> > > Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
> > > if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
> > > assignment is only ever executed when the bus has an OF node, aka when
> > > it is not useful.
> > 
> > I don't like the fact that the driver bails out if it doesn't find the
> > "mdio" child node. This basically forces the hardware design to use the
> > MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
> > the switch are perfectly valid.
> > 
> > It looks to me that, to make all types of hardware designs work, we must
> > not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
> > cases of the ethernet controller lacking link definitions in OF so we
> > should enforce link definitions on ethernet controllers. This way, we make
> > sure all types of hardware designs work and are described in OF properly.
> > 
> > Arınç
> 
> The bindings for the realtek switches can be extended in compatible ways,
> e.g. by making the 'mdio' node optional. If we want that to mean "there
> is no internal PHY that needs to be used", there is no better time than
> now to drop the driver's linkage to ds->user_mii_bus, while its bindings
> still strictly require an 'mdio' node.
> 
> If we don't drop that linkage _before_ making 'mdio' optional, there
> is no way to disprove the existence of device trees which lack a link
> description on user ports (which is now possible). 

I strongly agree and I think that the direction you have suggested is
crystal clear, Vladimir. Nothing prohibits us from relaxing the bindings
later on to support whatever hardware Arınç is describing.

But for my own understanding - and maybe this is more a question for
Arınç since he brought it up up - what does this supposed hardware look
like, where the internal MDIO bus is not used? Here are my two (probably
wrong?) guesses:

(1) you use the MDIO bus of the parent Ethernet controller and access
    the internal PHYs directly, hence the internal MDIO bus goes unused;

(2) none of the internal PHYs are actually used, so only the so-called
    extension ports are available.

I don't know if (1) really qualifies. And (2) is also a bit strange,
because this family of switches has variants with up to only three
extension ports, most often two, which doesn't make for much of a
switch.

So while I agree in theory with your remark Arınç, I'm just wondering if
you had something specific in mind.

Kind regards,
Alvin

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 10:48         ` Vladimir Oltean
  2023-12-22 11:13           ` Alvin Šipraga
@ 2023-12-22 16:56           ` Arınç ÜNAL
  2024-01-03 18:44             ` Vladimir Oltean
  1 sibling, 1 reply; 38+ messages in thread
From: Arınç ÜNAL @ 2023-12-22 16:56 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Luiz Angelo Daros de Luca, linus.walleij, alsi, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

On 22.12.2023 13:48, Vladimir Oltean wrote:
> On Thu, Dec 21, 2023 at 09:34:52PM +0300, Arınç ÜNAL wrote:
>> On 21.12.2023 20:47, Vladimir Oltean wrote:
>>> ds->user_mii_bus helps when
>>> (1) the switch probes with platform_data (not on OF), or
>>> (2) the switch probes on OF but its MDIO bus is not described in OF
>>>
>>> Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
>>> if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
>>> assignment is only ever executed when the bus has an OF node, aka when
>>> it is not useful.
>>
>> I don't like the fact that the driver bails out if it doesn't find the
>> "mdio" child node. This basically forces the hardware design to use the
>> MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
>> the switch are perfectly valid.
>>
>> It looks to me that, to make all types of hardware designs work, we must
>> not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
>> cases of the ethernet controller lacking link definitions in OF so we
>> should enforce link definitions on ethernet controllers. This way, we make
>> sure all types of hardware designs work and are described in OF properly.
>>
>> Arınç
> 
> The bindings for the realtek switches can be extended in compatible ways,
> e.g. by making the 'mdio' node optional. If we want that to mean "there
> is no internal PHY that needs to be used", there is no better time than
> now to drop the driver's linkage to ds->user_mii_bus, while its bindings
> still strictly require an 'mdio' node.

"There is no internal PHY that needs to be used" is not the right statement
for all cases. The internal PHYs can be wired to another MDIO bus or they
may be described as fixed-link which would mean using the MDIO bus to read
link information from the PHYs becomes unnecessary. These may be very rare
hardware designs to come across but they are valid hardware descriptions in
OF. So "the MDIO bus of the switch is not being used for the purpose of
reading/writing from/to the PHYs (and not necessarily internal PHYs)" is
the correct statement.

> 
> If we don't drop that linkage _before_ making 'mdio' optional, there
> is no way to disprove the existence of device trees which lack a link
> description on user ports (which is now possible). So the driver will
> always have to pay the penalty of mdiobus_register(ds->user_mii_bus),
> which will always enumerate the internal PHYs even if they will end up
> unused, as you say should be possible. Listing the MDIO bus in OF
> deactivates bus scanning, which speeds up probing and booting in most
> cases.
> 
> There are other ways to reduce that PHY enumeration pain, like manually
> setting the bus->phy_mask and moving code around such that it gets
> executed only once in the presence of -EPROBE_DEFER. This is what Klaus
> Kudielka had to go through with mv88e6xxx, all because the Turris Omnia
> device tree lacks phy-handle to the internal PHYs, his boot time shot up
> by a wide margin.
> https://lore.kernel.org/lkml/449bde236c08d5ab5e54abd73b645d8b29955894.camel@gmail.com/
> commit 2c7e46edbd03 ("net: dsa: mv88e6xxx: mask apparently non-existing phys during probing")
> commit 2cb0658d4f88 ("net: dsa: mv88e6xxx: move call to mv88e6xxx_mdios_register()")
> 
> We support device trees with 'hidden' switch internal MDIO buses and it
> would be unwise to break them. But they are a self-inflicted pain and it
> would be even more unwise for me to go on record not discouraging their use.
> Honestly, I don't want any more of them.

Looks like with the direction you're suggesting here, we can enforce link
descriptions and, at the same time, support device trees with undescribed
switch MDIO bus on DSA. So I see all this as a step in the right direction.

So yeah, let's keep ds->user_mii_bus for switch probes on OF without the
switch MDIO bus defined, provided these switches have an MDIO bus.

We should also align all DSA subdrivers with this understanding. I will
modify the MDIO bus patch I submitted for the MT7530 DSA subdriver
accordingly.

I was wondering of moving the MDIO bus registration from DSA subdrivers to
the DSA core driver but probably it's not generic enough across switch
models with multiple MDIO buses and whatnot to manage this.

Arınç

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 11:13           ` Alvin Šipraga
@ 2023-12-22 17:04             ` Arınç ÜNAL
  2023-12-22 20:28               ` Luiz Angelo Daros de Luca
  0 siblings, 1 reply; 38+ messages in thread
From: Arınç ÜNAL @ 2023-12-22 17:04 UTC (permalink / raw)
  To: Alvin Šipraga, Vladimir Oltean
  Cc: Luiz Angelo Daros de Luca, linus.walleij, andrew, f.fainelli,
	davem, edumazet, kuba, pabeni, netdev

On 22.12.2023 14:13, Alvin Šipraga wrote:
> On Fri, Dec 22, 2023 at 12:48:31PM +0200, Vladimir Oltean wrote:
>> On Thu, Dec 21, 2023 at 09:34:52PM +0300, Arınç ÜNAL wrote:
>>> On 21.12.2023 20:47, Vladimir Oltean wrote:
>>>> ds->user_mii_bus helps when
>>>> (1) the switch probes with platform_data (not on OF), or
>>>> (2) the switch probes on OF but its MDIO bus is not described in OF
>>>>
>>>> Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
>>>> if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
>>>> assignment is only ever executed when the bus has an OF node, aka when
>>>> it is not useful.
>>>
>>> I don't like the fact that the driver bails out if it doesn't find the
>>> "mdio" child node. This basically forces the hardware design to use the
>>> MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
>>> the switch are perfectly valid.
>>>
>>> It looks to me that, to make all types of hardware designs work, we must
>>> not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
>>> cases of the ethernet controller lacking link definitions in OF so we
>>> should enforce link definitions on ethernet controllers. This way, we make
>>> sure all types of hardware designs work and are described in OF properly.
>>>
>>> Arınç
>>
>> The bindings for the realtek switches can be extended in compatible ways,
>> e.g. by making the 'mdio' node optional. If we want that to mean "there
>> is no internal PHY that needs to be used", there is no better time than
>> now to drop the driver's linkage to ds->user_mii_bus, while its bindings
>> still strictly require an 'mdio' node.
>>
>> If we don't drop that linkage _before_ making 'mdio' optional, there
>> is no way to disprove the existence of device trees which lack a link
>> description on user ports (which is now possible).
> 
> I strongly agree and I think that the direction you have suggested is
> crystal clear, Vladimir. Nothing prohibits us from relaxing the bindings
> later on to support whatever hardware Arınç is describing.
> 
> But for my own understanding - and maybe this is more a question for
> Arınç since he brought it up up - what does this supposed hardware look
> like, where the internal MDIO bus is not used? Here are my two (probably
> wrong?) guesses:
> 
> (1) you use the MDIO bus of the parent Ethernet controller and access
>      the internal PHYs directly, hence the internal MDIO bus goes unused;
> 
> (2) none of the internal PHYs are actually used, so only the so-called
>      extension ports are available.
> 
> I don't know if (1) really qualifies. And (2) is also a bit strange,
> because this family of switches has variants with up to only three
> extension ports, most often two, which doesn't make for much of a
> switch.
> 
> So while I agree in theory with your remark Arınç, I'm just wondering if
> you had something specific in mind.

I was speaking in the sense of all switches with CPU ports, which is
controlled by the DSA subsystem on Linux.

I am only stating the fact that if we don't take the literal approach with
hardware descriptions on the driver implementation, there will always be
cases where the drivers will fail to support certain hardware designs.

Arınç

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-21 17:47     ` Vladimir Oltean
  2023-12-21 18:34       ` Arınç ÜNAL
@ 2023-12-22 20:03       ` Luiz Angelo Daros de Luca
  2023-12-22 22:09         ` Vladimir Oltean
  1 sibling, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-22 20:03 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev, arinc.unal

> Ok. Please trim the quoted text from your replies to just what's relevant.
> It's easy to scroll past the new bits.

OK

>
> > > +int realtek_common_setup_user_mdio(struct dsa_switch *ds)
> > > +{
> > > +       const char *compatible = "realtek,smi-mdio";
> > > +       struct realtek_priv *priv =  ds->priv;
> > > +       struct device_node *phy_node;
> > > +       struct device_node *mdio_np;
> > > +       struct dsa_port *dp;
> > > +       int ret;
> > > +
> > > +       mdio_np = of_get_child_by_name(priv->dev->of_node, "mdio");
> > > +       if (!mdio_np) {
> > > +               mdio_np = of_get_compatible_child(priv->dev->of_node, compatible);
> > > +               if (!mdio_np) {
> > > +                       dev_err(priv->dev, "no MDIO bus node\n");
> > > +                       return -ENODEV;
> > > +               }
> > > +       }
> >
> > I just kept the code compatible with both realtek-smi and realtek-mdio
> > (that was using the generic "DSA user mii"), even when it might
> > violate the binding docs (for SMI with a node not named "mdio").
> >
> > You suggested using two new compatible strings for this driver
> > ("realtek,rtl8365mb-mdio" and "realtek,rtl8366rb-mdio"). However, it
> > might still not be a good name as it is similar to the MDIO-connected
> > subdriver of each variant. Anyway, if possible, I would like to keep
> > it out of this series as it would first require a change in the
> > bindings before any real code change and it might add some more path
> > cycles.
>
> I suppose what you don't want is to make the code inadvertently accept
> an MDIO bus named "realtek,smi-mdio" on MDIO-controlled switches.

I don't think it would hurt that much. I was just trying to keep the
old code behavior.

> I think it's safe to write a separate commit which just exercises a part
> of the dt-binding that the Linux driver hasn't used thus far: that the
> node name must be "mdio". You don't need to fall back to the search by
> compatible string if there is nothing broken to support, and it's all
> just theoretical (and even then, the theory is not supported by the DT
> binding).

OK. I'll drop the compatible part.

> > > +       priv->user_mii_bus = devm_mdiobus_alloc(priv->dev);
> > > +       if (!priv->user_mii_bus) {
> > > +               ret = -ENOMEM;
> > > +               goto err_put_node;
> > > +       }
> > > +       priv->user_mii_bus->priv = priv;
> > > +       priv->user_mii_bus->name = "Realtek user MII";
> > > +       priv->user_mii_bus->read = realtek_common_user_mdio_read;
> > > +       priv->user_mii_bus->write = realtek_common_user_mdio_write;
> > > +       snprintf(priv->user_mii_bus->id, MII_BUS_ID_SIZE, "Realtek-%d",
> > > +                ds->index);
> > > +       priv->user_mii_bus->parent = priv->dev;
> > > +
> > > +       /* When OF describes the MDIO, connecting ports with phy-handle,
> > > +        * ds->user_mii_bus should not be used *
> > > +        */
> > > +       dsa_switch_for_each_user_port(dp, ds) {
> > > +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> > > +               of_node_put(phy_node);
> > > +               if (phy_node)
> > > +                       continue;
> > > +
> > > +               dev_warn(priv->dev,
> > > +                        "DS user_mii_bus in use as '%s' is missing phy-handle",
> > > +                        dp->name);
> > > +               ds->user_mii_bus = priv->user_mii_bus;
> > > +               break;
> > > +       }
> >
> > Does this check align with how should ds->user_mii_bus be used (in a
> > first step for phasing it out, at least for this driver)?
>
> No. Thanks for asking.
>
> What I would like to see is a commit which removes the line assigning
> ds->user_mii_bus completely, with the following justification:
>
> ds->user_mii_bus helps when
> (1) the switch probes with platform_data (not on OF), or
> (2) the switch probes on OF but its MDIO bus is not described in OF
>
> Case (1) is eliminated because this driver uses of_device_get_match_data()
> and fails to probe if that returns NULL (which it will, with platform_data).
> So this switch driver only probes on OF.
>
> Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
> if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
> assignment is only ever executed when the bus has an OF node, aka when
> it is not useful.
>
> Having the MDIO bus described in OF, but no phy-handle to its children
> is a semantically broken device tree, we should make no effort whatsoever
> to support it.

OK. I was trying to keep exactly that setup working. Should I keep the
check and bail out with an error like:

+       dsa_switch_for_each_user_port(dp, ds) {
+               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
+               of_node_put(phy_node);
+               if (phy_node)
+                       continue;
+               dev_err(priv->dev,
+                       "'%s' is missing phy-handle",
+                       dp->name);
+               return -EINVAL;
+       }

or should I simply let it break silently? The device-tree writers
might like some feedback if they are doing it wrong. I guess neither
DSA nor MDIO bus will say a thing about the missing phy-handle.

Regards,

Luiz

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 17:04             ` Arınç ÜNAL
@ 2023-12-22 20:28               ` Luiz Angelo Daros de Luca
  2023-12-22 20:59                 ` Arınç ÜNAL
  0 siblings, 1 reply; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-22 20:28 UTC (permalink / raw)
  To: Arınç ÜNAL
  Cc: Alvin Šipraga, Vladimir Oltean, linus.walleij, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

> >>>> ds->user_mii_bus helps when
> >>>> (1) the switch probes with platform_data (not on OF), or
> >>>> (2) the switch probes on OF but its MDIO bus is not described in OF
> >>>>
> >>>> Case (2) is also eliminated because realtek_smi_setup_mdio() bails out
> >>>> if it cannot find the "mdio" node described in OF. So the ds->user_mii_bus
> >>>> assignment is only ever executed when the bus has an OF node, aka when
> >>>> it is not useful.
> >>>
> >>> I don't like the fact that the driver bails out if it doesn't find the
> >>> "mdio" child node. This basically forces the hardware design to use the
> >>> MDIO bus of the switch. Hardware designs which don't use the MDIO bus of
> >>> the switch are perfectly valid.
> >>>
> >>> It looks to me that, to make all types of hardware designs work, we must
> >>> not use ds->user_mii_bus for switch probes on OF. Case (2) is one of the
> >>> cases of the ethernet controller lacking link definitions in OF so we
> >>> should enforce link definitions on ethernet controllers. This way, we make
> >>> sure all types of hardware designs work and are described in OF properly.
> >>>
> >>> Arınç
> >>
> >> The bindings for the realtek switches can be extended in compatible ways,
> >> e.g. by making the 'mdio' node optional. If we want that to mean "there
> >> is no internal PHY that needs to be used", there is no better time than
> >> now to drop the driver's linkage to ds->user_mii_bus, while its bindings
> >> still strictly require an 'mdio' node.
> >>
> >> If we don't drop that linkage _before_ making 'mdio' optional, there
> >> is no way to disprove the existence of device trees which lack a link
> >> description on user ports (which is now possible).
> >
> > I strongly agree and I think that the direction you have suggested is
> > crystal clear, Vladimir. Nothing prohibits us from relaxing the bindings
> > later on to support whatever hardware Arınç is describing.
> >
> > But for my own understanding - and maybe this is more a question for
> > Arınç since he brought it up up - what does this supposed hardware look
> > like, where the internal MDIO bus is not used? Here are my two (probably
> > wrong?) guesses:
> >
> > (1) you use the MDIO bus of the parent Ethernet controller and access
> >      the internal PHYs directly, hence the internal MDIO bus goes unused;
> >
> > (2) none of the internal PHYs are actually used, so only the so-called
> >      extension ports are available.
> >
> > I don't know if (1) really qualifies. And (2) is also a bit strange,
> > because this family of switches has variants with up to only three
> > extension ports, most often two, which doesn't make for much of a
> > switch.
> >
> > So while I agree in theory with your remark Arınç, I'm just wondering if
> > you had something specific in mind.
>
> I was speaking in the sense of all switches with CPU ports, which is
> controlled by the DSA subsystem on Linux.
>
> I am only stating the fact that if we don't take the literal approach with
> hardware descriptions on the driver implementation, there will always be
> cases where the drivers will fail to support certain hardware designs.

Hi Arinç,

The old code was already requiring a single switch child node
describing the internal MDIO bus akin to binding docs. I believe what
we use to match it, being the name or the compatible string property,
wouldn't improve the diversity of HW we could support. This series
doesn't want to solve all issues and limitations nor prepare the
ground for different HWs. It's mostly a reorganization without nice
new stuff.

After this series, we could easily turn the mdio node optional,
skipping the MDIO bus when not found. Anyway, if such HW appears just
now, I believe we could simply workaround it by declaring an empty
mdio node.

Regards,

Luiz

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 20:28               ` Luiz Angelo Daros de Luca
@ 2023-12-22 20:59                 ` Arınç ÜNAL
  0 siblings, 0 replies; 38+ messages in thread
From: Arınç ÜNAL @ 2023-12-22 20:59 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: Alvin Šipraga, Vladimir Oltean, linus.walleij, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

Hey Luiz.

On 22.12.2023 23:28, Luiz Angelo Daros de Luca wrote:
>> I was speaking in the sense of all switches with CPU ports, which is
>> controlled by the DSA subsystem on Linux.
>>
>> I am only stating the fact that if we don't take the literal approach with
>> hardware descriptions on the driver implementation, there will always be
>> cases where the drivers will fail to support certain hardware designs.
> 
> Hi Arinç,
> 
> The old code was already requiring a single switch child node
> describing the internal MDIO bus akin to binding docs. I believe what
> we use to match it, being the name or the compatible string property,
> wouldn't improve the diversity of HW we could support. This series
> doesn't want to solve all issues and limitations nor prepare the
> ground for different HWs. It's mostly a reorganization without nice
> new stuff.
> 
> After this series, we could easily turn the mdio node optional,
> skipping the MDIO bus when not found. Anyway, if such HW appears just
> now, I believe we could simply workaround it by declaring an empty
> mdio node.

I agree that there's no need to add new things to this patch series. Just
address Vladimir's suggestions on the next version. You got into this
rabbit hole because you were just trying to add reset controller support on
the rtl8365mb driver, no? Geez!

Arınç

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

* Re: [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module
  2023-12-21 15:21 ` [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Vladimir Oltean
@ 2023-12-22 21:32   ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-22 21:32 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: netdev, linus.walleij, alsi, andrew, f.fainelli, davem, edumazet,
	kuba, pabeni, arinc.unal

> Could you please do word wrapping at around 80 characters per line,
> so that the cover letter doesn't look horrible when used as the message
> for the merge commit? Thanks.

Sure. vim normally deals with that automatically. However, recently it
is avoiding breaking the lines while pasting. I just missed fixing
that this time. I'll check if I can force vim to obey the limit even
during pasting.

Regards,

Luiz

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 20:03       ` Luiz Angelo Daros de Luca
@ 2023-12-22 22:09         ` Vladimir Oltean
  2023-12-22 22:12           ` Luiz Angelo Daros de Luca
  0 siblings, 1 reply; 38+ messages in thread
From: Vladimir Oltean @ 2023-12-22 22:09 UTC (permalink / raw)
  To: Luiz Angelo Daros de Luca
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev, arinc.unal

On Fri, Dec 22, 2023 at 05:03:38PM -0300, Luiz Angelo Daros de Luca wrote:
> > Having the MDIO bus described in OF, but no phy-handle to its children
> > is a semantically broken device tree, we should make no effort whatsoever
> > to support it.
> 
> OK. I was trying to keep exactly that setup working.

Which setup exactly?

> Should I keep the check and bail out with an error like:
> 
> +       dsa_switch_for_each_user_port(dp, ds) {
> +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> +               of_node_put(phy_node);
> +               if (phy_node)
> +                       continue;
> +               dev_err(priv->dev,
> +                       "'%s' is missing phy-handle",
> +                       dp->name);
> +               return -EINVAL;
> +       }
> 
> or should I simply let it break silently? The device-tree writers
> might like some feedback if they are doing it wrong. I guess neither
> DSA nor MDIO bus will say a thing about the missing phy-handle.

FWIW, it will not break silently, but like this (very easy to test, no need to guess):

[    7.196687] mscc_felix 0000:00:00.5 swp3 (uninitialized): failed to connect to PHY: -ENODEV
[    7.205168] mscc_felix 0000:00:00.5 swp3 (uninitialized): error -19 setting up PHY for tree 0, switch 0, port 3

If you have no other decision to make in the driver based on the
presence/absence of "phy-handle", it doesn't make much sense to bloat
the driver with dubious logic just to get an arguably prettier error.
I'm saying "dubious" because my understanding is that rtl8365mb "extint"
ports can also serve as user ports, and can additionally be fixed-links.
But arbitrary logic like this breaks that.

The cost/benefit ratio does not seem too favorable for this addition.

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 22:09         ` Vladimir Oltean
@ 2023-12-22 22:12           ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-22 22:12 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: linus.walleij, alsi, andrew, f.fainelli, davem, edumazet, kuba,
	pabeni, netdev, arinc.unal

> On Fri, Dec 22, 2023 at 05:03:38PM -0300, Luiz Angelo Daros de Luca wrote:
> > > Having the MDIO bus described in OF, but no phy-handle to its children
> > > is a semantically broken device tree, we should make no effort whatsoever
> > > to support it.
> >
> > OK. I was trying to keep exactly that setup working.
>
> Which setup exactly?

Ports without a phy-handle. But, as you said, it is a broken device
tree without a known device using it.

> > Should I keep the check and bail out with an error like:
> >
> > +       dsa_switch_for_each_user_port(dp, ds) {
> > +               phy_node = of_parse_phandle(dp->dn, "phy-handle", 0);
> > +               of_node_put(phy_node);
> > +               if (phy_node)
> > +                       continue;
> > +               dev_err(priv->dev,
> > +                       "'%s' is missing phy-handle",
> > +                       dp->name);
> > +               return -EINVAL;
> > +       }
> >
> > or should I simply let it break silently? The device-tree writers
> > might like some feedback if they are doing it wrong. I guess neither
> > DSA nor MDIO bus will say a thing about the missing phy-handle.
>
> FWIW, it will not break silently, but like this (very easy to test, no need to guess):
>
> [    7.196687] mscc_felix 0000:00:00.5 swp3 (uninitialized): failed to connect to PHY: -ENODEV
> [    7.205168] mscc_felix 0000:00:00.5 swp3 (uninitialized): error -19 setting up PHY for tree 0, switch 0, port 3
>
> If you have no other decision to make in the driver based on the
> presence/absence of "phy-handle", it doesn't make much sense to bloat
> the driver with dubious logic just to get an arguably prettier error.
> I'm saying "dubious" because my understanding is that rtl8365mb "extint"
> ports can also serve as user ports, and can additionally be fixed-links.
> But arbitrary logic like this breaks that.
>
> The cost/benefit ratio does not seem too favorable for this addition.

OK, I'll remove them. Thanks.

Regards,

Luiz

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

* Re: [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops
  2023-12-21 20:05       ` Alvin Šipraga
@ 2023-12-22 22:32         ` Luiz Angelo Daros de Luca
  0 siblings, 0 replies; 38+ messages in thread
From: Luiz Angelo Daros de Luca @ 2023-12-22 22:32 UTC (permalink / raw)
  To: Alvin Šipraga
  Cc: Vladimir Oltean, netdev, linus.walleij, andrew, f.fainelli,
	davem, edumazet, kuba, pabeni, arinc.unal

> On Thu, Dec 21, 2023 at 07:04:18PM +0200, Vladimir Oltean wrote:
> > On Wed, Dec 20, 2023 at 01:57:41PM +0000, Alvin Šipraga wrote:
> > > On Wed, Dec 20, 2023 at 01:24:24AM -0300, Luiz Angelo Daros de Luca wrote:
> > > > It was never used and never referenced.
> > > >
> > > > Signed-off-by: Luiz Angelo Daros de Luca <luizluca@gmail.com>
> > > > Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
> > >
> > > You should always put your Signed-off-by last when sending patches.
> >
> > I'm not so sure about that.
> >
> > When you send a patch, it gets reviewed and then accepted all in the
> > same version, the Reviewed-by tag will be after your sign off. It makes
> > more sense to me that if you send a patch with a review tag carried
> > over, you put it in the same place where it would sit if it was received
> > on the final patch version. Idk, not too big of a deal.
>
> It's what I see most of the time, and Andrew recently pointed out the
> same [1]. Still there does not seem to be a consensus... [2] [3] [4]
>
> But yea, not a big deal!
>
> [1] https://lore.kernel.org/all/8d2dd95b-13f7-41d8-997f-d5c2953dcb06@lunn.ch/
> [2] https://lore.kernel.org/all/20200408073603.GA948@gerhold.net/
> [3] https://lore.kernel.org/all/20190627083443.4f4918a7@lwn.net/
> [4] https://lore.kernel.org/all/87a7zzd47q.fsf@intel.com/

I'll keep the original sequence. Normally, the last Signed-off-by is
the one that merged it, not the author.

Regards,

Luiz

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2023-12-22 16:56           ` Arınç ÜNAL
@ 2024-01-03 18:44             ` Vladimir Oltean
  2024-01-05 18:43               ` Arınç ÜNAL
  0 siblings, 1 reply; 38+ messages in thread
From: Vladimir Oltean @ 2024-01-03 18:44 UTC (permalink / raw)
  To: Arınç ÜNAL
  Cc: Luiz Angelo Daros de Luca, linus.walleij, alsi, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

On Fri, Dec 22, 2023 at 07:56:48PM +0300, Arınç ÜNAL wrote:
> We should also align all DSA subdrivers with this understanding. I will
> modify the MDIO bus patch I submitted for the MT7530 DSA subdriver
> accordingly.

I began working on this, and I do have some patches. But returns start
to diminish very quickly. Some drivers are just not worth it to change.
So I will also respin the documentation patch set to at least advise to
not continue the pattern to new drivers.

> I was wondering of moving the MDIO bus registration from DSA subdrivers to
> the DSA core driver but probably it's not generic enough across switch
> models with multiple MDIO buses and whatnot to manage this.

Actually this is the logic after which everything starts to unravel -
"multiple DSA switches have internal MDIO buses, so let's make DSA
assist with their registration".

If you can't do a good job at it, it's more honest to not even try -
and you gave the perfect example of handling multiple internal MDIO buses.

I just don't want to maintain stuff that I am really clueless about.
If registering an MDIO bus is so hard that DSA has to help with it,
make the MDIO API better.

Where things would be comfortable for me is if the optional ds->user_mii_bus
pointer could be always provided by individual subdrivers, and never allocated
by the framework. So that dsa_switch_ops :: phy_read() and :: phy_write()
would not exist at all.

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

* Re: [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa
  2024-01-03 18:44             ` Vladimir Oltean
@ 2024-01-05 18:43               ` Arınç ÜNAL
  0 siblings, 0 replies; 38+ messages in thread
From: Arınç ÜNAL @ 2024-01-05 18:43 UTC (permalink / raw)
  To: Vladimir Oltean
  Cc: Luiz Angelo Daros de Luca, linus.walleij, alsi, andrew,
	f.fainelli, davem, edumazet, kuba, pabeni, netdev

On 3.01.2024 21:44, Vladimir Oltean wrote:
> On Fri, Dec 22, 2023 at 07:56:48PM +0300, Arınç ÜNAL wrote:
>> We should also align all DSA subdrivers with this understanding. I will
>> modify the MDIO bus patch I submitted for the MT7530 DSA subdriver
>> accordingly.
> 
> I began working on this, and I do have some patches. But returns start
> to diminish very quickly. Some drivers are just not worth it to change.
> So I will also respin the documentation patch set to at least advise to
> not continue the pattern to new drivers.

I've seen your patch series regarding this. I like that you've thought to
skip registering the bus if its node is explicitly disabled. I will
implement that on the MT7530 subdriver as well.

> 
>> I was wondering of moving the MDIO bus registration from DSA subdrivers to
>> the DSA core driver but probably it's not generic enough across switch
>> models with multiple MDIO buses and whatnot to manage this.
> 
> Actually this is the logic after which everything starts to unravel -
> "multiple DSA switches have internal MDIO buses, so let's make DSA
> assist with their registration".
> 
> If you can't do a good job at it, it's more honest to not even try -
> and you gave the perfect example of handling multiple internal MDIO buses.

Makes sense. Setting the interrupts is another good example. Currently, DSA
registers the bus non-OF-based but won't set the interrupts, as far as I
can see.

> 
> I just don't want to maintain stuff that I am really clueless about.
> If registering an MDIO bus is so hard that DSA has to help with it,
> make the MDIO API better.
> 
> Where things would be comfortable for me is if the optional ds->user_mii_bus
> pointer could be always provided by individual subdrivers, and never allocated
> by the framework. So that dsa_switch_ops :: phy_read() and :: phy_write()
> would not exist at all.

I agree. Why don't we do this? These are the subdrivers that we need to
deal with before getting rid of dsa_switch_ops :: phy_read() and ::
phy_write(), and the code block for registering the MDIO bus on the DSA
core driver:

drivers/net/dsa/b53/b53_common.c:
- The DSA subdriver lets the DSA driver register the bus.

drivers/net/dsa/microchip/ksz_common.c:
- The DSA subdriver lets the DSA driver register the bus when "mdio" child
   node is not defined.

drivers/net/dsa/realtek/realtek-mdio.c:
- The DSA subdriver lets the DSA driver register the bus.

This won't be the case after "[PATCH net-next v3 0/8] net: dsa: realtek:
variants to drivers, interfaces to a common module" is applied.

drivers/net/dsa/lan9303-core.c:
- The DSA subdriver lets the DSA driver register the bus.

drivers/net/dsa/vitesse-vsc73xx-core.c:
- The DSA subdriver lets the DSA driver register the bus.

All these subdrivers populate dsa_switch_ops :: phy_read() and ::
phy_write() and won't populate ds->user_mii_bus.

Arınç

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

end of thread, other threads:[~2024-01-05 18:43 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-20  4:24 [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 1/7] net: dsa: realtek: drop cleanup from realtek_ops Luiz Angelo Daros de Luca
2023-12-20 13:57   ` Alvin Šipraga
2023-12-21 17:04     ` Vladimir Oltean
2023-12-21 20:05       ` Alvin Šipraga
2023-12-22 22:32         ` Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 2/7] net: dsa: realtek: convert variants into real drivers Luiz Angelo Daros de Luca
2023-12-21 17:08   ` Vladimir Oltean
2023-12-20  4:24 ` [PATCH net-next v2 3/7] net: dsa: realtek: common realtek-dsa module Luiz Angelo Daros de Luca
2023-12-20 10:40   ` Alvin Šipraga
2023-12-20 15:50     ` Alvin Šipraga
2023-12-21  3:25       ` Luiz Angelo Daros de Luca
2023-12-21  3:11     ` Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 4/7] net: dsa: realtek: merge common and interface modules into realtek-dsa Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 5/7] net: dsa: realtek: Migrate user_mii_bus setup to realtek-dsa Luiz Angelo Daros de Luca
2023-12-20  4:51   ` Luiz Angelo Daros de Luca
2023-12-21 17:47     ` Vladimir Oltean
2023-12-21 18:34       ` Arınç ÜNAL
2023-12-22 10:48         ` Vladimir Oltean
2023-12-22 11:13           ` Alvin Šipraga
2023-12-22 17:04             ` Arınç ÜNAL
2023-12-22 20:28               ` Luiz Angelo Daros de Luca
2023-12-22 20:59                 ` Arınç ÜNAL
2023-12-22 16:56           ` Arınç ÜNAL
2024-01-03 18:44             ` Vladimir Oltean
2024-01-05 18:43               ` Arınç ÜNAL
2023-12-22 20:03       ` Luiz Angelo Daros de Luca
2023-12-22 22:09         ` Vladimir Oltean
2023-12-22 22:12           ` Luiz Angelo Daros de Luca
2023-12-20 13:17   ` Alvin Šipraga
2023-12-21  3:03     ` Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 6/7] net: dsa: realtek: embed dsa_switch into realtek_priv Luiz Angelo Daros de Luca
2023-12-20  4:24 ` [PATCH net-next v2 7/7] Revert "net: dsa: OF-ware slave_mii_bus" Luiz Angelo Daros de Luca
2023-12-20 13:19   ` Alvin Šipraga
2023-12-21  3:45     ` Luiz Angelo Daros de Luca
2023-12-21  0:41   ` kernel test robot
2023-12-21 15:21 ` [PATCH net-next v2 0/7] net: dsa: realtek: variants to drivers, interfaces to a common module Vladimir Oltean
2023-12-22 21:32   ` Luiz Angelo Daros de Luca

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.