ramips: add support for Sercomm CPJ routers
authorMikhail Zhilkin <csharper2005@gmail.com>
Sun, 12 Nov 2023 07:58:26 +0000 (07:58 +0000)
committerHauke Mehrtens <hauke@hauke-m.de>
Sat, 25 Nov 2023 00:11:18 +0000 (01:11 +0100)
This commit adds support for following wireless routers:
 - Rostelecom RT-FL-1 (Serсomm RT-FL-1)
 - Rostelecom S1010 (Serсomm S1010.RT)

The devices are almost identical and the only difference is one bit in the
factory image PID (thanks to Maximilian Weinmann <x1@disroot.org>
(@MaxS0niX) for the info and idea to make one PR for two devices at once).

Devices specification
---------------------
   SoC:          MediaTek MT7620A, MIPS
   RAM:          64 MB
   Flash:        16 MB SPI NOR
   Wireless 2.4: MT7620 (b/g/n, 2x2)
   Wireless 5:   MT7612EN (a/n/ac, 2x2)
   Ethernet:     5xFE (WAN, LAN1-4)
   BootLoader:   U-Boot
   Buttons:      2 (wps, reset)
   LEDs:         1 amber and 1 green status GPIO leds
                 5 green ethernet GPIO leds
                 1 green GPIO 2.4 GHz WLAN led
                 1 green PHY 5 GHz WLAN led
                 1 green unmanaged power led
   USB ports:    No
   Power:        12 VDC, 1 A
   Connector:    Barrel

OEM easy installation
---------------------
1. Remove all dots from the factory image filename (except the dot
   before file extension)
2. Upload and update the firmware via the original web interface
3. Wait until green status led stops blinking (can take several minutes)
4. Login to OpenWrt initramsfs. It's recommended to make a backup of the
   mtd partitions at this point.
4. Perform sysupgrade using the following command (or use Luci):
   sysupgrade -n sysupgrade.bin
5. Wait until green status les stops blinking (can take several minutes)
6. Mission acomplished

Return to Stock
---------------
Option 1. Restore firmware Slot1 from a backup (firmware2.bin):
   cd /tmp
   mtd -e Firmware2 write firmware2.bin Firmware2
   printf 1 | dd bs=1 seek=$((0x18007)) count=1 of=/dev/mtdblock2
   reboot

Option 2. Decrypt, ungzip and split stock firmware image into the parts,
take Slot1 parts (kernel2.bin, rootfs2.bin) and write them:
   cd /tmp
   mtd -e Kernel2 write kernel2.bin Kernel2
   mtd -e RootFS2 write rootfs2.bin RootFS2
   printf 1 | dd bs=1 seek=$((0x18007)) count=1 of=/dev/mtdblock2
   reboot
More about stock firmware decryption:
Link: https://github.com/Psychotropos/sercomm_fwutils/
Debricking
----------
Use sercomm-recovery tool. You can use "ALL" mtd partition backup as a
recovery image.
Link: https://github.com/danitool/sercomm-recovery
MAC addresses
-------------
+---------+-------------------+-----------+
|         | MAC               | Algorithm |
+---------+-------------------+-----------+
| label   | 48:3e:xx:xx:xx:1e | label     |
| LAN     | 48:3e:xx:xx:xx:1e | label     |
| WAN     | 48:3e:xx:xx:xx:28 | label+10  |
| WLAN 2g | 48:3e:xx:xx:xx:20 | label+2   |
| WLAN 5g | 48:3e:xx:xx:xx:24 | label+6   |
+---------+-------------------+-----------+

Co-authored-by: Vadzim Vabishchevich <bestmc2009@gmail.com>
Signed-off-by: Mikhail Zhilkin <csharper2005@gmail.com>
target/linux/ramips/dts/mt7620a_rostelecom_rt-fl-1.dts [new file with mode: 0644]
target/linux/ramips/dts/mt7620a_rostelecom_s1010.dts [new file with mode: 0644]
target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi [new file with mode: 0644]
target/linux/ramips/image/common-sercomm.mk
target/linux/ramips/image/mt7620.mk
target/linux/ramips/mt7620/base-files/etc/board.d/01_leds
target/linux/ramips/mt7620/base-files/etc/board.d/02_network
target/linux/ramips/mt7620/base-files/lib/upgrade/platform.sh

