Working hardware flow offload for MT7620

I implemented the support for hardware flow offloading for MT7620 device.
It uses the same api form MT7621. Right now, it just works on Archer C5v4. That is because it uses the the port 5 of mt7620 switch to communicate with external switch. I'm working on other switchs configurations....

5 Likes

Ah... This is Openwrt 19.07 ... The current master have the api removed from the driver (it only works on the kernel driver)... mt7620 can be ported to DSA with little adjustments... will work on that in the future...

5 Likes

For RTL8367S, you will need a different driver.

The offloading is done in the MT7620 SoC, not in 8367S switch... MT7620 and MT7621 have a PPE engine (Packet Processing Engine). NAT, PPPoE, the bridge interface, all is processed by this PPE engine. RTL8367S is connected to port 5 of MT7620 and all packets are forwarded thru that port. And MT7620 can process the packet and send it back to RTL8367S. Without the PPE, the packets are forwarded to the CPU, limiting the bandwidth...

With the PPE enabled, I can get 900M from Archer C5v4, using the same driver that we use now for RTL8367S. Actually, this driver is in the Mediatek branch of openwrt (target/linux/mediatek). If we have this driver in generic, we can use it in C5v4 release the support for the router....

3 Likes

Well I meant DSA driver for RTL8367S

Oh... Yes, the RTL8367S need a different port for DSA... But it is close related to the RTL8367R/B ... I think the DSA for both can be implemented together...

https://patchwork.ozlabs.org/project/openwrt/patch/117be9a8-4641-0033-1900-95f53af653e8@yandex.ru/

Is it possible to make hardware flow offload work within wifi?

Yes... @nbd is working on an integration of the kernel with the wireless drivers... After that, we can work on 7620 PPE to offload to wifi mt76... I'm waiting to see his final solution to build on top of that...

1 Like

another one has done something like this.

2 Likes

I did a search on the forum and this is maybe the mose relevant post.

I have not compiled openwrt for a couple of months but with the latest build from master (MT7621+MT7615DN) it seems HW NAT is working now.

I only did a simple test with iperf3 without PPPoE. It seems I get full gigabit with no CPU usage from htop.

I had a quick look at the commits trying to find when this was turned on but I couldn't see it. Needless to say it is a very good extra.

I will test with PPPoE when I get a chance but I only havd a 250mb connection at home. I guess I can confirm just by looking at CPU usage.

Hello.Ihave lava lr25g001 route(mt7620 +qca8337) and I build firmware for this sources. It really 900mb...but when i have more 2 dhcp client lan and wan due.

I have an Archer C5 (MT7620 + RTL8367S/C)... It is working... Maybe it is something with the qca chip? I don't have any router like that to test here...

How i can test what going with router? top atop or something else?

with this patch LAVA Working stable.... but without HWnat
https://drive.google.com/file/d/14wF9qCgdTH9chfsr7ezU-u8Nas46Vl7X/view?usp=sharing
And i try use another driver for Ar8327
and now i change dts for lava

/dts-v1/;

#include "mt7620a.dtsi"

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

