OpenWrt support for Linksys MX8500

You definitively need to attach it to dp6_syn, but make sure to set the phy-mode = "usxgmii" as well.

Since its using MAC2 then its definitively port 6

root@OpenWrt:~# mdio 
90000.mdio-1
fixed-0
root@OpenWrt:~# mdio 90000.mdio-1
 DEV      PHY-ID  LINK
0x00  0x004dd0b1  down
0x01  0x004dd0b1  down
0x02  0x004dd0b1  down
0x03  0x004dd0b1  down
0x04  0x004dd0b1  down
0x05  0x04820a05  down
root@OpenWrt:~# mdio fixed-0
 DEV      PHY-ID  LINK

Mode is set correctly. Not sure about this:

	qcom,mactype = <1>;

Maybe firmware is not correctly read:

		partitions {
			compatible = "qcom,smem-part";

			partition-0-ethphyfw {
				compatible = "fixed-partitions";
				label = "0:ethphyfw";
				read-only;
				#address-cells = <1>;
				#size-cells = <1>;

				nvmem-layout {
					compatible = "fixed-layout";
					#address-cells = <1>;
					#size-cells = <1>;

					aqr_fw: firmware@0 {
						/* Skip the QCOM MBN Header of 40 bytes */
						reg = <0x28 0x5f82a>;
					};
				};
			};
		};

And in the logs:

[    1.294129] mdio_bus 90000.mdio-1: MDIO device at address 8 is missing.

Most likely bootloader leaves it in reset.

Check GPIO44 for the value and try toggling it and then look with MDIO

By default loading AQR firmware from u-boot is disabled. They use this scripts:

loadAQflag=`fw_printenv -n bootcmd |grep aq_load_fw` 
if [ -n "$loadAQflag" ] ; then
        echo "remove loading AQR fw in uboot..."
        newcmd=`echo $loadAQflag | sed 's/aq_load_fw && //g' `
        fw_setenv bootcmd "$newcmd"
fi

#load AQR PHY FW and monitor it's heartbeat
[ -f /etc/init.d/service_wan/wan_AQR_monitor.sh ] && /etc/init.d/service_wan/wan_AQR_monitor.sh&
#load AQR PHY FW end.

wan_AQR_monitor.sh:

#!/bin/sh
reload_AQR114C_fw()
{
    ssdk_sh debug phy set 0x8 0x401e2680 0x1 2>&1 > /dev/null
    sleep 0.1
    aq-fw-download /etc/AQR_Diablo.cld miireg 8 2>&1 > /dev/null
    sleep 0.5
    ssdk_sh port autoneg restart 5 2>&1 > /dev/null
    ssdk_sh debug phy set 8 0x401ec430 0xc0ef 2>&1 > /dev/null
    ssdk_sh debug phy set 8 0x401ec431 0xc0e0 2>&1 > /dev/null
    ssdk_sh debug phy set 8 0x40070010 0x91e1 2>&1 > /dev/null
    ssdk_sh debug phy set 8 0x40070000 0x3200 2>&1 > /dev/null
    ssdk_sh debug phy set 8 0x4004c441 0x8 2>&1 > /dev/null
}
if [ ! -f /usr/sbin/aq-fw-download ] || [ ! -f /etc/AQR_Diablo.cld ]; then
    return
fi
first_init=1
pre_status=0
while true; do
    if [ $first_init -eq 1 ]; then
        echo "[utopia][init] Load aquantia phy fw"
        reload_AQR114C_fw
        first_init=0
        echo "[utopia][init] Load aquantia phy fw done"
    else
        cur_status=$(ssdk_sh debug phy get 0x8 0x401ec886 | grep Data | awk -F':' '{print $2}')
        if [ "$pre_status" = "$cur_status" ]; then
            echo "[utopia] Reload aquantia phy fw"
            reload_AQR114C_fw
            pre_status=
            echo "[utopia] Reload aquantia phy fw done"
        else
            pre_status=$cur_status
        fi
    fi
    sleep 3
done

After loading firmware in u-boot before boot things are better. QCA8075 ports are working. AQR port detects the cable connection but does not work:

[  367.755421] nss-dp 3a007000.dp6-syn wan: PHY Link up speed: 100
[  368.576056] uniphy autoneg time out!

