ath79: support Ruckus ZoneFlex 7341/7343/7363
authorLech Perczak <lech.perczak@gmail.com>
Tue, 7 Mar 2023 20:25:59 +0000 (21:25 +0100)
committerHauke Mehrtens <hauke@hauke-m.de>
Wed, 22 Mar 2023 21:25:08 +0000 (22:25 +0100)
Ruckus ZoneFlex 7363 is a dual-band, dual-radio 802.11n 2x2 MIMO enterprise
access point. ZoneFlex 7343 is the single band variant of 7363
restricted to 2.4GHz, and ZoneFlex 7341 is 7343 minus two Fast Ethernet
ports.

Hardware highligts:
- CPU: Atheros AR7161 SoC at 680 MHz
- RAM: 64MB DDR
- Flash: 16MB SPI-NOR
- Wi-Fi 2.4GHz: AR9280 PCI 2x2 MIMO radio with external beamforming
- Wi-Fi 5GHz: AR9280 PCI 2x2 MIMO radio with external beamforming
- Ethernet 1: single Gigabit Ethernet port through Marvell 88E1116R gigabit PHY
- Ethernet 2: two Fast Ethernet ports through Realtek RTL8363S switch,
  connected with Fast Ethernet link to CPU.
- PoE: input through Gigabit port
- Standalone 12V/1A power input
- USB: optional single USB 2.0 host port on the -U variants.

Serial console: 115200-8-N-1 on internal H1 header.
Pinout:

H1 ----------
   |1|x3|4|5|
   ----------

Pin 1 is near the "H1" marking.
1 - RX
x - no pin
3 - VCC (3.3V)
4 - GND
5 - TX

Installation:
- Using serial console - requires some disassembly, 3.3V USB-Serial
  adapter, TFTP server, and removing a single PH1 screw.

0. Connect serial console to H1 header. Ensure the serial converter
   does not back-power the board, otherwise it will fail to boot.

1. Power-on the board. Then quickly connect serial converter to PC and
   hit Ctrl+C in the terminal to break boot sequence. If you're lucky,
   you'll enter U-boot shell. Then skip to point 3.
   Connection parameters are 115200-8-N-1.

2. Allow the board to boot.  Press the reset button, so the board
   reboots into U-boot again and go back to point 1.

3. Set the "bootcmd" variable to disable the dual-boot feature of the
   system and ensure that uImage is loaded. This is critical step, and
   needs to be done only on initial installation.

   > setenv bootcmd "bootm 0xbf040000"
   > saveenv

4. Boot the OpenWrt initramfs using TFTP. Replace IP addresses as needed.
   Use the Gigabit interface, Fast Ethernet ports are not supported
   under U-boot:

   > setenv serverip 192.168.1.2
   > setenv ipaddr 192.168.1.1
   > tftpboot 0x81000000 openwrt-ath79-generic-ruckus_zf7363-initramfs-kernel.bin
   > bootm 0x81000000

5. Optional, but highly recommended: back up contents of "firmware" partition:

   $ ssh root@192.168.1.1 cat /dev/mtd1 > ruckus_zf7363_fw_backup.bin

6. Copy over sysupgrade image, and perform actual installation. OpenWrt
   shall boot from flash afterwards:

   $ ssh root@192.168.1.1
   # sysupgrade -n openwrt-ath79-generic-ruckus_zf7363-squashfs-sysupgrade.bin

   After unit boots, it should be available at the usual 192.168.1.1/24.

Return to factory firmware:

1. Copy over the backup to /tmp, for example using scp
2. Unset the "bootcmd" variable:
   fw_setenv bootcmd ""
3. Use sysupgrade with force to restore the backup:
   sysupgrade -F ruckus_zf7363_backup.bin
4. System will reboot.

Quirks and known issues:
- Fast Ethernet ports on ZF7363 and ZF7343 are supported, but management
  features of the RTL8363S switch aren't implemented yet, though the
  switch is visible over MDIO0 bus. This is a gigabit-capable switch, so
  link establishment with a gigabit link partner may take a longer time
  because RTL8363S advertises gigabit, and the port magnetics don't
  support it, so a downshift needs to occur. Both ports are accessible
  at eth1 interface, which - strangely - runs only at 100Mbps itself.
- Flash layout is changed from the factory, to use both firmware image
  partitions for storage using mtd-concat, and uImage format is used to
  actually boot the system, which rules out the dual-boot capability.
- Both radio has its own EEPROM on board, not connected to CPU.
- The stock firmware has dual-boot capability, which is not supported in
  OpenWrt by choice.
  It is controlled by data in the top 64kB of RAM which is unmapped,
  to avoid the interference in the boot process and accidental
  switch to the inactive image, although boot script presence in
  form of "bootcmd" variable should prevent this entirely.
