Converting to DSA with dual switches

Router is a Netgear R9000 running Egorenar's OpenWrt fork for the R9000.

The R9000 has two QCA8337N switches. They are setup as follows:

 * Switch configuration
 *
 * There are two switches: master and slave.
 *
 * Ports P0 and P5 of the master switch are connected to the CPU ports
 * ETH1 and ETH2, respectively. ETH1 (and VID1 --> ETH1.1) shall
 * be used for LAN and ETH2 (and VID2 --> ETH2.2) for WAN.
 *
 * Ports P4 and P6 of the master switch are connected with ports P5 and P0
 * of the slave switch, respectively. These ports are set up into trunks:
 *   - P4 and P6 into TRUNK1 on the master switch
 *   - P5 and P0 into TRUNK0 on the slave switch
 *
 * Master switch:
 *   - P0: CPU ETH1
 *   - P1: LAN2
 *   - P2: LAN1
 *   - P3: WAN
 *   - P4: connected to slave's P5
 *   - P5: CPU ETH2
 *   - P6: connected to slave's P0
 *
 * Slave switch:
 *   - P0: connected to master's P6
 *   - P1: LAN6
 *   - P2: LAN5
 *   - P3: LAN4
 *   - P4: LAN3
 *   - P5: connected to master's P4
 *   - P6: -
 *
 * Master switch P3 and P5 are on VID2
 * All other ports on both switches on VID 1

By default the switches are set up with swconfig, but when I built the image I went out of my way to ensure that the QCA8k DSA driver was compiled in. Id like to try out converting to a DSA switch setup (in large part because, supposedly, the QCA8k DSA driver supports hardware flow offloading). However, I'm not quite sure how to deal with TRUNK0 and TRUNK1 in the DSA setup, or if I need to explicitly set these up at all (none of the examples I found showed the configuration for 2 switches connected by dual trunks....).

Any tips are much appreciated. Thanks in advance.

Heres the relevant info from /etc/board.d/02_network and /etc/config/network. If any other info is needed let me know.

/etc/board.d/02_network

#
# Switch configuration
#
# There are two switches: master (switch0) and slave (switch1).
#
# Ports P0 and P5 of the master switch are connected to the CPU ports
# ETH1 and ETH2, respectively. ETH1 shall be used for LAN and ETH2 for WAN.
#
# Port P3 of the master switch is the WAN port. VLAN2 is set up
# to isolate P3 and P5 of the master switch from LAN ports of
# both the master and the slave switch.
#
# All ports of the master switch except P3 and P5 are assigned to VLAN1.
#
# All ports of the slave switch are assigned to VLAN1. Port P6 of the slave
# switch is unused and idle.
#

case "$board" in
netgear,r9000|\
netgear,xr700)
        ucidef_set_interfaces_lan_wan "eth1.1" "eth2.2"
        ucidef_add_switch "switch0" \
                "0t@eth1" "1:lan" "2:lan" "4:lan" "6:lan" "3:wan" "5t@eth2"
        ucidef_add_switch "switch1" \
                "6t@eth1" "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan"
        ;;
*)
        echo "Unsupported hardware. Network interfaces not intialized"
        ;;
esac

/etc/config/network

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth1.1'
        option igmp_snooping '1'
        option stp '1'
        option igmpversion '3'
        option mldversion '2'

config interface 'wan'
        option device 'eth2.2'
        option proto 'dhcp'
        option peerdns '0'
        option delegate '0'

config switch
        option name 'switch0'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch0'
        option vlan '1'
        option ports '1 2 4 6 0t'

config switch_vlan
        option device 'switch0'
        option vlan '2'
        option ports '3 5t'

config switch
        option name 'switch1'
        option reset '1'
        option enable_vlan '1'

config switch_vlan
        option device 'switch1'
        option vlan '1'
        option ports '0 1 2 3 4 5 6t'

config device
        option name 'eth1'
        option igmpversion '3'
        option mldversion '2'

