ar71xx: add support for the devolo dLAN pro 500 Wireless+
[15.05/openwrt.git] / target / linux / ar71xx / base-files / lib / upgrade / dir825.sh
1 #!/bin/sh
2 #
3 # Copyright (C) 2012 OpenWrt.org
4 #
5
6 . /lib/functions.sh
7 . /lib/ar71xx.sh
8
9 get_magic_at() {
10         local mtddev=$1
11         local pos=$2
12         dd bs=1 count=2 skip=$pos if=$mtddev 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"'
13 }
14
15 dir825b_is_caldata_valid() {
16         local mtddev=$1
17         local magic
18
19         magic=$(get_magic_at $mtddev 4096)
20         [ "$magic" != "a55a" ] && return 0
21
22         magic=$(get_magic_at $mtddev 20480)
23         [ "$magic" != "a55a" ] && return 0
24
25         return 1
26 }
27
28 dir825b_copy_caldata() {
29         local cal_src=$1
30         local cal_dst=$2
31         local mtd_src
32         local mtd_dst
33         local md5_src
34         local md5_dst
35
36         mtd_src=$(find_mtd_part $cal_src)
37         [ -z "$mtd_src" ] && {
38                 echo "no $cal_src partition found"
39                 return 1
40         }
41
42         mtd_dst=$(find_mtd_part $cal_dst)
43         [ -z "$mtd_dst" ] && {
44                 echo "no $cal_dst partition found"
45                 return 1
46         }
47
48         dir825b_is_caldata_valid "$mtd_src" && {
49                 echo "no valid calibration data found in $cal_src"
50                 return 1
51         }
52
53         dir825b_is_caldata_valid "$mtd_dst" && {
54                 echo "Copying calibration data from $cal_src to $cal_dst..."
55                 dd if="$mtd_src" 2>/dev/null | mtd -q -q write - "$cal_dst"
56         }
57
58         md5_src=$(md5sum "$mtd_src") && md5_src="${md5_src%% *}"
59         md5_dst=$(md5sum "$mtd_dst") && md5_dst="${md5_dst%% *}"
60
61         [ "$md5_src" != "$md5_dst" ] && {
62                 echo "calibration data mismatch $cal_src:$md5_src $cal_dst:$md5_dst"
63                 return 1
64         }
65
66         return 0
67 }
68
69 dir825b_do_upgrade_combined() {
70         local fw_part=$1
71         local fw_file=$2
72         local fw_mtd=$(find_mtd_part $fw_part)
73         local fw_length=0x$(dd if="$fw_file" bs=2 skip=1 count=4 2>/dev/null)
74         local fw_blocks=$(($fw_length / 65536))
75
76         if [ -n "$fw_mtd" ] &&  [ ${fw_blocks:-0} -gt 0 ]; then
77                 local append=""
78                 [ -f "$CONF_TAR" -a "$SAVE_CONFIG" -eq 1 ] && append="-j $CONF_TAR"
79
80                 sync
81                 dd if="$fw_file" bs=64k skip=1 count=$fw_blocks 2>/dev/null | \
82                         mtd $append write - "$fw_part"
83         fi
84 }
85
86 dir825b_check_image() {
87         local magic="$(get_magic_long "$1")"
88         local fw_mtd=$(find_mtd_part "firmware_orig")
89
90         case "$magic" in
91         "27051956")
92                 ;;
93         "43493030")
94                 local md5_img=$(dd if="$1" bs=2 skip=9 count=16 2>/dev/null)
95                 local md5_chk=$(dd if="$1" bs=64k skip=1 2>/dev/null | md5sum -); md5_chk="${md5_chk%% *}"
96                 local fw_len=$(dd if="$1" bs=2 skip=1 count=4 2>/dev/null)
97                 local fw_part_len=$(mtd_get_part_size "firmware")
98
99                 if [ -z "$fw_mtd" ]; then
100                         ask_bool 0 "Do you have a backup of the caldata partition?" || {
101                                 echo "Warning, please make sure that you have a backup of the caldata partition."
102                                 echo "Once you have that, use 'sysupgrade -i' for upgrading to the 'fat' firmware."
103                                 return 1
104                         }
105                 fi
106
107                 if [ -z "$md5_img" -o -z "$md5_chk" ]; then
108                         echo "Unable to get image checksums. Maybe you are using a streamed image?"
109                         return 1
110                 fi
111
112                 if [ "$md5_img" != "$md5_chk" ]; then
113                         echo "Invalid image. Contents do not match checksum (image:$md5_img calculated:$md5_chk)"
114                         return 1
115                 fi
116
117                 fw_len=$((0x$fw_len))
118                 fw_part_len=${fw_part_len:-0}
119
120                 if [ $fw_part_len -lt $fw_len ]; then
121                         echo "The upgrade image is too big (size:$fw_len available:$fw_part_len)"
122                         return 1
123                 fi
124                 ;;
125         *)
126                 echo "Unsupported image format."
127                 return 1
128                 ;;
129         esac
130
131         return 0
132 }
133
134 platform_do_upgrade_dir825b() {
135         local magic="$(get_magic_long "$1")"
136         local fw_mtd=$(find_mtd_part "firmware_orig")
137
138         case "$magic" in
139         "27051956")
140                 if [ -n "$fw_mtd" ]; then
141                         # restore calibration data before downgrading to
142                         # the normal image
143                         dir825b_copy_caldata "caldata" "caldata_orig" || {
144                                 echo "unable to restore calibration data"
145                                 exit 1
146                         }
147                         PART_NAME="firmware_orig"
148                 else
149                         PART_NAME="firmware"
150                 fi
151                 default_do_upgrade "$ARGV"
152                 ;;
153         "43493030")
154                 if [ -z "$fw_mtd" ]; then
155                         # backup calibration data before upgrading to the
156                         # fat image
157                         dir825b_copy_caldata "caldata" "caldata_copy" || {
158                                 echo "unable to backup calibration data"
159                                 exit 1
160                         }
161                 fi
162                 dir825b_do_upgrade_combined "firmware" "$ARGV"
163                 ;;
164         esac
165 }