[openwrt/openwrt] ipq806x: fix Linksys EAX500 family devices dead Ethernet switch

LEDE Commits lede-commits at lists.infradead.org
Fri Feb 17 09:12:50 PST 2023


ansuel pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/9a24040d20356482b4a481bbd62b287a9eb338f2

commit 9a24040d20356482b4a481bbd62b287a9eb338f2
Author: Christian Marangi <ansuelsmth at gmail.com>
AuthorDate: Fri Feb 17 03:43:29 2023 +0100

    ipq806x: fix Linksys EAX500 family devices dead Ethernet switch
    
    With 5.15 kernel version Linksys EAX500 family devices suffered from a
    big regression where the Ethernet switch became silent and started to
    malfunction.
    
    It was discovered later that the cause was not really the kernel upgrade
    itself but a hackish implementation of the hw implementation of these
    special routers.
    
    In the original Linksys source code, GPIO 63 was handled in a special way
    and was reset on reboot.
    
    Normally GPIO 63 is used for pcie2 reset but in every device we support,
    pcie2 is actually never used as nothing is attached to it.
    
    Linksys rerouted GPIO 63 to the switch reset pin and deviates from
    common hw implementation.
    
    Till now it was used an hack to handle this case... It was set pcie3 as
    working (while actually nothing was connected), set it to output low
    (for assert-deassert from the pcie init code) and be done with it.
    The result was that the GPIO was reset for enough time in early boot and
    everything worked correctly.
    This hack implementation was born to fail from the very start and in
    kernel 5.15 finally problem arised.
    
    In 5.15 pcie code changed and now the GPIO reset pin is not asserted as
    probe won't fail if nothing is connected to the line (the old behaviour)
    This result in the switch hold the reset pin and the Ethernet switch
    dead.
    
    On top of that with 5.15 code got optimized and simply attaching the
    GPIO reset to the mdio wasn't enough as the switch require at least 10ms
    to be correctly reset.
    
    So implement finally a correct solution where:
    - pcie2 is correctly disabled (nothing attached, unused)
    - drop the wrong output-low for pcie2 reset pin
    - define GPIO 63 as switch reset
    - Add the reset-gpios to the mdio0 node
    - Set the reset-post-delay-us to 12ms to correctly give time the switch
      to reset
    
    Fixes: #10983
    Signed-off-by: Christian Marangi <ansuelsmth at gmail.com>
---
 .../arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi       | 20 ++++++++++++++++----
 .../arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi       | 20 ++++++++++++++++----
 .../patches-5.10/082-ipq8064-dtsi-tweaks.patch       |  8 --------
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/target/linux/ipq806x/files-5.10/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi b/target/linux/ipq806x/files-5.10/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
index e74d2dcdbd..e5282efaab 100644
--- a/target/linux/ipq806x/files-5.10/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
+++ b/target/linux/ipq806x/files-5.10/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
@@ -12,6 +12,18 @@
 	};
 };
 
+&qcom_pinmux {
+	/* eax500 routers reuse the pcie2 reset pin for switch reset pin */
+	switch_reset: switch_reset_pins {
+		mux {
+			pins = "gpio63";
+			function = "gpio";
+			drive-strength = <12>;
+			bias-pull-up;
+		};
+	};
+};
+
 &usb3_0 {
 	status = "okay";
 };
@@ -30,10 +42,6 @@
 	status = "okay";
 };
 
-&pcie2 {
-	status = "okay";
-};
-
 &nand {
 	status = "okay";
 
@@ -160,6 +168,10 @@
 	pinctrl-0 = <&mdio0_pins>;
 	pinctrl-names = "default";
 
+	/* Switch from documentation require at least 10ms for reset */
+	reset-gpios = <&qcom_pinmux 63 GPIO_ACTIVE_HIGH>;
+	reset-post-delay-us = <12000>;
+
 	phy0: ethernet-phy at 0 {
 		reg = <0>;
 		qca,ar8327-initvals = <
diff --git a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
index adf5192ac8..910bd86bc5 100644
--- a/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
+++ b/target/linux/ipq806x/files-5.15/arch/arm/boot/dts/qcom-ipq8064-eax500.dtsi
@@ -12,6 +12,18 @@
 	};
 };
 
+&qcom_pinmux {
+	/* eax500 routers reuse the pcie2 reset pin for switch reset pin */
+	switch_reset: switch_reset_pins {
+		mux {
+			pins = "gpio63";
+			function = "gpio";
+			drive-strength = <12>;
+			bias-pull-up;
+		};
+	};
+};
+
 &hs_phy_0 {
 	status = "okay";
 };
@@ -46,10 +58,6 @@
 	status = "okay";
 };
 
-&pcie2 {
-	status = "okay";
-};
-
 &nand {
 	status = "okay";
 
@@ -173,6 +181,10 @@
 	pinctrl-0 = <&mdio0_pins>;
 	pinctrl-names = "default";
 
+	/* Switch from documentation require at least 10ms for reset */
+	reset-gpios = <&qcom_pinmux 63 GPIO_ACTIVE_HIGH>;
+	reset-post-delay-us = <12000>;
+
 	phy0: ethernet-phy at 0 {
 		reg = <0>;
 		qca,ar8327-initvals = <
diff --git a/target/linux/ipq806x/patches-5.10/082-ipq8064-dtsi-tweaks.patch b/target/linux/ipq806x/patches-5.10/082-ipq8064-dtsi-tweaks.patch
index d6a4593749..301963f4f9 100644
--- a/target/linux/ipq806x/patches-5.10/082-ipq8064-dtsi-tweaks.patch
+++ b/target/linux/ipq806x/patches-5.10/082-ipq8064-dtsi-tweaks.patch
@@ -35,14 +35,6 @@
  			#interrupt-cells = <2>;
  			interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
  
-@@ -155,6 +156,7 @@
- 					function = "pcie3_rst";
- 					drive-strength = <12>;
- 					bias-disable;
-+					output-low;
- 				};
- 			};
- 
 @@ -190,6 +192,7 @@
  		intc: interrupt-controller at 2000000 {
  			compatible = "qcom,msm-qgic2";




More information about the lede-commits mailing list