diff --git a/target/linux/ramips/dts/mt7620a_rostelecom_rt-fl-1.dts b/target/linux/ramips/dts/mt7620a_rostelecom_rt-fl-1.dts
new file mode 100644 (file)
index 0000000..14081ba
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_sercomm_cpj.dtsi"
+
+/ {
+       compatible = "rostelecom,rt-fl-1", "ralink,mt7620a-soc";
+       model = "Rostelecom RT-FL-1";
+};
diff --git a/target/linux/ramips/dts/mt7620a_rostelecom_s1010.dts b/target/linux/ramips/dts/mt7620a_rostelecom_s1010.dts
new file mode 100644 (file)
index 0000000..37ce9ed
--- /dev/null
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a_sercomm_cpj.dtsi"
+
+/ {
+       compatible = "rostelecom,s1010", "ralink,mt7620a-soc";
+       model = "Rostelecom S1010";
+};
diff --git a/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi b/target/linux/ramips/dts/mt7620a_sercomm_cpj.dtsi
new file mode 100644 (file)
index 0000000..e903f9f
--- /dev/null
@@ -0,0 +1,309 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+
+#include "mt7620a.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       aliases {
+               label-mac-device = &ethernet;
+
+               led-boot = &status_green;
+               led-failsafe = &status_amber;
+               led-running = &status_green;
+               led-upgrade = &status_amber;
+       };
+
+       keys {
+               compatible = "gpio-keys";
+
+               button-0 {
+                       label = "reset";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio1 6 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+
+               button-1 {
+                       label = "wps";
+                       linux,code = <KEY_RESTART>;
+                       gpios = <&gpio1 7 GPIO_ACTIVE_LOW>;
+                       debounce-interval = <60>;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               status_green: led-0 {
+                       label = "green:status";
+                       gpios = <&gpio0 9 GPIO_ACTIVE_LOW>;
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_STATUS;
+               };
+
+               status_amber: led-1 {
+                       label = "amber:status";
+                       gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
+                       color = <LED_COLOR_ID_AMBER>;
+                       function = LED_FUNCTION_STATUS;
+               };
+
+               led-2 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_WAN;
+                       gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
+               };
+
+               led-3 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_LAN;
+                       function-enumerator = <1>;
+                       gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+               };
+
+               led-4 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_LAN;
+                       function-enumerator = <2>;
+                       gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
+               };
+
+               led-5 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_LAN;
+                       function-enumerator = <3>;
+                       gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+               };
+
+               led-6 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_LAN;
+                       function-enumerator = <4>;
+                       gpios = <&gpio2 4 GPIO_ACTIVE_LOW>;
+               };
+
+               led-7 {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_WLAN;
+                       function-enumerator = <24>;
+                       gpios = <&gpio3 0 GPIO_ACTIVE_LOW>;
+                       linux,default-trigger = "phy1tpt";
+               };
+       };
+
+       virtual_flash {
+               compatible = "mtd-concat";
+
+               devices = <&fwconcat0 &fwconcat1>;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       partition@0 {
+                               compatible = "openwrt,uimage";
+                               /* sercomm krnl hdr with fw chksums */
+                               openwrt,offset = <0x100>;
+                               label = "firmware";
+                               reg = <0x0 0x0>;
+                       };
+               };
+       };
+};
+
+&ethernet {
+       nvmem-cells = <&macaddr_label 0>;
+       nvmem-cell-names = "mac-address";
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gpio2 {
+       status = "okay";
+};
+
+&gpio3 {
+       status = "okay";
+};
+
+&pcie {
+       status = "okay";
+};
+
+/* mt7612 */
+&pcie0 {
+       wifi@0,0 {
+               compatible = "mediatek,mt76";
+               reg = <0x0000 0 0 0 0>;
+               ieee80211-freq-limit = <5000000 6000000>;
+
+               nvmem-cells = <&eeprom_factory_8000>, <&macaddr_label 6>;
+               nvmem-cell-names = "eeprom", "mac-address";
+
+               /* 5 GHz WLAN phy green led */
+               led {
+                       led-sources = <2>;
+                       led-active-low;
+               };
+       };
+};
+
+&spi0 {
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <70000000>;
+               m25p,fast-read;
+
+               partitions {
+                       compatible = "fixed-partitions";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       /* whole flash */
+                       partition@0_all {
+                               label = "ALL";
+                               reg = <0x0 0x1000000>;
+                               read-only;
+                       };
+
+                       partition@0 {
+                               label = "u-boot";
+                               reg = <0x0 0x30000>;
+                               read-only;
+                       };
+
+                       partition@30000 {
+                               label = "ftd_and_bootflag";
+                               reg = <0x30000 0x20000>;
+                       };
+
+                       partition@50000 {
+                               label = "Factory";
+                               reg = <0x50000 0x10000>;
+                               read-only;
+
+                               nvmem-layout {
+                                       compatible = "fixed-layout";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       eeprom_factory_0: eeprom@0 {
+                                               reg = <0x0 0x200>;
+                                       };
+
+                                       eeprom_factory_8000: eeprom@8000 {
+                                               reg = <0x8000 0x200>;
+                                       };
+                               };
+                       };
+
+                       partition@60000 {
+                               label = "SC Nvram(permanent data)";
+                               reg = <0x60000 0x10000>;
+                               read-only;
+
+                               nvmem-layout {
+                                       compatible = "fixed-layout";
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       macaddr_label: macaddr@0 {
+                                               compatible = "mac-base";
+                                               reg = <0x0 0x6>;
+                                               #nvmem-cell-cells = <1>;
+                                       };
+                               };
+                       };
+
+                       fwconcat0: partition@70000 {
+                               label = "Firmware";
+                               reg = <0x70000 0x790000>;
+
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               partition@0 {
+                                       label = "Kernel";
+                                       reg = <0x0 0x200000>;
+                               };
+
+                               partition@200000 {
+                                       label = "RootFS";
+                                       reg = <0x200000 0x590000>;
+                               };
+                       };
+
+                       fwconcat1: partition@800000 {
+                               label = "Firmware2";
+                               reg = <0x800000 0x790000>;
+
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               partition@0 {
+                                       label = "Kernel2";
+                                       reg = <0x0 0x200000>;
+                               };
+
+                               partition@200000 {
+                                       label = "RootFS2";
+                                       reg = <0x200000 0x590000>;
+                               };
+                       };
+
+                       partition@f90000 {
+                               label = "MAC IP";
+                               reg = <0xf90000 0x10000>;
+                               read-only;
+                       };
+
+                       partition@fa0000 {
+                               label = "Critical Log";
+                               reg = <0xfa0000 0x10000>;
+                               read-only;
+                       };
+
+                       partition@fb000 {
+                               label = "Critical Log Bak";
+                               reg = <0xfb0000 0x10000>;
+                               read-only;
+                       };
+
+                       partition@fc0000 {
+                               label = "Xml Config";
+                               reg = <0xfc0000 0x20000>;
+                               read-only;
+                       };
+
+                       partition@fe0000 {
+                               label = "Xml Config Bak";
+                               reg = <0xfe0000 0x20000>;
+                               read-only;
+                       };
+               };
+       };
+};
+
+&state_default {
+       gpio {
+               groups = "ephy", "rgmii1", "uartf", "wled";
+               function = "gpio";
+       };
+};
+
+/* mt7620 */
+&wmac {
+       nvmem-cells = <&eeprom_factory_0>, <&macaddr_label 2>;
+       nvmem-cell-names = "eeprom", "mac-address";
+};
index 182f2251ba78e03ba829306c21223fd55fae505d..0987010911209a308182d17f7225f8deb00ba6dc 100644 (file)
@@ -23,6 +23,35 @@ define Build/sercomm-crypto
        rm -f $@.enc $@.key
 endef
 
