diff mbox series

[v4,2/5] dt-bindings: net: dsa: qca,ar9331 switch documentation

Message ID 20191022055743.6832-3-o.rempel@pengutronix.de (mailing list archive)
State Superseded
Headers show
Series add dsa switch support for ar9331 | expand

Commit Message

Oleksij Rempel Oct. 22, 2019, 5:57 a.m. UTC
Atheros AR9331 has built-in 5 port switch. The switch can be configured
to use all 5 or 4 ports. One of built-in PHYs can be used by first built-in
ethernet controller or to be used directly by the switch over second ethernet
controller.

Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
---
 .../devicetree/bindings/net/dsa/ar9331.txt    | 148 ++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/dsa/ar9331.txt

Comments

Andrew Lunn Oct. 23, 2019, 12:35 a.m. UTC | #1
On Tue, Oct 22, 2019 at 07:57:40AM +0200, Oleksij Rempel wrote:
> Atheros AR9331 has built-in 5 port switch. The switch can be configured
> to use all 5 or 4 ports. One of built-in PHYs can be used by first built-in
> ethernet controller or to be used directly by the switch over second ethernet
> controller.
> 
> Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>

Hi Oleksij

What we never really discussed is how this MUXing of the PHY works.

What i'm worried about is that when we do understand how it works, we
cannot properly support it using this binding.

Please could you try to find information about this.

Thanks
	Andrew
Oleksij Rempel Oct. 29, 2019, 7:34 a.m. UTC | #2
On Wed, Oct 23, 2019 at 02:35:43AM +0200, Andrew Lunn wrote:
> On Tue, Oct 22, 2019 at 07:57:40AM +0200, Oleksij Rempel wrote:
> > Atheros AR9331 has built-in 5 port switch. The switch can be configured
> > to use all 5 or 4 ports. One of built-in PHYs can be used by first built-in
> > ethernet controller or to be used directly by the switch over second ethernet
> > controller.
> > 
> > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> 
> Hi Oleksij
> 
> What we never really discussed is how this MUXing of the PHY works.
> 
> What i'm worried about is that when we do understand how it works, we
> cannot properly support it using this binding.

good point. i would prefer to make it properly.

> Please could you try to find information about this.

Documentation says:
The PHY interfaces (PHY0, PHY1, PHY2, PHY3 and PHY4) can connect to the switch
in bridge mode. In this case GE0 must be under reset. All five LAN ports are
switched together and connect to the CPU through the GMII interface (MAC0),
which is controlled by the ETH_CFG register bit SW_ONLY_MODE. If GE0 connects
separately to PHY, then MAC5 should be under reset.

There is no SW_ONLY_MODE bit in the documentation.
I found:
CFG_SW_PHY_SWAP - Used to switch the wires connection of PHY port 0 with that of
port 4 in the Ethernet switch. MAC1 and PHY4 are paired while MAC5 and PHY0 are
paired.

CFG_SW_PHY_ADDR_SWAP - Exchanges the address of PHY port 0 with that of
PHY port 4 in the Ethernet switch.

It feels like this are the right bits. I'll try to test it after ELC-E
conference (If you are here, please ping me).
If this are the right bits, should it be registered as separate driver? This
register is on MMIO and not part of the switches MDIO.

Regards,
Oleksij
Oleksij Rempel Dec. 15, 2019, 2:57 p.m. UTC | #3
Hi Andrew,

On Tue, Oct 29, 2019 at 08:34:19AM +0100, Oleksij Rempel wrote:
> On Wed, Oct 23, 2019 at 02:35:43AM +0200, Andrew Lunn wrote:
> > On Tue, Oct 22, 2019 at 07:57:40AM +0200, Oleksij Rempel wrote:
> > > Atheros AR9331 has built-in 5 port switch. The switch can be configured
> > > to use all 5 or 4 ports. One of built-in PHYs can be used by first built-in
> > > ethernet controller or to be used directly by the switch over second ethernet
> > > controller.
> > > 
> > > Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
> > 
> > Hi Oleksij
> > 
> > What we never really discussed is how this MUXing of the PHY works.
> > 
> > What i'm worried about is that when we do understand how it works, we
> > cannot properly support it using this binding.
> 
> good point. i would prefer to make it properly.
> 
> > Please could you try to find information about this.
> 
> Documentation says:
> The PHY interfaces (PHY0, PHY1, PHY2, PHY3 and PHY4) can connect to the switch
> in bridge mode. In this case GE0 must be under reset. All five LAN ports are
> switched together and connect to the CPU through the GMII interface (MAC0),
> which is controlled by the ETH_CFG register bit SW_ONLY_MODE. If GE0 connects
> separately to PHY, then MAC5 should be under reset.
> 
> There is no SW_ONLY_MODE bit in the documentation.
> I found:
> CFG_SW_PHY_SWAP - Used to switch the wires connection of PHY port 0 with that of
> port 4 in the Ethernet switch. MAC1 and PHY4 are paired while MAC5 and PHY0 are
> paired.
> 
> CFG_SW_PHY_ADDR_SWAP - Exchanges the address of PHY port 0 with that of
> PHY port 4 in the Ethernet switch.
> 
> It feels like this are the right bits. I'll try to test it after ELC-E
> conference (If you are here, please ping me).
> If this are the right bits, should it be registered as separate driver? This
> register is on MMIO and not part of the switches MDIO.

I spend some tine on investigating and testing it. So, the result is
pretty simple. It looks like *MII lines of ethernet controller GMAC0 and
MAC of switch port5 are just connected together and wired to the PHY4.
Something like this:

GMAC1-->switch--mac5-+--->phy4
                     ^
GMAC0---------------/


