IPQ5018: Potential future support for Linksys MX2000 Atlas 6 & MX5500 Atlas 6 Pro

Ive got a number of DataGEM D50-5G devices which run QSDK out of the box, so trying to move them to OpenWRT.

1 Like

Hi, I just got a Community Fiber router mx5501/mx5500/ax5400/SPNMX55 (can't get worse with naming) router, is https://github.com/georgemoussalem/openwrt where all the magic happens ? Any prebuild images and guides ? Thanks to all involved, great community as always!

that's all WIP and the images aren't ready

1 Like

I'm still fighting with the switch. From what I can tell, I can't take the switch out of reset.
On stock FW:

~ # cat /sys/kernel/debug/gpio | grep 39
 gpio39  : out 0 8mA pull down

On OpenWRT:

gpio39  : out high func0 2mA pull up

SSDK uses a GPIO to reset the PHYs and the switch using the 'phy-reset-gpio' property under the mdio node and the reset_gpio property under the ess-switch node in the stock DTS.

I've tried setting the reset-gpios property under the mdio node and under the qca8k switch node (under either one or under both), but it still doesn't deassert.

This is the diagram (courtesy of @hzyitc's patch):

 * =======================================================================
 *       _________________________________
 *       |  _______   IPQ50xx   ______    | P0             ______
 *       | | GMAC0 |___________| GPHY |---|------UTP------| RJ45 |
 *       | |_______|           |______|   |               |______|
 *       |  _______           _________   |               _________
 *       | | GMAC1 |_________| UNIPHY0 |  | P1           |   GPHY  |
 *       | |_______|         |_________|--|----SGMII(+)--| /Switch |
 *       |________________________________|              |_________|
 *
 * =======================================================================

Both the MX2000 and MX5500 don't actually use the GEPHY and only use GMAC1/UNIPHY0 to connect to a secondary QCA8337 switch, and it's that switch I'm struggling with.

This is the mdio1 node in my DTS:

&mdio1 {
	status = "okay";

	pinctrl-0 = <&mdio1_pins>;
	pinctrl-names = "default";
	/*reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;*/

	// QCA8337 Phy0 -> IPQ5018 GE Phy (NOT CONNECTED)
	/*qca8337_0: ethernet-phy@0 {
		reg = <0>;
	};*/

	// QCA8337 Phy1 -> WAN
	qca8337_1: ethernet-phy@1 {
		reg = <1>;
	};

	// QCA8337 Phy2 -> LAN1
	qca8337_2: ethernet-phy@2 {
		reg = <2>;
	};

	// QCA8337 Phy3 -> LAN2
	qca8337_3: ethernet-phy@3 {
		reg = <3>;
	};

	// QCA8337 Phy4 -> LAN3
	qca8337_4: ethernet-phy@4 {
		reg = <4>;
	};

	// QCA8337 switch
	switch1: ethernet-switch@17 {
		compatible = "qca,qca8337";
		reg = <17>;
		#address-cells = <1>;
		#size-cells = <0>;

		reset-gpios = <&tlmm 39 GPIO_ACTIVE_LOW>;

		ports {
			#address-cells = <1>;
			#size-cells = <0>;

			/*port@1 {
				reg = <1>;
				label = "cpu0";
				phy-handle = <&qca8337_0>;
			};*/

			port@2 {
				reg = <2>;
				label = "wan";
				phy-handle = <&qca8337_1>;
			};

			port@3 {
				reg = <3>;
				label = "lan1";
				phy-handle = <&qca8337_2>;
			};

			port@4 {
				reg = <4>;
				label = "lan2";
				phy-handle = <&qca8337_3>;
			};

			port@5 {
				reg = <5>;
				label = "lan3";
				phy-handle = <&qca8337_4>;
			};

			port@6 {
				reg = <6>;
				label = "cpu";
				phy-mode = "sgmii";
				ethernet = <&gmac1>;

				fixed-link {
					speed = <1000>;
					full-duplex;
				};
			};
		};
	};
};

The full DTS and DTSI can be found here:
ipq5018.dtsi
ipq5018-mx2000.dts
stock-dts

@robimarko, @lytr, @hzyitc, or anyone else, have you got any ideas?

Add a print to see if kernel acquires the reset GPIO because qca8k itself is directly acquiring the reset GPIO since its set under its node and should dessert it:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/net/dsa/qca/qca8k-8xxx.c?h=next-20240328#n2052

yeah, tried that. It's interesting it's printing it twice:

	if (priv->reset_gpio) {
		/* The active low duration must be greater than 10 ms
		 * and checkpatch.pl wants 20 ms.
		 */
		msleep(20);
		dev_info(priv->dev, "setting gpio39 to 0\n");    //added this line
		gpiod_set_value_cansleep(priv->reset_gpio, 0);
	}
root@OpenWrt:/# dmesg | grep qca8k
[    2.337376] qca8k 90000.mdio-1:11: setting gpio39 to 0
[    3.347364] qca8k 90000.mdio-1:11: setting gpio39 to 0
[    3.414971] qca8k 90000.mdio-1:11: configuring for fixed/sgmii link mode
[    3.417548] qca8k 90000.mdio-1:11: Link is Up - 1Gbps/Full - flow control off
[    3.497712] qca8k 90000.mdio-1:11 wan (uninitialized): PHY [90000.mdio-1:01] driver [Qualcomm Atheros 8337 internal PHY] (irq=POLL)
[    3.497790] qca8k 90000.mdio-1:11: nonfatal error -22 setting MTU to 1500 on port 2
[    3.587733] qca8k 90000.mdio-1:11 lan1 (uninitialized): PHY [90000.mdio-1:02] driver [Qualcomm Atheros 8337 internal PHY] (irq=POLL)
[    3.587815] qca8k 90000.mdio-1:11: nonfatal error -22 setting MTU to 1500 on port 3
[    3.657864] qca8k 90000.mdio-1:11 lan2 (uninitialized): PHY [90000.mdio-1:03] driver [Qualcomm Atheros 8337 internal PHY] (irq=POLL)
[    3.657943] qca8k 90000.mdio-1:11: nonfatal error -22 setting MTU to 1500 on port 4
[    3.727714] qca8k 90000.mdio-1:11 lan3 (uninitialized): PHY [90000.mdio-1:04] driver [Qualcomm Atheros 8337 internal PHY] (irq=POLL)
[    3.727792] qca8k 90000.mdio-1:11: nonfatal error -22 setting MTU to 1500 on port 5
[    8.281994] qca8k 90000.mdio-1:11 lan1: configuring for phy/gmii link mode
[   21.739559] qca8k 90000.mdio-1:11 lan1: configuring for phy/gmii link mode
[   21.863634] qca8k 90000.mdio-1:11 lan2: configuring for phy/gmii link mode
[   21.904358] qca8k 90000.mdio-1:11 lan3: configuring for phy/gmii link mode
[   21.977531] qca8k 90000.mdio-1:11 wan: configuring for phy/gmii link mode
[   25.049686] qca8k 90000.mdio-1:11 lan3: Link is Up - 1Gbps/Full - flow control rx/tx
[   43.769808] qca8k 90000.mdio-1:11 lan3: Link is Down
[   45.849694] qca8k 90000.mdio-1:11 lan3: Link is Up - 1Gbps/Full - flow control rx/tx
[   67.689763] qca8k 90000.mdio-1:11 lan3: Link is Down
[   70.809646] qca8k 90000.mdio-1:11 lan3: Link is Up - 1Gbps/Full - flow control rx/tx
[   92.649778] qca8k 90000.mdio-1:11 lan3: Link is Down
[   94.729666] qca8k 90000.mdio-1:11 lan3: Link is Up - 1Gbps/Full - flow control rx/tx

So, I dont follow whats the issue since even your previous post clearly shows that GPIO39 is deasserted as its output HIGH and switch is clearly alive

well, I'm trying to figure out why there's no traffic between the internal switch and the qca8k switch so I started comparing things. One observation was that the reset gpio is in a low state in stock vs high in this openwrt build, or am I misinterpreting the output? (thought 0=low in stock and openwrt reports it being high).

what else would you recommend me to investigate?

while the cable in lan3 is plugged in, you can see the link is going down and back up in intervals.

the RX bytes counter also remains at 0:

lan3      Link encap:Ethernet  HWaddr D8:EC:5E:FE:A1:31
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:2528 (2.4 KiB)

If you are sure that this GPIO resets the switch then it should be HIGH to dessert the reset as QCA8337 uses an active low reset.

As for debugging, no idea really as it literally could be anything

1 Like

So, finally got the switch working when loading from uboot.
It was a property (qca,sgmii-enable-pll) missing on the cpu port (port 6) to enable SGMII and related settings after I checked the stock initvals of the qca8337 switch in the documentation.

Will continue later to find out why it’s not working when loading the image from nand…

1 Like

Working on v2 and qca8081 (test for SGMII/SGMII+ auto-switch) for a long time, make me forge how to configure qca8337. lol. Give me some time to find out it.

1 Like

A small patch is necessary for v1

From 528d65f342487d3a335d3e4b1accfceb071db914 Mon Sep 17 00:00:00 2001
From: hzyitc <hzyitc@outlook.com>
Date: Fri, 5 Apr 2024 00:59:12 +0800
Subject: [PATCH 1/1] net: dsa: qca8k: always enable SGMII auto-negotiation

---
 drivers/net/dsa/qca/qca8k-8xxx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
index de1dc22cf683..89932d78ca05 100644
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
@@ -1526,6 +1526,7 @@ static int qca8k_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	/* Enable/disable SerDes auto-negotiation as necessary */
 	val = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ?
 		0 : QCA8K_PWS_SERDES_AEN_DIS;
+	val = 0;
 
 	ret = qca8k_rmw(priv, QCA8K_REG_PWS, QCA8K_PWS_SERDES_AEN_DIS, val);
 	if (ret)
-- 
2.40.1


And FYI, here is the dts I used

&uniphy0 {
        mode = <QCOM_ETH_UNIPHY_MODE_SGMII>;

	clkout-frequency = <QCOM_ETH_UNIPHY_CLKOUT_FREQ_25M>;
	clkout-drive-strength = <QCOM_ETH_UNIPHY_CLKOUT_DS_1_5V>;

	status = "ok";
};

&gmac0 {
	status = "ok";
};

&gmac1 {
	status = "ok";

	//phy-handle = <&switch0cpu>;
	phy-mode = "sgmii";

	// managed = "in-band-status";
	fixed-link {
		speed = <1000>;
		full-duplex;
	};
};

&mdio0 {
	status = "ok";
};

&mdio1 {
	pinctrl-0 = <&mdio1_pins>;
	pinctrl-names = "default";
	status = "ok";

	// QCA8337 Phy0 -> LAN1
	qca8337_0: ethernet-phy@0 {
		reg = <0>;
	};

	// QCA8337 Phy1 -> LAN2
	qca8337_1: ethernet-phy@1 {
		reg = <1>;
	};

	// QCA8337 Phy2 -> LAN3
	qca8337_2: ethernet-phy@2 {
		reg = <2>;
	};

	// QCA8337 Phy3 -> WAN
	qca8337_3: ethernet-phy@3 {
		reg = <3>;
	};

	// QCA8337 Phy4 -> IPQ5018 GE Phy
	qca8337_4: ethernet-phy@4 {
		reg = <4>;
	};

	// QCA8337 switch
	switch0: ethernet-switch@17 {
		compatible = "qca,qca8337";
		#address-cells = <1>;
		#size-cells = <0>;

		reset-gpios = <&tlmm 26 GPIO_ACTIVE_LOW>;

		reg = <17>;

		ports {
			#address-cells = <1>;
			#size-cells = <0>;

			switch0cpu: port@0 {
				reg = <0>;
				label = "cpu";
				phy-mode = "sgmii";
				ethernet = <&gmac1>;
				qca,sgmii-enable-pll;

				fixed-link {
					speed = <1000>;
					full-duplex;
				};
			};

			port@1 {
				reg = <1>;
				label = "lan1";
				phy-handle = <&qca8337_0>;
			};

			port@2 {
				reg = <2>;
				label = "lan2";
				phy-handle = <&qca8337_1>;
			};

			port@3 {
				reg = <3>;
				label = "lan3";
				phy-handle = <&qca8337_2>;
			};

			port@4 {
				reg = <4>;
				label = "wan";
				phy-handle = <&qca8337_3>;
			};

			port@5 {
				reg = <5>;
				label = "cpu2";
				phy-handle = <&qca8337_4>;
			};
		};
	};
};

Thank you @hzyitc, will test that small patch tomorrow.

I’ve got the same DTS except for port6 being configured as the cpu port on the switch and the reset-gpios property is defined at the mdio level, else the phys can’t be scanned.
Will circle back tomorrow :+1:

so, just tested the suggested patch and the results are confusing.
The patch enables Serdev auto-negotiation when BIT(7) of the PWS reg is set to 0 (disabled when set to 1)

When the patch is applied and auto-neg is enabled:

  • boot from uboot (initramfs image): there's no traffic
  • boot from nand (factory image): there's traffic and the switch works correctly

When the patch is not applied and auto-neg is disabled, the results are opposite:

  • boot from uboot (initramfs image): there's traffic and the switch works correctly
  • boot from nand (factory image): there's no traffic

any thoughts?

The reset GPIO of switch maybe incorrect. So when booting from uboot, some settings may be inherited from uboot.

These are very interesting updates. As someone with an abundance of MX5500 nodes, I'm eagerly awaiting a build. Happy to help with testing and validation. I'm a network and security guy by trade, so I should be able to meaningfully test anything you want me to.

I'm having issues with wifi, the MX5500 has a QCN9074 (9024 actually) radio.
Ath11k loads correctly, finds the regdb.bin (extracted from the qca repo on codelinaro). I've used the same bdwlan file that the stock FW uses (bdwlan.ba0), but get the following error:

[   21.900849] ath11k_pci 0001:01:00.0: No reg rules available
[   21.904037] ath11k_pci 0001:01:00.0: failed to extract regulatory info from received event

I then tried the same file from different regions such as FCC and EU and also the .bin instead of .ba0 files. With some BDFs, luci suggests it's using a 6Ghz channel while the radio doesn't support that, and with others it shows the correct 5Ghz channel, but only when specific countries are selected (for ex. US when using the FCC BDF file). In that case, one may think it works, but none of my devices can actually detect the SSID or can connect to it.

@lytr: I know you have looked into this as well, perhaps you can give me some pointers?
Anyone else?

You probably have this problem: OpenWrt support for Linksys MX8500 - #47 by lytr

you're right, the stock FW version is 2.4 (WLAN.HK.2.4-02142-QCAHKSWPL_SILICONZ-1.395212.1.407947.2 v1)
I've downloaded the board-2.bin v2.4 from the qca repo here but it contains no regdb info. Is there any way to convert the regdb found in v2.9 and make it work for v.2.4?

qca swiss army-knife maybe ? https://github.com/qca/qca-swiss-army-knife