Firmware from 0:ethphyfw partition is different than AQR_Diablo.cld (AQR-G4_v5.6.5-AQR_WNC_SAQA-L2_GT_ID45287_VER24005.cld) from OEM firmware.

1 Like

Look, just start by getting the AQR out of reset in the kernel, GPIO44 should be its reset gpio.
Then its rather easy to get the kernel to load the FW, and the autoneg timeout is most likely due to USXGMII autoneg bit not being set (As its off by default) but SSDK will set that bit by default once PHY is visible

After set up gpio44 I can see this PHY:

 DEV      PHY-ID  LINK
0x00  0x004dd0b1  down
0x01  0x004dd0b1  down
0x02  0x004dd0b1  down
0x03  0x004dd0b1  down
0x04  0x004dd0b1  down
0x05  0x04820a05  down
0x08  0x00000000  down

How to load the firmware?

Error is still displayed:

[  402.646792] hsl_phy_phydev_get[805]:ERROR:phy_addr 8 phydev is NULL
[  403.686789] hsl_phy_phydev_get[805]:ERROR:phy_addr 8 phydev is NULL

That error is irrelevant.

For testing you can define the firmware name and the simply include it in the rootfs, look at qnap 301w DTS for the exact property.

I added gpio setting at startup:

	aqr_pins: aqr-state {
		pins = "gpio44";
		function = "gpio";
		bias-pull-up;
		output-high;
	};

and now I get this error:

[    2.599443] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x31c31c22 phytype doesn't match

Looks like the phy_id is unknown for SSDK.
What aquantia chip is this exactly?

I've made a patch:

--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -31,6 +31,7 @@
 #define PHY_ID_AQR412	0x03a1b712
 #define PHY_ID_AQR112C	0x03a1b790
 #define PHY_ID_AQR112R	0x31c31d12
+#define PHY_ID_AQR114C	0x31c31c22
 
 #define MDIO_PHYXS_VEND_IF_STATUS		0xe812
 #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK	GENMASK(7, 3)
@@ -986,6 +987,25 @@
 	.get_strings	= aqr107_get_strings,
 	.get_stats	= aqr107_get_stats,
 },
+{
+	PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
+	.name		= "Aquantia AQR114C",
+	.probe		= aqr107_probe,
+	.get_rate_matching	= aqr107_get_rate_matching,
+	.config_init	= aqr107_config_init,
+	.config_aneg	= aqr_config_aneg,
+	.config_intr	= aqr_config_intr,
+	.handle_interrupt = aqr_handle_interrupt,
+	.read_status	= aqr107_read_status,
+	.get_tunable	= aqr107_get_tunable,
+	.set_tunable	= aqr107_set_tunable,
+	.suspend	= aqr107_suspend,
+	.resume		= aqr107_resume,
+	.get_sset_count	= aqr107_get_sset_count,
+	.get_strings	= aqr107_get_strings,
+	.get_stats	= aqr107_get_stats,
+	.link_change_notify	= aqr107_link_change_notify,
+},
 };
 
 module_phy_driver(aqr_driver);
@@ -1007,6 +1027,7 @@
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112C) },
 	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112R) },
+	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
 	{ }
 };

AQR firmware should be placed in /lib/firmware directory?

You should just add it as reset gpio under the phy node itself, not via pinctrl.

And probably SSDK and the kernel lack the ID for this PHY

So how do I set gpio44 at startup?
By default it is low:

 gpio44  : out low  func0 2mA pull up

I tried these configurations:

