diff --git a/include/image-commands.mk b/include/image-commands.mk index 1d69485019..9220b8dec0 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -399,6 +399,15 @@ define Build/lzma-no-dict @mv $@.new $@ endef +define Build/moxa-encode-fw + $(TOPDIR)/scripts/moxa-encode-fw.py \ + --input $@ \ + --output $@ \ + --magic $(MOXA_MAGIC) \ + --hwid $(MOXA_HWID) \ + --buildid 00000000 +endef + define Build/netgear-chk $(STAGING_DIR_HOST)/bin/mkchkimg \ -o $@.new \ diff --git a/package/boot/uboot-envtools/files/ath79 b/package/boot/uboot-envtools/files/ath79 index 5201b8b27a..e83703b035 100644 --- a/package/boot/uboot-envtools/files/ath79 +++ b/package/boot/uboot-envtools/files/ath79 @@ -47,6 +47,7 @@ etactica,eg200|\ glinet,gl-ar750s-nor|\ glinet,gl-ar750s-nor-nand|\ librerouter,librerouter-v1|\ +moxa,awk-1137c|\ netgear,ex7300|\ netgear,ex7300-v2|\ netgear,wndr4300-v2|\ diff --git a/scripts/moxa-encode-fw.py b/scripts/moxa-encode-fw.py new file mode 100755 index 0000000000..48d139b839 --- /dev/null +++ b/scripts/moxa-encode-fw.py @@ -0,0 +1,109 @@ +#! /usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later + +import argparse +import struct + +from binascii import crc32 +from dataclasses import dataclass +from itertools import cycle +from typing import List + + +def xor(data: bytes) -> bytes: + passphrase = "Seek AGREEMENT for the date of completion.\0" + pw = cycle(bytearray(passphrase.encode('ascii'))) + return bytearray(b ^ next(pw) for b in data) + + +def add_fw_header(data: bytes, magic: int, hwid: int, build_id: int, + offsets: List[int]) -> bytes: + unknown_1 = 0x01 + unknown_2 = 0x0000 + unknown_3 = 0x00000000 + unknown_4 = 0x01000000 + file_crc = crc(data, 0) + + header_struct = struct.Struct('>QIBBHIIIIII' + 'I' * len(offsets)) + header_size = header_struct.size + file_size = header_size + len(data) + + header_offsets = map(lambda x: x + header_size, offsets) + + header_data = header_struct.pack(magic, file_size, unknown_1, len(offsets), + unknown_2, hwid, build_id, unknown_3, + build_id, unknown_4, *header_offsets, + file_crc) + return header_data + data + + +def add_file_header(data: bytes, filename: str, build_id: int) -> bytes: + unknown1 = 0x01000000 + unknown2 = 0x00000000 + file_crc = crc(data, 0) + + header_struct = struct.Struct(">16sIIIII") + file_size = header_struct.size + len(data) + + header_data = header_struct.pack(filename.encode('ascii'), file_size, + unknown1, build_id, unknown2, file_crc) + return header_data + data + + +def crc(data: bytes, init_val: int) -> int: + return 0xffffffff ^ (crc32(data, 0xffffffff ^ init_val)) + + +@dataclass +class Partition: + name: str + size: int + + +def main(): + partitions = [ + Partition(name='kernel', size=2048 * 1024), + Partition(name='root', size=9216 * 1024), + Partition(name='userdisk', size=3076 * 1024), + ] + + parser = argparse.ArgumentParser(prog='moxa-encode-fw', + description='MOXA IW firmware encoder') + parser.add_argument('-i', '--input', required=True, type=str, help='Firmware file') + parser.add_argument('-o', '--output', required=True, type=str, help="Output path for encoded firmware file") + parser.add_argument('-m', '--magic', required=True, type=lambda x: int(x,0), help="Magic for firmware header") + parser.add_argument('-d', '--hwid', required=True, type=lambda x: int(x,0), help="Hardware id of device") + parser.add_argument('-b', '--buildid', required=True, type=lambda x: int(x,0), help="Build id of firmware") + args = parser.parse_args() + + with open(args.input, 'rb') as input_file: + firmware = bytearray(input_file.read()) + + offsets = [] + pos_input = 0 + pos_output = 0 + firmware_seg = bytearray() + + for partition in partitions: + part_data = firmware[pos_input:pos_input + partition.size] + + # just to make sure that no partition is empty + if len(part_data) == 0: + part_data = bytearray([0x00]) + + header = add_file_header(part_data, partition.name, args.buildid) + firmware_seg += header + + offsets.append(pos_output) + pos_input += partition.size + pos_output += len(header) + + moxa_firmware = add_fw_header(firmware_seg, args.magic, args.hwid, args.buildid, offsets) + + encrypted = xor(moxa_firmware) + with open(args.output, 'wb') as output_file: + output_file.write(encrypted) + + +if __name__ == '__main__': + main() diff --git a/target/linux/ath79/dts/ar9344_moxa_awk-1137c.dts b/target/linux/ath79/dts/ar9344_moxa_awk-1137c.dts new file mode 100644 index 0000000000..d2c5171402 --- /dev/null +++ b/target/linux/ath79/dts/ar9344_moxa_awk-1137c.dts @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT + +#include "ar9344.dtsi" + +#include +#include +#include + +/ { + compatible = "moxa,awk-1137c", "qca,ar9344"; + model = "MOXA AWK-1137C"; + + aliases { + led-boot = &led_status_red; + led-failsafe = &led_status_red; + led-running = &led_status_green; + led-upgrade = &led_status_red; + label-mac-device = ð1; + }; + + keys { + compatible = "gpio-keys"; + + reset { + label = "reset"; + linux,code = ; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-names = "default"; + + led_status_green: led-0 { + label = "green:status"; + color = ; + function = LED_FUNCTION_STATUS; + function-enumerator = <0>; + gpios = <&gpio 2 GPIO_ACTIVE_LOW>; + }; + + led_status_red: led-1 { + label = "red:status"; + color = ; + function = LED_FUNCTION_STATUS; + function-enumerator = <1>; + gpios = <&gpio 3 GPIO_ACTIVE_LOW>; + }; + + led-2 { + label = "green:wifi"; + color = ; + function = LED_FUNCTION_WLAN; + function-enumerator = <0>; + gpios = <&gpio 12 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0tpt"; + }; + + led-3 { + label = "green:lan1"; + color = ; + function = LED_FUNCTION_WAN; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + }; + + led-4 { + label = "green:lan2"; + color = ; + function = LED_FUNCTION_LAN; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + }; + + led-5 { + label = "yellow:wifi"; + color = ; + function = LED_FUNCTION_WLAN; + function-enumerator = <1>; + gpios = <&gpio 21 GPIO_ACTIVE_LOW>; + linux,default-trigger = "phy0assoc"; + }; + }; +}; + +&ref { + clock-frequency = <40000000>; +}; + +&spi { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x000000 0x040000>; + read-only; + }; + + partition@40000 { + label = "u-boot-env"; + reg = <0x040000 0x010000>; + }; + + partition@50000 { + label = "firmware"; + reg = <0x050000 0xe00000>; + compatible = "denx,uimage"; + }; + + partition@e50000 { + label = "log1"; + reg = <0xe50000 0x020000>; + read-only; + }; + + partition@e70000 { + label = "log2"; + reg = <0xe70000 0x020000>; + read-only; + }; + + partition@e90000 { + label = "version"; + reg = <0xe90000 0x020000>; + read-only; + }; + + partition@eb0000 { + label = "config1"; + reg = <0xeb0000 0x020000>; + read-only; + }; + + partition@ed0000 { + label = "config2"; + reg = <0xed0000 0x020000>; + read-only; + }; + + partition@ef0000 { + label = "config-data"; + reg = <0xef0000 0x0c0000>; + read-only; + }; + + partition@fb0000 { + label = "mib0"; + reg = <0xfb0000 0x030000>; + read-only; + }; + + art: partition@fe0000 { + label = "art"; + reg = <0xfe0000 0x010000>; + read-only; + }; + + partition@ff0000 { + label = "fis"; + reg = <0xff0000 0x010000>; + read-only; + }; + }; + }; +}; + +ð1 { + status = "okay"; +}; + +&wmac { + status = "okay"; + qca,no-eeprom; +}; diff --git a/target/linux/ath79/generic/base-files/etc/board.d/01_leds b/target/linux/ath79/generic/base-files/etc/board.d/01_leds index 10c67991fd..65cf7b3292 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/01_leds +++ b/target/linux/ath79/generic/base-files/etc/board.d/01_leds @@ -302,6 +302,10 @@ tplink,cpe210-v3) meraki,mr16) ucidef_set_led_netdev "wan" "WAN" "green:wan" "eth0" ;; +moxa,awk-1137c) + ucidef_set_led_switch "wan" "LAN1" "green:lan1" "switch0" "0x02" + ucidef_set_led_switch "lan" "LAN2" "green:lan2" "switch0" "0x04" + ;; netgear,wnr2200-8m|\ netgear,wnr2200-16m) ucidef_set_led_netdev "wan-amber" "WAN (amber)" "amber:wan" "eth0" diff --git a/target/linux/ath79/generic/base-files/etc/board.d/02_network b/target/linux/ath79/generic/base-files/etc/board.d/02_network index d18eddf5b7..64869701c6 100644 --- a/target/linux/ath79/generic/base-files/etc/board.d/02_network +++ b/target/linux/ath79/generic/base-files/etc/board.d/02_network @@ -240,7 +240,8 @@ ath79_setup_interfaces() ubnt,routerstation) ucidef_set_interfaces_lan_wan "eth1" "eth0" ;; - comfast,cf-e375ac) + comfast,cf-e375ac|\ + moxa,awk-1137c) ucidef_add_switch "switch0" \ "0@eth0" "1:wan" "2:lan" ;; @@ -731,6 +732,11 @@ ath79_setup_macs() lan_mac=$(mtd_get_mac_encrypted_deco $(find_mtd_part config)) label_mac=$lan_mac ;; + moxa,awk-1137c) + lan_mac=$(mtd_get_mac_ascii u-boot-env mac_addr) + wan_mac=$(mtd_get_mac_ascii u-boot-env mac_addr) + label_mac=$lan_mac + ;; nec,wf1200cr|\ nec,wg1200cr) lan_mac=$(mtd_get_mac_ascii devdata "lanmac") diff --git a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom index c46573ece5..3b089885b3 100644 --- a/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom +++ b/target/linux/ath79/generic/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom @@ -62,6 +62,10 @@ case "$FIRMWARE" in caldata_extract "art" 0x1000 0x440 ath9k_patch_mac $(mtd_get_mac_ascii u-boot-env ethaddr) ;; + moxa,awk-1137c) + caldata_extract "art" 0x1000 0x440 + ath9k_patch_mac $(mtd_get_mac_ascii u-boot-env mac_addr) + ;; nec,wg800hp) caldata_extract "art" 0x1000 0x440 ath9k_patch_mac $(mtd_get_mac_text board_data 0x680) diff --git a/target/linux/ath79/generic/base-files/etc/init.d/bootcount b/target/linux/ath79/generic/base-files/etc/init.d/bootcount index 7807559d81..01c446b1bb 100755 --- a/target/linux/ath79/generic/base-files/etc/init.d/bootcount +++ b/target/linux/ath79/generic/base-files/etc/init.d/bootcount @@ -8,6 +8,9 @@ boot() { adtran,bsap1840) fconfig -s -w -d $(find_mtd_part "RedBoot config") -n boot_cntb -x 0 ;; + moxa,awk-1137c) + fw_setenv fwr_verify 0 + ;; qihoo,c301) local n=$(fw_printenv activeregion | cut -d = -f 2) fw_setenv "image${n}trynum" 0 diff --git a/target/linux/ath79/generic/base-files/lib/preinit/10_fix_eth_mac.sh b/target/linux/ath79/generic/base-files/lib/preinit/10_fix_eth_mac.sh index 5fa23e8eb6..8b39a17eb0 100644 --- a/target/linux/ath79/generic/base-files/lib/preinit/10_fix_eth_mac.sh +++ b/target/linux/ath79/generic/base-files/lib/preinit/10_fix_eth_mac.sh @@ -28,6 +28,9 @@ preinit_set_mac_address() { fortinet,fap-221-b) ip link set dev eth0 address $(mtd_get_mac_text u-boot 0x3ff80 12) ;; + moxa,awk-1137c) + ip link set dev eth0 address $(mtd_get_mac_ascii u-boot-env mac_addr) + ;; tplink,deco-s4-v2) base_mac=$(mtd_get_mac_encrypted_deco $(find_mtd_part config)) ip link set dev eth0 address $base_mac diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk index 1a558c30a0..6a2131f5ae 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk @@ -9,6 +9,7 @@ DEVICE_VARS += ADDPATTERN_ID ADDPATTERN_VERSION DEVICE_VARS += SEAMA_SIGNATURE SEAMA_MTDBLOCK DEVICE_VARS += KERNEL_INITRAMFS_PREFIX DAP_SIGNATURE DEVICE_VARS += EDIMAX_HEADER_MAGIC EDIMAX_HEADER_MODEL +DEVICE_VARS += MOXA_MAGIC MOXA_HWID DEVICE_VARS += OPENMESH_CE_TYPE ZYXEL_MODEL_STRING DEVICE_VARS += SUPPORTED_TELTONIKA_DEVICES @@ -1819,6 +1820,19 @@ define Device/mercury_mw4530r-v1 endef TARGET_DEVICES += mercury_mw4530r-v1 +define Device/moxa_awk-1137c + SOC := ar9344 + DEVICE_MODEL := AWK-1137C + DEVICE_VENDOR := MOXA + MOXA_MAGIC := 0x8919123028877702 + MOXA_HWID := 0x01080000 + IMAGE_SIZE := 14336k + DEVICE_PACKAGES := uboot-envtools + IMAGES += factory.rom + IMAGE/factory.rom := $$(IMAGE/sysupgrade.bin) | moxa-encode-fw +endef +TARGET_DEVICES += moxa_awk-1137c + define Device/nec_wx1200cr DEVICE_VENDOR := NEC IMAGE/default := append-kernel | pad-offset $$$$(BLOCKSIZE) 64 | append-rootfs