IPQ806x NSS Drivers

My ‘lede-17.01-ipq806x-nss’ branch has the ‘safe parent’ patches to the gcc clocks drivers. Unfortunately the random reboots still happens unless I force NSS clocks to a fix freq.

I built an image with this patch and turned on NSS scaling.
I will check if there will still be failures.

I'll know in a few minutes...

You're right - it doesn't work.
The router was running for about 10 minutes and it was frozen and restarted.
End of tests. I'm going back to my stable version.

problem is that adding only that patch is useless if the safe_switch is not defined in the gcc driver...
I don't know if you applied that too... anyway I pushed the commit.

Turns out I applied a partial solution and only added a patch. I didn't do anything in the gcc driver.
I will check this solution again later.

I managed to make my wifi connected devices to communicate among each other. Turns out it was not a build config problem but rather a firewall rule that was causing me trouble. I had my "lan forward" firewall rule set to "drop" which worked alright with the regular master build but it did not work with the nss version. I changed it to "accept" and voila...

The router was quite stable (using locked frequency) but I had two other minor puzzling problems. My Netflix app in my Samsung TV was not loading (it was accessing the internet but was not accessing Netflix servers) and my Ring doorbell could not be accessed by my Samsung phone but (strangely) could be accessed by my wife's iPhone. Totally non-sense but I tested twice by changing nss x regular builds and these problems were only present in the nss version. The only thing that comes to mind and that needs my checking is to use regular DNS servers as I'm using dnscrypt-proxy2. Can someone think of something else?

I have a very weird issue related to wireless offload. I can't send tweet on the phone when I enabled MAC80211_NSS_SUPPORT. Disable the config then everything normal.

edit:
It seems wireless offload have some issue deal with route table, if i running VPN that have multiple default gateway then weird thing happened.

edit2:
Enable lan > wan masquerading fixed the issue. It doesn't need it normally.

@Ansuel I've pushed an update for the mac80211 integration here:

It'll make mac80211 NSS virtual interfaces play nice with NSS QDISC shapers when its brought up/down.

Also, I've change the receive flow (i.e. WiFi client uploads) to a queue implementation. I think it'll make uploads from WiFi clients more consistent.

1 Like

Shouldn't this be on by default for OpenWrt? Unless you've configured your router as a router instead of a gateway, NAT should be enabled for LAN<->WAN.

Odd. NSS firmware should mirror all Linux netfilter rules. Did you insert a lot of custom rules?

Turn out the culprit is Forward other than nat.

Hi @Ansuel
I can build your repo with original qcom-ipq8064-ea7500-v1.dts for my ea7500 and it works
but if I add something to gmac1 & gmac2 DTS nodes for qcom-ipq8064-ea7500-v1.dts ,the router can't be connected,just like no dhcp server,evern set static ip on pc

Could you help me solve this,thanks

here are the orginal gmac1 & gmac2 DTS nodes