&mdio {
	status = "okay";

	pinctrl-0 = <&mdio_pins>;
	pinctrl-names = "default";
	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;

	ethernet-phy-package@0 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "qcom,qca8075-package";
		reg = <0>;

		qcom,package-mode = "qsgmii";

		qca8075_0: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
		};

		qca8075_1: ethernet-phy@1 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <1>;
		};

		qca8075_2: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <2>;
		};

		qca8075_3: ethernet-phy@3 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <3>;
		};
	};

	aqr114c: ethernet-phy@8 {
		compatible ="ethernet-phy-ieee802.3-c45";
		reg = <8>;
		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
		firmware-name = "marvell/AQR-G4_v5.6.5-AQR_WNC_SAQA-L2_GT_ID45287_VER24005.cld";
		nvmem-cells = <&aqr_fw>;
		nvmem-cell-names = "firmware";
	};
};
&mdio {
	status = "okay";

	pinctrl-0 = <&mdio_pins>;
	pinctrl-names = "default";
	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>, /* QCA8075 RESET */
		<&tlmm 44 GPIO_ACTIVE_LOW>; /* AQR114C RESET */

	ethernet-phy-package@0 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "qcom,qca8075-package";
		reg = <0>;

		qcom,package-mode = "qsgmii";

		qca8075_0: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
		};

		qca8075_1: ethernet-phy@1 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <1>;
		};

		qca8075_2: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <2>;
		};

		qca8075_3: ethernet-phy@3 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <3>;
		};
	};

	aqr114c: ethernet-phy@8 {
		compatible ="ethernet-phy-ieee802.3-c45";
		reg = <8>;
		firmware-name = "marvell/AQR-G4_v5.6.5-AQR_WNC_SAQA-L2_GT_ID45287_VER24005.cld";
		nvmem-cells = <&aqr_fw>;
		nvmem-cell-names = "firmware";
	};
};

But every time I have:

[    2.469485] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0xffffffff phytype doesn't match
[    3.788489] nss-dp 3a007000.dp6-syn wan (uninitialized): failed to connect to phy device
[    3.794206] nss-dp: probe of 3a007000.dp6-syn failed with error -14

Try adding a deassert-delay, and you need the first configuration example

The same after add:

reset-deassert-us = <10000>;

Is the MAC_MODE_USXGMII correct for 5GBASE-T chip?

USXGMII is correct, that is the link between PHY and MAC so it doesnt matter that its 5GBase-T.

Can you check whether that GPIO was toggled to high via /sys/kernel/debug/gpio

Still low:

root@OpenWrt:/# cat /sys/kernel/debug/gpio | grep gpio44
 gpio44  : out low  func0 2mA pull up

PHY is available after manually toggle gpio:

root@OpenWrt:~# echo "486" > /sys/class/gpio/export
root@OpenWrt:~# echo "1" > /sys/class/gpio/gpio486/value 
root@OpenWrt:~# cat /sys/kernel/debug/gpio | grep gpio44
 gpio44  : out high func0 2mA pull up
root@OpenWrt:~# mdio 9*
 DEV      PHY-ID  LINK
0x00  0x004dd0b1  down
0x01  0x004dd0b1  down
0x02  0x004dd0b1  down
0x03  0x004dd0b1  down
0x04  0x004dd0b1  down
0x05  0x04820a05  down
0x08  0x00000000  down

From OEM dts:

		mdio@90000 {
			#address-cells = <0x01>;
			#size-cells = <0x01>;
			compatible = "qcom,ipq40xx-mdio";
			linux,phandle = <0x5e>;
			phandle = <0x5e>;
			phy-reset-gpio = <0x1f 0x25 0x00 0x1f 0x2c 0x01>;
			pinctrl-0 = <0x1e>;
			pinctrl-names = "default";
			reg = <0x90000 0x64>;

			ethernet-phy@0 {
				reg = <0x00>;
			};

			ethernet-phy@1 {
				reg = <0x01>;
			};

			ethernet-phy@2 {
				reg = <0x02>;
			};

			ethernet-phy@3 {
				reg = <0x03>;
			};

			ethernet-phy@4 {
				reg = <0x04>;
			};

			ethernet-phy@5 {
				compatible = "ethernet-phy-ieee802.3-c45";
				reg = <0x08>;
			};
		};

Can you post the whole WIP DTS?

DTS:

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT

/dts-v1/;

#include "ipq8074.dtsi"
#include "ipq8074-hk-cpu.dtsi"
#include "ipq8074-ess.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/leds/common.h>