config device
        option name 'eth2'
        option igmpversion '3'
        option mldversion '2'

config device
        option name 'eth1.1'
        option type '8021q'
        option ifname 'eth1'
        option vid '1'
        option igmpversion '3'
        option mldversion '2'
        option multicast_to_unicast '1'

config device
        option name 'eth2.2'
        option type '8021q'
        option ifname 'eth2'
        option vid '2'
        option igmpversion '3'
        option mldversion '2'

Casual first attempt at a DSA configuration for this device. No idea what to do with the PAD configuration and trunking though; I have a feeling that doing it this way would just cause a broadcast loop.

Also, IIRC dual-CPU port DSA patches haven't landed in mainline yet.

&mdio0 {
	status = "okay";

	switch0@0{
		compatible = “qca,qca8337”;
		#address-cells = <1>;
		#size-cells = <0>;

		reg = <0>;

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

			port@0 {
				reg = <0>;
				label = "cpu”;
				ethernet = <&eth1>;
				phy-mode = “sgmii”;
				tx-internal-delay-ps = <2000>;

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

			port@1 {
				reg = <1>;
				label = "lan2”;
				phy-mode = "internal";
				phy-handle = <&phy_port1>;
			};

			port@2 {
				reg = <2>;
				label = "lan1";
				phy-mode = "internal";
				phy-handle = <&phy_port2>;
			};

			port@3 {
				reg = <3>;
				label = “wan";
				phy-mode = "internal";
				phy-handle = <&phy_port3>;
			};

			switch0port4: port@4 {
				reg = <4>;
				label = “dsa”;
				link = <&switch1port0>;

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

			// TODO port@5: multi-cpu dsa support has not landed yet

			switch0port6: port@6 {
				reg = <6>;
				label = “dsa”;
				link = <&switch1port5>;

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

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

			phy_port1: phy@0 {
				reg = <0>;
			};

			phy_port2: phy@1 {
				reg = <1>;
			};

			phy_port3: phy@2 {
				reg = <2>;
			};
		};
	};
};

&mdio1 {
	status = "okay";

	switch1@0{
		compatible = “qca,qca8337”;
		#address-cells = <1>;
		#size-cells = <0>;

		reg = <0>;

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

			switch1port0: port@0 {
				reg = <0>;
				label = “dsa”;
				link = <&switch0port4>;

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

			port@1 {
				reg = <1>;
				label = "lan6”;
				phy-mode = "internal";
				phy-handle = <&phy_port1>;
			};

			port@2 {
				reg = <2>;
				label = "lan5”;
				phy-mode = "internal";
				phy-handle = <&phy_port2>;
			};

			port@3 {
				reg = <3>;
				label = “lan4”;
				phy-mode = "internal";
				phy-handle = <&phy_port3>;
			};

			port@4 {
				reg = <4>;
				label = “lan3”;
				phy-mode = "internal";
				phy-handle = <&phy_port4>;
			};

			switch1port5: port@0 {
				reg = <5>;
				label = “dsa”;
				link = <&switch0port6>;

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

			// NOTE port@6 unused on switch1
		};

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

			phy_port1: phy@0 {
				reg = <0>;
			};

			phy_port2: phy@1 {
				reg = <1>;
			};

			phy_port3: phy@2 {
				reg = <2>;
			};

			phy_port4: phy@3 {
				reg = <3>;
			};
		};
	};
};

Did you ever attempted again getting DSA to work on this unit? This would allow us to use hardware offload as the driver (QCA8337N) supports so?

I hate to say it, but Im pretty sure the R9000 uses QCA8337 switches, not QCA8337N switches, meaning no hardware flow offload. wikidev lists QCA8337N switches, but the FCC teardown pictures (see the 6th page in the PDF for a reasonably clear picture) seems to show the switches as 'QCA8337-AL3C'.

Personally, I stopped seriously looking into converting to DSA after discovering this, but perhaps someone else has continued working on it.