ath79: GL-AR300M: provide NAND support; increase to 4 MB kernel

The GL.iNet GL-AR300M has been supported by the ar71xx and ath79
platforms with access to its 16 MB NOR flash, but not its 128 MB
SPI NAND flash.

This commit provides support for the NAND through the upstream
SPI-NAND framework. Devices with both NOR and NAND flash can support
independent firmware on each, with U-Boot able to boot from either.
The OEM U-Boot will fall back to the NOR firmware after three
"unsuccessful" boots.

The family of GL-AR300M devices on the ath79 platform now includes:

  * glinet,gl-ar300m-lite       "generic" target, NOR-only board
  * glinet,gl-ar300m-nand       "nand" target
  * glinet,gl-ar300m-nor        "nand" target (NAND-aware)

NB: This commit increases the kernel size from 2 MB to 4 MB

"Force-less" sysupgrade is presently supported from the current
versions of following NOR-based firmwre images to the version of
glinet,gl-ar300m-nor firmware produced by this commit:

  * gl-ar300m            -- OEM v3 NOR    ar71xx (openwrt-ar300m16-*.bin)
  * gl-ar300m            -- OpenWrt 18.06 ar71xx
  * gl-ar300m            -- OpenWrt 19.07 ar71xx

Other upgrades to these images should be performed through U-Boot.

The GL-AR300M OEM U-Boot allows upload and flashing of either NOR
firmware (sysupgrade.bin) or NAND firmware (factory.img) through its
HTTP-based GUI. Serial connectivity is not required.

The glinet,gl-ar300m-nand and glinet,gl-ar300m-nor images generated
after this commit should safely flash each other using sysupgrade.

The boot counter is implemented by the OEM using u-boot-env. At this
time, it does not appear that the switch on the side of the unit can
be used to select NOR vs. NAND boot and the fail-over is only from
NAND to NOR. To save flash wear, it is only reset when running the
glinet,gl-ar300m-nand firmware.

NAND-specific base-files are used to remove impact on existing
generic and tiny targets.

As there is now no "generic" build appropriate for the GL-AR300M16,
(or for users of the GL-AR300M that do not need access to NAND)
it will be introduced in a subsequent commit.

Note: `mtd_get_mac_binary art 0x6` does not return the proper MAC
and the GL.iNet source indicates that only the 0x0 offset is valid

The ar71xx targets are unmodified.

Signed-off-by: Jeff Kletsky <git-commits@allycomm.com>
This commit is contained in:
Jeff Kletsky 2019-06-01 17:51:17 -07:00 committed by Chuanhong Guo
parent 20b3e77ba3
commit 55e6c903ae
11 changed files with 183 additions and 56 deletions

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "qca9531_glinet_gl-ar300m.dtsi"
@ -7,6 +9,8 @@
model = "GL.iNet GL-AR300M-Lite";
};
/delete-node/ &nand_flash;
// "Disable" unpopulated GMAC1
&eth1 {

View File

@ -1,3 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
/dts-v1/;
#include "qca9531_glinet_gl-ar300m.dtsi"
@ -7,28 +9,10 @@
model = "GL.iNet GL-AR300M (NAND)";
};
&spi {
num-cs = <1>;
flash@1 {
compatible = "spinand,mt29f";
reg = <1>;
spi-max-frequency = <25000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
partition@0 {
label = "kernel";
reg = <0x000000 0x0200000>;
};
partition@1 {
label = "ubi";
reg = <0x200000 0x7e00000>;
};
};
};
&nand_kernel {
label = "kernel";
};
&nand_ubi {
label = "ubi";
};

View File

@ -6,3 +6,8 @@
compatible = "glinet,gl-ar300m-nor", "qca,qca9531";
model = "GL.iNet GL-AR300M (NOR)";
};
&nor_firmware {
compatible = "denx,uimage";
label = "firmware";
};

View File