/ {
	model = "Linksys MX8500";
	compatible = "linksys,mx8500", "qcom,ipq8074";

	aliases {
		serial0 = &blsp1_uart5;
		serial1 = &blsp1_uart6;
		led-boot = &led_system_blue;
		led-running = &led_system_blue;
		led-failsafe = &led_system_red;
		led-upgrade = &led_system_green;
	};

	chosen {
		stdout-path = "serial0:115200n8";
		bootargs-append = " root=/dev/ubiblock0_0 rootfstype=squashfs ro";
	};

	keys {
		compatible = "gpio-keys";
		pinctrl-0 = <&button_pins>;
		pinctrl-names = "default";

		reset-button {
			label = "reset";
			gpios = <&tlmm 67 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};

		wps-button {
			label = "wps";
			gpios = <&tlmm 64 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_WPS_BUTTON>;
		};
	};

	gpio_export {
		compatible = "gpio-export";
		#size-cells = <0>;

		bt_pwr {
			gpio-export,name = "bt_pwr";
			gpio-export,output = <1>;
			gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>;
		};
	};
};

&tlmm {
	button_pins: button-state {
		pins = "gpio64", "gpio67";
		function = "gpio";
		drive-strength = <8>;
		bias-pull-up;
	};

	mdio_pins: mdio-state {
		mdc-pins {
			pins = "gpio68";
			function = "mdc";
			drive-strength = <8>;
			bias-pull-up;
		};

		mdio-pins {
			pins = "gpio69";
			function = "mdio";
			drive-strength = <8>;
			bias-pull-up;
		};
	};

	qpic_pins_new: qpic-pins {
		pins = "gpio1", "gpio3", "gpio4",
			"gpio5", "gpio6", "gpio7",
			"gpio8", "gpio10", "gpio11",
			"gpio12", "gpio13", "gpio14",
			"gpio15", "gpio17";
		function = "qpic";
		drive-strength = <8>;
		bias-disable;
	};
};

&blsp1_uart5 {
	status = "okay";
};

&blsp1_uart6 {
	status = "okay";
};

&prng {
	status = "okay";
};

&cryptobam {
	status = "okay";
};

&crypto {
	status = "okay";
};

&qpic_bam {
	status = "okay";
};

&qpic_nand {
	status = "okay";

	pinctrl-0 = <&qpic_pins_new>;

	nand@0 {
		reg = <0>;

		nand-ecc-strength = <4>;
		nand-ecc-step-size = <512>;
		nand-bus-width = <8>;

		partitions {
			compatible = "qcom,smem-part";

			partition-0-ethphyfw {
				compatible = "fixed-partitions";
				label = "0:ethphyfw";
				read-only;
				#address-cells = <1>;
				#size-cells = <1>;

				nvmem-layout {
					compatible = "fixed-layout";
					#address-cells = <1>;
					#size-cells = <1>;

					aqr_fw: firmware@0 {
						/* Skip the QCOM MBN Header of 40 bytes */
						reg = <0x28 0x5f82a>;
					};
				};
			};
		};
	};
};

&blsp1_i2c2 {
	status = "okay";

	led-controller@62 {
		compatible = "nxp,pca9633";
		#address-cells = <1>;
		#size-cells = <0>;
		reg = <0x62>;
		nxp,hw-blink;

		led_system_red: led@0 {
			reg = <0>;
			color = <LED_COLOR_ID_RED>;
			function = LED_FUNCTION_STATUS;
		};

		led_system_green: led@1 {
			reg = <1>;
			color = <LED_COLOR_ID_GREEN>;
			function = LED_FUNCTION_STATUS;
		};

		led_system_blue: led@2 {
			reg = <2>;
			color = <LED_COLOR_ID_BLUE>;
			function = LED_FUNCTION_STATUS;
		};
	};
};

&mdio {
	status = "okay";

	pinctrl-0 = <&mdio_pins>;
	pinctrl-names = "default";
	reset-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>;

	ethernet-phy-package@0 {
		#address-cells = <1>;
		#size-cells = <0>;
		compatible = "qcom,qca8075-package";
		reg = <0>;

		qcom,package-mode = "qsgmii";

		qca8075_0: ethernet-phy@0 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <0>;
		};

		qca8075_1: ethernet-phy@1 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <1>;
		};

		qca8075_2: ethernet-phy@2 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <2>;
		};

		qca8075_3: ethernet-phy@3 {
			compatible = "ethernet-phy-ieee802.3-c22";
			reg = <3>;
		};
	};

	aqr114c: ethernet-phy@8 {
		compatible ="ethernet-phy-ieee802.3-c45";
		reg = <8>;
		reset-gpios = <&tlmm 44 GPIO_ACTIVE_LOW>;
		firmware-name = "marvell/AQR-G4_v5.6.5-AQR_WNC_SAQA-L2_GT_ID45287_VER24005.cld";
		nvmem-cells = <&aqr_fw>;
		nvmem-cell-names = "firmware";
	};
};