+define Build/sercomm-factory-cpj
+       dd bs=$$((0x1fff00)) count=1 if=$@ of=$@.kernel conv=notrunc \
+               2>/dev/null
+       dd bs=$$((0x1fff00)) skip=1 if=$@ of=$@.rootfs1 conv=notrunc \
+               2>/dev/null
+       cp $@.rootfs1 $@.rootfs2
+       $(TOPDIR)/scripts/sercomm-kernel-header.py \
+               --kernel-image $@.kernel \
+               --kernel-offset $(SERCOMM_KERNEL_OFFSET) \
+               --rootfs-image $@.rootfs1 \
+               --rootfs-offset $(SERCOMM_ROOTFS_OFFSET) \
+               --output-header $@.header1
+       $(TOPDIR)/scripts/sercomm-kernel-header.py \
+               --kernel-image $@.kernel \
+               --kernel-offset $(SERCOMM_KERNEL2_OFFSET) \
+               --rootfs-image $@.rootfs2 \
+               --rootfs-offset $(SERCOMM_ROOTFS2_OFFSET) \
+               --output-header $@.header2
+       cat $@.header1 $@.kernel > $@.kernel1
+       cat $@.header2 $@.kernel > $@.kernel2
+       rm $@.header1 $@.header2 $@.kernel
+       $(call Build/sercomm-part-tag-common,kernel $@.kernel1)
+       $(call Build/sercomm-part-tag-common,kernel2 $@.kernel2)
+       $(call Build/sercomm-part-tag-common,rootfs $@.rootfs1)
+       $(call Build/sercomm-part-tag-common,rootfs2 $@.rootfs2)
+       cat $@.kernel2 $@.rootfs2 $@.kernel1 $@.rootfs1 > $@
+       rm $@.kernel1 $@.rootfs1 $@.kernel2 $@.rootfs2
+endef
+
 define Build/sercomm-factory-cqr
        $(TOPDIR)/scripts/sercomm-pid.py \
                --hw-version $(SERCOMM_HWVER) \
@@ -117,12 +146,46 @@ define Build/sercomm-reset-slot1-chksum
                dd of=$@ seek=$$((0x118)) bs=1 conv=notrunc 2>/dev/null
 endef
 
+define Build/sercomm-sysupgrade-cpj
+       dd bs=$$((0x1fff00)) count=1 if=$@ of=$@.kernel conv=notrunc \
+               2>/dev/null
+       dd bs=$$((0x1fff00)) skip=1 if=$@ of=$@.rootfs conv=notrunc \
+               2>/dev/null
+       $(TOPDIR)/scripts/sercomm-kernel-header.py \
+               --kernel-image $@.kernel \
+               --kernel-offset $(SERCOMM_KERNEL_OFFSET) \
+               --rootfs-image $@.rootfs \
+               --rootfs-offset $(SERCOMM_ROOTFS_OFFSET) \
+               --output-header $@.header
+       cat $@.header $@.kernel $@.rootfs > $@
+       rm $@.header $@.kernel $@.rootfs
+endef
+
 define Device/sercomm
   $(Device/nand)
   LOADER_TYPE := bin
   IMAGES += factory.img
 endef
 
+define Device/sercomm_cpj
+  SOC := mt7620a
+  DEVICE_VENDOR := Rostelecom
+  DEVICE_ALT0_VENDOR := Sercomm
+  IMAGE_SIZE := 7743k
+  SERCOMM_HWID := CPJ
+  SERCOMM_HWVER := 10000
+  SERCOMM_SWVER := 1001
+  SERCOMM_KERNEL_OFFSET := 0x70100
+  SERCOMM_ROOTFS_OFFSET := 0x270000
+  SERCOMM_KERNEL2_OFFSET := 0x800100
+  SERCOMM_ROOTFS2_OFFSET := 0xa00000
+  IMAGE/sysupgrade.bin := append-kernel | append-rootfs | \
+       sercomm-sysupgrade-cpj | pad-rootfs | check-size | \
+       append-metadata
+  ARTIFACTS := initramfs-factory.img
+  DEVICE_PACKAGES := kmod-mt76x2
+endef
+
 define Device/sercomm_cxx_dxx
   $(Device/sercomm)
   KERNEL_SIZE := 6144k
index f85f3c8521e8604b6c8d2968d40e884362df340f..883aacabe06268d3791ab00d201fc13ea1e63c91 100644 (file)
@@ -2,6 +2,7 @@
 # MT7620A Profiles
 #
 
+include ./common-sercomm.mk
 include ./common-tp-link.mk
 
 DEVICE_VARS += DLINK_ROM_ID DLINK_FAMILY_MEMBER DLINK_FIRMWARE_SIZE DLINK_IMAGE_OFFSET
@@ -1102,6 +1103,27 @@ define Device/ravpower_rp-wd03
 endef
 TARGET_DEVICES += ravpower_rp-wd03
 
+define Device/rostelecom_rt-fl-1
+  $(Device/sercomm_cpj)
+  DEVICE_MODEL := RT-FL-1
+  DEVICE_ALT0_MODEL := RT-FL-1
+  ARTIFACT/initramfs-factory.img := \
+       append-image-stage initramfs-kernel.bin | check-size | \
+       sercomm-factory-cpj | gzip | sercomm-payload | \
+       sercomm-pid-setbit 0x11 | sercomm-crypto
+endef
+TARGET_DEVICES += rostelecom_rt-fl-1
+
+define Device/rostelecom_s1010
+  $(Device/sercomm_cpj)
+  DEVICE_MODEL := S1010
+  DEVICE_ALT0_MODEL := S1010.RT
+  ARTIFACT/initramfs-factory.img := \
+       append-image-stage initramfs-kernel.bin | check-size | \
+       sercomm-factory-cpj | gzip | sercomm-payload | sercomm-crypto
+endef
+TARGET_DEVICES += rostelecom_s1010
+
 define Device/sanlinking_d240
   SOC := mt7620a
   IMAGE_SIZE := 16064k
index 22e79ca755319959ee60b17141e30b4b9b51d30e..c4f7fcbb8762b5d23989d1101a3e63c17bce2ec0 100644 (file)
@@ -208,6 +208,14 @@ zbtlink,zbt-we826-e)
 ravpower,rp-wd03)
        ucidef_set_led_netdev "internet" "internet" "green:wifi" "eth0"
        ;;
+rostelecom,rt-fl-1|\
+rostelecom,s1010)
+       ucidef_set_led_switch "lan-1" "lan-1" "green:lan-1" "switch0" "0x02"
+       ucidef_set_led_switch "lan-2" "lan-2" "green:lan-2" "switch0" "0x04"
+       ucidef_set_led_switch "lan-3" "lan-3" "green:lan-3" "switch0" "0x08"
+       ucidef_set_led_switch "lan-4" "lan-4" "green:lan-4" "switch0" "0x10"
+       ucidef_set_led_switch "wan" "wan" "green:wan" "switch0" "0x01"
+       ;;
 tplink,archer-c2-v1)
        ucidef_set_led_switch "lan" "lan" "green:lan" "switch1" "0x1e"
        ucidef_set_led_switch "wan" "wan" "green:wan" "switch1" "0x01"
index a31fa2bc13dd9f812ae1e76650124f48836eb18f..cbfb8a1d863f31bcee32135fbfcd9dc93611f3fd 100644 (file)
@@ -119,6 +119,8 @@ ramips_setup_interfaces()
        netgear,jwnr2010-v5|\
        phicomm,k2-v22.4|\
        phicomm,k2-v22.5|\
+       rostelecom,rt-fl-1|\
+       rostelecom,s1010|\
        trendnet,tew-810dr|\
        zbtlink,zbt-we2026)
                ucidef_add_switch "switch0" \
@@ -392,6 +394,11 @@ ramips_setup_macs()
        linksys,e1700)
                wan_mac=$(mtd_get_mac_ascii config WAN_MAC_ADDR)
                ;;
+       rostelecom,rt-fl-1|\
+       rostelecom,s1010)
+               label_mac=$(mtd_get_mac_binary "SC Nvram(permanent data)" 0x0)
+               wan_mac=$(macaddr_add "$label_mac" 10)
+               ;;
        snr,cpe-w4n-mt)
                lan_mac=$(mtd_get_mac_binary Factory 0x28)
                wan_mac=$(mtd_get_mac_binary Factory 0x2e)
index 9f71dc918e50a21d3d14a077a4f4252e39267a68..6dd7fc7cef1af4ab8b93bdfc260e20f2ed798aac 100755 (executable)
@@ -30,6 +30,14 @@ platform_do_upgrade() {
                }
                default_do_upgrade "$1"
                ;;
+       rostelecom,rt-fl-1|\
+       rostelecom,s1010)
+               idx="$(find_mtd_index ftd_and_bootflag)"
+               [ -n "$idx" ] && \
+                       printf 0 | dd bs=1 seek=$((0x18007)) count=1 \
+                               of=/dev/mtdblock$idx
+               default_do_upgrade "$1"
+               ;;
        *)
                default_do_upgrade "$1"
                ;;