diff mbox

[OpenWrt-Devel,v5] Add support for Ubiquiti EdgeRouter X (UBNT-ERX)

Message ID 1449126984-4711-1-git-send-email-mar.kolya@gmail.com
State Superseded
Headers show

Commit Message

Nikolay Martynov Dec. 3, 2015, 7:16 a.m. UTC
This router is based on MT7621 SoC, no wifi, nand.

Works:
* Boots.
* Ethernet.
* Switch.
* Button (reset).
* Flashing OpenWrt from stock firmware.
* Upgrading OpenWrt.

Doesn't work:
* No GPIO leds. All leds are controlled by switch,
  but stock firmware was able to control them.
* SoC has crypto engine but no open driver.
* SoC has nat acceleration, but no open driver.
* This router has 2MB spi flash soldered in but MT
  nand/spi drivers do not support pin sharing,
  so it is not accessable and disabled. Stock
  firmware could read it and it was empty.

Unknown status: PoE support.

Router has serial pins populated. If looking at the top
of the router, then counting from Eth sockets pins go as:
'GND, RX, TX, GND'. 3.3v, 57600.

U-boot bootloader supports tftpboot, controlled from serial.
This router has two kernel partitions: 'live' and 'backup'.
They are swapped during flashing (on both stock and OpenWrt).
Active partition is controlled by a flag in factory partition.
U-boot has cusotm command to switch active kernel partition.
Kernel partitions are 'bare flash' 3MB. Stock bootloader has
no UBI support. Stock rootfs is UBIFS.

Flashing procedure.
Stock firmware uses custom kernel patch to mount squashfs
from a file that is located on UBIFS volume. This makes wiping
out this volume from within stock firmware difficult.
Instead this patch builds image that is flashable by stock firmware
and contains initrams image (with minimal set of packages
to fit into kernel partition). Once this is flashed one can reboot
into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
rootfs into nand.
Note: factory image is only built if initramfs image is enabled.

v2: Fix building all mt7621 targets along with ubnt-erx.
v3: Undo change to MT7621 nand partitions, make nand detection
    less likely to affect other nands.
v4: Update as per Piotr Dymacz comments.
v5: Fix upgrading code to actually upgrade kernel.

Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
---
 package/system/procd/files/nand.sh                 |   4 +
 .../linux/ramips/base-files/etc/board.d/02_network |   1 +
 target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
 .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
 target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
 target/linux/ramips/dts/MT7621.dts                 |  22 ++++
 target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
 target/linux/ramips/dts/mt7621.dtsi                |  20 ----
 target/linux/ramips/image/Makefile                 |  61 ++++++++++-
 target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
 .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
 11 files changed, 363 insertions(+), 22 deletions(-)
 create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
 create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
 create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
 create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch

Comments

Nikolay Martynov Dec. 9, 2015, 3:34 p.m. UTC | #1
Hi.

  I know you guys a probably very busy, but could you please confirm
that this is the right list to submit such patches and format of this
patch is correct - so I could fix it if it's not.

Thanks!