/ {
	compatible = "lava,lr-25g001", "ralink,mt7620a-soc";
	model = "LAVA LR-25G001";

	aliases {
		led-boot = &led_status;
		led-failsafe = &led_status;
		led-running = &led_status;
		led-upgrade = &led_status;
	};

	keys {
		compatible = "gpio-keys-polled";
		poll-interval = <20>;

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

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

	leds {
		compatible = "gpio-leds";

		led_status: status {
			label = "lr-25g001:green:status";
			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
		};

		wifi2g {
			label = "lr-25g001:green:wifi2g";
			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
		};

		wifi5g {
			label = "lr-25g001:green:wifi5g";
			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
		};
	};

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

		usbpower {
			gpio-export,name = "usbpower";
			gpio-export,output = <1>;
			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
		};
	};

qca8337 {
		compatible = "qca,ar8xxx";
		qca,mdio = <&mdio0>;

		/* CPU PORT = 0, PORT6 is disable */
		qca,ar8327-initvals = <
			0x04 0x87300000 /* PORT0 PAD MODE CTRL */
			0x10 0x40000000 /* Power-on Strapping: 176-pin interface configuration */
			0x50 0xcc35cc35 /* LED Control Register 0 */
			0x54 0xca35ca35 /* LED Control Register 1 */
			0x58 0xc935c935 /* LED Control Register 2 */
			0x5c 0x03ffff00 /* LED Control Register 3 */
			0x7c 0x0000007e /* PORT0_STATUS */
			0x80 0x000002b0 /* PORT1_STATUS */
			0x84 0x000002b0 /* PORT2_STATUS */
			0x88 0x000002b0 /* PORT3_STATUS */
			0x8c 0x000002b0 /* PORT4_STATUS */
			0x90 0x000002b0 /* PORT5_STATUS */
			0x94 0x00001280 /* PORT6_STATUS */
		>;
	};
};

&gpio0 {
	status = "okay";
};

&spi0 {
	status = "okay";

	flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;

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

			partition@0 {
				label = "jboot";
				reg = <0x0 0x10000>;
				read-only;
			};

			partition@10000 {
				compatible = "amit,jimage";
				label = "firmware";
				reg = <0x10000 0xfe0000>;
			};

			config: partition@ff0000 {
				label = "config";
				reg = <0xff0000 0x10000>;
				read-only;
			};
		};
	};
};

&ehci {
	status = "okay";
};

&ohci {
	status = "okay";
};

&ethernet {
	status = "okay";
	pinctrl-names = "default";
	pinctrl-0 = <&rgmii1_pins &mdio_pins>;
	mtd-mac-address = <&config 0xe07e>;

	port@5 {
		status = "okay";
		phy-mode = "rgmii";
		mediatek,fixed-link = <1000 1 1 1>;
	};

	mdio0: mdio-bus {
		status = "okay";	
		};
};
	

&pcie {
	status = "okay";
};

&pcie0 {
	mt76x0e@0,0 {
		reg = <0x0000 0 0 0 0>;
		mtd-mac-address = <&config 0xe07e>;
		mtd-mac-address-increment = <(2)>;
		mediatek,mtd-eeprom = <&config 0xe08a>;
	};
};

&wmac {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
ralink,mtd-eeprom = <&config 0xe290 >;
};

&gsw {
	mediatek,phy_init = "disable";
};

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "uartf", "i2c";
			ralink,function = "gpio";
		};
	};
};

The qca,ar8327-initvals makes an initialisation of the switch ports... MTK uses port 7 for PPE... Maybe this router needs some different initialisation to work with PPE...

maybe you can tell me how to reconfigure ar8327? in which mode do you need to configure the switch? or how to debug and determine why wan dies?

Hi. I Fix WAN die when more then one device connected.

diff --git a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7621.c b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7621.c
index 26a198fa2b..fe5ad73c31 100644
--- a/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7621.c
+++ b/target/linux/ramips/files-4.14/drivers/net/ethernet/mediatek/soc_mt7621.c
@@ -142,8 +142,9 @@ static void mt7621_init_data(struct fe_soc_data *data,
                FE_FLAG_HAS_SWITCH | FE_FLAG_JUMBO_FRAME;

        netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
-               NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
-               NETIF_F_SG | NETIF_F_TSO |
+//leks         NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
+               NETIF_F_SG |
+//leks         NETIF_F_TSO |
                NETIF_F_TSO6 | NETIF_F_IPV6_CSUM |
                NETIF_F_TSO_MANGLEID;
 }

and change dts to initial qca8337. And now router work great

/dts-v1/;

#include "mt7620a.dtsi"

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