- On some versions of stock firmware, it is possible to obtain root shell,
  however not much is available in terms of debugging facitilies.
  1. Login to the rkscli
  2. Execute hidden command "Ruckus"
  3. Copy and paste ";/bin/sh;" including quotes. This is required only
     once, the payload will be stored in writable filesystem.
  4. Execute hidden command "!v54!". Press Enter leaving empty reply for
     "What's your chow?" prompt.
  5. Busybox shell shall open.
  Source: https://alephsecurity.com/vulns/aleph-2019014
- There is second method to achieve root shell, using command injection
  in the web interface:
  1. Login to web administration interface
  2. Go to Administration > Diagnostics
  3. Enter |telnetd${IFS}-p${IFS}204${IFS}-l${IFS}/bin/sh into "ping"
     field
  4. Press "Run test"
  5. Telnet to the device IP at port 204
  6. Busybox shell shall open.
  Source: https://github.com/chk-jxcn/ruckusremoteshell

Signed-off-by: Lech Perczak <lech.perczak@gmail.com>
package/boot/uboot-envtools/files/ath79
target/linux/ath79/dts/ar7161_ruckus_gd11.dtsi
target/linux/ath79/dts/ar7161_ruckus_zf7341.dts [new file with mode: 0644]
target/linux/ath79/dts/ar7161_ruckus_zf734x.dtsi [new file with mode: 0644]
target/linux/ath79/dts/ar7161_ruckus_zf7363.dts [new file with mode: 0644]
target/linux/ath79/generic/base-files/etc/board.d/02_network
target/linux/ath79/image/generic.mk

index 3b3ff43b13f58ac546c79aae6dd50f552533066e..b968fa8fdeca49b0ec8464aaf95095d40444c264 100644 (file)
@@ -140,7 +140,9 @@ qihoo,c301)
        ubootenv_add_uci_config "/dev/mtd9" "0x0" "0x10000" "0x10000"
        ;;
 ruckus,zf7025|\
-ruckus,zf7351)
+ruckus,zf7341|\
+ruckus,zf7351|\
+ruckus,zf7363)
        ubootenv_add_uci_config "/dev/mtd5" "0x0" "0x40000" "0x40000"
        ;;
 ruckus,zf7321|\
index c6407655457c23569cba4b258ad9d9631ae3badd..e97e31e58ec656603e04916e4433f2574b91e549 100644 (file)
@@ -16,7 +16,7 @@
                label-mac-device = &eth0;
        };
 