&gmac1 {
	status = "okay";
	phy-mode = "rgmii";
	qcom,id = <1>;

	pinctrl-0 = <&rgmii2_pins>;
	pinctrl-names = "default";

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

&gmac2 {
	status = "okay";
	phy-mode = "sgmii";
	qcom,id = <2>;

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

and here is modified

&gmac1 {
	status = "okay";
	compatible = "qcom,nss-gmac";
	reg = <0x37200000 0x200000>;
	interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
	phy-mode = "rgmii";
	qcom,id = <1>;
	qcom,forced-speed = <1000>;
	qcom,forced-duplex = <1>;
	qcom,socver = <0>;
	pinctrl-0 = <&rgmii2_pins>;
	pinctrl-names = "default";

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

&gmac2 {
	status = "okay";
	compatible = "qcom,nss-gmac";
	reg = <0x37400000 0x200000>;
	interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
	phy-mode = "sgmii";
	qcom,id = <2>;
	qcom,forced-speed = <1000>;
	qcom,forced-duplex = <1>;
	qcom,socver = <0>;
	fixed-link {
		speed = <1000>;
		full-duplex;
	};
};

what do you mean with original ?
you should try to find what is set in the oem dts

original means it's from offical
because @quarky said "Once you make the build reliable, all you need to do is to change he gmac1 & gmac2 DTS nodes of your EA7500v1 to use the QCA GMAC drivers and the rest will startup automatically, if you select all related NSS drivers."

here is the offical

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq8064-v2.0.dtsi"

#include <dt-bindings/input/input.h>

/ {
	model = "Linksys EA7500 V1 WiFi Router";
	compatible = "linksys,ea7500-v1", "qcom,ipq8064";

	memory@0 {
		reg = <0x42000000 0xe000000>;
		device_type = "memory";
	};

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
		rsvd@41200000 {
			reg = <0x41200000 0x300000>;
			no-map;
		};
	};

	aliases {
		serial0 = &gsbi4_serial;

		led-boot = &led_power;
		led-failsafe = &led_power;
		led-running = &led_power;
		led-upgrade = &led_power;
	};

	chosen {
		bootargs = "console=ttyMSM0,115200n8";
		stdout-path = "serial0:115200n8";
		append-rootblock = "ubi.mtd=";  /* append to bootargs adding the root deviceblock nbr from bootloader */
		find-rootblock = "ubi.mtd=";  /* look for root deviceblock nbr in this bootarg */
	};

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

		reset {
			label = "reset";
			gpios = <&qcom_pinmux 68 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};

		wps {
			label = "wps";
			gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_WPS_BUTTON>;
		};
	};

	leds {
		compatible = "gpio-leds";
		pinctrl-0 = <&led_pins>;
		pinctrl-names = "default";

		led_power: power {
			label = "ea7500-v1:white:power";
			gpios = <&qcom_pinmux 6 GPIO_ACTIVE_LOW>;
			default-state = "keep";
		};
	};
};

&qcom_pinmux {
	button_pins: button_pins {
		mux {
			pins = "gpio65", "gpio68";
			function = "gpio";
			drive-strength = <2>;
			bias-pull-up;
		};
	};

	led_pins: led_pins {
		mux {
			pins = "gpio6";
			function = "gpio";
			drive-strength = <2>;
			bias-pull-up;
		};
	};
};

&gsbi4 {
	qcom,mode = <GSBI_PROT_I2C_UART>;
	status = "okay";
	serial@16340000 {
		status = "okay";
	};
	/*
	* The i2c device on gsbi4 should not be enabled.
	* On ipq806x designs gsbi4 i2c is meant for exclusive
	* RPM usage. Turning this on in kernel manifests as
	* i2c failure for the RPM.
	*/
};

&usb3_0 {
	status = "okay";
};

&usb3_1 {
	status = "okay";
};

&pcie0 {
	status = "okay";
	force_gen1 = <1>;
};

&pcie1 {
	status = "okay";
};

&pcie2 {
	status = "okay";
};

&nand_controller {
	status = "okay";

	pinctrl-0 = <&nand_pins>;
	pinctrl-names = "default";

	nand@0 {
		reg = <0>;
		compatible = "qcom,nandcs";

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

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

			partition@0 {
				label = "SBL1";
				reg = <0x0000000 0x0040000>;
				read-only;
			};

			partition@40000 {
				label = "MIBIB";
				reg = <0x0040000 0x0140000>;
				read-only;
			};

			partition@180000 {
				label = "SBL2";
				reg = <0x0180000 0x0140000>;
				read-only;
			};

			partition@2c0000 {
				label = "SBL3";
				reg = <0x02c0000 0x0280000>;
				read-only;
			};

			partition@540000 {
				label = "DDRCONFIG";
				reg = <0x0540000 0x0120000>;
				read-only;
			};

			partition@660000 {
				label = "SSD";
				reg = <0x0660000 0x0120000>;
				read-only;
			};

			partition@780000 {
				label = "TZ";
				reg = <0x0780000 0x0280000>;
				read-only;
			};

			partition@a00000 {
				label = "RPM";
				reg = <0x0a00000 0x0280000>;
				read-only;
			};

			art: partition@c80000 {
				label = "art";
				reg = <0x0c80000 0x0140000>;
				read-only;
			};

			partition@dc0000 {
				label = "APPSBL";
				reg = <0x0dc0000 0x0100000>;
				read-only;
			};

			partition@ec0000 {
				label = "u_env";
				reg = <0x0ec0000 0x0040000>;
			};

			partition@f00000 {
				label = "s_env";
				reg = <0x0f00000 0x0040000>;
			};

			partition@f40000 {
				label = "devinfo";
				reg = <0x0f40000 0x0040000>;
			};

			partition@f80000 {
				label = "kernel1";
				reg = <0x0f80000 0x2800000>;  /* 3 MB spill to rootfs*/
			};

			partition@1280000 {
				label = "rootfs1";
				reg = <0x1280000 0x2500000>;
			};

			partition@3780000 {
				label = "kernel2";
				reg = <0x3780000 0x2800000>;
			};

			partition@3a80000 {
				label = "rootfs2";
				reg = <0x3a80000 0x2500000>;
			};

			partition@5f80000 {
				label = "sysdiag";
				reg = <0x5f80000 0x100000>;
			};

			partition@6080000 {
				label = "syscfg";
				reg = <0x6080000 0x1f80000>;
			};
		};
	};
};

