* [PATCH net-next v6 0/6] RTL9300 MDIO driver
@ 2025-02-04 3:02 Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
` (5 more replies)
0 siblings, 6 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
This series adds a driver for the MDIO controller on the RTL9300 family
of devices. The controller is a little unique in that we can't access the SMI
interfaces directly. This means we need to use the hardware description from
the DTS to compute a mapping of switch port to mdio bus/address.
Note that the dt-bindings: mfd patch is dependent on the dt-bindings: net patch.
It looks as if we're off Google's naughty list. It's kind of hard to tell.
This iteration makes use of the ethernet-ports property to figure out the
mapping from port to PHY which removes the need for any extar vendor specific
properties.
I've sent this as net-next. The first 4 patches could probably come in via
net-next if the mfd maintainers are happy with that. Not sure about the mips
ones. I've included them because the updated bindings will start complaining
about missing properties on the one in-tree dts file.
Chris Packham (6):
dt-bindings: mfd: Add switch to RTL9300
dt-bindings: net: Add Realtek MDIO controller
dt-bindings: mfd: Add MDIO interface to rtl9301-switch
net: mdio: Add RTL9300 MDIO driver
mips: dts: realtek: Add MDIO controller
mips: dts: cameo-rtl9302c: Add switch block
.../bindings/mfd/realtek,rtl9301-switch.yaml | 47 +-
.../bindings/net/realtek,rtl9301-mdio.yaml | 86 ++++
.../cameo-rtl9302c-2x-rtl8224-2xge.dts | 96 ++++
arch/mips/boot/dts/realtek/rtl930x.dtsi | 33 ++
drivers/net/mdio/Kconfig | 7 +
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/mdio-realtek-rtl9300.c | 472 ++++++++++++++++++
7 files changed, 741 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
create mode 100644 drivers/net/mdio/mdio-realtek-rtl9300.c
--
2.48.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
2025-02-04 8:09 ` Krzysztof Kozlowski
2025-02-04 16:02 ` Rob Herring
2025-02-04 3:02 ` [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller Chris Packham
` (4 subsequent siblings)
5 siblings, 2 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
Add bindings for the ethernet-switch portion of the RTL9300.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v6:
- New
- I'd like to enforce the property being "ethernet-ports" but I see the
generic binding allows "ports" as well. Can I just add ethernet-ports:
type: object here or does by driver need to handle both "ports" and
"ethernet-ports" (I see some do and some don't).
.../bindings/mfd/realtek,rtl9301-switch.yaml | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
index f053303ab1e6..cb54abda5e6a 100644
--- a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
+++ b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
@@ -14,6 +14,8 @@ description:
number of different peripherals are accessed through a common register block,
represented here as a syscon node.
+$ref: /schemas/net/ethernet-switch.yaml#
+
properties:
compatible:
items:
@@ -45,7 +47,7 @@ required:
- compatible
- reg
-additionalProperties: false
+unevaluatedProperties: false
examples:
- |
@@ -110,5 +112,17 @@ examples:
};
};
};
+
+ ethernet-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ };
+ port@1 {
+ reg = <1>;
+ };
+ };
};
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
2025-02-04 16:03 ` Rob Herring (Arm)
2025-02-04 3:02 ` [PATCH net-next v6 3/6] dt-bindings: mfd: Add MDIO interface to rtl9301-switch Chris Packham
` (3 subsequent siblings)
5 siblings, 1 reply; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
Add dtschema for the MDIO controller found in the RTL9300 SoCs. The
controller is slightly unusual in that direct MDIO communication is not
possible. We model the MDIO controller with the MDIO buses as child
nodes and the PHYs as children of the buses. The mapping of switch port
number to MDIO bus/addr requires the ethernet-ports sibling to provide
the mapping via the phy-handle property.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v6:
- Remove realtek,port property. The driver will parse the ethernet-ports
sibling node to figure out the mapping (do I need to mention that
somewhere in this binding?).
- Correct number of mdio buses. 4 possible buses numbered 0-3.
Changes in v5:
- Add back reg property to mdio-controller node
- Make unit address in the node name required
- Andrew suggested perhaps doing away with the realtek,port property and
providing the overall mapping via an array of phandles. I've explored
this a little, it is doable but I'm not sure it actually makes things
any clearer when the portmap has gaps so I haven't made this change.
Changes in v4:
- Model the MDIO controller with the buses as child nodes. We still need
to deal with the switch port number so this is represented with the
"realtek,port" property which needs to be added to the MDIO bus
children (i.e. the PHYs)
- Because the above is quite a departure from earlier I've dropped the
r-by
Changes in v3:
- Add r-by from Connor
Changes in v2:
- None
.../bindings/net/realtek,rtl9301-mdio.yaml | 86 +++++++++++++++++++
1 file changed, 86 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
new file mode 100644
index 000000000000..02e4e33e9969
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/realtek,rtl9301-mdio.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Realtek RTL9300 MDIO Controller
+
+maintainers:
+ - Chris Packham <chris.packham@alliedtelesis.co.nz>
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - realtek,rtl9302b-mdio
+ - realtek,rtl9302c-mdio
+ - realtek,rtl9303-mdio
+ - const: realtek,rtl9301-mdio
+ - const: realtek,rtl9301-mdio
+
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ reg:
+ maxItems: 1
+
+patternProperties:
+ '^mdio-bus@[0-3]$':
+ $ref: mdio.yaml#
+
+ properties:
+ reg:
+ maxItems: 1
+
+ required:
+ - reg
+
+ patternProperties:
+ '^ethernet-phy@[a-f0-9]+$':
+ type: object
+ $ref: ethernet-phy.yaml#
+ unevaluatedProperties: false
+
+ unevaluatedProperties: false
+
+required:
+ - compatible
+ - reg
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ mdio-controller@ca00 {
+ compatible = "realtek,rtl9301-mdio";
+ reg = <0xca00 0x200>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio-bus@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0>;
+ };
+ };
+
+ mdio-bus@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethernet-phy@0 {
+ compatible = "ethernet-phy-ieee802.3-c45";
+ reg = <0>;
+ };
+ };
+ };
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v6 3/6] dt-bindings: mfd: Add MDIO interface to rtl9301-switch
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver Chris Packham
` (2 subsequent siblings)
5 siblings, 0 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
The MDIO controller is part of the switch on the RTL9300 family of
devices. Add a $ref to the mfd binding for these devices.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
This patch is dependent on "dt-bindings: net: Add Realtek MDIO
controller" which adds the realtek,rtl9301-mdio.yaml binding.
Changes in v6:
- Remove realtek,port property
- Remove leftover mdio-controller node.
- Fix some style issues.
- Fuller example including the port to phy-handle mapping
Changes in v5:
- Note dependency on realtek,rtl9301-mdio.yaml patch
- Add back reg property to the mdio-controller node.
Changes in v4:
- There is a single MDIO controller that has MDIO buses as children
Changes in v3:
- None
Changes in v2:
- None
.../bindings/mfd/realtek,rtl9301-switch.yaml | 31 +++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
index cb54abda5e6a..587fc3cf2524 100644
--- a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
+++ b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
@@ -43,6 +43,9 @@ patternProperties:
'i2c@[0-9a-f]+$':
$ref: /schemas/i2c/realtek,rtl9301-i2c.yaml#
+ 'mdio-controller@[0-9a-f]+$':
+ $ref: /schemas/net/realtek,rtl9301-mdio.yaml#
+
required:
- compatible
- reg
@@ -113,15 +116,43 @@ examples:
};
};
+ mdio-controller@ca00 {
+ compatible = "realtek,rtl9301-mdio";
+ reg = <0xca00 0x200>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ mdio-bus@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+ mdio-bus@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ phy2: ethernet-phy@0 {
+ reg = <0>;
+ };
+ };
+ };
+
ethernet-ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
+ phy-handle = <&phy1>;
};
port@1 {
reg = <1>;
+ phy-handle = <&phy2>;
};
};
};
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
` (2 preceding siblings ...)
2025-02-04 3:02 ` [PATCH net-next v6 3/6] dt-bindings: mfd: Add MDIO interface to rtl9301-switch Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
2025-02-09 14:19 ` Sander Vanheule
2025-02-04 3:02 ` [PATCH net-next v6 5/6] mips: dts: realtek: Add MDIO controller Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 6/6] mips: dts: cameo-rtl9302c: Add switch block Chris Packham
5 siblings, 1 reply; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
Add a driver for the MDIO controller on the RTL9300 family of Ethernet
switches with integrated SoC. There are 4 physical SMI interfaces on the
RTL9300 however access is done using the switch ports. The driver takes
the MDIO bus hierarchy from the DTS and uses this to configure the
switch ports so they are associated with the correct PHY. This mapping
is also used when dealing with software requests from phylib.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v6:
- Parse port->phy mapping from devicetree removing the need for the
realtek,port property
- Remove erroneous code dealing with SMI_POLL_CTRL. When actually
implemented this stops the LED unit from updating correctly.
Changes in v5:
- Reword out of date comment
- Use GENMASK/FIELD_PREP where appropriate
- Introduce port validity bitmap.
- Use more obvious names for PHY_CTRL_READ/WRITE and
PHY_CTRL_TYPE_C45/C22
Changes in v4:
- rename to realtek-rtl9300
- s/realtek_/rtl9300_/
- add locking to support concurrent access
- The dtbinding now represents the MDIO bus hierarchy so we consume this
information and use it to configure the switch port to MDIO bus+addr.
Changes in v3:
- Fix (another) off-by-one error
Changes in v2:
- Add clause 22 support
- Remove commented out code
- Formatting cleanup
- Set MAX_PORTS correctly for MDIO interface
- Fix off-by-one error in pn check
drivers/net/mdio/Kconfig | 7 +
drivers/net/mdio/Makefile | 1 +
drivers/net/mdio/mdio-realtek-rtl9300.c | 472 ++++++++++++++++++++++++
3 files changed, 480 insertions(+)
create mode 100644 drivers/net/mdio/mdio-realtek-rtl9300.c
diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
index 4a7a303be2f7..058fcdaf6c18 100644
--- a/drivers/net/mdio/Kconfig
+++ b/drivers/net/mdio/Kconfig
@@ -185,6 +185,13 @@ config MDIO_IPQ8064
This driver supports the MDIO interface found in the network
interface units of the IPQ8064 SoC
+config MDIO_REALTEK_RTL9300
+ tristate "Realtek RTL9300 MDIO interface support"
+ depends on MACH_REALTEK_RTL || COMPILE_TEST
+ help
+ This driver supports the MDIO interface found in the Realtek
+ RTL9300 family of Ethernet switches with integrated SoC.
+
config MDIO_REGMAP
tristate
help
diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
index 1015f0db4531..c23778e73890 100644
--- a/drivers/net/mdio/Makefile
+++ b/drivers/net/mdio/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxart.o
obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
+obj-$(CONFIG_MDIO_REALTEK_RTL9300) += mdio-realtek-rtl9300.o
obj-$(CONFIG_MDIO_REGMAP) += mdio-regmap.o
obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
new file mode 100644
index 000000000000..177163af1a1b
--- /dev/null
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -0,0 +1,472 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * MDIO controller for RTL9300 switches with integrated SoC.
+ *
+ * The MDIO communication is abstracted by the switch. At the software level
+ * communication uses the switch port to address the PHY. We work out the
+ * mapping based on the MDIO bus described in device tree and the realtek,port
+ * property.
+ */
+
+#include <linux/bitfield.h>
+#include <linux/bitmap.h>
+#include <linux/bits.h>
+#include <linux/cleanup.h>
+#include <linux/find.h>
+#include <linux/mdio.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/mutex.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#define SMI_GLB_CTRL 0xca00
+#define GLB_CTRL_INTF_SEL(intf) BIT(16 + (intf))
+#define SMI_PORT0_15_POLLING_SEL 0xca08
+#define SMI_ACCESS_PHY_CTRL_0 0xcb70
+#define SMI_ACCESS_PHY_CTRL_1 0xcb74
+#define PHY_CTRL_WRITE BIT(2)
+#define PHY_CTRL_READ 0
+#define PHY_CTRL_TYPE_C45 BIT(1)
+#define PHY_CTRL_TYPE_C22 0
+#define PHY_CTRL_CMD BIT(0)
+#define PHY_CTRL_FAIL BIT(25)
+#define SMI_ACCESS_PHY_CTRL_2 0xcb78
+#define SMI_ACCESS_PHY_CTRL_3 0xcb7c
+#define SMI_PORT0_5_ADDR_CTRL 0xcb80
+
+#define MAX_PORTS 28
+#define MAX_SMI_BUSSES 4
+#define MAX_SMI_ADDR 0x1f
+
+struct rtl9300_mdio_priv {
+ struct regmap *regmap;
+ struct mutex lock; /* protect HW access */
+ DECLARE_BITMAP(valid_ports, MAX_PORTS);
+ u8 smi_bus[MAX_PORTS];
+ u8 smi_addr[MAX_PORTS];
+ bool smi_bus_is_c45[MAX_SMI_BUSSES];
+ struct mii_bus *bus[MAX_SMI_BUSSES];
+};
+
+struct rtl9300_mdio_chan {
+ struct rtl9300_mdio_priv *priv;
+ u8 mdio_bus;
+};
+
+static int rtl9300_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
+{
+ struct rtl9300_mdio_chan *chan = bus->priv;
+ struct rtl9300_mdio_priv *priv = chan->priv;
+ int i;
+
+ for (i = find_first_bit(priv->valid_ports, MAX_PORTS);
+ i < MAX_PORTS;
+ i = find_next_bit(priv->valid_ports, MAX_PORTS, i + 1))
+ if (priv->smi_bus[i] == chan->mdio_bus &&
+ priv->smi_addr[i] == phy_id)
+ return i;
+
+ return -ENOENT;
+}
+
+static int rtl9300_mdio_wait_ready(struct rtl9300_mdio_priv *priv)
+{
+ struct regmap *regmap = priv->regmap;
+ u32 val;
+
+ lockdep_assert_held(&priv->lock);
+
+ return regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
+ val, !(val & PHY_CTRL_CMD), 10, 1000);
+}
+
+static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
+{
+ struct rtl9300_mdio_chan *chan = bus->priv;
+ struct rtl9300_mdio_priv *priv = chan->priv;
+ struct regmap *regmap = priv->regmap;
+ int port;
+ u32 val;
+ int err;
+
+ guard(mutex)(&priv->lock);
+
+ port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ if (port < 0)
+ return port;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, port << 16);
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(24, 20), regnum) |
+ FIELD_PREP(GENMASK(19, 15), 0x1f) |
+ FIELD_PREP(GENMASK(14, 3), 0xfff) |
+ PHY_CTRL_READ | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
+ if (err)
+ return err;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ err = regmap_read(regmap, SMI_ACCESS_PHY_CTRL_2, &val);
+ if (err)
+ return err;
+
+ return FIELD_GET(GENMASK(15, 0), val);
+}
+
+static int rtl9300_mdio_write_c22(struct mii_bus *bus, int phy_id, int regnum, u16 value)
+{
+ struct rtl9300_mdio_chan *chan = bus->priv;
+ struct rtl9300_mdio_priv *priv = chan->priv;
+ struct regmap *regmap = priv->regmap;
+ int port;
+ u32 val;
+ int err;
+
+ guard(mutex)(&priv->lock);
+
+ port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ if (port < 0)
+ return port;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_0, BIT(port));
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, value << 16);
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(24, 20), regnum) |
+ FIELD_PREP(GENMASK(19, 15), 0x1f) |
+ FIELD_PREP(GENMASK(14, 3), 0xfff) |
+ PHY_CTRL_WRITE | PHY_CTRL_TYPE_C22 | PHY_CTRL_CMD;
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1, val);
+ if (err)
+ return err;
+
+ err = regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
+ val, !(val & PHY_CTRL_CMD), 10, 100);
+ if (err)
+ return err;
+
+ if (val & PHY_CTRL_FAIL)
+ return -ENXIO;
+
+ return 0;
+}
+
+static int rtl9300_mdio_read_c45(struct mii_bus *bus, int phy_id, int dev_addr, int regnum)
+{
+ struct rtl9300_mdio_chan *chan = bus->priv;
+ struct rtl9300_mdio_priv *priv = chan->priv;
+ struct regmap *regmap = priv->regmap;
+ int port;
+ u32 val;
+ int err;
+
+ guard(mutex)(&priv->lock);
+
+ port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ if (port < 0)
+ return port;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(31, 16), port);
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, val);
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(20, 16), dev_addr) |
+ FIELD_PREP(GENMASK(15, 0), regnum);
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_3, val);
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1,
+ PHY_CTRL_READ | PHY_CTRL_TYPE_C45 | PHY_CTRL_CMD);
+ if (err)
+ return err;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ err = regmap_read(regmap, SMI_ACCESS_PHY_CTRL_2, &val);
+ if (err)
+ return err;
+
+ return FIELD_GET(GENMASK(15, 0), val);
+}
+
+static int rtl9300_mdio_write_c45(struct mii_bus *bus, int phy_id, int dev_addr,
+ int regnum, u16 value)
+{
+ struct rtl9300_mdio_chan *chan = bus->priv;
+ struct rtl9300_mdio_priv *priv = chan->priv;
+ struct regmap *regmap = priv->regmap;
+ int port;
+ u32 val;
+ int err;
+
+ guard(mutex)(&priv->lock);
+
+ port = rtl9300_mdio_phy_to_port(bus, phy_id);
+ if (port < 0)
+ return port;
+
+ err = rtl9300_mdio_wait_ready(priv);
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_0, BIT(port));
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(31, 16), value);
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, val);
+ if (err)
+ return err;
+
+ val = FIELD_PREP(GENMASK(20, 16), dev_addr) |
+ FIELD_PREP(GENMASK(15, 0), regnum);
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_3, val);
+ if (err)
+ return err;
+
+ err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_1,
+ PHY_CTRL_TYPE_C45 | PHY_CTRL_WRITE | PHY_CTRL_CMD);
+ if (err)
+ return err;
+
+ err = regmap_read_poll_timeout(regmap, SMI_ACCESS_PHY_CTRL_1,
+ val, !(val & PHY_CTRL_CMD), 10, 100);
+ if (err)
+ return err;
+
+ if (val & PHY_CTRL_FAIL)
+ return -ENXIO;
+
+ return 0;
+}
+
+static int rtl9300_mdiobus_init(struct rtl9300_mdio_priv *priv)
+{
+ u32 glb_ctrl_mask = 0, glb_ctrl_val = 0;
+ struct regmap *regmap = priv->regmap;
+ u32 port_addr[5] = { 0 };
+ u32 poll_sel[2] = { 0 };
+ int i, err;
+
+ /* Associate the port with the SMI interface and PHY */
+ for (i = find_first_bit(priv->valid_ports, MAX_PORTS);
+ i < MAX_PORTS;
+ i = find_next_bit(priv->valid_ports, MAX_PORTS, i + 1)) {
+ int pos;
+
+ pos = (i % 6) * 5;
+ port_addr[i / 6] |= (priv->smi_addr[i] & 0x1f) << pos;
+
+ pos = (i % 16) * 2;
+ poll_sel[i / 16] |= (priv->smi_bus[i] & 0x3) << pos;
+ }
+
+ /* Put the interfaces into C45 mode if required */
+ glb_ctrl_mask = GENMASK(19, 16);
+ for (i = 0; i < MAX_SMI_BUSSES; i++)
+ if (priv->smi_bus_is_c45[i])
+ glb_ctrl_val |= GLB_CTRL_INTF_SEL(i);
+
+ err = regmap_bulk_write(regmap, SMI_PORT0_5_ADDR_CTRL,
+ port_addr, 5);
+ if (err)
+ return err;
+
+ err = regmap_bulk_write(regmap, SMI_PORT0_15_POLLING_SEL,
+ poll_sel, 2);
+ if (err)
+ return err;
+
+ err = regmap_update_bits(regmap, SMI_GLB_CTRL,
+ glb_ctrl_mask, glb_ctrl_val);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int rtl9300_mdiobus_probe_one(struct device *dev, struct rtl9300_mdio_priv *priv,
+ struct fwnode_handle *node)
+{
+ struct rtl9300_mdio_chan *chan;
+ struct fwnode_handle *child;
+ struct mii_bus *bus;
+ u32 mdio_bus;
+ int err;
+
+ err = fwnode_property_read_u32(node, "reg", &mdio_bus);
+ if (err)
+ return err;
+
+ fwnode_for_each_child_node(node, child)
+ if (fwnode_device_is_compatible(child, "ethernet-phy-ieee802.3-c45"))
+ priv->smi_bus_is_c45[mdio_bus] = true;
+
+ bus = devm_mdiobus_alloc_size(dev, sizeof(*chan));
+ if (!bus)
+ return -ENOMEM;
+
+ bus->name = "Reaktek Switch MDIO Bus";
+ bus->read = rtl9300_mdio_read_c22;
+ bus->write = rtl9300_mdio_write_c22;
+ bus->read_c45 = rtl9300_mdio_read_c45;
+ bus->write_c45 = rtl9300_mdio_write_c45;
+ bus->parent = dev;
+ chan = bus->priv;
+ chan->mdio_bus = mdio_bus;
+ chan->priv = priv;
+
+ snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", dev_name(dev), mdio_bus);
+
+ err = devm_of_mdiobus_register(dev, bus, to_of_node(node));
+ if (err)
+ return dev_err_probe(dev, err, "cannot register MDIO bus\n");
+
+ return 0;
+}
+
+/* The mdio-controller is part of a switch block so we parse the sibling
+ * ethernet-ports node and build a mapping of the switch port to MDIO bus/addr
+ * based on the phy-handle.
+ */
+static int rtl9300_mdiobus_map_ports(struct device *dev)
+{
+ struct rtl9300_mdio_priv *priv = dev_get_drvdata(dev);
+ struct device *parent = dev->parent;
+ struct fwnode_handle *port;
+ int err;
+
+ struct fwnode_handle *ports __free(fwnode_handle) =
+ device_get_named_child_node(parent, "ethernet-ports");
+ if (!ports)
+ return dev_err_probe(dev, -EINVAL, "%pfwP missing ethernet-ports\n",
+ dev_fwnode(parent));
+
+ fwnode_for_each_child_node(ports, port) {
+ struct device_node *mdio_dn;
+ u32 addr;
+ u32 bus;
+ u32 pn;
+
+ struct device_node *phy_dn __free(device_node) =
+ of_parse_phandle(to_of_node(port), "phy-handle", 0);
+ /* skip ports without phys */
+ if (!phy_dn)
+ continue;
+
+ mdio_dn = phy_dn->parent;
+ /* only map ports that are connected to this mdio-controller */
+ if (mdio_dn->parent != dev->of_node)
+ continue;
+
+ err = fwnode_property_read_u32(port, "reg", &pn);
+ if (err)
+ return err;
+
+ if (pn >= MAX_PORTS)
+ return dev_err_probe(dev, -EINVAL, "illegal port number %d\n", pn);
+
+ err = of_property_read_u32(mdio_dn, "reg", &bus);
+ if (err)
+ return err;
+
+ if (bus >= MAX_SMI_BUSSES)
+ return dev_err_probe(dev, -EINVAL, "illegal smi bus number %d\n", bus);
+
+ err = of_property_read_u32(phy_dn, "reg", &addr);
+ if (err)
+ return err;
+
+ bitmap_set(priv->valid_ports, pn, 1);
+ priv->smi_bus[pn] = bus;
+ priv->smi_addr[pn] = addr;
+ }
+
+ return 0;
+}
+
+static int rtl9300_mdiobus_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct rtl9300_mdio_priv *priv;
+ struct fwnode_handle *child;
+ int err;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ err = devm_mutex_init(dev, &priv->lock);
+ if (err)
+ return err;
+
+ priv->regmap = syscon_node_to_regmap(dev->parent->of_node);
+ if (IS_ERR(priv->regmap))
+ return PTR_ERR(priv->regmap);
+
+ platform_set_drvdata(pdev, priv);
+
+ err = rtl9300_mdiobus_map_ports(dev);
+ if (err)
+ return err;
+
+ device_for_each_child_node(dev, child) {
+ err = rtl9300_mdiobus_probe_one(dev, priv, child);
+ if (err)
+ return err;
+ }
+
+ err = rtl9300_mdiobus_init(priv);
+ if (err)
+ return dev_err_probe(dev, err, "failed to initialise MDIO bus controller\n");
+
+ return 0;
+}
+
+static const struct of_device_id rtl9300_mdio_ids[] = {
+ { .compatible = "realtek,rtl9301-mdio" },
+ {}
+};
+MODULE_DEVICE_TABLE(of, rtl9300_mdio_ids);
+
+static struct platform_driver rtl9300_mdio_driver = {
+ .probe = rtl9300_mdiobus_probe,
+ .driver = {
+ .name = "mdio-rtl9300",
+ .of_match_table = rtl9300_mdio_ids,
+ },
+};
+
+module_platform_driver(rtl9300_mdio_driver);
+
+MODULE_DESCRIPTION("RTL9300 MDIO driver");
+MODULE_LICENSE("GPL");
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v6 5/6] mips: dts: realtek: Add MDIO controller
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
` (3 preceding siblings ...)
2025-02-04 3:02 ` [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 6/6] mips: dts: cameo-rtl9302c: Add switch block Chris Packham
5 siblings, 0 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
Add a device tree node for the MDIO controller on the RTL9300 chips.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v6:
- None
Changes in v5:
- Add reg property to mdio-controller
Changes in v4:
- Have a single mdio-controller with the individual buses as child
nodes
Changes in v3:
- None
Changes in v2:
- None
arch/mips/boot/dts/realtek/rtl930x.dtsi | 33 +++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/arch/mips/boot/dts/realtek/rtl930x.dtsi b/arch/mips/boot/dts/realtek/rtl930x.dtsi
index f2e57ea3a60c..101bab72a95f 100644
--- a/arch/mips/boot/dts/realtek/rtl930x.dtsi
+++ b/arch/mips/boot/dts/realtek/rtl930x.dtsi
@@ -69,6 +69,39 @@ i2c1: i2c@388 {
#size-cells = <0>;
status = "disabled";
};
+
+ mdio_controller: mdio-controller@ca00 {
+ compatible = "realtek,rtl9301-mdio";
+ reg = <0xca00 0x200>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+
+ mdio0: mdio-bus@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ mdio1: mdio-bus@1 {
+ reg = <1>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ mdio2: mdio-bus@2 {
+ reg = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ mdio3: mdio-bus@3 {
+ reg = <3>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+ };
};
soc: soc@18000000 {
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH net-next v6 6/6] mips: dts: cameo-rtl9302c: Add switch block
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
` (4 preceding siblings ...)
2025-02-04 3:02 ` [PATCH net-next v6 5/6] mips: dts: realtek: Add MDIO controller Chris Packham
@ 2025-02-04 3:02 ` Chris Packham
5 siblings, 0 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 3:02 UTC (permalink / raw)
To: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips, Chris Packham
Add the switch port and phys to the cameo-rtl9302c-2x-rtl8224-2xge
board.
Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
---
Notes:
Changes in v6:
- New. This is needed to comply with the updated bindings. It could
possibly be split to add the ports then the PHYs. Technically the
ports are the required property that dtbs_check will complain about
but it didn't seem worth separating out the PHYs.
.../cameo-rtl9302c-2x-rtl8224-2xge.dts | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts b/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts
index 6789bf374044..28ab2442b37a 100644
--- a/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts
+++ b/arch/mips/boot/dts/realtek/cameo-rtl9302c-2x-rtl8224-2xge.dts
@@ -71,3 +71,99 @@ partition@1180000 {
};
};
};
+
+&mdio0 {
+ /* External RTL8224 */
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy1: ethernet-phy@1 {
+ reg = <1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+};
+
+&mdio1 {
+ /* External RTL8224 */
+ phy4: ethernet-phy@0 {
+ reg = <0>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy5: ethernet-phy@1 {
+ reg = <1>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy6: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+ phy7: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "ethernet-phy-ieee802.3-c45";
+ };
+};
+
+&switch0 {
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ phy-handle = <&phy0>;
+ phy-mode = "usxgmii";
+ };
+ port@1 {
+ reg = <1>;
+ phy-handle = <&phy1>;
+ phy-mode = "usxgmii";
+ };
+ port@2 {
+ reg = <2>;
+ phy-handle = <&phy2>;
+ phy-mode = "usxgmii";
+ };
+ port@3 {
+ reg = <3>;
+ phy-handle = <&phy3>;
+ phy-mode = "usxgmii";
+ };
+ port@16 {
+ reg = <16>;
+ phy-handle = <&phy4>;
+ phy-mode = "usxgmii";
+ };
+ port@17 {
+ reg = <17>;
+ phy-handle = <&phy5>;
+ phy-mode = "usxgmii";
+ };
+ port@18 {
+ reg = <18>;
+ phy-handle = <&phy6>;
+ phy-mode = "usxgmii";
+ };
+ port@19 {
+ reg = <19>;
+ phy-handle = <&phy7>;
+ phy-mode = "usxgmii";
+ };
+ port@24{
+ reg = <24>;
+ phy-mode = "10gbase-r";
+ };
+ port@25{
+ reg = <25>;
+ phy-mode = "10gbase-r";
+ };
+ };
+};
--
2.48.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
@ 2025-02-04 8:09 ` Krzysztof Kozlowski
2025-02-04 20:14 ` Chris Packham
2025-02-04 16:02 ` Rob Herring
1 sibling, 1 reply; 13+ messages in thread
From: Krzysztof Kozlowski @ 2025-02-04 8:09 UTC (permalink / raw)
To: Chris Packham
Cc: lee, robh, krzk+dt, conor+dt, andrew+netdev, davem, edumazet,
kuba, pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen, devicetree, linux-kernel, netdev, linux-mips
On Tue, Feb 04, 2025 at 04:02:44PM +1300, Chris Packham wrote:
> Add bindings for the ethernet-switch portion of the RTL9300.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>
> Notes:
> Changes in v6:
> - New
> - I'd like to enforce the property being "ethernet-ports" but I see the
> generic binding allows "ports" as well. Can I just add ethernet-ports:
> type: object here or does by driver need to handle both "ports" and
> "ethernet-ports" (I see some do and some don't).
>
> .../bindings/mfd/realtek,rtl9301-switch.yaml | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> index f053303ab1e6..cb54abda5e6a 100644
> --- a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> +++ b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> @@ -14,6 +14,8 @@ description:
> number of different peripherals are accessed through a common register block,
> represented here as a syscon node.
>
> +$ref: /schemas/net/ethernet-switch.yaml#
> +
> properties:
> compatible:
> items:
> @@ -45,7 +47,7 @@ required:
> - compatible
> - reg
>
I don't get why this device receives now children without addresses.
Either your children have 'reg' or they do not. Mixing is a sign of a
mess, like this was never actually simple-mfd.
You would get this comment if you posted complete schema the first time.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
2025-02-04 8:09 ` Krzysztof Kozlowski
@ 2025-02-04 16:02 ` Rob Herring
1 sibling, 0 replies; 13+ messages in thread
From: Rob Herring @ 2025-02-04 16:02 UTC (permalink / raw)
To: Chris Packham
Cc: lee, krzk+dt, conor+dt, andrew+netdev, davem, edumazet, kuba,
pabeni, tsbogend, hkallweit1, linux, sander, daniel,
markus.stockhausen, devicetree, linux-kernel, netdev, linux-mips
On Tue, Feb 04, 2025 at 04:02:44PM +1300, Chris Packham wrote:
> Add bindings for the ethernet-switch portion of the RTL9300.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>
> Notes:
> Changes in v6:
> - New
> - I'd like to enforce the property being "ethernet-ports" but I see the
> generic binding allows "ports" as well. Can I just add ethernet-ports:
> type: object here
Yes. And keep 'additionalProperties'.
> or does by driver need to handle both "ports" and
> "ethernet-ports" (I see some do and some don't).
No, it doesn't.
>
> .../bindings/mfd/realtek,rtl9301-switch.yaml | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> index f053303ab1e6..cb54abda5e6a 100644
> --- a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> +++ b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
> @@ -14,6 +14,8 @@ description:
> number of different peripherals are accessed through a common register block,
> represented here as a syscon node.
>
> +$ref: /schemas/net/ethernet-switch.yaml#
If you don't have any device specific per port properties, then this
needs to be: ethernet-switch.yaml#/$defs/ethernet-ports
> +
> properties:
> compatible:
> items:
> @@ -45,7 +47,7 @@ required:
> - compatible
> - reg
>
> -additionalProperties: false
> +unevaluatedProperties: false
>
> examples:
> - |
> @@ -110,5 +112,17 @@ examples:
> };
> };
> };
> +
> + ethernet-ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + port@0 {
> + reg = <0>;
> + };
> + port@1 {
> + reg = <1>;
> + };
> + };
> };
>
> --
> 2.48.1
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller
2025-02-04 3:02 ` [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller Chris Packham
@ 2025-02-04 16:03 ` Rob Herring (Arm)
0 siblings, 0 replies; 13+ messages in thread
From: Rob Herring (Arm) @ 2025-02-04 16:03 UTC (permalink / raw)
To: Chris Packham
Cc: netdev, linux-mips, devicetree, hkallweit1, kuba, conor+dt, lee,
andrew+netdev, davem, pabeni, tsbogend, linux, sander, krzk+dt,
markus.stockhausen, daniel, linux-kernel, edumazet
On Tue, 04 Feb 2025 16:02:45 +1300, Chris Packham wrote:
> Add dtschema for the MDIO controller found in the RTL9300 SoCs. The
> controller is slightly unusual in that direct MDIO communication is not
> possible. We model the MDIO controller with the MDIO buses as child
> nodes and the PHYs as children of the buses. The mapping of switch port
> number to MDIO bus/addr requires the ethernet-ports sibling to provide
> the mapping via the phy-handle property.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>
> Notes:
> Changes in v6:
> - Remove realtek,port property. The driver will parse the ethernet-ports
> sibling node to figure out the mapping (do I need to mention that
> somewhere in this binding?).
> - Correct number of mdio buses. 4 possible buses numbered 0-3.
> Changes in v5:
> - Add back reg property to mdio-controller node
> - Make unit address in the node name required
> - Andrew suggested perhaps doing away with the realtek,port property and
> providing the overall mapping via an array of phandles. I've explored
> this a little, it is doable but I'm not sure it actually makes things
> any clearer when the portmap has gaps so I haven't made this change.
> Changes in v4:
> - Model the MDIO controller with the buses as child nodes. We still need
> to deal with the switch port number so this is represented with the
> "realtek,port" property which needs to be added to the MDIO bus
> children (i.e. the PHYs)
> - Because the above is quite a departure from earlier I've dropped the
> r-by
> Changes in v3:
> - Add r-by from Connor
> Changes in v2:
> - None
>
> .../bindings/net/realtek,rtl9301-mdio.yaml | 86 +++++++++++++++++++
> 1 file changed, 86 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300
2025-02-04 8:09 ` Krzysztof Kozlowski
@ 2025-02-04 20:14 ` Chris Packham
0 siblings, 0 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-04 20:14 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: lee@kernel.org, robh@kernel.org, krzk+dt@kernel.org,
conor+dt@kernel.org, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
tsbogend@alpha.franken.de, hkallweit1@gmail.com,
linux@armlinux.org.uk, sander@svanheule.net,
daniel@makrotopia.org, markus.stockhausen@gmx.de,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-mips@vger.kernel.org
Hi Krzysztof,
On 04/02/2025 21:09, Krzysztof Kozlowski wrote:
> On Tue, Feb 04, 2025 at 04:02:44PM +1300, Chris Packham wrote:
>> Add bindings for the ethernet-switch portion of the RTL9300.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> ---
>>
>> Notes:
>> Changes in v6:
>> - New
>> - I'd like to enforce the property being "ethernet-ports" but I see the
>> generic binding allows "ports" as well. Can I just add ethernet-ports:
>> type: object here or does by driver need to handle both "ports" and
>> "ethernet-ports" (I see some do and some don't).
>>
>> .../bindings/mfd/realtek,rtl9301-switch.yaml | 16 +++++++++++++++-
>> 1 file changed, 15 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
>> index f053303ab1e6..cb54abda5e6a 100644
>> --- a/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
>> +++ b/Documentation/devicetree/bindings/mfd/realtek,rtl9301-switch.yaml
>> @@ -14,6 +14,8 @@ description:
>> number of different peripherals are accessed through a common register block,
>> represented here as a syscon node.
>>
>> +$ref: /schemas/net/ethernet-switch.yaml#
>> +
>> properties:
>> compatible:
>> items:
>> @@ -45,7 +47,7 @@ required:
>> - compatible
>> - reg
>>
> I don't get why this device receives now children without addresses.
> Either your children have 'reg' or they do not. Mixing is a sign of a
> mess, like this was never actually simple-mfd.
>
> You would get this comment if you posted complete schema the first time.
Yes fair enough. I think I erred too far on the side of trying to send
small chunks (and also not wanting to commit to a binding before I had
working drivers).
So how do we move forward? There's one more patch I haven't sent yet
that adds interrupts for the switch block. But other than that I think
what I have now covers all of the major components in this chip.
There's only one in-tree board that uses this and I'm the maintainer of
it so withdrawing the mfd binding and replacing it with something else
is not out of the question. There may be some complaints from make
dtbs_check while we get this sorted but hopefully we can get that done soon.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver
2025-02-04 3:02 ` [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver Chris Packham
@ 2025-02-09 14:19 ` Sander Vanheule
2025-02-11 21:06 ` Chris Packham
0 siblings, 1 reply; 13+ messages in thread
From: Sander Vanheule @ 2025-02-09 14:19 UTC (permalink / raw)
To: Chris Packham, lee, robh, krzk+dt, conor+dt, andrew+netdev, davem,
edumazet, kuba, pabeni, tsbogend, hkallweit1, linux, daniel,
markus.stockhausen
Cc: devicetree, linux-kernel, netdev, linux-mips
Hi Chris,
On Tue, 2025-02-04 at 16:02 +1300, Chris Packham wrote:
> Add a driver for the MDIO controller on the RTL9300 family of Ethernet
> switches with integrated SoC. There are 4 physical SMI interfaces on the
> RTL9300 however access is done using the switch ports. The driver takes
> the MDIO bus hierarchy from the DTS and uses this to configure the
> switch ports so they are associated with the correct PHY. This mapping
> is also used when dealing with software requests from phylib.
>
> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
> ---
>
> Notes:
> Changes in v6:
> - Parse port->phy mapping from devicetree removing the need for the
> realtek,port property
Good to see you found a way to do this!
> +/*
> + * MDIO controller for RTL9300 switches with integrated SoC.
> + *
> + * The MDIO communication is abstracted by the switch. At the software level
> + * communication uses the switch port to address the PHY. We work out the
> + * mapping based on the MDIO bus described in device tree and the realtek,port
> + * property.
> + */
Needs an update again ;-)
> +static int rtl9300_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
> +{
> + struct rtl9300_mdio_chan *chan = bus->priv;
> + struct rtl9300_mdio_priv *priv = chan->priv;
> + int i;
> +
> + for (i = find_first_bit(priv->valid_ports, MAX_PORTS);
> + i < MAX_PORTS;
> + i = find_next_bit(priv->valid_ports, MAX_PORTS, i + 1))
You could use the for_each_set_bit(i, priv->valid_ports, MAX_PORTS) loop macro.
> +static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
> +{
[...]
> +
> + err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, port << 16);
Another candidate for FIELD_PREP()
> + if (err)
> + return err;
> +
> + val = FIELD_PREP(GENMASK(24, 20), regnum) |
> + FIELD_PREP(GENMASK(19, 15), 0x1f) |
> + FIELD_PREP(GENMASK(14, 3), 0xfff) |
You could use #define-s for the GENMASK() field masks too, similar to PHY_CTRL_*. That
would make what you're setting a bit clearer, compared to these literal values.
Nit: You're also setting all-one values, so GENMASK(19, 15) and GENMASK(14, 3) by
themselves are sufficient. E.g. PHY_CTRL_NO_PAGE_PARK and PHY_CTRL_NO_PAGE_SELECT.
> +static int rtl9300_mdiobus_probe(struct platform_device *pdev)
> +{
[...]
> +
> + device_for_each_child_node(dev, child) {
> + err = rtl9300_mdiobus_probe_one(dev, priv, child);
In your next patch you use 'status = "disabled"' for the base dtsi. You may want to use
fwnode_for_each_available_child_node() in that case, so unused busses are not probed.
Best,
Sander
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver
2025-02-09 14:19 ` Sander Vanheule
@ 2025-02-11 21:06 ` Chris Packham
0 siblings, 0 replies; 13+ messages in thread
From: Chris Packham @ 2025-02-11 21:06 UTC (permalink / raw)
To: Sander Vanheule, lee@kernel.org, robh@kernel.org,
krzk+dt@kernel.org, conor+dt@kernel.org, andrew+netdev@lunn.ch,
davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, tsbogend@alpha.franken.de,
hkallweit1@gmail.com, linux@armlinux.org.uk,
daniel@makrotopia.org, markus.stockhausen@gmx.de
Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org, linux-mips@vger.kernel.org
Hi Sander,
I'll hold off on sending v7 until I sort out the mess I've made with the
dt-bindings (spun off into a different series [1])
[1] -
https://lore.kernel.org/lkml/20250209234751.460404-1-chris.packham@alliedtelesis.co.nz/
On 10/02/2025 03:19, Sander Vanheule wrote:
> Hi Chris,
>
> On Tue, 2025-02-04 at 16:02 +1300, Chris Packham wrote:
>> Add a driver for the MDIO controller on the RTL9300 family of Ethernet
>> switches with integrated SoC. There are 4 physical SMI interfaces on the
>> RTL9300 however access is done using the switch ports. The driver takes
>> the MDIO bus hierarchy from the DTS and uses this to configure the
>> switch ports so they are associated with the correct PHY. This mapping
>> is also used when dealing with software requests from phylib.
>>
>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>> ---
>>
>> Notes:
>> Changes in v6:
>> - Parse port->phy mapping from devicetree removing the need for the
>> realtek,port property
> Good to see you found a way to do this!
>
>
>> +/*
>> + * MDIO controller for RTL9300 switches with integrated SoC.
>> + *
>> + * The MDIO communication is abstracted by the switch. At the software level
>> + * communication uses the switch port to address the PHY. We work out the
>> + * mapping based on the MDIO bus described in device tree and the realtek,port
>> + * property.
>> + */
> Needs an update again ;-)
Yep will do.
>> +static int rtl9300_mdio_phy_to_port(struct mii_bus *bus, int phy_id)
>> +{
>> + struct rtl9300_mdio_chan *chan = bus->priv;
>> + struct rtl9300_mdio_priv *priv = chan->priv;
>> + int i;
>> +
>> + for (i = find_first_bit(priv->valid_ports, MAX_PORTS);
>> + i < MAX_PORTS;
>> + i = find_next_bit(priv->valid_ports, MAX_PORTS, i + 1))
> You could use the for_each_set_bit(i, priv->valid_ports, MAX_PORTS) loop macro.
I figured there must be a wrapper for this idiom but I couldn't find it
for looking.
>> +static int rtl9300_mdio_read_c22(struct mii_bus *bus, int phy_id, int regnum)
>> +{
> [...]
>> +
>> + err = regmap_write(regmap, SMI_ACCESS_PHY_CTRL_2, port << 16);
> Another candidate for FIELD_PREP()
Yep. There's a couple more too.
>
>> + if (err)
>> + return err;
>> +
>> + val = FIELD_PREP(GENMASK(24, 20), regnum) |
>> + FIELD_PREP(GENMASK(19, 15), 0x1f) |
>> + FIELD_PREP(GENMASK(14, 3), 0xfff) |
> You could use #define-s for the GENMASK() field masks too, similar to PHY_CTRL_*. That
> would make what you're setting a bit clearer, compared to these literal values.
Sure will do.
> Nit: You're also setting all-one values, so GENMASK(19, 15) and GENMASK(14, 3) by
> themselves are sufficient. E.g. PHY_CTRL_NO_PAGE_PARK and PHY_CTRL_NO_PAGE_SELECT.
This part I'm not planning on doing. Right now I am just setting them to
all-ones but the same code may end up needing to grow page logic
(Realtek's SDK has code that adds page read/write functions to phylib).
>> +static int rtl9300_mdiobus_probe(struct platform_device *pdev)
>> +{
> [...]
>> +
>> + device_for_each_child_node(dev, child) {
>> + err = rtl9300_mdiobus_probe_one(dev, priv, child);
> In your next patch you use 'status = "disabled"' for the base dtsi. You may want to use
> fwnode_for_each_available_child_node() in that case, so unused busses are not probed.
Hmm, the existing code is only registering two mdio buses. Although I
can't see why it's not attempting to to register the other two.
Ah OK. It's because device_for_each_child_node() wraps
device_get_next_child_node() which calls fwnode_get_next_child_node()
which calls of_fwnode_get_next_child_node() which does the available
check with of_get_next_available_child().
So I don't think there's any change to be made here.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-02-11 21:06 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-04 3:02 [PATCH net-next v6 0/6] RTL9300 MDIO driver Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 1/6] dt-bindings: mfd: Add switch to RTL9300 Chris Packham
2025-02-04 8:09 ` Krzysztof Kozlowski
2025-02-04 20:14 ` Chris Packham
2025-02-04 16:02 ` Rob Herring
2025-02-04 3:02 ` [PATCH net-next v6 2/6] dt-bindings: net: Add Realtek MDIO controller Chris Packham
2025-02-04 16:03 ` Rob Herring (Arm)
2025-02-04 3:02 ` [PATCH net-next v6 3/6] dt-bindings: mfd: Add MDIO interface to rtl9301-switch Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 4/6] net: mdio: Add RTL9300 MDIO driver Chris Packham
2025-02-09 14:19 ` Sander Vanheule
2025-02-11 21:06 ` Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 5/6] mips: dts: realtek: Add MDIO controller Chris Packham
2025-02-04 3:02 ` [PATCH net-next v6 6/6] mips: dts: cameo-rtl9302c: Add switch block Chris Packham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).