-       keys {
+       keys: keys {
                compatible = "gpio-keys";
 
                reset {
diff --git a/target/linux/ath79/dts/ar7161_ruckus_zf7341.dts b/target/linux/ath79/dts/ar7161_ruckus_zf7341.dts
new file mode 100644 (file)
index 0000000..17735e5
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar7161_ruckus_zf734x.dtsi"
+
+/ {
+       model = "Ruckus ZoneFlex 7341[-U]";
+       compatible = "ruckus,zf7341", "qca,ar7161";
+};
diff --git a/target/linux/ath79/dts/ar7161_ruckus_zf734x.dtsi b/target/linux/ath79/dts/ar7161_ruckus_zf734x.dtsi
new file mode 100644 (file)
index 0000000..8861b09
--- /dev/null
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar7161_ruckus_gd11.dtsi"
+
+&keys {
+       opt {
+               /* Not used by stock firmware */
+               label = "opt";
+               linux,code = <KEY_WPS_BUTTON>;
+               gpios = <&gpio 11 GPIO_ACTIVE_HIGH>;
+               debounce-interval = <60>;
+       };
+};
+
+&beamforming_2g_gpio {
+       /* Default beamforming switches configuration from stock firmware,
+        * the AP is started and for broadcast frames - all outputs high */
+       lb0 {
+               line-name = "beamforming:2g:lb0";
+               gpios = <0 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb1 {
+               line-name = "beamforming:2g:lb1";
+               gpios = <1 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb2 {
+               line-name = "beamforming:2g:lb2";
+               gpios = <2 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb3 {
+               line-name = "beamforming:2g:lb3";
+               gpios = <3 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb4 {
+               line-name = "beamforming:2g:lb4";
+               gpios = <4 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb5 {
+               line-name = "beamforming:2g:lb5";
+               gpios = <5 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb6 {
+               line-name = "beamforming:2g:lb6";
+               gpios = <6 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       lb7 {
+               line-name = "beamforming:2g:lb7";
+               gpios = <7 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+};
+
+&beamforming_5g_gpio {
+       /* Default beamforming switches configuration from stock firmware,
+        * the AP is started and for broadcast frames - all outputs high */
+       hb0 {
+               line-name = "beamforming:5g:hb0";
+               gpios = <0 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       hb1 {
+               line-name = "beamforming:5g:hb1";
+               gpios = <1 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       hb2 {
+               line-name = "beamforming:5g:hb2";
+               gpios = <2 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       hb3 {
+               line-name = "beamforming:5g:hb3";
+               gpios = <3 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       hb4 {
+               line-name = "beamforming:5g:hb4";
+               gpios = <4 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+
+       hb5 {
+               line-name = "beamforming:5g:hb5";
+               gpios = <5 GPIO_ACTIVE_LOW>;
+               output-high;
+               gpio-hog;
+       };
+};
diff --git a/target/linux/ath79/dts/ar7161_ruckus_zf7363.dts b/target/linux/ath79/dts/ar7161_ruckus_zf7363.dts
new file mode 100644 (file)
index 0000000..4ece56d
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "ar7161_ruckus_zf734x.dtsi"
+
+/ {
+       model = "Ruckus ZoneFlex 7343/7363[-U]";
+       compatible = "ruckus,zf7363", "qca,ar7161";
+};
+
+&mdio0 {
+       ethernet-phy@0 {
+               reg = <0x0>;
+               max-speed = <100>;
+       };
+
+       ethernet-phy@1 {
+               reg = <0x1>;
+               max-speed = <100>;
+       };
+};
+
+&eth1 {
+       status = "okay";
+       pll-data = <0x00110000 0x00001099 0x00991099>;
+       nvmem-cells = <&macaddr_bdata_6c>;
+       nvmem-cell-names = "mac-address";
+       phy-mode = "rgmii-id";
+
+       fixed-link {
+               speed = <100>;
+               full-duplex;
+       };
+};
+
+&board_data {
+       macaddr_bdata_6c: macaddr@6c {
+               reg = <0x6c 0x6>;
+       };
+};
index a4392e0353f83131314637435dda7076ee9557a4..31ea891d5727bafd906d587c618df771e7968e85 100644 (file)
@@ -67,6 +67,7 @@ ath79_setup_interfaces()
        pisen,wmb001n|\
        pisen,wmm003n|\
        ruckus,zf7321|\
+       ruckus,zf7341|\
        ruckus,zf7351|\
        siemens,ws-ap3610|\
        sophos,ap15|\
@@ -139,6 +140,7 @@ ath79_setup_interfaces()
        engenius,ews511ap|\
        engenius,ews660ap|\
        ocedo,ursus|\
+       ruckus,zf7363|\
        ruckus,zf7372|\
        ubnt,unifi-ap-outdoor-plus)
                ucidef_set_interface_lan "eth0 eth1"
@@ -745,7 +747,9 @@ ath79_setup_macs()
                ;;
        ruckus,zf7025|\
        ruckus,zf7321|\
+       ruckus,zf7341|\
        ruckus,zf7351|\
+       ruckus,zf7363|\
        ruckus,zf7372)
                lan_mac=$(mtd_get_mac_binary board-data 0x807E)
                label_mac=$lan_mac
index fd63b623cdedf181cd75faa608e706babed56326..608b51766fa4f969d752f8367b64dbb3fc878183 100644 (file)
@@ -2538,6 +2538,13 @@ define Device/ruckus_gd11_common
   DEVICE_PACKAGES := kmod-usb2 kmod-usb-chipidea2
 endef
 
+define Device/ruckus_zf7341
+  $(Device/ruckus_gd11_common)
+  DEVICE_MODEL := ZoneFlex 7341[-U]
+  DEVICE_PACKAGES += -swconfig
+endef
+TARGET_DEVICES += ruckus_zf7341
+
 define Device/ruckus_zf7351
   $(Device/ruckus_gd11_common)
   DEVICE_MODEL := ZoneFlex 7351[-U]
@@ -2545,6 +2552,14 @@ define Device/ruckus_zf7351
 endef
 TARGET_DEVICES += ruckus_zf7351
 
+define Device/ruckus_zf7363
+  $(Device/ruckus_gd11_common)
+  DEVICE_MODEL := ZoneFlex 7363[-U]
+  DEVICE_ALT0_VENDOR := Ruckus
+  DEVICE_ALT0_MODEL := ZoneFlex 7343[-U]
+endef
+TARGET_DEVICES += ruckus_zf7363
+
 define Device/ruckus_zf73xx_common
   $(Device/ruckus_common)
   DEVICE_PACKAGES := -swconfig kmod-usb2 kmod-usb-chipidea2