&mdio0 {
	status = "okay";

	pinctrl-0 = <&mdio0_pins>;
	pinctrl-names = "default";

	phy0: ethernet-phy@0 {
		reg = <0>;
		qca,ar8327-initvals = <
			0x00004 0x7600000   /* PAD0_MODE */
			0x00008 0x1000000   /* PAD5_MODE */
			0x0000c 0x80        /* PAD6_MODE */
			0x00010 0x2613a0    /* PWS_REG */
			0x000e4 0x6a545     /* MAC_POWER_SEL */
			0x000e0 0xc74164de  /* SGMII_CTRL */
			0x0007c 0x4e        /* PORT0_STATUS */
			0x00094 0x4e        /* PORT6_STATUS */
			>;
	};
};

&gmac1 {
	status = "okay";
	phy-mode = "rgmii";
	qcom,id = <1>;

	pinctrl-0 = <&rgmii2_pins>;
	pinctrl-names = "default";

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

&gmac2 {
	status = "okay";
	phy-mode = "sgmii";
	qcom,id = <2>;

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

&adm_dma {
	status = "okay";
};

and here is modified

// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
#include "qcom-ipq8064-v2.0.dtsi"

#include <dt-bindings/input/input.h>

/ {
	model = "Linksys EA7500 V1 WiFi Router";
	compatible = "linksys,ea7500-v1", "qcom,ipq8064";

	memory@0 {
		reg = <0x42000000 0xe000000>;
		device_type = "memory";
	};

	reserved-memory {
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;
		rsvd@41200000 {
			reg = <0x41200000 0x300000>;
			no-map;
		};
	};

	aliases {
		serial0 = &gsbi4_serial;

		led-boot = &led_power;
		led-failsafe = &led_power;
		led-running = &led_power;
		led-upgrade = &led_power;
	};

	chosen {
		bootargs = "console=ttyMSM0,115200n8";
		stdout-path = "serial0:115200n8";
		append-rootblock = "ubi.mtd=";  /* append to bootargs adding the root deviceblock nbr from bootloader */
		find-rootblock = "ubi.mtd=";  /* look for root deviceblock nbr in this bootarg */
	};

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

		reset {
			label = "reset";
			gpios = <&qcom_pinmux 68 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};

		wps {
			label = "wps";
			gpios = <&qcom_pinmux 65 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_WPS_BUTTON>;
		};
	};

	leds {
		compatible = "gpio-leds";
		pinctrl-0 = <&led_pins>;
		pinctrl-names = "default";

		led_power: power {
			label = "ea7500-v1:white:power";
			gpios = <&qcom_pinmux 6 GPIO_ACTIVE_LOW>;
			default-state = "keep";
		};
	};
};

&qcom_pinmux {
	button_pins: button_pins {
		mux {
			pins = "gpio65", "gpio68";
			function = "gpio";
			drive-strength = <2>;
			bias-pull-up;
		};
	};

	led_pins: led_pins {
		mux {
			pins = "gpio6";
			function = "gpio";
			drive-strength = <2>;
			bias-pull-up;
		};
	};
};

&gsbi4 {
	qcom,mode = <GSBI_PROT_I2C_UART>;
	status = "okay";
	serial@16340000 {
		status = "okay";
	};
	/*
	* The i2c device on gsbi4 should not be enabled.
	* On ipq806x designs gsbi4 i2c is meant for exclusive
	* RPM usage. Turning this on in kernel manifests as
	* i2c failure for the RPM.
	*/
};

&usb3_0 {
	status = "okay";
};

&usb3_1 {
	status = "okay";
};

&pcie0 {
	status = "okay";
	force_gen1 = <1>;
};

&pcie1 {
	status = "okay";
};

&pcie2 {
	status = "okay";
};

&nand_controller {
	status = "okay";

	pinctrl-0 = <&nand_pins>;
	pinctrl-names = "default";

	nand@0 {
		reg = <0>;
		compatible = "qcom,nandcs";

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

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

			partition@0 {
				label = "SBL1";
				reg = <0x0000000 0x0040000>;
				read-only;
			};

			partition@40000 {
				label = "MIBIB";
				reg = <0x0040000 0x0140000>;
				read-only;
			};

			partition@180000 {
				label = "SBL2";
				reg = <0x0180000 0x0140000>;
				read-only;
			};

			partition@2c0000 {
				label = "SBL3";
				reg = <0x02c0000 0x0280000>;
				read-only;
			};

			partition@540000 {
				label = "DDRCONFIG";
				reg = <0x0540000 0x0120000>;
				read-only;
			};

			partition@660000 {
				label = "SSD";
				reg = <0x0660000 0x0120000>;
				read-only;
			};

			partition@780000 {
				label = "TZ";
				reg = <0x0780000 0x0280000>;
				read-only;
			};

			partition@a00000 {
				label = "RPM";
				reg = <0x0a00000 0x0280000>;
				read-only;
			};

			art: partition@c80000 {
				label = "art";
				reg = <0x0c80000 0x0140000>;
				read-only;
			};

			partition@dc0000 {
				label = "APPSBL";
				reg = <0x0dc0000 0x0100000>;
				read-only;
			};

			partition@ec0000 {
				label = "u_env";
				reg = <0x0ec0000 0x0040000>;
			};

			partition@f00000 {
				label = "s_env";
				reg = <0x0f00000 0x0040000>;
			};

			partition@f40000 {
				label = "devinfo";
				reg = <0x0f40000 0x0040000>;
			};

			partition@f80000 {
				label = "kernel1";
				reg = <0x0f80000 0x2800000>;  /* 3 MB spill to rootfs*/
			};

			partition@1280000 {
				label = "rootfs1";
				reg = <0x1280000 0x2500000>;
			};

			partition@3780000 {
				label = "kernel2";
				reg = <0x3780000 0x2800000>;
			};

			partition@3a80000 {
				label = "rootfs2";
				reg = <0x3a80000 0x2500000>;
			};

			partition@5f80000 {
				label = "sysdiag";
				reg = <0x5f80000 0x100000>;
			};

			partition@6080000 {
				label = "syscfg";
				reg = <0x6080000 0x1f80000>;
			};
		};
	};
};