@ -42,7 +42,7 @@
leds {
compatible = "gpio-leds";
// Colors from non-Lite versions
// Colors for non-Lite versions
led_status: status {
label = "gl-ar300m:green:status";
@ -75,10 +75,12 @@
&spi {
status = "okay";
num-cs = <0>;
num-cs = <2>;
cs-gpios = <0>, <0>;
flash@0 {
compatible = "winbond,w25q128", "jedec,spi-nor";
compatible = "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <25000000>;
@ -93,24 +95,45 @@
read-only;
};
partition@1 {
partition@40000 {
label = "u-boot-env";
reg = <0x040000 0x010000>;
};
partition@2 {
compatible = "denx,uimage";
label = "firmware";
nor_firmware: partition@50000 {
label = "nor_firmware";
reg = <0x050000 0xfa0000>;
};
art: partition@3 {
art: partition@ff0000 {
label = "art";
reg = <0xff0000 0x010000>;
read-only;
};
};
};
nand_flash: flash@1 {
compatible = "spi-nand";
reg = <1>;
spi-max-frequency = <25000000>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
nand_kernel: partition@0 {
label = "nand_kernel";
reg = <0x000000 0x400000>;
};
nand_ubi: partition@400000 {
label = "nand_ubi";
reg = <0x400000 0x7c00000>;
};
};
};
};
&uart {

View File

@ -94,9 +94,6 @@ glinet,gl-ar150)
ucidef_set_led_netdev "wan" "WAN" "$boardname:green:wan" "eth1"
ucidef_set_led_switch "lan" "LAN" "$boardname:green:lan" "switch0" "0x02"
;;
glinet,gl-ar300m-nor)
ucidef_set_led_netdev "lan" "LAN" "gl-ar300m:green:lan" "eth0"
;;
glinet,gl-ar300m-lite)
ucidef_set_led_netdev "lan" "LAN" "gl-ar300m-lite:green:lan" "eth0"
;;

View File

@ -562,12 +562,6 @@ define Device/glinet_gl-ar300m-lite
endef
TARGET_DEVICES += glinet_gl-ar300m-lite
define Device/glinet_gl-ar300m-nor
$(Device/glinet_gl-ar300m-common-nor)
DEVICE_MODEL := GL-AR300M
endef
TARGET_DEVICES += glinet_gl-ar300m-nor
define Device/glinet_gl-ar750
ATH_SOC := qca9531
DEVICE_VENDOR := GL.iNet

View File

@ -45,22 +45,36 @@ define Device/aerohive_hiveap-121
endef
TARGET_DEVICES += aerohive_hiveap-121
define Device/glinet_gl-ar300m-nand
define Device/glinet_gl-ar300m-common-nand
ATH_SOC := qca9531
DEVICE_VENDOR := GL.iNet
DEVICE_MODEL := GL-AR300M
DEVICE_VARIANT := NAND
DEVICE_PACKAGES := kmod-usb2 kmod-usb-storage kmod-usb-ledtrig-usbport
KERNEL_SIZE := 2048k
BLOCKSIZE := 128k
DEVICE_PACKAGES := kmod-usb2
KERNEL_SIZE := 4096k
IMAGE_SIZE := 16000k
PAGESIZE := 2048
VID_HDR_OFFSET := 512
IMAGES += factory.ubi
IMAGE/sysupgrade.bin := sysupgrade-tar
IMAGE/factory.ubi := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
VID_HDR_OFFSET := 2048
endef
define Device/glinet_gl-ar300m-nand
$(Device/glinet_gl-ar300m-common-nand)
DEVICE_VARIANT := NAND
BLOCKSIZE := 128k
IMAGES += factory.img
IMAGE/factory.img := append-kernel | pad-to $$$$(KERNEL_SIZE) | append-ubi
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
SUPPORTED_DEVICES += glinet,gl-ar300m-nor
endef
TARGET_DEVICES += glinet_gl-ar300m-nand
define Device/glinet_gl-ar300m-nor
$(Device/glinet_gl-ar300m-common-nand)
DEVICE_VARIANT := NOR
BLOCKSIZE := 64k
SUPPORTED_DEVICES += glinet,gl-ar300m-nand gl-ar300m
endef
TARGET_DEVICES += glinet_gl-ar300m-nor
# fake rootfs is mandatory, pad-offset 129 equals (2 * uimage_header + 0xff)
define Device/netgear_ath79_nand
DEVICE_VENDOR := NETGEAR

View File