/ {
	compatible = "lava,lr-25g001", "ralink,mt7620a-soc";
	model = "LAVA LR-25G001";

	aliases {
		led-boot = &led_status;
		led-failsafe = &led_status;
		led-running = &led_status;
		led-upgrade = &led_status;
	};

	keys {
		compatible = "gpio-keys-polled";
		poll-interval = <20>;

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

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

	leds {
		compatible = "gpio-leds";

		led_status: status {
			label = "lr-25g001:green:status";
			gpios = <&gpio0 14 GPIO_ACTIVE_LOW>;
		};

		wifi2g {
			label = "lr-25g001:green:wifi2g";
			gpios = <&gpio0 11 GPIO_ACTIVE_LOW>;
		};

		wifi5g {
			label = "lr-25g001:green:wifi5g";
			gpios = <&gpio0 13 GPIO_ACTIVE_LOW>;
		};
	};

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

		usbpower {
			gpio-export,name = "usbpower";
			gpio-export,output = <1>;
			gpios = <&gpio0 12 GPIO_ACTIVE_HIGH>;
		};
	};

};

&gpio0 {
	status = "okay";
};

&spi0 {
	status = "okay";

	flash@0 {
		compatible = "jedec,spi-nor";
		reg = <0>;
		spi-max-frequency = <10000000>;

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

			partition@0 {
				label = "jboot";
				reg = <0x0 0x10000>;
				read-only;
			};

			partition@10000 {
				compatible = "amit,jimage";
				label = "firmware";
				reg = <0x10000 0xfe0000>;
			};

			config: partition@ff0000 {
				label = "config";
				reg = <0xff0000 0x10000>;
				read-only;
			};
		};
	};
};

&ehci {
	status = "okay";
};

&ohci {
	status = "okay";
};

&ethernet {
	status = "okay";
	mtd-mac-address = <&config 0xe07e>;
	pinctrl-names = "default";
	pinctrl-0 = <&rgmii1_pins  &mdio_pins>;

	port@5 {
		status = "okay";
		phy-mode = "rgmii";
		mediatek,fixed-link = <1000 1 1 1>;
	};

		mdio-bus {
		status = "okay";
		mediatek,mdio-mode;

		ethernet-phy@0 {
			reg = <0>;
			phy-mode = "rgmii";
			qca,ar8327-initvals = <
				0x04 0x87600000 /* PORT0 PAD MODE CTRL */
				0x08 0x01000000 /* PORT5 PAD MODE CTRL */
				0x0c 0x00080080 /* PORT6 PAD MODE CTRL */
				0x10 0x81000080 /* POWER_ON_STRIP */
				0x7c 0x0000004e /* PORT0_STATUS */
				0x94 0x0000004e /* PORT6 STATUS */
				>;
		};
	};
};


&pcie {
	status = "okay";
};

&pcie0 {
	mt76x0e@0,0 {
		reg = <0x0000 0 0 0 0>;
		mtd-mac-address = <&config 0xe07e>;
		mtd-mac-address-increment = <(2)>;
		mediatek,mtd-eeprom = <&config 0xe08a>;
	};
};

&wmac {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&pa_pins>;
ralink,mtd-eeprom = <&config 0xe290 >;
};

&gsw {
	mediatek,phy_init = "disable";
};

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "uartf", "i2c";
			ralink,function = "gpio";
		};
	};
};

Hi,

Sorry to bump this old topic.
According to this document https://raw.githubusercontent.com/Deoptim/atheros/master/IPQ4019-datasheet.pdf, IPQ4019 has hardware NAT engine. You said:

NAT, PPPoE, the bridge interface, all is processed by this PPE engine.

So, MTK PPE is more powerful than IPQ4019 HW NAT engine, right? Do we have similar method to use IPQ4019 HW NAT engine to offload? Does this need QCA provide some APIs or tech document?

I dont know about the QCA HW NAT... The MTK PPE can change the ip address from normal packets and PPPoE packets. In the case of PPPoE, the frame is different from normal packets.

wizards. simply. browsing for too long on openwrt forum makes me realize no matter how much i know i know nothing lol.

2 Likes