So, both of MACs can be enabled at same time and introduce resource
conflict. If one is enabled, other one should be set in to reset mode.

The questions are:
- how this can be reflected in devicetree?
- how this can be properly implemented in kernel?

Regards,
Oleksij
Andrew Lunn Dec. 17, 2019, 8:44 a.m. UTC | #4
> I spend some tine on investigating and testing it. So, the result is
> pretty simple. It looks like *MII lines of ethernet controller GMAC0 and
> MAC of switch port5 are just connected together and wired to the PHY4.
> Something like this:
> 
> GMAC1-->switch--mac5-+--->phy4
>                      ^
> GMAC0---------------/
> 
> 
> So, both of MACs can be enabled at same time and introduce resource
> conflict. If one is enabled, other one should be set in to reset mode.
> 
> The questions are:
> - how this can be reflected in devicetree?
> - how this can be properly implemented in kernel?

That is, er, interesting.

So in device tree, i would use a phy-handle in GMAC1 or GMAC0 to point
to phy4. I don't think there is anything you can do in DT to prevent
both GMAC0 and GMAC1 having a phandle to phy4, other than adding a
comment in the binding. You could ask Rob if DT schema provides any
sorts of checks like this? But i doubt it.

In the driver, it would be good to check if two MACs try to connect to
one PHY. This in general should not happen, so maybe you can add a
check to the core, in phylib and/or phylink. Just watch out for
cpsw. It connects two PHYs to one MAC. Just don't make the assumption
one MAC and one PHY is correct, everything else is wrong.

    Andrew
diff mbox series

Patch

diff --git a/Documentation/devicetree/bindings/net/dsa/ar9331.txt b/Documentation/devicetree/bindings/net/dsa/ar9331.txt
new file mode 100644
index 000000000000..40a1f6e1f85f
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/dsa/ar9331.txt
@@ -0,0 +1,148 @@ 
+Atheros AR9331 built-in switch
+=============================
+
+It is a switch built-in to Atheros AR9331 WiSoC and addressable over internal
+MDIO bus. All PHYs are build-in as well. 
+
+Required properties:
+
+ - compatible: should be: "qca,ar9331-switch" 
+ - reg: Address on the MII bus for the switch.
+ - resets : Must contain an entry for each entry in reset-names.
+ - reset-names : Must include the following entries: "switch"
+ - interrupt-parent: Phandle to the parent interrupt controller
+ - interrupts: IRQ line for the switch
+ - interrupt-controller: Indicates the switch is itself an interrupt
+   controller. This is used for the PHY interrupts.
+ - #interrupt-cells: must be 1
+ - mdio: Container of PHY and devices on the switches MDIO bus.
+
+See Documentation/devicetree/bindings/net/dsa/dsa.txt for a list of additional
+required and optional properties.
+Examples:
+
+eth0: ethernet@19000000 {
+	compatible = "qca,ar9330-eth";
+	reg = <0x19000000 0x200>;
+	interrupts = <4>;
+
+	resets = <&rst 9>, <&rst 22>;
+	reset-names = "mac", "mdio";
+	clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>;
+	clock-names = "eth", "mdio";
+
+	phy-mode = "mii";
+	phy-handle = <&phy_port4>;
+};
+
+eth1: ethernet@1a000000 {
+	compatible = "qca,ar9330-eth";
+	reg = <0x1a000000 0x200>;
+	interrupts = <5>;
+	resets = <&rst 13>, <&rst 23>;
+	reset-names = "mac", "mdio";
+	clocks = <&pll ATH79_CLK_AHB>, <&pll ATH79_CLK_AHB>;
+	clock-names = "eth", "mdio";
+
+	phy-mode = "gmii";
+
+	fixed-link {
+		speed = <1000>;
+		full-duplex;
+	};
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		switch10: switch@10 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+
+			compatible = "qca,ar9331-switch";
+			reg = <0x10>;
+			resets = <&rst 8>;
+			reset-names = "switch";
+
+			interrupt-parent = <&miscintc>;
+			interrupts = <12>;
+
+			interrupt-controller;
+			#interrupt-cells = <1>;
+
+			ports {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				switch_port0: port@0 {
+					reg = <0x0>;
+					label = "cpu";
+					ethernet = <&eth1>;
+
+					phy-mode = "gmii";
+
+					fixed-link {
+						speed = <1000>;
+						full-duplex;
+					};
+				};
+
+				switch_port1: port@1 {
+					reg = <0x1>;
+					phy-handle = <&phy_port0>;
+					phy-mode = "internal";
+				};
+
+				switch_port2: port@2 {
+					reg = <0x2>;
+					phy-handle = <&phy_port1>;
+					phy-mode = "internal";
+				};
+
+				switch_port3: port@3 {
+					reg = <0x3>;
+					phy-handle = <&phy_port2>;
+					phy-mode = "internal";
+				};
+
+				switch_port4: port@4 {
+					reg = <0x4>;
+					phy-handle = <&phy_port3>;
+					phy-mode = "internal";
+				};
+			};
+
+			mdio {
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				interrupt-parent = <&switch10>;
+
+				phy_port0: phy@0 {
+					reg = <0x0>;
+					interrupts = <0>;
+				};
+
+				phy_port1: phy@1 {
+					reg = <0x1>;
+					interrupts = <0>;
+				};
+
+				phy_port2: phy@2 {
+					reg = <0x2>;
+					interrupts = <0>;
+				};
+
+				phy_port3: phy@3 {
+					reg = <0x3>;
+					interrupts = <0>;
+				};
+
+				phy_port4: phy@4 {
+					reg = <0x4>;
+					interrupts = <0>;
+				};
+			};
+		};
+	};
+};