From cd7d6a23f7f53e7b7adde38b1775bb153d6e8a61 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Tue, 25 Sep 2012 12:57:41 +0000
Subject: ar71xx: create 'fat' images for the DIR-825/TEW-673GRU boards

With these images, it is possible to use the 'unused'
partition of the flash. The 'fat' images can be installed
with the sysupgrade command. When a 'fat' image is
installed from a regular one, the platform specific
sysupgrade script copies the calibration data to the
end of the flash. Likewise, when a regular image is
installed  from the 'fat' version the sysupgrade script
copies the calibration data back to the original location.

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@33540 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../linux/ar71xx/base-files/lib/upgrade/dir825.sh  | 177 +++++++++++++++++++++
 .../ar71xx/base-files/lib/upgrade/platform.sh      |  12 +-
 2 files changed, 187 insertions(+), 2 deletions(-)
 create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/dir825.sh

(limited to 'target/linux/ar71xx/base-files')

diff --git a/target/linux/ar71xx/base-files/lib/upgrade/dir825.sh b/target/linux/ar71xx/base-files/lib/upgrade/dir825.sh
new file mode 100644
index 0000000000..e16128a9c5
--- /dev/null
+++ b/target/linux/ar71xx/base-files/lib/upgrade/dir825.sh
@@ -0,0 +1,177 @@
+#!/bin/sh
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+
+. /lib/functions.sh
+. /lib/ar71xx.sh
+
+get_mtd_part_size() {
+	local part_name=$1
+	local first dev size erasesize name
+	while read dev size erasesize name; do
+		name=${name#'"'}; name=${name%'"'}
+		if [ "$name" = "$part_name" ]; then
+			echo $((0x$size))
+			break
+		fi
+	done < /proc/mtd
+}
+
+get_magic_at() {
+	local mtddev=$1
+	local pos=$2
+	dd bs=1 count=2 skip=$pos if=$mtddev 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
+}
+
+dir825b_is_caldata_valid() {
+	local mtddev=$1
+	local magic
+
+	magic=$(get_magic_at $mtddev 4096)
+	[ "$magic" != "a55a" ] && return 0
+
+	magic=$(get_magic_at $mtddev 20480)
+	[ "$magic" != "a55a" ] && return 0
+
+	return 1
+}
+
+dir825b_copy_caldata() {
+	local cal_src=$1
+	local cal_dst=$2
+	local mtd_src
+	local mtd_dst
+	local md5_src
+	local md5_dst
+
+	mtd_src=$(find_mtd_part $cal_src)
+	[ -z "$mtd_src" ] && {
+		echo "no $cal_src partition found"
+		return 1
+	}
+
+	mtd_dst=$(find_mtd_part $cal_dst)
+	[ -z "$mtd_dst" ] && {
+		echo "no $cal_dst partition found"
+		return 1
+	}
+
+	dir825b_is_caldata_valid "$mtd_src" && {
+		echo "no valid calibration data found in $cal_src"
+		return 1
+	}
+
+	dir825b_is_caldata_valid "$mtd_dst" && {
+		echo "Copying calibration data from $cal_src to $cal_dst..."
+		dd if="$mtd_src" 2>/dev/null | mtd -q -q write - "$cal_dst"
+	}
+
+        md5_src=$(md5sum "$mtd_src") && md5_src="${md5_src%% *}"
+        md5_dst=$(md5sum "$mtd_dst") && md5_dst="${md5_dst%% *}"
+
+	[ "$md5_src" != "$md5_dst" ] && {
+		echo "calibration data mismatch $cal_src:$md5_src $cal_dst:$md5_dst"
+		return 1
+	}
+
+	return 0
+}
+
+dir825b_do_upgrade_combined() {
+	local fw_part=$1
+	local fw_file=$2
+	local fw_mtd=$(find_mtd_part $fw_part)
+	local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null)
+	local fw_blocks=$(($fw_length / 65536))
+
+	if [ -n "$fw_mtd" ] &&  [ ${fw_blocks:-0} -gt 0 ]; then
+		local append=""
+		[ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR"
+
+		sync
+		dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \
+			mtd $append write - "$fw_part"
+	fi
+}
+
+dir825b_check_image() {
+	local magic="$(get_magic_long "$1")"
+	local fw_mtd=$(find_mtd_part "firmware_orig")
+
+	case "$magic" in
+	"27051956")
+		;;
+	"43493030")
+		local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null)
+		local md5_chk=$(dd if="$1" bs=64k skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}"
+		local fw_len=$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null)
+		local fw_part_len=$(get_mtd_part_size "firmware")
+
+		if [ -z "$fw_mtd" ]; then
+			ask_bool 0 "Do you have a backup of the caldata partition?" || {
+				echo "Warning, please make sure that you have a backup of the caldata partition."
+				echo "Once you have that, use 'sysupgrade -i' for upgrading to the 'fat' firmware."
+				return 1
+			}
+		fi
+
+		if [ -z "$md5_img" -o -z "$md5_chk" ]; then
+			echo "Unable to get image checksums. Maybe you are using a streamed image?"
+			return 1
+		fi
+
+		if [ "$md5_img" != "$md5_chk" ]; then
+			echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)"
+			return 1
+		fi
+
+		fw_len=$((0x$fw_len))
+		fw_part_len=${fw_part_len:-0}
+
+		if [ $fw_part_len -lt $fw_len ]; then
+			echo "The upgrade image is too big (size:$fw_len available:$fw_part_len)"
+			return 1
+		fi
+		;;
+	*)
+		echo "Unsupported image format."
+		return 1
+		;;
+	esac
+
+	return 0
+}
+
+platform_do_upgrade_dir825b() {
+	local magic="$(get_magic_long "$1")"
+	local fw_mtd=$(find_mtd_part "firmware_orig")
+
+	case "$magic" in
+	"27051956")
+		if [ -n "$fw_mtd" ]; then
+			# restore calibration data before downgrading to
+			# the normal image
+			dir825b_copy_caldata "caldata" "caldata_orig" || {
+				echo "unable to restore calibration data"
+				exit 1
+			}
+			PART_NAME="firmware_orig"
+		else
+			PART_NAME="firmware"
+		fi
+		default_do_upgrade "$ARGV"
+		;;
+	"43493030")
+		if [ -z "$fw_mtd" ]; then
+			# backup calibration data before upgrading to the
+			# fat image
+			dir825b_copy_caldata "caldata" "caldata_copy" || {
+				echo "unable to backup calibration data"
+				exit 1
+			}
+		fi
+		dir825b_do_upgrade_combined "firmware" "$ARGV"
+		;;
+	esac
+}
diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
index 9f4ce2cb83..cdd463edbe 100755
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
@@ -100,13 +100,11 @@ platform_check_image() {
 	dir-600-a1 | \
 	dir-615-c1 | \
 	dir-615-e4 | \
-	dir-825-b1 | \
 	ew-dorin | \
 	ew-dorin-router | \
 	mzk-w04nu | \
 	mzk-w300nh | \
 	tew-632brp | \
-	tew-673gru | \
 	tew-712br | \
 	wrt400n | \
 	airrouter | \
@@ -130,6 +128,12 @@ platform_check_image() {
 		}
 		return 0
 		;;
+
+	dir-825-b1 | \
+	tew-673gru)
+		dir825b_check_image "$1" && return 0
+		;;
+
 	om2p | \
 	om2p-lc)
 		platform_check_image_om2p "$magic_long" "$1" && return 0
@@ -239,6 +243,10 @@ platform_do_upgrade() {
 	all0315n )
 		platform_do_upgrade_allnet "0x9f080000" "$ARGV"
 		;;
+	dir-825-b1 |\
+	tew-673gru)
+		platform_do_upgrade_dir825b "$ARGV"
+		;;
 	om2p | \
 	om2p-lc)
 		platform_do_upgrade_om2p "$ARGV"
-- 
cgit v1.2.3