&switch {
	status = "okay";

	switch_lan_bmp = <(ESS_PORT1 | ESS_PORT2 | ESS_PORT3 | ESS_PORT4)>; /* lan port bitmap */
	switch_wan_bmp = <ESS_PORT6>; /* wan port bitmap */
	switch_mac_mode = <MAC_MODE_QSGMII>; /* mac mode for uniphy instance0*/
	switch_mac_mode2 = <MAC_MODE_USXGMII>; /* mac mode for uniphy instance2*/

	qcom,port_phyinfo {
		port@1 {
			port_id = <1>;
			phy_address = <0>;
		};
		port@2 {
			port_id = <2>;
			phy_address = <1>;
		};
		port@3 {
			port_id = <3>;
			phy_address = <2>;
		};
		port@4 {
			port_id = <4>;
			phy_address = <3>;
		};
		port@6 {
			port_id = <6>;
			phy_address = <8>;
			compatible = "ethernet-phy-ieee802.3-c45";
			ethernet-phy-ieee802.3-c45;
		};
	};
};

&edma {
	status = "okay";
};

&dp1 {
	status = "okay";
	phy-mode = "qsgmii";
	phy-handle = <&qca8075_0>;
	label = "lan1";
};

&dp2 {
	status = "okay";
	phy-mode = "qsgmii";
	phy-handle = <&qca8075_1>;
	label = "lan2";
};

&dp3 {
	status = "okay";
	phy-mode = "qsgmii";
	phy-handle = <&qca8075_2>;
	label = "lan3";
};

&dp4 {
	status = "okay";
	phy-mode = "qsgmii";
	phy-handle = <&qca8075_3>;
	label = "lan4";
};

&dp6_syn {
	status = "okay";
	qcom,mactype = <1>;
	phy-mode = "usxgmii";
	phy-handle = <&aqr114c>;
	label = "wan";
};

&ssphy_0 {
	status = "okay";
};

&qusb_phy_0 {
	status = "okay";
};

&usb_0 {
	status = "okay";
};

&pcie_qmp0 {
	status = "okay";
};

&pcie0 {
	status = "okay";

	perst-gpio = <&tlmm 61 GPIO_ACTIVE_LOW>;

	bridge@0,0 {
		reg = <0x00000000 0 0 0 0>;
		#address-cells = <3>;
		#size-cells = <2>;
		ranges;

		wifi@1,0 {
			status = "okay";

			/* ath11k has no DT compatible for PCI cards */
			compatible = "pci17cb,1104";
			reg = <0x00010000 0 0 0 0>;

			qcom,ath11k-calibration-variant = "Linksys-MX8500";
		};
	};
};

&wifi {
	status = "okay";

	qcom,ath11k-calibration-variant = "Linksys-MX8500";
};

There is also this message at the beginning:

[    0.022111] OF: /soc/mdio@90000/ethernet-phy@8: could not find phandle 13

For now I was only able to set gpio44 high using pinctrl:

[    0.022200] OF: /soc/mdio@90000/ethernet-phy@8: could not find phandle 14
[    2.483378] OF: /soc/mdio@90000/ethernet-phy@8: could not find phandle 14
[    2.488659] Aquantia AQR114C 90000.mdio-1:08: loading firmware version 'v9.9.5 WNC SAQA-L2 082721 12:00:46' from 'FS'
[   13.930017] ssdk_phy_driver_init[371]:INFO:dev_id = 0, phy_adress = 8, phy_id = 0x31c31c22 phytype doesn't match

[  190.808205] nss-dp 3a007000.dp6-syn wan: PHY Link up speed: 1000
[  190.808285] IPv6: ADDRCONF(NETDEV_CHANGE): wan: link becomes ready
[  191.708447] uniphy autoneg time out!
[  201.207880] nss-dp 3a007000.dp6-syn wan: PHY Link is down

How to add new phy_id to the SSDK?

Could the problem with QCN9074 be that the regdb size inside the BDF is 7KB (like IPQ8074) and not 10KB like other BDFs for QCN9074?