&mdio0 {
	status = "okay";

	pinctrl-0 = <&mdio0_pins>;
	pinctrl-names = "default";

	phy0: ethernet-phy@0 {
		reg = <0>;
		qca,ar8327-initvals = <
			0x00004 0x7600000   /* PAD0_MODE */
			0x00008 0x1000000   /* PAD5_MODE */
			0x0000c 0x80        /* PAD6_MODE */
			0x00010 0x2613a0    /* PWS_REG */
			0x000e4 0x6a545     /* MAC_POWER_SEL */
			0x000e0 0xc74164de  /* SGMII_CTRL */
			0x0007c 0x4e        /* PORT0_STATUS */
			0x00094 0x4e        /* PORT6_STATUS */
			>;
	};
};

&gmac1 {
	status = "okay";
	compatible = "qcom,nss-gmac";
	reg = <0x37200000 0x200000>;
	interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
	phy-mode = "rgmii";
	qcom,id = <1>;
	qcom,forced-speed = <1000>;
	qcom,forced-duplex = <1>;
	qcom,socver = <0>;
	pinctrl-0 = <&rgmii2_pins>;
	pinctrl-names = "default";

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

&gmac2 {
	status = "okay";
	compatible = "qcom,nss-gmac";
	reg = <0x37400000 0x200000>;
	interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
	phy-mode = "sgmii";
	qcom,id = <2>;
	qcom,forced-speed = <1000>;
	qcom,forced-duplex = <1>;
	qcom,socver = <0>;
	fixed-link {
		speed = <1000>;
		full-duplex;
	};
};

&adm_dma {
	status = "okay";
};

post also the original ipq8064 dtsi

Here it is
https://raw.githubusercontent.com/jack338c/nss/master/qcom-ipq8064.dtsi

this is not the oem dtsi it's the upstream openwrt

where can find it ? I only have the ipq8064 dtsi file from your repo or officail openwrt
thanks

@jack338c your GMAC DTS nodes are missing some of the properties required by the GMAC driver. Make sure those defined in the working DTS are also in yours.

The GMAC driver will not load if it finds required properties missing.

It's a little complex for me, I do have no idea
Thanks