@ -8,7 +8,8 @@ board=$(board_name)
boardname="${board##*,}"
case "$board" in
glinet,gl-ar300m-nand)
glinet,gl-ar300m-nand|\
glinet,gl-ar300m-nor)
ucidef_set_led_netdev "lan" "LAN" "gl-ar300m:green:lan" "eth0"
;;
netgear,wndr4300)

View File

@ -0,0 +1,13 @@
#!/bin/sh /etc/rc.common
# SPDX-License-Identifier: GPL-2.0
START=99
boot() {
case $(board_name) in
glinet,gl-ar300m-nand)
fw_setenv bootcount 0
;;
esac
}

View File

@ -0,0 +1,90 @@
# SPDX-License-Identifier: GPL-2.0
#
# Copyright (C) 2019 Jeff Kletsky
#
glinet_using_boot_dev_switch() {
if [ "$(fw_printenv -n boot_dev 2>/dev/null)" = "on" ] ; then
>&2 echo "NOTE: boot_dev=on; use switch to control boot partition"
true
else
false
fi
}
glinet_set_next_boot_nand() {
mkdir -p /var/lock
! glinet_using_boot_dev_switch && \
fw_setenv bootcount 0 && \
>&2 echo "Next boot set for NAND"
}
glinet_set_next_boot_nor() {
mkdir -p /var/lock
! glinet_using_boot_dev_switch && \
fw_setenv bootcount 3 && \
>&2 echo "Next boot set for NOR"
}
glinet_nand_nor_do_upgrade() {
set_next_boot_nand() { glinet_set_next_boot_nand; }
set_next_boot_nor() { glinet_set_next_boot_nor; }
nand_nor_do_upgrade "$1"
}
nand_nor_do_upgrade() {
local upgrade_file="$1"
local pn
local found=""
local err
case "$(get_magic_long "$upgrade_file")" in
"27051956") # U-Boot Image Magic
for pn in "nor_${PART_NAME}" "$PART_NAME" ; do # firmware
if [ "$(find_mtd_index "$pn")" ] ; then
PART_NAME="$pn"
found="yes"
break
fi
done
if [ "$found" = "yes" ] ; then
>&2 echo "Running NOR upgrade"
default_do_upgrade "$upgrade_file"
# At this time, default_do_upgrade() exits on error
type set_next_boot_nor >/dev/null && set_next_boot_nor
else
>&2 echo "ERROR: UPGRADE FAILED: Unable to locate '$PART_NAME' or 'nor_${PART_NAME}'"
exit 1
fi
;;
*) # otherwise a file that nand_do_upgrade can process
for pn in "nand_${CI_KERNPART}" "$CI_KERNPART" ; do # kernel
if [ "$(find_mtd_index "$pn")" ] ; then
CI_KERNPART="$pn"
break
fi
done
for pn in "nand_${CI_UBIPART}" "$CI_UBIPART" ; do # ubi
if [ "$(find_mtd_index "$pn")" ] ; then
CI_UBIPART="$pn"
break
fi
done
for pn in "nand_${CI_ROOTPART}" "$CI_ROOTPART" ; do #rootfs
if [ "$(find_mtd_index "$pn")" ] ; then
CI_ROOTPART="$pn"
break
fi
done
>&2 echo "Running NAND upgrade"
# TODO: change order when NAND upgrade offers return
type set_next_boot_nand >/dev/null && set_next_boot_nand
nand_do_upgrade "$upgrade_file"
;;
esac
}

View File

@ -1,20 +1,22 @@
#
# Copyright (C) 2011 OpenWrt.org
#
PART_NAME=firmware
REQUIRE_IMAGE_METADATA=1
REQUIRE_IMAGE_METADATA=1
platform_check_image() {
return 0
}
RAMFS_COPY_BIN='fw_printenv fw_setenv'
RAMFS_COPY_DATA='/etc/fw_env.config /var/lock/fw_printenv.lock'
platform_do_upgrade() {
local board=$(board_name)
case "$board" in
glinet,gl-ar300m-nand)
default_do_upgrade "$1"
glinet,gl-ar300m-nand|\
glinet,gl-ar300m-nor)
glinet_nand_nor_do_upgrade "$1"
;;
*)
nand_do_upgrade "$1"