2015-12-03 2:16 GMT-05:00 Nikolay Martynov <mar.kolya@gmail.com>:
> This router is based on MT7621 SoC, no wifi, nand.
>
> Works:
> * Boots.
> * Ethernet.
> * Switch.
> * Button (reset).
> * Flashing OpenWrt from stock firmware.
> * Upgrading OpenWrt.
>
> Doesn't work:
> * No GPIO leds. All leds are controlled by switch,
>   but stock firmware was able to control them.
> * SoC has crypto engine but no open driver.
> * SoC has nat acceleration, but no open driver.
> * This router has 2MB spi flash soldered in but MT
>   nand/spi drivers do not support pin sharing,
>   so it is not accessable and disabled. Stock
>   firmware could read it and it was empty.
>
> Unknown status: PoE support.
>
> Router has serial pins populated. If looking at the top
> of the router, then counting from Eth sockets pins go as:
> 'GND, RX, TX, GND'. 3.3v, 57600.
>
> U-boot bootloader supports tftpboot, controlled from serial.
> This router has two kernel partitions: 'live' and 'backup'.
> They are swapped during flashing (on both stock and OpenWrt).
> Active partition is controlled by a flag in factory partition.
> U-boot has cusotm command to switch active kernel partition.
> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
> no UBI support. Stock rootfs is UBIFS.
>
> Flashing procedure.
> Stock firmware uses custom kernel patch to mount squashfs
> from a file that is located on UBIFS volume. This makes wiping
> out this volume from within stock firmware difficult.
> Instead this patch builds image that is flashable by stock firmware
> and contains initrams image (with minimal set of packages
> to fit into kernel partition). Once this is flashed one can reboot
> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
> rootfs into nand.
> Note: factory image is only built if initramfs image is enabled.
>
> v2: Fix building all mt7621 targets along with ubnt-erx.
> v3: Undo change to MT7621 nand partitions, make nand detection
>     less likely to affect other nands.
> v4: Update as per Piotr Dymacz comments.
> v5: Fix upgrading code to actually upgrade kernel.
>
> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
> ---
>  package/system/procd/files/nand.sh                 |   4 +
>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>  11 files changed, 363 insertions(+), 22 deletions(-)
>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>
> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
> index 0c179cb..67867da 100644
> --- a/package/system/procd/files/nand.sh
> +++ b/package/system/procd/files/nand.sh
> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>  nand_do_upgrade_stage2() {
>         local file_type=$(identify $1)
>
> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
> +           platform_nand_pre_upgrade "$1"
> +       fi
> +
>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>
>         case "$file_type" in
> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
> index 7e51229..de81553 100755
> --- a/target/linux/ramips/base-files/etc/board.d/02_network
> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>         f5d8235-v2|\
>         hg255d|\
>         rt-n14u|\
> +       ubnt-erx|\
>         ur-326n4g|\
>         wrtnode|\
>         wt3020|\
> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
> index 92e13c0..ba23939 100755
> --- a/target/linux/ramips/base-files/lib/ramips.sh
> +++ b/target/linux/ramips/base-files/lib/ramips.sh
> @@ -349,6 +349,9 @@ ramips_board_detect() {
>         *"TEW-692GR")
>                 name="tew-692gr"
>                 ;;
> +       *"UBNT-ERX")
> +               name="ubnt-erx"
> +               ;;
>         *"UR-326N4G")
>                 name="ur-326n4g"
>                 ;;
> @@ -396,7 +399,7 @@ ramips_board_detect() {
>                 ;;
>         *"WizFi630A")
>                 name="wizfi630a"
> -               ;;
> +               ;;
>         *"WL-330N")
>                 name="wl-330n"
>                 ;;
> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
> index 073593a..b0d624e 100755
> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
> @@ -181,12 +181,36 @@ platform_check_image() {
>                 }
>                 return 0
>                 ;;
> +       ubnt-erx)
> +               nand_do_platform_check "$board" "$1"
> +               return $?;
> +               ;;
>         esac
>
>         echo "Sysupgrade is not yet supported on $board."
>         return 1
>  }
>
> +platform_nand_pre_upgrade() {
> +       local board=$(ramips_board_name)
> +
> +       case "$board" in
> +       ubnt-erx)
> +               platform_upgrade_ubnt_erx "$ARGV"
> +               ;;
> +       esac
> +}
> +
> +platform_pre_upgrade() {
> +       local board=$(ramips_board_name)
> +
> +       case "$board" in
> +       ubnt-erx)
> +               nand_do_upgrade "$ARGV"
> +               ;;
> +       esac
> +}
> +
>  platform_do_upgrade() {
>         local board=$(ramips_board_name)
>
> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
> new file mode 100644
> index 0000000..0dc602b
> --- /dev/null
> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
> @@ -0,0 +1,71 @@
> +#
> +# Copyright (C) 2015 OpenWrt.org
> +#
> +
> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
> +
> +ubnt_get_target_kernel() {
> +        local factory_mtd=$1
> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
> +
> +       if [ $current_kernel_index == "0" ]; then
> +            echo 'kernel2'
> +       elif [ $current_kernel_index == "1" ]; then
> +            echo 'kernel1'
> +       fi
> +}
> +
> +ubnt_update_target_kernel() {
> +       local factory_mtd=$1
> +       local kernel_part=$2
> +
> +       local new_kernel_index
> +       if [ $kernel_part == "kernel1" ]; then
> +            new_kernel_index="\x00"
> +       elif [ $kernel_part == "kernel2" ]; then
> +            new_kernel_index="\x01"
> +       else
> +           echo 'Unknown kernel image index'
> +            exit 1
> +       fi
> +
> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
> +            echo 'Failed to update kernel bootup index'
> +            exit 1
> +       fi
> +}
> +
> +platform_upgrade_ubnt_erx() {
> +       local factory_mtd=$(find_mtd_part factory)
> +       if [ ! -n "$factory_mtd" ]; then
> +               echo "cannot find factory partition"
> +               exit 1
> +       fi
> +
> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
> +       if [ ! -n "$kernel_part" ]; then
> +               echo "cannot find factory partition"
> +               exit 1
> +       fi
> +
> +       CI_KERNPART=${kernel_part}
> +
> +       #Remove volume possibly left over from stock firmware
> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
> +       if [ ! "$ubidev" ]; then
> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
> +               if [ ! "$mtdnum" ]; then
> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
> +                       return 1
> +               fi
> +               ubiattach -m "$mtdnum"
> +               sync
> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
> +       fi
> +       if [ -n "$ubidev" ]; then
> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
> +       fi
> +
> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
> +}
> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
> index c90fc95..96f3416 100644
> --- a/target/linux/ramips/dts/MT7621.dts
> +++ b/target/linux/ramips/dts/MT7621.dts
> @@ -31,4 +31,26 @@
>                         };
>                 };
>         };
> +
> +       nand@1e003000 {
> +               partition@0 {
> +                       label = "uboot";
> +                       reg = <0x00000 0x80000>; /* 64 KB */
> +               };
> +
> +               partition@80000 {
> +                       label = "uboot_env";
> +                       reg = <0x80000 0x80000>; /* 64 KB */
> +               };
> +
> +               partition@100000 {
> +                       label = "factory";
> +                       reg = <0x100000 0x40000>;
> +               };
> +
> +               partition@140000 {
> +                       label = "rootfs";
> +                       reg = <0x140000 0xec0000>;
> +               };
> +       };
>  };
> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
> new file mode 100644
> index 0000000..4aa3be9
> --- /dev/null
> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
> @@ -0,0 +1,117 @@
> +/dts-v1/;
> +
> +/include/ "mt7621.dtsi"
> +
> +/ {
> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
> +       model = "UBNT-ERX";
> +
> +       memory@0 {
> +               device_type = "memory";
> +               reg = <0x0 0x10000000>;
> +       };
> +
> +       chosen {
> +               bootargs = "console=ttyS0,57600";
> +       };
> +
> +       palmbus@1E000000 {
> +               spi@b00 {
> +                       /* This board has 2Mb spi flash soldered in and visible
> +                          from manufacturer's firmware.
> +                          But this SoC shares spi and nand pins,
> +                          and current driver desn't handle this sharing well */
> +                       status = "disabled";
> +                       m25p80@0 {
> +                               #address-cells = <1>;
> +                               #size-cells = <1>;
> +                               compatible = "m25p80";
> +                               reg = <1>;
> +                               linux,modalias = "m25p80";
> +                               spi-max-frequency = <10000000>;
> +
> +                               partition@0 {
> +                                       label = "spi";
> +                                       reg = <0x0 0x200000>;
> +                                       read-only;
> +                               };
> +                       };
> +               };
> +       };
> +
> +       nand@1e003000 {
> +               compatible = "mtk,mt7621-nand";
> +               bank-width = <2>;
> +               reg = <0x1e003000 0x800
> +                      0x1e003800 0x800>;
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +
> +               partition@0 {
> +                       label = "u-boot";
> +                       reg = <0x0 0x80000>;
> +                       read-only;
> +               };
> +
> +               partition@80000 {
> +                       label = "u-boot-env";
> +                       reg = <0x80000 0x60000>;
> +                       read-only;
> +               };
> +
> +               factory: partition@e0000 {
> +                       label = "factory";
> +                       reg = <0xe0000 0x60000>;
> +               };
> +
> +               partition@140000 {
> +                       label = "kernel1";
> +                       reg = <0x140000 0x300000>;
> +               };
> +
> +               partition@440000 {
> +                       label = "kernel2";
> +                       reg = <0x440000 0x300000>;
> +               };
> +
> +               partition@740000 {
> +                       label = "ubi";
> +                       reg = <0x740000 0xf7c0000>;
> +               };
> +
> +       };
> +
> +       ethernet@1e100000 {
> +               mtd-mac-address = <&factory 0x22>;
> +       };
> +
> +       pinctrl {
> +               state_default: pinctrl0 {
> +                       gpio {
> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
> +                               ralink,function = "gpio";
> +                       };
> +               };
> +       };
> +
> +       sdhci@1E130000 {
> +               status = "disabled";
> +       };
> +
> +       pcie@1e140000 {
> +               status = "disabled";
> +       };
> +
> +       gpio-keys-polled {
> +               compatible = "gpio-keys-polled";
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               poll-interval = <20>;
> +
> +               reset {
> +                       label = "reset";
> +                       gpios = <&gpio0 12 1>;
> +                       linux,code = <0x198>;
> +               };
> +       };
> +};
> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
> index fd2e100..c29a040 100644
> --- a/target/linux/ramips/dts/mt7621.dtsi
> +++ b/target/linux/ramips/dts/mt7621.dtsi
> @@ -241,26 +241,6 @@
>                         0x1e003800 0x800>;
>                 #address-cells = <1>;
>                 #size-cells = <1>;
> -
> -               partition@0 {
> -                       label = "uboot";
> -                       reg = <0x00000 0x80000>; /* 64 KB */
> -               };
> -
> -               partition@80000 {
> -                       label = "uboot_env";
> -                       reg = <0x80000 0x80000>; /* 64 KB */
> -               };
> -
> -               partition@100000 {
> -                       label = "factory";
> -                       reg = <0x100000 0x40000>;
> -               };
> -
> -               partition@140000 {
> -                       label = "rootfs";
> -                       reg = <0x140000 0xec0000>;
> -               };
>         };
>
>         ethernet@1e100000 {
> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
> index 00a2923..6230688 100644
> --- a/target/linux/ramips/image/Makefile
> +++ b/target/linux/ramips/image/Makefile
> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>         mv $@.new $@
>  endef
>
> +define Build/ubnt-erx-factory-compat
> +       echo '21001:6' > $@.compat
> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
> +       $(RM) $@.compat
> +endef
> +
> +define Build/ubnt-erx-factory-kernel
> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
> +               \
> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
> +               $(RM) $@.md5; \
> +       fi
> +endef
> +
> +define Build/ubnt-erx-factory-rootfs
> +       echo "dummy" > $@.rootfs
> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
> +
> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
> +       $(RM) $@.md5
> +       $(RM) $@.rootfs
> +endef
> +
> +define Build/ubnt-erx-factory-version
> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
> +       $(RM) $@.version
> +endef
> +
> +#We need kernel+initrams fit into kernel partition
> +define Build/ubnt-erx-factory-check-size
> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
> +               $(RM) -f $@; \
> +       }
> +
> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
> +               echo "WARNING: Kernel for image $@ not found" >&2; \
> +               $(RM) -f $@; \
> +       }
> +endef
> +
>  define MkCombineduImage
>         $(call PatchKernelLzma,$(2),$(3))
>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
> @@ -954,7 +999,7 @@ endif
>  #
>
>  ifeq ($(SUBTARGET),mt7621)
> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>  endif
>
>  define Device/mt7621
> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>  endef
>
> +define Device/ubnt-erx
> +  DTS := UBNT-ERX
> +  FILESYSTEMS := squashfs
> +  KERNEL_SIZE := 3145728
> +  KERNEL := $(KERNEL_DTB) | uImage lzma
> +  IMAGES := sysupgrade.tar factory-initramfs.tar
> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
> +                                ubnt-erx-factory-kernel | \
> +                                ubnt-erx-factory-rootfs | \
> +                                ubnt-erx-factory-version | \
> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
> +  IMAGE/sysupgrade.tar := sysupgrade-nand
> +endef
> +
>  #
>  # MT7628 Profiles
>  #
> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
> new file mode 100644
> index 0000000..67efa60
> --- /dev/null
> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
> @@ -0,0 +1,17 @@
> +#
> +# Copyright (C) 2015 OpenWrt.org
> +#
> +# This is free software, licensed under the GNU General Public License v2.
> +# See /LICENSE for more information.
> +#
> +
> +define Profile/UBNT-ERX
> +       NAME:=Ubiquiti EdgeRouter X
> +       FEATURES += nand
> +       PACKAGES:=-kmod-mt76 -wpad-mini
> +endef
> +
> +define Profile/UBNT-ERX/Description
> +       Package set compatible with the Ubiquiti EdgeRouter X
> +endef
> +$(eval $(call Profile,UBNT-ERX))
> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
> new file mode 100644
> index 0000000..a327674
> --- /dev/null
> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
> @@ -0,0 +1,43 @@
> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
> +From: Nikolay Martynov <mar.kolya@gmail.com>
> +Date: Wed, 25 Nov 2015 20:43:46 -0500
> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
> +
> +According to datasheet S34ML02G2 and S34ML04G2 have
> +larger sparea area size than was detected.
> +
> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
> +---
> + drivers/mtd/nand/nand_base.c | 9 +++++++++
> + 1 file changed, 9 insertions(+)
> +
> +--- a/drivers/mtd/nand/nand_base.c
> ++++ b/drivers/mtd/nand/nand_base.c
> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
> +       /*
> +        * Field definitions are in the following datasheets:
> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
> ++       *                          Spansion S34ML02G2 (p.33)
> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
> +        *
> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
> +
> +               /*
> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
> ++               * as S34ML01G2 encoded in the same bit. We
> ++               * differinciate them by their ID length
> ++               */
> ++              if (id_data[0] == NAND_MFR_AMD
> ++                              && (id_data[1] == 0xda
> ++                               || id_data[1] == 0xdc
> ++                               || id_data[1] == 0xca
> ++                               || id_data[1] == 0xcc)) {
> ++                      mtd->oobsize *= 2;
> ++              }
> ++
> ++              /*
> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
> +                * follows:
> --
> 2.6.3
>
John Crispin Dec. 10, 2015, 8:29 a.m. UTC | #2
it is the correct list, just been real busy this week with other stuff.
i'll be merging stuff again as of the weekend, sorry for the delay.

On 09/12/2015 16:34, Nikolay Martynov wrote:
> Hi.
> 
>   I know you guys a probably very busy, but could you please confirm
> that this is the right list to submit such patches and format of this
> patch is correct - so I could fix it if it's not.
> 
> Thanks!
> 
> 2015-12-03 2:16 GMT-05:00 Nikolay Martynov <mar.kolya@gmail.com>:
>> This router is based on MT7621 SoC, no wifi, nand.
>>
>> Works:
>> * Boots.
>> * Ethernet.
>> * Switch.
>> * Button (reset).
>> * Flashing OpenWrt from stock firmware.
>> * Upgrading OpenWrt.
>>
>> Doesn't work:
>> * No GPIO leds. All leds are controlled by switch,
>>   but stock firmware was able to control them.
>> * SoC has crypto engine but no open driver.
>> * SoC has nat acceleration, but no open driver.
>> * This router has 2MB spi flash soldered in but MT
>>   nand/spi drivers do not support pin sharing,
>>   so it is not accessable and disabled. Stock
>>   firmware could read it and it was empty.
>>
>> Unknown status: PoE support.
>>
>> Router has serial pins populated. If looking at the top
>> of the router, then counting from Eth sockets pins go as:
>> 'GND, RX, TX, GND'. 3.3v, 57600.
>>
>> U-boot bootloader supports tftpboot, controlled from serial.
>> This router has two kernel partitions: 'live' and 'backup'.
>> They are swapped during flashing (on both stock and OpenWrt).
>> Active partition is controlled by a flag in factory partition.
>> U-boot has cusotm command to switch active kernel partition.
>> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
>> no UBI support. Stock rootfs is UBIFS.
>>
>> Flashing procedure.
>> Stock firmware uses custom kernel patch to mount squashfs
>> from a file that is located on UBIFS volume. This makes wiping
>> out this volume from within stock firmware difficult.
>> Instead this patch builds image that is flashable by stock firmware
>> and contains initrams image (with minimal set of packages
>> to fit into kernel partition). Once this is flashed one can reboot
>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>> rootfs into nand.
>> Note: factory image is only built if initramfs image is enabled.
>>
>> v2: Fix building all mt7621 targets along with ubnt-erx.
>> v3: Undo change to MT7621 nand partitions, make nand detection
>>     less likely to affect other nands.
>> v4: Update as per Piotr Dymacz comments.
>> v5: Fix upgrading code to actually upgrade kernel.
>>
>> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>> ---
>>  package/system/procd/files/nand.sh                 |   4 +
>>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>>  11 files changed, 363 insertions(+), 22 deletions(-)
>>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>
>> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
>> index 0c179cb..67867da 100644
>> --- a/package/system/procd/files/nand.sh
>> +++ b/package/system/procd/files/nand.sh
>> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>>  nand_do_upgrade_stage2() {
>>         local file_type=$(identify $1)
>>
>> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
>> +           platform_nand_pre_upgrade "$1"
>> +       fi
>> +
>>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>>
>>         case "$file_type" in
>> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
>> index 7e51229..de81553 100755
>> --- a/target/linux/ramips/base-files/etc/board.d/02_network
>> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
>> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>>         f5d8235-v2|\
>>         hg255d|\
>>         rt-n14u|\
>> +       ubnt-erx|\
>>         ur-326n4g|\
>>         wrtnode|\
>>         wt3020|\
>> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
>> index 92e13c0..ba23939 100755
>> --- a/target/linux/ramips/base-files/lib/ramips.sh
>> +++ b/target/linux/ramips/base-files/lib/ramips.sh
>> @@ -349,6 +349,9 @@ ramips_board_detect() {
>>         *"TEW-692GR")
>>                 name="tew-692gr"
>>                 ;;
>> +       *"UBNT-ERX")
>> +               name="ubnt-erx"
>> +               ;;
>>         *"UR-326N4G")
>>                 name="ur-326n4g"
>>                 ;;
>> @@ -396,7 +399,7 @@ ramips_board_detect() {
>>                 ;;
>>         *"WizFi630A")
>>                 name="wizfi630a"
>> -               ;;
>> +               ;;
>>         *"WL-330N")
>>                 name="wl-330n"
>>                 ;;
>> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> index 073593a..b0d624e 100755
>> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> @@ -181,12 +181,36 @@ platform_check_image() {
>>                 }
>>                 return 0
>>                 ;;
>> +       ubnt-erx)
>> +               nand_do_platform_check "$board" "$1"
>> +               return $?;
>> +               ;;
>>         esac
>>
>>         echo "Sysupgrade is not yet supported on $board."
>>         return 1
>>  }
>>
>> +platform_nand_pre_upgrade() {
>> +       local board=$(ramips_board_name)
>> +
>> +       case "$board" in
>> +       ubnt-erx)
>> +               platform_upgrade_ubnt_erx "$ARGV"
>> +               ;;
>> +       esac
>> +}
>> +
>> +platform_pre_upgrade() {
>> +       local board=$(ramips_board_name)
>> +
>> +       case "$board" in
>> +       ubnt-erx)
>> +               nand_do_upgrade "$ARGV"
>> +               ;;
>> +       esac
>> +}
>> +
>>  platform_do_upgrade() {
>>         local board=$(ramips_board_name)
>>
>> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>> new file mode 100644
>> index 0000000..0dc602b
>> --- /dev/null
>> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>> @@ -0,0 +1,71 @@
>> +#
>> +# Copyright (C) 2015 OpenWrt.org
>> +#
>> +
>> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
>> +
>> +ubnt_get_target_kernel() {
>> +        local factory_mtd=$1
>> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
>> +
>> +       if [ $current_kernel_index == "0" ]; then
>> +            echo 'kernel2'
>> +       elif [ $current_kernel_index == "1" ]; then
>> +            echo 'kernel1'
>> +       fi
>> +}
>> +
>> +ubnt_update_target_kernel() {
>> +       local factory_mtd=$1
>> +       local kernel_part=$2
>> +
>> +       local new_kernel_index
>> +       if [ $kernel_part == "kernel1" ]; then
>> +            new_kernel_index="\x00"
>> +       elif [ $kernel_part == "kernel2" ]; then
>> +            new_kernel_index="\x01"
>> +       else
>> +           echo 'Unknown kernel image index'
>> +            exit 1
>> +       fi
>> +
>> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
>> +            echo 'Failed to update kernel bootup index'
>> +            exit 1
>> +       fi
>> +}
>> +
>> +platform_upgrade_ubnt_erx() {
>> +       local factory_mtd=$(find_mtd_part factory)
>> +       if [ ! -n "$factory_mtd" ]; then
>> +               echo "cannot find factory partition"
>> +               exit 1
>> +       fi
>> +
>> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
>> +       if [ ! -n "$kernel_part" ]; then
>> +               echo "cannot find factory partition"
>> +               exit 1
>> +       fi
>> +
>> +       CI_KERNPART=${kernel_part}
>> +
>> +       #Remove volume possibly left over from stock firmware
>> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>> +       if [ ! "$ubidev" ]; then
>> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
>> +               if [ ! "$mtdnum" ]; then
>> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
>> +                       return 1
>> +               fi
>> +               ubiattach -m "$mtdnum"
>> +               sync
>> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>> +       fi
>> +       if [ -n "$ubidev" ]; then
>> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
>> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
>> +       fi
>> +
>> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
>> +}
>> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
>> index c90fc95..96f3416 100644
>> --- a/target/linux/ramips/dts/MT7621.dts
>> +++ b/target/linux/ramips/dts/MT7621.dts
>> @@ -31,4 +31,26 @@
>>                         };
>>                 };
>>         };
>> +
>> +       nand@1e003000 {
>> +               partition@0 {
>> +                       label = "uboot";
>> +                       reg = <0x00000 0x80000>; /* 64 KB */
>> +               };
>> +
>> +               partition@80000 {
>> +                       label = "uboot_env";
>> +                       reg = <0x80000 0x80000>; /* 64 KB */
>> +               };
>> +
>> +               partition@100000 {
>> +                       label = "factory";
>> +                       reg = <0x100000 0x40000>;
>> +               };
>> +
>> +               partition@140000 {
>> +                       label = "rootfs";
>> +                       reg = <0x140000 0xec0000>;
>> +               };
>> +       };
>>  };
>> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
>> new file mode 100644
>> index 0000000..4aa3be9
>> --- /dev/null
>> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
>> @@ -0,0 +1,117 @@
>> +/dts-v1/;
>> +
>> +/include/ "mt7621.dtsi"
>> +
>> +/ {
>> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
>> +       model = "UBNT-ERX";
>> +
>> +       memory@0 {
>> +               device_type = "memory";
>> +               reg = <0x0 0x10000000>;
>> +       };
>> +
>> +       chosen {
>> +               bootargs = "console=ttyS0,57600";
>> +       };
>> +
>> +       palmbus@1E000000 {
>> +               spi@b00 {
>> +                       /* This board has 2Mb spi flash soldered in and visible
>> +                          from manufacturer's firmware.
>> +                          But this SoC shares spi and nand pins,
>> +                          and current driver desn't handle this sharing well */
>> +                       status = "disabled";
>> +                       m25p80@0 {
>> +                               #address-cells = <1>;
>> +                               #size-cells = <1>;
>> +                               compatible = "m25p80";
>> +                               reg = <1>;
>> +                               linux,modalias = "m25p80";
>> +                               spi-max-frequency = <10000000>;
>> +
>> +                               partition@0 {
>> +                                       label = "spi";
>> +                                       reg = <0x0 0x200000>;
>> +                                       read-only;
>> +                               };
>> +                       };
>> +               };
>> +       };
>> +
>> +       nand@1e003000 {
>> +               compatible = "mtk,mt7621-nand";
>> +               bank-width = <2>;
>> +               reg = <0x1e003000 0x800
>> +                      0x1e003800 0x800>;
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +
>> +               partition@0 {
>> +                       label = "u-boot";
>> +                       reg = <0x0 0x80000>;
>> +                       read-only;
>> +               };
>> +
>> +               partition@80000 {
>> +                       label = "u-boot-env";
>> +                       reg = <0x80000 0x60000>;
>> +                       read-only;
>> +               };
>> +
>> +               factory: partition@e0000 {
>> +                       label = "factory";
>> +                       reg = <0xe0000 0x60000>;
>> +               };
>> +
>> +               partition@140000 {
>> +                       label = "kernel1";
>> +                       reg = <0x140000 0x300000>;
>> +               };
>> +
>> +               partition@440000 {
>> +                       label = "kernel2";
>> +                       reg = <0x440000 0x300000>;
>> +               };
>> +
>> +               partition@740000 {
>> +                       label = "ubi";
>> +                       reg = <0x740000 0xf7c0000>;
>> +               };
>> +
>> +       };
>> +
>> +       ethernet@1e100000 {
>> +               mtd-mac-address = <&factory 0x22>;
>> +       };
>> +
>> +       pinctrl {
>> +               state_default: pinctrl0 {
>> +                       gpio {
>> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
>> +                               ralink,function = "gpio";
>> +                       };
>> +               };
>> +       };
>> +
>> +       sdhci@1E130000 {
>> +               status = "disabled";
>> +       };
>> +
>> +       pcie@1e140000 {
>> +               status = "disabled";
>> +       };
>> +
>> +       gpio-keys-polled {
>> +               compatible = "gpio-keys-polled";
>> +               #address-cells = <1>;
>> +               #size-cells = <0>;
>> +               poll-interval = <20>;
>> +
>> +               reset {
>> +                       label = "reset";
>> +                       gpios = <&gpio0 12 1>;
>> +                       linux,code = <0x198>;
>> +               };
>> +       };
>> +};
>> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
>> index fd2e100..c29a040 100644
>> --- a/target/linux/ramips/dts/mt7621.dtsi
>> +++ b/target/linux/ramips/dts/mt7621.dtsi
>> @@ -241,26 +241,6 @@
>>                         0x1e003800 0x800>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>> -
>> -               partition@0 {
>> -                       label = "uboot";
>> -                       reg = <0x00000 0x80000>; /* 64 KB */
>> -               };
>> -
>> -               partition@80000 {
>> -                       label = "uboot_env";
>> -                       reg = <0x80000 0x80000>; /* 64 KB */
>> -               };
>> -
>> -               partition@100000 {
>> -                       label = "factory";
>> -                       reg = <0x100000 0x40000>;
>> -               };
>> -
>> -               partition@140000 {
>> -                       label = "rootfs";
>> -                       reg = <0x140000 0xec0000>;
>> -               };
>>         };
>>
>>         ethernet@1e100000 {
>> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
>> index 00a2923..6230688 100644
>> --- a/target/linux/ramips/image/Makefile
>> +++ b/target/linux/ramips/image/Makefile
>> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>>         mv $@.new $@
>>  endef
>>
>> +define Build/ubnt-erx-factory-compat
>> +       echo '21001:6' > $@.compat
>> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
>> +       $(RM) $@.compat
>> +endef
>> +
>> +define Build/ubnt-erx-factory-kernel
>> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
>> +               \
>> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
>> +               $(RM) $@.md5; \
>> +       fi
>> +endef
>> +
>> +define Build/ubnt-erx-factory-rootfs
>> +       echo "dummy" > $@.rootfs
>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
>> +
>> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
>> +       $(RM) $@.md5
>> +       $(RM) $@.rootfs
>> +endef
>> +
>> +define Build/ubnt-erx-factory-version
>> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
>> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
>> +       $(RM) $@.version
>> +endef
>> +
>> +#We need kernel+initrams fit into kernel partition
>> +define Build/ubnt-erx-factory-check-size
>> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
>> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
>> +               $(RM) -f $@; \
>> +       }
>> +
>> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
>> +               echo "WARNING: Kernel for image $@ not found" >&2; \
>> +               $(RM) -f $@; \
>> +       }
>> +endef
>> +
>>  define MkCombineduImage
>>         $(call PatchKernelLzma,$(2),$(3))
>>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
>> @@ -954,7 +999,7 @@ endif
>>  #
>>
>>  ifeq ($(SUBTARGET),mt7621)
>> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
>> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>>  endif
>>
>>  define Device/mt7621
>> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>>  endef
>>
>> +define Device/ubnt-erx
>> +  DTS := UBNT-ERX
>> +  FILESYSTEMS := squashfs
>> +  KERNEL_SIZE := 3145728
>> +  KERNEL := $(KERNEL_DTB) | uImage lzma
>> +  IMAGES := sysupgrade.tar factory-initramfs.tar
>> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
>> +                                ubnt-erx-factory-kernel | \
>> +                                ubnt-erx-factory-rootfs | \
>> +                                ubnt-erx-factory-version | \
>> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
>> +  IMAGE/sysupgrade.tar := sysupgrade-nand
>> +endef
>> +
>>  #
>>  # MT7628 Profiles
>>  #
>> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
>> new file mode 100644
>> index 0000000..67efa60
>> --- /dev/null
>> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
>> @@ -0,0 +1,17 @@
>> +#
>> +# Copyright (C) 2015 OpenWrt.org
>> +#
>> +# This is free software, licensed under the GNU General Public License v2.
>> +# See /LICENSE for more information.
>> +#
>> +
>> +define Profile/UBNT-ERX
>> +       NAME:=Ubiquiti EdgeRouter X
>> +       FEATURES += nand
>> +       PACKAGES:=-kmod-mt76 -wpad-mini
>> +endef
>> +
>> +define Profile/UBNT-ERX/Description
>> +       Package set compatible with the Ubiquiti EdgeRouter X
>> +endef
>> +$(eval $(call Profile,UBNT-ERX))
>> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>> new file mode 100644
>> index 0000000..a327674
>> --- /dev/null
>> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>> @@ -0,0 +1,43 @@
>> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
>> +From: Nikolay Martynov <mar.kolya@gmail.com>
>> +Date: Wed, 25 Nov 2015 20:43:46 -0500
>> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
>> +
>> +According to datasheet S34ML02G2 and S34ML04G2 have
>> +larger sparea area size than was detected.
>> +
>> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>> +---
>> + drivers/mtd/nand/nand_base.c | 9 +++++++++
>> + 1 file changed, 9 insertions(+)
>> +
>> +--- a/drivers/mtd/nand/nand_base.c
>> ++++ b/drivers/mtd/nand/nand_base.c
>> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
>> +       /*
>> +        * Field definitions are in the following datasheets:
>> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
>> ++       *                          Spansion S34ML02G2 (p.33)
>> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
>> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>> +        *
>> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
>> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
>> +
>> +               /*
>> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
>> ++               * as S34ML01G2 encoded in the same bit. We
>> ++               * differinciate them by their ID length
>> ++               */
>> ++              if (id_data[0] == NAND_MFR_AMD
>> ++                              && (id_data[1] == 0xda
>> ++                               || id_data[1] == 0xdc
>> ++                               || id_data[1] == 0xca
>> ++                               || id_data[1] == 0xcc)) {
>> ++                      mtd->oobsize *= 2;
>> ++              }
>> ++
>> ++              /*
>> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
>> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
>> +                * follows:
>> --
>> 2.6.3
>>
> 
> 
>
Nikolay Martynov Dec. 10, 2015, 7:52 p.m. UTC | #3
Hi, John.

  It looks like 4.3 has just landed for this platform and this patch
probably will not apply. Should I resubmit it?

  I was also playing with 4.3 (and 4.4) on this platform and I have
some patches that would make it use CPS multiprocessing (instead of
MIPS CMP which is obsolete). Would you be interested in these?

Thanks.


2015-12-10 3:29 GMT-05:00 John Crispin <blogic@openwrt.org>:
> it is the correct list, just been real busy this week with other stuff.
> i'll be merging stuff again as of the weekend, sorry for the delay.
>
> On 09/12/2015 16:34, Nikolay Martynov wrote:
>> Hi.
>>
>>   I know you guys a probably very busy, but could you please confirm
>> that this is the right list to submit such patches and format of this
>> patch is correct - so I could fix it if it's not.
>>
>> Thanks!
>>
>> 2015-12-03 2:16 GMT-05:00 Nikolay Martynov <mar.kolya@gmail.com>:
>>> This router is based on MT7621 SoC, no wifi, nand.
>>>
>>> Works:
>>> * Boots.
>>> * Ethernet.
>>> * Switch.
>>> * Button (reset).
>>> * Flashing OpenWrt from stock firmware.
>>> * Upgrading OpenWrt.
>>>
>>> Doesn't work:
>>> * No GPIO leds. All leds are controlled by switch,
>>>   but stock firmware was able to control them.
>>> * SoC has crypto engine but no open driver.
>>> * SoC has nat acceleration, but no open driver.
>>> * This router has 2MB spi flash soldered in but MT
>>>   nand/spi drivers do not support pin sharing,
>>>   so it is not accessable and disabled. Stock
>>>   firmware could read it and it was empty.
>>>
>>> Unknown status: PoE support.
>>>
>>> Router has serial pins populated. If looking at the top
>>> of the router, then counting from Eth sockets pins go as:
>>> 'GND, RX, TX, GND'. 3.3v, 57600.
>>>
>>> U-boot bootloader supports tftpboot, controlled from serial.
>>> This router has two kernel partitions: 'live' and 'backup'.
>>> They are swapped during flashing (on both stock and OpenWrt).
>>> Active partition is controlled by a flag in factory partition.
>>> U-boot has cusotm command to switch active kernel partition.
>>> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
>>> no UBI support. Stock rootfs is UBIFS.
>>>
>>> Flashing procedure.
>>> Stock firmware uses custom kernel patch to mount squashfs
>>> from a file that is located on UBIFS volume. This makes wiping
>>> out this volume from within stock firmware difficult.
>>> Instead this patch builds image that is flashable by stock firmware
>>> and contains initrams image (with minimal set of packages
>>> to fit into kernel partition). Once this is flashed one can reboot
>>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>>> rootfs into nand.
>>> Note: factory image is only built if initramfs image is enabled.
>>>
>>> v2: Fix building all mt7621 targets along with ubnt-erx.
>>> v3: Undo change to MT7621 nand partitions, make nand detection
>>>     less likely to affect other nands.
>>> v4: Update as per Piotr Dymacz comments.
>>> v5: Fix upgrading code to actually upgrade kernel.
>>>
>>> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>>> ---
>>>  package/system/procd/files/nand.sh                 |   4 +
>>>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>>>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>>>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>>>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>>>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>>>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>>>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>>>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>>>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>>>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>>>  11 files changed, 363 insertions(+), 22 deletions(-)
>>>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>>>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>>>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>>
>>> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
>>> index 0c179cb..67867da 100644
>>> --- a/package/system/procd/files/nand.sh
>>> +++ b/package/system/procd/files/nand.sh
>>> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>>>  nand_do_upgrade_stage2() {
>>>         local file_type=$(identify $1)
>>>
>>> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
>>> +           platform_nand_pre_upgrade "$1"
>>> +       fi
>>> +
>>>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>>>
>>>         case "$file_type" in
>>> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
>>> index 7e51229..de81553 100755
>>> --- a/target/linux/ramips/base-files/etc/board.d/02_network
>>> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
>>> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>>>         f5d8235-v2|\
>>>         hg255d|\
>>>         rt-n14u|\
>>> +       ubnt-erx|\
>>>         ur-326n4g|\
>>>         wrtnode|\
>>>         wt3020|\
>>> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
>>> index 92e13c0..ba23939 100755
>>> --- a/target/linux/ramips/base-files/lib/ramips.sh
>>> +++ b/target/linux/ramips/base-files/lib/ramips.sh
>>> @@ -349,6 +349,9 @@ ramips_board_detect() {
>>>         *"TEW-692GR")
>>>                 name="tew-692gr"
>>>                 ;;
>>> +       *"UBNT-ERX")
>>> +               name="ubnt-erx"
>>> +               ;;
>>>         *"UR-326N4G")
>>>                 name="ur-326n4g"
>>>                 ;;
>>> @@ -396,7 +399,7 @@ ramips_board_detect() {
>>>                 ;;
>>>         *"WizFi630A")
>>>                 name="wizfi630a"
>>> -               ;;
>>> +               ;;
>>>         *"WL-330N")
>>>                 name="wl-330n"
>>>                 ;;
>>> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> index 073593a..b0d624e 100755
>>> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> @@ -181,12 +181,36 @@ platform_check_image() {
>>>                 }
>>>                 return 0
>>>                 ;;
>>> +       ubnt-erx)
>>> +               nand_do_platform_check "$board" "$1"
>>> +               return $?;
>>> +               ;;
>>>         esac
>>>
>>>         echo "Sysupgrade is not yet supported on $board."
>>>         return 1
>>>  }
>>>
>>> +platform_nand_pre_upgrade() {
>>> +       local board=$(ramips_board_name)
>>> +
>>> +       case "$board" in
>>> +       ubnt-erx)
>>> +               platform_upgrade_ubnt_erx "$ARGV"
>>> +               ;;
>>> +       esac
>>> +}
>>> +
>>> +platform_pre_upgrade() {
>>> +       local board=$(ramips_board_name)
>>> +
>>> +       case "$board" in
>>> +       ubnt-erx)
>>> +               nand_do_upgrade "$ARGV"
>>> +               ;;
>>> +       esac
>>> +}
>>> +
>>>  platform_do_upgrade() {
>>>         local board=$(ramips_board_name)
>>>
>>> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>> new file mode 100644
>>> index 0000000..0dc602b
>>> --- /dev/null
>>> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>> @@ -0,0 +1,71 @@
>>> +#
>>> +# Copyright (C) 2015 OpenWrt.org
>>> +#
>>> +
>>> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
>>> +
>>> +ubnt_get_target_kernel() {
>>> +        local factory_mtd=$1
>>> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
>>> +
>>> +       if [ $current_kernel_index == "0" ]; then
>>> +            echo 'kernel2'
>>> +       elif [ $current_kernel_index == "1" ]; then
>>> +            echo 'kernel1'
>>> +       fi
>>> +}
>>> +
>>> +ubnt_update_target_kernel() {
>>> +       local factory_mtd=$1
>>> +       local kernel_part=$2
>>> +
>>> +       local new_kernel_index
>>> +       if [ $kernel_part == "kernel1" ]; then
>>> +            new_kernel_index="\x00"
>>> +       elif [ $kernel_part == "kernel2" ]; then
>>> +            new_kernel_index="\x01"
>>> +       else
>>> +           echo 'Unknown kernel image index'
>>> +            exit 1
>>> +       fi
>>> +
>>> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
>>> +            echo 'Failed to update kernel bootup index'
>>> +            exit 1
>>> +       fi
>>> +}
>>> +
>>> +platform_upgrade_ubnt_erx() {
>>> +       local factory_mtd=$(find_mtd_part factory)
>>> +       if [ ! -n "$factory_mtd" ]; then
>>> +               echo "cannot find factory partition"
>>> +               exit 1
>>> +       fi
>>> +
>>> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
>>> +       if [ ! -n "$kernel_part" ]; then
>>> +               echo "cannot find factory partition"
>>> +               exit 1
>>> +       fi
>>> +
>>> +       CI_KERNPART=${kernel_part}
>>> +
>>> +       #Remove volume possibly left over from stock firmware
>>> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>>> +       if [ ! "$ubidev" ]; then
>>> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
>>> +               if [ ! "$mtdnum" ]; then
>>> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
>>> +                       return 1
>>> +               fi
>>> +               ubiattach -m "$mtdnum"
>>> +               sync
>>> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>>> +       fi
>>> +       if [ -n "$ubidev" ]; then
>>> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
>>> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
>>> +       fi
>>> +
>>> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
>>> +}
>>> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
>>> index c90fc95..96f3416 100644
>>> --- a/target/linux/ramips/dts/MT7621.dts
>>> +++ b/target/linux/ramips/dts/MT7621.dts
>>> @@ -31,4 +31,26 @@
>>>                         };
>>>                 };
>>>         };
>>> +
>>> +       nand@1e003000 {
>>> +               partition@0 {
>>> +                       label = "uboot";
>>> +                       reg = <0x00000 0x80000>; /* 64 KB */
>>> +               };
>>> +
>>> +               partition@80000 {
>>> +                       label = "uboot_env";
>>> +                       reg = <0x80000 0x80000>; /* 64 KB */
>>> +               };
>>> +
>>> +               partition@100000 {
>>> +                       label = "factory";
>>> +                       reg = <0x100000 0x40000>;
>>> +               };
>>> +
>>> +               partition@140000 {
>>> +                       label = "rootfs";
>>> +                       reg = <0x140000 0xec0000>;
>>> +               };
>>> +       };
>>>  };
>>> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
>>> new file mode 100644
>>> index 0000000..4aa3be9
>>> --- /dev/null
>>> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
>>> @@ -0,0 +1,117 @@
>>> +/dts-v1/;
>>> +
>>> +/include/ "mt7621.dtsi"
>>> +
>>> +/ {
>>> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
>>> +       model = "UBNT-ERX";
>>> +
>>> +       memory@0 {
>>> +               device_type = "memory";
>>> +               reg = <0x0 0x10000000>;
>>> +       };
>>> +
>>> +       chosen {
>>> +               bootargs = "console=ttyS0,57600";
>>> +       };
>>> +
>>> +       palmbus@1E000000 {
>>> +               spi@b00 {
>>> +                       /* This board has 2Mb spi flash soldered in and visible
>>> +                          from manufacturer's firmware.
>>> +                          But this SoC shares spi and nand pins,
>>> +                          and current driver desn't handle this sharing well */
>>> +                       status = "disabled";
>>> +                       m25p80@0 {
>>> +                               #address-cells = <1>;
>>> +                               #size-cells = <1>;
>>> +                               compatible = "m25p80";
>>> +                               reg = <1>;
>>> +                               linux,modalias = "m25p80";
>>> +                               spi-max-frequency = <10000000>;
>>> +
>>> +                               partition@0 {
>>> +                                       label = "spi";
>>> +                                       reg = <0x0 0x200000>;
>>> +                                       read-only;
>>> +                               };
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       nand@1e003000 {
>>> +               compatible = "mtk,mt7621-nand";
>>> +               bank-width = <2>;
>>> +               reg = <0x1e003000 0x800
>>> +                      0x1e003800 0x800>;
>>> +               #address-cells = <1>;
>>> +               #size-cells = <1>;
>>> +
>>> +               partition@0 {
>>> +                       label = "u-boot";
>>> +                       reg = <0x0 0x80000>;
>>> +                       read-only;
>>> +               };
>>> +
>>> +               partition@80000 {
>>> +                       label = "u-boot-env";
>>> +                       reg = <0x80000 0x60000>;
>>> +                       read-only;
>>> +               };
>>> +
>>> +               factory: partition@e0000 {
>>> +                       label = "factory";
>>> +                       reg = <0xe0000 0x60000>;
>>> +               };
>>> +
>>> +               partition@140000 {
>>> +                       label = "kernel1";
>>> +                       reg = <0x140000 0x300000>;
>>> +               };
>>> +
>>> +               partition@440000 {
>>> +                       label = "kernel2";
>>> +                       reg = <0x440000 0x300000>;
>>> +               };
>>> +
>>> +               partition@740000 {
>>> +                       label = "ubi";
>>> +                       reg = <0x740000 0xf7c0000>;
>>> +               };
>>> +
>>> +       };
>>> +
>>> +       ethernet@1e100000 {
>>> +               mtd-mac-address = <&factory 0x22>;
>>> +       };
>>> +
>>> +       pinctrl {
>>> +               state_default: pinctrl0 {
>>> +                       gpio {
>>> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
>>> +                               ralink,function = "gpio";
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       sdhci@1E130000 {
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       pcie@1e140000 {
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       gpio-keys-polled {
>>> +               compatible = "gpio-keys-polled";
>>> +               #address-cells = <1>;
>>> +               #size-cells = <0>;
>>> +               poll-interval = <20>;
>>> +
>>> +               reset {
>>> +                       label = "reset";
>>> +                       gpios = <&gpio0 12 1>;
>>> +                       linux,code = <0x198>;
>>> +               };
>>> +       };
>>> +};
>>> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
>>> index fd2e100..c29a040 100644
>>> --- a/target/linux/ramips/dts/mt7621.dtsi
>>> +++ b/target/linux/ramips/dts/mt7621.dtsi
>>> @@ -241,26 +241,6 @@
>>>                         0x1e003800 0x800>;
>>>                 #address-cells = <1>;
>>>                 #size-cells = <1>;
>>> -
>>> -               partition@0 {
>>> -                       label = "uboot";
>>> -                       reg = <0x00000 0x80000>; /* 64 KB */
>>> -               };
>>> -
>>> -               partition@80000 {
>>> -                       label = "uboot_env";
>>> -                       reg = <0x80000 0x80000>; /* 64 KB */
>>> -               };
>>> -
>>> -               partition@100000 {
>>> -                       label = "factory";
>>> -                       reg = <0x100000 0x40000>;
>>> -               };
>>> -
>>> -               partition@140000 {
>>> -                       label = "rootfs";
>>> -                       reg = <0x140000 0xec0000>;
>>> -               };
>>>         };
>>>
>>>         ethernet@1e100000 {
>>> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
>>> index 00a2923..6230688 100644
>>> --- a/target/linux/ramips/image/Makefile
>>> +++ b/target/linux/ramips/image/Makefile
>>> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>>>         mv $@.new $@
>>>  endef
>>>
>>> +define Build/ubnt-erx-factory-compat
>>> +       echo '21001:6' > $@.compat
>>> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
>>> +       $(RM) $@.compat
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-kernel
>>> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
>>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
>>> +               \
>>> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
>>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
>>> +               $(RM) $@.md5; \
>>> +       fi
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-rootfs
>>> +       echo "dummy" > $@.rootfs
>>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
>>> +
>>> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
>>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
>>> +       $(RM) $@.md5
>>> +       $(RM) $@.rootfs
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-version
>>> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
>>> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
>>> +       $(RM) $@.version
>>> +endef
>>> +
>>> +#We need kernel+initrams fit into kernel partition
>>> +define Build/ubnt-erx-factory-check-size
>>> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
>>> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
>>> +               $(RM) -f $@; \
>>> +       }
>>> +
>>> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
>>> +               echo "WARNING: Kernel for image $@ not found" >&2; \
>>> +               $(RM) -f $@; \
>>> +       }
>>> +endef
>>> +
>>>  define MkCombineduImage
>>>         $(call PatchKernelLzma,$(2),$(3))
>>>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
>>> @@ -954,7 +999,7 @@ endif
>>>  #
>>>
>>>  ifeq ($(SUBTARGET),mt7621)
>>> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
>>> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>>>  endif
>>>
>>>  define Device/mt7621
>>> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>>>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>>>  endef
>>>
>>> +define Device/ubnt-erx
>>> +  DTS := UBNT-ERX
>>> +  FILESYSTEMS := squashfs
>>> +  KERNEL_SIZE := 3145728
>>> +  KERNEL := $(KERNEL_DTB) | uImage lzma
>>> +  IMAGES := sysupgrade.tar factory-initramfs.tar
>>> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
>>> +                                ubnt-erx-factory-kernel | \
>>> +                                ubnt-erx-factory-rootfs | \
>>> +                                ubnt-erx-factory-version | \
>>> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
>>> +  IMAGE/sysupgrade.tar := sysupgrade-nand
>>> +endef
>>> +
>>>  #
>>>  # MT7628 Profiles
>>>  #
>>> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
>>> new file mode 100644
>>> index 0000000..67efa60
>>> --- /dev/null
>>> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
>>> @@ -0,0 +1,17 @@
>>> +#
>>> +# Copyright (C) 2015 OpenWrt.org
>>> +#
>>> +# This is free software, licensed under the GNU General Public License v2.
>>> +# See /LICENSE for more information.
>>> +#
>>> +
>>> +define Profile/UBNT-ERX
>>> +       NAME:=Ubiquiti EdgeRouter X
>>> +       FEATURES += nand
>>> +       PACKAGES:=-kmod-mt76 -wpad-mini
>>> +endef
>>> +
>>> +define Profile/UBNT-ERX/Description
>>> +       Package set compatible with the Ubiquiti EdgeRouter X
>>> +endef
>>> +$(eval $(call Profile,UBNT-ERX))
>>> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>> new file mode 100644
>>> index 0000000..a327674
>>> --- /dev/null
>>> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>> @@ -0,0 +1,43 @@
>>> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
>>> +From: Nikolay Martynov <mar.kolya@gmail.com>
>>> +Date: Wed, 25 Nov 2015 20:43:46 -0500
>>> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
>>> +
>>> +According to datasheet S34ML02G2 and S34ML04G2 have
>>> +larger sparea area size than was detected.
>>> +
>>> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>>> +---
>>> + drivers/mtd/nand/nand_base.c | 9 +++++++++
>>> + 1 file changed, 9 insertions(+)
>>> +
>>> +--- a/drivers/mtd/nand/nand_base.c
>>> ++++ b/drivers/mtd/nand/nand_base.c
>>> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
>>> +       /*
>>> +        * Field definitions are in the following datasheets:
>>> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
>>> ++       *                          Spansion S34ML02G2 (p.33)
>>> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
>>> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>>> +        *
>>> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
>>> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
>>> +
>>> +               /*
>>> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
>>> ++               * as S34ML01G2 encoded in the same bit. We
>>> ++               * differinciate them by their ID length
>>> ++               */
>>> ++              if (id_data[0] == NAND_MFR_AMD
>>> ++                              && (id_data[1] == 0xda
>>> ++                               || id_data[1] == 0xdc
>>> ++                               || id_data[1] == 0xca
>>> ++                               || id_data[1] == 0xcc)) {
>>> ++                      mtd->oobsize *= 2;
>>> ++              }
>>> ++
>>> ++              /*
>>> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
>>> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
>>> +                * follows:
>>> --
>>> 2.6.3
>>>
>>
>>
>>
Yousong Zhou Dec. 11, 2015, 5:33 a.m. UTC | #4
Hi, Nikolay,

On 3 December 2015 at 15:16, Nikolay Martynov <mar.kolya@gmail.com> wrote:
> This router is based on MT7621 SoC, no wifi, nand.
>
> Works:
> * Boots.
> * Ethernet.
> * Switch.
> * Button (reset).
> * Flashing OpenWrt from stock firmware.
> * Upgrading OpenWrt.
>
> Doesn't work:
> * No GPIO leds. All leds are controlled by switch,
>   but stock firmware was able to control them.

Try enabling SWCONFIG_LEDS and configure the trigger with
ucidef_set_led_switch like other platforms have done.  This works for
me with a mt7620 board.

> * SoC has crypto engine but no open driver.
> * SoC has nat acceleration, but no open driver.
> * This router has 2MB spi flash soldered in but MT
>   nand/spi drivers do not support pin sharing,
>   so it is not accessable and disabled. Stock
>   firmware could read it and it was empty.
>
> Unknown status: PoE support.
>
> Router has serial pins populated. If looking at the top
> of the router, then counting from Eth sockets pins go as:
> 'GND, RX, TX, GND'. 3.3v, 57600.
>
> U-boot bootloader supports tftpboot, controlled from serial.
> This router has two kernel partitions: 'live' and 'backup'.
> They are swapped during flashing (on both stock and OpenWrt).
> Active partition is controlled by a flag in factory partition.
> U-boot has cusotm command to switch active kernel partition.
> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
> no UBI support. Stock rootfs is UBIFS.
>
> Flashing procedure.
> Stock firmware uses custom kernel patch to mount squashfs
> from a file that is located on UBIFS volume. This makes wiping
> out this volume from within stock firmware difficult.
> Instead this patch builds image that is flashable by stock firmware
> and contains initrams image (with minimal set of packages
> to fit into kernel partition). Once this is flashed one can reboot
> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
> rootfs into nand.
> Note: factory image is only built if initramfs image is enabled.

Most of these info should go to a wiki page for the device.

>
> v2: Fix building all mt7621 targets along with ubnt-erx.
> v3: Undo change to MT7621 nand partitions, make nand detection
>     less likely to affect other nands.
> v4: Update as per Piotr Dymacz comments.
> v5: Fix upgrading code to actually upgrade kernel.

The changelog should go below the three-dashes line (---).

A few indentation issues were spotted and pointed out inline.

>
> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
> ---
>  package/system/procd/files/nand.sh                 |   4 +
>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>  11 files changed, 363 insertions(+), 22 deletions(-)
>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>
> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
> index 0c179cb..67867da 100644
> --- a/package/system/procd/files/nand.sh
> +++ b/package/system/procd/files/nand.sh
> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>  nand_do_upgrade_stage2() {
>         local file_type=$(identify $1)
>
> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
> +           platform_nand_pre_upgrade "$1"

bad indentation (tab replaced with blank spaces).  And this should be
in a separate patch

> +       fi
> +
>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>
>         case "$file_type" in
> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
> index 7e51229..de81553 100755
> --- a/target/linux/ramips/base-files/etc/board.d/02_network
> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>         f5d8235-v2|\
>         hg255d|\
>         rt-n14u|\
> +       ubnt-erx|\
>         ur-326n4g|\
>         wrtnode|\
>         wt3020|\
> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
> index 92e13c0..ba23939 100755
> --- a/target/linux/ramips/base-files/lib/ramips.sh
> +++ b/target/linux/ramips/base-files/lib/ramips.sh
> @@ -349,6 +349,9 @@ ramips_board_detect() {
>         *"TEW-692GR")
>                 name="tew-692gr"
>                 ;;
> +       *"UBNT-ERX")
> +               name="ubnt-erx"
> +               ;;
>         *"UR-326N4G")
>                 name="ur-326n4g"
>                 ;;
> @@ -396,7 +399,7 @@ ramips_board_detect() {
>                 ;;
>         *"WizFi630A")
>                 name="wizfi630a"
> -               ;;
> +               ;;
>         *"WL-330N")
>                 name="wl-330n"
>                 ;;
> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
> index 073593a..b0d624e 100755
> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
> @@ -181,12 +181,36 @@ platform_check_image() {
>                 }
>                 return 0
>                 ;;
> +       ubnt-erx)
> +               nand_do_platform_check "$board" "$1"

bad indentation

> +               return $?;
> +               ;;
>         esac
>
>         echo "Sysupgrade is not yet supported on $board."
>         return 1
>  }
>
> +platform_nand_pre_upgrade() {
> +       local board=$(ramips_board_name)
> +
> +       case "$board" in
> +       ubnt-erx)

bad indentation

> +               platform_upgrade_ubnt_erx "$ARGV"
> +               ;;
> +       esac
> +}
> +
> +platform_pre_upgrade() {
> +       local board=$(ramips_board_name)
> +
> +       case "$board" in
> +       ubnt-erx)
> +               nand_do_upgrade "$ARGV"
> +               ;;
> +       esac
> +}
> +
>  platform_do_upgrade() {
>         local board=$(ramips_board_name)
>
> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
> new file mode 100644
> index 0000000..0dc602b
> --- /dev/null
> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh

Indentation issues exist in this file.

> @@ -0,0 +1,71 @@
> +#
> +# Copyright (C) 2015 OpenWrt.org
> +#
> +
> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
> +
> +ubnt_get_target_kernel() {
> +        local factory_mtd=$1
> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')

hexdump alone can do the job with option -s <offset> -n <count>

> +
> +       if [ $current_kernel_index == "0" ]; then
> +            echo 'kernel2'
> +       elif [ $current_kernel_index == "1" ]; then
> +            echo 'kernel1'
> +       fi
> +}
> +
> +ubnt_update_target_kernel() {
> +       local factory_mtd=$1
> +       local kernel_part=$2
> +
> +       local new_kernel_index
> +       if [ $kernel_part == "kernel1" ]; then
> +            new_kernel_index="\x00"
> +       elif [ $kernel_part == "kernel2" ]; then
> +            new_kernel_index="\x01"
> +       else
> +           echo 'Unknown kernel image index'

Should echo to stderr >&2

> +            exit 1

Can we "return 1" and let the caller make the decision?

> +       fi
> +
> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
> +            echo 'Failed to update kernel bootup index'
> +            exit 1

ditto

> +       fi
> +}
> +
> +platform_upgrade_ubnt_erx() {
> +       local factory_mtd=$(find_mtd_part factory)

find_mtd_part is in another file, so better source it again here.

> +       if [ ! -n "$factory_mtd" ]; then

[ -z xxx ] should do

> +               echo "cannot find factory partition"
> +               exit 1
> +       fi
> +
> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
> +       if [ ! -n "$kernel_part" ]; then
> +               echo "cannot find factory partition"
> +               exit 1
> +       fi
> +
> +       CI_KERNPART=${kernel_part}

this variable is not referenced in the whole patch?

> +
> +       #Remove volume possibly left over from stock firmware
> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
> +       if [ ! "$ubidev" ]; then

I thought [ -z "$ubidev" ] is the convention

> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
> +               if [ ! "$mtdnum" ]; then

ditto

> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
> +                       return 1
> +               fi
> +               ubiattach -m "$mtdnum"
> +               sync
> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
> +       fi
> +       if [ -n "$ubidev" ]; then
> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true

ditto

> +       fi
> +
> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
> +}
> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
> index c90fc95..96f3416 100644
> --- a/target/linux/ramips/dts/MT7621.dts
> +++ b/target/linux/ramips/dts/MT7621.dts
> @@ -31,4 +31,26 @@
>                         };
>                 };
>         };
> +
> +       nand@1e003000 {
> +               partition@0 {
> +                       label = "uboot";
> +                       reg = <0x00000 0x80000>; /* 64 KB */
> +               };
> +
> +               partition@80000 {
> +                       label = "uboot_env";
> +                       reg = <0x80000 0x80000>; /* 64 KB */
> +               };
> +
> +               partition@100000 {
> +                       label = "factory";
> +                       reg = <0x100000 0x40000>;
> +               };
> +
> +               partition@140000 {
> +                       label = "rootfs";
> +                       reg = <0x140000 0xec0000>;
> +               };
> +       };
>  };

moving something from mt7621.dtsi to MT7621.dts should be in a
separate patch with explanation.

> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
> new file mode 100644
> index 0000000..4aa3be9
> --- /dev/null
> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
> @@ -0,0 +1,117 @@
> +/dts-v1/;
> +
> +/include/ "mt7621.dtsi"
> +
> +/ {
> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
> +       model = "UBNT-ERX";
> +
> +       memory@0 {
> +               device_type = "memory";
> +               reg = <0x0 0x10000000>;
> +       };
> +
> +       chosen {
> +               bootargs = "console=ttyS0,57600";
> +       };
> +
> +       palmbus@1E000000 {
> +               spi@b00 {
> +                       /* This board has 2Mb spi flash soldered in and visible
> +                          from manufacturer's firmware.
> +                          But this SoC shares spi and nand pins,
> +                          and current driver desn't handle this sharing well */
> +                       status = "disabled";
> +                       m25p80@0 {
> +                               #address-cells = <1>;
> +                               #size-cells = <1>;
> +                               compatible = "m25p80";
> +                               reg = <1>;
> +                               linux,modalias = "m25p80";
> +                               spi-max-frequency = <10000000>;
> +
> +                               partition@0 {
> +                                       label = "spi";
> +                                       reg = <0x0 0x200000>;
> +                                       read-only;
> +                               };
> +                       };
> +               };
> +       };
> +
> +       nand@1e003000 {
> +               compatible = "mtk,mt7621-nand";
> +               bank-width = <2>;
> +               reg = <0x1e003000 0x800
> +                      0x1e003800 0x800>;
> +               #address-cells = <1>;
> +               #size-cells = <1>;
> +
> +               partition@0 {
> +                       label = "u-boot";
> +                       reg = <0x0 0x80000>;
> +                       read-only;
> +               };
> +
> +               partition@80000 {
> +                       label = "u-boot-env";
> +                       reg = <0x80000 0x60000>;
> +                       read-only;
> +               };
> +
> +               factory: partition@e0000 {
> +                       label = "factory";
> +                       reg = <0xe0000 0x60000>;
> +               };
> +
> +               partition@140000 {
> +                       label = "kernel1";
> +                       reg = <0x140000 0x300000>;
> +               };
> +
> +               partition@440000 {
> +                       label = "kernel2";
> +                       reg = <0x440000 0x300000>;
> +               };
> +
> +               partition@740000 {
> +                       label = "ubi";
> +                       reg = <0x740000 0xf7c0000>;
> +               };
> +
> +       };
> +
> +       ethernet@1e100000 {
> +               mtd-mac-address = <&factory 0x22>;
> +       };
> +
> +       pinctrl {
> +               state_default: pinctrl0 {
> +                       gpio {
> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
> +                               ralink,function = "gpio";
> +                       };
> +               };
> +       };
> +
> +       sdhci@1E130000 {
> +               status = "disabled";
> +       };
> +
> +       pcie@1e140000 {
> +               status = "disabled";
> +       };
> +
> +       gpio-keys-polled {
> +               compatible = "gpio-keys-polled";
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               poll-interval = <20>;
> +
> +               reset {
> +                       label = "reset";
> +                       gpios = <&gpio0 12 1>;
> +                       linux,code = <0x198>;
> +               };
> +       };
> +};
> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
> index fd2e100..c29a040 100644
> --- a/target/linux/ramips/dts/mt7621.dtsi
> +++ b/target/linux/ramips/dts/mt7621.dtsi
> @@ -241,26 +241,6 @@
>                         0x1e003800 0x800>;
>                 #address-cells = <1>;
>                 #size-cells = <1>;
> -
> -               partition@0 {
> -                       label = "uboot";
> -                       reg = <0x00000 0x80000>; /* 64 KB */
> -               };
> -
> -               partition@80000 {
> -                       label = "uboot_env";
> -                       reg = <0x80000 0x80000>; /* 64 KB */
> -               };
> -
> -               partition@100000 {
> -                       label = "factory";
> -                       reg = <0x100000 0x40000>;
> -               };
> -
> -               partition@140000 {
> -                       label = "rootfs";
> -                       reg = <0x140000 0xec0000>;
> -               };
>         };
>
>         ethernet@1e100000 {
> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
> index 00a2923..6230688 100644
> --- a/target/linux/ramips/image/Makefile
> +++ b/target/linux/ramips/image/Makefile
> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>         mv $@.new $@
>  endef
>
> +define Build/ubnt-erx-factory-compat
> +       echo '21001:6' > $@.compat
> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
> +       $(RM) $@.compat
> +endef
> +
> +define Build/ubnt-erx-factory-kernel
> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
> +               \
> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
> +               $(RM) $@.md5; \
> +       fi
> +endef
> +
> +define Build/ubnt-erx-factory-rootfs
> +       echo "dummy" > $@.rootfs
> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
> +
> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
> +       $(RM) $@.md5
> +       $(RM) $@.rootfs
> +endef
> +
> +define Build/ubnt-erx-factory-version
> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
> +       $(RM) $@.version
> +endef
> +
> +#We need kernel+initrams fit into kernel partition
> +define Build/ubnt-erx-factory-check-size
> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
> +               $(RM) -f $@; \
> +       }
> +
> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
> +               echo "WARNING: Kernel for image $@ not found" >&2; \
> +               $(RM) -f $@; \
> +       }
> +endef
> +
>  define MkCombineduImage
>         $(call PatchKernelLzma,$(2),$(3))
>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
> @@ -954,7 +999,7 @@ endif
>  #
>
>  ifeq ($(SUBTARGET),mt7621)
> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>  endif
>
>  define Device/mt7621
> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>  endef
>
> +define Device/ubnt-erx
> +  DTS := UBNT-ERX
> +  FILESYSTEMS := squashfs
> +  KERNEL_SIZE := 3145728
> +  KERNEL := $(KERNEL_DTB) | uImage lzma
> +  IMAGES := sysupgrade.tar factory-initramfs.tar
> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
> +                                ubnt-erx-factory-kernel | \
> +                                ubnt-erx-factory-rootfs | \
> +                                ubnt-erx-factory-version | \
> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
> +  IMAGE/sysupgrade.tar := sysupgrade-nand
> +endef
> +
>  #
>  # MT7628 Profiles
>  #
> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
> new file mode 100644
> index 0000000..67efa60
> --- /dev/null
> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
> @@ -0,0 +1,17 @@
> +#
> +# Copyright (C) 2015 OpenWrt.org
> +#
> +# This is free software, licensed under the GNU General Public License v2.
> +# See /LICENSE for more information.
> +#
> +
> +define Profile/UBNT-ERX
> +       NAME:=Ubiquiti EdgeRouter X
> +       FEATURES += nand
> +       PACKAGES:=-kmod-mt76 -wpad-mini
> +endef
> +
> +define Profile/UBNT-ERX/Description
> +       Package set compatible with the Ubiquiti EdgeRouter X
> +endef
> +$(eval $(call Profile,UBNT-ERX))
> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
> new file mode 100644
> index 0000000..a327674
> --- /dev/null
> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
> @@ -0,0 +1,43 @@
> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
> +From: Nikolay Martynov <mar.kolya@gmail.com>
> +Date: Wed, 25 Nov 2015 20:43:46 -0500
> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
> +
> +According to datasheet S34ML02G2 and S34ML04G2 have
> +larger sparea area size than was detected.
> +
> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
> +---
> + drivers/mtd/nand/nand_base.c | 9 +++++++++
> + 1 file changed, 9 insertions(+)
> +
> +--- a/drivers/mtd/nand/nand_base.c
> ++++ b/drivers/mtd/nand/nand_base.c
> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
> +       /*
> +        * Field definitions are in the following datasheets:
> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
> ++       *                          Spansion S34ML02G2 (p.33)
> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
> +        *
> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
> +
> +               /*
> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
> ++               * as S34ML01G2 encoded in the same bit. We
> ++               * differinciate them by their ID length
> ++               */
> ++              if (id_data[0] == NAND_MFR_AMD
> ++                              && (id_data[1] == 0xda
> ++                               || id_data[1] == 0xdc
> ++                               || id_data[1] == 0xca
> ++                               || id_data[1] == 0xcc)) {
> ++                      mtd->oobsize *= 2;
> ++              }
> ++
> ++              /*
> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
> +                * follows:
> --
> 2.6.3
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Yousong Zhou Dec. 11, 2015, 5:36 a.m. UTC | #5
yousong


On 11 December 2015 at 13:33, Yousong Zhou <yszhou4tech@gmail.com> wrote:
> Hi, Nikolay,
>
> On 3 December 2015 at 15:16, Nikolay Martynov <mar.kolya@gmail.com> wrote:
>> This router is based on MT7621 SoC, no wifi, nand.
>>
>> Works:
>> * Boots.
>> * Ethernet.
>> * Switch.
>> * Button (reset).
>> * Flashing OpenWrt from stock firmware.
>> * Upgrading OpenWrt.
>>
>> Doesn't work:
>> * No GPIO leds. All leds are controlled by switch,
>>   but stock firmware was able to control them.
>
> Try enabling SWCONFIG_LEDS and configure the trigger with
> ucidef_set_led_switch like other platforms have done.  This works for
> me with a mt7620 board.
>
>> * SoC has crypto engine but no open driver.
>> * SoC has nat acceleration, but no open driver.
>> * This router has 2MB spi flash soldered in but MT
>>   nand/spi drivers do not support pin sharing,
>>   so it is not accessable and disabled. Stock
>>   firmware could read it and it was empty.
>>
>> Unknown status: PoE support.
>>
>> Router has serial pins populated. If looking at the top
>> of the router, then counting from Eth sockets pins go as:
>> 'GND, RX, TX, GND'. 3.3v, 57600.
>>
>> U-boot bootloader supports tftpboot, controlled from serial.
>> This router has two kernel partitions: 'live' and 'backup'.
>> They are swapped during flashing (on both stock and OpenWrt).
>> Active partition is controlled by a flag in factory partition.
>> U-boot has cusotm command to switch active kernel partition.
>> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
>> no UBI support. Stock rootfs is UBIFS.
>>
>> Flashing procedure.
>> Stock firmware uses custom kernel patch to mount squashfs
>> from a file that is located on UBIFS volume. This makes wiping
>> out this volume from within stock firmware difficult.
>> Instead this patch builds image that is flashable by stock firmware
>> and contains initrams image (with minimal set of packages
>> to fit into kernel partition). Once this is flashed one can reboot
>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>> rootfs into nand.
>> Note: factory image is only built if initramfs image is enabled.
>
> Most of these info should go to a wiki page for the device.
>
>>
>> v2: Fix building all mt7621 targets along with ubnt-erx.
>> v3: Undo change to MT7621 nand partitions, make nand detection
>>     less likely to affect other nands.
>> v4: Update as per Piotr Dymacz comments.
>> v5: Fix upgrading code to actually upgrade kernel.
>
> The changelog should go below the three-dashes line (---).
>
> A few indentation issues were spotted and pointed out inline.
>
>>
>> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>> ---
>>  package/system/procd/files/nand.sh                 |   4 +
>>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>>  11 files changed, 363 insertions(+), 22 deletions(-)
>>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>
>> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
>> index 0c179cb..67867da 100644
>> --- a/package/system/procd/files/nand.sh
>> +++ b/package/system/procd/files/nand.sh
>> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>>  nand_do_upgrade_stage2() {
>>         local file_type=$(identify $1)
>>
>> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
>> +           platform_nand_pre_upgrade "$1"
>
> bad indentation (tab replaced with blank spaces).  And this should be
> in a separate patch
>
>> +       fi
>> +
>>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>>
>>         case "$file_type" in
>> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
>> index 7e51229..de81553 100755
>> --- a/target/linux/ramips/base-files/etc/board.d/02_network
>> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
>> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>>         f5d8235-v2|\
>>         hg255d|\
>>         rt-n14u|\
>> +       ubnt-erx|\
>>         ur-326n4g|\
>>         wrtnode|\
>>         wt3020|\
>> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
>> index 92e13c0..ba23939 100755
>> --- a/target/linux/ramips/base-files/lib/ramips.sh
>> +++ b/target/linux/ramips/base-files/lib/ramips.sh
>> @@ -349,6 +349,9 @@ ramips_board_detect() {
>>         *"TEW-692GR")
>>                 name="tew-692gr"
>>                 ;;
>> +       *"UBNT-ERX")
>> +               name="ubnt-erx"
>> +               ;;
>>         *"UR-326N4G")
>>                 name="ur-326n4g"
>>                 ;;
>> @@ -396,7 +399,7 @@ ramips_board_detect() {
>>                 ;;
>>         *"WizFi630A")
>>                 name="wizfi630a"
>> -               ;;
>> +               ;;
>>         *"WL-330N")
>>                 name="wl-330n"
>>                 ;;
>> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> index 073593a..b0d624e 100755
>> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>> @@ -181,12 +181,36 @@ platform_check_image() {
>>                 }
>>                 return 0
>>                 ;;
>> +       ubnt-erx)
>> +               nand_do_platform_check "$board" "$1"
>
> bad indentation
>
>> +               return $?;
>> +               ;;
>>         esac
>>
>>         echo "Sysupgrade is not yet supported on $board."
>>         return 1
>>  }
>>
>> +platform_nand_pre_upgrade() {
>> +       local board=$(ramips_board_name)
>> +
>> +       case "$board" in
>> +       ubnt-erx)
>
> bad indentation
>
>> +               platform_upgrade_ubnt_erx "$ARGV"
>> +               ;;
>> +       esac
>> +}
>> +
>> +platform_pre_upgrade() {
>> +       local board=$(ramips_board_name)
>> +
>> +       case "$board" in
>> +       ubnt-erx)
>> +               nand_do_upgrade "$ARGV"
>> +               ;;
>> +       esac
>> +}
>> +
>>  platform_do_upgrade() {
>>         local board=$(ramips_board_name)
>>
>> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>> new file mode 100644
>> index 0000000..0dc602b
>> --- /dev/null
>> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>
> Indentation issues exist in this file.
>
>> @@ -0,0 +1,71 @@
>> +#
>> +# Copyright (C) 2015 OpenWrt.org
>> +#
>> +
>> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
>> +
>> +ubnt_get_target_kernel() {
>> +        local factory_mtd=$1
>> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
>
> hexdump alone can do the job with option -s <offset> -n <count>
>
>> +
>> +       if [ $current_kernel_index == "0" ]; then
>> +            echo 'kernel2'
>> +       elif [ $current_kernel_index == "1" ]; then
>> +            echo 'kernel1'
>> +       fi
>> +}
>> +
>> +ubnt_update_target_kernel() {
>> +       local factory_mtd=$1
>> +       local kernel_part=$2
>> +
>> +       local new_kernel_index
>> +       if [ $kernel_part == "kernel1" ]; then
>> +            new_kernel_index="\x00"
>> +       elif [ $kernel_part == "kernel2" ]; then
>> +            new_kernel_index="\x01"
>> +       else
>> +           echo 'Unknown kernel image index'
>
> Should echo to stderr >&2
>
>> +            exit 1
>
> Can we "return 1" and let the caller make the decision?
>
>> +       fi
>> +
>> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
>> +            echo 'Failed to update kernel bootup index'
>> +            exit 1
>
> ditto
>
>> +       fi
>> +}
>> +
>> +platform_upgrade_ubnt_erx() {
>> +       local factory_mtd=$(find_mtd_part factory)
>
> find_mtd_part is in another file, so better source it again here.
>
>> +       if [ ! -n "$factory_mtd" ]; then
>
> [ -z xxx ] should do
>
>> +               echo "cannot find factory partition"
>> +               exit 1
>> +       fi
>> +
>> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
>> +       if [ ! -n "$kernel_part" ]; then
>> +               echo "cannot find factory partition"
>> +               exit 1
>> +       fi
>> +
>> +       CI_KERNPART=${kernel_part}
>
> this variable is not referenced in the whole patch?

ok, it's a global defined by procd nand.sh.  the comment still slipped in...

>
>> +
>> +       #Remove volume possibly left over from stock firmware
>> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>> +       if [ ! "$ubidev" ]; then
>
> I thought [ -z "$ubidev" ] is the convention
>
>> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
>> +               if [ ! "$mtdnum" ]; then
>
> ditto
>
>> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
>> +                       return 1
>> +               fi
>> +               ubiattach -m "$mtdnum"
>> +               sync
>> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>> +       fi
>> +       if [ -n "$ubidev" ]; then
>> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
>> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
>
> ditto
>
>> +       fi
>> +
>> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
>> +}
>> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
>> index c90fc95..96f3416 100644
>> --- a/target/linux/ramips/dts/MT7621.dts
>> +++ b/target/linux/ramips/dts/MT7621.dts
>> @@ -31,4 +31,26 @@
>>                         };
>>                 };
>>         };
>> +
>> +       nand@1e003000 {
>> +               partition@0 {
>> +                       label = "uboot";
>> +                       reg = <0x00000 0x80000>; /* 64 KB */
>> +               };
>> +
>> +               partition@80000 {
>> +                       label = "uboot_env";
>> +                       reg = <0x80000 0x80000>; /* 64 KB */
>> +               };
>> +
>> +               partition@100000 {
>> +                       label = "factory";
>> +                       reg = <0x100000 0x40000>;
>> +               };
>> +
>> +               partition@140000 {
>> +                       label = "rootfs";
>> +                       reg = <0x140000 0xec0000>;
>> +               };
>> +       };
>>  };
>
> moving something from mt7621.dtsi to MT7621.dts should be in a
> separate patch with explanation.
>
>> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
>> new file mode 100644
>> index 0000000..4aa3be9
>> --- /dev/null
>> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
>> @@ -0,0 +1,117 @@
>> +/dts-v1/;
>> +
>> +/include/ "mt7621.dtsi"
>> +
>> +/ {
>> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
>> +       model = "UBNT-ERX";
>> +
>> +       memory@0 {
>> +               device_type = "memory";
>> +               reg = <0x0 0x10000000>;
>> +       };
>> +
>> +       chosen {
>> +               bootargs = "console=ttyS0,57600";
>> +       };
>> +
>> +       palmbus@1E000000 {
>> +               spi@b00 {
>> +                       /* This board has 2Mb spi flash soldered in and visible
>> +                          from manufacturer's firmware.
>> +                          But this SoC shares spi and nand pins,
>> +                          and current driver desn't handle this sharing well */
>> +                       status = "disabled";
>> +                       m25p80@0 {
>> +                               #address-cells = <1>;
>> +                               #size-cells = <1>;
>> +                               compatible = "m25p80";
>> +                               reg = <1>;
>> +                               linux,modalias = "m25p80";
>> +                               spi-max-frequency = <10000000>;
>> +
>> +                               partition@0 {
>> +                                       label = "spi";
>> +                                       reg = <0x0 0x200000>;
>> +                                       read-only;
>> +                               };
>> +                       };
>> +               };
>> +       };
>> +
>> +       nand@1e003000 {
>> +               compatible = "mtk,mt7621-nand";
>> +               bank-width = <2>;
>> +               reg = <0x1e003000 0x800
>> +                      0x1e003800 0x800>;
>> +               #address-cells = <1>;
>> +               #size-cells = <1>;
>> +
>> +               partition@0 {
>> +                       label = "u-boot";
>> +                       reg = <0x0 0x80000>;
>> +                       read-only;
>> +               };
>> +
>> +               partition@80000 {
>> +                       label = "u-boot-env";
>> +                       reg = <0x80000 0x60000>;
>> +                       read-only;
>> +               };
>> +
>> +               factory: partition@e0000 {
>> +                       label = "factory";
>> +                       reg = <0xe0000 0x60000>;
>> +               };
>> +
>> +               partition@140000 {
>> +                       label = "kernel1";
>> +                       reg = <0x140000 0x300000>;
>> +               };
>> +
>> +               partition@440000 {
>> +                       label = "kernel2";
>> +                       reg = <0x440000 0x300000>;
>> +               };
>> +
>> +               partition@740000 {
>> +                       label = "ubi";
>> +                       reg = <0x740000 0xf7c0000>;
>> +               };
>> +
>> +       };
>> +
>> +       ethernet@1e100000 {
>> +               mtd-mac-address = <&factory 0x22>;
>> +       };
>> +
>> +       pinctrl {
>> +               state_default: pinctrl0 {
>> +                       gpio {
>> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
>> +                               ralink,function = "gpio";
>> +                       };
>> +               };
>> +       };
>> +
>> +       sdhci@1E130000 {
>> +               status = "disabled";
>> +       };
>> +
>> +       pcie@1e140000 {
>> +               status = "disabled";
>> +       };
>> +
>> +       gpio-keys-polled {
>> +               compatible = "gpio-keys-polled";
>> +               #address-cells = <1>;
>> +               #size-cells = <0>;
>> +               poll-interval = <20>;
>> +
>> +               reset {
>> +                       label = "reset";
>> +                       gpios = <&gpio0 12 1>;
>> +                       linux,code = <0x198>;
>> +               };
>> +       };
>> +};
>> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
>> index fd2e100..c29a040 100644
>> --- a/target/linux/ramips/dts/mt7621.dtsi
>> +++ b/target/linux/ramips/dts/mt7621.dtsi
>> @@ -241,26 +241,6 @@
>>                         0x1e003800 0x800>;
>>                 #address-cells = <1>;
>>                 #size-cells = <1>;
>> -
>> -               partition@0 {
>> -                       label = "uboot";
>> -                       reg = <0x00000 0x80000>; /* 64 KB */
>> -               };
>> -
>> -               partition@80000 {
>> -                       label = "uboot_env";
>> -                       reg = <0x80000 0x80000>; /* 64 KB */
>> -               };
>> -
>> -               partition@100000 {
>> -                       label = "factory";
>> -                       reg = <0x100000 0x40000>;
>> -               };
>> -
>> -               partition@140000 {
>> -                       label = "rootfs";
>> -                       reg = <0x140000 0xec0000>;
>> -               };
>>         };
>>
>>         ethernet@1e100000 {
>> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
>> index 00a2923..6230688 100644
>> --- a/target/linux/ramips/image/Makefile
>> +++ b/target/linux/ramips/image/Makefile
>> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>>         mv $@.new $@
>>  endef
>>
>> +define Build/ubnt-erx-factory-compat
>> +       echo '21001:6' > $@.compat
>> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
>> +       $(RM) $@.compat
>> +endef
>> +
>> +define Build/ubnt-erx-factory-kernel
>> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
>> +               \
>> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
>> +               $(RM) $@.md5; \
>> +       fi
>> +endef
>> +
>> +define Build/ubnt-erx-factory-rootfs
>> +       echo "dummy" > $@.rootfs
>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
>> +
>> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
>> +       $(RM) $@.md5
>> +       $(RM) $@.rootfs
>> +endef
>> +
>> +define Build/ubnt-erx-factory-version
>> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
>> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
>> +       $(RM) $@.version
>> +endef
>> +
>> +#We need kernel+initrams fit into kernel partition
>> +define Build/ubnt-erx-factory-check-size
>> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
>> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
>> +               $(RM) -f $@; \
>> +       }
>> +
>> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
>> +               echo "WARNING: Kernel for image $@ not found" >&2; \
>> +               $(RM) -f $@; \
>> +       }
>> +endef
>> +
>>  define MkCombineduImage
>>         $(call PatchKernelLzma,$(2),$(3))
>>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
>> @@ -954,7 +999,7 @@ endif
>>  #
>>
>>  ifeq ($(SUBTARGET),mt7621)
>> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
>> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>>  endif
>>
>>  define Device/mt7621
>> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>>  endef
>>
>> +define Device/ubnt-erx
>> +  DTS := UBNT-ERX
>> +  FILESYSTEMS := squashfs
>> +  KERNEL_SIZE := 3145728
>> +  KERNEL := $(KERNEL_DTB) | uImage lzma
>> +  IMAGES := sysupgrade.tar factory-initramfs.tar
>> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
>> +                                ubnt-erx-factory-kernel | \
>> +                                ubnt-erx-factory-rootfs | \
>> +                                ubnt-erx-factory-version | \
>> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
>> +  IMAGE/sysupgrade.tar := sysupgrade-nand
>> +endef
>> +
>>  #
>>  # MT7628 Profiles
>>  #
>> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
>> new file mode 100644
>> index 0000000..67efa60
>> --- /dev/null
>> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
>> @@ -0,0 +1,17 @@
>> +#
>> +# Copyright (C) 2015 OpenWrt.org
>> +#
>> +# This is free software, licensed under the GNU General Public License v2.
>> +# See /LICENSE for more information.
>> +#
>> +
>> +define Profile/UBNT-ERX
>> +       NAME:=Ubiquiti EdgeRouter X
>> +       FEATURES += nand
>> +       PACKAGES:=-kmod-mt76 -wpad-mini
>> +endef
>> +
>> +define Profile/UBNT-ERX/Description
>> +       Package set compatible with the Ubiquiti EdgeRouter X
>> +endef
>> +$(eval $(call Profile,UBNT-ERX))
>> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>> new file mode 100644
>> index 0000000..a327674
>> --- /dev/null
>> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>> @@ -0,0 +1,43 @@
>> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
>> +From: Nikolay Martynov <mar.kolya@gmail.com>
>> +Date: Wed, 25 Nov 2015 20:43:46 -0500
>> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
>> +
>> +According to datasheet S34ML02G2 and S34ML04G2 have
>> +larger sparea area size than was detected.
>> +
>> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>> +---
>> + drivers/mtd/nand/nand_base.c | 9 +++++++++
>> + 1 file changed, 9 insertions(+)
>> +
>> +--- a/drivers/mtd/nand/nand_base.c
>> ++++ b/drivers/mtd/nand/nand_base.c
>> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
>> +       /*
>> +        * Field definitions are in the following datasheets:
>> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
>> ++       *                          Spansion S34ML02G2 (p.33)
>> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
>> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>> +        *
>> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
>> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
>> +
>> +               /*
>> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
>> ++               * as S34ML01G2 encoded in the same bit. We
>> ++               * differinciate them by their ID length
>> ++               */
>> ++              if (id_data[0] == NAND_MFR_AMD
>> ++                              && (id_data[1] == 0xda
>> ++                               || id_data[1] == 0xdc
>> ++                               || id_data[1] == 0xca
>> ++                               || id_data[1] == 0xcc)) {
>> ++                      mtd->oobsize *= 2;
>> ++              }
>> ++
>> ++              /*
>> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
>> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
>> +                * follows:
>> --
>> 2.6.3
>> _______________________________________________
>> openwrt-devel mailing list
>> openwrt-devel@lists.openwrt.org
>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Nikolay Martynov Dec. 11, 2015, 2:12 p.m. UTC | #6
Hi Yousong,

  Thank you so much for your review.
  Unfortunately I've resubmitted this patch as part of 4.3 fixes for
ramips before I've seen this message.
  I think I'll update and resubmit this patch again after John merges
CPS changes from series to avoid unnecessary conflicts.

Thanks!

2015-12-11 0:36 GMT-05:00 Yousong Zhou <yszhou4tech@gmail.com>:
>                 yousong
>
>
> On 11 December 2015 at 13:33, Yousong Zhou <yszhou4tech@gmail.com> wrote:
>> Hi, Nikolay,
>>
>> On 3 December 2015 at 15:16, Nikolay Martynov <mar.kolya@gmail.com> wrote:
>>> This router is based on MT7621 SoC, no wifi, nand.
>>>
>>> Works:
>>> * Boots.
>>> * Ethernet.
>>> * Switch.
>>> * Button (reset).
>>> * Flashing OpenWrt from stock firmware.
>>> * Upgrading OpenWrt.
>>>
>>> Doesn't work:
>>> * No GPIO leds. All leds are controlled by switch,
>>>   but stock firmware was able to control them.
>>
>> Try enabling SWCONFIG_LEDS and configure the trigger with
>> ucidef_set_led_switch like other platforms have done.  This works for
>> me with a mt7620 board.
>>
>>> * SoC has crypto engine but no open driver.
>>> * SoC has nat acceleration, but no open driver.
>>> * This router has 2MB spi flash soldered in but MT
>>>   nand/spi drivers do not support pin sharing,
>>>   so it is not accessable and disabled. Stock
>>>   firmware could read it and it was empty.
>>>
>>> Unknown status: PoE support.
>>>
>>> Router has serial pins populated. If looking at the top
>>> of the router, then counting from Eth sockets pins go as:
>>> 'GND, RX, TX, GND'. 3.3v, 57600.
>>>
>>> U-boot bootloader supports tftpboot, controlled from serial.
>>> This router has two kernel partitions: 'live' and 'backup'.
>>> They are swapped during flashing (on both stock and OpenWrt).
>>> Active partition is controlled by a flag in factory partition.
>>> U-boot has cusotm command to switch active kernel partition.
>>> Kernel partitions are 'bare flash' 3MB. Stock bootloader has
>>> no UBI support. Stock rootfs is UBIFS.
>>>
>>> Flashing procedure.
>>> Stock firmware uses custom kernel patch to mount squashfs
>>> from a file that is located on UBIFS volume. This makes wiping
>>> out this volume from within stock firmware difficult.
>>> Instead this patch builds image that is flashable by stock firmware
>>> and contains initrams image (with minimal set of packages
>>> to fit into kernel partition). Once this is flashed one can reboot
>>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>>> rootfs into nand.
>>> Note: factory image is only built if initramfs image is enabled.
>>
>> Most of these info should go to a wiki page for the device.
>>
>>>
>>> v2: Fix building all mt7621 targets along with ubnt-erx.
>>> v3: Undo change to MT7621 nand partitions, make nand detection
>>>     less likely to affect other nands.
>>> v4: Update as per Piotr Dymacz comments.
>>> v5: Fix upgrading code to actually upgrade kernel.
>>
>> The changelog should go below the three-dashes line (---).
>>
>> A few indentation issues were spotted and pointed out inline.
>>
>>>
>>> Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>>> ---
>>>  package/system/procd/files/nand.sh                 |   4 +
>>>  .../linux/ramips/base-files/etc/board.d/02_network |   1 +
>>>  target/linux/ramips/base-files/lib/ramips.sh       |   5 +-
>>>  .../ramips/base-files/lib/upgrade/platform.sh      |  24 +++++
>>>  target/linux/ramips/base-files/lib/upgrade/ubnt.sh |  71 +++++++++++++
>>>  target/linux/ramips/dts/MT7621.dts                 |  22 ++++
>>>  target/linux/ramips/dts/UBNT-ERX.dts               | 117 +++++++++++++++++++++
>>>  target/linux/ramips/dts/mt7621.dtsi                |  20 ----
>>>  target/linux/ramips/image/Makefile                 |  61 ++++++++++-
>>>  target/linux/ramips/mt7621/profiles/ubnt.mk        |  17 +++
>>>  .../patches-3.18/0901-spansion_nand_id_fix.patch   |  43 ++++++++
>>>  11 files changed, 363 insertions(+), 22 deletions(-)
>>>  create mode 100644 target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>>  create mode 100644 target/linux/ramips/dts/UBNT-ERX.dts
>>>  create mode 100644 target/linux/ramips/mt7621/profiles/ubnt.mk
>>>  create mode 100644 target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>>
>>> diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
>>> index 0c179cb..67867da 100644
>>> --- a/package/system/procd/files/nand.sh
>>> +++ b/package/system/procd/files/nand.sh
>>> @@ -275,6 +275,10 @@ nand_upgrade_tar() {
>>>  nand_do_upgrade_stage2() {
>>>         local file_type=$(identify $1)
>>>
>>> +       if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
>>> +           platform_nand_pre_upgrade "$1"
>>
>> bad indentation (tab replaced with blank spaces).  And this should be
>> in a separate patch
>>
>>> +       fi
>>> +
>>>         [ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
>>>
>>>         case "$file_type" in
>>> diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
>>> index 7e51229..de81553 100755
>>> --- a/target/linux/ramips/base-files/etc/board.d/02_network
>>> +++ b/target/linux/ramips/base-files/etc/board.d/02_network
>>> @@ -122,6 +122,7 @@ ramips_setup_interfaces()
>>>         f5d8235-v2|\
>>>         hg255d|\
>>>         rt-n14u|\
>>> +       ubnt-erx|\
>>>         ur-326n4g|\
>>>         wrtnode|\
>>>         wt3020|\
>>> diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
>>> index 92e13c0..ba23939 100755
>>> --- a/target/linux/ramips/base-files/lib/ramips.sh
>>> +++ b/target/linux/ramips/base-files/lib/ramips.sh
>>> @@ -349,6 +349,9 @@ ramips_board_detect() {
>>>         *"TEW-692GR")
>>>                 name="tew-692gr"
>>>                 ;;
>>> +       *"UBNT-ERX")
>>> +               name="ubnt-erx"
>>> +               ;;
>>>         *"UR-326N4G")
>>>                 name="ur-326n4g"
>>>                 ;;
>>> @@ -396,7 +399,7 @@ ramips_board_detect() {
>>>                 ;;
>>>         *"WizFi630A")
>>>                 name="wizfi630a"
>>> -               ;;
>>> +               ;;
>>>         *"WL-330N")
>>>                 name="wl-330n"
>>>                 ;;
>>> diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> index 073593a..b0d624e 100755
>>> --- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> +++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
>>> @@ -181,12 +181,36 @@ platform_check_image() {
>>>                 }
>>>                 return 0
>>>                 ;;
>>> +       ubnt-erx)
>>> +               nand_do_platform_check "$board" "$1"
>>
>> bad indentation
>>
>>> +               return $?;
>>> +               ;;
>>>         esac
>>>
>>>         echo "Sysupgrade is not yet supported on $board."
>>>         return 1
>>>  }
>>>
>>> +platform_nand_pre_upgrade() {
>>> +       local board=$(ramips_board_name)
>>> +
>>> +       case "$board" in
>>> +       ubnt-erx)
>>
>> bad indentation
>>
>>> +               platform_upgrade_ubnt_erx "$ARGV"
>>> +               ;;
>>> +       esac
>>> +}
>>> +
>>> +platform_pre_upgrade() {
>>> +       local board=$(ramips_board_name)
>>> +
>>> +       case "$board" in
>>> +       ubnt-erx)
>>> +               nand_do_upgrade "$ARGV"
>>> +               ;;
>>> +       esac
>>> +}
>>> +
>>>  platform_do_upgrade() {
>>>         local board=$(ramips_board_name)
>>>
>>> diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>> new file mode 100644
>>> index 0000000..0dc602b
>>> --- /dev/null
>>> +++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
>>
>> Indentation issues exist in this file.
>>
>>> @@ -0,0 +1,71 @@
>>> +#
>>> +# Copyright (C) 2015 OpenWrt.org
>>> +#
>>> +
>>> +UBNT_ERX_KERNEL_INDEX_OFFSET=160
>>> +
>>> +ubnt_get_target_kernel() {
>>> +        local factory_mtd=$1
>>> +        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
>>
>> hexdump alone can do the job with option -s <offset> -n <count>
>>
>>> +
>>> +       if [ $current_kernel_index == "0" ]; then
>>> +            echo 'kernel2'
>>> +       elif [ $current_kernel_index == "1" ]; then
>>> +            echo 'kernel1'
>>> +       fi
>>> +}
>>> +
>>> +ubnt_update_target_kernel() {
>>> +       local factory_mtd=$1
>>> +       local kernel_part=$2
>>> +
>>> +       local new_kernel_index
>>> +       if [ $kernel_part == "kernel1" ]; then
>>> +            new_kernel_index="\x00"
>>> +       elif [ $kernel_part == "kernel2" ]; then
>>> +            new_kernel_index="\x01"
>>> +       else
>>> +           echo 'Unknown kernel image index'
>>
>> Should echo to stderr >&2
>>
>>> +            exit 1
>>
>> Can we "return 1" and let the caller make the decision?
>>
>>> +       fi
>>> +
>>> +       if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
>>> +            echo 'Failed to update kernel bootup index'
>>> +            exit 1
>>
>> ditto
>>
>>> +       fi
>>> +}
>>> +
>>> +platform_upgrade_ubnt_erx() {
>>> +       local factory_mtd=$(find_mtd_part factory)
>>
>> find_mtd_part is in another file, so better source it again here.
>>
>>> +       if [ ! -n "$factory_mtd" ]; then
>>
>> [ -z xxx ] should do
>>
>>> +               echo "cannot find factory partition"
>>> +               exit 1
>>> +       fi
>>> +
>>> +       local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
>>> +       if [ ! -n "$kernel_part" ]; then
>>> +               echo "cannot find factory partition"
>>> +               exit 1
>>> +       fi
>>> +
>>> +       CI_KERNPART=${kernel_part}
>>
>> this variable is not referenced in the whole patch?
>
> ok, it's a global defined by procd nand.sh.  the comment still slipped in...
>
>>
>>> +
>>> +       #Remove volume possibly left over from stock firmware
>>> +       local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>>> +       if [ ! "$ubidev" ]; then
>>
>> I thought [ -z "$ubidev" ] is the convention
>>
>>> +               local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
>>> +               if [ ! "$mtdnum" ]; then
>>
>> ditto
>>
>>> +                       echo "cannot find ubi mtd partition $CI_UBIPART"
>>> +                       return 1
>>> +               fi
>>> +               ubiattach -m "$mtdnum"
>>> +               sync
>>> +               ubidev="$( nand_find_ubi "$CI_UBIPART" )"
>>> +       fi
>>> +       if [ -n "$ubidev" ]; then
>>> +               local troot_ubivol="$( nand_find_volume $ubidev troot )"
>>> +               [ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
>>
>> ditto
>>
>>> +       fi
>>> +
>>> +       ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
>>> +}
>>> diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
>>> index c90fc95..96f3416 100644
>>> --- a/target/linux/ramips/dts/MT7621.dts
>>> +++ b/target/linux/ramips/dts/MT7621.dts
>>> @@ -31,4 +31,26 @@
>>>                         };
>>>                 };
>>>         };
>>> +
>>> +       nand@1e003000 {
>>> +               partition@0 {
>>> +                       label = "uboot";
>>> +                       reg = <0x00000 0x80000>; /* 64 KB */
>>> +               };
>>> +
>>> +               partition@80000 {
>>> +                       label = "uboot_env";
>>> +                       reg = <0x80000 0x80000>; /* 64 KB */
>>> +               };
>>> +
>>> +               partition@100000 {
>>> +                       label = "factory";
>>> +                       reg = <0x100000 0x40000>;
>>> +               };
>>> +
>>> +               partition@140000 {
>>> +                       label = "rootfs";
>>> +                       reg = <0x140000 0xec0000>;
>>> +               };
>>> +       };
>>>  };
>>
>> moving something from mt7621.dtsi to MT7621.dts should be in a
>> separate patch with explanation.
>>
>>> diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
>>> new file mode 100644
>>> index 0000000..4aa3be9
>>> --- /dev/null
>>> +++ b/target/linux/ramips/dts/UBNT-ERX.dts
>>> @@ -0,0 +1,117 @@
>>> +/dts-v1/;
>>> +
>>> +/include/ "mt7621.dtsi"
>>> +
>>> +/ {
>>> +       compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
>>> +       model = "UBNT-ERX";
>>> +
>>> +       memory@0 {
>>> +               device_type = "memory";
>>> +               reg = <0x0 0x10000000>;
>>> +       };
>>> +
>>> +       chosen {
>>> +               bootargs = "console=ttyS0,57600";
>>> +       };
>>> +
>>> +       palmbus@1E000000 {
>>> +               spi@b00 {
>>> +                       /* This board has 2Mb spi flash soldered in and visible
>>> +                          from manufacturer's firmware.
>>> +                          But this SoC shares spi and nand pins,
>>> +                          and current driver desn't handle this sharing well */
>>> +                       status = "disabled";
>>> +                       m25p80@0 {
>>> +                               #address-cells = <1>;
>>> +                               #size-cells = <1>;
>>> +                               compatible = "m25p80";
>>> +                               reg = <1>;
>>> +                               linux,modalias = "m25p80";
>>> +                               spi-max-frequency = <10000000>;
>>> +
>>> +                               partition@0 {
>>> +                                       label = "spi";
>>> +                                       reg = <0x0 0x200000>;
>>> +                                       read-only;
>>> +                               };
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       nand@1e003000 {
>>> +               compatible = "mtk,mt7621-nand";
>>> +               bank-width = <2>;
>>> +               reg = <0x1e003000 0x800
>>> +                      0x1e003800 0x800>;
>>> +               #address-cells = <1>;
>>> +               #size-cells = <1>;
>>> +
>>> +               partition@0 {
>>> +                       label = "u-boot";
>>> +                       reg = <0x0 0x80000>;
>>> +                       read-only;
>>> +               };
>>> +
>>> +               partition@80000 {
>>> +                       label = "u-boot-env";
>>> +                       reg = <0x80000 0x60000>;
>>> +                       read-only;
>>> +               };
>>> +
>>> +               factory: partition@e0000 {
>>> +                       label = "factory";
>>> +                       reg = <0xe0000 0x60000>;
>>> +               };
>>> +
>>> +               partition@140000 {
>>> +                       label = "kernel1";
>>> +                       reg = <0x140000 0x300000>;
>>> +               };
>>> +
>>> +               partition@440000 {
>>> +                       label = "kernel2";
>>> +                       reg = <0x440000 0x300000>;
>>> +               };
>>> +
>>> +               partition@740000 {
>>> +                       label = "ubi";
>>> +                       reg = <0x740000 0xf7c0000>;
>>> +               };
>>> +
>>> +       };
>>> +
>>> +       ethernet@1e100000 {
>>> +               mtd-mac-address = <&factory 0x22>;
>>> +       };
>>> +
>>> +       pinctrl {
>>> +               state_default: pinctrl0 {
>>> +                       gpio {
>>> +                               ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
>>> +                               ralink,function = "gpio";
>>> +                       };
>>> +               };
>>> +       };
>>> +
>>> +       sdhci@1E130000 {
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       pcie@1e140000 {
>>> +               status = "disabled";
>>> +       };
>>> +
>>> +       gpio-keys-polled {
>>> +               compatible = "gpio-keys-polled";
>>> +               #address-cells = <1>;
>>> +               #size-cells = <0>;
>>> +               poll-interval = <20>;
>>> +
>>> +               reset {
>>> +                       label = "reset";
>>> +                       gpios = <&gpio0 12 1>;
>>> +                       linux,code = <0x198>;
>>> +               };
>>> +       };
>>> +};
>>> diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
>>> index fd2e100..c29a040 100644
>>> --- a/target/linux/ramips/dts/mt7621.dtsi
>>> +++ b/target/linux/ramips/dts/mt7621.dtsi
>>> @@ -241,26 +241,6 @@
>>>                         0x1e003800 0x800>;
>>>                 #address-cells = <1>;
>>>                 #size-cells = <1>;
>>> -
>>> -               partition@0 {
>>> -                       label = "uboot";
>>> -                       reg = <0x00000 0x80000>; /* 64 KB */
>>> -               };
>>> -
>>> -               partition@80000 {
>>> -                       label = "uboot_env";
>>> -                       reg = <0x80000 0x80000>; /* 64 KB */
>>> -               };
>>> -
>>> -               partition@100000 {
>>> -                       label = "factory";
>>> -                       reg = <0x100000 0x40000>;
>>> -               };
>>> -
>>> -               partition@140000 {
>>> -                       label = "rootfs";
>>> -                       reg = <0x140000 0xec0000>;
>>> -               };
>>>         };
>>>
>>>         ethernet@1e100000 {
>>> diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
>>> index 00a2923..6230688 100644
>>> --- a/target/linux/ramips/image/Makefile
>>> +++ b/target/linux/ramips/image/Makefile
>>> @@ -69,6 +69,51 @@ define Build/relocate-kernel
>>>         mv $@.new $@
>>>  endef
>>>
>>> +define Build/ubnt-erx-factory-compat
>>> +       echo '21001:6' > $@.compat
>>> +       $(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
>>> +       $(RM) $@.compat
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-kernel
>>> +       if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
>>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
>>> +               \
>>> +               md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
>>> +               $(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
>>> +               $(RM) $@.md5; \
>>> +       fi
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-rootfs
>>> +       echo "dummy" > $@.rootfs
>>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
>>> +
>>> +       md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
>>> +       $(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
>>> +       $(RM) $@.md5
>>> +       $(RM) $@.rootfs
>>> +endef
>>> +
>>> +define Build/ubnt-erx-factory-version
>>> +       echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
>>> +       $(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
>>> +       $(RM) $@.version
>>> +endef
>>> +
>>> +#We need kernel+initrams fit into kernel partition
>>> +define Build/ubnt-erx-factory-check-size
>>> +       @[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
>>> +               echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
>>> +               $(RM) -f $@; \
>>> +       }
>>> +
>>> +       @[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
>>> +               echo "WARNING: Kernel for image $@ not found" >&2; \
>>> +               $(RM) -f $@; \
>>> +       }
>>> +endef
>>> +
>>>  define MkCombineduImage
>>>         $(call PatchKernelLzma,$(2),$(3))
>>>         if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
>>> @@ -954,7 +999,7 @@ endif
>>>  #
>>>
>>>  ifeq ($(SUBTARGET),mt7621)
>>> -  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
>>> +  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
>>>  endif
>>>
>>>  define Device/mt7621
>>> @@ -1018,6 +1063,20 @@ define Device/wf-2881
>>>    IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
>>>  endef
>>>
>>> +define Device/ubnt-erx
>>> +  DTS := UBNT-ERX
>>> +  FILESYSTEMS := squashfs
>>> +  KERNEL_SIZE := 3145728
>>> +  KERNEL := $(KERNEL_DTB) | uImage lzma
>>> +  IMAGES := sysupgrade.tar factory-initramfs.tar
>>> +  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
>>> +                                ubnt-erx-factory-kernel | \
>>> +                                ubnt-erx-factory-rootfs | \
>>> +                                ubnt-erx-factory-version | \
>>> +                                ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
>>> +  IMAGE/sysupgrade.tar := sysupgrade-nand
>>> +endef
>>> +
>>>  #
>>>  # MT7628 Profiles
>>>  #
>>> diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
>>> new file mode 100644
>>> index 0000000..67efa60
>>> --- /dev/null
>>> +++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
>>> @@ -0,0 +1,17 @@
>>> +#
>>> +# Copyright (C) 2015 OpenWrt.org
>>> +#
>>> +# This is free software, licensed under the GNU General Public License v2.
>>> +# See /LICENSE for more information.
>>> +#
>>> +
>>> +define Profile/UBNT-ERX
>>> +       NAME:=Ubiquiti EdgeRouter X
>>> +       FEATURES += nand
>>> +       PACKAGES:=-kmod-mt76 -wpad-mini
>>> +endef
>>> +
>>> +define Profile/UBNT-ERX/Description
>>> +       Package set compatible with the Ubiquiti EdgeRouter X
>>> +endef
>>> +$(eval $(call Profile,UBNT-ERX))
>>> diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>> new file mode 100644
>>> index 0000000..a327674
>>> --- /dev/null
>>> +++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
>>> @@ -0,0 +1,43 @@
>>> +From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
>>> +From: Nikolay Martynov <mar.kolya@gmail.com>
>>> +Date: Wed, 25 Nov 2015 20:43:46 -0500
>>> +Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
>>> +
>>> +According to datasheet S34ML02G2 and S34ML04G2 have
>>> +larger sparea area size than was detected.
>>> +
>>> +Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
>>> +---
>>> + drivers/mtd/nand/nand_base.c | 9 +++++++++
>>> + 1 file changed, 9 insertions(+)
>>> +
>>> +--- a/drivers/mtd/nand/nand_base.c
>>> ++++ b/drivers/mtd/nand/nand_base.c
>>> +@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
>>> +       /*
>>> +        * Field definitions are in the following datasheets:
>>> +        * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
>>> ++       *                          Spansion S34ML02G2 (p.33)
>>> +        * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
>>> +        * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
>>> +        *
>>> +@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
>>> +               *busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
>>> +
>>> +               /*
>>> ++               * Spansion S34ML0[24]G2 have oobsize twice as large
>>> ++               * as S34ML01G2 encoded in the same bit. We
>>> ++               * differinciate them by their ID length
>>> ++               */
>>> ++              if (id_data[0] == NAND_MFR_AMD
>>> ++                              && (id_data[1] == 0xda
>>> ++                               || id_data[1] == 0xdc
>>> ++                               || id_data[1] == 0xca
>>> ++                               || id_data[1] == 0xcc)) {
>>> ++                      mtd->oobsize *= 2;
>>> ++              }
>>> ++
>>> ++              /*
>>> +                * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
>>> +                * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
>>> +                * follows:
>>> --
>>> 2.6.3
>>> _______________________________________________
>>> openwrt-devel mailing list
>>> openwrt-devel@lists.openwrt.org
>>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
Nikolay Martynov Dec. 12, 2015, 6:33 a.m. UTC | #7
Hi

>>
>> Doesn't work:
>> * No GPIO leds. All leds are controlled by switch,
>>   but stock firmware was able to control them.
>
> Try enabling SWCONFIG_LEDS and configure the trigger with
> ucidef_set_led_switch like other platforms have done.  This works for
> me with a mt7620 board.

  I've tried enabling SWCONFIG_LEDS and adding ucidef_set_led_switch
but could ntot make it work. And it also doesn't seem to produce any
log output. Is SWCONFIG_LEDS known to work with mt7621 switch? Is
there something else I need to do to enable it?
  Would this patch be acceptable without leds working? I will see if I
can make them work later.

>> Flashing procedure.
>> Stock firmware uses custom kernel patch to mount squashfs
>> from a file that is located on UBIFS volume. This makes wiping
>> out this volume from within stock firmware difficult.
>> Instead this patch builds image that is flashable by stock firmware
>> and contains initrams image (with minimal set of packages
>> to fit into kernel partition). Once this is flashed one can reboot
>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>> rootfs into nand.
>> Note: factory image is only built if initramfs image is enabled.
>
> Most of these info should go to a wiki page for the device.

  I was hoping to have these saved in commit message first and then
see if I can create/update wiki page for this device.

  I have other requested changes sitting it my git, so if lack of leds
support is fine I'll resubmit.

Thanks!
John Crispin Dec. 12, 2015, 6:39 a.m. UTC | #8
On 12/12/2015 07:33, Nikolay Martynov wrote:
>   Hi
> 
>>>
>>> Doesn't work:
>>> * No GPIO leds. All leds are controlled by switch,
>>>   but stock firmware was able to control them.
>>
>> Try enabling SWCONFIG_LEDS and configure the trigger with
>> ucidef_set_led_switch like other platforms have done.  This works for
>> me with a mt7620 board.
> 
>   I've tried enabling SWCONFIG_LEDS and adding ucidef_set_led_switch
> but could ntot make it work. And it also doesn't seem to produce any
> log output. Is SWCONFIG_LEDS known to work with mt7621 switch? Is
> there something else I need to do to enable it?
>   Would this patch be acceptable without leds working? I will see if I
> can make them work later.
> 

sure. we are opportunistic when it comes to patches ;)

as for the led support, you need to add an extra hook function so that
swconfig can read the per port traffic counters. it can then make gpio
leds flash based on those values.

the function to be added is called .get_port_stats if i am not mistaken.
i think the swconfig driver already reads the traffic counters in some
other place/context

>>> Flashing procedure.
>>> Stock firmware uses custom kernel patch to mount squashfs
>>> from a file that is located on UBIFS volume. This makes wiping
>>> out this volume from within stock firmware difficult.
>>> Instead this patch builds image that is flashable by stock firmware
>>> and contains initrams image (with minimal set of packages
>>> to fit into kernel partition). Once this is flashed one can reboot
>>> into initramfs OpenWrt and use sysupgrade to flash OpenWrt including
>>> rootfs into nand.
>>> Note: factory image is only built if initramfs image is enabled.
>>
>> Most of these info should go to a wiki page for the device.
> 
>   I was hoping to have these saved in commit message first and then
> see if I can create/update wiki page for this device.
> 
>   I have other requested changes sitting it my git, so if lack of leds
> support is fine I'll resubmit.
> 

ok, go for it ... leds are nice but not a blocker.

on a related matter .. does this unit have a locked down bootloader ?
Nikolay Martynov Dec. 12, 2015, 6:50 a.m. UTC | #9
Hi, John.

>
> as for the led support, you need to add an extra hook function so that
> swconfig can read the per port traffic counters. it can then make gpio
> leds flash based on those values.

  Just to make sure we are on the same page: the problem is that this
router doesn't have gpio-driven leds. Only leds it has are connected
directly to switch and those are not exposed as gpios.
  Is SWCONFIG_LEDS the thing that designed to help is this case? Or is
it for the case when we have leds on gpios and switch without directly
connected leds?

>>   I have other requested changes sitting it my git, so if lack of leds
>> support is fine I'll resubmit.
>>
>
> ok, go for it ... leds are nice but not a blocker.
Thanks!

>
> on a related matter .. does this unit have a locked down bootloader ?
No, as far as I can see it does not. It has uboot and they provide code for it.

Thanks!
John Crispin Dec. 12, 2015, 7:01 a.m. UTC | #10
On 12/12/2015 07:50, Nikolay Martynov wrote:
> Hi, John.
> 
>>
>> as for the led support, you need to add an extra hook function so that
>> swconfig can read the per port traffic counters. it can then make gpio
>> leds flash based on those values.
> 
>   Just to make sure we are on the same page: the problem is that this
> router doesn't have gpio-driven leds. Only leds it has are connected
> directly to switch and those are not exposed as gpios.
>   Is SWCONFIG_LEDS the thing that designed to help is this case? Or is
> it for the case when we have leds on gpios and switch without directly
> connected leds?

ah ok, i though the automagic leds dont work and you have gpio leds.
some ODMs do that for unknown reasons. in those cases the you need the
SWCONFIG_LEDS. do they just stay silent for you now ?







> 
>>>   I have other requested changes sitting it my git, so if lack of leds
>>> support is fine I'll resubmit.
>>>
>>
>> ok, go for it ... leds are nice but not a blocker.
> Thanks!
> 
>>
>> on a related matter .. does this unit have a locked down bootloader ?
> No, as far as I can see it does not. It has uboot and they provide code for it.
> 
> Thanks!
>
Nikolay Martynov Dec. 12, 2015, 4:03 p.m. UTC | #11
Hi

2015-12-12 2:01 GMT-05:00 John Crispin <blogic@openwrt.org>:
>
>
> On 12/12/2015 07:50, Nikolay Martynov wrote:
>> Hi, John.
>>
>>>
>>> as for the led support, you need to add an extra hook function so that
>>> swconfig can read the per port traffic counters. it can then make gpio
>>> leds flash based on those values.
>>
>>   Just to make sure we are on the same page: the problem is that this
>> router doesn't have gpio-driven leds. Only leds it has are connected
>> directly to switch and those are not exposed as gpios.
>>   Is SWCONFIG_LEDS the thing that designed to help is this case? Or is
>> it for the case when we have leds on gpios and switch without directly
>> connected leds?
>
> ah ok, i though the automagic leds dont work and you have gpio leds.
> some ODMs do that for unknown reasons. in those cases the you need the
> SWCONFIG_LEDS. do they just stay silent for you now ?
>
  No, they blink with traffic alright.

  The problem I was trying to solve is to give some visual
notification during upgrade.
  Stock firmware locked one led on. I do not have source for stock
kernel module that does it, but I looked at U-boot and it looks like
there's some code that controls those leds via mdio. I do not know
what exactly they are doing - it might well be they just make link
status stuck on.
  I couldn't find anything similar to this in linux kernel.
John Crispin Dec. 12, 2015, 4:15 p.m. UTC | #12
On 12/12/2015 17:03, Nikolay Martynov wrote:
> Hi
> 
> 2015-12-12 2:01 GMT-05:00 John Crispin <blogic@openwrt.org>:
>>
>>
>> On 12/12/2015 07:50, Nikolay Martynov wrote:
>>> Hi, John.
>>>
>>>>
>>>> as for the led support, you need to add an extra hook function so that
>>>> swconfig can read the per port traffic counters. it can then make gpio
>>>> leds flash based on those values.
>>>
>>>   Just to make sure we are on the same page: the problem is that this
>>> router doesn't have gpio-driven leds. Only leds it has are connected
>>> directly to switch and those are not exposed as gpios.
>>>   Is SWCONFIG_LEDS the thing that designed to help is this case? Or is
>>> it for the case when we have leds on gpios and switch without directly
>>> connected leds?
>>
>> ah ok, i though the automagic leds dont work and you have gpio leds.
>> some ODMs do that for unknown reasons. in those cases the you need the
>> SWCONFIG_LEDS. do they just stay silent for you now ?
>>
>   No, they blink with traffic alright.
> 
>   The problem I was trying to solve is to give some visual
> notification during upgrade.
>   Stock firmware locked one led on. I do not have source for stock
> kernel module that does it, but I looked at U-boot and it looks like
> there's some code that controls those leds via mdio. I do not know
> what exactly they are doing - it might well be they just make link
> status stuck on.
>   I couldn't find anything similar to this in linux kernel.
> 

i just checked the switches datasheet and there is a register to turn
the leds into gpios. and another to control them. i'll convert the
relevant bits of the pdf to a header file during the next days.
diff mbox

Patch

diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh
index 0c179cb..67867da 100644
--- a/package/system/procd/files/nand.sh
+++ b/package/system/procd/files/nand.sh
@@ -275,6 +275,10 @@  nand_upgrade_tar() {
 nand_do_upgrade_stage2() {
 	local file_type=$(identify $1)
 
+	if type 'platform_nand_pre_upgrade' >/dev/null 2>/dev/null; then
+	    platform_nand_pre_upgrade "$1"
+	fi
+
 	[ ! "$(find_mtd_index "$CI_UBIPART")" ] && CI_UBIPART="rootfs"
 
 	case "$file_type" in
diff --git a/target/linux/ramips/base-files/etc/board.d/02_network b/target/linux/ramips/base-files/etc/board.d/02_network
index 7e51229..de81553 100755
--- a/target/linux/ramips/base-files/etc/board.d/02_network
+++ b/target/linux/ramips/base-files/etc/board.d/02_network
@@ -122,6 +122,7 @@  ramips_setup_interfaces()
 	f5d8235-v2|\
 	hg255d|\
 	rt-n14u|\
+	ubnt-erx|\
 	ur-326n4g|\
 	wrtnode|\
 	wt3020|\
diff --git a/target/linux/ramips/base-files/lib/ramips.sh b/target/linux/ramips/base-files/lib/ramips.sh
index 92e13c0..ba23939 100755
--- a/target/linux/ramips/base-files/lib/ramips.sh
+++ b/target/linux/ramips/base-files/lib/ramips.sh
@@ -349,6 +349,9 @@  ramips_board_detect() {
 	*"TEW-692GR")
 		name="tew-692gr"
 		;;
+	*"UBNT-ERX")
+		name="ubnt-erx"
+		;;
 	*"UR-326N4G")
 		name="ur-326n4g"
 		;;
@@ -396,7 +399,7 @@  ramips_board_detect() {
 		;;
 	*"WizFi630A")
 		name="wizfi630a"
-		;;                
+		;;
 	*"WL-330N")
 		name="wl-330n"
 		;;
diff --git a/target/linux/ramips/base-files/lib/upgrade/platform.sh b/target/linux/ramips/base-files/lib/upgrade/platform.sh
index 073593a..b0d624e 100755
--- a/target/linux/ramips/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ramips/base-files/lib/upgrade/platform.sh
@@ -181,12 +181,36 @@  platform_check_image() {
 		}
 		return 0
 		;;
+	ubnt-erx)
+    		nand_do_platform_check "$board" "$1"
+		return $?;
+		;;
 	esac
 
 	echo "Sysupgrade is not yet supported on $board."
 	return 1
 }
 
+platform_nand_pre_upgrade() {
+	local board=$(ramips_board_name)
+
+	case "$board" in
+    	ubnt-erx)
+		platform_upgrade_ubnt_erx "$ARGV"
+		;;
+	esac
+}
+
+platform_pre_upgrade() {
+	local board=$(ramips_board_name)
+
+	case "$board" in
+    	ubnt-erx)
+		nand_do_upgrade "$ARGV"
+		;;
+	esac
+}
+
 platform_do_upgrade() {
 	local board=$(ramips_board_name)
 
diff --git a/target/linux/ramips/base-files/lib/upgrade/ubnt.sh b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
new file mode 100644
index 0000000..0dc602b
--- /dev/null
+++ b/target/linux/ramips/base-files/lib/upgrade/ubnt.sh
@@ -0,0 +1,71 @@ 
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+
+UBNT_ERX_KERNEL_INDEX_OFFSET=160
+
+ubnt_get_target_kernel() {
+        local factory_mtd=$1
+        local current_kernel_index=$(dd if=${factory_mtd} bs=1 count=1 skip=$UBNT_ERX_KERNEL_INDEX_OFFSET 2>/dev/null|hexdump -e '/1 "%X "')
+
+	if [ $current_kernel_index == "0" ]; then
+            echo 'kernel2'
+	elif [ $current_kernel_index == "1" ]; then
+            echo 'kernel1'
+	fi
+}
+
+ubnt_update_target_kernel() {
+	local factory_mtd=$1
+	local kernel_part=$2
+
+	local new_kernel_index
+	if [ $kernel_part == "kernel1" ]; then
+            new_kernel_index="\x00"
+	elif [ $kernel_part == "kernel2" ]; then
+            new_kernel_index="\x01"
+	else
+	    echo 'Unknown kernel image index'
+            exit 1
+	fi
+
+	if ! (echo -e $new_kernel_index | dd of=${factory_mtd} bs=1 count=1 seek=$UBNT_ERX_KERNEL_INDEX_OFFSET); then
+            echo 'Failed to update kernel bootup index'
+            exit 1
+	fi
+}
+
+platform_upgrade_ubnt_erx() {
+ 	local factory_mtd=$(find_mtd_part factory)
+	if [ ! -n "$factory_mtd" ]; then
+		echo "cannot find factory partition"
+		exit 1
+	fi
+
+	local kernel_part="$(ubnt_get_target_kernel ${factory_mtd})"
+	if [ ! -n "$kernel_part" ]; then
+		echo "cannot find factory partition"
+		exit 1
+	fi
+
+	CI_KERNPART=${kernel_part}
+
+	#Remove volume possibly left over from stock firmware
+	local ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	if [ ! "$ubidev" ]; then
+	    	local mtdnum="$( find_mtd_index "$CI_UBIPART" )"
+		if [ ! "$mtdnum" ]; then
+			echo "cannot find ubi mtd partition $CI_UBIPART"
+			return 1
+		fi
+		ubiattach -m "$mtdnum"
+		sync
+		ubidev="$( nand_find_ubi "$CI_UBIPART" )"
+	fi
+	if [ -n "$ubidev" ]; then
+	    	local troot_ubivol="$( nand_find_volume $ubidev troot )"
+		[ "$troot_ubivol" ] && ubirmvol /dev/$ubidev -N troot || true
+	fi
+
+	ubnt_update_target_kernel ${factory_mtd} ${kernel_part}
+}
diff --git a/target/linux/ramips/dts/MT7621.dts b/target/linux/ramips/dts/MT7621.dts
index c90fc95..96f3416 100644
--- a/target/linux/ramips/dts/MT7621.dts
+++ b/target/linux/ramips/dts/MT7621.dts
@@ -31,4 +31,26 @@ 
 			};
 		};
 	};
+
+	nand@1e003000 {
+		partition@0 {
+			label = "uboot";
+			reg = <0x00000 0x80000>; /* 64 KB */
+		};
+
+		partition@80000 {
+			label = "uboot_env";
+			reg = <0x80000 0x80000>; /* 64 KB */
+		};
+
+		partition@100000 {
+			label = "factory";
+			reg = <0x100000 0x40000>;
+		};
+
+		partition@140000 {
+			label = "rootfs";
+			reg = <0x140000 0xec0000>;
+		};
+	};
 };
diff --git a/target/linux/ramips/dts/UBNT-ERX.dts b/target/linux/ramips/dts/UBNT-ERX.dts
new file mode 100644
index 0000000..4aa3be9
--- /dev/null
+++ b/target/linux/ramips/dts/UBNT-ERX.dts
@@ -0,0 +1,117 @@ 
+/dts-v1/;
+
+/include/ "mt7621.dtsi"
+
+/ {
+	compatible = "mediatek,mt7621-eval-board", "mediatek,mt7621-soc";
+	model = "UBNT-ERX";
+
+	memory@0 {
+		device_type = "memory";
+		reg = <0x0 0x10000000>;
+	};
+
+	chosen {
+		bootargs = "console=ttyS0,57600";
+	};
+
+	palmbus@1E000000 {
+		spi@b00 {
+			/* This board has 2Mb spi flash soldered in and visible
+			   from manufacturer's firmware.
+			   But this SoC shares spi and nand pins,
+			   and current driver desn't handle this sharing well */
+			status = "disabled";
+			m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "m25p80";
+				reg = <1>;
+				linux,modalias = "m25p80";
+				spi-max-frequency = <10000000>;
+
+				partition@0 {
+					label = "spi";
+					reg = <0x0 0x200000>;
+					read-only;
+				};
+			};
+		};
+	};
+
+	nand@1e003000 {
+		compatible = "mtk,mt7621-nand";
+		bank-width = <2>;
+		reg = <0x1e003000 0x800
+		       0x1e003800 0x800>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+
+		partition@0 {
+			label = "u-boot";
+			reg = <0x0 0x80000>;
+			read-only;
+		};
+
+		partition@80000 {
+			label = "u-boot-env";
+			reg = <0x80000 0x60000>;
+			read-only;
+		};
+
+		factory: partition@e0000 {
+			label = "factory";
+			reg = <0xe0000 0x60000>;
+		};
+
+		partition@140000 {
+			label = "kernel1";
+			reg = <0x140000 0x300000>;
+		};
+
+		partition@440000 {
+			label = "kernel2";
+			reg = <0x440000 0x300000>;
+		};
+
+		partition@740000 {
+			label = "ubi";
+			reg = <0x740000 0xf7c0000>;
+		};
+
+	};
+
+	ethernet@1e100000 {
+		mtd-mac-address = <&factory 0x22>;
+	};
+
+	pinctrl {
+		state_default: pinctrl0 {
+			gpio {
+				ralink,group = "uart2", "uart3", "i2c", "pcie", "rgmii2", "jtag";
+				ralink,function = "gpio";
+			};
+		};
+	};
+
+	sdhci@1E130000 {
+		status = "disabled";
+	};
+
+	pcie@1e140000 {
+		status = "disabled";
+	};
+
+	gpio-keys-polled {
+		compatible = "gpio-keys-polled";
+		#address-cells = <1>;
+		#size-cells = <0>;
+		poll-interval = <20>;
+
+		reset {
+			label = "reset";
+			gpios = <&gpio0 12 1>;
+			linux,code = <0x198>;
+		};
+	};
+};
diff --git a/target/linux/ramips/dts/mt7621.dtsi b/target/linux/ramips/dts/mt7621.dtsi
index fd2e100..c29a040 100644
--- a/target/linux/ramips/dts/mt7621.dtsi
+++ b/target/linux/ramips/dts/mt7621.dtsi
@@ -241,26 +241,6 @@ 
 			0x1e003800 0x800>;
 		#address-cells = <1>;
 		#size-cells = <1>;
-
-		partition@0 {
-			label = "uboot";
-			reg = <0x00000 0x80000>; /* 64 KB */
-		};
-
-		partition@80000 {
-			label = "uboot_env";
-			reg = <0x80000 0x80000>; /* 64 KB */
-		};
-
-		partition@100000 {
-			label = "factory";
-			reg = <0x100000 0x40000>;
-		};
-
-		partition@140000 {
-			label = "rootfs";
-			reg = <0x140000 0xec0000>;
-		};
 	};
 
 	ethernet@1e100000 {
diff --git a/target/linux/ramips/image/Makefile b/target/linux/ramips/image/Makefile
index 00a2923..6230688 100644
--- a/target/linux/ramips/image/Makefile
+++ b/target/linux/ramips/image/Makefile
@@ -69,6 +69,51 @@  define Build/relocate-kernel
 	mv $@.new $@
 endef
 
+define Build/ubnt-erx-factory-compat
+	echo '21001:6' > $@.compat
+	$(TAR) -cf $@ --transform='s/^.*/compat/' $@.compat
+	$(RM) $@.compat
+endef
+
+define Build/ubnt-erx-factory-kernel
+	if [ -e $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) ]; then \
+		$(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp/' $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE); \
+		\
+		md5sum --binary $(BIN_DIR)/$(KERNEL_INITRAMFS_IMAGE) | awk '{print $$1}'> $@.md5; \
+		$(TAR) -rf $@ --transform='s/^.*/vmlinux.tmp.md5/' $@.md5; \
+		$(RM) $@.md5; \
+	fi
+endef
+
+define Build/ubnt-erx-factory-rootfs
+	echo "dummy" > $@.rootfs
+	$(TAR) -rf $@ --transform='s/^.*/squashfs.tmp/' $@.rootfs
+
+	md5sum --binary $@.rootfs | awk '{print $$1}'> $@.md5
+	$(TAR) -rf $@ --transform='s/^.*/squashfs.tmp.md5/' $@.md5
+	$(RM) $@.md5
+	$(RM) $@.rootfs
+endef
+
+define Build/ubnt-erx-factory-version
+	echo '$(BOARD) $(VERSION_CODE) $(VERSION_NUMBER)' > $@.version
+	$(TAR) -rf $@ --transform='s/^.*/version.tmp/' $@.version
+	$(RM) $@.version
+endef
+
+#We need kernel+initrams fit into kernel partition
+define Build/ubnt-erx-factory-check-size
+	@[ $$(($(subst k,* 1024,$(subst m, * 1024k,$(1))))) -ge "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" ] || { \
+		echo "WARNING: Initramfs kernel for image $@ is too big (kernel size: $$($(TAR) -xf $@ vmlinux.tmp -O | wc -c), max size $(1))" >&2; \
+		$(RM) -f $@; \
+	}
+
+	@[ "$$($(TAR) -xf $@ vmlinux.tmp -O | wc -c)" -gt 0 ] || { \
+		echo "WARNING: Kernel for image $@ not found" >&2; \
+		$(RM) -f $@; \
+	}
+endef
+
 define MkCombineduImage
 	$(call PatchKernelLzma,$(2),$(3))
 	if [ `stat -c%s "$(KDIR)/vmlinux-$(2).bin.lzma"` -gt `expr $(4) - 64` ]; then \
@@ -954,7 +999,7 @@  endif
 #
 
 ifeq ($(SUBTARGET),mt7621)
-  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881
+  TARGET_DEVICES += mt7621 wsr-600 wsr-1166 dir-860l-b1 firewrt pbr-m1 re6500 sap-g3200u3 zbt-wg2626 wf-2881 ubnt-erx
 endif
 
 define Device/mt7621
@@ -1018,6 +1063,20 @@  define Device/wf-2881
   IMAGE/sysupgrade.bin := append-kernel | pad-to $$(KERNEL_SIZE) | append-ubi | check-size $$$$(IMAGE_SIZE)
 endef
 
+define Device/ubnt-erx
+  DTS := UBNT-ERX
+  FILESYSTEMS := squashfs
+  KERNEL_SIZE := 3145728
+  KERNEL := $(KERNEL_DTB) | uImage lzma
+  IMAGES := sysupgrade.tar factory-initramfs.tar
+  IMAGE/factory-initramfs.tar := ubnt-erx-factory-compat | \
+				 ubnt-erx-factory-kernel | \
+				 ubnt-erx-factory-rootfs | \
+				 ubnt-erx-factory-version | \
+				 ubnt-erx-factory-check-size $$$$(KERNEL_SIZE)
+  IMAGE/sysupgrade.tar := sysupgrade-nand
+endef
+
 #
 # MT7628 Profiles
 #
diff --git a/target/linux/ramips/mt7621/profiles/ubnt.mk b/target/linux/ramips/mt7621/profiles/ubnt.mk
new file mode 100644
index 0000000..67efa60
--- /dev/null
+++ b/target/linux/ramips/mt7621/profiles/ubnt.mk
@@ -0,0 +1,17 @@ 
+#
+# Copyright (C) 2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+define Profile/UBNT-ERX
+	NAME:=Ubiquiti EdgeRouter X
+	FEATURES += nand
+	PACKAGES:=-kmod-mt76 -wpad-mini
+endef
+
+define Profile/UBNT-ERX/Description
+	Package set compatible with the Ubiquiti EdgeRouter X
+endef
+$(eval $(call Profile,UBNT-ERX))
diff --git a/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
new file mode 100644
index 0000000..a327674
--- /dev/null
+++ b/target/linux/ramips/patches-3.18/0901-spansion_nand_id_fix.patch
@@ -0,0 +1,43 @@ 
+From 8b61a1a33e41456ebeafa0ebe7ec0fccf859861e Mon Sep 17 00:00:00 2001
+From: Nikolay Martynov <mar.kolya@gmail.com>
+Date: Wed, 25 Nov 2015 20:43:46 -0500
+Subject: [PATCH] mtd: nand: Fix Spansion sparearea size detection
+
+According to datasheet S34ML02G2 and S34ML04G2 have
+larger sparea area size than was detected.
+
+Signed-off-by: Nikolay Martynov <mar.kolya@gmail.com>
+---
+ drivers/mtd/nand/nand_base.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/mtd/nand/nand_base.c
++++ b/drivers/mtd/nand/nand_base.c
+@@ -3399,6 +3399,7 @@ static void nand_decode_ext_id(struct mt
+ 	/*
+ 	 * Field definitions are in the following datasheets:
+ 	 * Old style (4,5 byte ID): Samsung K9GAG08U0M (p.32)
++	 *                          Spansion S34ML02G2 (p.33)
+ 	 * New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44)
+ 	 * Hynix MLC   (6 byte ID): Hynix H27UBG8T2B (p.22)
+ 	 *
+@@ -3496,6 +3497,19 @@ static void nand_decode_ext_id(struct mt
+ 		*busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
+ 
+ 		/*
++		 * Spansion S34ML0[24]G2 have oobsize twice as large
++		 * as S34ML01G2 encoded in the same bit. We
++		 * differinciate them by their ID length
++		 */
++		if (id_data[0] == NAND_MFR_AMD
++		    		&& (id_data[1] == 0xda
++				 || id_data[1] == 0xdc
++				 || id_data[1] == 0xca
++				 || id_data[1] == 0xcc)) {
++			mtd->oobsize *= 2;
++		}
++
++		/*
+ 		 * Toshiba 24nm raw SLC (i.e., not BENAND) have 32B OOB per
+ 		 * 512B page. For Toshiba SLC, we decode the 5th/6th byte as
+ 		 * follows: